Compare commits
207 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 85ca4fd100 | |||
| 136b1cc924 | |||
| e4b7d528f5 | |||
| 2903ebfbac | |||
| 931ca1b2c0 | |||
| 85e724d88a | |||
| e41f83a2dd | |||
| 69b52cfe88 | |||
| 7591821e57 | |||
| 0ce0dcf2e9 | |||
| 73811c3a6b | |||
| 2a887b7794 | |||
| ad9f482e76 | |||
| 6eaef94459 | |||
| 4f5c616240 | |||
| f5947dded9 | |||
| 77e0acc16b | |||
| e48646c5ff | |||
| 5e48fe51ea | |||
| 6b30dbef65 | |||
| d6508a2be4 | |||
| dfcadfb3bd | |||
| 7888b92129 | |||
| 5b48dffa77 | |||
| 5bf4650da1 | |||
| 8e9c270b77 | |||
| 00080331df | |||
| 27e40e2069 | |||
| 3a93877de3 | |||
| 7f70784cd3 | |||
| ed6e3df66e | |||
| eb5becbbd4 | |||
| 9599316fbc | |||
| cc1c951ef8 | |||
| d23c4cba18 | |||
| 3d30b0b96f | |||
| ad1e5d555a | |||
| 14ea5f1c72 | |||
| 709d44e4d9 | |||
| 8df00e9c41 | |||
| 8dbb0ec058 | |||
| b8310eedae | |||
| c04754afe1 | |||
| 3155aa6815 | |||
| ea27b1a081 | |||
| 4d078f9597 | |||
| 67459cbbbd | |||
| 932de4e969 | |||
| 41e28291ad | |||
| 6ae6324368 | |||
| 4858716f05 | |||
| 24fb4cfe4a | |||
| 186138d0c0 | |||
| 6690564017 | |||
| 89a0a900cc | |||
| 391a24db3f | |||
| 4b546af642 | |||
| ee8aabbf97 | |||
| 45994e2b94 | |||
| 13bdc69da8 | |||
| c0184fde8e | |||
| cbd297e59d | |||
| c6cf7c950e | |||
| fe5d80e017 | |||
| e985a8f15b | |||
| 615767f758 | |||
| 65a24b2295 | |||
| 94c2afe67a | |||
| 9bbca37ecd | |||
| 58241a0f5c | |||
| a960a01ca1 | |||
| 67d8ee773c | |||
| c6f2675278 | |||
| 2380be230e | |||
| 833276b7b3 | |||
| 9b32835720 | |||
| 61634a9cc3 | |||
| 408a35db8d | |||
| 9695a85131 | |||
| d027cf4f2a | |||
| c2f8bfc5b4 | |||
| 486425a62c | |||
| f9681d4c66 | |||
| cd0671dc59 | |||
| 7ebca16948 | |||
| e8cbdde518 | |||
| 7ca6f05151 | |||
| f4f17e90e5 | |||
| 3ea48efb1d | |||
| ffc3533688 | |||
| bd309855a2 | |||
| 1473c7e9b7 | |||
| 15cc7b6d18 | |||
| 1c89c5f779 | |||
| ca7f1cc8ca | |||
| 8fd1de84e4 | |||
| 95d9168b6b | |||
| c1db827132 | |||
| d10b78ab46 | |||
| 2d70523f43 | |||
| 42fb7ad3df | |||
| e90d0950d4 | |||
| 888d4190d1 | |||
| 57696b2538 | |||
| 1440537f6b | |||
| a16ff88c8d | |||
| 041de12ea7 | |||
| 5e36f66c4e | |||
| a6a5a6104d | |||
| 6f7b225ce8 | |||
| 81a85883d2 | |||
| 3f06d2fea4 | |||
| 26b390268a | |||
| 486d55f349 | |||
| 5948090d63 | |||
| 32340191de | |||
| 0b09875bb3 | |||
| 078a36d304 | |||
| 3ef4ec522b | |||
| cd6fa03990 | |||
| bba9fb68e6 | |||
| dcb7038833 | |||
| f8a058259d | |||
| 1696d5daeb | |||
| ac69af012a | |||
| 692546a232 | |||
| b0478b627f | |||
| 2cdca4b990 | |||
| 4c0b2adef4 | |||
| 191dd078b8 | |||
| 2de7807bec | |||
| 9d4f1dd370 | |||
| 6f769150b1 | |||
| 155dc0b621 | |||
| 07acea53e3 | |||
| 1fcb3a2b1b | |||
| 16eabc8deb | |||
| e0efd8d407 | |||
| 969f0b96fd | |||
| 8a9d88c9ac | |||
| 3b55728c75 | |||
| 240bffa7ed | |||
| c313236eec | |||
| 21f7928b9c | |||
| 1304c11381 | |||
| 79932e15ab | |||
| 25ee166e41 | |||
| 299510e663 | |||
| d3d76cae16 | |||
| 0e815c676d | |||
| f81ad670ed | |||
| 5b3aebaba1 | |||
| 3ef1afce2f | |||
| a3c15d673b | |||
| d8f1c5f77c | |||
| 1ddcdafe50 | |||
| 3c35eaaf54 | |||
| 094ce5a427 | |||
| e19d324dca | |||
| 58f6d55b0d | |||
| 32e92b4b04 | |||
| 24a06e0bac | |||
| ae9da5b7c1 | |||
| 2e39a8bfc1 | |||
| e3130ca936 | |||
| 378e19a614 | |||
| e2fd978d8b | |||
| 8f8ce7a453 | |||
| ddfffd3d31 | |||
| d23c15476a | |||
| 55bb40a684 | |||
| c056c490da | |||
| c483591ea8 | |||
| 4c3dfb3bc9 | |||
| 0010fafc13 | |||
| f4cf98089c | |||
| 8e3a33b084 | |||
| b1478de6fe | |||
| 1d247e2d56 | |||
| e8292f1e96 | |||
| bc0b712e2b | |||
| 47135f00d7 | |||
| c615ad365c | |||
| 39c3989796 | |||
| e808ab2b1f | |||
| a25f942722 | |||
| 14e481a71d | |||
| ac226f1444 | |||
| 741d918d9b | |||
| f504505bf5 | |||
| fb010d3726 | |||
| c64731e7a9 | |||
| d3837a6185 | |||
| 80cf77ecc6 | |||
| 3d3806c20b | |||
| d952e9b255 | |||
| 33c8f08adf | |||
| 315f2e4b02 | |||
| d3df59df73 | |||
| cfd3e796e1 | |||
| d97e843f7b | |||
| 15a153fe11 | |||
| d00b7279ee | |||
| 0142cc05bc | |||
| 23621b8045 | |||
| 7f2978bc7a | |||
| 312364ba77 |
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"homepage": "https://www.curseforge.com/minecraft/mc-mods/electroblobs-wizardry",
|
||||
"promos": {
|
||||
"1.12.2-latest": "4.3.11",
|
||||
"1.12.2-recommended": "4.3.11"
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Report a crash or something that isn't working as it should
|
||||
title: "[Give a brief, relevant title here]"
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/CONTRIBUTING.md) before posting.
|
||||
|
||||
Minecraft version: 1.12.2 [change as necessary]
|
||||
Wizardry version: 4.3 [change as necessary]
|
||||
Environment: Singleplayer/LAN game/Server [delete as necessary]
|
||||
|
||||
Issue details: [describe what you were doing when the issue occurred, what went wrong, what you expected to happen, etc.]
|
||||
|
||||
Other mods involved: [only list mods that are relevant to the problem]
|
||||
|
||||
Link to crash report (if applicable): [give a link to the crash report on gist, pastebin, etc.]
|
||||
@@ -0,0 +1,85 @@
|
||||
name: 🐛 Bug Report
|
||||
description: Something is not working as expected
|
||||
title: "[Bug] <write the title here>"
|
||||
labels: [ "bug", "Needs Triage" ]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/CONTRIBUTING.md) before posting. You may also find the [troubleshooting page](https://github.com/Electroblob77/Wizardry/wiki/Troubleshooting) helpful.
|
||||
Please try the latest version of the mod and check if the issue persist before submitting a report.
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Is there an existing issue for this?
|
||||
description: Please search to see if an issue already exists for the bug you encountered.
|
||||
options:
|
||||
- label: I have searched the existing issues
|
||||
required: true
|
||||
- type: textarea
|
||||
id: observed
|
||||
attributes:
|
||||
label: Observed behaviour
|
||||
description: Describe what happened and when this happened
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: expected
|
||||
attributes:
|
||||
label: Expected behaviour
|
||||
description: Describe what you expected to happen
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduction
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Step by step instructions on how to reproduce the observed behaviour
|
||||
placeholder: |
|
||||
1. Join a server
|
||||
2. Cast the [spell]
|
||||
3. ...
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: crashlog
|
||||
attributes:
|
||||
label: Crashlog
|
||||
description: If this was a crash, grab [minecraft instance]/logs/debug.log, upload it as a [gist](https://gist.github.com/) and paste the link here. Alternatively, give a link to the crash report on gist, pastebin if you already have one there.
|
||||
placeholder: https://gist.github.com/<your-user>/abcdef124
|
||||
- type: dropdown
|
||||
id: environment
|
||||
attributes:
|
||||
label: Environment (Singleplayer/Server, etc.)
|
||||
options:
|
||||
- Singleplayer
|
||||
- LAN game/Server
|
||||
- Issue present on both sides
|
||||
- Not sure
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: mod-version
|
||||
attributes:
|
||||
label: Mod version
|
||||
placeholder: 1.0.0
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: minecraft-version
|
||||
attributes:
|
||||
label: Minecraft version
|
||||
placeholder: 12.2.2
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: forge-version
|
||||
attributes:
|
||||
label: Forge version
|
||||
placeholder: 1.12.2 - 14.23.5.2860
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: other-mods
|
||||
attributes:
|
||||
label: Other mods
|
||||
description: List any other mods present when the bug was encountered, include the mod versions. You only have to fill this if no crash log was attached
|
||||
@@ -0,0 +1,14 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: 📖 Mod Wiki Page
|
||||
url: https://github.com/Electroblob77/Wizardry/wiki
|
||||
about: Most features are documented in the mod's wiki page --- Link --->
|
||||
- name: 💬 Electroblob's Wizardry discord
|
||||
url: https://discord.gg/hs8yJP2
|
||||
about: Ask for help or get more info on Discord. --- Discord Server link --->
|
||||
- name: 💡 Feature requests / suggestions
|
||||
url: https://discord.gg/hs8yJP2
|
||||
about: Please use the discord server to suggest stuff. --- Discord Server link --->
|
||||
- name: ❓ Question
|
||||
url: https://discord.gg/hs8yJP2
|
||||
about: Ask a question about the mod or the code. --- Discord Server link --->
|
||||
@@ -1,16 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Make a suggestion for improving the mod
|
||||
title: "[Give a brief, relevant title here]"
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/CONTRIBUTING.md) before posting.
|
||||
|
||||
Minecraft versions: [if this suggestion only applies to some versions, list them here]
|
||||
|
||||
Suggestion details: [describe what you would like to see added to the mod and why]
|
||||
|
||||
Other mods involved: [if this suggestion involves integration with other mods, list them here]
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
name: Question
|
||||
about: Ask a question about the mod or the code
|
||||
title: "[Give a brief, relevant title here]"
|
||||
labels: question
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/CONTRIBUTING.md) before posting.
|
||||
|
||||
Minecraft version: 1.12.2 [change as necessary]
|
||||
Wizardry version: 4.3 [change as necessary]
|
||||
|
||||
Question details: [explain your question here]
|
||||
|
||||
Other mods involved: [if this question involves other mods, list them here]
|
||||
@@ -0,0 +1,38 @@
|
||||
name: Potential Duplicates
|
||||
on:
|
||||
issues:
|
||||
types: [opened, edited]
|
||||
|
||||
jobs:
|
||||
run:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: bubkoo/potential-duplicates@v1
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
label: potential duplicate
|
||||
exclude: |
|
||||
adding
|
||||
add
|
||||
creating
|
||||
create
|
||||
icons
|
||||
icon
|
||||
logos
|
||||
logo
|
||||
missing
|
||||
miss
|
||||
needing
|
||||
need
|
||||
please
|
||||
requesting
|
||||
request
|
||||
1.12.2
|
||||
wizardry
|
||||
state: all
|
||||
threshold: 0.7
|
||||
comment: |
|
||||
This issue is potentially a duplicate of one of the following issues:
|
||||
{{#issues}}
|
||||
- [#{{ number }}] {{ title }} ({{ accuracy }}% match)
|
||||
{{/issues}}
|
||||
+3
-1
@@ -49,8 +49,10 @@ Pull requests aren't just for code - if you would like to help translate Wizardr
|
||||
|
||||
- `#image tag` adds an image to the text with the given tag. Image tags are defined in the `"images": {...}` block at the start of the file. Each named entry in this block defines a single image with that name as its tag. Each entry is a JSON object containing a file location and optional caption/dimensions.
|
||||
- `#recipe tag` adds a crafting recipe to the text with the given tag. Similar to image tags, recipe tags are defined in the `"recipes": {...}` block at the start of the file. Each named entry in this block defines a recipe with that name as its tag. Each entry contains a list of one or more locations or recipes to display (if more than one is specified, the display will cycle through the different recipes).
|
||||
- Anything else with a `#` directly before it (with no space) will be treated as a format argument if possible. This means everything between the `#` and the next space will be replaced with something else at runtime, similar to the `%X$s` bits in a normal .lang file. The current available format arguments can be found [here](https://github.com/Electroblob77/Wizardry/blob/1.12.2/src/main/java/electroblob/wizardry/client/gui/handbook/GuiWizardHandbook.java#L177-L203).
|
||||
- Anything else with a `#` directly before it (with no space) will be treated as a format argument if possible. This means the text after the `#` will be replaced with something else at runtime, similar to the `%X$s` bits in a normal .lang file, if it matches one of the available format arguments. The current format arguments can be found [here](https://github.com/Electroblob77/Wizardry/blob/1.12.2/src/main/java/electroblob/wizardry/client/gui/handbook/GuiWizardHandbook.java#L177-L203).
|
||||
- `@section@` adds a hyperlink to the given section, which will display as the name of that section. `@section alt text@` is the same, except alt text is displayed instead of the section name (alt text may contain spaces). It is also possible to hyperlink to a webpage, simply replace the section name with the url (e.g. `@https://example.com/@` or `@https://example.com/ alt text@`).
|
||||
|
||||
> Translators for Chinese, Japanese, Korean and similar East Asian languages: Due to how Minecraft's word wrapping works, for best results you should _remove spaces before and after hyperlinks and formatting tags_, excluding images and recipes. However, do not remove the space between a hyperlink's destination and its alt text or the link will break!
|
||||
|
||||
If all of that confused you, the simple rule is: _Don't translate anything directly after an `@` symbol, directly after a `#`, or the first word after `#image` or `#recipe`_. However, you should translate the `"caption"` entries in the `images` block.
|
||||
|
||||
|
||||
+14
-6
@@ -1,7 +1,7 @@
|
||||
# Credits
|
||||
|
||||
Electroblob's Wizardry
|
||||
Version 4.3
|
||||
Version 4.3.7
|
||||
For Minecraft 1.12.2
|
||||
|
||||
Designed, coded and textured by Electroblob
|
||||
@@ -12,6 +12,11 @@ Thanks also to the Minecraft modding community, which always has an answer to my
|
||||
|
||||
In addition, I'd like to thank the following individuals for their contributions to the mod:
|
||||
|
||||
#### Discord Moderators (and all-round awesome people)
|
||||
|
||||
- FavouriteDragon
|
||||
- WinDanesz
|
||||
|
||||
#### Code
|
||||
|
||||
- Corail31
|
||||
@@ -25,18 +30,21 @@ In addition, I'd like to thank the following individuals for their contributions
|
||||
- Azim-Palmer
|
||||
- raoulvdberge
|
||||
- rafasoares
|
||||
- xinyuan-liu
|
||||
- SettingDust
|
||||
- Aralu115
|
||||
|
||||
#### Translations
|
||||
|
||||
- Spanish: MadWrist, Alsentar
|
||||
- Mexican Spanish: MadWrist
|
||||
- Russian: VilagVil, kellixon, bigenergy, MugGod2
|
||||
- French: Hahdrim
|
||||
- Russian: VilagVil, kellixon, bigenergy, MugGod2, DrHesperus
|
||||
- French: Hahdrim, Crowller
|
||||
- Brazilian Portuguese: lorrampi
|
||||
- Chinese (Simplified): ZHENGLOC, dragon-evol, Hokorizero, TUsama, Determancer
|
||||
- Korean: shejery, rewi_wire
|
||||
- Polish: Trozuu
|
||||
- German: BirdyDragon
|
||||
- Korean: shejery, rewi_wire, 방통, red1854th
|
||||
- Polish: Trozuu, Olej
|
||||
- German: BirdyDragon, Lemopav
|
||||
- Chinese (Traditional): chesterccj305
|
||||
- Hungarian: Bombadil
|
||||
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/guide_for_contributing.md) before posting.
|
||||
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/guide_for_contributing.md) before posting. You may also find the [troubleshooting page](https://github.com/Electroblob77/Wizardry/wiki/Troubleshooting) helpful.
|
||||
|
||||
Minecraft version: 1.12.2 [change as necessary]
|
||||
Wizardry version: 4.3 [change as necessary]
|
||||
Wizardry version: [change as necessary]
|
||||
Environment: Singleplayer/LAN game/Server [delete as necessary]
|
||||
|
||||
Issue details: [describe what you were doing when the issue occurred, what went wrong, what you expected to happen, etc.]
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ apply plugin: 'net.minecraftforge.gradle.forge'
|
||||
//Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
|
||||
|
||||
|
||||
version = "4.3" // There, it matches semver, happy now?
|
||||
version = "4.3.11"
|
||||
group= "electroblob.wizardry"// http://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||
archivesBaseName = "ElectroblobsWizardry"
|
||||
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+1
-2
@@ -1,6 +1,5 @@
|
||||
#Mon Sep 14 12:28:28 PDT 2015
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/usr/bin/env sh
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
@@ -6,47 +6,6 @@
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
||||
if $cygwin ; then
|
||||
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
fi
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
@@ -61,9 +20,49 @@ while [ -h "$PRG" ] ; do
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >&-
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >&-
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
@@ -79,18 +78,18 @@ if [ -n "$JAVA_HOME" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
locations of your Java installation."
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
locations of your Java installation."
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
@@ -114,6 +113,7 @@ fi
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
@@ -154,11 +154,19 @@ if $cygwin ; then
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
||||
Vendored
+6
-12
@@ -8,14 +8,14 @@
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
@@ -27,7 +27,7 @@ echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo locations of your Java installation.
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
@@ -41,15 +41,14 @@ echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo locations of your Java installation.
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
@@ -60,11 +59,6 @@ set _SKIP=2
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -154,6 +156,12 @@ public final class Settings {
|
||||
public Pair<ResourceLocation, Short>[] treeBlocks = parseItemMetaStrings(DEFAULT_TREE_BLOCKS);
|
||||
/** <b>[Server-only]</b> The chance for wizard towers to generate with an evil wizard and chest inside. */
|
||||
public double evilWizardChance = 0.2;
|
||||
public double cooldownReductionPerLevel = 0.15;
|
||||
public double potencyIncreasePerTier = 0.15;
|
||||
public double durationIncreasePerLevel = 0.25;
|
||||
public double rangeIncreasePerLevel = 0.25;
|
||||
public double blastIncreasePerLevel = 0.25;
|
||||
public double frostSlownessIncreasePerLevel = 0.5;
|
||||
/** <b>[Server-only]</b> List of dimension ids in which to generate crystal ore. */
|
||||
public int[] oreDimensions = {0};
|
||||
/** <b>[Server-only]</b> List of dimension ids in which to generate crystal flowers. */
|
||||
@@ -190,12 +198,23 @@ public final class Settings {
|
||||
public boolean playerBlockDamage = true;
|
||||
/** <b>[Server-only]</b> Whether spells cast by dispensers can destroy blocks in the world. */
|
||||
public boolean dispenserBlockDamage = true;
|
||||
/** <b>[Server-only]</b> Whether damage should be registered with the old system (wizardry_magic/indirect_wizardry_magic) prefixed damage with the elements like
|
||||
* necromancy_indirect_wizardry_magic, necromancy_wizardry_magic*/
|
||||
public boolean damageTypePerElement = false;
|
||||
/** <b>[Server-only]</b> Whether spell books are consumed when they are bound to a wand.*/
|
||||
public boolean singleUseSpellBooks = false;
|
||||
/** <b>[Server-only]</b> Whether to prevent binding the same spell to a wand multiple times*/
|
||||
public boolean preventBindingSameSpellTwiceToWands = false;
|
||||
/** <b>[Server-only]</b> Whether to revert to the old wand upgrade system, which only requires tomes of arcana. */
|
||||
public boolean legacyWandLevelling = false;
|
||||
/** <b>[Server-only]</b> Whether to tweak the blindness effect to reduce follow distance when used on non-players. */
|
||||
public boolean blindnessTweak = true;
|
||||
/** <b>[Server-only]</b> Whether using bonemeal on grass blocks has a chance to grow crystal flowers. */
|
||||
public boolean bonemealGrowsCrystalFlowers = true;
|
||||
/** <b>[Server-only]</b> Whether wands only decrement their cooldowns if a player holds them. */
|
||||
public boolean wandsMustBeHeldToDecrementCooldown = false;
|
||||
/** <b>[Server-only]</b> Whether to enable Wizardry mob loot injection. Allows an easier switch instead of blacklisting all entities. */
|
||||
public boolean injectMobDrops = true;
|
||||
/**
|
||||
* <b>[Server-only]</b> List of registry names of entities which summoned creatures are allowed to attack, in addition
|
||||
* to the defaults.
|
||||
@@ -375,6 +394,9 @@ public final class Settings {
|
||||
public boolean showSpellHUD = true;
|
||||
/** <b>[Client-only]</b> Whether to show the charge meter when charging up a spell. */
|
||||
public boolean showChargeMeter = true;
|
||||
/** <b>[Client-only]</b> Whether to initialise the handbook's data. Setting this to false will break the in-game handbook, but might help with some
|
||||
* startup crashes */
|
||||
public boolean loadHandbook = true;
|
||||
/** <b>[Client-only]</b> The position of the spell HUD. */
|
||||
public GuiPosition spellHUDPosition = GuiPosition.BOTTOM_LEFT;
|
||||
|
||||
@@ -446,6 +468,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 +508,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 +526,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 +570,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 +582,7 @@ public final class Settings {
|
||||
spell.setEnabled(property.getBoolean(true));
|
||||
}
|
||||
|
||||
checkForRedundantOptions(SPELLS_CATEGORY, keys);
|
||||
}
|
||||
|
||||
private void setupArtefactsConfig(){
|
||||
@@ -536,8 +592,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 +606,7 @@ public final class Settings {
|
||||
}
|
||||
}
|
||||
|
||||
checkForRedundantOptions(ARTEFACTS_CATEGORY, keys);
|
||||
}
|
||||
|
||||
private void setupGameplayConfig(){
|
||||
@@ -572,6 +632,29 @@ public final class Settings {
|
||||
dispenserBlockDamage = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(GAMEPLAY_CATEGORY, "damageTypePerElement", false,
|
||||
"Whether damage should be registered with the old system (wizardry_magic/indirect_wizardry_magic) prefixed damage with the elements like "
|
||||
+ "necromancy_indirect_wizardry_magic, necromancy_wizardry_magic. This is disabled by default to not break existing modpacks."
|
||||
+ "The intention of this setting is to allow differentiating various damage types for e.g. the Distinct Damage Descriptions mod");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".damage_type_per_element");
|
||||
Wizardry.proxy.setToNamedBooleanEntry(property);
|
||||
damageTypePerElement = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(GAMEPLAY_CATEGORY, "singleUseSpellBooks", false,
|
||||
"Whether spell books are consumed when they are bound to a wand.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".single_use_spell_books");
|
||||
Wizardry.proxy.setToNamedBooleanEntry(property);
|
||||
singleUseSpellBooks = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(GAMEPLAY_CATEGORY, "preventBindingSameSpellTwiceToWands", false,
|
||||
"Whether to prevent binding the same spell to a wand multiple times");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".prevent_binding_same_spell_twice_to_wands");
|
||||
Wizardry.proxy.setToNamedBooleanEntry(property);
|
||||
preventBindingSameSpellTwiceToWands = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(GAMEPLAY_CATEGORY, "playersMoveEachOther", true,
|
||||
"Whether to allow players to move other players around using magic.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".players_move_each_other");
|
||||
@@ -623,6 +706,14 @@ public final class Settings {
|
||||
bonemealGrowsCrystalFlowers = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(GAMEPLAY_CATEGORY, "wandsMustBeHeldToDecrementCooldown", false,
|
||||
"Whether wands only decrement their cooldowns if a player holds them.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".wands_must_be_held_to_decrement_cooldown");
|
||||
Wizardry.proxy.setToNamedBooleanEntry(property);
|
||||
wandsMustBeHeldToDecrementCooldown = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
checkForRedundantOptions(GAMEPLAY_CATEGORY, propOrder); // Must be before the order is set!
|
||||
config.setCategoryPropertyOrder(GAMEPLAY_CATEGORY, propOrder);
|
||||
|
||||
}
|
||||
@@ -730,6 +821,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 +857,13 @@ public final class Settings {
|
||||
blindnessTweak = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(TWEAKS_CATEGORY, "injectMobDrops", true,
|
||||
"Whether to inject Wizardry loot to mobs, based on the loot table 'Mob Loot Table Whitelist' / 'Mob Loot Table Blacklist' settings. If disabled, the lists won't have any effect!");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".inject_mob_drops");
|
||||
Wizardry.proxy.setToNamedBooleanEntry(property);
|
||||
injectMobDrops = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(TWEAKS_CATEGORY, "mobLootTableWhitelist", new String[0], "Whitelist for loot tables to inject additional mob drops (as specified in loot_tables/entities/mob_additions.json) into. Wizardry makes a best guess as to which loot tables belong to hostile mobs, but this may not always be correct or appropriate; add loot table locations (not entity IDs) to this list to manually include them.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".mob_loot_table_whitelist");
|
||||
property.setRequiresMcRestart(true);
|
||||
@@ -872,6 +971,51 @@ public final class Settings {
|
||||
}
|
||||
}
|
||||
|
||||
property = config.get(TWEAKS_CATEGORY, "cooldown_reduction_per_level", 0.15,
|
||||
"The fraction by which cooldowns are reduced for each level of cooldown upgrade.",
|
||||
0.05, Integer.MAX_VALUE); // Sure, I mean you COULD set it to 2^31-1... what could possibly go wrong?
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".cast_command_multiplier_limit");
|
||||
cooldownReductionPerLevel = property.getDouble();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(TWEAKS_CATEGORY, "potency_increase_per_tier", 0.15,
|
||||
"The fraction by which potency is increased for each tier of matching wand. May cause extreme lag with high values!",
|
||||
0.05, Integer.MAX_VALUE);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".potency_increase_per_tier");
|
||||
potencyIncreasePerTier = property.getDouble();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(TWEAKS_CATEGORY, "duration_increase_per_level", 0.25,
|
||||
"The fraction by which spell duration is increased for each level of duration upgrade.",
|
||||
0.05, Integer.MAX_VALUE);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".duration_increase_per_level");
|
||||
durationIncreasePerLevel = property.getDouble();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(TWEAKS_CATEGORY, "range_increase_per_level", 0.25,
|
||||
"The fraction by which spell range is increased for each level of range upgrade. May cause extreme lag with high values!",
|
||||
0.05, Integer.MAX_VALUE);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".range_increase_per_level");
|
||||
rangeIncreasePerLevel = property.getDouble();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(TWEAKS_CATEGORY, "blast_increase_per_level", 0.25,
|
||||
"The fraction by which spell blast is increased for each level of blast upgrade. May cause extreme lag with high values!",
|
||||
0.05, Integer.MAX_VALUE);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".blast_increase_per_level");
|
||||
blastIncreasePerLevel = property.getDouble();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
|
||||
property = config.get(TWEAKS_CATEGORY, "frost_slowness_increase_per_level", 0.5,
|
||||
"The fraction by which movement speed is reduced per level of frost effect.",
|
||||
0.05, Integer.MAX_VALUE);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".frost_slowness_increase_per_level");
|
||||
frostSlownessIncreasePerLevel = property.getDouble();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
|
||||
checkForRedundantOptions(TWEAKS_CATEGORY, propOrder); // Must be before the order is set!
|
||||
config.setCategoryPropertyOrder(TWEAKS_CATEGORY, propOrder);
|
||||
|
||||
}
|
||||
@@ -1019,6 +1163,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);
|
||||
}
|
||||
|
||||
@@ -1059,6 +1204,13 @@ public final class Settings {
|
||||
showChargeMeter = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(CLIENT_CATEGORY, "loadHandbook", true, "Whether to initialise the in-game handbook. Setting this to false will brick the in-game handbook, but it might help if you have startup crashes.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".load_handbook");
|
||||
property.setRequiresWorldRestart(false);
|
||||
Wizardry.proxy.setToNamedBooleanEntry(property);
|
||||
loadHandbook = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(CLIENT_CATEGORY, "spellHUDPosition", GuiPosition.BOTTOM_LEFT.name, "The position of the spell HUD.", GuiPosition.names);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".spell_hud_position");
|
||||
spellHUDPosition = GuiPosition.fromName(property.getString());
|
||||
@@ -1120,6 +1272,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 +1319,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 +1397,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 +1487,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,23 @@ import electroblob.wizardry.inventory.ContainerBookshelf;
|
||||
import electroblob.wizardry.misc.DonationPerksHandler;
|
||||
import electroblob.wizardry.misc.Forfeit;
|
||||
import electroblob.wizardry.packet.WizardryPacketHandler;
|
||||
import electroblob.wizardry.registry.*;
|
||||
import electroblob.wizardry.registry.Spells;
|
||||
import electroblob.wizardry.registry.WizardryAdvancementTriggers;
|
||||
import electroblob.wizardry.registry.WizardryBlocks;
|
||||
import electroblob.wizardry.registry.WizardryItems;
|
||||
import electroblob.wizardry.registry.WizardryLoot;
|
||||
import electroblob.wizardry.registry.WizardrySounds;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
import electroblob.wizardry.util.SpellNetworkIDSorter;
|
||||
import electroblob.wizardry.util.SpellProperties;
|
||||
import electroblob.wizardry.util.WandHelper;
|
||||
import electroblob.wizardry.worldgen.*;
|
||||
import electroblob.wizardry.worldgen.WorldGenCrystalFlower;
|
||||
import electroblob.wizardry.worldgen.WorldGenCrystalOre;
|
||||
import electroblob.wizardry.worldgen.WorldGenLibraryRuins;
|
||||
import electroblob.wizardry.worldgen.WorldGenObelisk;
|
||||
import electroblob.wizardry.worldgen.WorldGenShrine;
|
||||
import electroblob.wizardry.worldgen.WorldGenUndergroundLibraryRuins;
|
||||
import electroblob.wizardry.worldgen.WorldGenWizardTower;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
@@ -51,6 +63,7 @@ import java.util.Calendar;
|
||||
|
||||
@Mod(modid = Wizardry.MODID, name = Wizardry.NAME, version = Wizardry.VERSION, acceptedMinecraftVersions = "[1.12.2]",
|
||||
guiFactory = "electroblob.wizardry.WizardryGuiFactory",
|
||||
updateJSON = Wizardry.updateJSON,
|
||||
dependencies = "required-after:forge@[14.23.5.2847,);after:jei@[4.15.0,);after:baubles@[1.5.2,);after:antiqueatlas@[4.6,)")
|
||||
|
||||
public class Wizardry {
|
||||
@@ -69,7 +82,13 @@ public class Wizardry {
|
||||
* 1.x.x represents Minecraft 1.7.x versions, 2.x.x represents Minecraft 1.10.x versions, 3.x.x represents Minecraft
|
||||
* 1.11.x versions, and so on.
|
||||
*/
|
||||
public static final String VERSION = "4.3";
|
||||
public static final String VERSION = "4.3.11";
|
||||
|
||||
/**
|
||||
* Json file used by Forge's built-in <a href="https://mcforge.readthedocs.io/en/1.12.x/gettingstarted/autoupdate/">update checker</a>.
|
||||
* Used by the in-game mod menu to show that green icon whenever a newer version is available of the mod.
|
||||
*/
|
||||
public static final String updateJSON = "https://github.com/Electroblob77/Wizardry/blob/1.12.2/.forge/update.json";
|
||||
|
||||
// IDEA: Triggering of inbuilt Forge events in relevant places?
|
||||
// IDEA: Abstract the vanilla particles behind the particle builder
|
||||
@@ -108,11 +127,10 @@ public class Wizardry {
|
||||
public void preInit(FMLPreInitializationEvent event){
|
||||
|
||||
logger = event.getModLog();
|
||||
|
||||
proxy.registerResourceReloadListeners();
|
||||
|
||||
configDirectory = new File(event.getModConfigurationDirectory(), Wizardry.MODID);
|
||||
settings.initConfig(event);
|
||||
proxy.registerResourceReloadListeners();
|
||||
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
tisTheSeason = calendar.get(Calendar.MONTH) + 1 == 12 && calendar.get(Calendar.DAY_OF_MONTH) >= 24
|
||||
@@ -168,8 +186,6 @@ public class Wizardry {
|
||||
// Post-registry extras
|
||||
BlockBookshelf.compileBookModelTextures();
|
||||
ContainerBookshelf.initDefaultBookItems();
|
||||
WizardryItems.populateWandMap();
|
||||
WizardryItems.populateArmourMap();
|
||||
WizardryItems.registerDispenseBehaviours();
|
||||
WizardryItems.registerBannerPatterns();
|
||||
WandHelper.populateUpgradeMap();
|
||||
@@ -186,6 +202,8 @@ public class Wizardry {
|
||||
public void postInit(FMLPostInitializationEvent event){
|
||||
proxy.initialiseLayers();
|
||||
proxy.initialiseAnimations();
|
||||
|
||||
SpellNetworkIDSorter.init();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
||||
@@ -79,13 +79,13 @@ public final class WizardryEventHandler {
|
||||
public static void onPlayerLoggedInEvent(PlayerLoggedInEvent event){
|
||||
// When a player logs in, they are sent the glyph data, server settings and spell properties.
|
||||
if(event.player instanceof EntityPlayerMP){
|
||||
SpellGlyphData.get(event.player.world).sync((EntityPlayerMP)event.player);
|
||||
SpellEmitterData.get(event.player.world).sync((EntityPlayerMP)event.player);
|
||||
Wizardry.settings.sync((EntityPlayerMP)event.player);
|
||||
syncAdvancements((EntityPlayerMP)event.player, false);
|
||||
EntityPlayerMP player = (EntityPlayerMP)event.player;
|
||||
SpellGlyphData.get(player.world).sync(player);
|
||||
SpellEmitterData.get(player.world).sync(player);
|
||||
Wizardry.settings.sync(player);
|
||||
syncAdvancements(player, false);
|
||||
Spell.syncProperties(player);
|
||||
}
|
||||
|
||||
Spell.syncProperties(event.player);
|
||||
}
|
||||
|
||||
@SubscribeEvent(priority = EventPriority.HIGH)
|
||||
@@ -203,7 +203,6 @@ public final class WizardryEventHandler {
|
||||
// Find the angle between the direction the mob is looking and the direction the player is in
|
||||
// Angle between a and b = acos((a.b) / (|a|*|b|))
|
||||
double angle = Math.acos(vec.dotProduct(event.getEntity().getLookVec()) / vec.length());
|
||||
System.out.println(angle);
|
||||
// If the player is not within the 144-degree arc in front of the mob, it won't detect them
|
||||
if(angle > 0.4 * Math.PI){
|
||||
((EntityLiving)event.getEntityLiving()).setAttackTarget(null);
|
||||
@@ -269,7 +268,7 @@ public final class WizardryEventHandler {
|
||||
// Fireskin
|
||||
if(event.getEntityLiving().isPotionActive(WizardryPotions.fireskin)
|
||||
&& !MagicDamage.isEntityImmune(DamageType.FIRE, event.getEntityLiving()))
|
||||
attacker.setFire(Spells.fire_breath.getProperty(Spell.BURN_DURATION).intValue());
|
||||
attacker.setFire(Spells.fire_breath.getProperty(Spell.BURN_DURATION).intValue() * 20);
|
||||
|
||||
// Ice Shroud
|
||||
if(event.getEntityLiving().isPotionActive(WizardryPotions.ice_shroud)
|
||||
@@ -307,7 +306,7 @@ public final class WizardryEventHandler {
|
||||
PotionEffect effect = event.getEntityLiving().getActivePotionEffect(WizardryPotions.ward);
|
||||
|
||||
if(effect != null && event.getSource().isMagicDamage()){
|
||||
event.setAmount(event.getAmount() * Math.max(0, 1 - 0.4f * effect.getAmplifier())); // Resistance is 20%
|
||||
event.setAmount(event.getAmount() * Math.max(0, 1 - 0.2f * (1 + effect.getAmplifier()))); // Resistance is 20%
|
||||
}
|
||||
|
||||
// Flaming and freezing swords
|
||||
@@ -491,4 +490,4 @@ public final class WizardryEventHandler {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -108,7 +108,18 @@ public class BlockImbuementAltar extends Block implements ITileEntityProvider {
|
||||
&& world.getBlockState(pos.offset(s)).getValue(BlockReceptacle.FACING) == s);
|
||||
|
||||
if(world.getBlockState(pos).getValue(ACTIVE) != shouldBeActive){ // Only set when it actually needs changing
|
||||
|
||||
// Get contents of altar before replacing it
|
||||
TileEntity te = world.getTileEntity(pos);
|
||||
ItemStack stack = ItemStack.EMPTY;
|
||||
if(te instanceof TileEntityImbuementAltar) stack = ((TileEntityImbuementAltar)te).getStack();
|
||||
|
||||
world.setBlockState(pos, world.getBlockState(pos).withProperty(ACTIVE, shouldBeActive));
|
||||
|
||||
// Copy over contents of altar from before to new tile entity
|
||||
te = world.getTileEntity(pos);
|
||||
if(te instanceof TileEntityImbuementAltar) ((TileEntityImbuementAltar)te).setStack(stack);
|
||||
|
||||
world.checkLight(pos);
|
||||
}
|
||||
|
||||
|
||||
@@ -132,6 +132,13 @@ public class BlockReceptacle extends BlockTorch implements ITileEntityProvider {
|
||||
return super.checkForDrop(world, pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean onNeighborChangeInternal(World world, BlockPos pos, IBlockState state){
|
||||
// This is so stupid, BlockTorch DUPLICATES the code that checks for valid placement in the super method instead
|
||||
// of checking the existing methods...
|
||||
return !this.checkForDrop(world, pos, state); // Literally all we need. None of the rubbish in super.
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer){
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package electroblob.wizardry.client;
|
||||
|
||||
import electroblob.wizardry.CommonProxy;
|
||||
import electroblob.wizardry.Settings;
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.block.BlockBookshelf;
|
||||
import electroblob.wizardry.client.animation.ActionAnimation;
|
||||
@@ -14,9 +15,12 @@ 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;
|
||||
import electroblob.wizardry.client.renderer.RenderSpectralGolem;
|
||||
import electroblob.wizardry.client.renderer.entity.*;
|
||||
import electroblob.wizardry.client.renderer.entity.layers.*;
|
||||
import electroblob.wizardry.client.renderer.overlay.RenderBlinkEffect;
|
||||
@@ -39,6 +43,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 +70,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 +126,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 +144,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
|
||||
@@ -152,7 +166,8 @@ public class ClientProxy extends CommonProxy {
|
||||
IResourceManager manager = Minecraft.getMinecraft().getResourceManager();
|
||||
if(manager instanceof IReloadableResourceManager){
|
||||
((IReloadableResourceManager)manager).registerReloadListener(GuiSpellDisplay::loadSkins);
|
||||
((IReloadableResourceManager)manager).registerReloadListener(GuiWizardHandbook::loadHandbookFile);
|
||||
if (Wizardry.settings.loadHandbook)
|
||||
((IReloadableResourceManager)manager).registerReloadListener(GuiWizardHandbook::loadHandbookFile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -716,6 +731,9 @@ public class ClientProxy extends CommonProxy {
|
||||
LayerTiledOverlay.initialiseLayers(LayerMindControl::new);
|
||||
LayerTiledOverlay.initialiseLayers(LayerSummonAnimation::new);
|
||||
LayerTiledOverlay.initialiseLayers(LayerDisintegrateAnimation::new);
|
||||
LayerTiledOverlay.initialiseLayers(LayerOak::new);
|
||||
LayerTiledOverlay.initialiseLayers(LayerIron::new);
|
||||
LayerTiledOverlay.initialiseLayers(LayerDiamond::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -754,6 +772,7 @@ public class ClientProxy extends CommonProxy {
|
||||
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityIceGiant.class, RenderIceGiant::new);
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityPhoenix.class, RenderPhoenix::new);
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntitySpectralGolem.class, RenderSpectralGolem::new);
|
||||
|
||||
// Projectiles
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityMagicMissile.class, manager -> new RenderMagicArrow(manager,
|
||||
@@ -768,6 +787,7 @@ public class ClientProxy extends CommonProxy {
|
||||
new ResourceLocation(Wizardry.MODID, "textures/entity/ice_lance.png"), false, 16.0, 3.0, 22, 5, false));
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityFlamecatcherArrow.class, manager -> new RenderMagicArrow(manager,
|
||||
new ResourceLocation(Wizardry.MODID, "textures/entity/flamecatcher_arrow.png"), false, 8, 2.0, 16, 5, true));
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityConjuredArrow.class, RenderConjuredArrow::new);
|
||||
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityForceArrow.class, RenderForceArrow::new);
|
||||
|
||||
|
||||
@@ -42,6 +42,8 @@ public class ModelRendererExtended extends ModelRenderer {
|
||||
this.rotationPointX = delegate.rotationPointX;
|
||||
this.rotationPointY = delegate.rotationPointY;
|
||||
this.rotationPointZ = delegate.rotationPointZ;
|
||||
this.cubeList = delegate.cubeList;
|
||||
this.childModels = delegate.childModels;
|
||||
this.resetRotation();
|
||||
}
|
||||
|
||||
@@ -91,6 +93,33 @@ public class ModelRendererExtended extends ModelRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given {@link ModelBiped} is fully wrapped, i.e. all its parts are instances of
|
||||
* {@code ModelRendererExtended}. If the given model is a {@link ModelPlayer}, this also checks the extra boxes for
|
||||
* player skin overlays.
|
||||
*/
|
||||
public static boolean isWrapped(ModelBiped model){
|
||||
|
||||
boolean flag = true;
|
||||
|
||||
if(model instanceof ModelPlayer){
|
||||
flag = flag && ((ModelPlayer)model).bipedBodyWear instanceof ModelRendererExtended;
|
||||
flag = flag && ((ModelPlayer)model).bipedRightArmwear instanceof ModelRendererExtended;
|
||||
flag = flag && ((ModelPlayer)model).bipedLeftArmwear instanceof ModelRendererExtended;
|
||||
flag = flag && ((ModelPlayer)model).bipedRightLegwear instanceof ModelRendererExtended;
|
||||
flag = flag && ((ModelPlayer)model).bipedLeftLegwear instanceof ModelRendererExtended;
|
||||
}
|
||||
|
||||
return flag
|
||||
&& model.bipedHead instanceof ModelRendererExtended
|
||||
&& model.bipedBody instanceof ModelRendererExtended
|
||||
&& model.bipedRightArm instanceof ModelRendererExtended
|
||||
&& model.bipedLeftArm instanceof ModelRendererExtended
|
||||
&& model.bipedRightLeg instanceof ModelRendererExtended
|
||||
&& model.bipedLeftLeg instanceof ModelRendererExtended
|
||||
&& model.bipedHeadwear instanceof ModelRendererExtended;
|
||||
}
|
||||
|
||||
/** Resets the rotation of this model part to the angle set by the parent model. */
|
||||
public void resetRotation(){
|
||||
this.actualRotationX = Float.NaN;
|
||||
|
||||
@@ -25,6 +25,7 @@ import net.minecraft.util.EnumHandSide;
|
||||
import net.minecraftforge.client.ForgeHooksClient;
|
||||
import net.minecraftforge.client.event.RenderPlayerEvent;
|
||||
import net.minecraftforge.client.event.RenderSpecificHandEvent;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
@@ -58,6 +59,9 @@ public class PlayerAnimator {
|
||||
/** Reflected into {@link RenderLivingBase}{@code #layerRenderers}. */
|
||||
private static final Field layerRenderers;
|
||||
|
||||
/** True if wizardry's player animations have been overridden with another mod (currently only MoBends) */
|
||||
private static boolean overridden;
|
||||
|
||||
static {
|
||||
layerRenderers = ObfuscationReflectionHelper.findField(RenderLivingBase.class, "field_177097_h");
|
||||
}
|
||||
@@ -75,86 +79,113 @@ public class PlayerAnimator {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Figure out if calling this from postInit ensures we catch all the layers, and lazy-load it if not
|
||||
@SuppressWarnings("unchecked")
|
||||
/** Returns true if spellcasting animations are enabled, false otherwise. */
|
||||
public static boolean areAnimationsEnabled(){
|
||||
return Wizardry.settings.spellcastingAnimations && !overridden;
|
||||
}
|
||||
|
||||
public static void init(){
|
||||
|
||||
if(!Wizardry.settings.spellcastingAnimations) return;
|
||||
if(Loader.isModLoaded("mobends")) overridden = true;
|
||||
|
||||
if(!areAnimationsEnabled()) return;
|
||||
|
||||
for(RenderPlayer renderer : Minecraft.getMinecraft().getRenderManager().getSkinMap().values()){
|
||||
loadLayersForRenderer(renderer);
|
||||
}
|
||||
}
|
||||
|
||||
List<ModelBiped> models = new ArrayList<>();
|
||||
ModelRendererExtended.wrap(renderer.getMainModel());
|
||||
models.add(renderer.getMainModel());
|
||||
@SuppressWarnings("unchecked")
|
||||
private static void loadLayersForRenderer(RenderPlayer renderer){
|
||||
|
||||
try {
|
||||
List<ModelBiped> models = new ArrayList<>();
|
||||
ModelRendererExtended.wrap(renderer.getMainModel());
|
||||
models.add(renderer.getMainModel());
|
||||
|
||||
List<LayerRenderer<? extends EntityLivingBase>> layers = (List<LayerRenderer<? extends EntityLivingBase>>)layerRenderers.get(renderer);
|
||||
try {
|
||||
|
||||
// Save armour layers for lazy-loading later (ignore other layers so iteration is faster)
|
||||
playerLayers.put(renderer, layers.stream().filter(l -> l instanceof LayerBipedArmor).collect(Collectors.toList()));
|
||||
List<LayerRenderer<? extends EntityLivingBase>> layers = (List<LayerRenderer<? extends EntityLivingBase>>)layerRenderers.get(renderer);
|
||||
|
||||
for(LayerRenderer<?> layer : layers){
|
||||
// Save armour layers for lazy-loading later (ignore other layers so iteration is faster)
|
||||
playerLayers.put(renderer, layers.stream().filter(l -> l instanceof LayerBipedArmor).collect(Collectors.toList()));
|
||||
|
||||
for(Field field : JavaUtils.getAllFields(layer.getClass())){
|
||||
for(LayerRenderer<?> layer : layers){
|
||||
|
||||
field.setAccessible(true);
|
||||
for(Field field : JavaUtils.getAllFields(layer.getClass())){
|
||||
|
||||
// If your layer model doesn't extend ModelBiped, you DESERVE to be incompatible!
|
||||
// (Just kidding... there's nothing I can do about it anyway)
|
||||
if(field.get(layer) instanceof ModelBiped){
|
||||
ModelBiped model = (ModelBiped)field.get(layer);
|
||||
ModelRendererExtended.wrap(model);
|
||||
models.add(model);
|
||||
}
|
||||
field.setAccessible(true);
|
||||
|
||||
// If your layer model doesn't extend ModelBiped, you DESERVE to be incompatible!
|
||||
// (Just kidding... there's nothing I can do about it anyway)
|
||||
if(field.get(layer) instanceof ModelBiped){
|
||||
ModelBiped model = (ModelBiped)field.get(layer);
|
||||
ModelRendererExtended.wrap(model);
|
||||
models.add(model);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}catch(IllegalAccessException e){
|
||||
Wizardry.logger.error("Error during reflective access of render layers: ", e);
|
||||
}
|
||||
|
||||
playerLayerModels.put(renderer, models);
|
||||
|
||||
}catch(IllegalAccessException e){
|
||||
Wizardry.logger.error("Error during reflective access of render layers: ", e);
|
||||
}
|
||||
|
||||
playerLayerModels.put(renderer, models);
|
||||
}
|
||||
|
||||
private static void updateModels(EntityPlayer player, Render<?> renderer, float partialTicks, boolean firstPerson){
|
||||
|
||||
// Biped armour is special because of Forge's armour item render hook
|
||||
// This needs to be lazy-loaded because we need access to an actual item
|
||||
for(LayerRenderer<? extends EntityLivingBase> layer : playerLayers.get(renderer)){
|
||||
if(layer instanceof LayerBipedArmor){
|
||||
for(EntityEquipmentSlot slot : InventoryUtils.ARMOUR_SLOTS){
|
||||
// Lazy-load models from custom renderers (some mods assign their custom renderers in postInit, so they might
|
||||
// not be picked up from PlayerAnimator#init)
|
||||
if(renderer instanceof RenderPlayer && !playerLayerModels.containsKey(renderer)){
|
||||
loadLayersForRenderer((RenderPlayer)renderer);
|
||||
}
|
||||
|
||||
ItemStack armour = player.getItemStackFromSlot(slot);
|
||||
// This method could behave dynamically depending on stuff like NBT so there's not really any way to
|
||||
// optimise it further, we *have* to retrieve the model every time (shouldn't be too bad though)
|
||||
ModelBiped model = ForgeHooksClient.getArmorModel(player, armour, slot, ((LayerBipedArmor)layer).getModelFromSlot(slot));
|
||||
List<ModelBiped> models = playerLayerModels.get(renderer);
|
||||
|
||||
List<ModelBiped> models = playerLayerModels.get(renderer);
|
||||
// If no models were registered for the given renderer, don't do anything
|
||||
if(models != null){
|
||||
|
||||
if(!models.contains(model)){ // Ignore already-wrapped models
|
||||
models.add(model);
|
||||
ModelRendererExtended.wrap(model);
|
||||
List<LayerRenderer<? extends EntityLivingBase>> layers = playerLayers.get(renderer);
|
||||
|
||||
// If no layers were registered for the given renderer there's no point trying to lazy-load anything!
|
||||
if(layers != null){
|
||||
|
||||
// Biped armour is special because of Forge's armour item render hook
|
||||
// This needs to be lazy-loaded because we need access to an actual item
|
||||
for(LayerRenderer<? extends EntityLivingBase> layer : layers){
|
||||
if(layer instanceof LayerBipedArmor){
|
||||
for(EntityEquipmentSlot slot : InventoryUtils.ARMOUR_SLOTS){
|
||||
|
||||
ItemStack armour = player.getItemStackFromSlot(slot);
|
||||
// This method could behave dynamically depending on stuff like NBT so there's not really any way to
|
||||
// optimise it further, we *have* to retrieve the model every time (shouldn't be too bad though)
|
||||
ModelBiped model = ForgeHooksClient.getArmorModel(player, armour, slot, ((LayerBipedArmor)layer).getModelFromSlot(slot));
|
||||
|
||||
if(!models.contains(model)){ // Ignore already-wrapped models
|
||||
models.add(model);
|
||||
ModelRendererExtended.wrap(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(Animation animation : animations){
|
||||
for(Animation animation : animations){
|
||||
|
||||
if(animation.shouldDisplay(player, firstPerson)){
|
||||
if(animation.shouldDisplay(player, firstPerson)){
|
||||
|
||||
boolean autoRotateSecondLayer = animation.autoRotateSecondLayer(player, firstPerson);
|
||||
boolean autoRotateSecondLayer = animation.autoRotateSecondLayer(player, firstPerson);
|
||||
|
||||
for(ModelBiped model : playerLayerModels.get(renderer)){
|
||||
for(ModelBiped model : models){
|
||||
|
||||
animation.setRotationAngles(player, model, partialTicks, firstPerson);
|
||||
if(!ModelRendererExtended.isWrapped(model)) continue; // Should never happen but somehow it does
|
||||
|
||||
if(autoRotateSecondLayer && model instanceof ModelPlayer){
|
||||
alignSecondLayer((ModelPlayer)model);
|
||||
animation.setRotationAngles(player, model, partialTicks, firstPerson);
|
||||
|
||||
if(autoRotateSecondLayer && model instanceof ModelPlayer){
|
||||
alignSecondLayer((ModelPlayer)model);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -174,7 +205,7 @@ public class PlayerAnimator {
|
||||
@SubscribeEvent
|
||||
public static void onRenderHandEvent(RenderSpecificHandEvent event){
|
||||
|
||||
if(!Wizardry.settings.spellcastingAnimations) return;
|
||||
if(!areAnimationsEnabled()) return;
|
||||
|
||||
AbstractClientPlayer player = Minecraft.getMinecraft().player;
|
||||
|
||||
@@ -193,7 +224,7 @@ public class PlayerAnimator {
|
||||
@SubscribeEvent
|
||||
public static void onRenderPlayerPreEvent(RenderPlayerEvent.Pre event){
|
||||
|
||||
if(!Wizardry.settings.spellcastingAnimations) return;
|
||||
if(!areAnimationsEnabled()) return;
|
||||
|
||||
// boolean firstPerson = event.getEntityPlayer() == Minecraft.getMinecraft().player
|
||||
// && Minecraft.getMinecraft().gameSettings.thirdPersonView == 0;
|
||||
@@ -204,13 +235,17 @@ public class PlayerAnimator {
|
||||
@SubscribeEvent
|
||||
public static void onRenderPlayerPostEvent(RenderPlayerEvent.Post event){
|
||||
|
||||
if(!Wizardry.settings.spellcastingAnimations) return;
|
||||
if(!areAnimationsEnabled()) return;
|
||||
|
||||
for(ModelBiped model : playerLayerModels.get(event.getRenderer())){
|
||||
for(ModelRenderer box : model.boxList){ // For ModelPlayer, this will include the second layer
|
||||
// Some models have extra boxes, they (probably) don't need wrapping but we need this check!
|
||||
if(box instanceof ModelRendererExtended){
|
||||
((ModelRendererExtended)box).resetRotation();
|
||||
List<ModelBiped> models = playerLayerModels.get(event.getRenderer());
|
||||
|
||||
if(models != null){
|
||||
for(ModelBiped model : models){
|
||||
for(ModelRenderer box : model.boxList){ // For ModelPlayer, this will include the second layer
|
||||
// Some models have extra boxes, they (probably) don't need wrapping but we need this check!
|
||||
if(box instanceof ModelRendererExtended){
|
||||
((ModelRendererExtended)box).resetRotation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +93,7 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
||||
private ContainerArcaneWorkbench arcaneWorkbenchContainer;
|
||||
|
||||
private GuiButton applyBtn;
|
||||
private GuiButton clearBtn;
|
||||
private GuiButton[] sortButtons = new GuiButton[3];
|
||||
|
||||
private GuiTextField searchField;
|
||||
@@ -126,6 +127,7 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
||||
|
||||
this.buttonList.clear();
|
||||
this.buttonList.add(this.applyBtn = new GuiButtonApply(0, this.width / 2 + 64, this.height / 2 + 3));
|
||||
this.buttonList.add(this.clearBtn = new GuiButtonClear(0, this.width / 2 + 64, this.height / 2 - 16));
|
||||
this.buttonList.add(sortButtons[0] = new GuiButtonSpellSort(1, this.guiLeft - 44, this.guiTop + 8, ISpellSortable.SortType.TIER, arcaneWorkbenchContainer, this));
|
||||
this.buttonList.add(sortButtons[1] = new GuiButtonSpellSort(2, this.guiLeft - 31, this.guiTop + 8, ISpellSortable.SortType.ELEMENT, arcaneWorkbenchContainer, this));
|
||||
this.buttonList.add(sortButtons[2] = new GuiButtonSpellSort(3, this.guiLeft - 18, this.guiTop + 8, ISpellSortable.SortType.ALPHABETICAL, arcaneWorkbenchContainer, this));
|
||||
@@ -205,6 +207,7 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
||||
|
||||
// Show/hide the relevant gui elements
|
||||
this.applyBtn.enabled = centreSlot.getHasStack();
|
||||
this.clearBtn.enabled = centreSlot.getHasStack() && centreSlot.getStack().getItem() instanceof IWorkbenchItem && ((IWorkbenchItem) centreSlot.getStack().getItem()).isClearable();
|
||||
for(GuiButton button : this.sortButtons) button.visible = arcaneWorkbenchContainer.hasBookshelves();
|
||||
this.searchField.setVisible(arcaneWorkbenchContainer.hasBookshelves());
|
||||
|
||||
@@ -444,6 +447,17 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
||||
animationTimer = 20;
|
||||
}
|
||||
|
||||
if(button == clearBtn){
|
||||
// Packet building
|
||||
IMessage msg = new PacketControlInput.Message(PacketControlInput.ControlType.CLEAR_BUTTON);
|
||||
WizardryPacketHandler.net.sendToServer(msg);
|
||||
// Sound
|
||||
Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.getMasterRecord(
|
||||
WizardrySounds.BLOCK_ARCANE_WORKBENCH_SPELLBIND, 0.8f));
|
||||
// Animation
|
||||
animationTimer = 20;
|
||||
}
|
||||
|
||||
if(button instanceof GuiButtonSpellSort) this.arcaneWorkbenchContainer.setSortType(((GuiButtonSpellSort)button).sortType);
|
||||
}
|
||||
}
|
||||
@@ -1006,4 +1020,36 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
||||
}
|
||||
}
|
||||
|
||||
private static class GuiButtonClear extends GuiButton {
|
||||
|
||||
public GuiButtonClear(int id, int x, int y){
|
||||
super(id, x, y, 16, 16, I18n.format("container." + Wizardry.MODID + ":arcane_workbench.clear"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawButton(Minecraft minecraft, int mouseX, int mouseY, float partialTicks){
|
||||
|
||||
// Whether the button is highlighted
|
||||
this.hovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height;
|
||||
|
||||
int k = 72;
|
||||
int l = 236;
|
||||
//int colour = 14737632;
|
||||
|
||||
if(this.enabled){
|
||||
if(this.hovered){
|
||||
k += this.width * 2;
|
||||
//colour = 16777120;
|
||||
}
|
||||
}else{
|
||||
k += this.width;
|
||||
//colour = 10526880;
|
||||
}
|
||||
|
||||
DrawingUtils.drawTexturedRect(this.x, this.y, k, l, this.width, this.height, TEXTURE_WIDTH, TEXTURE_HEIGHT);
|
||||
//this.drawCenteredString(minecraft.fontRenderer, this.displayString, this.x + this.width / 2,
|
||||
// this.y + (this.height - 8) / 2, colour);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -34,12 +34,13 @@ import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@Mod.EventBusSubscriber(Side.CLIENT)
|
||||
public class GuiSpellDisplay {
|
||||
@@ -96,9 +97,28 @@ public class GuiSpellDisplay {
|
||||
return Collections.unmodifiableMap(skins);
|
||||
}
|
||||
|
||||
/** Returns the skin that corresponds to the given key. */
|
||||
/** Returns the skin that corresponds to the given key. If no such skin exists, returns the default skin as a
|
||||
* fallback. If the fallback skin is missing, prints a warning to the console and returns null. */
|
||||
@Nullable
|
||||
public static Skin getSkin(String key){
|
||||
return skins.get(key);
|
||||
|
||||
Skin skin = skins.get(key);
|
||||
|
||||
if(skin == null){
|
||||
|
||||
Wizardry.logger.info("The spell HUD skin '" + Wizardry.settings.spellHUDSkin + "' specified in the config"
|
||||
+ " did not match any of the loaded skins; using the default skin as a fallback.");
|
||||
|
||||
skin = skins.get(Settings.DEFAULT_HUD_SKIN_KEY);
|
||||
|
||||
if(skin == null){
|
||||
Wizardry.logger.warn("The default spell HUD skin is missing! A resource pack must have overridden it"
|
||||
+ " with an invalid JSON file (default.json), please try again without any resource packs.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return skin;
|
||||
}
|
||||
|
||||
// Normally when extending Gui, you'd have to have an instance to access its methods. However, we're not actually
|
||||
@@ -212,21 +232,9 @@ public class GuiSpellDisplay {
|
||||
flipX = flipX == ((mainHand ? player.getPrimaryHand() : player.getPrimaryHand().opposite()) == EnumHandSide.LEFT);
|
||||
}
|
||||
|
||||
Skin skin = skins.get(Wizardry.settings.spellHUDSkin);
|
||||
Skin skin = getSkin(Wizardry.settings.spellHUDSkin);
|
||||
|
||||
if(skin == null){
|
||||
|
||||
Wizardry.logger.info("The spell HUD skin '" + Wizardry.settings.spellHUDSkin + "' specified in the config"
|
||||
+ " did not match any of the loaded skins; using the default skin as a fallback.");
|
||||
|
||||
skin = skins.get(Settings.DEFAULT_HUD_SKIN_KEY);
|
||||
|
||||
if(skin == null){
|
||||
Wizardry.logger.warn("The default spell HUD skin is missing! A resource pack must have overridden it"
|
||||
+ " with an invalid JSON file (default.json), please try again without any resource packs.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(skin == null) return; // Can't draw anything if there is no skin loaded!
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
|
||||
|
||||
@@ -90,28 +90,30 @@ public class WizardTradeTweaksHandler {
|
||||
// New spell indicator
|
||||
if(gui.inventorySlots instanceof ContainerMerchant){
|
||||
|
||||
// Can't use getCurrentRecipe because that only gets updated when the correct items are given
|
||||
MerchantRecipe recipe = trades.get(tradeIndex);
|
||||
if(tradeIndex < trades.size()){ // Seems to happen with certain mods' GUIs
|
||||
|
||||
if(recipe != null && recipe.getItemToSell().getItem() instanceof ItemSpellBook){
|
||||
// Can't use getCurrentRecipe because that only gets updated when the correct items are given
|
||||
MerchantRecipe recipe = trades.get(tradeIndex);
|
||||
|
||||
EntityPlayer player = Minecraft.getMinecraft().player;
|
||||
Spell spell = Spell.byMetadata(recipe.getItemToSell().getMetadata());
|
||||
if(recipe != null && recipe.getItemToSell().getItem() instanceof ItemSpellBook){
|
||||
|
||||
if(Wizardry.settings.discoveryMode && !player.isCreative() && Wizardry.proxy.shouldDisplayDiscovered(spell, recipe.getItemToSell())
|
||||
&& WizardData.get(player) != null && !WizardData.get(player).hasSpellBeenDiscovered(spell)){
|
||||
|
||||
int x = gui.inventorySlots.getSlot(2).xPos + 14;
|
||||
int y = gui.inventorySlots.getSlot(2).yPos - 17;
|
||||
EntityPlayer player = Minecraft.getMinecraft().player;
|
||||
Spell spell = Spell.byMetadata(recipe.getItemToSell().getMetadata());
|
||||
|
||||
RenderHelper.enableGUIStandardItemLighting();
|
||||
GlStateManager.color(1, 1, 1);
|
||||
Minecraft.getMinecraft().renderEngine.bindTexture(NEW_SPELL_ICON);
|
||||
if(Wizardry.settings.discoveryMode && !player.isCreative() && Wizardry.proxy.shouldDisplayDiscovered(spell, recipe.getItemToSell())
|
||||
&& WizardData.get(player) != null && !WizardData.get(player).hasSpellBeenDiscovered(spell)){
|
||||
|
||||
int frame = Math.max(player.ticksExisted/ANIMATION_FRAME_TIME % ANIMATION_PERIOD - (ANIMATION_PERIOD - ANIMATION_FRAMES), 0);
|
||||
DrawingUtils.drawTexturedRect(x, y, 0, frame * ICON_HEIGHT, ICON_WIDTH, ICON_HEIGHT, ICON_WIDTH, ICON_HEIGHT * ANIMATION_FRAMES);
|
||||
int x = gui.inventorySlots.getSlot(2).xPos + 14;
|
||||
int y = gui.inventorySlots.getSlot(2).yPos - 17;
|
||||
|
||||
RenderHelper.disableStandardItemLighting();
|
||||
RenderHelper.enableGUIStandardItemLighting();
|
||||
GlStateManager.color(1, 1, 1);
|
||||
Minecraft.getMinecraft().renderEngine.bindTexture(NEW_SPELL_ICON);
|
||||
|
||||
int frame = Math.max(player.ticksExisted / ANIMATION_FRAME_TIME % ANIMATION_PERIOD - (ANIMATION_PERIOD - ANIMATION_FRAMES), 0);
|
||||
DrawingUtils.drawTexturedRect(x, y, 0, frame * ICON_HEIGHT, ICON_WIDTH, ICON_HEIGHT, ICON_WIDTH, ICON_HEIGHT * ANIMATION_FRAMES);
|
||||
|
||||
RenderHelper.disableStandardItemLighting();
|
||||
|
||||
// int mouseX = event.getMouseX() - gui.getGuiLeft();
|
||||
// int mouseY = event.getMouseY() - gui.getGuiTop();
|
||||
@@ -120,6 +122,7 @@ public class WizardTradeTweaksHandler {
|
||||
// GuiUtils.drawHoveringText(Collections.singletonList("You haven't discovered this spell yet"), mouseX,
|
||||
// mouseY, gui.width, gui.height, 150, Minecraft.getMinecraft().fontRenderer);
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(){
|
||||
|
||||
@@ -59,31 +59,34 @@ public class GuiSelectHUDSkin extends GuiSelectString {
|
||||
this.drawGradientRect(previewLeft, previewTop, previewRight, previewBottom, 0x88000000, 0x88000000);
|
||||
|
||||
int previewBorder = 10;
|
||||
|
||||
|
||||
Skin skin = GuiSpellDisplay.getSkin((String)this.currentValue);
|
||||
|
||||
float scale = Math.min((previewRight - previewLeft - 2*previewBorder)/(float)skin.getWidth(),
|
||||
(previewBottom - previewTop - 2*previewBorder)/(float)skin.getHeight());
|
||||
|
||||
float x = (previewLeft + previewRight)/2f - (skin.getWidth()*scale)/2;
|
||||
float y = (previewBottom + previewTop)/2f + (skin.getHeight()*scale)/2;
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
|
||||
GlStateManager.scale(scale, scale, scale);
|
||||
|
||||
skin.drawBackground((int)(x/scale), (int)(y/scale), false, false,
|
||||
Spells.magic_missile.getIcon(), 0.6f, false, false);
|
||||
|
||||
skin.drawText((int)(x/scale), (int)(y/scale), false, false,
|
||||
Spells.none.getDisplayNameWithFormatting(),
|
||||
Spells.magic_missile.getDisplayNameWithFormatting(),
|
||||
Spells.none.getDisplayNameWithFormatting(), 0);
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
|
||||
if(skin != null){
|
||||
|
||||
float scale = Math.min((previewRight - previewLeft - 2 * previewBorder) / (float)skin.getWidth(),
|
||||
(previewBottom - previewTop - 2 * previewBorder) / (float)skin.getHeight());
|
||||
|
||||
float x = (previewLeft + previewRight) / 2f - (skin.getWidth() * scale) / 2;
|
||||
float y = (previewBottom + previewTop) / 2f + (skin.getHeight() * scale) / 2;
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
|
||||
GlStateManager.scale(scale, scale, scale);
|
||||
|
||||
skin.drawBackground((int)(x / scale), (int)(y / scale), false, false,
|
||||
Spells.magic_missile.getIcon(), 0.6f, false, false);
|
||||
|
||||
skin.drawText((int)(x / scale), (int)(y / scale), false, false,
|
||||
Spells.none.getDisplayNameWithFormatting(),
|
||||
Spells.magic_missile.getDisplayNameWithFormatting(),
|
||||
Spells.none.getDisplayNameWithFormatting(), 0);
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
Skin hovered = getHoveredSkin(mouseX, mouseY);
|
||||
|
||||
|
||||
if(hovered != null){
|
||||
this.drawToolTip(Lists.newArrayList("\u00A7a" + hovered.getName(), "\u00A7e" + hovered.getDescription()),
|
||||
mouseX, mouseY);
|
||||
|
||||
@@ -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;
|
||||
@@ -19,7 +20,7 @@ import java.util.*;
|
||||
|
||||
/**
|
||||
* Instances of this class represent sections in the wizard's handbook. As of wizardry 4.2, this class handles
|
||||
* everything within the section itself, including JSON parsing, unlock triggers and drawing the actual rawText.
|
||||
* everything within the section itself, including JSON parsing, unlock triggers and drawing the actual text.
|
||||
* Sections may now also be nested and have other elements within them, such as images and a table of contents, a
|
||||
* behaviour which is also handled within this class.
|
||||
* <p></p>
|
||||
@@ -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,10 +318,10 @@ 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 rawText in the main string
|
||||
// If the link has no display rawText specified, it displays the unformatted target string
|
||||
// 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
|
||||
paragraph = paragraph.replace(linkRaw, arguments[arguments.length - 1]);
|
||||
}
|
||||
|
||||
@@ -385,7 +392,7 @@ class Section {
|
||||
|
||||
if(JsonUtils.hasField(json, "text")){
|
||||
section.rawText = Streams.stream(JsonUtils.getJsonArray(json, "text"))
|
||||
.map(e -> JsonUtils.getString(e, "element of array rawText"))
|
||||
.map(e -> JsonUtils.getString(e, "element of array text"))
|
||||
.toArray(String[]::new);
|
||||
}
|
||||
|
||||
|
||||
@@ -119,11 +119,19 @@ public class BakedModelGenerateOverrides implements IBakedModel {
|
||||
|
||||
IBakedModel original = event.getModelRegistry().getObject(location);
|
||||
|
||||
if(original != null){
|
||||
original.getOverrides().getOverrides().stream().map(ItemOverride::getLocation)
|
||||
.filter(l -> l.getPath().contains(OVERRIDE_GENERATORS)).findFirst()
|
||||
.ifPresent(l -> event.getModelRegistry().putObject(location,
|
||||
substituteWandModel(event.getModelManager(), location, original, l)));
|
||||
try{
|
||||
|
||||
// Ignore the warnings, IntelliJ is right that these can't be null in the dev environment but certain
|
||||
// mods seem to be doing ASM hackery that makes it so they can be null
|
||||
if(original != null && original.getOverrides() != null && original.getOverrides().getOverrides() != null){
|
||||
original.getOverrides().getOverrides().stream().map(ItemOverride::getLocation)
|
||||
.filter(l -> l.getPath().contains(OVERRIDE_GENERATORS)).findFirst()
|
||||
.ifPresent(l -> event.getModelRegistry().putObject(location,
|
||||
substituteWandModel(event.getModelManager(), location, original, l)));
|
||||
}
|
||||
|
||||
}catch(NullPointerException e){
|
||||
Wizardry.logger.info("The model {} threw an error when trying to access item overrides, it will be ignored. If you're an addon dev and you made this model, something is wrong with it! Otherwise, please ignore this message.", location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package electroblob.wizardry.client.renderer;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import net.minecraft.client.model.ModelIronGolem;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.entity.RenderLiving;
|
||||
import net.minecraft.client.renderer.entity.RenderManager;
|
||||
import net.minecraft.entity.monster.EntityIronGolem;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class RenderSpectralGolem extends RenderLiving<EntityIronGolem>
|
||||
{
|
||||
private static final ResourceLocation SPECTRAL_GOLEM_TEXTURES = new ResourceLocation(Wizardry.MODID, "textures/entity/spectral_golem.png");
|
||||
|
||||
public RenderSpectralGolem(RenderManager renderManagerIn)
|
||||
{
|
||||
super(renderManagerIn, new ModelIronGolem(), 0.5F);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture.
|
||||
*/
|
||||
protected ResourceLocation getEntityTexture(EntityIronGolem entity)
|
||||
{
|
||||
return SPECTRAL_GOLEM_TEXTURES;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void preRenderCallback(EntityIronGolem entity, float partialTickTime){
|
||||
super.preRenderCallback(entity, partialTickTime);
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
GlStateManager.color(1, 1, 1, 0.7f);
|
||||
}
|
||||
|
||||
protected void applyRotations(EntityIronGolem entityLiving, float ageInTicks, float rotationYaw, float partialTicks)
|
||||
{
|
||||
super.applyRotations(entityLiving, ageInTicks, rotationYaw, partialTicks);
|
||||
|
||||
if ((double)entityLiving.limbSwingAmount >= 0.01D)
|
||||
{
|
||||
float f = 13.0F;
|
||||
float f1 = entityLiving.limbSwing - entityLiving.limbSwingAmount * (1.0F - partialTicks) + 6.0F;
|
||||
float f2 = (Math.abs(f1 % 13.0F - 6.5F) - 3.25F) / 3.25F;
|
||||
GlStateManager.rotate(6.5F * f2, 0.0F, 0.0F, 1.0F);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package electroblob.wizardry.client.renderer.entity;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.entity.projectile.EntityConjuredArrow;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.entity.RenderArrow;
|
||||
import net.minecraft.client.renderer.entity.RenderManager;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class RenderConjuredArrow extends RenderArrow<EntityConjuredArrow> {
|
||||
|
||||
public static final ResourceLocation CONJURED_ARROW_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/entity/conjured_arrow.png");
|
||||
|
||||
public RenderConjuredArrow(RenderManager manager) {
|
||||
super(manager);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceLocation getEntityTexture(EntityConjuredArrow entity) {
|
||||
return CONJURED_ARROW_TEXTURE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doRender(EntityConjuredArrow entity, double x, double y, double z, float entityYaw, float partialTicks) {
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
GlStateManager.color(1, 1, 1, 0.4f);
|
||||
super.doRender(entity, x, y, z, entityYaw, partialTicks);
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package electroblob.wizardry.client.renderer.entity.layers;
|
||||
|
||||
import electroblob.wizardry.registry.WizardryPotions;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.GlStateManager.DestFactor;
|
||||
import net.minecraft.client.renderer.GlStateManager.SourceFactor;
|
||||
import net.minecraft.client.renderer.OpenGlHelper;
|
||||
import net.minecraft.client.renderer.entity.RenderLivingBase;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Layer used to render the diamondflesh texture on creatures with the diamondflesh effect.
|
||||
*
|
||||
* @author WinDanesz
|
||||
* @since Wizardry 4.3.7
|
||||
*/
|
||||
public class LayerDiamond extends LayerTiledOverlay<EntityLivingBase> {
|
||||
|
||||
private static final ResourceLocation TEXTURE = new ResourceLocation("textures/blocks/diamond_block.png");
|
||||
|
||||
public LayerDiamond(RenderLivingBase<?> renderer){
|
||||
super(renderer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRender(EntityLivingBase entity, float partialTicks){
|
||||
return !entity.isInvisible() && entity.isPotionActive(WizardryPotions.diamondflesh);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getTexture(EntityLivingBase entity, float partialTicks){
|
||||
return TEXTURE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doRenderLayer(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks,
|
||||
float ageInTicks, float netHeadYaw, float headPitch, float scale){
|
||||
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
int j = entity.getBrightnessForRender();
|
||||
int k = j % 65536;
|
||||
int l = j / 65536;
|
||||
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float) k, (float) l);
|
||||
|
||||
super.doRenderLayer(entity, limbSwing, limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch, scale);
|
||||
|
||||
GlStateManager.disableBlend();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package electroblob.wizardry.client.renderer.entity.layers;
|
||||
|
||||
import electroblob.wizardry.registry.WizardryPotions;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.GlStateManager.DestFactor;
|
||||
import net.minecraft.client.renderer.GlStateManager.SourceFactor;
|
||||
import net.minecraft.client.renderer.OpenGlHelper;
|
||||
import net.minecraft.client.renderer.entity.RenderLivingBase;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Layer used to render the ironflesh texture on creatures with the ironflesh effect.
|
||||
*
|
||||
* @author WinDanesz
|
||||
* @since Wizardry 4.3.7
|
||||
*/
|
||||
public class LayerIron extends LayerTiledOverlay<EntityLivingBase> {
|
||||
|
||||
private static final ResourceLocation TEXTURE = new ResourceLocation("textures/blocks/iron_block.png");
|
||||
|
||||
public LayerIron(RenderLivingBase<?> renderer){
|
||||
super(renderer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRender(EntityLivingBase entity, float partialTicks){
|
||||
return !entity.isInvisible() && entity.isPotionActive(WizardryPotions.ironflesh);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getTexture(EntityLivingBase entity, float partialTicks){
|
||||
return TEXTURE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doRenderLayer(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks,
|
||||
float ageInTicks, float netHeadYaw, float headPitch, float scale){
|
||||
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
int j = entity.getBrightnessForRender();
|
||||
int k = j % 65536;
|
||||
int l = j / 65536;
|
||||
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float) k, (float) l);
|
||||
|
||||
super.doRenderLayer(entity, limbSwing, limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch, scale);
|
||||
|
||||
GlStateManager.disableBlend();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package electroblob.wizardry.client.renderer.entity.layers;
|
||||
|
||||
import electroblob.wizardry.registry.WizardryPotions;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.GlStateManager.DestFactor;
|
||||
import net.minecraft.client.renderer.GlStateManager.SourceFactor;
|
||||
import net.minecraft.client.renderer.OpenGlHelper;
|
||||
import net.minecraft.client.renderer.entity.RenderLivingBase;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Layer used to render the oakflesh texture on creatures with the oakflesh effect.
|
||||
*
|
||||
* @author WinDanesz
|
||||
* @since Wizardry 4.3.7
|
||||
*/
|
||||
public class LayerOak extends LayerTiledOverlay<EntityLivingBase> {
|
||||
|
||||
private static final ResourceLocation TEXTURE = new ResourceLocation("textures/blocks/log_oak.png");
|
||||
|
||||
public LayerOak(RenderLivingBase<?> renderer){
|
||||
super(renderer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRender(EntityLivingBase entity, float partialTicks){
|
||||
return !entity.isInvisible() && entity.isPotionActive(WizardryPotions.oakflesh);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getTexture(EntityLivingBase entity, float partialTicks){
|
||||
return TEXTURE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doRenderLayer(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks,
|
||||
float ageInTicks, float netHeadYaw, float headPitch, float scale){
|
||||
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
int j = entity.getBrightnessForRender();
|
||||
int k = j % 65536;
|
||||
int l = j / 65536;
|
||||
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float) k, (float) l);
|
||||
|
||||
super.doRenderLayer(entity, limbSwing, limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch, scale);
|
||||
|
||||
GlStateManager.disableBlend();
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -143,7 +143,7 @@ public abstract class LayerTiledOverlay<T extends EntityLivingBase> implements L
|
||||
double scaleX = 1, scaleY = 1;
|
||||
// It's more logical to use the model's texture size, but some classes don't bother setting it properly
|
||||
// (e.g. ModelVillager), so to get the correct dimensions I'm getting them from the first box instead.
|
||||
if(model.boxList != null && model.boxList.get(0) != null){
|
||||
if(model.boxList != null && model.boxList.size() >= 1 && model.boxList.get(0) != null){
|
||||
scaleX = (double)model.boxList.get(0).textureWidth / textureWidth;
|
||||
scaleY = (double)model.boxList.get(0).textureHeight / textureHeight;
|
||||
}else{ // Fallback to model fields; should never be needed
|
||||
|
||||
@@ -30,12 +30,11 @@ import org.lwjgl.opengl.GL11;
|
||||
@EventBusSubscriber(Side.CLIENT)
|
||||
public class RenderSixthSense {
|
||||
|
||||
private static final ResourceLocation MARKER_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/gui/sixth_sense_marker.png");
|
||||
private static final ResourceLocation SCREEN_OVERLAY_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/gui/sixth_sense_overlay.png");
|
||||
|
||||
private static final int PASSIVE_MOB_MARKER_COLOUR = 0xc6ff00;
|
||||
private static final int HOSTILE_MOB_MARKER_COLOUR = 0x004a97;
|
||||
private static final int PLAYER_MARKER_COLOUR = 0xffffff;
|
||||
private static final ResourceLocation PASSIVE_MOB_MARKER_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/gui/sixth_sense_marker_passive.png");
|
||||
private static final ResourceLocation HOSTILE_MOB_MARKER_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/gui/sixth_sense_marker_hostile.png");
|
||||
private static final ResourceLocation PLAYER_MARKER_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/gui/sixth_sense_marker_player.png");
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onRenderGameOverlayEvent(RenderGameOverlayEvent.Post event){
|
||||
@@ -88,26 +87,19 @@ public class RenderSixthSense {
|
||||
GlStateManager.rotate(180 - renderManager.playerViewY, 0.0F, 1.0F, 0.0F);
|
||||
GlStateManager.rotate(yaw, 1.0F, 0.0F, 0.0F);
|
||||
|
||||
// Makes the colour add to the colour of the texture pixels, rather than the default multiplying
|
||||
GlStateManager.glTexEnvi(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_ADD);
|
||||
GlStateManager.color(1, 1, 1, 1);
|
||||
|
||||
int colour = PASSIVE_MOB_MARKER_COLOUR;
|
||||
ResourceLocation texture = PASSIVE_MOB_MARKER_TEXTURE;
|
||||
|
||||
if(ItemArtefact.isArtefactActive(mc.player, WizardryItems.charm_sixth_sense)){
|
||||
if(event.getEntity() instanceof IMob) colour = HOSTILE_MOB_MARKER_COLOUR;
|
||||
else if(event.getEntity() instanceof EntityPlayer) colour = PLAYER_MARKER_COLOUR;
|
||||
if(event.getEntity() instanceof IMob) texture = HOSTILE_MOB_MARKER_TEXTURE;
|
||||
else if(event.getEntity() instanceof EntityPlayer) texture = PLAYER_MARKER_TEXTURE;
|
||||
}
|
||||
|
||||
int r = colour >> 16 & 255;
|
||||
int g = colour >> 8 & 255;
|
||||
int b = colour & 255;
|
||||
|
||||
GlStateManager.color(r/255f, g/255f, b/255f, 1);
|
||||
mc.renderEngine.bindTexture(texture);
|
||||
|
||||
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
|
||||
|
||||
mc.renderEngine.bindTexture(MARKER_TEXTURE);
|
||||
|
||||
buffer.pos(-0.6, 0.6, 0).tex(0, 0).endVertex();
|
||||
buffer.pos(0.6, 0.6, 0).tex(1, 0).endVertex();
|
||||
buffer.pos(0.6, -0.6, 0).tex(1, 1).endVertex();
|
||||
@@ -119,8 +111,6 @@ public class RenderSixthSense {
|
||||
GlStateManager.disableBlend();
|
||||
GlStateManager.enableLighting();
|
||||
GlStateManager.enableDepth();
|
||||
// Reverses the colour addition change from before
|
||||
GlStateManager.glTexEnvi(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_MODULATE);
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package electroblob.wizardry.constants;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.WizardryEventHandler;
|
||||
|
||||
/** Stores various global constants used in Wizardry. */
|
||||
@@ -17,21 +18,17 @@ public final class Constants {
|
||||
/** The bonus amount of wand upgrades that can be applied to a non-elemental wand. */
|
||||
public static final int NON_ELEMENTAL_UPGRADE_BONUS = 3;
|
||||
/** The fraction by which cooldowns are reduced for each level of cooldown upgrade. */
|
||||
public static final float COOLDOWN_REDUCTION_PER_LEVEL = 0.15f;
|
||||
public static float COOLDOWN_REDUCTION_PER_LEVEL = 0.15f;
|
||||
/** The fraction by which maximum charge is increased for each level of storage upgrade. */
|
||||
public static final float STORAGE_INCREASE_PER_LEVEL = 0.15f;
|
||||
/** The fraction by which potency is increased for each tier of matching wand. */
|
||||
public static final float POTENCY_INCREASE_PER_TIER = 0.15f;
|
||||
/** 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;
|
||||
public static float POTENCY_INCREASE_PER_TIER = 0.15f;
|
||||
/** The fraction by which spell duration is increased for each level of duration upgrade. */
|
||||
public static final float DURATION_INCREASE_PER_LEVEL = 0.25f;
|
||||
public static float DURATION_INCREASE_PER_LEVEL = 0.25f;
|
||||
/** The fraction by which spell range is increased for each level of range upgrade. */
|
||||
public static final float RANGE_INCREASE_PER_LEVEL = 0.25f;
|
||||
public static float RANGE_INCREASE_PER_LEVEL = 0.25f;
|
||||
/** The fraction by which spell blast radius is increased for each level of range upgrade. */
|
||||
public static final float BLAST_RADIUS_INCREASE_PER_LEVEL = 0.25f;
|
||||
public static float BLAST_RADIUS_INCREASE_PER_LEVEL = 0.25f;
|
||||
/** The fraction by which movement speed is reduced per level of frost effect. */
|
||||
public static final double FROST_SLOWNESS_PER_LEVEL = 0.5;
|
||||
/** The fraction by which movement speed is reduced per level of decay effect. */
|
||||
@@ -50,7 +47,15 @@ public final class Constants {
|
||||
* won't spawn again if something is already standing in it.
|
||||
*/
|
||||
public static final int DECAY_SPREAD_INTERVAL = 8;
|
||||
/** The fraction by which potency is increased per level of the empowerment effect. */
|
||||
public static final float EMPOWERMENT_POTENCY_PER_LEVEL = 0.25f;
|
||||
|
||||
|
||||
// making this as an update to the existing values to not break addons directly relying on the fields
|
||||
static {
|
||||
POTENCY_INCREASE_PER_TIER = (float) Wizardry.settings.potencyIncreasePerTier;
|
||||
COOLDOWN_REDUCTION_PER_LEVEL = (float) Wizardry.settings.cooldownReductionPerLevel;
|
||||
DURATION_INCREASE_PER_LEVEL = (float) Wizardry.settings.durationIncreasePerLevel;
|
||||
RANGE_INCREASE_PER_LEVEL = (float) Wizardry.settings.rangeIncreasePerLevel;
|
||||
BLAST_RADIUS_INCREASE_PER_LEVEL = (float) Wizardry.settings.blastIncreasePerLevel;
|
||||
RANGE_INCREASE_PER_LEVEL = (float) Wizardry.settings.frostSlownessIncreasePerLevel;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -346,35 +346,48 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
|
||||
|
||||
// For each item in the player's inventory
|
||||
for(ItemStack stack : player.inventory.mainInventory){
|
||||
if(stack.isItemEnchanted()){
|
||||
updateImbutedItem(stack, activeImbuements);
|
||||
}
|
||||
for(ItemStack stack : player.inventory.armorInventory){
|
||||
updateImbutedItem(stack, activeImbuements);
|
||||
}
|
||||
for(ItemStack stack : player.inventory.offHandInventory){
|
||||
updateImbutedItem(stack, activeImbuements);
|
||||
}
|
||||
|
||||
NBTTagList enchantmentList = stack.getItem() == Items.ENCHANTED_BOOK ?
|
||||
ItemEnchantedBook.getEnchantments(stack) : stack.getEnchantmentTagList();
|
||||
// Removes all imbuements from the map that are no longer active
|
||||
this.imbuementDurations.keySet().retainAll(activeImbuements);
|
||||
}
|
||||
|
||||
Iterator<NBTBase> iterator = enchantmentList.iterator();
|
||||
// For each of the item's enchantments
|
||||
while(iterator.hasNext()){
|
||||
NBTTagCompound enchantmentTag = (NBTTagCompound) iterator.next();
|
||||
Enchantment enchantment = Enchantment.getEnchantmentByID(enchantmentTag.getShort("id"));
|
||||
// Ignores the enchantment unless it is an imbuement
|
||||
if(enchantment instanceof Imbuement){
|
||||
int duration = this.getImbuementDuration(enchantment);
|
||||
// If the imbuement is still active:
|
||||
if(duration > 0){
|
||||
// Decrements the timer
|
||||
this.imbuementDurations.put((Imbuement)enchantment, duration - IMBUEMENT_UPDATE_INTERVAL);
|
||||
// Adds this imbuement to the set of imbuements that need to be kept
|
||||
activeImbuements.add((Imbuement)enchantment);
|
||||
}else{
|
||||
// Otherwise, removes the enchantment from the item
|
||||
iterator.remove(); // FIXME: Apparently this can cause a CME
|
||||
}
|
||||
private void updateImbutedItem(ItemStack stack, Set<Imbuement> activeImbuements){
|
||||
|
||||
if(stack.isItemEnchanted()){
|
||||
|
||||
NBTTagList enchantmentList = stack.getItem() == Items.ENCHANTED_BOOK ?
|
||||
ItemEnchantedBook.getEnchantments(stack) : stack.getEnchantmentTagList();
|
||||
|
||||
Iterator<NBTBase> iterator = enchantmentList.iterator();
|
||||
// For each of the item's enchantments
|
||||
while(iterator.hasNext()){
|
||||
NBTTagCompound enchantmentTag = (NBTTagCompound) iterator.next();
|
||||
Enchantment enchantment = Enchantment.getEnchantmentByID(enchantmentTag.getShort("id"));
|
||||
// Ignores the enchantment unless it is an imbuement
|
||||
if(enchantment instanceof Imbuement){
|
||||
int duration = this.getImbuementDuration(enchantment);
|
||||
// If the imbuement is still active:
|
||||
if(duration > 0){
|
||||
// Decrements the timer
|
||||
this.imbuementDurations.put((Imbuement)enchantment, duration - IMBUEMENT_UPDATE_INTERVAL);
|
||||
// Adds this imbuement to the set of imbuements that need to be kept
|
||||
activeImbuements.add((Imbuement)enchantment);
|
||||
}else{
|
||||
// Otherwise, removes the enchantment from the item
|
||||
((Imbuement) enchantment).onImbuementRemoval(stack);
|
||||
iterator.remove(); // FIXME: Apparently this can cause a CME
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Removes all imbuements from the map that are no longer active
|
||||
this.imbuementDurations.keySet().retainAll(activeImbuements);
|
||||
}
|
||||
|
||||
// Ally designation system
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
package electroblob.wizardry.entity.construct;
|
||||
|
||||
import electroblob.wizardry.entity.projectile.EntityConjuredArrow;
|
||||
import electroblob.wizardry.registry.Spells;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
import net.minecraft.entity.projectile.EntityTippedArrow;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
@@ -30,7 +28,7 @@ public class EntityArrowRain extends EntityScaledConstruct {
|
||||
double y = posY + world.rand.nextDouble() * (double)height;
|
||||
double z = posZ + (world.rand.nextDouble() - 0.5D) * (double)width;
|
||||
|
||||
EntityTippedArrow arrow = new EntityTippedArrow(world, x, y, z);
|
||||
EntityConjuredArrow arrow = new EntityConjuredArrow(world, x, y, z);
|
||||
|
||||
arrow.motionX = MathHelper.cos((float)Math.toRadians(this.rotationYaw + 90));
|
||||
arrow.motionY = -0.6;
|
||||
@@ -38,7 +36,6 @@ public class EntityArrowRain extends EntityScaledConstruct {
|
||||
|
||||
arrow.shootingEntity = this.getCaster();
|
||||
arrow.setDamage(7.0d * damageMultiplier);
|
||||
arrow.setPotionEffect(new ItemStack(Items.ARROW));
|
||||
|
||||
this.world.spawnEntity(arrow);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ public class EntityFireRing extends EntityScaledConstruct {
|
||||
|
||||
super.onUpdate();
|
||||
|
||||
if(!this.world.isRemote){
|
||||
if(this.ticksExisted % 5 == 0 && !this.world.isRemote){
|
||||
|
||||
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(width/2, this.posX, this.posY, this.posZ, this.world);
|
||||
|
||||
|
||||
@@ -168,6 +168,10 @@ public class EntityForcefield extends EntityMagicConstruct implements ICustomHit
|
||||
((EntityPlayerMP)target).connection.sendPacket(new SPacketEntityVelocity(target));
|
||||
}
|
||||
|
||||
if (this.ticksExisted % 5 == 0) {
|
||||
this.lifetime = (int) (lifetime * 0.99);
|
||||
}
|
||||
|
||||
}else{
|
||||
|
||||
Vec3d relativeImpactPos = targetRelativePos.normalize().scale(radius);
|
||||
|
||||
@@ -68,13 +68,15 @@ public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntity
|
||||
/** Data parameter for the wizard's element. */
|
||||
private static final DataParameter<Integer> ELEMENT = EntityDataManager.createKey(EntityEvilWizard.class,
|
||||
DataSerializers.VARINT);
|
||||
/** Data parameters for the wizard's current continuous spell. */
|
||||
private static final DataParameter<String> CONTINUOUS_SPELL = EntityDataManager.createKey(EntityEvilWizard.class, DataSerializers.STRING);
|
||||
private static final DataParameter<Integer> SPELL_COUNTER = EntityDataManager.createKey(EntityEvilWizard.class, DataSerializers.VARINT);
|
||||
|
||||
/** The resource location for the evil wizard's loot table. */
|
||||
private static final ResourceLocation LOOT_TABLE = new ResourceLocation(Wizardry.MODID, "entities/evil_wizard");
|
||||
|
||||
// Field implementations
|
||||
private List<Spell> spells = new ArrayList<Spell>(4);
|
||||
private Spell continuousSpell;
|
||||
private int spellCounter;
|
||||
|
||||
public EntityEvilWizard(World world){
|
||||
|
||||
@@ -93,6 +95,8 @@ public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntity
|
||||
super.entityInit();
|
||||
this.dataManager.register(HEAL_COOLDOWN, -1);
|
||||
this.dataManager.register(ELEMENT, -1);
|
||||
this.dataManager.register(CONTINUOUS_SPELL, "ebwizardry:none");
|
||||
this.dataManager.register(SPELL_COUNTER, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -168,23 +172,23 @@ public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntity
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContinuousSpell(Spell spell){
|
||||
this.continuousSpell = spell;
|
||||
public void setContinuousSpell(Spell spell) {
|
||||
this.dataManager.set(CONTINUOUS_SPELL, spell.getRegistryName().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spell getContinuousSpell(){
|
||||
return this.continuousSpell;
|
||||
public Spell getContinuousSpell() {
|
||||
return Spell.get(this.dataManager.get(CONTINUOUS_SPELL));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpellCounter(int count){
|
||||
spellCounter = count;
|
||||
public void setSpellCounter(int count) {
|
||||
this.dataManager.set(SPELL_COUNTER, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSpellCounter(){
|
||||
return spellCounter;
|
||||
public int getSpellCounter() {
|
||||
return this.dataManager.get(SPELL_COUNTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -278,7 +282,8 @@ public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntity
|
||||
@Override
|
||||
public void writeEntityToNBT(NBTTagCompound nbt){
|
||||
super.writeEntityToNBT(nbt);
|
||||
nbt.setInteger("element", this.getElement().ordinal());
|
||||
Element element = this.getElement();
|
||||
nbt.setInteger("element", element == null ? 0 : element.ordinal());
|
||||
nbt.setInteger("skin", this.textureIndex);
|
||||
NBTExtras.storeTagSafely(nbt, "spells", NBTExtras.listToNBT(spells, spell -> new NBTTagInt(spell.metadata())));
|
||||
nbt.setBoolean("hasStructure", this.hasStructure);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
package electroblob.wizardry.entity.living;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.util.ParticleBuilder;
|
||||
import net.minecraft.entity.EntityFlying;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.ai.EntityAIAttackMelee;
|
||||
import net.minecraft.entity.ai.EntityAIHurtByTarget;
|
||||
import net.minecraft.entity.ai.EntityAILookAtVillager;
|
||||
import net.minecraft.entity.ai.EntityAILookIdle;
|
||||
import net.minecraft.entity.ai.EntityAIMoveThroughVillage;
|
||||
import net.minecraft.entity.ai.EntityAIMoveTowardsRestriction;
|
||||
import net.minecraft.entity.ai.EntityAIMoveTowardsTarget;
|
||||
import net.minecraft.entity.ai.EntityAINearestAttackableTarget;
|
||||
import net.minecraft.entity.ai.EntityAIWanderAvoidWater;
|
||||
import net.minecraft.entity.ai.EntityAIWatchClosest;
|
||||
import net.minecraft.entity.monster.EntityIronGolem;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.datasync.DataParameter;
|
||||
import net.minecraft.network.datasync.DataSerializers;
|
||||
import net.minecraft.network.datasync.EntityDataManager;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.EnumParticleTypes;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
import net.minecraft.world.DifficultyInstance;
|
||||
import net.minecraft.world.EnumDifficulty;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class EntitySpectralGolem extends EntityIronGolem implements ISummonedCreature {
|
||||
|
||||
private static final DataParameter<Boolean> SPAWN_PARTICLES = EntityDataManager.createKey(EntitySpectralGolem.class, DataSerializers.BOOLEAN);
|
||||
|
||||
// Field implementations
|
||||
private int lifetime = -1;
|
||||
private UUID casterUUID;
|
||||
|
||||
// Setter + getter implementations
|
||||
@Override public int getLifetime(){ return lifetime; }
|
||||
@Override public void setLifetime(int lifetime){ this.lifetime = lifetime; }
|
||||
@Override public UUID getOwnerId(){ return casterUUID; }
|
||||
@Override public void setOwnerId(UUID uuid){ this.casterUUID = uuid; }
|
||||
|
||||
/** Creates a new golem minion in the given world. */
|
||||
public EntitySpectralGolem(World world){
|
||||
super(world);
|
||||
this.experienceValue = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void entityInit(){
|
||||
super.entityInit();
|
||||
this.dataManager.register(SPAWN_PARTICLES, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initEntityAI() {
|
||||
this.tasks.addTask(1, new EntityAIAttackMelee(this, 1.0D, true));
|
||||
this.tasks.addTask(2, new EntityAIMoveTowardsTarget(this, 0.9D, 32.0F));
|
||||
this.tasks.addTask(3, new EntityAIMoveThroughVillage(this, 0.6D, true));
|
||||
this.tasks.addTask(4, new EntityAIMoveTowardsRestriction(this, 1.0D));
|
||||
this.tasks.addTask(5, new EntityAILookAtVillager(this));
|
||||
this.tasks.addTask(6, new EntityAIWanderAvoidWater(this, 0.6D));
|
||||
this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F));
|
||||
this.tasks.addTask(8, new EntityAILookIdle(this));
|
||||
this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false));
|
||||
this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityLivingBase.class,
|
||||
0, false, true, this.getTargetSelector()));
|
||||
}
|
||||
|
||||
@Override protected void setEquipmentBasedOnDifficulty(DifficultyInstance difficulty){} // They don't have equipment!
|
||||
|
||||
// Implementations
|
||||
|
||||
@Override
|
||||
public void setRevengeTarget(EntityLivingBase entity){
|
||||
if(this.shouldRevengeTarget(entity)) super.setRevengeTarget(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(){
|
||||
super.onUpdate();
|
||||
this.updateDelegate();
|
||||
|
||||
// Adds a dust particle effect
|
||||
if(this.world.isRemote){
|
||||
double x = this.posX - this.width / 2 + this.rand.nextFloat() * width;
|
||||
double y = this.posY + this.height * this.rand.nextFloat() + 0.2f;
|
||||
double z = this.posZ - this.width / 2 + this.rand.nextFloat() * width;
|
||||
ParticleBuilder.create(ParticleBuilder.Type.DUST).pos(x, y, z).clr(0.7f, 0.9f, 1).shaded(true).spawn(world);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpawn(){
|
||||
if(this.dataManager.get(SPAWN_PARTICLES)) this.spawnParticleEffect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDespawn(){
|
||||
this.spawnParticleEffect();
|
||||
}
|
||||
|
||||
private void spawnParticleEffect(){
|
||||
if(this.world.isRemote){
|
||||
for(int i = 0; i < 15; i++){
|
||||
this.world.spawnParticle(EnumParticleTypes.SMOKE_LARGE, this.posX + this.rand.nextFloat() - 0.5f,
|
||||
this.posY + this.rand.nextFloat() * 2, this.posZ + this.rand.nextFloat() - 0.5f, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasParticleEffect(){
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAnimation(){
|
||||
return this.dataManager.get(SPAWN_PARTICLES) || this.ticksExisted > 20;
|
||||
}
|
||||
|
||||
public void hideParticles(){
|
||||
this.dataManager.set(SPAWN_PARTICLES, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean processInteract(EntityPlayer player, EnumHand hand){
|
||||
// In this case, the delegate method determines whether super is called.
|
||||
// Rather handily, we can make use of Java's short-circuiting method of evaluating OR statements.
|
||||
return this.interactDelegate(player, hand) || super.processInteract(player, hand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeEntityToNBT(NBTTagCompound nbttagcompound){
|
||||
super.writeEntityToNBT(nbttagcompound);
|
||||
this.writeNBTDelegate(nbttagcompound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readEntityFromNBT(NBTTagCompound nbttagcompound){
|
||||
super.readEntityFromNBT(nbttagcompound);
|
||||
this.readNBTDelegate(nbttagcompound);
|
||||
}
|
||||
|
||||
// Recommended overrides
|
||||
|
||||
@Override protected int getExperiencePoints(EntityPlayer player){ return 0; }
|
||||
@Override protected boolean canDropLoot(){ return false; }
|
||||
@Override protected Item getDropItem(){ return null; }
|
||||
@Override protected ResourceLocation getLootTable(){ return null; }
|
||||
@Override public boolean canPickUpLoot(){ return false; }
|
||||
|
||||
// This vanilla method has nothing to do with the custom despawn() method.
|
||||
@Override protected boolean canDespawn(){
|
||||
return getCaster() == null && getOwnerId() == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getCanSpawnHere(){
|
||||
return this.world.getDifficulty() != EnumDifficulty.PEACEFUL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAttackClass(Class<? extends EntityLivingBase> entityType){
|
||||
// Returns true unless the given entity type is a flying entity.
|
||||
return !EntityFlying.class.isAssignableFrom(entityType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITextComponent getDisplayName(){
|
||||
if(getCaster() != null){
|
||||
return new TextComponentTranslation(NAMEPLATE_TRANSLATION_KEY, getCaster().getName(),
|
||||
new TextComponentTranslation("entity." + this.getEntityString() + ".name"));
|
||||
}else{
|
||||
return super.getDisplayName();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCustomName(){
|
||||
// If this returns true, the renderer will show the nameplate when looking directly at the entity
|
||||
return Wizardry.settings.summonedCreatureNames && getCaster() != null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -47,6 +47,7 @@ import net.minecraftforge.common.util.FakePlayer;
|
||||
import net.minecraftforge.event.world.BlockEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.registry.ForgeRegistries;
|
||||
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
@@ -81,11 +82,12 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
private static final DataParameter<Integer> HEAL_COOLDOWN = EntityDataManager.createKey(EntityWizard.class, DataSerializers.VARINT);
|
||||
/** Data parameter for the wizard's element. */
|
||||
private static final DataParameter<Integer> ELEMENT = EntityDataManager.createKey(EntityWizard.class, DataSerializers.VARINT);
|
||||
/** Data parameters for the wizard's current continuous spell. */
|
||||
private static final DataParameter<String> CONTINUOUS_SPELL = EntityDataManager.createKey(EntityWizard.class, DataSerializers.STRING);
|
||||
private static final DataParameter<Integer> SPELL_COUNTER = EntityDataManager.createKey(EntityWizard.class, DataSerializers.VARINT);
|
||||
|
||||
// Field implementations
|
||||
private List<Spell> spells = new ArrayList<Spell>(4);
|
||||
private Spell continuousSpell;
|
||||
private int spellCounter;
|
||||
|
||||
/** A set of the positions of the blocks that are part of this wizard's tower. */
|
||||
private Set<BlockPos> towerBlocks;
|
||||
@@ -102,6 +104,8 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
super.entityInit();
|
||||
this.dataManager.register(HEAL_COOLDOWN, -1);
|
||||
this.dataManager.register(ELEMENT, 0);
|
||||
this.dataManager.register(CONTINUOUS_SPELL, "ebwizardry:none");
|
||||
this.dataManager.register(SPELL_COUNTER, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -182,23 +186,23 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContinuousSpell(Spell spell){
|
||||
this.continuousSpell = spell;
|
||||
public void setContinuousSpell(Spell spell) {
|
||||
this.dataManager.set(CONTINUOUS_SPELL, spell.getRegistryName().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spell getContinuousSpell(){
|
||||
return this.continuousSpell;
|
||||
public Spell getContinuousSpell() {
|
||||
return Spell.get(this.dataManager.get(CONTINUOUS_SPELL));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpellCounter(int count){
|
||||
spellCounter = count;
|
||||
public void setSpellCounter(int count) {
|
||||
this.dataManager.set(SPELL_COUNTER, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSpellCounter(){
|
||||
return spellCounter;
|
||||
public int getSpellCounter() {
|
||||
return this.dataManager.get(SPELL_COUNTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -404,7 +408,8 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
NBTExtras.storeTagSafely(nbt, "trades", this.trades.getRecipiesAsTags());
|
||||
}
|
||||
|
||||
nbt.setInteger("element", this.getElement().ordinal());
|
||||
Element element = this.getElement();
|
||||
nbt.setInteger("element", element == null ? 0 : element.ordinal());
|
||||
nbt.setInteger("skin", this.textureIndex);
|
||||
NBTExtras.storeTagSafely(nbt, "spells", NBTExtras.listToNBT(spells, spell -> new NBTTagInt(spell.metadata())));
|
||||
|
||||
@@ -633,10 +638,9 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0 && !specialismSpells.isEmpty()){
|
||||
// This means it is more likely for spell books sold to be of the same element as the wizard if the
|
||||
// wizard has an element.
|
||||
return new ItemStack(WizardryItems.spell_book, 1,
|
||||
specialismSpells.get(rand.nextInt(specialismSpells.size())).metadata());
|
||||
return getBookStackForSpell(specialismSpells.get(rand.nextInt(specialismSpells.size())));
|
||||
}else{
|
||||
return new ItemStack(WizardryItems.spell_book, 1, spells.get(rand.nextInt(spells.size())).metadata());
|
||||
return getBookStackForSpell(spells.get(rand.nextInt(spells.size())));
|
||||
}
|
||||
}else{
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0){
|
||||
@@ -655,10 +659,9 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0 && !specialismSpells.isEmpty()){
|
||||
// This means it is more likely for spell books sold to be of the same element as the wizard if the
|
||||
// wizard has an element.
|
||||
return new ItemStack(WizardryItems.spell_book, 1,
|
||||
specialismSpells.get(rand.nextInt(specialismSpells.size())).metadata());
|
||||
return getBookStackForSpell(specialismSpells.get(rand.nextInt(specialismSpells.size())));
|
||||
}else{
|
||||
return new ItemStack(WizardryItems.spell_book, 1, spells.get(rand.nextInt(spells.size())).metadata());
|
||||
return getBookStackForSpell(spells.get(rand.nextInt(spells.size())));
|
||||
}
|
||||
}else if(randomiser < 6){
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0){
|
||||
@@ -692,10 +695,9 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0 && !specialismSpells.isEmpty()){
|
||||
// This means it is more likely for spell books sold to be of the same element as the wizard if the
|
||||
// wizard has an element.
|
||||
return new ItemStack(WizardryItems.spell_book, 1,
|
||||
specialismSpells.get(rand.nextInt(specialismSpells.size())).metadata());
|
||||
return getBookStackForSpell(specialismSpells.get(rand.nextInt(specialismSpells.size())));
|
||||
}else{
|
||||
return new ItemStack(WizardryItems.spell_book, 1, spells.get(rand.nextInt(spells.size())).metadata());
|
||||
return getBookStackForSpell(spells.get(rand.nextInt(spells.size())));
|
||||
}
|
||||
}else if(randomiser < 6){
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0){
|
||||
@@ -720,8 +722,7 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
|
||||
if(randomiser < 5 && this.getElement() != Element.MAGIC && !specialismSpells.isEmpty()){
|
||||
// Master spells can only be sold by a specialist in that element.
|
||||
return new ItemStack(WizardryItems.spell_book, 1,
|
||||
specialismSpells.get(rand.nextInt(specialismSpells.size())).metadata());
|
||||
return getBookStackForSpell(specialismSpells.get(rand.nextInt(specialismSpells.size())));
|
||||
|
||||
}else if(randomiser < 6){
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0){
|
||||
@@ -797,7 +798,6 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
Tier maxTier = Tier.NOVICE;
|
||||
|
||||
List<Spell> npcSpells = Spell.getSpells(s -> s.canBeCastBy(wizard, false));
|
||||
npcSpells.removeIf(s -> !s.applicableForItem(WizardryItems.spell_book));
|
||||
|
||||
for(int i = 0; i < n; i++){
|
||||
|
||||
@@ -845,6 +845,22 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
return maxTier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to handle addon spell books.
|
||||
* @param spell the spell to look up.
|
||||
* @return Checks all items of the spell's namespace (modid) if they are applicable for the spell and returns the first match, or falls back to WizardryItems.spell_book if no match was found.
|
||||
*/
|
||||
public static ItemStack getBookStackForSpell(Spell spell) {
|
||||
String modid = spell.getRegistryName().getNamespace();
|
||||
if (modid.equals(Wizardry.MODID)) {
|
||||
return new ItemStack(WizardryItems.spell_book, 1, spell.metadata());
|
||||
}
|
||||
Optional<Item> firstMatch = ForgeRegistries.ITEMS.getValuesCollection().stream().filter(v -> v instanceof ItemSpellBook && spell.applicableForItem(v)
|
||||
&& v.getRegistryName().getNamespace().equals(modid)).findFirst();
|
||||
|
||||
return firstMatch.map(item -> new ItemStack(item, 1, spell.metadata())).orElseGet(() -> new ItemStack(WizardryItems.spell_book, 1, spell.metadata()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSpawnData(ByteBuf data){
|
||||
data.writeInt(textureIndex);
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package electroblob.wizardry.entity.projectile;
|
||||
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.projectile.EntityArrow;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class EntityConjuredArrow extends EntityArrow {
|
||||
|
||||
public EntityConjuredArrow(World worldIn) {
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
public EntityConjuredArrow(World worldIn, double x, double y, double z) {
|
||||
super(worldIn, x, y, z);
|
||||
}
|
||||
|
||||
public EntityConjuredArrow(World worldIn, EntityLivingBase shooter) {
|
||||
super(worldIn, shooter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate() {
|
||||
super.onUpdate();
|
||||
if (this.timeInGround > 400) {
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemStack getArrowStack() {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
}
|
||||
@@ -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,45 @@
|
||||
package electroblob.wizardry.event;
|
||||
|
||||
import electroblob.wizardry.item.ItemArtefact;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||
import net.minecraftforge.fml.common.eventhandler.Cancelable;
|
||||
import net.minecraftforge.fml.common.eventhandler.Event;
|
||||
|
||||
/**
|
||||
* SpellBindEvent is fired when a check happens for an ItemArtefact using {@link electroblob.wizardry.item.ItemArtefact#isArtefactActive(net.minecraft.entity.player.EntityPlayer, net.minecraft.item.Item)}
|
||||
* <i>Fired on both sides.</i><br>
|
||||
* <br>
|
||||
* This event is {@link Cancelable}. <br>
|
||||
* <br>
|
||||
* This event has a result. {@link HasResult}. Set the result to Result.ALLOW to consider an artefact "active"<br>
|
||||
* <br>
|
||||
* This event is fired on the {@link MinecraftForge#EVENT_BUS}.
|
||||
*
|
||||
* @author WinDanesz
|
||||
* @since Wizardry 4.3.10
|
||||
*/
|
||||
@Cancelable
|
||||
@Event.HasResult
|
||||
public class ArtefactCheckEvent extends PlayerEvent {
|
||||
|
||||
ItemArtefact artefact;
|
||||
EntityPlayer player;
|
||||
|
||||
public ArtefactCheckEvent(EntityPlayer player, ItemArtefact artefact) {
|
||||
super(player);
|
||||
this.player = player;
|
||||
this.artefact = artefact;
|
||||
setResult(Result.DENY);
|
||||
}
|
||||
|
||||
public ItemArtefact getArtefact() {
|
||||
return artefact;
|
||||
}
|
||||
|
||||
public EntityPlayer getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package electroblob.wizardry.event;
|
||||
|
||||
import electroblob.wizardry.constants.Element;
|
||||
import electroblob.wizardry.tileentity.TileEntityImbuementAltar;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.fml.common.eventhandler.Cancelable;
|
||||
import net.minecraftforge.fml.common.eventhandler.Event;
|
||||
|
||||
/**
|
||||
* ImbuementActivateEvent is fired when {@link TileEntityImbuementAltar#getImbuementResult(net.minecraft.item.ItemStack, electroblob.wizardry.constants.Element[],
|
||||
* boolean, net.minecraft.world.World, net.minecraft.entity.player.EntityPlayer)} is called to allow adding in imbuement "recipes" dynamically, based on the
|
||||
* contents of the Imbuement altar's receptacles and the item placed on the altar.
|
||||
*
|
||||
* <i>Note that this event is only fired on the server side.</i><br>
|
||||
* <br>
|
||||
* To alter the result of the imbuement process, change the {@link electroblob.wizardry.event.ImbuementActivateEvent#result} result of the process.<br>
|
||||
* <br>
|
||||
* This event is {@link Cancelable}. If this event is canceled, no further processing takes place.<br>
|
||||
* <br>
|
||||
* This event does not have a result. {@link Event.HasResult}<br>
|
||||
* <br>
|
||||
* This event is fired on the {@link MinecraftForge#EVENT_BUS}.
|
||||
*
|
||||
* @author WinDanesz
|
||||
* @since Wizardry 4.3.5
|
||||
*/
|
||||
@Cancelable
|
||||
public class ImbuementActivateEvent extends Event {
|
||||
|
||||
/** The item stack being imbued */
|
||||
public ItemStack input;
|
||||
|
||||
/** The elements of the four receptacles */
|
||||
public Element[] receptacleElements;
|
||||
|
||||
/** A reference to the current world object (may be null if {@code fullLootGen} is false) */
|
||||
public World world;
|
||||
|
||||
/** The player that last interacted with the imbuement altar, or null if there isn't one (or if this is being queried for other reasons, e.g. JEI) */
|
||||
public EntityPlayer lastUser;
|
||||
|
||||
/** The resulting item stack of the imbuement process */
|
||||
public ItemStack result;
|
||||
|
||||
public ImbuementActivateEvent(ItemStack input, Element[] receptacleElements, World world, EntityPlayer lastUser, ItemStack result) {
|
||||
super();
|
||||
this.input = input;
|
||||
this.receptacleElements = receptacleElements;
|
||||
this.world = world;
|
||||
this.lastUser = lastUser;
|
||||
this.result = result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package electroblob.wizardry.event;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||
import net.minecraftforge.fml.common.eventhandler.Cancelable;
|
||||
|
||||
/**
|
||||
* ResurrectionEvent is fired when a player is about to be resurrected, after all other checks have been performed.
|
||||
* <i>Note that this event is only fired on the server side.</i><br>
|
||||
* <br>
|
||||
* This event is {@link Cancelable}. If this event is canceled, the player is not resurrected.<br>
|
||||
* <br>
|
||||
* This event does not have a result. {@link HasResult}<br>
|
||||
* <br>
|
||||
* This event is fired on the {@link MinecraftForge#EVENT_BUS}.
|
||||
*
|
||||
* @author Electroblob
|
||||
* @since Wizardry 2.1
|
||||
*/
|
||||
@Cancelable
|
||||
public class ResurrectionEvent extends PlayerEvent {
|
||||
|
||||
private final EntityPlayer caster;
|
||||
|
||||
public ResurrectionEvent(EntityPlayer player, EntityPlayer caster){
|
||||
super(player);
|
||||
this.caster = caster;
|
||||
}
|
||||
|
||||
/** Returns the player that cast the resurrection spell. If the player resurrected themselves, this will be the
|
||||
* same as {@link ResurrectionEvent#getEntityPlayer()}. */
|
||||
public EntityPlayer getCaster(){
|
||||
return caster;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -46,6 +46,10 @@ public final class WizardryBaublesIntegration {
|
||||
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.RING, BaubleType.RING);
|
||||
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.AMULET, BaubleType.AMULET);
|
||||
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.CHARM, BaubleType.CHARM);
|
||||
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.BELT, BaubleType.BELT);
|
||||
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.BODY, BaubleType.BODY);
|
||||
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.HEAD, BaubleType.HEAD);
|
||||
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.TRINKET, BaubleType.TRINKET);
|
||||
}
|
||||
|
||||
public static boolean enabled(){
|
||||
|
||||
@@ -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());
|
||||
@@ -450,6 +452,24 @@ public class ContainerArcaneWorkbench extends Container implements ISpellSortabl
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called (via {@link electroblob.wizardry.packet.PacketControlInput PacketControlInput}) when the clear button in
|
||||
* the arcane workbench GUI is pressed.
|
||||
*/
|
||||
// As of 2.1, for the sake of events and neatness of code, this was moved here from TileEntityArcaneWorkbench.
|
||||
// As of 4.2, the spell binding/charging/upgrading code was delegated (via IWorkbenchItem) to the items themselves.
|
||||
public void onClearButtonPressed(EntityPlayer player){
|
||||
|
||||
Slot centre = this.getSlot(CENTRE_SLOT);
|
||||
|
||||
if(centre.getStack().getItem() instanceof IWorkbenchItem){ // Should always be true, but no harm in checking.
|
||||
|
||||
Slot[] spellBooks = this.inventorySlots.subList(0, 8).toArray(new Slot[8]);
|
||||
|
||||
((IWorkbenchItem) centre.getStack().getItem()).onClearButtonPressed(player, centre, this.getSlot(CRYSTAL_SLOT), this.getSlot(UPGRADE_SLOT), spellBooks);
|
||||
}
|
||||
}
|
||||
|
||||
/** Scrolls to the given row number. */
|
||||
public void scrollTo(int row){
|
||||
this.scroll = row;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -55,6 +55,26 @@ public interface IWorkbenchItem {
|
||||
*/
|
||||
boolean onApplyButtonPressed(EntityPlayer player, Slot centre, Slot crystals, Slot upgrade, Slot[] spellBooks);
|
||||
|
||||
/**
|
||||
* Called when this item is in the central slot of an arcane workbench and the apply clear is pressed. Items must
|
||||
* implement this method to define what happens when the apply button is pressed.
|
||||
* @param player The player that pressed the apply button.
|
||||
* @param centre The central slot in the arcane workbench. This slot will always contain a stack of the implementing
|
||||
* item, or in other words, <i>it is guaranteed that</i> {@code this == centre.getStack().getItem()}.
|
||||
* @param crystals The magic crystal slot of the arcane workbench.
|
||||
* @param upgrade The upgrade slot of the arcane workbench.
|
||||
* @param spellBooks An array of the <i>active</i> (visible) spell book slots in the arcane workbench. The length of
|
||||
* the array will be equal to the value returned by {@link IWorkbenchItem#getSpellSlotCount(ItemStack)}.
|
||||
* */
|
||||
default void onClearButtonPressed(EntityPlayer player, Slot centre, Slot crystals, Slot upgrade, Slot[] spellBooks){};
|
||||
|
||||
/**
|
||||
* Must be overridden in the item class to make the clear button in the Arcane Workbench clickable.
|
||||
* */
|
||||
default boolean isClearable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the tooltip (dark grey box) should be drawn when this item is in an arcane workbench. Only
|
||||
* called client-side.
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import electroblob.wizardry.entity.living.ISummonedCreature;
|
||||
import electroblob.wizardry.entity.projectile.EntityDart;
|
||||
import electroblob.wizardry.entity.projectile.EntityForceOrb;
|
||||
import electroblob.wizardry.entity.projectile.EntityIceShard;
|
||||
import electroblob.wizardry.event.ArtefactCheckEvent;
|
||||
import electroblob.wizardry.event.SpellCastEvent;
|
||||
import electroblob.wizardry.event.SpellCastEvent.Source;
|
||||
import electroblob.wizardry.integration.DamageSafetyChecker;
|
||||
@@ -37,6 +38,7 @@ import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraftforge.common.BiomeDictionary;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.common.capabilities.ICapabilityProvider;
|
||||
import net.minecraftforge.event.entity.living.LivingDeathEvent;
|
||||
import net.minecraftforge.event.entity.living.LivingEvent;
|
||||
@@ -88,7 +90,11 @@ public class ItemArtefact extends Item {
|
||||
|
||||
/** An artefact that improves attacking spells. Two of these can be active at any one time. */ RING(2),
|
||||
/** An artefact that improves defensive spells. One of these can be active at any one time. */ AMULET(1),
|
||||
/** An artefact that improves utility spells. One of these can be active at any one time. */ CHARM(1);
|
||||
/** An artefact that improves utility spells. One of these can be active at any one time. */ CHARM(1),
|
||||
/** Added for add-on artefacts. */ BELT(1),
|
||||
/** Added for add-on artefacts. */ BODY(1),
|
||||
/** Added for add-on artefacts. */ HEAD(1),
|
||||
/** Added for add-on artefacts. */ TRINKET(1);
|
||||
|
||||
public final int maxAtOnce;
|
||||
|
||||
@@ -123,6 +129,8 @@ public class ItemArtefact extends Item {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isEnabled() { return enabled; }
|
||||
|
||||
@Override
|
||||
public EnumRarity getRarity(ItemStack stack){
|
||||
return rarity;
|
||||
@@ -176,6 +184,13 @@ public class ItemArtefact extends Item {
|
||||
|
||||
if(!((ItemArtefact)artefact).enabled) return false; // Disabled in the config
|
||||
|
||||
ArtefactCheckEvent event = new ArtefactCheckEvent(player, (ItemArtefact) artefact);
|
||||
if(MinecraftForge.EVENT_BUS.post(event)) return false;
|
||||
|
||||
if (event.getResult() == Event.Result.ALLOW) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(WizardryBaublesIntegration.enabled()){
|
||||
return WizardryBaublesIntegration.isBaubleEquipped(player, artefact);
|
||||
}else{
|
||||
@@ -344,6 +359,8 @@ public class ItemArtefact extends Item {
|
||||
|
||||
findMatchingWandAndExecute(player, Spells.shield, wand -> {
|
||||
|
||||
if(wand.getItem() instanceof ItemScroll) return; // Ignore scrolls since they shouldn't work
|
||||
|
||||
List<Entity> projectiles = EntityUtils.getEntitiesWithinRadius(5, player.posX, player.posY, player.posZ, world, Entity.class);
|
||||
projectiles.removeIf(e -> !(e instanceof IProjectile));
|
||||
Vec3d look = player.getLookVec();
|
||||
@@ -765,6 +782,7 @@ public class ItemArtefact extends Item {
|
||||
&& Streams.stream(player.getHeldEquipment()).anyMatch(s -> s.getItem() instanceof ISpellCastingItem
|
||||
&& ((ISpellCastingItem)s.getItem()).getCurrentSpell(s).getElement() == Element.NECROMANCY))){
|
||||
|
||||
event.getEntityLiving().addPotionEffect(new PotionEffect(WizardryPotions.curse_of_soulbinding, 400));
|
||||
CurseOfSoulbinding.getSoulboundCreatures(WizardData.get(player)).add(event.getEntity().getUniqueID());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package electroblob.wizardry.item;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.client.DrawingUtils;
|
||||
import electroblob.wizardry.entity.projectile.EntityFlamecatcherArrow;
|
||||
import electroblob.wizardry.registry.Spells;
|
||||
import electroblob.wizardry.registry.WizardrySounds;
|
||||
import electroblob.wizardry.spell.Flamecatcher;
|
||||
import electroblob.wizardry.util.InventoryUtils;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
@@ -111,7 +111,7 @@ public class ItemFlamecatcher extends ItemBow implements IConjuredItem {
|
||||
@Override
|
||||
public void onUpdate(ItemStack stack, World world, Entity entity, int slot, boolean selected){
|
||||
int damage = stack.getItemDamage();
|
||||
if(damage > stack.getMaxDamage()) entity.replaceItemInInventory(slot, ItemStack.EMPTY);
|
||||
if(damage > stack.getMaxDamage()) InventoryUtils.replaceItemInInventory(entity, slot, stack, ItemStack.EMPTY);
|
||||
stack.setItemDamage(damage + 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.google.common.collect.Multimap;
|
||||
import electroblob.wizardry.registry.Spells;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
import electroblob.wizardry.util.EntityUtils;
|
||||
import electroblob.wizardry.util.InventoryUtils;
|
||||
import electroblob.wizardry.util.MagicDamage;
|
||||
import electroblob.wizardry.util.MagicDamage.DamageType;
|
||||
import net.minecraft.entity.Entity;
|
||||
@@ -81,7 +82,7 @@ public class ItemFlamingAxe extends ItemAxe implements IConjuredItem {
|
||||
@Override
|
||||
public void onUpdate(ItemStack stack, World world, Entity entity, int slot, boolean selected){
|
||||
int damage = stack.getItemDamage();
|
||||
if(damage > stack.getMaxDamage()) entity.replaceItemInInventory(slot, ItemStack.EMPTY);
|
||||
if(damage > stack.getMaxDamage()) InventoryUtils.replaceItemInInventory(entity, slot, stack, ItemStack.EMPTY);
|
||||
stack.setItemDamage(damage + 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import electroblob.wizardry.registry.Spells;
|
||||
import electroblob.wizardry.registry.WizardryPotions;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
import electroblob.wizardry.util.EntityUtils;
|
||||
import electroblob.wizardry.util.InventoryUtils;
|
||||
import electroblob.wizardry.util.MagicDamage;
|
||||
import electroblob.wizardry.util.MagicDamage.DamageType;
|
||||
import net.minecraft.entity.Entity;
|
||||
@@ -83,7 +84,7 @@ public class ItemFrostAxe extends ItemAxe implements IConjuredItem {
|
||||
@Override
|
||||
public void onUpdate(ItemStack stack, World world, Entity entity, int slot, boolean selected){
|
||||
int damage = stack.getItemDamage();
|
||||
if(damage > stack.getMaxDamage()) entity.replaceItemInInventory(slot, ItemStack.EMPTY);
|
||||
if(damage > stack.getMaxDamage()) InventoryUtils.replaceItemInInventory(entity, slot, stack, ItemStack.EMPTY);
|
||||
stack.setItemDamage(damage + 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import electroblob.wizardry.registry.WizardrySounds;
|
||||
import electroblob.wizardry.spell.LightningHammer;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
import electroblob.wizardry.util.EntityUtils;
|
||||
import electroblob.wizardry.util.InventoryUtils;
|
||||
import electroblob.wizardry.util.MagicDamage;
|
||||
import electroblob.wizardry.util.MagicDamage.DamageType;
|
||||
import electroblob.wizardry.util.ParticleBuilder;
|
||||
@@ -112,7 +113,7 @@ public class ItemLightningHammer extends Item implements IConjuredItem {
|
||||
@Override
|
||||
public void onUpdate(ItemStack stack, World world, Entity entity, int slot, boolean selected){
|
||||
int damage = stack.getItemDamage();
|
||||
if(damage > stack.getMaxDamage()) entity.replaceItemInInventory(slot, ItemStack.EMPTY);
|
||||
if(damage > stack.getMaxDamage()) InventoryUtils.replaceItemInInventory(entity, slot, stack, ItemStack.EMPTY);
|
||||
stack.setItemDamage(damage + 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -230,7 +244,7 @@ public class ItemScroll extends Item implements ISpellCastingItem, IWorkbenchIte
|
||||
MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Finish(Source.SCROLL, spell, user, modifiers, castingTick));
|
||||
spell.finishCasting(user.world, user, Double.NaN, Double.NaN, Double.NaN, null, castingTick, modifiers);
|
||||
|
||||
if(user instanceof EntityPlayer){
|
||||
if(user instanceof EntityPlayer && !((EntityPlayer)user).isCreative()){
|
||||
((EntityPlayer)user).getCooldownTracker().setCooldown(this, spell.getCooldown());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package electroblob.wizardry.item;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.entity.projectile.EntityConjuredArrow;
|
||||
import electroblob.wizardry.registry.Spells;
|
||||
import electroblob.wizardry.util.InventoryUtils;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
@@ -13,6 +15,7 @@ import net.minecraft.init.SoundEvents;
|
||||
import net.minecraft.item.IItemPropertyGetter;
|
||||
import net.minecraft.item.ItemArrow;
|
||||
import net.minecraft.item.ItemBow;
|
||||
import net.minecraft.item.ItemSpectralArrow;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.stats.StatList;
|
||||
import net.minecraft.util.*;
|
||||
@@ -105,7 +108,7 @@ public class ItemSpectralBow extends ItemBow implements IConjuredItem {
|
||||
@Override
|
||||
public void onUpdate(ItemStack stack, World world, Entity entity, int slot, boolean selected){
|
||||
int damage = stack.getItemDamage();
|
||||
if(damage > stack.getMaxDamage()) entity.replaceItemInInventory(slot, ItemStack.EMPTY);
|
||||
if(damage > stack.getMaxDamage()) InventoryUtils.replaceItemInInventory(entity, slot, stack, ItemStack.EMPTY);
|
||||
stack.setItemDamage(damage + 1);
|
||||
}
|
||||
|
||||
@@ -196,8 +199,7 @@ public class ItemSpectralBow extends ItemBow implements IConjuredItem {
|
||||
|
||||
if(!world.isRemote){
|
||||
|
||||
ItemArrow itemarrow = (ItemArrow)Items.ARROW;
|
||||
EntityArrow entityarrow = itemarrow.createArrow(world, new ItemStack(itemarrow), entityplayer);
|
||||
EntityConjuredArrow entityarrow = new EntityConjuredArrow(world, entityplayer);
|
||||
entityarrow.shoot(entityplayer, entityplayer.rotationPitch, entityplayer.rotationYaw, 0.0F,
|
||||
f * 3.0F, 1.0F);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package electroblob.wizardry.item;
|
||||
|
||||
import electroblob.wizardry.registry.Spells;
|
||||
import electroblob.wizardry.util.InventoryUtils;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
@@ -62,7 +63,7 @@ public class ItemSpectralPickaxe extends ItemPickaxe implements IConjuredItem {
|
||||
@Override
|
||||
public void onUpdate(ItemStack stack, World world, Entity entity, int slot, boolean selected){
|
||||
int damage = stack.getItemDamage();
|
||||
if(damage > stack.getMaxDamage()) entity.replaceItemInInventory(slot, ItemStack.EMPTY);
|
||||
if(damage > stack.getMaxDamage()) InventoryUtils.replaceItemInInventory(entity, slot, stack, ItemStack.EMPTY);
|
||||
stack.setItemDamage(damage + 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package electroblob.wizardry.item;
|
||||
import com.google.common.collect.Multimap;
|
||||
import electroblob.wizardry.registry.Spells;
|
||||
import electroblob.wizardry.util.EntityUtils;
|
||||
import electroblob.wizardry.util.InventoryUtils;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.entity.ai.attributes.AttributeModifier;
|
||||
@@ -77,7 +78,7 @@ public class ItemSpectralSword extends ItemSword implements IConjuredItem {
|
||||
@Override
|
||||
public void onUpdate(ItemStack stack, World world, Entity entity, int slot, boolean selected){
|
||||
int damage = stack.getItemDamage();
|
||||
if(damage > stack.getMaxDamage()) entity.replaceItemInInventory(slot, ItemStack.EMPTY);
|
||||
if(damage > stack.getMaxDamage()) InventoryUtils.replaceItemInInventory(entity, slot, stack, ItemStack.EMPTY);
|
||||
stack.setItemDamage(damage + 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,10 +12,15 @@ import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.*;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.EnumActionResult;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.text.Style;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
@@ -96,6 +101,13 @@ public class ItemSpellBook extends Item {
|
||||
tooltip.add(spell.getElement().getDisplayName());
|
||||
tooltip.add(spell.getType().getDisplayName());
|
||||
}
|
||||
// Advanced tooltips displays the source mod's name if the spell is not from Wizardry
|
||||
if (advanced.isAdvanced() && this.getRegistryName().toString().equals(Wizardry.MODID + ":spell_book") && !spell.getRegistryName().getNamespace().equals(Wizardry.MODID)) {
|
||||
String modId = spell.getRegistryName().getNamespace();
|
||||
String name = new Style().setColor(TextFormatting.BLUE).setItalic(true).getFormattingCode() +
|
||||
Loader.instance().getIndexedModList().get(modId).getMetadata().name;
|
||||
tooltip.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.EnumAction;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.*;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
@@ -45,6 +46,7 @@ import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
@@ -101,7 +103,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);
|
||||
@@ -226,9 +228,15 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(ItemStack stack, World world, Entity entity, int slot, boolean isHeld){
|
||||
public void onUpdate(ItemStack stack, World world, Entity entity, int slot, boolean isHeldInMainhand){
|
||||
boolean isHeld = isHeldInMainhand || entity instanceof EntityLivingBase && ItemStack.areItemStacksEqual(stack, ((EntityLivingBase) entity).getHeldItemOffhand());
|
||||
|
||||
WandHelper.decrementCooldowns(stack);
|
||||
// If Wizardry.settings.wandsMustBeHeldToDecrementCooldown is false, the cooldowns will be decremented.
|
||||
// If Wizardry.settings.wandsMustBeHeldToDecrementCooldown is true and isHeld is true, the cooldowns will also be decremented.
|
||||
// If Wizardry.settings.wandsMustBeHeldToDecrementCooldown is true and isHeld is false, the cooldowns will not be decremented.
|
||||
if (!Wizardry.settings.wandsMustBeHeldToDecrementCooldown || isHeld) {
|
||||
WandHelper.decrementCooldowns(stack);
|
||||
}
|
||||
|
||||
// Decrements wand damage (increases mana) every 1.5 seconds if it has a condenser upgrade
|
||||
if(!world.isRemote && !this.isManaFull(stack) && world.getTotalWorldTime() % Constants.CONDENSER_TICK_INTERVAL == 0){
|
||||
@@ -709,7 +717,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 +791,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 +823,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.
|
||||
@@ -812,8 +844,19 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
|
||||
Spell spell = Spell.byMetadata(spellBooks[i].getStack().getItemDamage());
|
||||
// If the wand is powerful enough for the spell, it's not already bound to that slot and it's enabled for wands
|
||||
if(!(spell.getTier().level > this.tier.level) && spells[i] != spell && spell.isEnabled(SpellProperties.Context.WANDS)){
|
||||
|
||||
// Decide if we can bind this multiple times
|
||||
if (Wizardry.settings.preventBindingSameSpellTwiceToWands && Arrays.stream(spells).anyMatch(s -> s == spell)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
spells[i] = spell;
|
||||
changed = true;
|
||||
|
||||
// setting to consume books upon use
|
||||
if (Wizardry.settings.singleUseSpellBooks) {
|
||||
spellBooks[i].getStack().shrink(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -825,7 +868,12 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
|
||||
|
||||
int chargeDepleted = this.getManaCapacity(centre.getStack()) - this.getMana(centre.getStack());
|
||||
|
||||
int manaPerItem = Constants.MANA_PER_CRYSTAL;
|
||||
// Not too pretty but allows addons implementing the IManaStoringItem interface to provide their mana amount for custom crystals,
|
||||
// previously this was defaulted to the regular crystal's amount, allowing players to exploit it if a crystal was worth less mana than that.
|
||||
int manaPerItem = crystals.getStack().getItem() instanceof IManaStoringItem ?
|
||||
((IManaStoringItem) crystals.getStack().getItem()).getMana(crystals.getStack()) :
|
||||
crystals.getStack().getItem() instanceof ItemCrystal ? Constants.MANA_PER_CRYSTAL : Constants.MANA_PER_SHARD;
|
||||
|
||||
if(crystals.getStack().getItem() == WizardryItems.crystal_shard) manaPerItem = Constants.MANA_PER_SHARD;
|
||||
if(crystals.getStack().getItem() == WizardryItems.grand_crystal) manaPerItem = Constants.GRAND_CRYSTAL_MANA;
|
||||
|
||||
@@ -846,6 +894,19 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
|
||||
return changed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClearButtonPressed(EntityPlayer player, Slot centre, Slot crystals, Slot upgrade, Slot[] spellBooks){
|
||||
ItemStack stack = centre.getStack();
|
||||
if (stack.hasTagCompound() && stack.getTagCompound().hasKey(WandHelper.SPELL_ARRAY_KEY)) {
|
||||
NBTTagCompound nbt = stack.getTagCompound();
|
||||
nbt.removeTag(WandHelper.SPELL_ARRAY_KEY);
|
||||
stack.setTagCompound(nbt);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClearable() { return true; }
|
||||
|
||||
// hitEntity is only called server-side, so we'll have to use events
|
||||
@SubscribeEvent
|
||||
public static void onAttackEntityEvent(AttackEntityEvent event){
|
||||
|
||||
@@ -1,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 && player.ticksExisted % 20 == 0
|
||||
&& isWearingFullSet(player, element, ArmourClass.BATTLEMAGE) && doAllArmourPiecesHaveMana(player)){
|
||||
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) && doAllArmourPiecesHaveMana(caster)){
|
||||
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
|
||||
@@ -229,7 +334,12 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
|
||||
|
||||
int chargeDepleted = this.getManaCapacity(centre.getStack()) - this.getMana(centre.getStack());
|
||||
|
||||
int manaPerItem = Constants.MANA_PER_CRYSTAL;
|
||||
// Not too pretty but allows addons implementing the IManaStoringItem interface to provide their mana amount for custom crystals,
|
||||
// previously this was defaulted to the regular crystal's amount, allowing players to exploit it if a crystal was worth less mana than that.
|
||||
int manaPerItem = crystals.getStack().getItem() instanceof IManaStoringItem ?
|
||||
((IManaStoringItem) crystals.getStack().getItem()).getMana(crystals.getStack()) :
|
||||
crystals.getStack().getItem() instanceof ItemCrystal ? Constants.MANA_PER_CRYSTAL : Constants.MANA_PER_SHARD;
|
||||
|
||||
if(crystals.getStack().getItem() == WizardryItems.crystal_shard) manaPerItem = Constants.MANA_PER_SHARD;
|
||||
if(crystals.getStack().getItem() == WizardryItems.grand_crystal) manaPerItem = Constants.GRAND_CRYSTAL_MANA;
|
||||
|
||||
@@ -252,34 +362,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) && doAllArmourPiecesHaveMana(event.getEntityLiving())){
|
||||
// Only apply the modifier once (can't just check this is the helmet since it might not be the last piece equipped)
|
||||
if(movementSpeed.getModifier(WARLOCK_SPEED_BOOST_UUID) == null){
|
||||
movementSpeed.applyModifier(new AttributeModifier(WARLOCK_SPEED_BOOST_UUID, "Warlock set bonus", WARLOCK_SPEED_BOOST, Operations.MULTIPLY_FLAT));
|
||||
}
|
||||
}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 +406,59 @@ 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.
|
||||
*/
|
||||
public static boolean isWearingFullSet(EntityLivingBase entity, @Nullable Element element, @Nullable ArmourClass armourClass){
|
||||
ItemStack helmet = entity.getItemStackFromSlot(EntityEquipmentSlot.HEAD);
|
||||
if(!(helmet.getItem() instanceof ItemWizardArmour)) return false;
|
||||
Element e = element == null ? ((ItemWizardArmour)helmet.getItem()).element : element;
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given entity's armour pieces which implement {@link IManaStoringItem} has mana. Ignores pieces which doesn't have a mana storage.
|
||||
* @param entity The entity to query.
|
||||
* @return True if all armour pieces which implement {@link IManaStoringItem} has mana, false otherwise.
|
||||
*/
|
||||
public static boolean doAllArmourPiecesHaveMana(EntityLivingBase entity){
|
||||
return Arrays.stream(InventoryUtils.ARMOUR_SLOTS).noneMatch(s -> entity.getItemStackFromSlot(s).getItem() instanceof IManaStoringItem
|
||||
&& ((IManaStoringItem) entity.getItemStackFromSlot(s).getItem()).isManaEmpty(entity.getItemStackFromSlot(s)));
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onLivingSetAttackTargetEvent(LivingSetAttackTargetEvent event){
|
||||
// Undo the mob detection penalty for wearing armour when invisible
|
||||
@@ -306,7 +478,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);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.EnumActionResult;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.text.Style;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
@@ -36,7 +37,11 @@ public class ItemWizardHandbook extends Item {
|
||||
@Override
|
||||
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand){
|
||||
ItemStack stack = player.getHeldItem(hand);
|
||||
player.openGui(Wizardry.instance, WizardryGuiHandler.WIZARD_HANDBOOK, world, 0, 0, 0);
|
||||
if (Wizardry.settings.loadHandbook) {
|
||||
player.openGui(Wizardry.instance, WizardryGuiHandler.WIZARD_HANDBOOK, world, 0, 0, 0);
|
||||
} else if (!world.isRemote){
|
||||
player.sendStatusMessage(new TextComponentTranslation("item." + Wizardry.MODID + ":wizard_handbook.disabled"), false);
|
||||
}
|
||||
return ActionResult.newResult(EnumActionResult.SUCCESS, stack);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,9 +9,9 @@ import electroblob.wizardry.packet.WizardryPacketHandler;
|
||||
import electroblob.wizardry.util.Box;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedInEvent;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||
|
||||
import java.util.List;
|
||||
@@ -37,6 +37,9 @@ public class DonationPerksHandler {
|
||||
.put(UUID.fromString("32ca0099-c1d6-4682-82ab-8f06059bb801"), new Box<>(Element.MAGIC))
|
||||
.put(UUID.fromString("0a704e20-1e7a-413e-9122-fae5b244a05e"), new Box<>(Element.MAGIC))
|
||||
.put(UUID.fromString("41fec037-12a5-4b19-868e-b62e39952e96"), new Box<>(Element.MAGIC))
|
||||
.put(UUID.fromString("3f5e0cec-949a-4dd4-ae60-f4eae481dd06"), new Box<>(Element.MAGIC))
|
||||
.put(UUID.fromString("3ad78c5f-d8cf-47f1-bff9-a890f8e638ff"), new Box<>(Element.MAGIC))
|
||||
.put(UUID.fromString("93479771-d23a-4d80-8868-2950e144500b"), new Box<>(Element.MAGIC))
|
||||
.build();
|
||||
|
||||
/** Returns true if the given player's UUID appears in the list of donor UUIDs, false otherwise (thread-safe). */
|
||||
@@ -59,7 +62,7 @@ public class DonationPerksHandler {
|
||||
Box<Element> box = DONOR_UUID_MAP.get(player.getUniqueID());
|
||||
if(box != null && box.get() != element){
|
||||
box.set(element);
|
||||
syncAll();
|
||||
syncAll(player.dimension);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,11 +73,11 @@ public class DonationPerksHandler {
|
||||
return box == null ? null : box.get();
|
||||
}
|
||||
|
||||
/** Sends the current donor perk information to all connected players (server-side only). */
|
||||
private static void syncAll(){
|
||||
/** Sends the current donor perk information to all players in the given dimension (server-side only). */
|
||||
private static void syncAll(int dimension){
|
||||
Wizardry.logger.info("Sending global donation perk settings to all players");
|
||||
PacketSyncDonationPerks.Message packet = new PacketSyncDonationPerks.Message(DONOR_UUID_MAP.values().stream().map(Box::get).collect(Collectors.toList()));
|
||||
WizardryPacketHandler.net.sendToAll(packet);
|
||||
WizardryPacketHandler.net.sendToDimension(packet, dimension);
|
||||
}
|
||||
|
||||
/** Sends the current donor perk information to the given player (server-side only). */
|
||||
@@ -92,13 +95,13 @@ public class DonationPerksHandler {
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onPlayerLoggedInEvent(PlayerLoggedInEvent event){
|
||||
if(event.player instanceof EntityPlayerMP){
|
||||
public static void onEntityJoinWorldEvent(EntityJoinWorldEvent event){
|
||||
if(event.getEntity() instanceof EntityPlayerMP){
|
||||
// Send donation perks to anyone who logs in
|
||||
syncWith((EntityPlayerMP)event.player);
|
||||
}else{
|
||||
syncWith((EntityPlayerMP)event.getEntity());
|
||||
}else if(event.getEntity() instanceof EntityPlayer){
|
||||
// Send donation perks setting to the server if the player is a donor
|
||||
if(isDonor(event.player)) sendToServer(event.player);
|
||||
if(isDonor((EntityPlayer)event.getEntity())) sendToServer((EntityPlayer)event.getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -49,6 +51,17 @@ public class PacketControlInput implements IMessageHandler<Message, IMessage> {
|
||||
|
||||
break;
|
||||
|
||||
case CLEAR_BUTTON:
|
||||
|
||||
if(!(player.openContainer instanceof ContainerArcaneWorkbench)){
|
||||
Wizardry.logger.warn("Received a PacketControlInput, but the player that sent it was not " +
|
||||
"currently using an arcane workbench. This should not happen!");
|
||||
}else{
|
||||
((ContainerArcaneWorkbench)player.openContainer).onClearButtonPressed(player);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case NEXT_SPELL_KEY:
|
||||
|
||||
if(wand.getItem() instanceof ISpellCastingItem){
|
||||
@@ -79,6 +92,7 @@ public class PacketControlInput implements IMessageHandler<Message, IMessage> {
|
||||
.filter(s -> Resurrection.canStackResurrect(s, player)).findFirst().orElse(null);
|
||||
|
||||
if(stack != null){
|
||||
if(MinecraftForge.EVENT_BUS.post(new ResurrectionEvent(player, player))) break;
|
||||
// This should suffice, since this is the only way a player can cast resurrection when dead!
|
||||
((ISpellCastingItem)stack.getItem()).cast(stack, Spells.resurrection, player, EnumHand.MAIN_HAND, 0, new SpellModifiers());
|
||||
break;
|
||||
@@ -130,7 +144,7 @@ public class PacketControlInput implements IMessageHandler<Message, IMessage> {
|
||||
}
|
||||
|
||||
public enum ControlType {
|
||||
APPLY_BUTTON, NEXT_SPELL_KEY, PREVIOUS_SPELL_KEY, RESURRECT_BUTTON, CANCEL_RESURRECT, POSSESSION_PROJECTILE
|
||||
APPLY_BUTTON, NEXT_SPELL_KEY, PREVIOUS_SPELL_KEY, RESURRECT_BUTTON, CANCEL_RESURRECT, POSSESSION_PROJECTILE, CLEAR_BUTTON
|
||||
}
|
||||
|
||||
public static class Message implements IMessage {
|
||||
|
||||
@@ -3,7 +3,6 @@ package electroblob.wizardry.packet;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
import electroblob.wizardry.util.SpellProperties;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
|
||||
@@ -18,13 +17,11 @@ public class PacketSpellProperties implements IMessageHandler<PacketSpellPropert
|
||||
public IMessage onMessage(Message message, MessageContext ctx){
|
||||
|
||||
// Just to make sure that the side is correct
|
||||
if(ctx.side.isServer()){
|
||||
if(ctx.side.isClient()){
|
||||
|
||||
final EntityPlayerMP player = ctx.getServerHandler().player;
|
||||
|
||||
player.getServerWorld().addScheduledTask(() -> {
|
||||
net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(() -> {
|
||||
for(int i=0; i<message.propertiesArray.length; i++){
|
||||
Spell.byNetworkID(i).setProperties(message.propertiesArray[i]);
|
||||
Spell.byNetworkID(i).setPropertiesClient(message.propertiesArray[i]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package electroblob.wizardry.potion;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.item.ItemWizardArmour;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.inventory.EntityEquipmentSlot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraftforge.common.ISpecialArmor;
|
||||
|
||||
public class CurseUndeath extends Curse {
|
||||
|
||||
@@ -25,7 +28,7 @@ public class CurseUndeath extends Curse {
|
||||
|
||||
// Adapted from EntityZombie
|
||||
if(entitylivingbase.world.isDaytime() && !entitylivingbase.world.isRemote){
|
||||
|
||||
|
||||
float f = entitylivingbase.getBrightness();
|
||||
|
||||
if(f > 0.5F && entitylivingbase.world.rand.nextFloat() * 30.0F < (f - 0.4F) * 2.0F
|
||||
@@ -35,14 +38,21 @@ public class CurseUndeath extends Curse {
|
||||
boolean flag = true;
|
||||
ItemStack itemstack = entitylivingbase.getItemStackFromSlot(EntityEquipmentSlot.HEAD);
|
||||
|
||||
if(!itemstack.isEmpty()){
|
||||
if(itemstack.isItemStackDamageable()){
|
||||
if (!itemstack.isEmpty()) {
|
||||
if (itemstack.isItemStackDamageable()) {
|
||||
|
||||
itemstack.setItemDamage(itemstack.getItemDamage() + entitylivingbase.world.rand.nextInt(2));
|
||||
|
||||
if(itemstack.getItemDamage() >= itemstack.getMaxDamage()){
|
||||
entitylivingbase.renderBrokenItemStack(itemstack);
|
||||
entitylivingbase.setItemStackToSlot(EntityEquipmentSlot.HEAD, ItemStack.EMPTY);
|
||||
if (itemstack.getItem() instanceof ISpecialArmor) {
|
||||
((ISpecialArmor) itemstack.getItem()).damageArmor(entitylivingbase, itemstack, DamageSource.ON_FIRE, entitylivingbase.world.rand.nextInt(2), EntityEquipmentSlot.HEAD.getSlotIndex());
|
||||
} else {
|
||||
itemstack.setItemDamage(itemstack.getItemDamage() + entitylivingbase.world.rand.nextInt(2));
|
||||
if (itemstack.getItemDamage() >= itemstack.getMaxDamage()) {
|
||||
if (itemstack.getItem() instanceof ItemWizardArmour) {
|
||||
entitylivingbase.setFire(8);
|
||||
} else {
|
||||
entitylivingbase.renderBrokenItemStack(itemstack);
|
||||
entitylivingbase.setItemStackToSlot(EntityEquipmentSlot.HEAD, ItemStack.EMPTY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,17 +2,14 @@ package electroblob.wizardry.potion;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.registry.WizardryPotions;
|
||||
import electroblob.wizardry.registry.WizardrySounds;
|
||||
import electroblob.wizardry.util.EntityUtils;
|
||||
import electroblob.wizardry.util.GeometryUtils;
|
||||
import electroblob.wizardry.util.NBTExtras;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.nbt.NBTUtil;
|
||||
import net.minecraft.network.play.server.SPacketEntityVelocity;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
@@ -23,8 +20,6 @@ public class PotionContainment extends PotionMagicEffect {
|
||||
|
||||
public static final String ENTITY_TAG = "containmentPos";
|
||||
|
||||
private static final double RUBBERBAND_THRESHOLD = 0.24;
|
||||
|
||||
public PotionContainment(boolean isBadEffect, int liquidColour){
|
||||
super(isBadEffect, liquidColour, new ResourceLocation(Wizardry.MODID, "textures/gui/potion_icons/containment.png"));
|
||||
this.setPotionName("potion." + Wizardry.MODID + ":containment");
|
||||
@@ -41,7 +36,6 @@ public class PotionContainment extends PotionMagicEffect {
|
||||
|
||||
@Override
|
||||
public void performEffect(EntityLivingBase target, int strength){
|
||||
|
||||
float maxDistance = getContainmentDistance(strength);
|
||||
|
||||
// Initialise the containment position to the entity's position if it wasn't set already
|
||||
@@ -63,59 +57,14 @@ public class PotionContainment extends PotionMagicEffect {
|
||||
if(target.getEntityBoundingBox().maxZ > origin.z + maxDistance) z = origin.z + maxDistance - target.width/2;
|
||||
if(target.getEntityBoundingBox().minZ < origin.z - maxDistance) z = origin.z - maxDistance + target.width/2;
|
||||
|
||||
if(x != target.posX || y != target.posY || z != target.posZ){
|
||||
|
||||
// if(target.world.isRemote){
|
||||
//
|
||||
// if(x != target.posX){
|
||||
// for(int i = 0; i < 20; i++){
|
||||
// ParticleBuilder.create(ParticleBuilder.Type.DUST).pos(
|
||||
// x,
|
||||
// target.posY + target.height * target.world.rand.nextFloat(),
|
||||
// target.posZ + target.width * (target.world.rand.nextFloat() - 0.5f))
|
||||
// .face(EnumFacing.EAST).clr(0.8f, 0.9f, 1).spawn(target.world);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if(y != target.posY){
|
||||
// for(int i = 0; i < 20; i++){
|
||||
// ParticleBuilder.create(ParticleBuilder.Type.DUST).pos(
|
||||
// target.posX + target.width * (target.world.rand.nextFloat() - 0.5f),
|
||||
// y,
|
||||
// target.posZ + target.width * (target.world.rand.nextFloat() - 0.5f))
|
||||
// .face(EnumFacing.UP).clr(0.8f, 0.9f, 1).spawn(target.world);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if(z != target.posZ){
|
||||
// for(int i = 0; i < 20; i++){
|
||||
// ParticleBuilder.create(ParticleBuilder.Type.DUST).pos(
|
||||
// target.posX + target.width * (target.world.rand.nextFloat() - 0.5f),
|
||||
// target.posY + target.height * target.world.rand.nextFloat(),
|
||||
// z)
|
||||
// .face(EnumFacing.SOUTH).clr(0.8f, 0.9f, 1).spawn(target.world);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// Rubberbanding prevention (the 0.25 limit is from NetHandlerPlayServer, just search "moved wrongly"
|
||||
if(target instanceof EntityPlayer){
|
||||
x = MathHelper.clamp(x, target.posX - RUBBERBAND_THRESHOLD, target.posX + RUBBERBAND_THRESHOLD);
|
||||
y = MathHelper.clamp(y, target.posY - RUBBERBAND_THRESHOLD, target.posY + RUBBERBAND_THRESHOLD);
|
||||
z = MathHelper.clamp(z, target.posZ - RUBBERBAND_THRESHOLD, target.posZ + RUBBERBAND_THRESHOLD);
|
||||
}
|
||||
|
||||
if(x != target.posX || y != target.posY || z != target.posZ)
|
||||
{
|
||||
target.addVelocity(0.15 * Math.signum(x - target.posX), 0.15 * Math.signum(y - target.posY), 0.15 * Math.signum(z - target.posZ));
|
||||
EntityUtils.undoGravity(target);
|
||||
target.addVelocity(0.35 * Math.signum(x - target.posX), 0.35 * Math.signum(y - target.posY), 0.35 * Math.signum(z - target.posZ));
|
||||
target.setPositionAndUpdate(x, y, z); // FIXME: This line must be causing the server rubberbanding, not sure why
|
||||
// Player motion is handled on that player's client so needs packets
|
||||
if(target instanceof EntityPlayerMP){
|
||||
((EntityPlayerMP)target).connection.sendPacket(new SPacketEntityVelocity(target));
|
||||
if(target.world.isRemote){
|
||||
target.world.playSound(target.posX, target.posY, target.posZ, WizardrySounds.ENTITY_FORCEFIELD_DEFLECT,
|
||||
WizardrySounds.SPELLS, 0.3f, 1f, false);
|
||||
}
|
||||
//
|
||||
// target.world.playSound(target.posX, target.posY, target.posZ, WizardrySounds.ENTITY_FORCEFIELD_DEFLECT,
|
||||
// WizardrySounds.SPELLS, 0.3f, 1f, false);
|
||||
|
||||
}
|
||||
|
||||
// Need to do this here because it's the only way to hook into potion ending both client- and server-side
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package electroblob.wizardry.potion;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.util.EntityUtils;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
@Mod.EventBusSubscriber
|
||||
public class PotionDiamondflesh extends PotionMagicEffect {
|
||||
|
||||
public PotionDiamondflesh(boolean isBadEffect, int liquidColour) {
|
||||
super(isBadEffect, liquidColour, new ResourceLocation(Wizardry.MODID, "textures/gui/potion_icons/diamondflesh.png"));
|
||||
// This needs to be here because registerPotionAttributeModifier doesn't like it if the potion has no name yet.
|
||||
this.setPotionName("potion." + Wizardry.MODID + ":ironflesh");
|
||||
this.registerPotionAttributeModifier(SharedMonsterAttributes.MOVEMENT_SPEED,
|
||||
"158a8af2-6db0-4340-a01c-a7b60d10ddf4", -0.1f, EntityUtils.Operations.MULTIPLY_CUMULATIVE);
|
||||
this.registerPotionAttributeModifier(SharedMonsterAttributes.ARMOR_TOUGHNESS,
|
||||
"a68d4532-5847-426c-9b03-d541b113cec2", 3.0f, EntityUtils.Operations.ADD);
|
||||
this.registerPotionAttributeModifier(SharedMonsterAttributes.ARMOR,
|
||||
"46a095be-82dd-43fd-8b67-13f51591eb8e", 4.0f, EntityUtils.Operations.ADD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady(int duration, int amplifier) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import electroblob.wizardry.constants.Constants;
|
||||
import electroblob.wizardry.registry.WizardryPotions;
|
||||
import electroblob.wizardry.util.ParticleBuilder;
|
||||
import electroblob.wizardry.util.ParticleBuilder.Type;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.world.World;
|
||||
@@ -50,4 +51,18 @@ public class PotionFrost extends PotionMagicEffect implements ICustomPotionParti
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performEffect(EntityLivingBase entitylivingbase, int strength) {
|
||||
if (entitylivingbase.isBurning()) {
|
||||
if (entitylivingbase.isPotionActive(WizardryPotions.frost)) {
|
||||
entitylivingbase.removePotionEffect(WizardryPotions.frost);
|
||||
entitylivingbase.extinguish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady(int duration, int amplifier) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package electroblob.wizardry.potion;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.util.EntityUtils;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
@Mod.EventBusSubscriber
|
||||
public class PotionIronflesh extends PotionMagicEffect {
|
||||
|
||||
public PotionIronflesh(boolean isBadEffect, int liquidColour) {
|
||||
super(isBadEffect, liquidColour, new ResourceLocation(Wizardry.MODID, "textures/gui/potion_icons/ironflesh.png"));
|
||||
// This needs to be here because registerPotionAttributeModifier doesn't like it if the potion has no name yet.
|
||||
this.setPotionName("potion." + Wizardry.MODID + ":ironflesh");
|
||||
this.registerPotionAttributeModifier(SharedMonsterAttributes.MOVEMENT_SPEED,
|
||||
"fe607d55-50e3-4f4f-a959-6571503f92f4", -0.1f, EntityUtils.Operations.MULTIPLY_CUMULATIVE);
|
||||
this.registerPotionAttributeModifier(SharedMonsterAttributes.KNOCKBACK_RESISTANCE,
|
||||
"6f78206e-8dd4-4d44-9792-d7a882111951", 0.3f, EntityUtils.Operations.ADD);
|
||||
this.registerPotionAttributeModifier(SharedMonsterAttributes.ARMOR,
|
||||
"e1adff1e-8510-4a09-96ed-ef677cad20c1", 4.0f, EntityUtils.Operations.ADD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady(int duration, int amplifier) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package electroblob.wizardry.potion;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.util.EntityUtils;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
@Mod.EventBusSubscriber
|
||||
public class PotionOakflesh extends PotionMagicEffect {
|
||||
|
||||
public PotionOakflesh(boolean isBadEffect, int liquidColour) {
|
||||
super(isBadEffect, liquidColour, new ResourceLocation(Wizardry.MODID, "textures/gui/potion_icons/oakflesh.png"));
|
||||
// This needs to be here because registerPotionAttributeModifier doesn't like it if the potion has no name yet.
|
||||
this.setPotionName("potion." + Wizardry.MODID + ":ironflesh");
|
||||
this.registerPotionAttributeModifier(SharedMonsterAttributes.MOVEMENT_SPEED,
|
||||
"98b4ba66-7c50-4a4c-9f3f-40bcb37313b5", -0.1f, EntityUtils.Operations.MULTIPLY_CUMULATIVE);
|
||||
this.registerPotionAttributeModifier(SharedMonsterAttributes.MAX_HEALTH,
|
||||
"ed9d0423-60f4-4998-bd8d-dc7c33bd45b8", 0.2f, EntityUtils.Operations.MULTIPLY_FLAT);
|
||||
this.registerPotionAttributeModifier(SharedMonsterAttributes.ARMOR,
|
||||
"0b607c3f-fb14-43d7-96b5-1c1b6f6da242", 3.0f, EntityUtils.Operations.ADD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady(int duration, int amplifier) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -359,7 +359,7 @@ public final class Spells {
|
||||
registry.register(new GreaterHeal());
|
||||
registry.register(new SpellConstruct<>("healing_aura", SpellActions.POINT_DOWN, EntityHealAura::new, false).addProperties(Spell.EFFECT_RADIUS, Spell.DAMAGE, Spell.HEALTH));
|
||||
registry.register(new Forcefield());
|
||||
registry.register(new SpellBuff("ironflesh", 0.4f, 0.5f, 0.6f, () -> MobEffects.RESISTANCE).soundValues(0.7f, 1.2f, 0.4f));
|
||||
registry.register(new SpellBuff("ironflesh", 0.4f, 0.5f, 0.6f, () -> WizardryPotions.ironflesh).soundValues(0.7f, 1.2f, 0.4f));
|
||||
registry.register(new Transience());
|
||||
|
||||
registry.register(new Meteor());
|
||||
@@ -378,9 +378,10 @@ public final class Spells {
|
||||
registry.register(new SpellMinion<>("silverfish_swarm", EntitySilverfishMinion::new).soundValues(1, 1.1f, 0.1f));
|
||||
registry.register(new SpellConstructRanged<>("black_hole", EntityBlackHole::new, false).addProperties(Spell.EFFECT_RADIUS).soundValues(2, 0.7f, 0));
|
||||
registry.register(new Shockwave());
|
||||
registry.register(new SummonIronGolem());
|
||||
registry.register(new SpellMinion<>("summon_iron_golem", EntitySpectralGolem::new).soundValues(1, 1.1f, 0.1f));
|
||||
|
||||
registry.register(new ArrowRain());
|
||||
registry.register(new SpellBuff("diamondflesh", 0.1f, 0.7f, 1, () -> MobEffects.RESISTANCE).soundValues(0.7f, 1.2f, 0.4f));
|
||||
registry.register(new SpellBuff("diamondflesh", 0.1f, 0.7f, 1, () -> WizardryPotions.diamondflesh).soundValues(0.7f, 1.2f, 0.4f));
|
||||
registry.register(new SpellBuff("font_of_vitality", 1, 0.8f, 0.3f, () -> MobEffects.ABSORPTION, () -> MobEffects.REGENERATION).soundValues(0.7f, 1.2f, 0.4f));
|
||||
|
||||
// Wizardry 1.1 spells
|
||||
@@ -398,7 +399,7 @@ public final class Spells {
|
||||
registry.register(new PocketWorkbench());
|
||||
registry.register(new ImbueWeapon());
|
||||
registry.register(new InvigoratingPresence());
|
||||
registry.register(new SpellBuff("oakflesh", 0.6f, 0.5f, 0.4f, () -> MobEffects.RESISTANCE).soundValues(0.7f, 1.2f, 0.4f));
|
||||
registry.register(new SpellBuff("oakflesh", 0.6f, 0.5f, 0.4f, () -> WizardryPotions.oakflesh).soundValues(0.7f, 1.2f, 0.4f));
|
||||
|
||||
registry.register(new SpellProjectile<>("greater_fireball", EntityLargeMagicFireball::new).addProperties(Spell.DAMAGE, EntityLargeMagicFireball.EXPLOSION_POWER));//new GreaterFireball());
|
||||
registry.register(new FlamingWeapon());
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -88,6 +88,7 @@ public class WizardryEntities {
|
||||
registry.register(createEntry(EntitySpiritHorse.class, "spirit_horse", TrackingType.LIVING).egg(0x5464c6, 0xbcc2e8).build());
|
||||
registry.register(createEntry(EntityPhoenix.class, "phoenix", TrackingType.LIVING).egg(0xff4900, 0xfde535).build());
|
||||
registry.register(createEntry(EntityIceGiant.class, "ice_giant", TrackingType.LIVING).egg(0x5bacd9, 0xeffaff).build());
|
||||
registry.register(createEntry(EntitySpectralGolem.class, "spectral_golem", TrackingType.LIVING).egg(0x5bacd9, 0xeffaff).build());
|
||||
|
||||
registry.register(createEntry(EntityMagicSlime.class, "magic_slime", TrackingType.LIVING).build());
|
||||
registry.register(createEntry(EntityDecoy.class, "decoy", TrackingType.LIVING).build());
|
||||
@@ -113,6 +114,7 @@ public class WizardryEntities {
|
||||
registry.register(createEntry(EntityDart.class, "dart", TrackingType.PROJECTILE).build());
|
||||
registry.register(createEntry(EntityIceLance.class, "ice_lance", TrackingType.PROJECTILE).build());
|
||||
registry.register(createEntry(EntityFlamecatcherArrow.class, "flamecatcher_arrow", TrackingType.PROJECTILE).build());
|
||||
registry.register(createEntry(EntityConjuredArrow.class, "conjured_arrow", TrackingType.PROJECTILE).build());
|
||||
|
||||
// Directionless projectiles
|
||||
registry.register(createEntry(EntityFirebomb.class, "firebomb", TrackingType.PROJECTILE).build());
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -57,6 +57,9 @@ public final class WizardryPotions {
|
||||
public static final Potion frost_step = placeholder();
|
||||
public static final Potion mark_of_sacrifice = placeholder();
|
||||
public static final Potion mirage = placeholder();
|
||||
public static final Potion oakflesh = placeholder();
|
||||
public static final Potion ironflesh = placeholder();
|
||||
public static final Potion diamondflesh = placeholder();
|
||||
|
||||
/**
|
||||
* Sets both the registry and unlocalised names of the given potion, then registers it with the given registry. Use
|
||||
@@ -201,6 +204,10 @@ public final class WizardryPotions {
|
||||
public void spawnCustomParticle(World world, double x, double y, double z){} // We only want the syncing
|
||||
}.setBeneficial());
|
||||
|
||||
registerPotion(registry, "oakflesh", new PotionOakflesh(false, 0).setBeneficial());
|
||||
registerPotion(registry, "ironflesh", new PotionIronflesh(false, 0).setBeneficial());
|
||||
registerPotion(registry, "diamondflesh", new PotionDiamondflesh(false, 0).setBeneficial());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user