Compare commits

..

21 Commits

Author SHA1 Message Date
WinDanesz 65ed0e8a22 version bump to 4.3.14 2024-05-18 16:07:11 +02:00
WinDanesz 936601cbad fix: Fixed a bug that caused stackable artefacts to alway double their effect 2024-05-18 15:57:15 +02:00
WinDanesz f9cf1b39db Fix telekineticDisarmament setting and Amulet of Anchoring 2024-03-29 18:07:19 +01:00
WinDanesz 3fb3c1c039 feat: made EntityWizard.trades public so that addon devs can manipulate trades 2024-03-28 01:00:26 +01:00
WinDanesz e8bc6ca725 version bump to 4.3.13 2024-03-28 01:00:26 +01:00
WinDanesz df531d3724 fix: Fixed all synchronized WizardData stored variables on dedicated servers. This issue was causing e.g. the Ancient Compass to not display its targets on servers. Fixes #857 2024-03-28 00:46:32 +01:00
ScoTWT 2728012f33 Update zh_tw.lang (#709) 2024-03-27 22:19:46 +01:00
red1854th 853df2eb42 Update ko_kr.lang (#714)
* Update Korean translations, courtesy of red1854th

* Update Korean translations, courtesy of red1854th
2024-03-27 22:18:20 +01:00
ipdnaeip 0cb2165ddf Added methods for retrieving entities within a cylinder, replaced radius-based methods, implemented DPS check for heal aura, adjusted targeting criteria for summoned creatures, tweaked heal method, fixed flamecatcher ammo loss, updated Enrage target and expanded spellcasting item compatibility for movement speed charm. - by ipdnaeip (#864)
Added getEntitiesWithinCylinder and getLivingWithinCylinder methods to return all entities within a cylinder.

Replaced getLivingWithinRadius for spells that should use a cylinder instead. The height of the cylinder is determined by the height of the entities.

Added a DPS checker on the heal aura damage just in case someone has damage immunity disabled.

Modified the AllyDesignationSystem and Wizard classes to no longer target summoned creatures automatically. They will still target hostile summoned creatures or creatures from players that have aggressed on them.

Modified the heal method in the Heal class to not reduce absorption amount. It should never really happen, but just in case.

Modified the flamecatcher to no longer lose ammo if it was used but no arrow was fired.

Enrage now targets EntityLiving instead of EntityCreature.

The movement speed charm now works with any spellcasting item as opposed to just wands.
2024-03-27 22:11:29 +01:00
WinDanesz ca7e9034ed feat: Added WandHelper.rechargeManaOnApplyButtonPressed static method for easier mana recharging across addons 2024-03-27 22:03:01 +01:00
WinDanesz 1322c920f5 fix: Spells are now sorted alphabetically by their names, instead of first being sorted by modid 2024-03-15 01:31:51 +01:00
WinDanesz e5c00e3882 feat: The Amulet of Anchoring also prevents the Telekinesis spell to knock items out of the wearer's hand. (Previously it only granted protection against being moved by Greater Telekinesis) 2024-03-14 00:05:40 +01:00
WinDanesz c030629bab fix: Fixed clear button and Attunement 2023-12-30 21:08:14 +01:00
WinDanesz 165d079251 Added getApplicableItems() to Spell.java 2023-10-25 10:10:20 +02:00
WinDanesz 7cc9200adf feat: added teleport_self_large_distance forfeit 2023-10-18 22:53:00 +02:00
WinDanesz 01a9d8c075 chore: 4.3.11 -> 4.3.12 version bump 2023-10-18 22:53:00 +02:00
WinDanesz 0a0a08d220 fix: Probably fixed a recurring Handbook crash for good 2023-10-18 22:53:00 +02:00
WinDanesz 410768e6f3 feat: Support for addon Wizard's Handbook
content
2023-10-18 22:53:00 +02:00
WinDanesz bbbe024bb3 build: Updated to ForgeGradle5 with FancyGradle 2023-10-18 22:53:00 +02:00
WinDanesz 93112d5192 docs: Update ArtefactCheckEvent.java javadoc 2023-09-10 16:10:15 +02:00
ipdnaeip 112a562b2d fix: Increased the tick rate of continuous spells (#849)
... and added some checks to make sure the spells don't deal too much with mods that interact with the hurt resistance timer.
2023-09-09 18:08:38 +02:00
46 changed files with 4795 additions and 4035 deletions
+2 -2
View File
@@ -1,7 +1,7 @@
{
"homepage": "https://www.curseforge.com/minecraft/mc-mods/electroblobs-wizardry",
"promos": {
"1.12.2-latest": "4.3.11",
"1.12.2-recommended": "4.3.11"
"1.12.2-latest": "4.3.14",
"1.12.2-recommended": "4.3.14"
}
}
+112 -50
View File
@@ -1,64 +1,127 @@
import groovy.json.JsonOutput
buildscript {
repositories {
jcenter()
maven { url = "http://files.minecraftforge.net/maven" }
gradlePluginPortal()
maven {
name 'MinecraftForge'
url 'https://maven.minecraftforge.net/'
}
maven {
name 'Garden of Fancy'
url 'https://maven.gofancy.wtf/releases'
}
//fallback for fancygradle maven
//mavenLocal()
maven {
name 'Sponge'
url 'https://repo.spongepowered.org/repository/maven-public/'
}
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
classpath 'net.minecraftforge.gradle:ForgeGradle:5.+'
classpath 'org.ajoberstar.grgit:grgit-gradle:3.1.1'
classpath group: 'wtf.gofancy.fancygradle', name: 'wtf.gofancy.fancygradle.gradle.plugin', version: '1.1.+'
}
repositories.each {
if (it instanceof MavenArtifactRepository && it.url.toString() == "https://files.minecraftforge.net/maven") {
it.url = "https://maven.minecraftforge.net"
}
}
}
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.
apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'idea'
apply plugin: 'maven-publish'
apply plugin: org.ajoberstar.grgit.gradle.GrgitPlugin
apply plugin: 'wtf.gofancy.fancygradle'
version = "4.3.11"
version = "4.3.14"
group= "electroblob.wizardry"// http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = "ElectroblobsWizardry"
sourceCompatibility = targetCompatibility = "1.8" // Need this here so eclipse task generates correctly.
compileJava {
sourceCompatibility = targetCompatibility = "1.8"
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly.
minecraft {
// The mappings can be changed at any time, and must be in the following format.
// snapshot_YYYYMMDD Snapshot are built nightly.
// stable_# Stables are built at the discretion of the MCP team.
// Use non-default mappings at your own risk. they may not always work.
// Simply re-run your setup task after changing the mappings to update your workspace.
//mappings channel: 'snapshot', version: '20171003-1.12'
mappings channel: "stable", version: "39-1.12"
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
// accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
// Default run configurations.
// These can be tweaked, removed, or duplicated as needed.
runs {
client {
workingDirectory project.file('run')
// Recommended logging data for a userdev environment
property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
// Recommended logging level for the console
property 'forge.logging.console.level', 'info'
}
server {
// Recommended logging data for a userdev environment
property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
// Recommended logging level for the console
property 'forge.logging.console.level', 'info'
}
}
}
repositories {
google()
mavenCentral()
maven {
// location of the maven that hosts JEI files
name = "Progwml6 maven"
url = "http://dvs1.progwml6.com/files/maven"
url = uri('https://www.cursemaven.com')
content {
includeGroup 'curse.maven'
}
}
maven {
// location of a maven mirror for JEI files, as a fallback
name = "ModMaven"
url = "modmaven.k-4u.nl"
name = 'Modrinth'
url = uri('https://api.modrinth.com/maven')
content {
includeGroup 'maven.modrinth'
}
}
maven {
name = "Curseforge Maven"
url = "https://minecraft.curseforge.com/api/maven/"
name = 'Sponge'
url = uri('https://repo.spongepowered.org/maven')
}
maven {
url = uri('https://maven.blamejared.com')
}
maven {
url = uri('https://m2.dv8tion.net/releases')
}
maven {
url = uri('https://jitpack.io')
}
}
minecraft {
version = "1.12.2-14.23.5.2847"
runDir = "run"
// the mappings can be changed at any time, and must be in the following format.
// snapshot_YYYYMMDD snapshot are built nightly.
// stable_# stables are built at the discretion of the MCP team.
// Use non-default mappings at your own risk. they may not always work.
// simply re-run your setup task after changing the mappings to update your workspace.
mappings = "stable_39"
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
}
dependencies {
// Compile against the JEI API but do not include it at runtime
deobfProvided "mezz.jei:jei_${mc_version}:${jei_version}:api"
// At runtime, use the full JEI jar
runtime "mezz.jei:jei_${mc_version}:${jei_version}"
deobfCompile "baubles:Baubles:${mc_version_short}:${baubles_version}"
deobfCompile "antique-atlas:antiqueatlas:${mc_version}:${antique_atlas_version}"
//// MC version ////
// Specify the version of Minecraft to use, If this is any group other then 'net.minecraft' it is assumed
// that the dep is a ForgeGradle 'patcher' dependency. And it's patches will be applied.
// The userdev artifact is a special name and will get all sorts of transformations applied to it.
minecraft "net.minecraftforge:forge:${project.mc_version}-${project.forge_version}"
//// MC version ////
implementation fg.deobf("curse.maven:baubles-${baubles_projectid}:${baubles_fileid}")
implementation fg.deobf("mezz.jei:jei_${mc_version}:${jei_version}")
implementation fg.deobf("curse.maven:antique-atlas-${antiqueatlas_projectid}:${antiqueatlas_fileid}")
}
@@ -68,20 +131,19 @@ task deobfJar(type: Jar) {
}
processResources {
// this will ensure that this task is redone when the versions change.
inputs.property "version", project.version
inputs.property "mcversion", project.minecraft.version
// replace stuff in mcmod.info, nothing else
// replace tokens in mcmod.info, and pack.mcmeta
from(sourceSets.main.resources.srcDirs) {
include 'pack.mcmeta'
include 'mcmod.info'
// replace version and mcversion
expand 'version':project.version, 'mcversion':project.minecraft.version
}
// copy everything else except the mcmod.info
from(sourceSets.main.resources.srcDirs) {
exclude 'mcmod.info'
duplicatesStrategy = 'include'
}
fancyGradle {
patches {
resources
coremods
asm
}
}
+15 -1
View File
@@ -1,8 +1,22 @@
# Sets default memory used for gradle commands. Can be overridden by user or command line properties.
# This is required to provide enough memory for the Minecraft decompilation process.
org.gradle.jvmargs=-Xmx3G
mod_id=ebwizardry
mc_version=1.12.2
mc_version_short=1.12
jei_version=4.15.0.291
baubles_version=1.5.2
antique_atlas_version=4.6.3
antique_atlas_version=4.6.3
forge_version=14.23.5.2860
mappings_version=39
mappings_channel=stable
mappings_mc_version=1.12
baubles_projectid=227083
baubles_fileid=2518667
jei_projectid=238222
artemislib_projectid=313590
artemislib_version=1.0.6
artemislib_fileid=2741812
antiqueatlas_projectid=227795
antiqueatlas_fileid=2823030
org.gradle.daemon=false
+2 -2
View File
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip
zipStorePath=wrapper/dists
Vendored
+175 -115
View File
@@ -1,172 +1,232 @@
#!/usr/bin/env sh
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
APP_BASE_NAME=${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=""
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
MAX_FD=maximum
warn () {
echo "$*"
}
} >&2
die () {
echo
echo "$*"
echo
exit 1
}
} >&2
# 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
;;
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD="$JAVA_HOME/bin/java"
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; 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
location of your Java installation."
fi
else
JAVACMD="java"
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
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
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
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
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`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# 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"
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
# 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")"
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
exec "$JAVACMD" "$@"
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
Vendored
+25 -20
View File
@@ -1,3 +1,19 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@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 DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -35,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -45,28 +64,14 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
@@ -81,4 +86,4 @@ exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
:omega
@@ -82,7 +82,7 @@ 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.11";
public static final String VERSION = "4.3.14";
/**
* Json file used by Forge's built-in <a href="https://mcforge.readthedocs.io/en/1.12.x/gettingstarted/autoupdate/">update checker</a>.
@@ -130,7 +130,6 @@ public class Wizardry {
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
@@ -161,6 +160,7 @@ public class Wizardry {
@EventHandler
public void init(FMLInitializationEvent event){
proxy.registerResourceReloadListeners();
settings.initConfigExtras();
@@ -3,10 +3,7 @@ package electroblob.wizardry.client;
import electroblob.wizardry.client.renderer.overlay.RenderBlinkEffect;
import electroblob.wizardry.data.DispenserCastingData;
import electroblob.wizardry.data.SpellEmitterData;
import electroblob.wizardry.item.ItemArtefact;
import electroblob.wizardry.item.ItemFlamecatcher;
import electroblob.wizardry.item.ItemSpectralBow;
import electroblob.wizardry.item.ItemWand;
import electroblob.wizardry.item.*;
import electroblob.wizardry.potion.PotionSlowTime;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardryPotions;
@@ -120,6 +117,7 @@ public final class WizardryClientEventHandler {
Minecraft.getMinecraft().player.prevRotationPitch = 0;
Minecraft.getMinecraft().player.rotationYaw = 0;
Minecraft.getMinecraft().player.rotationPitch = 0;
}
}
@@ -133,10 +131,10 @@ public final class WizardryClientEventHandler {
event.getMovementInput().jump = false;
event.getMovementInput().sneak = false;
}
if(ItemArtefact.isArtefactActive(event.getEntityPlayer(), WizardryItems.charm_move_speed)
&& event.getEntityPlayer().isHandActive()
&& event.getEntityPlayer().getActiveItemStack().getItem() instanceof ItemWand){
&& event.getEntityPlayer().getActiveItemStack().getItem() instanceof ISpellCastingItem){
// Normally speed is set to 20% when using items, this makes it 80%
event.getMovementInput().moveStrafe *= 4;
event.getMovementInput().moveForward *= 4;
@@ -33,9 +33,13 @@ import java.awt.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* GUI class for the wizard's handbook. Like any GUI class, this is instantiated each time the book is opened. As of
@@ -55,6 +59,8 @@ public class GuiWizardHandbook extends GuiScreen {
private static final ResourceLocation DEFAULT = new ResourceLocation(Wizardry.MODID, "texts/handbook_en_us.json");
private static List<String> ADDONS = new ArrayList<>();
static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID, "textures/gui/handbook/handbook.png");
/** Global Gson instance for the handbook. */
@@ -406,9 +412,10 @@ public class GuiWizardHandbook extends GuiScreen {
return;
}
IResource handbookFile = getHandbookResource(manager);
// IResource handbookFile = getHandbookResource(manager);
List<IResource> handbookFiles = getHandbookResource(manager);
if(handbookFile != null){
if(!handbookFiles.isEmpty()){
// Wipes all the maps before repopulating them
images.clear();
@@ -418,28 +425,31 @@ public class GuiWizardHandbook extends GuiScreen {
bookmarkSection = null; // Also need to wipe the reference to the old bookmarked section
BufferedReader reader = new BufferedReader(new InputStreamReader(handbookFile.getInputStream(), StandardCharsets.UTF_8));
for (IResource handbookFile : handbookFiles) {
JsonElement je = gson.fromJson(reader, JsonElement.class);
JsonObject json = je.getAsJsonObject();
BufferedReader reader = new BufferedReader(new InputStreamReader(handbookFile.getInputStream(), StandardCharsets.UTF_8));
JsonUtils.getJsonObject(json, "colours").entrySet().forEach(e -> colours.put(e.getKey(),
Color.decode(e.getValue().getAsString()).getRGB()));
JsonElement je = gson.fromJson(reader, JsonElement.class);
JsonObject json = je.getAsJsonObject();
// Repopulates the remaining maps
Image.populate(images, json);
CraftingRecipe.populate(recipes, json);
Section.populate(sections, json);
JsonUtils.getJsonObject(json, "colours").entrySet().forEach(e -> colours.put(e.getKey(),
Color.decode(e.getValue().getAsString()).getRGB()));
sectionList = Collections.unmodifiableList(new ArrayList<>(sections.values()));
// Repopulates the remaining maps
Image.populate(images, json);
CraftingRecipe.populate(recipes, json);
Section.populate(sections, json);
if(sections.isEmpty()){
Wizardry.logger.warn("Handbook has no sections! Aborting loading...");
return;
sectionList = Collections.unmodifiableList(new ArrayList<>(sections.values()));
if(sections.isEmpty()){
Wizardry.logger.warn("Handbook has no sections! Aborting loading...");
return;
}
bookmarkSection = JsonUtils.getString(json, "bookmark_start_section");
if(!sections.containsKey(bookmarkSection)) throw new JsonSyntaxException("Section with id " + bookmarkSection + " is undefined");
}
bookmarkSection = JsonUtils.getString(json, "bookmark_start_section");
if(!sections.containsKey(bookmarkSection)) throw new JsonSyntaxException("Section with id " + bookmarkSection + " is undefined");
}
// The first resource load on startup is done before the packet handler is loaded
@@ -455,16 +465,17 @@ public class GuiWizardHandbook extends GuiScreen {
* @param manager The resource manager instance to use.
* @return The handbook JSON file, as an IResource, or null if it was not found.
*/
private static IResource getHandbookResource(IResourceManager manager){
private static List<IResource> getHandbookResource(IResourceManager manager){
// TODO: Implement resource pack stacking to allow addon mods and texture packs to add/overwrite content
IResource handbookFile = null;
List<IResource> handbookFiles = new ArrayList<>();
try{
handbookFile = manager.getResource(new ResourceLocation(Wizardry.MODID, "texts/handbook_"
+ Minecraft.getMinecraft().getLanguageManager().getCurrentLanguage().getLanguageCode() + ".json"));
}catch(IOException e){
}catch(Exception e){
Wizardry.logger.info("Wizard handbook JSON file missing for the current language (" + Minecraft.getMinecraft()
.getLanguageManager().getCurrentLanguage() + "). Using default (English-US) instead.");
@@ -476,7 +487,29 @@ public class GuiWizardHandbook extends GuiScreen {
}
}
return handbookFile;
handbookFiles.add(handbookFile);
for (String modid : ADDONS) {
// Addons
Wizardry.logger.info("Registering addon Wizard's Handbook contents for " + modid);
try{
handbookFile = manager.getResource(new ResourceLocation(modid, "texts/handbook_"
+ Minecraft.getMinecraft().getLanguageManager().getCurrentLanguage().getLanguageCode() + ".json"));
}catch(Exception e){
Wizardry.logger.info("Wizard handbook JSON file missing for the current language (" + Minecraft.getMinecraft()
.getLanguageManager().getCurrentLanguage() + "). Using default (English-US) instead.");
try{
handbookFile = manager.getResource(new ResourceLocation(modid, "texts/handbook_en_us.json"));
}catch(IOException x){
Wizardry.logger.error("Couldn't find file: " + DEFAULT + ". The file may be missing; please try re-downloading and reinstalling Wizardry.", x);
}
}
handbookFiles.add(handbookFile);
}
return handbookFiles;
}
// Controls
@@ -576,4 +609,9 @@ public class GuiWizardHandbook extends GuiScreen {
sections.values().forEach(s -> s.updateUnlockStatus(showToasts, completedAdvancements));
}
public static void registerAddonHandbookContent(String modid) {
if (!ADDONS.contains(modid)) {
ADDONS.add(modid);
}
}
}
@@ -299,7 +299,7 @@ class Section {
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());
boolean spaceless = SPACELESS_LANGUAGES.contains(Minecraft.getMinecraft().getLanguageManager().getCurrentLanguage() == null ? "en_us" : 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
@@ -64,6 +64,11 @@ public interface IStoredVariable<T> extends IVariable<T> {
this.ticker = (p, t) -> t; // Initialise this with a do-nothing function, can be overwritten later
}
@Override
public String getKey() {
return key;
}
/**
* Replaces this variable's update method with the given update function. <i>Beware of auto-unboxing of
* primitive types! For lambda expressions, check the second parameter isn't null before operating on it.
@@ -47,7 +47,10 @@ public interface IVariable<T> {
*/
void write(ByteBuf buf, T value);
String getKey();
/**
*
* Reads this variable's value from the given {@link ByteBuf}.
*/
T read(ByteBuf buf);
@@ -110,6 +113,11 @@ public interface IVariable<T> {
// NYI
}
@Override
public String getKey() {
return "none"; // we don't mind as these are never synced (electroblob.wizardry.data.IVariable.Variable.isSynced)
}
@Override
public T read(ByteBuf buf){
return null; // NYI
@@ -199,9 +199,14 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
}
/** Returns a set containing the registered {@link IStoredVariable} objects for which {@link IVariable#isSynced()}
* returns true. Used internally for packet reading. */
public static Set<IVariable> getSyncedVariables(){
return storedVariables.stream().filter(IVariable::isSynced).collect(Collectors.toSet());
* returns true, ordered by their keys obtained from {@link IVariable#getKey()}. Used internally for packets. */
public static Set<IVariable> getSyncedVariablesOrderedByKey(){
Comparator<IVariable> keyComparator = Comparator.comparing(IVariable::getKey);
return storedVariables.stream()
.filter(IVariable::isSynced)
.sorted(keyComparator)
.collect(Collectors.toCollection(LinkedHashSet::new));
}
/**
@@ -35,8 +35,8 @@ public class EntityDecay extends EntityMagicConstruct {
0.6F + rand.nextFloat() * 0.15F);
if(!this.world.isRemote){
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(1.0d, this.posX, this.posY,
this.posZ, this.world);
List<EntityLivingBase> targets = EntityUtils.getLivingWithinCylinder(this.width/2f, this.posX, this.posY,
this.posZ, this.height, this.world);
for(EntityLivingBase target : targets){
if(target != this.getCaster()){
// If this check wasn't here the potion would be reapplied every tick and hence the entity would be
@@ -34,7 +34,7 @@ public class EntityFireRing extends EntityScaledConstruct {
if(this.ticksExisted % 5 == 0 && !this.world.isRemote){
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(width/2, this.posX, this.posY, this.posZ, this.world);
List<EntityLivingBase> targets = EntityUtils.getLivingWithinCylinder(this.width/2, this.posX, this.posY, this.posZ, this.height, this.world);
for(EntityLivingBase target : targets){
@@ -34,7 +34,7 @@ public class EntityFireSigil extends EntityScaledConstruct {
if(!this.world.isRemote){
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(width/2, posX, posY, posZ, world);
List<EntityLivingBase> targets = EntityUtils.getLivingWithinCylinder(this.width/2, this.posX, this.posY, this.posZ, this.height, this.world);
for(EntityLivingBase target : targets){
@@ -36,8 +36,8 @@ public class EntityFrostSigil extends EntityScaledConstruct {
if(!this.world.isRemote){
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(width/2, this.posX, this.posY,
this.posZ, this.world);
List<EntityLivingBase> targets = EntityUtils.getLivingWithinCylinder(width/2, this.posX, this.posY,
this.posZ, this.height, this.world);
for(EntityLivingBase target : targets){
@@ -33,30 +33,32 @@ public class EntityHealAura extends EntityScaledConstruct {
if(!this.world.isRemote){
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(width/2, posX, posY, posZ, world);
List<EntityLivingBase> targets = EntityUtils.getLivingWithinCylinder(width/2, posX, posY, posZ, this.height, world);
for(EntityLivingBase target : targets){
if(this.isValidTarget(target)){
if(target.isEntityUndead()){
if(target.isEntityUndead()) {
double velX = target.motionX;
double velY = target.motionY;
double velZ = target.motionZ;
if(this.getCaster() != null){
target.attackEntityFrom(
MagicDamage.causeIndirectMagicDamage(this, getCaster(), DamageType.RADIANT),
Spells.healing_aura.getProperty(Spell.DAMAGE).floatValue() * damageMultiplier);
}else{
target.attackEntityFrom(DamageSource.MAGIC, Spells.healing_aura.getProperty(Spell.DAMAGE).floatValue() * damageMultiplier);
}
if (this.ticksExisted % 10 == 1) {
if (this.getCaster() != null) {
target.attackEntityFrom(
MagicDamage.causeIndirectMagicDamage(this, getCaster(), DamageType.RADIANT),
Spells.healing_aura.getProperty(Spell.DAMAGE).floatValue() * damageMultiplier);
} else {
target.attackEntityFrom(DamageSource.MAGIC, Spells.healing_aura.getProperty(Spell.DAMAGE).floatValue() * damageMultiplier);
}
// Removes knockback
target.motionX = velX;
target.motionY = velY;
target.motionZ = velZ;
// Removes knockback
target.motionX = velX;
target.motionY = velY;
target.motionZ = velZ;
}
}
}else if(target.getHealth() < target.getMaxHealth() && target.ticksExisted % 5 == 0){
@@ -39,8 +39,8 @@ public class EntityLightningSigil extends EntityScaledConstruct {
this.setDead();
}
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(width/2, this.posX, this.posY,
this.posZ, this.world);
List<EntityLivingBase> targets = EntityUtils.getLivingWithinCylinder(this.width/2, this.posX, this.posY,
this.posZ, this.height, this.world);
for(EntityLivingBase target : targets){
@@ -68,7 +68,7 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
protected Predicate<Entity> targetSelector;
/** The wizard's trades. */
private MerchantRecipeList trades;
public MerchantRecipeList trades;
/** The wizard's current customer. */
@Nullable
private EntityPlayer customer;
@@ -130,8 +130,12 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
if(entity != null && !entity.isInvisible()
&& AllyDesignationSystem.isValidTarget(EntityWizard.this, entity)){
// ... and is a mob, a summoned creature ...
if((entity instanceof IMob || entity instanceof ISummonedCreature
// ... and is a non summoned creature mob ...
if((entity instanceof IMob && !(entity instanceof ISummonedCreature)
// or is a summoned creature with a mob owner or an owner who has attacked the wizard ...
|| entity instanceof ISummonedCreature && (((ISummonedCreature)entity).getOwner() instanceof IMob || ((ISummonedCreature)entity).getOwner() == this.getRevengeTarget() || ((ISummonedCreature) entity).getOwner() == this.getAttackTarget())
// ... or in the whitelist ...
|| Arrays.asList(Wizardry.settings.summonedCreatureTargetsWhitelist)
.contains(EntityList.getKey(entity.getClass())))
@@ -8,7 +8,7 @@ import net.minecraftforge.fml.common.eventhandler.Cancelable;
import net.minecraftforge.fml.common.eventhandler.Event;
/**
* SpellBindEvent is fired when a check happens for an ItemArtefact using {@link electroblob.wizardry.item.ItemArtefact#isArtefactActive(net.minecraft.entity.player.EntityPlayer, net.minecraft.item.Item)}
* ArtefactCheckEvent is fired when a check happens for an ItemArtefact using {@link electroblob.wizardry.item.ItemArtefact#isArtefactActive(net.minecraft.entity.player.EntityPlayer, net.minecraft.item.Item)}
* <i>Fired on both sides.</i><br>
* <br>
* This event is {@link Cancelable}. <br>
@@ -42,4 +42,4 @@ public class ArtefactCheckEvent extends PlayerEvent {
return player;
}
}
}
@@ -49,7 +49,6 @@ public final class WizardryBaublesIntegration {
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.BELT, BaubleType.BELT);
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.BODY, BaubleType.BODY);
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.HEAD, BaubleType.HEAD);
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.TRINKET, BaubleType.TRINKET);
}
public static boolean enabled(){
@@ -93,8 +93,7 @@ public class ItemArtefact extends Item {
/** An artefact that improves utility spells. One of these can be active at any one time. */ CHARM(1),
/** Added for add-on artefacts. */ BELT(1),
/** Added for add-on artefacts. */ BODY(1),
/** Added for add-on artefacts. */ HEAD(1),
/** Added for add-on artefacts. */ TRINKET(1);
/** Added for add-on artefacts. */ HEAD(1);
public final int maxAtOnce;
@@ -193,14 +193,6 @@ public class ItemFlamecatcher extends ItemBow implements IConjuredItem {
charge = net.minecraftforge.event.ForgeEventFactory.onArrowLoose(stack, world, (EntityPlayer)entity, charge, true);
if(charge < 0) return;
if(stack.getTagCompound() != null){
int shotsLeft = stack.getTagCompound().getInteger(Flamecatcher.SHOTS_REMAINING_NBT_KEY) - 1;
stack.getTagCompound().setInteger(Flamecatcher.SHOTS_REMAINING_NBT_KEY, shotsLeft);
if(shotsLeft == 0 && !world.isRemote){
stack.setItemDamage(getMaxDamage(stack) - getAnimationFrames());
}
}
float velocity = (float)charge / DRAW_TIME;
velocity = (velocity * velocity + velocity * 2) / 3;
@@ -208,6 +200,14 @@ public class ItemFlamecatcher extends ItemBow implements IConjuredItem {
if((double)velocity >= 0.1D){
if(stack.getTagCompound() != null){
int shotsLeft = stack.getTagCompound().getInteger(Flamecatcher.SHOTS_REMAINING_NBT_KEY) - 1;
stack.getTagCompound().setInteger(Flamecatcher.SHOTS_REMAINING_NBT_KEY, shotsLeft);
if(shotsLeft == 0 && !world.isRemote){
stack.setItemDamage(getMaxDamage(stack) - getAnimationFrames());
}
}
if(!world.isRemote){
EntityFlamecatcherArrow arrow = new EntityFlamecatcherArrow(world);
arrow.aim(player, EntityFlamecatcherArrow.SPEED * velocity);
@@ -864,33 +864,10 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
WandHelper.setSpells(centre.getStack(), spells);
// Charges wand by appropriate amount
if(crystals.getStack() != ItemStack.EMPTY && !this.isManaFull(centre.getStack())){
int chargeDepleted = this.getManaCapacity(centre.getStack()) - this.getMana(centre.getStack());
// 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;
if(crystals.getStack().getCount() * manaPerItem < chargeDepleted){
// If there aren't enough crystals to fully charge the wand
this.rechargeMana(centre.getStack(), crystals.getStack().getCount() * manaPerItem);
crystals.decrStackSize(crystals.getStack().getCount());
}else{
// If there are excess crystals (or just enough)
this.setMana(centre.getStack(), this.getManaCapacity(centre.getStack()));
crystals.decrStackSize((int)Math.ceil(((double)chargeDepleted) / manaPerItem));
}
if (WandHelper.rechargeManaOnApplyButtonPressed(centre, crystals)) {
changed = true;
}
return changed;
}
@@ -899,7 +876,16 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
ItemStack stack = centre.getStack();
if (stack.hasTagCompound() && stack.getTagCompound().hasKey(WandHelper.SPELL_ARRAY_KEY)) {
NBTTagCompound nbt = stack.getTagCompound();
nbt.removeTag(WandHelper.SPELL_ARRAY_KEY);
int[] spells = nbt.getIntArray(WandHelper.SPELL_ARRAY_KEY);
int expectedSlotCount = BASE_SPELL_SLOTS + WandHelper.getUpgradeLevel(stack,
WizardryItems.attunement_upgrade);
// unbrick broken wands
if (spells.length < expectedSlotCount) {
spells = new int[expectedSlotCount];
}
Arrays.fill(spells, 0);
nbt.setIntArray(WandHelper.SPELL_ARRAY_KEY, spells);
stack.setTagCompound(nbt);
}
}
@@ -486,6 +486,8 @@ public abstract class Forfeit {
}
}));
add(Tier.MASTER, Element.SORCERY, create("teleport_self_large_distance", (w, p) -> ((Banish)Spells.banish).teleport(p, w, 8 + w.rand.nextDouble() * 700)));
add(Tier.NOVICE, Element.HEALING, create("damage_self", (w, p) -> p.attackEntityFrom(DamageSource.MAGIC, 4)));
add(Tier.NOVICE, Element.HEALING, create("spill_armour", (w, p) -> {
@@ -10,7 +10,11 @@ import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import java.util.*;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
/**
* <b>[Server -> Client]</b> This packet is sent to synchronise any fields that need synchronising in
@@ -54,9 +58,8 @@ public class PacketPlayerSync implements IMessageHandler<Message, IMessage> {
this.seed = buf.readLong();
this.selectedMinionID = buf.readInt();
this.spellData = new HashMap<>();
WizardData.getSyncedVariables().forEach(v -> spellData.put(v, v.read(buf)));
WizardData.getSyncedVariablesOrderedByKey().forEach(v -> spellData.put(v, v.read(buf)));
// Have to send empty tags to guarantee correct ByteBuf size/order, but no point keeping the resulting nulls
spellData.values().removeIf(Objects::isNull);
@@ -73,7 +76,7 @@ public class PacketPlayerSync implements IMessageHandler<Message, IMessage> {
buf.writeLong(seed);
buf.writeInt(selectedMinionID);
WizardData.getSyncedVariables().forEach(v -> v.write(buf, spellData.get(v)));
WizardData.getSyncedVariablesOrderedByKey().forEach(v -> v.write(buf, spellData.get(v)));
if(this.spellsDiscovered == null) return;
for(Spell spell : this.spellsDiscovered){
@@ -4,7 +4,7 @@ import electroblob.wizardry.item.SpellActions;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import net.minecraft.entity.EntityCreature;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.tileentity.TileEntityDispenser;
import net.minecraft.util.math.Vec3d;
@@ -29,7 +29,7 @@ public class Enrage extends SpellAreaEffect {
@Override
protected boolean affectEntity(World world, Vec3d origin, @Nullable EntityLivingBase caster, EntityLivingBase target, int targetCount, int ticksInUse, SpellModifiers modifiers){
if(caster != null && target instanceof EntityCreature){
if(caster != null && target instanceof EntityLiving){
target.setRevengeTarget(caster); // Yours truly, angry mobs
}
@@ -53,7 +53,7 @@ public class FireBreath 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 if(ticksInUse % 10 == 0){
target.setFire((int)(getProperty(BURN_DURATION).floatValue() * modifiers.get(WizardryItems.duration_upgrade)));
EntityUtils.attackEntityWithoutKnockback(target,
MagicDamage.causeDirectMagicDamage(caster, DamageType.FIRE),
@@ -56,7 +56,7 @@ public class FlameRay 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 if(ticksInUse % 10 == 0){
target.setFire((int)(getProperty(BURN_DURATION).floatValue() * modifiers.get(WizardryItems.duration_upgrade)));
EntityUtils.attackEntityWithoutKnockback(target,
MagicDamage.causeDirectMagicDamage(caster, DamageType.FIRE),
@@ -65,7 +65,7 @@ public class FrostRay extends SpellRay {
(int)(getProperty(EFFECT_DURATION).floatValue() * modifiers.get(WizardryItems.duration_upgrade)),
getProperty(EFFECT_STRENGTH).intValue()));
if(ticksInUse % ((EntityLivingBase)target).maxHurtResistantTime == 1){
if(ticksInUse % 10 == 0){
float damage = getProperty(DAMAGE).floatValue() * modifiers.get(SpellModifiers.POTENCY);
if(target instanceof EntityBlaze || target instanceof EntityMagmaCube) damage *= 2;
@@ -38,7 +38,7 @@ public class Heal extends SpellBuff {
entity.heal(health);
// If the player is able to heal, they can't possibly have absorption hearts, so no need to check!
if(excessHealth > 0 && entity instanceof EntityPlayer
if(excessHealth > entity.getAbsorptionAmount() && entity instanceof EntityPlayer
&& ItemArtefact.isArtefactActive((EntityPlayer)entity, WizardryItems.amulet_absorption)){
entity.setAbsorptionAmount(excessHealth);
}
@@ -47,7 +47,7 @@ public class LifeDrain extends SpellRay {
if(EntityUtils.isLiving(target)){
if(ticksInUse % 12 == 0){
if(ticksInUse % 10 == 0){
float damage = getProperty(DAMAGE).floatValue() * modifiers.get(SpellModifiers.POTENCY);
@@ -51,7 +51,7 @@ public class LightningRay 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 if(ticksInUse % 10 == 0){
EntityUtils.attackEntityWithoutKnockback(target,
MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK),
getProperty(DAMAGE).floatValue() * modifiers.get(SpellModifiers.POTENCY));
@@ -53,7 +53,7 @@ public class LightningWeb extends SpellRay {
@Override
protected boolean onEntityHit(World world, Entity target, Vec3d hit, EntityLivingBase caster, Vec3d origin, int ticksInUse, SpellModifiers modifiers){
if(EntityUtils.isLiving(target)){
if(EntityUtils.isLiving(target) && ticksInUse % 10 == 0){
electrocute(world, caster, origin, target, getProperty(PRIMARY_DAMAGE).floatValue()
* modifiers.get(SpellModifiers.POTENCY), ticksInUse);
@@ -58,7 +58,7 @@ public class RayOfPurification extends SpellRay {
if(!world.isRemote && ticksInUse == 1 && caster instanceof EntityPlayer) ((EntityPlayer)caster)
.sendStatusMessage(new TextComponentTranslation("spell.resist", target.getName(),
this.getNameForTranslationFormatted()), true);
}else{
}else if (ticksInUse % 10 == 0) {
float damage = getProperty(DAMAGE).floatValue() * modifiers.get(SpellModifiers.POTENCY);
// Fire
@@ -922,6 +922,11 @@ public abstract class Spell extends IForgeRegistryEntry.Impl<Spell> implements C
return Arrays.asList(applicableItems).contains(item);
}
/** Returns the list of items this spell is applicable to. */
public List<Item> getApplicableItems() {
return Arrays.asList(applicableItems);
}
/**
* Sets which items this spell can appear on (these default to the regular spell book and scroll).
* @param applicableItems The items this spell should naturally appear on (or no items at all).
@@ -1,7 +1,9 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.item.ItemArtefact;
import electroblob.wizardry.item.SpellActions;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.util.SpellModifiers;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
@@ -34,15 +36,15 @@ public class Telekinesis extends SpellRay {
target.motionZ = (origin.z - target.posZ) / 6;
return true;
}else if(target instanceof EntityPlayer && (Wizardry.settings.telekineticDisarmament || !(caster instanceof EntityPlayer))){
} else if (target instanceof EntityPlayer && (Wizardry.settings.telekineticDisarmament && !ItemArtefact.isArtefactActive((EntityPlayer) target, WizardryItems.amulet_anchoring))) {
EntityPlayer player = (EntityPlayer) target;
EntityPlayer player = (EntityPlayer)target;
// IDEA: Disarm the offhand if the mainhand is empty or otherwise harmless?
if(!player.getHeldItemMainhand().isEmpty()){
if (!player.getHeldItemMainhand().isEmpty()) {
if(!world.isRemote){
if (!world.isRemote) {
EntityItem item = player.entityDropItem(player.getHeldItemMainhand(), 0);
// Makes the item move towards the caster
item.motionX = (origin.x - player.posX) / 20;
@@ -50,7 +52,7 @@ public class Telekinesis extends SpellRay {
}
player.setHeldItem(EnumHand.MAIN_HAND, ItemStack.EMPTY);
return true;
}
}
@@ -141,6 +141,11 @@ public final class AllyDesignationSystem {
return false;
}
// Tests whether the target is a creature that was summoned/tamed (or is otherwise owned) by the attacker
if(target instanceof IEntityOwnable && attacker instanceof EntityLiving && !(((EntityLiving)attacker).getRevengeTarget() == ((IEntityOwnable)target).getOwner() || ((EntityLiving)attacker).getAttackTarget() == ((IEntityOwnable)target).getOwner())){
return false;
}
// Tests whether the target is a creature that was mind controlled by the attacker
if(target instanceof EntityLiving && ((EntityLivingBase)target).isPotionActive(WizardryPotions.mind_control)){
@@ -117,6 +117,45 @@ public final class EntityUtils {
return entityList;
}
/**
* Returns all EntityLivingBase within the cylinder radius of the given coordinates. This should
* used by circle effects.
*
* @param radius The search radius
* @param x The x coordinate to search around
* @param y The y coordinate to search around
* @param z The z coordinate to search around
* @param height The height of the cylinder
* @param world The world to search in
*/
public static List<EntityLivingBase> getLivingWithinCylinder(double radius, double x, double y, double z, double height, World world) {
return getEntitiesWithinCylinder(radius, x, y, z, height, world, EntityLivingBase.class);
}
/**
* Returns all entities of the specified type within the cylinder radius of the given coordinates. This should
* used by circle effects.
*
* @param radius The search radius
* @param x The x coordinate to search around
* @param y The y coordinate to search around
* @param z The z coordinate to search around
* @param height The height of the cylinder
* @param world The world to search in
* @param entityType The class of entity to search for; pass in Entity.class for all entities
*/
public static <T extends Entity> List<T> getEntitiesWithinCylinder(double radius, double x, double y, double z, double height, World world, Class<T> entityType) {
AxisAlignedBB aabb = new AxisAlignedBB(x - radius, y, z - radius, x + radius, y + height, z + radius);
List<T> entityList = world.getEntitiesWithinAABB(entityType, aabb);
for(T entity : entityList) {
if (entity.getDistance(x, entity.posY, z) > radius) {
entityList.remove(entity);
break;
}
}
return entityList;
}
/**
* Gets an entity from its UUID. If the UUID is known to belong to an {@code EntityPlayer}, use the more efficient
* {@link World#getPlayerEntityByUUID(UUID)} instead.
@@ -20,8 +20,7 @@ public interface ISpellSortable {
TIER("tier", Comparator.naturalOrder()),
ELEMENT("element", Comparator.comparing(Spell::getElement).thenComparing(Spell::getTier)),
ALPHABETICAL("alphabetical", Comparator.comparing(Spell::getUnlocalisedName));
ALPHABETICAL("alphabetical", Comparator.comparing(s -> s.getRegistryName().getPath().toString()));
public String name;
public Comparator<? super Spell> comparator;
@@ -1,9 +1,14 @@
package electroblob.wizardry.util;
import electroblob.wizardry.constants.Constants;
import electroblob.wizardry.item.IManaStoringItem;
import electroblob.wizardry.item.IWorkbenchItem;
import electroblob.wizardry.item.ItemCrystal;
import electroblob.wizardry.item.ItemWand;
import electroblob.wizardry.registry.Spells;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.spell.Spell;
import net.minecraft.inventory.Slot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
@@ -494,4 +499,49 @@ public final class WandHelper {
setProgression(wand, getProgression(wand) + progression);
}
/**
* Recharges the mana of an item when the apply button is pressed in the arcane workbench GUI.
* This method requires the central item to implement both the {@link IWorkbenchItem} and {@link IManaStoringItem} interfaces.
*
* @param centre The slot representing the central item to be recharged.
* @param crystals The slot containing mana crystals for recharging.
* @return {@code true} if the mana of the central item was successfully recharged, {@code false} otherwise.
*/
public static boolean rechargeManaOnApplyButtonPressed(Slot centre, Slot crystals) {
boolean changed = false;
if (!(centre.getStack().getItem() instanceof IWorkbenchItem) || !(centre.getStack().getItem() instanceof IManaStoringItem)) {
return false;
}
IManaStoringItem iManaStoringItem = (IManaStoringItem) centre.getStack().getItem();
// Charges the item by appropriate amount
if (crystals.getStack() != ItemStack.EMPTY && !iManaStoringItem.isManaFull(centre.getStack())) {
int chargeDepleted = iManaStoringItem.getManaCapacity(centre.getStack()) - iManaStoringItem.getMana(centre.getStack());
// 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;}
if (crystals.getStack().getCount() * manaPerItem < chargeDepleted) {
// If there aren't enough crystals to fully charge the item
iManaStoringItem.rechargeMana(centre.getStack(), crystals.getStack().getCount() * manaPerItem);
crystals.decrStackSize(crystals.getStack().getCount());
} else {
// If there are excess crystals (or just enough)
iManaStoringItem.setMana(centre.getStack(), iManaStoringItem.getManaCapacity(centre.getStack()));
crystals.decrStackSize((int) Math.ceil(((double) chargeDepleted) / manaPerItem));
}
changed = true;
}
return changed;
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -2,7 +2,7 @@
{
"modid" : "ebwizardry",
"name" : "Electroblob's Wizardry",
"version" : "4.3.7",
"version" : "4.3.14",
"mcversion" : "1.12.2",
"url" : "https://minecraft.curseforge.com/projects/electroblobs-wizardry",
"credits" : "\nDesigned, coded and textured by Electroblob.\nDiscord Moderators: FavouriteDragon, WinDanesz\nCode contributed by: Corail31, 12foo, Shadows-of-Fire, Tora-B, Avatair, Aeronica, UltraHex, Azim-Palmer, raoulvdberge, rafasoares, xinyuan-liu, SettingDust, Aralu115, WinDanesz, ZettaSword.\nTranslators: Alsentar (Spanish), MadWrist (Mexican Spanish), VilagVil, kellixon, bigenergy, MugGod2 & DrHesperus (Russian), Hahdrim & Crowller (French), lorrampi (Brazilian Portuguese), ZHENGLOC, dragon-evol, Hokorizero, TUsama & Determancer (Chinese - Simplified), shejery, rewi_wire, 방통 & red1854th (Korean), Trozuu & Olej (Polish), BirdyDragon & Lemopav (German), chesterccj305 (Chinese - Traditional), Bombadil (Hungarian).\nSound Effects: OhhWowProductions, fredzed, deleted_user_3277771, DiscoveryME, OGSoundFX, leosalom, juskiddink",