├── .github └── workflows │ └── gradle.yml ├── .gitignore ├── LICENSE ├── README.md ├── build.gradle ├── buildscript ├── forge-1.7-mixin.gradle └── forge-1.7.gradle ├── docs └── dmod_banner.png ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── makalibs.gradle ├── project.gradle ├── publish ├── .gitignore ├── README.txt ├── build.gradle ├── build_and_release.sh ├── curseforge_all.sh ├── gameVersions.json ├── get_version.py ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── modrinth_all.sh ├── prepare_publish.py └── update_updatejson.py ├── src └── main │ ├── java │ └── makamys │ │ └── dmod │ │ ├── ConfigDMod.java │ │ ├── DMod.java │ │ ├── DModConstants.java │ │ ├── DModItems.java │ │ ├── MixinConfigPlugin.java │ │ ├── ai │ │ ├── EntityAIFollowOwnerEx.java │ │ └── EntityAIPanicWithTimeout.java │ │ ├── client │ │ ├── render │ │ │ ├── ModelFox.java │ │ │ └── RenderFox.java │ │ └── tooltip │ │ │ ├── BundleTooltipHandler.java │ │ │ └── DTooltipHandler.java │ │ ├── compat │ │ ├── Compat.java │ │ ├── IBerryBushHandler.java │ │ └── NEICompat.java │ │ ├── constants │ │ ├── AIMutex.java │ │ └── NBTType.java │ │ ├── entity │ │ ├── EntityFox.java │ │ └── ITameable.java │ │ ├── etfuturum │ │ ├── BlockPos.java │ │ └── Vec3i.java │ │ ├── future │ │ ├── entity │ │ │ ├── EntityFuture.java │ │ │ ├── EntityLivingFuture.java │ │ │ ├── EntityLivingFutured.java │ │ │ ├── ai │ │ │ │ ├── EntityAIAttackOnCollideFuture.java │ │ │ │ ├── EntityAIDiveJump.java │ │ │ │ ├── EntityAIFleeSunModern.java │ │ │ │ ├── EntityAIModernAvoidEntity.java │ │ │ │ ├── EntityAIMoveToTargetPos.java │ │ │ │ ├── EntityAINearestAttackableTargetEx.java │ │ │ │ ├── ModernEntityLookHelper.java │ │ │ │ └── TargetPredicate.java │ │ │ ├── item │ │ │ │ └── EntityItemFuture.java │ │ │ └── passive │ │ │ │ ├── AnimalEntityEmulator.java │ │ │ │ ├── EntityAnimalFuture.java │ │ │ │ └── PassiveEntityEmulator.java │ │ ├── inventory │ │ │ └── SlotFuture.java │ │ ├── item │ │ │ ├── ItemFuture.java │ │ │ └── ItemStackFuture.java │ │ ├── nbt │ │ │ └── NBTTagListFuture.java │ │ ├── predicate │ │ │ └── entity │ │ │ │ └── EntityPredicates.java │ │ ├── util │ │ │ ├── BlockPos.java │ │ │ ├── MathHelperFuture.java │ │ │ └── Vec3i.java │ │ └── world │ │ │ └── EntityViewEmulator.java │ │ ├── inventory │ │ └── DSlotClickHandler.java │ │ ├── item │ │ ├── IConfigurable.java │ │ └── ItemBundle.java │ │ ├── mixin │ │ ├── MixinContainer.java │ │ ├── MixinEntityLiving.java │ │ ├── MixinEntityLivingBase.java │ │ ├── MixinEntityWolf.java │ │ └── MixinRenderItem.java │ │ ├── proxy │ │ ├── DProxyClient.java │ │ └── DProxyCommon.java │ │ └── util │ │ ├── DUtil.java │ │ ├── EggHelper.java │ │ ├── StatRegistry.java │ │ └── WeightedRandomItem.java │ └── resources │ ├── META-INF │ └── dmod_at.cfg │ ├── assets │ ├── dmod │ │ ├── lang │ │ │ ├── en_US.lang │ │ │ └── zh_CN.lang │ │ ├── sounds.json │ │ └── textures │ │ │ ├── gui │ │ │ └── container │ │ │ │ └── bundle.png │ │ │ └── items │ │ │ ├── bundle.png │ │ │ └── bundle_filled.png │ └── minecraft │ │ ├── sounds │ │ └── mob │ │ │ └── fox │ │ │ ├── aggro1.ogg │ │ │ ├── aggro2.ogg │ │ │ ├── aggro3.ogg │ │ │ ├── aggro4.ogg │ │ │ ├── aggro5.ogg │ │ │ ├── aggro6.ogg │ │ │ ├── aggro7.ogg │ │ │ ├── bite1.ogg │ │ │ ├── bite2.ogg │ │ │ ├── bite3.ogg │ │ │ ├── death1.ogg │ │ │ ├── death2.ogg │ │ │ ├── eat1.ogg │ │ │ ├── eat2.ogg │ │ │ ├── eat3.ogg │ │ │ ├── hurt1.ogg │ │ │ ├── hurt2.ogg │ │ │ ├── hurt3.ogg │ │ │ ├── hurt4.ogg │ │ │ ├── idle1.ogg │ │ │ ├── idle2.ogg │ │ │ ├── idle3.ogg │ │ │ ├── idle4.ogg │ │ │ ├── idle5.ogg │ │ │ ├── idle6.ogg │ │ │ ├── screech1.ogg │ │ │ ├── screech2.ogg │ │ │ ├── screech3.ogg │ │ │ ├── screech4.ogg │ │ │ ├── sleep1.ogg │ │ │ ├── sleep2.ogg │ │ │ ├── sleep3.ogg │ │ │ ├── sleep4.ogg │ │ │ ├── sleep5.ogg │ │ │ ├── sniff1.ogg │ │ │ ├── sniff2.ogg │ │ │ ├── sniff3.ogg │ │ │ ├── sniff4.ogg │ │ │ ├── spit1.ogg │ │ │ ├── spit2.ogg │ │ │ └── spit3.ogg │ │ └── textures │ │ └── entity │ │ └── fox │ │ ├── fox.png │ │ ├── fox_sleep.png │ │ ├── snow_fox.png │ │ └── snow_fox_sleep.png │ ├── dmod.mixin.json │ └── mcmod.info └── updatejson └── update.json /.github/workflows/gradle.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Gradle 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle 3 | 4 | name: Java CI with Gradle 5 | 6 | on: [push, pull_request] 7 | 8 | jobs: 9 | build: 10 | 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v3 15 | with: 16 | fetch-depth: 0 17 | - name: Set up JDK 1.8 18 | uses: actions/setup-java@v3 19 | with: 20 | distribution: 'temurin' 21 | java-version: 8 22 | - name: Grant execute permission for gradlew 23 | run: chmod +x gradlew 24 | - name: Set up Gradle build 25 | run: ./gradlew SetupCIWorkspace build 26 | - name: Build with Gradle 27 | run: ./gradlew cleanBuildAll 28 | working-directory: publish 29 | - uses: actions/upload-artifact@v3 30 | with: 31 | name: Package 32 | path: build/libs 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # mac os 2 | .DS_Store 3 | 4 | # forge / gradle 5 | .gradle 6 | build/ 7 | out/ 8 | classes/ 9 | run/ 10 | 11 | # eclipse 12 | *.launch 13 | .settings 14 | .classpath 15 | .project 16 | .metadata 17 | eclipse 18 | *.launch 19 | 20 | # idea 21 | .idea/ 22 | *.iml 23 | *.ipr 24 | *.iws 25 | 26 | # vscode 27 | .settings/ 28 | .vscode/ 29 | bin/ 30 | .classpath 31 | 32 | # other 33 | bin/ 34 | jars/ 35 | /.nb-gradle/ 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![downloads](https://img.shields.io/badge/-⬇%20releases-brightgreen)](https://github.com/makamys/DMod/releases) 2 | [![builds](https://img.shields.io/badge/-🛈%20builds-blue)](https://makamys.github.io/docs/CI-Downloads/CI-Downloads.html) 3 | [![CurseForge](https://shields.io/badge/CurseForge-555555?logo=curseforge)](https://www.curseforge.com/minecraft/mc-mods/dmod) 4 | 5 | # D-Mod 6 | 7 | ![](https://raw.githubusercontent.com/makamys/DMod/master/docs/dmod_banner.png) 8 | 9 | D-Mod is a mod that backports some features from later versions of Minecraft to 1.7.10. You could consider it an add-on to [Et Futurum Requiem](https://www.curseforge.com/minecraft/mc-mods/et-futurum-requiem) (though it's not a hard dependency). 10 | 11 | Currently implemented: 12 | 13 | * Foxes 14 | * Bundles 15 | 16 | ## Foxes 17 | 18 | Foxes have some (optional) extra features implemented. Untamed, they behave the same as they do in new vanilla versions. But as they defeat enemies, they gain EXP and unlock various new abilities and AI improvements. 19 | 20 | The major ones are getting healed when fed food, following the owner after being fed a sweet berry, and possessing Looting I intrinsically (does not stack with swords that have Looting). Foxes pass down their EXP to their children. 21 | 22 | More info [in the wiki](https://github.com/makamys/DMod/wiki/Fox). 23 | 24 | # Dependencies 25 | 26 | * Item icons in bundle tooltips will only be drawn if [NEI](https://www.curseforge.com/minecraft/mc-mods/notenoughitems) is installed (I recommend the [GTNH fork](https://www.curseforge.com/minecraft/mc-mods/notenoughitems-gtnh)). 27 | * [Et Futurum Requiem](https://www.curseforge.com/minecraft/mc-mods/et-futurum-requiem) is highly recommended as it backports sweet berries (useful for foxes) and rabbits (useful for bundles). 28 | 29 | # Incompatibilities 30 | 31 | * [Hodgepodge](https://github.com/GTNewHorizons/Hodgepodge): set `preventPickupLoot=false` or else foxes won't be able to pick up items 32 | * Various coremods will crash during startup due to an incompatibility with Mixin. For example, [Backlytra](https://github.com/unascribed/Backlytra) crashes if D-Mod's `lootingFoxFix` is enabled. This is fixed by [Mixingasm](https://github.com/makamys/Mixingasm). 33 | 34 | ### About `nomixin` builds 35 | 36 | The mod comes in two flavors: 37 | * The regular version embeds Mixin 0.7.11, allowing the mod to run standalone. However, this makes the jar a bit larger, and can cause problems in certain use cases. 38 | * The version marked with `+nomixin` doesn't embed Mixin, which lets it avoid these problems. But it requires a separate [Mixin bootstrap mod](https://gist.github.com/makamys/7cb74cd71d93a4332d2891db2624e17c#mixin-bootstrap-mods) to be installed in order to run. If you have one installed already, getting this version is recommended. 39 | 40 | # License 41 | 42 | This mod is licensed under [the Unlicense](https://github.com/makamys/DMod/blob/master/LICENSE). It largely consists of ported Mojang code though, so keep that in mind. 43 | 44 | # Contributing 45 | 46 | When running in an IDE, add these program arguments 47 | ``` 48 | --tweakClass org.spongepowered.asm.launch.MixinTweaker --mixin dmod.mixin.json 49 | ``` 50 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | /** The root of the build. Exposed for flexibility, but you shouldn't edit it 2 | unless you have to. Edit project.gradle instead. */ 3 | 4 | buildscript { 5 | repositories { 6 | mavenCentral() 7 | maven { 8 | name = "forge" 9 | url = "https://maven.minecraftforge.net/" 10 | } 11 | maven { 12 | url = "https://jitpack.io" 13 | } 14 | } 15 | dependencies { 16 | classpath 'com.github.GTNewHorizons:ForgeGradle:1.2.11' 17 | } 18 | } 19 | 20 | apply from: "buildscript/forge-1.7.gradle" 21 | -------------------------------------------------------------------------------- /buildscript/forge-1.7-mixin.gradle: -------------------------------------------------------------------------------- 1 | /** Applying this file in a Forge build will imbue it with the powers of Mixin. */ 2 | 3 | repositories { 4 | maven { 5 | name = 'sponge' 6 | url = 'https://repo.spongepowered.org/maven/' 7 | } 8 | } 9 | 10 | def embedMixin = !project.hasProperty("nomixin"); 11 | 12 | if(!embedMixin){ 13 | project.version += "+nomixin" 14 | } 15 | 16 | dependencies { 17 | if(embedMixin){ 18 | embed('org.spongepowered:mixin:0.7.11-SNAPSHOT'){ 19 | setTransitive false 20 | } 21 | } else { 22 | compile('org.spongepowered:mixin:0.7.11-SNAPSHOT'){ 23 | setTransitive false 24 | } 25 | } 26 | } 27 | 28 | ext.outRefMapFile = "${tasks.compileJava.temporaryDir}/${project.modid}.mixin.refmap.json" 29 | 30 | jar { 31 | manifest { 32 | attributes ( 33 | 'MixinConfigs': "${project.modid}.mixin.json", 34 | 'TweakClass': 'org.spongepowered.asm.launch.MixinTweaker', 35 | 'TweakOrder': 0, 36 | 37 | // If these two are not set, Forge will not detect the mod, it will only run the mixins 38 | 'FMLCorePluginContainsFMLMod': 'true', 39 | 'ForceLoadAsMod': 'true', 40 | ) 41 | } 42 | 43 | from outRefMapFile; 44 | } 45 | 46 | def outSrgFile = "${tasks.compileJava.temporaryDir}/outSrg.srg" 47 | 48 | afterEvaluate { 49 | tasks.compileJava.options.compilerArgs += ["-AreobfSrgFile=${tasks.reobf.srg}", "-AoutSrgFile=${outSrgFile}", "-AoutRefMapFile=${outRefMapFile}"]; 50 | } 51 | 52 | reobf { 53 | addExtraSrgFile outSrgFile 54 | } 55 | -------------------------------------------------------------------------------- /buildscript/forge-1.7.gradle: -------------------------------------------------------------------------------- 1 | /** Common code for Forge 1.7.10 builds */ 2 | 3 | apply plugin: 'forge' 4 | 5 | ext.publishDir = project.multiproject_structure.toBoolean() ? "${projectDir}/../publish" : "${projectDir}/publish" 6 | 7 | def getCommitVersion(){ 8 | try { 9 | def commitHashProc = "python3 ${ext.publishDir}/get_version.py".execute() 10 | commitHashProc.waitFor() 11 | if(commitHashProc.exitValue() == 0){ 12 | def commitHash = commitHashProc.text.trim() 13 | 14 | return commitHash 15 | } else { 16 | println commitHashProc.err.text 17 | throw new Exception("get_version.py exited with non-zero return value") 18 | } 19 | } catch(Exception e){ 20 | println "Failed to run get_version.py: " + e.getMessage() 21 | } 22 | return "UNKNOWN" // fallback 23 | } 24 | 25 | project.version = getCommitVersion() 26 | 27 | group = project.group 28 | archivesBaseName = "${project.archives_base}-${project.minecraft_version}" 29 | 30 | minecraft { 31 | version = "${project.minecraft_version}-${project.forge_version}" 32 | runDir = "run" 33 | replace '@VERSION@', project.version 34 | } 35 | 36 | // These settings allow you to choose what version of Java you want to be compatible with. Forge 1.7.10 runs on Java 6 to 8. 37 | sourceCompatibility = 1.8 38 | targetCompatibility = 1.8 39 | 40 | repositories { 41 | maven { 42 | name = "chickenbones" 43 | url = "http://chickenbones.net/maven/" 44 | } 45 | } 46 | 47 | configurations { 48 | embed 49 | compile.extendsFrom(embed) 50 | shade 51 | compile.extendsFrom(shade) 52 | } 53 | 54 | if(project.enable_mixin.toBoolean()) { 55 | apply from: "buildscript/forge-1.7-mixin.gradle" 56 | } 57 | 58 | project.ext.override_dependencies = false 59 | 60 | apply from: "project.gradle" 61 | 62 | if(!project.ext.override_dependencies) { 63 | dependencies { 64 | runtimeOnly "codechicken:CodeChickenLib:1.7.10-1.1.3.140:dev" 65 | runtimeOnly "codechicken:CodeChickenCore:1.7.10-1.0.7.47:dev" 66 | } 67 | } 68 | 69 | jar { 70 | from(sourceSets.main.output); 71 | 72 | // embed libraries in jar 73 | from configurations.embed.collect { 74 | exclude '**/LICENSE', '**/LICENSE.txt' 75 | it.isDirectory() ? it : zipTree(it) 76 | } 77 | 78 | configurations.shade.each { dep -> 79 | from(project.zipTree(dep)){ 80 | exclude '**/LICENSE', '**/LICENSE.txt', 'META-INF', 'META-INF/**' 81 | } 82 | } 83 | } 84 | 85 | processResources { 86 | // This will ensure that this task is redone when the versions or any 87 | // user-defined properties change. 88 | inputs.property "version", version 89 | inputs.property "mcversion", project.minecraft.version 90 | inputs.properties project.ext.getProperties() 91 | 92 | filesMatching('*.info') { 93 | expand project.properties 94 | } 95 | } 96 | 97 | // Ensures that the encoding of source files is set to UTF-8, see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html 98 | tasks.withType(JavaCompile) { 99 | options.encoding = "UTF-8" 100 | } 101 | 102 | // Add git commit hash to MANIFEST.MF 103 | 104 | def getCommitHash(){ 105 | try { 106 | def commitHashProc = "git describe --always --dirty".execute() 107 | commitHashProc.waitFor() 108 | if(commitHashProc.exitValue() == 0){ 109 | def commitHash = commitHashProc.text.trim() 110 | 111 | return commitHash 112 | } else { 113 | println commitHashProc.err.text 114 | throw new Exception("git describe exited with non-zero return value") 115 | } 116 | } catch(Exception e){ 117 | println "Failed to get commit version: " + e.getMessage() 118 | } 119 | return "UNKNOWN" // fallback 120 | } 121 | 122 | 123 | jar { 124 | manifest { 125 | attributes ( 126 | 'Commit-ID': getCommitHash(), 127 | ) 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /docs/dmod_banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/docs/dmod_banner.png -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Mod properties 2 | modid=dmod 3 | archives_base=DMod 4 | # http://maven.apache.org/guides/mini/guide-naming-conventions.html 5 | group=makamys.dmod 6 | 7 | # Forge properties 8 | minecraft_version=1.7.10 9 | forge_version=10.13.4.1614-1.7.10 10 | update_url=https://raw.githubusercontent.com/makamys/DMod/master/updatejson/update.json 11 | 12 | enable_mixin=true 13 | multiproject_structure=false 14 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.4.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | 86 | # Determine the Java command to use to start the JVM. 87 | if [ -n "$JAVA_HOME" ] ; then 88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 89 | # IBM's JDK on AIX uses strange locations for the executables 90 | JAVACMD="$JAVA_HOME/jre/sh/java" 91 | else 92 | JAVACMD="$JAVA_HOME/bin/java" 93 | fi 94 | if [ ! -x "$JAVACMD" ] ; then 95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 96 | 97 | Please set the JAVA_HOME variable in your environment to match the 98 | location of your Java installation." 99 | fi 100 | else 101 | JAVACMD="java" 102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 103 | 104 | Please set the JAVA_HOME variable in your environment to match the 105 | location of your Java installation." 106 | fi 107 | 108 | # Increase the maximum file descriptors if we can. 109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 110 | MAX_FD_LIMIT=`ulimit -H -n` 111 | if [ $? -eq 0 ] ; then 112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 113 | MAX_FD="$MAX_FD_LIMIT" 114 | fi 115 | ulimit -n $MAX_FD 116 | if [ $? -ne 0 ] ; then 117 | warn "Could not set maximum file descriptor limit: $MAX_FD" 118 | fi 119 | else 120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 121 | fi 122 | fi 123 | 124 | # For Darwin, add options to specify how the application appears in the dock 125 | if $darwin; then 126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 127 | fi 128 | 129 | # For Cygwin or MSYS, switch paths to Windows format before running java 130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 133 | 134 | JAVACMD=`cygpath --unix "$JAVACMD"` 135 | 136 | # We build the pattern for arguments to be converted via cygpath 137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 138 | SEP="" 139 | for dir in $ROOTDIRSRAW ; do 140 | ROOTDIRS="$ROOTDIRS$SEP$dir" 141 | SEP="|" 142 | done 143 | OURCYGPATTERN="(^($ROOTDIRS))" 144 | # Add a user-defined pattern to the cygpath arguments 145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 147 | fi 148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 149 | i=0 150 | for arg in "$@" ; do 151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 153 | 154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 156 | else 157 | eval `echo args$i`="\"$arg\"" 158 | fi 159 | i=`expr $i + 1` 160 | done 161 | case $i in 162 | 0) set -- ;; 163 | 1) set -- "$args0" ;; 164 | 2) set -- "$args0" "$args1" ;; 165 | 3) set -- "$args0" "$args1" "$args2" ;; 166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 172 | esac 173 | fi 174 | 175 | # Escape application args 176 | save () { 177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 178 | echo " " 179 | } 180 | APP_ARGS=`save "$@"` 181 | 182 | # Collect all arguments for the java command, following the shell quoting and substitution rules 183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 184 | 185 | exec "$JAVACMD" "$@" 186 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /makalibs.gradle: -------------------------------------------------------------------------------- 1 | /* Common code in my projects using my libraries */ 2 | 3 | repositories { 4 | maven { url 'https://jitpack.io' } 5 | } 6 | 7 | minecraft { 8 | srgExtra "PK: makamys/mclib makamys/${project.modid}/lib/makamys/mclib" 9 | } 10 | 11 | dependencies { 12 | shade('com.github.makamys:MCLib:d78ddd3'){ 13 | exclude group: "codechicken" 14 | } 15 | } 16 | 17 | minecraft { 18 | replace '@UPDATE_URL@', project.update_url 19 | } -------------------------------------------------------------------------------- /project.gradle: -------------------------------------------------------------------------------- 1 | repositories { 2 | maven { 3 | name = "gt" 4 | url = "http://gregtech.overminddl1.com/" 5 | } 6 | } 7 | 8 | dependencies { 9 | // also pulls in NEI 10 | compileOnly "ganymedes01.etfuturum:Et_Futurum_Requiem:2.1.2:dev" 11 | } 12 | 13 | jar.manifest.attributes ( 14 | 'FMLAT': "${project.modid}_at.cfg", 15 | ) 16 | 17 | apply from: "makalibs.gradle" -------------------------------------------------------------------------------- /publish/.gitignore: -------------------------------------------------------------------------------- 1 | changelog.md 2 | gameVersions.txt -------------------------------------------------------------------------------- /publish/README.txt: -------------------------------------------------------------------------------- 1 | # How to publish 2 | 3 | Push the release's tag before running this. 4 | 5 | ``` 6 | sh ./build_and_release.sh $GITHUB_TOKEN [$CURSEFORGE_TOKEN] [$MODRINTH_TOKEN] 7 | ``` 8 | -------------------------------------------------------------------------------- /publish/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.github.breadmoirai.github-release" version "2.2.12" 3 | id "com.matthewprenger.cursegradle" version "1.4.0" 4 | id "com.modrinth.minotaur" version "1.2.1" 5 | } 6 | 7 | import com.modrinth.minotaur.TaskModrinthUpload 8 | import groovy.json.JsonSlurper 9 | import okhttp3.OkHttpClient 10 | import java.util.concurrent.TimeUnit 11 | 12 | def getCommitVersion(){ 13 | try { 14 | def commitHashProc = "python3 ${projectDir}/get_version.py".execute() 15 | commitHashProc.waitFor() 16 | if(commitHashProc.exitValue() == 0){ 17 | def commitHash = commitHashProc.text.trim() 18 | 19 | return commitHash 20 | } else { 21 | println commitHashProc.err.text 22 | throw new Exception("get_version.py exited with non-zero return value") 23 | } 24 | } catch(Exception e){ 25 | println "Failed to run get_version.py: " + e.getMessage() 26 | } 27 | return "UNKNOWN" // fallback 28 | } 29 | 30 | def buildVersion = getCommitVersion() 31 | def changeLogFile = new File("${projectDir}/changelog.md") 32 | def changeLog = changeLogFile.exists() ? changeLogFile.getText('UTF-8') : "" 33 | ext.gameVersionsMap = new JsonSlurper().parseText(file("gameVersions.json").getText('UTF-8')) 34 | ext.gameVersions = gameVersionsMap.keySet() 35 | 36 | def githubOK = project.hasProperty("githubToken") 37 | def curseOK = project.hasProperty("curseToken") && project.hasProperty("gameVersion") 38 | def modrinthOK = project.hasProperty("modrinthToken") && project.hasProperty("gameVersion") 39 | 40 | def debugPublish = project.hasProperty("debugPublish") && project.debugPublish.toBoolean() 41 | 42 | def useVPrefixForTag = project.hasProperty("useVPrefixForTag") && project.useVPrefixForTag.toBoolean() 43 | 44 | task build {} 45 | task assemble {} 46 | 47 | if(githubOK){ 48 | githubRelease { 49 | token project.githubToken // This is your personal access token with Repo permissions 50 | // You get this from your user settings > developer settings > Personal Access Tokens 51 | owner project.githubOwner // default is the last part of your group. Eg group: "com.github.breadmoirai" => owner: "breadmoirai" 52 | repo project.githubRepo // by default this is set to your project name 53 | tagName ((useVPrefixForTag ? "v" : "") + "${buildVersion}") // by default this is set to "v${project.version}" 54 | targetCommitish "master" // by default this is set to "master" 55 | releaseName "${project.releaseName} ${buildVersion}" 56 | body changeLog // by default this is empty 57 | draft false // by default this is false 58 | prerelease false // by default this is false 59 | releaseAssets getFiles() // this points to which files you want to upload as assets with your release 60 | 61 | overwrite false // by default false; if set to true, will delete an existing release with the same tag and name 62 | dryRun debugPublish // by default false; you can use this to see what actions would be taken without making a release 63 | apiEndpoint "https://api.github.com" // should only change for github enterprise users 64 | client new OkHttpClient.Builder() 65 | .writeTimeout(5, TimeUnit.MINUTES) 66 | .readTimeout(5, TimeUnit.MINUTES) 67 | .build() // Added because I kept getting SocketTimeoutExceptions 68 | } 69 | } else { 70 | println("Not configuring GitHub publish because project arguments are missing.") 71 | } 72 | 73 | if(project.hasProperty("gameVersion")){ 74 | def gameVersion = project.gameVersion 75 | def baseVersion = toBaseVersion(gameVersion) 76 | def files = getFiles(baseVersion) 77 | def shortest = null 78 | files.each { 79 | if(shortest == null || it.name.length() < shortest.name.length()){ 80 | shortest = it 81 | } 82 | } 83 | def additionalFiles = files - shortest 84 | 85 | if(curseOK) { 86 | curseforge { 87 | apiKey = project.curseToken 88 | project { 89 | id = project.curseID 90 | changelogType = 'markdown' 91 | changelog = changeLog 92 | releaseType = 'release' 93 | addGameVersion gameVersion 94 | addGameVersion "Forge" 95 | 96 | mainArtifact(file(shortest)) { 97 | displayName = "${releaseName} ${buildVersion} for Minecraft ${gameVersion}" 98 | } 99 | additionalFiles.each { addArtifact(it) } 100 | } 101 | options { 102 | debug = debugPublish 103 | javaIntegration = false 104 | forgeGradleIntegration = false 105 | javaVersionAutoDetect = false 106 | } 107 | } 108 | } else { 109 | println("Not configuring CurseForge publish because project arguments are missing.") 110 | } 111 | 112 | if(modrinthOK) { 113 | task publishModrinth (type: TaskModrinthUpload) { 114 | token = project.modrinthToken 115 | projectId = project.modrinthID 116 | versionNumber = "$gameVersion-$buildVersion" 117 | versionName = "$gameVersion-$buildVersion" // the doc says this defaults to the versionNumber, but it defaulted to the string "undefined" for me so i'm setting it 118 | uploadFile = shortest 119 | addGameVersion(gameVersion) 120 | additionalFiles.each { addFile(it) } 121 | addLoader('forge') 122 | changelog = changeLog 123 | detectLoaders = false 124 | } 125 | } else { 126 | println("Not configuring Modrinth publish because project arguments are missing.") 127 | } 128 | } 129 | 130 | def toBaseVersion(ver){ 131 | return String.join(".", ver.tokenize(".").subList(0, 2)) 132 | } 133 | 134 | def getVersionProjectPath(ver){ 135 | if(project.versionedProjectDirectories.toBoolean()){ 136 | return "${projectDir}/../${ver}" 137 | } else { 138 | return "${projectDir}/.." 139 | } 140 | } 141 | 142 | def getFiles(ver) { 143 | def files = [] 144 | new File("${getVersionProjectPath(ver)}/build/libs").eachFile(groovy.io.FileType.FILES, { 145 | if(!(it.name.endsWith("-sources.jar") || it.name.endsWith("-dev.jar"))){ 146 | files << it 147 | } 148 | }) 149 | return files 150 | } 151 | 152 | def getFiles() { 153 | def files = [] 154 | project.gameVersions.collect({toBaseVersion(it)}).each { 155 | files += getFiles(it) 156 | } 157 | return files 158 | } 159 | 160 | // for debug 161 | task listFiles { 162 | doLast { 163 | project.gameVersions.collect({toBaseVersion(it)}).each { 164 | println("$it: ${getFiles(it)}") 165 | } 166 | } 167 | } 168 | 169 | def getBuildArgumentSets(ver) { 170 | def projectConfig = new Properties() 171 | projectConfig.load(file("../gradle.properties").newReader()) 172 | return projectConfig.enable_mixin ? ["", "-Pnomixin"] : [""] 173 | } 174 | 175 | project.gameVersions.each { ver -> 176 | def baseVer = toBaseVersion(ver) 177 | def dir = getVersionProjectPath(baseVer) 178 | task ("cleanBuild-$baseVer", type: Exec) { 179 | workingDir dir 180 | commandLine 'sh', '-c', "rm -f build/libs/* && " + String.join(" && ", getBuildArgumentSets(ver).collect({"./gradlew build ${it}"})) 181 | } 182 | } 183 | 184 | task cleanBuildAll(dependsOn: project.gameVersions.collect({"cleanBuild-${toBaseVersion(it)}"})) { 185 | 186 | } 187 | -------------------------------------------------------------------------------- /publish/build_and_release.sh: -------------------------------------------------------------------------------- 1 | if [ ! -s changelog.md ]; then 2 | echo "Changelog is empty, refusing to publish." 3 | exit 3 4 | fi 5 | 6 | if [[ $(git diff --cached --stat) != '' ]] 7 | then 8 | echo "There are staged uncommitted changes, refusing to publish." 9 | exit 2 10 | fi 11 | 12 | if [ "$#" -lt 1 ] || [ "$#" -gt 3 ] 13 | then 14 | echo "Usage: $0 GITHUB_TOKEN CURSEFORGE_TOKEN [MODRINTH_TOKEN]" 15 | exit 1 16 | fi 17 | 18 | # exit when any command fails 19 | set -e 20 | 21 | GITHUB_TOKEN=$1 22 | CURSEFORGE_TOKEN=$2 23 | MODRINTH_TOKEN=$3 24 | 25 | # build the release 26 | ./gradlew cleanBuildAll 27 | 28 | # release 29 | py prepare_publish.py 30 | ./gradlew githubRelease -PgithubToken=$GITHUB_TOKEN 31 | 32 | if [ -n "$CURSEFORGE_TOKEN" ] 33 | then 34 | ./curseforge_all.sh -PcurseToken=$CURSEFORGE_TOKEN 35 | fi 36 | 37 | /dev/null > changelog.md 38 | 39 | if [ -n "$MODRINTH_TOKEN" ] 40 | then 41 | ./modrinth_all.sh -PmodrinthToken=$MODRINTH_TOKEN 42 | fi 43 | 44 | py update_updatejson.py 45 | -------------------------------------------------------------------------------- /publish/curseforge_all.sh: -------------------------------------------------------------------------------- 1 | for proj in `cat gameVersions.txt`; do 2 | ./gradlew curseforge -PgameVersion=$proj $* 3 | done 4 | -------------------------------------------------------------------------------- /publish/gameVersions.json: -------------------------------------------------------------------------------- 1 | { 2 | "1.7.10": {} 3 | } -------------------------------------------------------------------------------- /publish/get_version.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | import sys 3 | import os 4 | 5 | ver = None 6 | 7 | versionPath = os.path.dirname(sys.argv[0]) + "/version.txt" 8 | if os.path.exists(versionPath): 9 | with open(versionPath, "r", encoding="utf8") as fp: 10 | ver = fp.read() 11 | else: 12 | ver = subprocess.run(["git", "describe", "--tags", "--dirty"], capture_output=True, text=True).stdout or "UNKNOWN-" + subprocess.run(["git", "describe", "--always", "--dirty"], capture_output=True, text=True).stdout or "UNKNOWN" 13 | 14 | ver = ver.strip() 15 | if ver[0] == "v": 16 | ver = ver[1:] 17 | 18 | print(ver) 19 | -------------------------------------------------------------------------------- /publish/gradle.properties: -------------------------------------------------------------------------------- 1 | githubOwner=makamys 2 | githubRepo=DMod 3 | 4 | curseID=513764 5 | modrinthID= 6 | 7 | releaseName=D-Mod 8 | 9 | versionedProjectDirectories=false 10 | updateJsonFullVersionFormat=false 11 | useVPrefixForTag=false 12 | -------------------------------------------------------------------------------- /publish/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/publish/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /publish/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Sep 14 12:28:28 PDT 2015 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip 7 | -------------------------------------------------------------------------------- /publish/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /publish/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /publish/modrinth_all.sh: -------------------------------------------------------------------------------- 1 | for proj in `cat gameVersions.txt`; do 2 | ./gradlew publishModrinth -PgameVersion=$proj $* 3 | done 4 | -------------------------------------------------------------------------------- /publish/prepare_publish.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | open("gameVersions.txt", "w").write(" ".join(json.load(open("gameVersions.json", "r")).keys())) 4 | -------------------------------------------------------------------------------- /publish/update_updatejson.py: -------------------------------------------------------------------------------- 1 | import json 2 | import subprocess 3 | 4 | jsonPath = "../updatejson/update.json" 5 | 6 | # lol 7 | fullFormat = "updateJsonFullVersionFormat=true" in open("gradle.properties", "r", encoding="utf8").read() 8 | 9 | data = json.load(open(jsonPath, "r", encoding="utf8")) 10 | ver = subprocess.run(["python3", "get_version.py"], capture_output=True, text=True).stdout.strip() 11 | 12 | for gameVer in json.load(open("gameVersions.json", "r")).keys(): 13 | modVer = "{}".format(ver) if not fullFormat else "{}-{}".format(gameVer, ver) 14 | 15 | if gameVer not in data: 16 | data[gameVer] = {} 17 | 18 | data[gameVer][modVer] = "" 19 | data["promos"]["{}-latest".format(gameVer)] = modVer 20 | 21 | json.dump(data, open(jsonPath, "w", encoding="utf8"), indent=2) 22 | 23 | subprocess.run(["git", "add", jsonPath]) 24 | subprocess.run(["git", "commit", "-m", "[skip ci] Update update json"]) 25 | subprocess.run(["git", "push"]) 26 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/ConfigDMod.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod; 2 | 3 | import static makamys.dmod.DModConstants.LOGGER; 4 | 5 | import java.io.File; 6 | import java.util.ArrayList; 7 | import java.util.Arrays; 8 | import java.util.List; 9 | import java.util.Map; 10 | import java.util.stream.Collectors; 11 | import java.util.stream.Stream; 12 | 13 | import org.apache.commons.lang3.EnumUtils; 14 | 15 | import makamys.dmod.entity.EntityFox; 16 | import makamys.dmod.util.WeightedRandomItem; 17 | import makamys.mclib.config.item.BackpackConfigHelper; 18 | import net.minecraft.entity.Entity; 19 | import net.minecraft.entity.EntityList; 20 | import net.minecraft.init.Items; 21 | import net.minecraft.item.Item; 22 | import net.minecraft.launchwrapper.Launch; 23 | import net.minecraftforge.common.config.Configuration; 24 | 25 | public class ConfigDMod { 26 | 27 | public static List foxBreedingItems; 28 | public static List> foxMouthItems; 29 | public static List> rabbitEntities; 30 | public static EntityFox.AbilityMode foxAbilityMode; 31 | public static float foxExpModifier; 32 | 33 | public static boolean wolvesTargetFoxes; 34 | public static ForceableBoolean lootingFoxFix; 35 | 36 | public static boolean enableFox; 37 | public static boolean enableBundle; 38 | 39 | public static List bundleCraftingItems; 40 | public static boolean compactBundleGUI; 41 | public static boolean durabilityBarColor; 42 | 43 | public static BackpackConfigHelper backpackHelper; 44 | 45 | private static List resolveItemListOrDefault(Configuration config, String propName, String propCat, String[] propDefault, String propComment, Item... defaults){ 46 | String[] list = config.getStringList(propName, propCat, propDefault, propComment); 47 | List items = new ArrayList<>(); 48 | for(String itemStr : list) { 49 | Object itemObj = Item.itemRegistry.getObject(itemStr); 50 | if(itemObj != null) { 51 | items.add((Item)itemObj); 52 | } 53 | } 54 | if(items.isEmpty() && list.length > 0) { 55 | LOGGER.debug("Couldn't resolve any of the items in " + propCat + "." + propName + ", falling back to defaults"); 56 | items = Arrays.asList(defaults); 57 | } 58 | 59 | LOGGER.debug("Resolved " + propCat + "." + propName + " to " + items.stream().map(i -> i.getUnlocalizedName()).collect(Collectors.toList())); 60 | return items; 61 | } 62 | 63 | // nice copypasta 64 | private static List> resolveEntityClassListOrDefault(Configuration config, String propName, String propCat, String[] propDefault, String propComment, Class... defaults){ 65 | String[] list = config.getStringList(propName, propCat, propDefault, propComment); 66 | List> items = new ArrayList<>(); 67 | for(String itemStr : list) { 68 | Object itemObj = EntityList.stringToClassMapping.get(itemStr); 69 | if(itemObj != null) { 70 | items.add((Class)itemObj); 71 | } 72 | } 73 | if(items.isEmpty() && list.length > 0) { 74 | LOGGER.debug("Couldn't resolve any of the entity names in " + propCat + "." + propName + ", falling back to defaults"); 75 | items = Arrays.asList(defaults); 76 | } 77 | 78 | LOGGER.debug("Resolved " + propCat + "." + propName + " to " + items.stream().map(e -> EntityList.classToStringMapping.get(e)).collect(Collectors.toList())); 79 | return items; 80 | } 81 | 82 | private static E getEnum(Configuration config, String propName, String propCat, E propDefault, String propComment) { 83 | return getEnum(config, propName, propCat, propDefault, propComment, false); 84 | } 85 | 86 | private static E getEnum(Configuration config, String propName, String propCat, E propDefault, String propComment, boolean lowerCase) { 87 | Map enumMap = EnumUtils.getEnumMap(propDefault.getClass()); 88 | String[] valuesStr = (String[])enumMap.keySet().toArray(new String[]{}); 89 | String defaultString = propDefault.toString(); 90 | if(lowerCase) defaultString = defaultString.toLowerCase(); 91 | return (E)enumMap.get(config.getString(propName, propCat, defaultString, propComment, valuesStr).toUpperCase()); 92 | } 93 | 94 | public static void reload() { 95 | reload(false); 96 | } 97 | 98 | public static void reload(boolean early) { 99 | LOGGER.debug("Loading config (" + (early ? "Early" : "Late") + ")"); 100 | 101 | Configuration config = new Configuration(new File(Launch.minecraftHome, "config/dmod.cfg")); 102 | 103 | config.load(); 104 | 105 | enableFox = config.getBoolean("enableFox", "_features", true, ""); 106 | enableBundle = config.getBoolean("enableBundle", "_features", true, ""); 107 | 108 | wolvesTargetFoxes = config.getBoolean("wolvesTargetFoxes", "Mixins", true, ""); 109 | lootingFoxFix = getEnum(config, "lootingFoxFix", "Mixins", ForceableBoolean.TRUE, "Make looting enchants of fox weapons have an effect.", true); 110 | durabilityBarColor = config.getBoolean("durabilityBarColor", "Mixins", true, "Change the durability bar color of certain items (bundles)"); 111 | 112 | compactBundleGUI = config.getBoolean("compactBundleGUI", "bundle", false, "Remove extra spacing between rows in the bundle tooltip."); 113 | 114 | // TODO tweak the level requirements of each individual ability 115 | foxAbilityMode = getEnum(config, "foxAbilityMode", "fox", EntityFox.AbilityMode.NORMAL, "NORMAL: Foxes unlock abilities as they level up\nUNLOCK_ALL: All abilities are unlocked from the start\nUNLOCK_NONE: No abilities will ever be unlocked\nNote: changing this won't affect the amount of exp foxes have, just whether the abilities will be enabled or not"); 116 | foxExpModifier = config.getFloat("foxExpModifier", "Fox", 1f, 0f, Float.POSITIVE_INFINITY, "The EXP foxes earn will get multiplied by this value."); 117 | 118 | if(!early) { 119 | foxBreedingItems = 120 | resolveItemListOrDefault(config, "foxBreedingItems", "Fox", new String[]{"etfuturum:sweet_berries"}, "Falls back to wheat if none of the items can be resolved", Items.wheat); 121 | rabbitEntities = 122 | resolveEntityClassListOrDefault(config, "rabbitEntities", "Fox", new String[]{"etfuturum.rabbit"}, ""); 123 | foxMouthItems = Arrays.stream(config.getStringList("foxMouthItems", "Fox", new String[] {"emerald=5", "egg=15", "etfuturum:rabbit_foot=10", "etfuturum:rabbit_hide=10", "wheat=20", "leather=20", "feather=20"}, "item=weight pairs deciding the relative likelyhood of foxes spawning with certain items. Entries containing items that can't be resolved will be ignored.")) 124 | .map(str -> parseWeightedItemEntry(str)).filter(p -> p != null).collect(Collectors.toList()); 125 | bundleCraftingItems = 126 | resolveItemListOrDefault(config, "bundleCraftingItems", "bundle", new String[]{"etfuturum:rabbit_hide"}, "Falls back to leather if none of the items can be resolved", Items.leather); 127 | backpackHelper = new BackpackConfigHelper(Arrays.asList(config.getStringList("bundleItemBlacklist", "bundle", Stream.of( 128 | new String[]{"etfuturum:shulker_box"}, 129 | BackpackConfigHelper.NON_NESTABLE_BACKPACK_BLACKLIST).flatMap(Stream::of).toArray(String[]::new), 130 | "Items that aren't allowed in bundles" + BackpackConfigHelper.CONFIG_DESCRIPTION_SUFFIX))); 131 | } 132 | 133 | if (config.hasChanged()) 134 | { 135 | config.save(); 136 | } 137 | } 138 | 139 | private static WeightedRandomItem parseWeightedItemEntry(String str) { 140 | String[] halves = str.split("="); 141 | if(halves.length == 2) { 142 | Object itemObj = Item.itemRegistry.getObject(halves[0]); 143 | if(itemObj != null) { 144 | Item item = (Item)itemObj; 145 | try { 146 | int weight = Integer.parseInt(halves[1]); 147 | return new WeightedRandomItem<>(weight, item); 148 | } catch(NumberFormatException e) { 149 | LOGGER.warn("Invalid weight (must be an integer): " + halves[1]); 150 | } 151 | } else { 152 | LOGGER.debug("No item called " + halves[0]); 153 | } 154 | } else { 155 | LOGGER.warn("Incorrect pair: " + str); 156 | } 157 | return null; 158 | } 159 | 160 | public static enum ForceableBoolean { TRUE, FALSE, FORCE } 161 | 162 | } 163 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/DMod.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod; 2 | 3 | import static makamys.dmod.DModConstants.MODID; 4 | import static makamys.dmod.DModConstants.VERSION; 5 | 6 | import cpw.mods.fml.common.Mod; 7 | import cpw.mods.fml.common.Mod.EventHandler; 8 | import cpw.mods.fml.common.Mod.Instance; 9 | import cpw.mods.fml.common.SidedProxy; 10 | import cpw.mods.fml.common.event.FMLInitializationEvent; 11 | import cpw.mods.fml.common.event.FMLPostInitializationEvent; 12 | import cpw.mods.fml.common.event.FMLPreInitializationEvent; 13 | import cpw.mods.fml.common.event.FMLServerAboutToStartEvent; 14 | import cpw.mods.fml.common.event.FMLServerStartingEvent; 15 | import cpw.mods.fml.common.event.FMLServerStoppedEvent; 16 | import makamys.dmod.proxy.DProxyCommon; 17 | import makamys.dmod.util.StatRegistry; 18 | import makamys.mclib.core.MCLib; 19 | import makamys.mclib.core.MCLibModules; 20 | import net.minecraftforge.common.MinecraftForge; 21 | 22 | @Mod(modid = MODID, version = VERSION) 23 | public class DMod 24 | { 25 | @Instance(MODID) 26 | public static DMod instance; 27 | 28 | @SidedProxy(clientSide = "makamys.dmod.proxy.DProxyClient", serverSide = "makamys.dmod.proxy.DProxyCommon") 29 | public static DProxyCommon proxy; 30 | 31 | static { 32 | MCLib.init(); 33 | } 34 | 35 | @EventHandler 36 | public void preInit(FMLPreInitializationEvent event) { 37 | DModItems.preInit(); 38 | MCLibModules.updateCheckAPI.submitModTask(MODID, "@UPDATE_URL@"); 39 | } 40 | 41 | @EventHandler 42 | public void init(FMLInitializationEvent event) 43 | { 44 | instance = this; 45 | MinecraftForge.EVENT_BUS.register(proxy); 46 | 47 | proxy.init(); 48 | } 49 | 50 | @EventHandler 51 | public void postInit(FMLPostInitializationEvent event) { 52 | ConfigDMod.reload(); 53 | DModItems.postInit(); 54 | } 55 | 56 | @EventHandler 57 | public void onServerAboutToStart(FMLServerAboutToStartEvent event) { 58 | ConfigDMod.reload(); 59 | } 60 | 61 | @EventHandler 62 | public void onServerStarting(FMLServerStartingEvent event) { 63 | StatRegistry.instance.onServerStarting(event); 64 | } 65 | 66 | @EventHandler 67 | public void onServerStopped(FMLServerStoppedEvent event) { 68 | StatRegistry.instance.onServerStopped(event); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/DModConstants.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod; 2 | 3 | import org.apache.logging.log4j.LogManager; 4 | import org.apache.logging.log4j.Logger; 5 | 6 | public class DModConstants { 7 | 8 | public static final String MODID = "dmod"; 9 | public static final String VERSION = "@VERSION@"; 10 | 11 | public static final Logger LOGGER = LogManager.getLogger("dmod"); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/DModItems.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod; 2 | 3 | import cpw.mods.fml.common.registry.GameRegistry; 4 | import makamys.dmod.item.IConfigurable; 5 | import makamys.dmod.item.ItemBundle; 6 | import net.minecraft.init.Items; 7 | import net.minecraft.item.Item; 8 | import net.minecraft.item.ItemStack; 9 | 10 | // Class structure insprired by Et Futurum 11 | 12 | public class DModItems { 13 | 14 | public static final Item bundle = initItem(new ItemBundle()); 15 | 16 | public static void preInit() { 17 | 18 | } 19 | 20 | public static void postInit() { 21 | registerRecipes(); 22 | } 23 | 24 | private static void registerRecipes() { 25 | for(Item bundleCraftingItem : ConfigDMod.bundleCraftingItems) { 26 | GameRegistry.addShapedRecipe(new ItemStack(bundle), new Object[] {"SLS", "L L", "LLL", 'L', bundleCraftingItem, 'S', Items.string}); 27 | } 28 | } 29 | 30 | private static Item initItem(Item item) { 31 | if(!(item instanceof IConfigurable) || ((IConfigurable)item).isEnabled()) { 32 | String name = item.getUnlocalizedName(); 33 | int firstDot = name.lastIndexOf('.'); 34 | GameRegistry.registerItem(item, name.substring(firstDot + 1)); 35 | } 36 | return item; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/MixinConfigPlugin.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.Set; 6 | 7 | import org.spongepowered.asm.lib.tree.ClassNode; 8 | import org.spongepowered.asm.mixin.MixinEnvironment; 9 | import org.spongepowered.asm.mixin.MixinEnvironment.Side; 10 | import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; 11 | import org.spongepowered.asm.mixin.extensibility.IMixinInfo; 12 | 13 | import makamys.dmod.ConfigDMod.ForceableBoolean; 14 | 15 | public class MixinConfigPlugin implements IMixinConfigPlugin { 16 | 17 | @Override 18 | public void onLoad(String mixinPackage) { 19 | ConfigDMod.reload(true); 20 | } 21 | 22 | @Override 23 | public String getRefMapperConfig() { 24 | // TODO Auto-generated method stub 25 | return null; 26 | } 27 | 28 | @Override 29 | public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { 30 | if(Arrays.asList( 31 | "makamys.dmod.mixin.MixinEntityWolf" 32 | ).contains(mixinClassName)){ 33 | return ConfigDMod.wolvesTargetFoxes; 34 | } else if(Arrays.asList( 35 | "makamys.dmod.mixin.MixinEntityLivingBase" 36 | ).contains(mixinClassName)){ 37 | return ConfigDMod.enableFox && ConfigDMod.lootingFoxFix != ForceableBoolean.FALSE; 38 | } else if(Arrays.asList( 39 | "makamys.dmod.mixin.MixinRenderItem" 40 | ).contains(mixinClassName)){ 41 | return MixinEnvironment.getCurrentEnvironment().getSide() == Side.CLIENT && ConfigDMod.durabilityBarColor; 42 | } else if(Arrays.asList( 43 | "makamys.dmod.mixin.MixinContainer" 44 | ).contains(mixinClassName)){ 45 | return ConfigDMod.enableBundle; 46 | } else { 47 | return true; 48 | } 49 | } 50 | 51 | @Override 52 | public void acceptTargets(Set myTargets, Set otherTargets) { 53 | // TODO Auto-generated method stub 54 | 55 | } 56 | 57 | @Override 58 | public List getMixins() { 59 | // TODO Auto-generated method stub 60 | return null; 61 | } 62 | 63 | @Override 64 | public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { 65 | // TODO Auto-generated method stub 66 | 67 | } 68 | 69 | @Override 70 | public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { 71 | // TODO Auto-generated method stub 72 | 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/ai/EntityAIFollowOwnerEx.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.ai; 2 | 3 | import makamys.dmod.entity.ITameable; 4 | import net.minecraft.entity.EntityLiving; 5 | import net.minecraft.entity.EntityLivingBase; 6 | import net.minecraft.entity.ai.EntityAIBase; 7 | import net.minecraft.pathfinding.PathNavigate; 8 | import net.minecraft.util.MathHelper; 9 | import net.minecraft.world.World; 10 | 11 | public class EntityAIFollowOwnerEx extends EntityAIBase 12 | { 13 | private EntityLiving thePet; 14 | private ITameable thePetI; 15 | private EntityLivingBase theOwner; 16 | World theWorld; 17 | private double field_75336_f; 18 | private PathNavigate petPathfinder; 19 | private int field_75343_h; 20 | float maxDist; 21 | float minDist; 22 | private boolean field_75344_i; 23 | private double minTeleportDistSq; 24 | 25 | public EntityAIFollowOwnerEx(EntityLiving p_i1625_1_, double p_i1625_2_, float p_i1625_4_, float p_i1625_5_, double minTeleportDistSq) 26 | { 27 | if(!(p_i1625_1_ instanceof ITameable)) { 28 | throw new IllegalArgumentException("The pet entity must implement ITameable"); 29 | } 30 | this.thePet = p_i1625_1_; 31 | this.thePetI = (ITameable)p_i1625_1_; 32 | this.theWorld = p_i1625_1_.worldObj; 33 | this.field_75336_f = p_i1625_2_; 34 | this.petPathfinder = p_i1625_1_.getNavigator(); 35 | this.minDist = p_i1625_4_; 36 | this.maxDist = p_i1625_5_; 37 | this.minTeleportDistSq = minTeleportDistSq; 38 | this.setMutexBits(3); 39 | } 40 | 41 | public EntityAIFollowOwnerEx(EntityLiving p_i1625_1_, double p_i1625_2_, float p_i1625_4_, float p_i1625_5_) 42 | { 43 | this(p_i1625_1_, p_i1625_2_, p_i1625_4_, p_i1625_5_, Double.POSITIVE_INFINITY); 44 | } 45 | 46 | /** 47 | * Returns whether the EntityAIBase should begin execution. 48 | */ 49 | public boolean shouldExecute() 50 | { 51 | EntityLivingBase entitylivingbase = this.thePetI.getPetOwner(); 52 | 53 | if (entitylivingbase == null) 54 | { 55 | return false; 56 | } 57 | else if (this.thePetI.isPetSitting()) 58 | { 59 | return false; 60 | } 61 | else if (this.thePet.getDistanceSqToEntity(entitylivingbase) < Math.pow(this.minDist * (this.thePet.getEntitySenses().canSee(entitylivingbase) ? 1.0 : 0.5), 2)) 62 | { 63 | return false; 64 | } 65 | else 66 | { 67 | this.theOwner = entitylivingbase; 68 | return true; 69 | } 70 | } 71 | 72 | /** 73 | * Returns whether an in-progress EntityAIBase should continue executing 74 | */ 75 | public boolean continueExecuting() 76 | { 77 | return !this.petPathfinder.noPath() && (this.thePet.getDistanceSqToEntity(this.theOwner) > Math.pow(this.maxDist * (this.thePet.getEntitySenses().canSee(this.theOwner) ? 1.0 : 0.5), 2)) && !this.thePetI.isPetSitting(); 78 | } 79 | 80 | /** 81 | * Execute a one shot task or start executing a continuous task 82 | */ 83 | public void startExecuting() 84 | { 85 | this.field_75343_h = 0; 86 | this.field_75344_i = this.thePet.getNavigator().getAvoidsWater(); 87 | this.thePet.getNavigator().setAvoidsWater(false); 88 | } 89 | 90 | /** 91 | * Resets the task 92 | */ 93 | public void resetTask() 94 | { 95 | this.theOwner = null; 96 | this.petPathfinder.clearPathEntity(); 97 | this.thePet.getNavigator().setAvoidsWater(this.field_75344_i); 98 | } 99 | 100 | /** 101 | * Updates the task 102 | */ 103 | public void updateTask() 104 | { 105 | this.thePet.getLookHelper().setLookPositionWithEntity(this.theOwner, 10.0F, (float)this.thePet.getVerticalFaceSpeed()); 106 | 107 | if (!this.thePetI.isPetSitting()) 108 | { 109 | if (--this.field_75343_h <= 0) 110 | { 111 | this.field_75343_h = 10; 112 | 113 | if (!this.petPathfinder.tryMoveToEntityLiving(this.theOwner, this.field_75336_f)) 114 | { 115 | if (!this.thePet.getLeashed()) 116 | { 117 | if (this.thePet.getDistanceSqToEntity(this.theOwner) >= minTeleportDistSq) 118 | { 119 | int i = MathHelper.floor_double(this.theOwner.posX) - 2; 120 | int j = MathHelper.floor_double(this.theOwner.posZ) - 2; 121 | int k = MathHelper.floor_double(this.theOwner.boundingBox.minY); 122 | 123 | for (int l = 0; l <= 4; ++l) 124 | { 125 | for (int i1 = 0; i1 <= 4; ++i1) 126 | { 127 | if ((l < 1 || i1 < 1 || l > 3 || i1 > 3) && World.doesBlockHaveSolidTopSurface(this.theWorld, i + l, k - 1, j + i1) && !this.theWorld.getBlock(i + l, k, j + i1).isNormalCube() && !this.theWorld.getBlock(i + l, k + 1, j + i1).isNormalCube()) 128 | { 129 | this.thePet.setLocationAndAngles((double)((float)(i + l) + 0.5F), (double)k, (double)((float)(j + i1) + 0.5F), this.thePet.rotationYaw, this.thePet.rotationPitch); 130 | this.petPathfinder.clearPathEntity(); 131 | return; 132 | } 133 | } 134 | } 135 | } 136 | } 137 | } 138 | } 139 | } 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/ai/EntityAIPanicWithTimeout.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.ai; 2 | 3 | import static makamys.dmod.DModConstants.LOGGER; 4 | 5 | import net.minecraft.entity.EntityCreature; 6 | import net.minecraft.entity.ai.EntityAIPanic; 7 | 8 | public class EntityAIPanicWithTimeout extends EntityAIPanic { 9 | 10 | protected EntityCreature theCreature; 11 | protected int startTime; 12 | protected int maxDuration; 13 | 14 | public EntityAIPanicWithTimeout(EntityCreature creature, double speed, int maxDuration) { 15 | super(creature, speed); 16 | this.theCreature = creature; 17 | this.maxDuration = maxDuration; 18 | } 19 | 20 | public EntityAIPanicWithTimeout(EntityCreature creature, double speed) { 21 | this(creature, speed, 7 * 20); 22 | } 23 | 24 | @Override 25 | public void startExecuting() { 26 | startTime = theCreature.ticksExisted; 27 | super.startExecuting(); 28 | } 29 | 30 | @Override 31 | public boolean continueExecuting() { 32 | if(isTimedOut()) { 33 | LOGGER.warn("Terminated runaway panic task of " + theCreature + " because it passed the timeout of " + maxDuration + " ticks"); 34 | } 35 | return super.continueExecuting() && !isTimedOut(); 36 | } 37 | 38 | private boolean isTimedOut() { 39 | return theCreature.ticksExisted >= startTime + maxDuration; 40 | } 41 | 42 | @Override 43 | public void resetTask() { 44 | if(isTimedOut()) { 45 | theCreature.getNavigator().clearPathEntity(); 46 | } 47 | super.resetTask(); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/client/render/ModelFox.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.client.render; 2 | 3 | import org.lwjgl.opengl.GL11; 4 | 5 | import makamys.dmod.entity.EntityFox; 6 | import net.minecraft.client.model.ModelBase; 7 | import net.minecraft.client.model.ModelRenderer; 8 | import net.minecraft.entity.Entity; 9 | import net.minecraft.entity.EntityLivingBase; 10 | import net.minecraft.util.MathHelper; 11 | 12 | public class ModelFox extends ModelBase 13 | { 14 | public ModelRenderer head; 15 | public ModelRenderer rightEar; 16 | public ModelRenderer leftEar; 17 | public ModelRenderer nose; 18 | public ModelRenderer torso; 19 | public ModelRenderer rightBackLeg; 20 | public ModelRenderer leftBackLeg; 21 | public ModelRenderer rightFrontLeg; 22 | public ModelRenderer leftFrontLeg; 23 | public ModelRenderer tail; 24 | private float legPitchModifier; 25 | 26 | private float partialTicks; 27 | 28 | public ModelFox(){ 29 | this.textureWidth = 48; 30 | this.textureHeight = 32; 31 | this.head = new ModelRenderer(this, 1, 5); 32 | this.head.addBox(-3.0F, -2.0F, -5.0F, 8, 6, 6, 0.0F); 33 | this.head.setRotationPoint(-1.0F, 16.5F, -3.0F); 34 | this.rightEar = new ModelRenderer(this, 8, 1); 35 | this.rightEar.addBox(-3.0F, -4.0F, -4.0F, 2, 2, 1, 0.0F); 36 | this.leftEar = new ModelRenderer(this, 15, 1); 37 | this.leftEar.addBox(3.0F, -4.0F, -4.0F, 2, 2, 1, 0.0F); 38 | this.nose = new ModelRenderer(this, 6, 18); 39 | this.nose.addBox(-1.0F, 2.01F, -8.0F, 4, 2, 3, 0.0F); 40 | this.head.addChild(this.rightEar); 41 | this.head.addChild(this.leftEar); 42 | this.head.addChild(this.nose); 43 | this.torso = new ModelRenderer(this, 24, 15); 44 | this.torso.addBox(-3.0F, 3.999F, -3.5F, 6, 11, 6, 0.0F); 45 | this.torso.setRotationPoint(0.0F, 16.0F, -6.0F); 46 | float f = 0.001F; 47 | this.rightBackLeg = new ModelRenderer(this, 13, 24); 48 | this.rightBackLeg.addBox(2.0F, 0.5F, -1.0F, 2, 6, 2, 0.001F); 49 | this.rightBackLeg.setRotationPoint(-5.0F, 17.5F, 7.0F); 50 | this.leftBackLeg = new ModelRenderer(this, 4, 24); 51 | this.leftBackLeg.addBox(2.0F, 0.5F, -1.0F, 2, 6, 2, 0.001F); 52 | this.leftBackLeg.setRotationPoint(-1.0F, 17.5F, 7.0F); 53 | this.rightFrontLeg = new ModelRenderer(this, 13, 24); 54 | this.rightFrontLeg.addBox(2.0F, 0.5F, -1.0F, 2, 6, 2, 0.001F); 55 | this.rightFrontLeg.setRotationPoint(-5.0F, 17.5F, 0.0F); 56 | this.leftFrontLeg = new ModelRenderer(this, 4, 24); 57 | this.leftFrontLeg.addBox(2.0F, 0.5F, -1.0F, 2, 6, 2, 0.001F); 58 | this.leftFrontLeg.setRotationPoint(-1.0F, 17.5F, 0.0F); 59 | this.tail = new ModelRenderer(this, 30, 0); 60 | this.tail.addBox(2.0F, 0.0F, -1.0F, 4, 9, 5, 0.0F); 61 | this.tail.setRotationPoint(-4.0F, 15.0F, -1.0F); 62 | this.torso.addChild(this.tail); 63 | } 64 | 65 | /** 66 | * Used for easily adding entity-dependent animations. The second and third float params here are the same second 67 | * and third as in the setRotationAngles method. 68 | */ 69 | public void setLivingAnimations(EntityLivingBase p_78086_1_, float f, float g, float h) 70 | { 71 | EntityFox foxEntity = (EntityFox)p_78086_1_; 72 | 73 | this.torso.rotateAngleX = 1.5707964F; 74 | this.tail.rotateAngleX = -0.05235988F; 75 | this.rightBackLeg.rotateAngleX = MathHelper.cos(f * 0.6662F) * 1.4F * g; 76 | this.leftBackLeg.rotateAngleX = MathHelper.cos(f * 0.6662F + 3.1415927F) * 1.4F * g; 77 | this.rightFrontLeg.rotateAngleX = MathHelper.cos(f * 0.6662F + 3.1415927F) * 1.4F * g; 78 | this.leftFrontLeg.rotateAngleX = MathHelper.cos(f * 0.6662F) * 1.4F * g; 79 | this.head.setRotationPoint(-1.0F, 16.5F, -3.0F); 80 | this.head.rotateAngleY = 0.0F; 81 | this.head.rotateAngleZ = foxEntity.getHeadRoll(h); 82 | this.rightBackLeg.showModel = true; 83 | this.leftBackLeg.showModel = true; 84 | this.rightFrontLeg.showModel = true; 85 | this.leftFrontLeg.showModel = true; 86 | this.torso.setRotationPoint(0.0F, 16.0F, -6.0F); 87 | this.torso.rotateAngleZ = 0.0F; 88 | this.rightBackLeg.setRotationPoint(-5.0F, 17.5F, 7.0F); 89 | this.leftBackLeg.setRotationPoint(-1.0F, 17.5F, 7.0F); 90 | if (foxEntity.isInSneakingPose()) { 91 | this.torso.rotateAngleX = 1.6755161F; 92 | float i = foxEntity.getBodyRotationHeightOffset(h); 93 | this.torso.setRotationPoint(0.0F, 16.0F + foxEntity.getBodyRotationHeightOffset(h), -6.0F); 94 | this.head.setRotationPoint(-1.0F, 16.5F + i, -3.0F); 95 | this.head.rotateAngleY = 0.0F; 96 | } else if (foxEntity.isPlayerSleeping()) { 97 | this.torso.rotateAngleZ = -1.5707964F; 98 | this.torso.setRotationPoint(0.0F, 21.0F, -6.0F); 99 | this.tail.rotateAngleX = -2.6179938F; 100 | if (this.isChild) { 101 | this.tail.rotateAngleX = -2.1816616F; 102 | this.torso.setRotationPoint(0.0F, 21.0F, -2.0F); 103 | } 104 | 105 | this.head.setRotationPoint(1.0F, 19.49F, -3.0F); 106 | this.head.rotateAngleX = 0.0F; 107 | this.head.rotateAngleY = -2.0943952F; 108 | this.head.rotateAngleZ = 0.0F; 109 | this.rightBackLeg.showModel = false; 110 | this.leftBackLeg.showModel = false; 111 | this.rightFrontLeg.showModel = false; 112 | this.leftFrontLeg.showModel = false; 113 | } else if (foxEntity.isSitting()) { 114 | this.torso.rotateAngleX = 0.5235988F; 115 | this.torso.setRotationPoint(0.0F, 9.0F, -3.0F); 116 | this.tail.rotateAngleX = 0.7853982F; 117 | this.tail.setRotationPoint(-4.0F, 15.0F, -2.0F); 118 | this.head.setRotationPoint(-1.0F, 10.0F, -0.25F); 119 | this.head.rotateAngleX = 0.0F; 120 | this.head.rotateAngleY = 0.0F; 121 | if (this.isChild) { 122 | this.head.setRotationPoint(-1.0F, 13.0F, -3.75F); 123 | } 124 | 125 | this.rightBackLeg.rotateAngleX = -1.3089969F; 126 | this.rightBackLeg.setRotationPoint(-5.0F, 21.5F, 6.75F); 127 | this.leftBackLeg.rotateAngleX = -1.3089969F; 128 | this.leftBackLeg.setRotationPoint(-1.0F, 21.5F, 6.75F); 129 | this.rightFrontLeg.rotateAngleX = -0.2617994F; 130 | this.leftFrontLeg.rotateAngleX = -0.2617994F; 131 | } 132 | 133 | this.partialTicks = h; 134 | } 135 | 136 | /** 137 | * Sets the models various rotation angles then renders the model. 138 | */ 139 | public void render(Entity p_78088_1_, float p_78088_2_, float p_78088_3_, float p_78088_4_, float p_78088_5_, float p_78088_6_, float p_78088_7_) 140 | { 141 | this.setRotationAngles(p_78088_2_, p_78088_3_, p_78088_4_, p_78088_5_, p_78088_6_, p_78088_7_, p_78088_1_); 142 | 143 | float childHeadYOffset = 8.0F; 144 | float childHeadZOffset = 3.35F; 145 | float invertedChildHeadScale = 2.0F; 146 | float invertedChildBodyScale = 2.0F; 147 | float childBodyYOffset = 24.0F; 148 | 149 | if (this.isChild) 150 | { 151 | GL11.glPushMatrix(); 152 | float g = 1.5F / invertedChildHeadScale; 153 | GL11.glScalef(g, g, g); 154 | GL11.glTranslatef(0.0F, childHeadYOffset / 16F, childHeadZOffset / 16F); 155 | this.head.render(p_78088_7_); 156 | GL11.glPopMatrix(); 157 | GL11.glPushMatrix(); 158 | g = 1.0F / invertedChildBodyScale; 159 | GL11.glScalef(g, g, g); 160 | GL11.glTranslatef(0.0F, childBodyYOffset / 16F, 0.0F); 161 | this.torso.render(p_78088_7_); 162 | this.rightBackLeg.render(p_78088_7_); 163 | this.leftBackLeg.render(p_78088_7_); 164 | this.rightFrontLeg.render(p_78088_7_); 165 | this.leftFrontLeg.render(p_78088_7_); 166 | GL11.glPopMatrix(); 167 | } 168 | else 169 | { 170 | this.head.render(p_78088_7_); 171 | this.torso.render(p_78088_7_); 172 | this.rightBackLeg.render(p_78088_7_); 173 | this.leftBackLeg.render(p_78088_7_); 174 | this.rightFrontLeg.render(p_78088_7_); 175 | this.leftFrontLeg.render(p_78088_7_); 176 | } 177 | } 178 | 179 | /** 180 | * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms 181 | * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how 182 | * "far" arms and legs can swing at most. 183 | */ 184 | public void setRotationAngles(float p_78087_1_, float p_78087_2_, float h, float i, float j, float p_78087_6_, Entity p_78087_7_) 185 | { 186 | EntityFox foxEntity = (EntityFox)p_78087_7_; 187 | 188 | if (!foxEntity.isPlayerSleeping() && !foxEntity.isWalking() && !foxEntity.isInSneakingPose()) { 189 | this.head.rotateAngleX = j * 0.017453292F; 190 | float swing = 0f; 191 | if(foxEntity.hasAbility(EntityFox.Ability.SWORD_SWING_ANIMATION)) { 192 | swing = foxEntity.getSwingProgress(partialTicks); 193 | if(swing != 0f) { 194 | if(foxEntity.finishedSwings % 2 == 0) { 195 | swing = 1f - swing; 196 | } 197 | swing = (swing / 2f - 1/4f); 198 | } 199 | } 200 | this.head.rotateAngleY = i * 0.017453292F + swing * ((float)Math.PI); 201 | } 202 | 203 | if (foxEntity.isPlayerSleeping()) { 204 | this.head.rotateAngleX = 0.0F; 205 | this.head.rotateAngleY = -2.0943952F; 206 | this.head.rotateAngleZ = MathHelper.cos(h * 0.027F) / 22.0F; 207 | } 208 | 209 | float l; 210 | if (foxEntity.isInSneakingPose()) { 211 | l = MathHelper.cos(h) * 0.01F; 212 | this.torso.rotateAngleY = l; 213 | this.rightBackLeg.rotateAngleZ = l; 214 | this.leftBackLeg.rotateAngleZ = l; 215 | this.rightFrontLeg.rotateAngleZ = l / 2.0F; 216 | this.leftFrontLeg.rotateAngleZ = l / 2.0F; 217 | } 218 | 219 | if (foxEntity.isWalking()) { 220 | l = 0.1F; 221 | this.legPitchModifier += 0.67F; 222 | this.rightBackLeg.rotateAngleX = MathHelper.cos(this.legPitchModifier * 0.4662F) * 0.1F; 223 | this.leftBackLeg.rotateAngleX = MathHelper.cos(this.legPitchModifier * 0.4662F + 3.1415927F) * 0.1F; 224 | this.rightFrontLeg.rotateAngleX = MathHelper.cos(this.legPitchModifier * 0.4662F + 3.1415927F) * 0.1F; 225 | this.leftFrontLeg.rotateAngleX = MathHelper.cos(this.legPitchModifier * 0.4662F) * 0.1F; 226 | } 227 | } 228 | } 229 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/client/render/RenderFox.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.client.render; 2 | 3 | import org.lwjgl.opengl.GL11; 4 | 5 | import makamys.dmod.entity.EntityFox; 6 | import makamys.dmod.future.util.MathHelperFuture; 7 | import net.minecraft.block.Block; 8 | import net.minecraft.client.model.ModelBase; 9 | import net.minecraft.client.renderer.RenderBlocks; 10 | import net.minecraft.client.renderer.entity.RenderLiving; 11 | import net.minecraft.entity.Entity; 12 | import net.minecraft.entity.EntityLivingBase; 13 | import net.minecraft.item.ItemBlock; 14 | import net.minecraft.item.ItemStack; 15 | import net.minecraft.item.ItemSword; 16 | import net.minecraft.util.ResourceLocation; 17 | 18 | public class RenderFox extends RenderLiving 19 | { 20 | private static final ResourceLocation texture = new ResourceLocation("textures/entity/fox/fox.png"); 21 | private static final ResourceLocation sleepingTexture = new ResourceLocation("textures/entity/fox/fox_sleep.png"); 22 | private static final ResourceLocation snowTexture = new ResourceLocation("textures/entity/fox/snow_fox.png"); 23 | private static final ResourceLocation sleepingSnowTexture = new ResourceLocation("textures/entity/fox/snow_fox_sleep.png"); 24 | 25 | public RenderFox(ModelBase p_i1252_1_, float p_i1252_2_) 26 | { 27 | super(p_i1252_1_, p_i1252_2_); 28 | } 29 | 30 | /** 31 | * Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture. 32 | */ 33 | protected ResourceLocation getEntityTexture(EntityFox foxEntity) 34 | { 35 | if (foxEntity.getFoxType() == EntityFox.Type.RED) { 36 | return foxEntity.isPlayerSleeping() ? sleepingTexture : texture; 37 | } else { 38 | return foxEntity.isPlayerSleeping() ? sleepingSnowTexture : snowTexture; 39 | } 40 | } 41 | 42 | /** 43 | * Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture. 44 | */ 45 | protected ResourceLocation getEntityTexture(Entity p_110775_1_) 46 | { 47 | return this.getEntityTexture((EntityFox)p_110775_1_); 48 | } 49 | 50 | // what the heck are these MCP names 51 | protected void rotateCorpse(EntityFox foxEntity, float animationProgress, float bodyYaw, float tickDelta) { 52 | super.rotateCorpse(foxEntity, animationProgress, bodyYaw, tickDelta); 53 | if (foxEntity.isChasing() || foxEntity.isWalking()) { 54 | float i = -MathHelperFuture.lerp(tickDelta, foxEntity.prevRotationPitch, foxEntity.rotationPitch); 55 | GL11.glRotatef(i, 1f, 0f, 0f); 56 | } 57 | } 58 | 59 | @Override 60 | protected void rotateCorpse(EntityLivingBase entity, float animationProgress, float bodyYaw, float tickDelta) { 61 | rotateCorpse((EntityFox)entity, animationProgress, bodyYaw, tickDelta); 62 | } 63 | 64 | protected void renderEquippedItems(EntityLivingBase p_77029_1_, float p_77029_2_) 65 | { 66 | this.renderEquippedItems((EntityFox)p_77029_1_, p_77029_2_); 67 | } 68 | 69 | protected void renderEquippedItems(EntityFox p_77029_1_, float p_77029_2_) 70 | { 71 | GL11.glColor3f(1.0F, 1.0F, 1.0F); 72 | super.renderEquippedItems(p_77029_1_, p_77029_2_); 73 | ItemStack itemstack = p_77029_1_.getHeldItem(); 74 | 75 | if (itemstack != null) 76 | { 77 | GL11.glPushMatrix(); 78 | float f1; 79 | 80 | if(this.mainModel.isChild) { 81 | GL11.glScalef(0.75F, 0.75F, 0.75F); 82 | GL11.glTranslatef(0.0f, 0.5f, 0.20937499403953552f); 83 | } 84 | 85 | ModelFox mf = (ModelFox)mainModel; 86 | GL11.glTranslatef(mf.head.rotationPointX/16f, mf.head.rotationPointY/16f, mf.head.rotationPointZ/16f); 87 | 88 | GL11.glRotatef((float)Math.toDegrees(mf.head.rotateAngleY), 0f, 1f, 0f); 89 | GL11.glRotatef((float)Math.toDegrees(mf.head.rotateAngleX), 1f, 0f, 0f); 90 | 91 | GL11.glTranslatef(0f, 0.3f, -0.35f); 92 | 93 | if (itemstack.getItem() instanceof ItemBlock && RenderBlocks.renderItemIn3d(Block.getBlockFromItem(itemstack.getItem()).getRenderType())) 94 | { 95 | f1 = 0.5F; 96 | GL11.glTranslatef(0.0F, 0.1875F, -0.3125F); 97 | f1 *= 0.45F; 98 | 99 | GL11.glScalef(f1, -f1, f1); 100 | GL11.glTranslatef(0.3f, 1f, 1.5f); 101 | } 102 | else { 103 | if (p_77029_1_.hasAbility(EntityFox.Ability.IMPROVED_HELD_ITEM_RENDERING) 104 | && itemstack.getItem().isFull3D()) 105 | { 106 | f1 = 0.625F * 0.7f; 107 | 108 | if (itemstack.getItem().shouldRotateAroundWhenRendering()) 109 | { 110 | GL11.glRotatef(180.0F, 0.0F, 0.0F, 1.0F); 111 | GL11.glTranslatef(0.0F, -0.125F, 0.0F); 112 | } 113 | 114 | GL11.glTranslatef(0.02f + (itemstack.getItem() instanceof ItemSword ? 0f : 0.32f), 0.0f, 0f); 115 | GL11.glScalef(f1, -f1, f1); 116 | float swing = 0f; 117 | if(p_77029_1_.hasAbility(EntityFox.Ability.SWORD_SWING_ANIMATION)) { 118 | swing = p_77029_1_.getSwingProgress(p_77029_2_); 119 | if(p_77029_1_.finishedSwings % 2 == 1) { 120 | swing = 1f - swing; 121 | } 122 | } 123 | GL11.glRotatef(-swing*180f, 0.0F, 1.0F, 0.0F); 124 | } 125 | else 126 | { 127 | f1 = 0.335F; 128 | GL11.glScalef(f1, f1, f1); 129 | GL11.glTranslatef(0.72f,-0.15f,-0.45f); 130 | GL11.glRotatef(-45.0F + 90f, 0.0F, 1.0F, 0.0F); 131 | } 132 | GL11.glRotatef(-45F, 0.0F, 1.0F, 0.0F); 133 | 134 | GL11.glRotatef(90F, 1.0F, 0.0F, 0.0F); 135 | 136 | // undo renderItem's rotation 137 | 138 | GL11.glRotatef(-335.0F, 0.0F, 0.0F, 1.0F); 139 | GL11.glRotatef(-50.0F, 0.0F, 1.0F, 0.0F); 140 | } 141 | 142 | 143 | if (itemstack.getItem().requiresMultipleRenderPasses()) 144 | { 145 | for (int k = 0; k < itemstack.getItem().getRenderPasses(itemstack.getItemDamage()); ++k) 146 | { 147 | int i = itemstack.getItem().getColorFromItemStack(itemstack, k); 148 | float f12 = (float)(i >> 16 & 255) / 255.0F; 149 | float f3 = (float)(i >> 8 & 255) / 255.0F; 150 | float f4 = (float)(i & 255) / 255.0F; 151 | GL11.glColor4f(f12, f3, f4, 1.0F); 152 | this.renderManager.itemRenderer.renderItem(p_77029_1_, itemstack, k); 153 | } 154 | } 155 | else 156 | { 157 | int k = itemstack.getItem().getColorFromItemStack(itemstack, 0); 158 | float f11 = (float)(k >> 16 & 255) / 255.0F; 159 | float f12 = (float)(k >> 8 & 255) / 255.0F; 160 | float f3 = (float)(k & 255) / 255.0F; 161 | GL11.glColor4f(f11, f12, f3, 1.0F); 162 | this.renderManager.itemRenderer.renderItem(p_77029_1_, itemstack, 0); 163 | } 164 | 165 | GL11.glPopMatrix(); 166 | } 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/client/tooltip/BundleTooltipHandler.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.client.tooltip; 2 | 3 | import static makamys.dmod.DModConstants.MODID; 4 | 5 | import java.awt.Dimension; 6 | import java.util.List; 7 | 8 | import org.lwjgl.opengl.GL11; 9 | import org.lwjgl.opengl.GL12; 10 | 11 | import codechicken.lib.gui.GuiDraw; 12 | import codechicken.lib.gui.GuiDraw.ITooltipLineHandler; 13 | import codechicken.nei.guihook.GuiContainerManager; 14 | import cpw.mods.fml.relauncher.Side; 15 | import cpw.mods.fml.relauncher.SideOnly; 16 | import makamys.dmod.ConfigDMod; 17 | import net.minecraft.client.gui.FontRenderer; 18 | import net.minecraft.client.renderer.RenderHelper; 19 | import net.minecraft.client.renderer.entity.RenderItem; 20 | import net.minecraft.client.renderer.texture.TextureManager; 21 | import net.minecraft.item.ItemStack; 22 | import net.minecraft.util.ResourceLocation; 23 | 24 | public class BundleTooltipHandler implements ITooltipLineHandler { 25 | 26 | public static final ResourceLocation TEXTURE = new ResourceLocation(MODID, "textures/gui/container/bundle.png"); 27 | private static int field_32381 = 4; 28 | private static int field_32382 = 1; 29 | private static int field_32383 = 128; 30 | private static int SLOT_WIDTH = 18; 31 | private static int SLOT_HEIGHT = 20; 32 | 33 | private List inventory; 34 | private int occupancy; 35 | 36 | private static Sprites sprites = new Sprites(); 37 | 38 | public BundleTooltipHandler(List stacks, int slots) { 39 | this.inventory = stacks; 40 | this.occupancy = slots; 41 | 42 | int newSlotHeight = ConfigDMod.compactBundleGUI ? 18 : 20; 43 | if(newSlotHeight != SLOT_HEIGHT) { 44 | SLOT_HEIGHT = newSlotHeight; 45 | sprites = new Sprites(); 46 | } 47 | } 48 | 49 | @Override 50 | public Dimension getSize() { 51 | return new Dimension(this.getColumns() * 18 + 2, this.getRows() * SLOT_HEIGHT + 2 + 4 52 | + (ConfigDMod.compactBundleGUI ? 1 : 0)); 53 | } 54 | 55 | @Override 56 | public void draw(int x, int y) { 57 | int i = this.getColumns(); 58 | int j = this.getRows(); 59 | boolean bl = this.occupancy >= 64; 60 | int k = 0; 61 | 62 | GL11.glEnable(GL12.GL_RESCALE_NORMAL); 63 | RenderHelper.enableGUIStandardItemLighting(); 64 | GuiContainerManager.enable2DRender(); 65 | 66 | for (int l = 0; l < j; ++l) { 67 | for (int m = 0; m < i; ++m) { 68 | int n = x + m * 18 + 1; 69 | int o = y + l * SLOT_HEIGHT + 1; 70 | this.drawSlot(n, o, k++, bl, GuiDraw.fontRenderer, GuiContainerManager.drawItems, GuiDraw.renderEngine); 71 | } 72 | } 73 | 74 | this.drawOutline(x, y, i, j, GuiDraw.renderEngine); 75 | 76 | GL11.glDisable(GL12.GL_RESCALE_NORMAL); 77 | RenderHelper.disableStandardItemLighting(); 78 | } 79 | 80 | private void drawSlot(int x, int y, int index, boolean shouldBlock, FontRenderer textRenderer, 81 | RenderItem itemRenderer, TextureManager textureManager) { 82 | if (index >= this.inventory.size()) { 83 | this.draw(x, y, textureManager, 84 | shouldBlock ? sprites.BLOCKED_SLOT : sprites.SLOT); 85 | } else { 86 | ItemStack itemStack = (ItemStack) this.inventory.get(index); 87 | this.draw(x, y, textureManager, sprites.SLOT); 88 | GuiContainerManager.drawItems.zLevel += 250f; 89 | GuiContainerManager.drawItem(x + 1, y + 1, itemStack); 90 | GuiContainerManager.drawItems.zLevel -= 250f; 91 | if (index == 0) { 92 | GuiDraw.drawRect(x + 1, y + 1, 16, 16, 0x80FFFFFF);//highlight 93 | } 94 | } 95 | } 96 | 97 | private void drawOutline(int x, int y, int columns, int rows, 98 | TextureManager textureManager) { 99 | this.draw(x, y, textureManager, sprites.BORDER_CORNER_TOP); 100 | this.draw(x + columns * 18 + 1, y, textureManager, 101 | sprites.BORDER_CORNER_TOP); 102 | 103 | int bottomOff = ConfigDMod.compactBundleGUI ? 1 : 0; 104 | 105 | int j; 106 | for (j = 0; j < columns; ++j) { 107 | this.draw(x + 1 + j * 18, y, textureManager, 108 | sprites.BORDER_HORIZONTAL_TOP); 109 | this.draw(x + 1 + j * 18, y + rows * SLOT_HEIGHT + bottomOff, textureManager, 110 | sprites.BORDER_HORIZONTAL_BOTTOM); 111 | } 112 | 113 | for (j = 0; j < rows; ++j) { 114 | this.draw(x, y + j * SLOT_HEIGHT + 1, textureManager, sprites.BORDER_VERTICAL); 115 | this.draw(x + columns * 18 + 1, y + j * SLOT_HEIGHT + 1, textureManager, 116 | sprites.BORDER_VERTICAL); 117 | } 118 | 119 | this.draw(x, y + rows * SLOT_HEIGHT + bottomOff, textureManager, sprites.BORDER_CORNER_BOTTOM); 120 | this.draw(x + columns * 18 + 1, y + rows * SLOT_HEIGHT + bottomOff, textureManager, 121 | sprites.BORDER_CORNER_BOTTOM); 122 | } 123 | 124 | private void draw(int x, int y, TextureManager textureManager, 125 | Sprite sprite) { 126 | GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); 127 | GuiDraw.changeTexture(TEXTURE); 128 | GuiDraw.drawTexturedModalRect(x, y, sprite.u, sprite.v, sprite.width, sprite.height); 129 | } 130 | 131 | private int getColumns() { 132 | return Math.max(2, (int) Math.ceil(Math.sqrt((double) this.inventory.size() + 1.0D))); 133 | } 134 | 135 | private int getRows() { 136 | return (int) Math.ceil(((double) this.inventory.size() + 1.0D) / (double) this.getColumns()); 137 | } 138 | 139 | private static class Sprites { 140 | public Sprite 141 | SLOT = new Sprite(0, 0, 18, SLOT_HEIGHT), 142 | BLOCKED_SLOT = new Sprite(0, 40, 18, SLOT_HEIGHT), 143 | BORDER_VERTICAL = new Sprite(0, 18, 1, SLOT_HEIGHT), 144 | BORDER_HORIZONTAL_TOP = new Sprite(0, SLOT_HEIGHT, 18, 1), 145 | BORDER_HORIZONTAL_BOTTOM = new Sprite(0, 60, 18, 1), 146 | BORDER_CORNER_TOP = new Sprite(0, SLOT_HEIGHT, 1, 1), 147 | BORDER_CORNER_BOTTOM = new Sprite(0, 60, 1, 1); 148 | } 149 | 150 | @SideOnly(Side.CLIENT) 151 | private static class Sprite { 152 | public int u; 153 | public int v; 154 | public int width; 155 | public int height; 156 | 157 | private Sprite(int u, int v, int width, int height) { 158 | this.u = u; 159 | this.v = v; 160 | this.width = width; 161 | this.height = height; 162 | } 163 | } 164 | 165 | } 166 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/client/tooltip/DTooltipHandler.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.client.tooltip; 2 | 3 | import java.util.List; 4 | import java.util.stream.Collectors; 5 | 6 | import codechicken.lib.gui.GuiDraw; 7 | import codechicken.nei.guihook.IContainerTooltipHandler; 8 | import makamys.dmod.future.item.ItemFuture; 9 | import net.minecraft.client.gui.inventory.GuiContainer; 10 | import net.minecraft.item.ItemStack; 11 | 12 | public class DTooltipHandler implements IContainerTooltipHandler { 13 | 14 | @Override 15 | public List handleTooltip(GuiContainer gui, int mousex, int mousey, List currenttip) { 16 | return currenttip; 17 | } 18 | 19 | @Override 20 | public List handleItemDisplayName(GuiContainer gui, ItemStack itemstack, List currenttip) { 21 | return currenttip; 22 | } 23 | 24 | @Override 25 | public List handleItemTooltip(GuiContainer gui, ItemStack itemstack, int mousex, int mousey, 26 | List currenttip) { 27 | if(itemstack != null && itemstack.getItem() instanceof ItemFuture) { 28 | List strings = ((ItemFuture)itemstack.getItem()).getTooltipHandlers(itemstack).stream().map(handler -> GuiDraw.TOOLTIP_HANDLER + GuiDraw.getTipLineId(handler)).collect(Collectors.toList()); 29 | currenttip.addAll(1, strings); 30 | } 31 | return currenttip; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/compat/Compat.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.compat; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import cpw.mods.fml.common.Loader; 7 | import cpw.mods.fml.common.registry.GameRegistry; 8 | import ganymedes01.etfuturum.blocks.BlockBerryBush; 9 | import net.minecraft.block.Block; 10 | import net.minecraft.item.Item; 11 | import net.minecraft.util.DamageSource; 12 | import net.minecraft.world.World; 13 | 14 | public class Compat { 15 | 16 | private static List berryBushHandlers = new ArrayList<>(); 17 | 18 | public static void init() { 19 | if(Loader.isModLoaded("etfuturum")) { 20 | registerBerryBushHandler(new EtFuturumBerryBushHandler()); 21 | } 22 | } 23 | 24 | public static void registerBerryBushHandler(IBerryBushHandler bbh) { 25 | berryBushHandlers.add(bbh); 26 | } 27 | 28 | public static BerryBushState getBerryBushState(World world, int x, int y, int z) { 29 | for(IBerryBushHandler bbh : berryBushHandlers) { 30 | if(bbh.isBerryBush(world, x, y, z)) { 31 | return new BerryBushState(world, x, y, z, bbh); 32 | } 33 | } 34 | return null; 35 | } 36 | 37 | public static boolean isBerryBushDamageSource(DamageSource source) { 38 | return berryBushHandlers.stream().anyMatch(bbh -> bbh.isBerryBushDamageSource(source)); 39 | } 40 | 41 | public static class BerryBushState { 42 | public World world; 43 | public int x; 44 | public int y; 45 | public int z; 46 | public IBerryBushHandler handler; 47 | 48 | public BerryBushState(World world, int x, int y, int z, IBerryBushHandler bbh) { 49 | this.world = world; 50 | this.x = x; 51 | this.y = y; 52 | this.z = z; 53 | this.handler = bbh; 54 | } 55 | 56 | public int getAge() { 57 | return handler.getBerryBushAge(world, x, y, z); 58 | } 59 | 60 | public int getMetaForNewAge(int newAge) { 61 | return handler.getMetaForNewAge(world, x, y, z, newAge); 62 | } 63 | } 64 | 65 | static class EtFuturumBerryBushHandler implements IBerryBushHandler { 66 | 67 | private final Block sweetBerryBush; 68 | private final Item sweetBerry; 69 | 70 | public EtFuturumBerryBushHandler() { 71 | sweetBerryBush = GameRegistry.findBlock("etfuturum", "sweet_berry_bush"); 72 | sweetBerry = GameRegistry.findItem("etfuturum", "sweet_berries"); 73 | } 74 | 75 | @Override 76 | public boolean isBerryBush(World world, int x, int y, int z) { 77 | return world.getBlock(x, y, z) == sweetBerryBush; 78 | } 79 | 80 | @Override 81 | public int getBerryBushAge(World world, int x, int y, int z) { 82 | return world.getBlockMetadata(x, y, z); 83 | } 84 | 85 | @Override 86 | public int getMetaForNewAge(World world, int x, int y, int z, int newAge) { 87 | return newAge; 88 | } 89 | 90 | @Override 91 | public Item getSweetBerryItem() { 92 | return sweetBerry; 93 | } 94 | 95 | @Override 96 | public boolean isBerryBushDamageSource(DamageSource source) { 97 | return source == BlockBerryBush.SWEET_BERRY_BUSH; 98 | } 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/compat/IBerryBushHandler.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.compat; 2 | 3 | import net.minecraft.item.Item; 4 | import net.minecraft.util.DamageSource; 5 | import net.minecraft.world.World; 6 | 7 | public interface IBerryBushHandler { 8 | 9 | public boolean isBerryBush(World world, int x, int y, int z); 10 | public int getBerryBushAge(World world, int x, int y, int z); 11 | public int getMetaForNewAge(World world, int x, int y, int z, int newAge); 12 | public Item getSweetBerryItem(); 13 | public boolean isBerryBushDamageSource(DamageSource source); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/compat/NEICompat.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.compat; 2 | 3 | import codechicken.nei.guihook.GuiContainerManager; 4 | import makamys.dmod.client.tooltip.DTooltipHandler; 5 | 6 | public class NEICompat { 7 | 8 | public static void init() { 9 | GuiContainerManager.addTooltipHandler(new DTooltipHandler()); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/constants/AIMutex.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.constants; 2 | 3 | public class AIMutex { 4 | public static final byte MOVE = 1; 5 | public static final byte LOOK = 2; 6 | public static final byte JUMP = 4; 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/constants/NBTType.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.constants; 2 | 3 | public class NBTType { 4 | 5 | public static final byte STRING = 8; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/entity/ITameable.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.entity; 2 | 3 | import net.minecraft.entity.EntityLivingBase; 4 | 5 | public interface ITameable { 6 | 7 | public EntityLivingBase getPetOwner(); 8 | 9 | public default boolean isPetSitting() { 10 | return false; 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/etfuturum/BlockPos.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.etfuturum; 2 | 3 | import net.minecraft.entity.Entity; 4 | import net.minecraft.util.EnumFacing; 5 | import net.minecraft.util.Vec3; 6 | 7 | public class BlockPos extends Vec3i { 8 | 9 | public static final BlockPos ORIGIN = new BlockPos(0, 0, 0); 10 | 11 | private static final int NUM_X_BITS = 26; 12 | private static final int NUM_Z_BITS = NUM_X_BITS; 13 | private static final int NUM_Y_BITS = 64 - NUM_X_BITS - NUM_Z_BITS; 14 | private static final int Y_SHIFT = 0 + NUM_Z_BITS; 15 | private static final int X_SHIFT = Y_SHIFT + NUM_Y_BITS; 16 | private static final long X_MASK = (1L << NUM_X_BITS) - 1L; 17 | private static final long Y_MASK = (1L << NUM_Y_BITS) - 1L; 18 | private static final long Z_MASK = (1L << NUM_Z_BITS) - 1L; 19 | 20 | public BlockPos(int x, int y, int z) { 21 | super(x, y, z); 22 | } 23 | 24 | public BlockPos(double x, double y, double z) { 25 | super(x, y, z); 26 | } 27 | 28 | public BlockPos(Entity source) { 29 | this(source.posX, source.posY, source.posZ); 30 | } 31 | 32 | public BlockPos(Vec3 source) { 33 | this(source.xCoord, source.yCoord, source.zCoord); 34 | } 35 | 36 | public BlockPos(Vec3i source) { 37 | this(source.getX(), source.getY(), source.getZ()); 38 | } 39 | 40 | public BlockPos add(double x, double y, double z) { 41 | return new BlockPos(getX() + x, getY() + y, getZ() + z); 42 | } 43 | 44 | public BlockPos add(int x, int y, int z) { 45 | return new BlockPos(getX() + x, getY() + y, getZ() + z); 46 | } 47 | 48 | public BlockPos add(Vec3i vec) { 49 | return new BlockPos(getX() + vec.getX(), getY() + vec.getY(), getZ() + vec.getZ()); 50 | } 51 | 52 | public BlockPos multiply(int factor) { 53 | return new BlockPos(getX() * factor, getY() * factor, getZ() * factor); 54 | } 55 | 56 | public BlockPos up() { 57 | return this.up(1); 58 | } 59 | 60 | public BlockPos subtract(Vec3i vec) { 61 | return new BlockPos(getX() - vec.getX(), getY() - vec.getY(), getZ() - vec.getZ()); 62 | } 63 | 64 | public BlockPos up(int n) { 65 | return this.offset(EnumFacing.UP, n); 66 | } 67 | 68 | public BlockPos down() { 69 | return this.down(1); 70 | } 71 | 72 | public BlockPos down(int n) { 73 | return this.offset(EnumFacing.DOWN, n); 74 | } 75 | 76 | public BlockPos north() { 77 | return this.north(1); 78 | } 79 | 80 | public BlockPos north(int n) { 81 | return this.offset(EnumFacing.NORTH, n); 82 | } 83 | 84 | public BlockPos south() { 85 | return this.south(1); 86 | } 87 | 88 | public BlockPos south(int n) { 89 | return this.offset(EnumFacing.SOUTH, n); 90 | } 91 | 92 | public BlockPos west() { 93 | return this.west(1); 94 | } 95 | 96 | public BlockPos west(int n) { 97 | return this.offset(EnumFacing.WEST, n); 98 | } 99 | 100 | public BlockPos east() { 101 | return this.east(1); 102 | } 103 | 104 | public BlockPos east(int n) { 105 | return this.offset(EnumFacing.EAST, n); 106 | } 107 | 108 | public BlockPos offset(EnumFacing facing) { 109 | return this.offset(facing, 1); 110 | } 111 | 112 | public BlockPos offset(EnumFacing facing, int n) { 113 | return new BlockPos(getX() + facing.getFrontOffsetX() * n, getY() + facing.getFrontOffsetY() * n, getZ() + facing.getFrontOffsetZ() * n); 114 | } 115 | 116 | public BlockPos crossProductBP(Vec3i vec) { 117 | return new BlockPos(getY() * vec.getZ() - getZ() * vec.getY(), getZ() * vec.getX() - getX() * vec.getZ(), getX() * vec.getY() - getY() * vec.getX()); 118 | } 119 | 120 | public long toLong() { 121 | return (getX() & X_MASK) << X_SHIFT | (getY() & Y_MASK) << Y_SHIFT | (getZ() & Z_MASK) << 0; 122 | } 123 | 124 | public static BlockPos fromLong(long serialized) { 125 | int j = (int) (serialized << 64 - X_SHIFT - NUM_X_BITS >> 64 - NUM_X_BITS); 126 | int k = (int) (serialized << 64 - Y_SHIFT - NUM_Y_BITS >> 64 - NUM_Y_BITS); 127 | int l = (int) (serialized << 64 - NUM_Z_BITS >> 64 - NUM_Z_BITS); 128 | return new BlockPos(j, k, l); 129 | } 130 | 131 | @Override 132 | public Vec3i crossProduct(Vec3i vec) { 133 | return crossProductBP(vec); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/etfuturum/Vec3i.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.etfuturum; 2 | 3 | import com.google.common.base.Objects; 4 | 5 | import net.minecraft.util.MathHelper; 6 | 7 | public class Vec3i implements Comparable { 8 | 9 | private final int x, y, z; 10 | 11 | public Vec3i(int xIn, int yIn, int zIn) { 12 | x = xIn; 13 | y = yIn; 14 | z = zIn; 15 | } 16 | 17 | public Vec3i(double xIn, double yIn, double zIn) { 18 | this(MathHelper.floor_double(xIn), MathHelper.floor_double(yIn), MathHelper.floor_double(zIn)); 19 | } 20 | 21 | @Override 22 | public boolean equals(Object p_equals_1_) { 23 | if (this == p_equals_1_) 24 | return true; 25 | else if (!(p_equals_1_ instanceof Vec3i)) 26 | return false; 27 | else { 28 | Vec3i vec3i = (Vec3i) p_equals_1_; 29 | return getX() != vec3i.getX() ? false : getY() != vec3i.getY() ? false : getZ() == vec3i.getZ(); 30 | } 31 | } 32 | 33 | @Override 34 | public int hashCode() { 35 | return (getY() + getZ() * 31) * 31 + getX(); 36 | } 37 | 38 | @Override 39 | public int compareTo(Vec3i vec) { 40 | return getY() == vec.getY() ? getZ() == vec.getZ() ? getX() - vec.getX() : getZ() - vec.getZ() : getY() - vec.getY(); 41 | } 42 | 43 | public int getX() { 44 | return x; 45 | } 46 | 47 | public int getY() { 48 | return y; 49 | } 50 | 51 | public int getZ() { 52 | return z; 53 | } 54 | 55 | public Vec3i crossProduct(Vec3i vec) { 56 | return new Vec3i(getY() * vec.getZ() - getZ() * vec.getY(), getZ() * vec.getX() - getX() * vec.getZ(), getX() * vec.getY() - getY() * vec.getX()); 57 | } 58 | 59 | public double distanceSq(double toX, double toY, double toZ) { 60 | double d3 = getX() - toX; 61 | double d4 = getY() - toY; 62 | double d5 = getZ() - toZ; 63 | return d3 * d3 + d4 * d4 + d5 * d5; 64 | } 65 | 66 | public double distanceSqToCenter(double xIn, double yIn, double zIn) { 67 | double d3 = getX() + 0.5D - xIn; 68 | double d4 = getY() + 0.5D - yIn; 69 | double d5 = getZ() + 0.5D - zIn; 70 | return d3 * d3 + d4 * d4 + d5 * d5; 71 | } 72 | 73 | public double distanceSq(Vec3i to) { 74 | return this.distanceSq(to.getX(), to.getY(), to.getZ()); 75 | } 76 | 77 | @Override 78 | public String toString() { 79 | return Objects.toStringHelper(this).add("x", getX()).add("y", getY()).add("z", getZ()).toString(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/future/entity/EntityFuture.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.future.entity; 2 | 3 | import net.minecraft.entity.Entity; 4 | import net.minecraft.util.MathHelper; 5 | import net.minecraft.util.Vec3; 6 | 7 | public class EntityFuture { 8 | 9 | public static Vec3 getRotationVector(Entity dis) { 10 | return getRotationVector(dis.rotationPitch, dis.rotationYaw); 11 | } 12 | 13 | protected static final Vec3 getRotationVector(float pitch, float yaw) { 14 | float f = pitch * 0.017453292F; 15 | float g = -yaw * 0.017453292F; 16 | float h = MathHelper.cos(g); 17 | float i = MathHelper.sin(g); 18 | float j = MathHelper.cos(f); 19 | float k = MathHelper.sin(f); 20 | return Vec3.createVectorHelper((double)(i * j), (double)(-k), (double)(h * j)); 21 | } 22 | 23 | public static int getHorizontalFacing(Entity entity) { 24 | return (MathHelper.floor_double((double)(entity.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3) % 4; 25 | } 26 | 27 | public static int getMovementDirection(Entity entity) { 28 | // in vanilla 1.16.5 this is only implemented differently for boats and minecarts 29 | return getHorizontalFacing(entity); 30 | } 31 | 32 | public static Vec3 getVelocity(Entity dis) { 33 | return Vec3.createVectorHelper(dis.motionX, dis.motionY, dis.motionZ); 34 | } 35 | 36 | public static void setVelocity(Entity dis, Vec3 vel) { 37 | dis.motionX = vel.xCoord; 38 | dis.motionY = vel.yCoord; 39 | dis.motionZ = vel.zCoord; 40 | } 41 | 42 | public static double squaredHorizontalLength(Vec3 vector) { 43 | return vector.xCoord * vector.xCoord + vector.zCoord * vector.zCoord; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/future/entity/EntityLivingFuture.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.future.entity; 2 | 3 | import makamys.dmod.future.entity.passive.EntityAnimalFuture; 4 | import makamys.dmod.future.item.ItemStackFuture; 5 | import net.minecraft.entity.EntityLivingBase; 6 | import net.minecraft.entity.player.EntityPlayer; 7 | import net.minecraft.item.Item; 8 | import net.minecraft.item.ItemFood; 9 | import net.minecraft.item.ItemStack; 10 | import net.minecraft.potion.PotionEffect; 11 | import net.minecraft.world.World; 12 | 13 | public class EntityLivingFuture { 14 | public static ItemStack eatFood(EntityLivingBase dis, World world, ItemStack stack) { 15 | if(dis instanceof EntityAnimalFuture) { 16 | return ((EntityAnimalFuture)dis).eatFood(world, stack); 17 | } else { 18 | return eatFoodBody(dis, world, stack); 19 | } 20 | } 21 | 22 | public static ItemStack eatFoodBody(EntityLivingBase dis, World world, ItemStack stack) { 23 | if (stack.getItem() instanceof ItemFood) { 24 | world.playSound(dis.posX, dis.posY, dis.posZ, ((EntityLivingFutured)dis).getEatSound(stack), 1.0F, 1.0F + (world.rand.nextFloat() - world.rand.nextFloat()) * 0.4F, false); 25 | EntityLivingFuture.applyFoodEffects(dis, stack, world, dis); 26 | if (!(dis instanceof EntityPlayer) || !((EntityPlayer) dis).capabilities.isCreativeMode) { 27 | ItemStackFuture.decrement(stack, 1); 28 | } 29 | } 30 | return stack; 31 | } 32 | 33 | public static void applyFoodEffects(EntityLivingBase dis, ItemStack stack, World world, EntityLivingBase targetEntity) { 34 | Item item = stack.getItem(); 35 | if (item instanceof ItemFood) { 36 | ItemFood food = (ItemFood)item; 37 | if (!world.isRemote && food.potionId > 0 && world.rand.nextFloat() < food.potionEffectProbability) 38 | { 39 | dis.addPotionEffect(new PotionEffect(food.potionId, food.potionDuration * 20, food.potionAmplifier)); 40 | } 41 | } 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/future/entity/EntityLivingFutured.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.future.entity; 2 | 3 | import net.minecraft.item.ItemStack; 4 | 5 | public interface EntityLivingFutured { 6 | public String getEatSound(ItemStack stack); 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/future/entity/ai/EntityAIAttackOnCollideFuture.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.future.entity.ai; 2 | 3 | import net.minecraft.entity.EntityCreature; 4 | import net.minecraft.entity.EntityLivingBase; 5 | import net.minecraft.entity.ai.EntityAIBase; 6 | import net.minecraft.pathfinding.PathEntity; 7 | import net.minecraft.pathfinding.PathPoint; 8 | import net.minecraft.util.MathHelper; 9 | import net.minecraft.world.World; 10 | 11 | public class EntityAIAttackOnCollideFuture extends EntityAIBase 12 | { 13 | World worldObj; 14 | protected EntityCreature attacker; 15 | /** An amount of decrementing ticks that allows the entity to attack once the tick reaches 0. */ 16 | int attackTick; 17 | /** The speed with which the mob will approach the target */ 18 | double speedTowardsTarget; 19 | /** When true, the mob will continue chasing its target, even if it can't find a path to them right now. */ 20 | boolean longMemory; 21 | /** The PathEntity of our entity. */ 22 | PathEntity entityPathEntity; 23 | Class classTarget; 24 | private int field_75445_i; 25 | private double field_151497_i; 26 | private double field_151495_j; 27 | private double field_151496_k; 28 | private static final String __OBFID = "CL_00001595"; 29 | 30 | private int failedPathFindingPenalty; 31 | 32 | public EntityAIAttackOnCollideFuture(EntityCreature p_i1635_1_, Class p_i1635_2_, double p_i1635_3_, boolean p_i1635_5_) 33 | { 34 | this(p_i1635_1_, p_i1635_3_, p_i1635_5_); 35 | this.classTarget = p_i1635_2_; 36 | } 37 | 38 | public EntityAIAttackOnCollideFuture(EntityCreature p_i1636_1_, double p_i1636_2_, boolean p_i1636_4_) 39 | { 40 | this.attacker = p_i1636_1_; 41 | this.worldObj = p_i1636_1_.worldObj; 42 | this.speedTowardsTarget = p_i1636_2_; 43 | this.longMemory = p_i1636_4_; 44 | this.setMutexBits(3); 45 | } 46 | 47 | /** 48 | * Returns whether the EntityAIBase should begin execution. 49 | */ 50 | public boolean shouldExecute() 51 | { 52 | EntityLivingBase entitylivingbase = this.attacker.getAttackTarget(); 53 | 54 | if (entitylivingbase == null) 55 | { 56 | return false; 57 | } 58 | else if (!entitylivingbase.isEntityAlive()) 59 | { 60 | return false; 61 | } 62 | else if (this.classTarget != null && !this.classTarget.isAssignableFrom(entitylivingbase.getClass())) 63 | { 64 | return false; 65 | } 66 | else 67 | { 68 | if (-- this.field_75445_i <= 0) 69 | { 70 | this.entityPathEntity = this.attacker.getNavigator().getPathToEntityLiving(entitylivingbase); 71 | this.field_75445_i = 4 + this.attacker.getRNG().nextInt(7); 72 | return this.entityPathEntity != null; 73 | } 74 | else 75 | { 76 | return true; 77 | } 78 | } 79 | } 80 | 81 | /** 82 | * Returns whether an in-progress EntityAIBase should continue executing 83 | */ 84 | public boolean continueExecuting() 85 | { 86 | EntityLivingBase entitylivingbase = this.attacker.getAttackTarget(); 87 | return entitylivingbase == null ? false : (!entitylivingbase.isEntityAlive() ? false : (!this.longMemory ? !this.attacker.getNavigator().noPath() : this.attacker.isWithinHomeDistance(MathHelper.floor_double(entitylivingbase.posX), MathHelper.floor_double(entitylivingbase.posY), MathHelper.floor_double(entitylivingbase.posZ)))); 88 | } 89 | 90 | /** 91 | * Execute a one shot task or start executing a continuous task 92 | */ 93 | public void startExecuting() 94 | { 95 | this.attacker.getNavigator().setPath(this.entityPathEntity, this.speedTowardsTarget); 96 | this.field_75445_i = 0; 97 | } 98 | 99 | /** 100 | * Resets the task 101 | */ 102 | public void resetTask() 103 | { 104 | this.attacker.getNavigator().clearPathEntity(); 105 | } 106 | 107 | /** 108 | * Updates the task 109 | */ 110 | public void updateTask() 111 | { 112 | EntityLivingBase entitylivingbase = this.attacker.getAttackTarget(); 113 | this.attacker.getLookHelper().setLookPositionWithEntity(entitylivingbase, 30.0F, 30.0F); 114 | double d0 = this.attacker.getDistanceSq(entitylivingbase.posX, entitylivingbase.boundingBox.minY, entitylivingbase.posZ); 115 | double d1 = (double)(this.attacker.width * 2.0F * this.attacker.width * 2.0F + entitylivingbase.width); 116 | --this.field_75445_i; 117 | 118 | if ((this.longMemory || this.attacker.getEntitySenses().canSee(entitylivingbase)) && this.field_75445_i <= 0 && (this.field_151497_i == 0.0D && this.field_151495_j == 0.0D && this.field_151496_k == 0.0D || entitylivingbase.getDistanceSq(this.field_151497_i, this.field_151495_j, this.field_151496_k) >= 1.0D || this.attacker.getRNG().nextFloat() < 0.05F)) 119 | { 120 | this.field_151497_i = entitylivingbase.posX; 121 | this.field_151495_j = entitylivingbase.boundingBox.minY; 122 | this.field_151496_k = entitylivingbase.posZ; 123 | this.field_75445_i = failedPathFindingPenalty + 4 + this.attacker.getRNG().nextInt(7); 124 | 125 | if (this.attacker.getNavigator().getPath() != null) 126 | { 127 | PathPoint finalPathPoint = this.attacker.getNavigator().getPath().getFinalPathPoint(); 128 | if (finalPathPoint != null && entitylivingbase.getDistanceSq(finalPathPoint.xCoord, finalPathPoint.yCoord, finalPathPoint.zCoord) < 1) 129 | { 130 | failedPathFindingPenalty = 0; 131 | } 132 | else 133 | { 134 | failedPathFindingPenalty += 10; 135 | } 136 | } 137 | else 138 | { 139 | failedPathFindingPenalty += 10; 140 | } 141 | 142 | if (d0 > 1024.0D) 143 | { 144 | this.field_75445_i += 10; 145 | } 146 | else if (d0 > 256.0D) 147 | { 148 | this.field_75445_i += 5; 149 | } 150 | 151 | if (!this.attacker.getNavigator().tryMoveToEntityLiving(entitylivingbase, this.speedTowardsTarget)) 152 | { 153 | this.field_75445_i += 15; 154 | } 155 | } 156 | 157 | this.attackTick = Math.max(this.attackTick - 1, 0); 158 | 159 | attack(entitylivingbase, d0); 160 | } 161 | 162 | protected void attack(EntityLivingBase target, double squaredDistance) { 163 | double d1 = (double)(this.attacker.width * 2.0F * this.attacker.width * 2.0F + target.width); 164 | if (squaredDistance <= d1 && this.attackTick <= 20) 165 | { 166 | this.attackTick = 20; 167 | 168 | if (this.attacker.getHeldItem() != null) 169 | { 170 | this.attacker.swingItem(); 171 | } 172 | 173 | this.attacker.attackEntityAsMob(target); 174 | } 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/future/entity/ai/EntityAIDiveJump.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.future.entity.ai; 2 | 3 | import makamys.dmod.constants.AIMutex; 4 | import net.minecraft.entity.ai.EntityAIBase; 5 | 6 | public abstract class EntityAIDiveJump extends EntityAIBase { 7 | public EntityAIDiveJump() { 8 | this.setMutexBits(AIMutex.MOVE | AIMutex.JUMP); 9 | } 10 | } 11 | 12 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/future/entity/ai/EntityAIFleeSunModern.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.future.entity.ai; 2 | 3 | import java.util.Random; 4 | 5 | import net.minecraft.entity.EntityCreature; 6 | import net.minecraft.entity.ai.EntityAIBase; 7 | import net.minecraft.util.MathHelper; 8 | import net.minecraft.util.Vec3; 9 | import net.minecraft.world.World; 10 | 11 | public class EntityAIFleeSunModern extends EntityAIBase 12 | { 13 | private EntityCreature theCreature; 14 | private double shelterX; 15 | private double shelterY; 16 | private double shelterZ; 17 | private double movementSpeed; 18 | private World theWorld; 19 | private static final String __OBFID = "CL_00001583"; 20 | 21 | public EntityAIFleeSunModern(EntityCreature p_i1623_1_, double p_i1623_2_) 22 | { 23 | this.theCreature = p_i1623_1_; 24 | this.movementSpeed = p_i1623_2_; 25 | this.theWorld = p_i1623_1_.worldObj; 26 | this.setMutexBits(1); 27 | } 28 | 29 | /** 30 | * Returns whether the EntityAIBase should begin execution. 31 | */ 32 | public boolean shouldExecute() 33 | { 34 | if (!this.theWorld.isDaytime()) 35 | { 36 | return false; 37 | } 38 | else if (!this.theCreature.isBurning()) 39 | { 40 | return false; 41 | } 42 | else if (!this.theWorld.canBlockSeeTheSky(MathHelper.floor_double(this.theCreature.posX), (int)this.theCreature.boundingBox.minY, MathHelper.floor_double(this.theCreature.posZ))) 43 | { 44 | return false; 45 | } 46 | else 47 | { 48 | return this.targetShadedPos(); 49 | } 50 | } 51 | 52 | protected boolean targetShadedPos() { 53 | Vec3 vec3 = this.findPossibleShelter(); 54 | 55 | if (vec3 == null) 56 | { 57 | return false; 58 | } 59 | else 60 | { 61 | this.shelterX = vec3.xCoord; 62 | this.shelterY = vec3.yCoord; 63 | this.shelterZ = vec3.zCoord; 64 | return true; 65 | } 66 | } 67 | 68 | /** 69 | * Returns whether an in-progress EntityAIBase should continue executing 70 | */ 71 | public boolean continueExecuting() 72 | { 73 | return !this.theCreature.getNavigator().noPath(); 74 | } 75 | 76 | /** 77 | * Execute a one shot task or start executing a continuous task 78 | */ 79 | public void startExecuting() 80 | { 81 | this.theCreature.getNavigator().tryMoveToXYZ(this.shelterX, this.shelterY, this.shelterZ, this.movementSpeed); 82 | } 83 | 84 | private Vec3 findPossibleShelter() 85 | { 86 | Random random = this.theCreature.getRNG(); 87 | 88 | for (int i = 0; i < 10; ++i) 89 | { 90 | int j = MathHelper.floor_double(this.theCreature.posX + (double)random.nextInt(20) - 10.0D); 91 | int k = MathHelper.floor_double(this.theCreature.boundingBox.minY + (double)random.nextInt(6) - 3.0D); 92 | int l = MathHelper.floor_double(this.theCreature.posZ + (double)random.nextInt(20) - 10.0D); 93 | 94 | if (!this.theWorld.canBlockSeeTheSky(j, k, l) && this.theCreature.getBlockPathWeight(j, k, l) < 0.0F) 95 | { 96 | return Vec3.createVectorHelper((double)j, (double)k, (double)l); 97 | } 98 | } 99 | 100 | return null; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/future/entity/ai/EntityAIModernAvoidEntity.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.future.entity.ai; 2 | 3 | import java.util.function.Predicate; 4 | 5 | import makamys.dmod.constants.AIMutex; 6 | import makamys.dmod.future.predicate.entity.EntityPredicates; 7 | import makamys.dmod.future.world.EntityViewEmulator; 8 | import net.minecraft.command.IEntitySelector; 9 | import net.minecraft.entity.Entity; 10 | import net.minecraft.entity.EntityCreature; 11 | import net.minecraft.entity.EntityLivingBase; 12 | import net.minecraft.entity.ai.EntityAIBase; 13 | import net.minecraft.entity.ai.RandomPositionGenerator; 14 | import net.minecraft.pathfinding.PathEntity; 15 | import net.minecraft.pathfinding.PathNavigate; 16 | import net.minecraft.util.Vec3; 17 | 18 | public class EntityAIModernAvoidEntity extends EntityAIBase { 19 | public static final IEntitySelector alive = new IEntitySelector() 20 | { 21 | /** 22 | * Return whether the specified entity is applicable to this filter. 23 | */ 24 | public boolean isEntityApplicable(Entity p_82704_1_) 25 | { 26 | return p_82704_1_.isEntityAlive(); 27 | } 28 | }; 29 | 30 | public final IEntitySelector field_98218_a = new IEntitySelector() 31 | { 32 | /** 33 | * Return whether the specified entity is applicable to this filter. 34 | */ 35 | public boolean isEntityApplicable(Entity p_82704_1_) 36 | { 37 | return p_82704_1_.isEntityAlive() && EntityAIModernAvoidEntity.this.mob.getEntitySenses().canSee(p_82704_1_); 38 | } 39 | }; 40 | 41 | protected final EntityCreature mob; 42 | private final double slowSpeed; 43 | private final double fastSpeed; 44 | protected Entity targetEntity; 45 | protected final float fleeDistance; 46 | protected PathEntity fleePath; 47 | protected final PathNavigate fleeingEntityNavigation; 48 | protected final Class classToFleeFrom; 49 | protected final Predicate extraInclusionSelector; 50 | protected final Predicate inclusionSelector; 51 | private final TargetPredicate withinRangePredicate; 52 | 53 | public EntityAIModernAvoidEntity(EntityCreature mob, Class fleeFromType, float distance, double slowSpeed, double fastSpeed) { 54 | this(mob, fleeFromType, (livingEntity) -> { 55 | return true; 56 | }, distance, slowSpeed, fastSpeed, EntityPredicates.EXCEPT_CREATIVE_OR_SPECTATOR::test); 57 | } 58 | 59 | public EntityAIModernAvoidEntity(EntityCreature mob, Class fleeFromType, Predicate extraInclusionSelector, float distance, double slowSpeed, double fastSpeed, Predicate inclusionSelector, boolean includeHidden) { 60 | this.mob = mob; 61 | this.classToFleeFrom = fleeFromType; 62 | this.extraInclusionSelector = extraInclusionSelector; 63 | this.fleeDistance = distance; 64 | this.slowSpeed = slowSpeed; 65 | this.fastSpeed = fastSpeed; 66 | this.inclusionSelector = inclusionSelector; 67 | this.fleeingEntityNavigation = mob.getNavigator(); 68 | this.setMutexBits(AIMutex.MOVE); 69 | this.withinRangePredicate = (new TargetPredicate()).setBaseMaxDistance((double)distance).setPredicate(inclusionSelector.and(extraInclusionSelector)); 70 | if(includeHidden) { 71 | withinRangePredicate.includeHidden(); 72 | } 73 | } 74 | 75 | public EntityAIModernAvoidEntity(EntityCreature mob, Class fleeFromType, Predicate extraInclusionSelector, float distance, double slowSpeed, double fastSpeed, Predicate inclusionSelector) { 76 | this(mob, fleeFromType, extraInclusionSelector, distance, slowSpeed, fastSpeed, inclusionSelector, false); 77 | } 78 | 79 | public EntityAIModernAvoidEntity(EntityCreature fleeingEntity, Class classToFleeFrom, float fleeDistance, double fleeSlowSpeed, double fleeFastSpeed, Predicate inclusionSelector, boolean includeHidden) { 80 | this(fleeingEntity, classToFleeFrom, (livingEntity) -> { 81 | return true; 82 | }, fleeDistance, fleeSlowSpeed, fleeFastSpeed, inclusionSelector, includeHidden); 83 | } 84 | 85 | public EntityAIModernAvoidEntity(EntityCreature fleeingEntity, Class classToFleeFrom, float fleeDistance, double fleeSlowSpeed, double fleeFastSpeed, Predicate inclusionSelector) { 86 | this(fleeingEntity, classToFleeFrom, fleeDistance, fleeSlowSpeed, fleeFastSpeed, inclusionSelector, false); 87 | } 88 | 89 | @Override 90 | public boolean shouldExecute() { 91 | this.targetEntity = EntityViewEmulator.getClosestEntityIncludingUngeneratedChunks(this.mob.worldObj, 92 | this.classToFleeFrom, 93 | this.withinRangePredicate, this.mob, this.mob.posX, this.mob.posY, this.mob.posZ, 94 | this.mob.boundingBox.expand((double) this.fleeDistance, 3.0D, (double) this.fleeDistance)); 95 | if (this.targetEntity == null) { 96 | return false; 97 | } else { 98 | Vec3 vec3d = RandomPositionGenerator.findRandomTargetBlockAwayFrom(this.mob, 16, 7, 99 | Vec3.createVectorHelper(this.targetEntity.posX, this.targetEntity.posY, this.targetEntity.posZ)); 100 | if (vec3d == null) { 101 | return false; 102 | } else if (this.targetEntity.getDistanceSq(vec3d.xCoord, vec3d.yCoord, vec3d.zCoord) < this.targetEntity 103 | .getDistanceSqToEntity(this.mob)) { 104 | return false; 105 | } else { 106 | this.fleePath = this.fleeingEntityNavigation.getPathToXYZ(vec3d.xCoord, vec3d.yCoord, vec3d.zCoord); 107 | return this.fleePath != null; 108 | } 109 | } 110 | } 111 | 112 | @Override 113 | public boolean continueExecuting() { 114 | return !this.fleeingEntityNavigation.noPath(); 115 | } 116 | 117 | @Override 118 | public void startExecuting() { 119 | this.fleeingEntityNavigation.setPath(this.fleePath, this.slowSpeed); 120 | } 121 | 122 | @Override 123 | public void resetTask() { 124 | this.targetEntity = null; 125 | } 126 | 127 | @Override 128 | public void updateTask() { 129 | if (this.mob.getDistanceSqToEntity(this.targetEntity) < 49.0D) { 130 | this.mob.getNavigator().setSpeed(this.fastSpeed); 131 | } else { 132 | this.mob.getNavigator().setSpeed(this.slowSpeed); 133 | } 134 | 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/future/entity/ai/EntityAIMoveToTargetPos.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.future.entity.ai; 2 | 3 | import makamys.dmod.constants.AIMutex; 4 | import makamys.dmod.future.util.BlockPos; 5 | import net.minecraft.entity.EntityCreature; 6 | import net.minecraft.entity.ai.EntityAIBase; 7 | import net.minecraft.util.MathHelper; 8 | import net.minecraft.world.World; 9 | 10 | public abstract class EntityAIMoveToTargetPos extends EntityAIBase { 11 | protected final EntityCreature mob; 12 | public final double speed; 13 | protected int cooldown; 14 | protected int tryingTime; 15 | private int safeWaitingTime; 16 | protected BlockPos targetPos; 17 | private boolean reached; 18 | private final int range; 19 | private final int maxYDifference; 20 | protected int lowestY; 21 | 22 | public EntityAIMoveToTargetPos(EntityCreature mob, double speed, int range) { 23 | this(mob, speed, range, 1); 24 | } 25 | 26 | public EntityAIMoveToTargetPos(EntityCreature mob, double speed, int range, int maxYDifference) { 27 | this.targetPos = BlockPos.ORIGIN; 28 | this.mob = mob; 29 | this.speed = speed; 30 | this.range = range; 31 | this.lowestY = 0; 32 | this.maxYDifference = maxYDifference; 33 | this.setMutexBits(AIMutex.MOVE | AIMutex.JUMP); 34 | } 35 | 36 | @Override 37 | public boolean shouldExecute() { 38 | if (this.cooldown > 0) { 39 | --this.cooldown; 40 | return false; 41 | } else { 42 | this.cooldown = this.getInterval(this.mob); 43 | return this.findTargetPos(); 44 | } 45 | } 46 | 47 | protected int getInterval(EntityCreature mob) { 48 | return 200 + mob.getRNG().nextInt(200); 49 | } 50 | 51 | @Override 52 | public boolean continueExecuting() { 53 | return this.tryingTime >= -this.safeWaitingTime && this.tryingTime <= 1200 && this.isTargetPos(this.mob.worldObj, this.targetPos); 54 | } 55 | 56 | @Override 57 | public void startExecuting() { 58 | this.startMovingToTarget(); 59 | this.tryingTime = 0; 60 | this.safeWaitingTime = this.mob.getRNG().nextInt(this.mob.getRNG().nextInt(1200) + 1200) + 1200; 61 | } 62 | 63 | protected void startMovingToTarget() { 64 | this.mob.getNavigator().tryMoveToXYZ((double)((float)this.targetPos.getX()) + 0.5D, (double)(this.targetPos.getY() + 1), (double)((float)this.targetPos.getZ()) + 0.5D, this.speed); 65 | } 66 | 67 | public double getDesiredSquaredDistanceToTarget() { 68 | return 1.0D; 69 | } 70 | 71 | protected BlockPos getTargetPos() { 72 | return this.targetPos.up(); 73 | } 74 | 75 | @Override 76 | public void updateTask() { 77 | BlockPos blockPos = this.getTargetPos(); 78 | if (this.mob.getDistanceSq(blockPos.getX(), blockPos.getY(), blockPos.getZ()) >= Math.pow(this.getDesiredSquaredDistanceToTarget(), 2)) { 79 | this.reached = false; 80 | ++this.tryingTime; 81 | if (this.shouldResetPath()) { 82 | this.mob.getNavigator().tryMoveToXYZ((double)((float)blockPos.getX()) + 0.5D, (double)blockPos.getY(), (double)((float)blockPos.getZ()) + 0.5D, this.speed); 83 | } 84 | } else { 85 | this.reached = true; 86 | --this.tryingTime; 87 | } 88 | 89 | } 90 | 91 | public boolean shouldResetPath() { 92 | return this.tryingTime % 40 == 0; 93 | } 94 | 95 | protected boolean hasReached() { 96 | return this.reached; 97 | } 98 | 99 | protected boolean findTargetPos() { 100 | int i = this.range; 101 | int j = this.maxYDifference; 102 | int mobX = MathHelper.floor_double(mob.posX); 103 | int mobY = MathHelper.floor_double(mob.posY); 104 | int mobZ = MathHelper.floor_double(mob.posZ); 105 | int bx, by, bz; 106 | 107 | for(int k = this.lowestY; k <= j; k = k > 0 ? -k : 1 - k) { 108 | for(int l = 0; l < i; ++l) { 109 | for(int m = 0; m <= l; m = m > 0 ? -m : 1 - m) { 110 | for(int n = m < l && m > -l ? l : 0; n <= l; n = n > 0 ? -n : 1 - n) { 111 | bx = mobX + m; 112 | by = mobY + k - 1; 113 | bz = mobZ + n; 114 | if (this.mob.isWithinHomeDistance(bx, by, bz) && this.isTargetPos(this.mob.worldObj, bx, by, bz)) { 115 | this.targetPos = new BlockPos(bx, by, bz); 116 | return true; 117 | } 118 | } 119 | } 120 | } 121 | } 122 | 123 | return false; 124 | } 125 | 126 | private boolean isTargetPos(World world, BlockPos pos) { 127 | return this.isTargetPos(world, pos.getX(), pos.getY(), pos.getZ()); 128 | } 129 | 130 | protected abstract boolean isTargetPos(World world, int bx, int by, int bz); 131 | } 132 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/future/entity/ai/EntityAINearestAttackableTargetEx.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.future.entity.ai; 2 | 3 | import net.minecraft.command.IEntitySelector; 4 | import net.minecraft.entity.EntityCreature; 5 | import net.minecraft.entity.EntityLivingBase; 6 | import net.minecraft.entity.ai.EntityAINearestAttackableTarget; 7 | 8 | public class EntityAINearestAttackableTargetEx extends EntityAINearestAttackableTarget { 9 | private IEntitySelector extraSelector; 10 | 11 | public EntityAINearestAttackableTargetEx(EntityCreature creature, Class targetClass, int reciprocalChance, boolean checkVisibility, boolean checkCanNavigate, IEntitySelector extraSelector) { 12 | super(creature, targetClass, reciprocalChance, checkVisibility, checkCanNavigate, null); 13 | this.extraSelector = extraSelector; 14 | } 15 | 16 | @Override 17 | protected boolean isSuitableTarget(EntityLivingBase p_75296_1_, boolean p_75296_2_) { 18 | return super.isSuitableTarget(p_75296_1_, p_75296_2_) && extraSelector.isEntityApplicable(p_75296_1_); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/future/entity/ai/ModernEntityLookHelper.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.future.entity.ai; 2 | 3 | import net.minecraft.entity.Entity; 4 | import net.minecraft.entity.EntityLiving; 5 | import net.minecraft.entity.EntityLivingBase; 6 | import net.minecraft.entity.ai.EntityLookHelper; 7 | import net.minecraft.util.MathHelper; 8 | 9 | /** shouldStayHorizontal is the only new thing */ 10 | // TODO move this into a mixin to not redistribute so much Mojang code? 11 | public class ModernEntityLookHelper extends EntityLookHelper 12 | { 13 | private EntityLiving entity; 14 | /** The amount of change that is made each update for an entity facing a direction. */ 15 | private float deltaLookYaw; 16 | /** The amount of change that is made each update for an entity facing a direction. */ 17 | private float deltaLookPitch; 18 | /** Whether or not the entity is trying to look at something. */ 19 | private boolean isLooking; 20 | private double posX; 21 | private double posY; 22 | private double posZ; 23 | private static final String __OBFID = "CL_00001572"; 24 | 25 | public ModernEntityLookHelper(EntityLiving p_i1613_1_) 26 | { 27 | super(p_i1613_1_); 28 | this.entity = p_i1613_1_; 29 | } 30 | 31 | /** 32 | * Sets position to look at using entity 33 | */ 34 | @Override 35 | public void setLookPositionWithEntity(Entity p_75651_1_, float p_75651_2_, float p_75651_3_) 36 | { 37 | this.posX = p_75651_1_.posX; 38 | 39 | if (p_75651_1_ instanceof EntityLivingBase) 40 | { 41 | this.posY = p_75651_1_.posY + (double)p_75651_1_.getEyeHeight(); 42 | } 43 | else 44 | { 45 | this.posY = (p_75651_1_.boundingBox.minY + p_75651_1_.boundingBox.maxY) / 2.0D; 46 | } 47 | 48 | this.posZ = p_75651_1_.posZ; 49 | this.deltaLookYaw = p_75651_2_; 50 | this.deltaLookPitch = p_75651_3_; 51 | this.isLooking = true; 52 | } 53 | 54 | /** 55 | * Sets position to look at 56 | */ 57 | @Override 58 | public void setLookPosition(double p_75650_1_, double p_75650_3_, double p_75650_5_, float p_75650_7_, float p_75650_8_) 59 | { 60 | this.posX = p_75650_1_; 61 | this.posY = p_75650_3_; 62 | this.posZ = p_75650_5_; 63 | this.deltaLookYaw = p_75650_7_; 64 | this.deltaLookPitch = p_75650_8_; 65 | this.isLooking = true; 66 | } 67 | 68 | /** 69 | * Updates look 70 | */ 71 | @Override 72 | public void onUpdateLook() 73 | { 74 | if(shouldStayHorizontal()) { 75 | this.entity.rotationPitch = 0.0F; 76 | } 77 | 78 | if (this.isLooking) 79 | { 80 | this.isLooking = false; 81 | double d0 = this.posX - this.entity.posX; 82 | double d1 = this.posY - (this.entity.posY + (double)this.entity.getEyeHeight()); 83 | double d2 = this.posZ - this.entity.posZ; 84 | double d3 = (double)MathHelper.sqrt_double(d0 * d0 + d2 * d2); 85 | float f = (float)(Math.atan2(d2, d0) * 180.0D / Math.PI) - 90.0F; 86 | float f1 = (float)(-(Math.atan2(d1, d3) * 180.0D / Math.PI)); 87 | this.entity.rotationPitch = this.updateRotation(this.entity.rotationPitch, f1, this.deltaLookPitch); 88 | this.entity.rotationYawHead = this.updateRotation(this.entity.rotationYawHead, f, this.deltaLookYaw); 89 | } 90 | else 91 | { 92 | this.entity.rotationYawHead = this.updateRotation(this.entity.rotationYawHead, this.entity.renderYawOffset, 10.0F); 93 | } 94 | 95 | float f2 = MathHelper.wrapAngleTo180_float(this.entity.rotationYawHead - this.entity.renderYawOffset); 96 | 97 | if (!this.entity.getNavigator().noPath()) 98 | { 99 | if (f2 < -75.0F) 100 | { 101 | this.entity.rotationYawHead = this.entity.renderYawOffset - 75.0F; 102 | } 103 | 104 | if (f2 > 75.0F) 105 | { 106 | this.entity.rotationYawHead = this.entity.renderYawOffset + 75.0F; 107 | } 108 | } 109 | } 110 | 111 | protected boolean shouldStayHorizontal() { 112 | return true; 113 | } 114 | 115 | private float updateRotation(float p_75652_1_, float p_75652_2_, float p_75652_3_) 116 | { 117 | float f3 = MathHelper.wrapAngleTo180_float(p_75652_2_ - p_75652_1_); 118 | 119 | if (f3 > p_75652_3_) 120 | { 121 | f3 = p_75652_3_; 122 | } 123 | 124 | if (f3 < -p_75652_3_) 125 | { 126 | f3 = -p_75652_3_; 127 | } 128 | 129 | return p_75652_1_ + f3; 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/future/entity/ai/TargetPredicate.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.future.entity.ai; 2 | 3 | import java.util.function.Predicate; 4 | 5 | import javax.annotation.Nullable; 6 | 7 | import net.minecraft.entity.EntityLiving; 8 | import net.minecraft.entity.EntityLivingBase; 9 | 10 | public class TargetPredicate { 11 | public static final TargetPredicate DEFAULT = new TargetPredicate(); 12 | private double baseMaxDistance = -1.0D; 13 | private boolean includeInvulnerable; 14 | private boolean includeTeammates; 15 | private boolean includeHidden; 16 | private boolean ignoreEntityTargetRules; 17 | private boolean useDistanceScalingFactor = true; 18 | private Predicate predicate; 19 | 20 | public TargetPredicate setBaseMaxDistance(double baseMaxDistance) { 21 | this.baseMaxDistance = baseMaxDistance; 22 | return this; 23 | } 24 | 25 | public TargetPredicate includeInvulnerable() { 26 | this.includeInvulnerable = true; 27 | return this; 28 | } 29 | 30 | public TargetPredicate includeTeammates() { 31 | this.includeTeammates = true; 32 | return this; 33 | } 34 | 35 | public TargetPredicate includeHidden() { 36 | this.includeHidden = true; 37 | return this; 38 | } 39 | 40 | public TargetPredicate ignoreEntityTargetRules() { 41 | this.ignoreEntityTargetRules = true; 42 | return this; 43 | } 44 | 45 | public TargetPredicate ignoreDistanceScalingFactor() { 46 | this.useDistanceScalingFactor = false; 47 | return this; 48 | } 49 | 50 | public TargetPredicate setPredicate(@Nullable Predicate predicate) { 51 | this.predicate = predicate; 52 | return this; 53 | } 54 | 55 | public boolean test(@Nullable EntityLiving baseEntity, EntityLivingBase targetEntity) { 56 | if (baseEntity == targetEntity) { 57 | return false; 58 | /*} else if (targetEntity.isSpectator()) { 59 | return false;*/ 60 | } else if (!targetEntity.isEntityAlive()) { 61 | return false; 62 | } else if (!this.includeInvulnerable && targetEntity.isEntityInvulnerable()) { 63 | return false; 64 | } else if (this.predicate != null && !this.predicate.test(targetEntity)) { 65 | return false; 66 | } else { 67 | if (baseEntity != null) { 68 | /*if (!this.ignoreEntityTargetRules) { 69 | if (!baseEntity.canTarget(targetEntity)) { 70 | return false; 71 | } 72 | 73 | if (!baseEntity.canTarget(targetEntity.getType())) { 74 | return false; 75 | } 76 | } 77 | 78 | if (!this.includeTeammates && baseEntity.isTeammate(targetEntity)) { 79 | return false; 80 | }*/ 81 | 82 | if (this.baseMaxDistance > 0.0D) { 83 | double d = /*this.useDistanceScalingFactor ? targetEntity.getAttackDistanceScalingFactor(baseEntity) : */1.0D; 84 | double e = Math.max(this.baseMaxDistance * d, 2.0D); 85 | double f = baseEntity.getDistanceSq(targetEntity.posX, targetEntity.posY, targetEntity.posZ); 86 | if (f > e * e) { 87 | return false; 88 | } 89 | } 90 | 91 | if (!this.includeHidden && !baseEntity.getEntitySenses().canSee(targetEntity)) { 92 | return false; 93 | } 94 | } 95 | 96 | return true; 97 | } 98 | } 99 | } 100 | 101 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/future/entity/item/EntityItemFuture.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.future.entity.item; 2 | 3 | import net.minecraft.entity.item.EntityItem; 4 | 5 | public class EntityItemFuture { 6 | 7 | public static boolean cannotPickUp(EntityItem dis) { 8 | return dis.delayBeforeCanPickup > 0; 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/future/entity/passive/AnimalEntityEmulator.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.future.entity.passive; 2 | 3 | public class AnimalEntityEmulator { 4 | 5 | /*public static boolean interact(EntityAnimal dis, EntityPlayer player, Callable superImpl) { 6 | ItemStack itemStack = player.inventory.getCurrentItem(); 7 | AnimalEntityFutured disF = (AnimalEntityFutured)dis; 8 | if (dis.isBreedingItem(itemStack)) { 9 | int i = dis.getGrowingAge(); 10 | if (!dis.worldObj.isRemote && i == 0 && disF.canEat(dis)) { 11 | if(disF.eat(dis, player, itemStack)) { 12 | eat(dis, player, itemStack); 13 | } 14 | dis.func_146082_f(player); 15 | return true; 16 | } 17 | /* 18 | if (this.isBaby()) { 19 | this.eat(player, itemStack); 20 | this.growUp((int)((float)(-i / 20) * 0.1F), true); 21 | return ActionResult.success(this.world.isClient); 22 | } 23 | 24 | if (this.world.isClient) { 25 | return ActionResult.CONSUME; 26 | }*/ 27 | /* } 28 | 29 | try { 30 | return superImpl.call(); 31 | } catch (Exception e) { 32 | e.printStackTrace(); 33 | return false; 34 | } 35 | } 36 | 37 | public static void eat(EntityAnimal dis, EntityPlayer player, ItemStack itemStack) { 38 | if (!player.capabilities.isCreativeMode) { 39 | --itemStack.stackSize; 40 | 41 | if (itemStack.stackSize <= 0) { 42 | player.inventory.setInventorySlotContents(player.inventory.currentItem, (ItemStack) null); 43 | } 44 | } 45 | }*/ 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/future/entity/passive/EntityAnimalFuture.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.future.entity.passive; 2 | 3 | import makamys.dmod.future.entity.EntityLivingFuture; 4 | import makamys.dmod.future.entity.EntityLivingFutured; 5 | import makamys.dmod.util.EggHelper; 6 | import net.minecraft.enchantment.EnchantmentHelper; 7 | import net.minecraft.entity.Entity; 8 | import net.minecraft.entity.EntityLivingBase; 9 | import net.minecraft.entity.SharedMonsterAttributes; 10 | import net.minecraft.entity.passive.EntityAnimal; 11 | import net.minecraft.entity.player.EntityPlayer; 12 | import net.minecraft.init.Items; 13 | import net.minecraft.item.ItemStack; 14 | import net.minecraft.util.DamageSource; 15 | import net.minecraft.util.MathHelper; 16 | import net.minecraft.util.MovingObjectPosition; 17 | import net.minecraft.world.World; 18 | 19 | public abstract class EntityAnimalFuture extends EntityAnimal implements EntityLivingFutured { 20 | 21 | public EntityAnimalFuture(World p_i1681_1_) { 22 | super(p_i1681_1_); 23 | } 24 | 25 | @Override 26 | public boolean interact(EntityPlayer player) { 27 | ItemStack itemStack = player.inventory.getCurrentItem(); 28 | if (this.isBreedingItem(itemStack)) { 29 | int i = this.getGrowingAge(); 30 | if (!this.worldObj.isRemote && i == 0 && this.canEat()) { 31 | this.eat(player, itemStack); 32 | this.func_146082_f(player); 33 | return true; 34 | } 35 | /* 36 | if (this.isBaby()) { 37 | this.eat(player, itemStack); 38 | this.growUp((int)((float)(-i / 20) * 0.1F), true); 39 | return ActionResult.success(this.world.isClient); 40 | } 41 | 42 | if (this.world.isClient) { 43 | return ActionResult.CONSUME; 44 | }*/ 45 | } 46 | return super.interact(player); 47 | } 48 | 49 | public void eat(EntityPlayer player, ItemStack itemStack) { 50 | if (!player.capabilities.isCreativeMode) { 51 | --itemStack.stackSize; 52 | 53 | if (itemStack.stackSize <= 0) { 54 | player.inventory.setInventorySlotContents(player.inventory.currentItem, (ItemStack) null); 55 | } 56 | } 57 | } 58 | 59 | public boolean canEat() { 60 | return !this.isInLove(); 61 | } 62 | 63 | @Override 64 | public String getEatSound(ItemStack stack) { 65 | return "SoundEvents.ENTITY_GENERIC_EAT"; // TODO 66 | } 67 | 68 | public int getLookPitchSpeed() { 69 | return 40; 70 | } 71 | 72 | public int getBodyYawSpeed() { 73 | return 75; 74 | } 75 | 76 | public int getLookYawSpeed() { 77 | return 10; 78 | } 79 | 80 | @Override 81 | public boolean attackEntityAsMob(Entity target) 82 | { 83 | float f = (float)this.getEntityAttribute(SharedMonsterAttributes.attackDamage).getAttributeValue(); 84 | int i = 0; 85 | 86 | if (target instanceof EntityLivingBase) 87 | { 88 | f += EnchantmentHelper.getEnchantmentModifierLiving(this, (EntityLivingBase)target); 89 | i += EnchantmentHelper.getKnockbackModifier(this, (EntityLivingBase)target); 90 | } 91 | 92 | int j = EnchantmentHelper.getFireAspectModifier(this); 93 | 94 | if (j > 0) 95 | { 96 | target.setFire(j * 4); 97 | } 98 | 99 | boolean flag = target.attackEntityFrom(DamageSource.causeMobDamage(this), f); 100 | 101 | if (flag) 102 | { 103 | if (i > 0) 104 | { 105 | target.addVelocity((double)(-MathHelper.sin(this.rotationYaw * (float)Math.PI / 180.0F) * (float)i * 0.5F), 0.1D, (double)(MathHelper.cos(this.rotationYaw * (float)Math.PI / 180.0F) * (float)i * 0.5F)); 106 | this.motionX *= 0.6D; 107 | this.motionZ *= 0.6D; 108 | } 109 | 110 | this.dealDamage(this, target); 111 | this.onAttacking(target); 112 | } 113 | 114 | return flag; 115 | } 116 | 117 | public void dealDamage(EntityLivingBase attacker, Entity target) { 118 | if (target instanceof EntityLivingBase) 119 | { 120 | EnchantmentHelper.func_151384_a((EntityLivingBase)target, attacker); 121 | } 122 | 123 | EnchantmentHelper.func_151385_b(attacker, target); 124 | } 125 | 126 | public void onAttacking(Entity target) { 127 | this.setLastAttacker(target instanceof EntityLivingBase ? (EntityLivingBase)target : null); 128 | } 129 | 130 | public float computeFallDistance(float fallDistance) { 131 | return fallDistance; 132 | } 133 | 134 | public ItemStack eatFood(World world, ItemStack stack) { 135 | return EntityLivingFuture.eatFoodBody(this, world, stack); 136 | } 137 | 138 | @Override 139 | public ItemStack getPickedResult(MovingObjectPosition target) { 140 | int eggID = EggHelper.getIDForClass(getClass()); 141 | return eggID != -1 ? new ItemStack(Items.spawn_egg, 1, eggID) : super.getPickedResult(target); 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/future/entity/passive/PassiveEntityEmulator.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.future.entity.passive; 2 | 3 | import java.util.Random; 4 | 5 | import net.minecraft.entity.EntityAgeable; 6 | import net.minecraft.entity.IEntityLivingData; 7 | 8 | public class PassiveEntityEmulator { 9 | 10 | public static IEntityLivingData postOnSpawnWithEgg(EntityAgeable dis, IEntityLivingData entityData, Random rand) { 11 | if (entityData == null) { 12 | entityData = new PassiveEntityEmulator.PassiveData(true); 13 | } 14 | 15 | PassiveEntityEmulator.PassiveData passiveData = (PassiveEntityEmulator.PassiveData)entityData; 16 | if (passiveData.canSpawnBaby() && passiveData.getSpawnedCount() > 0 && rand.nextFloat() <= passiveData.getBabyChance()) { 17 | dis.setGrowingAge(-24000); 18 | } 19 | 20 | passiveData.countSpawned(); 21 | return entityData; 22 | //return super.initialize(world, difficulty, spawnReason, (EntityData)entityData, entityTag); 23 | } 24 | 25 | public static class PassiveData implements IEntityLivingData { 26 | private int spawnCount; 27 | private final boolean babyAllowed; 28 | private final float babyChance; 29 | 30 | private PassiveData(boolean bl, float f) { 31 | this.babyAllowed = bl; 32 | this.babyChance = f; 33 | } 34 | 35 | public PassiveData(boolean bl) { 36 | this(bl, 0.05F); 37 | } 38 | 39 | public PassiveData(float f) { 40 | this(true, f); 41 | } 42 | 43 | public int getSpawnedCount() { 44 | return this.spawnCount; 45 | } 46 | 47 | public void countSpawned() { 48 | ++this.spawnCount; 49 | } 50 | 51 | public boolean canSpawnBaby() { 52 | return this.babyAllowed; 53 | } 54 | 55 | public float getBabyChance() { 56 | return this.babyChance; 57 | } 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/future/inventory/SlotFuture.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.future.inventory; 2 | 3 | import makamys.dmod.future.item.ItemStackFuture; 4 | import net.minecraft.entity.player.EntityPlayer; 5 | import net.minecraft.inventory.Slot; 6 | import net.minecraft.item.ItemStack; 7 | 8 | public class SlotFuture { 9 | 10 | public static ItemStack insertStack(Slot dis, ItemStack stack) { 11 | return insertStack(dis, stack, stack.stackSize); 12 | } 13 | 14 | /*** can return an item stack of size 0 that should be converted to null */ 15 | public static ItemStack insertStack(Slot dis, ItemStack stack, int count) { 16 | if (stack != null && dis.isItemValid(stack)) { 17 | ItemStack itemStack = dis.getStack(); 18 | int slotItemCount = itemStack != null ? itemStack.stackSize : 0; 19 | int i = Math.min(Math.min(count, stack.stackSize), getMaxItemCount(dis, stack) - slotItemCount); 20 | if (itemStack == null) { 21 | dis.putStack(stack.splitStack(i)); 22 | } else if (ItemStackFuture.canCombine(itemStack, stack)) { 23 | ItemStackFuture.decrement(stack, i); 24 | ItemStackFuture.increment(itemStack, i); 25 | dis.putStack(itemStack); 26 | } 27 | 28 | return ItemStackFuture.oldify(stack); 29 | } else { 30 | return ItemStackFuture.oldify(stack); 31 | } 32 | } 33 | 34 | public static int getMaxItemCount(Slot dis, ItemStack stack) { 35 | return Math.min(dis.getSlotStackLimit(), stack.getMaxStackSize()); 36 | } 37 | 38 | public static ItemStack takeStackRange(Slot dis, int min, int max, EntityPlayer player) { 39 | ItemStack stack = tryTakeStackRange(dis, min, max, player); 40 | if(stack != null) { 41 | dis.onPickupFromSlot(player, stack); 42 | } 43 | return stack; 44 | } 45 | 46 | public static ItemStack tryTakeStackRange(Slot dis, int min, int max, EntityPlayer player) { 47 | if (!dis.canTakeStack(player)) { 48 | return null; 49 | } else if (!canTakePartial(dis, player) && max < dis.getStack().stackSize) { 50 | return null; 51 | } else { 52 | min = Math.min(min, max); 53 | ItemStack itemStack = dis.decrStackSize(min); 54 | if (itemStack == null) { 55 | return null; 56 | } else { 57 | if (dis.getStack() == null) { 58 | dis.putStack(null); 59 | } 60 | 61 | return itemStack; 62 | } 63 | } 64 | } 65 | 66 | public static boolean canTakePartial(Slot dis, EntityPlayer player) { 67 | return dis.canTakeStack(player) && dis.isItemValid(dis.getStack()); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/future/item/ItemFuture.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.future.item; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | import codechicken.lib.gui.GuiDraw.ITooltipLineHandler; 7 | import cpw.mods.fml.relauncher.Side; 8 | import cpw.mods.fml.relauncher.SideOnly; 9 | import makamys.dmod.future.entity.EntityLivingFuture; 10 | import net.minecraft.entity.EntityLiving; 11 | import net.minecraft.entity.player.EntityPlayer; 12 | import net.minecraft.inventory.Slot; 13 | import net.minecraft.item.Item; 14 | import net.minecraft.item.ItemFood; 15 | import net.minecraft.item.ItemStack; 16 | import net.minecraft.world.World; 17 | 18 | public abstract class ItemFuture extends Item { 19 | 20 | public boolean onStackClicked(ItemStack stack, Slot slot, int button, EntityPlayer player) { 21 | return false; 22 | } 23 | 24 | public boolean onClicked(ItemStack stack, ItemStack otherStack, Slot slot, int button, EntityPlayer player) { 25 | return false; 26 | } 27 | 28 | public static ItemStack finishUsing(Item dis, ItemStack stack, World world, EntityLiving user) { 29 | return dis instanceof ItemFood ? EntityLivingFuture.eatFood(user, world, stack) : stack; 30 | } 31 | 32 | public static boolean canBeNested(Item dis) { 33 | return true; // TODO don't allow shulker box, configurable blacklist? 34 | } 35 | 36 | public boolean getItemBarHasColor(ItemStack stack) { 37 | return false; 38 | } 39 | 40 | public int getItemBarColor(ItemStack stack) { 41 | return 0x00FF00; 42 | } 43 | 44 | @SideOnly(Side.CLIENT) 45 | public void appendTooltip(ItemStack stack, World world, List tooltip) {} 46 | 47 | @cpw.mods.fml.common.Optional.Method(modid = "CodeChickenCore") 48 | @SideOnly(Side.CLIENT) 49 | public List getTooltipHandlers(ItemStack stack){ 50 | return Arrays.asList(); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/future/item/ItemStackFuture.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.future.item; 2 | 3 | import net.minecraft.entity.EntityLiving; 4 | import net.minecraft.item.ItemStack; 5 | import net.minecraft.nbt.NBTTagCompound; 6 | import net.minecraft.world.World; 7 | 8 | public class ItemStackFuture { 9 | 10 | public static ItemStack finishUsing(ItemStack dis, World world, EntityLiving user) { 11 | return ItemFuture.finishUsing(dis.getItem(), dis, world, user); 12 | } 13 | 14 | public static void decrement(ItemStack dis, int count) { 15 | // TODO is this correct? 16 | increment(dis, -count); 17 | } 18 | 19 | public static void increment(ItemStack dis, int count) { 20 | dis.stackSize += count; 21 | } 22 | 23 | public static boolean isEmpty(ItemStack dis) { 24 | if (dis == null) { 25 | return true; 26 | } else if (dis.getItem() != null/* && dis.getItem() != Items.AIR*/) { 27 | return dis.stackSize <= 0; 28 | } else { 29 | return true; 30 | } 31 | } 32 | 33 | public static boolean canCombine(ItemStack a, ItemStack b) { 34 | return a.getItem() == b.getItem() && a.getItemDamage() == b.getItemDamage() && ItemStack.areItemStackTagsEqual(a, b); 35 | } 36 | 37 | public static ItemStack oldify(ItemStack stack) { 38 | if(stack.stackSize == 0) { 39 | return null; 40 | } 41 | return stack; 42 | } 43 | 44 | public static NBTTagCompound getOrCreateNbt(ItemStack dis) { 45 | if(!dis.hasTagCompound()) { 46 | dis.stackTagCompound = new NBTTagCompound(); 47 | } 48 | return dis.getTagCompound(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/future/nbt/NBTTagListFuture.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.future.nbt; 2 | 3 | import java.util.List; 4 | 5 | import cpw.mods.fml.relauncher.ReflectionHelper; 6 | import net.minecraft.nbt.NBTBase; 7 | import net.minecraft.nbt.NBTTagList; 8 | 9 | public class NBTTagListFuture { 10 | 11 | public static List toList(NBTTagList tagList) { 12 | return ReflectionHelper.getPrivateValue(NBTTagList.class, tagList, "tagList", "field_74747_a"); 13 | } 14 | 15 | public static void add(NBTTagList tagList, int index, NBTBase element) { 16 | if(tagList.tagCount() == 0) { 17 | tagList.appendTag(element); 18 | } else { 19 | toList(tagList).add(index, element); 20 | } 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/future/predicate/entity/EntityPredicates.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.future.predicate.entity; 2 | 3 | import java.util.function.Predicate; 4 | 5 | import net.minecraft.entity.EntityLivingBase; 6 | import net.minecraft.entity.player.EntityPlayer; 7 | 8 | public class EntityPredicates { 9 | public static final Predicate EXCEPT_CREATIVE_OR_SPECTATOR = (entity) -> { 10 | return !(entity instanceof EntityPlayer) || /*!entity.isSpectator() && */!((EntityPlayer)entity).capabilities.isCreativeMode; 11 | }; 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/future/util/BlockPos.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.future.util; 2 | 3 | import net.minecraft.entity.Entity; 4 | import net.minecraft.util.EnumFacing; 5 | import net.minecraft.util.Vec3; 6 | 7 | // Copied from ganymedes01.etfuturum.entities.ai 8 | 9 | public class BlockPos extends Vec3i { 10 | 11 | public static final BlockPos ORIGIN = new BlockPos(0, 0, 0); 12 | 13 | private static final int NUM_X_BITS = 26; 14 | private static final int NUM_Z_BITS = NUM_X_BITS; 15 | private static final int NUM_Y_BITS = 64 - NUM_X_BITS - NUM_Z_BITS; 16 | private static final int Y_SHIFT = 0 + NUM_Z_BITS; 17 | private static final int X_SHIFT = Y_SHIFT + NUM_Y_BITS; 18 | private static final long X_MASK = (1L << NUM_X_BITS) - 1L; 19 | private static final long Y_MASK = (1L << NUM_Y_BITS) - 1L; 20 | private static final long Z_MASK = (1L << NUM_Z_BITS) - 1L; 21 | 22 | public BlockPos(int x, int y, int z) { 23 | super(x, y, z); 24 | } 25 | 26 | public BlockPos(double x, double y, double z) { 27 | super(x, y, z); 28 | } 29 | 30 | public BlockPos(Entity source) { 31 | this(source.posX, source.posY, source.posZ); 32 | } 33 | 34 | public BlockPos(Vec3 source) { 35 | this(source.xCoord, source.yCoord, source.zCoord); 36 | } 37 | 38 | public BlockPos(Vec3i source) { 39 | this(source.getX(), source.getY(), source.getZ()); 40 | } 41 | 42 | public BlockPos add(double x, double y, double z) { 43 | return new BlockPos(getX() + x, getY() + y, getZ() + z); 44 | } 45 | 46 | public BlockPos add(int x, int y, int z) { 47 | return new BlockPos(getX() + x, getY() + y, getZ() + z); 48 | } 49 | 50 | public BlockPos add(Vec3i vec) { 51 | return new BlockPos(getX() + vec.getX(), getY() + vec.getY(), getZ() + vec.getZ()); 52 | } 53 | 54 | public BlockPos multiply(int factor) { 55 | return new BlockPos(getX() * factor, getY() * factor, getZ() * factor); 56 | } 57 | 58 | public BlockPos up() { 59 | return this.up(1); 60 | } 61 | 62 | public BlockPos subtract(Vec3i vec) { 63 | return new BlockPos(getX() - vec.getX(), getY() - vec.getY(), getZ() - vec.getZ()); 64 | } 65 | 66 | public BlockPos up(int n) { 67 | return this.offset(EnumFacing.UP, n); 68 | } 69 | 70 | public BlockPos down() { 71 | return this.down(1); 72 | } 73 | 74 | public BlockPos down(int n) { 75 | return this.offset(EnumFacing.DOWN, n); 76 | } 77 | 78 | public BlockPos north() { 79 | return this.north(1); 80 | } 81 | 82 | public BlockPos north(int n) { 83 | return this.offset(EnumFacing.NORTH, n); 84 | } 85 | 86 | public BlockPos south() { 87 | return this.south(1); 88 | } 89 | 90 | public BlockPos south(int n) { 91 | return this.offset(EnumFacing.SOUTH, n); 92 | } 93 | 94 | public BlockPos west() { 95 | return this.west(1); 96 | } 97 | 98 | public BlockPos west(int n) { 99 | return this.offset(EnumFacing.WEST, n); 100 | } 101 | 102 | public BlockPos east() { 103 | return this.east(1); 104 | } 105 | 106 | public BlockPos east(int n) { 107 | return this.offset(EnumFacing.EAST, n); 108 | } 109 | 110 | public BlockPos offset(EnumFacing facing) { 111 | return this.offset(facing, 1); 112 | } 113 | 114 | public BlockPos offset(EnumFacing facing, int n) { 115 | return new BlockPos(getX() + facing.getFrontOffsetX() * n, getY() + facing.getFrontOffsetY() * n, getZ() + facing.getFrontOffsetZ() * n); 116 | } 117 | 118 | public BlockPos crossProductBP(Vec3i vec) { 119 | return new BlockPos(getY() * vec.getZ() - getZ() * vec.getY(), getZ() * vec.getX() - getX() * vec.getZ(), getX() * vec.getY() - getY() * vec.getX()); 120 | } 121 | 122 | public long toLong() { 123 | return (getX() & X_MASK) << X_SHIFT | (getY() & Y_MASK) << Y_SHIFT | (getZ() & Z_MASK) << 0; 124 | } 125 | 126 | public static BlockPos fromLong(long serialized) { 127 | int j = (int) (serialized << 64 - X_SHIFT - NUM_X_BITS >> 64 - NUM_X_BITS); 128 | int k = (int) (serialized << 64 - Y_SHIFT - NUM_Y_BITS >> 64 - NUM_Y_BITS); 129 | int l = (int) (serialized << 64 - NUM_Z_BITS >> 64 - NUM_Z_BITS); 130 | return new BlockPos(j, k, l); 131 | } 132 | 133 | @Override 134 | public Vec3i crossProduct(Vec3i vec) { 135 | return crossProductBP(vec); 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/future/util/MathHelperFuture.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.future.util; 2 | 3 | public class MathHelperFuture { 4 | 5 | public static float lerp(float delta, float start, float end) { 6 | return start + delta * (end - start); 7 | } 8 | 9 | public static double lerp(double delta, double start, double end) { 10 | return start + delta * (end - start); 11 | } 12 | 13 | @Deprecated 14 | public static float lerpAngle(float start, float end, float delta) { 15 | float f; 16 | for(f = end - start; f < -180.0F; f += 360.0F) { 17 | } 18 | 19 | while(f >= 180.0F) { 20 | f -= 360.0F; 21 | } 22 | 23 | return start + delta * f; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/future/util/Vec3i.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.future.util; 2 | 3 | import com.google.common.base.Objects; 4 | 5 | import net.minecraft.util.MathHelper; 6 | 7 | // Copied from ganymedes01.etfuturum.entities.ai 8 | 9 | public class Vec3i implements Comparable { 10 | 11 | private final int x, y, z; 12 | 13 | public Vec3i(int xIn, int yIn, int zIn) { 14 | x = xIn; 15 | y = yIn; 16 | z = zIn; 17 | } 18 | 19 | public Vec3i(double xIn, double yIn, double zIn) { 20 | this(MathHelper.floor_double(xIn), MathHelper.floor_double(yIn), MathHelper.floor_double(zIn)); 21 | } 22 | 23 | @Override 24 | public boolean equals(Object p_equals_1_) { 25 | if (this == p_equals_1_) 26 | return true; 27 | else if (!(p_equals_1_ instanceof Vec3i)) 28 | return false; 29 | else { 30 | Vec3i vec3i = (Vec3i) p_equals_1_; 31 | return getX() != vec3i.getX() ? false : getY() != vec3i.getY() ? false : getZ() == vec3i.getZ(); 32 | } 33 | } 34 | 35 | @Override 36 | public int hashCode() { 37 | return (getY() + getZ() * 31) * 31 + getX(); 38 | } 39 | 40 | @Override 41 | public int compareTo(Vec3i vec) { 42 | return getY() == vec.getY() ? getZ() == vec.getZ() ? getX() - vec.getX() : getZ() - vec.getZ() : getY() - vec.getY(); 43 | } 44 | 45 | public int getX() { 46 | return x; 47 | } 48 | 49 | public int getY() { 50 | return y; 51 | } 52 | 53 | public int getZ() { 54 | return z; 55 | } 56 | 57 | public Vec3i crossProduct(Vec3i vec) { 58 | return new Vec3i(getY() * vec.getZ() - getZ() * vec.getY(), getZ() * vec.getX() - getX() * vec.getZ(), getX() * vec.getY() - getY() * vec.getX()); 59 | } 60 | 61 | public double distanceSq(double toX, double toY, double toZ) { 62 | double d3 = getX() - toX; 63 | double d4 = getY() - toY; 64 | double d5 = getZ() - toZ; 65 | return d3 * d3 + d4 * d4 + d5 * d5; 66 | } 67 | 68 | public double distanceSqToCenter(double xIn, double yIn, double zIn) { 69 | double d3 = getX() + 0.5D - xIn; 70 | double d4 = getY() + 0.5D - yIn; 71 | double d5 = getZ() + 0.5D - zIn; 72 | return d3 * d3 + d4 * d4 + d5 * d5; 73 | } 74 | 75 | public double distanceSq(Vec3i to) { 76 | return this.distanceSq(to.getX(), to.getY(), to.getZ()); 77 | } 78 | 79 | @Override 80 | public String toString() { 81 | return Objects.toStringHelper(this).add("x", getX()).add("y", getY()).add("z", getZ()).toString(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/future/world/EntityViewEmulator.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.future.world; 2 | 3 | import java.util.Iterator; 4 | import java.util.List; 5 | 6 | import com.google.common.collect.Lists; 7 | 8 | import makamys.dmod.future.entity.ai.TargetPredicate; 9 | import net.minecraft.command.IEntitySelector; 10 | import net.minecraft.entity.Entity; 11 | import net.minecraft.entity.EntityLiving; 12 | import net.minecraft.entity.EntityLivingBase; 13 | import net.minecraft.util.AxisAlignedBB; 14 | import net.minecraft.world.World; 15 | 16 | public class EntityViewEmulator { 17 | 18 | public static Entity getClosestEntityIncludingUngeneratedChunks(World world, Class entityClass, TargetPredicate targetPredicate, EntityLiving entity, double x, double y, double z, AxisAlignedBB box) { 19 | return getClosestEntity(world, world.selectEntitiesWithinAABB(entityClass, box, IEntitySelector.selectAnything/*EntityAIModernAvoidEntity.alive*/), targetPredicate, entity, x, y, z); 20 | // XXX alive? why? 21 | } 22 | 23 | public static Entity getClosestEntity(World world, List entityList, TargetPredicate targetPredicate, EntityLiving entity, double x, double y, double z) { 24 | double d = -1.0D; 25 | Entity livingEntity = null; 26 | Iterator var13 = entityList.iterator(); 27 | 28 | while(true) { 29 | Entity livingEntity2; 30 | double e; 31 | do { 32 | do { 33 | if (!var13.hasNext()) { 34 | return livingEntity; 35 | } 36 | 37 | livingEntity2 = (Entity)var13.next(); 38 | } while(!(livingEntity2 instanceof EntityLivingBase && targetPredicate.test(entity, (EntityLivingBase)livingEntity2))); 39 | 40 | e = livingEntity2.getDistanceSq(x, y, z); 41 | } while(d != -1.0D && e >= d); 42 | 43 | d = e; 44 | livingEntity = livingEntity2; 45 | } 46 | } 47 | 48 | public static List getTargets(World world, Class entityClass, TargetPredicate targetPredicate, EntityLiving targetingEntity, AxisAlignedBB box) { 49 | List list = world.selectEntitiesWithinAABB(entityClass, box, null); 50 | List list2 = Lists.newArrayList(); 51 | Iterator var7 = list.iterator(); 52 | 53 | while(var7.hasNext()) { 54 | Entity livingEntity = (Entity)var7.next(); 55 | if (livingEntity instanceof EntityLiving && targetPredicate.test(targetingEntity, (EntityLiving)livingEntity)) { 56 | list2.add(livingEntity); 57 | } 58 | } 59 | 60 | return list2; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/inventory/DSlotClickHandler.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.inventory; 2 | 3 | import static makamys.dmod.DModConstants.LOGGER; 4 | 5 | import makamys.dmod.future.item.ItemFuture; 6 | import net.minecraft.entity.player.EntityPlayer; 7 | import net.minecraft.inventory.Container; 8 | import net.minecraft.inventory.Slot; 9 | import net.minecraft.item.ItemStack; 10 | 11 | public class DSlotClickHandler { 12 | 13 | // See https://wiki.vg/Protocol#Click_Window 14 | public static boolean onSlotClick(Container container, int slotNumber, int button, int modifier, EntityPlayer slotClickPlayer) { 15 | boolean eventconsumed = false; 16 | if(modifier == 0 || modifier == 5) { 17 | if(modifier == 5) { 18 | switch(button) { 19 | case 1: 20 | button = 0; 21 | break; 22 | case 5: 23 | button = 1; 24 | break; 25 | case 9: 26 | button = 2; 27 | break; 28 | default: 29 | button = -1; 30 | } 31 | } 32 | if(button >= 0 && button <= 2 && slotNumber >= 0) { 33 | if(slotNumber < container.inventorySlots.size()) { 34 | Slot slot = container.getSlot(slotNumber); 35 | EntityPlayer player = slotClickPlayer; 36 | ItemStack cursor = player.inventory.getItemStack(); 37 | 38 | ItemStack stack = slot.getStack(); 39 | if(cursor != null && cursor.getItem() instanceof ItemFuture) { 40 | eventconsumed |= ((ItemFuture)cursor.getItem()).onStackClicked(cursor, slot, button, player); 41 | } else if(stack != null && stack.getItem() instanceof ItemFuture) { 42 | eventconsumed |= ((ItemFuture)stack.getItem()).onClicked(stack, cursor, slot, button, player); 43 | } 44 | if(eventconsumed) { 45 | slot.onSlotChanged(); 46 | } 47 | } else { 48 | LOGGER.warn("Invalid index in DSlotClickHandler.onSlotClick: slotNumber=" + slotNumber + ", but container " + container + " only has " + container.inventorySlots.size() + " slots."); 49 | // TODO figure out why this can happen. (TrashSlot?) 50 | } 51 | } 52 | } 53 | return eventconsumed; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/item/IConfigurable.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.item; 2 | 3 | public interface IConfigurable { 4 | public boolean isEnabled(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/mixin/MixinContainer.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.mixin; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 7 | 8 | import makamys.dmod.inventory.DSlotClickHandler; 9 | import net.minecraft.entity.player.EntityPlayer; 10 | import net.minecraft.inventory.Container; 11 | import net.minecraft.item.ItemStack; 12 | 13 | @Mixin(Container.class) 14 | public class MixinContainer { 15 | 16 | @Inject(method = "slotClick", at = @At("HEAD"), cancellable = true) 17 | private void preSlotClick(int p1, int p2, int p3, EntityPlayer player, CallbackInfoReturnable cir) { 18 | if(DSlotClickHandler.onSlotClick((Container)(Object)this, p1, p2, p3, player)) { 19 | cir.setReturnValue(null); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/mixin/MixinEntityLiving.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.mixin; 2 | 3 | import java.util.Iterator; 4 | import java.util.List; 5 | 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.Shadow; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 11 | 12 | import makamys.dmod.future.entity.passive.EntityAnimalFuture; 13 | import net.minecraft.entity.EntityLiving; 14 | import net.minecraft.entity.EntityLivingBase; 15 | import net.minecraft.entity.item.EntityItem; 16 | import net.minecraft.item.ItemArmor; 17 | import net.minecraft.item.ItemStack; 18 | import net.minecraft.item.ItemSword; 19 | import net.minecraft.world.World; 20 | 21 | @Mixin(EntityLiving.class) 22 | public abstract class MixinEntityLiving extends EntityLivingBase { 23 | 24 | @Shadow 25 | protected float[] equipmentDropChances; 26 | @Shadow 27 | private boolean persistenceRequired; 28 | 29 | public MixinEntityLiving(World p_i1594_1_) { 30 | super(p_i1594_1_); 31 | } 32 | 33 | @Inject(method = "onLivingUpdate", at = @At("HEAD"), cancellable = true) 34 | public void preOnLivingUpdate(CallbackInfo ci) { 35 | if(EntityAnimalFuture.class.isInstance(this)) { 36 | ci.cancel(); 37 | EntityLiving dis = ((EntityLiving)(Object)this); 38 | 39 | super.onLivingUpdate(); 40 | 41 | this.worldObj.theProfiler.startSection("looting"); 42 | 43 | if (!this.worldObj.isRemote && dis.canPickUpLoot() && this.isEntityAlive() && !this.dead && this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing")) { 44 | List list = this.worldObj.getEntitiesWithinAABB(EntityItem.class, this.boundingBox.expand(1.0D, 0.0D, 1.0D)); 45 | Iterator iterator = list.iterator(); 46 | 47 | while(iterator.hasNext()) { 48 | EntityItem entityitem = (EntityItem)iterator.next(); 49 | if (!entityitem.isDead && entityitem.getEntityItem() != null && entityitem.delayBeforeCanPickup <= 0) { 50 | this.loot(entityitem); 51 | } 52 | } 53 | } 54 | 55 | this.worldObj.theProfiler.endSection(); 56 | } 57 | } 58 | 59 | protected void loot(EntityItem item) { 60 | ItemStack itemStack = item.getEntityItem(); 61 | if (this.tryEquip(itemStack)) { 62 | // this.method_29499(item); advancement check 63 | this.onItemPickup(item, itemStack.stackSize); 64 | item.setDead(); 65 | } 66 | 67 | } 68 | 69 | public boolean tryEquip(ItemStack equipment) { 70 | EntityLiving dis = ((EntityLiving)(Object)this); 71 | 72 | int equipmentSlot = dis.getArmorPosition(equipment); 73 | if(equipmentSlot > -1) { 74 | ItemStack itemStack = this.getEquipmentInSlot(equipmentSlot); 75 | boolean bl = this.prefersNewEquipment(equipment, itemStack); 76 | if (bl && this.canPickupItem(equipment)) { 77 | double d = (double)this.getDropChance(equipmentSlot); 78 | if (itemStack != null && this.rand.nextFloat() - 0.1F < d) { 79 | this.entityDropItem(itemStack, 0.0F); 80 | } 81 | 82 | equipLootStack(equipmentSlot, itemStack); 83 | return true; 84 | } else { 85 | return false; 86 | } 87 | } else { 88 | return false; 89 | } 90 | } 91 | 92 | public double getDropChance(int equipmentSlot) { 93 | return this.equipmentDropChances[equipmentSlot]; 94 | } 95 | 96 | public boolean prefersNewEquipment(ItemStack itemstack, ItemStack itemstack1) { 97 | boolean flag = true; 98 | if (itemstack1 != null) 99 | { 100 | //if (i == 0) 101 | //{ 102 | if (itemstack.getItem() instanceof ItemSword && !(itemstack1.getItem() instanceof ItemSword)) 103 | { 104 | flag = true; 105 | } 106 | else if (itemstack.getItem() instanceof ItemSword && itemstack1.getItem() instanceof ItemSword) 107 | { 108 | ItemSword itemsword = (ItemSword)itemstack.getItem(); 109 | ItemSword itemsword1 = (ItemSword)itemstack1.getItem(); 110 | 111 | if (itemsword.func_150931_i() == itemsword1.func_150931_i()) 112 | { 113 | flag = itemstack.getItemDamage() > itemstack1.getItemDamage() || itemstack.hasTagCompound() && !itemstack1.hasTagCompound(); 114 | } 115 | else 116 | { 117 | flag = itemsword.func_150931_i() > itemsword1.func_150931_i(); 118 | } 119 | } 120 | //else 121 | //{ 122 | // flag = false; 123 | //} 124 | //} 125 | else if (itemstack.getItem() instanceof ItemArmor && !(itemstack1.getItem() instanceof ItemArmor)) 126 | { 127 | flag = true; 128 | } 129 | else if (itemstack.getItem() instanceof ItemArmor && itemstack1.getItem() instanceof ItemArmor) 130 | { 131 | ItemArmor itemarmor = (ItemArmor)itemstack.getItem(); 132 | ItemArmor itemarmor1 = (ItemArmor)itemstack1.getItem(); 133 | 134 | if (itemarmor.damageReduceAmount == itemarmor1.damageReduceAmount) 135 | { 136 | flag = itemstack.getItemDamage() > itemstack1.getItemDamage() || itemstack.hasTagCompound() && !itemstack1.hasTagCompound(); 137 | } 138 | else 139 | { 140 | flag = itemarmor.damageReduceAmount > itemarmor1.damageReduceAmount; 141 | } 142 | } 143 | else 144 | { 145 | flag = false; 146 | } 147 | } 148 | return flag; 149 | } 150 | 151 | protected void equipLootStack(int slot, ItemStack stack) { 152 | this.setCurrentItemOrArmor(slot, stack); 153 | this.equipmentDropChances[slot] = 2.0F; 154 | this.persistenceRequired = true; 155 | } 156 | 157 | public boolean canPickupItem(ItemStack stack) { 158 | return true; 159 | } 160 | 161 | } 162 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/mixin/MixinEntityLivingBase.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.mixin; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.ModifyVariable; 7 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 8 | 9 | import makamys.dmod.entity.EntityFox; 10 | import net.minecraft.entity.Entity; 11 | import net.minecraft.entity.EntityLivingBase; 12 | import net.minecraft.util.DamageSource; 13 | 14 | @Mixin(EntityLivingBase.class) 15 | public abstract class MixinEntityLivingBase { 16 | 17 | DamageSource lastDamageSource; 18 | 19 | @Inject(method = "onDeath", at = @At("HEAD")) 20 | public void preOnDeath(DamageSource src, CallbackInfo ci) { 21 | lastDamageSource = src; 22 | } 23 | 24 | @ModifyVariable(method = "onDeath", at = @At("STORE"), name = "i", ordinal = 0) 25 | public int lootingModifier(int value) { 26 | Entity entity = lastDamageSource.getEntity(); 27 | if(entity instanceof EntityFox) { 28 | value = ((EntityFox)entity).getLootingLevel(); 29 | } 30 | return value; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/mixin/MixinEntityWolf.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.mixin; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 7 | 8 | import makamys.dmod.entity.EntityFox; 9 | import net.minecraft.entity.ai.EntityAITargetNonTamed; 10 | import net.minecraft.entity.passive.EntityTameable; 11 | import net.minecraft.entity.passive.EntityWolf; 12 | import net.minecraft.world.World; 13 | 14 | @Mixin(EntityWolf.class) 15 | public abstract class MixinEntityWolf extends EntityTameable { 16 | 17 | public MixinEntityWolf(World p_i1604_1_) { 18 | super(p_i1604_1_); 19 | } 20 | 21 | @Inject(method = "*", at = @At("RETURN")) 22 | public void postConstructed(CallbackInfo ci) { 23 | this.targetTasks.addTask(targetTasks.taskEntries.size(), new EntityAITargetNonTamed((EntityWolf)(Object)this, EntityFox.class, 200, false)); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/mixin/MixinRenderItem.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.mixin; 2 | 3 | import org.spongepowered.asm.mixin.Mixin; 4 | import org.spongepowered.asm.mixin.injection.At; 5 | import org.spongepowered.asm.mixin.injection.Inject; 6 | import org.spongepowered.asm.mixin.injection.ModifyVariable; 7 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 8 | 9 | import makamys.dmod.future.item.ItemFuture; 10 | import net.minecraft.client.gui.FontRenderer; 11 | import net.minecraft.client.renderer.entity.RenderItem; 12 | import net.minecraft.client.renderer.texture.TextureManager; 13 | import net.minecraft.item.ItemStack; 14 | 15 | @Mixin(RenderItem.class) 16 | public abstract class MixinRenderItem { 17 | 18 | ItemStack lastStack; 19 | 20 | @Inject(method = "renderItemOverlayIntoGUI(Lnet/minecraft/client/gui/FontRenderer;Lnet/minecraft/client/renderer/texture/TextureManager;Lnet/minecraft/item/ItemStack;IILjava/lang/String;)V", at = @At(value = "HEAD")) 21 | private void preRenderItemOverlayIntoGUI(FontRenderer fontRenderer, TextureManager textureManager, ItemStack stack, int x, int y, String string, CallbackInfo ci) { 22 | lastStack = stack; 23 | } 24 | 25 | @ModifyVariable(method = "renderItemOverlayIntoGUI(Lnet/minecraft/client/gui/FontRenderer;Lnet/minecraft/client/renderer/texture/TextureManager;Lnet/minecraft/item/ItemStack;IILjava/lang/String;)V", at = @At(value = "STORE"), name = "l") 26 | private int getBarColor(int old) { 27 | if(lastStack.getItem() instanceof ItemFuture) { 28 | ItemFuture item = (ItemFuture)lastStack.getItem(); 29 | if(item.getItemBarHasColor(lastStack)) { 30 | return item.getItemBarColor(lastStack); 31 | } 32 | } 33 | return old; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/proxy/DProxyClient.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.proxy; 2 | 3 | import static makamys.dmod.DModConstants.LOGGER; 4 | 5 | import cpw.mods.fml.client.registry.RenderingRegistry; 6 | import cpw.mods.fml.common.Loader; 7 | import cpw.mods.fml.common.eventhandler.SubscribeEvent; 8 | import makamys.dmod.ConfigDMod; 9 | import makamys.dmod.client.render.ModelFox; 10 | import makamys.dmod.client.render.RenderFox; 11 | import makamys.dmod.compat.NEICompat; 12 | import makamys.dmod.entity.EntityFox; 13 | import makamys.dmod.future.item.ItemFuture; 14 | import net.minecraftforge.event.entity.player.ItemTooltipEvent; 15 | 16 | public class DProxyClient extends DProxyCommon { 17 | 18 | @Override 19 | public void init() { 20 | super.init(); 21 | 22 | if(ConfigDMod.enableFox) { 23 | RenderingRegistry.registerEntityRenderingHandler(EntityFox.class, new RenderFox(new ModelFox(), 0.4F)); 24 | } 25 | 26 | // TODO don't crash if chicken is not present 27 | if(Loader.isModLoaded("NotEnoughItems")) { 28 | NEICompat.init(); 29 | } else { 30 | LOGGER.warn("NotEnoughItems was not found. Some optional features will not work."); 31 | } 32 | } 33 | 34 | @SubscribeEvent 35 | public void onItemTooltip(ItemTooltipEvent event) { 36 | if(event.itemStack.getItem() instanceof ItemFuture) { 37 | ((ItemFuture)event.itemStack.getItem()).appendTooltip(event.itemStack, event.entity.worldObj, event.toolTip); 38 | } 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/proxy/DProxyCommon.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.proxy; 2 | 3 | import static makamys.dmod.DModConstants.LOGGER; 4 | 5 | import java.util.List; 6 | import java.util.stream.Collectors; 7 | 8 | import com.google.common.cache.Cache; 9 | import com.google.common.cache.CacheBuilder; 10 | 11 | import cpw.mods.fml.common.eventhandler.SubscribeEvent; 12 | import cpw.mods.fml.common.registry.EntityRegistry; 13 | import makamys.dmod.ConfigDMod; 14 | import makamys.dmod.DMod; 15 | import makamys.dmod.compat.Compat; 16 | import makamys.dmod.entity.EntityFox; 17 | import makamys.dmod.future.entity.passive.EntityAnimalFuture; 18 | import makamys.dmod.util.DUtil; 19 | import makamys.dmod.util.EggHelper; 20 | import net.minecraft.entity.EntityLivingBase; 21 | import net.minecraft.entity.EnumCreatureType; 22 | import net.minecraft.entity.item.EntityItem; 23 | import net.minecraft.entity.passive.EntityChicken; 24 | import net.minecraft.entity.player.EntityPlayer; 25 | import net.minecraft.init.Items; 26 | import net.minecraft.item.Item; 27 | import net.minecraft.world.biome.BiomeGenBase; 28 | import net.minecraftforge.common.BiomeDictionary; 29 | import net.minecraftforge.event.entity.item.ItemTossEvent; 30 | import net.minecraftforge.event.entity.living.LivingDropsEvent; 31 | import net.minecraftforge.event.entity.living.LivingFallEvent; 32 | 33 | public class DProxyCommon { 34 | 35 | public Cache itemDropperMap = CacheBuilder.newBuilder().maximumSize(1000).build(); 36 | 37 | public void init() { 38 | Compat.init(); 39 | 40 | if(ConfigDMod.enableFox) { 41 | EntityRegistry.registerModEntity(EntityFox.class, "fox", 0, DMod.instance, 64, 1, true); 42 | 43 | List foxBiomes = DUtil.getBiomesMatchingTag(BiomeDictionary.Type.CONIFEROUS); 44 | LOGGER.debug("Fox spawn biomes: " + String.join(", ", foxBiomes.stream().map(b -> b.biomeName + " (" + b.getClass().getName() + ")").collect(Collectors.toList()))); 45 | EntityRegistry.addSpawn(EntityFox.class, 8, 2, 4, EnumCreatureType.creature, foxBiomes.toArray(new BiomeGenBase[] {})); 46 | EggHelper.addEgg(EntityFox.class, 14005919, 13396256); 47 | } 48 | } 49 | 50 | @SubscribeEvent 51 | public void onLivingFall(LivingFallEvent event) { 52 | if(event.entity instanceof EntityAnimalFuture) { 53 | event.distance = ((EntityAnimalFuture)event.entity).computeFallDistance(event.distance); 54 | } 55 | } 56 | 57 | @SubscribeEvent 58 | public void onLivingDrops(LivingDropsEvent event) { 59 | if(event.source.getEntity() instanceof EntityFox) { 60 | EntityFox fox = (EntityFox)event.source.getEntity(); 61 | int looting = fox.getLootingLevel(); 62 | EntityLivingBase victim = event.entityLiving; 63 | if(victim instanceof EntityChicken) { 64 | int extraChicken = victim.getRNG().nextInt(1 + looting); 65 | for(EntityItem entityItem : event.drops) { 66 | Item item = entityItem.getEntityItem().getItem(); 67 | if(item == Items.cooked_chicken || item == Items.chicken) { 68 | entityItem.getEntityItem().stackSize += extraChicken; 69 | } 70 | } 71 | } 72 | } 73 | } 74 | 75 | @SubscribeEvent 76 | public void onItemTossEvent(ItemTossEvent event) { 77 | itemDropperMap.put(event.entityItem, event.player); 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/util/DUtil.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.util; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.UUID; 6 | import java.util.function.Predicate; 7 | 8 | import net.minecraft.command.IEntitySelector; 9 | import net.minecraft.entity.Entity; 10 | import net.minecraft.item.Item; 11 | import net.minecraft.item.ItemStack; 12 | import net.minecraft.world.biome.BiomeGenBase; 13 | import net.minecraftforge.common.BiomeDictionary; 14 | 15 | public class DUtil { 16 | public static UUID UUIDorNullFromString(String str) { 17 | return str == null || str.isEmpty() ? null : UUID.fromString(str); 18 | } 19 | 20 | public static BiomeGenBase getMutation(BiomeGenBase base) { 21 | return BiomeGenBase.getBiomeGenArray()[base.biomeID + 128]; 22 | } 23 | 24 | public static String getItemStackParticleName(ItemStack p_71010_1_) { 25 | String s = "iconcrack_" + Item.getIdFromItem(p_71010_1_.getItem()); 26 | 27 | if (p_71010_1_.getHasSubtypes()) 28 | { 29 | s = s + "_" + p_71010_1_.getItemDamage(); 30 | } 31 | return s; 32 | } 33 | 34 | public static List getBiomesMatchingTag(BiomeDictionary.Type tag){ 35 | BiomeGenBase[] biomes = BiomeGenBase.getBiomeGenArray(); 36 | List list = new ArrayList<>(); 37 | for(int i = 0; i < biomes.length; i++) { 38 | BiomeGenBase biome = biomes[i]; 39 | if(biome != null && BiomeDictionary.isBiomeOfType(biome, tag)) { 40 | list.add(biome); 41 | if(i + 128 < biomes.length) { 42 | BiomeGenBase mutatedMaybe = biomes[i + 128]; 43 | if(biome.isEqualTo(mutatedMaybe)) { 44 | list.add(mutatedMaybe); 45 | } 46 | } 47 | } 48 | } 49 | return list; 50 | } 51 | 52 | /** Helper function that lets you create an IEntitySelector as a lambda. 53 | * Not using this will cause a crash in a production environment, because lambdas don't get obfuscated. */ 54 | public static IEntitySelector entitySelector(Predicate predicate) { 55 | return new IEntitySelector() { 56 | @Override 57 | public boolean isEntityApplicable(Entity entity) { 58 | return predicate.test(entity); 59 | } 60 | }; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/util/EggHelper.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.util; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import net.minecraft.entity.Entity; 7 | import net.minecraft.entity.EntityList; 8 | import net.minecraft.entity.EntityList.EntityEggInfo; 9 | 10 | public class EggHelper { 11 | 12 | private static Map, Integer> addedEggIDs = new HashMap<>(); 13 | 14 | public static void addEgg(Class clazz, int color1, int color2) { 15 | int eggID = getNextFreeEggSlot(); 16 | EntityList.IDtoClassMapping.put(eggID, clazz); 17 | EntityList.entityEggs.put(eggID, new EntityEggInfo(eggID, color1, color2)); 18 | addedEggIDs.put(clazz, eggID); 19 | } 20 | 21 | public static int getIDForClass(Class clazz) { 22 | return addedEggIDs.getOrDefault(clazz, -1); 23 | } 24 | 25 | public static int getNextFreeEggSlot() { 26 | int eggID = 0; 27 | while(EntityList.getStringFromID(eggID) != null) { 28 | eggID++; 29 | } 30 | return eggID; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/util/StatRegistry.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.util; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import cpw.mods.fml.common.Mod.EventHandler; 7 | import cpw.mods.fml.common.event.FMLServerStartingEvent; 8 | import cpw.mods.fml.common.event.FMLServerStoppedEvent; 9 | import net.minecraft.item.Item; 10 | import net.minecraft.item.ItemBlock; 11 | import net.minecraft.item.ItemStack; 12 | import net.minecraft.stats.StatBase; 13 | import net.minecraft.stats.StatCrafting; 14 | import net.minecraft.stats.StatList; 15 | import net.minecraft.util.ChatComponentTranslation; 16 | 17 | // TODO support crafting and depletion too 18 | public class StatRegistry { 19 | 20 | public static StatRegistry instance = new StatRegistry(); 21 | 22 | private static List items = new ArrayList<>(); 23 | 24 | private boolean applied = false; 25 | 26 | public static void registerItem(Item item) { 27 | if (item != null) { 28 | items.add(new RegistryInfo(item)); 29 | } 30 | } 31 | 32 | private static void clearIDs() { 33 | for(RegistryInfo info : items) { 34 | StatList.itemStats.remove(info.stat); 35 | StatList.objectUseStats[info.id] = null; 36 | 37 | info.id = -1; 38 | } 39 | } 40 | 41 | @EventHandler 42 | public void onServerStarting(FMLServerStartingEvent event) { 43 | for(RegistryInfo info : items) { 44 | Item item = info.item; 45 | info.id = Item.getIdFromItem(item); 46 | if(info.stat == null) { 47 | info.stat = (new StatCrafting("stat.useItem." + item.getUnlocalizedName(), new ChatComponentTranslation("stat.useItem", new Object[] {(new ItemStack(item)).func_151000_E()}), item)).registerStat(); 48 | } 49 | 50 | StatList.objectUseStats[info.id] = info.stat; 51 | 52 | if (!(item instanceof ItemBlock)) { 53 | StatList.itemStats.add(info.stat); 54 | } 55 | } 56 | applied = true; 57 | } 58 | 59 | @EventHandler 60 | public void onServerStopped(FMLServerStoppedEvent event) { 61 | if(applied) { 62 | clearIDs(); 63 | applied = false; 64 | } 65 | } 66 | 67 | private static class RegistryInfo { 68 | public Item item; 69 | public int id = -1; 70 | public StatBase stat; 71 | 72 | public RegistryInfo(Item item) { 73 | this.item = item; 74 | } 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/makamys/dmod/util/WeightedRandomItem.java: -------------------------------------------------------------------------------- 1 | package makamys.dmod.util; 2 | 3 | import net.minecraft.util.WeightedRandom; 4 | 5 | public class WeightedRandomItem extends WeightedRandom.Item { 6 | 7 | public T data; 8 | 9 | public WeightedRandomItem(int weight, T data) { 10 | super(weight); 11 | this.data = data; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/dmod_at.cfg: -------------------------------------------------------------------------------- 1 | public net.minecraft.item.ItemFood field_77851_ca #potionId 2 | public net.minecraft.item.ItemFood field_77850_cb #potionDuration 3 | public net.minecraft.item.ItemFood field_77858_cd #potionEffectProbability 4 | public net.minecraft.item.ItemFood field_77850_cb #potionDuration 5 | public net.minecraft.item.ItemFood field_77857_cc #potionAmplifier 6 | 7 | protected net.minecraft.entity.ai.EntityAIMate func_75388_i()V #spawnBaby() 8 | protected net.minecraft.entity.ai.EntityAIMate field_75390_d #theAnimal 9 | protected net.minecraft.entity.ai.EntityAIMate field_75391_e #targetMate 10 | 11 | public net.minecraft.block.Block func_149642_a(Lnet/minecraft/world/World;IIILnet/minecraft/item/ItemStack;)V #dropBlockAsItem 12 | 13 | protected net.minecraft.entity.ai.EntityAINearestAttackableTarget field_75308_c #targetChance 14 | protected net.minecraft.entity.ai.EntityAITarget field_75303_a #nearbyOnly 15 | protected net.minecraft.entity.ai.EntityAITarget field_75302_c #targetSearchDelay 16 | protected net.minecraft.entity.ai.EntityAITarget field_75301_b #targetSearchStatus 17 | protected net.minecraft.entity.ai.EntityAINearestAttackableTarget field_75309_a #targetEntity 18 | protected net.minecraft.entity.ai.EntityAITarget func_75295_a(Lnet/minecraft/entity/EntityLivingBase;)Z #canEasilyReach -------------------------------------------------------------------------------- /src/main/resources/assets/dmod/lang/en_US.lang: -------------------------------------------------------------------------------- 1 | item.dmod.bundle.name=Bundle 2 | item.dmod.bundle.fullness=%s/%s 3 | 4 | entity.dmod.fox.name=Fox 5 | -------------------------------------------------------------------------------- /src/main/resources/assets/dmod/lang/zh_CN.lang: -------------------------------------------------------------------------------- 1 | item.dmod.bundle.name=收纳袋 2 | item.dmod.bundle.fullness=%s/%s 3 | 4 | entity.dmod.fox.name=狐狸 5 | -------------------------------------------------------------------------------- /src/main/resources/assets/dmod/sounds.json: -------------------------------------------------------------------------------- 1 | { 2 | "entity.fox.ambient": { 3 | "sounds": [ 4 | { 5 | "name": "minecraft:mob/fox/idle1", 6 | "volume": 0.8 7 | }, 8 | { 9 | "name": "minecraft:mob/fox/idle2", 10 | "volume": 1 11 | }, 12 | { 13 | "name": "minecraft:mob/fox/idle3", 14 | "volume": 1 15 | }, 16 | { 17 | "name": "minecraft:mob/fox/idle4", 18 | "volume": 1 19 | }, 20 | { 21 | "name": "minecraft:mob/fox/idle5", 22 | "volume": 1 23 | }, 24 | { 25 | "name": "minecraft:mob/fox/idle6", 26 | "volume": 1 27 | } 28 | ], 29 | "subtitle": "subtitles.entity.fox.ambient" 30 | }, 31 | "entity.fox.hurt": { 32 | "sounds": [ 33 | { 34 | "name": "minecraft:mob/fox/hurt1", 35 | "volume": 0.75 36 | }, 37 | { 38 | "name": "minecraft:mob/fox/hurt2", 39 | "volume": 0.75 40 | }, 41 | { 42 | "name": "minecraft:mob/fox/hurt3", 43 | "volume": 0.75 44 | }, 45 | { 46 | "name": "minecraft:mob/fox/hurt4", 47 | "volume": 0.75 48 | } 49 | ], 50 | "subtitle": "subtitles.entity.fox.hurt" 51 | }, 52 | "entity.fox.death": { 53 | "sounds": [ 54 | { 55 | "name": "minecraft:mob/fox/death1", 56 | "volume": 0.9 57 | }, 58 | { 59 | "name": "minecraft:mob/fox/death2", 60 | "volume": 0.9 61 | } 62 | ], 63 | "subtitle": "subtitles.entity.fox.death" 64 | }, 65 | "entity.fox.aggro": { 66 | "sounds": [ 67 | { 68 | "name": "minecraft:mob/fox/aggro1", 69 | "volume": 0.65 70 | }, 71 | { 72 | "name": "minecraft:mob/fox/aggro2", 73 | "volume": 0.65 74 | }, 75 | { 76 | "name": "minecraft:mob/fox/aggro3", 77 | "volume": 0.65 78 | }, 79 | { 80 | "name": "minecraft:mob/fox/aggro4", 81 | "volume": 0.65 82 | }, 83 | { 84 | "name": "minecraft:mob/fox/aggro5", 85 | "volume": 0.65 86 | }, 87 | { 88 | "name": "minecraft:mob/fox/aggro6", 89 | "volume": 0.65 90 | }, 91 | { 92 | "name": "minecraft:mob/fox/aggro7", 93 | "volume": 0.65 94 | } 95 | ], 96 | "subtitle": "subtitles.entity.fox.aggro" 97 | }, 98 | "entity.fox.sniff": { 99 | "sounds": [ 100 | { 101 | "name": "minecraft:mob/fox/sniff1", 102 | "volume": 0.6 103 | }, 104 | { 105 | "name": "minecraft:mob/fox/sniff2", 106 | "volume": 0.6 107 | }, 108 | { 109 | "name": "minecraft:mob/fox/sniff3", 110 | "volume": 0.6 111 | }, 112 | { 113 | "name": "minecraft:mob/fox/sniff4", 114 | "volume": 0.6 115 | } 116 | ], 117 | "subtitle": "subtitles.entity.fox.sniff" 118 | }, 119 | "entity.fox.bite": { 120 | "sounds": [ 121 | { 122 | "name": "minecraft:mob/fox/bite1", 123 | "volume": 0.6, 124 | "pitch": 1.1 125 | }, 126 | { 127 | "name": "minecraft:mob/fox/bite2", 128 | "volume": 0.6, 129 | "pitch": 1.1 130 | }, 131 | { 132 | "name": "minecraft:mob/fox/bite3", 133 | "volume": 0.6, 134 | "pitch": 1.1 135 | } 136 | ], 137 | "subtitle": "subtitles.entity.fox.bite" 138 | }, 139 | "entity.fox.eat": { 140 | "sounds": [ 141 | { 142 | "name": "minecraft:mob/fox/eat1", 143 | "volume": 0.65 144 | }, 145 | { 146 | "name": "minecraft:mob/fox/eat2", 147 | "volume": 0.65 148 | }, 149 | { 150 | "name": "minecraft:mob/fox/eat3", 151 | "volume": 0.65 152 | } 153 | ], 154 | "subtitle": "subtitles.entity.fox.eat" 155 | }, 156 | "entity.fox.screech": { 157 | "sounds": [ 158 | { 159 | "name": "minecraft:mob/fox/screech1", 160 | "attenuation_distance": 32, 161 | "volume": 0.45 162 | }, 163 | { 164 | "name": "minecraft:mob/fox/screech2", 165 | "attenuation_distance": 32, 166 | "volume": 0.45 167 | }, 168 | { 169 | "name": "minecraft:mob/fox/screech3", 170 | "attenuation_distance": 32, 171 | "volume": 0.45 172 | }, 173 | { 174 | "name": "minecraft:mob/fox/screech4", 175 | "attenuation_distance": 32, 176 | "volume": 0.4 177 | } 178 | ], 179 | "subtitle": "subtitles.entity.fox.screech" 180 | }, 181 | "entity.fox.sleep": { 182 | "sounds": [ 183 | { 184 | "name": "minecraft:mob/fox/sleep1", 185 | "volume": 0.8 186 | }, 187 | { 188 | "name": "minecraft:mob/fox/sleep2", 189 | "volume": 0.8 190 | }, 191 | { 192 | "name": "minecraft:mob/fox/sleep3", 193 | "volume": 0.8 194 | }, 195 | { 196 | "name": "minecraft:mob/fox/sleep4", 197 | "volume": 0.8 198 | }, 199 | { 200 | "name": "minecraft:mob/fox/sleep5", 201 | "volume": 0.8 202 | } 203 | ], 204 | "subtitle": "subtitles.entity.fox.sleep" 205 | }, 206 | "entity.fox.spit": { 207 | "sounds": [ 208 | { 209 | "name": "minecraft:mob/fox/spit1", 210 | "volume": 0.7 211 | }, 212 | { 213 | "name": "minecraft:mob/fox/spit2", 214 | "volume": 0.7 215 | }, 216 | { 217 | "name": "minecraft:mob/fox/spit3", 218 | "volume": 0.7 219 | } 220 | ], 221 | "subtitle": "subtitles.entity.fox.spit" 222 | }, 223 | "entity.fox.teleport": { 224 | "sounds": [ 225 | "minecraft:mob/endermen/portal", 226 | "minecraft:mob/endermen/portal2" 227 | ], 228 | "subtitle": "subtitles.entity.fox.teleport" 229 | } 230 | } 231 | -------------------------------------------------------------------------------- /src/main/resources/assets/dmod/textures/gui/container/bundle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/dmod/textures/gui/container/bundle.png -------------------------------------------------------------------------------- /src/main/resources/assets/dmod/textures/items/bundle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/dmod/textures/items/bundle.png -------------------------------------------------------------------------------- /src/main/resources/assets/dmod/textures/items/bundle_filled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/dmod/textures/items/bundle_filled.png -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/aggro1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/aggro1.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/aggro2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/aggro2.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/aggro3.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/aggro3.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/aggro4.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/aggro4.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/aggro5.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/aggro5.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/aggro6.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/aggro6.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/aggro7.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/aggro7.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/bite1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/bite1.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/bite2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/bite2.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/bite3.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/bite3.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/death1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/death1.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/death2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/death2.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/eat1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/eat1.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/eat2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/eat2.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/eat3.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/eat3.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/hurt1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/hurt1.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/hurt2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/hurt2.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/hurt3.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/hurt3.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/hurt4.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/hurt4.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/idle1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/idle1.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/idle2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/idle2.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/idle3.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/idle3.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/idle4.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/idle4.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/idle5.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/idle5.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/idle6.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/idle6.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/screech1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/screech1.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/screech2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/screech2.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/screech3.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/screech3.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/screech4.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/screech4.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/sleep1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/sleep1.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/sleep2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/sleep2.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/sleep3.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/sleep3.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/sleep4.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/sleep4.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/sleep5.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/sleep5.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/sniff1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/sniff1.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/sniff2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/sniff2.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/sniff3.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/sniff3.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/sniff4.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/sniff4.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/spit1.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/spit1.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/spit2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/spit2.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/sounds/mob/fox/spit3.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/sounds/mob/fox/spit3.ogg -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/textures/entity/fox/fox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/textures/entity/fox/fox.png -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/textures/entity/fox/fox_sleep.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/textures/entity/fox/fox_sleep.png -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/textures/entity/fox/snow_fox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/textures/entity/fox/snow_fox.png -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/textures/entity/fox/snow_fox_sleep.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/makamys/DMod/d9ae747f3a87ac8451245bcc97e5aea4fa08a261/src/main/resources/assets/minecraft/textures/entity/fox/snow_fox_sleep.png -------------------------------------------------------------------------------- /src/main/resources/dmod.mixin.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "minVersion": "0.6", 4 | "package": "makamys.dmod.mixin", 5 | "refmap": "dmod.mixin.refmap.json", 6 | "compatibilityLevel": "JAVA_8", 7 | "mixins": [ 8 | "MixinEntityLiving", 9 | "MixinEntityWolf", 10 | "MixinEntityLivingBase", 11 | "MixinContainer", 12 | "MixinRenderItem" 13 | ], 14 | "plugin": "makamys.dmod.MixinConfigPlugin" 15 | } 16 | -------------------------------------------------------------------------------- /src/main/resources/mcmod.info: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "modid": "${modid}", 4 | "name": "D-Mod", 5 | "description": "Yet another backport mod. Featuring foxes and bundles.", 6 | "version": "${version}", 7 | "mcversion": "${minecraft_version}", 8 | "url": "", 9 | "updateUrl": "", 10 | "authorList": ["makamys"], 11 | "credits": "Mojang for providing the original features", 12 | "logoFile": "", 13 | "screenshots": [], 14 | "dependencies": [] 15 | } 16 | ] 17 | -------------------------------------------------------------------------------- /updatejson/update.json: -------------------------------------------------------------------------------- 1 | { 2 | "homepage": "https://github.com/makamys/DMod/releases", 3 | "1.7.10": { 4 | "1.0": "", 5 | "1.0.1": "", 6 | "1.0.2": "", 7 | "1.0.3": "", 8 | "1.0.3.1": "", 9 | "1.0.3.2": "", 10 | "1.0.3.3": "", 11 | "1.0.3.4": "", 12 | "1.0.3.5": "" 13 | }, 14 | "promos": { 15 | "1.7.10-latest": "1.0.3.5" 16 | } 17 | } --------------------------------------------------------------------------------