Compare commits

..

95 Commits

Author SHA1 Message Date
WinDanesz 89a0a900cc v4.3.5 2022-02-07 23:06:39 +01:00
WinDanesz 391a24db3f Fixes integration with Construct's Armory and other mod's unbreakable helmets. #547 2022-02-07 22:10:28 +01:00
WinDanesz 4b546af642 Added a new ImbuementActivateEvent to allow addons hooking into the imbuement process 2022-02-07 21:50:26 +01:00
WinDanesz ee8aabbf97 This might fix the lingering Frost effect (from Frost Ray) 2022-02-07 21:37:01 +01:00
Rodro 45994e2b94 Fixed player rubberbanding when touching the wall of a containment field. Fixes #469 (Rodrogamby)
This fixed player rubberbanding when touching the wall of a containment field for me.

I took the liberty of uncommenting some code which produces a sound when the player tries to leave the field, and also deleted line 113 along with everything related to it since it seemed unnecessary.

I've tested this on singleplayer and on my 200ms multiplayer server and appears to be working perfectly in both.
(It works even if allow-flight is set to false on server.properties; I also tried using an elytra, levitation effect and extra speed, which all worked well too).
All tests were done using Forge-2860
2022-02-06 22:19:32 +01:00
WinDanesz 13bdc69da8 Added support for Forge's in-game mod version update notifier 2022-02-05 23:04:14 +01:00
WinDanesz c0184fde8e Fixed a bug with EntityWizard using one of EntityEvilWizard's DataParameter 2022-02-05 22:48:35 +01:00
WinDanesz cbd297e59d updated gradle version 2022-02-05 22:48:34 +01:00
WinDanesz c6cf7c950e increased duplicate detect threshold 2022-02-03 14:49:37 +01:00
WinDanesz fe5d80e017 Fixed dispenser crash with Conjure Block spell. Fixes #735 2022-02-03 11:57:22 +01:00
WinDanesz e985a8f15b Fixed dispenser crash with Slime spell. Fixes #735 2022-02-03 11:57:22 +01:00
Electroblob 615767f758 Merge pull request #688 from WinDanesz/1.12.2.dev
added onImbuementRemoval(ItemStack stack) to Imbuement interface
2022-02-01 18:34:24 +00:00
Electroblob 65a24b2295 Merge pull request #744 from WinDanesz/patch-2
Added duplicate issue detector & labeling tool
2022-02-01 18:33:18 +00:00
Electroblob 94c2afe67a Merge pull request #747 from WinDanesz/patch-1225-2
Fixes Mark Sacrifice not doing damage with low spell potency
2022-02-01 18:32:02 +00:00
Electroblob 9bbca37ecd Merge pull request #749 from WinDanesz/patch-1225-4
Scrolls no longer have cooldown in Creative mode
2022-02-01 18:30:47 +00:00
Electroblob 58241a0f5c Merge pull request #748 from WinDanesz/patch-1225-3
Added getter for ItemArtefact.enabled
2022-02-01 18:28:21 +00:00
Electroblob a960a01ca1 Merge pull request #750 from WinDanesz/patch-1226-2
Splitting PacketSpellProperties into batches of 100 spells.
2022-02-01 18:27:47 +00:00
Electroblob 67d8ee773c Merge pull request #751 from WinDanesz/patch-1227-1
Added tooltip for Spell Book and Scroll items, displaying the spell's…
2022-02-01 18:27:25 +00:00
Electroblob c6f2675278 Merge pull request #753 from WinDanesz/patch-1228-1
Fixed bug with wizard armours always providing protection even withou…
2022-02-01 18:26:54 +00:00
Electroblob77 2380be230e Merge branch '1.12.2' of https://github.com/Electroblob77/Wizardry into 1.12.2 2022-02-01 18:24:34 +00:00
Electroblob77 833276b7b3 TODOs 2022-02-01 18:24:26 +00:00
Electroblob77 9b32835720 Add resurrection event 2022-02-01 18:24:17 +00:00
Electroblob77 61634a9cc3 Change resurrection wait time and add particles to indicate where an ally died 2022-02-01 18:23:47 +00:00
Electroblob 408a35db8d Merge pull request #754 from WinDanesz/patch-1228-2
Remove soulbinding curse effect if the potion is no longer active. fi…
2022-02-01 18:20:37 +00:00
Electroblob 9695a85131 Merge pull request #755 from WinDanesz/patch-0102-1
Frostbite effect and burning now cancels each other
2022-02-01 18:20:20 +00:00
Electroblob d027cf4f2a Merge pull request #756 from WinDanesz/patch-0103-1
Added injectMobDrops setting to easily disable mob loot injection for…
2022-02-01 18:19:29 +00:00
WinDanesz c2f8bfc5b4 Added injectMobDrops setting to easily disable mob loot injection for all entities 2022-01-03 14:47:33 +01:00
WinDanesz 486425a62c Frostbite effect and entity burning now cancels each other 2022-01-02 22:07:05 +01:00
WinDanesz f9681d4c66 Remove soulbinding curse effect if the potion is no longer active. fixes #619. 2021-12-28 16:10:31 +01:00
WinDanesz cd0671dc59 Fixed bug with wizard armours always providing protection even without mana. Fixes #752 2021-12-28 16:08:18 +01:00
WinDanesz 7ebca16948 Added tooltip for Spell Book and Scroll items, displaying the spell's source mod if it's from an addon 2021-12-27 11:31:07 +01:00
WinDanesz e8cbdde518 Splitting PacketSpellProperties into batches of 100 spells. Fixes world load issue with large list of spells 2021-12-26 22:08:29 +01:00
WinDanesz 7ca6f05151 Scrolls no longer have cooldown in Creative mode 2021-12-25 18:16:32 +01:00
WinDanesz f4f17e90e5 Added getter for ItemArtefact.enabled 2021-12-25 18:10:09 +01:00
WinDanesz 3ea48efb1d Fixes Mark Sacrifice not doing damage with a potion amplifier of 0 2021-12-25 18:01:43 +01:00
WinDanesz ffc3533688 Create potential-duplicates.yml 2021-12-20 18:36:08 +01:00
Electroblob bd309855a2 Merge pull request #721 from WinDanesz/1.12.2-PR-10-02
Fixes wizards being stuck in a continuous, client-side only spellcast…
2021-10-03 18:10:51 +01:00
WinDanesz 1473c7e9b7 Fixes wizards being stuck in a continuous, client-side only spellcasting loop of their continuous spells if their target dies 2021-10-02 00:26:31 +02:00
WinDanesz 15cc7b6d18 added isEnabled() public method to ItemArtefact 2021-07-07 13:26:21 +02:00
WinDanesz 1c89c5f779 added onImbuementRemoval(ItemStack stack) to Imbuement interface 2021-07-07 12:40:05 +02:00
Electroblob77 ca7f1cc8ca Prevent Hyeleth's amulet from casting the shield spell from a scroll, fixes #680 2021-06-20 23:44:04 +01:00
Electroblob77 8fd1de84e4 Fix next/previous section button weirdness 2021-06-19 16:19:22 +01:00
Electroblob77 95d9168b6b Fix hyperlink wrapping for spaceless languages and remove remaining newlines 2021-06-19 16:01:23 +01:00
Electroblob77 c1db827132 Remove manual newline characters from Chinese handbook translations
I'm not 100% sure which to remove so I've only removed single newlines in block text for now
2021-06-19 13:01:58 +01:00
Electroblob77 d10b78ab46 Ignore hyperlink suffixes in spaceless languages, fixes #620
There's no real way to do this other than hardcoding which languages are exceptions (currently only the two Chinese locales)
2021-06-19 13:01:47 +01:00
Electroblob77 2d70523f43 Remove obsolete plain text Russian handbook translation 2021-06-19 12:47:00 +01:00
Electroblob77 42fb7ad3df Have all the baked bookshelf models use the same set of book models, fixes #621
This effectively cuts the number of book models by a factor equal to the number of bookshelf variants, which is 6 in the base mod
2021-06-19 00:01:24 +01:00
Electroblob77 e90d0950d4 Replace glide end sound with dummy sound (which for some reason seems not to play at all? Oh well ¯\_(ツ)_/¯), fixes #646 2021-06-18 17:47:55 +01:00
Electroblob77 888d4190d1 Store static map of mana flask charging recipes rather than iterating, fixes #671 2021-06-18 17:26:40 +01:00
Electroblob77 57696b2538 Make all forfeits respect claims via the methods in BlockUtils, fixes #672 2021-06-18 16:27:57 +01:00
Electroblob77 1440537f6b Missed one! 2021-06-18 14:23:40 +01:00
Electroblob77 a16ff88c8d Update credits (and put the discord mods in their rightful place at the top of the list <3) 2021-06-18 14:21:21 +01:00
Electroblob77 041de12ea7 Update Russian translations, courtesy of DrHesperus 2021-06-18 13:52:01 +01:00
Electroblob77 5e36f66c4e Update Korean translations, courtesy of red1854th 2021-06-18 13:51:32 +01:00
Electroblob77 a6a5a6104d Update French translations, courtesy of Crowller 2021-06-18 13:50:53 +01:00
Electroblob77 6f7b225ce8 ParticleBuilder is not thread-safe! 2021-06-18 13:49:45 +01:00
Electroblob77 81a85883d2 Consume mana/scrolls when forfeits are triggered, fixes #673 2021-06-18 13:49:29 +01:00
Electroblob 3f06d2fea4 Update bug_report.md 2021-06-18 00:08:29 +01:00
Electroblob 26b390268a Update ISSUE_TEMPLATE.md 2021-06-18 00:08:12 +01:00
Electroblob 486d55f349 Merge pull request #636 from LWHK/class-build
Add LF for CHS translation
2021-03-03 16:08:01 +00:00
TUsama 5948090d63 add LF manually
add LF manually
2021-03-01 17:55:32 +08:00
Electroblob77 32340191de Update version number 2021-02-01 16:49:30 +00:00
Electroblob77 0b09875bb3 Fix problems with combining spell modifiers 2021-02-01 16:41:31 +00:00
Electroblob77 078a36d304 Update The Wizard's Handbook 2021-01-31 20:34:57 +00:00
Electroblob77 3ef4ec522b Make mana flasks instant-use in creative mode 2021-01-31 16:17:18 +00:00
Electroblob77 cd6fa03990 Limit cooldowns to a minimum of 1 tick and replace armour cooldown reductions with correct values, fixes #603 2021-01-31 15:50:55 +00:00
Electroblob77 bba9fb68e6 Fix Hungarian handbook translation syntax error, fixes #610 2021-01-30 18:11:16 +00:00
Electroblob77 dcb7038833 Remove JSON generator code, fixes #615 2021-01-30 17:50:29 +00:00
Electroblob77 f8a058259d ItemArmor#getEquipmentSlot() is client-side only for some reason... fixes #608 2021-01-30 17:47:30 +00:00
Electroblob77 1696d5daeb Merge branch '1.12.2' of https://github.com/Electroblob77/Wizardry into 1.12.2 2021-01-30 17:46:25 +00:00
Electroblob77 ac69af012a Update Korean translations, courtesy of red1854th 2021-01-30 17:46:19 +00:00
Electroblob 692546a232 Merge pull request #606 from LWHK/armor-build
Update zh_cn.lang
2021-01-30 17:17:57 +00:00
TUsama b0478b627f some changes 2021-01-28 18:44:16 +08:00
Determancer 2cdca4b990 Merge pull request #1 from LWHK/Determancer-patch-1 2021-01-19 13:07:37 +08:00
Determancer 4c0b2adef4 武士 -> 巫师 2021-01-19 13:07:07 +08:00
Determancer 191dd078b8 Update src/main/resources/assets/ebwizardry/lang/zh_cn.lang
Co-authored-by: Clefal <1716976420@qq.com>
2021-01-19 13:04:35 +08:00
Determancer 2de7807bec Update src/main/resources/assets/ebwizardry/lang/zh_cn.lang
Co-authored-by: Clefal <1716976420@qq.com>
2021-01-19 13:04:13 +08:00
Determancer 9d4f1dd370 Translating All 2021-01-19 11:41:07 +08:00
Determancer 6f769150b1 Sync en_us.lang 2021-01-18 16:01:59 +08:00
TUsama 155dc0b621 update 2021-01-18 15:54:22 +08:00
Electroblob77 07acea53e3 A couple of tweaks for backwards compatiblity 2021-01-17 21:33:09 +00:00
Electroblob77 1fcb3a2b1b Reduce capacity of medium mana flask and reduce number of crystals required to craft it accordingly 2021-01-17 20:27:21 +00:00
Electroblob77 16eabc8deb Update version number 2021-01-17 20:23:28 +00:00
Electroblob77 e0efd8d407 Make mana flasks take time to use 2021-01-17 19:25:14 +00:00
Electroblob77 969f0b96fd Have custom large fireballs deal magic damage to ghasts in order to get around vanilla's hardcoded instanceof check, fixes #443 2021-01-17 17:40:09 +00:00
Electroblob77 8a9d88c9ac Guard against null item entities in LivingDropsEvent, fixes #464 2021-01-17 17:19:07 +00:00
Electroblob77 3b55728c75 Actually register font of mana with the event bus, fixes #477 2021-01-17 15:26:30 +00:00
Electroblob77 240bffa7ed Sometimes, I surprise even myself with my own stupidity... fixes #594
(This is literally why I have a helper method. To prevent exactly this error :/)
2021-01-17 15:14:23 +00:00
Electroblob77 c313236eec Disable weather forfeit when invoke weather is disabled, closes #554 2021-01-17 15:08:34 +00:00
Electroblob77 21f7928b9c Guard against null target in remant AI, fixes #600 2021-01-17 14:58:59 +00:00
Electroblob77 1304c11381 People don't listen to me, so let's spell it out to them 2021-01-17 14:41:21 +00:00
Electroblob77 79932e15ab Allow class armour to be imbued properly at the imbuement altar 2021-01-17 13:36:56 +00:00
Electroblob77 25ee166e41 Derp 2021-01-17 13:32:38 +00:00
Electroblob77 299510e663 Add armour classes!
- Added 3 new armour variants - the sage, the battlemage and the warlock - each in the 8 elemental varieties
- Added resplendent thread, crystal silver plating and ethereal crystalweave, used to upgrade regular armour into class armour
- Added the new armour upgrades to loot tables
- Added recipes for the new armour to JEI, along with info pages for the 3 upgrade items
- Added advancements for the new armour classes
- Removed legendary wizard armour
- Removed arcane seal of protection
- Removed the 'legendary' advancement
2021-01-16 23:02:03 +00:00
Electroblob77 d3d76cae16 Update Russian translations, courtesy of DrHesperus 2021-01-05 20:35:42 +00:00
353 changed files with 6445 additions and 2803 deletions
+7
View File
@@ -0,0 +1,7 @@
{
"homepage": "https://www.curseforge.com/minecraft/mc-mods/electroblobs-wizardry",
"promos": {
"1.12.2-latest": "4.3.5",
"1.12.2-recommended": "4.3.5"
}
}
+2 -2
View File
@@ -7,10 +7,10 @@ assignees: ''
---
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/CONTRIBUTING.md) before posting.
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.
Minecraft version: 1.12.2 [change as necessary]
Wizardry version: 4.3.2 [change as necessary]
Wizardry version: 4.3.5 [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
View File
@@ -10,7 +10,7 @@ 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.2 [change as necessary]
Wizardry version: [change as necessary]
Question details: [explain your question 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
View File
@@ -1,7 +1,7 @@
# Credits
Electroblob's Wizardry
Version 4.3.2
Version 4.3.5
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
View File
@@ -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.2 [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
View File
@@ -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.2" // There, it matches semver, happy now?
version = "4.3.5" // There, it matches semver, happy now?
group= "electroblob.wizardry"// http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = "ElectroblobsWizardry"
Binary file not shown.
+1 -2
View File
@@ -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
Vendored
+61 -53
View File
@@ -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
View File
@@ -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
@@ -10,6 +10,7 @@ import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemArmor.ArmorMaterial;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundCategory;
@@ -48,7 +49,7 @@ public class CommonProxy {
public void registerKeyBindings(){}
public net.minecraft.client.model.ModelBiped getWizardArmourModel(){
public net.minecraft.client.model.ModelBiped getWizardArmourModel(ArmorMaterial material){
return null;
}
@@ -93,6 +93,8 @@ public final class Settings {
/** The wizardry config file. */
private Configuration config;
private List<String> redundantKeys = new ArrayList<>();
// Server-only settings. These only affect server-side code and hence are not synced. Changing these locally only
// has an effect if the local game is the host, i.e. a dedicated server, a LAN host or a singleplayer world.
@@ -196,6 +198,8 @@ public final class Settings {
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 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.
@@ -446,6 +450,8 @@ public final class Settings {
*/
void initConfig(FMLPreInitializationEvent event){
redundantKeys.clear();
config = new Configuration(new File(Wizardry.configDirectory, Wizardry.MODID + ".cfg"));
config.load();
@@ -484,6 +490,8 @@ public final class Settings {
/** Called to save changes to the config file after it has been edited in game from the menus. */
void saveConfigChanges(){
redundantKeys.clear();
Wizardry.logger.info("Saving in-game config changes");
setupGameplayConfig();
@@ -500,6 +508,32 @@ public final class Settings {
config.save();
}
void checkForRedundantOptions(String categoryName, Collection<String> validKeys){
ConfigCategory category = config.getCategory(categoryName);
boolean redundantKeysFound = false;
for(String key : category.keySet()){
if(!validKeys.contains(key)){
redundantKeys.add(key);
if(!redundantKeysFound){
redundantKeysFound = true;
Wizardry.logger.info("Config category {} contains redundant options:", categoryName);
}
Wizardry.logger.info(key);
}
}
if(redundantKeysFound){
Wizardry.logger.info("These options will have no effect (they are probably left over from an older version of wizardry). It is recommended to either remove them manually, or delete ebwizardry.cfg and allow a fresh config to be generated.");
}
}
/** Returns true if the config file contains keys that are not valid options (usually because of updates). */
public boolean hasRedundantKeys(){
return !redundantKeys.isEmpty();
}
/** Sends a packet to the specified player's client containing all the <b>synchronised</b> settings. */
public void sync(EntityPlayerMP player){
Wizardry.logger.info("Synchronising config settings for " + player.getName());
@@ -518,7 +552,10 @@ public final class Settings {
Property property;
List<String> keys = new ArrayList<>();
for(Spell spell : Spell.getAllSpells()){
keys.add(spell.getRegistryName().toString());
property = config.get(SPELLS_CATEGORY, spell.getRegistryName().toString(), true,
"Set to false to disable this spell");
// Uses the same config key as the spell name, because - well, that's what it's called!
@@ -527,6 +564,7 @@ public final class Settings {
spell.setEnabled(property.getBoolean(true));
}
checkForRedundantOptions(SPELLS_CATEGORY, keys);
}
private void setupArtefactsConfig(){
@@ -536,8 +574,11 @@ public final class Settings {
Property property;
List<String> keys = new ArrayList<>();
for(Item item : Item.REGISTRY){
if(item instanceof ItemArtefact){
keys.add(item.getRegistryName().toString());
property = config.get(ARTEFACTS_CATEGORY, item.getRegistryName().toString(), true,
"Set to false to disable this item");
// Uses the same config key as the item name, because - well, that's what it's called!
@@ -547,6 +588,7 @@ public final class Settings {
}
}
checkForRedundantOptions(ARTEFACTS_CATEGORY, keys);
}
private void setupGameplayConfig(){
@@ -623,6 +665,7 @@ public final class Settings {
bonemealGrowsCrystalFlowers = property.getBoolean();
propOrder.add(property.getName());
checkForRedundantOptions(GAMEPLAY_CATEGORY, propOrder); // Must be before the order is set!
config.setCategoryPropertyOrder(GAMEPLAY_CATEGORY, propOrder);
}
@@ -730,6 +773,7 @@ public final class Settings {
lightningWraithSpawnRate = property.getInt();
propOrder.add(property.getName());
checkForRedundantOptions(DIFFICULTY_CATEGORY, propOrder); // Must be before the order is set!
config.setCategoryPropertyOrder(DIFFICULTY_CATEGORY, propOrder);
}
@@ -765,6 +809,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);
@@ -872,6 +923,7 @@ public final class Settings {
}
}
checkForRedundantOptions(TWEAKS_CATEGORY, propOrder); // Must be before the order is set!
config.setCategoryPropertyOrder(TWEAKS_CATEGORY, propOrder);
}
@@ -1019,6 +1071,7 @@ public final class Settings {
lootInjectionLocations = getResourceLocationList(property);
propOrder.add(property.getName());
checkForRedundantOptions(WORLDGEN_CATEGORY, propOrder); // Must be before the order is set!
config.setCategoryPropertyOrder(WORLDGEN_CATEGORY, propOrder);
}
@@ -1120,6 +1173,7 @@ public final class Settings {
donationPerkElement = Element.fromName(property.getString(), null); // Fallback to null for no element
propOrder.add(property.getName());
checkForRedundantOptions(CLIENT_CATEGORY, propOrder); // Must be before the order is set!
config.setCategoryPropertyOrder(CLIENT_CATEGORY, propOrder);
}
@@ -1166,6 +1220,7 @@ public final class Settings {
alliesCommandName = property.getString();
propOrder.add(property.getName());
checkForRedundantOptions(COMMANDS_CATEGORY, propOrder); // Must be before the order is set!
config.setCategoryPropertyOrder(COMMANDS_CATEGORY, propOrder);
}
@@ -1243,6 +1298,7 @@ public final class Settings {
}
propOrder.add(property.getName());
checkForRedundantOptions(RESISTANCES_CATEGORY, propOrder); // Must be before the order is set!
config.setCategoryPropertyOrder(RESISTANCES_CATEGORY, propOrder);
}
@@ -1332,6 +1388,7 @@ public final class Settings {
autoUndergroundLibraryMarkers = property.getBoolean();
propOrder.add(property.getName());
checkForRedundantOptions(COMPATIBILITY_CATEGORY, propOrder); // Must be before the order is set!
config.setCategoryPropertyOrder(COMPATIBILITY_CATEGORY, propOrder);
}
@@ -13,11 +13,22 @@ 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.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;
@@ -51,6 +62,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 {
@@ -69,7 +81,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.2";
public static final String VERSION = "4.3.5";
/**
* 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
@@ -168,8 +186,6 @@ public class Wizardry {
// Post-registry extras
BlockBookshelf.compileBookModelTextures();
ContainerBookshelf.initDefaultBookItems();
WizardryItems.populateWandMap();
WizardryItems.populateArmourMap();
WizardryItems.registerDispenseBehaviours();
WizardryItems.registerBannerPatterns();
WandHelper.populateUpgradeMap();
@@ -261,7 +261,6 @@ public class BlockBookshelf extends BlockHorizontal implements ITileEntityProvid
registerBookModelTexture(() -> WizardryItems.scroll, new ResourceLocation(Wizardry.MODID, "blocks/scrolls_blue"));
registerBookModelTexture(() -> WizardryItems.blank_scroll, new ResourceLocation(Wizardry.MODID, "blocks/scrolls_blue"));
registerBookModelTexture(() -> WizardryItems.identification_scroll, new ResourceLocation(Wizardry.MODID, "blocks/scrolls_purple"));
registerBookModelTexture(() -> WizardryItems.armour_upgrade, new ResourceLocation(Wizardry.MODID, "blocks/scrolls_red"));
// Can't use the map in WandHelper because this is called from preInit (addons will have to add theirs manually)
registerBookModelTexture(() -> WizardryItems.storage_upgrade, new ResourceLocation(Wizardry.MODID, "blocks/scrolls_wooden"));
registerBookModelTexture(() -> WizardryItems.siphon_upgrade, new ResourceLocation(Wizardry.MODID, "blocks/scrolls_wooden"));
@@ -14,6 +14,8 @@ import electroblob.wizardry.client.gui.GuiSpellDisplay;
import electroblob.wizardry.client.gui.config.NamedBooleanEntry;
import electroblob.wizardry.client.gui.config.SpellHUDSkinChooserEntry;
import electroblob.wizardry.client.gui.handbook.GuiWizardHandbook;
import electroblob.wizardry.client.model.ModelRobeArmour;
import electroblob.wizardry.client.model.ModelSageArmour;
import electroblob.wizardry.client.model.ModelWizardArmour;
import electroblob.wizardry.client.particle.*;
import electroblob.wizardry.client.particle.ParticleWizardry.IWizardryParticleFactory;
@@ -39,6 +41,7 @@ import electroblob.wizardry.item.ItemSpellBook;
import electroblob.wizardry.item.ItemWand;
import electroblob.wizardry.packet.*;
import electroblob.wizardry.registry.Spells;
import electroblob.wizardry.registry.WizardryItems.Materials;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.spell.*;
import electroblob.wizardry.tileentity.*;
@@ -65,6 +68,7 @@ import net.minecraft.entity.monster.EntityBlaze;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.ContainerMerchant;
import net.minecraft.item.Item;
import net.minecraft.item.ItemArmor.ArmorMaterial;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityDispenser;
@@ -120,8 +124,16 @@ public class ClientProxy extends CommonProxy {
}
}
// Armour Model
public static final ModelBiped WIZARD_ARMOUR_MODEL = new ModelWizardArmour(0.75f);
// Armour Models
// Can't use an EnumMap here because our additional values aren't really part of the enum
public static final Map<ArmorMaterial, ModelBiped> wizard_armour_models = new HashMap<>();
static {
wizard_armour_models.put(Materials.SILK, new ModelWizardArmour(0.75f));
wizard_armour_models.put(Materials.SAGE, new ModelSageArmour(0.75f));
wizard_armour_models.put(Materials.BATTLEMAGE, new ModelRobeArmour(0.75f, true));
wizard_armour_models.put(Materials.WARLOCK, new ModelRobeArmour(0.75f, false));
}
/** The wrap width for standard multi-line descriptions (see {@link ClientProxy#addMultiLineDescription(List, String, Style, Object...)}). */
private static final int TOOLTIP_WRAP_WIDTH = 140;
@@ -130,8 +142,8 @@ public class ClientProxy extends CommonProxy {
// ===============================================================================================================
@Override
public ModelBiped getWizardArmourModel(){
return WIZARD_ARMOUR_MODEL;
public ModelBiped getWizardArmourModel(ArmorMaterial material){
return wizard_armour_models.get(material);
}
@Override
@@ -1,5 +1,6 @@
package electroblob.wizardry.client.gui.config;
import com.mojang.realmsclient.gui.ChatFormatting;
import electroblob.wizardry.Settings;
import electroblob.wizardry.Wizardry;
import net.minecraft.client.gui.GuiScreen;
@@ -18,9 +19,13 @@ import java.util.List;
public class GuiConfigWizardry extends GuiConfig {
public GuiConfigWizardry(GuiScreen parent){
super(parent, getConfigEntries(), Wizardry.MODID, false, false,
Wizardry.NAME + " - " + I18n.format("config." + Wizardry.MODID + ".title.general"));
// this.titleLine2 = "File location: " + Wizardry.config.getConfigFile().getAbsolutePath();
if(Wizardry.settings.hasRedundantKeys()){
this.titleLine2 = ChatFormatting.GOLD.toString() + I18n.format("config." + Wizardry.MODID + ".redundant_keys");
}
}
private static List<IConfigElement> getConfigEntries(){
@@ -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,66 @@
package electroblob.wizardry.client.model;
import electroblob.wizardry.block.BlockStatue;
import net.minecraft.client.model.ModelRenderer;
import net.minecraft.entity.Entity;
public class ModelRobeArmour extends ModelArmourFixer {
ModelRenderer robe;
private boolean showHeadWithBody;
public ModelRobeArmour(float delta, boolean showHeadWithBody){
super(delta, 0, 64, 64);
this.showHeadWithBody = showHeadWithBody;
bipedBody = new ModelRenderer(this, 16, 16);
bipedBody.addBox(-4F, 0F, -2F, 8, 11, 4, delta);
bipedBody.setRotationPoint(0F, 0F, 0F);
bipedBody.setTextureSize(64, 64);
bipedBody.mirror = true;
setRotation(bipedBody, 0F, 0F, 0F);
robe = new ModelRenderer(this, 40, 32);
robe.addBox(-4F, 0F, -2F, 8, 9, 4, delta);
robe.setRotationPoint(0F, 12, 0F); // 12.5 accounts for the expansion of each box
robe.setTextureSize(64, 64);
robe.mirror = true;
setRotation(robe, 0F, 0F, 0F);
}
public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5){
if(entity.isInvisible() && !entity.getEntityData().getBoolean(BlockStatue.PETRIFIED_NBT_KEY)
&& !entity.getEntityData().getBoolean(BlockStatue.FROZEN_NBT_KEY)) return;
super.render(entity, f, f1, f2, f3, f4, f5);
setRotationAngles(f, f1, f2, f3, f4, f5, entity);
this.robe.render(f5);
}
private void setRotation(ModelRenderer model, float x, float y, float z){
model.rotateAngleX = x;
model.rotateAngleY = y;
model.rotateAngleZ = z;
}
public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5, Entity entity){
super.setRotationAngles(f, f1, f2, f3, f4, f5, entity);
this.robe.showModel = this.bipedBody.showModel;
if(showHeadWithBody) this.bipedHead.showModel = this.bipedBody.showModel;
if(this.isSneak){
//this.robe.rotationPointY = 10.5f;
this.robe.rotationPointZ = 4;
}else{
//this.robe.rotationPointY = 12.5f;
this.robe.rotationPointZ = 0;
}
// The bottom part of the robe takes the y rotation from the rest of the robe but the x/z rotation
// from the average of the two legs
this.robe.rotateAngleX = (this.bipedLeftLeg.rotateAngleX + this.bipedRightLeg.rotateAngleX) / 2f;
this.robe.rotateAngleY = this.bipedBody.rotateAngleY;
this.robe.rotateAngleZ = (this.bipedLeftLeg.rotateAngleZ + this.bipedRightLeg.rotateAngleZ) / 2f;
}
}
@@ -0,0 +1,146 @@
package electroblob.wizardry.client.model;
import electroblob.wizardry.block.BlockStatue;
import net.minecraft.client.model.ModelRenderer;
import net.minecraft.entity.Entity;
public class ModelSageArmour extends ModelArmourFixer {
ModelRenderer hatBrim;
ModelRenderer hatSegment1;
ModelRenderer hatSegment2;
ModelRenderer hatSegment3;
ModelRenderer hatSegment4;
ModelRenderer hatSegment5;
ModelRenderer hatSegment6;
ModelRenderer robe;
ModelRenderer collar;
public ModelSageArmour(float delta){
super(delta, 0, 64, 64);
// This is necessary to stop the head from scaling.
this.bipedHead = new ModelRenderer(this, 0, 0);
// The hat layer has an offset of 0.5, so 0.6 is about the smallest we can get away with
this.bipedHead.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, 0.6f);
this.bipedHead.setRotationPoint(0.0F, 0.0F + 0, 0.0F);
hatBrim = new ModelRenderer(this, 10, 45);
// Making the height 1 stops the top and bottom z-fighting when the hat is enchanted
hatBrim.addBox(-9F, -5.7F, -9F, 18, 1, 18, 0.6f);
hatBrim.setRotationPoint(0F, 0F, 0F);
hatBrim.setTextureSize(64, 64);
hatBrim.mirror = true;
setRotation(hatBrim, 0F, 0F, 0F);
hatSegment1 = new ModelRenderer(this, 0, 42);
hatSegment1.addBox(0F, 0F, 0F, 6, 2, 6, 0.2f);
hatSegment1.setRotationPoint(-3F, -10.6F, -3F);
hatSegment1.setTextureSize(64, 64);
hatSegment1.mirror = true;
setRotation(hatSegment1, -0.1396263F, 0F, 0F);
hatSegment2 = new ModelRenderer(this, 0, 50);
hatSegment2.addBox(0F, 0F, 0F, 5, 2, 5, 0.1f);
hatSegment2.setRotationPoint(-2.5F, -12.13333F, -2F);
hatSegment2.setTextureSize(64, 64);
hatSegment2.mirror = true;
setRotation(hatSegment2, -0.2443461F, 0F, 0F);
hatSegment3 = new ModelRenderer(this, 0, 57);
hatSegment3.addBox(0F, 0F, 0F, 4, 2, 4);
hatSegment3.setRotationPoint(-2F, -13.6F, -1F);
hatSegment3.setTextureSize(64, 64);
hatSegment3.mirror = true;
setRotation(hatSegment3, -0.4014257F, 0F, 0F);
hatSegment4 = new ModelRenderer(this, 16, 58);
hatSegment4.addBox(0F, 0F, 0F, 3, 2, 3);
hatSegment4.setRotationPoint(-1.5F, -14.6F, 0F);
hatSegment4.setTextureSize(64, 64);
hatSegment4.mirror = true;
setRotation(hatSegment4, -0.5759587F, 0F, 0F);
hatSegment5 = new ModelRenderer(this, 20, 54);
hatSegment5.addBox(0F, 0F, 0F, 2, 2, 2);
hatSegment5.setRotationPoint(-1F, -14.6F, 0F);
hatSegment5.setTextureSize(64, 64);
hatSegment5.mirror = true;
setRotation(hatSegment5, 0.3316126F, 0F, 0F);
hatSegment6 = new ModelRenderer(this, 20, 50);
hatSegment6.addBox(0F, 0F, 0F, 1, 1, 3);
hatSegment6.setRotationPoint(-0.5F, -15.1F, 2F);
hatSegment6.setTextureSize(64, 64);
hatSegment6.mirror = true;
setRotation(hatSegment6, -0.5585054F, 0F, 0F);
bipedBody = new ModelRenderer(this, 16, 16);
bipedBody.addBox(-4F, 0F, -2F, 8, 11, 4, delta);
bipedBody.setRotationPoint(0F, 0F, 0F);
bipedBody.setTextureSize(64, 64);
bipedBody.mirror = true;
setRotation(bipedBody, 0F, 0F, 0F);
robe = new ModelRenderer(this, 40, 32);
robe.addBox(-4F, 0F, -2F, 8, 9, 4, delta);
robe.setRotationPoint(0F, 12, 0F); // 12.5 accounts for the expansion of each box
robe.setTextureSize(64, 64);
robe.mirror = true;
setRotation(robe, 0F, 0F, 0F);
collar = new ModelRenderer(this, 0, 32);
collar.addBox(-7F, 0F, -2F, 14, 4, 4, 1);
collar.setRotationPoint(0F, 0F, 0F);
collar.setTextureSize(64, 64);
collar.mirror = true;
setRotation(collar, 0F, 0F, 0F);
// Makes the hat rotate with the head.
bipedHead.addChild(hatBrim);
bipedHead.addChild(hatSegment1);
bipedHead.addChild(hatSegment2);
bipedHead.addChild(hatSegment3);
bipedHead.addChild(hatSegment4);
bipedHead.addChild(hatSegment5);
bipedHead.addChild(hatSegment6);
bipedBody.addChild(collar);
}
public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5){
if(entity.isInvisible() && !entity.getEntityData().getBoolean(BlockStatue.PETRIFIED_NBT_KEY)
&& !entity.getEntityData().getBoolean(BlockStatue.FROZEN_NBT_KEY)) return;
super.render(entity, f, f1, f2, f3, f4, f5);
setRotationAngles(f, f1, f2, f3, f4, f5, entity);
this.robe.render(f5);
}
private void setRotation(ModelRenderer model, float x, float y, float z){
model.rotateAngleX = x;
model.rotateAngleY = y;
model.rotateAngleZ = z;
}
public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5, Entity entity){
super.setRotationAngles(f, f1, f2, f3, f4, f5, entity);
this.robe.showModel = this.bipedBody.showModel;
if(this.isSneak){
//this.robe.rotationPointY = 10.5f;
this.robe.rotationPointZ = 4;
}else{
//this.robe.rotationPointY = 12.5f;
this.robe.rotationPointZ = 0;
}
// The bottom part of the robe takes the y rotation from the rest of the robe but the x/z rotation
// from the average of the two legs
this.robe.rotateAngleX = (this.bipedLeftLeg.rotateAngleX + this.bipedRightLeg.rotateAngleX) / 2f;
this.robe.rotateAngleY = this.bipedBody.rotateAngleY;
this.robe.rotateAngleZ = (this.bipedLeftLeg.rotateAngleZ + this.bipedRightLeg.rotateAngleZ) / 2f;
}
}
@@ -22,10 +22,6 @@ public final class Constants {
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;
/** The fraction by which costs are reduced for each piece of matching armour. */
public static final float COST_REDUCTION_PER_ARMOUR = 0.15f;
/** The extra fraction by which costs are reduced for a full set of elemental armour. */
public static final float FULL_ARMOUR_SET_BONUS = 0.2f;
/** The fraction by which spell duration is increased for each level of duration upgrade. */
public static final float DURATION_INCREASE_PER_LEVEL = 0.25f;
/** The fraction by which spell range is increased for each level of range upgrade. */
@@ -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
@@ -45,7 +45,8 @@ public interface Imbuement {
public static void onLivingDropsEvent(LivingDropsEvent event){
// Instantly disenchants an imbued weapon if it is dropped when the player dies.
for(EntityItem item : event.getDrops()){
removeImbuements(item.getItem());
// Apparently some mods don't behave and shove null items in the list, quite why I have no idea
if(item != null) removeImbuements(item.getItem());
}
}
@@ -68,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.
@@ -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;
@@ -225,6 +225,7 @@ public class EntityRemnant extends EntityMob {
@Override
public void startExecuting(){
EntityLivingBase entitylivingbase = EntityRemnant.this.getAttackTarget();
if(entitylivingbase == null) return;
Vec3d vec3d = entitylivingbase.getPositionEyes(1.0F);
EntityRemnant.this.moveHelper.setMoveTo(vec3d.x, vec3d.y, vec3d.z, 1.0D);
EntityRemnant.this.setAttacking(true);
@@ -241,6 +242,8 @@ public class EntityRemnant extends EntityMob {
EntityLivingBase entitylivingbase = EntityRemnant.this.getAttackTarget();
if(entitylivingbase == null) return;
if(EntityRemnant.this.getEntityBoundingBox().intersects(entitylivingbase.getEntityBoundingBox())){
EntityRemnant.this.attackEntityAsMob(entitylivingbase);
EntityRemnant.this.setAttacking(false);
@@ -81,11 +81,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 +103,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 +185,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
@@ -4,9 +4,14 @@ import electroblob.wizardry.Wizardry;
import electroblob.wizardry.registry.Spells;
import electroblob.wizardry.spell.Spell;
import electroblob.wizardry.util.EntityUtils;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.Entity;
import net.minecraft.entity.monster.EntityGhast;
import net.minecraft.entity.projectile.EntityLargeFireball;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.DamageSource;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World;
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
@@ -47,6 +52,15 @@ public class EntityLargeMagicFireball extends EntityMagicFireball {
return damage == -1 ? Spells.greater_fireball.getProperty(Spell.DAMAGE).floatValue() : damage;
}
@Override
protected DamageSource getDamageSource(Entity entityHit){
if(entityHit instanceof EntityGhast){
return MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.MAGIC).setProjectile();
}else{
return super.getDamageSource(entityHit);
}
}
@Override
protected void onImpact(RayTraceResult rayTrace){
@@ -10,6 +10,7 @@ import electroblob.wizardry.util.ParticleBuilder;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.monster.EntityGhast;
import net.minecraft.entity.projectile.EntitySmallFireball;
import net.minecraft.init.Blocks;
import net.minecraft.nbt.NBTTagCompound;
@@ -75,9 +76,9 @@ public class EntityMagicFireball extends EntityMagicProjectile {
float damage = getDamage() * damageMultiplier;
entityHit.attackEntityFrom(
MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.FIRE).setProjectile(),
damage);
DamageSource source = getDamageSource(entityHit);
entityHit.attackEntityFrom(source, damage);
if(!MagicDamage.isEntityImmune(DamageType.FIRE, entityHit) && getBurnDuration() > 0)
entityHit.setFire(getBurnDuration());
@@ -99,6 +100,10 @@ public class EntityMagicFireball extends EntityMagicProjectile {
}
}
protected DamageSource getDamageSource(Entity entityHit){
return MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.FIRE).setProjectile();
}
@Override
public void onUpdate(){
@@ -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 */
ItemStack input;
/** The elements of the four receptacles */
Element[] receptacleElements;
/** A reference to the current world object (may be null if {@code fullLootGen} is false) */
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) */
EntityPlayer lastUser;
/** The resulting item stack of the imbuement process */
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;
}
}
@@ -73,7 +73,9 @@ public class WizardryJEIPlugin implements IModPlugin {
addItemInfo(registry, WizardryItems.identification_scroll, ".desc_extended");
addItemInfo(registry, WizardryItems.spell_book);
addItemInfo(registry, WizardryItems.scroll);
addItemInfo(registry, WizardryItems.armour_upgrade, ".desc_extended");
addItemInfo(registry, WizardryItems.resplendent_thread, ".desc_extended");
addItemInfo(registry, WizardryItems.crystal_silver_plating, ".desc_extended");
addItemInfo(registry, WizardryItems.ethereal_crystalweave, ".desc_extended");
addItemInfo(registry, WizardryItems.purifying_elixir, ".desc_extended");
addItemInfo(registry, WizardryItems.astral_diamond);
addItemInfo(registry, WizardryItems.ruined_spell_book);
@@ -99,7 +99,9 @@ public class ContainerArcaneWorkbench extends Container implements ISpellSortabl
Set<Item> upgrades = new HashSet<>(WandHelper.getSpecialUpgrades()); // Can't be done statically.
upgrades.add(WizardryItems.arcane_tome);
upgrades.add(WizardryItems.armour_upgrade);
upgrades.add(WizardryItems.resplendent_thread);
upgrades.add(WizardryItems.crystal_silver_plating);
upgrades.add(WizardryItems.ethereal_crystalweave);
this.addSlotToContainer(new SlotItemList(tileentity, UPGRADE_SLOT, 147, 17, 1, upgrades.toArray(new Item[0])))
.setBackgroundName(EMPTY_SLOT_UPGRADE.toString());
@@ -133,7 +133,6 @@ public class ContainerBookshelf extends Container {
registerBookItem(WizardryItems.scroll);
registerBookItem(WizardryItems.blank_scroll);
registerBookItem(WizardryItems.identification_scroll);
registerBookItem(WizardryItems.armour_upgrade);
// Not using the map in WandHelper for consistency with BlockBookshelf (again, addons must add theirs manually)
registerBookItem(WizardryItems.storage_upgrade);
registerBookItem(WizardryItems.siphon_upgrade);
@@ -34,7 +34,7 @@ public class ItemArmourUpgrade extends Item {
@Override
@SideOnly(Side.CLIENT)
public void addInformation(ItemStack stack, @Nullable World worldIn, List<String> tooltip, net.minecraft.client.util.ITooltipFlag flagIn) {
Wizardry.proxy.addMultiLineDescription(tooltip, "item." + this.getRegistryName() + ".desc", "\u00A7d");
Wizardry.proxy.addMultiLineDescription(tooltip, "item." + this.getRegistryName() + ".desc");
}
}
@@ -123,6 +123,8 @@ public class ItemArtefact extends Item {
this.enabled = enabled;
}
public boolean isEnabled() { return enabled; }
@Override
public EnumRarity getRarity(ItemStack stack){
return rarity;
@@ -344,6 +346,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();
@@ -5,14 +5,19 @@ import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.registry.WizardryTabs;
import electroblob.wizardry.util.EntityUtils;
import electroblob.wizardry.util.InventoryUtils;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.item.EnumRarity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@@ -25,15 +30,17 @@ public class ItemManaFlask extends Item {
public enum Size {
SMALL(75, EnumRarity.COMMON),
MEDIUM(700, EnumRarity.COMMON),
LARGE(1400, EnumRarity.RARE);
SMALL(75, 25, EnumRarity.COMMON),
MEDIUM(350, 40, EnumRarity.COMMON),
LARGE(1400, 60, EnumRarity.RARE);
public int capacity;
public int useDuration;
public EnumRarity rarity;
Size(int capacity, EnumRarity rarity){
Size(int capacity, int useDuration, EnumRarity rarity){
this.capacity = capacity;
this.useDuration = useDuration;
this.rarity = rarity;
}
}
@@ -58,6 +65,16 @@ public class ItemManaFlask extends Item {
Wizardry.proxy.addMultiLineDescription(tooltip, "item." + Wizardry.MODID + ":mana_flask.desc", size.capacity);
}
@Override
public EnumAction getItemUseAction(ItemStack stack){
return EnumAction.BLOCK;
}
@Override
public int getMaxItemUseDuration(ItemStack stack){
return size.useDuration;
}
@Override
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand){
@@ -66,6 +83,47 @@ public class ItemManaFlask extends Item {
List<ItemStack> stacks = InventoryUtils.getPrioritisedHotbarAndOffhand(player);
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))){
if(player.capabilities.isCreativeMode){
findAndChargeItem(flask, player);
}else{
player.setActiveHand(hand);
}
return new ActionResult<>(EnumActionResult.SUCCESS, flask);
}else{
return new ActionResult<>(EnumActionResult.FAIL, flask);
}
}
@Override
public void onUsingTick(ItemStack stack, EntityLivingBase player, int count){
if(player.world.isRemote){
float f = count/(float)getMaxItemUseDuration(stack);
Vec3d pos = player.getPositionEyes(0).subtract(0, 0.2, 0).add(player.getLookVec().scale(0.6));
Vec3d delta = new Vec3d(0, 0.2 * f, 0).rotatePitch(count * 0.5f).rotateYaw((float)Math.toRadians(90 - player.rotationYawHead));
ParticleBuilder.create(Type.DUST).pos(pos.add(delta)).vel(delta.scale(0.2)).time(12 + player.world.rand.nextInt(6))
.clr(1, 1, 0.65f).fade(0.7f, 0, 1).spawn(player.world);
}
}
@Override
public ItemStack onItemUseFinish(ItemStack stack, World world, EntityLivingBase entity){
if(entity instanceof EntityPlayer){
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))
@@ -78,13 +136,9 @@ public class ItemManaFlask extends Item {
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()) flask.shrink(1);
if(!player.isCreative()) stack.shrink(1);
player.getCooldownTracker().setCooldown(this, 20);
return new ActionResult<>(EnumActionResult.SUCCESS, flask);
}else{
return new ActionResult<>(EnumActionResult.FAIL, flask);
}
}
}
@@ -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;
@@ -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);
}
}
}
@@ -101,7 +101,7 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
|| s.getItemUseAction() == SpellActions.GRAPPLE
|| s.getItemUseAction() == SpellActions.SUMMON) ? 1 : 0);
}
@Override
public Spell getCurrentSpell(ItemStack stack){
return WandHelper.getCurrentSpell(stack);
@@ -709,7 +709,7 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
if(player != null) WizardData.get(player).setTierReached(tier);
ItemStack newWand = new ItemStack(WizardryItems.getWand(tier, this.element));
ItemStack newWand = new ItemStack(getWand(tier, this.element));
newWand.setTagCompound(wand.getTagCompound());
// This needs to be done after copying the tag compound so the mana capacity for the new wand
// takes storage upgrades into account
@@ -783,6 +783,30 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
return wand;
}
/**
* Helper method to return the appropriate wand based on tier and element. This replaces the cumbersome wand map in
* {@link WizardryItems} by accessing the item registry dynamically by generating the registry name on the fly.
* <p></p>
* <i><b>This method will only return wands from the base mod.</b> It is unlikely that addons will need it, but it
* has been left public just in case. The intention is that this method is only used where there is no alternative.</i>
*
* @param tier The tier of the wand required.
* @param element The element of the wand required. Null will be converted to {@link Element#MAGIC}.
* @return The wand item which corresponds to the given tier and element, or null if no such item exists.
* @throws NullPointerException if the given tier is null.
*/
// As noted above, in a few SPECIFIC cases this method is necessary (without using a data-driven system, at least,
// which I'm not going to spend the time making in the near future). Wizard trades and gear have been left using the
// WizardryItems version because they need to be replaced with a better system that doesn't use this at all.
public static Item getWand(Tier tier, Element element){
if(tier == null) throw new NullPointerException("The given tier cannot be null.");
if(element == null) element = Element.MAGIC;
String registryName = tier == Tier.NOVICE && element == Element.MAGIC ? "magic" : tier.getUnlocalisedName();
if(element != Element.MAGIC) registryName = registryName + "_" + element.getName();
registryName = registryName + "_wand";
return Item.REGISTRY.getObject(new ResourceLocation(Wizardry.MODID, registryName));
}
@Override
public boolean onApplyButtonPressed(EntityPlayer player, Slot centre, Slot crystals, Slot upgrade, Slot[] spellBooks){
@@ -791,7 +815,7 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
if(upgrade.getHasStack()){
ItemStack original = centre.getStack().copy();
centre.putStack(this.applyUpgrade(player, centre.getStack(), upgrade.getStack()));
changed = ItemStack.areItemStacksEqual(centre.getStack(), original);
changed = !ItemStack.areItemStacksEqual(centre.getStack(), original);
}
// Reads NBT spell metadata array to variable, edits this, then writes it back to NBT.
@@ -1,6 +1,6 @@
package electroblob.wizardry.item;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Streams;
import electroblob.wizardry.Wizardry;
@@ -8,10 +8,13 @@ import electroblob.wizardry.client.DrawingUtils;
import electroblob.wizardry.constants.Constants;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.event.SpellCastEvent;
import electroblob.wizardry.registry.WizardryAdvancementTriggers;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardryItems.Materials;
import electroblob.wizardry.registry.WizardryPotions;
import electroblob.wizardry.registry.WizardryRecipes;
import electroblob.wizardry.registry.WizardryTabs;
import electroblob.wizardry.spell.Spell;
import electroblob.wizardry.util.EntityUtils.Operations;
import electroblob.wizardry.util.InventoryUtils;
import electroblob.wizardry.util.SpellModifiers;
import net.minecraft.enchantment.Enchantment;
@@ -24,13 +27,17 @@ import net.minecraft.entity.ai.attributes.AttributeModifier;
import net.minecraft.entity.ai.attributes.IAttributeInstance;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.inventory.EntityEquipmentSlot.Type;
import net.minecraft.inventory.Slot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemArmor;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.potion.PotionEffect;
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.event.entity.living.LivingEquipmentChangeEvent;
import net.minecraftforge.event.entity.living.LivingSetAttackTargetEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.EventPriority;
@@ -40,21 +47,94 @@ import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nullable;
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
public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IManaStoringItem {
// VanillaCopy, ItemArmor has this set to private for some reason.
public 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")};
// Damage reduction values that used to be in WizardryItems.SILK [feet, legs, chest, head]
private static int[] reductions = new int[]{2, 4, 5, 2};
public Element element;
// Full set bonuses
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.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;
/** The item that upgrades regular wizard armour into this class of armour. */
final Supplier<Item> upgradeItem;
/** The fraction by which spell cost is reduced for each armour piece of this class with the matching element. */
final float elementalCostReduction;
/** The fraction by which spell cooldown is reduced for each armour piece of this class. */
final float cooldownReduction;
/** The first part of the texture filenames for this armour class. Also defines certain translation keys. */
final String name;
/** The middle part of each item name (in the registry) for this armour class, e.g. "hat" or "chestplate". */
final Map<EntityEquipmentSlot, String> armourPieceNames;
ArmourClass(ArmorMaterial material, Supplier<Item> upgradeItem, String name, float elementalCostReduction,
float cooldownReduction, String... armourPieceNames){
this.material = material;
this.upgradeItem = upgradeItem;
this.name = name;
this.elementalCostReduction = elementalCostReduction;
this.cooldownReduction = cooldownReduction;
if(armourPieceNames.length != 4) throw new IllegalArgumentException("armourPieceNames must have a length of 4");
this.armourPieceNames = new EnumMap<>(EntityEquipmentSlot.class);
this.armourPieceNames.put(EntityEquipmentSlot.HEAD, armourPieceNames[0]);
this.armourPieceNames.put(EntityEquipmentSlot.CHEST, armourPieceNames[1]);
this.armourPieceNames.put(EntityEquipmentSlot.LEGS, armourPieceNames[2]);
this.armourPieceNames.put(EntityEquipmentSlot.FEET, armourPieceNames[3]);
}
}
public Element element; // Should be final, but isn't for backwards compatibility
public final ArmourClass armourClass;
@Deprecated // Retained for backwards-compatibility with addons, will be removed in future
public ItemWizardArmour(ArmorMaterial material, int renderIndex, EntityEquipmentSlot armourType, Element element){
super(material, renderIndex, armourType);
this.armourClass = ArmourClass.WIZARD;
this.element = element;
setCreativeTab(WizardryTabs.GEAR);
WizardryRecipes.addToManaFlaskCharging(this);
}
public ItemWizardArmour(ArmourClass armourClass, EntityEquipmentSlot armourType, Element element){
super(armourClass.material, 1, armourType);
this.armourClass = armourClass;
this.element = element;
setCreativeTab(WizardryTabs.GEAR);
WizardryRecipes.addToManaFlaskCharging(this);
@@ -94,15 +174,75 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
@SideOnly(Side.CLIENT)
public void addInformation(ItemStack stack, World world, List<String> tooltip, net.minecraft.client.util.ITooltipFlag advanced){
if(stack.hasTagCompound() && stack.getTagCompound().getBoolean("legendary"))
tooltip.add(Wizardry.proxy.translate("item." + Wizardry.MODID + ":wizard_armour.legendary",
new Style().setColor(TextFormatting.LIGHT_PURPLE)));
if(element != null){
tooltip.add(Wizardry.proxy.translate("item." + Wizardry.MODID + ":wizard_armour.buff",
tooltip.add(Wizardry.proxy.translate("item." + Wizardry.MODID + ":wizard_armour.element_cost_reduction",
new Style().setColor(TextFormatting.DARK_GRAY),
(int)(Constants.COST_REDUCTION_PER_ARMOUR * 100), element.getDisplayName()));
(int)(armourClass.elementalCostReduction * 100), element.getDisplayName()));
}
if(armourClass == ArmourClass.SAGE){
tooltip.add(Wizardry.proxy.translate("item." + Wizardry.MODID + ":wizard_armour.enchantability",
new Style().setColor(TextFormatting.BLUE)));
}
if(armourClass.cooldownReduction > 0){
tooltip.add(Wizardry.proxy.translate("item." + Wizardry.MODID + ":wizard_armour.cooldown_reduction",
new Style().setColor(TextFormatting.DARK_GRAY), (int)(armourClass.cooldownReduction * 100)));
}
if(armourClass != ArmourClass.WIZARD){
tooltip.add(Wizardry.proxy.translate("item." + Wizardry.MODID + ":wizard_armour.full_set",
new Style().setColor(TextFormatting.AQUA)));
Object args = new Object[0];
if(armourClass == ArmourClass.SAGE) args = (int)(SAGE_OTHER_COST_REDUCTION * 100);
if(armourClass == ArmourClass.WARLOCK) args = (int)(WARLOCK_SPEED_BOOST * 100);
tooltip.add(Wizardry.proxy.translate("item." + Wizardry.MODID + ":" + armourClass.name
+ "_armour.full_set_bonus", new Style().setColor(TextFormatting.AQUA), args));
}
}
@Override
public void onArmorTick(World world, EntityPlayer player, ItemStack itemStack){
if(armorType == EntityEquipmentSlot.HEAD && isWearingFullSet(player, element, ArmourClass.BATTLEMAGE)
&& player.ticksExisted % 20 == 0){
player.addPotionEffect(new PotionEffect(WizardryPotions.ward, 219, 0, true, false));
}
}
/**
* Allows this armour piece to change the modifiers for spells cast while wearing it. This is called once for
* <b>each piece of wizard armour</b> the caster is wearing. This means if you need to apply a full set bonus, you
* should have only one of the pieces handle it (by convention, this is usually the helmet, but it doesn't matter).
* <p></p>
* <i>N.B. The modifiers object passed into this method is not the actual one from the spell cast event. It is a
* blank one local to armour that then gets combined with the actual one via
* {@link SpellModifiers#combine(SpellModifiers)} after all four pieces have been processed. This is important as it
* allows armour modifiers to stack linearly. This means the values should be <b>added/subtracted rather than multiplied.</b></i>
* @param caster The entity casting the spell and wearing the armour.
* @param spell The spell being cast.
* @param modifiers The modifiers specific to armour to apply to the global ones after all four slots are processed.
*/
protected void applySpellModifiers(EntityLivingBase caster, Spell spell, SpellModifiers modifiers){
if(spell.getElement() == this.element){
modifiers.set(SpellModifiers.COST, modifiers.get(SpellModifiers.COST) - armourClass.elementalCostReduction, false);
}
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(armourClass == ArmourClass.SAGE && spell.getElement() != this.element){
modifiers.set(SpellModifiers.COST, 1 - SAGE_OTHER_COST_REDUCTION, false);
}
}
}
@Override
@@ -118,25 +258,18 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
// Legs use modelBiped
if(armourSlot == EntityEquipmentSlot.LEGS && !entityLiving.isInvisible()) return null;
return Wizardry.proxy.getWizardArmourModel();
return Wizardry.proxy.getWizardArmourModel(getArmorMaterial());
}
@Override
public String getArmorTexture(ItemStack stack, Entity entity, EntityEquipmentSlot slot, String type){
// Returns a completely transparent texture if the player is invisible. This is such an annoyingly easy
// fix, considering how long I spent trying to do this before - a bit of lateral thinking was all it took.
// Do note however that a texture pack could override this.
// if(entity instanceof EntityLivingBase && entity.isInvisible() && !entity.getEntityData().getBoolean(BlockStatue.PETRIFIED_NBT_KEY))
// return "ebwizardry:textures/armour/invisible_armour.png";
String s = armourClass.name + "_armour";
String s = "wizard_armour";
if(Wizardry.tisTheSeason){
if(Wizardry.tisTheSeason && armourClass == ArmourClass.WIZARD){
s = s + "_festive";
}else{
if(this.element != null) s = s + "_" + this.element.getName();
if(stack.hasTagCompound() && stack.getTagCompound().getBoolean("legendary")) s = "legendary_" + s;
}
if(slot == EntityEquipmentSlot.LEGS) s = s + "_legs";
@@ -155,34 +288,6 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
return !(enchantment instanceof EnchantmentMending) && super.canApplyAtEnchantingTable(stack, enchantment);
}
/**
* Properly handles the defence value of the armour. This method is responsible for the tooltip on top of
* the armour value. It is also what handles armour toughness.
*/
@Override
public Multimap<String, AttributeModifier> getAttributeModifiers(EntityEquipmentSlot slot, ItemStack stack){
Multimap<String, AttributeModifier> map = HashMultimap.create();
if(!this.isManaEmpty(stack) && this.armorType == slot){
int defense = reductions[slot.getIndex()];
float toughness = 0f;
if(stack.hasTagCompound() && stack.getTagCompound().getBoolean("legendary")) {
defense = ArmorMaterial.DIAMOND.getDamageReductionAmount(slot);
toughness = ArmorMaterial.DIAMOND.getToughness();
}
map.put(SharedMonsterAttributes.ARMOR.getName(), new AttributeModifier(ARMOR_MODIFIERS[slot.getIndex()],
"Armor modifier", defense, 0));
map.put(SharedMonsterAttributes.ARMOR.getName(), new AttributeModifier(ARMOR_MODIFIERS[slot.getIndex()],
"Armor toughness", toughness, 0));
}
return map;
}
// Workbench stuff
@Override
@@ -196,17 +301,17 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
@Override
public ItemStack applyUpgrade(@Nullable EntityPlayer player, ItemStack stack, ItemStack upgrade){
// Applies legendary upgrade
if(upgrade.getItem() == WizardryItems.armour_upgrade){
if(!stack.hasTagCompound()){
stack.setTagCompound(new NBTTagCompound());
}
if(!stack.getTagCompound().hasKey("legendary")){
stack.getTagCompound().setBoolean("legendary", true);
upgrade.shrink(1);
if(player != null) WizardryAdvancementTriggers.legendary.triggerFor(player);
// Apply class upgrades
if(this.armourClass == ArmourClass.WIZARD){
for(ArmourClass armourClass : ArmourClass.values()){
if(upgrade.getItem() == armourClass.upgradeItem.get()){
Item newArmour = getArmour(this.element, armourClass, this.armorType);
ItemStack newStack = new ItemStack(newArmour);
((ItemWizardArmour)newArmour).setMana(newStack, this.getMana(stack));
newStack.setTagCompound(stack.getTagCompound());
upgrade.shrink(1);
return newStack;
}
}
}
@@ -221,7 +326,7 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
if(upgrade.getHasStack()){
ItemStack original = centre.getStack().copy();
centre.putStack(this.applyUpgrade(player, centre.getStack(), upgrade.getStack()));
changed = ItemStack.areItemStacksEqual(centre.getStack(), original);
changed = !ItemStack.areItemStacksEqual(centre.getStack(), original);
}
// Charges armour by appropriate amount
@@ -252,34 +357,43 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
// Event Handlers
// @SubscribeEvent
// public static void onLivingUpdateEvent(LivingUpdateEvent event){
//
// if(event.getEntityLiving() instanceof EntityPlayer){
//
// EntityPlayer player = (EntityPlayer)event.getEntityLiving();
//
// for(ItemStack stack : player.getArmorInventoryList()){
// if(!(stack.getItem() instanceof ItemWizardArmour)){
// return; // If any of the armour slots doesn't contain wizard armour, don't trigger the achievement.
// }
// }
// // If it gets this far, then all slots must be wizard armour, so trigger the achievement.
// WizardryAdvancementTriggers.armour_set.triggerFor(player);
// }
// }
// Can't use Item#getItemAttributeModifiers because it's not player-sensitive, grrr
@SubscribeEvent
public static void onLivingEquipmentChangeEvent(LivingEquipmentChangeEvent event){
IAttributeInstance movementSpeed = event.getEntityLiving().getAttributeMap().getAttributeInstance(SharedMonsterAttributes.MOVEMENT_SPEED);
if(isWearingFullSet(event.getEntityLiving(), null, ArmourClass.WARLOCK)){
// 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));
}
}else{
movementSpeed.removeModifier(WARLOCK_SPEED_BOOST_UUID);
}
}
@SubscribeEvent(priority = EventPriority.LOW)
public static void onSpellCastPreEvent(SpellCastEvent.Pre event){
// Armour cost reduction
if(event.getCaster() == null) return;
int armourPieces = getMatchingArmourCount(event.getCaster(), event.getSpell().getElement());
float multiplier = 1f - armourPieces * Constants.COST_REDUCTION_PER_ARMOUR;
if(armourPieces == InventoryUtils.ARMOUR_SLOTS.length) multiplier -= Constants.FULL_ARMOUR_SET_BONUS;
event.getModifiers().set(SpellModifiers.COST, event.getModifiers().get(SpellModifiers.COST) * multiplier, false);
final SpellModifiers armourModifiers = new SpellModifiers();
Arrays.stream(InventoryUtils.ARMOUR_SLOTS).map(s -> event.getCaster().getItemStackFromSlot(s).getItem())
.filter(i -> i instanceof ItemWizardArmour)
.forEach(i -> ((ItemWizardArmour)i).applySpellModifiers(event.getCaster(), event.getSpell(), armourModifiers));
event.getModifiers().combine(armourModifiers);
}
/** Counts the number of armour pieces the given entity is wearing that match the given element. */
/**
* Counts the number of armour pieces the given entity is wearing that match the given element.
* @deprecated in favour of {@link ItemWizardArmour#applySpellModifiers(EntityLivingBase, Spell, SpellModifiers)}
* and {@link ItemWizardArmour#isWearingFullSet(EntityLivingBase, Element, ArmourClass)}. Retained for API stability
* between minor versions, will be removed in future.
*/
@Deprecated
public static int getMatchingArmourCount(EntityLivingBase entity, Element element){
return (int)Arrays.stream(InventoryUtils.ARMOUR_SLOTS)
.map(s -> entity.getItemStackFromSlot(s).getItem())
@@ -287,6 +401,49 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
.count();
}
/**
* Helper method to return the appropriate wand based on tier and element. This replaces the cumbersome wand map in
* {@link WizardryItems} by accessing the item registry dynamically by generating the registry name on the fly.
* <p></p>
* <i><b>This method will only return armour from the base mod.</b> It is unlikely that addons will need it, but it
* has been left public just in case. The intention is that this method is only used where there is no alternative.</i>
*
* @param element The element of the wand required. Null will be converted to {@link Element#MAGIC}.
* @param armourClass The {@link ArmourClass} required
* @param slot EntityEquipmentSlot of the armour piece required
* @return The wand item which corresponds to the given tier and element, or null if no such item exists.
* @throws NullPointerException if the given tier is null.
*/
// As noted above, in a few SPECIFIC cases this method is necessary (without using a data-driven system, at least,
// which I'm not going to spend the time making in the near future). Wizard trades and gear have been left using the
// WizardryItems version because they need to be replaced with a better system that doesn't use this at all.
public static Item getArmour(Element element, ArmourClass armourClass, EntityEquipmentSlot slot){
if(slot == null || slot.getSlotType() != Type.ARMOR)
throw new IllegalArgumentException("Must be a valid armour slot");
if(element == null) element = Element.MAGIC;
String registryName = armourClass.name + "_" + armourClass.armourPieceNames.get(slot);
if(element != Element.MAGIC) registryName = registryName + "_" + element.getName();
return Item.REGISTRY.getObject(new ResourceLocation(Wizardry.MODID, registryName));
}
/**
* Returns whether the given entity is wearing a full set of wizard armour of the given class and element.
* @param entity The entity to query.
* @param element The element to check, or null to accept any element as long as they are all the same.
* @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){
ItemStack helmet = entity.getItemStackFromSlot(EntityEquipmentSlot.HEAD);
if(!(helmet.getItem() instanceof ItemWizardArmour)) return false;
Element e = element == null ? ((ItemWizardArmour)helmet.getItem()).element : element;
ArmourClass ac = armourClass == null ? ((ItemWizardArmour)helmet.getItem()).armourClass : armourClass;
return Arrays.stream(InventoryUtils.ARMOUR_SLOTS)
.allMatch(s -> entity.getItemStackFromSlot(s).getItem() instanceof ItemWizardArmour
&& ((ItemWizardArmour)entity.getItemStackFromSlot(s).getItem()).element == e
&& ((ItemWizardArmour)entity.getItemStackFromSlot(s).getItem()).armourClass == ac);
}
@SubscribeEvent
public static void onLivingSetAttackTargetEvent(LivingSetAttackTargetEvent event){
// Undo the mob detection penalty for wearing armour when invisible
@@ -306,7 +463,7 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
if(event.getTarget().isSneaking()) followRange *= 0.8;
float f = (float)armourPieces / ((EntityPlayer)event.getTarget()).inventory.armorInventory.size();
if(f < 0.1F) f = 0.1F;
followRange *= (double)(0.7F * f);
followRange *= 0.7F * f;
// Don't need to worry about the isSuitableTarget check since it must already have been checked to get this far
if(event.getTarget().getDistance(event.getEntity()) > followRange) ((EntityLiving)event.getEntityLiving()).setAttackTarget(null);
}
@@ -12,11 +12,16 @@ 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.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;
import net.minecraft.entity.passive.EntitySquid;
@@ -172,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);
@@ -220,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());
}
}
}));
@@ -296,6 +319,7 @@ public abstract class Forfeit {
}));
add(Tier.APPRENTICE, Element.LIGHTNING, create("storm", (w, p) -> {
if(!Spells.invoke_weather.isEnabled(Context.WANDS)) return;
int standardWeatherTime = (300 + (new Random()).nextInt(600)) * 20;
w.getWorldInfo().setRaining(true);
w.getWorldInfo().setRainTime(standardWeatherTime);
@@ -373,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());
}
}
}));
@@ -390,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));
}
}));
@@ -400,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()));
}
}));
@@ -410,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;
@@ -79,6 +81,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;
@@ -20,7 +20,9 @@ public class PacketSpellProperties implements IMessageHandler<PacketSpellPropert
if(ctx.side.isClient()){
net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(() -> {
for(int i=0; i<message.propertiesArray.length; i++){
int first = message.firstId;
for(int i = first; i <message.propertiesArray.length; i++){
Spell.byNetworkID(i).setPropertiesClient(message.propertiesArray[i]);
}
});
@@ -32,21 +34,24 @@ public class PacketSpellProperties implements IMessageHandler<PacketSpellPropert
public static class Message implements IMessage {
private SpellProperties[] propertiesArray;
private int firstId;
private int count;
// This constructor is required otherwise you'll get errors (used somewhere in fml through reflection)
public Message(){}
public Message(SpellProperties... properties){
public Message(int firstId, int count, SpellProperties... properties){
this.firstId = firstId;
this.count = count;
this.propertiesArray = properties;
}
@Override
public void fromBytes(ByteBuf buf){
List<SpellProperties> propertiesList = new ArrayList<>();
int i = 0;
while(buf.isReadable()){
int i = buf.readInt();
count = buf.readInt();
firstId = i;
while(buf.isReadable() && i < count){
propertiesList.add(new SpellProperties(Spell.byNetworkID(i++), buf));
}
@@ -55,6 +60,8 @@ public class PacketSpellProperties implements IMessageHandler<PacketSpellPropert
@Override
public void toBytes(ByteBuf buf){
buf.writeInt(firstId);
buf.writeInt(count);
for(SpellProperties properties : propertiesArray) properties.write(buf);
}
}
@@ -4,8 +4,10 @@ import electroblob.wizardry.Wizardry;
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 +27,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 +37,17 @@ 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()) {
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,15 @@ 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(x != target.posX || y != target.posY || z != target.posZ)
{
if(target.world.isRemote){
EntityUtils.undoGravity(target);
target.addVelocity(0.15 * Math.signum(x - target.posX), 0.15 * Math.signum(y - target.posY), 0.15 * Math.signum(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);
target.world.playSound(target.posX, target.posY, target.posZ, WizardrySounds.ENTITY_FORCEFIELD_DEFLECT,
WizardrySounds.SPELLS, 0.3f, 1f, false);
}
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));
}
//
// 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
@@ -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;
}
}
@@ -17,7 +17,6 @@ public final class WizardryAdvancementTriggers {
private WizardryAdvancementTriggers(){} // No instances!
public static final CustomAdvancementTrigger legendary = new CustomAdvancementTrigger("trigger_legendary");
public static final CustomAdvancementTrigger max_out_wand = new CustomAdvancementTrigger("trigger_max_out_wand");
public static final CustomAdvancementTrigger special_upgrade = new CustomAdvancementTrigger("trigger_special_upgrade");
public static final CustomAdvancementTrigger anger_wizard = new CustomAdvancementTrigger("trigger_anger_wizard");
@@ -35,7 +34,6 @@ public final class WizardryAdvancementTriggers {
public static void register(){
CriteriaTriggers.register(legendary);
CriteriaTriggers.register(max_out_wand);
CriteriaTriggers.register(special_upgrade);
CriteriaTriggers.register(anger_wizard);
@@ -8,6 +8,7 @@ import electroblob.wizardry.entity.projectile.EntityPoisonBomb;
import electroblob.wizardry.entity.projectile.EntitySmokeBomb;
import electroblob.wizardry.entity.projectile.EntitySparkBomb;
import electroblob.wizardry.item.*;
import electroblob.wizardry.item.ItemWizardArmour.ArmourClass;
import electroblob.wizardry.misc.BehaviourSpellDispense;
import electroblob.wizardry.registry.WizardryTabs.CreativeTabListed;
import electroblob.wizardry.registry.WizardryTabs.CreativeTabSorted;
@@ -18,7 +19,6 @@ import net.minecraft.dispenser.BehaviorProjectileDispense;
import net.minecraft.dispenser.IPosition;
import net.minecraft.entity.IProjectile;
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.inventory.EntityEquipmentSlot.Type;
import net.minecraft.item.EnumRarity;
import net.minecraft.item.Item;
import net.minecraft.item.Item.ToolMaterial;
@@ -33,14 +33,10 @@ import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder;
import net.minecraftforge.registries.IForgeRegistry;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import javax.annotation.Nonnull;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
/**
* Class responsible for defining, storing and registering all of wizardry's items. Also registers the ItemBlocks for
@@ -62,8 +58,15 @@ public final class WizardryItems {
public static final ToolMaterial MAGICAL = EnumHelper.addToolMaterial("MAGICAL", 3, 1000, 8.0f, 4.0f, 0);
public static final ArmorMaterial SILK = EnumHelper.addArmorMaterial("SILK", "wizardry/textures/armour/wizard_armour",
15, new int[]{0, 0, 0, 0}, 15, WizardrySounds.ITEM_ARMOUR_EQUIP_SILK, 0.0F);
// The parameter textureName is incorrectly-named, it's actually the name field in ArmorMaterial
public static final ArmorMaterial SILK = EnumHelper.addArmorMaterial("SILK", "silk",
15, new int[]{2, 4, 5, 2}, 15, WizardrySounds.ITEM_ARMOUR_EQUIP_SILK, 0.0F);
public static final ArmorMaterial SAGE = EnumHelper.addArmorMaterial("SAGE", "sage",
15, new int[]{2, 5, 6, 3}, 25, WizardrySounds.ITEM_ARMOUR_EQUIP_SAGE, 0.0F);
public static final ArmorMaterial BATTLEMAGE = EnumHelper.addArmorMaterial("BATTLEMAGE", "battlemage",
15, new int[]{3, 6, 8, 3}, 15, WizardrySounds.ITEM_ARMOUR_EQUIP_BATTLEMAGE, 1.0F);
public static final ArmorMaterial WARLOCK = EnumHelper.addArmorMaterial("WARLOCK", "warlock",
20, new int[]{2, 4, 5, 2}, 15, WizardrySounds.ITEM_ARMOUR_EQUIP_WARLOCK, 0.0F);
}
@@ -148,7 +151,9 @@ public final class WizardryItems {
public static final Item frost_axe = placeholder();
public static final Item identification_scroll = placeholder();
public static final Item armour_upgrade = placeholder();
public static final Item resplendent_thread = placeholder();
public static final Item crystal_silver_plating = placeholder();
public static final Item ethereal_crystalweave = placeholder();
public static final Item astral_diamond = placeholder();
public static final Item purifying_elixir = placeholder();
@@ -199,6 +204,126 @@ public final class WizardryItems {
public static final Item wizard_leggings_healing = placeholder();
public static final Item wizard_boots_healing = placeholder();
public static final Item sage_hat = placeholder();
public static final Item sage_robe = placeholder();
public static final Item sage_leggings = placeholder();
public static final Item sage_boots = placeholder();
public static final Item sage_hat_fire = placeholder();
public static final Item sage_robe_fire = placeholder();
public static final Item sage_leggings_fire = placeholder();
public static final Item sage_boots_fire = placeholder();
public static final Item sage_hat_ice = placeholder();
public static final Item sage_robe_ice = placeholder();
public static final Item sage_leggings_ice = placeholder();
public static final Item sage_boots_ice = placeholder();
public static final Item sage_hat_lightning = placeholder();
public static final Item sage_robe_lightning = placeholder();
public static final Item sage_leggings_lightning = placeholder();
public static final Item sage_boots_lightning = placeholder();
public static final Item sage_hat_necromancy = placeholder();
public static final Item sage_robe_necromancy = placeholder();
public static final Item sage_leggings_necromancy = placeholder();
public static final Item sage_boots_necromancy = placeholder();
public static final Item sage_hat_earth = placeholder();
public static final Item sage_robe_earth = placeholder();
public static final Item sage_leggings_earth = placeholder();
public static final Item sage_boots_earth = placeholder();
public static final Item sage_hat_sorcery = placeholder();
public static final Item sage_robe_sorcery = placeholder();
public static final Item sage_leggings_sorcery = placeholder();
public static final Item sage_boots_sorcery = placeholder();
public static final Item sage_hat_healing = placeholder();
public static final Item sage_robe_healing = placeholder();
public static final Item sage_leggings_healing = placeholder();
public static final Item sage_boots_healing = placeholder();
public static final Item battlemage_helmet = placeholder();
public static final Item battlemage_chestplate = placeholder();
public static final Item battlemage_leggings = placeholder();
public static final Item battlemage_boots = placeholder();
public static final Item battlemage_helmet_fire = placeholder();
public static final Item battlemage_chestplate_fire = placeholder();
public static final Item battlemage_leggings_fire = placeholder();
public static final Item battlemage_boots_fire = placeholder();
public static final Item battlemage_helmet_ice = placeholder();
public static final Item battlemage_chestplate_ice = placeholder();
public static final Item battlemage_leggings_ice = placeholder();
public static final Item battlemage_boots_ice = placeholder();
public static final Item battlemage_helmet_lightning = placeholder();
public static final Item battlemage_chestplate_lightning = placeholder();
public static final Item battlemage_leggings_lightning = placeholder();
public static final Item battlemage_boots_lightning = placeholder();
public static final Item battlemage_helmet_necromancy = placeholder();
public static final Item battlemage_chestplate_necromancy = placeholder();
public static final Item battlemage_leggings_necromancy = placeholder();
public static final Item battlemage_boots_necromancy = placeholder();
public static final Item battlemage_helmet_earth = placeholder();
public static final Item battlemage_chestplate_earth = placeholder();
public static final Item battlemage_leggings_earth = placeholder();
public static final Item battlemage_boots_earth = placeholder();
public static final Item battlemage_helmet_sorcery = placeholder();
public static final Item battlemage_chestplate_sorcery = placeholder();
public static final Item battlemage_leggings_sorcery = placeholder();
public static final Item battlemage_boots_sorcery = placeholder();
public static final Item battlemage_helmet_healing = placeholder();
public static final Item battlemage_chestplate_healing = placeholder();
public static final Item battlemage_leggings_healing = placeholder();
public static final Item battlemage_boots_healing = placeholder();
public static final Item warlock_hood = placeholder();
public static final Item warlock_robe = placeholder();
public static final Item warlock_leggings = placeholder();
public static final Item warlock_boots = placeholder();
public static final Item warlock_hood_fire = placeholder();
public static final Item warlock_robe_fire = placeholder();
public static final Item warlock_leggings_fire = placeholder();
public static final Item warlock_boots_fire = placeholder();
public static final Item warlock_hood_ice = placeholder();
public static final Item warlock_robe_ice = placeholder();
public static final Item warlock_leggings_ice = placeholder();
public static final Item warlock_boots_ice = placeholder();
public static final Item warlock_hood_lightning = placeholder();
public static final Item warlock_robe_lightning = placeholder();
public static final Item warlock_leggings_lightning = placeholder();
public static final Item warlock_boots_lightning = placeholder();
public static final Item warlock_hood_necromancy = placeholder();
public static final Item warlock_robe_necromancy = placeholder();
public static final Item warlock_leggings_necromancy = placeholder();
public static final Item warlock_boots_necromancy = placeholder();
public static final Item warlock_hood_earth = placeholder();
public static final Item warlock_robe_earth = placeholder();
public static final Item warlock_leggings_earth = placeholder();
public static final Item warlock_boots_earth = placeholder();
public static final Item warlock_hood_sorcery = placeholder();
public static final Item warlock_robe_sorcery = placeholder();
public static final Item warlock_leggings_sorcery = placeholder();
public static final Item warlock_boots_sorcery = placeholder();
public static final Item warlock_hood_healing = placeholder();
public static final Item warlock_robe_healing = placeholder();
public static final Item warlock_leggings_healing = placeholder();
public static final Item warlock_boots_healing = placeholder();
public static final Item spectral_helmet = placeholder();
public static final Item spectral_chestplate = placeholder();
public static final Item spectral_leggings = placeholder();
@@ -285,46 +410,44 @@ public final class WizardryItems {
public static final Item charm_mount_teleporting = placeholder();
public static final Item charm_feeding = placeholder();
private static final Map<Pair<Tier, Element>, Item> WAND_MAP = new HashMap<>();
private static final Map<Pair<EntityEquipmentSlot, Element>, Item> ARMOUR_MAP = new HashMap<>();
/**
* Helper method to return the appropriate wand based on tier and element. As of Wizardry 2.1, this uses the
* immutable map stored in {@link WizardryItems#WAND_MAP}. Currently used for upgrading wands, for chest generation
* and to iterate through wands for charging recipes.
* Helper method to return the appropriate wand based on tier and element. As of Wizardry 4.3.3, this delegates to
* the cleaner replacement method {@link ItemWand#getWand(Tier, Element)}, which accesses the item registry
* dynamically by generating the registry name on the fly.
*
* @param tier The tier of the wand required.
* @param element The element of the wand required. Null will be converted to {@link Element#MAGIC}.
* @return The wand item which corresponds to the given tier and element, or null if no such item exists.
* @throws NullPointerException if the given tier is null.
* @deprecated This is being phased out; it is now only used for wizard gear and trades. To add an item to
* charging recipes, use {@link WizardryRecipes#addToManaFlaskCharging(Item)}.
* @deprecated This is being phased out; it is now only used for wizard gear and trades. To add an item to charging
* recipes, use {@link WizardryRecipes#addToManaFlaskCharging(Item)}. If you absolutely must use this method, usages
* may be replaced with {@link ItemWand#getWand(Tier, Element)}. However, this should only be done in cases where it
* is appropriate to ignore all wands that are not in the base mod.
*/
@Deprecated
public static Item getWand(Tier tier, Element element){
if(tier == null) throw new NullPointerException("The given tier cannot be null.");
if(element == null) element = Element.MAGIC;
return WAND_MAP.get(ImmutablePair.of(tier, element));
return ItemWand.getWand(tier, element); // Delegate to replacement method
}
/**
* Helper method to return the appropriate armour item based on element and slot. As of Wizardry 2.1, this uses the
* immutable map stored in {@link WizardryItems#ARMOUR_MAP}. Currently used to iterate through armour for
* registering charging recipes and for chest generation.
* Helper method to return the appropriate armour item based on element and slot. As of Wizardry 4.3.3, this
* delegates to the cleaner replacement method {@link ItemWizardArmour#getArmour(Element, ArmourClass, EntityEquipmentSlot)},
* which accesses the item registry dynamically by generating the registry name on the fly.
* <p></p>
* <i>This method only returns the original, basic armour set ({@link ArmourClass#WIZARD}).</i>
*
* @param element The EnumElement of the armour required. Null will be converted to {@link Element#MAGIC}.
* @param slot EntityEquipmentSlot of the armour piece required
* @return The armour item which corresponds to the given element and slot, or null if no such item exists.
* @throws IllegalArgumentException if the given slot is not an armour slot.
* @deprecated This is being phased out; it is now only used for wizard gear and trades. To add an item to
* charging recipes, use {@link WizardryRecipes#addToManaFlaskCharging(Item)}.
* charging recipes, use {@link WizardryRecipes#addToManaFlaskCharging(Item)}. If you absolutely must use this
* method, usages may be replaced with {@link ItemWand#getWand(Tier, Element)}. However, this should only be done in
* cases where it is appropriate to ignore all armour that is not in the base mod.
*/
@Deprecated
public static Item getArmour(Element element, EntityEquipmentSlot slot){
if(slot == null || slot.getSlotType() != Type.ARMOR)
throw new IllegalArgumentException("Must be a valid armour slot");
if(element == null) element = Element.MAGIC;
return ARMOUR_MAP.get(ImmutablePair.of(slot, element));
return ItemWizardArmour.getArmour(element, ArmourClass.WIZARD, slot); // Delegate to replacement method
}
/**
@@ -444,218 +567,340 @@ public final class WizardryItems {
// Items
registerItem(registry, "magic_crystal", new ItemCrystal());
registerItem(registry, "magic_crystal", new ItemCrystal());
registerItem(registry, "crystal_shard", new Item().setCreativeTab(WizardryTabs.WIZARDRY));
registerItem(registry, "grand_crystal", new Item().setCreativeTab(WizardryTabs.WIZARDRY));
registerItem(registry, "crystal_shard", new Item().setCreativeTab(WizardryTabs.WIZARDRY));
registerItem(registry, "grand_crystal", new Item().setCreativeTab(WizardryTabs.WIZARDRY));
registerItem(registry, "wizard_handbook", new ItemWizardHandbook(), true);
registerItem(registry, "arcane_tome", new ItemArcaneTome());
registerItem(registry, "spell_book", new ItemSpellBook(), true);
registerItem(registry, "scroll", new ItemScroll());
registerItem(registry, "ruined_spell_book", new Item().setCreativeTab(WizardryTabs.WIZARDRY).setMaxStackSize(16));
registerItem(registry, "wizard_handbook", new ItemWizardHandbook(), true);
registerItem(registry, "arcane_tome", new ItemArcaneTome());
registerItem(registry, "spell_book", new ItemSpellBook(), true);
registerItem(registry, "scroll", new ItemScroll());
registerItem(registry, "ruined_spell_book", new Item().setCreativeTab(WizardryTabs.WIZARDRY).setMaxStackSize(16));
registerItem(registry, "magic_wand", new ItemWand(Tier.NOVICE, null));
registerItem(registry, "apprentice_wand", new ItemWand(Tier.APPRENTICE, null));
registerItem(registry, "advanced_wand", new ItemWand(Tier.ADVANCED, null));
registerItem(registry, "master_wand", new ItemWand(Tier.MASTER, null));
registerItem(registry, "magic_wand", new ItemWand(Tier.NOVICE, null));
registerItem(registry, "apprentice_wand", new ItemWand(Tier.APPRENTICE, null));
registerItem(registry, "advanced_wand", new ItemWand(Tier.ADVANCED, null));
registerItem(registry, "master_wand", new ItemWand(Tier.MASTER, null));
registerItem(registry, "novice_fire_wand", new ItemWand(Tier.NOVICE, Element.FIRE));
registerItem(registry, "apprentice_fire_wand", new ItemWand(Tier.APPRENTICE, Element.FIRE));
registerItem(registry, "advanced_fire_wand", new ItemWand(Tier.ADVANCED, Element.FIRE));
registerItem(registry, "master_fire_wand", new ItemWand(Tier.MASTER, Element.FIRE));
registerItem(registry, "novice_fire_wand", new ItemWand(Tier.NOVICE, Element.FIRE));
registerItem(registry, "apprentice_fire_wand", new ItemWand(Tier.APPRENTICE, Element.FIRE));
registerItem(registry, "advanced_fire_wand", new ItemWand(Tier.ADVANCED, Element.FIRE));
registerItem(registry, "master_fire_wand", new ItemWand(Tier.MASTER, Element.FIRE));
registerItem(registry, "novice_ice_wand", new ItemWand(Tier.NOVICE, Element.ICE));
registerItem(registry, "apprentice_ice_wand", new ItemWand(Tier.APPRENTICE, Element.ICE));
registerItem(registry, "advanced_ice_wand", new ItemWand(Tier.ADVANCED, Element.ICE));
registerItem(registry, "master_ice_wand", new ItemWand(Tier.MASTER, Element.ICE));
registerItem(registry, "novice_ice_wand", new ItemWand(Tier.NOVICE, Element.ICE));
registerItem(registry, "apprentice_ice_wand", new ItemWand(Tier.APPRENTICE, Element.ICE));
registerItem(registry, "advanced_ice_wand", new ItemWand(Tier.ADVANCED, Element.ICE));
registerItem(registry, "master_ice_wand", new ItemWand(Tier.MASTER, Element.ICE));
registerItem(registry, "novice_lightning_wand", new ItemWand(Tier.NOVICE, Element.LIGHTNING));
registerItem(registry, "apprentice_lightning_wand", new ItemWand(Tier.APPRENTICE, Element.LIGHTNING));
registerItem(registry, "advanced_lightning_wand", new ItemWand(Tier.ADVANCED, Element.LIGHTNING));
registerItem(registry, "master_lightning_wand", new ItemWand(Tier.MASTER, Element.LIGHTNING));
registerItem(registry, "novice_lightning_wand", new ItemWand(Tier.NOVICE, Element.LIGHTNING));
registerItem(registry, "apprentice_lightning_wand", new ItemWand(Tier.APPRENTICE, Element.LIGHTNING));
registerItem(registry, "advanced_lightning_wand", new ItemWand(Tier.ADVANCED, Element.LIGHTNING));
registerItem(registry, "master_lightning_wand", new ItemWand(Tier.MASTER, Element.LIGHTNING));
registerItem(registry, "novice_necromancy_wand", new ItemWand(Tier.NOVICE, Element.NECROMANCY));
registerItem(registry, "apprentice_necromancy_wand", new ItemWand(Tier.APPRENTICE, Element.NECROMANCY));
registerItem(registry, "advanced_necromancy_wand", new ItemWand(Tier.ADVANCED, Element.NECROMANCY));
registerItem(registry, "master_necromancy_wand", new ItemWand(Tier.MASTER, Element.NECROMANCY));
registerItem(registry, "novice_necromancy_wand", new ItemWand(Tier.NOVICE, Element.NECROMANCY));
registerItem(registry, "apprentice_necromancy_wand", new ItemWand(Tier.APPRENTICE, Element.NECROMANCY));
registerItem(registry, "advanced_necromancy_wand", new ItemWand(Tier.ADVANCED, Element.NECROMANCY));
registerItem(registry, "master_necromancy_wand", new ItemWand(Tier.MASTER, Element.NECROMANCY));
registerItem(registry, "novice_earth_wand", new ItemWand(Tier.NOVICE, Element.EARTH));
registerItem(registry, "apprentice_earth_wand", new ItemWand(Tier.APPRENTICE, Element.EARTH));
registerItem(registry, "advanced_earth_wand", new ItemWand(Tier.ADVANCED, Element.EARTH));
registerItem(registry, "master_earth_wand", new ItemWand(Tier.MASTER, Element.EARTH));
registerItem(registry, "novice_earth_wand", new ItemWand(Tier.NOVICE, Element.EARTH));
registerItem(registry, "apprentice_earth_wand", new ItemWand(Tier.APPRENTICE, Element.EARTH));
registerItem(registry, "advanced_earth_wand", new ItemWand(Tier.ADVANCED, Element.EARTH));
registerItem(registry, "master_earth_wand", new ItemWand(Tier.MASTER, Element.EARTH));
registerItem(registry, "novice_sorcery_wand", new ItemWand(Tier.NOVICE, Element.SORCERY));
registerItem(registry, "apprentice_sorcery_wand", new ItemWand(Tier.APPRENTICE, Element.SORCERY));
registerItem(registry, "advanced_sorcery_wand", new ItemWand(Tier.ADVANCED, Element.SORCERY));
registerItem(registry, "master_sorcery_wand", new ItemWand(Tier.MASTER, Element.SORCERY));
registerItem(registry, "novice_sorcery_wand", new ItemWand(Tier.NOVICE, Element.SORCERY));
registerItem(registry, "apprentice_sorcery_wand", new ItemWand(Tier.APPRENTICE, Element.SORCERY));
registerItem(registry, "advanced_sorcery_wand", new ItemWand(Tier.ADVANCED, Element.SORCERY));
registerItem(registry, "master_sorcery_wand", new ItemWand(Tier.MASTER, Element.SORCERY));
registerItem(registry, "novice_healing_wand", new ItemWand(Tier.NOVICE, Element.HEALING));
registerItem(registry, "apprentice_healing_wand", new ItemWand(Tier.APPRENTICE, Element.HEALING));
registerItem(registry, "advanced_healing_wand", new ItemWand(Tier.ADVANCED, Element.HEALING));
registerItem(registry, "master_healing_wand", new ItemWand(Tier.MASTER, Element.HEALING));
registerItem(registry, "novice_healing_wand", new ItemWand(Tier.NOVICE, Element.HEALING));
registerItem(registry, "apprentice_healing_wand", new ItemWand(Tier.APPRENTICE, Element.HEALING));
registerItem(registry, "advanced_healing_wand", new ItemWand(Tier.ADVANCED, Element.HEALING));
registerItem(registry, "master_healing_wand", new ItemWand(Tier.MASTER, Element.HEALING));
registerItem(registry, "spectral_sword", new ItemSpectralSword(ToolMaterial.IRON));
registerItem(registry, "spectral_pickaxe", new ItemSpectralPickaxe(ToolMaterial.IRON));
registerItem(registry, "spectral_bow", new ItemSpectralBow());
registerItem(registry, "spectral_sword", new ItemSpectralSword(ToolMaterial.IRON));
registerItem(registry, "spectral_pickaxe", new ItemSpectralPickaxe(ToolMaterial.IRON));
registerItem(registry, "spectral_bow", new ItemSpectralBow());
registerItem(registry, "blank_scroll", new ItemBlankScroll());
registerItem(registry, "magic_silk", new Item().setCreativeTab(WizardryTabs.WIZARDRY));
registerItem(registry, "blank_scroll", new ItemBlankScroll());
registerItem(registry, "magic_silk", new Item().setCreativeTab(WizardryTabs.WIZARDRY));
registerItem(registry, "small_mana_flask", new ItemManaFlask(ItemManaFlask.Size.SMALL));
registerItem(registry, "medium_mana_flask", new ItemManaFlask(ItemManaFlask.Size.MEDIUM));
registerItem(registry, "large_mana_flask", new ItemManaFlask(ItemManaFlask.Size.LARGE));
registerItem(registry, "small_mana_flask", new ItemManaFlask(ItemManaFlask.Size.SMALL));
registerItem(registry, "medium_mana_flask", new ItemManaFlask(ItemManaFlask.Size.MEDIUM));
registerItem(registry, "large_mana_flask", new ItemManaFlask(ItemManaFlask.Size.LARGE));
registerItem(registry, "storage_upgrade", new ItemWandUpgrade());
registerItem(registry, "siphon_upgrade", new ItemWandUpgrade());
registerItem(registry, "condenser_upgrade", new ItemWandUpgrade());
registerItem(registry, "range_upgrade", new ItemWandUpgrade());
registerItem(registry, "duration_upgrade", new ItemWandUpgrade());
registerItem(registry, "cooldown_upgrade", new ItemWandUpgrade());
registerItem(registry, "blast_upgrade", new ItemWandUpgrade());
registerItem(registry, "attunement_upgrade", new ItemWandUpgrade());
registerItem(registry, "melee_upgrade", new ItemWandUpgrade());
registerItem(registry, "storage_upgrade", new ItemWandUpgrade());
registerItem(registry, "siphon_upgrade", new ItemWandUpgrade());
registerItem(registry, "condenser_upgrade", new ItemWandUpgrade());
registerItem(registry, "range_upgrade", new ItemWandUpgrade());
registerItem(registry, "duration_upgrade", new ItemWandUpgrade());
registerItem(registry, "cooldown_upgrade", new ItemWandUpgrade());
registerItem(registry, "blast_upgrade", new ItemWandUpgrade());
registerItem(registry, "attunement_upgrade", new ItemWandUpgrade());
registerItem(registry, "melee_upgrade", new ItemWandUpgrade());
registerItem(registry, "flaming_axe", new ItemFlamingAxe(Materials.MAGICAL));
registerItem(registry, "frost_axe", new ItemFrostAxe(Materials.MAGICAL));
registerItem(registry, "flaming_axe", new ItemFlamingAxe(Materials.MAGICAL));
registerItem(registry, "frost_axe", new ItemFrostAxe(Materials.MAGICAL));
registerItem(registry, "identification_scroll", new ItemIdentificationScroll());
registerItem(registry, "armour_upgrade", new ItemArmourUpgrade());
registerItem(registry, "astral_diamond", new Item(){ @Override public EnumRarity getRarity(ItemStack stack){ return EnumRarity.RARE; }}.setCreativeTab(WizardryTabs.WIZARDRY));
registerItem(registry, "purifying_elixir", new ItemPurifyingElixir());
registerItem(registry, "identification_scroll", new ItemIdentificationScroll());
registerItem(registry, "resplendent_thread", new ItemArmourUpgrade());
registerItem(registry, "crystal_silver_plating", new ItemArmourUpgrade());
registerItem(registry, "ethereal_crystalweave", new ItemArmourUpgrade());
registerItem(registry, "astral_diamond", new Item(){ @Override public EnumRarity getRarity(ItemStack stack){ return EnumRarity.RARE; }}.setCreativeTab(WizardryTabs.WIZARDRY));
registerItem(registry, "purifying_elixir", new ItemPurifyingElixir());
registerItem(registry, "firebomb", new ItemFirebomb());
registerItem(registry, "poison_bomb", new ItemPoisonBomb());
registerItem(registry, "smoke_bomb", new ItemSmokeBomb());
registerItem(registry, "spark_bomb", new ItemSparkBomb());
registerItem(registry, "firebomb", new ItemFirebomb());
registerItem(registry, "poison_bomb", new ItemPoisonBomb());
registerItem(registry, "smoke_bomb", new ItemSmokeBomb());
registerItem(registry, "spark_bomb", new ItemSparkBomb());
registerItem(registry, "spectral_dust", new ItemSpectralDust());
registerItem(registry, "spectral_dust", new ItemSpectralDust());
registerItem(registry, "wizard_hat", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.HEAD, null), true);
registerItem(registry, "wizard_robe", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.CHEST, null));
registerItem(registry, "wizard_leggings", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.LEGS, null));
registerItem(registry, "wizard_boots", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.FEET, null));
registerItem(registry, "wizard_hat", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.HEAD, null), true);
registerItem(registry, "wizard_robe", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.CHEST, null));
registerItem(registry, "wizard_leggings", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.LEGS, null));
registerItem(registry, "wizard_boots", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.FEET, null));
registerItem(registry, "wizard_hat_fire", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.HEAD, Element.FIRE));
registerItem(registry, "wizard_robe_fire", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.CHEST, Element.FIRE));
registerItem(registry, "wizard_leggings_fire", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.LEGS, Element.FIRE));
registerItem(registry, "wizard_boots_fire", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.FEET, Element.FIRE));
registerItem(registry, "wizard_hat_fire", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.HEAD, Element.FIRE));
registerItem(registry, "wizard_robe_fire", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.CHEST, Element.FIRE));
registerItem(registry, "wizard_leggings_fire", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.LEGS, Element.FIRE));
registerItem(registry, "wizard_boots_fire", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.FEET, Element.FIRE));
registerItem(registry, "wizard_hat_ice", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.HEAD, Element.ICE));
registerItem(registry, "wizard_robe_ice", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.CHEST, Element.ICE));
registerItem(registry, "wizard_leggings_ice", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.LEGS, Element.ICE));
registerItem(registry, "wizard_boots_ice", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.FEET, Element.ICE));
registerItem(registry, "wizard_hat_ice", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.HEAD, Element.ICE));
registerItem(registry, "wizard_robe_ice", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.CHEST, Element.ICE));
registerItem(registry, "wizard_leggings_ice", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.LEGS, Element.ICE));
registerItem(registry, "wizard_boots_ice", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.FEET, Element.ICE));
registerItem(registry, "wizard_hat_lightning", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.HEAD, Element.LIGHTNING));
registerItem(registry, "wizard_robe_lightning", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.CHEST, Element.LIGHTNING));
registerItem(registry, "wizard_leggings_lightning", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.LEGS, Element.LIGHTNING));
registerItem(registry, "wizard_boots_lightning", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.FEET, Element.LIGHTNING));
registerItem(registry, "wizard_hat_lightning", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.HEAD, Element.LIGHTNING));
registerItem(registry, "wizard_robe_lightning", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.CHEST, Element.LIGHTNING));
registerItem(registry, "wizard_leggings_lightning", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.LEGS, Element.LIGHTNING));
registerItem(registry, "wizard_boots_lightning", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.FEET, Element.LIGHTNING));
registerItem(registry, "wizard_hat_necromancy", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.HEAD, Element.NECROMANCY));
registerItem(registry, "wizard_robe_necromancy", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.CHEST, Element.NECROMANCY));
registerItem(registry, "wizard_leggings_necromancy", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.LEGS, Element.NECROMANCY));
registerItem(registry, "wizard_boots_necromancy", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.FEET, Element.NECROMANCY));
registerItem(registry, "wizard_hat_necromancy", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.HEAD, Element.NECROMANCY));
registerItem(registry, "wizard_robe_necromancy", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.CHEST, Element.NECROMANCY));
registerItem(registry, "wizard_leggings_necromancy", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.LEGS, Element.NECROMANCY));
registerItem(registry, "wizard_boots_necromancy", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.FEET, Element.NECROMANCY));
registerItem(registry, "wizard_hat_earth", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.HEAD, Element.EARTH));
registerItem(registry, "wizard_robe_earth", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.CHEST, Element.EARTH));
registerItem(registry, "wizard_leggings_earth", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.LEGS, Element.EARTH));
registerItem(registry, "wizard_boots_earth", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.FEET, Element.EARTH));
registerItem(registry, "wizard_hat_earth", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.HEAD, Element.EARTH));
registerItem(registry, "wizard_robe_earth", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.CHEST, Element.EARTH));
registerItem(registry, "wizard_leggings_earth", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.LEGS, Element.EARTH));
registerItem(registry, "wizard_boots_earth", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.FEET, Element.EARTH));
registerItem(registry, "wizard_hat_sorcery", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.HEAD, Element.SORCERY));
registerItem(registry, "wizard_robe_sorcery", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.CHEST, Element.SORCERY));
registerItem(registry, "wizard_leggings_sorcery", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.LEGS, Element.SORCERY));
registerItem(registry, "wizard_boots_sorcery", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.FEET, Element.SORCERY));
registerItem(registry, "wizard_hat_sorcery", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.HEAD, Element.SORCERY));
registerItem(registry, "wizard_robe_sorcery", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.CHEST, Element.SORCERY));
registerItem(registry, "wizard_leggings_sorcery", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.LEGS, Element.SORCERY));
registerItem(registry, "wizard_boots_sorcery", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.FEET, Element.SORCERY));
registerItem(registry, "wizard_hat_healing", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.HEAD, Element.HEALING));
registerItem(registry, "wizard_robe_healing", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.CHEST, Element.HEALING));
registerItem(registry, "wizard_leggings_healing", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.LEGS, Element.HEALING));
registerItem(registry, "wizard_boots_healing", new ItemWizardArmour(Materials.SILK, 1, EntityEquipmentSlot.FEET, Element.HEALING));
registerItem(registry, "wizard_hat_healing", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.HEAD, Element.HEALING));
registerItem(registry, "wizard_robe_healing", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.CHEST, Element.HEALING));
registerItem(registry, "wizard_leggings_healing", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.LEGS, Element.HEALING));
registerItem(registry, "wizard_boots_healing", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.FEET, Element.HEALING));
registerItem(registry, "spectral_helmet", new ItemSpectralArmour(ArmorMaterial.IRON, 1, EntityEquipmentSlot.HEAD));
registerItem(registry, "spectral_chestplate", new ItemSpectralArmour(ArmorMaterial.IRON, 1, EntityEquipmentSlot.CHEST));
registerItem(registry, "spectral_leggings", new ItemSpectralArmour(ArmorMaterial.IRON, 1, EntityEquipmentSlot.LEGS));
registerItem(registry, "spectral_boots", new ItemSpectralArmour(ArmorMaterial.IRON, 1, EntityEquipmentSlot.FEET));
registerItem(registry, "sage_hat", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.HEAD, null));
registerItem(registry, "sage_robe", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.CHEST, null));
registerItem(registry, "sage_leggings", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.LEGS, null));
registerItem(registry, "sage_boots", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.FEET, null));
registerItem(registry, "lightning_hammer", new ItemLightningHammer());
registerItem(registry, "flamecatcher", new ItemFlamecatcher());
registerItem(registry, "sage_hat_fire", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.HEAD, Element.FIRE));
registerItem(registry, "sage_robe_fire", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.CHEST, Element.FIRE));
registerItem(registry, "sage_leggings_fire", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.LEGS, Element.FIRE));
registerItem(registry, "sage_boots_fire", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.FEET, Element.FIRE));
registerItem(registry, "ring_condensing", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.RING));
registerItem(registry, "ring_siphoning", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.RING));
registerItem(registry, "ring_battlemage", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.RING));
registerItem(registry, "ring_combustion", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.RING));
registerItem(registry, "ring_fire_melee", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.RING));
registerItem(registry, "ring_fire_biome", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.RING));
registerItem(registry, "ring_disintegration", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.RING));
registerItem(registry, "ring_meteor", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.RING));
registerItem(registry, "ring_ice_melee", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.RING));
registerItem(registry, "ring_ice_biome", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.RING));
registerItem(registry, "ring_arcane_frost", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.RING));
registerItem(registry, "ring_shattering", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.RING));
registerItem(registry, "ring_lightning_melee", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.RING));
registerItem(registry, "ring_storm", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.RING));
registerItem(registry, "ring_seeking", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.RING));
registerItem(registry, "ring_hammer", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.RING));
registerItem(registry, "ring_stormcloud", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.RING));
registerItem(registry, "ring_soulbinding", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.RING));
registerItem(registry, "ring_leeching", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.RING));
registerItem(registry, "ring_necromancy_melee", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.RING));
registerItem(registry, "ring_mind_control", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.RING));
registerItem(registry, "ring_poison", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.RING));
registerItem(registry, "ring_earth_melee", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.RING));
registerItem(registry, "ring_earth_biome", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.RING));
registerItem(registry, "ring_full_moon", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.RING));
registerItem(registry, "ring_evoker", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.RING));
registerItem(registry, "ring_extraction", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.RING));
registerItem(registry, "ring_mana_return", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.RING));
registerItem(registry, "ring_blockwrangler", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.RING));
registerItem(registry, "ring_conjurer", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.RING));
registerItem(registry, "ring_defender", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.RING));
registerItem(registry, "ring_paladin", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.RING));
registerItem(registry, "ring_interdiction", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.RING));
registerItem(registry, "sage_hat_ice", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.HEAD, Element.ICE));
registerItem(registry, "sage_robe_ice", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.CHEST, Element.ICE));
registerItem(registry, "sage_leggings_ice", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.LEGS, Element.ICE));
registerItem(registry, "sage_boots_ice", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.FEET, Element.ICE));
registerItem(registry, "amulet_arcane_defence", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_warding", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_wisdom", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_fire_protection", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_fire_cloaking", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_ice_immunity", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_ice_protection", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_frost_warding", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_potential", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_channeling", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_lich", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_wither_immunity", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_glide", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_banishing", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_anchoring", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_recovery", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_transience", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_resurrection", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_auto_shield", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_absorption", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.AMULET));
registerItem(registry, "sage_hat_lightning", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.HEAD, Element.LIGHTNING));
registerItem(registry, "sage_robe_lightning", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.CHEST, Element.LIGHTNING));
registerItem(registry, "sage_leggings_lightning", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.LEGS, Element.LIGHTNING));
registerItem(registry, "sage_boots_lightning", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.FEET, Element.LIGHTNING));
registerItem(registry, "charm_haggler", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_experience_tome", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_move_speed", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_spell_discovery", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_auto_smelt", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_lava_walking", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_storm", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_minion_health", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_minion_variants", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_undead_helmets", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_hunger_casting", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_flight", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_growth", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_abseiling", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_silk_touch", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_sixth_sense", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_stop_time", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_light", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_transportation", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_black_hole", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_mount_teleporting", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_feeding", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.CHARM));
registerItem(registry, "sage_hat_necromancy", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.HEAD, Element.NECROMANCY));
registerItem(registry, "sage_robe_necromancy", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.CHEST, Element.NECROMANCY));
registerItem(registry, "sage_leggings_necromancy", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.LEGS, Element.NECROMANCY));
registerItem(registry, "sage_boots_necromancy", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.FEET, Element.NECROMANCY));
registerItem(registry, "sage_hat_earth", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.HEAD, Element.EARTH));
registerItem(registry, "sage_robe_earth", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.CHEST, Element.EARTH));
registerItem(registry, "sage_leggings_earth", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.LEGS, Element.EARTH));
registerItem(registry, "sage_boots_earth", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.FEET, Element.EARTH));
registerItem(registry, "sage_hat_sorcery", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.HEAD, Element.SORCERY));
registerItem(registry, "sage_robe_sorcery", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.CHEST, Element.SORCERY));
registerItem(registry, "sage_leggings_sorcery", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.LEGS, Element.SORCERY));
registerItem(registry, "sage_boots_sorcery", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.FEET, Element.SORCERY));
registerItem(registry, "sage_hat_healing", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.HEAD, Element.HEALING));
registerItem(registry, "sage_robe_healing", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.CHEST, Element.HEALING));
registerItem(registry, "sage_leggings_healing", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.LEGS, Element.HEALING));
registerItem(registry, "sage_boots_healing", new ItemWizardArmour(ArmourClass.SAGE, EntityEquipmentSlot.FEET, Element.HEALING));
registerItem(registry, "battlemage_helmet", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.HEAD, null));
registerItem(registry, "battlemage_chestplate", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.CHEST, null));
registerItem(registry, "battlemage_leggings", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.LEGS, null));
registerItem(registry, "battlemage_boots", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.FEET, null));
registerItem(registry, "battlemage_helmet_fire", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.HEAD, Element.FIRE));
registerItem(registry, "battlemage_chestplate_fire", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.CHEST, Element.FIRE));
registerItem(registry, "battlemage_leggings_fire", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.LEGS, Element.FIRE));
registerItem(registry, "battlemage_boots_fire", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.FEET, Element.FIRE));
registerItem(registry, "battlemage_helmet_ice", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.HEAD, Element.ICE));
registerItem(registry, "battlemage_chestplate_ice", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.CHEST, Element.ICE));
registerItem(registry, "battlemage_leggings_ice", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.LEGS, Element.ICE));
registerItem(registry, "battlemage_boots_ice", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.FEET, Element.ICE));
registerItem(registry, "battlemage_helmet_lightning", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.HEAD, Element.LIGHTNING));
registerItem(registry, "battlemage_chestplate_lightning", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.CHEST, Element.LIGHTNING));
registerItem(registry, "battlemage_leggings_lightning", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.LEGS, Element.LIGHTNING));
registerItem(registry, "battlemage_boots_lightning", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.FEET, Element.LIGHTNING));
registerItem(registry, "battlemage_helmet_necromancy", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.HEAD, Element.NECROMANCY));
registerItem(registry, "battlemage_chestplate_necromancy", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.CHEST, Element.NECROMANCY));
registerItem(registry, "battlemage_leggings_necromancy", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.LEGS, Element.NECROMANCY));
registerItem(registry, "battlemage_boots_necromancy", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.FEET, Element.NECROMANCY));
registerItem(registry, "battlemage_helmet_earth", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.HEAD, Element.EARTH));
registerItem(registry, "battlemage_chestplate_earth", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.CHEST, Element.EARTH));
registerItem(registry, "battlemage_leggings_earth", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.LEGS, Element.EARTH));
registerItem(registry, "battlemage_boots_earth", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.FEET, Element.EARTH));
registerItem(registry, "battlemage_helmet_sorcery", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.HEAD, Element.SORCERY));
registerItem(registry, "battlemage_chestplate_sorcery", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.CHEST, Element.SORCERY));
registerItem(registry, "battlemage_leggings_sorcery", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.LEGS, Element.SORCERY));
registerItem(registry, "battlemage_boots_sorcery", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.FEET, Element.SORCERY));
registerItem(registry, "battlemage_helmet_healing", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.HEAD, Element.HEALING));
registerItem(registry, "battlemage_chestplate_healing", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.CHEST, Element.HEALING));
registerItem(registry, "battlemage_leggings_healing", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.LEGS, Element.HEALING));
registerItem(registry, "battlemage_boots_healing", new ItemWizardArmour(ArmourClass.BATTLEMAGE, EntityEquipmentSlot.FEET, Element.HEALING));
registerItem(registry, "warlock_hood", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.HEAD, null));
registerItem(registry, "warlock_robe", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.CHEST, null));
registerItem(registry, "warlock_leggings", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.LEGS, null));
registerItem(registry, "warlock_boots", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.FEET, null));
registerItem(registry, "warlock_hood_fire", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.HEAD, Element.FIRE));
registerItem(registry, "warlock_robe_fire", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.CHEST, Element.FIRE));
registerItem(registry, "warlock_leggings_fire", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.LEGS, Element.FIRE));
registerItem(registry, "warlock_boots_fire", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.FEET, Element.FIRE));
registerItem(registry, "warlock_hood_ice", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.HEAD, Element.ICE));
registerItem(registry, "warlock_robe_ice", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.CHEST, Element.ICE));
registerItem(registry, "warlock_leggings_ice", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.LEGS, Element.ICE));
registerItem(registry, "warlock_boots_ice", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.FEET, Element.ICE));
registerItem(registry, "warlock_hood_lightning", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.HEAD, Element.LIGHTNING));
registerItem(registry, "warlock_robe_lightning", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.CHEST, Element.LIGHTNING));
registerItem(registry, "warlock_leggings_lightning", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.LEGS, Element.LIGHTNING));
registerItem(registry, "warlock_boots_lightning", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.FEET, Element.LIGHTNING));
registerItem(registry, "warlock_hood_necromancy", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.HEAD, Element.NECROMANCY));
registerItem(registry, "warlock_robe_necromancy", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.CHEST, Element.NECROMANCY));
registerItem(registry, "warlock_leggings_necromancy", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.LEGS, Element.NECROMANCY));
registerItem(registry, "warlock_boots_necromancy", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.FEET, Element.NECROMANCY));
registerItem(registry, "warlock_hood_earth", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.HEAD, Element.EARTH));
registerItem(registry, "warlock_robe_earth", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.CHEST, Element.EARTH));
registerItem(registry, "warlock_leggings_earth", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.LEGS, Element.EARTH));
registerItem(registry, "warlock_boots_earth", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.FEET, Element.EARTH));
registerItem(registry, "warlock_hood_sorcery", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.HEAD, Element.SORCERY));
registerItem(registry, "warlock_robe_sorcery", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.CHEST, Element.SORCERY));
registerItem(registry, "warlock_leggings_sorcery", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.LEGS, Element.SORCERY));
registerItem(registry, "warlock_boots_sorcery", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.FEET, Element.SORCERY));
registerItem(registry, "warlock_hood_healing", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.HEAD, Element.HEALING));
registerItem(registry, "warlock_robe_healing", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.CHEST, Element.HEALING));
registerItem(registry, "warlock_leggings_healing", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.LEGS, Element.HEALING));
registerItem(registry, "warlock_boots_healing", new ItemWizardArmour(ArmourClass.WARLOCK, EntityEquipmentSlot.FEET, Element.HEALING));
registerItem(registry, "spectral_helmet", new ItemSpectralArmour(ArmorMaterial.IRON, 1, EntityEquipmentSlot.HEAD));
registerItem(registry, "spectral_chestplate", new ItemSpectralArmour(ArmorMaterial.IRON, 1, EntityEquipmentSlot.CHEST));
registerItem(registry, "spectral_leggings", new ItemSpectralArmour(ArmorMaterial.IRON, 1, EntityEquipmentSlot.LEGS));
registerItem(registry, "spectral_boots", new ItemSpectralArmour(ArmorMaterial.IRON, 1, EntityEquipmentSlot.FEET));
registerItem(registry, "lightning_hammer", new ItemLightningHammer());
registerItem(registry, "flamecatcher", new ItemFlamecatcher());
registerItem(registry, "ring_condensing", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.RING));
registerItem(registry, "ring_siphoning", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.RING));
registerItem(registry, "ring_battlemage", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.RING));
registerItem(registry, "ring_combustion", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.RING));
registerItem(registry, "ring_fire_melee", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.RING));
registerItem(registry, "ring_fire_biome", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.RING));
registerItem(registry, "ring_disintegration", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.RING));
registerItem(registry, "ring_meteor", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.RING));
registerItem(registry, "ring_ice_melee", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.RING));
registerItem(registry, "ring_ice_biome", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.RING));
registerItem(registry, "ring_arcane_frost", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.RING));
registerItem(registry, "ring_shattering", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.RING));
registerItem(registry, "ring_lightning_melee", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.RING));
registerItem(registry, "ring_storm", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.RING));
registerItem(registry, "ring_seeking", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.RING));
registerItem(registry, "ring_hammer", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.RING));
registerItem(registry, "ring_stormcloud", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.RING));
registerItem(registry, "ring_soulbinding", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.RING));
registerItem(registry, "ring_leeching", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.RING));
registerItem(registry, "ring_necromancy_melee", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.RING));
registerItem(registry, "ring_mind_control", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.RING));
registerItem(registry, "ring_poison", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.RING));
registerItem(registry, "ring_earth_melee", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.RING));
registerItem(registry, "ring_earth_biome", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.RING));
registerItem(registry, "ring_full_moon", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.RING));
registerItem(registry, "ring_evoker", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.RING));
registerItem(registry, "ring_extraction", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.RING));
registerItem(registry, "ring_mana_return", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.RING));
registerItem(registry, "ring_blockwrangler", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.RING));
registerItem(registry, "ring_conjurer", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.RING));
registerItem(registry, "ring_defender", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.RING));
registerItem(registry, "ring_paladin", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.RING));
registerItem(registry, "ring_interdiction", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.RING));
registerItem(registry, "amulet_arcane_defence", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_warding", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_wisdom", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_fire_protection", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_fire_cloaking", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_ice_immunity", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_ice_protection", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_frost_warding", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_potential", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_channeling", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_lich", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_wither_immunity", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_glide", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_banishing", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_anchoring", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_recovery", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_transience", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_resurrection", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_auto_shield", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.AMULET));
registerItem(registry, "amulet_absorption", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.AMULET));
registerItem(registry, "charm_haggler", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_experience_tome", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_move_speed", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_spell_discovery", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_auto_smelt", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_lava_walking", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_storm", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_minion_health", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_minion_variants", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_undead_helmets", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_hunger_casting", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_flight", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_growth", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_abseiling", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_silk_touch", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_sixth_sense", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_stop_time", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_light", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_transportation", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_black_hole", new ItemArtefact(EnumRarity.EPIC, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_mount_teleporting", new ItemArtefact(EnumRarity.RARE, ItemArtefact.Type.CHARM));
registerItem(registry, "charm_feeding", new ItemArtefact(EnumRarity.UNCOMMON, ItemArtefact.Type.CHARM));
}
@@ -756,76 +1001,4 @@ public final class WizardryItems {
EnumHelper.addEnum(BannerPattern.class, codeName, new Class[]{String.class, String.class, ItemStack.class}, fileName, hashName, patternItem);
}
public static void populateWandMap(){
WAND_MAP.put(ImmutablePair.of(Tier.NOVICE, Element.MAGIC), magic_wand);
WAND_MAP.put(ImmutablePair.of(Tier.NOVICE, Element.FIRE), novice_fire_wand);
WAND_MAP.put(ImmutablePair.of(Tier.NOVICE, Element.ICE), novice_ice_wand);
WAND_MAP.put(ImmutablePair.of(Tier.NOVICE, Element.LIGHTNING), novice_lightning_wand);
WAND_MAP.put(ImmutablePair.of(Tier.NOVICE, Element.NECROMANCY), novice_necromancy_wand);
WAND_MAP.put(ImmutablePair.of(Tier.NOVICE, Element.EARTH), novice_earth_wand);
WAND_MAP.put(ImmutablePair.of(Tier.NOVICE, Element.SORCERY), novice_sorcery_wand);
WAND_MAP.put(ImmutablePair.of(Tier.NOVICE, Element.HEALING), novice_healing_wand);
WAND_MAP.put(ImmutablePair.of(Tier.APPRENTICE, Element.MAGIC), apprentice_wand);
WAND_MAP.put(ImmutablePair.of(Tier.APPRENTICE, Element.FIRE), apprentice_fire_wand);
WAND_MAP.put(ImmutablePair.of(Tier.APPRENTICE, Element.ICE), apprentice_ice_wand);
WAND_MAP.put(ImmutablePair.of(Tier.APPRENTICE, Element.LIGHTNING), apprentice_lightning_wand);
WAND_MAP.put(ImmutablePair.of(Tier.APPRENTICE, Element.NECROMANCY), apprentice_necromancy_wand);
WAND_MAP.put(ImmutablePair.of(Tier.APPRENTICE, Element.EARTH), apprentice_earth_wand);
WAND_MAP.put(ImmutablePair.of(Tier.APPRENTICE, Element.SORCERY), apprentice_sorcery_wand);
WAND_MAP.put(ImmutablePair.of(Tier.APPRENTICE, Element.HEALING), apprentice_healing_wand);
WAND_MAP.put(ImmutablePair.of(Tier.ADVANCED, Element.MAGIC), advanced_wand);
WAND_MAP.put(ImmutablePair.of(Tier.ADVANCED, Element.FIRE), advanced_fire_wand);
WAND_MAP.put(ImmutablePair.of(Tier.ADVANCED, Element.ICE), advanced_ice_wand);
WAND_MAP.put(ImmutablePair.of(Tier.ADVANCED, Element.LIGHTNING), advanced_lightning_wand);
WAND_MAP.put(ImmutablePair.of(Tier.ADVANCED, Element.NECROMANCY), advanced_necromancy_wand);
WAND_MAP.put(ImmutablePair.of(Tier.ADVANCED, Element.EARTH), advanced_earth_wand);
WAND_MAP.put(ImmutablePair.of(Tier.ADVANCED, Element.SORCERY), advanced_sorcery_wand);
WAND_MAP.put(ImmutablePair.of(Tier.ADVANCED, Element.HEALING), advanced_healing_wand);
WAND_MAP.put(ImmutablePair.of(Tier.MASTER, Element.MAGIC), master_wand);
WAND_MAP.put(ImmutablePair.of(Tier.MASTER, Element.FIRE), master_fire_wand);
WAND_MAP.put(ImmutablePair.of(Tier.MASTER, Element.ICE), master_ice_wand);
WAND_MAP.put(ImmutablePair.of(Tier.MASTER, Element.LIGHTNING), master_lightning_wand);
WAND_MAP.put(ImmutablePair.of(Tier.MASTER, Element.NECROMANCY), master_necromancy_wand);
WAND_MAP.put(ImmutablePair.of(Tier.MASTER, Element.EARTH), master_earth_wand);
WAND_MAP.put(ImmutablePair.of(Tier.MASTER, Element.SORCERY), master_sorcery_wand);
WAND_MAP.put(ImmutablePair.of(Tier.MASTER, Element.HEALING), master_healing_wand);
}
public static void populateArmourMap(){
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.HEAD, Element.MAGIC), wizard_hat);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.HEAD, Element.FIRE), wizard_hat_fire);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.HEAD, Element.ICE), wizard_hat_ice);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.HEAD, Element.LIGHTNING), wizard_hat_lightning);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.HEAD, Element.NECROMANCY), wizard_hat_necromancy);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.HEAD, Element.EARTH), wizard_hat_earth);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.HEAD, Element.SORCERY), wizard_hat_sorcery);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.HEAD, Element.HEALING), wizard_hat_healing);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.CHEST, Element.MAGIC), wizard_robe);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.CHEST, Element.FIRE), wizard_robe_fire);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.CHEST, Element.ICE), wizard_robe_ice);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.CHEST, Element.LIGHTNING), wizard_robe_lightning);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.CHEST, Element.NECROMANCY), wizard_robe_necromancy);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.CHEST, Element.EARTH), wizard_robe_earth);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.CHEST, Element.SORCERY), wizard_robe_sorcery);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.CHEST, Element.HEALING), wizard_robe_healing);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.LEGS, Element.MAGIC), wizard_leggings);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.LEGS, Element.FIRE), wizard_leggings_fire);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.LEGS, Element.ICE), wizard_leggings_ice);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.LEGS, Element.LIGHTNING), wizard_leggings_lightning);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.LEGS, Element.NECROMANCY), wizard_leggings_necromancy);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.LEGS, Element.EARTH), wizard_leggings_earth);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.LEGS, Element.SORCERY), wizard_leggings_sorcery);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.LEGS, Element.HEALING), wizard_leggings_healing);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.FEET, Element.MAGIC), wizard_boots);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.FEET, Element.FIRE), wizard_boots_fire);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.FEET, Element.ICE), wizard_boots_ice);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.FEET, Element.LIGHTNING), wizard_boots_lightning);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.FEET, Element.NECROMANCY), wizard_boots_necromancy);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.FEET, Element.EARTH), wizard_boots_earth);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.FEET, Element.SORCERY), wizard_boots_sorcery);
ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.FEET, Element.HEALING), wizard_boots_healing);
}
}
@@ -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
@@ -40,6 +40,9 @@ public final class WizardrySounds {
public static final SoundEvent ITEM_WAND_MELEE = createSound("item.wand.melee");
public static final SoundEvent ITEM_WAND_CHARGEUP = createSound("item.wand.chargeup");
public static final SoundEvent ITEM_ARMOUR_EQUIP_SILK = createSound("item.armour.equip_silk");
public static final SoundEvent ITEM_ARMOUR_EQUIP_SAGE = createSound("item.armour.equip_sage");
public static final SoundEvent ITEM_ARMOUR_EQUIP_BATTLEMAGE = createSound("item.armour.equip_battlemage");
public static final SoundEvent ITEM_ARMOUR_EQUIP_WARLOCK = createSound("item.armour.equip_warlock");
public static final SoundEvent ITEM_PURIFYING_ELIXIR_DRINK = createSound("item.purifying_elixir.drink");
public static final SoundEvent ITEM_MANA_FLASK_USE = createSound("item.mana_flask.use");
public static final SoundEvent ITEM_MANA_FLASK_RECHARGE = createSound("item.mana_flask.recharge");
@@ -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(),
@@ -12,11 +12,13 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.common.eventhandler.EventPriority;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import javax.annotation.Nullable;
@EventBusSubscriber
public class FontOfMana extends SpellAreaEffect {
public FontOfMana(){
@@ -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 + 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()));
@@ -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);
}
}
}
}
}
}
}
@@ -319,8 +319,24 @@ public abstract class Spell extends IForgeRegistryEntry.Impl<Spell> implements C
// To avoid sending extra data unnecessarily, the spell properties are sent in order of spell ID
List<Spell> spells = new ArrayList<>(registry.getValuesCollection());
spells.sort(Comparator.comparingInt(Spell::networkID));
WizardryPacketHandler.net.sendTo(new PacketSpellProperties.Message(spells.stream()
.map(s -> s.properties).toArray(SpellProperties[]::new)), player);
SpellProperties[] propertiesArray = spells.stream().map(s -> s.properties).toArray(SpellProperties[]::new);
// splitting the packet into batches of 100 spells
int i = 0;
while (i < propertiesArray.length) {
List<SpellProperties> propertiesList = new ArrayList<>();
int first = i;
int batchCounter = 0;
for (int currentIndex = i; currentIndex < propertiesArray.length && batchCounter < 100; currentIndex++) {
propertiesList.add(propertiesArray[currentIndex]);
batchCounter++;
i++;
}
SpellProperties[] currentArray = propertiesList.toArray(new SpellProperties[0]);
PacketSpellProperties.Message currentPacket = new PacketSpellProperties.Message(first, currentArray.length, currentArray);
WizardryPacketHandler.net.sendTo(currentPacket, player);
}
}
private static void clearProperties(){
@@ -189,7 +189,9 @@ public class TileEntityArcaneWorkbench extends TileEntity implements IInventory,
}else if(slotNumber == ContainerArcaneWorkbench.UPGRADE_SLOT){
Set<Item> upgrades = new HashSet<>(WandHelper.getSpecialUpgrades());
upgrades.add(WizardryItems.arcane_tome);
upgrades.add(WizardryItems.armour_upgrade);
upgrades.add(WizardryItems.resplendent_thread);
upgrades.add(WizardryItems.crystal_silver_plating);
upgrades.add(WizardryItems.ethereal_crystalweave);
return upgrades.contains(itemstack.getItem());
}
@@ -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,11 +235,19 @@ 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
ItemStack result = new ItemStack(WizardryItems.getArmour(receptacleElements[0], ((ItemWizardArmour)input.getItem()).armorType));
ItemStack result = new ItemStack(ItemWizardArmour.getArmour(receptacleElements[0], ((ItemWizardArmour)input.getItem()).armourClass, ((ItemWizardArmour)input.getItem()).armorType));
result.setTagCompound(input.getTagCompound());
((IManaStoringItem)result.getItem()).setMana(result, ((ItemWizardArmour)input.getItem()).getMana(input));
@@ -419,7 +419,7 @@ public final class BlockUtils {
world.setBlockState(pos, Blocks.OBSIDIAN.getDefaultState());
}else if(freezeLava && (block == Blocks.LAVA || block == Blocks.FLOWING_LAVA)){
world.setBlockState(pos, Blocks.COBBLESTONE.getDefaultState());
}else if(world.getBlockState(pos).getBlock().isReplaceable(world, pos.up()) && Blocks.SNOW_LAYER.canPlaceBlockAt(world, pos.up())){
}else if(canBlockBeReplaced(world, pos.up()) && Blocks.SNOW_LAYER.canPlaceBlockAt(world, pos.up())){
world.setBlockState(pos.up(), Blocks.SNOW_LAYER.getDefaultState());
}else{
return false;
@@ -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;
@@ -68,6 +69,24 @@ public final class SpellModifiers {
return new SpellModifiers(new HashMap<>(this.multiplierMap), new HashMap<>(this.syncedMultiplierMap));
}
/**
* Combines the given SpellModifiers object with this one. More specifically: for each modifier, multiplies the
* values from both objects together and sets it to sync if either object does so. This method changes the object
* it is called on but not the one given as a parameter; apart from this it does not matter which way round the two
* objects are.
* @param modifiers The SpellModifiers object to combine with this one; will not be modified by this method.
* @return The SpellModifiers object, allowing this method to be chained onto the constructor.
*/
public SpellModifiers combine(SpellModifiers modifiers){
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
boolean sync = this.syncedMultiplierMap.containsKey(key) || modifiers.syncedMultiplierMap.containsKey(key);
this.set(key, newValue, sync);
}
return this;
}
/**
* Adds the given multiplier to this SpellModifiers object, using the string identifier that the given wand upgrade
* item was registered with.
@@ -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);
@@ -0,0 +1,309 @@
{
"display": {
"title": {
"translate": "advancement.ebwizardry:battlemage"
},
"description": {
"translate": "advancement.ebwizardry:battlemage.desc"
},
"icon": {
"item": "ebwizardry:battlemage_boots"
},
"frame": "goal"
},
"parent": "ebwizardry:armour_set",
"criteria": {
"head": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_helmet"
}
}
},
"chest": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_chestplate"
}
}
},
"legs": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_leggings"
}
}
},
"feet": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_boots"
}
}
},
"head_fire": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_helmet_fire"
}
}
},
"chest_fire": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_chestplate_fire"
}
}
},
"legs_fire": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_leggings_fire"
}
}
},
"feet_fire": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_boots_fire"
}
}
},
"head_ice": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_helmet_ice"
}
}
},
"chest_ice": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_chestplate_ice"
}
}
},
"legs_ice": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_leggings_ice"
}
}
},
"feet_ice": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_boots_ice"
}
}
},
"head_lightning": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_helmet_lightning"
}
}
},
"chest_lightning": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_chestplate_lightning"
}
}
},
"legs_lightning": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_leggings_lightning"
}
}
},
"feet_lightning": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_boots_lightning"
}
}
},
"head_necromancy": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_helmet_necromancy"
}
}
},
"chest_necromancy": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_chestplate_necromancy"
}
}
},
"legs_necromancy": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_leggings_necromancy"
}
}
},
"feet_necromancy": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_boots_necromancy"
}
}
},
"head_earth": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_helmet_earth"
}
}
},
"chest_earth": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_chestplate_earth"
}
}
},
"legs_earth": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_leggings_earth"
}
}
},
"feet_earth": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_boots_earth"
}
}
},
"head_sorcery": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_helmet_sorcery"
}
}
},
"chest_sorcery": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_chestplate_sorcery"
}
}
},
"legs_sorcery": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_leggings_sorcery"
}
}
},
"feet_sorcery": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_boots_sorcery"
}
}
},
"head_healing": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_helmet_healing"
}
}
},
"chest_healing": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_chestplate_healing"
}
}
},
"legs_healing": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_leggings_healing"
}
}
},
"feet_healing": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:battlemage_boots_healing"
}
}
}
},
"requirements": [
[
"head",
"chest",
"legs",
"feet",
"head_fire",
"chest_fire",
"legs_fire",
"feet_fire",
"head_ice",
"chest_ice",
"legs_ice",
"feet_ice",
"head_lightning",
"chest_lightning",
"legs_lightning",
"feet_lightning",
"head_necromancy",
"chest_necromancy",
"legs_necromancy",
"feet_necromancy",
"head_earth",
"chest_earth",
"legs_earth",
"feet_earth",
"head_sorcery",
"chest_sorcery",
"legs_sorcery",
"feet_sorcery",
"head_healing",
"chest_healing",
"legs_healing",
"feet_healing"
]
]
}
@@ -1,20 +0,0 @@
{
"display": {
"title": {
"translate": "advancement.ebwizardry:legendary"
},
"description": {
"translate": "advancement.ebwizardry:legendary.desc"
},
"icon": {
"item": "ebwizardry:armour_upgrade"
},
"frame": "goal"
},
"parent": "ebwizardry:armour_set",
"criteria": {
"criteria_0": {
"trigger": "ebwizardry:trigger_legendary"
}
}
}
@@ -0,0 +1,309 @@
{
"display": {
"title": {
"translate": "advancement.ebwizardry:sage"
},
"description": {
"translate": "advancement.ebwizardry:sage.desc"
},
"icon": {
"item": "ebwizardry:sage_robe"
},
"frame": "goal"
},
"parent": "ebwizardry:armour_set",
"criteria": {
"head": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_hat"
}
}
},
"chest": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_robe"
}
}
},
"legs": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_leggings"
}
}
},
"feet": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_boots"
}
}
},
"head_fire": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_hat_fire"
}
}
},
"chest_fire": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_robe_fire"
}
}
},
"legs_fire": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_leggings_fire"
}
}
},
"feet_fire": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_boots_fire"
}
}
},
"head_ice": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_hat_ice"
}
}
},
"chest_ice": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_robe_ice"
}
}
},
"legs_ice": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_leggings_ice"
}
}
},
"feet_ice": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_boots_ice"
}
}
},
"head_lightning": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_hat_lightning"
}
}
},
"chest_lightning": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_robe_lightning"
}
}
},
"legs_lightning": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_leggings_lightning"
}
}
},
"feet_lightning": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_boots_lightning"
}
}
},
"head_necromancy": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_hat_necromancy"
}
}
},
"chest_necromancy": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_robe_necromancy"
}
}
},
"legs_necromancy": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_leggings_necromancy"
}
}
},
"feet_necromancy": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_boots_necromancy"
}
}
},
"head_earth": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_hat_earth"
}
}
},
"chest_earth": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_robe_earth"
}
}
},
"legs_earth": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_leggings_earth"
}
}
},
"feet_earth": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_boots_earth"
}
}
},
"head_sorcery": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_hat_sorcery"
}
}
},
"chest_sorcery": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_robe_sorcery"
}
}
},
"legs_sorcery": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_leggings_sorcery"
}
}
},
"feet_sorcery": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_boots_sorcery"
}
}
},
"head_healing": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_hat_healing"
}
}
},
"chest_healing": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_robe_healing"
}
}
},
"legs_healing": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_leggings_healing"
}
}
},
"feet_healing": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:sage_boots_healing"
}
}
}
},
"requirements": [
[
"head",
"chest",
"legs",
"feet",
"head_fire",
"chest_fire",
"legs_fire",
"feet_fire",
"head_ice",
"chest_ice",
"legs_ice",
"feet_ice",
"head_lightning",
"chest_lightning",
"legs_lightning",
"feet_lightning",
"head_necromancy",
"chest_necromancy",
"legs_necromancy",
"feet_necromancy",
"head_earth",
"chest_earth",
"legs_earth",
"feet_earth",
"head_sorcery",
"chest_sorcery",
"legs_sorcery",
"feet_sorcery",
"head_healing",
"chest_healing",
"legs_healing",
"feet_healing"
]
]
}
@@ -0,0 +1,309 @@
{
"display": {
"title": {
"translate": "advancement.ebwizardry:warlock"
},
"description": {
"translate": "advancement.ebwizardry:warlock.desc"
},
"icon": {
"item": "ebwizardry:warlock_hood"
},
"frame": "goal"
},
"parent": "ebwizardry:armour_set",
"criteria": {
"head": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_hood"
}
}
},
"chest": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_robe"
}
}
},
"legs": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_leggings"
}
}
},
"feet": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_boots"
}
}
},
"head_fire": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_hood_fire"
}
}
},
"chest_fire": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_robe_fire"
}
}
},
"legs_fire": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_leggings_fire"
}
}
},
"feet_fire": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_boots_fire"
}
}
},
"head_ice": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_hood_ice"
}
}
},
"chest_ice": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_robe_ice"
}
}
},
"legs_ice": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_leggings_ice"
}
}
},
"feet_ice": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_boots_ice"
}
}
},
"head_lightning": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_hood_lightning"
}
}
},
"chest_lightning": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_robe_lightning"
}
}
},
"legs_lightning": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_leggings_lightning"
}
}
},
"feet_lightning": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_boots_lightning"
}
}
},
"head_necromancy": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_hood_necromancy"
}
}
},
"chest_necromancy": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_robe_necromancy"
}
}
},
"legs_necromancy": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_leggings_necromancy"
}
}
},
"feet_necromancy": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_boots_necromancy"
}
}
},
"head_earth": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_hood_earth"
}
}
},
"chest_earth": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_robe_earth"
}
}
},
"legs_earth": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_leggings_earth"
}
}
},
"feet_earth": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_boots_earth"
}
}
},
"head_sorcery": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_hood_sorcery"
}
}
},
"chest_sorcery": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_robe_sorcery"
}
}
},
"legs_sorcery": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_leggings_sorcery"
}
}
},
"feet_sorcery": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_boots_sorcery"
}
}
},
"head_healing": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_hood_healing"
}
}
},
"chest_healing": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_robe_healing"
}
}
},
"legs_healing": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_leggings_healing"
}
}
},
"feet_healing": {
"trigger": "ebwizardry:arcane_workbench",
"conditions": {
"item": {
"item": "ebwizardry:warlock_boots_healing"
}
}
}
},
"requirements": [
[
"head",
"chest",
"legs",
"feet",
"head_fire",
"chest_fire",
"legs_fire",
"feet_fire",
"head_ice",
"chest_ice",
"legs_ice",
"feet_ice",
"head_lightning",
"chest_lightning",
"legs_lightning",
"feet_lightning",
"head_necromancy",
"chest_necromancy",
"legs_necromancy",
"feet_necromancy",
"head_earth",
"chest_earth",
"legs_earth",
"feet_earth",
"head_sorcery",
"chest_sorcery",
"legs_sorcery",
"feet_sorcery",
"head_healing",
"chest_healing",
"legs_healing",
"feet_healing"
]
]
}
@@ -200,18 +200,32 @@ item.ebwizardry\:identification_scroll.desc=Identifies an unknown spell book or
item.ebwizardry\:identification_scroll.desc_extended=Right-click while holding this scroll to identify the first undiscovered spell book or scroll on your hotbar.
item.ebwizardry\:identification_scroll.nothing_to_identify=Nothing to identify!
item.ebwizardry\:armour_upgrade.name=Arcane Seal of Protection
item.ebwizardry\:armour_upgrade.desc=Upgrades any wizard armour to make it %1$slegendary
item.ebwizardry\:armour_upgrade.desc_extended=Apply this upgrade to a piece of wizard armour in the arcane workbench.
item.ebwizardry\:resplendent_thread.name=Resplendent Thread
item.ebwizardry\:resplendent_thread.desc=Upgrades regular wizard armour into sage armour
item.ebwizardry\:resplendent_thread.desc_extended=A shimmering silken thread used to embroider the finest robes with arcane symbols, improving their enchantability.\n\nApply this upgrade to a piece of wizard armour in the arcane workbench.
item.ebwizardry\:crystal_silver_plating.name=Crystal Silver Plating
item.ebwizardry\:crystal_silver_plating.desc=Upgrades regular wizard armour into battlemage armour
item.ebwizardry\:crystal_silver_plating.desc_extended=An almost mythical alloy forged in the foundries of Eldar, with exceptional magic deflection properties.\n\nApply this upgrade to a piece of wizard armour in the arcane workbench.
item.ebwizardry\:ethereal_crystalweave.name=Ethereal Crystalweave
item.ebwizardry\:ethereal_crystalweave.desc=Upgrades regular wizard armour into warlock armour
item.ebwizardry\:ethereal_crystalweave.desc_extended=An enchanted fabric that is as thick as animal hide, yet somehow feels lighter than paper in one's hands.\n\nApply this upgrade to a piece of wizard armour in the arcane workbench.
item.ebwizardry\:magic_silk.name=Magical Silk
item.ebwizardry\:spectral_dust.name=Spectral Dust
item.ebwizardry\:wizard_armour.legendary=Legendary
item.ebwizardry\:wizard_armour.buff=-%1$s%% %2$s cost
item.ebwizardry\:wizard_armour.element_cost_reduction=-%1$s%% %2$s cost
item.ebwizardry\:wizard_armour.cooldown_reduction=-%1$s%% Cooldown
item.ebwizardry\:wizard_armour.enchantability=Extra enchantability
item.ebwizardry\:wizard_armour.mana=Mana\: %1$s/%2$s
item.ebwizardry\:wizard_armour.full_set=Full set:
item.ebwizardry\:sage_armour.full_set_bonus=-%1$s%% Other element cost
item.ebwizardry\:battlemage_armour.full_set_bonus=Ward I effect
item.ebwizardry\:warlock_armour.full_set_bonus=+%1$s%% Movement speed
item.ebwizardry\:wizard_hat.name=Wizard Hat
item.ebwizardry\:wizard_robe.name=Wizard Robes
item.ebwizardry\:wizard_leggings.name=Wizard Leggings
@@ -252,6 +266,126 @@ item.ebwizardry\:wizard_robe_healing.name=Healer Robes
item.ebwizardry\:wizard_leggings_healing.name=Healer Leggings
item.ebwizardry\:wizard_boots_healing.name=Healer Boots
item.ebwizardry\:sage_hat.name=Sage Hat
item.ebwizardry\:sage_robe.name=Sage Robes
item.ebwizardry\:sage_leggings.name=Sage Leggings
item.ebwizardry\:sage_boots.name=Sage Boots
item.ebwizardry\:sage_hat_fire.name=Pyromancer Sage Hat
item.ebwizardry\:sage_robe_fire.name=Pyromancer Sage Robes
item.ebwizardry\:sage_leggings_fire.name=Pyromancer Sage Leggings
item.ebwizardry\:sage_boots_fire.name=Pyromancer Sage Boots
item.ebwizardry\:sage_hat_ice.name=Ice Sage Hat
item.ebwizardry\:sage_robe_ice.name=Ice Sage Robes
item.ebwizardry\:sage_leggings_ice.name=Ice Sage Leggings
item.ebwizardry\:sage_boots_ice.name=Ice Sage Boots
item.ebwizardry\:sage_hat_lightning.name=Storm Sage Hat
item.ebwizardry\:sage_robe_lightning.name=Storm Sage Robes
item.ebwizardry\:sage_leggings_lightning.name=Storm Sage Leggings
item.ebwizardry\:sage_boots_lightning.name=Storm Sage Boots
item.ebwizardry\:sage_hat_necromancy.name=Necromancer Sage Hat
item.ebwizardry\:sage_robe_necromancy.name=Necromancer Sage Robes
item.ebwizardry\:sage_leggings_necromancy.name=Necromancer Sage Leggings
item.ebwizardry\:sage_boots_necromancy.name=Necromancer Sage Boots
item.ebwizardry\:sage_hat_earth.name=Earth Sage Hat
item.ebwizardry\:sage_robe_earth.name=Earth Sage Robes
item.ebwizardry\:sage_leggings_earth.name=Earth Sage Leggings
item.ebwizardry\:sage_boots_earth.name=Earth Sage Boots
item.ebwizardry\:sage_hat_sorcery.name=Sorcerer Sage Hat
item.ebwizardry\:sage_robe_sorcery.name=Sorcerer Sage Robes
item.ebwizardry\:sage_leggings_sorcery.name=Sorcerer Sage Leggings
item.ebwizardry\:sage_boots_sorcery.name=Sorcerer Sage Boots
item.ebwizardry\:sage_hat_healing.name=Healer Sage Hat
item.ebwizardry\:sage_robe_healing.name=Healer Sage Robes
item.ebwizardry\:sage_leggings_healing.name=Healer Sage Leggings
item.ebwizardry\:sage_boots_healing.name=Healer Sage Boots
item.ebwizardry\:battlemage_helmet.name=Battlemage Helmet
item.ebwizardry\:battlemage_chestplate.name=Battlemage Chestplate
item.ebwizardry\:battlemage_leggings.name=Battlemage Leggings
item.ebwizardry\:battlemage_boots.name=Battlemage Boots
item.ebwizardry\:battlemage_helmet_fire.name=Pyromancer Battlemage Helmet
item.ebwizardry\:battlemage_chestplate_fire.name=Pyromancer Battlemage Chestplate
item.ebwizardry\:battlemage_leggings_fire.name=Pyromancer Battlemage Leggings
item.ebwizardry\:battlemage_boots_fire.name=Pyromancer Battlemage Boots
item.ebwizardry\:battlemage_helmet_ice.name=Ice Battlemage Helmet
item.ebwizardry\:battlemage_chestplate_ice.name=Ice Battlemage Chestplate
item.ebwizardry\:battlemage_leggings_ice.name=Ice Battlemage Leggings
item.ebwizardry\:battlemage_boots_ice.name=Ice Battlemage Boots
item.ebwizardry\:battlemage_helmet_lightning.name=Storm Battlemage Helmet
item.ebwizardry\:battlemage_chestplate_lightning.name=Storm Battlemage Chestplate
item.ebwizardry\:battlemage_leggings_lightning.name=Storm Battlemage Leggings
item.ebwizardry\:battlemage_boots_lightning.name=Storm Battlemage Boots
item.ebwizardry\:battlemage_helmet_necromancy.name=Necromancer Battlemage Helmet
item.ebwizardry\:battlemage_chestplate_necromancy.name=Necromancer Battlemage Chestplate
item.ebwizardry\:battlemage_leggings_necromancy.name=Necromancer Battlemage Leggings
item.ebwizardry\:battlemage_boots_necromancy.name=Necromancer Battlemage Boots
item.ebwizardry\:battlemage_helmet_earth.name=Earth Battlemage Helmet
item.ebwizardry\:battlemage_chestplate_earth.name=Earth Battlemage Chestplate
item.ebwizardry\:battlemage_leggings_earth.name=Earth Battlemage Leggings
item.ebwizardry\:battlemage_boots_earth.name=Earth Battlemage Boots
item.ebwizardry\:battlemage_helmet_sorcery.name=Sorcerer Battlemage Helmet
item.ebwizardry\:battlemage_chestplate_sorcery.name=Sorcerer Battlemage Chestplate
item.ebwizardry\:battlemage_leggings_sorcery.name=Sorcerer Battlemage Leggings
item.ebwizardry\:battlemage_boots_sorcery.name=Sorcerer Battlemage Boots
item.ebwizardry\:battlemage_helmet_healing.name=Healer Battlemage Helmet
item.ebwizardry\:battlemage_chestplate_healing.name=Healer Battlemage Chestplate
item.ebwizardry\:battlemage_leggings_healing.name=Healer Battlemage Leggings
item.ebwizardry\:battlemage_boots_healing.name=Healer Battlemage Boots
item.ebwizardry\:warlock_hood.name=Warlock Hood
item.ebwizardry\:warlock_robe.name=Warlock Robes
item.ebwizardry\:warlock_leggings.name=Warlock Leggings
item.ebwizardry\:warlock_boots.name=Warlock Boots
item.ebwizardry\:warlock_hood_fire.name=Pyromancer Warlock Hood
item.ebwizardry\:warlock_robe_fire.name=Pyromancer Warlock Robes
item.ebwizardry\:warlock_leggings_fire.name=Pyromancer Warlock Leggings
item.ebwizardry\:warlock_boots_fire.name=Pyromancer Warlock Boots
item.ebwizardry\:warlock_hood_ice.name=Ice Warlock Hood
item.ebwizardry\:warlock_robe_ice.name=Ice Warlock Robes
item.ebwizardry\:warlock_leggings_ice.name=Ice Warlock Leggings
item.ebwizardry\:warlock_boots_ice.name=Ice Warlock Boots
item.ebwizardry\:warlock_hood_lightning.name=Storm Warlock Hood
item.ebwizardry\:warlock_robe_lightning.name=Storm Warlock Robes
item.ebwizardry\:warlock_leggings_lightning.name=Storm Warlock Leggings
item.ebwizardry\:warlock_boots_lightning.name=Storm Warlock Boots
item.ebwizardry\:warlock_hood_necromancy.name=Necromancer Warlock Hood
item.ebwizardry\:warlock_robe_necromancy.name=Necromancer Warlock Robes
item.ebwizardry\:warlock_leggings_necromancy.name=Necromancer Warlock Leggings
item.ebwizardry\:warlock_boots_necromancy.name=Necromancer Warlock Boots
item.ebwizardry\:warlock_hood_earth.name=Earth Warlock Hood
item.ebwizardry\:warlock_robe_earth.name=Earth Warlock Robes
item.ebwizardry\:warlock_leggings_earth.name=Earth Warlock Leggings
item.ebwizardry\:warlock_boots_earth.name=Earth Warlock Boots
item.ebwizardry\:warlock_hood_sorcery.name=Sorcerer Warlock Hood
item.ebwizardry\:warlock_robe_sorcery.name=Sorcerer Warlock Robes
item.ebwizardry\:warlock_leggings_sorcery.name=Sorcerer Warlock Leggings
item.ebwizardry\:warlock_boots_sorcery.name=Sorcerer Warlock Boots
item.ebwizardry\:warlock_hood_healing.name=Healer Warlock Hood
item.ebwizardry\:warlock_robe_healing.name=Healer Warlock Robes
item.ebwizardry\:warlock_leggings_healing.name=Healer Warlock Leggings
item.ebwizardry\:warlock_boots_healing.name=Healer Warlock Boots
item.ebwizardry\:spawn_wizard.name=Spawn Wizard
item.ebwizardry\:spawn_evil_wizard.name=Spawn Evil Wizard
@@ -711,8 +845,12 @@ advancement.ebwizardry\:craft_lectern.desc=Craft a lectern to keep track of your
advancement.ebwizardry\:armour_set=Now You're A Proper Wizard
advancement.ebwizardry\:armour_set.desc=Craft and equip a full set of wizard armour
advancement.ebwizardry\:legendary=Legendary
advancement.ebwizardry\:legendary.desc=Obtain a piece of legendary wizard armour
advancement.ebwizardry\:sage=The Path Of The Sage
advancement.ebwizardry\:sage.desc=Obtain a piece of sage armour
advancement.ebwizardry\:battlemage=The Pledge Of The Battlemage
advancement.ebwizardry\:battlemage.desc=Obtain a piece of battlemage armour
advancement.ebwizardry\:warlock=The Way Of The Warlock
advancement.ebwizardry\:warlock.desc=Obtain a piece of warlock armour
advancement.ebwizardry\:enchant_scroll=Scroll Up!
advancement.ebwizardry\:enchant_scroll.desc=Craft a blank scroll and enchant it with a spell at an arcane workbench
@@ -1336,6 +1474,8 @@ commands.ebwizardry\:discoverspell.removespell=Removed %1$s from %2$s's spell di
config.ebwizardry.title.general=Mod Options
config.ebwizardry.redundant_keys=Your config file contains redundant options, these will not do anything! [See log for details]
config.ebwizardry.generic.true=Enabled
config.ebwizardry.generic.false=Disabled
@@ -200,18 +200,32 @@ item.ebwizardry\:identification_scroll.desc=Identifies an unknown spell book or
item.ebwizardry\:identification_scroll.desc_extended=Right-click while holding this scroll to identify the first undiscovered spell book or scroll on your hotbar.
item.ebwizardry\:identification_scroll.nothing_to_identify=Nothing to identify!
item.ebwizardry\:armour_upgrade.name=Arcane Seal of Protection
item.ebwizardry\:armour_upgrade.desc=Upgrades any wizard armour to make it %1$slegendary
item.ebwizardry\:armour_upgrade.desc_extended=Apply this upgrade to a piece of wizard armour in the arcane workbench.
item.ebwizardry\:resplendent_thread.name=Resplendent Thread
item.ebwizardry\:resplendent_thread.desc=Upgrades regular wizard armor into sage armor
item.ebwizardry\:resplendent_thread.desc_extended=A shimmering silken thread used to embroider the finest robes with arcane symbols, improving their enchantability.\n\nApply this upgrade to a piece of wizard armor in the arcane workbench.
item.ebwizardry\:crystal_silver_plating.name=Crystal Silver Plating
item.ebwizardry\:crystal_silver_plating.desc=Upgrades regular wizard armor into battlemage armor
item.ebwizardry\:crystal_silver_plating.desc_extended=An almost mythical alloy forged in the foundries of Eldar, with exceptional magic deflection properties.\n\nApply this upgrade to a piece of wizard armor in the arcane workbench.
item.ebwizardry\:ethereal_crystalweave.name=Ethereal Crystalweave
item.ebwizardry\:ethereal_crystalweave.desc=Upgrades regular wizard armor into warlock armor
item.ebwizardry\:ethereal_crystalweave.desc_extended=An enchanted fabric that is as thick as animal hide, yet somehow feels lighter than paper in one's hands.\n\nApply this upgrade to a piece of wizard armor in the arcane workbench.
item.ebwizardry\:magic_silk.name=Magical Silk
item.ebwizardry\:spectral_dust.name=Spectral Dust
item.ebwizardry\:wizard_armour.legendary=Legendary
item.ebwizardry\:wizard_armour.buff=-%1$s%% %2$s cost
item.ebwizardry\:wizard_armour.element_cost_reduction=-%1$s%% %2$s cost
item.ebwizardry\:wizard_armour.cooldown_reduction=-%1$s%% Cooldown
item.ebwizardry\:wizard_armour.enchantability=Extra enchantability
item.ebwizardry\:wizard_armour.mana=Mana\: %1$s/%2$s
item.ebwizardry\:wizard_armour.full_set=Full set:
item.ebwizardry\:sage_armour.full_set_bonus=-%1$s%% Other element cost
item.ebwizardry\:battlemage_armour.full_set_bonus=Ward I effect
item.ebwizardry\:warlock_armour.full_set_bonus=+%1$s%% Movement speed
item.ebwizardry\:wizard_hat.name=Wizard Hat
item.ebwizardry\:wizard_robe.name=Wizard Robes
item.ebwizardry\:wizard_leggings.name=Wizard Leggings
@@ -252,6 +266,126 @@ item.ebwizardry\:wizard_robe_healing.name=Healer Robes
item.ebwizardry\:wizard_leggings_healing.name=Healer Leggings
item.ebwizardry\:wizard_boots_healing.name=Healer Boots
item.ebwizardry\:sage_hat.name=Sage Hat
item.ebwizardry\:sage_robe.name=Sage Robes
item.ebwizardry\:sage_leggings.name=Sage Leggings
item.ebwizardry\:sage_boots.name=Sage Boots
item.ebwizardry\:sage_hat_fire.name=Pyromancer Sage Hat
item.ebwizardry\:sage_robe_fire.name=Pyromancer Sage Robes
item.ebwizardry\:sage_leggings_fire.name=Pyromancer Sage Leggings
item.ebwizardry\:sage_boots_fire.name=Pyromancer Sage Boots
item.ebwizardry\:sage_hat_ice.name=Ice Sage Hat
item.ebwizardry\:sage_robe_ice.name=Ice Sage Robes
item.ebwizardry\:sage_leggings_ice.name=Ice Sage Leggings
item.ebwizardry\:sage_boots_ice.name=Ice Sage Boots
item.ebwizardry\:sage_hat_lightning.name=Storm Sage Hat
item.ebwizardry\:sage_robe_lightning.name=Storm Sage Robes
item.ebwizardry\:sage_leggings_lightning.name=Storm Sage Leggings
item.ebwizardry\:sage_boots_lightning.name=Storm Sage Boots
item.ebwizardry\:sage_hat_necromancy.name=Necromancer Sage Hat
item.ebwizardry\:sage_robe_necromancy.name=Necromancer Sage Robes
item.ebwizardry\:sage_leggings_necromancy.name=Necromancer Sage Leggings
item.ebwizardry\:sage_boots_necromancy.name=Necromancer Sage Boots
item.ebwizardry\:sage_hat_earth.name=Earth Sage Hat
item.ebwizardry\:sage_robe_earth.name=Earth Sage Robes
item.ebwizardry\:sage_leggings_earth.name=Earth Sage Leggings
item.ebwizardry\:sage_boots_earth.name=Earth Sage Boots
item.ebwizardry\:sage_hat_sorcery.name=Sorcerer Sage Hat
item.ebwizardry\:sage_robe_sorcery.name=Sorcerer Sage Robes
item.ebwizardry\:sage_leggings_sorcery.name=Sorcerer Sage Leggings
item.ebwizardry\:sage_boots_sorcery.name=Sorcerer Sage Boots
item.ebwizardry\:sage_hat_healing.name=Healer Sage Hat
item.ebwizardry\:sage_robe_healing.name=Healer Sage Robes
item.ebwizardry\:sage_leggings_healing.name=Healer Sage Leggings
item.ebwizardry\:sage_boots_healing.name=Healer Sage Boots
item.ebwizardry\:battlemage_helmet.name=Battlemage Helmet
item.ebwizardry\:battlemage_chestplate.name=Battlemage Chestplate
item.ebwizardry\:battlemage_leggings.name=Battlemage Leggings
item.ebwizardry\:battlemage_boots.name=Battlemage Boots
item.ebwizardry\:battlemage_helmet_fire.name=Pyromancer Battlemage Helmet
item.ebwizardry\:battlemage_chestplate_fire.name=Pyromancer Battlemage Chestplate
item.ebwizardry\:battlemage_leggings_fire.name=Pyromancer Battlemage Leggings
item.ebwizardry\:battlemage_boots_fire.name=Pyromancer Battlemage Boots
item.ebwizardry\:battlemage_helmet_ice.name=Ice Battlemage Helmet
item.ebwizardry\:battlemage_chestplate_ice.name=Ice Battlemage Chestplate
item.ebwizardry\:battlemage_leggings_ice.name=Ice Battlemage Leggings
item.ebwizardry\:battlemage_boots_ice.name=Ice Battlemage Boots
item.ebwizardry\:battlemage_helmet_lightning.name=Storm Battlemage Helmet
item.ebwizardry\:battlemage_chestplate_lightning.name=Storm Battlemage Chestplate
item.ebwizardry\:battlemage_leggings_lightning.name=Storm Battlemage Leggings
item.ebwizardry\:battlemage_boots_lightning.name=Storm Battlemage Boots
item.ebwizardry\:battlemage_helmet_necromancy.name=Necromancer Battlemage Helmet
item.ebwizardry\:battlemage_chestplate_necromancy.name=Necromancer Battlemage Chestplate
item.ebwizardry\:battlemage_leggings_necromancy.name=Necromancer Battlemage Leggings
item.ebwizardry\:battlemage_boots_necromancy.name=Necromancer Battlemage Boots
item.ebwizardry\:battlemage_helmet_earth.name=Earth Battlemage Helmet
item.ebwizardry\:battlemage_chestplate_earth.name=Earth Battlemage Chestplate
item.ebwizardry\:battlemage_leggings_earth.name=Earth Battlemage Leggings
item.ebwizardry\:battlemage_boots_earth.name=Earth Battlemage Boots
item.ebwizardry\:battlemage_helmet_sorcery.name=Sorcerer Battlemage Helmet
item.ebwizardry\:battlemage_chestplate_sorcery.name=Sorcerer Battlemage Chestplate
item.ebwizardry\:battlemage_leggings_sorcery.name=Sorcerer Battlemage Leggings
item.ebwizardry\:battlemage_boots_sorcery.name=Sorcerer Battlemage Boots
item.ebwizardry\:battlemage_helmet_healing.name=Healer Battlemage Helmet
item.ebwizardry\:battlemage_chestplate_healing.name=Healer Battlemage Chestplate
item.ebwizardry\:battlemage_leggings_healing.name=Healer Battlemage Leggings
item.ebwizardry\:battlemage_boots_healing.name=Healer Battlemage Boots
item.ebwizardry\:warlock_hood.name=Warlock Hood
item.ebwizardry\:warlock_robe.name=Warlock Robes
item.ebwizardry\:warlock_leggings.name=Warlock Leggings
item.ebwizardry\:warlock_boots.name=Warlock Boots
item.ebwizardry\:warlock_hood_fire.name=Pyromancer Warlock Hood
item.ebwizardry\:warlock_robe_fire.name=Pyromancer Warlock Robes
item.ebwizardry\:warlock_leggings_fire.name=Pyromancer Warlock Leggings
item.ebwizardry\:warlock_boots_fire.name=Pyromancer Warlock Boots
item.ebwizardry\:warlock_hood_ice.name=Ice Warlock Hood
item.ebwizardry\:warlock_robe_ice.name=Ice Warlock Robes
item.ebwizardry\:warlock_leggings_ice.name=Ice Warlock Leggings
item.ebwizardry\:warlock_boots_ice.name=Ice Warlock Boots
item.ebwizardry\:warlock_hood_lightning.name=Storm Warlock Hood
item.ebwizardry\:warlock_robe_lightning.name=Storm Warlock Robes
item.ebwizardry\:warlock_leggings_lightning.name=Storm Warlock Leggings
item.ebwizardry\:warlock_boots_lightning.name=Storm Warlock Boots
item.ebwizardry\:warlock_hood_necromancy.name=Necromancer Warlock Hood
item.ebwizardry\:warlock_robe_necromancy.name=Necromancer Warlock Robes
item.ebwizardry\:warlock_leggings_necromancy.name=Necromancer Warlock Leggings
item.ebwizardry\:warlock_boots_necromancy.name=Necromancer Warlock Boots
item.ebwizardry\:warlock_hood_earth.name=Earth Warlock Hood
item.ebwizardry\:warlock_robe_earth.name=Earth Warlock Robes
item.ebwizardry\:warlock_leggings_earth.name=Earth Warlock Leggings
item.ebwizardry\:warlock_boots_earth.name=Earth Warlock Boots
item.ebwizardry\:warlock_hood_sorcery.name=Sorcerer Warlock Hood
item.ebwizardry\:warlock_robe_sorcery.name=Sorcerer Warlock Robes
item.ebwizardry\:warlock_leggings_sorcery.name=Sorcerer Warlock Leggings
item.ebwizardry\:warlock_boots_sorcery.name=Sorcerer Warlock Boots
item.ebwizardry\:warlock_hood_healing.name=Healer Warlock Hood
item.ebwizardry\:warlock_robe_healing.name=Healer Warlock Robes
item.ebwizardry\:warlock_leggings_healing.name=Healer Warlock Leggings
item.ebwizardry\:warlock_boots_healing.name=Healer Warlock Boots
item.ebwizardry\:spawn_wizard.name=Spawn Wizard
item.ebwizardry\:spawn_evil_wizard.name=Spawn Evil Wizard
@@ -711,8 +845,12 @@ advancement.ebwizardry\:craft_lectern.desc=Craft a lectern to keep track of your
advancement.ebwizardry\:armour_set=Now You're A Proper Wizard
advancement.ebwizardry\:armour_set.desc=Craft and equip a full set of wizard armor
advancement.ebwizardry\:legendary=Legendary
advancement.ebwizardry\:legendary.desc=Obtain a piece of legendary wizard armor
advancement.ebwizardry\:sage=The Path Of The Sage
advancement.ebwizardry\:sage.desc=Obtain a piece of sage armour
advancement.ebwizardry\:battlemage=The Pledge Of The Battlemage
advancement.ebwizardry\:battlemage.desc=Obtain a piece of battlemage armour
advancement.ebwizardry\:warlock=The Way Of The Warlock
advancement.ebwizardry\:warlock.desc=Obtain a piece of warlock armour
advancement.ebwizardry\:enchant_scroll=Scroll Up!
advancement.ebwizardry\:enchant_scroll.desc=Craft a blank scroll and enchant it with a spell at an arcane workbench
@@ -1336,6 +1474,8 @@ commands.ebwizardry\:discoverspell.removespell=Removed %1$s from %2$s's spell di
config.ebwizardry.title.general=Mod Options
config.ebwizardry.redundant_keys=Your config file contains redundant options, these will not do anything! [See log for details]
config.ebwizardry.generic.true=Enabled
config.ebwizardry.generic.false=Disabled
@@ -1440,6 +1580,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=치유사
File diff suppressed because it is too large Load Diff
@@ -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=关闭
@@ -95,11 +95,6 @@
"name": "ebwizardry:spark_bomb",
"weight": 8
},
{
"type": "item",
"name": "ebwizardry:armour_upgrade",
"weight": 1
},
{
"type": "item",
"name": "ebwizardry:astral_diamond",
@@ -17,6 +17,11 @@
"name": "ebwizardry:subsets/wand_upgrades",
"weight": 2
},
{
"type": "loot_table",
"name": "ebwizardry:subsets/armour_upgrades",
"weight": 1
},
{
"type": "item",
"name": "ebwizardry:spell_book",
@@ -38,6 +38,11 @@
"name": "ebwizardry:subsets/wand_upgrades",
"weight": 4
},
{
"type": "loot_table",
"name": "ebwizardry:subsets/armour_upgrades",
"weight": 2
},
{
"type": "item",
"name": "ebwizardry:spell_book",
@@ -100,11 +105,6 @@
}
]
},
{
"type": "item",
"name": "ebwizardry:armour_upgrade",
"weight": 1
},
{
"type": "item",
"name": "ebwizardry:astral_diamond",
@@ -27,6 +27,11 @@
"name": "ebwizardry:subsets/wand_upgrades",
"weight": 2
},
{
"type": "loot_table",
"name": "ebwizardry:subsets/armour_upgrades",
"weight": 2
},
{
"type": "item",
"name": "ebwizardry:magic_crystal",
@@ -70,11 +75,6 @@
}
]
},
{
"type": "item",
"name": "ebwizardry:armour_upgrade",
"weight": 1
},
{
"type": "item",
"name": "ebwizardry:identification_scroll",
@@ -0,0 +1,25 @@
{
"pools": [
{
"name": "upgrades",
"rolls": 1,
"entries": [
{
"type": "item",
"name": "ebwizardry:resplendent_thread",
"weight": 1
},
{
"type": "item",
"name": "ebwizardry:crystal_silver_plating",
"weight": 1
},
{
"type": "item",
"name": "ebwizardry:ethereal_crystalweave",
"weight": 1
}
]
}
]
}
@@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "ebwizardry:items/battlemage_boots"
}
}
@@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "ebwizardry:items/battlemage_boots_earth"
}
}
@@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "ebwizardry:items/battlemage_boots_fire"
}
}
@@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "ebwizardry:items/battlemage_boots_healing"
}
}
@@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "ebwizardry:items/battlemage_boots_ice"
}
}
@@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "ebwizardry:items/battlemage_boots_lightning"
}
}
@@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "ebwizardry:items/battlemage_boots_necromancy"
}
}
@@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "ebwizardry:items/battlemage_boots_sorcery"
}
}
@@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "ebwizardry:items/battlemage_chestplate"
}
}
@@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "ebwizardry:items/battlemage_chestplate_earth"
}
}
@@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "ebwizardry:items/battlemage_chestplate_fire"
}
}
@@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "ebwizardry:items/battlemage_chestplate_healing"
}
}
@@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "ebwizardry:items/battlemage_chestplate_ice"
}
}
@@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "ebwizardry:items/battlemage_chestplate_lightning"
}
}
@@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "ebwizardry:items/battlemage_chestplate_necromancy"
}
}

Some files were not shown because too many files have changed in this diff Show More