Compare commits
134 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 85ca4fd100 | |||
| 136b1cc924 | |||
| e4b7d528f5 | |||
| 2903ebfbac | |||
| 931ca1b2c0 | |||
| 85e724d88a | |||
| e41f83a2dd | |||
| 69b52cfe88 | |||
| 7591821e57 | |||
| 0ce0dcf2e9 | |||
| 73811c3a6b | |||
| 2a887b7794 | |||
| ad9f482e76 | |||
| 6eaef94459 | |||
| 4f5c616240 | |||
| f5947dded9 | |||
| 77e0acc16b | |||
| e48646c5ff | |||
| 5e48fe51ea | |||
| 6b30dbef65 | |||
| d6508a2be4 | |||
| dfcadfb3bd | |||
| 7888b92129 | |||
| 5b48dffa77 | |||
| 5bf4650da1 | |||
| 8e9c270b77 | |||
| 00080331df | |||
| 27e40e2069 | |||
| 3a93877de3 | |||
| 7f70784cd3 | |||
| ed6e3df66e | |||
| eb5becbbd4 | |||
| 9599316fbc | |||
| cc1c951ef8 | |||
| d23c4cba18 | |||
| 3d30b0b96f | |||
| ad1e5d555a | |||
| 14ea5f1c72 | |||
| 709d44e4d9 | |||
| 8df00e9c41 | |||
| 8dbb0ec058 | |||
| b8310eedae | |||
| c04754afe1 | |||
| 3155aa6815 | |||
| ea27b1a081 | |||
| 4d078f9597 | |||
| 67459cbbbd | |||
| 932de4e969 | |||
| 41e28291ad | |||
| 6ae6324368 | |||
| 4858716f05 | |||
| 24fb4cfe4a | |||
| 186138d0c0 | |||
| 6690564017 | |||
| 89a0a900cc | |||
| 391a24db3f | |||
| 4b546af642 | |||
| ee8aabbf97 | |||
| 45994e2b94 | |||
| 13bdc69da8 | |||
| c0184fde8e | |||
| cbd297e59d | |||
| c6cf7c950e | |||
| fe5d80e017 | |||
| e985a8f15b | |||
| 615767f758 | |||
| 65a24b2295 | |||
| 94c2afe67a | |||
| 9bbca37ecd | |||
| 58241a0f5c | |||
| a960a01ca1 | |||
| 67d8ee773c | |||
| c6f2675278 | |||
| 2380be230e | |||
| 833276b7b3 | |||
| 9b32835720 | |||
| 61634a9cc3 | |||
| 408a35db8d | |||
| 9695a85131 | |||
| d027cf4f2a | |||
| c2f8bfc5b4 | |||
| 486425a62c | |||
| f9681d4c66 | |||
| cd0671dc59 | |||
| 7ebca16948 | |||
| e8cbdde518 | |||
| 7ca6f05151 | |||
| f4f17e90e5 | |||
| 3ea48efb1d | |||
| ffc3533688 | |||
| bd309855a2 | |||
| 1473c7e9b7 | |||
| 15cc7b6d18 | |||
| 1c89c5f779 | |||
| ca7f1cc8ca | |||
| 8fd1de84e4 | |||
| 95d9168b6b | |||
| c1db827132 | |||
| d10b78ab46 | |||
| 2d70523f43 | |||
| 42fb7ad3df | |||
| e90d0950d4 | |||
| 888d4190d1 | |||
| 57696b2538 | |||
| 1440537f6b | |||
| a16ff88c8d | |||
| 041de12ea7 | |||
| 5e36f66c4e | |||
| a6a5a6104d | |||
| 6f7b225ce8 | |||
| 81a85883d2 | |||
| 3f06d2fea4 | |||
| 26b390268a | |||
| 486d55f349 | |||
| 5948090d63 | |||
| 32340191de | |||
| 0b09875bb3 | |||
| 078a36d304 | |||
| 3ef4ec522b | |||
| cd6fa03990 | |||
| bba9fb68e6 | |||
| dcb7038833 | |||
| f8a058259d | |||
| 1696d5daeb | |||
| ac69af012a | |||
| 692546a232 | |||
| b0478b627f | |||
| 2cdca4b990 | |||
| 4c0b2adef4 | |||
| 191dd078b8 | |||
| 2de7807bec | |||
| 9d4f1dd370 | |||
| 6f769150b1 | |||
| 155dc0b621 |
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"homepage": "https://www.curseforge.com/minecraft/mc-mods/electroblobs-wizardry",
|
||||
"promos": {
|
||||
"1.12.2-latest": "4.3.11",
|
||||
"1.12.2-recommended": "4.3.11"
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Report a crash or something that isn't working as it should
|
||||
title: "[Give a brief, relevant title here]"
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/CONTRIBUTING.md) before posting.
|
||||
|
||||
Minecraft version: 1.12.2 [change as necessary]
|
||||
Wizardry version: 4.3.3 [change as necessary]
|
||||
Environment: Singleplayer/LAN game/Server [delete as necessary]
|
||||
|
||||
Issue details: [describe what you were doing when the issue occurred, what went wrong, what you expected to happen, etc.]
|
||||
|
||||
Other mods involved: [only list mods that are relevant to the problem]
|
||||
|
||||
Link to crash report (if applicable): [give a link to the crash report on gist, pastebin, etc.]
|
||||
@@ -0,0 +1,85 @@
|
||||
name: 🐛 Bug Report
|
||||
description: Something is not working as expected
|
||||
title: "[Bug] <write the title here>"
|
||||
labels: [ "bug", "Needs Triage" ]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/CONTRIBUTING.md) before posting. You may also find the [troubleshooting page](https://github.com/Electroblob77/Wizardry/wiki/Troubleshooting) helpful.
|
||||
Please try the latest version of the mod and check if the issue persist before submitting a report.
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Is there an existing issue for this?
|
||||
description: Please search to see if an issue already exists for the bug you encountered.
|
||||
options:
|
||||
- label: I have searched the existing issues
|
||||
required: true
|
||||
- type: textarea
|
||||
id: observed
|
||||
attributes:
|
||||
label: Observed behaviour
|
||||
description: Describe what happened and when this happened
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: expected
|
||||
attributes:
|
||||
label: Expected behaviour
|
||||
description: Describe what you expected to happen
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduction
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Step by step instructions on how to reproduce the observed behaviour
|
||||
placeholder: |
|
||||
1. Join a server
|
||||
2. Cast the [spell]
|
||||
3. ...
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: crashlog
|
||||
attributes:
|
||||
label: Crashlog
|
||||
description: If this was a crash, grab [minecraft instance]/logs/debug.log, upload it as a [gist](https://gist.github.com/) and paste the link here. Alternatively, give a link to the crash report on gist, pastebin if you already have one there.
|
||||
placeholder: https://gist.github.com/<your-user>/abcdef124
|
||||
- type: dropdown
|
||||
id: environment
|
||||
attributes:
|
||||
label: Environment (Singleplayer/Server, etc.)
|
||||
options:
|
||||
- Singleplayer
|
||||
- LAN game/Server
|
||||
- Issue present on both sides
|
||||
- Not sure
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: mod-version
|
||||
attributes:
|
||||
label: Mod version
|
||||
placeholder: 1.0.0
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: minecraft-version
|
||||
attributes:
|
||||
label: Minecraft version
|
||||
placeholder: 12.2.2
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: forge-version
|
||||
attributes:
|
||||
label: Forge version
|
||||
placeholder: 1.12.2 - 14.23.5.2860
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: other-mods
|
||||
attributes:
|
||||
label: Other mods
|
||||
description: List any other mods present when the bug was encountered, include the mod versions. You only have to fill this if no crash log was attached
|
||||
@@ -0,0 +1,14 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: 📖 Mod Wiki Page
|
||||
url: https://github.com/Electroblob77/Wizardry/wiki
|
||||
about: Most features are documented in the mod's wiki page --- Link --->
|
||||
- name: 💬 Electroblob's Wizardry discord
|
||||
url: https://discord.gg/hs8yJP2
|
||||
about: Ask for help or get more info on Discord. --- Discord Server link --->
|
||||
- name: 💡 Feature requests / suggestions
|
||||
url: https://discord.gg/hs8yJP2
|
||||
about: Please use the discord server to suggest stuff. --- Discord Server link --->
|
||||
- name: ❓ Question
|
||||
url: https://discord.gg/hs8yJP2
|
||||
about: Ask a question about the mod or the code. --- Discord Server link --->
|
||||
@@ -1,16 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Make a suggestion for improving the mod
|
||||
title: "[Give a brief, relevant title here]"
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/CONTRIBUTING.md) before posting.
|
||||
|
||||
Minecraft versions: [if this suggestion only applies to some versions, list them here]
|
||||
|
||||
Suggestion details: [describe what you would like to see added to the mod and why]
|
||||
|
||||
Other mods involved: [if this suggestion involves integration with other mods, list them here]
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
name: Question
|
||||
about: Ask a question about the mod or the code
|
||||
title: "[Give a brief, relevant title here]"
|
||||
labels: question
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/CONTRIBUTING.md) before posting.
|
||||
|
||||
Minecraft version: 1.12.2 [change as necessary]
|
||||
Wizardry version: 4.3.3 [change as necessary]
|
||||
|
||||
Question details: [explain your question here]
|
||||
|
||||
Other mods involved: [if this question involves other mods, list them here]
|
||||
@@ -0,0 +1,38 @@
|
||||
name: Potential Duplicates
|
||||
on:
|
||||
issues:
|
||||
types: [opened, edited]
|
||||
|
||||
jobs:
|
||||
run:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: bubkoo/potential-duplicates@v1
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
label: potential duplicate
|
||||
exclude: |
|
||||
adding
|
||||
add
|
||||
creating
|
||||
create
|
||||
icons
|
||||
icon
|
||||
logos
|
||||
logo
|
||||
missing
|
||||
miss
|
||||
needing
|
||||
need
|
||||
please
|
||||
requesting
|
||||
request
|
||||
1.12.2
|
||||
wizardry
|
||||
state: all
|
||||
threshold: 0.7
|
||||
comment: |
|
||||
This issue is potentially a duplicate of one of the following issues:
|
||||
{{#issues}}
|
||||
- [#{{ number }}] {{ title }} ({{ accuracy }}% match)
|
||||
{{/issues}}
|
||||
+8
-2
@@ -1,7 +1,7 @@
|
||||
# Credits
|
||||
|
||||
Electroblob's Wizardry
|
||||
Version 4.3.3
|
||||
Version 4.3.7
|
||||
For Minecraft 1.12.2
|
||||
|
||||
Designed, coded and textured by Electroblob
|
||||
@@ -12,6 +12,11 @@ Thanks also to the Minecraft modding community, which always has an answer to my
|
||||
|
||||
In addition, I'd like to thank the following individuals for their contributions to the mod:
|
||||
|
||||
#### Discord Moderators (and all-round awesome people)
|
||||
|
||||
- FavouriteDragon
|
||||
- WinDanesz
|
||||
|
||||
#### Code
|
||||
|
||||
- Corail31
|
||||
@@ -27,13 +32,14 @@ In addition, I'd like to thank the following individuals for their contributions
|
||||
- rafasoares
|
||||
- xinyuan-liu
|
||||
- SettingDust
|
||||
- Aralu115
|
||||
|
||||
#### Translations
|
||||
|
||||
- Spanish: MadWrist, Alsentar
|
||||
- Mexican Spanish: MadWrist
|
||||
- Russian: VilagVil, kellixon, bigenergy, MugGod2, DrHesperus
|
||||
- French: Hahdrim
|
||||
- French: Hahdrim, Crowller
|
||||
- Brazilian Portuguese: lorrampi
|
||||
- Chinese (Simplified): ZHENGLOC, dragon-evol, Hokorizero, TUsama, Determancer
|
||||
- Korean: shejery, rewi_wire, 방통, red1854th
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/guide_for_contributing.md) before posting.
|
||||
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/guide_for_contributing.md) before posting. You may also find the [troubleshooting page](https://github.com/Electroblob77/Wizardry/wiki/Troubleshooting) helpful.
|
||||
|
||||
Minecraft version: 1.12.2 [change as necessary]
|
||||
Wizardry version: 4.3.3 [change as necessary]
|
||||
Wizardry version: [change as necessary]
|
||||
Environment: Singleplayer/LAN game/Server [delete as necessary]
|
||||
|
||||
Issue details: [describe what you were doing when the issue occurred, what went wrong, what you expected to happen, etc.]
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ apply plugin: 'net.minecraftforge.gradle.forge'
|
||||
//Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
|
||||
|
||||
|
||||
version = "4.3.3" // There, it matches semver, happy now?
|
||||
version = "4.3.11"
|
||||
group= "electroblob.wizardry"// http://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||
archivesBaseName = "ElectroblobsWizardry"
|
||||
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+1
-2
@@ -1,6 +1,5 @@
|
||||
#Mon Sep 14 12:28:28 PDT 2015
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/usr/bin/env sh
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
@@ -6,47 +6,6 @@
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
||||
if $cygwin ; then
|
||||
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
fi
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
@@ -61,9 +20,49 @@ while [ -h "$PRG" ] ; do
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >&-
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >&-
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
@@ -79,18 +78,18 @@ if [ -n "$JAVA_HOME" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
locations of your Java installation."
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
locations of your Java installation."
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
@@ -114,6 +113,7 @@ fi
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
@@ -154,11 +154,19 @@ if $cygwin ; then
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
||||
Vendored
+6
-12
@@ -8,14 +8,14 @@
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
@@ -27,7 +27,7 @@ echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo locations of your Java installation.
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
@@ -41,15 +41,14 @@ echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo locations of your Java installation.
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
@@ -60,11 +59,6 @@ set _SKIP=2
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
@@ -156,6 +156,12 @@ public final class Settings {
|
||||
public Pair<ResourceLocation, Short>[] treeBlocks = parseItemMetaStrings(DEFAULT_TREE_BLOCKS);
|
||||
/** <b>[Server-only]</b> The chance for wizard towers to generate with an evil wizard and chest inside. */
|
||||
public double evilWizardChance = 0.2;
|
||||
public double cooldownReductionPerLevel = 0.15;
|
||||
public double potencyIncreasePerTier = 0.15;
|
||||
public double durationIncreasePerLevel = 0.25;
|
||||
public double rangeIncreasePerLevel = 0.25;
|
||||
public double blastIncreasePerLevel = 0.25;
|
||||
public double frostSlownessIncreasePerLevel = 0.5;
|
||||
/** <b>[Server-only]</b> List of dimension ids in which to generate crystal ore. */
|
||||
public int[] oreDimensions = {0};
|
||||
/** <b>[Server-only]</b> List of dimension ids in which to generate crystal flowers. */
|
||||
@@ -192,12 +198,23 @@ public final class Settings {
|
||||
public boolean playerBlockDamage = true;
|
||||
/** <b>[Server-only]</b> Whether spells cast by dispensers can destroy blocks in the world. */
|
||||
public boolean dispenserBlockDamage = true;
|
||||
/** <b>[Server-only]</b> Whether damage should be registered with the old system (wizardry_magic/indirect_wizardry_magic) prefixed damage with the elements like
|
||||
* necromancy_indirect_wizardry_magic, necromancy_wizardry_magic*/
|
||||
public boolean damageTypePerElement = false;
|
||||
/** <b>[Server-only]</b> Whether spell books are consumed when they are bound to a wand.*/
|
||||
public boolean singleUseSpellBooks = false;
|
||||
/** <b>[Server-only]</b> Whether to prevent binding the same spell to a wand multiple times*/
|
||||
public boolean preventBindingSameSpellTwiceToWands = false;
|
||||
/** <b>[Server-only]</b> Whether to revert to the old wand upgrade system, which only requires tomes of arcana. */
|
||||
public boolean legacyWandLevelling = false;
|
||||
/** <b>[Server-only]</b> Whether to tweak the blindness effect to reduce follow distance when used on non-players. */
|
||||
public boolean blindnessTweak = true;
|
||||
/** <b>[Server-only]</b> Whether using bonemeal on grass blocks has a chance to grow crystal flowers. */
|
||||
public boolean bonemealGrowsCrystalFlowers = true;
|
||||
/** <b>[Server-only]</b> Whether wands only decrement their cooldowns if a player holds them. */
|
||||
public boolean wandsMustBeHeldToDecrementCooldown = false;
|
||||
/** <b>[Server-only]</b> Whether to enable Wizardry mob loot injection. Allows an easier switch instead of blacklisting all entities. */
|
||||
public boolean injectMobDrops = true;
|
||||
/**
|
||||
* <b>[Server-only]</b> List of registry names of entities which summoned creatures are allowed to attack, in addition
|
||||
* to the defaults.
|
||||
@@ -377,6 +394,9 @@ public final class Settings {
|
||||
public boolean showSpellHUD = true;
|
||||
/** <b>[Client-only]</b> Whether to show the charge meter when charging up a spell. */
|
||||
public boolean showChargeMeter = true;
|
||||
/** <b>[Client-only]</b> Whether to initialise the handbook's data. Setting this to false will break the in-game handbook, but might help with some
|
||||
* startup crashes */
|
||||
public boolean loadHandbook = true;
|
||||
/** <b>[Client-only]</b> The position of the spell HUD. */
|
||||
public GuiPosition spellHUDPosition = GuiPosition.BOTTOM_LEFT;
|
||||
|
||||
@@ -612,6 +632,29 @@ public final class Settings {
|
||||
dispenserBlockDamage = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(GAMEPLAY_CATEGORY, "damageTypePerElement", false,
|
||||
"Whether damage should be registered with the old system (wizardry_magic/indirect_wizardry_magic) prefixed damage with the elements like "
|
||||
+ "necromancy_indirect_wizardry_magic, necromancy_wizardry_magic. This is disabled by default to not break existing modpacks."
|
||||
+ "The intention of this setting is to allow differentiating various damage types for e.g. the Distinct Damage Descriptions mod");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".damage_type_per_element");
|
||||
Wizardry.proxy.setToNamedBooleanEntry(property);
|
||||
damageTypePerElement = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(GAMEPLAY_CATEGORY, "singleUseSpellBooks", false,
|
||||
"Whether spell books are consumed when they are bound to a wand.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".single_use_spell_books");
|
||||
Wizardry.proxy.setToNamedBooleanEntry(property);
|
||||
singleUseSpellBooks = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(GAMEPLAY_CATEGORY, "preventBindingSameSpellTwiceToWands", false,
|
||||
"Whether to prevent binding the same spell to a wand multiple times");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".prevent_binding_same_spell_twice_to_wands");
|
||||
Wizardry.proxy.setToNamedBooleanEntry(property);
|
||||
preventBindingSameSpellTwiceToWands = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(GAMEPLAY_CATEGORY, "playersMoveEachOther", true,
|
||||
"Whether to allow players to move other players around using magic.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".players_move_each_other");
|
||||
@@ -663,6 +706,13 @@ public final class Settings {
|
||||
bonemealGrowsCrystalFlowers = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(GAMEPLAY_CATEGORY, "wandsMustBeHeldToDecrementCooldown", false,
|
||||
"Whether wands only decrement their cooldowns if a player holds them.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".wands_must_be_held_to_decrement_cooldown");
|
||||
Wizardry.proxy.setToNamedBooleanEntry(property);
|
||||
wandsMustBeHeldToDecrementCooldown = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
checkForRedundantOptions(GAMEPLAY_CATEGORY, propOrder); // Must be before the order is set!
|
||||
config.setCategoryPropertyOrder(GAMEPLAY_CATEGORY, propOrder);
|
||||
|
||||
@@ -807,6 +857,13 @@ public final class Settings {
|
||||
blindnessTweak = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(TWEAKS_CATEGORY, "injectMobDrops", true,
|
||||
"Whether to inject Wizardry loot to mobs, based on the loot table 'Mob Loot Table Whitelist' / 'Mob Loot Table Blacklist' settings. If disabled, the lists won't have any effect!");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".inject_mob_drops");
|
||||
Wizardry.proxy.setToNamedBooleanEntry(property);
|
||||
injectMobDrops = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(TWEAKS_CATEGORY, "mobLootTableWhitelist", new String[0], "Whitelist for loot tables to inject additional mob drops (as specified in loot_tables/entities/mob_additions.json) into. Wizardry makes a best guess as to which loot tables belong to hostile mobs, but this may not always be correct or appropriate; add loot table locations (not entity IDs) to this list to manually include them.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".mob_loot_table_whitelist");
|
||||
property.setRequiresMcRestart(true);
|
||||
@@ -914,6 +971,50 @@ public final class Settings {
|
||||
}
|
||||
}
|
||||
|
||||
property = config.get(TWEAKS_CATEGORY, "cooldown_reduction_per_level", 0.15,
|
||||
"The fraction by which cooldowns are reduced for each level of cooldown upgrade.",
|
||||
0.05, Integer.MAX_VALUE); // Sure, I mean you COULD set it to 2^31-1... what could possibly go wrong?
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".cast_command_multiplier_limit");
|
||||
cooldownReductionPerLevel = property.getDouble();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(TWEAKS_CATEGORY, "potency_increase_per_tier", 0.15,
|
||||
"The fraction by which potency is increased for each tier of matching wand. May cause extreme lag with high values!",
|
||||
0.05, Integer.MAX_VALUE);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".potency_increase_per_tier");
|
||||
potencyIncreasePerTier = property.getDouble();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(TWEAKS_CATEGORY, "duration_increase_per_level", 0.25,
|
||||
"The fraction by which spell duration is increased for each level of duration upgrade.",
|
||||
0.05, Integer.MAX_VALUE);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".duration_increase_per_level");
|
||||
durationIncreasePerLevel = property.getDouble();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(TWEAKS_CATEGORY, "range_increase_per_level", 0.25,
|
||||
"The fraction by which spell range is increased for each level of range upgrade. May cause extreme lag with high values!",
|
||||
0.05, Integer.MAX_VALUE);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".range_increase_per_level");
|
||||
rangeIncreasePerLevel = property.getDouble();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(TWEAKS_CATEGORY, "blast_increase_per_level", 0.25,
|
||||
"The fraction by which spell blast is increased for each level of blast upgrade. May cause extreme lag with high values!",
|
||||
0.05, Integer.MAX_VALUE);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".blast_increase_per_level");
|
||||
blastIncreasePerLevel = property.getDouble();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
|
||||
property = config.get(TWEAKS_CATEGORY, "frost_slowness_increase_per_level", 0.5,
|
||||
"The fraction by which movement speed is reduced per level of frost effect.",
|
||||
0.05, Integer.MAX_VALUE);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".frost_slowness_increase_per_level");
|
||||
frostSlownessIncreasePerLevel = property.getDouble();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
|
||||
checkForRedundantOptions(TWEAKS_CATEGORY, propOrder); // Must be before the order is set!
|
||||
config.setCategoryPropertyOrder(TWEAKS_CATEGORY, propOrder);
|
||||
|
||||
@@ -1103,6 +1204,13 @@ public final class Settings {
|
||||
showChargeMeter = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(CLIENT_CATEGORY, "loadHandbook", true, "Whether to initialise the in-game handbook. Setting this to false will brick the in-game handbook, but it might help if you have startup crashes.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".load_handbook");
|
||||
property.setRequiresWorldRestart(false);
|
||||
Wizardry.proxy.setToNamedBooleanEntry(property);
|
||||
loadHandbook = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(CLIENT_CATEGORY, "spellHUDPosition", GuiPosition.BOTTOM_LEFT.name, "The position of the spell HUD.", GuiPosition.names);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".spell_hud_position");
|
||||
spellHUDPosition = GuiPosition.fromName(property.getString());
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package electroblob.wizardry;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonObject;
|
||||
import electroblob.wizardry.block.BlockBookshelf;
|
||||
import electroblob.wizardry.command.CommandCastSpell;
|
||||
import electroblob.wizardry.command.CommandDiscoverSpell;
|
||||
@@ -16,11 +13,23 @@ import electroblob.wizardry.inventory.ContainerBookshelf;
|
||||
import electroblob.wizardry.misc.DonationPerksHandler;
|
||||
import electroblob.wizardry.misc.Forfeit;
|
||||
import electroblob.wizardry.packet.WizardryPacketHandler;
|
||||
import electroblob.wizardry.registry.*;
|
||||
import electroblob.wizardry.registry.Spells;
|
||||
import electroblob.wizardry.registry.WizardryAdvancementTriggers;
|
||||
import electroblob.wizardry.registry.WizardryBlocks;
|
||||
import electroblob.wizardry.registry.WizardryItems;
|
||||
import electroblob.wizardry.registry.WizardryLoot;
|
||||
import electroblob.wizardry.registry.WizardrySounds;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
import electroblob.wizardry.util.SpellNetworkIDSorter;
|
||||
import electroblob.wizardry.util.SpellProperties;
|
||||
import electroblob.wizardry.util.WandHelper;
|
||||
import electroblob.wizardry.worldgen.*;
|
||||
import electroblob.wizardry.worldgen.WorldGenCrystalFlower;
|
||||
import electroblob.wizardry.worldgen.WorldGenCrystalOre;
|
||||
import electroblob.wizardry.worldgen.WorldGenLibraryRuins;
|
||||
import electroblob.wizardry.worldgen.WorldGenObelisk;
|
||||
import electroblob.wizardry.worldgen.WorldGenShrine;
|
||||
import electroblob.wizardry.worldgen.WorldGenUndergroundLibraryRuins;
|
||||
import electroblob.wizardry.worldgen.WorldGenWizardTower;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
@@ -39,8 +48,6 @@ import net.minecraftforge.fml.common.registry.GameRegistry;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.Calendar;
|
||||
|
||||
/**
|
||||
@@ -56,6 +63,7 @@ import java.util.Calendar;
|
||||
|
||||
@Mod(modid = Wizardry.MODID, name = Wizardry.NAME, version = Wizardry.VERSION, acceptedMinecraftVersions = "[1.12.2]",
|
||||
guiFactory = "electroblob.wizardry.WizardryGuiFactory",
|
||||
updateJSON = Wizardry.updateJSON,
|
||||
dependencies = "required-after:forge@[14.23.5.2847,);after:jei@[4.15.0,);after:baubles@[1.5.2,);after:antiqueatlas@[4.6,)")
|
||||
|
||||
public class Wizardry {
|
||||
@@ -74,7 +82,13 @@ public class Wizardry {
|
||||
* 1.x.x represents Minecraft 1.7.x versions, 2.x.x represents Minecraft 1.10.x versions, 3.x.x represents Minecraft
|
||||
* 1.11.x versions, and so on.
|
||||
*/
|
||||
public static final String VERSION = "4.3.3";
|
||||
public static final String VERSION = "4.3.11";
|
||||
|
||||
/**
|
||||
* Json file used by Forge's built-in <a href="https://mcforge.readthedocs.io/en/1.12.x/gettingstarted/autoupdate/">update checker</a>.
|
||||
* Used by the in-game mod menu to show that green icon whenever a newer version is available of the mod.
|
||||
*/
|
||||
public static final String updateJSON = "https://github.com/Electroblob77/Wizardry/blob/1.12.2/.forge/update.json";
|
||||
|
||||
// IDEA: Triggering of inbuilt Forge events in relevant places?
|
||||
// IDEA: Abstract the vanilla particles behind the particle builder
|
||||
@@ -113,11 +127,10 @@ public class Wizardry {
|
||||
public void preInit(FMLPreInitializationEvent event){
|
||||
|
||||
logger = event.getModLog();
|
||||
|
||||
proxy.registerResourceReloadListeners();
|
||||
|
||||
configDirectory = new File(event.getModConfigurationDirectory(), Wizardry.MODID);
|
||||
settings.initConfig(event);
|
||||
proxy.registerResourceReloadListeners();
|
||||
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
tisTheSeason = calendar.get(Calendar.MONTH) + 1 == 12 && calendar.get(Calendar.DAY_OF_MONTH) >= 24
|
||||
@@ -149,34 +162,6 @@ public class Wizardry {
|
||||
@EventHandler
|
||||
public void init(FMLInitializationEvent event){
|
||||
|
||||
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
|
||||
for(Item item : Item.REGISTRY){
|
||||
|
||||
if(item.getRegistryName().getNamespace().equals(MODID)){
|
||||
|
||||
try{
|
||||
|
||||
FileWriter writer = new FileWriter("generated\\" + item.getRegistryName().getPath() + ".json");
|
||||
|
||||
JsonObject json = new JsonObject();
|
||||
|
||||
json.addProperty("parent", "item/generated");
|
||||
|
||||
JsonObject textures = new JsonObject();
|
||||
textures.addProperty("layer0", MODID + ":items/" + item.getRegistryName().getPath());
|
||||
json.add("textures", textures);
|
||||
|
||||
gson.toJson(json, writer);
|
||||
|
||||
writer.close();
|
||||
|
||||
}catch(IOException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
settings.initConfigExtras();
|
||||
|
||||
// World generators
|
||||
@@ -217,6 +202,8 @@ public class Wizardry {
|
||||
public void postInit(FMLPostInitializationEvent event){
|
||||
proxy.initialiseLayers();
|
||||
proxy.initialiseAnimations();
|
||||
|
||||
SpellNetworkIDSorter.init();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
||||
@@ -203,7 +203,6 @@ public final class WizardryEventHandler {
|
||||
// Find the angle between the direction the mob is looking and the direction the player is in
|
||||
// Angle between a and b = acos((a.b) / (|a|*|b|))
|
||||
double angle = Math.acos(vec.dotProduct(event.getEntity().getLookVec()) / vec.length());
|
||||
System.out.println(angle);
|
||||
// If the player is not within the 144-degree arc in front of the mob, it won't detect them
|
||||
if(angle > 0.4 * Math.PI){
|
||||
((EntityLiving)event.getEntityLiving()).setAttackTarget(null);
|
||||
@@ -269,7 +268,7 @@ public final class WizardryEventHandler {
|
||||
// Fireskin
|
||||
if(event.getEntityLiving().isPotionActive(WizardryPotions.fireskin)
|
||||
&& !MagicDamage.isEntityImmune(DamageType.FIRE, event.getEntityLiving()))
|
||||
attacker.setFire(Spells.fire_breath.getProperty(Spell.BURN_DURATION).intValue());
|
||||
attacker.setFire(Spells.fire_breath.getProperty(Spell.BURN_DURATION).intValue() * 20);
|
||||
|
||||
// Ice Shroud
|
||||
if(event.getEntityLiving().isPotionActive(WizardryPotions.ice_shroud)
|
||||
@@ -307,7 +306,7 @@ public final class WizardryEventHandler {
|
||||
PotionEffect effect = event.getEntityLiving().getActivePotionEffect(WizardryPotions.ward);
|
||||
|
||||
if(effect != null && event.getSource().isMagicDamage()){
|
||||
event.setAmount(event.getAmount() * Math.max(0, 1 - 0.4f * effect.getAmplifier())); // Resistance is 20%
|
||||
event.setAmount(event.getAmount() * Math.max(0, 1 - 0.2f * (1 + effect.getAmplifier()))); // Resistance is 20%
|
||||
}
|
||||
|
||||
// Flaming and freezing swords
|
||||
@@ -491,4 +490,4 @@ public final class WizardryEventHandler {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package electroblob.wizardry.client;
|
||||
|
||||
import electroblob.wizardry.CommonProxy;
|
||||
import electroblob.wizardry.Settings;
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.block.BlockBookshelf;
|
||||
import electroblob.wizardry.client.animation.ActionAnimation;
|
||||
@@ -19,6 +20,7 @@ import electroblob.wizardry.client.model.ModelSageArmour;
|
||||
import electroblob.wizardry.client.model.ModelWizardArmour;
|
||||
import electroblob.wizardry.client.particle.*;
|
||||
import electroblob.wizardry.client.particle.ParticleWizardry.IWizardryParticleFactory;
|
||||
import electroblob.wizardry.client.renderer.RenderSpectralGolem;
|
||||
import electroblob.wizardry.client.renderer.entity.*;
|
||||
import electroblob.wizardry.client.renderer.entity.layers.*;
|
||||
import electroblob.wizardry.client.renderer.overlay.RenderBlinkEffect;
|
||||
@@ -164,7 +166,8 @@ public class ClientProxy extends CommonProxy {
|
||||
IResourceManager manager = Minecraft.getMinecraft().getResourceManager();
|
||||
if(manager instanceof IReloadableResourceManager){
|
||||
((IReloadableResourceManager)manager).registerReloadListener(GuiSpellDisplay::loadSkins);
|
||||
((IReloadableResourceManager)manager).registerReloadListener(GuiWizardHandbook::loadHandbookFile);
|
||||
if (Wizardry.settings.loadHandbook)
|
||||
((IReloadableResourceManager)manager).registerReloadListener(GuiWizardHandbook::loadHandbookFile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -728,6 +731,9 @@ public class ClientProxy extends CommonProxy {
|
||||
LayerTiledOverlay.initialiseLayers(LayerMindControl::new);
|
||||
LayerTiledOverlay.initialiseLayers(LayerSummonAnimation::new);
|
||||
LayerTiledOverlay.initialiseLayers(LayerDisintegrateAnimation::new);
|
||||
LayerTiledOverlay.initialiseLayers(LayerOak::new);
|
||||
LayerTiledOverlay.initialiseLayers(LayerIron::new);
|
||||
LayerTiledOverlay.initialiseLayers(LayerDiamond::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -766,6 +772,7 @@ public class ClientProxy extends CommonProxy {
|
||||
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityIceGiant.class, RenderIceGiant::new);
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityPhoenix.class, RenderPhoenix::new);
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntitySpectralGolem.class, RenderSpectralGolem::new);
|
||||
|
||||
// Projectiles
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityMagicMissile.class, manager -> new RenderMagicArrow(manager,
|
||||
@@ -780,6 +787,7 @@ public class ClientProxy extends CommonProxy {
|
||||
new ResourceLocation(Wizardry.MODID, "textures/entity/ice_lance.png"), false, 16.0, 3.0, 22, 5, false));
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityFlamecatcherArrow.class, manager -> new RenderMagicArrow(manager,
|
||||
new ResourceLocation(Wizardry.MODID, "textures/entity/flamecatcher_arrow.png"), false, 8, 2.0, 16, 5, true));
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityConjuredArrow.class, RenderConjuredArrow::new);
|
||||
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityForceArrow.class, RenderForceArrow::new);
|
||||
|
||||
|
||||
@@ -93,6 +93,7 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
||||
private ContainerArcaneWorkbench arcaneWorkbenchContainer;
|
||||
|
||||
private GuiButton applyBtn;
|
||||
private GuiButton clearBtn;
|
||||
private GuiButton[] sortButtons = new GuiButton[3];
|
||||
|
||||
private GuiTextField searchField;
|
||||
@@ -126,6 +127,7 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
||||
|
||||
this.buttonList.clear();
|
||||
this.buttonList.add(this.applyBtn = new GuiButtonApply(0, this.width / 2 + 64, this.height / 2 + 3));
|
||||
this.buttonList.add(this.clearBtn = new GuiButtonClear(0, this.width / 2 + 64, this.height / 2 - 16));
|
||||
this.buttonList.add(sortButtons[0] = new GuiButtonSpellSort(1, this.guiLeft - 44, this.guiTop + 8, ISpellSortable.SortType.TIER, arcaneWorkbenchContainer, this));
|
||||
this.buttonList.add(sortButtons[1] = new GuiButtonSpellSort(2, this.guiLeft - 31, this.guiTop + 8, ISpellSortable.SortType.ELEMENT, arcaneWorkbenchContainer, this));
|
||||
this.buttonList.add(sortButtons[2] = new GuiButtonSpellSort(3, this.guiLeft - 18, this.guiTop + 8, ISpellSortable.SortType.ALPHABETICAL, arcaneWorkbenchContainer, this));
|
||||
@@ -205,6 +207,7 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
||||
|
||||
// Show/hide the relevant gui elements
|
||||
this.applyBtn.enabled = centreSlot.getHasStack();
|
||||
this.clearBtn.enabled = centreSlot.getHasStack() && centreSlot.getStack().getItem() instanceof IWorkbenchItem && ((IWorkbenchItem) centreSlot.getStack().getItem()).isClearable();
|
||||
for(GuiButton button : this.sortButtons) button.visible = arcaneWorkbenchContainer.hasBookshelves();
|
||||
this.searchField.setVisible(arcaneWorkbenchContainer.hasBookshelves());
|
||||
|
||||
@@ -444,6 +447,17 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
||||
animationTimer = 20;
|
||||
}
|
||||
|
||||
if(button == clearBtn){
|
||||
// Packet building
|
||||
IMessage msg = new PacketControlInput.Message(PacketControlInput.ControlType.CLEAR_BUTTON);
|
||||
WizardryPacketHandler.net.sendToServer(msg);
|
||||
// Sound
|
||||
Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.getMasterRecord(
|
||||
WizardrySounds.BLOCK_ARCANE_WORKBENCH_SPELLBIND, 0.8f));
|
||||
// Animation
|
||||
animationTimer = 20;
|
||||
}
|
||||
|
||||
if(button instanceof GuiButtonSpellSort) this.arcaneWorkbenchContainer.setSortType(((GuiButtonSpellSort)button).sortType);
|
||||
}
|
||||
}
|
||||
@@ -1006,4 +1020,36 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
||||
}
|
||||
}
|
||||
|
||||
private static class GuiButtonClear extends GuiButton {
|
||||
|
||||
public GuiButtonClear(int id, int x, int y){
|
||||
super(id, x, y, 16, 16, I18n.format("container." + Wizardry.MODID + ":arcane_workbench.clear"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawButton(Minecraft minecraft, int mouseX, int mouseY, float partialTicks){
|
||||
|
||||
// Whether the button is highlighted
|
||||
this.hovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height;
|
||||
|
||||
int k = 72;
|
||||
int l = 236;
|
||||
//int colour = 14737632;
|
||||
|
||||
if(this.enabled){
|
||||
if(this.hovered){
|
||||
k += this.width * 2;
|
||||
//colour = 16777120;
|
||||
}
|
||||
}else{
|
||||
k += this.width;
|
||||
//colour = 10526880;
|
||||
}
|
||||
|
||||
DrawingUtils.drawTexturedRect(this.x, this.y, k, l, this.width, this.height, TEXTURE_WIDTH, TEXTURE_HEIGHT);
|
||||
//this.drawCenteredString(minecraft.fontRenderer, this.displayString, this.x + this.width / 2,
|
||||
// this.y + (this.height - 8) / 2, colour);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -151,7 +151,7 @@ class Contents {
|
||||
int x = GuiWizardHandbook.isRightPage(startPage) ? left + GuiWizardHandbook.GUI_WIDTH - GuiWizardHandbook.TEXT_INSET_X - GuiWizardHandbook.PAGE_WIDTH : left + GuiWizardHandbook.TEXT_INSET_X;
|
||||
int y = top + GuiWizardHandbook.TEXT_INSET_Y + startLine * font.FONT_HEIGHT;
|
||||
|
||||
list.add(new GuiButtonHyperlink.Internal(0, x, y, font, entry.title, entry, 0, "", maxLineNumber-startLine, GuiWizardHandbook.isRightPage(startPage)));
|
||||
list.add(new GuiButtonHyperlink.Internal(0, x, y, font, entry.title, entry, 0, "", maxLineNumber-startLine, GuiWizardHandbook.isRightPage(startPage), false));
|
||||
|
||||
startLine++;
|
||||
|
||||
|
||||
@@ -28,15 +28,17 @@ public abstract class GuiButtonHyperlink extends GuiButton {
|
||||
final List<String> lines;
|
||||
final int linesLeft;
|
||||
|
||||
GuiButtonHyperlink(int id, int x, int y, FontRenderer font, String text, int indent, String suffix, int linesLeft, boolean rightPage){
|
||||
GuiButtonHyperlink(int id, int x, int y, FontRenderer font, String text, int indent, String suffix, int linesLeft, boolean rightPage, boolean spaceless){
|
||||
|
||||
super(id, x, y, font.getStringWidth(text), font.FONT_HEIGHT, text);
|
||||
|
||||
// Sometimes a link has punctuation or something after it that causes it to wrap onto a new line
|
||||
String linkWithSuffix = text + suffix;
|
||||
|
||||
// If the string won't fit any words at the end of the current line, treat it as if we started a new line
|
||||
if(font.getStringWidth(linkWithSuffix.split("\\s")[0]) > GuiWizardHandbook.PAGE_WIDTH - indent){
|
||||
// If the string won't fit any words (or characters in a spaceless language) at the end of the current line,
|
||||
// treat it as if we started a new line
|
||||
String firstWord = spaceless ? linkWithSuffix.substring(0, 1) : linkWithSuffix.split("\\s")[0];
|
||||
if(font.getStringWidth(firstWord) > GuiWizardHandbook.PAGE_WIDTH - indent){
|
||||
indent = 0;
|
||||
this.y += font.FONT_HEIGHT;
|
||||
}
|
||||
@@ -149,7 +151,7 @@ public abstract class GuiButtonHyperlink extends GuiButton {
|
||||
* @throws IllegalArgumentException if the given argument array is empty or contains more than 2 arguments
|
||||
* @throws JsonSyntaxException if the specified link target is not a URL or a valid section ID
|
||||
*/
|
||||
public static GuiButtonHyperlink create(int x, int y, FontRenderer font, List<String> upToLink, String[] arguments, String suffix, int linesLeft, boolean rightPage){
|
||||
public static GuiButtonHyperlink create(int x, int y, FontRenderer font, List<String> upToLink, String[] arguments, String suffix, int linesLeft, boolean rightPage, boolean spaceless){
|
||||
|
||||
if(arguments.length == 0 || arguments.length > 2) throw new IllegalArgumentException("Incorrect array length!");
|
||||
|
||||
@@ -158,7 +160,7 @@ public abstract class GuiButtonHyperlink extends GuiButton {
|
||||
if(arguments[0].matches(URL_REGEX)){
|
||||
|
||||
button = new GuiButtonHyperlink.External(0, x, y, font, arguments[arguments.length - 1], arguments[0],
|
||||
font.getStringWidth(upToLink.get(upToLink.size() - 1)), suffix, linesLeft, rightPage);
|
||||
font.getStringWidth(upToLink.get(upToLink.size() - 1)), suffix, linesLeft, rightPage, spaceless);
|
||||
|
||||
}else{
|
||||
|
||||
@@ -167,7 +169,7 @@ public abstract class GuiButtonHyperlink extends GuiButton {
|
||||
if(target == null) throw new JsonSyntaxException("Hyperlink points to nonexistent section id " + arguments[0]);
|
||||
|
||||
button = new GuiButtonHyperlink.Internal(0, x, y, font, arguments[arguments.length - 1],
|
||||
target, font.getStringWidth(upToLink.get(upToLink.size() - 1)), suffix, linesLeft, rightPage);
|
||||
target, font.getStringWidth(upToLink.get(upToLink.size() - 1)), suffix, linesLeft, rightPage, spaceless);
|
||||
}
|
||||
|
||||
return button;
|
||||
@@ -177,8 +179,8 @@ public abstract class GuiButtonHyperlink extends GuiButton {
|
||||
|
||||
final Section target;
|
||||
|
||||
Internal(int id, int x, int y, FontRenderer font, String text, Section target, int indent, String suffix, int linesLeft, boolean rightPage){
|
||||
super(id, x, y, font, text, indent, suffix, linesLeft, rightPage);
|
||||
Internal(int id, int x, int y, FontRenderer font, String text, Section target, int indent, String suffix, int linesLeft, boolean rightPage, boolean spaceless){
|
||||
super(id, x, y, font, text, indent, suffix, linesLeft, rightPage, spaceless);
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@@ -216,8 +218,8 @@ public abstract class GuiButtonHyperlink extends GuiButton {
|
||||
|
||||
final ITextComponent link;
|
||||
|
||||
External(int id, int x, int y, FontRenderer font, String text, String url, int indent, String suffix, int linesLeft, boolean rightPage){
|
||||
super(id, x, y, font, text, indent, suffix, linesLeft, rightPage);
|
||||
External(int id, int x, int y, FontRenderer font, String text, String url, int indent, String suffix, int linesLeft, boolean rightPage, boolean spaceless){
|
||||
super(id, x, y, font, text, indent, suffix, linesLeft, rightPage, spaceless);
|
||||
this.link = new TextComponentString(text);
|
||||
link.getStyle().setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, url)).setColor(TextFormatting.DARK_BLUE);
|
||||
}
|
||||
|
||||
@@ -496,24 +496,30 @@ public class GuiWizardHandbook extends GuiScreen {
|
||||
|
||||
Section currentSection = null;
|
||||
|
||||
for(Section section : sections.values()){
|
||||
// We always want this button to do something, and taking the right-hand page means it always does
|
||||
if(section.containsPage(doubleToSinglePage(currentPage, true))){
|
||||
currentSection = section;
|
||||
break;
|
||||
if(currentPage < singleToDoublePage(pageCount)){
|
||||
// Find current section
|
||||
for(Section section : sections.values()){
|
||||
// Take the right-hand page if going to the next section, and the left-hand page otherwise
|
||||
if(section.containsPage(doubleToSinglePage(currentPage, button == nextSection))){
|
||||
currentSection = section;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(currentSection != null){
|
||||
List<Section> visibleSections = new ArrayList<>(sectionList);
|
||||
visibleSections.removeIf(s -> !s.isUnlocked());
|
||||
|
||||
List<Section> visibleSections = new ArrayList<>(sectionList);
|
||||
visibleSections.removeIf(s -> !s.isUnlocked());
|
||||
int index = currentSection == null ? visibleSections.size() : visibleSections.indexOf(currentSection);
|
||||
|
||||
int index = visibleSections.indexOf(currentSection);
|
||||
|
||||
if(button == nextSection && index + 1 < visibleSections.size()){
|
||||
if(button == nextSection){
|
||||
if(index + 1 < visibleSections.size()){
|
||||
currentPage = singleToDoublePage(visibleSections.get(index + 1).startPage);
|
||||
}else if(index > 0){
|
||||
}else{
|
||||
currentPage = singleToDoublePage(pageCount);
|
||||
}
|
||||
}else{
|
||||
if(index > 0){
|
||||
currentPage = singleToDoublePage(visibleSections.get(index - 1).startPage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package electroblob.wizardry.client.gui.handbook;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Streams;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
@@ -35,6 +36,8 @@ import java.util.*;
|
||||
// be a non-static inner class
|
||||
class Section {
|
||||
|
||||
private static final Set<String> SPACELESS_LANGUAGES = ImmutableSet.of("zh_cn", "zh_tw");
|
||||
|
||||
// Final fields are mandatory (none here though), the rest are optional
|
||||
String title;
|
||||
private String[] rawText;
|
||||
@@ -293,7 +296,11 @@ class Section {
|
||||
|
||||
String linkRaw = paragraph.substring(linkStart, linkEnd + 1);
|
||||
String[] arguments = paragraph.substring(linkStart + 1, linkEnd).split("\\s", 2);
|
||||
String suffix = paragraph.substring(linkEnd).split("\\s", 2)[0].substring(1); // substring(1) to remove the @
|
||||
String suffix = "";
|
||||
|
||||
// Account for trailing punctuation, except in languages that don't use spaces such as Chinese
|
||||
boolean spaceless = SPACELESS_LANGUAGES.contains(Minecraft.getMinecraft().getLanguageManager().getCurrentLanguage().getLanguageCode());
|
||||
if(!spaceless) paragraph.substring(linkEnd).split("\\s", 2)[0].substring(1); // substring(1) to remove the @
|
||||
|
||||
// The index of the single page currently being formatted, relative to the section
|
||||
int pageRelative = (lines.size() + upToLink.size() - 1) / maxLineNumber;
|
||||
@@ -311,7 +318,7 @@ class Section {
|
||||
}
|
||||
|
||||
// The button id only does what you use it for, so we're just not using it at all.
|
||||
this.buttons.get(pageRelative).add(GuiButtonHyperlink.create(x, y, font, upToLink, arguments, suffix, maxLineNumber - lineNumber - 1, GuiWizardHandbook.isRightPage(page)));
|
||||
this.buttons.get(pageRelative).add(GuiButtonHyperlink.create(x, y, font, upToLink, arguments, suffix, maxLineNumber - lineNumber - 1, GuiWizardHandbook.isRightPage(page), spaceless));
|
||||
|
||||
// The link button should exactly overlay the display text in the main string
|
||||
// If the link has no display text specified, it displays the unformatted target string
|
||||
|
||||
@@ -13,17 +13,17 @@ import net.minecraftforge.client.model.IModel;
|
||||
import net.minecraftforge.client.model.ModelLoaderRegistry;
|
||||
import net.minecraftforge.common.model.IModelState;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ModelBookshelf implements IModel {
|
||||
|
||||
private static final ResourceLocation DEFAULT_BOOK_TEXTURE = new ResourceLocation(Wizardry.MODID, "blocks/books");
|
||||
//private static final ResourceLocation DEFAULT_BOOK_TEXTURE = new ResourceLocation(Wizardry.MODID, "blocks/books");
|
||||
|
||||
private static final List<ResourceLocation> bookModelLocations = new ArrayList<>();
|
||||
|
||||
private static final Map<String, IBakedModel[][]> bakedBookModels = new HashMap<>();
|
||||
|
||||
private final ModelResourceLocation bookshelfModelLocation;
|
||||
private final String variant;
|
||||
|
||||
@@ -49,19 +49,7 @@ public class ModelBookshelf implements IModel {
|
||||
// I don't know why default state works here (surely it ought to be the state param?), but it works so who cares
|
||||
IBakedModel bookshelf = bookshelfModel.bake(bookshelfModel.getDefaultState(), format, bakedTextureGetter);
|
||||
|
||||
ImmutableList<ResourceLocation> textures = BlockBookshelf.getBookTextures();
|
||||
|
||||
IBakedModel[][] books = new IBakedModel[textures.size()][BlockBookshelf.SLOT_COUNT];
|
||||
|
||||
for(int i = 0; i < textures.size(); i++){
|
||||
|
||||
ImmutableMap<String, String> retexturer = ImmutableMap.of("books", textures.get(i).toString());
|
||||
|
||||
for(int j = 0; j < BlockBookshelf.SLOT_COUNT; j++){
|
||||
IModel bookModel = ModelLoaderRegistry.getModel(new ModelResourceLocation(bookModelLocations.get(j), variant)).retexture(retexturer);
|
||||
books[i][j] = bookModel.bake(bookModel.getDefaultState(), format, bakedTextureGetter); // Same here!
|
||||
}
|
||||
}
|
||||
IBakedModel[][] books = getBakedBookModels(format, bakedTextureGetter);
|
||||
|
||||
// To clarify: the whole point of doing this was to avoid having to bake 4 * 2^12 models per bookshelf type
|
||||
// Therefore we have to have a baked bookshelf model that's kind of dynamic
|
||||
@@ -74,6 +62,29 @@ public class ModelBookshelf implements IModel {
|
||||
|
||||
}
|
||||
|
||||
/** Retrieves the baked book models, or bakes them if they haven't been created yet. */
|
||||
protected IBakedModel[][] getBakedBookModels(VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter) throws Exception{
|
||||
|
||||
if(bakedBookModels.get(variant) == null){
|
||||
|
||||
ImmutableList<ResourceLocation> textures = BlockBookshelf.getBookTextures();
|
||||
|
||||
bakedBookModels.put(variant, new IBakedModel[textures.size()][BlockBookshelf.SLOT_COUNT]);
|
||||
|
||||
for(int i = 0; i < textures.size(); i++){
|
||||
|
||||
ImmutableMap<String, String> retexturer = ImmutableMap.of("books", textures.get(i).toString());
|
||||
|
||||
for(int j = 0; j < BlockBookshelf.SLOT_COUNT; j++){
|
||||
IModel bookModel = ModelLoaderRegistry.getModel(new ModelResourceLocation(bookModelLocations.get(j), variant)).retexture(retexturer);
|
||||
bakedBookModels.get(variant)[i][j] = bookModel.bake(bookModel.getDefaultState(), format, bakedTextureGetter); // Same here!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bakedBookModels.get(variant);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ResourceLocation> getDependencies(){
|
||||
return bookModelLocations;
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
package electroblob.wizardry.client.renderer;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import net.minecraft.client.model.ModelIronGolem;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.entity.RenderLiving;
|
||||
import net.minecraft.client.renderer.entity.RenderManager;
|
||||
import net.minecraft.entity.monster.EntityIronGolem;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class RenderSpectralGolem extends RenderLiving<EntityIronGolem>
|
||||
{
|
||||
private static final ResourceLocation SPECTRAL_GOLEM_TEXTURES = new ResourceLocation(Wizardry.MODID, "textures/entity/spectral_golem.png");
|
||||
|
||||
public RenderSpectralGolem(RenderManager renderManagerIn)
|
||||
{
|
||||
super(renderManagerIn, new ModelIronGolem(), 0.5F);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture.
|
||||
*/
|
||||
protected ResourceLocation getEntityTexture(EntityIronGolem entity)
|
||||
{
|
||||
return SPECTRAL_GOLEM_TEXTURES;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void preRenderCallback(EntityIronGolem entity, float partialTickTime){
|
||||
super.preRenderCallback(entity, partialTickTime);
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
GlStateManager.color(1, 1, 1, 0.7f);
|
||||
}
|
||||
|
||||
protected void applyRotations(EntityIronGolem entityLiving, float ageInTicks, float rotationYaw, float partialTicks)
|
||||
{
|
||||
super.applyRotations(entityLiving, ageInTicks, rotationYaw, partialTicks);
|
||||
|
||||
if ((double)entityLiving.limbSwingAmount >= 0.01D)
|
||||
{
|
||||
float f = 13.0F;
|
||||
float f1 = entityLiving.limbSwing - entityLiving.limbSwingAmount * (1.0F - partialTicks) + 6.0F;
|
||||
float f2 = (Math.abs(f1 % 13.0F - 6.5F) - 3.25F) / 3.25F;
|
||||
GlStateManager.rotate(6.5F * f2, 0.0F, 0.0F, 1.0F);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package electroblob.wizardry.client.renderer.entity;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.entity.projectile.EntityConjuredArrow;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.entity.RenderArrow;
|
||||
import net.minecraft.client.renderer.entity.RenderManager;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class RenderConjuredArrow extends RenderArrow<EntityConjuredArrow> {
|
||||
|
||||
public static final ResourceLocation CONJURED_ARROW_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/entity/conjured_arrow.png");
|
||||
|
||||
public RenderConjuredArrow(RenderManager manager) {
|
||||
super(manager);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceLocation getEntityTexture(EntityConjuredArrow entity) {
|
||||
return CONJURED_ARROW_TEXTURE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doRender(EntityConjuredArrow entity, double x, double y, double z, float entityYaw, float partialTicks) {
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
GlStateManager.color(1, 1, 1, 0.4f);
|
||||
super.doRender(entity, x, y, z, entityYaw, partialTicks);
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package electroblob.wizardry.client.renderer.entity.layers;
|
||||
|
||||
import electroblob.wizardry.registry.WizardryPotions;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.GlStateManager.DestFactor;
|
||||
import net.minecraft.client.renderer.GlStateManager.SourceFactor;
|
||||
import net.minecraft.client.renderer.OpenGlHelper;
|
||||
import net.minecraft.client.renderer.entity.RenderLivingBase;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Layer used to render the diamondflesh texture on creatures with the diamondflesh effect.
|
||||
*
|
||||
* @author WinDanesz
|
||||
* @since Wizardry 4.3.7
|
||||
*/
|
||||
public class LayerDiamond extends LayerTiledOverlay<EntityLivingBase> {
|
||||
|
||||
private static final ResourceLocation TEXTURE = new ResourceLocation("textures/blocks/diamond_block.png");
|
||||
|
||||
public LayerDiamond(RenderLivingBase<?> renderer){
|
||||
super(renderer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRender(EntityLivingBase entity, float partialTicks){
|
||||
return !entity.isInvisible() && entity.isPotionActive(WizardryPotions.diamondflesh);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getTexture(EntityLivingBase entity, float partialTicks){
|
||||
return TEXTURE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doRenderLayer(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks,
|
||||
float ageInTicks, float netHeadYaw, float headPitch, float scale){
|
||||
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
int j = entity.getBrightnessForRender();
|
||||
int k = j % 65536;
|
||||
int l = j / 65536;
|
||||
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float) k, (float) l);
|
||||
|
||||
super.doRenderLayer(entity, limbSwing, limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch, scale);
|
||||
|
||||
GlStateManager.disableBlend();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package electroblob.wizardry.client.renderer.entity.layers;
|
||||
|
||||
import electroblob.wizardry.registry.WizardryPotions;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.GlStateManager.DestFactor;
|
||||
import net.minecraft.client.renderer.GlStateManager.SourceFactor;
|
||||
import net.minecraft.client.renderer.OpenGlHelper;
|
||||
import net.minecraft.client.renderer.entity.RenderLivingBase;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Layer used to render the ironflesh texture on creatures with the ironflesh effect.
|
||||
*
|
||||
* @author WinDanesz
|
||||
* @since Wizardry 4.3.7
|
||||
*/
|
||||
public class LayerIron extends LayerTiledOverlay<EntityLivingBase> {
|
||||
|
||||
private static final ResourceLocation TEXTURE = new ResourceLocation("textures/blocks/iron_block.png");
|
||||
|
||||
public LayerIron(RenderLivingBase<?> renderer){
|
||||
super(renderer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRender(EntityLivingBase entity, float partialTicks){
|
||||
return !entity.isInvisible() && entity.isPotionActive(WizardryPotions.ironflesh);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getTexture(EntityLivingBase entity, float partialTicks){
|
||||
return TEXTURE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doRenderLayer(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks,
|
||||
float ageInTicks, float netHeadYaw, float headPitch, float scale){
|
||||
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
int j = entity.getBrightnessForRender();
|
||||
int k = j % 65536;
|
||||
int l = j / 65536;
|
||||
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float) k, (float) l);
|
||||
|
||||
super.doRenderLayer(entity, limbSwing, limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch, scale);
|
||||
|
||||
GlStateManager.disableBlend();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package electroblob.wizardry.client.renderer.entity.layers;
|
||||
|
||||
import electroblob.wizardry.registry.WizardryPotions;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.GlStateManager.DestFactor;
|
||||
import net.minecraft.client.renderer.GlStateManager.SourceFactor;
|
||||
import net.minecraft.client.renderer.OpenGlHelper;
|
||||
import net.minecraft.client.renderer.entity.RenderLivingBase;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Layer used to render the oakflesh texture on creatures with the oakflesh effect.
|
||||
*
|
||||
* @author WinDanesz
|
||||
* @since Wizardry 4.3.7
|
||||
*/
|
||||
public class LayerOak extends LayerTiledOverlay<EntityLivingBase> {
|
||||
|
||||
private static final ResourceLocation TEXTURE = new ResourceLocation("textures/blocks/log_oak.png");
|
||||
|
||||
public LayerOak(RenderLivingBase<?> renderer){
|
||||
super(renderer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRender(EntityLivingBase entity, float partialTicks){
|
||||
return !entity.isInvisible() && entity.isPotionActive(WizardryPotions.oakflesh);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getTexture(EntityLivingBase entity, float partialTicks){
|
||||
return TEXTURE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doRenderLayer(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks,
|
||||
float ageInTicks, float netHeadYaw, float headPitch, float scale){
|
||||
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
int j = entity.getBrightnessForRender();
|
||||
int k = j % 65536;
|
||||
int l = j / 65536;
|
||||
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float) k, (float) l);
|
||||
|
||||
super.doRenderLayer(entity, limbSwing, limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch, scale);
|
||||
|
||||
GlStateManager.disableBlend();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package electroblob.wizardry.constants;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.WizardryEventHandler;
|
||||
|
||||
/** Stores various global constants used in Wizardry. */
|
||||
@@ -17,17 +18,17 @@ public final class Constants {
|
||||
/** The bonus amount of wand upgrades that can be applied to a non-elemental wand. */
|
||||
public static final int NON_ELEMENTAL_UPGRADE_BONUS = 3;
|
||||
/** The fraction by which cooldowns are reduced for each level of cooldown upgrade. */
|
||||
public static final float COOLDOWN_REDUCTION_PER_LEVEL = 0.15f;
|
||||
public static float COOLDOWN_REDUCTION_PER_LEVEL = 0.15f;
|
||||
/** The fraction by which maximum charge is increased for each level of storage upgrade. */
|
||||
public static final float STORAGE_INCREASE_PER_LEVEL = 0.15f;
|
||||
/** The fraction by which potency is increased for each tier of matching wand. */
|
||||
public static final float POTENCY_INCREASE_PER_TIER = 0.15f;
|
||||
public static float POTENCY_INCREASE_PER_TIER = 0.15f;
|
||||
/** The fraction by which spell duration is increased for each level of duration upgrade. */
|
||||
public static final float DURATION_INCREASE_PER_LEVEL = 0.25f;
|
||||
public static float DURATION_INCREASE_PER_LEVEL = 0.25f;
|
||||
/** The fraction by which spell range is increased for each level of range upgrade. */
|
||||
public static final float RANGE_INCREASE_PER_LEVEL = 0.25f;
|
||||
public static float RANGE_INCREASE_PER_LEVEL = 0.25f;
|
||||
/** The fraction by which spell blast radius is increased for each level of range upgrade. */
|
||||
public static final float BLAST_RADIUS_INCREASE_PER_LEVEL = 0.25f;
|
||||
public static float BLAST_RADIUS_INCREASE_PER_LEVEL = 0.25f;
|
||||
/** The fraction by which movement speed is reduced per level of frost effect. */
|
||||
public static final double FROST_SLOWNESS_PER_LEVEL = 0.5;
|
||||
/** The fraction by which movement speed is reduced per level of decay effect. */
|
||||
@@ -46,7 +47,15 @@ public final class Constants {
|
||||
* won't spawn again if something is already standing in it.
|
||||
*/
|
||||
public static final int DECAY_SPREAD_INTERVAL = 8;
|
||||
/** The fraction by which potency is increased per level of the empowerment effect. */
|
||||
public static final float EMPOWERMENT_POTENCY_PER_LEVEL = 0.25f;
|
||||
|
||||
|
||||
// making this as an update to the existing values to not break addons directly relying on the fields
|
||||
static {
|
||||
POTENCY_INCREASE_PER_TIER = (float) Wizardry.settings.potencyIncreasePerTier;
|
||||
COOLDOWN_REDUCTION_PER_LEVEL = (float) Wizardry.settings.cooldownReductionPerLevel;
|
||||
DURATION_INCREASE_PER_LEVEL = (float) Wizardry.settings.durationIncreasePerLevel;
|
||||
RANGE_INCREASE_PER_LEVEL = (float) Wizardry.settings.rangeIncreasePerLevel;
|
||||
BLAST_RADIUS_INCREASE_PER_LEVEL = (float) Wizardry.settings.blastIncreasePerLevel;
|
||||
RANGE_INCREASE_PER_LEVEL = (float) Wizardry.settings.frostSlownessIncreasePerLevel;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,6 +382,7 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
|
||||
activeImbuements.add((Imbuement)enchantment);
|
||||
}else{
|
||||
// Otherwise, removes the enchantment from the item
|
||||
((Imbuement) enchantment).onImbuementRemoval(stack);
|
||||
iterator.remove(); // FIXME: Apparently this can cause a CME
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ import java.util.Iterator;
|
||||
* than having to deal with each of them separately, which would be inefficient and cumbersome (the former of those
|
||||
* classes cannot extend the latter because they both need to extend different subclasses of
|
||||
* {@link net.minecraft.enchantment.Enchantment}).
|
||||
*
|
||||
*
|
||||
* @since Wizardry 1.2
|
||||
*/
|
||||
@Mod.EventBusSubscriber
|
||||
@@ -69,12 +69,16 @@ public interface Imbuement {
|
||||
Enchantment enchantment = Enchantment.getEnchantmentByID(enchantmentTag.getShort("id"));
|
||||
// If the item contains a magic weapon enchantment, remove it from the item
|
||||
if(enchantment instanceof Imbuement){
|
||||
((Imbuement) enchantment).onImbuementRemoval(stack);
|
||||
enchantmentIt.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Allows executing some custom logic before this imbuement is being removed from the stack. Called when the imbuement is about to be removed. */
|
||||
default void onImbuementRemoval(ItemStack stack){}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onPlayerOpenContainerEvent(PlayerContainerEvent event){
|
||||
// Brute-force fix to stop enchanted books in dungeon chests from having imbuements on them.
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
package electroblob.wizardry.entity.construct;
|
||||
|
||||
import electroblob.wizardry.entity.projectile.EntityConjuredArrow;
|
||||
import electroblob.wizardry.registry.Spells;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
import net.minecraft.entity.projectile.EntityTippedArrow;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
@@ -30,7 +28,7 @@ public class EntityArrowRain extends EntityScaledConstruct {
|
||||
double y = posY + world.rand.nextDouble() * (double)height;
|
||||
double z = posZ + (world.rand.nextDouble() - 0.5D) * (double)width;
|
||||
|
||||
EntityTippedArrow arrow = new EntityTippedArrow(world, x, y, z);
|
||||
EntityConjuredArrow arrow = new EntityConjuredArrow(world, x, y, z);
|
||||
|
||||
arrow.motionX = MathHelper.cos((float)Math.toRadians(this.rotationYaw + 90));
|
||||
arrow.motionY = -0.6;
|
||||
@@ -38,7 +36,6 @@ public class EntityArrowRain extends EntityScaledConstruct {
|
||||
|
||||
arrow.shootingEntity = this.getCaster();
|
||||
arrow.setDamage(7.0d * damageMultiplier);
|
||||
arrow.setPotionEffect(new ItemStack(Items.ARROW));
|
||||
|
||||
this.world.spawnEntity(arrow);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ public class EntityFireRing extends EntityScaledConstruct {
|
||||
|
||||
super.onUpdate();
|
||||
|
||||
if(!this.world.isRemote){
|
||||
if(this.ticksExisted % 5 == 0 && !this.world.isRemote){
|
||||
|
||||
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(width/2, this.posX, this.posY, this.posZ, this.world);
|
||||
|
||||
|
||||
@@ -168,6 +168,10 @@ public class EntityForcefield extends EntityMagicConstruct implements ICustomHit
|
||||
((EntityPlayerMP)target).connection.sendPacket(new SPacketEntityVelocity(target));
|
||||
}
|
||||
|
||||
if (this.ticksExisted % 5 == 0) {
|
||||
this.lifetime = (int) (lifetime * 0.99);
|
||||
}
|
||||
|
||||
}else{
|
||||
|
||||
Vec3d relativeImpactPos = targetRelativePos.normalize().scale(radius);
|
||||
|
||||
@@ -68,13 +68,15 @@ public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntity
|
||||
/** Data parameter for the wizard's element. */
|
||||
private static final DataParameter<Integer> ELEMENT = EntityDataManager.createKey(EntityEvilWizard.class,
|
||||
DataSerializers.VARINT);
|
||||
/** Data parameters for the wizard's current continuous spell. */
|
||||
private static final DataParameter<String> CONTINUOUS_SPELL = EntityDataManager.createKey(EntityEvilWizard.class, DataSerializers.STRING);
|
||||
private static final DataParameter<Integer> SPELL_COUNTER = EntityDataManager.createKey(EntityEvilWizard.class, DataSerializers.VARINT);
|
||||
|
||||
/** The resource location for the evil wizard's loot table. */
|
||||
private static final ResourceLocation LOOT_TABLE = new ResourceLocation(Wizardry.MODID, "entities/evil_wizard");
|
||||
|
||||
// Field implementations
|
||||
private List<Spell> spells = new ArrayList<Spell>(4);
|
||||
private Spell continuousSpell;
|
||||
private int spellCounter;
|
||||
|
||||
public EntityEvilWizard(World world){
|
||||
|
||||
@@ -93,6 +95,8 @@ public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntity
|
||||
super.entityInit();
|
||||
this.dataManager.register(HEAL_COOLDOWN, -1);
|
||||
this.dataManager.register(ELEMENT, -1);
|
||||
this.dataManager.register(CONTINUOUS_SPELL, "ebwizardry:none");
|
||||
this.dataManager.register(SPELL_COUNTER, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -168,23 +172,23 @@ public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntity
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContinuousSpell(Spell spell){
|
||||
this.continuousSpell = spell;
|
||||
public void setContinuousSpell(Spell spell) {
|
||||
this.dataManager.set(CONTINUOUS_SPELL, spell.getRegistryName().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spell getContinuousSpell(){
|
||||
return this.continuousSpell;
|
||||
public Spell getContinuousSpell() {
|
||||
return Spell.get(this.dataManager.get(CONTINUOUS_SPELL));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpellCounter(int count){
|
||||
spellCounter = count;
|
||||
public void setSpellCounter(int count) {
|
||||
this.dataManager.set(SPELL_COUNTER, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSpellCounter(){
|
||||
return spellCounter;
|
||||
public int getSpellCounter() {
|
||||
return this.dataManager.get(SPELL_COUNTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -52,7 +52,7 @@ public class EntityMagicSlime extends EntitySlime implements ISummonedCreature {
|
||||
super(world);
|
||||
this.setPosition(target.posX, target.posY, target.posZ);
|
||||
this.startRiding(target);
|
||||
this.setOwnerId(caster.getUniqueID());
|
||||
if (caster != null) this.setOwnerId(caster.getUniqueID());
|
||||
this.setSlimeSize(2, false); // Needs to be called before setting the experience value to 0
|
||||
this.experienceValue = 0;
|
||||
this.lifetime = lifetime;
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
package electroblob.wizardry.entity.living;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.util.ParticleBuilder;
|
||||
import net.minecraft.entity.EntityFlying;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.ai.EntityAIAttackMelee;
|
||||
import net.minecraft.entity.ai.EntityAIHurtByTarget;
|
||||
import net.minecraft.entity.ai.EntityAILookAtVillager;
|
||||
import net.minecraft.entity.ai.EntityAILookIdle;
|
||||
import net.minecraft.entity.ai.EntityAIMoveThroughVillage;
|
||||
import net.minecraft.entity.ai.EntityAIMoveTowardsRestriction;
|
||||
import net.minecraft.entity.ai.EntityAIMoveTowardsTarget;
|
||||
import net.minecraft.entity.ai.EntityAINearestAttackableTarget;
|
||||
import net.minecraft.entity.ai.EntityAIWanderAvoidWater;
|
||||
import net.minecraft.entity.ai.EntityAIWatchClosest;
|
||||
import net.minecraft.entity.monster.EntityIronGolem;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.datasync.DataParameter;
|
||||
import net.minecraft.network.datasync.DataSerializers;
|
||||
import net.minecraft.network.datasync.EntityDataManager;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.EnumParticleTypes;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
import net.minecraft.world.DifficultyInstance;
|
||||
import net.minecraft.world.EnumDifficulty;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class EntitySpectralGolem extends EntityIronGolem implements ISummonedCreature {
|
||||
|
||||
private static final DataParameter<Boolean> SPAWN_PARTICLES = EntityDataManager.createKey(EntitySpectralGolem.class, DataSerializers.BOOLEAN);
|
||||
|
||||
// Field implementations
|
||||
private int lifetime = -1;
|
||||
private UUID casterUUID;
|
||||
|
||||
// Setter + getter implementations
|
||||
@Override public int getLifetime(){ return lifetime; }
|
||||
@Override public void setLifetime(int lifetime){ this.lifetime = lifetime; }
|
||||
@Override public UUID getOwnerId(){ return casterUUID; }
|
||||
@Override public void setOwnerId(UUID uuid){ this.casterUUID = uuid; }
|
||||
|
||||
/** Creates a new golem minion in the given world. */
|
||||
public EntitySpectralGolem(World world){
|
||||
super(world);
|
||||
this.experienceValue = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void entityInit(){
|
||||
super.entityInit();
|
||||
this.dataManager.register(SPAWN_PARTICLES, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initEntityAI() {
|
||||
this.tasks.addTask(1, new EntityAIAttackMelee(this, 1.0D, true));
|
||||
this.tasks.addTask(2, new EntityAIMoveTowardsTarget(this, 0.9D, 32.0F));
|
||||
this.tasks.addTask(3, new EntityAIMoveThroughVillage(this, 0.6D, true));
|
||||
this.tasks.addTask(4, new EntityAIMoveTowardsRestriction(this, 1.0D));
|
||||
this.tasks.addTask(5, new EntityAILookAtVillager(this));
|
||||
this.tasks.addTask(6, new EntityAIWanderAvoidWater(this, 0.6D));
|
||||
this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F));
|
||||
this.tasks.addTask(8, new EntityAILookIdle(this));
|
||||
this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false));
|
||||
this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityLivingBase.class,
|
||||
0, false, true, this.getTargetSelector()));
|
||||
}
|
||||
|
||||
@Override protected void setEquipmentBasedOnDifficulty(DifficultyInstance difficulty){} // They don't have equipment!
|
||||
|
||||
// Implementations
|
||||
|
||||
@Override
|
||||
public void setRevengeTarget(EntityLivingBase entity){
|
||||
if(this.shouldRevengeTarget(entity)) super.setRevengeTarget(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(){
|
||||
super.onUpdate();
|
||||
this.updateDelegate();
|
||||
|
||||
// Adds a dust particle effect
|
||||
if(this.world.isRemote){
|
||||
double x = this.posX - this.width / 2 + this.rand.nextFloat() * width;
|
||||
double y = this.posY + this.height * this.rand.nextFloat() + 0.2f;
|
||||
double z = this.posZ - this.width / 2 + this.rand.nextFloat() * width;
|
||||
ParticleBuilder.create(ParticleBuilder.Type.DUST).pos(x, y, z).clr(0.7f, 0.9f, 1).shaded(true).spawn(world);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpawn(){
|
||||
if(this.dataManager.get(SPAWN_PARTICLES)) this.spawnParticleEffect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDespawn(){
|
||||
this.spawnParticleEffect();
|
||||
}
|
||||
|
||||
private void spawnParticleEffect(){
|
||||
if(this.world.isRemote){
|
||||
for(int i = 0; i < 15; i++){
|
||||
this.world.spawnParticle(EnumParticleTypes.SMOKE_LARGE, this.posX + this.rand.nextFloat() - 0.5f,
|
||||
this.posY + this.rand.nextFloat() * 2, this.posZ + this.rand.nextFloat() - 0.5f, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasParticleEffect(){
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAnimation(){
|
||||
return this.dataManager.get(SPAWN_PARTICLES) || this.ticksExisted > 20;
|
||||
}
|
||||
|
||||
public void hideParticles(){
|
||||
this.dataManager.set(SPAWN_PARTICLES, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean processInteract(EntityPlayer player, EnumHand hand){
|
||||
// In this case, the delegate method determines whether super is called.
|
||||
// Rather handily, we can make use of Java's short-circuiting method of evaluating OR statements.
|
||||
return this.interactDelegate(player, hand) || super.processInteract(player, hand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeEntityToNBT(NBTTagCompound nbttagcompound){
|
||||
super.writeEntityToNBT(nbttagcompound);
|
||||
this.writeNBTDelegate(nbttagcompound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readEntityFromNBT(NBTTagCompound nbttagcompound){
|
||||
super.readEntityFromNBT(nbttagcompound);
|
||||
this.readNBTDelegate(nbttagcompound);
|
||||
}
|
||||
|
||||
// Recommended overrides
|
||||
|
||||
@Override protected int getExperiencePoints(EntityPlayer player){ return 0; }
|
||||
@Override protected boolean canDropLoot(){ return false; }
|
||||
@Override protected Item getDropItem(){ return null; }
|
||||
@Override protected ResourceLocation getLootTable(){ return null; }
|
||||
@Override public boolean canPickUpLoot(){ return false; }
|
||||
|
||||
// This vanilla method has nothing to do with the custom despawn() method.
|
||||
@Override protected boolean canDespawn(){
|
||||
return getCaster() == null && getOwnerId() == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getCanSpawnHere(){
|
||||
return this.world.getDifficulty() != EnumDifficulty.PEACEFUL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAttackClass(Class<? extends EntityLivingBase> entityType){
|
||||
// Returns true unless the given entity type is a flying entity.
|
||||
return !EntityFlying.class.isAssignableFrom(entityType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITextComponent getDisplayName(){
|
||||
if(getCaster() != null){
|
||||
return new TextComponentTranslation(NAMEPLATE_TRANSLATION_KEY, getCaster().getName(),
|
||||
new TextComponentTranslation("entity." + this.getEntityString() + ".name"));
|
||||
}else{
|
||||
return super.getDisplayName();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCustomName(){
|
||||
// If this returns true, the renderer will show the nameplate when looking directly at the entity
|
||||
return Wizardry.settings.summonedCreatureNames && getCaster() != null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -47,6 +47,7 @@ import net.minecraftforge.common.util.FakePlayer;
|
||||
import net.minecraftforge.event.world.BlockEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.registry.ForgeRegistries;
|
||||
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
@@ -81,11 +82,12 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
private static final DataParameter<Integer> HEAL_COOLDOWN = EntityDataManager.createKey(EntityWizard.class, DataSerializers.VARINT);
|
||||
/** Data parameter for the wizard's element. */
|
||||
private static final DataParameter<Integer> ELEMENT = EntityDataManager.createKey(EntityWizard.class, DataSerializers.VARINT);
|
||||
/** Data parameters for the wizard's current continuous spell. */
|
||||
private static final DataParameter<String> CONTINUOUS_SPELL = EntityDataManager.createKey(EntityWizard.class, DataSerializers.STRING);
|
||||
private static final DataParameter<Integer> SPELL_COUNTER = EntityDataManager.createKey(EntityWizard.class, DataSerializers.VARINT);
|
||||
|
||||
// Field implementations
|
||||
private List<Spell> spells = new ArrayList<Spell>(4);
|
||||
private Spell continuousSpell;
|
||||
private int spellCounter;
|
||||
|
||||
/** A set of the positions of the blocks that are part of this wizard's tower. */
|
||||
private Set<BlockPos> towerBlocks;
|
||||
@@ -102,6 +104,8 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
super.entityInit();
|
||||
this.dataManager.register(HEAL_COOLDOWN, -1);
|
||||
this.dataManager.register(ELEMENT, 0);
|
||||
this.dataManager.register(CONTINUOUS_SPELL, "ebwizardry:none");
|
||||
this.dataManager.register(SPELL_COUNTER, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -182,23 +186,23 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContinuousSpell(Spell spell){
|
||||
this.continuousSpell = spell;
|
||||
public void setContinuousSpell(Spell spell) {
|
||||
this.dataManager.set(CONTINUOUS_SPELL, spell.getRegistryName().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spell getContinuousSpell(){
|
||||
return this.continuousSpell;
|
||||
public Spell getContinuousSpell() {
|
||||
return Spell.get(this.dataManager.get(CONTINUOUS_SPELL));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpellCounter(int count){
|
||||
spellCounter = count;
|
||||
public void setSpellCounter(int count) {
|
||||
this.dataManager.set(SPELL_COUNTER, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSpellCounter(){
|
||||
return spellCounter;
|
||||
public int getSpellCounter() {
|
||||
return this.dataManager.get(SPELL_COUNTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -634,10 +638,9 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0 && !specialismSpells.isEmpty()){
|
||||
// This means it is more likely for spell books sold to be of the same element as the wizard if the
|
||||
// wizard has an element.
|
||||
return new ItemStack(WizardryItems.spell_book, 1,
|
||||
specialismSpells.get(rand.nextInt(specialismSpells.size())).metadata());
|
||||
return getBookStackForSpell(specialismSpells.get(rand.nextInt(specialismSpells.size())));
|
||||
}else{
|
||||
return new ItemStack(WizardryItems.spell_book, 1, spells.get(rand.nextInt(spells.size())).metadata());
|
||||
return getBookStackForSpell(spells.get(rand.nextInt(spells.size())));
|
||||
}
|
||||
}else{
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0){
|
||||
@@ -656,10 +659,9 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0 && !specialismSpells.isEmpty()){
|
||||
// This means it is more likely for spell books sold to be of the same element as the wizard if the
|
||||
// wizard has an element.
|
||||
return new ItemStack(WizardryItems.spell_book, 1,
|
||||
specialismSpells.get(rand.nextInt(specialismSpells.size())).metadata());
|
||||
return getBookStackForSpell(specialismSpells.get(rand.nextInt(specialismSpells.size())));
|
||||
}else{
|
||||
return new ItemStack(WizardryItems.spell_book, 1, spells.get(rand.nextInt(spells.size())).metadata());
|
||||
return getBookStackForSpell(spells.get(rand.nextInt(spells.size())));
|
||||
}
|
||||
}else if(randomiser < 6){
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0){
|
||||
@@ -693,10 +695,9 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0 && !specialismSpells.isEmpty()){
|
||||
// This means it is more likely for spell books sold to be of the same element as the wizard if the
|
||||
// wizard has an element.
|
||||
return new ItemStack(WizardryItems.spell_book, 1,
|
||||
specialismSpells.get(rand.nextInt(specialismSpells.size())).metadata());
|
||||
return getBookStackForSpell(specialismSpells.get(rand.nextInt(specialismSpells.size())));
|
||||
}else{
|
||||
return new ItemStack(WizardryItems.spell_book, 1, spells.get(rand.nextInt(spells.size())).metadata());
|
||||
return getBookStackForSpell(spells.get(rand.nextInt(spells.size())));
|
||||
}
|
||||
}else if(randomiser < 6){
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0){
|
||||
@@ -721,8 +722,7 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
|
||||
if(randomiser < 5 && this.getElement() != Element.MAGIC && !specialismSpells.isEmpty()){
|
||||
// Master spells can only be sold by a specialist in that element.
|
||||
return new ItemStack(WizardryItems.spell_book, 1,
|
||||
specialismSpells.get(rand.nextInt(specialismSpells.size())).metadata());
|
||||
return getBookStackForSpell(specialismSpells.get(rand.nextInt(specialismSpells.size())));
|
||||
|
||||
}else if(randomiser < 6){
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0){
|
||||
@@ -798,7 +798,6 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
Tier maxTier = Tier.NOVICE;
|
||||
|
||||
List<Spell> npcSpells = Spell.getSpells(s -> s.canBeCastBy(wizard, false));
|
||||
npcSpells.removeIf(s -> !s.applicableForItem(WizardryItems.spell_book));
|
||||
|
||||
for(int i = 0; i < n; i++){
|
||||
|
||||
@@ -846,6 +845,22 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
return maxTier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to handle addon spell books.
|
||||
* @param spell the spell to look up.
|
||||
* @return Checks all items of the spell's namespace (modid) if they are applicable for the spell and returns the first match, or falls back to WizardryItems.spell_book if no match was found.
|
||||
*/
|
||||
public static ItemStack getBookStackForSpell(Spell spell) {
|
||||
String modid = spell.getRegistryName().getNamespace();
|
||||
if (modid.equals(Wizardry.MODID)) {
|
||||
return new ItemStack(WizardryItems.spell_book, 1, spell.metadata());
|
||||
}
|
||||
Optional<Item> firstMatch = ForgeRegistries.ITEMS.getValuesCollection().stream().filter(v -> v instanceof ItemSpellBook && spell.applicableForItem(v)
|
||||
&& v.getRegistryName().getNamespace().equals(modid)).findFirst();
|
||||
|
||||
return firstMatch.map(item -> new ItemStack(item, 1, spell.metadata())).orElseGet(() -> new ItemStack(WizardryItems.spell_book, 1, spell.metadata()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSpawnData(ByteBuf data){
|
||||
data.writeInt(textureIndex);
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package electroblob.wizardry.entity.projectile;
|
||||
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.projectile.EntityArrow;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class EntityConjuredArrow extends EntityArrow {
|
||||
|
||||
public EntityConjuredArrow(World worldIn) {
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
public EntityConjuredArrow(World worldIn, double x, double y, double z) {
|
||||
super(worldIn, x, y, z);
|
||||
}
|
||||
|
||||
public EntityConjuredArrow(World worldIn, EntityLivingBase shooter) {
|
||||
super(worldIn, shooter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate() {
|
||||
super.onUpdate();
|
||||
if (this.timeInGround > 400) {
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemStack getArrowStack() {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package electroblob.wizardry.event;
|
||||
|
||||
import electroblob.wizardry.item.ItemArtefact;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||
import net.minecraftforge.fml.common.eventhandler.Cancelable;
|
||||
import net.minecraftforge.fml.common.eventhandler.Event;
|
||||
|
||||
/**
|
||||
* SpellBindEvent is fired when a check happens for an ItemArtefact using {@link electroblob.wizardry.item.ItemArtefact#isArtefactActive(net.minecraft.entity.player.EntityPlayer, net.minecraft.item.Item)}
|
||||
* <i>Fired on both sides.</i><br>
|
||||
* <br>
|
||||
* This event is {@link Cancelable}. <br>
|
||||
* <br>
|
||||
* This event has a result. {@link HasResult}. Set the result to Result.ALLOW to consider an artefact "active"<br>
|
||||
* <br>
|
||||
* This event is fired on the {@link MinecraftForge#EVENT_BUS}.
|
||||
*
|
||||
* @author WinDanesz
|
||||
* @since Wizardry 4.3.10
|
||||
*/
|
||||
@Cancelable
|
||||
@Event.HasResult
|
||||
public class ArtefactCheckEvent extends PlayerEvent {
|
||||
|
||||
ItemArtefact artefact;
|
||||
EntityPlayer player;
|
||||
|
||||
public ArtefactCheckEvent(EntityPlayer player, ItemArtefact artefact) {
|
||||
super(player);
|
||||
this.player = player;
|
||||
this.artefact = artefact;
|
||||
setResult(Result.DENY);
|
||||
}
|
||||
|
||||
public ItemArtefact getArtefact() {
|
||||
return artefact;
|
||||
}
|
||||
|
||||
public EntityPlayer getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package electroblob.wizardry.event;
|
||||
|
||||
import electroblob.wizardry.constants.Element;
|
||||
import electroblob.wizardry.tileentity.TileEntityImbuementAltar;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.fml.common.eventhandler.Cancelable;
|
||||
import net.minecraftforge.fml.common.eventhandler.Event;
|
||||
|
||||
/**
|
||||
* ImbuementActivateEvent is fired when {@link TileEntityImbuementAltar#getImbuementResult(net.minecraft.item.ItemStack, electroblob.wizardry.constants.Element[],
|
||||
* boolean, net.minecraft.world.World, net.minecraft.entity.player.EntityPlayer)} is called to allow adding in imbuement "recipes" dynamically, based on the
|
||||
* contents of the Imbuement altar's receptacles and the item placed on the altar.
|
||||
*
|
||||
* <i>Note that this event is only fired on the server side.</i><br>
|
||||
* <br>
|
||||
* To alter the result of the imbuement process, change the {@link electroblob.wizardry.event.ImbuementActivateEvent#result} result of the process.<br>
|
||||
* <br>
|
||||
* This event is {@link Cancelable}. If this event is canceled, no further processing takes place.<br>
|
||||
* <br>
|
||||
* This event does not have a result. {@link Event.HasResult}<br>
|
||||
* <br>
|
||||
* This event is fired on the {@link MinecraftForge#EVENT_BUS}.
|
||||
*
|
||||
* @author WinDanesz
|
||||
* @since Wizardry 4.3.5
|
||||
*/
|
||||
@Cancelable
|
||||
public class ImbuementActivateEvent extends Event {
|
||||
|
||||
/** The item stack being imbued */
|
||||
public ItemStack input;
|
||||
|
||||
/** The elements of the four receptacles */
|
||||
public Element[] receptacleElements;
|
||||
|
||||
/** A reference to the current world object (may be null if {@code fullLootGen} is false) */
|
||||
public World world;
|
||||
|
||||
/** The player that last interacted with the imbuement altar, or null if there isn't one (or if this is being queried for other reasons, e.g. JEI) */
|
||||
public EntityPlayer lastUser;
|
||||
|
||||
/** The resulting item stack of the imbuement process */
|
||||
public ItemStack result;
|
||||
|
||||
public ImbuementActivateEvent(ItemStack input, Element[] receptacleElements, World world, EntityPlayer lastUser, ItemStack result) {
|
||||
super();
|
||||
this.input = input;
|
||||
this.receptacleElements = receptacleElements;
|
||||
this.world = world;
|
||||
this.lastUser = lastUser;
|
||||
this.result = result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package electroblob.wizardry.event;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||
import net.minecraftforge.fml.common.eventhandler.Cancelable;
|
||||
|
||||
/**
|
||||
* ResurrectionEvent is fired when a player is about to be resurrected, after all other checks have been performed.
|
||||
* <i>Note that this event is only fired on the server side.</i><br>
|
||||
* <br>
|
||||
* This event is {@link Cancelable}. If this event is canceled, the player is not resurrected.<br>
|
||||
* <br>
|
||||
* This event does not have a result. {@link HasResult}<br>
|
||||
* <br>
|
||||
* This event is fired on the {@link MinecraftForge#EVENT_BUS}.
|
||||
*
|
||||
* @author Electroblob
|
||||
* @since Wizardry 2.1
|
||||
*/
|
||||
@Cancelable
|
||||
public class ResurrectionEvent extends PlayerEvent {
|
||||
|
||||
private final EntityPlayer caster;
|
||||
|
||||
public ResurrectionEvent(EntityPlayer player, EntityPlayer caster){
|
||||
super(player);
|
||||
this.caster = caster;
|
||||
}
|
||||
|
||||
/** Returns the player that cast the resurrection spell. If the player resurrected themselves, this will be the
|
||||
* same as {@link ResurrectionEvent#getEntityPlayer()}. */
|
||||
public EntityPlayer getCaster(){
|
||||
return caster;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -46,6 +46,10 @@ public final class WizardryBaublesIntegration {
|
||||
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.RING, BaubleType.RING);
|
||||
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.AMULET, BaubleType.AMULET);
|
||||
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.CHARM, BaubleType.CHARM);
|
||||
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.BELT, BaubleType.BELT);
|
||||
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.BODY, BaubleType.BODY);
|
||||
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.HEAD, BaubleType.HEAD);
|
||||
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.TRINKET, BaubleType.TRINKET);
|
||||
}
|
||||
|
||||
public static boolean enabled(){
|
||||
|
||||
@@ -452,6 +452,24 @@ public class ContainerArcaneWorkbench extends Container implements ISpellSortabl
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called (via {@link electroblob.wizardry.packet.PacketControlInput PacketControlInput}) when the clear button in
|
||||
* the arcane workbench GUI is pressed.
|
||||
*/
|
||||
// As of 2.1, for the sake of events and neatness of code, this was moved here from TileEntityArcaneWorkbench.
|
||||
// As of 4.2, the spell binding/charging/upgrading code was delegated (via IWorkbenchItem) to the items themselves.
|
||||
public void onClearButtonPressed(EntityPlayer player){
|
||||
|
||||
Slot centre = this.getSlot(CENTRE_SLOT);
|
||||
|
||||
if(centre.getStack().getItem() instanceof IWorkbenchItem){ // Should always be true, but no harm in checking.
|
||||
|
||||
Slot[] spellBooks = this.inventorySlots.subList(0, 8).toArray(new Slot[8]);
|
||||
|
||||
((IWorkbenchItem) centre.getStack().getItem()).onClearButtonPressed(player, centre, this.getSlot(CRYSTAL_SLOT), this.getSlot(UPGRADE_SLOT), spellBooks);
|
||||
}
|
||||
}
|
||||
|
||||
/** Scrolls to the given row number. */
|
||||
public void scrollTo(int row){
|
||||
this.scroll = row;
|
||||
|
||||
@@ -55,6 +55,26 @@ public interface IWorkbenchItem {
|
||||
*/
|
||||
boolean onApplyButtonPressed(EntityPlayer player, Slot centre, Slot crystals, Slot upgrade, Slot[] spellBooks);
|
||||
|
||||
/**
|
||||
* Called when this item is in the central slot of an arcane workbench and the apply clear is pressed. Items must
|
||||
* implement this method to define what happens when the apply button is pressed.
|
||||
* @param player The player that pressed the apply button.
|
||||
* @param centre The central slot in the arcane workbench. This slot will always contain a stack of the implementing
|
||||
* item, or in other words, <i>it is guaranteed that</i> {@code this == centre.getStack().getItem()}.
|
||||
* @param crystals The magic crystal slot of the arcane workbench.
|
||||
* @param upgrade The upgrade slot of the arcane workbench.
|
||||
* @param spellBooks An array of the <i>active</i> (visible) spell book slots in the arcane workbench. The length of
|
||||
* the array will be equal to the value returned by {@link IWorkbenchItem#getSpellSlotCount(ItemStack)}.
|
||||
* */
|
||||
default void onClearButtonPressed(EntityPlayer player, Slot centre, Slot crystals, Slot upgrade, Slot[] spellBooks){};
|
||||
|
||||
/**
|
||||
* Must be overridden in the item class to make the clear button in the Arcane Workbench clickable.
|
||||
* */
|
||||
default boolean isClearable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the tooltip (dark grey box) should be drawn when this item is in an arcane workbench. Only
|
||||
* called client-side.
|
||||
|
||||
@@ -10,6 +10,7 @@ import electroblob.wizardry.entity.living.ISummonedCreature;
|
||||
import electroblob.wizardry.entity.projectile.EntityDart;
|
||||
import electroblob.wizardry.entity.projectile.EntityForceOrb;
|
||||
import electroblob.wizardry.entity.projectile.EntityIceShard;
|
||||
import electroblob.wizardry.event.ArtefactCheckEvent;
|
||||
import electroblob.wizardry.event.SpellCastEvent;
|
||||
import electroblob.wizardry.event.SpellCastEvent.Source;
|
||||
import electroblob.wizardry.integration.DamageSafetyChecker;
|
||||
@@ -37,6 +38,7 @@ import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraftforge.common.BiomeDictionary;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.common.capabilities.ICapabilityProvider;
|
||||
import net.minecraftforge.event.entity.living.LivingDeathEvent;
|
||||
import net.minecraftforge.event.entity.living.LivingEvent;
|
||||
@@ -88,7 +90,11 @@ public class ItemArtefact extends Item {
|
||||
|
||||
/** An artefact that improves attacking spells. Two of these can be active at any one time. */ RING(2),
|
||||
/** An artefact that improves defensive spells. One of these can be active at any one time. */ AMULET(1),
|
||||
/** An artefact that improves utility spells. One of these can be active at any one time. */ CHARM(1);
|
||||
/** An artefact that improves utility spells. One of these can be active at any one time. */ CHARM(1),
|
||||
/** Added for add-on artefacts. */ BELT(1),
|
||||
/** Added for add-on artefacts. */ BODY(1),
|
||||
/** Added for add-on artefacts. */ HEAD(1),
|
||||
/** Added for add-on artefacts. */ TRINKET(1);
|
||||
|
||||
public final int maxAtOnce;
|
||||
|
||||
@@ -123,6 +129,8 @@ public class ItemArtefact extends Item {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isEnabled() { return enabled; }
|
||||
|
||||
@Override
|
||||
public EnumRarity getRarity(ItemStack stack){
|
||||
return rarity;
|
||||
@@ -176,6 +184,13 @@ public class ItemArtefact extends Item {
|
||||
|
||||
if(!((ItemArtefact)artefact).enabled) return false; // Disabled in the config
|
||||
|
||||
ArtefactCheckEvent event = new ArtefactCheckEvent(player, (ItemArtefact) artefact);
|
||||
if(MinecraftForge.EVENT_BUS.post(event)) return false;
|
||||
|
||||
if (event.getResult() == Event.Result.ALLOW) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(WizardryBaublesIntegration.enabled()){
|
||||
return WizardryBaublesIntegration.isBaubleEquipped(player, artefact);
|
||||
}else{
|
||||
@@ -344,6 +359,8 @@ public class ItemArtefact extends Item {
|
||||
|
||||
findMatchingWandAndExecute(player, Spells.shield, wand -> {
|
||||
|
||||
if(wand.getItem() instanceof ItemScroll) return; // Ignore scrolls since they shouldn't work
|
||||
|
||||
List<Entity> projectiles = EntityUtils.getEntitiesWithinRadius(5, player.posX, player.posY, player.posZ, world, Entity.class);
|
||||
projectiles.removeIf(e -> !(e instanceof IProjectile));
|
||||
Vec3d look = player.getLookVec();
|
||||
@@ -765,6 +782,7 @@ public class ItemArtefact extends Item {
|
||||
&& Streams.stream(player.getHeldEquipment()).anyMatch(s -> s.getItem() instanceof ISpellCastingItem
|
||||
&& ((ISpellCastingItem)s.getItem()).getCurrentSpell(s).getElement() == Element.NECROMANCY))){
|
||||
|
||||
event.getEntityLiving().addPotionEffect(new PotionEffect(WizardryPotions.curse_of_soulbinding, 400));
|
||||
CurseOfSoulbinding.getSoulboundCreatures(WizardData.get(player)).add(event.getEntity().getUniqueID());
|
||||
}
|
||||
|
||||
|
||||
@@ -84,8 +84,15 @@ public class ItemManaFlask extends Item {
|
||||
stacks.addAll(player.inventory.armorInventory); // player#getArmorInventoryList() only returns an Iterable
|
||||
|
||||
if(stacks.stream().anyMatch(s -> s.getItem() instanceof IManaStoringItem && !((IManaStoringItem)s.getItem()).isManaFull(s))){
|
||||
player.setActiveHand(hand);
|
||||
|
||||
if(player.capabilities.isCreativeMode){
|
||||
findAndChargeItem(flask, player);
|
||||
}else{
|
||||
player.setActiveHand(hand);
|
||||
}
|
||||
|
||||
return new ActionResult<>(EnumActionResult.SUCCESS, flask);
|
||||
|
||||
}else{
|
||||
return new ActionResult<>(EnumActionResult.FAIL, flask);
|
||||
}
|
||||
@@ -106,30 +113,32 @@ public class ItemManaFlask extends Item {
|
||||
public ItemStack onItemUseFinish(ItemStack stack, World world, EntityLivingBase entity){
|
||||
|
||||
if(entity instanceof EntityPlayer){
|
||||
|
||||
EntityPlayer player = (EntityPlayer)entity;
|
||||
|
||||
List<ItemStack> stacks = InventoryUtils.getPrioritisedHotbarAndOffhand(player);
|
||||
stacks.addAll(player.inventory.armorInventory); // player#getArmorInventoryList() only returns an Iterable
|
||||
|
||||
// Find the chargeable item with the least mana
|
||||
ItemStack toCharge = stacks.stream()
|
||||
.filter(s -> s.getItem() instanceof IManaStoringItem && !((IManaStoringItem)s.getItem()).isManaFull(s))
|
||||
.min(Comparator.comparingDouble(s -> ((IManaStoringItem)s.getItem()).getFullness(s))).orElse(null);
|
||||
|
||||
if(toCharge != null){
|
||||
|
||||
((IManaStoringItem)toCharge.getItem()).rechargeMana(toCharge, size.capacity);
|
||||
|
||||
EntityUtils.playSoundAtPlayer(player, WizardrySounds.ITEM_MANA_FLASK_USE, 1, 1);
|
||||
EntityUtils.playSoundAtPlayer(player, WizardrySounds.ITEM_MANA_FLASK_RECHARGE, 0.7f, 1.1f);
|
||||
|
||||
if(!player.isCreative()) stack.shrink(1);
|
||||
player.getCooldownTracker().setCooldown(this, 20);
|
||||
}
|
||||
findAndChargeItem(stack, (EntityPlayer)entity);
|
||||
}
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
private void findAndChargeItem(ItemStack stack, EntityPlayer player){
|
||||
|
||||
List<ItemStack> stacks = InventoryUtils.getPrioritisedHotbarAndOffhand(player);
|
||||
stacks.addAll(player.inventory.armorInventory); // player#getArmorInventoryList() only returns an Iterable
|
||||
|
||||
// Find the chargeable item with the least mana
|
||||
ItemStack toCharge = stacks.stream()
|
||||
.filter(s -> s.getItem() instanceof IManaStoringItem && !((IManaStoringItem)s.getItem()).isManaFull(s))
|
||||
.min(Comparator.comparingDouble(s -> ((IManaStoringItem)s.getItem()).getFullness(s))).orElse(null);
|
||||
|
||||
if(toCharge != null){
|
||||
|
||||
((IManaStoringItem)toCharge.getItem()).rechargeMana(toCharge, size.capacity);
|
||||
|
||||
EntityUtils.playSoundAtPlayer(player, WizardrySounds.ITEM_MANA_FLASK_USE, 1, 1);
|
||||
EntityUtils.playSoundAtPlayer(player, WizardrySounds.ITEM_MANA_FLASK_RECHARGE, 0.7f, 1.1f);
|
||||
|
||||
if(!player.isCreative()) stack.shrink(1);
|
||||
player.getCooldownTracker().setCooldown(this, 20);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,9 +15,16 @@ import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.*;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.EnumActionResult;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.text.Style;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
@@ -100,6 +107,13 @@ public class ItemScroll extends Item implements ISpellCastingItem, IWorkbenchIte
|
||||
tooltip.add(spell.getElement().getDisplayName());
|
||||
tooltip.add(spell.getType().getDisplayName());
|
||||
}
|
||||
// Advanced tooltips displays the source mod's name if the spell is not from Wizardry
|
||||
if (advanced.isAdvanced() && this.getRegistryName().toString().equals(Wizardry.MODID + ":scroll") && !spell.getRegistryName().getNamespace().equals(Wizardry.MODID)) {
|
||||
String modId = spell.getRegistryName().getNamespace();
|
||||
String name = new Style().setColor(TextFormatting.BLUE).setItalic(true).getFormattingCode() +
|
||||
Loader.instance().getIndexedModList().get(modId).getMetadata().name;
|
||||
tooltip.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,7 +209,7 @@ public class ItemScroll extends Item implements ISpellCastingItem, IWorkbenchIte
|
||||
if(!spell.isContinuous && !caster.isCreative()) stack.shrink(1);
|
||||
|
||||
// Now uses the vanilla cooldown mechanic to prevent spamming of spells
|
||||
if(!spell.isContinuous) caster.getCooldownTracker().setCooldown(this, spell.getCooldown());
|
||||
if(!spell.isContinuous && !caster.isCreative()) caster.getCooldownTracker().setCooldown(this, spell.getCooldown());
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -230,7 +244,7 @@ public class ItemScroll extends Item implements ISpellCastingItem, IWorkbenchIte
|
||||
MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Finish(Source.SCROLL, spell, user, modifiers, castingTick));
|
||||
spell.finishCasting(user.world, user, Double.NaN, Double.NaN, Double.NaN, null, castingTick, modifiers);
|
||||
|
||||
if(user instanceof EntityPlayer){
|
||||
if(user instanceof EntityPlayer && !((EntityPlayer)user).isCreative()){
|
||||
((EntityPlayer)user).getCooldownTracker().setCooldown(this, spell.getCooldown());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package electroblob.wizardry.item;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.entity.projectile.EntityConjuredArrow;
|
||||
import electroblob.wizardry.registry.Spells;
|
||||
import electroblob.wizardry.util.InventoryUtils;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
@@ -14,6 +15,7 @@ import net.minecraft.init.SoundEvents;
|
||||
import net.minecraft.item.IItemPropertyGetter;
|
||||
import net.minecraft.item.ItemArrow;
|
||||
import net.minecraft.item.ItemBow;
|
||||
import net.minecraft.item.ItemSpectralArrow;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.stats.StatList;
|
||||
import net.minecraft.util.*;
|
||||
@@ -197,8 +199,7 @@ public class ItemSpectralBow extends ItemBow implements IConjuredItem {
|
||||
|
||||
if(!world.isRemote){
|
||||
|
||||
ItemArrow itemarrow = (ItemArrow)Items.ARROW;
|
||||
EntityArrow entityarrow = itemarrow.createArrow(world, new ItemStack(itemarrow), entityplayer);
|
||||
EntityConjuredArrow entityarrow = new EntityConjuredArrow(world, entityplayer);
|
||||
entityarrow.shoot(entityplayer, entityplayer.rotationPitch, entityplayer.rotationYaw, 0.0F,
|
||||
f * 3.0F, 1.0F);
|
||||
|
||||
|
||||
@@ -12,10 +12,15 @@ import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.*;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.EnumActionResult;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.text.Style;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
@@ -96,6 +101,13 @@ public class ItemSpellBook extends Item {
|
||||
tooltip.add(spell.getElement().getDisplayName());
|
||||
tooltip.add(spell.getType().getDisplayName());
|
||||
}
|
||||
// Advanced tooltips displays the source mod's name if the spell is not from Wizardry
|
||||
if (advanced.isAdvanced() && this.getRegistryName().toString().equals(Wizardry.MODID + ":spell_book") && !spell.getRegistryName().getNamespace().equals(Wizardry.MODID)) {
|
||||
String modId = spell.getRegistryName().getNamespace();
|
||||
String name = new Style().setColor(TextFormatting.BLUE).setItalic(true).getFormattingCode() +
|
||||
Loader.instance().getIndexedModList().get(modId).getMetadata().name;
|
||||
tooltip.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.EnumAction;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.*;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
@@ -45,6 +46,7 @@ import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
@@ -226,9 +228,15 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(ItemStack stack, World world, Entity entity, int slot, boolean isHeld){
|
||||
public void onUpdate(ItemStack stack, World world, Entity entity, int slot, boolean isHeldInMainhand){
|
||||
boolean isHeld = isHeldInMainhand || entity instanceof EntityLivingBase && ItemStack.areItemStacksEqual(stack, ((EntityLivingBase) entity).getHeldItemOffhand());
|
||||
|
||||
WandHelper.decrementCooldowns(stack);
|
||||
// If Wizardry.settings.wandsMustBeHeldToDecrementCooldown is false, the cooldowns will be decremented.
|
||||
// If Wizardry.settings.wandsMustBeHeldToDecrementCooldown is true and isHeld is true, the cooldowns will also be decremented.
|
||||
// If Wizardry.settings.wandsMustBeHeldToDecrementCooldown is true and isHeld is false, the cooldowns will not be decremented.
|
||||
if (!Wizardry.settings.wandsMustBeHeldToDecrementCooldown || isHeld) {
|
||||
WandHelper.decrementCooldowns(stack);
|
||||
}
|
||||
|
||||
// Decrements wand damage (increases mana) every 1.5 seconds if it has a condenser upgrade
|
||||
if(!world.isRemote && !this.isManaFull(stack) && world.getTotalWorldTime() % Constants.CONDENSER_TICK_INTERVAL == 0){
|
||||
@@ -836,8 +844,19 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
|
||||
Spell spell = Spell.byMetadata(spellBooks[i].getStack().getItemDamage());
|
||||
// If the wand is powerful enough for the spell, it's not already bound to that slot and it's enabled for wands
|
||||
if(!(spell.getTier().level > this.tier.level) && spells[i] != spell && spell.isEnabled(SpellProperties.Context.WANDS)){
|
||||
|
||||
// Decide if we can bind this multiple times
|
||||
if (Wizardry.settings.preventBindingSameSpellTwiceToWands && Arrays.stream(spells).anyMatch(s -> s == spell)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
spells[i] = spell;
|
||||
changed = true;
|
||||
|
||||
// setting to consume books upon use
|
||||
if (Wizardry.settings.singleUseSpellBooks) {
|
||||
spellBooks[i].getStack().shrink(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -849,7 +868,12 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
|
||||
|
||||
int chargeDepleted = this.getManaCapacity(centre.getStack()) - this.getMana(centre.getStack());
|
||||
|
||||
int manaPerItem = Constants.MANA_PER_CRYSTAL;
|
||||
// Not too pretty but allows addons implementing the IManaStoringItem interface to provide their mana amount for custom crystals,
|
||||
// previously this was defaulted to the regular crystal's amount, allowing players to exploit it if a crystal was worth less mana than that.
|
||||
int manaPerItem = crystals.getStack().getItem() instanceof IManaStoringItem ?
|
||||
((IManaStoringItem) crystals.getStack().getItem()).getMana(crystals.getStack()) :
|
||||
crystals.getStack().getItem() instanceof ItemCrystal ? Constants.MANA_PER_CRYSTAL : Constants.MANA_PER_SHARD;
|
||||
|
||||
if(crystals.getStack().getItem() == WizardryItems.crystal_shard) manaPerItem = Constants.MANA_PER_SHARD;
|
||||
if(crystals.getStack().getItem() == WizardryItems.grand_crystal) manaPerItem = Constants.GRAND_CRYSTAL_MANA;
|
||||
|
||||
@@ -870,6 +894,19 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
|
||||
return changed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClearButtonPressed(EntityPlayer player, Slot centre, Slot crystals, Slot upgrade, Slot[] spellBooks){
|
||||
ItemStack stack = centre.getStack();
|
||||
if (stack.hasTagCompound() && stack.getTagCompound().hasKey(WandHelper.SPELL_ARRAY_KEY)) {
|
||||
NBTTagCompound nbt = stack.getTagCompound();
|
||||
nbt.removeTag(WandHelper.SPELL_ARRAY_KEY);
|
||||
stack.setTagCompound(nbt);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClearable() { return true; }
|
||||
|
||||
// hitEntity is only called server-side, so we'll have to use events
|
||||
@SubscribeEvent
|
||||
public static void onAttackEntityEvent(AttackEntityEvent event){
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package electroblob.wizardry.item;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Streams;
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.client.DrawingUtils;
|
||||
@@ -44,7 +46,11 @@ import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Mod.EventBusSubscriber
|
||||
@@ -54,13 +60,35 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
|
||||
private static final float SAGE_OTHER_COST_REDUCTION = 0.2f;
|
||||
private static final float WARLOCK_SPEED_BOOST = 0.2f;
|
||||
private static final UUID WARLOCK_SPEED_BOOST_UUID = UUID.fromString("4bad7152-2663-4b1b-bb59-552e92847031");
|
||||
// Standard ItemArmor modifiers
|
||||
private static final UUID[] ARMOR_MODIFIERS = new UUID[] {UUID.fromString("845DB27C-C624-495F-8C9F-6020A9A58B6B"), UUID.fromString("D8499B04-0E66-4726-AB29-64469D734E0D"), UUID.fromString("9F3D476D-C118-4544-8365-64846904B48E"), UUID.fromString("2AD3F246-FEE1-4E67-B886-69FD380BB150")};
|
||||
|
||||
@Override
|
||||
public Multimap<String, AttributeModifier> getItemAttributeModifiers(EntityEquipmentSlot slot) {
|
||||
// The vanilla armor handling logic from ItemArmor.getItemAttributeModifiers was moved to ItemWizardArmour.getAttributeModifiers to allow checking if the stack has enough mana
|
||||
Multimap<String, AttributeModifier> multimap = ArrayListMultimap.create();
|
||||
return multimap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Multimap<String, AttributeModifier> getAttributeModifiers(EntityEquipmentSlot slot, ItemStack stack) {
|
||||
Multimap<String, AttributeModifier> multimap = super.getAttributeModifiers(slot, stack);
|
||||
|
||||
// only grant armor if the equipment has mana
|
||||
if (slot == this.armorType && !((ItemWizardArmour) stack.getItem()).isManaEmpty(stack)) {
|
||||
multimap.put(SharedMonsterAttributes.ARMOR.getName(), new AttributeModifier(ARMOR_MODIFIERS[slot.getIndex()], "Armor modifier", this.damageReduceAmount, 0));
|
||||
multimap.put(SharedMonsterAttributes.ARMOR_TOUGHNESS.getName(), new AttributeModifier(ARMOR_MODIFIERS[slot.getIndex()], "Armor toughness", this.toughness, 0));
|
||||
}
|
||||
|
||||
return multimap;
|
||||
}
|
||||
|
||||
public enum ArmourClass {
|
||||
|
||||
WIZARD(Materials.SILK, () -> null, "wizard", 0.1f, 0, "hat", "robe", "leggings", "boots"),
|
||||
SAGE(Materials.SAGE, () -> WizardryItems.resplendent_thread, "sage", 0.2f, 0, "hat", "robe", "leggings", "boots"),
|
||||
BATTLEMAGE(Materials.BATTLEMAGE, () -> WizardryItems.crystal_silver_plating, "battlemage", 0.05f, 0.15f, "helmet", "chestplate", "leggings", "boots"),
|
||||
WARLOCK(Materials.WARLOCK, () -> WizardryItems.ethereal_crystalweave, "warlock", 0.1f, 0.3f, "hood", "robe", "leggings", "boots");
|
||||
BATTLEMAGE(Materials.BATTLEMAGE, () -> WizardryItems.crystal_silver_plating, "battlemage", 0.05f, 0.05f, "helmet", "chestplate", "leggings", "boots"),
|
||||
WARLOCK(Materials.WARLOCK, () -> WizardryItems.ethereal_crystalweave, "warlock", 0.1f, 0.1f, "hood", "robe", "leggings", "boots");
|
||||
|
||||
/** The armour material to use for this armour class. */
|
||||
final ArmorMaterial material;
|
||||
@@ -181,8 +209,8 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
|
||||
|
||||
@Override
|
||||
public void onArmorTick(World world, EntityPlayer player, ItemStack itemStack){
|
||||
if(armorType == EntityEquipmentSlot.HEAD && isWearingFullSet(player, element, ArmourClass.BATTLEMAGE)
|
||||
&& player.ticksExisted % 20 == 0){
|
||||
if(armorType == EntityEquipmentSlot.HEAD && player.ticksExisted % 20 == 0
|
||||
&& isWearingFullSet(player, element, ArmourClass.BATTLEMAGE) && doAllArmourPiecesHaveMana(player)){
|
||||
player.addPotionEffect(new PotionEffect(WizardryPotions.ward, 219, 0, true, false));
|
||||
}
|
||||
}
|
||||
@@ -209,7 +237,7 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
|
||||
modifiers.set(WizardryItems.cooldown_upgrade, modifiers.get(WizardryItems.cooldown_upgrade) - armourClass.cooldownReduction, true);
|
||||
|
||||
// Full set bonuses
|
||||
if(this.armorType == EntityEquipmentSlot.HEAD && isWearingFullSet(caster, element, armourClass)){
|
||||
if(this.armorType == EntityEquipmentSlot.HEAD && isWearingFullSet(caster, element, armourClass) && doAllArmourPiecesHaveMana(caster)){
|
||||
if(armourClass == ArmourClass.SAGE && spell.getElement() != this.element){
|
||||
modifiers.set(SpellModifiers.COST, 1 - SAGE_OTHER_COST_REDUCTION, false);
|
||||
}
|
||||
@@ -277,7 +305,7 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
|
||||
if(this.armourClass == ArmourClass.WIZARD){
|
||||
for(ArmourClass armourClass : ArmourClass.values()){
|
||||
if(upgrade.getItem() == armourClass.upgradeItem.get()){
|
||||
Item newArmour = getArmour(this.element, armourClass, this.getEquipmentSlot());
|
||||
Item newArmour = getArmour(this.element, armourClass, this.armorType);
|
||||
ItemStack newStack = new ItemStack(newArmour);
|
||||
((ItemWizardArmour)newArmour).setMana(newStack, this.getMana(stack));
|
||||
newStack.setTagCompound(stack.getTagCompound());
|
||||
@@ -306,7 +334,12 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
|
||||
|
||||
int chargeDepleted = this.getManaCapacity(centre.getStack()) - this.getMana(centre.getStack());
|
||||
|
||||
int manaPerItem = Constants.MANA_PER_CRYSTAL;
|
||||
// Not too pretty but allows addons implementing the IManaStoringItem interface to provide their mana amount for custom crystals,
|
||||
// previously this was defaulted to the regular crystal's amount, allowing players to exploit it if a crystal was worth less mana than that.
|
||||
int manaPerItem = crystals.getStack().getItem() instanceof IManaStoringItem ?
|
||||
((IManaStoringItem) crystals.getStack().getItem()).getMana(crystals.getStack()) :
|
||||
crystals.getStack().getItem() instanceof ItemCrystal ? Constants.MANA_PER_CRYSTAL : Constants.MANA_PER_SHARD;
|
||||
|
||||
if(crystals.getStack().getItem() == WizardryItems.crystal_shard) manaPerItem = Constants.MANA_PER_SHARD;
|
||||
if(crystals.getStack().getItem() == WizardryItems.grand_crystal) manaPerItem = Constants.GRAND_CRYSTAL_MANA;
|
||||
|
||||
@@ -335,7 +368,7 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
|
||||
|
||||
IAttributeInstance movementSpeed = event.getEntityLiving().getAttributeMap().getAttributeInstance(SharedMonsterAttributes.MOVEMENT_SPEED);
|
||||
|
||||
if(isWearingFullSet(event.getEntityLiving(), null, ArmourClass.WARLOCK)){
|
||||
if(isWearingFullSet(event.getEntityLiving(), null, ArmourClass.WARLOCK) && doAllArmourPiecesHaveMana(event.getEntityLiving())){
|
||||
// Only apply the modifier once (can't just check this is the helmet since it might not be the last piece equipped)
|
||||
if(movementSpeed.getModifier(WARLOCK_SPEED_BOOST_UUID) == null){
|
||||
movementSpeed.applyModifier(new AttributeModifier(WARLOCK_SPEED_BOOST_UUID, "Warlock set bonus", WARLOCK_SPEED_BOOST, Operations.MULTIPLY_FLAT));
|
||||
@@ -405,7 +438,7 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
|
||||
* @param armourClass The class to check, or null to accept any class as long as they are all the same.
|
||||
* @return True if the entity is wearing a full set of the given element and class, false otherwise.
|
||||
*/
|
||||
private static boolean isWearingFullSet(EntityLivingBase entity, @Nullable Element element, @Nullable ArmourClass armourClass){
|
||||
public static boolean isWearingFullSet(EntityLivingBase entity, @Nullable Element element, @Nullable ArmourClass armourClass){
|
||||
ItemStack helmet = entity.getItemStackFromSlot(EntityEquipmentSlot.HEAD);
|
||||
if(!(helmet.getItem() instanceof ItemWizardArmour)) return false;
|
||||
Element e = element == null ? ((ItemWizardArmour)helmet.getItem()).element : element;
|
||||
@@ -416,6 +449,16 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
|
||||
&& ((ItemWizardArmour)entity.getItemStackFromSlot(s).getItem()).armourClass == ac);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given entity's armour pieces which implement {@link IManaStoringItem} has mana. Ignores pieces which doesn't have a mana storage.
|
||||
* @param entity The entity to query.
|
||||
* @return True if all armour pieces which implement {@link IManaStoringItem} has mana, false otherwise.
|
||||
*/
|
||||
public static boolean doAllArmourPiecesHaveMana(EntityLivingBase entity){
|
||||
return Arrays.stream(InventoryUtils.ARMOUR_SLOTS).noneMatch(s -> entity.getItemStackFromSlot(s).getItem() instanceof IManaStoringItem
|
||||
&& ((IManaStoringItem) entity.getItemStackFromSlot(s).getItem()).isManaEmpty(entity.getItemStackFromSlot(s)));
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onLivingSetAttackTargetEvent(LivingSetAttackTargetEvent event){
|
||||
// Undo the mob detection penalty for wearing armour when invisible
|
||||
|
||||
@@ -10,6 +10,7 @@ import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.EnumActionResult;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.text.Style;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
@@ -36,7 +37,11 @@ public class ItemWizardHandbook extends Item {
|
||||
@Override
|
||||
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand){
|
||||
ItemStack stack = player.getHeldItem(hand);
|
||||
player.openGui(Wizardry.instance, WizardryGuiHandler.WIZARD_HANDBOOK, world, 0, 0, 0);
|
||||
if (Wizardry.settings.loadHandbook) {
|
||||
player.openGui(Wizardry.instance, WizardryGuiHandler.WIZARD_HANDBOOK, world, 0, 0, 0);
|
||||
} else if (!world.isRemote){
|
||||
player.sendStatusMessage(new TextComponentTranslation("item." + Wizardry.MODID + ":wizard_handbook.disabled"), false);
|
||||
}
|
||||
return ActionResult.newResult(EnumActionResult.SUCCESS, stack);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,12 +12,15 @@ import electroblob.wizardry.entity.living.*;
|
||||
import electroblob.wizardry.entity.projectile.EntityFirebomb;
|
||||
import electroblob.wizardry.entity.projectile.EntityMagicFireball;
|
||||
import electroblob.wizardry.event.SpellCastEvent;
|
||||
import electroblob.wizardry.event.SpellCastEvent.Source;
|
||||
import electroblob.wizardry.item.IManaStoringItem;
|
||||
import electroblob.wizardry.item.ISpellCastingItem;
|
||||
import electroblob.wizardry.item.ItemArtefact;
|
||||
import electroblob.wizardry.registry.*;
|
||||
import electroblob.wizardry.spell.Banish;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
import electroblob.wizardry.util.BlockUtils;
|
||||
import electroblob.wizardry.util.EntityUtils;
|
||||
import electroblob.wizardry.util.SpellModifiers;
|
||||
import electroblob.wizardry.util.SpellProperties.Context;
|
||||
import net.minecraft.entity.effect.EntityLightningBolt;
|
||||
import net.minecraft.entity.item.EntityFallingBlock;
|
||||
@@ -174,6 +177,23 @@ public abstract class Forfeit {
|
||||
|
||||
forfeit.apply(event.getWorld(), player);
|
||||
|
||||
ItemStack stack = player.getHeldItemMainhand();
|
||||
|
||||
if(!(stack.getItem() instanceof ISpellCastingItem)){
|
||||
stack = player.getHeldItemOffhand();
|
||||
if(!(stack.getItem() instanceof ISpellCastingItem)) stack = ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
if(!stack.isEmpty()){
|
||||
// Still need to charge the player mana or consume the scroll
|
||||
if(event.getSource() == Source.SCROLL){
|
||||
if(!player.isCreative()) stack.shrink(1);
|
||||
}else if(stack.getItem() instanceof IManaStoringItem){
|
||||
int cost = (int)(event.getSpell().getCost() * event.getModifiers().get(SpellModifiers.COST) + 0.1f); // Weird floaty rounding
|
||||
((IManaStoringItem)stack.getItem()).consumeMana(stack, cost, player);
|
||||
}
|
||||
}
|
||||
|
||||
WizardryAdvancementTriggers.spell_failure.triggerFor(player);
|
||||
|
||||
EntityUtils.playSoundAtPlayer(player, forfeit.getSound(), WizardrySounds.SPELLS, 1, 1);
|
||||
@@ -222,10 +242,11 @@ public abstract class Forfeit {
|
||||
}));
|
||||
|
||||
add(Tier.MASTER, Element.FIRE, create("burn_surroundings", (w, p) -> {
|
||||
if(!w.isRemote){
|
||||
if(!w.isRemote && EntityUtils.canDamageBlocks(p, w)){
|
||||
List<BlockPos> sphere = BlockUtils.getBlockSphere(p.getPosition(), 6);
|
||||
for(BlockPos pos : sphere){
|
||||
if(w.rand.nextBoolean() && w.isAirBlock(pos)) w.setBlockState(pos, Blocks.FIRE.getDefaultState());
|
||||
if(w.rand.nextBoolean() && w.isAirBlock(pos) && BlockUtils.canPlaceBlock(p, w, pos))
|
||||
w.setBlockState(pos, Blocks.FIRE.getDefaultState());
|
||||
}
|
||||
}
|
||||
}));
|
||||
@@ -376,10 +397,11 @@ public abstract class Forfeit {
|
||||
}));
|
||||
|
||||
add(Tier.NOVICE, Element.EARTH, create("snares", (w, p) -> {
|
||||
if(!w.isRemote){
|
||||
if(!w.isRemote && EntityUtils.canDamageBlocks(p, w)){
|
||||
for(EnumFacing direction : EnumFacing.HORIZONTALS){
|
||||
BlockPos pos = p.getPosition().offset(direction);
|
||||
if(BlockUtils.canBlockBeReplaced(w, pos)) w.setBlockState(pos, WizardryBlocks.snare.getDefaultState());
|
||||
if(BlockUtils.canBlockBeReplaced(w, pos) && BlockUtils.canPlaceBlock(p, w, pos))
|
||||
w.setBlockState(pos, WizardryBlocks.snare.getDefaultState());
|
||||
}
|
||||
}
|
||||
}));
|
||||
@@ -393,9 +415,9 @@ public abstract class Forfeit {
|
||||
}));
|
||||
|
||||
add(Tier.APPRENTICE, Element.EARTH, create("uproot_plants", (w, p) -> {
|
||||
if(!w.isRemote){
|
||||
if(!w.isRemote && EntityUtils.canDamageBlocks(p, w)){
|
||||
List<BlockPos> sphere = BlockUtils.getBlockSphere(p.getPosition(), 5);
|
||||
sphere.removeIf(pos -> !(w.getBlockState(pos).getBlock() instanceof IPlantable));
|
||||
sphere.removeIf(pos -> !(w.getBlockState(pos).getBlock() instanceof IPlantable) || !BlockUtils.canBreakBlock(p, w, pos));
|
||||
sphere.forEach(pos -> w.destroyBlock(pos, true));
|
||||
}
|
||||
}));
|
||||
@@ -403,9 +425,9 @@ public abstract class Forfeit {
|
||||
add(Tier.APPRENTICE, Element.EARTH, create("poison_self", (w, p) -> p.addPotionEffect(new PotionEffect(MobEffects.POISON, 400, 1))));
|
||||
|
||||
add(Tier.ADVANCED, Element.EARTH, create("flood", (w, p) -> {
|
||||
if(!w.isRemote){
|
||||
if(!w.isRemote && EntityUtils.canDamageBlocks(p, w)){
|
||||
List<BlockPos> sphere = BlockUtils.getBlockSphere(p.getPosition().up(), 2);
|
||||
sphere.removeIf(pos -> !BlockUtils.canBlockBeReplaced(w, pos, true));
|
||||
sphere.removeIf(pos -> !BlockUtils.canBlockBeReplaced(w, pos, true) || !BlockUtils.canPlaceBlock(p, w, pos));
|
||||
sphere.forEach(pos -> w.setBlockState(pos, Blocks.WATER.getDefaultState()));
|
||||
}
|
||||
}));
|
||||
@@ -413,8 +435,7 @@ public abstract class Forfeit {
|
||||
add(Tier.MASTER, Element.EARTH, create("bury_self", (w, p) -> {
|
||||
if(!w.isRemote){
|
||||
List<BlockPos> sphere = BlockUtils.getBlockSphere(p.getPosition(), 4);
|
||||
sphere.removeIf(pos -> !w.getBlockState(pos).isFullCube());
|
||||
sphere.removeIf(pos -> BlockUtils.isBlockUnbreakable(w, pos));
|
||||
sphere.removeIf(pos -> !w.getBlockState(pos).isFullCube() || BlockUtils.isBlockUnbreakable(w, pos) || BlockUtils.canBreakBlock(p, w, pos));
|
||||
sphere.forEach(pos -> {
|
||||
EntityFallingBlock block = new EntityFallingBlock(w, pos.getX() + 0.5, pos.getY() + 0.5,
|
||||
pos.getZ() + 0.5, w.getBlockState(pos));
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package electroblob.wizardry.misc;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.item.IManaStoringItem;
|
||||
import electroblob.wizardry.item.ItemManaFlask;
|
||||
import net.minecraft.inventory.InventoryCrafting;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.CraftingManager;
|
||||
import net.minecraft.item.crafting.IRecipe;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
@@ -15,6 +15,8 @@ import net.minecraftforge.fml.common.gameevent.PlayerEvent;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
import net.minecraftforge.oredict.ShapelessOreRecipe;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Implements a dynamic crafting recipe for recharging items with mana flasks.
|
||||
*
|
||||
@@ -24,6 +26,8 @@ import net.minecraftforge.oredict.ShapelessOreRecipe;
|
||||
@Mod.EventBusSubscriber
|
||||
public class RecipeRechargeWithFlask extends ShapelessOreRecipe {
|
||||
|
||||
private static final Multimap<Item, RecipeRechargeWithFlask> FLASK_RECIPES = HashMultimap.create();
|
||||
|
||||
private final IManaStoringItem chargeable;
|
||||
private final ItemManaFlask flask;
|
||||
|
||||
@@ -38,6 +42,7 @@ public class RecipeRechargeWithFlask extends ShapelessOreRecipe {
|
||||
if(!(chargeable instanceof IManaStoringItem)) throw new IllegalArgumentException("Item to be charged must be an instance of IManaStoringItem");
|
||||
this.chargeable = (IManaStoringItem)chargeable;
|
||||
this.flask = flask;
|
||||
FLASK_RECIPES.put(chargeable, this);
|
||||
}
|
||||
|
||||
// Commented out for now because JEI spams the log with errors about the recipe having no output
|
||||
@@ -91,11 +96,11 @@ public class RecipeRechargeWithFlask extends ShapelessOreRecipe {
|
||||
// This means that although I no longer have to replace the result every tick, I still need to do it here
|
||||
// ... I thought the whole point of the new recipe system was so that I DIDN'T have to do this?!
|
||||
if(event.craftMatrix instanceof InventoryCrafting){
|
||||
for(IRecipe recipe : CraftingManager.REGISTRY){
|
||||
if(recipe instanceof RecipeRechargeWithFlask
|
||||
&& recipe.matches((InventoryCrafting)event.craftMatrix, event.player.world)){
|
||||
Collection<RecipeRechargeWithFlask> recipes = FLASK_RECIPES.get(event.crafting.getItem());
|
||||
for(RecipeRechargeWithFlask recipe : recipes){
|
||||
if(recipe.matches((InventoryCrafting)event.craftMatrix, event.player.world)){
|
||||
// Have to modify the itemstack in the actual event, it cannot be replaced
|
||||
((RecipeRechargeWithFlask)recipe).rechargeItemAndCopyNBT(event.crafting, (InventoryCrafting)event.craftMatrix);
|
||||
recipe.rechargeItemAndCopyNBT(event.crafting, (InventoryCrafting)event.craftMatrix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package electroblob.wizardry.packet;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.event.ResurrectionEvent;
|
||||
import electroblob.wizardry.inventory.ContainerArcaneWorkbench;
|
||||
import electroblob.wizardry.item.ISpellCastingItem;
|
||||
import electroblob.wizardry.packet.PacketControlInput.Message;
|
||||
@@ -13,6 +14,7 @@ import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
|
||||
@@ -49,6 +51,17 @@ public class PacketControlInput implements IMessageHandler<Message, IMessage> {
|
||||
|
||||
break;
|
||||
|
||||
case CLEAR_BUTTON:
|
||||
|
||||
if(!(player.openContainer instanceof ContainerArcaneWorkbench)){
|
||||
Wizardry.logger.warn("Received a PacketControlInput, but the player that sent it was not " +
|
||||
"currently using an arcane workbench. This should not happen!");
|
||||
}else{
|
||||
((ContainerArcaneWorkbench)player.openContainer).onClearButtonPressed(player);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case NEXT_SPELL_KEY:
|
||||
|
||||
if(wand.getItem() instanceof ISpellCastingItem){
|
||||
@@ -79,6 +92,7 @@ public class PacketControlInput implements IMessageHandler<Message, IMessage> {
|
||||
.filter(s -> Resurrection.canStackResurrect(s, player)).findFirst().orElse(null);
|
||||
|
||||
if(stack != null){
|
||||
if(MinecraftForge.EVENT_BUS.post(new ResurrectionEvent(player, player))) break;
|
||||
// This should suffice, since this is the only way a player can cast resurrection when dead!
|
||||
((ISpellCastingItem)stack.getItem()).cast(stack, Spells.resurrection, player, EnumHand.MAIN_HAND, 0, new SpellModifiers());
|
||||
break;
|
||||
@@ -130,7 +144,7 @@ public class PacketControlInput implements IMessageHandler<Message, IMessage> {
|
||||
}
|
||||
|
||||
public enum ControlType {
|
||||
APPLY_BUTTON, NEXT_SPELL_KEY, PREVIOUS_SPELL_KEY, RESURRECT_BUTTON, CANCEL_RESURRECT, POSSESSION_PROJECTILE
|
||||
APPLY_BUTTON, NEXT_SPELL_KEY, PREVIOUS_SPELL_KEY, RESURRECT_BUTTON, CANCEL_RESURRECT, POSSESSION_PROJECTILE, CLEAR_BUTTON
|
||||
}
|
||||
|
||||
public static class Message implements IMessage {
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package electroblob.wizardry.potion;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.item.ItemWizardArmour;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.inventory.EntityEquipmentSlot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraftforge.common.ISpecialArmor;
|
||||
|
||||
public class CurseUndeath extends Curse {
|
||||
|
||||
@@ -25,7 +28,7 @@ public class CurseUndeath extends Curse {
|
||||
|
||||
// Adapted from EntityZombie
|
||||
if(entitylivingbase.world.isDaytime() && !entitylivingbase.world.isRemote){
|
||||
|
||||
|
||||
float f = entitylivingbase.getBrightness();
|
||||
|
||||
if(f > 0.5F && entitylivingbase.world.rand.nextFloat() * 30.0F < (f - 0.4F) * 2.0F
|
||||
@@ -35,14 +38,21 @@ public class CurseUndeath extends Curse {
|
||||
boolean flag = true;
|
||||
ItemStack itemstack = entitylivingbase.getItemStackFromSlot(EntityEquipmentSlot.HEAD);
|
||||
|
||||
if(!itemstack.isEmpty()){
|
||||
if(itemstack.isItemStackDamageable()){
|
||||
if (!itemstack.isEmpty()) {
|
||||
if (itemstack.isItemStackDamageable()) {
|
||||
|
||||
itemstack.setItemDamage(itemstack.getItemDamage() + entitylivingbase.world.rand.nextInt(2));
|
||||
|
||||
if(itemstack.getItemDamage() >= itemstack.getMaxDamage()){
|
||||
entitylivingbase.renderBrokenItemStack(itemstack);
|
||||
entitylivingbase.setItemStackToSlot(EntityEquipmentSlot.HEAD, ItemStack.EMPTY);
|
||||
if (itemstack.getItem() instanceof ISpecialArmor) {
|
||||
((ISpecialArmor) itemstack.getItem()).damageArmor(entitylivingbase, itemstack, DamageSource.ON_FIRE, entitylivingbase.world.rand.nextInt(2), EntityEquipmentSlot.HEAD.getSlotIndex());
|
||||
} else {
|
||||
itemstack.setItemDamage(itemstack.getItemDamage() + entitylivingbase.world.rand.nextInt(2));
|
||||
if (itemstack.getItemDamage() >= itemstack.getMaxDamage()) {
|
||||
if (itemstack.getItem() instanceof ItemWizardArmour) {
|
||||
entitylivingbase.setFire(8);
|
||||
} else {
|
||||
entitylivingbase.renderBrokenItemStack(itemstack);
|
||||
entitylivingbase.setItemStackToSlot(EntityEquipmentSlot.HEAD, ItemStack.EMPTY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,17 +2,14 @@ package electroblob.wizardry.potion;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.registry.WizardryPotions;
|
||||
import electroblob.wizardry.registry.WizardrySounds;
|
||||
import electroblob.wizardry.util.EntityUtils;
|
||||
import electroblob.wizardry.util.GeometryUtils;
|
||||
import electroblob.wizardry.util.NBTExtras;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.nbt.NBTUtil;
|
||||
import net.minecraft.network.play.server.SPacketEntityVelocity;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
@@ -23,8 +20,6 @@ public class PotionContainment extends PotionMagicEffect {
|
||||
|
||||
public static final String ENTITY_TAG = "containmentPos";
|
||||
|
||||
private static final double RUBBERBAND_THRESHOLD = 0.24;
|
||||
|
||||
public PotionContainment(boolean isBadEffect, int liquidColour){
|
||||
super(isBadEffect, liquidColour, new ResourceLocation(Wizardry.MODID, "textures/gui/potion_icons/containment.png"));
|
||||
this.setPotionName("potion." + Wizardry.MODID + ":containment");
|
||||
@@ -41,7 +36,6 @@ public class PotionContainment extends PotionMagicEffect {
|
||||
|
||||
@Override
|
||||
public void performEffect(EntityLivingBase target, int strength){
|
||||
|
||||
float maxDistance = getContainmentDistance(strength);
|
||||
|
||||
// Initialise the containment position to the entity's position if it wasn't set already
|
||||
@@ -63,59 +57,14 @@ public class PotionContainment extends PotionMagicEffect {
|
||||
if(target.getEntityBoundingBox().maxZ > origin.z + maxDistance) z = origin.z + maxDistance - target.width/2;
|
||||
if(target.getEntityBoundingBox().minZ < origin.z - maxDistance) z = origin.z - maxDistance + target.width/2;
|
||||
|
||||
if(x != target.posX || y != target.posY || z != target.posZ){
|
||||
|
||||
// if(target.world.isRemote){
|
||||
//
|
||||
// if(x != target.posX){
|
||||
// for(int i = 0; i < 20; i++){
|
||||
// ParticleBuilder.create(ParticleBuilder.Type.DUST).pos(
|
||||
// x,
|
||||
// target.posY + target.height * target.world.rand.nextFloat(),
|
||||
// target.posZ + target.width * (target.world.rand.nextFloat() - 0.5f))
|
||||
// .face(EnumFacing.EAST).clr(0.8f, 0.9f, 1).spawn(target.world);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if(y != target.posY){
|
||||
// for(int i = 0; i < 20; i++){
|
||||
// ParticleBuilder.create(ParticleBuilder.Type.DUST).pos(
|
||||
// target.posX + target.width * (target.world.rand.nextFloat() - 0.5f),
|
||||
// y,
|
||||
// target.posZ + target.width * (target.world.rand.nextFloat() - 0.5f))
|
||||
// .face(EnumFacing.UP).clr(0.8f, 0.9f, 1).spawn(target.world);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if(z != target.posZ){
|
||||
// for(int i = 0; i < 20; i++){
|
||||
// ParticleBuilder.create(ParticleBuilder.Type.DUST).pos(
|
||||
// target.posX + target.width * (target.world.rand.nextFloat() - 0.5f),
|
||||
// target.posY + target.height * target.world.rand.nextFloat(),
|
||||
// z)
|
||||
// .face(EnumFacing.SOUTH).clr(0.8f, 0.9f, 1).spawn(target.world);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// Rubberbanding prevention (the 0.25 limit is from NetHandlerPlayServer, just search "moved wrongly"
|
||||
if(target instanceof EntityPlayer){
|
||||
x = MathHelper.clamp(x, target.posX - RUBBERBAND_THRESHOLD, target.posX + RUBBERBAND_THRESHOLD);
|
||||
y = MathHelper.clamp(y, target.posY - RUBBERBAND_THRESHOLD, target.posY + RUBBERBAND_THRESHOLD);
|
||||
z = MathHelper.clamp(z, target.posZ - RUBBERBAND_THRESHOLD, target.posZ + RUBBERBAND_THRESHOLD);
|
||||
}
|
||||
|
||||
if(x != target.posX || y != target.posY || z != target.posZ)
|
||||
{
|
||||
target.addVelocity(0.15 * Math.signum(x - target.posX), 0.15 * Math.signum(y - target.posY), 0.15 * Math.signum(z - target.posZ));
|
||||
EntityUtils.undoGravity(target);
|
||||
target.addVelocity(0.35 * Math.signum(x - target.posX), 0.35 * Math.signum(y - target.posY), 0.35 * Math.signum(z - target.posZ));
|
||||
target.setPositionAndUpdate(x, y, z); // FIXME: This line must be causing the server rubberbanding, not sure why
|
||||
// Player motion is handled on that player's client so needs packets
|
||||
if(target instanceof EntityPlayerMP){
|
||||
((EntityPlayerMP)target).connection.sendPacket(new SPacketEntityVelocity(target));
|
||||
if(target.world.isRemote){
|
||||
target.world.playSound(target.posX, target.posY, target.posZ, WizardrySounds.ENTITY_FORCEFIELD_DEFLECT,
|
||||
WizardrySounds.SPELLS, 0.3f, 1f, false);
|
||||
}
|
||||
//
|
||||
// target.world.playSound(target.posX, target.posY, target.posZ, WizardrySounds.ENTITY_FORCEFIELD_DEFLECT,
|
||||
// WizardrySounds.SPELLS, 0.3f, 1f, false);
|
||||
|
||||
}
|
||||
|
||||
// Need to do this here because it's the only way to hook into potion ending both client- and server-side
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package electroblob.wizardry.potion;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.util.EntityUtils;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
@Mod.EventBusSubscriber
|
||||
public class PotionDiamondflesh extends PotionMagicEffect {
|
||||
|
||||
public PotionDiamondflesh(boolean isBadEffect, int liquidColour) {
|
||||
super(isBadEffect, liquidColour, new ResourceLocation(Wizardry.MODID, "textures/gui/potion_icons/diamondflesh.png"));
|
||||
// This needs to be here because registerPotionAttributeModifier doesn't like it if the potion has no name yet.
|
||||
this.setPotionName("potion." + Wizardry.MODID + ":ironflesh");
|
||||
this.registerPotionAttributeModifier(SharedMonsterAttributes.MOVEMENT_SPEED,
|
||||
"158a8af2-6db0-4340-a01c-a7b60d10ddf4", -0.1f, EntityUtils.Operations.MULTIPLY_CUMULATIVE);
|
||||
this.registerPotionAttributeModifier(SharedMonsterAttributes.ARMOR_TOUGHNESS,
|
||||
"a68d4532-5847-426c-9b03-d541b113cec2", 3.0f, EntityUtils.Operations.ADD);
|
||||
this.registerPotionAttributeModifier(SharedMonsterAttributes.ARMOR,
|
||||
"46a095be-82dd-43fd-8b67-13f51591eb8e", 4.0f, EntityUtils.Operations.ADD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady(int duration, int amplifier) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import electroblob.wizardry.constants.Constants;
|
||||
import electroblob.wizardry.registry.WizardryPotions;
|
||||
import electroblob.wizardry.util.ParticleBuilder;
|
||||
import electroblob.wizardry.util.ParticleBuilder.Type;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.world.World;
|
||||
@@ -50,4 +51,18 @@ public class PotionFrost extends PotionMagicEffect implements ICustomPotionParti
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performEffect(EntityLivingBase entitylivingbase, int strength) {
|
||||
if (entitylivingbase.isBurning()) {
|
||||
if (entitylivingbase.isPotionActive(WizardryPotions.frost)) {
|
||||
entitylivingbase.removePotionEffect(WizardryPotions.frost);
|
||||
entitylivingbase.extinguish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady(int duration, int amplifier) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package electroblob.wizardry.potion;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.util.EntityUtils;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
@Mod.EventBusSubscriber
|
||||
public class PotionIronflesh extends PotionMagicEffect {
|
||||
|
||||
public PotionIronflesh(boolean isBadEffect, int liquidColour) {
|
||||
super(isBadEffect, liquidColour, new ResourceLocation(Wizardry.MODID, "textures/gui/potion_icons/ironflesh.png"));
|
||||
// This needs to be here because registerPotionAttributeModifier doesn't like it if the potion has no name yet.
|
||||
this.setPotionName("potion." + Wizardry.MODID + ":ironflesh");
|
||||
this.registerPotionAttributeModifier(SharedMonsterAttributes.MOVEMENT_SPEED,
|
||||
"fe607d55-50e3-4f4f-a959-6571503f92f4", -0.1f, EntityUtils.Operations.MULTIPLY_CUMULATIVE);
|
||||
this.registerPotionAttributeModifier(SharedMonsterAttributes.KNOCKBACK_RESISTANCE,
|
||||
"6f78206e-8dd4-4d44-9792-d7a882111951", 0.3f, EntityUtils.Operations.ADD);
|
||||
this.registerPotionAttributeModifier(SharedMonsterAttributes.ARMOR,
|
||||
"e1adff1e-8510-4a09-96ed-ef677cad20c1", 4.0f, EntityUtils.Operations.ADD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady(int duration, int amplifier) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package electroblob.wizardry.potion;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.util.EntityUtils;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
@Mod.EventBusSubscriber
|
||||
public class PotionOakflesh extends PotionMagicEffect {
|
||||
|
||||
public PotionOakflesh(boolean isBadEffect, int liquidColour) {
|
||||
super(isBadEffect, liquidColour, new ResourceLocation(Wizardry.MODID, "textures/gui/potion_icons/oakflesh.png"));
|
||||
// This needs to be here because registerPotionAttributeModifier doesn't like it if the potion has no name yet.
|
||||
this.setPotionName("potion." + Wizardry.MODID + ":ironflesh");
|
||||
this.registerPotionAttributeModifier(SharedMonsterAttributes.MOVEMENT_SPEED,
|
||||
"98b4ba66-7c50-4a4c-9f3f-40bcb37313b5", -0.1f, EntityUtils.Operations.MULTIPLY_CUMULATIVE);
|
||||
this.registerPotionAttributeModifier(SharedMonsterAttributes.MAX_HEALTH,
|
||||
"ed9d0423-60f4-4998-bd8d-dc7c33bd45b8", 0.2f, EntityUtils.Operations.MULTIPLY_FLAT);
|
||||
this.registerPotionAttributeModifier(SharedMonsterAttributes.ARMOR,
|
||||
"0b607c3f-fb14-43d7-96b5-1c1b6f6da242", 3.0f, EntityUtils.Operations.ADD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady(int duration, int amplifier) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -359,7 +359,7 @@ public final class Spells {
|
||||
registry.register(new GreaterHeal());
|
||||
registry.register(new SpellConstruct<>("healing_aura", SpellActions.POINT_DOWN, EntityHealAura::new, false).addProperties(Spell.EFFECT_RADIUS, Spell.DAMAGE, Spell.HEALTH));
|
||||
registry.register(new Forcefield());
|
||||
registry.register(new SpellBuff("ironflesh", 0.4f, 0.5f, 0.6f, () -> MobEffects.RESISTANCE).soundValues(0.7f, 1.2f, 0.4f));
|
||||
registry.register(new SpellBuff("ironflesh", 0.4f, 0.5f, 0.6f, () -> WizardryPotions.ironflesh).soundValues(0.7f, 1.2f, 0.4f));
|
||||
registry.register(new Transience());
|
||||
|
||||
registry.register(new Meteor());
|
||||
@@ -378,9 +378,10 @@ public final class Spells {
|
||||
registry.register(new SpellMinion<>("silverfish_swarm", EntitySilverfishMinion::new).soundValues(1, 1.1f, 0.1f));
|
||||
registry.register(new SpellConstructRanged<>("black_hole", EntityBlackHole::new, false).addProperties(Spell.EFFECT_RADIUS).soundValues(2, 0.7f, 0));
|
||||
registry.register(new Shockwave());
|
||||
registry.register(new SummonIronGolem());
|
||||
registry.register(new SpellMinion<>("summon_iron_golem", EntitySpectralGolem::new).soundValues(1, 1.1f, 0.1f));
|
||||
|
||||
registry.register(new ArrowRain());
|
||||
registry.register(new SpellBuff("diamondflesh", 0.1f, 0.7f, 1, () -> MobEffects.RESISTANCE).soundValues(0.7f, 1.2f, 0.4f));
|
||||
registry.register(new SpellBuff("diamondflesh", 0.1f, 0.7f, 1, () -> WizardryPotions.diamondflesh).soundValues(0.7f, 1.2f, 0.4f));
|
||||
registry.register(new SpellBuff("font_of_vitality", 1, 0.8f, 0.3f, () -> MobEffects.ABSORPTION, () -> MobEffects.REGENERATION).soundValues(0.7f, 1.2f, 0.4f));
|
||||
|
||||
// Wizardry 1.1 spells
|
||||
@@ -398,7 +399,7 @@ public final class Spells {
|
||||
registry.register(new PocketWorkbench());
|
||||
registry.register(new ImbueWeapon());
|
||||
registry.register(new InvigoratingPresence());
|
||||
registry.register(new SpellBuff("oakflesh", 0.6f, 0.5f, 0.4f, () -> MobEffects.RESISTANCE).soundValues(0.7f, 1.2f, 0.4f));
|
||||
registry.register(new SpellBuff("oakflesh", 0.6f, 0.5f, 0.4f, () -> WizardryPotions.oakflesh).soundValues(0.7f, 1.2f, 0.4f));
|
||||
|
||||
registry.register(new SpellProjectile<>("greater_fireball", EntityLargeMagicFireball::new).addProperties(Spell.DAMAGE, EntityLargeMagicFireball.EXPLOSION_POWER));//new GreaterFireball());
|
||||
registry.register(new FlamingWeapon());
|
||||
|
||||
@@ -88,6 +88,7 @@ public class WizardryEntities {
|
||||
registry.register(createEntry(EntitySpiritHorse.class, "spirit_horse", TrackingType.LIVING).egg(0x5464c6, 0xbcc2e8).build());
|
||||
registry.register(createEntry(EntityPhoenix.class, "phoenix", TrackingType.LIVING).egg(0xff4900, 0xfde535).build());
|
||||
registry.register(createEntry(EntityIceGiant.class, "ice_giant", TrackingType.LIVING).egg(0x5bacd9, 0xeffaff).build());
|
||||
registry.register(createEntry(EntitySpectralGolem.class, "spectral_golem", TrackingType.LIVING).egg(0x5bacd9, 0xeffaff).build());
|
||||
|
||||
registry.register(createEntry(EntityMagicSlime.class, "magic_slime", TrackingType.LIVING).build());
|
||||
registry.register(createEntry(EntityDecoy.class, "decoy", TrackingType.LIVING).build());
|
||||
@@ -113,6 +114,7 @@ public class WizardryEntities {
|
||||
registry.register(createEntry(EntityDart.class, "dart", TrackingType.PROJECTILE).build());
|
||||
registry.register(createEntry(EntityIceLance.class, "ice_lance", TrackingType.PROJECTILE).build());
|
||||
registry.register(createEntry(EntityFlamecatcherArrow.class, "flamecatcher_arrow", TrackingType.PROJECTILE).build());
|
||||
registry.register(createEntry(EntityConjuredArrow.class, "conjured_arrow", TrackingType.PROJECTILE).build());
|
||||
|
||||
// Directionless projectiles
|
||||
registry.register(createEntry(EntityFirebomb.class, "firebomb", TrackingType.PROJECTILE).build());
|
||||
|
||||
@@ -6,7 +6,11 @@ import electroblob.wizardry.loot.RandomSpell;
|
||||
import electroblob.wizardry.loot.WizardSpell;
|
||||
import net.minecraft.entity.EnumCreatureType;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.world.storage.loot.*;
|
||||
import net.minecraft.world.storage.loot.LootEntry;
|
||||
import net.minecraft.world.storage.loot.LootEntryTable;
|
||||
import net.minecraft.world.storage.loot.LootPool;
|
||||
import net.minecraft.world.storage.loot.LootTableList;
|
||||
import net.minecraft.world.storage.loot.RandomValueRange;
|
||||
import net.minecraft.world.storage.loot.conditions.LootCondition;
|
||||
import net.minecraft.world.storage.loot.functions.LootFunctionManager;
|
||||
import net.minecraftforge.event.LootTableLoadEvent;
|
||||
@@ -90,23 +94,27 @@ public final class WizardryLoot {
|
||||
event.getTable().addPool(getAdditive(Wizardry.MODID + ":chests/jungle_dispenser_additions", Wizardry.MODID + "_additional_dispenser_loot"));
|
||||
}
|
||||
// Mob drops
|
||||
// Let's hope mods will play nice and store their entity loot tables under 'entities' or 'entity'
|
||||
// If not, packmakers will have to sort it out themselves using the whitelist/blacklist
|
||||
if(Arrays.asList(Wizardry.settings.mobLootTableWhitelist).contains(event.getName())){
|
||||
event.getTable().addPool(getAdditive(Wizardry.MODID + ":entities/mob_additions", Wizardry.MODID + "_additional_mob_drops"));
|
||||
|
||||
}else if(!Arrays.asList(Wizardry.settings.mobLootTableBlacklist).contains(event.getName())
|
||||
&& event.getName().getPath().contains("entities") || event.getName().getPath().contains("entity")){
|
||||
// Get the filename of the loot table json, for well-behaved mods this will be the entity name
|
||||
String[] split = event.getName().getPath().split("/");
|
||||
String entityName = split[split.length - 1];
|
||||
|
||||
EntityEntry entry = ForgeRegistries.ENTITIES.getValue(new ResourceLocation(entityName));
|
||||
if(entry == null) return; // If this is true it didn't work :(
|
||||
Class entityClass = entry.getEntityClass();
|
||||
|
||||
if(EnumCreatureType.MONSTER.getCreatureClass().isAssignableFrom(entityClass)){
|
||||
if (Wizardry.settings.injectMobDrops) {
|
||||
// Let's hope mods will play nice and store their entity loot tables under 'entities' or 'entity'
|
||||
// If not, packmakers will have to sort it out themselves using the whitelist/blacklist
|
||||
if (Arrays.asList(Wizardry.settings.mobLootTableWhitelist).contains(event.getName())) {
|
||||
event.getTable().addPool(getAdditive(Wizardry.MODID + ":entities/mob_additions", Wizardry.MODID + "_additional_mob_drops"));
|
||||
|
||||
} else if (!Arrays.asList(Wizardry.settings.mobLootTableBlacklist).contains(event.getName())
|
||||
&& event.getName().getPath().contains("entities") || event.getName().getPath().contains("entity")) {
|
||||
// Get the filename of the loot table json, for well-behaved mods this will be the entity name
|
||||
String[] split = event.getName().getPath().split("/");
|
||||
String entityName = split[split.length - 1];
|
||||
|
||||
EntityEntry entry = ForgeRegistries.ENTITIES.getValue(new ResourceLocation(entityName));
|
||||
if (entry == null) {
|
||||
return; // If this is true it didn't work :(
|
||||
}
|
||||
Class entityClass = entry.getEntityClass();
|
||||
|
||||
if (EnumCreatureType.MONSTER.getCreatureClass().isAssignableFrom(entityClass)) {
|
||||
event.getTable().addPool(getAdditive(Wizardry.MODID + ":entities/mob_additions", Wizardry.MODID + "_additional_mob_drops"));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fishing loot
|
||||
|
||||
@@ -57,6 +57,9 @@ public final class WizardryPotions {
|
||||
public static final Potion frost_step = placeholder();
|
||||
public static final Potion mark_of_sacrifice = placeholder();
|
||||
public static final Potion mirage = placeholder();
|
||||
public static final Potion oakflesh = placeholder();
|
||||
public static final Potion ironflesh = placeholder();
|
||||
public static final Potion diamondflesh = placeholder();
|
||||
|
||||
/**
|
||||
* Sets both the registry and unlocalised names of the given potion, then registers it with the given registry. Use
|
||||
@@ -201,6 +204,10 @@ public final class WizardryPotions {
|
||||
public void spawnCustomParticle(World world, double x, double y, double z){} // We only want the syncing
|
||||
}.setBeneficial());
|
||||
|
||||
registerPotion(registry, "oakflesh", new PotionOakflesh(false, 0).setBeneficial());
|
||||
registerPotion(registry, "ironflesh", new PotionIronflesh(false, 0).setBeneficial());
|
||||
registerPotion(registry, "diamondflesh", new PotionDiamondflesh(false, 0).setBeneficial());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -33,7 +33,7 @@ public class ConjureBlock extends SpellRay {
|
||||
@Override
|
||||
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, Vec3d hit, EntityLivingBase caster, Vec3d origin, int ticksInUse, SpellModifiers modifiers){
|
||||
|
||||
if(caster.isSneaking() && world.getBlockState(pos).getBlock() == WizardryBlocks.spectral_block){
|
||||
if(caster != null && caster.isSneaking() && world.getBlockState(pos).getBlock() == WizardryBlocks.spectral_block){
|
||||
|
||||
if(!world.isRemote){
|
||||
// Dispelling of blocks
|
||||
|
||||
@@ -53,7 +53,7 @@ public class CurseOfSoulbinding extends SpellRay {
|
||||
|
||||
@Override
|
||||
protected boolean onEntityHit(World world, Entity target, Vec3d hit, EntityLivingBase caster, Vec3d origin, int ticksInUse, SpellModifiers modifiers){
|
||||
|
||||
|
||||
if(EntityUtils.isLiving(target) && caster instanceof EntityPlayer){
|
||||
WizardData data = WizardData.get((EntityPlayer)caster);
|
||||
if(data != null){
|
||||
@@ -66,7 +66,7 @@ public class CurseOfSoulbinding extends SpellRay {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ public class CurseOfSoulbinding extends SpellRay {
|
||||
protected boolean onMiss(World world, EntityLivingBase caster, Vec3d origin, Vec3d direction, int ticksInUse, SpellModifiers modifiers){
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
|
||||
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).clr(0.4f, 0, 0).spawn(world);
|
||||
@@ -103,9 +103,9 @@ public class CurseOfSoulbinding extends SpellRay {
|
||||
|
||||
Entity entity = EntityUtils.getEntityByUUID(player.world, iterator.next());
|
||||
|
||||
if(entity == null) iterator.remove();
|
||||
|
||||
if(entity instanceof EntityLivingBase){
|
||||
if (entity == null || (entity instanceof EntityLivingBase && !((EntityLivingBase) entity).isPotionActive(WizardryPotions.curse_of_soulbinding))) {
|
||||
iterator.remove();
|
||||
} else if (entity instanceof EntityLivingBase) {
|
||||
// Retaliatory effect
|
||||
if(DamageSafetyChecker.attackEntitySafely(entity, MagicDamage.causeDirectMagicDamage(player,
|
||||
MagicDamage.DamageType.MAGIC, true), event.getAmount(), event.getSource().getDamageType(),
|
||||
|
||||
@@ -5,6 +5,7 @@ import electroblob.wizardry.constants.Constants;
|
||||
import electroblob.wizardry.entity.living.ISpellCaster;
|
||||
import electroblob.wizardry.event.SpellCastEvent;
|
||||
import electroblob.wizardry.item.SpellActions;
|
||||
import electroblob.wizardry.registry.Spells;
|
||||
import electroblob.wizardry.registry.WizardryItems;
|
||||
import electroblob.wizardry.registry.WizardryPotions;
|
||||
import electroblob.wizardry.util.ParticleBuilder;
|
||||
@@ -24,11 +25,14 @@ import javax.annotation.Nullable;
|
||||
@Mod.EventBusSubscriber
|
||||
public class EmpoweringPresence extends SpellAreaEffect {
|
||||
|
||||
/** The fraction by which potency is increased per level of the empowerment effect. */
|
||||
public static final String POTENCY_PER_LEVEL = "potency_per_level";
|
||||
|
||||
public EmpoweringPresence(){
|
||||
super("empowering_presence", SpellActions.POINT_UP, false);
|
||||
this.alwaysSucceed(true);
|
||||
this.targetAllies(true);
|
||||
addProperties(EFFECT_DURATION, EFFECT_STRENGTH);
|
||||
addProperties(EFFECT_DURATION, EFFECT_STRENGTH, POTENCY_PER_LEVEL);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -62,7 +66,7 @@ public class EmpoweringPresence extends SpellAreaEffect {
|
||||
if(event.getCaster() != null && event.getCaster().isPotionActive(WizardryPotions.empowerment)
|
||||
&& !(event.getSpell() instanceof EmpoweringPresence)){ // Prevent exponential empowerment stacking!
|
||||
|
||||
float potency = 1 + Constants.EMPOWERMENT_POTENCY_PER_LEVEL
|
||||
float potency = 1 + Spells.empowering_presence.getProperty(POTENCY_PER_LEVEL).floatValue()
|
||||
* (event.getCaster().getActivePotionEffect(WizardryPotions.empowerment).getAmplifier() + 1);
|
||||
|
||||
event.getModifiers().set(SpellModifiers.POTENCY,
|
||||
|
||||
@@ -59,18 +59,19 @@ public class FrostRay extends SpellRay {
|
||||
this.getNameForTranslationFormatted()), true);
|
||||
// This now only damages in line with the maxHurtResistantTime. Some mods don't play nicely and fiddle
|
||||
// with this mechanic for their own purposes, so this line makes sure that doesn't affect wizardry.
|
||||
}else if(ticksInUse % ((EntityLivingBase)target).maxHurtResistantTime == 1){
|
||||
}else{
|
||||
// For frost ray the entity can move slightly, unlike freeze
|
||||
((EntityLivingBase)target).addPotionEffect(new PotionEffect(WizardryPotions.frost,
|
||||
(int)(getProperty(EFFECT_DURATION).floatValue() * modifiers.get(WizardryItems.duration_upgrade)),
|
||||
getProperty(EFFECT_STRENGTH).intValue()));
|
||||
|
||||
float damage = getProperty(DAMAGE).floatValue() * modifiers.get(SpellModifiers.POTENCY);
|
||||
if(target instanceof EntityBlaze || target instanceof EntityMagmaCube) damage *= 2;
|
||||
|
||||
EntityUtils.attackEntityWithoutKnockback(target, MagicDamage.causeDirectMagicDamage(caster,
|
||||
DamageType.FROST), damage);
|
||||
if(ticksInUse % ((EntityLivingBase)target).maxHurtResistantTime == 1){
|
||||
float damage = getProperty(DAMAGE).floatValue() * modifiers.get(SpellModifiers.POTENCY);
|
||||
if(target instanceof EntityBlaze || target instanceof EntityMagmaCube) damage *= 2;
|
||||
|
||||
EntityUtils.attackEntityWithoutKnockback(target, MagicDamage.causeDirectMagicDamage(caster,
|
||||
DamageType.FROST), damage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import electroblob.wizardry.util.ParticleBuilder.Type;
|
||||
import electroblob.wizardry.util.SpellModifiers;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.SoundEvents;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
@@ -24,14 +25,14 @@ public class Glide extends Spell {
|
||||
|
||||
@Override
|
||||
protected void playSound(World world, EntityLivingBase entity, int ticksInUse, int duration, SpellModifiers modifiers, String... sounds){
|
||||
if(ticksInUse == 0 && world.isRemote) Wizardry.proxy.playSpellSoundLoop(entity, this, this.sounds[0], this.sounds[0], this.sounds[0],
|
||||
if(ticksInUse == 0 && world.isRemote) Wizardry.proxy.playSpellSoundLoop(entity, this, this.sounds[0], this.sounds[0], SoundEvents.UI_TOAST_OUT,
|
||||
WizardrySounds.SPELLS, volume, pitch + pitchVariation * (world.rand.nextFloat() - 0.5f));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void playSound(World world, double x, double y, double z, int ticksInUse, int duration, SpellModifiers modifiers, String... sounds){
|
||||
if(ticksInUse == 0 && world.isRemote){
|
||||
Wizardry.proxy.playSpellSoundLoop(world, x, y, z, this, this.sounds[0], this.sounds[0], this.sounds[0],
|
||||
Wizardry.proxy.playSpellSoundLoop(world, x, y, z, this, this.sounds[0], this.sounds[0], SoundEvents.UI_TOAST_OUT,
|
||||
WizardrySounds.SPELLS, volume, pitch + pitchVariation * (world.rand.nextFloat() - 0.5f), duration);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ public class MarkSacrifice extends SpellRay {
|
||||
PotionEffect effect = event.getEntityLiving().getActivePotionEffect(WizardryPotions.mark_of_sacrifice);
|
||||
|
||||
if(effect != null && event.getSource().isMagicDamage()){
|
||||
event.setAmount(event.getAmount() * (1 + effect.getAmplifier() * DAMAGE_INCREASE_PER_LEVEL));
|
||||
event.setAmount(event.getAmount() * (1 + (1 + effect.getAmplifier()) * DAMAGE_INCREASE_PER_LEVEL));
|
||||
event.getEntityLiving().removePotionEffect(WizardryPotions.mark_of_sacrifice);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,6 +111,9 @@ public class MindControl extends SpellRay {
|
||||
|
||||
/** Returns true if the given entity can be mind controlled (i.e. is not a player, npc, evil wizard or boss). */
|
||||
public static boolean canControl(Entity target){
|
||||
|
||||
// TODO: Add a max health limit that scales with potency
|
||||
|
||||
return target instanceof EntityLiving && target.isNonBoss() && !(target instanceof INpc)
|
||||
&& !(target instanceof EntityEvilWizard) && !Arrays.asList(Wizardry.settings.mindControlTargetsBlacklist)
|
||||
.contains(EntityList.getKey(target.getClass()));
|
||||
|
||||
@@ -30,9 +30,14 @@ public class Paralysis extends SpellRay {
|
||||
* will end. */
|
||||
private static final String CRITICAL_HEALTH = "critical_health";
|
||||
|
||||
/**
|
||||
* Multiplier for affecting players
|
||||
*/
|
||||
private static final String PLAYER_EFFECT_DURATION_MULTIPLIER = "player_effect_duration_multiplier";
|
||||
|
||||
public Paralysis(){
|
||||
super("paralysis", SpellActions.POINT, false);
|
||||
addProperties(DAMAGE, EFFECT_DURATION, CRITICAL_HEALTH);
|
||||
addProperties(DAMAGE, EFFECT_DURATION, CRITICAL_HEALTH, PLAYER_EFFECT_DURATION_MULTIPLIER);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -57,9 +62,10 @@ public class Paralysis extends SpellRay {
|
||||
target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK),
|
||||
getProperty(DAMAGE).floatValue() * modifiers.get(SpellModifiers.POTENCY));
|
||||
}
|
||||
|
||||
|
||||
float durationMultiplier = target instanceof EntityPlayer ? modifiers.get(PLAYER_EFFECT_DURATION_MULTIPLIER) : 1.0f;
|
||||
((EntityLivingBase)target).addPotionEffect(new PotionEffect(WizardryPotions.paralysis,
|
||||
(int)(getProperty(EFFECT_DURATION).floatValue() * modifiers.get(WizardryItems.duration_upgrade)), 0));
|
||||
(int)(getProperty(EFFECT_DURATION).floatValue() * durationMultiplier * modifiers.get(WizardryItems.duration_upgrade)), 0));
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package electroblob.wizardry.spell;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.data.WizardData;
|
||||
import electroblob.wizardry.event.ResurrectionEvent;
|
||||
import electroblob.wizardry.item.ISpellCastingItem;
|
||||
import electroblob.wizardry.item.SpellActions;
|
||||
import electroblob.wizardry.packet.PacketResurrection;
|
||||
@@ -8,6 +10,7 @@ import electroblob.wizardry.packet.WizardryPacketHandler;
|
||||
import electroblob.wizardry.registry.Spells;
|
||||
import electroblob.wizardry.registry.WizardryItems;
|
||||
import electroblob.wizardry.util.ParticleBuilder;
|
||||
import electroblob.wizardry.util.ParticleBuilder.Type;
|
||||
import electroblob.wizardry.util.SpellModifiers;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
@@ -16,11 +19,16 @@ import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
||||
@EventBusSubscriber
|
||||
public class Resurrection extends Spell {
|
||||
|
||||
public static final String WAIT_TIME = "wait_time";
|
||||
@@ -55,6 +63,9 @@ public class Resurrection extends Spell {
|
||||
.orElse(null);
|
||||
|
||||
if(nearestDeadAlly != null){
|
||||
|
||||
if(MinecraftForge.EVENT_BUS.post(new ResurrectionEvent(nearestDeadAlly, caster))) return false;
|
||||
|
||||
// When the player entity dies, it is removed from world#loadedEntityList. However, it is NOT removed
|
||||
// from playerEntityList (and probably a few other places) until respawn is clicked, and since that
|
||||
// never happens here we need to clean up those references or the player will have duplicate entries
|
||||
@@ -112,4 +123,42 @@ public class Resurrection extends Spell {
|
||||
&& ((ISpellCastingItem)stack.getItem()).canCast(stack, Spells.resurrection, player, EnumHand.MAIN_HAND, 0, new SpellModifiers());
|
||||
}
|
||||
|
||||
}
|
||||
@SubscribeEvent
|
||||
public static void onPlayerTickEvent(LivingUpdateEvent event){
|
||||
|
||||
if(event.getEntity() instanceof EntityPlayer){
|
||||
|
||||
EntityPlayer player = (EntityPlayer)event.getEntity();
|
||||
|
||||
if(player.world.isRemote && !player.isEntityAlive()){
|
||||
|
||||
EntityPlayer firstPersonPlayer = Wizardry.proxy.getThePlayer();
|
||||
|
||||
if(WizardData.get(firstPersonPlayer).isPlayerAlly(player)){
|
||||
|
||||
ItemStack wand = firstPersonPlayer.getHeldItemMainhand();
|
||||
|
||||
if(!(wand.getItem() instanceof ISpellCastingItem)){
|
||||
wand = firstPersonPlayer.getHeldItemOffhand();
|
||||
if(!(wand.getItem() instanceof ISpellCastingItem)) return;
|
||||
}
|
||||
|
||||
if(((ISpellCastingItem)wand.getItem()).getCurrentSpell(wand) == Spells.resurrection){
|
||||
|
||||
// TODO: Find some way of getting at the modifiers before the spell is cast
|
||||
int waitTime = Spells.resurrection.getProperty(WAIT_TIME).intValue();
|
||||
|
||||
if(player.deathTime > waitTime){
|
||||
ParticleBuilder.create(Type.SPARKLE, player.world.rand, player.posX, player.posY + 0.5, player.posZ, 0.5, false)
|
||||
.clr(1, 1, 0.3f).vel(0, 0.02, 0).spawn(player.world);
|
||||
}else{
|
||||
ParticleBuilder.create(Type.DUST, player.world.rand, player.posX, player.posY + 0.5, player.posZ, 0.5, false)
|
||||
.clr(1, 1, 0.3f).vel(0, 0.02, 0).time(50).spawn(player.world);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -189,7 +189,7 @@ public abstract class Spell extends IForgeRegistryEntry.Impl<Spell> implements C
|
||||
private static int nextSpellId = 0;
|
||||
/** The spell's integer ID, mainly used for networking. */
|
||||
// This was added after I learnt the hard way why you can't assume Forge's registry IDs are sequential...
|
||||
private final int id;
|
||||
private int id;
|
||||
|
||||
/**
|
||||
* This constructor should be called from any subclasses, either feeding in the constants directly or through their
|
||||
@@ -225,6 +225,7 @@ public abstract class Spell extends IForgeRegistryEntry.Impl<Spell> implements C
|
||||
this.icon = new ResourceLocation(modID, "textures/spells/" + name + ".png");
|
||||
this.sounds = createSounds();
|
||||
this.id = nextSpellId++;
|
||||
Wizardry.logger.debug("Registering spell " + this.unlocalisedName +" with networkID " + id);
|
||||
this.items(WizardryItems.spell_book, WizardryItems.scroll);
|
||||
this.npcSelector((e, o) -> false);
|
||||
}
|
||||
@@ -560,6 +561,11 @@ public abstract class Spell extends IForgeRegistryEntry.Impl<Spell> implements C
|
||||
return id;
|
||||
}
|
||||
|
||||
/** Sets the networkID of this spell. Do not call this or it will cause all packets to fail. */
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/** Returns the {@code ResourceLocation} for this spell's icon. */
|
||||
public final ResourceLocation getIcon(){
|
||||
return icon;
|
||||
|
||||
@@ -125,7 +125,8 @@ public class SpellBuff extends Spell {
|
||||
@Override
|
||||
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){
|
||||
// Wizards can only cast a buff spell if they don't already have its effects.
|
||||
if(caster.getActivePotionMap().keySet().containsAll(potionSet)) return false;
|
||||
// Some buff spells doesn't add any potion effects, those are ignored by this check
|
||||
if(!potionSet.isEmpty() && caster.getActivePotionMap().keySet().containsAll(potionSet)) return false;
|
||||
// Only return on the server side or the client probably won't spawn particles
|
||||
if(!this.applyEffects(caster, modifiers) && !world.isRemote) return false;
|
||||
if(world.isRemote) this.spawnParticles(world, caster, modifiers);
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
package electroblob.wizardry.spell;
|
||||
|
||||
import electroblob.wizardry.item.SpellActions;
|
||||
import electroblob.wizardry.util.BlockUtils;
|
||||
import electroblob.wizardry.util.ParticleBuilder;
|
||||
import electroblob.wizardry.util.ParticleBuilder.Type;
|
||||
import electroblob.wizardry.util.SpellModifiers;
|
||||
import net.minecraft.entity.monster.EntityIronGolem;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class SummonIronGolem extends Spell {
|
||||
|
||||
public SummonIronGolem(){
|
||||
super("summon_iron_golem", SpellActions.SUMMON, false);
|
||||
addProperties(SpellMinion.SUMMON_RADIUS);
|
||||
soundValues(1, 1.1f, 0.2f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
|
||||
|
||||
BlockPos pos = BlockUtils.findNearbyFloorSpace(caster, getProperty(SpellMinion.SUMMON_RADIUS).intValue(),
|
||||
getProperty(SpellMinion.SUMMON_RADIUS).intValue());
|
||||
|
||||
if(pos == null) return false;
|
||||
|
||||
if(!world.isRemote){
|
||||
|
||||
EntityIronGolem golem = new EntityIronGolem(world);
|
||||
golem.setPosition(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5);
|
||||
golem.setPlayerCreated(true);
|
||||
world.spawnEntity(golem);
|
||||
|
||||
}else{
|
||||
|
||||
for(int i=0; i<10; i++){
|
||||
double x = pos.getX() + world.rand.nextDouble() * 2 - 1;
|
||||
double y = pos.getY() + 0.5 + world.rand.nextDouble();
|
||||
double z = pos.getZ() + world.rand.nextDouble() * 2 - 1;
|
||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).clr(0.6f, 0.6f, 1).spawn(world);
|
||||
}
|
||||
}
|
||||
|
||||
this.playSound(world, caster, ticksInUse, -1, modifiers);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package electroblob.wizardry.tileentity;
|
||||
|
||||
import electroblob.wizardry.block.BlockReceptacle;
|
||||
import electroblob.wizardry.constants.Element;
|
||||
import electroblob.wizardry.event.ImbuementActivateEvent;
|
||||
import electroblob.wizardry.item.IManaStoringItem;
|
||||
import electroblob.wizardry.item.ItemWizardArmour;
|
||||
import electroblob.wizardry.registry.*;
|
||||
@@ -24,6 +25,7 @@ import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraft.world.storage.loot.LootContext;
|
||||
import net.minecraft.world.storage.loot.LootTable;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
@@ -233,6 +235,14 @@ public class TileEntityImbuementAltar extends TileEntity implements ITickable {
|
||||
*/
|
||||
public static ItemStack getImbuementResult(ItemStack input, Element[] receptacleElements, boolean fullLootGen, World world, EntityPlayer lastUser){
|
||||
|
||||
ItemStack eventResult = ItemStack.EMPTY;
|
||||
|
||||
if (world != null && MinecraftForge.EVENT_BUS.post(new ImbuementActivateEvent(input, receptacleElements, world, lastUser, eventResult))) {
|
||||
// return the stack if something changes the result from an empty stack.
|
||||
//noinspection ConstantConditions
|
||||
if (eventResult != ItemStack.EMPTY) return eventResult;
|
||||
}
|
||||
|
||||
if(input.getItem() instanceof ItemWizardArmour && ((ItemWizardArmour)input.getItem()).element == null){
|
||||
|
||||
if(Arrays.stream(receptacleElements).distinct().count() == 1 && receptacleElements[0] != null){ // All the same element
|
||||
|
||||
@@ -201,7 +201,7 @@ public final class AllyDesignationSystem {
|
||||
// Owned entities inherit their owner's allies
|
||||
if(allyOf instanceof IEntityOwnable){
|
||||
Entity owner = ((IEntityOwnable)allyOf).getOwner();
|
||||
if(owner instanceof EntityLivingBase && isAllied((EntityLivingBase)owner, possibleAlly)) return true;
|
||||
if(owner instanceof EntityLivingBase && (owner == possibleAlly || isAllied((EntityLivingBase)owner, possibleAlly))) return true;
|
||||
}
|
||||
|
||||
if(allyOf instanceof EntityPlayer && possibleAlly instanceof EntityPlayer
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package electroblob.wizardry.util;
|
||||
|
||||
import electroblob.wizardry.Settings;
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.entity.living.*;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.boss.EntityDragon;
|
||||
@@ -195,7 +197,7 @@ public class MagicDamage extends EntityDamageSource implements IElementalDamage
|
||||
* @return A damagesource object of type EntityDamageSource
|
||||
*/
|
||||
public static DamageSource causeDirectMagicDamage(Entity caster, DamageType type, boolean isRetaliatory){
|
||||
return new MagicDamage(DIRECT_MAGIC_DAMAGE, caster, type, isRetaliatory);
|
||||
return new MagicDamage(getDirectDamageNameForType(type), caster, type, isRetaliatory);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -241,7 +243,15 @@ public class MagicDamage extends EntityDamageSource implements IElementalDamage
|
||||
*/
|
||||
public static DamageSource causeIndirectMagicDamage(Entity magic, Entity caster, DamageType type,
|
||||
boolean isRetaliatory){
|
||||
return new IndirectMagicDamage(INDIRECT_MAGIC_DAMAGE, magic, caster, type, isRetaliatory);
|
||||
return new IndirectMagicDamage(getIndirectDamageNameForType(type), magic, caster, type, isRetaliatory);
|
||||
}
|
||||
|
||||
public static String getIndirectDamageNameForType(DamageType type) {
|
||||
return Wizardry.settings.damageTypePerElement ? type.name().toLowerCase() + "_" + INDIRECT_MAGIC_DAMAGE : INDIRECT_MAGIC_DAMAGE;
|
||||
}
|
||||
|
||||
public static String getDirectDamageNameForType(DamageType type) {
|
||||
return Wizardry.settings.damageTypePerElement ? type.name().toLowerCase() + "_" + DIRECT_MAGIC_DAMAGE : DIRECT_MAGIC_DAMAGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -34,7 +34,9 @@ import java.util.Random;
|
||||
* <code>ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(vx, vy, vz).clr(r, g, b).spawn(world);</code>
|
||||
* <p></p>
|
||||
* It also goes without saying that <b>this class should only ever be used client-side</b>. Attempting to spawn particles
|
||||
* on the server side will not work and will print a warning to the console.
|
||||
* on the server side will not work and will print a warning to the console. {@code ParticleBuilder} is not threadsafe
|
||||
* and attempting to call it from multiple threads at once will very likely cause an {@link IllegalStateException}.
|
||||
*
|
||||
* @author Electroblob
|
||||
* @since Wizardry 4.2
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package electroblob.wizardry.util;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import electroblob.wizardry.event.SpellCastEvent;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.item.Item;
|
||||
@@ -77,13 +78,11 @@ public final class SpellModifiers {
|
||||
* @return The SpellModifiers object, allowing this method to be chained onto the constructor.
|
||||
*/
|
||||
public SpellModifiers combine(SpellModifiers modifiers){
|
||||
for(Entry<String, Float> entry : multiplierMap.entrySet()){
|
||||
float newValue = entry.getValue() * modifiers.get(entry.getKey());
|
||||
entry.setValue(newValue);
|
||||
for(String key : Sets.union(this.multiplierMap.keySet(), modifiers.multiplierMap.keySet())){
|
||||
float newValue = this.get(key) * modifiers.get(key);
|
||||
// Also need to update the synced map if the modifier is synced in either object
|
||||
if(this.syncedMultiplierMap.containsKey(entry.getKey()) || modifiers.syncedMultiplierMap.containsKey(entry.getKey())){
|
||||
this.syncedMultiplierMap.put(entry.getKey(), newValue);
|
||||
}
|
||||
boolean sync = this.syncedMultiplierMap.containsKey(key) || modifiers.syncedMultiplierMap.containsKey(key);
|
||||
this.set(key, newValue, sync);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package electroblob.wizardry.util;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Helper class which ensures that all spellpack spell networkIDs are distributed in alphabetical order. Introducing this was necessary as mods (especially with
|
||||
* (load-after) dependencies were not always registering their spells in the exact same order. This is definitely
|
||||
*/
|
||||
public class SpellNetworkIDSorter {
|
||||
|
||||
public static void init() {
|
||||
|
||||
//reorder network IDs based on addon modids. This is necessary as modloading order doesn't seem to be guaranteed to match between various servers and clients
|
||||
Wizardry.logger.debug("Reordering all spell NetworkIDs based on addon modid alphabetical order");
|
||||
|
||||
// the first available ID after all default spells
|
||||
int nextSpellId = (int) Spell.getAllSpells().stream().filter(spell -> spell.getRegistryName().getNamespace().equals(Wizardry.MODID)).count() + 1;
|
||||
List<Spell> addonSpells = Spell.getAllSpells().stream().filter(spell -> !spell.getRegistryName().getNamespace().equals(Wizardry.MODID)).collect(Collectors.toList());
|
||||
|
||||
// sorting spells
|
||||
addonSpells.sort(Comparator.comparing((Spell o) -> o.getRegistryName().toString()));
|
||||
for (Spell spell : addonSpells) {
|
||||
Wizardry.logger.debug("Updating networkID of spell " + spell.getRegistryName().toString() + " from " + spell.networkID() + " to " + nextSpellId);
|
||||
spell.setId(nextSpellId++);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -251,6 +251,7 @@ public final class WandHelper {
|
||||
|
||||
for(int i = 0; i < cooldowns.length; i++){
|
||||
if(cooldowns[i] > 0) cooldowns[i]--;
|
||||
if(cooldowns[i] < 0) cooldowns[i] = 0; // In case it got broken
|
||||
}
|
||||
|
||||
setCooldowns(wand, cooldowns);
|
||||
@@ -312,6 +313,8 @@ public final class WandHelper {
|
||||
// cast, which is impossible if there are no spells.
|
||||
if(cooldowns.length <= selectedSpell) cooldowns = new int[spellCount];
|
||||
|
||||
if(cooldown <= 0) cooldown = 1;
|
||||
|
||||
cooldowns[selectedSpell] = cooldown;
|
||||
|
||||
setCooldowns(wand, cooldowns);
|
||||
|
||||
@@ -83,6 +83,7 @@ item.ebwizardry\:arcane_tome.desc=Upgrades any %1$s wand with sufficient progres
|
||||
item.ebwizardry\:wizard_handbook.name=The Wizard's Handbook
|
||||
item.ebwizardry\:wizard_handbook.author=by %1$s
|
||||
item.ebwizardry\:wizard_handbook.desc=Your not-so-pocket-sized guide to the arcane arts! A must-have for any aspiring wizard who seeks to learn the secrets of magic.\n\nRight-click while holding this book to read it.
|
||||
item.ebwizardry\:wizard_handbook.disabled=This item was disabled in the config!
|
||||
|
||||
item.ebwizardry\:wand.generic=wand
|
||||
|
||||
@@ -402,6 +403,10 @@ item.ebwizardry\:generic.disabled=This item has been disabled in the config
|
||||
item.ebwizardry\:ring.generic.desc=Equip this ring in the Baubles inventory or by placing it on your hotbar. Up to 2 rings may be equipped at once.
|
||||
item.ebwizardry\:amulet.generic.desc=Equip this amulet in the Baubles inventory or by placing it on your hotbar. Only one amulet may be equipped at a time.
|
||||
item.ebwizardry\:charm.generic.desc=Equip this charm in the Baubles inventory or by placing it on your hotbar. Only one charm may be equipped at a time.
|
||||
item.ebwizardry\:belt.generic.desc=Equip this belt in the Baubles inventory or by placing it on your hotbar. Only one belt may be equipped at a time.
|
||||
item.ebwizardry\:body.generic.desc=Equip this body item in the Baubles inventory or by placing it on your hotbar. Only one body item may be equipped at a time.
|
||||
item.ebwizardry\:trinket.generic.desc=Equip this trinket in the Baubles inventory or by placing it on your hotbar. Only one trinklet may be equipped at a time.
|
||||
item.ebwizardry\:head.generic.desc=Equip this headgear in the Baubles inventory or by placing it on your hotbar. Only one headgear may be equipped at a time.
|
||||
|
||||
item.ebwizardry\:ring_condensing.name=Ring of Condensing
|
||||
item.ebwizardry\:ring_condensing.desc=Slowly regenerates mana for all wands on your hotbar
|
||||
@@ -438,7 +443,7 @@ item.ebwizardry\:ring_hammer.desc=Lightning hammers can be picked up and thrown
|
||||
item.ebwizardry\:ring_stormcloud.name=Lokenzen's Ring
|
||||
item.ebwizardry\:ring_stormcloud.desc=Stormcloud moves towards targets and lasts longer with every strike
|
||||
item.ebwizardry\:ring_soulbinding.name=Soulwalker's Ring
|
||||
item.ebwizardry\:ring_soulbinding.desc=Creatures damaged by necromancy spells become soulbound to you
|
||||
item.ebwizardry\:ring_soulbinding.desc=Creatures damaged by necromancy spells become soulbound to you for 20 seconds
|
||||
item.ebwizardry\:ring_leeching.name=Ring of Leeching
|
||||
item.ebwizardry\:ring_leeching.desc=All necromancy attacks have a 30%% chance to trigger a life drain effect
|
||||
item.ebwizardry\:ring_necromancy_melee.name=Ring of Necrotic Touch
|
||||
@@ -732,6 +737,7 @@ entity.ebwizardry\:evil_wizard.name=Wizard
|
||||
entity.ebwizardry\:decoy.name=Decoy
|
||||
entity.ebwizardry\:vex_minion.name=Vex
|
||||
entity.ebwizardry\:remnant.name=Remnant
|
||||
entity.ebwizardry\:spectral_golem.name=Spectral Golem
|
||||
|
||||
entity.ebwizardry\:magic_missile.name=Magic
|
||||
entity.ebwizardry\:arc.name=Magic
|
||||
@@ -758,6 +764,7 @@ entity.ebwizardry\:smoke_bomb.name=Magic
|
||||
entity.ebwizardry\:ice_spike.name=Magic
|
||||
entity.ebwizardry\:combustion_rune.name=Magic
|
||||
entity.ebwizardry\:flamecatcher_arrow.name=Magic
|
||||
entity.ebwizardry\:conjured_arrow.name=Magic
|
||||
|
||||
entity.ebwizardry\:black_hole.name=Black Hole
|
||||
entity.ebwizardry\:shield.name=Shield
|
||||
@@ -875,6 +882,7 @@ container.ebwizardry\:arcane_workbench.sort_tier=Sort by Tier
|
||||
container.ebwizardry\:arcane_workbench.sort_element=Sort by Element
|
||||
container.ebwizardry\:arcane_workbench.sort_alphabetical=Sort Alphabetically
|
||||
container.ebwizardry\:arcane_workbench.search_tooltip=%1$sSearch Tips\n\ntier=%2$s, %1$st=%2$s: match tiers\n%1$selement=%2$s, %1$se=%2$s: match elements\n%1$stype=%2$s, %1$sp=%2$s: match spell types\n%1$sdiscovered=true/false%2$s, %1$sd=t/f%2$s: include only (un)discovered\n%1$smodid=%2$s, %1$sm=%2$s: match mod IDs\n\nSeparate multiple values with %1$s,%2$s\nSeparate multiple criteria with %1$s;
|
||||
container.ebwizardry\:arcane_workbench.clear=Clear Spell Slots
|
||||
|
||||
container.ebwizardry\:bookshelf=Bookshelf
|
||||
|
||||
@@ -1075,7 +1083,7 @@ spell.ebwizardry\:stormcloud=Stormcloud
|
||||
spell.ebwizardry\:summon_blaze=Summon Blaze
|
||||
spell.ebwizardry\:summon_ice_giant=Summon Ice Giant
|
||||
spell.ebwizardry\:summon_ice_wraith=Summon Ice Wraith
|
||||
spell.ebwizardry\:summon_iron_golem=Summon Iron Golem
|
||||
spell.ebwizardry\:summon_iron_golem=Summon Spectral Golem
|
||||
spell.ebwizardry\:summon_lightning_wraith=Summon Lightning Wraith
|
||||
spell.ebwizardry\:summon_phoenix=Summon Phoenix
|
||||
spell.ebwizardry\:summon_shadow_wraith=Summon Shadow Wraith
|
||||
@@ -1203,7 +1211,7 @@ spell.ebwizardry\:intimidate.desc=Emits an intimidating growl which causes nearb
|
||||
spell.ebwizardry\:invigorating_presence.desc=Grants the caster and all nearby allies increased strength for 45 seconds.
|
||||
spell.ebwizardry\:invisibility.desc=Makes the caster invisible for 30 seconds.
|
||||
spell.ebwizardry\:invoke_weather.desc=Changes the weather in the world.
|
||||
spell.ebwizardry\:ironflesh.desc=Greatly improves the caster's damage resistance for 30 seconds.
|
||||
spell.ebwizardry\:ironflesh.desc=Greatly improves the caster's armor and knockback resistance for 30 seconds.
|
||||
spell.ebwizardry\:leap.desc=Causes the caster to jump upwards several blocks and slightly forward.
|
||||
spell.ebwizardry\:levitation.desc=Raises the caster upwards while the use item button is held. Will also negate fall damage if used before hitting the ground.
|
||||
spell.ebwizardry\:life_drain.desc=Creates a stream of withering energy in the direction you are pointing which drains the life of the target and uses it to gradually regenerate your health.
|
||||
@@ -1226,7 +1234,7 @@ spell.ebwizardry\:mine.desc=Breaks the block the caster is looking at. Potency w
|
||||
spell.ebwizardry\:mirage.desc=Creates an illusion where the caster appears to be a few blocks away from their actual position, blinking around every few seconds. The illusion lasts for 20 seconds.
|
||||
spell.ebwizardry\:muffle.desc=Silences any sounds made by the caster for 30 seconds. When muffled, mobs can only detect you when looking towards you.
|
||||
spell.ebwizardry\:none.desc=To get a spell book with the /give command, use id\: /give [player] ebwizardry\:spell_book 1 [spell id] (if you found this book in a chest, some other mod has messed things up).
|
||||
spell.ebwizardry\:oakflesh.desc=Improves the caster's damage resistance for 30 seconds.
|
||||
spell.ebwizardry\:oakflesh.desc=Slightly improves the caster's vitality and damage resistance for 30 seconds.
|
||||
spell.ebwizardry\:paralysis.desc=Delivers a powerful lightning bolt that paralyses targets for 5 seconds. Paralysed creatures cannot move and will still take damage - but too much will snap the creature out of paralysis.
|
||||
spell.ebwizardry\:permafrost.desc=Spreads a layer of slippery ice on the ground where you are pointing, the extreme cold of which causes creatures to slowly take damage.
|
||||
spell.ebwizardry\:petrify.desc=Turns the target to stone until broken out, with a chance for it to break out when it is dark. The target cannot move or do anything while petrified but is also impervious to all damage.
|
||||
@@ -1363,6 +1371,7 @@ forfeit.ebwizardry\:bury_self=The ground collapses beneath you!
|
||||
|
||||
forfeit.ebwizardry\:spill_inventory=Your items spill themselves everywhere!
|
||||
forfeit.ebwizardry\:teleport_self=You are instantly teleported somewhere!
|
||||
forfeit.ebwizardry\:teleport_self_large_distance=You are instantly teleported somewhere far away!
|
||||
forfeit.ebwizardry\:levitate_self=You begin to float upwards helplessly!
|
||||
forfeit.ebwizardry\:vex_horde=A horde of vexes materializes around you!
|
||||
forfeit.ebwizardry\:black_hole=A swirling vortex appears in front of you!
|
||||
@@ -1400,6 +1409,9 @@ potion.ebwizardry\:containment=Containment
|
||||
potion.ebwizardry\:frost_step=Frost Step
|
||||
potion.ebwizardry\:mark_of_sacrifice=Mark of Sacrifice
|
||||
potion.ebwizardry\:mirage=Mirage
|
||||
potion.ebwizardry\:oakflesh=Oakflesh
|
||||
potion.ebwizardry\:ironflesh=Ironflesh
|
||||
potion.ebwizardry\:diamondflesh=Diamondflesh
|
||||
|
||||
enchantment.ebwizardry\:magic_sword=Imbuement
|
||||
enchantment.ebwizardry\:magic_bow=Imbuement
|
||||
@@ -1436,6 +1448,25 @@ key.ebwizardry.spell_8=Spell Slot 8
|
||||
|
||||
death.attack.wizardry_magic=%1$s was killed by %2$s using magic
|
||||
death.attack.indirect_wizardry_magic=%1$s was killed by %2$s using magic
|
||||
death.attack.magic_wizardry_magic=%1$s was killed by %2$s using magic
|
||||
death.attack.magic_indirect_wizardry_magic=%1$s was killed by %2$s using magic
|
||||
|
||||
death.attack.fire_wizardry_magic=%1$s was killed by %2$s using fire magic
|
||||
death.attack.fire_indirect_wizardry_magic=%1$s was killed by %2$s using fire magic
|
||||
death.attack.frost_wizardry_magic=%1$s was killed by %2$s using frost magic
|
||||
death.attack.frost_indirect_wizardry_magic=%1$s was killed by %2$s using frost magic
|
||||
death.attack.shock_wizardry_magic=%1$s was killed by %2$s using a shock magic
|
||||
death.attack.shock_indirect_wizardry_magic=%1$s was killed by %2$s using shock magic
|
||||
death.attack.wither_wizardry_magic=%1$s was killed by %2$s using withering magic
|
||||
death.attack.wither_indirect_wizardry_magic=%1$s was killed by %2$s withering magic
|
||||
death.attack.poison_wizardry_magic=%1$s was killed by %2$s using poison magic
|
||||
death.attack.poison_indirect_wizardry_magic=%1$s was killed by %2$s poison magic
|
||||
death.attack.force_wizardry_magic=%1$s was killed by %2$s using a magical force
|
||||
death.attack.force_indirect_wizardry_magic=%1$s was killed by %2$s using magical force
|
||||
death.attack.blast_wizardry_magic=%1$s was killed by %2$s using a magical blast
|
||||
death.attack.blast_indirect_wizardry_magic=%1$s was killed by %2$s using magical blast
|
||||
death.attack.radiant_wizardry_magic=%1$s was killed by %2$s using radiant magic
|
||||
death.attack.radiant_indirect_wizardry_magic=%1$s was killed by %2$s using radiant magic
|
||||
|
||||
soundCategory.ebwizardry_spells=Spells
|
||||
|
||||
@@ -1504,6 +1535,12 @@ config.ebwizardry.player_block_damage.true=Yes - kaboom!
|
||||
config.ebwizardry.player_block_damage.false=No - activate anti-grief (TM)
|
||||
config.ebwizardry.dispenser_block_damage=Dispenser Block Damage
|
||||
config.ebwizardry.dispenser_block_damage.tooltip=Whether spells cast by dispensers can destroy blocks in the world. Wizardry makes every attempt to respect protection mods and plugins, but cannot guarantee it will work in all cases for every mod. If you need absolutely watertight anti-grief, disable this setting.
|
||||
config.ebwizardry.damage_type_per_element=Damage Type Per Element
|
||||
config.ebwizardry.damage_type_per_element.tooltip=Whether damage should be registered with the old system (wizardry_magic/indirect_wizardry_magic) prefixed damage with the elements like necromancy_indirect_wizardry_magic, necromancy_wizardry_magic. This is disabled by default to not break existing modpacks. The intention of this setting is to allow differentiating various damage types for e.g. the Distinct Damage Descriptions mod
|
||||
config.ebwizardry.single_use_spell_books=Spell Books Are Consumed By Wands
|
||||
config.ebwizardry.single_use_spell_books.tooltip=Whether spell books are consumed when they are bound to a wand.
|
||||
config.ebwizardry.prevent_binding_same_spell_twice_to_wands=Prevent Binding The Same Spell To A Wand Multiple Times
|
||||
config.ebwizardry.prevent_binding_same_spell_twice_to_wands.tooltip=Whether to prevent binding the same spell to a wand multiple times
|
||||
config.ebwizardry.telekinetic_disarmament=Telekinetic Disarmament
|
||||
config.ebwizardry.telekinetic_disarmament.tooltip=Whether to allow players to disarm other players using the telekinesis spell. Disable to prevent stealing of items.
|
||||
config.ebwizardry.telekinetic_disarmament.true=Yes - let people steal things
|
||||
@@ -1524,6 +1561,20 @@ config.ebwizardry.slow_time_affects_players=Slow Time Affects Players
|
||||
config.ebwizardry.slow_time_affects_players.tooltip=Whether players are slowed when another nearby player uses the slow time spell. If this is disabled, mobs and projectiles will still be affected but players will move at normal speed.
|
||||
config.ebwizardry.bonemeal_grows_crystal_flowers=Bonemeal Grows Crystal Flowers
|
||||
config.ebwizardry.bonemeal_grows_crystal_flowers.tooltip=Whether using bonemeal on grass blocks has a chance to grow crystal flowers.
|
||||
config.ebwizardry.wands_must_be_held_to_decrement_cooldown=Wands Must Be Held To Decrement Cooldown
|
||||
config.ebwizardry.wands_must_be_held_to_decrement_cooldown.tooltip=Whether wands only decrement their cooldowns if a player holds them.
|
||||
config.ebwizardry.cooldown_reduction_per_level=Cooldown Reduction Per Level
|
||||
config.ebwizardry.cooldown_reduction_per_level.tooltip=The fraction by which cooldowns are reduced for each level of cooldown upgrade.
|
||||
config.ebwizardry.potency_increase_per_tier=Potency Increase Per Tier
|
||||
config.ebwizardry.potency_increase_per_tier.tooltip=The fraction by which potency is increased for each tier of matching wand. May cause extreme lag with high values!
|
||||
config.ebwizardry.duration_increase_per_level=Duration Increase Per Level
|
||||
config.ebwizardry.duration_increase_per_level.tooltip=The fraction by which spell duration is increased for each level of duration upgrade.
|
||||
config.ebwizardry.range_increase_per_level=Range Increase Per Level
|
||||
config.ebwizardry.range_increase_per_level.tooltip=The fraction by which spell range is increased for each level of range upgrade. May cause extreme lag with high values!
|
||||
config.ebwizardry.blast_increase_per_level=Blast Increase Per Level
|
||||
config.ebwizardry.blast_increase_per_level.tooltip=The fraction by which spell blast is increased for each level of blast upgrade. May cause extreme lag with high values!
|
||||
config.ebwizardry.frost_slowness_increase_per_level=Frost Slowness Increase Per Level
|
||||
config.ebwizardry.frost_slowness_increase_per_level.tooltip=The fraction by which movement speed is reduced per level of frost effect.
|
||||
|
||||
config.ebwizardry.category.difficulty=Difficulty Settings
|
||||
config.ebwizardry.category.difficulty.tooltip=Configure wizardry's difficulty
|
||||
@@ -1580,6 +1631,8 @@ config.ebwizardry.mob_loot_table_whitelist=Mob Loot Table Whitelist
|
||||
config.ebwizardry.mob_loot_table_whitelist.tooltip=Whitelist for loot tables to inject additional mob drops (as specified in loot_tables/entities/mob_additions.json) into. Wizardry makes a best guess as to which loot tables belong to hostile mobs, but this may not always be correct or appropriate; add loot table locations (not entity IDs) to this list to manually include them.
|
||||
config.ebwizardry.mob_loot_table_blacklist=Mob Loot Table Blacklist
|
||||
config.ebwizardry.mob_loot_table_blacklist.tooltip=Blacklist for loot tables to inject additional mob drops (as specified in loot_tables/entities/mob_additions.json) into. Wizardry makes a best guess as to which loot tables belong to hostile mobs, but this may not always be correct or appropriate; add loot table locations (not entity IDs) to this list to manually exclude them.
|
||||
config.ebwizardry.inject_mob_drops=Allow Wizardry Mob Loot
|
||||
config.ebwizardry.inject_mob_drops.tooltip=Whether to inject Wizardry loot to mobs, based on the loot table 'Mob Loot Table Whitelist' / 'Mob Loot Table Blacklist' settings. If disabled, the lists won't have any effect!
|
||||
config.ebwizardry.mob_spawn_dimensions=Mob Spawning Dimensions
|
||||
config.ebwizardry.mob_spawn_dimensions.tooltip=List of ids of dimensions in which wizardry's hostile mobs can spawn.
|
||||
config.ebwizardry.mob_spawn_biome_blacklist=Mob Spawning Biome Blacklist
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -53,21 +53,21 @@ tile.ebwizardry\:receptacle.name=받침
|
||||
tile.ebwizardry\:imbuement_altar.name=고취의 제단
|
||||
|
||||
item.ebwizardry\:crystal_magic.name=마법수정
|
||||
item.ebwizardry\:crystal_magic.desc=무지갯빛의 아름다운 수정, 마법의 기운이 내부에서 서서히 변화하고 소용돌이치고 있다. 어쩌면 이 수정은 사용하면...
|
||||
item.ebwizardry\:crystal_magic.desc=무지갯빛의 아름다운 수정, 마법의 기운이 내부에서 서서히 변화하며 소용돌이치고 있습니다. 어쩌면 이 수정은 사용하면...
|
||||
item.ebwizardry\:crystal_fire.name=화염의 수정
|
||||
item.ebwizardry\:crystal_fire.desc=주황빛으로 불타는 수정. 어쩌면 불의 원소를 푸는 열쇠일지도 모른다...
|
||||
item.ebwizardry\:crystal_fire.desc=주황빛으로 불타는 수정, 어쩌면 불의 원소를 푸는 열쇠일지도 모릅니다...
|
||||
item.ebwizardry\:crystal_ice.name=얼음의 수정
|
||||
item.ebwizardry\:crystal_ice.desc=푸르스름한 색조의 차가운 수정. 어쩌면 서리의 힘의 비밀을 간직하고 있을지도 모른다...
|
||||
item.ebwizardry\:crystal_ice.desc=푸르스름한 색조의 차가운 수정, 어쩌면 서리의 힘의 비밀을 간직하고 있을지도 모릅니다...
|
||||
item.ebwizardry\:crystal_lightning.name=폭풍의 수정
|
||||
item.ebwizardry\:crystal_lightning.desc=어지럽게 소용돌이치고 번쩍이는 수정. 어쩌면 더 큰 힘을 숨기고 있을지도 모른다...
|
||||
item.ebwizardry\:crystal_lightning.desc=어지럽게 소용돌이치고 번쩍이는 수정, 어쩌면 더 큰 힘을 숨기고 있을지도 모릅니다...
|
||||
item.ebwizardry\:crystal_necromancy.name=어둠의 수정
|
||||
item.ebwizardry\:crystal_necromancy.desc=마치 끌어당기는 듯한 깊고 푸르스름한 수정. 어쩌면 더 어두운 곳으로 가는 관문일지도 모른다...
|
||||
item.ebwizardry\:crystal_necromancy.desc=마치 끌어당기는 듯한 깊고 푸르스름한 수정, 어쩌면 더 어두운 곳으로 가는 관문일지도 모릅니다...
|
||||
item.ebwizardry\:crystal_earth.name=신록의 수정
|
||||
item.ebwizardry\:crystal_earth.desc=녹색과 약간의 갈색으로 이루어진 수정. 어쩌면 자연의 힘과 연관이 있을지도 모른다...
|
||||
item.ebwizardry\:crystal_earth.desc=녹색과 약간의 갈색으로 이루어진 수정, 어쩌면 자연의 힘과 연관이 있을지도 모릅니다...
|
||||
item.ebwizardry\:crystal_sorcery.name=신령의 수정
|
||||
item.ebwizardry\:crystal_sorcery.desc=푸르스름한 초록빛의 반짝거리는 수정. 어쩌면 고대의 힘의 비밀을 감추고 있을지도 모른다...
|
||||
item.ebwizardry\:crystal_sorcery.desc=푸르스름한 초록빛의 반짝거리는 수정, 어쩌면 고대의 힘의 비밀을 감추고 있을지도 모릅니다...
|
||||
item.ebwizardry\:crystal_healing.name=복사의 수정
|
||||
item.ebwizardry\:crystal_healing.desc=금빛 햇살처럼 노랗게 반짝이는 수정. 어쩌면 신성한 힘의 연결고리일지도 모른다...
|
||||
item.ebwizardry\:crystal_healing.desc=금빛 햇살처럼 노랗게 반짝이는 수정, 어쩌면 신성한 힘의 연결고리일지도 모릅니다...
|
||||
|
||||
item.ebwizardry\:spell_book.name=주문서
|
||||
item.ebwizardry\:spell_book.desc=고대의 상형문자와 룬 문자로 채워진 책. 노력을 통해 그 내용을 해독할 수 있을 것 같습니다...\n\n책을 읽으려면 오른쪽 버튼을 누르세요.
|
||||
@@ -75,7 +75,7 @@ item.ebwizardry\:spell_book.new=아직 발견되지 않았습니다!
|
||||
item.ebwizardry\:spell_book.apply_to_wizard=%1$s의 주문 %2$s을 %3$s로 대체하였습니다
|
||||
|
||||
item.ebwizardry\:ruined_spell_book.name=빛바랜 주문서
|
||||
item.ebwizardry\:ruined_spell_book.desc=이 너덜너덜한 주문서는 너무 손상되어 제대로 읽혀지지 않지만, 어찌된 일인지, 아직도 마법의 기운이 남아있다. 만약 복원될 수만 있다면...
|
||||
item.ebwizardry\:ruined_spell_book.desc=이 너덜너덜한 주문서는 너무 손상되어 제대로 읽혀지지 않지만, 어찌된 일인지, 아직도 마법의 기운이 남아있습니다. 만약 복원될 수만 있다면...
|
||||
|
||||
item.ebwizardry\:arcane_tome.name=마도서
|
||||
item.ebwizardry\:arcane_tome.desc=아무 %1$s지팡이를 %2$s지팡이로 강화합니다
|
||||
@@ -112,7 +112,7 @@ item.ebwizardry\:novice_healing_wand.name=회복 지팡이
|
||||
item.ebwizardry\:apprentice_fire_wand.name=견습 화염 지팡이
|
||||
item.ebwizardry\:apprentice_ice_wand.name=견습 얼음 지팡이
|
||||
item.ebwizardry\:apprentice_lightning_wand.name=견습 벼락 지팡이
|
||||
item.ebwizardry\:apprentice_necromancy_wand.name=견습 혼령 지팡이
|
||||
item.ebwizardry\:apprentice_necromancy_wand.name=견습 사령 지팡이
|
||||
item.ebwizardry\:apprentice_earth_wand.name=견습 대지 지팡이
|
||||
item.ebwizardry\:apprentice_sorcery_wand.name=견습 신비 지팡이
|
||||
item.ebwizardry\:apprentice_healing_wand.name=견습 치유 지팡이
|
||||
@@ -120,7 +120,7 @@ item.ebwizardry\:apprentice_healing_wand.name=견습 치유 지팡이
|
||||
item.ebwizardry\:advanced_fire_wand.name=숙련 화염술사의 지팡이
|
||||
item.ebwizardry\:advanced_ice_wand.name=숙련 얼음법사의 지팡이
|
||||
item.ebwizardry\:advanced_lightning_wand.name=숙련 벼락술사의 지팡이
|
||||
item.ebwizardry\:advanced_necromancy_wand.name=숙련 혼령술사의 지팡이
|
||||
item.ebwizardry\:advanced_necromancy_wand.name=숙련 사령술사의 지팡이
|
||||
item.ebwizardry\:advanced_earth_wand.name=숙련 대지법사의 지팡이
|
||||
item.ebwizardry\:advanced_sorcery_wand.name=숙련 신비술사의 지팡이
|
||||
item.ebwizardry\:advanced_healing_wand.name=숙련 치유사의 지팡이
|
||||
@@ -146,16 +146,16 @@ item.ebwizardry\:large_mana_flask.name=큰 마나병
|
||||
item.ebwizardry\:mana_flask.desc=제작을 통해 %s마나를 지팡이나 갑옷에 충전합니다
|
||||
|
||||
item.ebwizardry\:grand_crystal.name=거대한 마법수정
|
||||
item.ebwizardry\:grand_crystal.desc=자연적으로 발견된 것의 몇 배 크기인 거대한 마법의 수정. 누군가 인공적으로 만든 게 틀림없다. 하지만 어떻게?
|
||||
item.ebwizardry\:grand_crystal.desc=자연적으로 발견된 것의 몇 배 크기인 거대한 마법의 수정, 누군가 인공적으로 만든 게 틀림없습니다. 하지만 어떻게?
|
||||
item.ebwizardry\:crystal_shard.name=마법수정 조각
|
||||
item.ebwizardry\:crystal_shard.desc=산산조각난 마법 수정의 작은 조각. 그 자체로는 마력이 거의 없지만, 다른 용도가 있을지도 모른다...
|
||||
item.ebwizardry\:crystal_shard.desc=산산조각난 마법 수정의 작은 조각, 그 자체로는 마력이 거의 없지만, 다른 용도가 있을지도 모릅니다...
|
||||
|
||||
item.ebwizardry\:astral_diamond.name=별의 다이아몬드
|
||||
item.ebwizardry\:astral_diamond.desc=별빛 아래 밝게 빛나는 아름다운 보석. 어떠한 마법사들은 강력한 마법의 거래 대가로 별의 다이아몬드를 찾는다네.
|
||||
item.ebwizardry\:astral_diamond.desc=별빛 아래 밝게 빛나는 아름다운 보석이라네. 어떠한 마법사들은 강력한 마법의 거래 대가로 별의 다이아몬드를 찾는다네.
|
||||
|
||||
item.ebwizardry\:purifying_elixir.name=정화의 영약
|
||||
item.ebwizardry\:purifying_elixir.desc=저주를 제거합니다
|
||||
item.ebwizardry\:purifying_elixir.desc_extended=특이한 금빛 액체가 담긴 작은 병으로, 강력한 회복의 특성을 보이고 있습니다.
|
||||
item.ebwizardry\:purifying_elixir.desc_extended=특이한 금빛 액체가 담긴 작은 병으로, 강력한 회복력을 보이고 있습니다.
|
||||
|
||||
item.ebwizardry\:storage_upgrade.name=지팡이 용량 강화
|
||||
item.ebwizardry\:siphon_upgrade.name=지팡이 흡수 강화
|
||||
@@ -194,24 +194,38 @@ item.ebwizardry\:blank_scroll.name=빈 두루마리
|
||||
item.ebwizardry\:scroll.generic=두루마리
|
||||
item.ebwizardry\:scroll.name=%1$s의 두루마리
|
||||
item.ebwizardry\:scroll.undiscovered.name="%1$s"두루마리
|
||||
item.ebwizardry\:scroll.desc=끈으로 느슨하게 묶인 마법이 부여된 종이. 두루마리에 부여된 주문을 외우면 외운 주문이 시전된다 .\n시전하려면 오른쪽 버튼을 누르세요.
|
||||
item.ebwizardry\:scroll.desc=끈으로 느슨하게 묶인 마법이 부여된 종이. 두루마리에 부여된 주문을 외우면 외운 주문이 시전됩니다.\n시전하려면 오른쪽 버튼을 누르세요.
|
||||
item.ebwizardry\:identification_scroll.name=지식의 두루마리
|
||||
item.ebwizardry\:identification_scroll.desc=알 수 없는 주문서나 두루마리를 식별합니다
|
||||
item.ebwizardry\:identification_scroll.desc_extended=오른쪽 버튼을 클릭하여 식별하지 않은 주문서를 식별할 수 있습니다.
|
||||
item.ebwizardry\:identification_scroll.nothing_to_identify=식별할 주문이 없습니다!
|
||||
|
||||
item.ebwizardry\:armour_upgrade.name=신비로운 보호의 문양
|
||||
item.ebwizardry\:armour_upgrade.desc=아무 마법사의 갑옷을 전설등급으로 만듭니다
|
||||
item.ebwizardry\:armour_upgrade.desc_extended=신비로운 작업대에서 갑옷에 적용할 수 있습니다.
|
||||
item.ebwizardry\:resplendent_thread.name=찬란한 실타래
|
||||
item.ebwizardry\:resplendent_thread.desc=일반적인 마법사의 갑옷을 학자의 갑옷으로 강화합니다
|
||||
item.ebwizardry\:resplendent_thread.desc_extended=희미하게 빛나는 실로 신비로운 무늬를 수놓아 로브의 질을 높이고, 마법 부여의 효과를 상승시킵니다.\n\n신비로운 작업대에서 마법사 갑옷에 이 강화를 적용할 수 있습니다.
|
||||
|
||||
item.ebwizardry\:crystal_silver_plating.name=은도금된 수정
|
||||
item.ebwizardry\:crystal_silver_plating.desc=일반적인 마법사의 갑옷을 전투법사의 갑옷으로 강화합니다
|
||||
item.ebwizardry\:crystal_silver_plating.desc_extended=엘다르의 대장간에서 만들어진 거의 신화적인 합금으로, 우수한 마법 굴절도를 가지고 있습니다.\n\n신비로운 작업대에서 마법사 갑옷에 이 강화를 적용할 수 있습니다.
|
||||
|
||||
item.ebwizardry\:ethereal_crystalweave.name=천상의 수정천
|
||||
item.ebwizardry\:ethereal_crystalweave.desc=일반적인 마법사의 갑옷을 주술사의 갑옷으로 강화합니다
|
||||
item.ebwizardry\:ethereal_crystalweave.desc_extended=동물의 가죽처럼 두껍지만 한 장의 종이보다 가벼운 마나의 천입니다.\n\n신비로운 작업대에서 마법사 갑옷에 이 강화를 적용할 수 있습니다.
|
||||
|
||||
item.ebwizardry\:magic_silk.name=마법 비단
|
||||
|
||||
item.ebwizardry\:spectral_dust.name=망령의 가루
|
||||
|
||||
item.ebwizardry\:wizard_armour.legendary=전설
|
||||
item.ebwizardry\:wizard_armour.buff=%2$s 주문의 비용이 %1$s 감소
|
||||
item.ebwizardry\:wizard_armour.element_cost_reduction=%2$s 주문의 마나 소모량이 %1$s 감소
|
||||
item.ebwizardry\:wizard_armour.cooldown_reduction=재사용 대기시간이 %1$s%% 감소
|
||||
item.ebwizardry\:wizard_armour.enchantability=마법 부여의 효과 상승
|
||||
item.ebwizardry\:wizard_armour.mana=마나\: %1$s/%2$s
|
||||
|
||||
item.ebwizardry\:wizard_armour.full_set=전부 착용 시:
|
||||
item.ebwizardry\:sage_armour.full_set_bonus=다른 원소의 주문의 마나 소모량이 %1$s%% 감소
|
||||
item.ebwizardry\:battlemage_armour.full_set_bonus=보호 I 효과가 부여
|
||||
item.ebwizardry\:warlock_armour.full_set_bonus=이동속도가 %1$s%% 상승
|
||||
|
||||
item.ebwizardry\:wizard_hat.name=마법사 모자
|
||||
item.ebwizardry\:wizard_robe.name=마법사 로브
|
||||
item.ebwizardry\:wizard_leggings.name=마법사 각반
|
||||
@@ -232,10 +246,10 @@ item.ebwizardry\:wizard_robe_lightning.name=벼락술사 로브
|
||||
item.ebwizardry\:wizard_leggings_lightning.name=벼락술사 각반
|
||||
item.ebwizardry\:wizard_boots_lightning.name=벼락술사 부츠
|
||||
|
||||
item.ebwizardry\:wizard_hat_necromancy.name=혼령술사 모자
|
||||
item.ebwizardry\:wizard_robe_necromancy.name=혼령술사 로브
|
||||
item.ebwizardry\:wizard_leggings_necromancy.name=혼령술사 각반
|
||||
item.ebwizardry\:wizard_boots_necromancy.name=혼령술사 부츠
|
||||
item.ebwizardry\:wizard_hat_necromancy.name=사령술사 모자
|
||||
item.ebwizardry\:wizard_robe_necromancy.name=사령술사 로브
|
||||
item.ebwizardry\:wizard_leggings_necromancy.name=사령술사 각반
|
||||
item.ebwizardry\:wizard_boots_necromancy.name=사령술사 부츠
|
||||
|
||||
item.ebwizardry\:wizard_hat_earth.name=대지법사 모자
|
||||
item.ebwizardry\:wizard_robe_earth.name=대지법사 로브
|
||||
@@ -252,6 +266,126 @@ item.ebwizardry\:wizard_robe_healing.name=치유사 로브
|
||||
item.ebwizardry\:wizard_leggings_healing.name=치유사 각반
|
||||
item.ebwizardry\:wizard_boots_healing.name=치유사 부츠
|
||||
|
||||
item.ebwizardry\:sage_hat.name=학자 모자
|
||||
item.ebwizardry\:sage_robe.name=학자 로브
|
||||
item.ebwizardry\:sage_leggings.name=학자 각반
|
||||
item.ebwizardry\:sage_boots.name=학자 부츠
|
||||
|
||||
item.ebwizardry\:sage_hat_fire.name=화염학자 모자
|
||||
item.ebwizardry\:sage_robe_fire.name=화염학자 로브
|
||||
item.ebwizardry\:sage_leggings_fire.name=화염학자 각반
|
||||
item.ebwizardry\:sage_boots_fire.name=화염학자 부츠
|
||||
|
||||
item.ebwizardry\:sage_hat_ice.name=얼음학자 모자
|
||||
item.ebwizardry\:sage_robe_ice.name=얼음학자 로브
|
||||
item.ebwizardry\:sage_leggings_ice.name=얼음학자 각반
|
||||
item.ebwizardry\:sage_boots_ice.name=얼음학자 부츠
|
||||
|
||||
item.ebwizardry\:sage_hat_lightning.name=벼락학자 모자
|
||||
item.ebwizardry\:sage_robe_lightning.name=벼락학자 로브
|
||||
item.ebwizardry\:sage_leggings_lightning.name=벼락학자 각반
|
||||
item.ebwizardry\:sage_boots_lightning.name=벼락학자 부츠
|
||||
|
||||
item.ebwizardry\:sage_hat_necromancy.name=사령학자 모자
|
||||
item.ebwizardry\:sage_robe_necromancy.name=사령학자 로브
|
||||
item.ebwizardry\:sage_leggings_necromancy.name=사령학자 각반
|
||||
item.ebwizardry\:sage_boots_necromancy.name=사령학자 부츠
|
||||
|
||||
item.ebwizardry\:sage_hat_earth.name=대지학자 모자
|
||||
item.ebwizardry\:sage_robe_earth.name=대지학자 로브
|
||||
item.ebwizardry\:sage_leggings_earth.name=대지학자 각반
|
||||
item.ebwizardry\:sage_boots_earth.name=대지학자 부츠
|
||||
|
||||
item.ebwizardry\:sage_hat_sorcery.name=신비학자 모자
|
||||
item.ebwizardry\:sage_robe_sorcery.name=신비학자 로브
|
||||
item.ebwizardry\:sage_leggings_sorcery.name=신비학자 각반
|
||||
item.ebwizardry\:sage_boots_sorcery.name=신비학자 부츠
|
||||
|
||||
item.ebwizardry\:sage_hat_healing.name=치유학자 모자
|
||||
item.ebwizardry\:sage_robe_healing.name=치유학자 로브
|
||||
item.ebwizardry\:sage_leggings_healing.name=치유학자 각반
|
||||
item.ebwizardry\:sage_boots_healing.name=치유학자 부츠
|
||||
|
||||
item.ebwizardry\:battlemage_helmet.name=전투법사 투구
|
||||
item.ebwizardry\:battlemage_chestplate.name=전투법사 흉갑
|
||||
item.ebwizardry\:battlemage_leggings.name=전투법사 각반
|
||||
item.ebwizardry\:battlemage_boots.name=전투법사 부츠
|
||||
|
||||
item.ebwizardry\:battlemage_helmet_fire.name=화염 전투법사 투구
|
||||
item.ebwizardry\:battlemage_chestplate_fire.name=화염 전투법사 흉갑
|
||||
item.ebwizardry\:battlemage_leggings_fire.name=화염 전투법사 각반
|
||||
item.ebwizardry\:battlemage_boots_fire.name=화염 전투법사 부츠
|
||||
|
||||
item.ebwizardry\:battlemage_helmet_ice.name=얼음 전투법사 투구
|
||||
item.ebwizardry\:battlemage_chestplate_ice.name=얼음 전투법사 흉갑
|
||||
item.ebwizardry\:battlemage_leggings_ice.name=얼음 전투법사 각반
|
||||
item.ebwizardry\:battlemage_boots_ice.name=얼음 전투법사 부츠
|
||||
|
||||
item.ebwizardry\:battlemage_helmet_lightning.name=벼락 전투법사 투구
|
||||
item.ebwizardry\:battlemage_chestplate_lightning.name=벼락 전투법사 흉갑
|
||||
item.ebwizardry\:battlemage_leggings_lightning.name=벼락 전투법사 각반
|
||||
item.ebwizardry\:battlemage_boots_lightning.name=벼락 전투법사 부츠
|
||||
|
||||
item.ebwizardry\:battlemage_helmet_necromancy.name=사령 전투법사 투구
|
||||
item.ebwizardry\:battlemage_chestplate_necromancy.name=사령 전투법사 흉갑
|
||||
item.ebwizardry\:battlemage_leggings_necromancy.name=사령 전투법사 각반
|
||||
item.ebwizardry\:battlemage_boots_necromancy.name=사령 전투법사 부츠
|
||||
|
||||
item.ebwizardry\:battlemage_helmet_earth.name=대지 전투법사 투구
|
||||
item.ebwizardry\:battlemage_chestplate_earth.name=대지 전투법사 흉갑
|
||||
item.ebwizardry\:battlemage_leggings_earth.name=대지 전투법사 각반
|
||||
item.ebwizardry\:battlemage_boots_earth.name=대지 전투법사 부츠
|
||||
|
||||
item.ebwizardry\:battlemage_helmet_sorcery.name=신비 전투법사 투구
|
||||
item.ebwizardry\:battlemage_chestplate_sorcery.name=신비 전투법사 흉갑
|
||||
item.ebwizardry\:battlemage_leggings_sorcery.name=신비 전투법사 각반
|
||||
item.ebwizardry\:battlemage_boots_sorcery.name=신비 전투법사 부츠
|
||||
|
||||
item.ebwizardry\:battlemage_helmet_healing.name=치유 전투법사 투구
|
||||
item.ebwizardry\:battlemage_chestplate_healing.name=치유 전투법사 흉갑
|
||||
item.ebwizardry\:battlemage_leggings_healing.name=치유 전투법사 각반
|
||||
item.ebwizardry\:battlemage_boots_healing.name=치유 전투법사 부츠
|
||||
|
||||
item.ebwizardry\:warlock_hood.name=주술사 후드
|
||||
item.ebwizardry\:warlock_robe.name=주술사 로브
|
||||
item.ebwizardry\:warlock_leggings.name=주술사 각반
|
||||
item.ebwizardry\:warlock_boots.name=주술사 부츠
|
||||
|
||||
item.ebwizardry\:warlock_hood_fire.name=화염주술사 후드
|
||||
item.ebwizardry\:warlock_robe_fire.name=화염주술사 로브
|
||||
item.ebwizardry\:warlock_leggings_fire.name=화염주술사 각반
|
||||
item.ebwizardry\:warlock_boots_fire.name=화염주술사 부츠
|
||||
|
||||
item.ebwizardry\:warlock_hood_ice.name=얼음주술사 후드
|
||||
item.ebwizardry\:warlock_robe_ice.name=얼음주술사 로브
|
||||
item.ebwizardry\:warlock_leggings_ice.name=얼음주술사 각반
|
||||
item.ebwizardry\:warlock_boots_ice.name=얼음주술사 부츠
|
||||
|
||||
item.ebwizardry\:warlock_hood_lightning.name=벼락주술사 후드
|
||||
item.ebwizardry\:warlock_robe_lightning.name=벼락주술사 로브
|
||||
item.ebwizardry\:warlock_leggings_lightning.name=벼락주술사 각반
|
||||
item.ebwizardry\:warlock_boots_lightning.name=벼락주술사 부츠
|
||||
|
||||
item.ebwizardry\:warlock_hood_necromancy.name=사령주술사 후드
|
||||
item.ebwizardry\:warlock_robe_necromancy.name=사령주술사 로브
|
||||
item.ebwizardry\:warlock_leggings_necromancy.name=사령주술사 각반
|
||||
item.ebwizardry\:warlock_boots_necromancy.name=사령주술사 부츠
|
||||
|
||||
item.ebwizardry\:warlock_hood_earth.name=대지주술사 후드
|
||||
item.ebwizardry\:warlock_robe_earth.name=대지주술사 로브
|
||||
item.ebwizardry\:warlock_leggings_earth.name=대지주술사 각반
|
||||
item.ebwizardry\:warlock_boots_earth.name=대지주술사 부츠
|
||||
|
||||
item.ebwizardry\:warlock_hood_sorcery.name=신비주술사 후드
|
||||
item.ebwizardry\:warlock_robe_sorcery.name=신비주술사 로브
|
||||
item.ebwizardry\:warlock_leggings_sorcery.name=신비주술사 각반
|
||||
item.ebwizardry\:warlock_boots_sorcery.name=신비주술사 부츠
|
||||
|
||||
item.ebwizardry\:warlock_hood_healing.name=치유주술사 후드
|
||||
item.ebwizardry\:warlock_robe_healing.name=치유주술사 로브
|
||||
item.ebwizardry\:warlock_leggings_healing.name=치유주술사 각반
|
||||
item.ebwizardry\:warlock_boots_healing.name=치유주술사 부츠
|
||||
|
||||
item.ebwizardry\:spawn_wizard.name=생성: 마법사
|
||||
item.ebwizardry\:spawn_evil_wizard.name=생성: 사악한 마법사
|
||||
|
||||
@@ -265,9 +399,9 @@ item.ebwizardry\:flamecatcher.name=화염의 활
|
||||
|
||||
item.ebwizardry\:generic.disabled=이 아이템은 설정에서 사용할 수 없도록 설정됨
|
||||
|
||||
item.ebwizardry\:ring.generic.desc=버블즈 인벤토리에 장착하거나, 단축바에 두어 최대 2개 까지 장착할 수 있다.
|
||||
item.ebwizardry\:amulet.generic.desc=버블즈 인벤토리에 장착하거나, 단축바에 두어 한 번에 한 개만 장착할 수 있다.
|
||||
item.ebwizardry\:charm.generic.desc=버블즈 인벤토리에 장착하거나, 단축바에 두어 한 번에 한 개만 장착할 수 있다.
|
||||
item.ebwizardry\:ring.generic.desc=버블즈 인벤토리에 장착하거나, 단축바에 올려둬 최대 2개 까지 장착할 수 있습니다.
|
||||
item.ebwizardry\:amulet.generic.desc=버블즈 인벤토리에 장착하거나, 단축바에 올려둬 한 번에 한 개만 장착할 수 있습니다.
|
||||
item.ebwizardry\:charm.generic.desc=버블즈 인벤토리에 장착하거나, 단축바에 올려둬 한 번에 한 개만 장착할 수 있습니다.
|
||||
|
||||
item.ebwizardry\:ring_condensing.name=축전의 반지
|
||||
item.ebwizardry\:ring_condensing.desc=단축바에 있는 모든 지팡이의 마나를 천천히 재생시킵니다
|
||||
@@ -404,7 +538,7 @@ item.ebwizardry\:charm_flight.name=에메랄드 딱정벌레 날개
|
||||
item.ebwizardry\:charm_flight.desc=비행 및 활공 속도가 50%%더 빨라집니다
|
||||
item.ebwizardry\:charm_growth.name=마법수정 꽃 부적
|
||||
item.ebwizardry\:charm_growth.desc=수확의 축복 주문이 35%%확률로 식물을 완전히 자라게 합니다
|
||||
item.ebwizardry\:charm_abseiling.name=마법이 부여된 실타래
|
||||
item.ebwizardry\:charm_abseiling.name=마법이 부여된 실뭉치
|
||||
item.ebwizardry\:charm_abseiling.desc=덩굴의 얽매임을 사용하며 공중에 있을 때 웅크리면 덩굴의 길이가 늘어납니다
|
||||
item.ebwizardry\:charm_silk_touch.name=월광석 보주
|
||||
item.ebwizardry\:charm_silk_touch.desc=채광 주문에 섬세한 손길이 적용됩니다
|
||||
@@ -577,6 +711,7 @@ entity.ebwizardry\:wizard.player_combat_3=너의 부주의함이 대가를 치
|
||||
entity.ebwizardry\:wizard.player_combat_4=싸울 준비나 해라, 악당아!
|
||||
entity.ebwizardry\:wizard.player_combat_5=분노를 느낄 준비나 해라!
|
||||
|
||||
entity.ebwizardry\:zombie_minion.name=좀비
|
||||
entity.ebwizardry\:husk_minion.name=허스크
|
||||
entity.ebwizardry\:skeleton_minion.name=스켈레톤
|
||||
entity.ebwizardry\:stray_minion.name=스트레이
|
||||
@@ -599,7 +734,7 @@ entity.ebwizardry\:decoy.name=분산
|
||||
entity.ebwizardry\:vex_minion.name=벡스
|
||||
entity.ebwizardry\:remnant.name=잔존체
|
||||
|
||||
entity.ebwizardry\:마법_missile.name=마법
|
||||
entity.ebwizardry\:magic_missile.name=마법
|
||||
entity.ebwizardry\:arc.name=마법
|
||||
entity.ebwizardry\:spark_bomb.name=마법
|
||||
entity.ebwizardry\:ice_shard.name=마법
|
||||
@@ -711,8 +846,12 @@ advancement.ebwizardry\:craft_lectern.desc=주문서 책장을 관리하기 위
|
||||
|
||||
advancement.ebwizardry\:armour_set=이제야 좀 제대로 된 마법사 같네
|
||||
advancement.ebwizardry\:armour_set.desc=마법사 갑옷의 모자, 로브, 각반, 부츠를 모두 장착하세요
|
||||
advancement.ebwizardry\:legendary=전설!
|
||||
advancement.ebwizardry\:legendary.desc=전설 마법사 갑옷을 획득하세요
|
||||
advancement.ebwizardry\:sage=학자의 길
|
||||
advancement.ebwizardry\:sage.desc=학자의 갑옷을 획득하세요
|
||||
advancement.ebwizardry\:battlemage=전투법사의 서약
|
||||
advancement.ebwizardry\:battlemage.desc=전투법사의 갑옷을 획득하세요
|
||||
advancement.ebwizardry\:warlock=주술사의 방식
|
||||
advancement.ebwizardry\:warlock.desc=주술사의 갑옷을 획득하세요
|
||||
|
||||
advancement.ebwizardry\:enchant_scroll=두루마리!
|
||||
advancement.ebwizardry\:enchant_scroll.desc=빈 두루마리를 만들고 신비로운 작업대에서 주문의 마법을 부여하세요
|
||||
@@ -758,7 +897,7 @@ element.magic.wizard=마법사
|
||||
element.fire.wizard=화염술사
|
||||
element.ice.wizard=얼음법사
|
||||
element.lightning.wizard=벼락술사
|
||||
element.necromancy.wizard=혼령술사
|
||||
element.necromancy.wizard=사령술사
|
||||
element.earth.wizard=대지법사
|
||||
element.sorcery.wizard=신비술사
|
||||
element.healing.wizard=치유사
|
||||
|
||||
@@ -52,8 +52,8 @@ tile.ebwizardry\:dark_oak_lectern.name=Кафедра из тёмного дуб
|
||||
tile.ebwizardry\:receptacle.name=Вместилище
|
||||
tile.ebwizardry\:imbuement_altar.name=Алтарь наполнения
|
||||
|
||||
item.ebwizardry\:crystal_magic.name=Магический кристалл
|
||||
item.ebwizardry\:crystal_magic.desc=Переливающиеся цвета этого кристалла, кажется, медленно меняются и кружатся, намекая на магическую энергию внутри. Возможно, эту магию можно задействовать, как-нибудь...
|
||||
item.ebwizardry\:crystal_magic.name=Волшебный кристалл
|
||||
item.ebwizardry\:crystal_magic.desc=Переливающиеся цвета этого кристалла, кажется, медленно меняются и кружатся, намекая на волшебную энергию внутри. Возможно, эту магию можно задействовать, как-нибудь...
|
||||
item.ebwizardry\:crystal_fire.name=Огненный кристалл
|
||||
item.ebwizardry\:crystal_fire.desc=Кристалл, который светится оранжево-огненным цветом. Возможно, он - ключ к разблокировки элемента огня...
|
||||
item.ebwizardry\:crystal_ice.name=Ледяной кристалл
|
||||
@@ -96,7 +96,7 @@ item.ebwizardry\:wand.levelup=%1$s готов улучшиться до уров
|
||||
item.ebwizardry\:wand.addally=%1$s был добавлен в Ваш список союзников.
|
||||
item.ebwizardry\:wand.removeally=%1$s был убран из Вашего списка союзников.
|
||||
|
||||
item.ebwizardry\:magic_wand.name=Магический жезл
|
||||
item.ebwizardry\:magic_wand.name=Волшебный жезл
|
||||
item.ebwizardry\:apprentice_wand.name=Жезл ученика
|
||||
item.ebwizardry\:advanced_wand.name=Продвинутый жезл
|
||||
item.ebwizardry\:master_wand.name=Жезл мастера
|
||||
@@ -145,10 +145,10 @@ item.ebwizardry\:medium_mana_flask.name=Средняя колба с маной
|
||||
item.ebwizardry\:large_mana_flask.name=Большая колба с маной
|
||||
item.ebwizardry\:mana_flask.desc=Изготовьте колбу с маной с использованием Жезла или части брони Волшебника, чтобы восстановить %s маны.
|
||||
|
||||
item.ebwizardry\:grand_crystal.name=Большой магический кристалл
|
||||
item.ebwizardry\:grand_crystal.desc=Крупный магический кристалл, в несколько раз больше тех, что обнаружены естественным образом. Кто-то, видимо, вырастил его искусственно - но как?
|
||||
item.ebwizardry\:crystal_shard.name=Магический кристальный осколок
|
||||
item.ebwizardry\:crystal_shard.desc=Маленький кусочек раздробленного магического кристалла. Он содержит в себе немного кол-во маны, но он может иметь другое применение...
|
||||
item.ebwizardry\:grand_crystal.name=Большой волшебный кристалл
|
||||
item.ebwizardry\:grand_crystal.desc=Крупный волшебный кристалл, в несколько раз больше тех, что обнаружены естественным образом. Кто-то, видимо, вырастил его искусственно - но как?
|
||||
item.ebwizardry\:crystal_shard.name=Волшебный кристальный осколок
|
||||
item.ebwizardry\:crystal_shard.desc=Маленький кусочек раздробленного волшебного кристалла. Он содержит в себе немного количество маны, но он может иметь другое применение...
|
||||
|
||||
item.ebwizardry\:astral_diamond.name=Звёздный алмаз
|
||||
item.ebwizardry\:astral_diamond.desc=Высоко-ценившиеся драгоценный камень, который ярко сверкает над звёздным светом. Поговаривают, что самые могущественные Волшебники ищут Звёздные алмазы в замен, на самые неуловимые Таинственные знания.
|
||||
@@ -176,7 +176,7 @@ item.ebwizardry\:range_upgrade.desc=Улучшает эффективный ра
|
||||
item.ebwizardry\:duration_upgrade.desc=Улучшает продолжительность эффектов брошенным Жезлом.
|
||||
item.ebwizardry\:cooldown_upgrade.desc=Улучшает скорость отката заклинания Жезла.
|
||||
item.ebwizardry\:blast_upgrade.desc=Улучшает область эффекта заклинаний брошенным Жезлом.
|
||||
item.ebwizardry\:attunement_upgrade.desc=Улучшает кол-во заклинаний, которых можно привязать к Жезлу.
|
||||
item.ebwizardry\:attunement_upgrade.desc=Улучшает количество заклинаний, которых можно привязать к Жезлу.
|
||||
item.ebwizardry\:melee_upgrade.desc=Улучшает жезл на использование маны, для нанесения большего урона по мобам, при ударе.
|
||||
|
||||
item.ebwizardry\:flaming_axe.name=Пылающий топор
|
||||
@@ -204,7 +204,7 @@ item.ebwizardry\:armour_upgrade.name=Мистическая печать защ
|
||||
item.ebwizardry\:armour_upgrade.desc=Улучшает любую Броню волшебника, чтобы сделать её %1$s Легендарной.
|
||||
item.ebwizardry\:armour_upgrade.desc_extended=Примените это Улучшение в часть брони Волшебника в Мистическом верстаке.
|
||||
|
||||
item.ebwizardry\:magic_silk.name=Магический шёлк
|
||||
item.ebwizardry\:magic_silk.name=Волшебный шёлк
|
||||
|
||||
item.ebwizardry\:spectral_dust.name=Спектральный прах
|
||||
|
||||
@@ -274,7 +274,7 @@ item.ebwizardry\:ring_condensing.desc=Медленно восстанавлив
|
||||
item.ebwizardry\:ring_siphoning.name=Кольцо выкачивания
|
||||
item.ebwizardry\:ring_siphoning.desc=Увеличивает выкачивание маны на 30%%.
|
||||
item.ebwizardry\:ring_battlemage.name=Кольцо боевого мага
|
||||
item.ebwizardry\:ring_battlemage.desc=Удерживая жезл в левой руке и меч в основной руке, даёт 10%% дополнительного магического урона.
|
||||
item.ebwizardry\:ring_battlemage.desc=Удерживая жезл в левой руке и меч в основной руке, даёт 10%% дополнительного волшебного урона.
|
||||
item.ebwizardry\:ring_combustion.name=Кольцо горения
|
||||
item.ebwizardry\:ring_combustion.desc=Существа, убитые Огненными заклинаниями, взрываются.
|
||||
item.ebwizardry\:ring_fire_melee.name=Кольцо огненного прикосновения
|
||||
@@ -339,7 +339,7 @@ item.ebwizardry\:ring_interdiction.desc=Ваше силовое поле пов
|
||||
item.ebwizardry\:amulet_arcane_defence.name=Амулет мистической защиты
|
||||
item.ebwizardry\:amulet_arcane_defence.desc=Медленно восстанавливается мана на всю одетую броню Волшебника.
|
||||
item.ebwizardry\:amulet_warding.name=Амулет защиты
|
||||
item.ebwizardry\:amulet_warding.desc=Сокращает весь входящий магический урон на 10%%.
|
||||
item.ebwizardry\:amulet_warding.desc=Сокращает весь входящий волшебный урон на 10%%.
|
||||
item.ebwizardry\:amulet_wisdom.name=Амулет мудрости
|
||||
item.ebwizardry\:amulet_wisdom.desc=Существенно сокращает шанс отрицательных эффектов при использовании неоткрытых Заклинаний.
|
||||
item.ebwizardry\:amulet_fire_protection.name=Амулет быстрой пламени
|
||||
@@ -591,7 +591,7 @@ entity.ebwizardry\:spirit_horse.name=Призрачная лошадь
|
||||
entity.ebwizardry\:ice_giant.name=Ледяной гигант
|
||||
entity.ebwizardry\:phoenix.name=Феникс
|
||||
entity.ebwizardry\:wizard.name=Волшебник
|
||||
entity.ebwizardry\:magic_slime.name=Магический слизень
|
||||
entity.ebwizardry\:magic_slime.name=Волшебный слизень
|
||||
entity.ebwizardry\:silverfish_minion.name=Чешуйница
|
||||
entity.ebwizardry\:storm_elemental.name=Грозовой элементаль
|
||||
entity.ebwizardry\:evil_wizard.name=Злой волшебник
|
||||
@@ -599,31 +599,31 @@ entity.ebwizardry\:decoy.name=Приманка
|
||||
entity.ebwizardry\:vex_minion.name=Досаждатель
|
||||
entity.ebwizardry\:remnant.name=Пережиток
|
||||
|
||||
entity.ebwizardry\:magic_missile.name=Магическая
|
||||
entity.ebwizardry\:arc.name=Магическая
|
||||
entity.ebwizardry\:spark_bomb.name=Магическая
|
||||
entity.ebwizardry\:ice_shard.name=Магическая
|
||||
entity.ebwizardry\:firebomb.name=Магическая
|
||||
entity.ebwizardry\:poison_bomb.name=Магическая
|
||||
entity.ebwizardry\:force_orb.name=Магическая
|
||||
entity.ebwizardry\:spark.name=Магическая
|
||||
entity.ebwizardry\:darkness_orb.name=Магическая
|
||||
entity.ebwizardry\:fire_sigil.name=Магическая
|
||||
entity.ebwizardry\:frost_sigil.name=Магическая
|
||||
entity.ebwizardry\:lightning_sigil.name=Магическая
|
||||
entity.ebwizardry\:lightning_arrow.name=Магическая
|
||||
entity.ebwizardry\:firebolt.name=Магическая
|
||||
entity.ebwizardry\:ice_charge.name=Магическая
|
||||
entity.ebwizardry\:force_arrow.name=Магическая
|
||||
entity.ebwizardry\:dart.name=Магическая
|
||||
entity.ebwizardry\:lightning_disc.name=Магическая
|
||||
entity.ebwizardry\:thunderbolt.name=Магическая
|
||||
entity.ebwizardry\:decay.name=Магическая
|
||||
entity.ebwizardry\:ice_lance.name=Магическая
|
||||
entity.ebwizardry\:smoke_bomb.name=Магическая
|
||||
entity.ebwizardry\:ice_spike.name=Магическая
|
||||
entity.ebwizardry\:combustion_rune.name=Магическая
|
||||
entity.ebwizardry\:flamecatcher_arrow.name=Магическая
|
||||
entity.ebwizardry\:magic_missile.name=Волшебная
|
||||
entity.ebwizardry\:arc.name=Волшебная
|
||||
entity.ebwizardry\:spark_bomb.name=Волшебная
|
||||
entity.ebwizardry\:ice_shard.name=Волшебная
|
||||
entity.ebwizardry\:firebomb.name=Волшебная
|
||||
entity.ebwizardry\:poison_bomb.name=Волшебная
|
||||
entity.ebwizardry\:force_orb.name=Волшебная
|
||||
entity.ebwizardry\:spark.name=Волшебная
|
||||
entity.ebwizardry\:darkness_orb.name=Волшебная
|
||||
entity.ebwizardry\:fire_sigil.name=Волшебная
|
||||
entity.ebwizardry\:frost_sigil.name=Волшебная
|
||||
entity.ebwizardry\:lightning_sigil.name=Волшебная
|
||||
entity.ebwizardry\:lightning_arrow.name=Волшебная
|
||||
entity.ebwizardry\:firebolt.name=Волшебная
|
||||
entity.ebwizardry\:ice_charge.name=Волшебная
|
||||
entity.ebwizardry\:force_arrow.name=Волшебная
|
||||
entity.ebwizardry\:dart.name=Волшебная
|
||||
entity.ebwizardry\:lightning_disc.name=Волшебная
|
||||
entity.ebwizardry\:thunderbolt.name=Волшебная
|
||||
entity.ebwizardry\:decay.name=Волшебная
|
||||
entity.ebwizardry\:ice_lance.name=Волшебная
|
||||
entity.ebwizardry\:smoke_bomb.name=Волшебная
|
||||
entity.ebwizardry\:ice_spike.name=Волшебная
|
||||
entity.ebwizardry\:combustion_rune.name=Волшебная
|
||||
entity.ebwizardry\:flamecatcher_arrow.name=Волшебная
|
||||
|
||||
entity.ebwizardry\:black_hole.name=Чёрная дыра
|
||||
entity.ebwizardry\:shield.name=Щит
|
||||
@@ -652,9 +652,9 @@ itemGroup.ebwizardrygear=Снаряжение wizardry
|
||||
advancement.ebwizardry\:root=Волшебство
|
||||
advancement.ebwizardry\:root.desc=Путешествие волшебника к освоению Мистики.
|
||||
advancement.ebwizardry\:crystal=Любопытный кристалл...
|
||||
advancement.ebwizardry\:crystal.desc=Добудьте магический кристалл.
|
||||
advancement.ebwizardry\:crystal.desc=Добудьте волшебный кристалл.
|
||||
advancement.ebwizardry\:arcane_initiate=Приступить к Мистике.
|
||||
advancement.ebwizardry\:arcane_initiate.desc=Создайте магический Жезл из Золотого самородка, Палки и Магического кристалла.
|
||||
advancement.ebwizardry\:arcane_initiate.desc=Создайте волшебный Жезл из Золотого самородка, Палки и Волшебного кристалла.
|
||||
|
||||
advancement.ebwizardry\:apprentice=Ученик волшебника.
|
||||
advancement.ebwizardry\:apprentice.desc=Используйте фолиант арканы, чтобы улучшить свой жезл.
|
||||
@@ -665,13 +665,13 @@ advancement.ebwizardry\:advanced.desc=Улучшите свой Жезл до П
|
||||
advancement.ebwizardry\:master=Мастер в Мистике.
|
||||
advancement.ebwizardry\:master.desc=Получите жезл мастера.
|
||||
advancement.ebwizardry\:max_out_wand=Полностью оборудован.
|
||||
advancement.ebwizardry\:max_out_wand.desc=Примените максимальное кол-во улучшений в жезл Мастера.
|
||||
advancement.ebwizardry\:max_out_wand.desc=Примените максимальное количество улучшений в жезл Мастера.
|
||||
advancement.ebwizardry\:all_spells=Маг на все руки.
|
||||
advancement.ebwizardry\:all_spells.desc=Бросьте каждое Заклинание в игре.
|
||||
|
||||
advancement.ebwizardry\:wizard_tower=Кто здесь живёт?
|
||||
advancement.ebwizardry\:wizard_tower.desc=Посетите башню Волшебника.
|
||||
advancement.ebwizardry\:wizard_trade=Магическое решение.
|
||||
advancement.ebwizardry\:wizard_trade=Волшебное решение.
|
||||
advancement.ebwizardry\:wizard_trade.desc=Купите предмет у Волшебника.
|
||||
advancement.ebwizardry\:anger_wizard=Вы пожалеете об этом.
|
||||
advancement.ebwizardry\:anger_wizard.desc=Разозлите волшебника.
|
||||
@@ -815,7 +815,7 @@ spell.ebwizardry\:disintegration=Распад
|
||||
spell.ebwizardry\:divination=Предсказание
|
||||
spell.ebwizardry\:dragon_fireball=Огненный шар дракона
|
||||
spell.ebwizardry\:earthquake=Землятресение
|
||||
spell.ebwizardry\:empowering_presence=Магическое усиление
|
||||
spell.ebwizardry\:empowering_presence=Волшебное усиление
|
||||
spell.ebwizardry\:enrage=Разозление
|
||||
spell.ebwizardry\:entrapment=Провокация
|
||||
spell.ebwizardry\:evade=Уклонение
|
||||
@@ -888,7 +888,7 @@ spell.ebwizardry\:lightning_pulse=Молниевый пульс
|
||||
spell.ebwizardry\:lightning_ray=Молниевый луч
|
||||
spell.ebwizardry\:lightning_sigil=Молниевый сигил
|
||||
spell.ebwizardry\:lightning_web=Молниевая паутина
|
||||
spell.ebwizardry\:magic_missile=Магический снаряд
|
||||
spell.ebwizardry\:magic_missile=Волшебный снаряд
|
||||
spell.ebwizardry\:mark_sacrifice=Знак жертвоприношения
|
||||
spell.ebwizardry\:metamorphosis=Метаморфоз
|
||||
spell.ebwizardry\:meteor=Метеор
|
||||
@@ -983,7 +983,7 @@ spell.ebwizardry\:chain_lightning.desc=Стреляет искрами свет
|
||||
spell.ebwizardry\:charge.desc=Заставляет заклинателя стремительно заряжаться в том направлении, куда он смотрит, повреждая и отбрасывая всё на своём пути.
|
||||
spell.ebwizardry\:clairvoyance.desc=Раскрывает путь в запоминающее место. С этим выбранным заклинанием, shift + пкм по блоку, чтобы задать место. Бросьте это Заклинание как обычно, чтобы раскрыть путь. Путь исчезнет через 90 секунд.
|
||||
spell.ebwizardry\:cobwebs.desc=Создаёт паутины туда, куда Вы указываете, она-же, сильно сдерживают движение любых существ пойманные среди них. Паутины пропадут через 20 секунд либо если сломать.
|
||||
spell.ebwizardry\:combustion_rune.desc=Помещает магические наземные мины на землю туда, куда Вы указываете, которые взрываются когда ступите на них.
|
||||
spell.ebwizardry\:combustion_rune.desc=Помещает волшебные наземные мины на землю туда, куда Вы указываете, которые взрываются когда ступите на них.
|
||||
spell.ebwizardry\:conjure_armour.desc=Создаёт спектральную броню вокруг Заклинателя, обеспечивающая защиту равной по защите Железной брони. Броня длится 60 секунд. У заклинателя должен быть Пустой слот для брони.
|
||||
spell.ebwizardry\:conjure_block.desc=Призывает спектральный блок туда, куда Вы указываете. Спектральный блок исчезает через 45 секунд, или Вы можете устранить его, снова бросив на него Заклинание.
|
||||
spell.ebwizardry\:conjure_bow.desc=Создаёт спектральный лук с безграничными стрелами, которые длятся 60 секунд.
|
||||
@@ -1005,7 +1005,7 @@ spell.ebwizardry\:disintegration.desc=Выстреливает мощной мо
|
||||
spell.ebwizardry\:divination.desc=Направляет заклинателя к близлежащим Рудам и Ресурсам. Мощь, увеличит вероятность найти больше ценных руд.
|
||||
spell.ebwizardry\:dragon_fireball.desc=Запускает огненный шар дракона в направлении, по которому Вы указываете, который выпускает сохраняющиеся Отравляющие облака при попадании.
|
||||
spell.ebwizardry\:earthquake.desc=Истинный мастер земной магии, который может сдвинуть горы.
|
||||
spell.ebwizardry\:empowering_presence.desc=Даёт Заклинателю и ближайшим Союзникам усиленный магический урон на 30 секунд.
|
||||
spell.ebwizardry\:empowering_presence.desc=Даёт Заклинателю и ближайшим Союзникам усиленный волшебный урон на 30 секунд.
|
||||
spell.ebwizardry\:enrage.desc=Причиняет близлежащих существ впадать в ярость, вместо этого, останавливая всё, что они делали напасть на Заклинателя.
|
||||
spell.ebwizardry\:entrapment.desc=Заманивает цель в Сферу тьмы, которая беспомощно тянет её вверх и непрерывно повреждает её.
|
||||
spell.ebwizardry\:evade.desc=Заставляет заклинателя быстро отпрыгнуть в сторону, чтобы увернуться от происходящих атак.
|
||||
@@ -1014,7 +1014,7 @@ spell.ebwizardry\:fireball.desc=Выпускает огненный шар в н
|
||||
spell.ebwizardry\:firebolt.desc=Выстреливает струёй огня на короткое расстояние перед Вами.
|
||||
spell.ebwizardry\:firebomb.desc=Выпускает огненную бомбу в направлении, по которому Вы указываете, которая взрывается при попадании, поджигая цели.
|
||||
spell.ebwizardry\:fire_resistance.desc=Даёт заклинателю огнестойкость на 30 секунд.
|
||||
spell.ebwizardry\:fire_sigil.desc=Помещает магическую огненную ловушку на землю, которая повреждает и поджигает существо сдетонирующее её.
|
||||
spell.ebwizardry\:fire_sigil.desc=Помещает волшебную огненную ловушку на землю, которая повреждает и поджигает существо сдетонирующее её.
|
||||
spell.ebwizardry\:fireskin.desc=Покрывает заклинателя в пламя на 30 секунд, причиняет всё, что атакует его загореться.
|
||||
spell.ebwizardry\:firestorm.desc="Очистите землю и очистите почву!\nДеревья должны гореть, а озера должны кипеть!\nСпалите дерево и подпалите камень!\nВсем склониться перед адским троном!"
|
||||
spell.ebwizardry\:fire_breath.desc="Я, дракон."
|
||||
@@ -1023,26 +1023,26 @@ spell.ebwizardry\:flame_ray.desc=Создаёт поток пламени в н
|
||||
spell.ebwizardry\:flaming_axe.desc=Создаёт пылающий топор, который поджигает врагов при ударе. Длится 30 секунд.
|
||||
spell.ebwizardry\:flaming_weapon.desc=Временно наполняет первое оружие в панели быстрого доступа Заклинателя энергией пламени, причиняя поджигание жертв. Магия выветрится через 45 секунд.
|
||||
spell.ebwizardry\:flight.desc=Парить как Орёл.
|
||||
spell.ebwizardry\:font_of_mana.desc="Мы были наполнены интенсивной магической энергией вытекающая из центра ..." - Отрывок из дневника забытого мага; оставшаяся часть страницы была сожжена.
|
||||
spell.ebwizardry\:font_of_mana.desc="Мы были наполнены интенсивной волшебной энергией вытекающая из центра ..." - Отрывок из дневника забытого мага; оставшаяся часть страницы была сожжена.
|
||||
spell.ebwizardry\:font_of_vitality.desc=Это потрясающее ощущение.
|
||||
spell.ebwizardry\:force_arrow.desc=Выстреливает усиленной стрелой в направлении, по которому Вы указываете.
|
||||
spell.ebwizardry\:forcefield.desc=Создаёт силовое поле вокруг Заклинателя, которое отталкивает существ и отражает большую часть снарядов.
|
||||
spell.ebwizardry\:force_orb.desc=Запускает силовую сферу, которая повреждает и отталкивает ближайших существ при попадании.
|
||||
spell.ebwizardry\:forests_curse.desc="Как Вы посмели войти в мой лес!"
|
||||
spell.ebwizardry\:forest_of_thorns.desc=Посреди леса кроется скрытая поляна,\nВ поляне играет Волшебник,\nМагические искусства невыразимого порядка,\nГлубоко в лесу шипов.
|
||||
spell.ebwizardry\:forest_of_thorns.desc=Посреди леса кроется скрытая поляна,\nВ поляне играет Волшебник,\nВолшебные искусства невыразимого порядка,\nГлубоко в лесу шипов.
|
||||
spell.ebwizardry\:freeze.desc=Замораживает цель на 10 секунд. Также будет замораживать воду и создавать на земле снег.
|
||||
spell.ebwizardry\:freezing_weapon.desc=Временно наполняет первое оружие в панели быстрого доступа Заклинателя силой мороза, причиняя замораживание жертв. Магия выветрится через 45 секунд.
|
||||
spell.ebwizardry\:frost_axe.desc=Создаёт морозный топор, который замораживает врагов при ударе. Длится 30 секунд.
|
||||
spell.ebwizardry\:frost_barrier.desc=Создаёт баррикаду льда впереди Заклинателя, которая ограждает их от поступающих атак. Барьер длится 20 секунд.
|
||||
spell.ebwizardry\:frost_ray.desc=Создаёт поток мороза в направлении, по которому Вы указываете, который замедляет и регулярно повреждает цели.
|
||||
spell.ebwizardry\:frost_sigil.desc=Помещает магическую ледяную ловушку на землю, которая повреждает и замораживает существо, сдетонирующее её.
|
||||
spell.ebwizardry\:frost_sigil.desc=Помещает волшебную ледяную ловушку на землю, которая повреждает и замораживает существо, сдетонирующее её.
|
||||
spell.ebwizardry\:frost_step.desc=Позволяет заклинателю замораживать воду пока он бродит, на 30 секунд.
|
||||
spell.ebwizardry\:grapple.desc=Выстреливает магической лианой, которая позволяет Заклинателю захватываться в сторону блоков или сматывать существ. Отпустите лкм, чтобы освободить Блок или Существо.
|
||||
spell.ebwizardry\:grapple.desc=Выстреливает волшебной лианой, которая позволяет Заклинателю захватываться в сторону блоков или сматывать существ. Отпустите лкм, чтобы освободить Блок или Существо.
|
||||
spell.ebwizardry\:glide.desc=При удержании Лкм, позволяет Заклинателю скользить вниз, пока он находится в воздухе.
|
||||
spell.ebwizardry\:greater_fireball.desc=Запускает большой огненный шар в направлении, по которому Вы указываете, который врывается при попадании.
|
||||
spell.ebwizardry\:greater_heal.desc=Излечивает заклинателя 4-мя сердцами.
|
||||
spell.ebwizardry\:greater_telekinesis.desc=Позволяет заклинателю подбирать блок или существо и удерживать его в воздухе до тех пор, пока зажата кнопка Лкм. Shift во время удержания блока или существа, выбросит его на короткое расстояние.
|
||||
spell.ebwizardry\:greater_ward.desc=Даёт заклинателю мощный защитный эффект, который существенно сокращает входящий магический урон на 30 секунд.
|
||||
spell.ebwizardry\:greater_ward.desc=Даёт заклинателю мощный защитный эффект, который существенно сокращает входящий волшебный урон на 30 секунд.
|
||||
spell.ebwizardry\:group_heal.desc=Лечит заклинателя и всех поблизости союзников, и, призывает существо с 3-мя сердцами.
|
||||
spell.ebwizardry\:growth_aura.desc=Выращивает все посевы рядом от Заклинателя. Также выращивает высокую траву и цветы на блоке травы.
|
||||
spell.ebwizardry\:guardian_beam.desc=Стреляет лучами из глаз Стража в направлении, по которому Вы указываете, который повреждает цели и истощает их запас воздуха под водой.
|
||||
@@ -1069,17 +1069,17 @@ spell.ebwizardry\:ironflesh.desc=Существенно улучшает соп
|
||||
spell.ebwizardry\:leap.desc=Заставляет заклинателя прыгать выше на несколько блоков и слегка вперёд.
|
||||
spell.ebwizardry\:levitation.desc=Поднимает заклинателя вверх, пока зажата кнопка Лкм. Также будет сводить на нет урон от падения, если оно используется до удара об землю.
|
||||
spell.ebwizardry\:life_drain.desc=Создаёт поток иссушительной энергии в направлении, по которому Вы указываете, которая высасывает жизнь из цели и использует её, чтобы мало-помалу восстановить Ваше здоровье.
|
||||
spell.ebwizardry\:light.desc=Создаёт магическую точку света, которая освещает окружающую область. Длится 30 секунд.
|
||||
spell.ebwizardry\:light.desc=Создаёт волшебную точку света, которая освещает окружающую область. Длится 30 секунд.
|
||||
spell.ebwizardry\:lightning_arrow.desc=Выстреливает молниевой стрелой в направлении, по которому Вы указываете.
|
||||
spell.ebwizardry\:lightning_bolt.desc=Вызывает молнию ударить туда, куда Вы указываете.
|
||||
spell.ebwizardry\:lightning_disc.desc=Направляет молниевый диск лететь в направлении, по которому Вы указываете, при этом разыскивает цели.
|
||||
spell.ebwizardry\:lightning_hammer.desc="Я поражу Вас гневом небес!"
|
||||
spell.ebwizardry\:lightning_pulse.desc=Заряжает землю около Заклинателя молнией, повреждает и отталкивает ближайших существ.
|
||||
spell.ebwizardry\:lightning_ray.desc=Создаёт поток молнии в направлении, по которому Вы указываете, который непрерывно повреждает цели.
|
||||
spell.ebwizardry\:lightning_sigil.desc=Размещает магическую молниевую ловушку на землю, которая повреждает существо, сдетонирующее её и зацепит других поблизости существ.
|
||||
spell.ebwizardry\:lightning_sigil.desc=Размещает волшебную молниевую ловушку на землю, которая повреждает существо, сдетонирующее её и зацепит других поблизости существ.
|
||||
spell.ebwizardry\:lightning_web.desc="Сконцентрируйтесь. Направьте шторм в свой разум сквозь Жезл и освободите свою ярость."
|
||||
spell.ebwizardry\:magic_missile.desc=Стреляет молнией магической энергией в направлении, по которому Вы указываете.
|
||||
spell.ebwizardry\:mark_sacrifice.desc=Помечает цель как божественную жертву. Следующая магическая атака на помеченного существа, нанесёт 60%% дополнительного урона с каждым уровнем эффекта.
|
||||
spell.ebwizardry\:magic_missile.desc=Стреляет молнией волшебной энергией в направлении, по которому Вы указываете.
|
||||
spell.ebwizardry\:mark_sacrifice.desc=Помечает цель как божественную жертву. Следующая волшебная атака на помеченного существа, нанесёт 60%% дополнительного урона с каждым уровнем эффекта.
|
||||
spell.ebwizardry\:metamorphosis.desc=Преобразует цель в другую форму. Работает только на определённых существ.
|
||||
spell.ebwizardry\:meteor.desc=Некоторые волшебники хотят увидеть, как горит мир...
|
||||
spell.ebwizardry\:mind_control.desc=Берёт контроль над разумом цели на 30 секунд, заставив его поменяться местами и драться вместо Заклинателя. Не будет работать на существ, которые слишком сильны волей.
|
||||
@@ -1099,12 +1099,12 @@ spell.ebwizardry\:pocket_workbench.desc=Позволяет заклинател
|
||||
spell.ebwizardry\:poison.desc=Стреляет ядом в направлении, по которому Вы указываете.
|
||||
spell.ebwizardry\:poison_bomb.desc=Запускает отравляющую бомбу в направлении, по которому Вы указываете, которая взрывается при попадании, а также отравляет ближайших существ.
|
||||
spell.ebwizardry\:possession.desc="Стать своим врагом."
|
||||
spell.ebwizardry\:radiant_totem.desc=Создаёт сияющий тотем, который выстреливает лучом света на поблизости существ, лечащий Союзников, но повреждает мобов. Длится 30 секунд. Мощь, повысит кол-во целей.
|
||||
spell.ebwizardry\:radiant_totem.desc=Создаёт сияющий тотем, который выстреливает лучом света на поблизости существ, лечащий Союзников, но повреждает мобов. Длится 30 секунд. Мощь, повысит количество целей.
|
||||
spell.ebwizardry\:ray_of_purification.desc=Испускает луч ослепительного света, который повреждает и слепит цели. Неживые существа получат 2-й урон и загорятся.
|
||||
spell.ebwizardry\:remove_curse.desc=Снимает любое проклятие, которое на данный момент влияет на Заклинателя.
|
||||
spell.ebwizardry\:replenish_hunger.desc=Восполняет уровень еды Заклинателя 3-мя очками голода.
|
||||
spell.ebwizardry\:resurrection.desc=С мастером целителем рядом с Вами, быть мертвым... необязательно.
|
||||
spell.ebwizardry\:reversal.desc=Снимает случайный отрицательный эффект зелья и наносит его на цель, который будет страдать от этого эффекта в течение оставшегося периода времени. Мощь, увеличивает кол-во эффектов, которые будут обращены.
|
||||
spell.ebwizardry\:reversal.desc=Снимает случайный отрицательный эффект зелья и наносит его на цель, который будет страдать от этого эффекта в течение оставшегося периода времени. Мощь, увеличивает количество эффектов, которые будут обращены.
|
||||
spell.ebwizardry\:ring_of_fire.desc=Создаёт кольцо огня вокруг Заклинателя, которое повреждает всех ближайших врагов и поджигает их.
|
||||
spell.ebwizardry\:satiety.desc=Пополняет уровень еды Заклинателя 8-ю очками голода.
|
||||
spell.ebwizardry\:shadow_ward.desc=Создаёт стену тьмы впереди Заклинателя, которая причиняет половину всего входящего урона наносимого нападающему.
|
||||
@@ -1119,7 +1119,7 @@ spell.ebwizardry\:smoke_bomb.desc=Запускает дымовую бомбу
|
||||
spell.ebwizardry\:snare.desc=Устанавливает ловушку на землю, которая повреждает и ненадолго замедляет существо, которое сдетонирует её.
|
||||
spell.ebwizardry\:snowball.desc=Запускает снежок в направлении, по которому Вы указываете.
|
||||
spell.ebwizardry\:spark_bomb.desc=Запускает шоковый заряд в направлении, по которому Вы указываете, который выпускает искры на ближайших врагов при попадании.
|
||||
spell.ebwizardry\:spectral_pathway.desc=Создаёт несокрушимый магический мост впереди Вас, который расширяется на 15 блоков. Мост исчезнет через 1 минуту.
|
||||
spell.ebwizardry\:spectral_pathway.desc=Создаёт несокрушимый волшебный мост впереди Вас, который расширяется на 15 блоков. Мост исчезнет через 1 минуту.
|
||||
spell.ebwizardry\:speed_time.desc=...день, ночь, рассвет, сумерки, восход и закат\: таким образом, проходит время, которое охватывает нас в бесконечном цикле...
|
||||
spell.ebwizardry\:spider_swarm.desc=Призывает рой ядовитых пауков сражающихся за Вас. Пауки пропадут через 30 секунд, либо если их убьют.
|
||||
spell.ebwizardry\:static_aura.desc=Окружает заклинателя молнией на 30 секунд, стреляя искрами молнии во что-либо, кто ударит его.
|
||||
@@ -1148,7 +1148,7 @@ spell.ebwizardry\:transportation.desc=Перемещает заклинател
|
||||
spell.ebwizardry\:vanishing_box.desc=Даёт заклинателю доступ к хранилищу Сундуку края.
|
||||
spell.ebwizardry\:vex_swarm.desc=Призывает рой летающих досаждателей сражающихся за Вас. Досаждатели пропадут через 30 секунд, либо если их убьют.
|
||||
spell.ebwizardry\:wall_of_frost.desc=Зима в Ваших пальцах.
|
||||
spell.ebwizardry\:ward.desc=Даёт заклинателю защитный эффект, который снижает входящий магический урон на 30 секунд.
|
||||
spell.ebwizardry\:ward.desc=Даёт заклинателю защитный эффект, который снижает входящий волшебный урон на 30 секунд.
|
||||
spell.ebwizardry\:water_breathing.desc=Позволяет заклинателю дышать под водой на 1 минуту.
|
||||
spell.ebwizardry\:whirlwind.desc=Заставляет цель взлетать вверх и подальше от Вас на скорости.
|
||||
spell.ebwizardry\:wither.desc=Стреляет лучом тьмы, которая иссушает всё, что прикоснётся.
|
||||
@@ -1269,7 +1269,7 @@ enchantment.ebwizardry\:flaming_weapon=Наполнение огнём
|
||||
enchantment.ebwizardry\:freezing_weapon=Наполнение морозом
|
||||
enchantment.ebwizardry\:shocking_weapon=Наполнение молнией
|
||||
|
||||
enchantment.ebwizardry\:magic_protection=Магическая защита
|
||||
enchantment.ebwizardry\:magic_protection=Волшебная защита
|
||||
enchantment.ebwizardry\:frost_protection=Морозная защита
|
||||
enchantment.ebwizardry\:shock_protection=Шоковая защита
|
||||
|
||||
@@ -1279,7 +1279,7 @@ enchantment.ebwizardry.flaming_weapon.desc=Часть заклинания Ог
|
||||
enchantment.ebwizardry.freezing_weapon.desc=Часть заклинания Замороженного оружия; недостижимо в режиме Выживания (книга не сработает).
|
||||
enchantment.ebwizardry.shocking_weapon.desc=Часть заклинания Шокирующего оружия; недостижимо в режиме Выживания (книга не сработает).
|
||||
|
||||
enchantment.ebwizardry.magic_protection.desc=Уменьшает весь магический урон.
|
||||
enchantment.ebwizardry.magic_protection.desc=Уменьшает весь волшебный урон.
|
||||
enchantment.ebwizardry.frost_protection.desc=Уменьшает урон от заморозки.
|
||||
enchantment.ebwizardry.shock_protection.desc=Уменьшает урон от шока.
|
||||
|
||||
@@ -1336,6 +1336,8 @@ commands.ebwizardry\:discoverspell.removespell=Убрано %1$s из данны
|
||||
|
||||
config.ebwizardry.title.general=Параметры мода
|
||||
|
||||
config.ebwizardry.redundant_keys=В Вашем файле конфигурации содержатся лишние параметры, они ничего не сделают! [Подробности см. В журнале]
|
||||
|
||||
config.ebwizardry.generic.true=Вкл
|
||||
config.ebwizardry.generic.false=Выкл
|
||||
|
||||
@@ -1463,9 +1465,9 @@ config.ebwizardry.bookshelf_blocks.tooltip=Список названий бло
|
||||
config.ebwizardry.book_items=Книги
|
||||
config.ebwizardry.book_items.tooltip=Список названий предметов в реестре, которых можно поместить в Книжную полку, в дополнение к стандартным. Названия предметов не чувствительны к регистру. Для предметов мода, префикс с ID мода (например: thaumcraft:thaumonomicon).
|
||||
config.ebwizardry.bookshelf_search_radius=Радиус поиска Книжной полки
|
||||
config.ebwizardry.bookshelf_search_radius.tooltip=Максимальное кол-во блоков может быть в Книжной полке из Мистического верстака или Кафедры, чтобы иметь возможность соединиться к ней.
|
||||
config.ebwizardry.bookshelf_search_radius.tooltip=Максимальное количество блоков может быть в Книжной полке из Мистического верстака или Кафедры, чтобы иметь возможность соединиться к ней.
|
||||
config.ebwizardry.currency_items=Предметы валюты
|
||||
config.ebwizardry.currency_items.tooltip=Список названий предметов в реестре, который торгующийся Волшебник может использовать в качестве Валюты (в первом слоте; второй слот не затрагивается). Каждая запись в этом списке должна содержать название предмета в реестре, с последующим одним местом, затем целое число, определяющее 'значение' предмета. Более высокие значения означают, что требуется меньшее кол-во Валютных предметов для получения торговли.
|
||||
config.ebwizardry.currency_items.tooltip=Список названий предметов в реестре, который торгующийся Волшебник может использовать в качестве Валюты (в первом слоте; второй слот не затрагивается). Каждая запись в этом списке должна содержать название предмета в реестре, с последующим одним местом, затем целое число, определяющее 'значение' предмета. Более высокие значения означают, что требуется меньшее количество Валютных предметов для получения торговли.
|
||||
|
||||
config.ebwizardry.category.worldgen=Настройки генерации мира
|
||||
config.ebwizardry.category.worldgen.tooltip=Настройте возможности генерации мира Wizardry
|
||||
@@ -1630,9 +1632,9 @@ integration.antiqueatlas.marker.ebwizardry.obelisk=Обелиск
|
||||
integration.antiqueatlas.marker.ebwizardry.shrine=Святилища
|
||||
integration.antiqueatlas.marker.ebwizardry.library_ruins=Разрушенная библиотека
|
||||
|
||||
spell.ebwizardry\:magic_missile_festive=Магическая омела
|
||||
spell.ebwizardry\:magic_missile_festive=Волшебная омела
|
||||
spell.ebwizardry\:summon_snow_golem_festive=Призывает замороженного Снеговика
|
||||
spell.ebwizardry\:invigorating_presence_festive=Бодрое усиление
|
||||
spell.ebwizardry\:empowering_presence_festive=Магическое усиление
|
||||
spell.ebwizardry\:empowering_presence_festive=Волшебное усиление
|
||||
|
||||
wizard.debug=%1$s, %2$s, %3$s.
|
||||
@@ -54,7 +54,6 @@ tile.ebwizardry\:imbuement_altar.name=注灵祭坛
|
||||
|
||||
item.ebwizardry\:crystal_magic.name=魔力水晶
|
||||
item.ebwizardry\:crystal_magic.desc=水晶闪耀斑斓的色彩似乎在缓慢地变幻流转,暗示着其内蕴含的魔法能量。或许能以某种方法来驾驭这种魔力......
|
||||
|
||||
item.ebwizardry\:crystal_fire.name=赤焰水晶
|
||||
item.ebwizardry\:crystal_fire.desc=发出烈火般橙色光彩的水晶。也许是揭示火焰元素奥秘的关键......
|
||||
item.ebwizardry\:crystal_ice.name=寒霜水晶
|
||||
@@ -201,18 +200,32 @@ item.ebwizardry\:identification_scroll.desc=识别的未知法术书或卷轴
|
||||
item.ebwizardry\:identification_scroll.desc_extended=手持鉴定卷轴右击,以鉴定快捷栏中的第一个未鉴定的法术书或卷轴。
|
||||
item.ebwizardry\:identification_scroll.nothing_to_identify=没有可鉴定的物品!
|
||||
|
||||
item.ebwizardry\:armour_upgrade.name=奥术护具升级圣印
|
||||
item.ebwizardry\:armour_upgrade.desc=将任意巫师盔甲升级至%1$s传奇
|
||||
item.ebwizardry\:armour_upgrade.desc_extended=在奥术工作台中将该升级圣印附加到巫师盔甲上。
|
||||
item.ebwizardry\:resplendent_thread.name=魔辉丝线
|
||||
item.ebwizardry\:resplendent_thread.desc=将寻常巫师盔甲升级至贤者盔甲
|
||||
item.ebwizardry\:resplendent_thread.desc_extended=一卷微光闪烁的丝线,用于将奥术符纹刺绣至绝品的长袍之上,以提升其附魔能力。\n\n在奥术工作台中可将该升级圣物附加到一件巫师盔甲上。
|
||||
|
||||
item.ebwizardry\:crystal_silver_plating.name=晶银镶板
|
||||
item.ebwizardry\:crystal_silver_plating.desc=将寻常巫师盔甲升级至战斗法师盔甲
|
||||
item.ebwizardry\:crystal_silver_plating.desc_extended=一片近乎神话般的合金,于艾尔达的锻炉中铸造而成,具有出色的魔力偏转特性。\n\n在奥术工作台中将该升级圣物附加到一件巫师盔甲上。
|
||||
|
||||
item.ebwizardry\:ethereal_crystalweave.name=缈晶纹绸
|
||||
item.ebwizardry\:ethereal_crystalweave.desc=将寻常巫师盔甲升级至巫术士盔甲
|
||||
item.ebwizardry\:ethereal_crystalweave.desc_extended=一块蕴含魔力的布匹,厚如动物的毛皮,但不知为何,放在手中时的感觉却比薄纸还要轻盈。\n\n在奥术工作台中将该升级圣物附加到一件巫师盔甲上。
|
||||
|
||||
item.ebwizardry\:magic_silk.name=魔法绸缎
|
||||
|
||||
item.ebwizardry\:spectral_dust.name=灵尘
|
||||
|
||||
item.ebwizardry\:wizard_armour.legendary=传奇
|
||||
item.ebwizardry\:wizard_armour.buff=-%1$s %2$s 法术魔力损耗
|
||||
item.ebwizardry\:wizard_armour.element_cost_reduction=-%1$s%% %2$s 魔力消耗
|
||||
item.ebwizardry\:wizard_armour.cooldown_reduction=-%1$s%% 冷却时间
|
||||
item.ebwizardry\:wizard_armour.enchantability=额外的附魔能力
|
||||
item.ebwizardry\:wizard_armour.mana=魔力:%1$s/%2$s
|
||||
|
||||
item.ebwizardry\:wizard_armour.full_set=全套:
|
||||
item.ebwizardry\:sage_armour.full_set_bonus=-%1$s%% 其他元素法术魔力损耗
|
||||
item.ebwizardry\:battlemage_armour.full_set_bonus=魔法护盾 I 效果
|
||||
item.ebwizardry\:warlock_armour.full_set_bonus=+%1$s%% 移动速度
|
||||
|
||||
item.ebwizardry\:wizard_hat.name=巫师帽
|
||||
item.ebwizardry\:wizard_robe.name=巫师长袍
|
||||
item.ebwizardry\:wizard_leggings.name=巫师护腿
|
||||
@@ -253,6 +266,126 @@ item.ebwizardry\:wizard_robe_healing.name=治愈巫师长袍
|
||||
item.ebwizardry\:wizard_leggings_healing.name=治愈巫师护腿
|
||||
item.ebwizardry\:wizard_boots_healing.name=治愈巫师靴子
|
||||
|
||||
item.ebwizardry\:sage_hat.name=贤者帽
|
||||
item.ebwizardry\:sage_robe.name=贤者长袍
|
||||
item.ebwizardry\:sage_leggings.name=贤者护腿
|
||||
item.ebwizardry\:sage_boots.name=贤者靴子
|
||||
|
||||
item.ebwizardry\:sage_hat_fire.name=烈焰贤者帽
|
||||
item.ebwizardry\:sage_robe_fire.name=烈焰贤者长袍
|
||||
item.ebwizardry\:sage_leggings_fire.name=烈焰贤者护腿
|
||||
item.ebwizardry\:sage_boots_fire.name=烈焰贤者靴子
|
||||
|
||||
item.ebwizardry\:sage_hat_ice.name=冰霜贤者帽
|
||||
item.ebwizardry\:sage_robe_ice.name=冰霜贤者长袍
|
||||
item.ebwizardry\:sage_leggings_ice.name=冰霜贤者护腿
|
||||
item.ebwizardry\:sage_boots_ice.name=冰霜贤者靴子
|
||||
|
||||
item.ebwizardry\:sage_hat_lightning.name=雷电贤者帽
|
||||
item.ebwizardry\:sage_robe_lightning.name=雷电贤者长袍
|
||||
item.ebwizardry\:sage_leggings_lightning.name=雷电贤者护腿
|
||||
item.ebwizardry\:sage_boots_lightning.name=雷电贤者靴子
|
||||
|
||||
item.ebwizardry\:sage_hat_necromancy.name=死灵贤者帽
|
||||
item.ebwizardry\:sage_robe_necromancy.name=死灵贤者长袍
|
||||
item.ebwizardry\:sage_leggings_necromancy.name=死灵贤者护腿
|
||||
item.ebwizardry\:sage_boots_necromancy.name=死灵贤者靴子
|
||||
|
||||
item.ebwizardry\:sage_hat_earth.name=自然贤者帽
|
||||
item.ebwizardry\:sage_robe_earth.name=自然贤者长袍
|
||||
item.ebwizardry\:sage_leggings_earth.name=自然贤者护腿
|
||||
item.ebwizardry\:sage_boots_earth.name=自然贤者靴子
|
||||
|
||||
item.ebwizardry\:sage_hat_sorcery.name=秘法贤者帽
|
||||
item.ebwizardry\:sage_robe_sorcery.name=秘法贤者长袍
|
||||
item.ebwizardry\:sage_leggings_sorcery.name=秘法贤者护腿
|
||||
item.ebwizardry\:sage_boots_sorcery.name=秘法贤者靴子
|
||||
|
||||
item.ebwizardry\:sage_hat_healing.name=治愈贤者帽
|
||||
item.ebwizardry\:sage_robe_healing.name=治愈贤者长袍
|
||||
item.ebwizardry\:sage_leggings_healing.name=治愈贤者护腿
|
||||
item.ebwizardry\:sage_boots_healing.name=治愈贤者靴子
|
||||
|
||||
item.ebwizardry\:battlemage_helmet.name=战斗法师头盔
|
||||
item.ebwizardry\:battlemage_chestplate.name=战斗法师胸甲
|
||||
item.ebwizardry\:battlemage_leggings.name=战斗法师护腿
|
||||
item.ebwizardry\:battlemage_boots.name=战斗法师靴子
|
||||
|
||||
item.ebwizardry\:battlemage_helmet_fire.name=烈焰战斗法师头盔
|
||||
item.ebwizardry\:battlemage_chestplate_fire.name=烈焰战斗法师胸甲
|
||||
item.ebwizardry\:battlemage_leggings_fire.name=烈焰战斗法师护腿
|
||||
item.ebwizardry\:battlemage_boots_fire.name=烈焰战斗法师靴子
|
||||
|
||||
item.ebwizardry\:battlemage_helmet_ice.name=冰霜战斗法师头盔
|
||||
item.ebwizardry\:battlemage_chestplate_ice.name=冰霜战斗法师胸甲
|
||||
item.ebwizardry\:battlemage_leggings_ice.name=冰霜战斗法师护腿
|
||||
item.ebwizardry\:battlemage_boots_ice.name=冰霜战斗法师靴子
|
||||
|
||||
item.ebwizardry\:battlemage_helmet_lightning.name=雷电战斗法师头盔
|
||||
item.ebwizardry\:battlemage_chestplate_lightning.name=雷电战斗法师胸甲
|
||||
item.ebwizardry\:battlemage_leggings_lightning.name=雷电战斗法师护腿
|
||||
item.ebwizardry\:battlemage_boots_lightning.name=雷电战斗法师靴子
|
||||
|
||||
item.ebwizardry\:battlemage_helmet_necromancy.name=死灵战斗法师头盔
|
||||
item.ebwizardry\:battlemage_chestplate_necromancy.name=死灵战斗法师胸甲
|
||||
item.ebwizardry\:battlemage_leggings_necromancy.name=死灵战斗法师护腿
|
||||
item.ebwizardry\:battlemage_boots_necromancy.name=死灵战斗法师靴子
|
||||
|
||||
item.ebwizardry\:battlemage_helmet_earth.name=自然战斗法师头盔
|
||||
item.ebwizardry\:battlemage_chestplate_earth.name=自然战斗法师胸甲
|
||||
item.ebwizardry\:battlemage_leggings_earth.name=自然战斗法师护腿
|
||||
item.ebwizardry\:battlemage_boots_earth.name=自然战斗法师靴子
|
||||
|
||||
item.ebwizardry\:battlemage_helmet_sorcery.name=秘法战斗法师头盔
|
||||
item.ebwizardry\:battlemage_chestplate_sorcery.name=秘法战斗法师胸甲
|
||||
item.ebwizardry\:battlemage_leggings_sorcery.name=秘法战斗法师护腿
|
||||
item.ebwizardry\:battlemage_boots_sorcery.name=秘法战斗法师靴子
|
||||
|
||||
item.ebwizardry\:battlemage_helmet_healing.name=治愈战斗法师头盔
|
||||
item.ebwizardry\:battlemage_chestplate_healing.name=治愈战斗法师胸甲
|
||||
item.ebwizardry\:battlemage_leggings_healing.name=治愈战斗法师护腿
|
||||
item.ebwizardry\:battlemage_boots_healing.name=治愈战斗法师靴子
|
||||
|
||||
item.ebwizardry\:warlock_hood.name=巫术士兜帽
|
||||
item.ebwizardry\:warlock_robe.name=巫术士长袍
|
||||
item.ebwizardry\:warlock_leggings.name=巫术士护腿
|
||||
item.ebwizardry\:warlock_boots.name=巫术士靴子
|
||||
|
||||
item.ebwizardry\:warlock_hood_fire.name=烈焰巫术士兜帽
|
||||
item.ebwizardry\:warlock_robe_fire.name=烈焰巫术士长袍
|
||||
item.ebwizardry\:warlock_leggings_fire.name=烈焰巫术士护腿
|
||||
item.ebwizardry\:warlock_boots_fire.name=烈焰巫术士靴子
|
||||
|
||||
item.ebwizardry\:warlock_hood_ice.name=冰霜巫术士兜帽
|
||||
item.ebwizardry\:warlock_robe_ice.name=冰霜巫术士长袍
|
||||
item.ebwizardry\:warlock_leggings_ice.name=冰霜巫术士护腿
|
||||
item.ebwizardry\:warlock_boots_ice.name=冰霜巫术士靴子
|
||||
|
||||
item.ebwizardry\:warlock_hood_lightning.name=雷电巫术士兜帽
|
||||
item.ebwizardry\:warlock_robe_lightning.name=雷电巫术士长袍
|
||||
item.ebwizardry\:warlock_leggings_lightning.name=雷电巫术士护腿
|
||||
item.ebwizardry\:warlock_boots_lightning.name=雷电巫术士靴子
|
||||
|
||||
item.ebwizardry\:warlock_hood_necromancy.name=死灵巫术士兜帽
|
||||
item.ebwizardry\:warlock_robe_necromancy.name=死灵巫术士长袍
|
||||
item.ebwizardry\:warlock_leggings_necromancy.name=死灵巫术士护腿
|
||||
item.ebwizardry\:warlock_boots_necromancy.name=死灵巫术士靴子
|
||||
|
||||
item.ebwizardry\:warlock_hood_earth.name=自然巫术士兜帽
|
||||
item.ebwizardry\:warlock_robe_earth.name=自然巫术士长袍
|
||||
item.ebwizardry\:warlock_leggings_earth.name=自然巫术士护腿
|
||||
item.ebwizardry\:warlock_boots_earth.name=自然巫术士靴子
|
||||
|
||||
item.ebwizardry\:warlock_hood_sorcery.name=秘法巫术士兜帽
|
||||
item.ebwizardry\:warlock_robe_sorcery.name=秘法巫术士长袍
|
||||
item.ebwizardry\:warlock_leggings_sorcery.name=秘法巫术士护腿
|
||||
item.ebwizardry\:warlock_boots_sorcery.name=秘法巫术士靴子
|
||||
|
||||
item.ebwizardry\:warlock_hood_healing.name=治愈巫术士兜帽
|
||||
item.ebwizardry\:warlock_robe_healing.name=治愈巫术士长袍
|
||||
item.ebwizardry\:warlock_leggings_healing.name=治愈巫术士护腿
|
||||
item.ebwizardry\:warlock_boots_healing.name=治愈巫术士靴子
|
||||
|
||||
item.ebwizardry\:spawn_wizard.name=生成巫师
|
||||
item.ebwizardry\:spawn_evil_wizard.name=生成邪恶巫师
|
||||
|
||||
@@ -409,7 +542,7 @@ item.ebwizardry\:charm_abseiling.desc=在施放藤蔓抓钩法术时潜行会减
|
||||
item.ebwizardry\:charm_silk_touch.name=月石宝珠
|
||||
item.ebwizardry\:charm_silk_touch.desc=使用挖掘魔法破坏的方块必定掉落其本身
|
||||
item.ebwizardry\:charm_sixth_sense.name=恐狼毛皮
|
||||
item.ebwizardry\:charm_sixth_sense.desc=第六感会为被动、中立和敌对生物显示不同颜色
|
||||
item.ebwizardry\:charm_sixth_sense.desc=第六感会以不同形状显示被动、中立和敌对生物
|
||||
item.ebwizardry\:charm_stop_time.name=奇特怀表
|
||||
item.ebwizardry\:charm_stop_time.desc=时间滞留魔法会让时间完全静止
|
||||
item.ebwizardry\:charm_light.name=Elevinia 的永燃圣灯
|
||||
@@ -712,8 +845,12 @@ advancement.ebwizardry\:craft_lectern.desc=合成一个览术台以随时掌握
|
||||
|
||||
advancement.ebwizardry\:armour_set=现在你是一名真正的巫师了
|
||||
advancement.ebwizardry\:armour_set.desc=制作并装备全套巫师护甲
|
||||
advancement.ebwizardry\:legendary=『传奇』
|
||||
advancement.ebwizardry\:legendary.desc=获得一件传奇巫师护甲
|
||||
advancement.ebwizardry\:sage=贤者之道
|
||||
advancement.ebwizardry\:sage.desc=获得一件贤者盔甲
|
||||
advancement.ebwizardry\:battlemage=战斗法师之证
|
||||
advancement.ebwizardry\:battlemage.desc=获得一件战斗法师盔甲
|
||||
advancement.ebwizardry\:warlock=巫术士之途
|
||||
advancement.ebwizardry\:warlock.desc=获得一件巫术士盔甲
|
||||
|
||||
advancement.ebwizardry\:enchant_scroll=魔法卷轴!
|
||||
advancement.ebwizardry\:enchant_scroll.desc=制作一个空白卷轴,并在奥术工作台上用法术书附魔
|
||||
@@ -1337,6 +1474,8 @@ commands.ebwizardry\:discoverspell.removespell=将 %1$s 由 %2$s 的已发现法
|
||||
|
||||
config.ebwizardry.title.general=模组选项
|
||||
|
||||
config.ebwizardry.redundant_keys=你的配置文件含有多余选项,它们不会发挥任何作用! [查看日志以获取详情]
|
||||
|
||||
config.ebwizardry.generic.true=开启
|
||||
config.ebwizardry.generic.false=关闭
|
||||
|
||||
|
||||
@@ -363,6 +363,7 @@
|
||||
"spell.zombie_apocalypse.start": {"category": "spells", "sounds": ["ebwizardry:dark_aura_start"]},
|
||||
"spell.zombie_apocalypse.loop": {"category": "spells", "sounds": ["ebwizardry:dark_aura_loop"]},
|
||||
"spell.zombie_apocalypse.end": {"category": "spells", "sounds": ["ebwizardry:dark_aura_end"]},
|
||||
"spell.mirage": {"category": "spells", "sounds": ["ebwizardry:buff"]},
|
||||
|
||||
"forfeit.burn_self": {"category": "spells", "sounds": ["fire/ignite"]},
|
||||
"forfeit.fireball": {"category": "spells", "sounds": ["mob/ghast/fireball4"]},
|
||||
@@ -409,4 +410,4 @@
|
||||
"forfeit.weaken_self": {"category": "spells", "sounds": ["mob/guardian/curse"]},
|
||||
"forfeit.jam_self": {"category": "spells", "sounds": ["ebwizardry:effect1", "ebwizardry:effect2"]},
|
||||
"forfeit.curse_self": {"category": "spells", "sounds": ["mob/guardian/curse"]}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"chargeup": 25,
|
||||
"cooldown": 300,
|
||||
"base_properties": {
|
||||
"resistance_duration": 600,
|
||||
"resistance_strength": 2
|
||||
"diamondflesh_duration": 600,
|
||||
"diamondflesh_strength": 0
|
||||
}
|
||||
}
|
||||
@@ -14,11 +14,12 @@
|
||||
"element": "healing",
|
||||
"type": "buff",
|
||||
"cost": 30,
|
||||
"chargeup": 0,
|
||||
"chargeup": 20,
|
||||
"cooldown": 60,
|
||||
"base_properties": {
|
||||
"effect_radius": 5,
|
||||
"effect_duration": 900,
|
||||
"effect_strength": 1
|
||||
"effect_strength": 0,
|
||||
"potency_per_level": 0.15
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
"chargeup": 15,
|
||||
"cooldown": 100,
|
||||
"base_properties": {
|
||||
"resistance_duration": 600,
|
||||
"resistance_strength": 1
|
||||
"ironflesh_duration": 600,
|
||||
"ironflesh_strength": 0
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
"chargeup": 0,
|
||||
"cooldown": 50,
|
||||
"base_properties": {
|
||||
"resistance_duration": 600,
|
||||
"resistance_strength": 0
|
||||
"oakflesh_duration": 600,
|
||||
"oakflesh_strength": 0
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@
|
||||
"range": 10,
|
||||
"damage": 4,
|
||||
"effect_duration": 100,
|
||||
"critical_health": 4
|
||||
"critical_health": 4,
|
||||
"player_effect_duration_multiplier": 0.5
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,6 @@
|
||||
"cooldown": 400,
|
||||
"base_properties": {
|
||||
"effect_radius": 8,
|
||||
"wait_time": 300
|
||||
"wait_time": 200
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,8 @@
|
||||
"chargeup": 20,
|
||||
"cooldown": 400,
|
||||
"base_properties": {
|
||||
"minion_lifetime": 600,
|
||||
"minion_count": 1,
|
||||
"summon_radius": 2
|
||||
}
|
||||
}
|
||||
@@ -70,6 +70,15 @@
|
||||
"width": 90,
|
||||
"height": 90
|
||||
},
|
||||
"classes": {
|
||||
"location": "ebwizardry:textures/gui/handbook/pictures/classes.png",
|
||||
"caption": "The Three Classes",
|
||||
"u": 0,
|
||||
"v": 0,
|
||||
"width": 96,
|
||||
"height": 32,
|
||||
"border": false
|
||||
},
|
||||
"obelisk": {
|
||||
"location": "ebwizardry:textures/gui/handbook/pictures/obelisk.png",
|
||||
"caption": "An Obelisk",
|
||||
@@ -496,7 +505,21 @@
|
||||
|
||||
"Those wizards who devote themselves to the practice of one element sometimes wear special garments which grant bonuses for that element. Full sets of such garments are very sought after among wizards and are not easy to find.",
|
||||
|
||||
"Legend speaks of an arcane seal used by the most powerful wizards to greatly improve their armour."
|
||||
"Once they have mastered the fundamentals of magic, many wizards choose to follow a particular path, or class, to further their training. There are three main classes that a wizard may align themselves with: sage, battlemage and warlock. Members of each class can easily be distinguished by their robes, which are modified - usually with rare and exotic materials - to better suit their needs.",
|
||||
|
||||
"#image classes",
|
||||
|
||||
"The Sage",
|
||||
|
||||
"By devoting their life to the pursuit of knowledge, the sage has perfected the art of efficient spellcasting, allowing them to cast spells using the smallest possible amount of mana. The finery of their silken robes belies the substantial protection they provide, as the sage is also an adept enchanter - though they are still no match for solid metal plating. Spending such long periods in the safety of a library does, however, make them rather sluggish in combat.",
|
||||
|
||||
"The Battlemage",
|
||||
|
||||
"The battlemage is geared for combat, clad in a combination of toughened cloth and crystal-silver plating sourced from the most skilled of foundries. Through discipline and training, the battlemage has also improved their speed and reactions, allowing them to cast spells more often. This does not come cheap, however, and a battlemage must be careful not to burn through mana too quickly.",
|
||||
|
||||
"The Warlock",
|
||||
|
||||
"The warlock lives for exploration, pushing the boundaries of what is possible to unearth lost arcane secrets. This, along with a willingness to experiment with what others may deem forbidden, has allowed them to break the constraints of traditional training and cast spells at a formidable rate, as well as reducing their mana usage. Their lightweight robes, though good for exploration, provide less protection in combat than their counterparts."
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user