Compare commits
103 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 461df00048 | |||
| dcf60a8b4b | |||
| 739a1573e1 | |||
| b7ffd61020 | |||
| b6682e1c52 | |||
| 5d337b93a6 | |||
| b1e70c01f0 | |||
| d30a40bdc4 | |||
| 25b2b0b8a5 | |||
| 3eef93b599 | |||
| 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 |
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"homepage": "https://www.curseforge.com/minecraft/mc-mods/electroblobs-wizardry",
|
||||
"promos": {
|
||||
"1.12.2-latest": "4.3.7",
|
||||
"1.12.2-recommended": "4.3.7"
|
||||
}
|
||||
}
|
||||
@@ -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.4 [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.4 [change as necessary]
|
||||
|
||||
Question details: [explain your question here]
|
||||
|
||||
Other mods involved: [if this question involves other mods, list them here]
|
||||
@@ -0,0 +1,38 @@
|
||||
name: Potential Duplicates
|
||||
on:
|
||||
issues:
|
||||
types: [opened, edited]
|
||||
|
||||
jobs:
|
||||
run:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: bubkoo/potential-duplicates@v1
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
label: potential duplicate
|
||||
exclude: |
|
||||
adding
|
||||
add
|
||||
creating
|
||||
create
|
||||
icons
|
||||
icon
|
||||
logos
|
||||
logo
|
||||
missing
|
||||
miss
|
||||
needing
|
||||
need
|
||||
please
|
||||
requesting
|
||||
request
|
||||
1.12.2
|
||||
wizardry
|
||||
state: all
|
||||
threshold: 0.7
|
||||
comment: |
|
||||
This issue is potentially a duplicate of one of the following issues:
|
||||
{{#issues}}
|
||||
- [#{{ number }}] {{ title }} ({{ accuracy }}% match)
|
||||
{{/issues}}
|
||||
+8
-2
@@ -1,7 +1,7 @@
|
||||
# Credits
|
||||
|
||||
Electroblob's Wizardry
|
||||
Version 4.3.4
|
||||
Version 4.3.7
|
||||
For Minecraft 1.12.2
|
||||
|
||||
Designed, coded and textured by Electroblob
|
||||
@@ -12,6 +12,11 @@ Thanks also to the Minecraft modding community, which always has an answer to my
|
||||
|
||||
In addition, I'd like to thank the following individuals for their contributions to the mod:
|
||||
|
||||
#### Discord Moderators (and all-round awesome people)
|
||||
|
||||
- FavouriteDragon
|
||||
- WinDanesz
|
||||
|
||||
#### Code
|
||||
|
||||
- Corail31
|
||||
@@ -27,13 +32,14 @@ In addition, I'd like to thank the following individuals for their contributions
|
||||
- rafasoares
|
||||
- xinyuan-liu
|
||||
- SettingDust
|
||||
- Aralu115
|
||||
|
||||
#### Translations
|
||||
|
||||
- Spanish: MadWrist, Alsentar
|
||||
- Mexican Spanish: MadWrist
|
||||
- Russian: VilagVil, kellixon, bigenergy, MugGod2, DrHesperus
|
||||
- French: Hahdrim
|
||||
- French: Hahdrim, Crowller
|
||||
- Brazilian Portuguese: lorrampi
|
||||
- Chinese (Simplified): ZHENGLOC, dragon-evol, Hokorizero, TUsama, Determancer
|
||||
- Korean: shejery, rewi_wire, 방통, red1854th
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/guide_for_contributing.md) before posting.
|
||||
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/guide_for_contributing.md) before posting. You may also find the [troubleshooting page](https://github.com/Electroblob77/Wizardry/wiki/Troubleshooting) helpful.
|
||||
|
||||
Minecraft version: 1.12.2 [change as necessary]
|
||||
Wizardry version: 4.3.4 [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.4" // There, it matches semver, happy now?
|
||||
version = "4.3.8"
|
||||
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
|
||||
|
||||
@@ -198,6 +198,8 @@ public final class Settings {
|
||||
public boolean blindnessTweak = true;
|
||||
/** <b>[Server-only]</b> Whether using bonemeal on grass blocks has a chance to grow crystal flowers. */
|
||||
public boolean bonemealGrowsCrystalFlowers = true;
|
||||
/** <b>[Server-only]</b> Whether to enable Wizardry mob loot injection. Allows an easier switch instead of blacklisting all entities. */
|
||||
public boolean injectMobDrops = true;
|
||||
/**
|
||||
* <b>[Server-only]</b> List of registry names of entities which summoned creatures are allowed to attack, in addition
|
||||
* to the defaults.
|
||||
@@ -377,6 +379,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;
|
||||
|
||||
@@ -807,6 +812,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);
|
||||
@@ -1103,6 +1115,13 @@ public final class Settings {
|
||||
showChargeMeter = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(CLIENT_CATEGORY, "loadHandbook", true, "Whether to initialise the in-game handbook. Setting this to false will brick the in-game handbook, but it might help if you have startup crashes.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".load_handbook");
|
||||
property.setRequiresWorldRestart(false);
|
||||
Wizardry.proxy.setToNamedBooleanEntry(property);
|
||||
loadHandbook = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(CLIENT_CATEGORY, "spellHUDPosition", GuiPosition.BOTTOM_LEFT.name, "The position of the spell HUD.", GuiPosition.names);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".spell_hud_position");
|
||||
spellHUDPosition = GuiPosition.fromName(property.getString());
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package electroblob.wizardry;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonObject;
|
||||
import electroblob.wizardry.block.BlockBookshelf;
|
||||
import electroblob.wizardry.command.CommandCastSpell;
|
||||
import electroblob.wizardry.command.CommandDiscoverSpell;
|
||||
@@ -16,11 +13,23 @@ import electroblob.wizardry.inventory.ContainerBookshelf;
|
||||
import electroblob.wizardry.misc.DonationPerksHandler;
|
||||
import electroblob.wizardry.misc.Forfeit;
|
||||
import electroblob.wizardry.packet.WizardryPacketHandler;
|
||||
import electroblob.wizardry.registry.*;
|
||||
import electroblob.wizardry.registry.Spells;
|
||||
import electroblob.wizardry.registry.WizardryAdvancementTriggers;
|
||||
import electroblob.wizardry.registry.WizardryBlocks;
|
||||
import electroblob.wizardry.registry.WizardryItems;
|
||||
import electroblob.wizardry.registry.WizardryLoot;
|
||||
import electroblob.wizardry.registry.WizardrySounds;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
import electroblob.wizardry.util.SpellNetworkIDSorter;
|
||||
import electroblob.wizardry.util.SpellProperties;
|
||||
import electroblob.wizardry.util.WandHelper;
|
||||
import electroblob.wizardry.worldgen.*;
|
||||
import electroblob.wizardry.worldgen.WorldGenCrystalFlower;
|
||||
import electroblob.wizardry.worldgen.WorldGenCrystalOre;
|
||||
import electroblob.wizardry.worldgen.WorldGenLibraryRuins;
|
||||
import electroblob.wizardry.worldgen.WorldGenObelisk;
|
||||
import electroblob.wizardry.worldgen.WorldGenShrine;
|
||||
import electroblob.wizardry.worldgen.WorldGenUndergroundLibraryRuins;
|
||||
import electroblob.wizardry.worldgen.WorldGenWizardTower;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
@@ -39,8 +48,6 @@ import net.minecraftforge.fml.common.registry.GameRegistry;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.Calendar;
|
||||
|
||||
/**
|
||||
@@ -56,6 +63,7 @@ import java.util.Calendar;
|
||||
|
||||
@Mod(modid = Wizardry.MODID, name = Wizardry.NAME, version = Wizardry.VERSION, acceptedMinecraftVersions = "[1.12.2]",
|
||||
guiFactory = "electroblob.wizardry.WizardryGuiFactory",
|
||||
updateJSON = Wizardry.updateJSON,
|
||||
dependencies = "required-after:forge@[14.23.5.2847,);after:jei@[4.15.0,);after:baubles@[1.5.2,);after:antiqueatlas@[4.6,)")
|
||||
|
||||
public class Wizardry {
|
||||
@@ -74,7 +82,13 @@ public class Wizardry {
|
||||
* 1.x.x represents Minecraft 1.7.x versions, 2.x.x represents Minecraft 1.10.x versions, 3.x.x represents Minecraft
|
||||
* 1.11.x versions, and so on.
|
||||
*/
|
||||
public static final String VERSION = "4.3.4";
|
||||
public static final String VERSION = "4.3.7";
|
||||
|
||||
/**
|
||||
* Json file used by Forge's built-in <a href="https://mcforge.readthedocs.io/en/1.12.x/gettingstarted/autoupdate/">update checker</a>.
|
||||
* Used by the in-game mod menu to show that green icon whenever a newer version is available of the mod.
|
||||
*/
|
||||
public static final String updateJSON = "https://github.com/Electroblob77/Wizardry/blob/1.12.2/.forge/update.json";
|
||||
|
||||
// IDEA: Triggering of inbuilt Forge events in relevant places?
|
||||
// IDEA: Abstract the vanilla particles behind the particle builder
|
||||
@@ -113,11 +127,10 @@ public class Wizardry {
|
||||
public void preInit(FMLPreInitializationEvent event){
|
||||
|
||||
logger = event.getModLog();
|
||||
|
||||
proxy.registerResourceReloadListeners();
|
||||
|
||||
configDirectory = new File(event.getModConfigurationDirectory(), Wizardry.MODID);
|
||||
settings.initConfig(event);
|
||||
proxy.registerResourceReloadListeners();
|
||||
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
tisTheSeason = calendar.get(Calendar.MONTH) + 1 == 12 && calendar.get(Calendar.DAY_OF_MONTH) >= 24
|
||||
@@ -189,6 +202,8 @@ public class Wizardry {
|
||||
public void postInit(FMLPostInitializationEvent event){
|
||||
proxy.initialiseLayers();
|
||||
proxy.initialiseAnimations();
|
||||
|
||||
SpellNetworkIDSorter.init();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
||||
@@ -307,7 +307,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
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package electroblob.wizardry.api;
|
||||
|
||||
import electroblob.wizardry.constants.Element;
|
||||
|
||||
public interface IElemental {
|
||||
|
||||
Element getElement();
|
||||
}
|
||||
@@ -18,7 +18,7 @@ public final class WizardryEnumHelper {
|
||||
// Make sure these are updated if the relevant constructors are updated!
|
||||
// Can't we do some kind of reflection to access them and generate these arrays?
|
||||
private static final Class[] TIER_ARGUMENTS = new Class[]{Integer.class, Integer.class, Integer.class, Style.class, String.class};
|
||||
private static final Class[] ELEMENT_ARGUMENTS = new Class[]{Style.class, String.class, String.class};
|
||||
private static final Class[] ELEMENT_ARGUMENTS = new Class[]{Style.class, String.class, String.class, boolean.class, boolean.class};
|
||||
private static final Class[] SPELL_TYPE_ARGUMENTS = new Class[]{String.class};
|
||||
private static final Class[] SPELL_CONTEXT_ARGUMENTS = new Class[]{String.class};
|
||||
|
||||
@@ -55,12 +55,14 @@ public final class WizardryEnumHelper {
|
||||
* @param colour The colour of text associated with this element, as a style object.
|
||||
* @param name The unlocalised name of this element, as used in translation keys.
|
||||
* @param modID The mod ID of the mod that added this element, for icon rendering purposes.
|
||||
* @param worldgen Whether this element should have obelisks and shrines.
|
||||
* @param wizards Whether this element should have naturally occurring evil and good wizards.
|
||||
* @return The resulting {@code Element} enum constant.
|
||||
*/
|
||||
// This is the only one that needs the mod ID argument because elements are the only ones that have icons
|
||||
// For some reason Minecraft doesn't seem to care about the resource domain for lang files, it just pools them
|
||||
public static Element addElement(String codeName, Style colour, String name, String modID){
|
||||
return EnumHelper.addEnum(Element.class, codeName, ELEMENT_ARGUMENTS, colour, name, modID);
|
||||
public static Element addElement(String codeName, Style colour, String name, String modID, boolean worldgen, boolean wizards){
|
||||
return EnumHelper.addEnum(Element.class, codeName, ELEMENT_ARGUMENTS, colour, name, modID, worldgen, wizards);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -256,7 +256,9 @@ public class BlockBookshelf extends BlockHorizontal implements ITileEntityProvid
|
||||
// Wizardry books
|
||||
registerBookModelTexture(() -> WizardryItems.spell_book, new ResourceLocation(Wizardry.MODID, "blocks/books_red"));
|
||||
registerBookModelTexture(() -> WizardryItems.wizard_handbook, new ResourceLocation(Wizardry.MODID, "blocks/books_blue"));
|
||||
registerBookModelTexture(() -> WizardryItems.arcane_tome, new ResourceLocation(Wizardry.MODID, "blocks/books_purple"));
|
||||
registerBookModelTexture(() -> WizardryItems.arcane_tome_apprentice,new ResourceLocation(Wizardry.MODID, "blocks/books_purple"));
|
||||
registerBookModelTexture(() -> WizardryItems.arcane_tome_advanced, new ResourceLocation(Wizardry.MODID, "blocks/books_purple"));
|
||||
registerBookModelTexture(() -> WizardryItems.arcane_tome_master, new ResourceLocation(Wizardry.MODID, "blocks/books_purple"));
|
||||
registerBookModelTexture(() -> WizardryItems.ruined_spell_book, new ResourceLocation(Wizardry.MODID, "blocks/books_brown"));
|
||||
registerBookModelTexture(() -> WizardryItems.scroll, new ResourceLocation(Wizardry.MODID, "blocks/scrolls_blue"));
|
||||
registerBookModelTexture(() -> WizardryItems.blank_scroll, new ResourceLocation(Wizardry.MODID, "blocks/scrolls_blue"));
|
||||
|
||||
@@ -1,29 +1,23 @@
|
||||
package electroblob.wizardry.block;
|
||||
|
||||
import electroblob.wizardry.api.IElemental;
|
||||
import electroblob.wizardry.constants.Element;
|
||||
import electroblob.wizardry.registry.WizardryTabs;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.MapColor;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.properties.PropertyEnum;
|
||||
import net.minecraft.block.state.BlockStateContainer;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
|
||||
import java.util.EnumMap;
|
||||
|
||||
public class BlockCrystal extends Block {
|
||||
public class BlockCrystal extends Block implements IElemental {
|
||||
|
||||
public static final PropertyEnum<Element> ELEMENT = PropertyEnum.create("element", Element.class);
|
||||
private static final EnumMap<Element, MapColor> map_colours = new EnumMap<>(Element.class);
|
||||
|
||||
private static final EnumMap<Element, MapColor> map_colours = new EnumMap<>(Element.class);
|
||||
|
||||
static {
|
||||
map_colours.put(Element.MAGIC, MapColor.PINK);
|
||||
static {
|
||||
map_colours.put(Element.MAGIC, MapColor.PINK);
|
||||
map_colours.put(Element.FIRE, MapColor.ORANGE_STAINED_HARDENED_CLAY);
|
||||
map_colours.put(Element.ICE, MapColor.LIGHT_BLUE);
|
||||
map_colours.put(Element.LIGHTNING, MapColor.CYAN);
|
||||
@@ -32,45 +26,22 @@ public class BlockCrystal extends Block {
|
||||
map_colours.put(Element.SORCERY, MapColor.LIME);
|
||||
map_colours.put(Element.HEALING, MapColor.YELLOW);
|
||||
}
|
||||
|
||||
public BlockCrystal(Material material){
|
||||
super(material);
|
||||
this.setDefaultState(this.blockState.getBaseState().withProperty(ELEMENT, Element.MAGIC));
|
||||
this.setCreativeTab(WizardryTabs.WIZARDRY);
|
||||
|
||||
@Override
|
||||
public Element getElement() { return element; }
|
||||
|
||||
private final Element element;
|
||||
|
||||
public BlockCrystal(Element element) {
|
||||
super(Material.IRON);
|
||||
this.setCreativeTab(WizardryTabs.WIZARDRY);
|
||||
this.setHarvestLevel("pickaxe", 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int damageDropped(IBlockState state){
|
||||
return (state.getValue(ELEMENT)).ordinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapColor getMapColor(IBlockState state, IBlockAccess world, BlockPos pos){
|
||||
return map_colours.get(state.getProperties().get(ELEMENT));
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getSubBlocks(CreativeTabs tab, NonNullList<ItemStack> items){
|
||||
if(this.getCreativeTab() == tab){
|
||||
for(Element element : Element.values()){
|
||||
items.add(new ItemStack(this, 1, element.ordinal()));
|
||||
}
|
||||
}
|
||||
public MapColor getMapColor(IBlockState state, IBlockAccess world, BlockPos pos) {
|
||||
return map_colours.get(state.getProperties().get(element));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getStateFromMeta(int metadata){
|
||||
return this.getDefaultState().withProperty(ELEMENT, Element.values()[metadata]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetaFromState(IBlockState state){
|
||||
return (state.getValue(ELEMENT)).ordinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockStateContainer createBlockState(){
|
||||
return new BlockStateContainer(this, ELEMENT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,30 @@
|
||||
package electroblob.wizardry.block;
|
||||
|
||||
import electroblob.wizardry.registry.WizardryTabs;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockPlanks;
|
||||
import net.minecraft.block.SoundType;
|
||||
import net.minecraft.block.material.MapColor;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.properties.IProperty;
|
||||
import net.minecraft.block.properties.PropertyEnum;
|
||||
import net.minecraft.block.state.BlockStateContainer;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.IStringSerializable;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
|
||||
public class BlockGildedWood extends BlockPlanks {
|
||||
public class BlockGildedWood extends Block {
|
||||
|
||||
public BlockGildedWood(){
|
||||
super();
|
||||
public BlockGildedWood()
|
||||
{
|
||||
super(Material.WOOD);
|
||||
this.setCreativeTab(WizardryTabs.WIZARDRY);
|
||||
this.setHardness(2.0F);
|
||||
this.setResistance(5.0F);
|
||||
this.setSoundType(SoundType.WOOD); // Why is this protected?!
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package electroblob.wizardry.block;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.constants.Element;
|
||||
import electroblob.wizardry.item.ItemSpectralDust;
|
||||
import electroblob.wizardry.registry.*;
|
||||
@@ -20,12 +21,14 @@ import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.common.registry.ForgeRegistries;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Arrays;
|
||||
@@ -110,7 +113,7 @@ public class BlockReceptacle extends BlockTorch implements ITileEntityProvider {
|
||||
|
||||
if(tileEntity instanceof TileEntityReceptacle){
|
||||
Element element = ((TileEntityReceptacle)tileEntity).getElement();
|
||||
if(element != null) drops.add(new ItemStack(WizardryItems.spectral_dust, 1, element.ordinal()));
|
||||
if(element != null) drops.add(new ItemStack(ForgeRegistries.ITEMS.getValue(new ResourceLocation(Wizardry.MODID, "spectral_dust_" + element.name().toLowerCase())), 1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,7 +222,7 @@ public class BlockReceptacle extends BlockTorch implements ITileEntityProvider {
|
||||
|
||||
((TileEntityReceptacle)tileEntity).setElement(null);
|
||||
|
||||
ItemStack dust = new ItemStack(WizardryItems.spectral_dust, 1, currentElement.ordinal());
|
||||
ItemStack dust = new ItemStack(ForgeRegistries.ITEMS.getValue(new ResourceLocation(Wizardry.MODID, "spectral_dust_" + currentElement.name().toLowerCase())));
|
||||
|
||||
if(stack.isEmpty()){
|
||||
player.setHeldItem(hand, dust);
|
||||
|
||||
@@ -5,24 +5,15 @@ import electroblob.wizardry.registry.WizardryTabs;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.MapColor;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.properties.PropertyEnum;
|
||||
import net.minecraft.block.state.BlockStateContainer;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.BlockRenderLayer;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumMap;
|
||||
|
||||
public class BlockRunestone extends Block {
|
||||
|
||||
public static final PropertyEnum<Element> ELEMENT = PropertyEnum.create("element", Element.class,
|
||||
Arrays.copyOfRange(Element.values(), 1, Element.values().length)); // Everything except MAGIC
|
||||
|
||||
private static final EnumMap<Element, MapColor> map_colours = new EnumMap<>(Element.class);
|
||||
|
||||
static {
|
||||
@@ -34,54 +25,24 @@ public class BlockRunestone extends Block {
|
||||
map_colours.put(Element.SORCERY, MapColor.GRAY);
|
||||
map_colours.put(Element.HEALING, MapColor.YELLOW_STAINED_HARDENED_CLAY);
|
||||
}
|
||||
|
||||
public BlockRunestone(Material material){
|
||||
|
||||
private final Element element;
|
||||
|
||||
public BlockRunestone(Material material, Element element) {
|
||||
super(material);
|
||||
this.setDefaultState(this.blockState.getBaseState().withProperty(ELEMENT, Element.FIRE));
|
||||
this.setCreativeTab(WizardryTabs.WIZARDRY);
|
||||
this.setCreativeTab(WizardryTabs.WIZARDRY);
|
||||
this.setHardness(1.5F);
|
||||
this.setResistance(10.0F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int damageDropped(IBlockState state){
|
||||
return state.getValue(ELEMENT).ordinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapColor getMapColor(IBlockState state, IBlockAccess world, BlockPos pos){
|
||||
return map_colours.get(state.getProperties().get(ELEMENT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getSubBlocks(CreativeTabs tab, NonNullList<ItemStack> items){
|
||||
if(this.getCreativeTab() == tab){
|
||||
for(Element element : Arrays.copyOfRange(Element.values(), 1, Element.values().length)){
|
||||
items.add(new ItemStack(this, 1, element.ordinal()));
|
||||
}
|
||||
}
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
public Element getElement() { return element; }
|
||||
|
||||
@Override
|
||||
public BlockRenderLayer getRenderLayer(){
|
||||
public MapColor getMapColor(IBlockState state, IBlockAccess world, BlockPos pos) { return map_colours.get(element); }
|
||||
|
||||
@Override
|
||||
public BlockRenderLayer getRenderLayer() {
|
||||
return BlockRenderLayer.CUTOUT; // Required to shade parts of the block faces differently to others
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getStateFromMeta(int metadata){
|
||||
Element element = Element.values()[metadata];
|
||||
if(!ELEMENT.getAllowedValues().contains(element)) return this.getDefaultState();
|
||||
return this.getDefaultState().withProperty(ELEMENT, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetaFromState(IBlockState state){
|
||||
return state.getValue(ELEMENT).ordinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockStateContainer createBlockState(){
|
||||
return new BlockStateContainer(this, ELEMENT);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+22
-43
@@ -1,5 +1,6 @@
|
||||
package electroblob.wizardry.block;
|
||||
|
||||
import electroblob.wizardry.api.IElemental;
|
||||
import electroblob.wizardry.constants.Element;
|
||||
import electroblob.wizardry.registry.WizardryTabs;
|
||||
import electroblob.wizardry.tileentity.TileEntityShrineCore;
|
||||
@@ -8,28 +9,20 @@ import net.minecraft.block.ITileEntityProvider;
|
||||
import net.minecraft.block.material.MapColor;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.properties.PropertyBool;
|
||||
import net.minecraft.block.properties.PropertyEnum;
|
||||
import net.minecraft.block.state.BlockStateContainer;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.BlockRenderLayer;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.Explosion;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumMap;
|
||||
|
||||
public class BlockPedestal extends Block implements ITileEntityProvider {
|
||||
|
||||
public static final PropertyEnum<Element> ELEMENT = PropertyEnum.create("element", Element.class,
|
||||
Arrays.copyOfRange(Element.values(), 1, Element.values().length)); // Everything except MAGIC
|
||||
public class BlockRunestonePedestal extends Block implements ITileEntityProvider, IElemental {
|
||||
|
||||
// A 'natural' pedestal is one that was generated as part of a structure, is unbreakable and has a tileentity
|
||||
public static final PropertyBool NATURAL = PropertyBool.create("natural");
|
||||
@@ -46,80 +39,66 @@ public class BlockPedestal extends Block implements ITileEntityProvider {
|
||||
map_colours.put(Element.HEALING, MapColor.YELLOW_STAINED_HARDENED_CLAY);
|
||||
}
|
||||
|
||||
public BlockPedestal(Material material){
|
||||
private final Element element;
|
||||
|
||||
public BlockRunestonePedestal(Material material, Element element) {
|
||||
super(material);
|
||||
this.setDefaultState(this.blockState.getBaseState().withProperty(ELEMENT, Element.FIRE).withProperty(NATURAL, false));
|
||||
this.setDefaultState(this.blockState.getBaseState().withProperty(NATURAL, false));
|
||||
this.setCreativeTab(WizardryTabs.WIZARDRY);
|
||||
this.setHardness(1.5F);
|
||||
this.setResistance(10.0F);
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int damageDropped(IBlockState state){
|
||||
return state.getValue(ELEMENT).ordinal(); // Ignore the NATURAL state here, it's unobtainable
|
||||
public Element getElement() {
|
||||
return element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapColor getMapColor(IBlockState state, IBlockAccess world, BlockPos pos){
|
||||
return map_colours.get(state.getProperties().get(ELEMENT));
|
||||
public MapColor getMapColor(IBlockState state, IBlockAccess world, BlockPos pos) {
|
||||
return map_colours.get(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getSubBlocks(CreativeTabs tab, NonNullList<ItemStack> items){
|
||||
// Ignore the NATURAL state here, it's unobtainable
|
||||
if(this.getCreativeTab() == tab){
|
||||
for(Element element : Arrays.copyOfRange(Element.values(), 1, Element.values().length)){
|
||||
items.add(new ItemStack(this, 1, element.ordinal()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockRenderLayer getRenderLayer(){
|
||||
public BlockRenderLayer getRenderLayer() {
|
||||
return BlockRenderLayer.CUTOUT; // Required to shade parts of the block faces differently to others
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getBlockHardness(IBlockState state, World world, BlockPos pos){
|
||||
public float getBlockHardness(IBlockState state, World world, BlockPos pos) {
|
||||
return state.getValue(NATURAL) ? -1 : super.getBlockHardness(state, world, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getExplosionResistance(World world, BlockPos pos, @Nullable Entity exploder, Explosion explosion){
|
||||
public float getExplosionResistance(World world, BlockPos pos, @Nullable Entity exploder, Explosion explosion) {
|
||||
return world.getBlockState(pos).getValue(NATURAL) ? 6000000.0F : super.getExplosionResistance(world, pos, exploder, explosion);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTileEntity(IBlockState state){
|
||||
public boolean hasTileEntity(IBlockState state) {
|
||||
return state.getValue(NATURAL); // Only naturally-generated pedestals have a (shrine core) tile entity
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TileEntity createNewTileEntity(World world, int meta){
|
||||
public TileEntity createNewTileEntity(World world, int meta) {
|
||||
return new TileEntityShrineCore();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getStateFromMeta(int metadata){
|
||||
boolean natural = false;
|
||||
if(metadata > ELEMENT.getAllowedValues().size()){
|
||||
natural = true;
|
||||
metadata -= ELEMENT.getAllowedValues().size();
|
||||
}
|
||||
Element element = Element.values()[metadata];
|
||||
if(!ELEMENT.getAllowedValues().contains(element)) return this.getDefaultState().withProperty(NATURAL, natural);
|
||||
return this.getDefaultState().withProperty(ELEMENT, element).withProperty(NATURAL, natural);
|
||||
public IBlockState getStateFromMeta(int meta) {
|
||||
return this.getDefaultState().withProperty(NATURAL, meta == 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetaFromState(IBlockState state){
|
||||
return state.getValue(ELEMENT).ordinal() + (state.getValue(NATURAL) ? ELEMENT.getAllowedValues().size() : 0);
|
||||
public int getMetaFromState(IBlockState state) {
|
||||
return state.getValue(NATURAL) ? 1 : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockStateContainer createBlockState(){
|
||||
return new BlockStateContainer(this, ELEMENT, NATURAL);
|
||||
protected BlockStateContainer createBlockState() {
|
||||
return new BlockStateContainer(this, NATURAL);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package electroblob.wizardry.client;
|
||||
|
||||
import electroblob.wizardry.CommonProxy;
|
||||
import electroblob.wizardry.Settings;
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.block.BlockBookshelf;
|
||||
import electroblob.wizardry.client.animation.ActionAnimation;
|
||||
@@ -19,6 +20,7 @@ import electroblob.wizardry.client.model.ModelSageArmour;
|
||||
import electroblob.wizardry.client.model.ModelWizardArmour;
|
||||
import electroblob.wizardry.client.particle.*;
|
||||
import electroblob.wizardry.client.particle.ParticleWizardry.IWizardryParticleFactory;
|
||||
import electroblob.wizardry.client.renderer.RenderSpectralGolem;
|
||||
import electroblob.wizardry.client.renderer.entity.*;
|
||||
import electroblob.wizardry.client.renderer.entity.layers.*;
|
||||
import electroblob.wizardry.client.renderer.overlay.RenderBlinkEffect;
|
||||
@@ -164,7 +166,8 @@ public class ClientProxy extends CommonProxy {
|
||||
IResourceManager manager = Minecraft.getMinecraft().getResourceManager();
|
||||
if(manager instanceof IReloadableResourceManager){
|
||||
((IReloadableResourceManager)manager).registerReloadListener(GuiSpellDisplay::loadSkins);
|
||||
((IReloadableResourceManager)manager).registerReloadListener(GuiWizardHandbook::loadHandbookFile);
|
||||
if (Wizardry.settings.loadHandbook)
|
||||
((IReloadableResourceManager)manager).registerReloadListener(GuiWizardHandbook::loadHandbookFile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -728,6 +731,9 @@ public class ClientProxy extends CommonProxy {
|
||||
LayerTiledOverlay.initialiseLayers(LayerMindControl::new);
|
||||
LayerTiledOverlay.initialiseLayers(LayerSummonAnimation::new);
|
||||
LayerTiledOverlay.initialiseLayers(LayerDisintegrateAnimation::new);
|
||||
LayerTiledOverlay.initialiseLayers(LayerOak::new);
|
||||
LayerTiledOverlay.initialiseLayers(LayerIron::new);
|
||||
LayerTiledOverlay.initialiseLayers(LayerDiamond::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -766,6 +772,7 @@ public class ClientProxy extends CommonProxy {
|
||||
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityIceGiant.class, RenderIceGiant::new);
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityPhoenix.class, RenderPhoenix::new);
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntitySpectralGolem.class, RenderSpectralGolem::new);
|
||||
|
||||
// Projectiles
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityMagicMissile.class, manager -> new RenderMagicArrow(manager,
|
||||
@@ -780,6 +787,7 @@ public class ClientProxy extends CommonProxy {
|
||||
new ResourceLocation(Wizardry.MODID, "textures/entity/ice_lance.png"), false, 16.0, 3.0, 22, 5, false));
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityFlamecatcherArrow.class, manager -> new RenderMagicArrow(manager,
|
||||
new ResourceLocation(Wizardry.MODID, "textures/entity/flamecatcher_arrow.png"), false, 8, 2.0, 16, 5, true));
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityConjuredArrow.class, RenderConjuredArrow::new);
|
||||
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityForceArrow.class, RenderForceArrow::new);
|
||||
|
||||
|
||||
@@ -151,7 +151,7 @@ class Contents {
|
||||
int x = GuiWizardHandbook.isRightPage(startPage) ? left + GuiWizardHandbook.GUI_WIDTH - GuiWizardHandbook.TEXT_INSET_X - GuiWizardHandbook.PAGE_WIDTH : left + GuiWizardHandbook.TEXT_INSET_X;
|
||||
int y = top + GuiWizardHandbook.TEXT_INSET_Y + startLine * font.FONT_HEIGHT;
|
||||
|
||||
list.add(new GuiButtonHyperlink.Internal(0, x, y, font, entry.title, entry, 0, "", maxLineNumber-startLine, GuiWizardHandbook.isRightPage(startPage)));
|
||||
list.add(new GuiButtonHyperlink.Internal(0, x, y, font, entry.title, entry, 0, "", maxLineNumber-startLine, GuiWizardHandbook.isRightPage(startPage), false));
|
||||
|
||||
startLine++;
|
||||
|
||||
|
||||
@@ -28,15 +28,17 @@ public abstract class GuiButtonHyperlink extends GuiButton {
|
||||
final List<String> lines;
|
||||
final int linesLeft;
|
||||
|
||||
GuiButtonHyperlink(int id, int x, int y, FontRenderer font, String text, int indent, String suffix, int linesLeft, boolean rightPage){
|
||||
GuiButtonHyperlink(int id, int x, int y, FontRenderer font, String text, int indent, String suffix, int linesLeft, boolean rightPage, boolean spaceless){
|
||||
|
||||
super(id, x, y, font.getStringWidth(text), font.FONT_HEIGHT, text);
|
||||
|
||||
// Sometimes a link has punctuation or something after it that causes it to wrap onto a new line
|
||||
String linkWithSuffix = text + suffix;
|
||||
|
||||
// If the string won't fit any words at the end of the current line, treat it as if we started a new line
|
||||
if(font.getStringWidth(linkWithSuffix.split("\\s")[0]) > GuiWizardHandbook.PAGE_WIDTH - indent){
|
||||
// If the string won't fit any words (or characters in a spaceless language) at the end of the current line,
|
||||
// treat it as if we started a new line
|
||||
String firstWord = spaceless ? linkWithSuffix.substring(0, 1) : linkWithSuffix.split("\\s")[0];
|
||||
if(font.getStringWidth(firstWord) > GuiWizardHandbook.PAGE_WIDTH - indent){
|
||||
indent = 0;
|
||||
this.y += font.FONT_HEIGHT;
|
||||
}
|
||||
@@ -149,7 +151,7 @@ public abstract class GuiButtonHyperlink extends GuiButton {
|
||||
* @throws IllegalArgumentException if the given argument array is empty or contains more than 2 arguments
|
||||
* @throws JsonSyntaxException if the specified link target is not a URL or a valid section ID
|
||||
*/
|
||||
public static GuiButtonHyperlink create(int x, int y, FontRenderer font, List<String> upToLink, String[] arguments, String suffix, int linesLeft, boolean rightPage){
|
||||
public static GuiButtonHyperlink create(int x, int y, FontRenderer font, List<String> upToLink, String[] arguments, String suffix, int linesLeft, boolean rightPage, boolean spaceless){
|
||||
|
||||
if(arguments.length == 0 || arguments.length > 2) throw new IllegalArgumentException("Incorrect array length!");
|
||||
|
||||
@@ -158,7 +160,7 @@ public abstract class GuiButtonHyperlink extends GuiButton {
|
||||
if(arguments[0].matches(URL_REGEX)){
|
||||
|
||||
button = new GuiButtonHyperlink.External(0, x, y, font, arguments[arguments.length - 1], arguments[0],
|
||||
font.getStringWidth(upToLink.get(upToLink.size() - 1)), suffix, linesLeft, rightPage);
|
||||
font.getStringWidth(upToLink.get(upToLink.size() - 1)), suffix, linesLeft, rightPage, spaceless);
|
||||
|
||||
}else{
|
||||
|
||||
@@ -167,7 +169,7 @@ public abstract class GuiButtonHyperlink extends GuiButton {
|
||||
if(target == null) throw new JsonSyntaxException("Hyperlink points to nonexistent section id " + arguments[0]);
|
||||
|
||||
button = new GuiButtonHyperlink.Internal(0, x, y, font, arguments[arguments.length - 1],
|
||||
target, font.getStringWidth(upToLink.get(upToLink.size() - 1)), suffix, linesLeft, rightPage);
|
||||
target, font.getStringWidth(upToLink.get(upToLink.size() - 1)), suffix, linesLeft, rightPage, spaceless);
|
||||
}
|
||||
|
||||
return button;
|
||||
@@ -177,8 +179,8 @@ public abstract class GuiButtonHyperlink extends GuiButton {
|
||||
|
||||
final Section target;
|
||||
|
||||
Internal(int id, int x, int y, FontRenderer font, String text, Section target, int indent, String suffix, int linesLeft, boolean rightPage){
|
||||
super(id, x, y, font, text, indent, suffix, linesLeft, rightPage);
|
||||
Internal(int id, int x, int y, FontRenderer font, String text, Section target, int indent, String suffix, int linesLeft, boolean rightPage, boolean spaceless){
|
||||
super(id, x, y, font, text, indent, suffix, linesLeft, rightPage, spaceless);
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@@ -216,8 +218,8 @@ public abstract class GuiButtonHyperlink extends GuiButton {
|
||||
|
||||
final ITextComponent link;
|
||||
|
||||
External(int id, int x, int y, FontRenderer font, String text, String url, int indent, String suffix, int linesLeft, boolean rightPage){
|
||||
super(id, x, y, font, text, indent, suffix, linesLeft, rightPage);
|
||||
External(int id, int x, int y, FontRenderer font, String text, String url, int indent, String suffix, int linesLeft, boolean rightPage, boolean spaceless){
|
||||
super(id, x, y, font, text, indent, suffix, linesLeft, rightPage, spaceless);
|
||||
this.link = new TextComponentString(text);
|
||||
link.getStyle().setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, url)).setColor(TextFormatting.DARK_BLUE);
|
||||
}
|
||||
|
||||
@@ -496,24 +496,30 @@ public class GuiWizardHandbook extends GuiScreen {
|
||||
|
||||
Section currentSection = null;
|
||||
|
||||
for(Section section : sections.values()){
|
||||
// We always want this button to do something, and taking the right-hand page means it always does
|
||||
if(section.containsPage(doubleToSinglePage(currentPage, true))){
|
||||
currentSection = section;
|
||||
break;
|
||||
if(currentPage < singleToDoublePage(pageCount)){
|
||||
// Find current section
|
||||
for(Section section : sections.values()){
|
||||
// Take the right-hand page if going to the next section, and the left-hand page otherwise
|
||||
if(section.containsPage(doubleToSinglePage(currentPage, button == nextSection))){
|
||||
currentSection = section;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(currentSection != null){
|
||||
List<Section> visibleSections = new ArrayList<>(sectionList);
|
||||
visibleSections.removeIf(s -> !s.isUnlocked());
|
||||
|
||||
List<Section> visibleSections = new ArrayList<>(sectionList);
|
||||
visibleSections.removeIf(s -> !s.isUnlocked());
|
||||
int index = currentSection == null ? visibleSections.size() : visibleSections.indexOf(currentSection);
|
||||
|
||||
int index = visibleSections.indexOf(currentSection);
|
||||
|
||||
if(button == nextSection && index + 1 < visibleSections.size()){
|
||||
if(button == nextSection){
|
||||
if(index + 1 < visibleSections.size()){
|
||||
currentPage = singleToDoublePage(visibleSections.get(index + 1).startPage);
|
||||
}else if(index > 0){
|
||||
}else{
|
||||
currentPage = singleToDoublePage(pageCount);
|
||||
}
|
||||
}else{
|
||||
if(index > 0){
|
||||
currentPage = singleToDoublePage(visibleSections.get(index - 1).startPage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package electroblob.wizardry.client.gui.handbook;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Streams;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
@@ -35,6 +36,8 @@ import java.util.*;
|
||||
// be a non-static inner class
|
||||
class Section {
|
||||
|
||||
private static final Set<String> SPACELESS_LANGUAGES = ImmutableSet.of("zh_cn", "zh_tw");
|
||||
|
||||
// Final fields are mandatory (none here though), the rest are optional
|
||||
String title;
|
||||
private String[] rawText;
|
||||
@@ -293,7 +296,11 @@ class Section {
|
||||
|
||||
String linkRaw = paragraph.substring(linkStart, linkEnd + 1);
|
||||
String[] arguments = paragraph.substring(linkStart + 1, linkEnd).split("\\s", 2);
|
||||
String suffix = paragraph.substring(linkEnd).split("\\s", 2)[0].substring(1); // substring(1) to remove the @
|
||||
String suffix = "";
|
||||
|
||||
// Account for trailing punctuation, except in languages that don't use spaces such as Chinese
|
||||
boolean spaceless = SPACELESS_LANGUAGES.contains(Minecraft.getMinecraft().getLanguageManager().getCurrentLanguage().getLanguageCode());
|
||||
if(!spaceless) paragraph.substring(linkEnd).split("\\s", 2)[0].substring(1); // substring(1) to remove the @
|
||||
|
||||
// The index of the single page currently being formatted, relative to the section
|
||||
int pageRelative = (lines.size() + upToLink.size() - 1) / maxLineNumber;
|
||||
@@ -311,7 +318,7 @@ class Section {
|
||||
}
|
||||
|
||||
// The button id only does what you use it for, so we're just not using it at all.
|
||||
this.buttons.get(pageRelative).add(GuiButtonHyperlink.create(x, y, font, upToLink, arguments, suffix, maxLineNumber - lineNumber - 1, GuiWizardHandbook.isRightPage(page)));
|
||||
this.buttons.get(pageRelative).add(GuiButtonHyperlink.create(x, y, font, upToLink, arguments, suffix, maxLineNumber - lineNumber - 1, GuiWizardHandbook.isRightPage(page), spaceless));
|
||||
|
||||
// The link button should exactly overlay the display text in the main string
|
||||
// If the link has no display text specified, it displays the unformatted target string
|
||||
|
||||
@@ -13,17 +13,17 @@ import net.minecraftforge.client.model.IModel;
|
||||
import net.minecraftforge.client.model.ModelLoaderRegistry;
|
||||
import net.minecraftforge.common.model.IModelState;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ModelBookshelf implements IModel {
|
||||
|
||||
private static final ResourceLocation DEFAULT_BOOK_TEXTURE = new ResourceLocation(Wizardry.MODID, "blocks/books");
|
||||
//private static final ResourceLocation DEFAULT_BOOK_TEXTURE = new ResourceLocation(Wizardry.MODID, "blocks/books");
|
||||
|
||||
private static final List<ResourceLocation> bookModelLocations = new ArrayList<>();
|
||||
|
||||
private static final Map<String, IBakedModel[][]> bakedBookModels = new HashMap<>();
|
||||
|
||||
private final ModelResourceLocation bookshelfModelLocation;
|
||||
private final String variant;
|
||||
|
||||
@@ -49,19 +49,7 @@ public class ModelBookshelf implements IModel {
|
||||
// I don't know why default state works here (surely it ought to be the state param?), but it works so who cares
|
||||
IBakedModel bookshelf = bookshelfModel.bake(bookshelfModel.getDefaultState(), format, bakedTextureGetter);
|
||||
|
||||
ImmutableList<ResourceLocation> textures = BlockBookshelf.getBookTextures();
|
||||
|
||||
IBakedModel[][] books = new IBakedModel[textures.size()][BlockBookshelf.SLOT_COUNT];
|
||||
|
||||
for(int i = 0; i < textures.size(); i++){
|
||||
|
||||
ImmutableMap<String, String> retexturer = ImmutableMap.of("books", textures.get(i).toString());
|
||||
|
||||
for(int j = 0; j < BlockBookshelf.SLOT_COUNT; j++){
|
||||
IModel bookModel = ModelLoaderRegistry.getModel(new ModelResourceLocation(bookModelLocations.get(j), variant)).retexture(retexturer);
|
||||
books[i][j] = bookModel.bake(bookModel.getDefaultState(), format, bakedTextureGetter); // Same here!
|
||||
}
|
||||
}
|
||||
IBakedModel[][] books = getBakedBookModels(format, bakedTextureGetter);
|
||||
|
||||
// To clarify: the whole point of doing this was to avoid having to bake 4 * 2^12 models per bookshelf type
|
||||
// Therefore we have to have a baked bookshelf model that's kind of dynamic
|
||||
@@ -74,6 +62,29 @@ public class ModelBookshelf implements IModel {
|
||||
|
||||
}
|
||||
|
||||
/** Retrieves the baked book models, or bakes them if they haven't been created yet. */
|
||||
protected IBakedModel[][] getBakedBookModels(VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter) throws Exception{
|
||||
|
||||
if(bakedBookModels.get(variant) == null){
|
||||
|
||||
ImmutableList<ResourceLocation> textures = BlockBookshelf.getBookTextures();
|
||||
|
||||
bakedBookModels.put(variant, new IBakedModel[textures.size()][BlockBookshelf.SLOT_COUNT]);
|
||||
|
||||
for(int i = 0; i < textures.size(); i++){
|
||||
|
||||
ImmutableMap<String, String> retexturer = ImmutableMap.of("books", textures.get(i).toString());
|
||||
|
||||
for(int j = 0; j < BlockBookshelf.SLOT_COUNT; j++){
|
||||
IModel bookModel = ModelLoaderRegistry.getModel(new ModelResourceLocation(bookModelLocations.get(j), variant)).retexture(retexturer);
|
||||
bakedBookModels.get(variant)[i][j] = bookModel.bake(bookModel.getDefaultState(), format, bakedTextureGetter); // Same here!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bakedBookModels.get(variant);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ResourceLocation> getDependencies(){
|
||||
return bookModelLocations;
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
package electroblob.wizardry.client.model;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.block.BlockCrystal;
|
||||
import electroblob.wizardry.block.BlockPedestal;
|
||||
import electroblob.wizardry.block.BlockRunestone;
|
||||
import electroblob.wizardry.block.BlockRunestonePedestal;
|
||||
import electroblob.wizardry.item.IMultiTexturedItem;
|
||||
import electroblob.wizardry.item.ItemBlockMultiTextured;
|
||||
import electroblob.wizardry.item.ItemCrystal;
|
||||
import electroblob.wizardry.item.ItemSpectralDust;
|
||||
import electroblob.wizardry.registry.WizardryBlocks;
|
||||
import electroblob.wizardry.registry.WizardryItems;
|
||||
import net.minecraft.block.BlockPlanks;
|
||||
@@ -50,35 +46,12 @@ public final class WizardryModels {
|
||||
@SubscribeEvent
|
||||
public static void register(ModelRegistryEvent event){
|
||||
|
||||
// ItemBlocks
|
||||
|
||||
ModelLoader.setCustomStateMapper(WizardryBlocks.crystal_block, new StateMap.Builder()
|
||||
.withName(BlockCrystal.ELEMENT).withSuffix("_crystal_block").build());
|
||||
// Yay unchecked casting! But we know it's always ok here, and it makes everything much neater.
|
||||
ItemBlockMultiTextured crystalBlockItem = (ItemBlockMultiTextured)Item.getItemFromBlock(WizardryBlocks.crystal_block);
|
||||
registerMultiTexturedModel(crystalBlockItem);
|
||||
|
||||
ModelLoader.setCustomStateMapper(WizardryBlocks.runestone, new StateMap.Builder()
|
||||
.withName(BlockRunestone.ELEMENT).withSuffix("_runestone").build());
|
||||
ItemBlockMultiTextured runestoneItem = (ItemBlockMultiTextured)Item.getItemFromBlock(WizardryBlocks.runestone);
|
||||
registerMultiTexturedModel(runestoneItem);
|
||||
|
||||
ModelLoader.setCustomStateMapper(WizardryBlocks.runestone_pedestal, new StateMap.Builder()
|
||||
.withName(BlockPedestal.ELEMENT).ignore(BlockPedestal.NATURAL).withSuffix("_runestone_pedestal").build()); // Don't care about NATURAL property
|
||||
ItemBlockMultiTextured pedestalItem = (ItemBlockMultiTextured)Item.getItemFromBlock(WizardryBlocks.runestone_pedestal);
|
||||
registerMultiTexturedModel(pedestalItem);
|
||||
|
||||
ModelLoader.setCustomStateMapper(WizardryBlocks.gilded_wood, new StateMap.Builder()
|
||||
.withName(BlockPlanks.VARIANT).withSuffix("_gilded_wood").build());
|
||||
ItemBlockMultiTextured gildedWoodItem = (ItemBlockMultiTextured)Item.getItemFromBlock(WizardryBlocks.gilded_wood);
|
||||
registerMultiTexturedModel(gildedWoodItem);
|
||||
|
||||
// Explanation for all this here -> https://github.com/TheGreyGhost/MinecraftByExample/tree/master/src/main/java/minecraftbyexample/mbe05_block_dynamic_block_model2
|
||||
ModelLoaderRegistry.registerLoader(new ModelLoaderBookshelf());
|
||||
|
||||
// Items
|
||||
|
||||
registerMultiTexturedModel((ItemCrystal)WizardryItems.magic_crystal);
|
||||
//registerMultiTexturedModel((ItemCrystal)WizardryItems.magic_crystal);
|
||||
|
||||
registerWandModel(WizardryItems.magic_wand);
|
||||
registerWandModel(WizardryItems.apprentice_wand);
|
||||
@@ -121,8 +94,6 @@ public final class WizardryModels {
|
||||
registerWandModel(WizardryItems.master_sorcery_wand);
|
||||
registerWandModel(WizardryItems.master_healing_wand);
|
||||
|
||||
registerMultiTexturedModel((ItemSpectralDust)WizardryItems.spectral_dust);
|
||||
|
||||
// Automatic item model registry
|
||||
for(Item item : Item.REGISTRY){
|
||||
if(!registeredItems.contains(item) && item.getRegistryName().getNamespace().equals(Wizardry.MODID)){
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -46,7 +46,5 @@ 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;
|
||||
|
||||
}
|
||||
|
||||
@@ -30,14 +30,23 @@ public enum Element implements IStringSerializable {
|
||||
/** The {@link ResourceLocation} for this element's 8x8 icon (displayed in the arcane workbench GUI) */
|
||||
private final ResourceLocation icon;
|
||||
|
||||
private String modid;
|
||||
/** true if this element should have worldgen structures generated (Obelisk, Shrine) */
|
||||
private final boolean worldgen;
|
||||
/** true if evil/good wizards of this element should naturally spawn */
|
||||
private final boolean wizards;
|
||||
|
||||
Element(Style colour, String name){
|
||||
this(colour, name, Wizardry.MODID);
|
||||
this(colour, name, Wizardry.MODID, true, true);
|
||||
}
|
||||
|
||||
Element(Style colour, String name, String modid){
|
||||
Element(Style colour, String name, String modid, boolean worldgen, boolean wizards){
|
||||
this.colour = colour;
|
||||
this.unlocalisedName = name;
|
||||
this.icon = new ResourceLocation(modid, "textures/gui/container/element_icon_" + unlocalisedName + ".png");
|
||||
this.modid = modid;
|
||||
this.worldgen = worldgen;
|
||||
this.wizards = wizards;
|
||||
}
|
||||
|
||||
/** Returns the element with the given name, or throws an {@link java.lang.IllegalArgumentException} if no such
|
||||
@@ -93,4 +102,10 @@ public enum Element implements IStringSerializable {
|
||||
public ResourceLocation getIcon(){
|
||||
return icon;
|
||||
}
|
||||
|
||||
public boolean hasWorldgen() { return worldgen; }
|
||||
|
||||
public boolean hasWizards() { return wizards; }
|
||||
|
||||
public String getModid() { return modid; }
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ import java.util.Iterator;
|
||||
* than having to deal with each of them separately, which would be inefficient and cumbersome (the former of those
|
||||
* classes cannot extend the latter because they both need to extend different subclasses of
|
||||
* {@link net.minecraft.enchantment.Enchantment}).
|
||||
*
|
||||
*
|
||||
* @since Wizardry 1.2
|
||||
*/
|
||||
@Mod.EventBusSubscriber
|
||||
@@ -69,12 +69,16 @@ public interface Imbuement {
|
||||
Enchantment enchantment = Enchantment.getEnchantmentByID(enchantmentTag.getShort("id"));
|
||||
// If the item contains a magic weapon enchantment, remove it from the item
|
||||
if(enchantment instanceof Imbuement){
|
||||
((Imbuement) enchantment).onImbuementRemoval(stack);
|
||||
enchantmentIt.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Allows executing some custom logic before this imbuement is being removed from the stack. Called when the imbuement is about to be removed. */
|
||||
default void onImbuementRemoval(ItemStack stack){}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onPlayerOpenContainerEvent(PlayerContainerEvent event){
|
||||
// Brute-force fix to stop enchanted books in dungeon chests from having imbuements on them.
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
package electroblob.wizardry.entity.construct;
|
||||
|
||||
import electroblob.wizardry.entity.projectile.EntityConjuredArrow;
|
||||
import electroblob.wizardry.registry.Spells;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
import net.minecraft.entity.projectile.EntityTippedArrow;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
@@ -30,7 +28,7 @@ public class EntityArrowRain extends EntityScaledConstruct {
|
||||
double y = posY + world.rand.nextDouble() * (double)height;
|
||||
double z = posZ + (world.rand.nextDouble() - 0.5D) * (double)width;
|
||||
|
||||
EntityTippedArrow arrow = new EntityTippedArrow(world, x, y, z);
|
||||
EntityConjuredArrow arrow = new EntityConjuredArrow(world, x, y, z);
|
||||
|
||||
arrow.motionX = MathHelper.cos((float)Math.toRadians(this.rotationYaw + 90));
|
||||
arrow.motionY = -0.6;
|
||||
@@ -38,7 +36,6 @@ public class EntityArrowRain extends EntityScaledConstruct {
|
||||
|
||||
arrow.shootingEntity = this.getCaster();
|
||||
arrow.setDamage(7.0d * damageMultiplier);
|
||||
arrow.setPotionEffect(new ItemStack(Items.ARROW));
|
||||
|
||||
this.world.spawnEntity(arrow);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ public class EntityFireRing extends EntityScaledConstruct {
|
||||
|
||||
super.onUpdate();
|
||||
|
||||
if(!this.world.isRemote){
|
||||
if(this.ticksExisted % 5 == 0 && !this.world.isRemote){
|
||||
|
||||
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(width/2, this.posX, this.posY, this.posZ, this.world);
|
||||
|
||||
|
||||
@@ -168,6 +168,10 @@ public class EntityForcefield extends EntityMagicConstruct implements ICustomHit
|
||||
((EntityPlayerMP)target).connection.sendPacket(new SPacketEntityVelocity(target));
|
||||
}
|
||||
|
||||
if (this.ticksExisted % 5 == 0) {
|
||||
this.lifetime = (int) (lifetime * 0.99);
|
||||
}
|
||||
|
||||
}else{
|
||||
|
||||
Vec3d relativeImpactPos = targetRelativePos.normalize().scale(radius);
|
||||
|
||||
@@ -68,13 +68,15 @@ public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntity
|
||||
/** Data parameter for the wizard's element. */
|
||||
private static final DataParameter<Integer> ELEMENT = EntityDataManager.createKey(EntityEvilWizard.class,
|
||||
DataSerializers.VARINT);
|
||||
/** Data parameters for the wizard's current continuous spell. */
|
||||
private static final DataParameter<String> CONTINUOUS_SPELL = EntityDataManager.createKey(EntityEvilWizard.class, DataSerializers.STRING);
|
||||
private static final DataParameter<Integer> SPELL_COUNTER = EntityDataManager.createKey(EntityEvilWizard.class, DataSerializers.VARINT);
|
||||
|
||||
/** The resource location for the evil wizard's loot table. */
|
||||
private static final ResourceLocation LOOT_TABLE = new ResourceLocation(Wizardry.MODID, "entities/evil_wizard");
|
||||
|
||||
// Field implementations
|
||||
private List<Spell> spells = new ArrayList<Spell>(4);
|
||||
private Spell continuousSpell;
|
||||
private int spellCounter;
|
||||
|
||||
public EntityEvilWizard(World world){
|
||||
|
||||
@@ -93,6 +95,8 @@ public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntity
|
||||
super.entityInit();
|
||||
this.dataManager.register(HEAL_COOLDOWN, -1);
|
||||
this.dataManager.register(ELEMENT, -1);
|
||||
this.dataManager.register(CONTINUOUS_SPELL, "ebwizardry:none");
|
||||
this.dataManager.register(SPELL_COUNTER, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -168,23 +172,23 @@ public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntity
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContinuousSpell(Spell spell){
|
||||
this.continuousSpell = spell;
|
||||
public void setContinuousSpell(Spell spell) {
|
||||
this.dataManager.set(CONTINUOUS_SPELL, spell.getRegistryName().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spell getContinuousSpell(){
|
||||
return this.continuousSpell;
|
||||
public Spell getContinuousSpell() {
|
||||
return Spell.get(this.dataManager.get(CONTINUOUS_SPELL));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpellCounter(int count){
|
||||
spellCounter = count;
|
||||
public void setSpellCounter(int count) {
|
||||
this.dataManager.set(SPELL_COUNTER, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSpellCounter(){
|
||||
return spellCounter;
|
||||
public int getSpellCounter() {
|
||||
return this.dataManager.get(SPELL_COUNTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -361,7 +365,8 @@ public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntity
|
||||
|
||||
if(getElement() == null){
|
||||
if(rand.nextBoolean()){
|
||||
this.setElement(Element.values()[rand.nextInt(Element.values().length - 1) + 1]);
|
||||
Element[] elements = (Element[]) Arrays.stream(Element.values()).filter(Element::hasWizards).toArray();
|
||||
this.setElement(elements[rand.nextInt(elements.length - 1) + 1]);
|
||||
}else{
|
||||
this.setElement(Element.MAGIC);
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ public class EntityMagicSlime extends EntitySlime implements ISummonedCreature {
|
||||
super(world);
|
||||
this.setPosition(target.posX, target.posY, target.posZ);
|
||||
this.startRiding(target);
|
||||
this.setOwnerId(caster.getUniqueID());
|
||||
if (caster != null) this.setOwnerId(caster.getUniqueID());
|
||||
this.setSlimeSize(2, false); // Needs to be called before setting the experience value to 0
|
||||
this.experienceValue = 0;
|
||||
this.lifetime = lifetime;
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
package electroblob.wizardry.entity.living;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.util.ParticleBuilder;
|
||||
import net.minecraft.entity.EntityFlying;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.ai.EntityAIAttackMelee;
|
||||
import net.minecraft.entity.ai.EntityAIHurtByTarget;
|
||||
import net.minecraft.entity.ai.EntityAILookAtVillager;
|
||||
import net.minecraft.entity.ai.EntityAILookIdle;
|
||||
import net.minecraft.entity.ai.EntityAIMoveThroughVillage;
|
||||
import net.minecraft.entity.ai.EntityAIMoveTowardsRestriction;
|
||||
import net.minecraft.entity.ai.EntityAIMoveTowardsTarget;
|
||||
import net.minecraft.entity.ai.EntityAINearestAttackableTarget;
|
||||
import net.minecraft.entity.ai.EntityAIWanderAvoidWater;
|
||||
import net.minecraft.entity.ai.EntityAIWatchClosest;
|
||||
import net.minecraft.entity.monster.EntityIronGolem;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.datasync.DataParameter;
|
||||
import net.minecraft.network.datasync.DataSerializers;
|
||||
import net.minecraft.network.datasync.EntityDataManager;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.EnumParticleTypes;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
import net.minecraft.world.DifficultyInstance;
|
||||
import net.minecraft.world.EnumDifficulty;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class EntitySpectralGolem extends EntityIronGolem implements ISummonedCreature {
|
||||
|
||||
private static final DataParameter<Boolean> SPAWN_PARTICLES = EntityDataManager.createKey(EntitySpectralGolem.class, DataSerializers.BOOLEAN);
|
||||
|
||||
// Field implementations
|
||||
private int lifetime = -1;
|
||||
private UUID casterUUID;
|
||||
|
||||
// Setter + getter implementations
|
||||
@Override public int getLifetime(){ return lifetime; }
|
||||
@Override public void setLifetime(int lifetime){ this.lifetime = lifetime; }
|
||||
@Override public UUID getOwnerId(){ return casterUUID; }
|
||||
@Override public void setOwnerId(UUID uuid){ this.casterUUID = uuid; }
|
||||
|
||||
/** Creates a new golem minion in the given world. */
|
||||
public EntitySpectralGolem(World world){
|
||||
super(world);
|
||||
this.experienceValue = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void entityInit(){
|
||||
super.entityInit();
|
||||
this.dataManager.register(SPAWN_PARTICLES, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initEntityAI() {
|
||||
this.tasks.addTask(1, new EntityAIAttackMelee(this, 1.0D, true));
|
||||
this.tasks.addTask(2, new EntityAIMoveTowardsTarget(this, 0.9D, 32.0F));
|
||||
this.tasks.addTask(3, new EntityAIMoveThroughVillage(this, 0.6D, true));
|
||||
this.tasks.addTask(4, new EntityAIMoveTowardsRestriction(this, 1.0D));
|
||||
this.tasks.addTask(5, new EntityAILookAtVillager(this));
|
||||
this.tasks.addTask(6, new EntityAIWanderAvoidWater(this, 0.6D));
|
||||
this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F));
|
||||
this.tasks.addTask(8, new EntityAILookIdle(this));
|
||||
this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false));
|
||||
this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityLivingBase.class,
|
||||
0, false, true, this.getTargetSelector()));
|
||||
}
|
||||
|
||||
@Override protected void setEquipmentBasedOnDifficulty(DifficultyInstance difficulty){} // They don't have equipment!
|
||||
|
||||
// Implementations
|
||||
|
||||
@Override
|
||||
public void setRevengeTarget(EntityLivingBase entity){
|
||||
if(this.shouldRevengeTarget(entity)) super.setRevengeTarget(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(){
|
||||
super.onUpdate();
|
||||
this.updateDelegate();
|
||||
|
||||
// Adds a dust particle effect
|
||||
if(this.world.isRemote){
|
||||
double x = this.posX - this.width / 2 + this.rand.nextFloat() * width;
|
||||
double y = this.posY + this.height * this.rand.nextFloat() + 0.2f;
|
||||
double z = this.posZ - this.width / 2 + this.rand.nextFloat() * width;
|
||||
ParticleBuilder.create(ParticleBuilder.Type.DUST).pos(x, y, z).clr(0.7f, 0.9f, 1).shaded(true).spawn(world);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpawn(){
|
||||
if(this.dataManager.get(SPAWN_PARTICLES)) this.spawnParticleEffect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDespawn(){
|
||||
this.spawnParticleEffect();
|
||||
}
|
||||
|
||||
private void spawnParticleEffect(){
|
||||
if(this.world.isRemote){
|
||||
for(int i = 0; i < 15; i++){
|
||||
this.world.spawnParticle(EnumParticleTypes.SMOKE_LARGE, this.posX + this.rand.nextFloat() - 0.5f,
|
||||
this.posY + this.rand.nextFloat() * 2, this.posZ + this.rand.nextFloat() - 0.5f, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasParticleEffect(){
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAnimation(){
|
||||
return this.dataManager.get(SPAWN_PARTICLES) || this.ticksExisted > 20;
|
||||
}
|
||||
|
||||
public void hideParticles(){
|
||||
this.dataManager.set(SPAWN_PARTICLES, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean processInteract(EntityPlayer player, EnumHand hand){
|
||||
// In this case, the delegate method determines whether super is called.
|
||||
// Rather handily, we can make use of Java's short-circuiting method of evaluating OR statements.
|
||||
return this.interactDelegate(player, hand) || super.processInteract(player, hand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeEntityToNBT(NBTTagCompound nbttagcompound){
|
||||
super.writeEntityToNBT(nbttagcompound);
|
||||
this.writeNBTDelegate(nbttagcompound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readEntityFromNBT(NBTTagCompound nbttagcompound){
|
||||
super.readEntityFromNBT(nbttagcompound);
|
||||
this.readNBTDelegate(nbttagcompound);
|
||||
}
|
||||
|
||||
// Recommended overrides
|
||||
|
||||
@Override protected int getExperiencePoints(EntityPlayer player){ return 0; }
|
||||
@Override protected boolean canDropLoot(){ return false; }
|
||||
@Override protected Item getDropItem(){ return null; }
|
||||
@Override protected ResourceLocation getLootTable(){ return null; }
|
||||
@Override public boolean canPickUpLoot(){ return false; }
|
||||
|
||||
// This vanilla method has nothing to do with the custom despawn() method.
|
||||
@Override protected boolean canDespawn(){
|
||||
return getCaster() == null && getOwnerId() == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getCanSpawnHere(){
|
||||
return this.world.getDifficulty() != EnumDifficulty.PEACEFUL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAttackClass(Class<? extends EntityLivingBase> entityType){
|
||||
// Returns true unless the given entity type is a flying entity.
|
||||
return !EntityFlying.class.isAssignableFrom(entityType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITextComponent getDisplayName(){
|
||||
if(getCaster() != null){
|
||||
return new TextComponentTranslation(NAMEPLATE_TRANSLATION_KEY, getCaster().getName(),
|
||||
new TextComponentTranslation("entity." + this.getEntityString() + ".name"));
|
||||
}else{
|
||||
return super.getDisplayName();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCustomName(){
|
||||
// If this returns true, the renderer will show the nameplate when looking directly at the entity
|
||||
return Wizardry.settings.summonedCreatureNames && getCaster() != null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -47,6 +47,7 @@ import net.minecraftforge.common.util.FakePlayer;
|
||||
import net.minecraftforge.event.world.BlockEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.registry.ForgeRegistries;
|
||||
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
@@ -71,7 +72,7 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
/** The wizard's current customer. */
|
||||
@Nullable
|
||||
private EntityPlayer customer;
|
||||
|
||||
|
||||
private int timeUntilReset;
|
||||
|
||||
/** addDefaultEquipmentAndRecipies is called if this is true */
|
||||
@@ -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
|
||||
@@ -254,11 +258,11 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
|
||||
@Override
|
||||
public ITextComponent getDisplayName(){
|
||||
|
||||
|
||||
if(this.hasCustomName()){
|
||||
return super.getDisplayName();
|
||||
}
|
||||
|
||||
|
||||
return this.getElement().getWizardName();
|
||||
}
|
||||
|
||||
@@ -266,7 +270,7 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
protected boolean canDespawn(){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected SoundEvent getAmbientSound(){
|
||||
if(Wizardry.tisTheSeason) return WizardrySounds.ENTITY_WIZARD_HOHOHO;
|
||||
@@ -634,10 +638,9 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0 && !specialismSpells.isEmpty()){
|
||||
// This means it is more likely for spell books sold to be of the same element as the wizard if the
|
||||
// wizard has an element.
|
||||
return new ItemStack(WizardryItems.spell_book, 1,
|
||||
specialismSpells.get(rand.nextInt(specialismSpells.size())).metadata());
|
||||
return getBookStackForSpell(specialismSpells.get(rand.nextInt(specialismSpells.size())));
|
||||
}else{
|
||||
return new ItemStack(WizardryItems.spell_book, 1, spells.get(rand.nextInt(spells.size())).metadata());
|
||||
return getBookStackForSpell(spells.get(rand.nextInt(spells.size())));
|
||||
}
|
||||
}else{
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0){
|
||||
@@ -656,10 +659,9 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0 && !specialismSpells.isEmpty()){
|
||||
// This means it is more likely for spell books sold to be of the same element as the wizard if the
|
||||
// wizard has an element.
|
||||
return new ItemStack(WizardryItems.spell_book, 1,
|
||||
specialismSpells.get(rand.nextInt(specialismSpells.size())).metadata());
|
||||
return getBookStackForSpell(specialismSpells.get(rand.nextInt(specialismSpells.size())));
|
||||
}else{
|
||||
return new ItemStack(WizardryItems.spell_book, 1, spells.get(rand.nextInt(spells.size())).metadata());
|
||||
return getBookStackForSpell(spells.get(rand.nextInt(spells.size())));
|
||||
}
|
||||
}else if(randomiser < 6){
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0){
|
||||
@@ -671,7 +673,7 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
WizardryItems.getWand(tier, Element.values()[rand.nextInt(Element.values().length)]));
|
||||
}
|
||||
}else if(randomiser < 8){
|
||||
return new ItemStack(WizardryItems.arcane_tome, 1, 1);
|
||||
return new ItemStack(WizardryItems.arcane_tome_apprentice, 1);
|
||||
}else if(randomiser < 10){
|
||||
EntityEquipmentSlot slot = InventoryUtils.ARMOUR_SLOTS[rand.nextInt(InventoryUtils.ARMOUR_SLOTS.length)];
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0){
|
||||
@@ -693,10 +695,9 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0 && !specialismSpells.isEmpty()){
|
||||
// This means it is more likely for spell books sold to be of the same element as the wizard if the
|
||||
// wizard has an element.
|
||||
return new ItemStack(WizardryItems.spell_book, 1,
|
||||
specialismSpells.get(rand.nextInt(specialismSpells.size())).metadata());
|
||||
return getBookStackForSpell(specialismSpells.get(rand.nextInt(specialismSpells.size())));
|
||||
}else{
|
||||
return new ItemStack(WizardryItems.spell_book, 1, spells.get(rand.nextInt(spells.size())).metadata());
|
||||
return getBookStackForSpell(spells.get(rand.nextInt(spells.size())));
|
||||
}
|
||||
}else if(randomiser < 6){
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0){
|
||||
@@ -708,7 +709,7 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
WizardryItems.getWand(tier, Element.values()[rand.nextInt(Element.values().length)]));
|
||||
}
|
||||
}else if(randomiser < 8){
|
||||
return new ItemStack(WizardryItems.arcane_tome, 1, 2);
|
||||
return new ItemStack(WizardryItems.arcane_tome_advanced, 1);
|
||||
}else{
|
||||
List<Item> upgrades = new ArrayList<Item>(WandHelper.getSpecialUpgrades());
|
||||
randomiser = rand.nextInt(upgrades.size());
|
||||
@@ -721,8 +722,7 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
|
||||
if(randomiser < 5 && this.getElement() != Element.MAGIC && !specialismSpells.isEmpty()){
|
||||
// Master spells can only be sold by a specialist in that element.
|
||||
return new ItemStack(WizardryItems.spell_book, 1,
|
||||
specialismSpells.get(rand.nextInt(specialismSpells.size())).metadata());
|
||||
return getBookStackForSpell(specialismSpells.get(rand.nextInt(specialismSpells.size())));
|
||||
|
||||
}else if(randomiser < 6){
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0){
|
||||
@@ -732,7 +732,7 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
return new ItemStack(WizardryItems.master_wand);
|
||||
}
|
||||
}else{
|
||||
return new ItemStack(WizardryItems.arcane_tome, 1, 3);
|
||||
return new ItemStack(WizardryItems.arcane_tome_master, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -747,7 +747,8 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
textureIndex = this.rand.nextInt(6);
|
||||
|
||||
if(rand.nextBoolean()){
|
||||
this.setElement(Element.values()[rand.nextInt(Element.values().length - 1) + 1]);
|
||||
Element[] elements = (Element[]) Arrays.stream(Element.values()).filter(Element::hasWizards).toArray();
|
||||
this.setElement(elements[rand.nextInt(elements.length - 1) + 1]);
|
||||
}else{
|
||||
this.setElement(Element.MAGIC);
|
||||
}
|
||||
@@ -798,7 +799,6 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
Tier maxTier = Tier.NOVICE;
|
||||
|
||||
List<Spell> npcSpells = Spell.getSpells(s -> s.canBeCastBy(wizard, false));
|
||||
npcSpells.removeIf(s -> !s.applicableForItem(WizardryItems.spell_book));
|
||||
|
||||
for(int i = 0; i < n; i++){
|
||||
|
||||
@@ -846,6 +846,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);
|
||||
@@ -869,7 +885,7 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
/**
|
||||
* Sets the list of blocks that are part of this wizard's tower. If a player breaks any of these blocks, the wizard
|
||||
* will get angry and attack them.
|
||||
*
|
||||
*
|
||||
* @param blocks A Set of BlockPos objects representing the blocks in the tower.
|
||||
*/
|
||||
public void setTowerBlocks(Set<BlockPos> blocks){
|
||||
@@ -901,11 +917,11 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Copied from their respective AI classes
|
||||
|
||||
|
||||
public static class EntityAILookAtTradePlayer extends EntityAIWatchClosest {
|
||||
|
||||
|
||||
private final EntityWizard wizard;
|
||||
|
||||
public EntityAILookAtTradePlayer(EntityWizard wizard){
|
||||
@@ -923,9 +939,9 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class EntityAITradePlayer extends EntityAIBase {
|
||||
|
||||
|
||||
private final EntityWizard wizard;
|
||||
|
||||
public EntityAITradePlayer(EntityWizard wizard){
|
||||
@@ -935,7 +951,7 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
|
||||
@Override
|
||||
public boolean shouldExecute(){
|
||||
|
||||
|
||||
if(!this.wizard.isEntityAlive()){
|
||||
return false;
|
||||
}else if(this.wizard.isInWater()){
|
||||
@@ -945,7 +961,7 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
}else if(this.wizard.velocityChanged){
|
||||
return false;
|
||||
}else{
|
||||
|
||||
|
||||
EntityPlayer entityplayer = this.wizard.getCustomer();
|
||||
|
||||
if(entityplayer == null){
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package electroblob.wizardry.entity.projectile;
|
||||
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.projectile.EntityArrow;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class EntityConjuredArrow extends EntityArrow {
|
||||
|
||||
public EntityConjuredArrow(World worldIn) {
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
public EntityConjuredArrow(World worldIn, double x, double y, double z) {
|
||||
super(worldIn, x, y, z);
|
||||
}
|
||||
|
||||
public EntityConjuredArrow(World worldIn, EntityLivingBase shooter) {
|
||||
super(worldIn, shooter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate() {
|
||||
super.onUpdate();
|
||||
if (this.timeInGround > 400) {
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemStack getArrowStack() {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package electroblob.wizardry.integration.jei;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.client.DrawingUtils;
|
||||
import electroblob.wizardry.constants.Constants;
|
||||
import electroblob.wizardry.constants.Element;
|
||||
@@ -11,7 +12,9 @@ import mezz.jei.api.ingredients.VanillaTypes;
|
||||
import mezz.jei.api.recipe.IRecipeWrapper;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraftforge.fml.common.registry.ForgeRegistries;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -95,8 +98,8 @@ public class ArcaneWorkbenchRecipe implements IRecipeWrapper {
|
||||
// A stack of crystals will almost certainly be enough mana, but you never know!
|
||||
// Using ItemStack.EMPTY to avoid deprecated method; crystals' stack size is not stack-sensitive so it doesn't matter
|
||||
if(count <= WizardryItems.magic_crystal.getItemStackLimit(ItemStack.EMPTY)){
|
||||
for(int meta = 0; meta < Element.values().length; meta++){
|
||||
crystalStacks.add(new ItemStack(WizardryItems.magic_crystal, count, meta));
|
||||
for (Element element : Element.values()) {
|
||||
crystalStacks.add(new ItemStack(ForgeRegistries.ITEMS.getValue(new ResourceLocation(Wizardry.MODID, element.name().toLowerCase() + "_crystal")), count));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -23,6 +23,7 @@ import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.common.registry.ForgeRegistries;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -214,7 +215,9 @@ public class ArcaneWorkbenchRecipeCategory implements IRecipeCategory<ArcaneWork
|
||||
List<ArcaneWorkbenchRecipe> recipes = new ArrayList<>();
|
||||
|
||||
List<ItemStack> crystals = new ArrayList<>();
|
||||
for(int meta = 0; meta < Element.values().length; meta++) crystals.add(new ItemStack(WizardryItems.magic_crystal, 1, meta));
|
||||
for (Element element : Element.values()) {
|
||||
crystals.add(new ItemStack(ForgeRegistries.ITEMS.getValue(new ResourceLocation(Wizardry.MODID, "crystal_" + element.name().toLowerCase()))));
|
||||
}
|
||||
List<ItemStack> shard = Collections.singletonList(new ItemStack(WizardryItems.crystal_shard));
|
||||
List<ItemStack> grandCrystal = Collections.singletonList(new ItemStack(WizardryItems.grand_crystal));
|
||||
|
||||
|
||||
+23
-9
@@ -19,6 +19,7 @@ import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.common.registry.ForgeRegistries;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -118,7 +119,13 @@ public class ImbuementAltarRecipeCategory implements IRecipeCategory<ImbuementAl
|
||||
List<ImbuementAltarRecipe> recipes = new ArrayList<>();
|
||||
|
||||
NonNullList<ItemStack> variants = NonNullList.create();
|
||||
WizardryItems.spectral_dust.getSubItems(WizardryItems.spectral_dust.getCreativeTab(), variants);
|
||||
variants.add(new ItemStack(WizardryItems.spectral_dust_earth));
|
||||
variants.add(new ItemStack(WizardryItems.spectral_dust_fire));
|
||||
variants.add(new ItemStack(WizardryItems.spectral_dust_healing));
|
||||
variants.add(new ItemStack(WizardryItems.spectral_dust_ice));
|
||||
variants.add(new ItemStack(WizardryItems.spectral_dust_lightning));
|
||||
variants.add(new ItemStack(WizardryItems.spectral_dust_necromancy));
|
||||
variants.add(new ItemStack(WizardryItems.spectral_dust_sorcery));
|
||||
|
||||
List<List<ItemStack>> dusts = new ArrayList<>();
|
||||
// Generate 4 separate lists, each in a different order to make it obvious they can be any element
|
||||
@@ -139,9 +146,10 @@ public class ImbuementAltarRecipeCategory implements IRecipeCategory<ImbuementAl
|
||||
|
||||
ItemStack input = new ItemStack(WizardryItems.magic_crystal);
|
||||
|
||||
for(int meta = 1; meta < Element.values().length; meta++){
|
||||
List<List<ItemStack>> dusts = Collections.nCopies(4, Collections.singletonList(new ItemStack(WizardryItems.spectral_dust, 1, meta)));
|
||||
ItemStack output = new ItemStack(WizardryItems.magic_crystal, 1, meta);
|
||||
for(Element element : Element.values()){
|
||||
List<List<ItemStack>> dusts = Collections.nCopies(4, Collections.singletonList(new ItemStack(ForgeRegistries.ITEMS.getValue(new ResourceLocation(Wizardry.MODID,
|
||||
"spectral_dust_" + element.name().toLowerCase())))));
|
||||
ItemStack output = new ItemStack(ForgeRegistries.ITEMS.getValue(new ResourceLocation(Wizardry.MODID, element.name().toLowerCase() + "_crystal")));
|
||||
recipes.add(new ImbuementAltarRecipe(input, dusts, output));
|
||||
}
|
||||
|
||||
@@ -153,11 +161,16 @@ public class ImbuementAltarRecipeCategory implements IRecipeCategory<ImbuementAl
|
||||
|
||||
List<ImbuementAltarRecipe> recipes = new ArrayList<>();
|
||||
|
||||
ItemStack input = new ItemStack(WizardryBlocks.crystal_block);
|
||||
ItemStack input = new ItemStack(WizardryBlocks.magic_crystal_block);
|
||||
|
||||
for(int meta = 1; meta < Element.values().length; meta++){
|
||||
List<List<ItemStack>> dusts = Collections.nCopies(4, Collections.singletonList(new ItemStack(WizardryItems.spectral_dust, 1, meta)));
|
||||
ItemStack output = new ItemStack(WizardryBlocks.crystal_block, 1, meta);
|
||||
for (Element element : Element.values()) {
|
||||
if (element == Element.MAGIC) { continue; }
|
||||
|
||||
List<List<ItemStack>> dusts = Collections.nCopies(4, Collections.singletonList(new ItemStack(ForgeRegistries.ITEMS.getValue(
|
||||
new ResourceLocation(Wizardry.MODID, "spectral_dust_" + element.name().toLowerCase())))));
|
||||
|
||||
ItemStack output = new ItemStack(ForgeRegistries.ITEMS.getValue(new ResourceLocation(Wizardry.MODID, element.getName().toLowerCase()
|
||||
+ "_crystal_block")));
|
||||
recipes.add(new ImbuementAltarRecipe(input, dusts, output));
|
||||
}
|
||||
|
||||
@@ -179,7 +192,8 @@ public class ImbuementAltarRecipeCategory implements IRecipeCategory<ImbuementAl
|
||||
|
||||
if(e == Element.MAGIC) continue;
|
||||
|
||||
List<List<ItemStack>> dusts = Collections.nCopies(4, Collections.singletonList(new ItemStack(WizardryItems.spectral_dust, 1, e.ordinal())));
|
||||
List<List<ItemStack>> dusts = Collections.nCopies(4, Collections.singletonList(new ItemStack(
|
||||
ForgeRegistries.ITEMS.getValue(new ResourceLocation(Wizardry.MODID, "spectral_dust_" + e.name().toLowerCase())))));
|
||||
ItemStack output = TileEntityImbuementAltar.getImbuementResult(input, new Element[]{e, e, e, e}, false, null, null);
|
||||
|
||||
if(!output.isEmpty()) recipes.add(new ImbuementAltarRecipe(input, dusts, output));
|
||||
|
||||
@@ -98,7 +98,9 @@ public class ContainerArcaneWorkbench extends Container implements ISpellSortabl
|
||||
this.addSlotToContainer(new SlotWorkbenchItem(tileentity, CENTRE_SLOT, 80, 64, this));
|
||||
|
||||
Set<Item> upgrades = new HashSet<>(WandHelper.getSpecialUpgrades()); // Can't be done statically.
|
||||
upgrades.add(WizardryItems.arcane_tome);
|
||||
upgrades.add(WizardryItems.arcane_tome_apprentice);
|
||||
upgrades.add(WizardryItems.arcane_tome_advanced);
|
||||
upgrades.add(WizardryItems.arcane_tome_master);
|
||||
upgrades.add(WizardryItems.resplendent_thread);
|
||||
upgrades.add(WizardryItems.crystal_silver_plating);
|
||||
upgrades.add(WizardryItems.ethereal_crystalweave);
|
||||
|
||||
@@ -127,7 +127,9 @@ public class ContainerBookshelf extends Container {
|
||||
registerBookItem(Items.WRITABLE_BOOK);
|
||||
registerBookItem(Items.ENCHANTED_BOOK);
|
||||
registerBookItem(WizardryItems.spell_book);
|
||||
registerBookItem(WizardryItems.arcane_tome);
|
||||
registerBookItem(WizardryItems.arcane_tome_apprentice);
|
||||
registerBookItem(WizardryItems.arcane_tome_advanced);
|
||||
registerBookItem(WizardryItems.arcane_tome_master);
|
||||
registerBookItem(WizardryItems.wizard_handbook);
|
||||
registerBookItem(WizardryItems.ruined_spell_book);
|
||||
registerBookItem(WizardryItems.scroll);
|
||||
|
||||
@@ -3,11 +3,9 @@ package electroblob.wizardry.item;
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.constants.Tier;
|
||||
import electroblob.wizardry.registry.WizardryTabs;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.item.EnumRarity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
@@ -16,54 +14,33 @@ import java.util.List;
|
||||
|
||||
public class ItemArcaneTome extends Item {
|
||||
|
||||
public ItemArcaneTome(){
|
||||
private final EnumRarity rarity;
|
||||
private final Tier tier;
|
||||
|
||||
public ItemArcaneTome(EnumRarity rarity, Tier tier){
|
||||
super();
|
||||
setHasSubtypes(true);
|
||||
setMaxStackSize(1);
|
||||
setCreativeTab(WizardryTabs.WIZARDRY);
|
||||
this.rarity = rarity;
|
||||
this.tier = tier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getSubItems(CreativeTabs tab, NonNullList<ItemStack> list){
|
||||
if(tab == WizardryTabs.WIZARDRY){ // Don't use isInCreativeTab here.
|
||||
for(int i = 1; i < Tier.values().length; i++){
|
||||
list.add(new ItemStack(this, 1, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
public Tier getTier() { return tier; }
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public boolean hasEffect(ItemStack stack){
|
||||
return true;
|
||||
}
|
||||
public boolean hasEffect(ItemStack stack){ return true; }
|
||||
|
||||
@Override
|
||||
public EnumRarity getRarity(ItemStack stack){
|
||||
switch(this.getDamage(stack)){
|
||||
case 1:
|
||||
return EnumRarity.UNCOMMON;
|
||||
case 2:
|
||||
return EnumRarity.RARE;
|
||||
case 3:
|
||||
return EnumRarity.EPIC;
|
||||
}
|
||||
return EnumRarity.COMMON;
|
||||
}
|
||||
public EnumRarity getRarity(ItemStack stack){ return rarity; }
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public void addInformation(ItemStack stack, World world, List<String> tooltip, net.minecraft.client.util.ITooltipFlag showAdvanced){
|
||||
|
||||
if(stack.getItemDamage() < 1){
|
||||
return; // If something's up with the metadata it will display a 'generic' tome of arcana with no info
|
||||
}
|
||||
|
||||
Tier tier = Tier.values()[stack.getItemDamage()];
|
||||
Tier tier2 = Tier.values()[stack.getItemDamage() - 1];
|
||||
|
||||
tooltip.add(tier.getDisplayNameWithFormatting());
|
||||
Wizardry.proxy.addMultiLineDescription(tooltip, "item." + this.getRegistryName() + ".desc",
|
||||
Tier tier2 = Tier.values()[tier.ordinal() - 1];
|
||||
|
||||
Wizardry.proxy.addMultiLineDescription(tooltip, "item." + Wizardry.MODID + ":arcane_tome.desc",
|
||||
tier2.getDisplayNameWithFormatting() + "\u00A77", tier.getDisplayNameWithFormatting() + "\u00A77");
|
||||
}
|
||||
|
||||
|
||||
@@ -123,6 +123,8 @@ public class ItemArtefact extends Item {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isEnabled() { return enabled; }
|
||||
|
||||
@Override
|
||||
public EnumRarity getRarity(ItemStack stack){
|
||||
return rarity;
|
||||
@@ -344,6 +346,8 @@ public class ItemArtefact extends Item {
|
||||
|
||||
findMatchingWandAndExecute(player, Spells.shield, wand -> {
|
||||
|
||||
if(wand.getItem() instanceof ItemScroll) return; // Ignore scrolls since they shouldn't work
|
||||
|
||||
List<Entity> projectiles = EntityUtils.getEntitiesWithinRadius(5, player.posX, player.posY, player.posZ, world, Entity.class);
|
||||
projectiles.removeIf(e -> !(e instanceof IProjectile));
|
||||
Vec3d look = player.getLookVec();
|
||||
@@ -765,6 +769,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,44 +1,21 @@
|
||||
package electroblob.wizardry.item;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.api.IElemental;
|
||||
import electroblob.wizardry.constants.Element;
|
||||
import electroblob.wizardry.registry.WizardryTabs;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/** Note that in 1.13, <i>the flattening</i> will make this class redundant, much like ItemCoal, which is probably its
|
||||
* closest analog in vanilla. */
|
||||
public class ItemCrystal extends Item implements IMultiTexturedItem {
|
||||
public class ItemCrystal extends Item implements IElemental {
|
||||
|
||||
public ItemCrystal(){
|
||||
private final Element element;
|
||||
|
||||
public ItemCrystal(Element element) {
|
||||
super();
|
||||
this.setHasSubtypes(true);
|
||||
this.setMaxDamage(0);
|
||||
this.setCreativeTab(WizardryTabs.WIZARDRY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getModelName(ItemStack stack){
|
||||
int metadata = stack.getMetadata();
|
||||
if(metadata >= Element.values().length) metadata = 0;
|
||||
return new ResourceLocation(Wizardry.MODID, "crystal_" + Element.values()[metadata].getName());
|
||||
this.setMaxDamage(0);
|
||||
this.setCreativeTab(WizardryTabs.WIZARDRY);
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTranslationKey(ItemStack stack){
|
||||
return "item." + this.getModelName(stack).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getSubItems(CreativeTabs tab, NonNullList<ItemStack> items){
|
||||
if(tab == WizardryTabs.WIZARDRY){
|
||||
for(Element element : Element.values()){
|
||||
items.add(new ItemStack(this, 1, element.ordinal()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Element getElement() { return element; }
|
||||
}
|
||||
|
||||
@@ -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,39 +1,13 @@
|
||||
package electroblob.wizardry.item;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.constants.Element;
|
||||
import electroblob.wizardry.registry.WizardryTabs;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class ItemSpectralDust extends Item implements IMultiTexturedItem {
|
||||
public class ItemSpectralDust extends Item {
|
||||
|
||||
public ItemSpectralDust(){
|
||||
super();
|
||||
this.setHasSubtypes(true);
|
||||
this.setMaxDamage(0);
|
||||
this.setCreativeTab(WizardryTabs.WIZARDRY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getModelName(ItemStack stack){
|
||||
int metadata = stack.getMetadata();
|
||||
if(metadata >= Element.values().length) metadata = 0;
|
||||
return new ResourceLocation(Wizardry.MODID, "spectral_dust_" + Element.values()[metadata].getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getSubItems(CreativeTabs tab, NonNullList<ItemStack> items){
|
||||
if(tab == WizardryTabs.WIZARDRY){
|
||||
for(Element element : Arrays.copyOfRange(Element.values(), 1, Element.values().length)){
|
||||
items.add(new ItemStack(this, 1, element.ordinal()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -227,8 +227,8 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
|
||||
|
||||
@Override
|
||||
public void onUpdate(ItemStack stack, World world, Entity entity, int slot, boolean isHeld){
|
||||
|
||||
WandHelper.decrementCooldowns(stack);
|
||||
|
||||
if(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){
|
||||
@@ -687,9 +687,9 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
|
||||
|
||||
// Upgrades wand if necessary. Damage is copied, preserving remaining durability,
|
||||
// and also the entire NBT tag compound.
|
||||
if(upgrade.getItem() == WizardryItems.arcane_tome){
|
||||
if(upgrade.getItem() instanceof ItemArcaneTome){
|
||||
|
||||
Tier tier = Tier.values()[upgrade.getItemDamage()];
|
||||
Tier tier = ((ItemArcaneTome) upgrade.getItem()).getTier();
|
||||
|
||||
// Checks the wand upgrade is for the tier above the wand's tier, and that either the wand has enough
|
||||
// progression or the player is in creative mode.
|
||||
@@ -849,7 +849,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;
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package electroblob.wizardry.item;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Streams;
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.client.DrawingUtils;
|
||||
@@ -44,7 +46,11 @@ import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Mod.EventBusSubscriber
|
||||
@@ -54,6 +60,28 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
|
||||
private static final float SAGE_OTHER_COST_REDUCTION = 0.2f;
|
||||
private static final float WARLOCK_SPEED_BOOST = 0.2f;
|
||||
private static final UUID WARLOCK_SPEED_BOOST_UUID = UUID.fromString("4bad7152-2663-4b1b-bb59-552e92847031");
|
||||
// Standard ItemArmor modifiers
|
||||
private static final UUID[] ARMOR_MODIFIERS = new UUID[] {UUID.fromString("845DB27C-C624-495F-8C9F-6020A9A58B6B"), UUID.fromString("D8499B04-0E66-4726-AB29-64469D734E0D"), UUID.fromString("9F3D476D-C118-4544-8365-64846904B48E"), UUID.fromString("2AD3F246-FEE1-4E67-B886-69FD380BB150")};
|
||||
|
||||
@Override
|
||||
public Multimap<String, AttributeModifier> getItemAttributeModifiers(EntityEquipmentSlot slot) {
|
||||
// The vanilla armor handling logic from ItemArmor.getItemAttributeModifiers was moved to ItemWizardArmour.getAttributeModifiers to allow checking if the stack has enough mana
|
||||
Multimap<String, AttributeModifier> multimap = ArrayListMultimap.create();
|
||||
return multimap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Multimap<String, AttributeModifier> getAttributeModifiers(EntityEquipmentSlot slot, ItemStack stack) {
|
||||
Multimap<String, AttributeModifier> multimap = super.getAttributeModifiers(slot, stack);
|
||||
|
||||
// only grant armor if the equipment has mana
|
||||
if (slot == this.armorType && !((ItemWizardArmour) stack.getItem()).isManaEmpty(stack)) {
|
||||
multimap.put(SharedMonsterAttributes.ARMOR.getName(), new AttributeModifier(ARMOR_MODIFIERS[slot.getIndex()], "Armor modifier", this.damageReduceAmount, 0));
|
||||
multimap.put(SharedMonsterAttributes.ARMOR_TOUGHNESS.getName(), new AttributeModifier(ARMOR_MODIFIERS[slot.getIndex()], "Armor toughness", this.toughness, 0));
|
||||
}
|
||||
|
||||
return multimap;
|
||||
}
|
||||
|
||||
public enum ArmourClass {
|
||||
|
||||
@@ -181,8 +209,8 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
|
||||
|
||||
@Override
|
||||
public void onArmorTick(World world, EntityPlayer player, ItemStack itemStack){
|
||||
if(armorType == EntityEquipmentSlot.HEAD && isWearingFullSet(player, element, ArmourClass.BATTLEMAGE)
|
||||
&& player.ticksExisted % 20 == 0){
|
||||
if(armorType == EntityEquipmentSlot.HEAD && player.ticksExisted % 20 == 0
|
||||
&& isWearingFullSet(player, element, ArmourClass.BATTLEMAGE) && doAllArmourPiecesHaveMana(player)){
|
||||
player.addPotionEffect(new PotionEffect(WizardryPotions.ward, 219, 0, true, false));
|
||||
}
|
||||
}
|
||||
@@ -209,7 +237,7 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
|
||||
modifiers.set(WizardryItems.cooldown_upgrade, modifiers.get(WizardryItems.cooldown_upgrade) - armourClass.cooldownReduction, true);
|
||||
|
||||
// Full set bonuses
|
||||
if(this.armorType == EntityEquipmentSlot.HEAD && isWearingFullSet(caster, element, armourClass)){
|
||||
if(this.armorType == EntityEquipmentSlot.HEAD && isWearingFullSet(caster, element, armourClass) && doAllArmourPiecesHaveMana(caster)){
|
||||
if(armourClass == ArmourClass.SAGE && spell.getElement() != this.element){
|
||||
modifiers.set(SpellModifiers.COST, 1 - SAGE_OTHER_COST_REDUCTION, false);
|
||||
}
|
||||
@@ -306,7 +334,12 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
|
||||
|
||||
int chargeDepleted = this.getManaCapacity(centre.getStack()) - this.getMana(centre.getStack());
|
||||
|
||||
int manaPerItem = Constants.MANA_PER_CRYSTAL;
|
||||
// Not too pretty but allows addons implementing the IManaStoringItem interface to provide their mana amount for custom crystals,
|
||||
// previously this was defaulted to the regular crystal's amount, allowing players to exploit it if a crystal was worth less mana than that.
|
||||
int manaPerItem = crystals.getStack().getItem() instanceof IManaStoringItem ?
|
||||
((IManaStoringItem) crystals.getStack().getItem()).getMana(crystals.getStack()) :
|
||||
crystals.getStack().getItem() instanceof ItemCrystal ? Constants.MANA_PER_CRYSTAL : Constants.MANA_PER_SHARD;
|
||||
|
||||
if(crystals.getStack().getItem() == WizardryItems.crystal_shard) manaPerItem = Constants.MANA_PER_SHARD;
|
||||
if(crystals.getStack().getItem() == WizardryItems.grand_crystal) manaPerItem = Constants.GRAND_CRYSTAL_MANA;
|
||||
|
||||
@@ -335,7 +368,7 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
|
||||
|
||||
IAttributeInstance movementSpeed = event.getEntityLiving().getAttributeMap().getAttributeInstance(SharedMonsterAttributes.MOVEMENT_SPEED);
|
||||
|
||||
if(isWearingFullSet(event.getEntityLiving(), null, ArmourClass.WARLOCK)){
|
||||
if(isWearingFullSet(event.getEntityLiving(), null, ArmourClass.WARLOCK) && doAllArmourPiecesHaveMana(event.getEntityLiving())){
|
||||
// Only apply the modifier once (can't just check this is the helmet since it might not be the last piece equipped)
|
||||
if(movementSpeed.getModifier(WARLOCK_SPEED_BOOST_UUID) == null){
|
||||
movementSpeed.applyModifier(new AttributeModifier(WARLOCK_SPEED_BOOST_UUID, "Warlock set bonus", WARLOCK_SPEED_BOOST, Operations.MULTIPLY_FLAT));
|
||||
@@ -405,7 +438,7 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
|
||||
* @param armourClass The class to check, or null to accept any class as long as they are all the same.
|
||||
* @return True if the entity is wearing a full set of the given element and class, false otherwise.
|
||||
*/
|
||||
private static boolean isWearingFullSet(EntityLivingBase entity, @Nullable Element element, @Nullable ArmourClass armourClass){
|
||||
public static boolean isWearingFullSet(EntityLivingBase entity, @Nullable Element element, @Nullable ArmourClass armourClass){
|
||||
ItemStack helmet = entity.getItemStackFromSlot(EntityEquipmentSlot.HEAD);
|
||||
if(!(helmet.getItem() instanceof ItemWizardArmour)) return false;
|
||||
Element e = element == null ? ((ItemWizardArmour)helmet.getItem()).element : element;
|
||||
@@ -416,6 +449,16 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
|
||||
&& ((ItemWizardArmour)entity.getItemStackFromSlot(s).getItem()).armourClass == ac);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given entity's armour pieces which implement {@link IManaStoringItem} has mana. Ignores pieces which doesn't have a mana storage.
|
||||
* @param entity The entity to query.
|
||||
* @return True if all armour pieces which implement {@link IManaStoringItem} has mana, false otherwise.
|
||||
*/
|
||||
public static boolean doAllArmourPiecesHaveMana(EntityLivingBase entity){
|
||||
return Arrays.stream(InventoryUtils.ARMOUR_SLOTS).noneMatch(s -> entity.getItemStackFromSlot(s).getItem() instanceof IManaStoringItem
|
||||
&& ((IManaStoringItem) entity.getItemStackFromSlot(s).getItem()).isManaEmpty(entity.getItemStackFromSlot(s)));
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onLivingSetAttackTargetEvent(LivingSetAttackTargetEvent event){
|
||||
// Undo the mob detection penalty for wearing armour when invisible
|
||||
|
||||
@@ -10,6 +10,7 @@ import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.EnumActionResult;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.text.Style;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
@@ -36,7 +37,11 @@ public class ItemWizardHandbook extends Item {
|
||||
@Override
|
||||
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand){
|
||||
ItemStack stack = player.getHeldItem(hand);
|
||||
player.openGui(Wizardry.instance, WizardryGuiHandler.WIZARD_HANDBOOK, world, 0, 0, 0);
|
||||
if (Wizardry.settings.loadHandbook) {
|
||||
player.openGui(Wizardry.instance, WizardryGuiHandler.WIZARD_HANDBOOK, world, 0, 0, 0);
|
||||
} else if (!world.isRemote){
|
||||
player.sendStatusMessage(new TextComponentTranslation("item." + Wizardry.MODID + ":wizard_handbook.disabled"), false);
|
||||
}
|
||||
return ActionResult.newResult(EnumActionResult.SUCCESS, stack);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,12 +12,15 @@ import electroblob.wizardry.entity.living.*;
|
||||
import electroblob.wizardry.entity.projectile.EntityFirebomb;
|
||||
import electroblob.wizardry.entity.projectile.EntityMagicFireball;
|
||||
import electroblob.wizardry.event.SpellCastEvent;
|
||||
import electroblob.wizardry.event.SpellCastEvent.Source;
|
||||
import electroblob.wizardry.item.IManaStoringItem;
|
||||
import electroblob.wizardry.item.ISpellCastingItem;
|
||||
import electroblob.wizardry.item.ItemArtefact;
|
||||
import electroblob.wizardry.registry.*;
|
||||
import electroblob.wizardry.spell.Banish;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
import electroblob.wizardry.util.BlockUtils;
|
||||
import electroblob.wizardry.util.EntityUtils;
|
||||
import electroblob.wizardry.util.SpellModifiers;
|
||||
import electroblob.wizardry.util.SpellProperties.Context;
|
||||
import net.minecraft.entity.effect.EntityLightningBolt;
|
||||
import net.minecraft.entity.item.EntityFallingBlock;
|
||||
@@ -174,6 +177,23 @@ public abstract class Forfeit {
|
||||
|
||||
forfeit.apply(event.getWorld(), player);
|
||||
|
||||
ItemStack stack = player.getHeldItemMainhand();
|
||||
|
||||
if(!(stack.getItem() instanceof ISpellCastingItem)){
|
||||
stack = player.getHeldItemOffhand();
|
||||
if(!(stack.getItem() instanceof ISpellCastingItem)) stack = ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
if(!stack.isEmpty()){
|
||||
// Still need to charge the player mana or consume the scroll
|
||||
if(event.getSource() == Source.SCROLL){
|
||||
if(!player.isCreative()) stack.shrink(1);
|
||||
}else if(stack.getItem() instanceof IManaStoringItem){
|
||||
int cost = (int)(event.getSpell().getCost() * event.getModifiers().get(SpellModifiers.COST) + 0.1f); // Weird floaty rounding
|
||||
((IManaStoringItem)stack.getItem()).consumeMana(stack, cost, player);
|
||||
}
|
||||
}
|
||||
|
||||
WizardryAdvancementTriggers.spell_failure.triggerFor(player);
|
||||
|
||||
EntityUtils.playSoundAtPlayer(player, forfeit.getSound(), WizardrySounds.SPELLS, 1, 1);
|
||||
@@ -222,10 +242,11 @@ public abstract class Forfeit {
|
||||
}));
|
||||
|
||||
add(Tier.MASTER, Element.FIRE, create("burn_surroundings", (w, p) -> {
|
||||
if(!w.isRemote){
|
||||
if(!w.isRemote && EntityUtils.canDamageBlocks(p, w)){
|
||||
List<BlockPos> sphere = BlockUtils.getBlockSphere(p.getPosition(), 6);
|
||||
for(BlockPos pos : sphere){
|
||||
if(w.rand.nextBoolean() && w.isAirBlock(pos)) w.setBlockState(pos, Blocks.FIRE.getDefaultState());
|
||||
if(w.rand.nextBoolean() && w.isAirBlock(pos) && BlockUtils.canPlaceBlock(p, w, pos))
|
||||
w.setBlockState(pos, Blocks.FIRE.getDefaultState());
|
||||
}
|
||||
}
|
||||
}));
|
||||
@@ -376,10 +397,11 @@ public abstract class Forfeit {
|
||||
}));
|
||||
|
||||
add(Tier.NOVICE, Element.EARTH, create("snares", (w, p) -> {
|
||||
if(!w.isRemote){
|
||||
if(!w.isRemote && EntityUtils.canDamageBlocks(p, w)){
|
||||
for(EnumFacing direction : EnumFacing.HORIZONTALS){
|
||||
BlockPos pos = p.getPosition().offset(direction);
|
||||
if(BlockUtils.canBlockBeReplaced(w, pos)) w.setBlockState(pos, WizardryBlocks.snare.getDefaultState());
|
||||
if(BlockUtils.canBlockBeReplaced(w, pos) && BlockUtils.canPlaceBlock(p, w, pos))
|
||||
w.setBlockState(pos, WizardryBlocks.snare.getDefaultState());
|
||||
}
|
||||
}
|
||||
}));
|
||||
@@ -393,9 +415,9 @@ public abstract class Forfeit {
|
||||
}));
|
||||
|
||||
add(Tier.APPRENTICE, Element.EARTH, create("uproot_plants", (w, p) -> {
|
||||
if(!w.isRemote){
|
||||
if(!w.isRemote && EntityUtils.canDamageBlocks(p, w)){
|
||||
List<BlockPos> sphere = BlockUtils.getBlockSphere(p.getPosition(), 5);
|
||||
sphere.removeIf(pos -> !(w.getBlockState(pos).getBlock() instanceof IPlantable));
|
||||
sphere.removeIf(pos -> !(w.getBlockState(pos).getBlock() instanceof IPlantable) || !BlockUtils.canBreakBlock(p, w, pos));
|
||||
sphere.forEach(pos -> w.destroyBlock(pos, true));
|
||||
}
|
||||
}));
|
||||
@@ -403,9 +425,9 @@ public abstract class Forfeit {
|
||||
add(Tier.APPRENTICE, Element.EARTH, create("poison_self", (w, p) -> p.addPotionEffect(new PotionEffect(MobEffects.POISON, 400, 1))));
|
||||
|
||||
add(Tier.ADVANCED, Element.EARTH, create("flood", (w, p) -> {
|
||||
if(!w.isRemote){
|
||||
if(!w.isRemote && EntityUtils.canDamageBlocks(p, w)){
|
||||
List<BlockPos> sphere = BlockUtils.getBlockSphere(p.getPosition().up(), 2);
|
||||
sphere.removeIf(pos -> !BlockUtils.canBlockBeReplaced(w, pos, true));
|
||||
sphere.removeIf(pos -> !BlockUtils.canBlockBeReplaced(w, pos, true) || !BlockUtils.canPlaceBlock(p, w, pos));
|
||||
sphere.forEach(pos -> w.setBlockState(pos, Blocks.WATER.getDefaultState()));
|
||||
}
|
||||
}));
|
||||
@@ -413,8 +435,7 @@ public abstract class Forfeit {
|
||||
add(Tier.MASTER, Element.EARTH, create("bury_self", (w, p) -> {
|
||||
if(!w.isRemote){
|
||||
List<BlockPos> sphere = BlockUtils.getBlockSphere(p.getPosition(), 4);
|
||||
sphere.removeIf(pos -> !w.getBlockState(pos).isFullCube());
|
||||
sphere.removeIf(pos -> BlockUtils.isBlockUnbreakable(w, pos));
|
||||
sphere.removeIf(pos -> !w.getBlockState(pos).isFullCube() || BlockUtils.isBlockUnbreakable(w, pos) || BlockUtils.canBreakBlock(p, w, pos));
|
||||
sphere.forEach(pos -> {
|
||||
EntityFallingBlock block = new EntityFallingBlock(w, pos.getX() + 0.5, pos.getY() + 0.5,
|
||||
pos.getZ() + 0.5, w.getBlockState(pos));
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package electroblob.wizardry.misc;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.item.IManaStoringItem;
|
||||
import electroblob.wizardry.item.ItemManaFlask;
|
||||
import net.minecraft.inventory.InventoryCrafting;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.CraftingManager;
|
||||
import net.minecraft.item.crafting.IRecipe;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
@@ -15,6 +15,8 @@ import net.minecraftforge.fml.common.gameevent.PlayerEvent;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
import net.minecraftforge.oredict.ShapelessOreRecipe;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Implements a dynamic crafting recipe for recharging items with mana flasks.
|
||||
*
|
||||
@@ -24,6 +26,8 @@ import net.minecraftforge.oredict.ShapelessOreRecipe;
|
||||
@Mod.EventBusSubscriber
|
||||
public class RecipeRechargeWithFlask extends ShapelessOreRecipe {
|
||||
|
||||
private static final Multimap<Item, RecipeRechargeWithFlask> FLASK_RECIPES = HashMultimap.create();
|
||||
|
||||
private final IManaStoringItem chargeable;
|
||||
private final ItemManaFlask flask;
|
||||
|
||||
@@ -38,6 +42,7 @@ public class RecipeRechargeWithFlask extends ShapelessOreRecipe {
|
||||
if(!(chargeable instanceof IManaStoringItem)) throw new IllegalArgumentException("Item to be charged must be an instance of IManaStoringItem");
|
||||
this.chargeable = (IManaStoringItem)chargeable;
|
||||
this.flask = flask;
|
||||
FLASK_RECIPES.put(chargeable, this);
|
||||
}
|
||||
|
||||
// Commented out for now because JEI spams the log with errors about the recipe having no output
|
||||
@@ -91,11 +96,11 @@ public class RecipeRechargeWithFlask extends ShapelessOreRecipe {
|
||||
// This means that although I no longer have to replace the result every tick, I still need to do it here
|
||||
// ... I thought the whole point of the new recipe system was so that I DIDN'T have to do this?!
|
||||
if(event.craftMatrix instanceof InventoryCrafting){
|
||||
for(IRecipe recipe : CraftingManager.REGISTRY){
|
||||
if(recipe instanceof RecipeRechargeWithFlask
|
||||
&& recipe.matches((InventoryCrafting)event.craftMatrix, event.player.world)){
|
||||
Collection<RecipeRechargeWithFlask> recipes = FLASK_RECIPES.get(event.crafting.getItem());
|
||||
for(RecipeRechargeWithFlask recipe : recipes){
|
||||
if(recipe.matches((InventoryCrafting)event.craftMatrix, event.player.world)){
|
||||
// Have to modify the itemstack in the actual event, it cannot be replaced
|
||||
((RecipeRechargeWithFlask)recipe).rechargeItemAndCopyNBT(event.crafting, (InventoryCrafting)event.craftMatrix);
|
||||
recipe.rechargeItemAndCopyNBT(event.crafting, (InventoryCrafting)event.craftMatrix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package electroblob.wizardry.packet;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.event.ResurrectionEvent;
|
||||
import electroblob.wizardry.inventory.ContainerArcaneWorkbench;
|
||||
import electroblob.wizardry.item.ISpellCastingItem;
|
||||
import electroblob.wizardry.packet.PacketControlInput.Message;
|
||||
@@ -13,6 +14,7 @@ import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
|
||||
@@ -79,6 +81,7 @@ public class PacketControlInput implements IMessageHandler<Message, IMessage> {
|
||||
.filter(s -> Resurrection.canStackResurrect(s, player)).findFirst().orElse(null);
|
||||
|
||||
if(stack != null){
|
||||
if(MinecraftForge.EVENT_BUS.post(new ResurrectionEvent(player, player))) break;
|
||||
// This should suffice, since this is the only way a player can cast resurrection when dead!
|
||||
((ISpellCastingItem)stack.getItem()).cast(stack, Spells.resurrection, player, EnumHand.MAIN_HAND, 0, new SpellModifiers());
|
||||
break;
|
||||
|
||||
@@ -4,8 +4,10 @@ import electroblob.wizardry.Wizardry;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.inventory.EntityEquipmentSlot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraftforge.common.ISpecialArmor;
|
||||
|
||||
public class CurseUndeath extends Curse {
|
||||
|
||||
@@ -25,7 +27,7 @@ public class CurseUndeath extends Curse {
|
||||
|
||||
// Adapted from EntityZombie
|
||||
if(entitylivingbase.world.isDaytime() && !entitylivingbase.world.isRemote){
|
||||
|
||||
|
||||
float f = entitylivingbase.getBrightness();
|
||||
|
||||
if(f > 0.5F && entitylivingbase.world.rand.nextFloat() * 30.0F < (f - 0.4F) * 2.0F
|
||||
@@ -35,14 +37,17 @@ public class CurseUndeath extends Curse {
|
||||
boolean flag = true;
|
||||
ItemStack itemstack = entitylivingbase.getItemStackFromSlot(EntityEquipmentSlot.HEAD);
|
||||
|
||||
if(!itemstack.isEmpty()){
|
||||
if(itemstack.isItemStackDamageable()){
|
||||
if (!itemstack.isEmpty()) {
|
||||
if (itemstack.isItemStackDamageable()) {
|
||||
|
||||
itemstack.setItemDamage(itemstack.getItemDamage() + entitylivingbase.world.rand.nextInt(2));
|
||||
|
||||
if(itemstack.getItemDamage() >= itemstack.getMaxDamage()){
|
||||
entitylivingbase.renderBrokenItemStack(itemstack);
|
||||
entitylivingbase.setItemStackToSlot(EntityEquipmentSlot.HEAD, ItemStack.EMPTY);
|
||||
if (itemstack.getItem() instanceof ISpecialArmor) {
|
||||
((ISpecialArmor) itemstack.getItem()).damageArmor(entitylivingbase, itemstack, DamageSource.ON_FIRE, entitylivingbase.world.rand.nextInt(2), EntityEquipmentSlot.HEAD.getSlotIndex());
|
||||
} else {
|
||||
itemstack.setItemDamage(itemstack.getItemDamage() + entitylivingbase.world.rand.nextInt(2));
|
||||
if (itemstack.getItemDamage() >= itemstack.getMaxDamage()) {
|
||||
entitylivingbase.renderBrokenItemStack(itemstack);
|
||||
entitylivingbase.setItemStackToSlot(EntityEquipmentSlot.HEAD, ItemStack.EMPTY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,17 +2,14 @@ package electroblob.wizardry.potion;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.registry.WizardryPotions;
|
||||
import electroblob.wizardry.registry.WizardrySounds;
|
||||
import electroblob.wizardry.util.EntityUtils;
|
||||
import electroblob.wizardry.util.GeometryUtils;
|
||||
import electroblob.wizardry.util.NBTExtras;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.nbt.NBTUtil;
|
||||
import net.minecraft.network.play.server.SPacketEntityVelocity;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
@@ -23,8 +20,6 @@ public class PotionContainment extends PotionMagicEffect {
|
||||
|
||||
public static final String ENTITY_TAG = "containmentPos";
|
||||
|
||||
private static final double RUBBERBAND_THRESHOLD = 0.24;
|
||||
|
||||
public PotionContainment(boolean isBadEffect, int liquidColour){
|
||||
super(isBadEffect, liquidColour, new ResourceLocation(Wizardry.MODID, "textures/gui/potion_icons/containment.png"));
|
||||
this.setPotionName("potion." + Wizardry.MODID + ":containment");
|
||||
@@ -41,7 +36,6 @@ public class PotionContainment extends PotionMagicEffect {
|
||||
|
||||
@Override
|
||||
public void performEffect(EntityLivingBase target, int strength){
|
||||
|
||||
float maxDistance = getContainmentDistance(strength);
|
||||
|
||||
// Initialise the containment position to the entity's position if it wasn't set already
|
||||
@@ -63,59 +57,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());
|
||||
|
||||
@@ -2,6 +2,7 @@ package electroblob.wizardry.registry;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.block.*;
|
||||
import electroblob.wizardry.constants.Element;
|
||||
import electroblob.wizardry.tileentity.*;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
@@ -43,7 +44,15 @@ public final class WizardryBlocks {
|
||||
public static final Block crystal_ore = placeholder();
|
||||
public static final Block crystal_flower = placeholder();
|
||||
public static final Block transportation_stone = placeholder();
|
||||
public static final Block crystal_block = placeholder();
|
||||
|
||||
public static final Block magic_crystal_block = placeholder();
|
||||
public static final Block fire_crystal_block = placeholder();
|
||||
public static final Block ice_crystal_block = placeholder();
|
||||
public static final Block lightning_crystal_block = placeholder();
|
||||
public static final Block necromancy_crystal_block = placeholder();
|
||||
public static final Block earth_crystal_block = placeholder();
|
||||
public static final Block sorcery_crystal_block = placeholder();
|
||||
public static final Block healing_crystal_block = placeholder();
|
||||
|
||||
public static final Block petrified_stone = placeholder();
|
||||
public static final Block ice_statue = placeholder();
|
||||
@@ -59,9 +68,28 @@ public final class WizardryBlocks {
|
||||
public static final Block permafrost = placeholder();
|
||||
|
||||
public static final Block runestone = placeholder();
|
||||
public static final Block runestone_pedestal = placeholder();
|
||||
public static final Block fire_runestone = placeholder();
|
||||
public static final Block ice_runestone = placeholder();
|
||||
public static final Block lightning_runestone = placeholder();
|
||||
public static final Block necromancy_runestone = placeholder();
|
||||
public static final Block earth_runestone = placeholder();
|
||||
public static final Block sorcery_runestone = placeholder();
|
||||
public static final Block healing_runestone = placeholder();
|
||||
|
||||
public static final Block gilded_wood = placeholder();
|
||||
public static final Block fire_runestone_pedestal = placeholder();
|
||||
public static final Block ice_runestone_pedestal = placeholder();
|
||||
public static final Block lightning_runestone_pedestal = placeholder();
|
||||
public static final Block necromancy_runestone_pedestal = placeholder();
|
||||
public static final Block earth_runestone_pedestal = placeholder();
|
||||
public static final Block healing_runestone_pedestal = placeholder();
|
||||
public static final Block sorcery_runestone_pedestal = placeholder();
|
||||
|
||||
public static final Block acacia_gilded_wood = placeholder();
|
||||
public static final Block birch_gilded_wood = placeholder();
|
||||
public static final Block dark_oak_gilded_wood = placeholder();
|
||||
public static final Block jungle_gilded_wood = placeholder();
|
||||
public static final Block oak_gilded_wood = placeholder();
|
||||
public static final Block spruce_gilded_wood = placeholder();
|
||||
|
||||
public static final Block oak_bookshelf = placeholder();
|
||||
public static final Block spruce_bookshelf = placeholder();
|
||||
@@ -108,7 +136,15 @@ public final class WizardryBlocks {
|
||||
registerBlock(registry, "crystal_ore", new BlockCrystalOre(Material.ROCK).setHardness(3.0F).setCreativeTab(WizardryTabs.WIZARDRY));
|
||||
registerBlock(registry, "crystal_flower", new BlockCrystalFlower(Material.PLANTS).setHardness(0.0F).setCreativeTab(WizardryTabs.WIZARDRY));
|
||||
registerBlock(registry, "transportation_stone", new BlockTransportationStone(Material.ROCK).setHardness(0.3F).setLightLevel(0.5f).setLightOpacity(0).setCreativeTab(WizardryTabs.WIZARDRY));
|
||||
registerBlock(registry, "crystal_block", new BlockCrystal(Material.IRON).setHardness(5.0F).setResistance(10.0F).setCreativeTab(WizardryTabs.WIZARDRY));
|
||||
|
||||
registerBlock(registry, "magic_crystal_block", new BlockCrystal(Element.MAGIC).setHardness(5.0F).setResistance(10.0F).setCreativeTab(WizardryTabs.WIZARDRY));
|
||||
registerBlock(registry, "fire_crystal_block", new BlockCrystal(Element.MAGIC).setHardness(5.0F).setResistance(10.0F).setCreativeTab(WizardryTabs.WIZARDRY));
|
||||
registerBlock(registry, "ice_crystal_block", new BlockCrystal(Element.MAGIC).setHardness(5.0F).setResistance(10.0F).setCreativeTab(WizardryTabs.WIZARDRY));
|
||||
registerBlock(registry, "lightning_crystal_block", new BlockCrystal(Element.MAGIC).setHardness(5.0F).setResistance(10.0F).setCreativeTab(WizardryTabs.WIZARDRY));
|
||||
registerBlock(registry, "necromancy_crystal_block", new BlockCrystal(Element.MAGIC).setHardness(5.0F).setResistance(10.0F).setCreativeTab(WizardryTabs.WIZARDRY));
|
||||
registerBlock(registry, "earth_crystal_block", new BlockCrystal(Element.MAGIC).setHardness(5.0F).setResistance(10.0F).setCreativeTab(WizardryTabs.WIZARDRY));
|
||||
registerBlock(registry, "sorcery_crystal_block", new BlockCrystal(Element.MAGIC).setHardness(5.0F).setResistance(10.0F).setCreativeTab(WizardryTabs.WIZARDRY));
|
||||
registerBlock(registry, "healing_crystal_block", new BlockCrystal(Element.MAGIC).setHardness(5.0F).setResistance(10.0F).setCreativeTab(WizardryTabs.WIZARDRY));
|
||||
|
||||
registerBlock(registry, "petrified_stone", new BlockStatue(Material.ROCK).setHardness(1.5F).setResistance(10.0F));
|
||||
registerBlock(registry, "ice_statue", new BlockStatue(Material.ICE).setHardness(0.5F).setLightOpacity(3));
|
||||
@@ -123,10 +159,28 @@ public final class WizardryBlocks {
|
||||
registerBlock(registry, "crystal_flower_pot", new BlockCrystalFlowerPot());
|
||||
registerBlock(registry, "permafrost", new BlockPermafrost());
|
||||
|
||||
registerBlock(registry, "runestone", new BlockRunestone(Material.ROCK));
|
||||
registerBlock(registry, "runestone_pedestal", new BlockPedestal(Material.ROCK));
|
||||
registerBlock(registry, "fire_runestone", new BlockRunestone(Material.ROCK, Element.FIRE));
|
||||
registerBlock(registry, "ice_runestone", new BlockRunestone(Material.ROCK, Element.ICE));
|
||||
registerBlock(registry, "lightning_runestone", new BlockRunestone(Material.ROCK, Element.LIGHTNING));
|
||||
registerBlock(registry, "necromancy_runestone", new BlockRunestone(Material.ROCK, Element.NECROMANCY));
|
||||
registerBlock(registry, "earth_runestone", new BlockRunestone(Material.ROCK, Element.EARTH));
|
||||
registerBlock(registry, "sorcery_runestone", new BlockRunestone(Material.ROCK, Element.SORCERY));
|
||||
registerBlock(registry, "healing_runestone", new BlockRunestone(Material.ROCK, Element.HEALING));
|
||||
|
||||
registerBlock(registry, "gilded_wood", new BlockGildedWood());
|
||||
registerBlock(registry, "fire_runestone_pedestal", new BlockRunestonePedestal(Material.ROCK, Element.FIRE));
|
||||
registerBlock(registry, "ice_runestone_pedestal", new BlockRunestonePedestal(Material.ROCK, Element.ICE));
|
||||
registerBlock(registry, "lightning_runestone_pedestal", new BlockRunestonePedestal(Material.ROCK, Element.LIGHTNING));
|
||||
registerBlock(registry, "necromancy_runestone_pedestal", new BlockRunestonePedestal(Material.ROCK, Element.NECROMANCY));
|
||||
registerBlock(registry, "earth_runestone_pedestal", new BlockRunestonePedestal(Material.ROCK, Element.EARTH));
|
||||
registerBlock(registry, "healing_runestone_pedestal", new BlockRunestonePedestal(Material.ROCK, Element.HEALING));
|
||||
registerBlock(registry, "sorcery_runestone_pedestal", new BlockRunestonePedestal(Material.ROCK, Element.SORCERY));
|
||||
|
||||
registerBlock(registry, "acacia_gilded_wood", new BlockGildedWood());
|
||||
registerBlock(registry, "birch_gilded_wood", new BlockGildedWood());
|
||||
registerBlock(registry, "dark_oak_gilded_wood", new BlockGildedWood());
|
||||
registerBlock(registry, "jungle_gilded_wood", new BlockGildedWood());
|
||||
registerBlock(registry, "oak_gilded_wood", new BlockGildedWood());
|
||||
registerBlock(registry, "spruce_gilded_wood", new BlockGildedWood());
|
||||
|
||||
registerBlock(registry, "oak_bookshelf", new BlockBookshelf());
|
||||
registerBlock(registry, "spruce_bookshelf", new BlockBookshelf());
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -26,11 +26,13 @@ import net.minecraft.item.ItemArmor.ArmorMaterial;
|
||||
import net.minecraft.item.ItemBlock;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.BannerPattern;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.EnumHelper;
|
||||
import net.minecraftforge.event.RegistryEvent;
|
||||
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.GameRegistry.ObjectHolder;
|
||||
import net.minecraftforge.registries.IForgeRegistry;
|
||||
|
||||
@@ -79,12 +81,21 @@ public final class WizardryItems {
|
||||
// which means you lose the individual fields...
|
||||
|
||||
public static final Item magic_crystal = placeholder();
|
||||
public static final Item earth_crystal = placeholder();
|
||||
public static final Item fire_crystal = placeholder();
|
||||
public static final Item healing_crystal = placeholder();
|
||||
public static final Item ice_crystal = placeholder();
|
||||
public static final Item lightning_crystal = placeholder();
|
||||
public static final Item necromancy_crystal = placeholder();
|
||||
public static final Item sorcery_crystal = placeholder();
|
||||
|
||||
public static final Item grand_crystal = placeholder();
|
||||
public static final Item crystal_shard = placeholder();
|
||||
|
||||
public static final Item wizard_handbook = placeholder();
|
||||
public static final Item arcane_tome = placeholder();
|
||||
public static final Item arcane_tome_apprentice = placeholder();
|
||||
public static final Item arcane_tome_advanced = placeholder();
|
||||
public static final Item arcane_tome_master = placeholder();
|
||||
public static final Item spell_book = placeholder();
|
||||
public static final Item scroll = placeholder();
|
||||
public static final Item ruined_spell_book = placeholder();
|
||||
@@ -162,7 +173,13 @@ public final class WizardryItems {
|
||||
public static final Item smoke_bomb = placeholder();
|
||||
public static final Item spark_bomb = placeholder();
|
||||
|
||||
public static final Item spectral_dust = placeholder();
|
||||
public static final Item spectral_dust_earth = placeholder();
|
||||
public static final Item spectral_dust_fire = placeholder();
|
||||
public static final Item spectral_dust_healing = placeholder();
|
||||
public static final Item spectral_dust_ice = placeholder();
|
||||
public static final Item spectral_dust_lightning = placeholder();
|
||||
public static final Item spectral_dust_necromancy = placeholder();
|
||||
public static final Item spectral_dust_sorcery = placeholder();
|
||||
|
||||
public static final Item wizard_hat = placeholder();
|
||||
public static final Item wizard_robe = placeholder();
|
||||
@@ -543,10 +560,37 @@ public final class WizardryItems {
|
||||
String[] elements = Arrays.stream(Element.values()).map(Element::getName).toArray(String[]::new);
|
||||
String[] woodTypes = Arrays.stream(BlockPlanks.EnumType.values()).map(BlockPlanks.EnumType::getName).toArray(String[]::new);
|
||||
|
||||
registerMultiTexturedItemBlock(registry, WizardryBlocks.crystal_block, true, elements);
|
||||
registerMultiTexturedItemBlock(registry, WizardryBlocks.runestone, false, elements);
|
||||
registerMultiTexturedItemBlock(registry, WizardryBlocks.runestone_pedestal, false, elements);
|
||||
registerMultiTexturedItemBlock(registry, WizardryBlocks.gilded_wood, true, woodTypes);
|
||||
registerItemBlock(registry, WizardryBlocks.magic_crystal_block);
|
||||
registerItemBlock(registry, WizardryBlocks.fire_crystal_block);
|
||||
registerItemBlock(registry, WizardryBlocks.ice_crystal_block);
|
||||
registerItemBlock(registry, WizardryBlocks.lightning_crystal_block);
|
||||
registerItemBlock(registry, WizardryBlocks.necromancy_crystal_block);
|
||||
registerItemBlock(registry, WizardryBlocks.earth_crystal_block);
|
||||
registerItemBlock(registry, WizardryBlocks.sorcery_crystal_block);
|
||||
registerItemBlock(registry, WizardryBlocks.healing_crystal_block);
|
||||
|
||||
registerItemBlock(registry, WizardryBlocks.fire_runestone);
|
||||
registerItemBlock(registry, WizardryBlocks.ice_runestone);
|
||||
registerItemBlock(registry, WizardryBlocks.lightning_runestone);
|
||||
registerItemBlock(registry, WizardryBlocks.necromancy_runestone);
|
||||
registerItemBlock(registry, WizardryBlocks.earth_runestone);
|
||||
registerItemBlock(registry, WizardryBlocks.sorcery_runestone);
|
||||
registerItemBlock(registry, WizardryBlocks.healing_runestone);
|
||||
|
||||
registerItemBlock(registry, WizardryBlocks.fire_runestone_pedestal);
|
||||
registerItemBlock(registry, WizardryBlocks.ice_runestone_pedestal);
|
||||
registerItemBlock(registry, WizardryBlocks.lightning_runestone_pedestal);
|
||||
registerItemBlock(registry, WizardryBlocks.necromancy_runestone_pedestal);
|
||||
registerItemBlock(registry, WizardryBlocks.earth_runestone_pedestal);
|
||||
registerItemBlock(registry, WizardryBlocks.healing_runestone_pedestal);
|
||||
registerItemBlock(registry, WizardryBlocks.sorcery_runestone_pedestal);
|
||||
|
||||
registerItemBlock(registry, WizardryBlocks.acacia_gilded_wood);
|
||||
registerItemBlock(registry, WizardryBlocks.birch_gilded_wood);
|
||||
registerItemBlock(registry, WizardryBlocks.dark_oak_gilded_wood);
|
||||
registerItemBlock(registry, WizardryBlocks.jungle_gilded_wood);
|
||||
registerItemBlock(registry, WizardryBlocks.oak_gilded_wood);
|
||||
registerItemBlock(registry, WizardryBlocks.spruce_gilded_wood);
|
||||
|
||||
registerItemBlock(registry, WizardryBlocks.oak_bookshelf);
|
||||
registerItemBlock(registry, WizardryBlocks.spruce_bookshelf);
|
||||
@@ -567,13 +611,22 @@ public final class WizardryItems {
|
||||
|
||||
// Items
|
||||
|
||||
registerItem(registry, "magic_crystal", new ItemCrystal());
|
||||
registerItem(registry, "magic_crystal", new ItemCrystal(Element.MAGIC));
|
||||
registerItem(registry, "earth_crystal", new ItemCrystal(Element.EARTH));
|
||||
registerItem(registry, "fire_crystal", new ItemCrystal(Element.FIRE));
|
||||
registerItem(registry, "healing_crystal", new ItemCrystal(Element.HEALING));
|
||||
registerItem(registry, "ice_crystal", new ItemCrystal(Element.ICE));
|
||||
registerItem(registry, "lightning_crystal", new ItemCrystal(Element.LIGHTNING));
|
||||
registerItem(registry, "necromancy_crystal", new ItemCrystal(Element.NECROMANCY));
|
||||
registerItem(registry, "sorcery_crystal", new ItemCrystal(Element.SORCERY));
|
||||
|
||||
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, "arcane_tome_apprentice", new ItemArcaneTome(EnumRarity.UNCOMMON, Tier.APPRENTICE));
|
||||
registerItem(registry, "arcane_tome_advanced", new ItemArcaneTome(EnumRarity.RARE, Tier.ADVANCED));
|
||||
registerItem(registry, "arcane_tome_master", new ItemArcaneTome(EnumRarity.EPIC, Tier.MASTER));
|
||||
registerItem(registry, "spell_book", new ItemSpellBook(), true);
|
||||
registerItem(registry, "scroll", new ItemScroll());
|
||||
registerItem(registry, "ruined_spell_book", new Item().setCreativeTab(WizardryTabs.WIZARDRY).setMaxStackSize(16));
|
||||
@@ -654,7 +707,13 @@ public final class WizardryItems {
|
||||
registerItem(registry, "smoke_bomb", new ItemSmokeBomb());
|
||||
registerItem(registry, "spark_bomb", new ItemSparkBomb());
|
||||
|
||||
registerItem(registry, "spectral_dust", new ItemSpectralDust());
|
||||
registerItem(registry, "spectral_dust_earth", new ItemSpectralDust());
|
||||
registerItem(registry, "spectral_dust_fire", new ItemSpectralDust());
|
||||
registerItem(registry, "spectral_dust_healing", new ItemSpectralDust());
|
||||
registerItem(registry, "spectral_dust_ice", new ItemSpectralDust());
|
||||
registerItem(registry, "spectral_dust_lightning", new ItemSpectralDust());
|
||||
registerItem(registry, "spectral_dust_necromancy", new ItemSpectralDust());
|
||||
registerItem(registry, "spectral_dust_sorcery", new ItemSpectralDust());
|
||||
|
||||
registerItem(registry, "wizard_hat", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.HEAD, null), true);
|
||||
registerItem(registry, "wizard_robe", new ItemWizardArmour(ArmourClass.WIZARD, EntityEquipmentSlot.CHEST, null));
|
||||
@@ -991,9 +1050,11 @@ public final class WizardryItems {
|
||||
/** Called from init() in the main mod class to register wizardry's banner patterns. */
|
||||
public static void registerBannerPatterns(){
|
||||
for(Element element : Element.values()){
|
||||
if(element != Element.MAGIC) addBannerPattern("WIZARDRY_" + element.getName().toUpperCase(Locale.ROOT),
|
||||
"wizardry_" + element.getName(), "eb" + element.getName().charAt(0),
|
||||
new ItemStack(WizardryItems.magic_crystal, 1, element.ordinal()));
|
||||
if (element != Element.MAGIC) {
|
||||
addBannerPattern("WIZARDRY_" + element.getName().toUpperCase(Locale.ROOT),
|
||||
"wizardry_" + element.getName(), "eb" + element.getName().charAt(0),
|
||||
new ItemStack(ForgeRegistries.ITEMS.getValue(new ResourceLocation(Wizardry.MODID, "crystal_" + element.name().toLowerCase()))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,11 @@ import electroblob.wizardry.loot.RandomSpell;
|
||||
import electroblob.wizardry.loot.WizardSpell;
|
||||
import net.minecraft.entity.EnumCreatureType;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.world.storage.loot.*;
|
||||
import net.minecraft.world.storage.loot.LootEntry;
|
||||
import net.minecraft.world.storage.loot.LootEntryTable;
|
||||
import net.minecraft.world.storage.loot.LootPool;
|
||||
import net.minecraft.world.storage.loot.LootTableList;
|
||||
import net.minecraft.world.storage.loot.RandomValueRange;
|
||||
import net.minecraft.world.storage.loot.conditions.LootCondition;
|
||||
import net.minecraft.world.storage.loot.functions.LootFunctionManager;
|
||||
import net.minecraftforge.event.LootTableLoadEvent;
|
||||
@@ -90,23 +94,27 @@ public final class WizardryLoot {
|
||||
event.getTable().addPool(getAdditive(Wizardry.MODID + ":chests/jungle_dispenser_additions", Wizardry.MODID + "_additional_dispenser_loot"));
|
||||
}
|
||||
// Mob drops
|
||||
// Let's hope mods will play nice and store their entity loot tables under 'entities' or 'entity'
|
||||
// If not, packmakers will have to sort it out themselves using the whitelist/blacklist
|
||||
if(Arrays.asList(Wizardry.settings.mobLootTableWhitelist).contains(event.getName())){
|
||||
event.getTable().addPool(getAdditive(Wizardry.MODID + ":entities/mob_additions", Wizardry.MODID + "_additional_mob_drops"));
|
||||
|
||||
}else if(!Arrays.asList(Wizardry.settings.mobLootTableBlacklist).contains(event.getName())
|
||||
&& event.getName().getPath().contains("entities") || event.getName().getPath().contains("entity")){
|
||||
// Get the filename of the loot table json, for well-behaved mods this will be the entity name
|
||||
String[] split = event.getName().getPath().split("/");
|
||||
String entityName = split[split.length - 1];
|
||||
|
||||
EntityEntry entry = ForgeRegistries.ENTITIES.getValue(new ResourceLocation(entityName));
|
||||
if(entry == null) return; // If this is true it didn't work :(
|
||||
Class entityClass = entry.getEntityClass();
|
||||
|
||||
if(EnumCreatureType.MONSTER.getCreatureClass().isAssignableFrom(entityClass)){
|
||||
if (Wizardry.settings.injectMobDrops) {
|
||||
// Let's hope mods will play nice and store their entity loot tables under 'entities' or 'entity'
|
||||
// If not, packmakers will have to sort it out themselves using the whitelist/blacklist
|
||||
if (Arrays.asList(Wizardry.settings.mobLootTableWhitelist).contains(event.getName())) {
|
||||
event.getTable().addPool(getAdditive(Wizardry.MODID + ":entities/mob_additions", Wizardry.MODID + "_additional_mob_drops"));
|
||||
|
||||
} else if (!Arrays.asList(Wizardry.settings.mobLootTableBlacklist).contains(event.getName())
|
||||
&& event.getName().getPath().contains("entities") || event.getName().getPath().contains("entity")) {
|
||||
// Get the filename of the loot table json, for well-behaved mods this will be the entity name
|
||||
String[] split = event.getName().getPath().split("/");
|
||||
String entityName = split[split.length - 1];
|
||||
|
||||
EntityEntry entry = ForgeRegistries.ENTITIES.getValue(new ResourceLocation(entityName));
|
||||
if (entry == null) {
|
||||
return; // If this is true it didn't work :(
|
||||
}
|
||||
Class entityClass = entry.getEntityClass();
|
||||
|
||||
if (EnumCreatureType.MONSTER.getCreatureClass().isAssignableFrom(entityClass)) {
|
||||
event.getTable().addPool(getAdditive(Wizardry.MODID + ":entities/mob_additions", Wizardry.MODID + "_additional_mob_drops"));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fishing loot
|
||||
|
||||
@@ -57,6 +57,9 @@ public final class WizardryPotions {
|
||||
public static final Potion frost_step = placeholder();
|
||||
public static final Potion mark_of_sacrifice = placeholder();
|
||||
public static final Potion mirage = placeholder();
|
||||
public static final Potion oakflesh = placeholder();
|
||||
public static final Potion ironflesh = placeholder();
|
||||
public static final Potion diamondflesh = placeholder();
|
||||
|
||||
/**
|
||||
* Sets both the registry and unlocalised names of the given potion, then registers it with the given registry. Use
|
||||
@@ -201,6 +204,10 @@ public final class WizardryPotions {
|
||||
public void spawnCustomParticle(World world, double x, double y, double z){} // We only want the syncing
|
||||
}.setBeneficial());
|
||||
|
||||
registerPotion(registry, "oakflesh", new PotionOakflesh(false, 0).setBeneficial());
|
||||
registerPotion(registry, "ironflesh", new PotionIronflesh(false, 0).setBeneficial());
|
||||
registerPotion(registry, "diamondflesh", new PotionDiamondflesh(false, 0).setBeneficial());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -33,7 +33,7 @@ public class ConjureBlock extends SpellRay {
|
||||
@Override
|
||||
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, Vec3d hit, EntityLivingBase caster, Vec3d origin, int ticksInUse, SpellModifiers modifiers){
|
||||
|
||||
if(caster.isSneaking() && world.getBlockState(pos).getBlock() == WizardryBlocks.spectral_block){
|
||||
if(caster != null && caster.isSneaking() && world.getBlockState(pos).getBlock() == WizardryBlocks.spectral_block){
|
||||
|
||||
if(!world.isRemote){
|
||||
// Dispelling of blocks
|
||||
|
||||
@@ -53,7 +53,7 @@ public class CurseOfSoulbinding extends SpellRay {
|
||||
|
||||
@Override
|
||||
protected boolean onEntityHit(World world, Entity target, Vec3d hit, EntityLivingBase caster, Vec3d origin, int ticksInUse, SpellModifiers modifiers){
|
||||
|
||||
|
||||
if(EntityUtils.isLiving(target) && caster instanceof EntityPlayer){
|
||||
WizardData data = WizardData.get((EntityPlayer)caster);
|
||||
if(data != null){
|
||||
@@ -66,7 +66,7 @@ public class CurseOfSoulbinding extends SpellRay {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ public class CurseOfSoulbinding extends SpellRay {
|
||||
protected boolean onMiss(World world, EntityLivingBase caster, Vec3d origin, Vec3d direction, int ticksInUse, SpellModifiers modifiers){
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
|
||||
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).clr(0.4f, 0, 0).spawn(world);
|
||||
@@ -103,9 +103,9 @@ public class CurseOfSoulbinding extends SpellRay {
|
||||
|
||||
Entity entity = EntityUtils.getEntityByUUID(player.world, iterator.next());
|
||||
|
||||
if(entity == null) iterator.remove();
|
||||
|
||||
if(entity instanceof EntityLivingBase){
|
||||
if (entity == null || (entity instanceof EntityLivingBase && !((EntityLivingBase) entity).isPotionActive(WizardryPotions.curse_of_soulbinding))) {
|
||||
iterator.remove();
|
||||
} else if (entity instanceof EntityLivingBase) {
|
||||
// Retaliatory effect
|
||||
if(DamageSafetyChecker.attackEntitySafely(entity, MagicDamage.causeDirectMagicDamage(player,
|
||||
MagicDamage.DamageType.MAGIC, true), event.getAmount(), event.getSource().getDamageType(),
|
||||
|
||||
@@ -5,6 +5,7 @@ import electroblob.wizardry.constants.Constants;
|
||||
import electroblob.wizardry.entity.living.ISpellCaster;
|
||||
import electroblob.wizardry.event.SpellCastEvent;
|
||||
import electroblob.wizardry.item.SpellActions;
|
||||
import electroblob.wizardry.registry.Spells;
|
||||
import electroblob.wizardry.registry.WizardryItems;
|
||||
import electroblob.wizardry.registry.WizardryPotions;
|
||||
import electroblob.wizardry.util.ParticleBuilder;
|
||||
@@ -24,11 +25,14 @@ import javax.annotation.Nullable;
|
||||
@Mod.EventBusSubscriber
|
||||
public class EmpoweringPresence extends SpellAreaEffect {
|
||||
|
||||
/** The fraction by which potency is increased per level of the empowerment effect. */
|
||||
public static final String POTENCY_PER_LEVEL = "potency_per_level";
|
||||
|
||||
public EmpoweringPresence(){
|
||||
super("empowering_presence", SpellActions.POINT_UP, false);
|
||||
this.alwaysSucceed(true);
|
||||
this.targetAllies(true);
|
||||
addProperties(EFFECT_DURATION, EFFECT_STRENGTH);
|
||||
addProperties(EFFECT_DURATION, EFFECT_STRENGTH, POTENCY_PER_LEVEL);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -62,7 +66,7 @@ public class EmpoweringPresence extends SpellAreaEffect {
|
||||
if(event.getCaster() != null && event.getCaster().isPotionActive(WizardryPotions.empowerment)
|
||||
&& !(event.getSpell() instanceof EmpoweringPresence)){ // Prevent exponential empowerment stacking!
|
||||
|
||||
float potency = 1 + Constants.EMPOWERMENT_POTENCY_PER_LEVEL
|
||||
float potency = 1 + Spells.empowering_presence.getProperty(POTENCY_PER_LEVEL).floatValue()
|
||||
* (event.getCaster().getActivePotionEffect(WizardryPotions.empowerment).getAmplifier() + 1);
|
||||
|
||||
event.getModifiers().set(SpellModifiers.POTENCY,
|
||||
|
||||
@@ -59,18 +59,19 @@ public class FrostRay extends SpellRay {
|
||||
this.getNameForTranslationFormatted()), true);
|
||||
// This now only damages in line with the maxHurtResistantTime. Some mods don't play nicely and fiddle
|
||||
// with this mechanic for their own purposes, so this line makes sure that doesn't affect wizardry.
|
||||
}else if(ticksInUse % ((EntityLivingBase)target).maxHurtResistantTime == 1){
|
||||
}else{
|
||||
// For frost ray the entity can move slightly, unlike freeze
|
||||
((EntityLivingBase)target).addPotionEffect(new PotionEffect(WizardryPotions.frost,
|
||||
(int)(getProperty(EFFECT_DURATION).floatValue() * modifiers.get(WizardryItems.duration_upgrade)),
|
||||
getProperty(EFFECT_STRENGTH).intValue()));
|
||||
|
||||
float damage = getProperty(DAMAGE).floatValue() * modifiers.get(SpellModifiers.POTENCY);
|
||||
if(target instanceof EntityBlaze || target instanceof EntityMagmaCube) damage *= 2;
|
||||
|
||||
EntityUtils.attackEntityWithoutKnockback(target, MagicDamage.causeDirectMagicDamage(caster,
|
||||
DamageType.FROST), damage);
|
||||
if(ticksInUse % ((EntityLivingBase)target).maxHurtResistantTime == 1){
|
||||
float damage = getProperty(DAMAGE).floatValue() * modifiers.get(SpellModifiers.POTENCY);
|
||||
if(target instanceof EntityBlaze || target instanceof EntityMagmaCube) damage *= 2;
|
||||
|
||||
EntityUtils.attackEntityWithoutKnockback(target, MagicDamage.causeDirectMagicDamage(caster,
|
||||
DamageType.FROST), damage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import electroblob.wizardry.util.ParticleBuilder.Type;
|
||||
import electroblob.wizardry.util.SpellModifiers;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.SoundEvents;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
@@ -24,14 +25,14 @@ public class Glide extends Spell {
|
||||
|
||||
@Override
|
||||
protected void playSound(World world, EntityLivingBase entity, int ticksInUse, int duration, SpellModifiers modifiers, String... sounds){
|
||||
if(ticksInUse == 0 && world.isRemote) Wizardry.proxy.playSpellSoundLoop(entity, this, this.sounds[0], this.sounds[0], this.sounds[0],
|
||||
if(ticksInUse == 0 && world.isRemote) Wizardry.proxy.playSpellSoundLoop(entity, this, this.sounds[0], this.sounds[0], SoundEvents.UI_TOAST_OUT,
|
||||
WizardrySounds.SPELLS, volume, pitch + pitchVariation * (world.rand.nextFloat() - 0.5f));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void playSound(World world, double x, double y, double z, int ticksInUse, int duration, SpellModifiers modifiers, String... sounds){
|
||||
if(ticksInUse == 0 && world.isRemote){
|
||||
Wizardry.proxy.playSpellSoundLoop(world, x, y, z, this, this.sounds[0], this.sounds[0], this.sounds[0],
|
||||
Wizardry.proxy.playSpellSoundLoop(world, x, y, z, this, this.sounds[0], this.sounds[0], SoundEvents.UI_TOAST_OUT,
|
||||
WizardrySounds.SPELLS, volume, pitch + pitchVariation * (world.rand.nextFloat() - 0.5f), duration);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ public class MarkSacrifice extends SpellRay {
|
||||
PotionEffect effect = event.getEntityLiving().getActivePotionEffect(WizardryPotions.mark_of_sacrifice);
|
||||
|
||||
if(effect != null && event.getSource().isMagicDamage()){
|
||||
event.setAmount(event.getAmount() * (1 + effect.getAmplifier() * DAMAGE_INCREASE_PER_LEVEL));
|
||||
event.setAmount(event.getAmount() * (1 + effect.getAmplifier()) * DAMAGE_INCREASE_PER_LEVEL);
|
||||
event.getEntityLiving().removePotionEffect(WizardryPotions.mark_of_sacrifice);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,6 +111,9 @@ public class MindControl extends SpellRay {
|
||||
|
||||
/** Returns true if the given entity can be mind controlled (i.e. is not a player, npc, evil wizard or boss). */
|
||||
public static boolean canControl(Entity target){
|
||||
|
||||
// TODO: Add a max health limit that scales with potency
|
||||
|
||||
return target instanceof EntityLiving && target.isNonBoss() && !(target instanceof INpc)
|
||||
&& !(target instanceof EntityEvilWizard) && !Arrays.asList(Wizardry.settings.mindControlTargetsBlacklist)
|
||||
.contains(EntityList.getKey(target.getClass()));
|
||||
|
||||
@@ -30,9 +30,14 @@ public class Paralysis extends SpellRay {
|
||||
* will end. */
|
||||
private static final String CRITICAL_HEALTH = "critical_health";
|
||||
|
||||
/**
|
||||
* Multiplier for affecting players
|
||||
*/
|
||||
private static final String PLAYER_EFFECT_DURATION_MULTIPLIER = "player_effect_duration_multiplier";
|
||||
|
||||
public Paralysis(){
|
||||
super("paralysis", SpellActions.POINT, false);
|
||||
addProperties(DAMAGE, EFFECT_DURATION, CRITICAL_HEALTH);
|
||||
addProperties(DAMAGE, EFFECT_DURATION, CRITICAL_HEALTH, PLAYER_EFFECT_DURATION_MULTIPLIER);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -57,9 +62,10 @@ public class Paralysis extends SpellRay {
|
||||
target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK),
|
||||
getProperty(DAMAGE).floatValue() * modifiers.get(SpellModifiers.POTENCY));
|
||||
}
|
||||
|
||||
|
||||
float durationMultiplier = target instanceof EntityPlayer ? modifiers.get(PLAYER_EFFECT_DURATION_MULTIPLIER) : 1.0f;
|
||||
((EntityLivingBase)target).addPotionEffect(new PotionEffect(WizardryPotions.paralysis,
|
||||
(int)(getProperty(EFFECT_DURATION).floatValue() * modifiers.get(WizardryItems.duration_upgrade)), 0));
|
||||
(int)(getProperty(EFFECT_DURATION).floatValue() * durationMultiplier * modifiers.get(WizardryItems.duration_upgrade)), 0));
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package electroblob.wizardry.spell;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.data.WizardData;
|
||||
import electroblob.wizardry.event.ResurrectionEvent;
|
||||
import electroblob.wizardry.item.ISpellCastingItem;
|
||||
import electroblob.wizardry.item.SpellActions;
|
||||
import electroblob.wizardry.packet.PacketResurrection;
|
||||
@@ -8,6 +10,7 @@ import electroblob.wizardry.packet.WizardryPacketHandler;
|
||||
import electroblob.wizardry.registry.Spells;
|
||||
import electroblob.wizardry.registry.WizardryItems;
|
||||
import electroblob.wizardry.util.ParticleBuilder;
|
||||
import electroblob.wizardry.util.ParticleBuilder.Type;
|
||||
import electroblob.wizardry.util.SpellModifiers;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
@@ -16,11 +19,16 @@ import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
||||
@EventBusSubscriber
|
||||
public class Resurrection extends Spell {
|
||||
|
||||
public static final String WAIT_TIME = "wait_time";
|
||||
@@ -55,6 +63,9 @@ public class Resurrection extends Spell {
|
||||
.orElse(null);
|
||||
|
||||
if(nearestDeadAlly != null){
|
||||
|
||||
if(MinecraftForge.EVENT_BUS.post(new ResurrectionEvent(nearestDeadAlly, caster))) return false;
|
||||
|
||||
// When the player entity dies, it is removed from world#loadedEntityList. However, it is NOT removed
|
||||
// from playerEntityList (and probably a few other places) until respawn is clicked, and since that
|
||||
// never happens here we need to clean up those references or the player will have duplicate entries
|
||||
@@ -112,4 +123,42 @@ public class Resurrection extends Spell {
|
||||
&& ((ISpellCastingItem)stack.getItem()).canCast(stack, Spells.resurrection, player, EnumHand.MAIN_HAND, 0, new SpellModifiers());
|
||||
}
|
||||
|
||||
}
|
||||
@SubscribeEvent
|
||||
public static void onPlayerTickEvent(LivingUpdateEvent event){
|
||||
|
||||
if(event.getEntity() instanceof EntityPlayer){
|
||||
|
||||
EntityPlayer player = (EntityPlayer)event.getEntity();
|
||||
|
||||
if(player.world.isRemote && !player.isEntityAlive()){
|
||||
|
||||
EntityPlayer firstPersonPlayer = Wizardry.proxy.getThePlayer();
|
||||
|
||||
if(WizardData.get(firstPersonPlayer).isPlayerAlly(player)){
|
||||
|
||||
ItemStack wand = firstPersonPlayer.getHeldItemMainhand();
|
||||
|
||||
if(!(wand.getItem() instanceof ISpellCastingItem)){
|
||||
wand = firstPersonPlayer.getHeldItemOffhand();
|
||||
if(!(wand.getItem() instanceof ISpellCastingItem)) return;
|
||||
}
|
||||
|
||||
if(((ISpellCastingItem)wand.getItem()).getCurrentSpell(wand) == Spells.resurrection){
|
||||
|
||||
// TODO: Find some way of getting at the modifiers before the spell is cast
|
||||
int waitTime = Spells.resurrection.getProperty(WAIT_TIME).intValue();
|
||||
|
||||
if(player.deathTime > waitTime){
|
||||
ParticleBuilder.create(Type.SPARKLE, player.world.rand, player.posX, player.posY + 0.5, player.posZ, 0.5, false)
|
||||
.clr(1, 1, 0.3f).vel(0, 0.02, 0).spawn(player.world);
|
||||
}else{
|
||||
ParticleBuilder.create(Type.DUST, player.world.rand, player.posX, player.posY + 0.5, player.posZ, 0.5, false)
|
||||
.clr(1, 1, 0.3f).vel(0, 0.02, 0).time(50).spawn(player.world);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -189,7 +189,7 @@ public abstract class Spell extends IForgeRegistryEntry.Impl<Spell> implements C
|
||||
private static int nextSpellId = 0;
|
||||
/** The spell's integer ID, mainly used for networking. */
|
||||
// This was added after I learnt the hard way why you can't assume Forge's registry IDs are sequential...
|
||||
private final int id;
|
||||
private int id;
|
||||
|
||||
/**
|
||||
* This constructor should be called from any subclasses, either feeding in the constants directly or through their
|
||||
@@ -225,6 +225,7 @@ public abstract class Spell extends IForgeRegistryEntry.Impl<Spell> implements C
|
||||
this.icon = new ResourceLocation(modID, "textures/spells/" + name + ".png");
|
||||
this.sounds = createSounds();
|
||||
this.id = nextSpellId++;
|
||||
Wizardry.logger.debug("Registering spell " + this.unlocalisedName +" with networkID " + id);
|
||||
this.items(WizardryItems.spell_book, WizardryItems.scroll);
|
||||
this.npcSelector((e, o) -> false);
|
||||
}
|
||||
@@ -560,6 +561,11 @@ public abstract class Spell extends IForgeRegistryEntry.Impl<Spell> implements C
|
||||
return id;
|
||||
}
|
||||
|
||||
/** Sets the networkID of this spell. Do not call this or it will cause all packets to fail. */
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/** Returns the {@code ResourceLocation} for this spell's icon. */
|
||||
public final ResourceLocation getIcon(){
|
||||
return icon;
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
package electroblob.wizardry.spell;
|
||||
|
||||
import electroblob.wizardry.item.SpellActions;
|
||||
import electroblob.wizardry.util.BlockUtils;
|
||||
import electroblob.wizardry.util.ParticleBuilder;
|
||||
import electroblob.wizardry.util.ParticleBuilder.Type;
|
||||
import electroblob.wizardry.util.SpellModifiers;
|
||||
import net.minecraft.entity.monster.EntityIronGolem;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class SummonIronGolem extends Spell {
|
||||
|
||||
public SummonIronGolem(){
|
||||
super("summon_iron_golem", SpellActions.SUMMON, false);
|
||||
addProperties(SpellMinion.SUMMON_RADIUS);
|
||||
soundValues(1, 1.1f, 0.2f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
|
||||
|
||||
BlockPos pos = BlockUtils.findNearbyFloorSpace(caster, getProperty(SpellMinion.SUMMON_RADIUS).intValue(),
|
||||
getProperty(SpellMinion.SUMMON_RADIUS).intValue());
|
||||
|
||||
if(pos == null) return false;
|
||||
|
||||
if(!world.isRemote){
|
||||
|
||||
EntityIronGolem golem = new EntityIronGolem(world);
|
||||
golem.setPosition(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5);
|
||||
golem.setPlayerCreated(true);
|
||||
world.spawnEntity(golem);
|
||||
|
||||
}else{
|
||||
|
||||
for(int i=0; i<10; i++){
|
||||
double x = pos.getX() + world.rand.nextDouble() * 2 - 1;
|
||||
double y = pos.getY() + 0.5 + world.rand.nextDouble();
|
||||
double z = pos.getZ() + world.rand.nextDouble() * 2 - 1;
|
||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).clr(0.6f, 0.6f, 1).spawn(world);
|
||||
}
|
||||
}
|
||||
|
||||
this.playSound(world, caster, ticksInUse, -1, modifiers);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -188,7 +188,9 @@ public class TileEntityArcaneWorkbench extends TileEntity implements IInventory,
|
||||
|
||||
}else if(slotNumber == ContainerArcaneWorkbench.UPGRADE_SLOT){
|
||||
Set<Item> upgrades = new HashSet<>(WandHelper.getSpecialUpgrades());
|
||||
upgrades.add(WizardryItems.arcane_tome);
|
||||
upgrades.add(WizardryItems.arcane_tome_apprentice);
|
||||
upgrades.add(WizardryItems.arcane_tome_advanced);
|
||||
upgrades.add(WizardryItems.arcane_tome_master);
|
||||
upgrades.add(WizardryItems.resplendent_thread);
|
||||
upgrades.add(WizardryItems.crystal_silver_plating);
|
||||
upgrades.add(WizardryItems.ethereal_crystalweave);
|
||||
|
||||
@@ -2,6 +2,7 @@ package electroblob.wizardry.tileentity;
|
||||
|
||||
import electroblob.wizardry.block.BlockReceptacle;
|
||||
import electroblob.wizardry.constants.Element;
|
||||
import electroblob.wizardry.event.ImbuementActivateEvent;
|
||||
import electroblob.wizardry.item.IManaStoringItem;
|
||||
import electroblob.wizardry.item.ItemWizardArmour;
|
||||
import electroblob.wizardry.registry.*;
|
||||
@@ -24,6 +25,7 @@ import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraft.world.storage.loot.LootContext;
|
||||
import net.minecraft.world.storage.loot.LootTable;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
@@ -233,6 +235,14 @@ public class TileEntityImbuementAltar extends TileEntity implements ITickable {
|
||||
*/
|
||||
public static ItemStack getImbuementResult(ItemStack input, Element[] receptacleElements, boolean fullLootGen, World world, EntityPlayer lastUser){
|
||||
|
||||
ItemStack eventResult = ItemStack.EMPTY;
|
||||
|
||||
if (world != null && MinecraftForge.EVENT_BUS.post(new ImbuementActivateEvent(input, receptacleElements, world, lastUser, eventResult))) {
|
||||
// return the stack if something changes the result from an empty stack.
|
||||
//noinspection ConstantConditions
|
||||
if (eventResult != ItemStack.EMPTY) return eventResult;
|
||||
}
|
||||
|
||||
if(input.getItem() instanceof ItemWizardArmour && ((ItemWizardArmour)input.getItem()).element == null){
|
||||
|
||||
if(Arrays.stream(receptacleElements).distinct().count() == 1 && receptacleElements[0] != null){ // All the same element
|
||||
@@ -246,8 +256,7 @@ public class TileEntityImbuementAltar extends TileEntity implements ITickable {
|
||||
}
|
||||
}
|
||||
|
||||
if((input.getItem() == WizardryItems.magic_crystal || input.getItem() == Item.getItemFromBlock(WizardryBlocks.crystal_block))
|
||||
&& input.getMetadata() == 0){
|
||||
if((input.getItem() == WizardryItems.magic_crystal || input.getItem() == Item.getItemFromBlock(WizardryBlocks.magic_crystal_block))){
|
||||
|
||||
if(Arrays.stream(receptacleElements).distinct().count() == 1 && receptacleElements[0] != null){ // All the same element
|
||||
return new ItemStack(input.getItem(), input.getCount(), receptacleElements[0].ordinal());
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package electroblob.wizardry.tileentity;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.block.BlockPedestal;
|
||||
import electroblob.wizardry.api.IElemental;
|
||||
import electroblob.wizardry.block.BlockRunestonePedestal;
|
||||
import electroblob.wizardry.constants.Element;
|
||||
import electroblob.wizardry.entity.living.EntityEvilWizard;
|
||||
import electroblob.wizardry.entity.living.EntityWizard;
|
||||
import electroblob.wizardry.packet.PacketConquerShrine;
|
||||
@@ -101,7 +103,8 @@ public class TileEntityShrineCore extends TileEntity implements ITickable {
|
||||
}
|
||||
|
||||
wizard.setLocationAndAngles(x1, y1 + 0.5, z1, 0, 0);
|
||||
wizard.setElement(world.getBlockState(pos).getValue(BlockPedestal.ELEMENT));
|
||||
wizard.setElement(world.getBlockState(pos).getBlock() instanceof IElemental
|
||||
? ((IElemental) world.getBlockState(pos).getBlock()).getElement() : Element.MAGIC);
|
||||
wizard.onInitialSpawn(world.getDifficultyForLocation(pos), null);
|
||||
wizard.hasStructure = true;
|
||||
|
||||
@@ -144,9 +147,8 @@ public class TileEntityShrineCore extends TileEntity implements ITickable {
|
||||
WizardryPacketHandler.net.sendToAllAround(new PacketConquerShrine.Message(this.pos),
|
||||
new NetworkRegistry.TargetPoint(this.world.provider.getDimension(), x, y, z, 64));
|
||||
|
||||
if(world.getBlockState(pos).getBlock() == WizardryBlocks.runestone_pedestal){
|
||||
world.setBlockState(pos, WizardryBlocks.runestone_pedestal.getDefaultState()
|
||||
.withProperty(BlockPedestal.ELEMENT, world.getBlockState(pos).getValue(BlockPedestal.ELEMENT)));
|
||||
if(world.getBlockState(pos).getBlock() instanceof BlockRunestonePedestal){
|
||||
world.setBlockState(pos, world.getBlockState(pos).getBlock().getDefaultState());
|
||||
}else{
|
||||
Wizardry.logger.warn("What's going on?! A shrine core is being conquered but the block at its position is not a runestone pedestal!");
|
||||
}
|
||||
|
||||
@@ -34,7 +34,9 @@ import java.util.Random;
|
||||
* <code>ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(vx, vy, vz).clr(r, g, b).spawn(world);</code>
|
||||
* <p></p>
|
||||
* It also goes without saying that <b>this class should only ever be used client-side</b>. Attempting to spawn particles
|
||||
* on the server side will not work and will print a warning to the console.
|
||||
* on the server side will not work and will print a warning to the console. {@code ParticleBuilder} is not threadsafe
|
||||
* and attempting to call it from multiple threads at once will very likely cause an {@link IllegalStateException}.
|
||||
*
|
||||
* @author Electroblob
|
||||
* @since Wizardry 4.2
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package electroblob.wizardry.util;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Helper class which ensures that all spellpack spell networkIDs are distributed in alphabetical order. Introducing this was necessary as mods (especially with
|
||||
* (load-after) dependencies were not always registering their spells in the exact same order. This is definitely
|
||||
*/
|
||||
public class SpellNetworkIDSorter {
|
||||
|
||||
public static void init() {
|
||||
|
||||
//reorder network IDs based on addon modids. This is necessary as modloading order doesn't seem to be guaranteed to match between various servers and clients
|
||||
Wizardry.logger.debug("Reordering all spell NetworkIDs based on addon modid alphabetical order");
|
||||
|
||||
// the first available ID after all default spells
|
||||
int nextSpellId = (int) Spell.getAllSpells().stream().filter(spell -> spell.getRegistryName().getNamespace().equals(Wizardry.MODID)).count() + 1;
|
||||
List<Spell> addonSpells = Spell.getAllSpells().stream().filter(spell -> !spell.getRegistryName().getNamespace().equals(Wizardry.MODID)).collect(Collectors.toList());
|
||||
|
||||
// sorting spells
|
||||
addonSpells.sort(Comparator.comparing((Spell o) -> o.getRegistryName().toString()));
|
||||
for (Spell spell : addonSpells) {
|
||||
Wizardry.logger.debug("Updating networkID of spell " + spell.getRegistryName().toString() + " from " + spell.networkID() + " to " + nextSpellId);
|
||||
spell.setId(nextSpellId++);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package electroblob.wizardry.worldgen;
|
||||
|
||||
import electroblob.wizardry.block.BlockGildedWood;
|
||||
import electroblob.wizardry.registry.WizardryBlocks;
|
||||
import electroblob.wizardry.util.BlockUtils;
|
||||
import net.minecraft.block.Block;
|
||||
@@ -89,11 +90,24 @@ public class WoodTypeTemplateProcessor implements ITemplateProcessor {
|
||||
public Template.BlockInfo processBlock(World world, BlockPos pos, Template.BlockInfo info){
|
||||
|
||||
// Why do these each have their own property key?
|
||||
if(info.blockState.getBlock() instanceof BlockPlanks){ // This covers gilded wood too
|
||||
if(info.blockState.getBlock() instanceof BlockPlanks){ // This doesn't cover gilded wood
|
||||
return new Template.BlockInfo(info.pos, info.blockState.withProperty(BlockPlanks.VARIANT, woodType), info.tileentityData);
|
||||
}else if(info.blockState.getBlock() instanceof BlockWoodSlab){
|
||||
return new Template.BlockInfo(info.pos, info.blockState.withProperty(BlockWoodSlab.VARIANT, woodType), info.tileentityData);
|
||||
// This is a mess, no wonder the flattening happened
|
||||
}else if(info.blockState.getBlock() instanceof BlockGildedWood){
|
||||
switch (woodType) {
|
||||
case OAK:
|
||||
return new Template.BlockInfo(info.pos, WizardryBlocks.oak_gilded_wood.getDefaultState(), info.tileentityData);
|
||||
case SPRUCE:
|
||||
return new Template.BlockInfo(info.pos, WizardryBlocks.spruce_gilded_wood.getDefaultState(), info.tileentityData);
|
||||
case BIRCH:
|
||||
return new Template.BlockInfo(info.pos, WizardryBlocks.birch_gilded_wood.getDefaultState(), info.tileentityData);
|
||||
case JUNGLE:
|
||||
return new Template.BlockInfo(info.pos, WizardryBlocks.jungle_gilded_wood.getDefaultState(), info.tileentityData);
|
||||
case ACACIA:
|
||||
return new Template.BlockInfo(info.pos, WizardryBlocks.acacia_gilded_wood.getDefaultState(), info.tileentityData);
|
||||
case DARK_OAK:
|
||||
return new Template.BlockInfo(info.pos, WizardryBlocks.dark_oak_gilded_wood.getDefaultState(), info.tileentityData);
|
||||
}
|
||||
// This is a mess, no wonder the flattening happened
|
||||
}else if(DOORS.containsValue(info.blockState.getBlock())){
|
||||
return new Template.BlockInfo(info.pos, BlockUtils.copyState(DOORS.get(woodType), info.blockState), info.tileentityData);
|
||||
}else if(STAIRS.containsValue(info.blockState.getBlock())){
|
||||
|
||||
@@ -5,6 +5,7 @@ import electroblob.wizardry.block.BlockRunestone;
|
||||
import electroblob.wizardry.constants.Element;
|
||||
import electroblob.wizardry.entity.living.EntityRemnant;
|
||||
import electroblob.wizardry.integration.antiqueatlas.WizardryAntiqueAtlasIntegration;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.MobSpawnerBaseLogic;
|
||||
@@ -17,8 +18,10 @@ import net.minecraft.world.World;
|
||||
import net.minecraft.world.gen.structure.template.ITemplateProcessor;
|
||||
import net.minecraft.world.gen.structure.template.PlacementSettings;
|
||||
import net.minecraft.world.gen.structure.template.Template;
|
||||
import net.minecraftforge.fml.common.registry.ForgeRegistries;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
@@ -57,10 +60,12 @@ public class WorldGenObelisk extends WorldGenSurfaceStructure {
|
||||
@Override
|
||||
public void spawnStructure(Random random, World world, BlockPos origin, Template template, PlacementSettings settings, ResourceLocation structureFile){
|
||||
|
||||
final Element element = Element.values()[1 + random.nextInt(Element.values().length-1)];
|
||||
Element[] elements = (Element[]) Arrays.stream(Element.values()).filter(Element::hasWorldgen).toArray();
|
||||
final Element element = elements[1 + random.nextInt(elements.length-1)];
|
||||
Block runeStone = ForgeRegistries.BLOCKS.getValue(new ResourceLocation(element.getModid(), element.getName().toLowerCase() + "_runestone"));
|
||||
|
||||
ITemplateProcessor processor = (w, p, i) -> i.blockState.getBlock() instanceof BlockRunestone ? new Template.BlockInfo(
|
||||
i.pos, i.blockState.withProperty(BlockRunestone.ELEMENT, element), i.tileentityData) : i;
|
||||
i.pos, runeStone.getDefaultState(), i.tileentityData) : i;
|
||||
|
||||
template.addBlocksToWorld(world, origin, processor, settings, 2 | 16);
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package electroblob.wizardry.worldgen;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.block.BlockPedestal;
|
||||
import electroblob.wizardry.block.BlockRunestone;
|
||||
import electroblob.wizardry.block.BlockRunestonePedestal;
|
||||
import electroblob.wizardry.constants.Element;
|
||||
import electroblob.wizardry.integration.antiqueatlas.WizardryAntiqueAtlasIntegration;
|
||||
import electroblob.wizardry.registry.WizardryBlocks;
|
||||
import electroblob.wizardry.spell.ArcaneLock;
|
||||
import electroblob.wizardry.tileentity.TileEntityShrineCore;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
@@ -15,8 +15,10 @@ import net.minecraft.world.World;
|
||||
import net.minecraft.world.gen.structure.template.ITemplateProcessor;
|
||||
import net.minecraft.world.gen.structure.template.PlacementSettings;
|
||||
import net.minecraft.world.gen.structure.template.Template;
|
||||
import net.minecraftforge.fml.common.registry.ForgeRegistries;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
@@ -49,10 +51,12 @@ public class WorldGenShrine extends WorldGenSurfaceStructure {
|
||||
@Override
|
||||
public void spawnStructure(Random random, World world, BlockPos origin, Template template, PlacementSettings settings, ResourceLocation structureFile){
|
||||
|
||||
final Element element = Element.values()[1 + random.nextInt(Element.values().length-1)];
|
||||
Element[] elements = (Element[]) Arrays.stream(Element.values()).filter(Element::hasWorldgen).toArray();
|
||||
final Element element = elements[1 + random.nextInt(elements.length-1)];
|
||||
Block runeStone = ForgeRegistries.BLOCKS.getValue(new ResourceLocation(element.getModid(), element.getName().toLowerCase() + "_runestone"));
|
||||
|
||||
ITemplateProcessor processor = (w, p, i) -> i.blockState.getBlock() instanceof BlockRunestone ? new Template.BlockInfo(
|
||||
i.pos, i.blockState.withProperty(BlockRunestone.ELEMENT, element), i.tileentityData) : i;
|
||||
i.pos, runeStone.getDefaultState(), i.tileentityData) : i;
|
||||
|
||||
template.addBlocksToWorld(world, origin, processor, settings, 2 | 16);
|
||||
|
||||
@@ -65,8 +69,8 @@ public class WorldGenShrine extends WorldGenSurfaceStructure {
|
||||
|
||||
if(entry.getValue().equals(CORE_DATA_BLOCK_TAG)){
|
||||
// This bit could have been done with a template processor, but we also need to link the chest and lock it
|
||||
world.setBlockState(entry.getKey(), WizardryBlocks.runestone_pedestal.getDefaultState()
|
||||
.withProperty(BlockPedestal.ELEMENT, element).withProperty(BlockPedestal.NATURAL, true));
|
||||
world.setBlockState(entry.getKey(), ForgeRegistries.BLOCKS.getValue(new ResourceLocation(Wizardry.MODID, element.getName().toLowerCase()
|
||||
+ "_runestone_pedestal")).getDefaultState().withProperty(BlockRunestonePedestal.NATURAL, true));
|
||||
|
||||
TileEntity core = world.getTileEntity(entry.getKey());
|
||||
TileEntity container = world.getTileEntity(entry.getKey().up());
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
"translate": "advancement.ebwizardry:crystal.desc"
|
||||
},
|
||||
"icon": {
|
||||
"item": "ebwizardry:magic_crystal",
|
||||
"data": 0
|
||||
"item": "ebwizardry:magic_crystal"
|
||||
}
|
||||
},
|
||||
"parent": "ebwizardry:root",
|
||||
@@ -18,8 +17,28 @@
|
||||
"conditions": {
|
||||
"items": [
|
||||
{
|
||||
"item": "ebwizardry:magic_crystal",
|
||||
"data": 0
|
||||
"item": "ebwizardry:magic_crystal"
|
||||
},
|
||||
{
|
||||
"item": "ebwizardry:fire_crystal"
|
||||
},
|
||||
{
|
||||
"item": "ebwizardry:ice_crystal"
|
||||
},
|
||||
{
|
||||
"item": "ebwizardry:lightning_crystal"
|
||||
},
|
||||
{
|
||||
"item": "ebwizardry:necromancy_crystal"
|
||||
},
|
||||
{
|
||||
"item": "ebwizardry:earth_crystal"
|
||||
},
|
||||
{
|
||||
"item": "ebwizardry:sorcery_crystal"
|
||||
},
|
||||
{
|
||||
"item": "ebwizardry:healing_crystal"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
"translate": "advancement.ebwizardry:defeat_remnant.desc"
|
||||
},
|
||||
"icon": {
|
||||
"item": "ebwizardry:spectral_dust",
|
||||
"data": 6
|
||||
"item": "ebwizardry:spectral_dust_sorcery"
|
||||
}
|
||||
},
|
||||
"parent": "ebwizardry:arcane_initiate",
|
||||
@@ -18,8 +17,7 @@
|
||||
"conditions": {
|
||||
"items": [
|
||||
{
|
||||
"item": "ebwizardry:spectral_dust",
|
||||
"data": 1
|
||||
"item": "ebwizardry:spectral_dust_fire"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -29,8 +27,7 @@
|
||||
"conditions": {
|
||||
"items": [
|
||||
{
|
||||
"item": "ebwizardry:spectral_dust",
|
||||
"data": 2
|
||||
"item": "ebwizardry:spectral_dust_ice"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -40,8 +37,7 @@
|
||||
"conditions": {
|
||||
"items": [
|
||||
{
|
||||
"item": "ebwizardry:spectral_dust",
|
||||
"data": 3
|
||||
"item": "ebwizardry:spectral_dust_lightning"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -51,8 +47,7 @@
|
||||
"conditions": {
|
||||
"items": [
|
||||
{
|
||||
"item": "ebwizardry:spectral_dust",
|
||||
"data": 4
|
||||
"item": "ebwizardry:spectral_dust_necromancy"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -62,8 +57,7 @@
|
||||
"conditions": {
|
||||
"items": [
|
||||
{
|
||||
"item": "ebwizardry:spectral_dust",
|
||||
"data": 5
|
||||
"item": "ebwizardry:spectral_dust_earth"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -73,8 +67,7 @@
|
||||
"conditions": {
|
||||
"items": [
|
||||
{
|
||||
"item": "ebwizardry:spectral_dust",
|
||||
"data": 6
|
||||
"item": "ebwizardry:spectral_dust_sorcery"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -84,7 +77,7 @@
|
||||
"conditions": {
|
||||
"items": [
|
||||
{
|
||||
"item": "ebwizardry:spectral_dust",
|
||||
"item": "ebwizardry:spectral_dust_healing",
|
||||
"data": 7
|
||||
}
|
||||
]
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user