├── .gitattributes ├── .github └── workflows │ ├── build.yml │ └── release.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── build.gradle ├── deps ├── GalacticraftCore-1.12.2-4.0.2.280-deobf.jar └── MicdoodleCore-1.12.2-4.0.2.280-deobf.jar ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src └── main ├── java └── com │ └── fuzs │ └── aquaacrobatics │ ├── AquaAcrobatics.java │ ├── biome │ └── BiomeWaterFogColors.java │ ├── block │ └── BlockBubbleColumn.java │ ├── client │ ├── entity │ │ └── IPlayerSPSwimming.java │ ├── gui │ │ └── GuiNoMixin.java │ ├── handler │ │ ├── AirMeterHandler.java │ │ ├── FogHandler.java │ │ └── NoMixinHandler.java │ ├── model │ │ ├── IModelBipedSwimming.java │ │ └── WaterResourcePack.java │ └── particle │ │ ├── ParticleBubbleColumnUp.java │ │ └── ParticleCurrentDown.java │ ├── config │ └── ConfigHandler.java │ ├── core │ ├── AquaAcrobaticsCore.java │ ├── AquaAcrobaticsMixinPlugin.java │ ├── AquaAcrobaticsSetupHook.java │ ├── ModCompatMixinHandler.java │ ├── UnderwaterGrassLikeHandler.java │ ├── galacticraft │ │ └── mixin │ │ │ ├── GCEntityClientPlayerMPMixin.java │ │ │ └── GalacticraftCoreMixin.java │ ├── journeymap55 │ │ └── mixin │ │ │ └── client │ │ │ └── VanillaBlockSpriteProxyMixin.java │ ├── journeymap57 │ │ └── mixin │ │ │ └── client │ │ │ └── VanillaBlockSpriteProxyMixin.java │ ├── mixin │ │ ├── BiomeColorHelperMixin.java │ │ ├── BiomeMixin.java │ │ ├── BlockGrassMixin.java │ │ ├── BlockLiquidMixin.java │ │ ├── BlockMagmaMixin.java │ │ ├── BlockMyceliumMixin.java │ │ ├── BlockSoulSandMixin.java │ │ ├── EntityBoatMixin.java │ │ ├── EntityItemMixin.java │ │ ├── EntityLivingBaseMixin.java │ │ ├── EntityMixin.java │ │ ├── EntityPlayerMPMixin.java │ │ ├── EntityPlayerMixin.java │ │ ├── EntityThrowableMixin.java │ │ ├── NetHandlerPlayServerMixin.java │ │ ├── accessor │ │ │ ├── FluidAccessor.java │ │ │ └── IEventBusAccessor.java │ │ └── client │ │ │ ├── BlockAliasesBubbleColumnMixin.java │ │ │ ├── BlockFluidRendererMixin.java │ │ │ ├── EntityPlayerSPMixin.java │ │ │ ├── EntityRendererMixin.java │ │ │ ├── ItemRendererMixin.java │ │ │ ├── ModelBipedMixin.java │ │ │ ├── ModelFluidMixin.java │ │ │ ├── PlayerControllerMPMixin.java │ │ │ ├── RenderBoatMixin.java │ │ │ └── RenderPlayerMixin.java │ ├── thaumcraft │ │ └── mixin │ │ │ └── client │ │ │ └── TileCrucibleRendererMixin.java │ └── xaerosminimap │ │ └── mixin │ │ └── client │ │ └── MinimapWriterMixin.java │ ├── entity │ ├── EntitySize.java │ ├── IBubbleColumnInteractable.java │ ├── IRockableBoat.java │ ├── Pose.java │ └── player │ │ └── IPlayerResizeable.java │ ├── handler │ └── CommonHandler.java │ ├── integration │ ├── IElytraOpenHook.java │ ├── IntegrationManager.java │ ├── ae2 │ │ └── AE2Integration.java │ ├── artemislib │ │ ├── ArtemisLibIntegration.java │ │ └── AttachAttributesFix.java │ ├── betweenlands │ │ └── BetweenlandsIntegration.java │ ├── chiseledme │ │ └── ChiseledMeIntegration.java │ ├── enderio │ │ └── EnderIOIntegration.java │ ├── hats │ │ └── HatsIntegration.java │ ├── mobends │ │ ├── MoBendsIntegration.java │ │ └── SwimmingPlayerData.java │ ├── morph │ │ └── MorphIntegration.java │ ├── thaumicaugmentation │ │ └── ThaumicAugmentationIntegration.java │ ├── trinketsandbaubles │ │ └── TrinketsAndBaublesIntegration.java │ ├── wings │ │ └── WingsIntegration.java │ └── witchery │ │ └── WitcheryResurrectedIntegration.java │ ├── network │ ├── NetworkHandler.java │ ├── datasync │ │ └── PoseSerializer.java │ └── message │ │ └── PacketSendKey.java │ ├── optifine │ └── OptifineHelper.java │ ├── proxy │ ├── ClientProxy.java │ └── CommonProxy.java │ └── util │ ├── Keybindings.java │ ├── MovementInputStorage.java │ └── math │ ├── AxisAlignedBBSpliterator.java │ ├── CubeCoordinateIterator.java │ └── MathHelperNew.java └── resources ├── META-INF ├── mixins.aquaacrobatics.galacticraft.json ├── mixins.aquaacrobatics.journeymap55.json ├── mixins.aquaacrobatics.journeymap57.json ├── mixins.aquaacrobatics.json ├── mixins.aquaacrobatics.thaumcraft.json └── mixins.aquaacrobatics.xaerosminimap.json ├── assets └── aquaacrobatics │ ├── blockstates │ └── bubble_column.json │ ├── lang │ ├── en_us.lang │ └── zh_cn.lang │ ├── overrides │ └── textures │ │ └── blocks │ │ ├── water_flow.png │ │ ├── water_flow.png.mcmeta │ │ ├── water_overlay.png │ │ ├── water_still.png │ │ └── water_still.png.mcmeta │ └── textures │ └── blocks │ ├── water_flow.png │ ├── water_flow.png.mcmeta │ ├── water_still.png │ └── water_still.png.mcmeta ├── mcmod.info ├── pack.mcmeta └── water_pack.mcmeta /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | /gradlew text eol=lf 4 | *.bat text eol=crlf 5 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build mod 2 | 3 | on: [ push, pull_request ] 4 | 5 | jobs: 6 | build: 7 | name: Build mod 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v4 12 | - name: Validate gradle wrapper checksum 13 | uses: gradle/wrapper-validation-action@v1 14 | - name: Set up JDK 15 | uses: actions/setup-java@v4 16 | with: 17 | distribution: 'zulu' 18 | java-version: | 19 | 8 20 | 17 21 | cache: 'gradle' 22 | - name: Grant execute permission for gradlew 23 | run: chmod +x gradlew 24 | - name: Build with Gradle 25 | run: ./gradlew --no-daemon --stacktrace build 26 | - name: Upload artifacts 27 | uses: actions/upload-artifact@v4 28 | with: 29 | name: aqua-acrobatics 30 | path: build/libs 31 | -------------------------------------------------------------------------------- /.github/workflows/release.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: Create Release 5 | 6 | on: 7 | push: 8 | tags: 9 | - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 10 | 11 | jobs: 12 | build: 13 | name: Create Release 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v4 18 | - name: Validate gradle wrapper checksum 19 | uses: gradle/wrapper-validation-action@v1 20 | - name: Set up JDK 21 | uses: actions/setup-java@v4 22 | with: 23 | distribution: 'zulu' 24 | java-version: | 25 | 8 26 | 17 27 | cache: 'gradle' 28 | - name: Grant execute permission for gradlew 29 | run: chmod +x gradlew 30 | - name: Build with Gradle 31 | run: ./gradlew --no-daemon --stacktrace build 32 | - name: Create Release 33 | id: create_release 34 | uses: actions/create-release@v1 35 | env: 36 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token 37 | with: 38 | tag_name: ${{ github.ref }} 39 | release_name: Release ${{ github.ref }} 40 | body: | 41 | Check the commit history for changes since the last release. 42 | draft: false 43 | prerelease: false 44 | - name: Upload jars to release 45 | uses: svenstaro/upload-release-action@v1-release 46 | with: 47 | repo_token: ${{ secrets.GITHUB_TOKEN }} 48 | file: ./build/libs/* 49 | tag: ${{ github.ref }} 50 | overwrite: true 51 | file_glob: true 52 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Java ### 2 | *.class 3 | 4 | # Mobile Tools for Java (J2ME) 5 | .mtj.tmp/ 6 | 7 | # Package Files 8 | *.war 9 | *.nar 10 | *.ear 11 | *.zip 12 | *.tar.gz 13 | *.rar 14 | 15 | # Virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 16 | hs_err_pid* 17 | 18 | ### Eclipse ### 19 | bin 20 | eclipse 21 | *.launch 22 | .settings 23 | .metadata 24 | .classpath 25 | .project 26 | 27 | ### IntelliJ IDEA ### 28 | out 29 | classes 30 | *.ipr 31 | *.iws 32 | *.iml 33 | .idea 34 | 35 | ### NetBeans ### 36 | nbproject/private/ 37 | build/ 38 | nbbuild/ 39 | dist/ 40 | nbdist/ 41 | nbactions.xml 42 | .nb-gradle/ 43 | .nb-gradle-properties 44 | 45 | ### Gradle ### 46 | build 47 | .gradle 48 | 49 | # Ignore Gradle GUI config 50 | gradle-app.setting 51 | 52 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 53 | !gradle-wrapper.jar 54 | 55 | # Cache of project 56 | .gradletasknamecache 57 | 58 | ### Other ### 59 | run 60 | .DS_Store 61 | *.txt 62 | 63 | # Log file 64 | *.log 65 | 66 | # BlueJ files 67 | *.ctxt -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog]. 5 | 6 | ## [v1.15.4-1.12.2] - 2024-03-31 7 | ### Fixed 8 | - Furniture Mod mirror rendering one block too high 9 | - New projectile behavior breaking gameplay mechanics from some mods with custom projectiles 10 | 11 | ## [v1.15.2-1.12.2] - 2023-02-11 12 | ### Fixed 13 | - Crash with Trinkets & Baubles 14 | - Removed redundant Dynamic Trees fix 15 | 16 | ## [v1.15.1-1.12.2] - 2022-12-18 17 | ### Fixed 18 | - Gray water in Thaumcraft crucibles 19 | 20 | ## [v1.15.0-1.12.2] - 2022-09-05 21 | ### Added 22 | - Parity for growing AE2 crystals' buoyancy with newer versions 23 | - Config option to disable item buoyancy 24 | 25 | ## [v1.14.5-1.12.2] - 2022-09-04 26 | ### Fixed 27 | - Fixed items launching themselves out of water when floating 28 | 29 | ## [v1.14.4-1.12.2] - 2022-08-06 30 | ### Fixed 31 | - Fixed incorrect water fog color for BOP bayou 32 | 33 | ## [v1.14.3-1.12.2] - 2022-07-26 34 | ### Added 35 | - Added support for automatically uploading new builds to CurseForge using CurseGradle 36 | ### Fixed 37 | - Fixed compat with RenderPlayerAPI and Player API mods 38 | 39 | [Keep a Changelog]: https://keepachangelog.com/en/1.0.0/ 40 | -------------------------------------------------------------------------------- /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 | # Aqua Acrobatics 2 | 3 | A Minecraft mod. Downloads can be found on CurseForge. 4 | 5 | ## Using in a dev environment (for modders) 6 | 7 | Aqua Acrobatics can be included at dev time using [CurseMaven](https://www.cursemaven.com/). 8 | 9 | ``` 10 | dependencies { 11 | /* Replace the file ID with the desired version */ 12 | deobfCompile 'curse.maven:aquaacrobatics-321792:3619657' 13 | /* Only needed if you don't have Mixin already */ 14 | compile ("org.spongepowered:mixin:0.8") 15 | } 16 | ``` 17 | 18 | ![](https://i.imgur.com/9XStAol.png) 19 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | import com.gtnewhorizons.retrofuturagradle.mcp.ReobfuscatedJar 2 | import org.jetbrains.gradle.ext.Gradle 3 | 4 | plugins { 5 | id("java") 6 | id("java-library") 7 | id("maven-publish") 8 | id("org.jetbrains.gradle.plugin.idea-ext") version "1.1.7" 9 | id("eclipse") 10 | id("com.gtnewhorizons.retrofuturagradle") version "1.4.2" 11 | id("com.matthewprenger.cursegradle") version "1.4.0" 12 | } 13 | 14 | version = mod_version 15 | group = "${mod_group}" 16 | ext.version = "${mod_version}" 17 | ext.id = "${mod_id}" 18 | ext.name = "${mod_name}" 19 | ext.author = "${mod_author}" 20 | ext.description = "${mod_description}" 21 | ext.url = "${mod_url}" 22 | ext.loader = "${loader_version.replaceAll("\\..*", "")}" 23 | ext.forge = "${loader_version}" 24 | ext.mc = "${mc_version}" 25 | 26 | // Set the toolchain version to decouple the Java we run Gradle with from the Java used to compile and run the mod 27 | java { 28 | toolchain { 29 | languageVersion.set(JavaLanguageVersion.of(8)) 30 | // Azul covers the most platforms for Java 8 toolchains, crucially including MacOS arm64 31 | vendor.set(org.gradle.jvm.toolchain.JvmVendorSpec.AZUL) 32 | } 33 | // Generate sources and javadocs jars when building and publishing 34 | withSourcesJar() 35 | withJavadocJar() 36 | } 37 | 38 | minecraft { 39 | mcVersion = "1.12.2" 40 | 41 | injectedTags.put("VERSION", project.version) 42 | 43 | extraRunJvmArguments.addAll("-ea:${project.group}", "-Dmixin.debug.export=true") 44 | } 45 | 46 | tasks.injectTags.configure { 47 | outputClassName.set("${project.group}.Tags") 48 | } 49 | 50 | repositories { 51 | maven { url = "https://repo.spongepowered.org/repository/maven-public" } 52 | //maven { url "https://maven.mcmoddev.com/" } 53 | maven { 54 | url "https://cursemaven.com" 55 | content { 56 | includeGroup "curse.maven" 57 | } 58 | } 59 | ivy { 60 | url "https://witchery-api.msrandom.net/download/" 61 | patternLayout { 62 | artifact "[organisation]/[artifact]-[revision](-[classifier])(.[ext])" 63 | } 64 | content { 65 | includeGroup "WitcheryResurrected0.5.2Hotfix4" 66 | } 67 | metadataSources { artifact() } 68 | } 69 | maven { 70 | name = "Progwml6 maven" 71 | url = "https://dvs1.progwml6.com/files/maven" 72 | } 73 | maven { url = "https://maven.cil.li/" } 74 | maven { url = "https://maven.gtceu.com/" } 75 | mavenLocal() 76 | } 77 | 78 | dependencies { 79 | //compileOnly rfg.deobf("net.ilexiconn:llibrary-core:1.0.11-1.12.2") 80 | //compileOnly rfg.deobf("net.ilexiconn:llibrary:1.7.9-1.12.2") 81 | compileOnly rfg.deobf("appeng:ae2-uel:v0.56.4") 82 | compileOnly rfg.deobf("curse.maven:artemislib-313590:2741812:") 83 | api rfg.deobf("curse.maven:baubles-227083:2518667:") 84 | compileOnly rfg.deobf("curse.maven:betweenlands-243363:3540287:") 85 | compileOnly rfg.deobf("curse.maven:chiseledme-250075:3467731") 86 | compileOnly rfg.deobf("curse.maven:endercore-231868:2972849:") 87 | compileOnly rfg.deobf("curse.maven:enderio-64578:3328811:") 88 | compileOnly rfg.deobf("curse.maven:hats-229073:2960397:") 89 | compileOnly rfg.deobf("curse.maven:ichunutil-229060:2801262:") 90 | compileOnly rfg.deobf("curse.maven:journeymap-32274:2916002:") 91 | compileOnly rfg.deobf("curse.maven:mobends-231347:3573346:") 92 | compileOnly rfg.deobf("curse.maven:morph-229080:2995522:") 93 | runtimeOnly "curse.maven:naturescompass-252848:2893527:" 94 | compileOnly rfg.deobf("curse.maven:thaumcraft-223628:2629023") 95 | compileOnly rfg.deobf("curse.maven:thaumicaugmentation-319441:3536155:") 96 | compileOnly rfg.deobf("curse.maven:trinketsandbaubles-279900:3604719:") 97 | compileOnly rfg.deobf("curse.maven:wings-302584:2829351:") 98 | compileOnly rfg.deobf("curse.maven:xaerosminimap-263420:3630494:") 99 | api rfg.deobf("curse.maven:mixinbooter-419286:4459218:") 100 | compileOnly files('deps/GalacticraftCore-1.12.2-4.0.2.280-deobf.jar') 101 | compileOnly files('deps/MicdoodleCore-1.12.2-4.0.2.280-deobf.jar') 102 | compileOnly 'WitcheryResurrected0.5.2Hotfix4:WitcheryResurrected:1.12.2-0.5.2.4:forge-all' 103 | 104 | api ("org.spongepowered:mixin:0.8.3") {transitive = false} 105 | annotationProcessor('org.ow2.asm:asm-debug-all:5.2') 106 | annotationProcessor('com.google.guava:guava:24.1.1-jre') 107 | annotationProcessor('com.google.code.gson:gson:2.8.6') 108 | annotationProcessor ("org.spongepowered:mixin:0.8.3") {transitive = false} 109 | } 110 | 111 | def mixinConfigRefMap = 'mixins.' + project.ext.id + '.refmap.json' 112 | def mixinTmpDir = buildDir.path + File.separator + 'tmp' + File.separator + 'mixins' 113 | def refMap = "${mixinTmpDir}" + File.separator + mixinConfigRefMap 114 | def mixinSrg = "${mixinTmpDir}" + File.separator + "mixins.srg" 115 | 116 | tasks.named("reobfJar", ReobfuscatedJar).configure { 117 | extraSrgFiles.from(mixinSrg) 118 | } 119 | 120 | tasks.named("compileJava", JavaCompile).configure { 121 | doFirst { 122 | new File(mixinTmpDir).mkdirs() 123 | } 124 | options.compilerArgs += [ 125 | "-AreobfSrgFile=${tasks.reobfJar.srg.get().asFile}", 126 | "-AoutSrgFile=${mixinSrg}", 127 | "-AoutRefMapFile=${refMap}", 128 | ] 129 | } 130 | 131 | processResources { 132 | // this will ensure that this task is redone when the versions change. 133 | inputs.property "mod_id", project.ext.id 134 | inputs.property "mod_name", project.ext.name 135 | inputs.property "mod_name2", project.ext.name.replaceAll("\\s", "") 136 | inputs.property "mod_version", project.ext.version 137 | inputs.property "mod_group", project.group 138 | inputs.property "mod_url", project.ext.url 139 | inputs.property "mod_description", project.ext.description 140 | inputs.property "mod_author", project.ext.author 141 | inputs.property "loader_version", project.ext.loader 142 | inputs.property "forge_version", project.ext.forge 143 | inputs.property "mc_version", project.ext.mc 144 | 145 | // replace stuff in mods.toml and pack.mcmeta 146 | filesMatching(['mcmod.info', 'pack.mcmeta']) { fcd -> 147 | fcd.expand ( 148 | 'mod_id': project.ext.id, 149 | 'mod_name': project.ext.name, 150 | 'mod_name2': project.ext.name.replaceAll("\\s", ""), 151 | 'mod_version': project.ext.version, 152 | 'mod_group': project.group, 153 | 'mod_url': project.ext.url, 154 | 'mod_description': project.ext.description, 155 | 'mod_author': project.ext.author, 156 | 'loader_version': project.ext.loader, 157 | 'forge_version': project.ext.forge, 158 | 'mc_version': project.ext.mc 159 | ) 160 | } 161 | 162 | // Embed mixin refmap 163 | from refMap 164 | dependsOn("compileJava") 165 | } 166 | 167 | jar { 168 | manifest { 169 | attributes "FMLCorePlugin": project.group + ".core." + project.ext.name.replaceAll("\\s", "") + "Core" 170 | attributes "FMLCorePluginContainsFMLMod": "true" 171 | attributes "ForceLoadAsMod": "true" 172 | } 173 | } 174 | 175 | publishing { 176 | 177 | publications { 178 | 179 | mavenJava (MavenPublication) { 180 | 181 | // artifact sourceJar 182 | // artifact javadocJar 183 | from components.java 184 | } 185 | } 186 | } 187 | 188 | idea { 189 | module { inheritOutputDirs = true } 190 | project { settings { 191 | runConfigurations { 192 | "1. Run Client"(Gradle) { 193 | taskNames = ["runClient"] 194 | } 195 | "2. Run Server"(Gradle) { 196 | taskNames = ["runServer"] 197 | } 198 | "3. Run Obfuscated Client"(Gradle) { 199 | taskNames = ["runObfClient"] 200 | } 201 | "4. Run Obfuscated Server"(Gradle) { 202 | taskNames = ["runObfServer"] 203 | } 204 | } 205 | compiler.javac { 206 | afterEvaluate { 207 | javacAdditionalOptions = "-encoding utf8" 208 | moduleJavacAdditionalOptions = [ 209 | (project.name + ".main"): tasks.compileJava.options.compilerArgs.collect { '"' + it + '"' }.join(' ') 210 | ] 211 | } 212 | } 213 | }} 214 | } 215 | 216 | tasks.named("processIdeaSettings").configure { 217 | dependsOn("injectTags") 218 | } 219 | 220 | curseforge { 221 | if (!file('CHANGELOG.md').canRead()) { throw new FileNotFoundException("Could not read changelog file") } 222 | apiKey = project.hasProperty('CURSEFORGE_TOKEN') ? project.findProperty('CURSEFORGE_TOKEN') : (System.getenv("CURSEFORGE_TOKEN") != null ? System.getenv("CURSEFORGE_TOKEN") : '') 223 | project { 224 | id = project_curse_id 225 | changelogType = 'markdown' 226 | changelog = file('CHANGELOG.md') 227 | releaseType = project_release_type 228 | addGameVersion 'Forge' 229 | // add supported game versions separated by comma 230 | project_game_versions.split(",").each { 231 | addGameVersion it.trim() 232 | } 233 | mainArtifact(reobfJar) { 234 | displayName = "[FORGE] [${mc_version}] ${rootProject.name}-v${mod_version}" 235 | relations { 236 | requiredDependency 'mixinbootstrap' 237 | optionalDependency 'mixin-booter' 238 | } 239 | } 240 | } 241 | options { 242 | javaVersionAutoDetect = false 243 | forgeGradleIntegration = false 244 | } 245 | } 246 | -------------------------------------------------------------------------------- /deps/GalacticraftCore-1.12.2-4.0.2.280-deobf.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/embeddedt/aquaacrobatics/4c96ac731c837979abc329942bb0d59df5ce5d96/deps/GalacticraftCore-1.12.2-4.0.2.280-deobf.jar -------------------------------------------------------------------------------- /deps/MicdoodleCore-1.12.2-4.0.2.280-deobf.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/embeddedt/aquaacrobatics/4c96ac731c837979abc329942bb0d59df5ce5d96/deps/MicdoodleCore-1.12.2-4.0.2.280-deobf.jar -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Sets default memory used for gradle commands. Can be overridden by user or command line properties. 2 | # This is required to provide enough memory for the Minecraft decompilation process. 3 | org.gradle.jvmargs=-Xmx3G 4 | org.gradle.daemon=true 5 | 6 | # environment 7 | forge_version=1.12.2-14.23.5.2847 8 | 9 | # dependencies 10 | mc_version=1.12.2 11 | loader_version=14.23.5 12 | 13 | # attributes 14 | mod_id=aquaacrobatics 15 | mod_name=Aqua Acrobatics 16 | mod_version=1.15.4 17 | mod_author=Fuzs 18 | mod_description=Fancy swimming, elegant sneaking: modern movement without compromises in 1.12. 19 | mod_url=https://www.curseforge.com/minecraft/mc-mods/aqua-acrobatics 20 | mod_group=com.fuzs.aquaacrobatics 21 | 22 | # curse 23 | project_release_type=release 24 | project_game_versions=1.12.2 25 | project_curse_id=321792 26 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/embeddedt/aquaacrobatics/4c96ac731c837979abc329942bb0d59df5ce5d96/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-8.10.1-bin.zip 4 | networkTimeout=10000 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original 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 POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | # This is normally unused 84 | # shellcheck disable=SC2034 85 | APP_BASE_NAME=${0##*/} 86 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit 87 | 88 | # Use the maximum available, or set MAX_FD != -1 to use that value. 89 | MAX_FD=maximum 90 | 91 | warn () { 92 | echo "$*" 93 | } >&2 94 | 95 | die () { 96 | echo 97 | echo "$*" 98 | echo 99 | exit 1 100 | } >&2 101 | 102 | # OS specific support (must be 'true' or 'false'). 103 | cygwin=false 104 | msys=false 105 | darwin=false 106 | nonstop=false 107 | case "$( uname )" in #( 108 | CYGWIN* ) cygwin=true ;; #( 109 | Darwin* ) darwin=true ;; #( 110 | MSYS* | MINGW* ) msys=true ;; #( 111 | NONSTOP* ) nonstop=true ;; 112 | esac 113 | 114 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 115 | 116 | 117 | # Determine the Java command to use to start the JVM. 118 | if [ -n "$JAVA_HOME" ] ; then 119 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 120 | # IBM's JDK on AIX uses strange locations for the executables 121 | JAVACMD=$JAVA_HOME/jre/sh/java 122 | else 123 | JAVACMD=$JAVA_HOME/bin/java 124 | fi 125 | if [ ! -x "$JAVACMD" ] ; then 126 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 127 | 128 | Please set the JAVA_HOME variable in your environment to match the 129 | location of your Java installation." 130 | fi 131 | else 132 | JAVACMD=java 133 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 134 | 135 | Please set the JAVA_HOME variable in your environment to match the 136 | location of your Java installation." 137 | fi 138 | 139 | # Increase the maximum file descriptors if we can. 140 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 141 | case $MAX_FD in #( 142 | max*) 143 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. 144 | # shellcheck disable=SC3045 145 | MAX_FD=$( ulimit -H -n ) || 146 | warn "Could not query maximum file descriptor limit" 147 | esac 148 | case $MAX_FD in #( 149 | '' | soft) :;; #( 150 | *) 151 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. 152 | # shellcheck disable=SC3045 153 | ulimit -n "$MAX_FD" || 154 | warn "Could not set maximum file descriptor limit to $MAX_FD" 155 | esac 156 | fi 157 | 158 | # Collect all arguments for the java command, stacking in reverse order: 159 | # * args from the command line 160 | # * the main class name 161 | # * -classpath 162 | # * -D...appname settings 163 | # * --module-path (only if needed) 164 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 165 | 166 | # For Cygwin or MSYS, switch paths to Windows format before running java 167 | if "$cygwin" || "$msys" ; then 168 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 169 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 170 | 171 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 172 | 173 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 174 | for arg do 175 | if 176 | case $arg in #( 177 | -*) false ;; # don't mess with options #( 178 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 179 | [ -e "$t" ] ;; #( 180 | *) false ;; 181 | esac 182 | then 183 | arg=$( cygpath --path --ignore --mixed "$arg" ) 184 | fi 185 | # Roll the args list around exactly as many times as the number of 186 | # args, so each arg winds up back in the position where it started, but 187 | # possibly modified. 188 | # 189 | # NB: a `for` loop captures its iteration list before it begins, so 190 | # changing the positional parameters here affects neither the number of 191 | # iterations, nor the values presented in `arg`. 192 | shift # remove old arg 193 | set -- "$@" "$arg" # push replacement arg 194 | done 195 | fi 196 | 197 | 198 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 199 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 200 | 201 | # Collect all arguments for the java command; 202 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 203 | # shell script including quotes and variable substitutions, so put them in 204 | # double quotes to make sure that they get re-expanded; and 205 | # * put everything else in single quotes, so that it's not re-expanded. 206 | 207 | set -- \ 208 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 209 | -classpath "$CLASSPATH" \ 210 | org.gradle.wrapper.GradleWrapperMain \ 211 | "$@" 212 | 213 | # Stop when "xargs" is not available. 214 | if ! command -v xargs >/dev/null 2>&1 215 | then 216 | die "xargs is not available" 217 | fi 218 | 219 | # Use "xargs" to parse quoted args. 220 | # 221 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 222 | # 223 | # In Bash we could simply go: 224 | # 225 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 226 | # set -- "${ARGS[@]}" "$@" 227 | # 228 | # but POSIX shell has neither arrays nor command substitution, so instead we 229 | # post-process each arg (as a line of input to sed) to backslash-escape any 230 | # character that might be a shell metacharacter, then use eval to reverse 231 | # that process (while maintaining the separation between arguments), and wrap 232 | # the whole thing up as a single "set" statement. 233 | # 234 | # This will of course break if any of these variables contains a newline or 235 | # an unmatched quote. 236 | # 237 | 238 | eval "set -- $( 239 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 240 | xargs -n1 | 241 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 242 | tr '\n' ' ' 243 | )" '"$@"' 244 | 245 | exec "$JAVACMD" "$@" 246 | -------------------------------------------------------------------------------- /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 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 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 %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 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 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { 4 | // RetroFuturaGradle 5 | name = "GTNH Maven" 6 | url = uri("http://jenkins.usrv.eu:8081/nexus/content/groups/public/") 7 | allowInsecureProtocol = true 8 | mavenContent { 9 | includeGroup("com.gtnewhorizons") 10 | includeGroup("com.gtnewhorizons.retrofuturagradle") 11 | } 12 | } 13 | gradlePluginPortal() 14 | mavenCentral() 15 | mavenLocal() 16 | } 17 | } 18 | 19 | plugins { 20 | // Automatic toolchain provisioning 21 | id("org.gradle.toolchains.foojay-resolver-convention") version "0.9.0" 22 | } 23 | 24 | rootProject.name = "${mod_name.replaceAll("\\s", "")}" 25 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/AquaAcrobatics.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics; 2 | 3 | import com.fuzs.aquaacrobatics.core.AquaAcrobaticsCore; 4 | import com.fuzs.aquaacrobatics.proxy.CommonProxy; 5 | import net.minecraftforge.fml.common.Mod; 6 | import net.minecraftforge.fml.common.SidedProxy; 7 | import net.minecraftforge.fml.common.event.FMLInitializationEvent; 8 | import net.minecraftforge.fml.common.event.FMLModIdMappingEvent; 9 | import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; 10 | import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; 11 | import org.apache.logging.log4j.LogManager; 12 | import org.apache.logging.log4j.Logger; 13 | 14 | @SuppressWarnings("unused") 15 | @Mod( 16 | modid = AquaAcrobatics.MODID, 17 | name = AquaAcrobatics.NAME, 18 | version = AquaAcrobatics.VERSION, 19 | acceptedMinecraftVersions = "[1.12.2]", 20 | acceptableRemoteVersions = "*", 21 | dependencies = "before:mobends@(0.24,)" 22 | ) 23 | public class AquaAcrobatics { 24 | 25 | public static final String MODID = "aquaacrobatics"; 26 | public static final String NAME = "Aqua Acrobatics"; 27 | public static final String VERSION = Tags.VERSION; 28 | public static final Logger LOGGER = LogManager.getLogger(NAME); 29 | 30 | private static final String CLIENT_PROXY = "com.fuzs." + MODID + ".proxy.ClientProxy"; 31 | private static final String COMMON_PROXY = "com.fuzs." + MODID + ".proxy.CommonProxy"; 32 | 33 | @SidedProxy(clientSide = CLIENT_PROXY, serverSide = COMMON_PROXY) 34 | private static CommonProxy proxy; 35 | 36 | @Mod.EventHandler 37 | public void onPreInit(final FMLPreInitializationEvent evt) { 38 | 39 | if (AquaAcrobaticsCore.isLoaded()) { 40 | 41 | proxy.onPreInit(evt); 42 | } 43 | } 44 | 45 | @Mod.EventHandler 46 | public void onInit(final FMLInitializationEvent evt) { 47 | if (AquaAcrobaticsCore.isLoaded()) { 48 | 49 | proxy.onInit(); 50 | } 51 | } 52 | 53 | @Mod.EventHandler 54 | public void onPostInit(final FMLPostInitializationEvent evt) { 55 | 56 | if (AquaAcrobaticsCore.isLoaded()) { 57 | 58 | proxy.onPostInit(); 59 | } 60 | } 61 | 62 | @Mod.EventHandler 63 | public void onMappings(FMLModIdMappingEvent evt) { 64 | proxy.onMappings(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/biome/BiomeWaterFogColors.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.biome; 2 | 3 | import com.fuzs.aquaacrobatics.AquaAcrobatics; 4 | import com.fuzs.aquaacrobatics.config.ConfigHandler; 5 | import net.minecraft.util.ResourceLocation; 6 | import net.minecraft.world.biome.Biome; 7 | import net.minecraftforge.event.terraingen.BiomeEvent; 8 | 9 | import java.util.HashMap; 10 | 11 | public abstract class BiomeWaterFogColors { 12 | public static final int DEFAULT_WATER_FOG_COLOR = 329011; 13 | public static final int DEFAULT_WATER_COLOR = 4159204; 14 | 15 | private static final int DEFAULT_WATER_COLOR_112 = 16777215; 16 | private static final int PERCEIVED_WATER_COLOR_112 = 0x2b3bf4; 17 | private static final HashMap fogColorMap = new HashMap<>(); 18 | private static final HashMap baseColorMap = new HashMap<>(); 19 | 20 | private static final String[] DEFAULT_COLORS = { 21 | "minecraft:mutated_swampland,6388580,2302743", 22 | "minecraft:swampland,6388580,2302743", 23 | "minecraft:frozen_river,3750089,", 24 | "minecraft:frozen_ocean,3750089,", 25 | "minecraft:cold_beach,4020182,", 26 | "minecraft:taiga_cold,4020182,", 27 | "minecraft:taiga_cold_hills,4020182,", 28 | "minecraft:mutated_taiga_cold,4020182,", 29 | "integrateddynamics:biome_meneglin,,5613789", 30 | "biomesoplenty:bayou,0x62AF84,0x0C211C", 31 | "biomesoplenty:dead_swamp,0x354762,0x040511", 32 | "biomesoplenty:mangrove,0x448FBD,0x061326", 33 | "biomesoplenty:mystic_grove,0x9C3FE4,0x2E0533", 34 | "biomesoplenty:ominous_woods,0x312346,0x0A030C", 35 | "biomesoplenty:tropical_rainforest,0x1FA14A,0x02271A", 36 | "biomesoplenty:quagmire,0x433721,0x0C0C03", 37 | "biomesoplenty:wetland,0x272179,0x0C031B", 38 | "biomesoplenty:bog,,", 39 | "biomesoplenty:moor,,", 40 | "thebetweenlands:swamplands,1589792,1589792", 41 | "thebetweenlands:swamplands_clearing,1589792,1589792", 42 | "thebetweenlands:coarse_islands,1784132,1784132", 43 | "thebetweenlands:deep_waters,1784132,1784132", 44 | "thebetweenlands:marsh_0,4742680,4742680", 45 | "thebetweenlands:marsh_1,4742680,4742680", 46 | "thebetweenlands:patchy_islands,1589792,1589792", 47 | "thebetweenlands:raised_isles,1784132,1784132", 48 | "thebetweenlands:sludge_plains,3813131,3813131", 49 | "thebetweenlands:sludge_plains_clearing,3813131,3813131", 50 | "traverse:autumnal_woods,0x3F76E4,0x50533", 51 | "traverse:woodlands,0x3F76E4,0x50533", 52 | "traverse:mini_jungle,0x003320,0x052721", 53 | "traverse:meadow,0x3F76E4,0x50533", 54 | "traverse:green_swamp,0x617B64,0x232317", 55 | "traverse:red_desert,0x3F76E4,0x50533", 56 | "traverse:temperate_rainforest,0x3F76E4,0x50533", 57 | "traverse:badlands,0x3F76E4,0x50533", 58 | "traverse:mountainous_desert,0x3F76E4,0x50533", 59 | "traverse:rocky_plateau,0x3F76E4,0x50533", 60 | "traverse:forested_hills,0x3F76E4,0x50533", 61 | "traverse:birch_forested_hills,0x3F76E4,0x50533", 62 | "traverse:autumnal_wooded_hills,0x3F76E4,0x50533", 63 | "traverse:cliffs,0x3F76E4,0x50533", 64 | "traverse:glacier,0x3F76E4,0x50533", 65 | "traverse:glacier_spikes,0x3F76E4,0x50533", 66 | "traverse:snowy_coniferous_forest,0x3F76E4,0x50533", 67 | "traverse:lush_hills,0x3F76E4,0x50533", 68 | "traverse:desert_shrubland,0x3F76E4,0x50533", 69 | "traverse:thicket,0x3F76E4,0x50533", 70 | "traverse:arid_highland,0x3F76E4,0x50533", 71 | "traverse:rocky_plains,0x3F76E4,0x50533", 72 | "thaumcraft:magical_forest,3035999,", 73 | "thaumcraft:eerie,3035999," 74 | }; 75 | 76 | private static int emulateLegacyColor(int modColor) { 77 | int modR = (modColor & 0xff0000) >> 16; 78 | int modG = (modColor & 0x00ff00) >> 8; 79 | int modB = (modColor & 0x0000ff); 80 | int legacyR = (PERCEIVED_WATER_COLOR_112 & 0xff0000) >> 16; 81 | int legacyG = (PERCEIVED_WATER_COLOR_112 & 0x00ff00) >> 8; 82 | int legacyB = (PERCEIVED_WATER_COLOR_112 & 0x0000ff); 83 | int displayedR = (modR * legacyR) / 255; 84 | int displayedG = (modG * legacyG) / 255; 85 | int displayedB = (modB * legacyB) / 255; 86 | return (displayedR << 16) | (displayedG << 8) | displayedB; 87 | } 88 | 89 | private static void processStringColor(String colorEntry) { 90 | String[] fields = colorEntry.split(",", -1); 91 | if(fields.length != 3) { 92 | AquaAcrobatics.LOGGER.error("Incorrect syntax for '" + colorEntry + "'. Should be modname:biome,color,fogcolor (color and fogcolor may be empty)"); 93 | return; 94 | } 95 | ResourceLocation location = new ResourceLocation(fields[0]); 96 | try { 97 | int mainColor = Integer.decode(fields[1]); 98 | baseColorMap.put(location, mainColor); 99 | } catch (NumberFormatException e) { 100 | if(!baseColorMap.containsKey(location)) 101 | baseColorMap.put(location, DEFAULT_WATER_COLOR); 102 | } 103 | try { 104 | int fogColor = Integer.decode(fields[2]); 105 | fogColorMap.put(location, fogColor); 106 | } catch (NumberFormatException e) { 107 | if(!fogColorMap.containsKey(location)) 108 | fogColorMap.put(location, DEFAULT_WATER_FOG_COLOR); 109 | } 110 | } 111 | public static void recomputeColors() { 112 | fogColorMap.clear(); 113 | baseColorMap.clear(); 114 | for(String colorEntry : DEFAULT_COLORS) { 115 | processStringColor(colorEntry); 116 | } 117 | for(String colorEntry : ConfigHandler.MiscellaneousConfig.customBiomeWaterColors) { 118 | processStringColor(colorEntry); 119 | } 120 | } 121 | 122 | public static int getWaterFogColorForBiome(Biome biome) { 123 | ResourceLocation location = biome.getRegistryName(); 124 | if(location == null) 125 | return DEFAULT_WATER_FOG_COLOR; 126 | Integer color = fogColorMap.get(location); 127 | if(color != null) 128 | return color; 129 | return DEFAULT_WATER_FOG_COLOR; 130 | } 131 | public static int getWaterColorForBiome(Biome biome, int oldColor) { 132 | ResourceLocation location = biome.getRegistryName(); 133 | if(location == null) { 134 | return DEFAULT_WATER_COLOR; 135 | } 136 | Integer color = baseColorMap.get(location); 137 | if(color != null) { 138 | return color; 139 | } 140 | if(oldColor != DEFAULT_WATER_COLOR_112) { 141 | AquaAcrobatics.LOGGER.info("Potentially missing water color mapping for " + location + ", attempting to fake old appearance"); 142 | color = emulateLegacyColor(oldColor); 143 | } else 144 | color = DEFAULT_WATER_COLOR; 145 | baseColorMap.put(location, color); 146 | return color; 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/block/BlockBubbleColumn.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.block; 2 | 3 | import java.util.Random; 4 | 5 | import com.fuzs.aquaacrobatics.client.particle.ParticleBubbleColumnUp; 6 | import com.fuzs.aquaacrobatics.client.particle.ParticleCurrentDown; 7 | import com.fuzs.aquaacrobatics.config.ConfigHandler; 8 | import com.fuzs.aquaacrobatics.entity.IBubbleColumnInteractable; 9 | import com.fuzs.aquaacrobatics.proxy.CommonProxy; 10 | import net.minecraft.block.Block; 11 | import net.minecraft.block.BlockLiquid; 12 | import net.minecraft.block.BlockStaticLiquid; 13 | import net.minecraft.block.material.Material; 14 | import net.minecraft.block.properties.IProperty; 15 | import net.minecraft.block.properties.PropertyBool; 16 | import net.minecraft.block.state.BlockStateContainer; 17 | import net.minecraft.block.state.IBlockState; 18 | import net.minecraft.client.Minecraft; 19 | import net.minecraft.entity.Entity; 20 | import net.minecraft.entity.EntityBodyHelper; 21 | import net.minecraft.entity.item.EntityBoat; 22 | import net.minecraft.init.Blocks; 23 | import net.minecraft.util.EnumParticleTypes; 24 | import net.minecraft.util.math.BlockPos; 25 | import net.minecraft.world.IBlockAccess; 26 | import net.minecraft.world.World; 27 | import net.minecraftforge.common.property.IUnlistedProperty; 28 | import net.minecraftforge.common.util.Constants; 29 | import net.minecraftforge.fluids.BlockFluidBase; 30 | import net.minecraftforge.fml.common.Loader; 31 | import net.minecraftforge.fml.relauncher.Side; 32 | import net.minecraftforge.fml.relauncher.SideOnly; 33 | 34 | public class BlockBubbleColumn extends BlockStaticLiquid { 35 | public static final PropertyBool DRAG = PropertyBool.create("drag"); /* true: upwards, false: downwards */ 36 | 37 | public BlockBubbleColumn() { 38 | super(Material.WATER); 39 | this.setRegistryName("bubble_column"); 40 | this.setTranslationKey("tile.aquaacrobatics.bubble.column.name"); 41 | this.setDefaultState(this.blockState.getBaseState().withProperty(LEVEL, 0).withProperty(DRAG, false)); 42 | } 43 | 44 | @Override 45 | protected BlockStateContainer createBlockState() 46 | { 47 | BlockStateContainer.Builder builder = new BlockStateContainer.Builder(this).add(LEVEL, DRAG); 48 | if(Loader.isModLoaded("fluidlogged_api")) 49 | builder = builder.add(BlockFluidBase.FLUID_RENDER_PROPS.toArray(new IUnlistedProperty[0])); 50 | return builder.build(); 51 | } 52 | 53 | 54 | @Override 55 | public void onEntityCollision(World worldIn, BlockPos pos, IBlockState state, Entity entityIn) { 56 | IBlockState iblockstate = worldIn.getBlockState(pos.up()); 57 | IBubbleColumnInteractable bubbleEntity = (IBubbleColumnInteractable)entityIn; 58 | boolean downwards = !state.getValue(DRAG); 59 | if (iblockstate.getBlock() == Blocks.AIR) { 60 | bubbleEntity.onEnterBubbleColumnWithAirAbove(downwards); 61 | } else { 62 | bubbleEntity.onEnterBubbleColumn(downwards); 63 | } 64 | } 65 | 66 | public static void placeBubbleColumn(World world, BlockPos pos, boolean isUpwards) { 67 | if(!ConfigHandler.MiscellaneousConfig.bubbleColumns) 68 | return; 69 | if (canHoldBubbleColumn(world, pos)) { 70 | world.setBlockState(pos, CommonProxy.BUBBLE_COLUMN.getDefaultState().withProperty(DRAG, isUpwards), Constants.BlockFlags.SEND_TO_CLIENTS); 71 | } 72 | } 73 | 74 | public static boolean canHoldBubbleColumn(World world, BlockPos pos) { 75 | if(world.provider.doesWaterVaporize()) 76 | return false; 77 | IBlockState self = world.getBlockState(pos); 78 | if(self.getMaterial() != Material.WATER) 79 | return false; 80 | if(!(self.getBlock() instanceof BlockLiquid)) 81 | return false; 82 | if(self.getValue(LEVEL) != 0) 83 | return false; 84 | return true; 85 | } 86 | 87 | @SideOnly(Side.CLIENT) 88 | public void randomDisplayTick(IBlockState stateIn, World worldIn, BlockPos pos, Random rand) { 89 | double d0 = pos.getX(); 90 | double d1 = pos.getY(); 91 | double d2 = pos.getZ(); 92 | Minecraft mc = Minecraft.getMinecraft(); 93 | if (!stateIn.getValue(DRAG)) { 94 | mc.effectRenderer.addEffect(new ParticleCurrentDown(worldIn, d0 + 0.5D, d1 + 0.8D, d2)); 95 | } else { 96 | mc.effectRenderer.addEffect(new ParticleBubbleColumnUp(worldIn, d0 + 0.5D, d1, d2 + 0.5D, 0.0D, 0.04D, 0.0D)); 97 | mc.effectRenderer.addEffect(new ParticleBubbleColumnUp(worldIn, d0 + (double)rand.nextFloat(), d1 + (double)rand.nextFloat(), d2 + (double)rand.nextFloat(), 0.0D, 0.04D, 0.0D)); 98 | } 99 | } 100 | 101 | public void neighborChanged(IBlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos) { 102 | if (!this.isValidPosition(worldIn, pos)) { 103 | worldIn.setBlockState(pos, Blocks.WATER.getDefaultState()); 104 | return; 105 | } 106 | if (fromPos.up().equals(pos)) { 107 | worldIn.setBlockState(pos, CommonProxy.BUBBLE_COLUMN.getDefaultState().withProperty(DRAG, getDrag(worldIn, fromPos)), Constants.BlockFlags.SEND_TO_CLIENTS); 108 | } else if (fromPos.down().equals(pos) && worldIn.getBlockState(fromPos).getBlock() != this && canHoldBubbleColumn(worldIn, fromPos)) { 109 | worldIn.scheduleUpdate(pos, this, this.tickRate(worldIn)); 110 | } 111 | if(fromPos.getX() != pos.getX() || fromPos.getZ() != pos.getZ()) 112 | super.neighborChanged(state, worldIn, pos, blockIn, fromPos); 113 | } 114 | 115 | public boolean isValidPosition(World worldIn, BlockPos pos) { 116 | Block block = worldIn.getBlockState(pos.down()).getBlock(); 117 | return block == this || block == (worldIn.getBlockState(pos).getValue(DRAG) ? Blocks.SOUL_SAND : Blocks.MAGMA); 118 | } 119 | 120 | private static boolean getDrag(IBlockAccess p_203157_0_, BlockPos p_203157_1_) { 121 | IBlockState iblockstate = p_203157_0_.getBlockState(p_203157_1_); 122 | Block block = iblockstate.getBlock(); 123 | if (block == CommonProxy.BUBBLE_COLUMN) { 124 | return iblockstate.getValue(DRAG); 125 | } else { 126 | return block == Blocks.SOUL_SAND; 127 | } 128 | } 129 | 130 | 131 | public void onBlockAdded(World worldIn, BlockPos pos, IBlockState state) { 132 | super.onBlockAdded(worldIn, pos, state); 133 | placeBubbleColumn(worldIn, pos.up(), getDrag(worldIn, pos.down())); 134 | } 135 | 136 | public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand) { 137 | placeBubbleColumn(worldIn, pos.up(), getDrag(worldIn, pos)); 138 | } 139 | 140 | 141 | public IBlockState getStateFromMeta(int meta) 142 | { 143 | return this.getDefaultState().withProperty(LEVEL, 0).withProperty(DRAG, (meta & 1) == 1); 144 | } 145 | 146 | public int tickRate(World worldIn) { 147 | return 5; 148 | } 149 | 150 | 151 | public int getMetaFromState(IBlockState state) 152 | { 153 | return state.getValue(DRAG) ? 1 : 0; 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/client/entity/IPlayerSPSwimming.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.client.entity; 2 | 3 | public interface IPlayerSPSwimming { 4 | 5 | boolean isActuallySneaking(); 6 | 7 | boolean isForcedDown(); 8 | 9 | boolean isUsingSwimmingAnimation(); 10 | 11 | boolean isUsingSwimmingAnimation(float moveForward, float moveStrafe); 12 | 13 | boolean canSwim(); 14 | 15 | boolean isMovingForward(float moveForward, float moveStrafe); 16 | 17 | boolean canPerformElytraTakeoff(); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/client/gui/GuiNoMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.client.gui; 2 | 3 | import com.fuzs.aquaacrobatics.AquaAcrobatics; 4 | import net.minecraft.client.gui.GuiButton; 5 | import net.minecraft.client.gui.GuiScreen; 6 | import net.minecraft.client.renderer.GlStateManager; 7 | import net.minecraft.util.ResourceLocation; 8 | import net.minecraft.util.text.Style; 9 | import net.minecraft.util.text.TextComponentString; 10 | import net.minecraftforge.fml.relauncher.Side; 11 | import net.minecraftforge.fml.relauncher.SideOnly; 12 | 13 | import java.net.URI; 14 | 15 | @SideOnly(Side.CLIENT) 16 | public class GuiNoMixin extends GuiScreen { 17 | 18 | private static final ResourceLocation DEMO_BACKGROUND_LOCATION = new ResourceLocation("textures/gui/demo_background.png"); 19 | 20 | private final GuiScreen parent; 21 | 22 | public GuiNoMixin(GuiScreen parent) { 23 | 24 | this.parent = parent; 25 | } 26 | 27 | @Override 28 | public void initGui() { 29 | 30 | this.buttonList.clear(); 31 | this.buttonList.add(new GuiButton(1, this.width / 2 - 116, this.height / 2 + 62 + -16, 114, 20, new TextComponentString("Go to CurseForge").getFormattedText())); 32 | this.buttonList.add(new GuiButton(2, this.width / 2 + 2, this.height / 2 + 62 + -16, 114, 20, new TextComponentString("Ignore Message").getFormattedText())); 33 | } 34 | 35 | @Override 36 | protected void actionPerformed(GuiButton button) { 37 | 38 | switch (button.id) 39 | { 40 | case 1: 41 | 42 | button.enabled = false; 43 | try { 44 | 45 | Class oclass = Class.forName("java.awt.Desktop"); 46 | Object object = oclass.getMethod("getDesktop").invoke(null); 47 | oclass.getMethod("browse", URI.class).invoke(object, new URI("https://www.curseforge.com/minecraft/mc-mods/mixinbootstrap")); 48 | } catch (Throwable throwable) { 49 | 50 | AquaAcrobatics.LOGGER.error("Couldn't open link", throwable); 51 | } 52 | 53 | break; 54 | case 2: 55 | 56 | this.mc.displayGuiScreen(this.parent); 57 | this.mc.setIngameFocus(); 58 | } 59 | } 60 | 61 | @Override 62 | public void drawDefaultBackground() { 63 | 64 | super.drawDefaultBackground(); 65 | GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); 66 | this.mc.getTextureManager().bindTexture(DEMO_BACKGROUND_LOCATION); 67 | int i = (this.width - 248) / 2; 68 | int j = (this.height - 166) / 2; 69 | this.drawTexturedModalRect(i, j, 0, 0, 248, 166); 70 | } 71 | 72 | @Override 73 | public void drawScreen(int mouseX, int mouseY, float partialTicks) { 74 | 75 | this.drawDefaultBackground(); 76 | int i = (this.width - 248) / 2 + 10; 77 | int j = (this.height - 166) / 2 + 8; 78 | String title = new TextComponentString(AquaAcrobatics.NAME + " Message").setStyle(new Style().setBold(true)).getFormattedText(); 79 | this.fontRenderer.drawString(title, this.width / 2 - this.fontRenderer.getStringWidth(title) / 2, j, 2039583); 80 | j += 12; 81 | this.fontRenderer.drawSplitString(new TextComponentString("WARNING! " + AquaAcrobatics.NAME + " has failed to load. No instance of the Mixin library detected.").getFormattedText(), i, j + 12, 218, 5197647); 82 | this.fontRenderer.drawSplitString(new TextComponentString("Download the MixinBootstrap mod from CurseForge to enable the Mixin library. Click the button below to head to the downloads page.").getFormattedText(), i, j + 56, 218, 2039583); 83 | super.drawScreen(mouseX, mouseY, partialTicks); 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/client/handler/AirMeterHandler.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.client.handler; 2 | 3 | import net.minecraft.block.material.Material; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.client.renderer.GlStateManager; 6 | import net.minecraft.entity.player.EntityPlayer; 7 | import net.minecraft.util.math.MathHelper; 8 | import net.minecraftforge.client.GuiIngameForge; 9 | import net.minecraftforge.client.event.RenderGameOverlayEvent; 10 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 11 | 12 | public class AirMeterHandler { 13 | 14 | private final Minecraft mc = Minecraft.getMinecraft(); 15 | 16 | @SuppressWarnings("unused") 17 | @SubscribeEvent 18 | public void onRenderGameOverlay(final RenderGameOverlayEvent.Pre evt) { 19 | 20 | if (evt.getType() != RenderGameOverlayEvent.ElementType.AIR) { 21 | 22 | return; 23 | } 24 | 25 | EntityPlayer playerIn = (EntityPlayer) this.mc.getRenderViewEntity(); 26 | assert playerIn != null; 27 | if (!playerIn.isInsideOfMaterial(Material.WATER) && playerIn.getAir() < 300) { 28 | 29 | this.mc.profiler.startSection("air"); 30 | GlStateManager.enableBlend(); 31 | int left = evt.getResolution().getScaledWidth() / 2 + 91; 32 | int top = evt.getResolution().getScaledHeight() - GuiIngameForge.right_height; 33 | int air = playerIn.getAir(); 34 | int full = MathHelper.ceil((double)(air - 2) * 10.0D / 300.0D); 35 | int partial = MathHelper.ceil((double)air * 10.0D / 300.0D) - full; 36 | for (int i = 0; i < full + partial; ++i) { 37 | 38 | this.mc.ingameGUI.drawTexturedModalRect(left - i * 8 - 9, top, (i < full ? 16 : 25), 18, 9, 9); 39 | } 40 | 41 | GuiIngameForge.right_height += 10; 42 | GlStateManager.disableBlend(); 43 | this.mc.profiler.endSection(); 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/client/handler/FogHandler.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.client.handler; 2 | 3 | import com.fuzs.aquaacrobatics.biome.BiomeWaterFogColors; 4 | import com.fuzs.aquaacrobatics.config.ConfigHandler; 5 | import com.fuzs.aquaacrobatics.entity.player.IPlayerResizeable; 6 | import com.fuzs.aquaacrobatics.proxy.CommonProxy; 7 | import com.fuzs.aquaacrobatics.util.math.MathHelperNew; 8 | import net.minecraft.entity.Entity; 9 | import net.minecraft.entity.EntityLivingBase; 10 | import net.minecraft.init.MobEffects; 11 | import net.minecraft.util.math.MathHelper; 12 | import net.minecraft.block.Block; 13 | import net.minecraft.block.material.Material; 14 | import net.minecraft.block.state.IBlockState; 15 | import net.minecraft.client.renderer.GlStateManager; 16 | import net.minecraft.client.renderer.color.IBlockColor; 17 | import net.minecraft.entity.player.EntityPlayer; 18 | import net.minecraft.init.Blocks; 19 | import net.minecraft.util.math.BlockPos; 20 | import net.minecraft.world.IBlockAccess; 21 | import net.minecraft.world.World; 22 | import net.minecraft.world.biome.Biome; 23 | import net.minecraft.world.biome.BiomeColorHelper; 24 | import net.minecraftforge.client.event.ColorHandlerEvent; 25 | import net.minecraftforge.client.event.EntityViewRenderEvent; 26 | import net.minecraftforge.common.BiomeDictionary; 27 | import net.minecraftforge.event.terraingen.BiomeEvent; 28 | import net.minecraftforge.fml.common.eventhandler.EventPriority; 29 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 30 | 31 | import javax.annotation.Nullable; 32 | import java.util.Arrays; 33 | import java.util.HashSet; 34 | 35 | /** 36 | * Uses Forge events to adjust water rendering so it more closely approximates 1.13+. 37 | * 38 | * Some of the code in this class is based off of Minecraft 1.16. 39 | */ 40 | public class FogHandler { 41 | 42 | private int targetFogColor = -1; 43 | private int prevFogColor = -1; 44 | private long fogAdjustTime = -1L; 45 | 46 | private static HashSet worldProviderClassNames = null; 47 | 48 | public static void recomputeBlacklist() { 49 | worldProviderClassNames = new HashSet<>(); 50 | worldProviderClassNames.addAll(Arrays.asList(ConfigHandler.MiscellaneousConfig.providerFogBlacklist)); 51 | } 52 | 53 | private boolean shouldSkipFogOverride(World world) { 54 | if(!ConfigHandler.BlocksConfig.newWaterFog) 55 | return true; 56 | return worldProviderClassNames.contains(world.provider.getClass().getName()); 57 | } 58 | 59 | @SubscribeEvent 60 | public void registerBlockColors(ColorHandlerEvent.Block event){ 61 | if(ConfigHandler.MiscellaneousConfig.bubbleColumns) 62 | event.getBlockColors().registerBlockColorHandler(new IBlockColor() 63 | { 64 | public int colorMultiplier(IBlockState state, @Nullable IBlockAccess worldIn, @Nullable BlockPos pos, int tintIndex) 65 | { 66 | return worldIn != null && pos != null ? BiomeColorHelper.getWaterColorAtPos(worldIn, pos) : -1; 67 | } 68 | 69 | }, CommonProxy.BUBBLE_COLUMN); 70 | } 71 | 72 | @SubscribeEvent 73 | public void onRenderFogDensity(EntityViewRenderEvent.FogDensity event) { 74 | Entity eventEntity = event.getEntity(); 75 | if(eventEntity instanceof EntityLivingBase && ((EntityLivingBase)eventEntity).isPotionActive(MobEffects.BLINDNESS)) 76 | return; 77 | if(event.getState().getMaterial() == Material.WATER && !shouldSkipFogOverride(eventEntity.getEntityWorld())) { 78 | GlStateManager.setFog(GlStateManager.FogMode.EXP2); 79 | float density = 0.05f; 80 | if(eventEntity instanceof EntityPlayer) { 81 | EntityPlayer playerEntity = (EntityPlayer)eventEntity; 82 | float waterVision = ((IPlayerResizeable)playerEntity).getWaterVision(); 83 | density -= waterVision * waterVision * 0.03F; 84 | Biome biome = playerEntity.world.getBiome(playerEntity.getPosition()); 85 | if (BiomeDictionary.hasType(biome, BiomeDictionary.Type.SWAMP)) { 86 | density += 0.005F; 87 | } 88 | } 89 | event.setDensity(density); 90 | event.setCanceled(true); 91 | } 92 | } 93 | 94 | /* LOW to override mods like Biomes O' Plenty which force their own underwater fog color */ 95 | @SubscribeEvent(priority = EventPriority.LOW) 96 | public void onRenderFogColor(EntityViewRenderEvent.FogColors event) { 97 | if(!ConfigHandler.BlocksConfig.newWaterColors) 98 | return; 99 | Block blockInside = event.getState().getBlock(); 100 | if((event.getState().getMaterial() == Material.WATER) && event.getEntity() instanceof EntityPlayer && !shouldSkipFogOverride(event.getEntity().getEntityWorld())) { 101 | float fogRed, fogGreen, fogBlue; 102 | EntityPlayer playerEntity = (EntityPlayer) event.getEntity(); 103 | long i = System.nanoTime() / 1000000L; 104 | int j = BiomeWaterFogColors.getWaterFogColorForBiome(playerEntity.world.getBiome(playerEntity.getPosition())); 105 | if (fogAdjustTime < 0L) { 106 | targetFogColor = j; 107 | prevFogColor = j; 108 | fogAdjustTime = i; 109 | } 110 | int k = targetFogColor >> 16 & 255; 111 | int l = targetFogColor >> 8 & 255; 112 | int i1 = targetFogColor & 255; 113 | int j1 = prevFogColor >> 16 & 255; 114 | int k1 = prevFogColor >> 8 & 255; 115 | int l1 = prevFogColor & 255; 116 | float f = MathHelper.clamp((float)(i - fogAdjustTime) / 5000.0F, 0.0F, 1.0F); 117 | float f1 = MathHelperNew.lerp(f, (float)j1, (float)k); 118 | float f2 = MathHelperNew.lerp(f, (float)k1, (float)l); 119 | float f3 = MathHelperNew.lerp(f, (float)l1, (float)i1); 120 | fogRed = f1 / 255.0F; 121 | fogGreen = f2 / 255.0F; 122 | fogBlue = f3 / 255.0F; 123 | if (targetFogColor != j) { 124 | targetFogColor = j; 125 | prevFogColor = MathHelper.floor(f1) << 16 | MathHelper.floor(f2) << 8 | MathHelper.floor(f3); 126 | fogAdjustTime = i; 127 | } 128 | float f6 = ((IPlayerResizeable)playerEntity).getWaterVision(); 129 | float f9 = Math.min(1.0F / fogRed, Math.min(1.0F / fogGreen, 1.0F / fogBlue)); 130 | fogRed = fogRed * (1.0F - f6) + fogRed * f9 * f6; 131 | fogGreen = fogGreen * (1.0F - f6) + fogGreen * f9 * f6; 132 | fogBlue = fogBlue * (1.0F - f6) + fogBlue * f9 * f6; 133 | 134 | double blindnessFactor = 1.0; 135 | if (playerEntity.isPotionActive(MobEffects.BLINDNESS)) { 136 | int potionDuration = playerEntity.getActivePotionEffect(MobEffects.BLINDNESS).getDuration(); 137 | if (potionDuration < 20) { 138 | blindnessFactor *= (1.0F - (float)i / 20.0F); 139 | } else { 140 | blindnessFactor = 0.0D; 141 | } 142 | } 143 | 144 | if (blindnessFactor < 1.0D) { 145 | if (blindnessFactor < 0.0D) { 146 | blindnessFactor = 0.0D; 147 | } 148 | 149 | blindnessFactor = blindnessFactor * blindnessFactor; 150 | fogRed = (float)((double)fogRed * blindnessFactor); 151 | fogGreen = (float)((double)fogGreen * blindnessFactor); 152 | fogBlue = (float)((double)fogBlue * blindnessFactor); 153 | } 154 | 155 | event.setRed(fogRed); 156 | event.setGreen(fogGreen); 157 | event.setBlue(fogBlue); 158 | } else if((blockInside == Blocks.LAVA || blockInside == Blocks.FLOWING_LAVA)) { 159 | event.setRed(0.6f); 160 | event.setGreen(0.1f); 161 | event.setBlue(0.0f); 162 | fogAdjustTime = -1L; 163 | } else { 164 | fogAdjustTime = -1L; 165 | } 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/client/handler/NoMixinHandler.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.client.handler; 2 | 3 | import com.fuzs.aquaacrobatics.client.gui.GuiNoMixin; 4 | import com.fuzs.aquaacrobatics.core.AquaAcrobaticsCore; 5 | import net.minecraft.client.gui.GuiMainMenu; 6 | import net.minecraftforge.client.event.GuiOpenEvent; 7 | import net.minecraftforge.common.MinecraftForge; 8 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 9 | 10 | public class NoMixinHandler { 11 | 12 | @SuppressWarnings("unused") 13 | @SubscribeEvent 14 | public void onGuiOpen(final GuiOpenEvent evt) { 15 | 16 | if (evt.getGui() instanceof GuiMainMenu) { 17 | if(!AquaAcrobaticsCore.isLoaded()) { 18 | evt.setGui(new GuiNoMixin(evt.getGui())); 19 | } 20 | MinecraftForge.EVENT_BUS.unregister(this); 21 | } 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/client/model/IModelBipedSwimming.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.client.model; 2 | 3 | public interface IModelBipedSwimming { 4 | 5 | void setSwimAnimation(float swimAnimation); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/client/model/WaterResourcePack.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.client.model; 2 | 3 | import com.fuzs.aquaacrobatics.AquaAcrobatics; 4 | import com.google.common.collect.ImmutableSet; 5 | import net.minecraft.client.resources.AbstractResourcePack; 6 | 7 | import javax.annotation.Nonnull; 8 | import java.io.File; 9 | import java.io.IOException; 10 | import java.io.InputStream; 11 | import java.util.Set; 12 | 13 | public class WaterResourcePack extends AbstractResourcePack { 14 | private static final Set CONTENTS_FILTER = ImmutableSet.of( 15 | "assets/minecraft/textures/blocks/water_still.png", 16 | "assets/minecraft/textures/blocks/water_still.png.mcmeta", 17 | "assets/minecraft/textures/blocks/water_flow.png", 18 | "assets/minecraft/textures/blocks/water_flow.png.mcmeta", 19 | "assets/minecraft/textures/blocks/water_overlay.png" 20 | ); 21 | 22 | public WaterResourcePack(File resourcePackFileIn) { 23 | super(resourcePackFileIn); 24 | } 25 | 26 | @Override 27 | protected InputStream getInputStreamByName(String name) throws IOException { 28 | if(name.equals("pack.mcmeta")) 29 | return AquaAcrobatics.class.getResourceAsStream("/water_pack.mcmeta"); 30 | String truePath = "/" + name.replace("minecraft", "aquaacrobatics/overrides"); 31 | return AquaAcrobatics.class.getResourceAsStream(truePath); 32 | } 33 | 34 | @Override 35 | protected boolean hasResourceName(String name) { 36 | return name.equals("pack.mcmeta") || CONTENTS_FILTER.contains(name); 37 | } 38 | 39 | @Override 40 | public Set getResourceDomains() { 41 | return ImmutableSet.of("minecraft"); 42 | } 43 | 44 | @Nonnull 45 | @Override 46 | public String getPackName() { 47 | return "aquaacrobatics-new-water"; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/client/particle/ParticleBubbleColumnUp.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.client.particle; 2 | 3 | import net.minecraft.block.material.Material; 4 | import net.minecraft.client.particle.IParticleFactory; 5 | import net.minecraft.client.particle.Particle; 6 | import net.minecraft.util.math.BlockPos; 7 | import net.minecraft.world.World; 8 | import net.minecraftforge.fml.relauncher.Side; 9 | import net.minecraftforge.fml.relauncher.SideOnly; 10 | 11 | public class ParticleBubbleColumnUp extends Particle { 12 | public ParticleBubbleColumnUp(World p_i48833_1_, double p_i48833_2_, double p_i48833_4_, double p_i48833_6_, double p_i48833_8_, double p_i48833_10_, double p_i48833_12_) { 13 | super(p_i48833_1_, p_i48833_2_, p_i48833_4_, p_i48833_6_, p_i48833_8_, p_i48833_10_, p_i48833_12_); 14 | this.particleRed = 1.0F; 15 | this.particleGreen = 1.0F; 16 | this.particleBlue = 1.0F; 17 | this.setParticleTextureIndex(32); 18 | this.setSize(0.02F, 0.02F); 19 | this.particleScale *= this.rand.nextFloat() * 0.6F + 0.2F; 20 | this.motionX = p_i48833_8_ * (double)0.2F + (Math.random() * 2.0D - 1.0D) * (double)0.02F; 21 | this.motionY = p_i48833_10_ * (double)0.2F + (Math.random() * 2.0D - 1.0D) * (double)0.02F; 22 | this.motionZ = p_i48833_12_ * (double)0.2F + (Math.random() * 2.0D - 1.0D) * (double)0.02F; 23 | this.particleMaxAge = (int)(40.0D / (Math.random() * 0.8D + 0.2D)); 24 | } 25 | 26 | public void onUpdate() { 27 | this.prevPosX = this.posX; 28 | this.prevPosY = this.posY; 29 | this.prevPosZ = this.posZ; 30 | this.motionY += 0.005D; 31 | this.move(this.motionX, this.motionY, this.motionZ); 32 | this.motionX *= (double)0.85F; 33 | this.motionY *= (double)0.85F; 34 | this.motionZ *= (double)0.85F; 35 | if (this.world.getBlockState(new BlockPos(this.posX, this.posY, this.posZ)).getMaterial() != Material.WATER) { 36 | this.setExpired(); 37 | } 38 | 39 | if (this.particleMaxAge-- <= 0) { 40 | this.setExpired(); 41 | } 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/client/particle/ParticleCurrentDown.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.client.particle; 2 | 3 | import javax.annotation.Nullable; 4 | 5 | import net.minecraft.block.material.Material; 6 | import net.minecraft.client.particle.IParticleFactory; 7 | import net.minecraft.client.particle.Particle; 8 | import net.minecraft.util.math.BlockPos; 9 | import net.minecraft.util.math.MathHelper; 10 | import net.minecraft.world.World; 11 | import net.minecraftforge.fml.relauncher.Side; 12 | import net.minecraftforge.fml.relauncher.SideOnly; 13 | 14 | @SideOnly(Side.CLIENT) 15 | public class ParticleCurrentDown extends Particle { 16 | private float field_203083_a; 17 | 18 | public ParticleCurrentDown(World p_i48830_1_, double p_i48830_2_, double p_i48830_4_, double p_i48830_6_) { 19 | super(p_i48830_1_, p_i48830_2_, p_i48830_4_, p_i48830_6_, 0.0D, 0.0D, 0.0D); 20 | this.setParticleTextureIndex(32); 21 | this.particleMaxAge = (int)(Math.random() * 60.0D) + 30; 22 | this.canCollide = false; 23 | this.motionX = 0.0D; 24 | this.motionY = -0.05D; 25 | this.motionZ = 0.0D; 26 | this.setSize(0.02F, 0.02F); 27 | this.particleScale *= this.rand.nextFloat() * 0.6F + 0.2F; 28 | this.particleGravity = 0.002F; 29 | } 30 | 31 | public void onUpdate() { 32 | this.prevPosX = this.posX; 33 | this.prevPosY = this.posY; 34 | this.prevPosZ = this.posZ; 35 | float f = 0.6F; 36 | this.motionX += (double)(0.6F * MathHelper.cos(this.field_203083_a)); 37 | this.motionZ += (double)(0.6F * MathHelper.sin(this.field_203083_a)); 38 | this.motionX *= 0.07D; 39 | this.motionZ *= 0.07D; 40 | this.move(this.motionX, this.motionY, this.motionZ); 41 | if (this.world.getBlockState(new BlockPos(this.posX, this.posY, this.posZ)).getMaterial() != Material.WATER) { 42 | this.setExpired(); 43 | } 44 | 45 | if (this.particleAge++ >= this.particleMaxAge || this.onGround) { 46 | this.setExpired(); 47 | } 48 | 49 | this.field_203083_a = (float)((double)this.field_203083_a + 0.08D); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/config/ConfigHandler.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.config; 2 | 3 | import com.fuzs.aquaacrobatics.AquaAcrobatics; 4 | import com.fuzs.aquaacrobatics.biome.BiomeWaterFogColors; 5 | import com.fuzs.aquaacrobatics.client.handler.FogHandler; 6 | import net.minecraftforge.common.config.Config; 7 | import net.minecraftforge.common.config.ConfigManager; 8 | import net.minecraftforge.fml.client.event.ConfigChangedEvent; 9 | import net.minecraftforge.fml.common.Mod; 10 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 11 | 12 | @Config(modid = AquaAcrobatics.MODID) 13 | @Mod.EventBusSubscriber 14 | public class ConfigHandler { 15 | 16 | @Config.Name("Push Player Out Of Blocks") 17 | @Config.Comment({"STANDARD - The player will occasionally be pushed out of certain spaces. Collisions are evaluated for full cubes only, non-full cubes are ignored. This is the default behavior up to Minecraft 1.12.", "APPROXIMATE - The player can move into more spaces, but will still be pushed out of some. Collisions are evaluated for full cubes only, non-full cubes are ignored.", "EXACT - The player can move into all spaces as expected. Collisions are evaluated for all types of cubes. This is the default behavior in Minecraft 1.13 and onwards."}) 18 | public static PlayerBlockCollisions playerBlockCollisions = PlayerBlockCollisions.APPROXIMATE; 19 | 20 | @SuppressWarnings("unused") 21 | @Config.Name("blocks") 22 | @Config.Comment("Block-related config options (must match server).") 23 | public static BlocksConfig blocksConfig; 24 | 25 | @SuppressWarnings("unused") 26 | @Config.Name("movement") 27 | @Config.Comment("Movement related config options.") 28 | public static MovementConfig movementConfig; 29 | 30 | @SuppressWarnings("unused") 31 | @Config.Name("miscellaneous") 32 | @Config.Comment("Config options for various features of the mod.") 33 | public static MiscellaneousConfig miscellaneousConfig; 34 | 35 | @SuppressWarnings("unused") 36 | @Config.Name("integration") 37 | @Config.Comment("Control compatibility settings for individual mods.") 38 | public static IntegrationConfig integrationConfig; 39 | 40 | public static class MovementConfig { 41 | 42 | @Config.Name("Easy Elytra Takeoff") 43 | @Config.Comment("Taking off with an elytra from the ground is now far easier like in Minecraft 1.15 and onwards.") 44 | public static boolean easyElytraTakeoff = true; 45 | 46 | @Config.Name("No Double Tab Sprinting") 47 | @Config.Comment("Prevent sprinting from being triggered by double tapping the walk forward key.") 48 | public static boolean noDoubleTapSprinting = false; 49 | 50 | @Config.Name("Sideways Sprinting") 51 | @Config.Comment("Enables sprinting to the left and right.") 52 | public static boolean sidewaysSprinting = false; 53 | 54 | @Config.Name("Sideways Swimming") 55 | @Config.Comment("Enables swimming to the left and right.") 56 | public static boolean sidewaysSwimming = false; 57 | 58 | @Config.Name("Enable Crawling") 59 | @Config.Comment("Enables crawling to prevent suffocation. Note that if you disable this there will probably be behavioral differences from 1.13.") 60 | public static boolean enableCrawling = true; 61 | 62 | @Config.Name("Enable Toggle Crawling") 63 | @Config.Comment("Enables a keybind to toggle crawling.") 64 | public static boolean enableToggleCrawling = false; 65 | 66 | @Config.Name("New Projectile Behavior") 67 | @Config.Comment("Modify projectile behavior to be closer to that of newer versions (fixes MC-73884 and allows bubble columns to work with ender pearls).") 68 | public static boolean newProjectileBehavior = false; 69 | 70 | @Config.Name("New Climbing Behavior") 71 | @Config.Comment("Allow climbing vines and climbing by pressing jump.") 72 | public static boolean newClimbingBehavior = false; 73 | 74 | } 75 | 76 | public static class BlocksConfig { 77 | @Config.Name("Seagrass") 78 | @Config.Comment("Allow seagrass to generate in the world.") 79 | public static boolean seagrass = false; 80 | 81 | @Config.Name("Brighter Water") 82 | @Config.Comment("Make water only reduce light level by 1 per Y-level, instead of 3.") 83 | public static boolean brighterWater = true; 84 | 85 | @Config.Name("New Water") 86 | @Config.Comment("Use the new water rendering in 1.13+.") 87 | public static boolean newWaterColors = true; 88 | 89 | @Config.Name("New Water Fog") 90 | @Config.Comment("Use the new fog rendering in 1.13+.") 91 | public static boolean newWaterFog = true; 92 | } 93 | 94 | public static class MiscellaneousConfig { 95 | 96 | @Config.Name("Replenish Air Slowly") 97 | @Config.Comment("Replenish air slowly when out of water instead of immediately.") 98 | public static boolean slowAirReplenish = false; 99 | 100 | @Config.Name("Sneaking Dismounts Parrots") 101 | @Config.Comment("Parrots no longer leave the players shoulders as easily, instead the player needs to press the sneak key.") 102 | public static boolean sneakingForParrots = true; 103 | 104 | @Config.Name("Eating Animation") 105 | @Config.Comment("Animate eating in third-person view.") 106 | public static boolean eatingAnimation = true; 107 | 108 | @Config.Name("Bubble Columns") 109 | @Config.Comment("Enable bubble columns.") 110 | public static boolean bubbleColumns = false; 111 | 112 | @Config.Name("Custom Biome Water Colors") 113 | @Config.Comment("Allows overriding the water and fog colors for a biome. Specify each entry like this (without quotes) - 'modname:biome,color,fogcolor'") 114 | public static String[] customBiomeWaterColors = new String[] {}; 115 | 116 | @Config.Name("WorldProvider Fog Blacklist") 117 | @Config.Comment("List of WorldProviders in which fog should be disabled.") 118 | public static String[] providerFogBlacklist = new String[] { "thebetweenlands.common.world.WorldProviderBetweenlands" }; 119 | 120 | @Config.Name("Floating Items") 121 | @Config.Comment("Whether or not items should float in water like in 1.13+.") 122 | public static boolean floatingItems = true; 123 | } 124 | 125 | public static class IntegrationConfig { 126 | 127 | private static final String COMPAT_DESCRIPTION = "Only applies when the mod is installed. Disable when there are issues with the mod."; 128 | 129 | @Config.Name("Applied Energistics 2 Integration") 130 | @Config.Comment(COMPAT_DESCRIPTION) 131 | @Config.RequiresMcRestart 132 | public static boolean ae2Integration = true; 133 | 134 | @Config.Name("Betweenlands Integration") 135 | @Config.Comment(COMPAT_DESCRIPTION) 136 | @Config.RequiresMcRestart 137 | public static boolean betweenlandsIntegration = true; 138 | 139 | @Config.Name("Chiseled Me Integration") 140 | @Config.Comment(COMPAT_DESCRIPTION) 141 | @Config.RequiresMcRestart 142 | public static boolean chiseledMeIntegration = true; 143 | 144 | @Config.Name("Ender IO Integration") 145 | @Config.Comment(COMPAT_DESCRIPTION) 146 | @Config.RequiresMcRestart 147 | public static boolean enderIoIntegration = true; 148 | 149 | @Config.Name("Random Patches Integration") 150 | @Config.Comment(COMPAT_DESCRIPTION) 151 | public static boolean randomPatchesIntegration = true; 152 | 153 | @Config.Name("Mo' Bends Integration") 154 | @Config.Comment(COMPAT_DESCRIPTION) 155 | @Config.RequiresMcRestart 156 | public static boolean moBendsIntegration = true; 157 | 158 | @Config.Name("Wings Integration") 159 | @Config.Comment(COMPAT_DESCRIPTION) 160 | public static boolean wingsIntegration = true; 161 | 162 | @Config.Name("ArtemisLib Integration") 163 | @Config.Comment(COMPAT_DESCRIPTION) 164 | @Config.RequiresMcRestart 165 | public static boolean artemisLibIntegration = true; 166 | 167 | @Config.Name("Morph Integration") 168 | @Config.Comment(COMPAT_DESCRIPTION) 169 | public static boolean morphIntegration = true; 170 | 171 | @Config.Name("Hats Integration") 172 | @Config.Comment(COMPAT_DESCRIPTION) 173 | @Config.RequiresMcRestart 174 | public static boolean hatsIntegration = true; 175 | 176 | @Config.Name("Thaumic Augmentation Integration") 177 | @Config.Comment(COMPAT_DESCRIPTION) 178 | public static boolean thaumicAugmentationIntegration = true; 179 | 180 | @Config.Name("Trinkets and Baubles Integration") 181 | @Config.Comment(COMPAT_DESCRIPTION) 182 | public static boolean trinketsAndBaublesIntegration = true; 183 | 184 | @Config.Name("Witchery: Resurrected Integration") 185 | @Config.Comment(COMPAT_DESCRIPTION) 186 | public static boolean witcheryResurrectedIntegration = true; 187 | 188 | } 189 | 190 | @SuppressWarnings("unused") 191 | @SubscribeEvent 192 | public static void onConfigChanged(final ConfigChangedEvent.OnConfigChangedEvent evt) { 193 | 194 | if (evt.getModID().equals(AquaAcrobatics.MODID)) { 195 | 196 | ConfigManager.sync(AquaAcrobatics.MODID, Config.Type.INSTANCE); 197 | } 198 | BiomeWaterFogColors.recomputeColors(); 199 | FogHandler.recomputeBlacklist(); 200 | } 201 | 202 | @SuppressWarnings("unused") 203 | public enum PlayerBlockCollisions { 204 | 205 | STANDARD, APPROXIMATE, EXACT 206 | } 207 | 208 | } -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/AquaAcrobaticsCore.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core; 2 | 3 | import com.fuzs.aquaacrobatics.AquaAcrobatics; 4 | import com.fuzs.aquaacrobatics.client.handler.NoMixinHandler; 5 | import net.minecraft.launchwrapper.Launch; 6 | import net.minecraftforge.common.MinecraftForge; 7 | import net.minecraftforge.common.config.Configuration; 8 | import net.minecraftforge.fml.common.FMLCommonHandler; 9 | import net.minecraftforge.fml.relauncher.CoreModManager; 10 | import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin; 11 | import net.minecraftforge.fml.relauncher.Side; 12 | import org.apache.logging.log4j.LogManager; 13 | import org.apache.logging.log4j.Logger; 14 | import org.spongepowered.asm.launch.MixinBootstrap; 15 | import org.spongepowered.asm.mixin.Mixins; 16 | 17 | import javax.annotation.Nullable; 18 | import java.io.File; 19 | import java.net.URISyntaxException; 20 | import java.net.URL; 21 | import java.security.CodeSource; 22 | import java.util.Map; 23 | 24 | @SuppressWarnings("unused") 25 | @IFMLLoadingPlugin.Name(AquaAcrobaticsCore.NAME) 26 | @IFMLLoadingPlugin.MCVersion("1.12.2") 27 | public class AquaAcrobaticsCore implements IFMLLoadingPlugin { 28 | 29 | public static final String MODID = AquaAcrobatics.MODID; 30 | public static final String NAME = AquaAcrobatics.NAME + " Transformer"; 31 | public static final String VERSION = AquaAcrobatics.VERSION; 32 | public static final Logger LOGGER = LogManager.getLogger(AquaAcrobaticsCore.NAME); 33 | private static AquaAcrobaticsCore SELF; 34 | 35 | private static boolean isLoaded; 36 | public static boolean isModCompatLoaded; 37 | public static boolean isFgDev; 38 | private static boolean isScreenRegistered; 39 | 40 | /* Config options */ 41 | public static boolean disableBlockUpdateMixins; 42 | 43 | public AquaAcrobaticsCore() { 44 | SELF = this; 45 | Configuration config = new Configuration(new File("config", "aquaacrobatics_core.cfg")); 46 | config.load(); 47 | disableBlockUpdateMixins = config.getBoolean("DisableBlockUpdateMixins", "hacks", false, "TickCentral has a buggy ASM transformer - this will disable these mixins from being applied. Make sure bubble columns are disabled if you use this."); 48 | config.save(); 49 | 50 | isFgDev = "true".equals(System.getProperty("aquaacrobatics.fghack")); 51 | if(isFgDev) 52 | setupMixins(); 53 | } 54 | 55 | static void setupMixins() { 56 | try { 57 | Class.forName("org.spongepowered.asm.launch.MixinTweaker"); 58 | } catch(ClassNotFoundException e) { 59 | AquaAcrobaticsCore.LOGGER.error("No instance of Mixin framework detected. Unable to proceed load.", e); 60 | return; 61 | } 62 | MixinBootstrap.init(); 63 | Mixins.addConfiguration("META-INF/mixins." + AquaAcrobaticsCore.MODID + ".json"); 64 | isLoaded = true; 65 | if(isFgDev) { 66 | AquaAcrobaticsCore.LOGGER.info("Running in userdev, proceeding to apply workaround to ensure mod is loaded"); 67 | CodeSource codeSource = SELF.getClass().getProtectionDomain().getCodeSource(); 68 | if (codeSource != null) { 69 | URL location = codeSource.getLocation(); 70 | try { 71 | File file = new File(location.toURI()); 72 | if (file.isFile()) { 73 | CoreModManager.getReparseableCoremods().remove(file.getName()); 74 | } 75 | } catch (URISyntaxException ignored) {} 76 | } else { 77 | AquaAcrobaticsCore.LOGGER.warn("No CodeSource, if this is not a development environment we might run into problems!"); 78 | AquaAcrobaticsCore.LOGGER.warn(SELF.getClass().getProtectionDomain()); 79 | } 80 | } else { 81 | AquaAcrobaticsCore.LOGGER.info("Running in obf, thanks for playing with the mod!"); 82 | } 83 | } 84 | 85 | @Override 86 | public String[] getASMTransformerClass() { 87 | 88 | return new String[0]; 89 | } 90 | 91 | @Override 92 | public String getModContainerClass() { 93 | 94 | return null; 95 | } 96 | 97 | @Nullable 98 | @Override 99 | public String getSetupClass() { 100 | return "com.fuzs.aquaacrobatics.core.AquaAcrobaticsSetupHook"; 101 | } 102 | 103 | @Override 104 | public void injectData(Map data) { 105 | } 106 | 107 | 108 | @Override 109 | public String getAccessTransformerClass() { 110 | 111 | return null; 112 | } 113 | 114 | public static boolean isLoaded() { 115 | 116 | if (!isScreenRegistered) { 117 | 118 | isScreenRegistered = true; 119 | if(FMLCommonHandler.instance().getSide() == Side.CLIENT) 120 | MinecraftForge.EVENT_BUS.register(new NoMixinHandler()); 121 | else if(!isLoaded) { 122 | throw new RuntimeException("Mixin framework is missing, please install it."); 123 | } 124 | } 125 | 126 | return isLoaded; 127 | } 128 | 129 | } 130 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/AquaAcrobaticsMixinPlugin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core; 2 | 3 | import org.objectweb.asm.tree.ClassNode; 4 | import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; 5 | import org.spongepowered.asm.mixin.extensibility.IMixinInfo; 6 | 7 | import java.util.List; 8 | import java.util.Set; 9 | 10 | public class AquaAcrobaticsMixinPlugin implements IMixinConfigPlugin { 11 | @Override 12 | public void onLoad(String mixinPackage) { 13 | 14 | } 15 | 16 | @Override 17 | public String getRefMapperConfig() { 18 | return null; 19 | } 20 | 21 | private boolean doesClassExist(String name) { 22 | try { 23 | Class.forName(name); 24 | return true; 25 | } catch (ClassNotFoundException e) { 26 | return false; 27 | } 28 | } 29 | 30 | @Override 31 | public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { 32 | if(AquaAcrobaticsCore.disableBlockUpdateMixins) { 33 | if(mixinClassName.equals("com.fuzs.aquaacrobatics.core.mixin.BlockSoulSandMixin") || mixinClassName.equals("com.fuzs.aquaacrobatics.core.mixin.BlockMagmaMixin")) { 34 | AquaAcrobaticsCore.LOGGER.error("Disabling soul sand and magma mixins as requested in config."); 35 | return false; 36 | } 37 | } 38 | 39 | if(mixinClassName.equals("com.fuzs.aquaacrobatics.core.mixin.client.BlockAliasesBubbleColumnMixin")) { 40 | return doesClassExist("optifine.OptiFineForgeTweaker"); 41 | } 42 | 43 | return true; 44 | } 45 | 46 | @Override 47 | public void acceptTargets(Set myTargets, Set otherTargets) { 48 | 49 | } 50 | 51 | @Override 52 | public List getMixins() { 53 | return null; 54 | } 55 | 56 | @Override 57 | public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { 58 | 59 | } 60 | 61 | @Override 62 | public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { 63 | 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/AquaAcrobaticsSetupHook.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core; 2 | 3 | import net.minecraftforge.fml.relauncher.IFMLCallHook; 4 | 5 | import java.util.Map; 6 | 7 | public class AquaAcrobaticsSetupHook implements IFMLCallHook { 8 | 9 | @Override 10 | public void injectData(Map data) { 11 | 12 | } 13 | 14 | @Override 15 | public Void call() { 16 | if(!AquaAcrobaticsCore.isFgDev) 17 | AquaAcrobaticsCore.setupMixins(); 18 | return null; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/ModCompatMixinHandler.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core; 2 | 3 | import net.minecraftforge.fml.common.FMLCommonHandler; 4 | import net.minecraftforge.fml.common.Loader; 5 | import net.minecraftforge.fml.common.ModContainer; 6 | import org.spongepowered.asm.mixin.Mixins; 7 | import zone.rong.mixinbooter.MixinLoader; 8 | 9 | @MixinLoader 10 | public class ModCompatMixinHandler { 11 | public ModCompatMixinHandler() { 12 | AquaAcrobaticsCore.LOGGER.info("Aqua Acrobatics is loading mod compatibility mixins"); 13 | if(Loader.isModLoaded("galacticraftcore")) { 14 | Mixins.addConfiguration("META-INF/mixins.aquaacrobatics.galacticraft.json"); 15 | } 16 | if(Loader.isModLoaded("journeymap")) { 17 | ModContainer jmMod = FMLCommonHandler.instance().findContainerFor("journeymap"); 18 | if(jmMod != null) { 19 | String version = jmMod.getVersion(); 20 | if(version.equals("1.12.2-5.5.4")) { 21 | Mixins.addConfiguration("META-INF/mixins.aquaacrobatics.journeymap55.json"); 22 | } else if(version.equals("1.12.2-5.7.1")) { 23 | Mixins.addConfiguration("META-INF/mixins.aquaacrobatics.journeymap57.json"); 24 | } else { 25 | AquaAcrobaticsCore.LOGGER.warn("You have JourneyMap " + version + " installed. Only 1.12.2-5.5.4 and 1.12.2-5.7.1 are patched for water color compatibility."); 26 | } 27 | } 28 | } 29 | if(Loader.isModLoaded("xaerominimap")) { 30 | Mixins.addConfiguration("META-INF/mixins.aquaacrobatics.xaerosminimap.json"); 31 | } 32 | if(Loader.isModLoaded("thaumcraft")) { 33 | Mixins.addConfiguration("META-INF/mixins.aquaacrobatics.thaumcraft.json"); 34 | } 35 | AquaAcrobaticsCore.isModCompatLoaded = true; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/UnderwaterGrassLikeHandler.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core; 2 | 3 | import com.fuzs.aquaacrobatics.config.ConfigHandler; 4 | import net.minecraft.block.state.IBlockState; 5 | import net.minecraft.init.Blocks; 6 | import net.minecraft.util.math.BlockPos; 7 | import net.minecraft.world.World; 8 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 9 | 10 | import java.util.Random; 11 | 12 | public class UnderwaterGrassLikeHandler { 13 | public static void handleUnderwaterGrassLikeBlock(World world, BlockPos pos, IBlockState state, Random rand, CallbackInfo ci) { 14 | if(world.isRemote || !world.isAreaLoaded(pos, 3)) { 15 | ci.cancel(); 16 | return; 17 | } 18 | IBlockState above = world.getBlockState(pos.up()); 19 | if(above.getMaterial().isLiquid()) { 20 | world.setBlockState(pos, Blocks.DIRT.getDefaultState()); 21 | ci.cancel(); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/galacticraft/mixin/GCEntityClientPlayerMPMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.galacticraft.mixin; 2 | 3 | import com.fuzs.aquaacrobatics.entity.Pose; 4 | import com.fuzs.aquaacrobatics.entity.player.IPlayerResizeable; 5 | import micdoodle8.mods.galacticraft.api.world.IZeroGDimension; 6 | import micdoodle8.mods.galacticraft.core.entities.player.GCEntityClientPlayerMP; 7 | import micdoodle8.mods.galacticraft.core.entities.player.GCPlayerStatsClient; 8 | import net.minecraft.client.Minecraft; 9 | import net.minecraft.client.entity.EntityPlayerSP; 10 | import net.minecraft.client.network.NetHandlerPlayClient; 11 | import net.minecraft.stats.RecipeBook; 12 | import net.minecraft.stats.StatisticsManager; 13 | import net.minecraft.world.World; 14 | import org.spongepowered.asm.mixin.Mixin; 15 | import org.spongepowered.asm.mixin.Overwrite; 16 | import org.spongepowered.asm.mixin.injection.At; 17 | import org.spongepowered.asm.mixin.injection.Inject; 18 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 19 | 20 | @Mixin(GCEntityClientPlayerMP.class) 21 | public abstract class GCEntityClientPlayerMPMixin extends EntityPlayerSP { 22 | public GCEntityClientPlayerMPMixin(Minecraft p_i47378_1_, World p_i47378_2_, NetHandlerPlayClient p_i47378_3_, StatisticsManager p_i47378_4_, RecipeBook p_i47378_5_) { 23 | super(p_i47378_1_, p_i47378_2_, p_i47378_3_, p_i47378_4_, p_i47378_5_); 24 | } 25 | 26 | /** 27 | * @author embeddedt 28 | */ 29 | @Overwrite 30 | public float getEyeHeight() { 31 | if (this.isPlayerSleeping()) { 32 | return 0.2f; 33 | } 34 | IPlayerResizeable player = ((IPlayerResizeable)this); 35 | return player.getStandingEyeHeight(player.getPose(), player.getSize(player.getPose())); 36 | /* 37 | if (this.isPlayerSleeping()) { 38 | return super.getEyeHeight(); 39 | } else { 40 | float ySize = 0.0f; 41 | if (this.world.provider instanceof IZeroGDimension) { 42 | GCPlayerStatsClient stats = GCPlayerStatsClient.get(this); 43 | if (stats.getLandingTicks() > 0) { 44 | ySize = stats.getLandingYOffset()[stats.getLandingTicks()]; 45 | } else if (stats.getFreefallHandler().pjumpticks > 0) { 46 | ySize = 0.01F * (float)stats.getFreefallHandler().pjumpticks; 47 | } 48 | } 49 | return Math.min(this.getDefaultEyeHeight() - ySize, super.getEyeHeight()); 50 | } 51 | 52 | */ 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/galacticraft/mixin/GalacticraftCoreMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.galacticraft.mixin; 2 | 3 | import com.fuzs.aquaacrobatics.core.AquaAcrobaticsCore; 4 | import micdoodle8.mods.galacticraft.core.GalacticraftCore; 5 | import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 10 | 11 | @Mixin(GalacticraftCore.class) 12 | public class GalacticraftCoreMixin { 13 | @Inject(method = "preInit", at = @At("TAIL"), remap = false) 14 | private void markHeightConflict(FMLPreInitializationEvent event, CallbackInfo ci) { 15 | AquaAcrobaticsCore.LOGGER.info("Notifying Galacticraft that we are a height-conflicting mod"); 16 | GalacticraftCore.isHeightConflictingModInstalled = true; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/journeymap55/mixin/client/VanillaBlockSpriteProxyMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.journeymap55.mixin.client; 2 | 3 | import com.fuzs.aquaacrobatics.config.ConfigHandler; 4 | import journeymap.client.cartography.color.ColoredSprite; 5 | import journeymap.client.mod.vanilla.VanillaBlockSpriteProxy; 6 | import journeymap.client.model.BlockMD; 7 | import journeymap.client.model.ChunkMD; 8 | import net.minecraft.block.Block; 9 | import net.minecraft.client.renderer.texture.TextureAtlasSprite; 10 | import net.minecraft.init.Blocks; 11 | import net.minecraft.util.math.BlockPos; 12 | import net.minecraftforge.fml.client.FMLClientHandler; 13 | import net.minecraftforge.fml.common.Loader; 14 | import org.spongepowered.asm.mixin.Mixin; 15 | import org.spongepowered.asm.mixin.injection.At; 16 | import org.spongepowered.asm.mixin.injection.Inject; 17 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 18 | 19 | import java.util.Collection; 20 | import java.util.Collections; 21 | 22 | @Mixin(VanillaBlockSpriteProxy.class) 23 | public class VanillaBlockSpriteProxyMixin { 24 | @Inject( 25 | method = "getSprites(Ljourneymap/client/model/BlockMD;)Ljava/util/Collection;", 26 | at = @At("HEAD"), 27 | cancellable = true, 28 | remap = false, 29 | require = 0 /* not all JourneyMaps have this method */ 30 | ) 31 | private void getSprites(BlockMD blockMD, CallbackInfoReturnable> cir) { 32 | Block block = blockMD.getBlockState().getBlock(); 33 | if(ConfigHandler.BlocksConfig.newWaterColors && (block == Blocks.WATER || block == Blocks.FLOWING_WATER) && !Loader.isModLoaded("fluidlogged_api")) { 34 | TextureAtlasSprite tas = FMLClientHandler.instance().getClient().getTextureMapBlocks().getAtlasSprite("aquaacrobatics:blocks/water_still"); 35 | cir.setReturnValue(Collections.singletonList(new ColoredSprite(tas, null))); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/journeymap57/mixin/client/VanillaBlockSpriteProxyMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.journeymap57.mixin.client; 2 | 3 | import com.fuzs.aquaacrobatics.config.ConfigHandler; 4 | import journeymap.client.cartography.color.ColoredSprite; 5 | import journeymap.client.mod.vanilla.VanillaBlockSpriteProxy; 6 | import journeymap.client.model.BlockMD; 7 | import journeymap.client.model.ChunkMD; 8 | import net.minecraft.block.Block; 9 | import net.minecraft.client.renderer.texture.TextureAtlasSprite; 10 | import net.minecraft.init.Blocks; 11 | import net.minecraft.util.math.BlockPos; 12 | import net.minecraftforge.fml.client.FMLClientHandler; 13 | import net.minecraftforge.fml.common.Loader; 14 | import org.spongepowered.asm.mixin.Mixin; 15 | import org.spongepowered.asm.mixin.injection.At; 16 | import org.spongepowered.asm.mixin.injection.Inject; 17 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 18 | 19 | import java.util.Collection; 20 | import java.util.Collections; 21 | 22 | @Mixin(VanillaBlockSpriteProxy.class) 23 | public class VanillaBlockSpriteProxyMixin { 24 | @Inject( 25 | method = "getSprites(Ljourneymap/client/model/BlockMD;Ljourneymap/client/model/ChunkMD;Lnet/minecraft/util/math/BlockPos;)Ljava/util/Collection;", 26 | at = @At("HEAD"), 27 | cancellable = true, 28 | remap = false, 29 | require = 0 /* not all JourneyMaps have this method */ 30 | ) 31 | private void getSprites(BlockMD blockMD, ChunkMD facing, BlockPos state, CallbackInfoReturnable> cir) { 32 | Block block = blockMD.getBlockState().getBlock(); 33 | if(ConfigHandler.BlocksConfig.newWaterColors && (block == Blocks.WATER || block == Blocks.FLOWING_WATER) && !Loader.isModLoaded("fluidlogged_api")) { 34 | TextureAtlasSprite tas = FMLClientHandler.instance().getClient().getTextureMapBlocks().getAtlasSprite("aquaacrobatics:blocks/water_still"); 35 | cir.setReturnValue(Collections.singletonList(new ColoredSprite(tas, null))); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/mixin/BiomeColorHelperMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.mixin; 2 | 3 | import com.fuzs.aquaacrobatics.biome.BiomeWaterFogColors; 4 | import com.fuzs.aquaacrobatics.config.ConfigHandler; 5 | import net.minecraft.util.math.BlockPos; 6 | import net.minecraft.world.biome.Biome; 7 | import org.spongepowered.asm.mixin.Dynamic; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.injection.At; 10 | import org.spongepowered.asm.mixin.injection.Inject; 11 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 12 | 13 | @Mixin(targets = { "net/minecraft/world/biome/BiomeColorHelper$3" }) 14 | public class BiomeColorHelperMixin { 15 | /** 16 | * Typically we would just use the GetWaterColor event... but mods like Thaumcraft don't call it 17 | * and try to force their own water color on us. 18 | */ 19 | @Inject(method = "func_180283_a", at = @At("RETURN"), cancellable = true, remap = false) 20 | @Dynamic("Exists only in an SRG environment") 21 | private void getNewWaterColorMultiplier(Biome biome, BlockPos position, CallbackInfoReturnable cir) { 22 | if(ConfigHandler.BlocksConfig.newWaterColors) 23 | cir.setReturnValue(BiomeWaterFogColors.getWaterColorForBiome(biome, cir.getReturnValue())); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/mixin/BiomeMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.mixin; 2 | 3 | import com.fuzs.aquaacrobatics.biome.BiomeWaterFogColors; 4 | import com.fuzs.aquaacrobatics.config.ConfigHandler; 5 | import net.minecraft.world.biome.Biome; 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.CallbackInfoReturnable; 11 | 12 | @Mixin(Biome.class) 13 | public abstract class BiomeMixin { 14 | @Shadow public abstract int getWaterColorMultiplier(); 15 | 16 | /* For OptiFine */ 17 | @SuppressWarnings("unused") 18 | public int aqua$waterColorMultiplier() { 19 | if(ConfigHandler.BlocksConfig.newWaterColors) { 20 | /* We might call getWaterColorForBiome twice, but it's fine because it caches after the first call */ 21 | return BiomeWaterFogColors.getWaterColorForBiome((Biome) (Object) this, getWaterColorMultiplier()); 22 | } else 23 | return getWaterColorMultiplier(); 24 | } 25 | 26 | @Inject(method = "getWaterColorMultiplier", at = @At("TAIL"), remap = false, cancellable = true) 27 | private void forceNewColor(CallbackInfoReturnable cir) { 28 | if(ConfigHandler.BlocksConfig.newWaterColors) { 29 | cir.setReturnValue(BiomeWaterFogColors.getWaterColorForBiome((Biome)(Object)this, cir.getReturnValue())); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/mixin/BlockGrassMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.mixin; 2 | 3 | import com.fuzs.aquaacrobatics.config.ConfigHandler; 4 | import com.fuzs.aquaacrobatics.core.UnderwaterGrassLikeHandler; 5 | import net.minecraft.block.BlockGrass; 6 | import net.minecraft.block.state.IBlockState; 7 | import net.minecraft.util.math.BlockPos; 8 | import net.minecraft.world.World; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Inject; 12 | import org.spongepowered.asm.mixin.injection.Redirect; 13 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 14 | 15 | import java.util.Random; 16 | 17 | /* MC-130137 */ 18 | @Mixin(BlockGrass.class) 19 | public abstract class BlockGrassMixin { 20 | @Inject(method = "updateTick", at = @At("HEAD"), cancellable = true) 21 | private void updateUnderwaterToDirt(World world, BlockPos pos, IBlockState state, Random rand, CallbackInfo ci) { 22 | UnderwaterGrassLikeHandler.handleUnderwaterGrassLikeBlock(world, pos, state, rand, ci); 23 | } 24 | 25 | @Redirect(method = "updateTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/state/IBlockState;)Z", ordinal = 1), require = 0) 26 | public boolean avoidSettingGrass(World world, BlockPos pos, IBlockState state) { 27 | if(world.getBlockState(pos.up()).getMaterial().isLiquid()) 28 | return false; 29 | return world.setBlockState(pos, state); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/mixin/BlockLiquidMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.mixin; 2 | 3 | import com.fuzs.aquaacrobatics.config.ConfigHandler; 4 | import net.minecraft.block.Block; 5 | import net.minecraft.block.BlockLiquid; 6 | import net.minecraft.block.material.Material; 7 | import net.minecraft.block.state.IBlockState; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | 10 | @Mixin(BlockLiquid.class) 11 | public abstract class BlockLiquidMixin extends Block { 12 | public BlockLiquidMixin(Material p_i45394_1_) { 13 | super(p_i45394_1_); 14 | } 15 | 16 | @Override 17 | @SuppressWarnings("deprecation") 18 | public int getLightOpacity(IBlockState state) { 19 | if(ConfigHandler.BlocksConfig.brighterWater && state.getMaterial() == Material.WATER) 20 | return 1; 21 | else 22 | return super.getLightOpacity(state); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/mixin/BlockMagmaMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.mixin; 2 | 3 | import com.fuzs.aquaacrobatics.block.BlockBubbleColumn; 4 | import net.minecraft.block.Block; 5 | import net.minecraft.block.BlockMagma; 6 | import net.minecraft.block.material.Material; 7 | import net.minecraft.block.state.IBlockState; 8 | import net.minecraft.init.Blocks; 9 | import net.minecraft.util.math.BlockPos; 10 | import net.minecraft.world.World; 11 | import org.spongepowered.asm.mixin.Mixin; 12 | 13 | import java.util.Random; 14 | 15 | @Mixin(BlockMagma.class) 16 | public abstract class BlockMagmaMixin extends Block { 17 | public BlockMagmaMixin(Material p_i45394_1_) { 18 | super(p_i45394_1_); 19 | } 20 | 21 | @Override 22 | @SuppressWarnings("deprecation") 23 | public void neighborChanged(IBlockState state, World worldIn, BlockPos thisPos, Block blockIn, BlockPos fromPos) { 24 | if(worldIn.getBlockState(thisPos.up()).getMaterial() == Material.WATER) { 25 | worldIn.scheduleUpdate(thisPos, this, this.tickRate(worldIn)); 26 | } 27 | } 28 | 29 | @Override 30 | public void onBlockAdded(World worldIn, BlockPos pos, IBlockState state) { 31 | worldIn.scheduleUpdate(pos, this, this.tickRate(worldIn)); 32 | } 33 | 34 | @Override 35 | public int tickRate(World worldIn) { 36 | return 20; 37 | } 38 | 39 | @Override 40 | public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand) { 41 | BlockBubbleColumn.placeBubbleColumn(worldIn, pos.up(), false); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/mixin/BlockMyceliumMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.mixin; 2 | 3 | import com.fuzs.aquaacrobatics.config.ConfigHandler; 4 | import com.fuzs.aquaacrobatics.core.UnderwaterGrassLikeHandler; 5 | import net.minecraft.block.BlockMycelium; 6 | import net.minecraft.block.state.IBlockState; 7 | import net.minecraft.util.math.BlockPos; 8 | import net.minecraft.world.World; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Inject; 12 | import org.spongepowered.asm.mixin.injection.Redirect; 13 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 14 | 15 | import java.util.Random; 16 | 17 | /* MC-130137 */ 18 | @Mixin(BlockMycelium.class) 19 | public abstract class BlockMyceliumMixin { 20 | @Inject(method = "updateTick", at = @At("HEAD"), cancellable = true) 21 | private void updateUnderwaterToDirt(World world, BlockPos pos, IBlockState state, Random rand, CallbackInfo ci) { 22 | UnderwaterGrassLikeHandler.handleUnderwaterGrassLikeBlock(world, pos, state, rand, ci); 23 | } 24 | 25 | @Redirect(method = "updateTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/state/IBlockState;)Z", ordinal = 1), require = 0) 26 | public boolean avoidSettingGrass(World world, BlockPos pos, IBlockState state) { 27 | if(world.getBlockState(pos.up()).getMaterial().isLiquid()) 28 | return false; 29 | return world.setBlockState(pos, state); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/mixin/BlockSoulSandMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.mixin; 2 | 3 | import com.fuzs.aquaacrobatics.block.BlockBubbleColumn; 4 | import net.minecraft.block.Block; 5 | import net.minecraft.block.BlockSoulSand; 6 | import net.minecraft.block.material.Material; 7 | import net.minecraft.block.state.IBlockState; 8 | import net.minecraft.init.Blocks; 9 | import net.minecraft.util.math.BlockPos; 10 | import net.minecraft.world.World; 11 | import org.spongepowered.asm.mixin.Mixin; 12 | 13 | import java.util.Random; 14 | 15 | @Mixin(BlockSoulSand.class) 16 | public abstract class BlockSoulSandMixin extends Block { 17 | public BlockSoulSandMixin(Material p_i45394_1_) { 18 | super(p_i45394_1_); 19 | } 20 | 21 | @Override 22 | @SuppressWarnings("deprecation") 23 | public void neighborChanged(IBlockState state, World worldIn, BlockPos thisPos, Block blockIn, BlockPos fromPos) { 24 | worldIn.scheduleUpdate(thisPos, this, this.tickRate(worldIn)); 25 | } 26 | 27 | @Override 28 | public void onBlockAdded(World worldIn, BlockPos pos, IBlockState state) { 29 | worldIn.scheduleUpdate(pos, this, this.tickRate(worldIn)); 30 | } 31 | 32 | @Override 33 | public int tickRate(World worldIn) { 34 | return 20; 35 | } 36 | 37 | @Override 38 | public void updateTick(World worldIn, BlockPos pos, IBlockState state, Random rand) { 39 | BlockBubbleColumn.placeBubbleColumn(worldIn, pos.up(), true); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/mixin/EntityBoatMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.mixin; 2 | 3 | import com.fuzs.aquaacrobatics.config.ConfigHandler; 4 | import com.fuzs.aquaacrobatics.entity.IBubbleColumnInteractable; 5 | import com.fuzs.aquaacrobatics.entity.IRockableBoat; 6 | import net.minecraft.entity.Entity; 7 | import net.minecraft.entity.item.EntityBoat; 8 | import net.minecraft.entity.player.EntityPlayer; 9 | import net.minecraft.network.datasync.DataParameter; 10 | import net.minecraft.network.datasync.DataSerializers; 11 | import net.minecraft.network.datasync.EntityDataManager; 12 | import net.minecraft.util.EnumParticleTypes; 13 | import net.minecraft.util.math.MathHelper; 14 | import net.minecraft.world.World; 15 | import net.minecraftforge.fml.relauncher.Side; 16 | import net.minecraftforge.fml.relauncher.SideOnly; 17 | import org.spongepowered.asm.mixin.Mixin; 18 | import org.spongepowered.asm.mixin.injection.At; 19 | import org.spongepowered.asm.mixin.injection.Inject; 20 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 21 | 22 | @Mixin(EntityBoat.class) 23 | public abstract class EntityBoatMixin extends Entity implements IBubbleColumnInteractable, IRockableBoat { 24 | private static final DataParameter BOAT_ROCKING_TICKS = EntityDataManager.createKey(EntityBoat.class, DataSerializers.VARINT); 25 | private boolean aqua$rocking; 26 | private boolean aqua$rockingDownwards; 27 | private float rockingIntensity; 28 | private float rockingAngle; 29 | private float prevRockingAngle; 30 | 31 | public EntityBoatMixin(World worldIn) { 32 | super(worldIn); 33 | } 34 | 35 | public void onEnterBubbleColumnWithAirAbove(boolean downwards) { 36 | if (!world.isRemote) { 37 | this.aqua$rocking = true; 38 | this.aqua$rockingDownwards = downwards; 39 | if (this.getRockingTicks() == 0) { 40 | this.setRockingTicks(60); 41 | } 42 | } 43 | 44 | this.world.spawnParticle(EnumParticleTypes.WATER_SPLASH, this.posX + (double)this.rand.nextFloat(), this.posY + 0.7D, this.posZ + (double)this.rand.nextFloat(), 0.0D, 0.0D, 0.0D); 45 | if (this.rand.nextInt(20) == 0) { 46 | this.world.playSound(this.posX, this.posY, this.posZ, this.getSplashSound(), this.getSoundCategory(), 1.0F, 0.8F + 0.4F * this.rand.nextFloat(), false); 47 | } 48 | } 49 | 50 | @Override 51 | public void aqua$doRegisterData() { 52 | this.dataManager.register(BOAT_ROCKING_TICKS, 0); 53 | } 54 | 55 | @Inject(method = "onUpdate", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/item/EntityBoat;doBlockCollisions()V")) 56 | private void updateRocking(CallbackInfo ci) { 57 | if (this.world.isRemote) { 58 | int i = this.getRockingTicks(); 59 | if (i > 0) { 60 | this.rockingIntensity += 0.05F; 61 | } else { 62 | this.rockingIntensity -= 0.1F; 63 | } 64 | 65 | this.rockingIntensity = MathHelper.clamp(this.rockingIntensity, 0.0F, 1.0F); 66 | this.prevRockingAngle = this.rockingAngle; 67 | this.rockingAngle = 10.0F * (float)Math.sin((double)(0.5F * (float)this.world.getTotalWorldTime())) * this.rockingIntensity; 68 | } else { 69 | if (!this.aqua$rocking) { 70 | this.setRockingTicks(0); 71 | } 72 | 73 | int k = this.getRockingTicks(); 74 | if (k > 0) { 75 | --k; 76 | this.setRockingTicks(k); 77 | int j = 60 - k - 1; 78 | if (j > 0 && k == 0) { 79 | this.setRockingTicks(0); 80 | if (this.aqua$rockingDownwards) { 81 | this.motionY -= 0.7D; 82 | this.removePassengers(); 83 | } else { 84 | this.motionY = this.aqua$isPlayerRiding() ? 2.7D : 0.6D; 85 | } 86 | } 87 | 88 | this.aqua$rocking = false; 89 | } 90 | } 91 | 92 | } 93 | 94 | private boolean aqua$isPlayerRiding() { 95 | for(Entity entity : this.getPassengers()) { 96 | if (EntityPlayer.class.isAssignableFrom(entity.getClass())) { 97 | return true; 98 | } 99 | } 100 | 101 | return false; 102 | } 103 | 104 | public void setRockingTicks(int p_203055_1_) { 105 | if(!ConfigHandler.MiscellaneousConfig.bubbleColumns) 106 | return; 107 | this.dataManager.set(BOAT_ROCKING_TICKS, p_203055_1_); 108 | } 109 | 110 | public int getRockingTicks() { 111 | if(!ConfigHandler.MiscellaneousConfig.bubbleColumns) 112 | return 0; 113 | return this.dataManager.get(BOAT_ROCKING_TICKS); 114 | } 115 | 116 | @SideOnly(Side.CLIENT) 117 | public float getRockingAngle(float partialTicks) { 118 | if(!ConfigHandler.MiscellaneousConfig.bubbleColumns) 119 | return 0.0f; 120 | return this.prevRockingAngle + (this.rockingAngle - this.prevRockingAngle) * partialTicks; 121 | } 122 | 123 | } 124 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/mixin/EntityItemMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.mixin; 2 | 3 | import com.fuzs.aquaacrobatics.config.ConfigHandler; 4 | import com.fuzs.aquaacrobatics.integration.IntegrationManager; 5 | import com.fuzs.aquaacrobatics.integration.ae2.AE2Integration; 6 | import net.minecraft.block.BlockLiquid; 7 | import net.minecraft.block.material.Material; 8 | import net.minecraft.block.state.IBlockState; 9 | import net.minecraft.entity.Entity; 10 | import net.minecraft.entity.item.EntityItem; 11 | import net.minecraft.item.ItemStack; 12 | import net.minecraft.util.math.BlockPos; 13 | import net.minecraft.world.World; 14 | import org.spongepowered.asm.mixin.Mixin; 15 | import org.spongepowered.asm.mixin.Shadow; 16 | import org.spongepowered.asm.mixin.injection.At; 17 | import org.spongepowered.asm.mixin.injection.Inject; 18 | import org.spongepowered.asm.mixin.injection.Redirect; 19 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 20 | 21 | /** 22 | * Allows items to float like post-1.13. 23 | */ 24 | @Mixin(EntityItem.class) 25 | public abstract class EntityItemMixin extends Entity { 26 | @Shadow public abstract ItemStack getItem(); 27 | 28 | public EntityItemMixin(World p_i1582_1_) { 29 | super(p_i1582_1_); 30 | } 31 | 32 | private void applyFloatMotion() { 33 | if (this.motionY < (double)0.06F) { 34 | this.motionY += (double)5.0E-4F; 35 | } 36 | this.motionX *= 0.99F; 37 | this.motionZ *= 0.99F; 38 | } 39 | 40 | private boolean aqua$shouldBeBuoyant() { 41 | if(!ConfigHandler.MiscellaneousConfig.floatingItems) 42 | return false; 43 | if(IntegrationManager.isAE2Enabled() && AE2Integration.isGrowingCrystal((EntityItem)(Object)this)) 44 | return false; 45 | return true; 46 | } 47 | 48 | @Redirect(method = "onUpdate", at = @At(value="INVOKE", target = "Lnet/minecraft/entity/item/EntityItem;hasNoGravity()Z", ordinal = 0), expect = 1, require = 0) 49 | private boolean applyFloatMotionIfInWater(EntityItem entityItem) { 50 | if(!aqua$shouldBeBuoyant()) { 51 | return false; 52 | } 53 | double eyePosition = this.posY + (double)this.getEyeHeight(); 54 | BlockPos eyeBlockPos = new BlockPos(this.posX, eyePosition, this.posZ); 55 | IBlockState state = this.world.getBlockState(eyeBlockPos); 56 | if(state.getMaterial() == Material.WATER && state.getBlock() instanceof BlockLiquid) { 57 | float thresholdHeight = eyeBlockPos.getY() + BlockLiquid.getBlockLiquidHeight(state, this.world, eyeBlockPos) + (1f/9f); 58 | if(eyePosition < thresholdHeight) { 59 | applyFloatMotion(); 60 | return true; 61 | } 62 | } 63 | return entityItem.hasNoGravity(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/mixin/EntityLivingBaseMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.mixin; 2 | 3 | import com.fuzs.aquaacrobatics.config.ConfigHandler; 4 | import com.fuzs.aquaacrobatics.entity.player.IPlayerResizeable; 5 | import com.fuzs.aquaacrobatics.proxy.CommonProxy; 6 | import net.minecraft.block.material.Material; 7 | import net.minecraft.entity.Entity; 8 | import net.minecraft.entity.EntityLivingBase; 9 | import net.minecraft.util.math.BlockPos; 10 | import net.minecraft.world.World; 11 | import org.objectweb.asm.Opcodes; 12 | import org.spongepowered.asm.mixin.Mixin; 13 | import org.spongepowered.asm.mixin.gen.Accessor; 14 | import org.spongepowered.asm.mixin.injection.At; 15 | import org.spongepowered.asm.mixin.injection.ModifyArg; 16 | import org.spongepowered.asm.mixin.injection.Redirect; 17 | 18 | @SuppressWarnings("unused") 19 | @Mixin(EntityLivingBase.class) 20 | public abstract class EntityLivingBaseMixin extends Entity { 21 | 22 | public EntityLivingBaseMixin(World worldIn) { 23 | 24 | super(worldIn); 25 | } 26 | 27 | @Accessor(value = "isJumping") 28 | public abstract boolean aqua$isJumping(); 29 | 30 | @Redirect(method = "travel", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/EntityLivingBase;isSneaking()Z")) 31 | public boolean isSneaking(EntityLivingBase entity) { 32 | 33 | // make sneaking on ladders work again since removing the pose client-side prevents the actual mechanic from working 34 | if (entity instanceof IPlayerResizeable) { 35 | 36 | return ((IPlayerResizeable) entity).isActuallySneaking(); 37 | } 38 | 39 | return this.isSneaking(); 40 | } 41 | 42 | private boolean aqua$isLosingAir() { 43 | if(ConfigHandler.MiscellaneousConfig.bubbleColumns 44 | && this.world.getBlockState(new BlockPos(this.posX, this.posY + (double)this.getEyeHeight(), this.posZ)).getBlock() == CommonProxy.BUBBLE_COLUMN) 45 | return false; /* pretend not to be in water */ 46 | return this.isInsideOfMaterial(Material.WATER); 47 | } 48 | 49 | @Redirect(method = "onEntityUpdate", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/EntityLivingBase;isInsideOfMaterial(Lnet/minecraft/block/material/Material;)Z")) 50 | private boolean checkBubbleBreathing(EntityLivingBase entityLivingBase, Material materialIn) { 51 | if(materialIn == Material.WATER) 52 | return aqua$isLosingAir(); 53 | return entityLivingBase.isInsideOfMaterial(materialIn); 54 | } 55 | 56 | @ModifyArg(method = "onEntityUpdate", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/EntityLivingBase;setAir(I)V"), index = 0) 57 | private int getNewAirValue(int original) { 58 | if(ConfigHandler.MiscellaneousConfig.slowAirReplenish && original == 300 && this.getAir() >= -20 && !aqua$isLosingAir()) { 59 | int oldAirValue = Math.max(this.getAir(), 0); 60 | return Math.min(oldAirValue + 4, 300); 61 | } 62 | return original; 63 | } 64 | 65 | @Redirect(method = "travel", at = @At(value = "FIELD", opcode = Opcodes.GETFIELD, target = "Lnet/minecraft/entity/EntityLivingBase;collidedHorizontally:Z", ordinal = 1)) 66 | private boolean isJumpingOnLadder(EntityLivingBase instance) { 67 | if(ConfigHandler.MovementConfig.newClimbingBehavior) 68 | return instance.collidedHorizontally || ((EntityLivingBaseMixin) (Object) instance).aqua$isJumping(); 69 | else 70 | return instance.collidedHorizontally; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/mixin/EntityMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.mixin; 2 | 3 | import com.fuzs.aquaacrobatics.config.ConfigHandler; 4 | import com.fuzs.aquaacrobatics.entity.IBubbleColumnInteractable; 5 | import com.fuzs.aquaacrobatics.entity.player.IPlayerResizeable; 6 | import net.minecraft.block.Block; 7 | import net.minecraft.block.BlockVine; 8 | import net.minecraft.block.state.IBlockState; 9 | import net.minecraft.entity.Entity; 10 | import net.minecraft.entity.item.EntityBoat; 11 | import net.minecraft.init.Blocks; 12 | import net.minecraft.network.datasync.DataParameter; 13 | import net.minecraft.network.datasync.DataSerializers; 14 | import net.minecraft.network.datasync.EntityDataManager; 15 | import net.minecraft.world.World; 16 | import org.spongepowered.asm.mixin.Mixin; 17 | import org.spongepowered.asm.mixin.Shadow; 18 | import org.spongepowered.asm.mixin.injection.At; 19 | import org.spongepowered.asm.mixin.injection.Inject; 20 | import org.spongepowered.asm.mixin.injection.ModifyVariable; 21 | import org.spongepowered.asm.mixin.injection.Redirect; 22 | 23 | @SuppressWarnings("unused") 24 | @Mixin(Entity.class) 25 | public abstract class EntityMixin implements IBubbleColumnInteractable { 26 | @Shadow 27 | public abstract boolean isSneaking(); 28 | 29 | @Shadow 30 | public double motionY; 31 | 32 | @Shadow 33 | public float fallDistance; 34 | 35 | @Shadow public World world; 36 | 37 | @Redirect(method = "move", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;isSneaking()Z")) 38 | public boolean isSneaking(Entity entity) { 39 | 40 | // patches two calls to allow falling off blocks when not pressing sneak key but being in crouching pose 41 | if (entity instanceof IPlayerResizeable) { 42 | 43 | return ((IPlayerResizeable) entity).isActuallySneaking(); 44 | } 45 | 46 | return this.isSneaking(); 47 | } 48 | 49 | @Override 50 | public void onEnterBubbleColumn(boolean downwards) { 51 | if(!downwards) { 52 | this.motionY = Math.min(0.7, this.motionY + 0.06); 53 | } else 54 | this.motionY = Math.max(-0.3, this.motionY - 0.03); 55 | this.fallDistance = 0.0F; 56 | } 57 | 58 | @Override 59 | public void onEnterBubbleColumnWithAirAbove(boolean downwards) { 60 | if(!downwards) { 61 | this.motionY = Math.min(1.8, this.motionY + 0.1); 62 | } else 63 | this.motionY = Math.max(-0.9, this.motionY - 0.03); 64 | } 65 | 66 | @ModifyVariable(method = "move", ordinal = 0, name = "block", at = @At("LOAD")) 67 | private Block getFakeClimbingBlock(Block original) { 68 | if(ConfigHandler.MovementConfig.newClimbingBehavior && original instanceof BlockVine) 69 | return Blocks.LADDER; 70 | return original; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/mixin/EntityPlayerMPMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.mixin; 2 | 3 | import com.fuzs.aquaacrobatics.entity.Pose; 4 | import com.fuzs.aquaacrobatics.entity.player.IPlayerResizeable; 5 | import com.mojang.authlib.GameProfile; 6 | import net.minecraft.entity.player.EntityPlayer; 7 | import net.minecraft.entity.player.EntityPlayerMP; 8 | import net.minecraft.util.DamageSource; 9 | import net.minecraft.world.World; 10 | import org.spongepowered.asm.mixin.Mixin; 11 | import org.spongepowered.asm.mixin.injection.At; 12 | import org.spongepowered.asm.mixin.injection.Inject; 13 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 14 | 15 | @SuppressWarnings("unused") 16 | @Mixin(EntityPlayerMP.class) 17 | public abstract class EntityPlayerMPMixin extends EntityPlayer { 18 | 19 | public EntityPlayerMPMixin(World worldIn, GameProfile gameProfileIn) { 20 | 21 | super(worldIn, gameProfileIn); 22 | } 23 | 24 | @Inject(method = "onDeath", at = @At("TAIL")) 25 | public void onDeath(DamageSource cause, CallbackInfo callbackInfo) { 26 | 27 | // super method is never called where this is set in vanilla 28 | ((IPlayerResizeable) this).setPose(Pose.DYING); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/mixin/EntityThrowableMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.mixin; 2 | 3 | import com.fuzs.aquaacrobatics.config.ConfigHandler; 4 | import net.minecraft.entity.Entity; 5 | import net.minecraft.entity.projectile.EntityThrowable; 6 | import net.minecraft.util.math.RayTraceResult; 7 | import net.minecraft.util.math.Vec3d; 8 | import net.minecraft.world.World; 9 | import org.objectweb.asm.Opcodes; 10 | import org.spongepowered.asm.mixin.Mixin; 11 | import org.spongepowered.asm.mixin.injection.At; 12 | import org.spongepowered.asm.mixin.injection.Inject; 13 | import org.spongepowered.asm.mixin.injection.Redirect; 14 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 15 | 16 | @Mixin(EntityThrowable.class) 17 | public abstract class EntityThrowableMixin extends Entity { 18 | public EntityThrowableMixin(World worldIn) { 19 | super(worldIn); 20 | } 21 | 22 | private final boolean aqua$isNewProjectile = aqua$checkEntityEligibleForProjectile(); 23 | 24 | private boolean aqua$checkEntityEligibleForProjectile() { 25 | return ConfigHandler.MovementConfig.newProjectileBehavior && getClass().getName().startsWith("net.minecraft."); 26 | } 27 | 28 | @Redirect(method = "onUpdate", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;rayTraceBlocks(Lnet/minecraft/util/math/Vec3d;Lnet/minecraft/util/math/Vec3d;)Lnet/minecraft/util/math/RayTraceResult;")) 29 | private RayTraceResult rayTraceThroughLiquid(World world, Vec3d start, Vec3d end) { 30 | if(aqua$isNewProjectile) 31 | return world.rayTraceBlocks(start, end, false, true, false); 32 | else 33 | return world.rayTraceBlocks(start, end); 34 | } 35 | @Inject(method = "onUpdate", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/projectile/EntityThrowable;posX:D", opcode = Opcodes.PUTFIELD, ordinal = 0)) 36 | private void doCheckBlockCollision(CallbackInfo ci) { 37 | if(aqua$isNewProjectile) 38 | this.doBlockCollisions(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/mixin/NetHandlerPlayServerMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.mixin; 2 | 3 | import com.fuzs.aquaacrobatics.config.ConfigHandler; 4 | import net.minecraft.entity.player.EntityPlayerMP; 5 | import net.minecraft.network.NetHandlerPlayServer; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Redirect; 9 | 10 | @SuppressWarnings("unused") 11 | @Mixin(NetHandlerPlayServer.class) 12 | public abstract class NetHandlerPlayServerMixin { 13 | 14 | @Redirect(method = "processEntityAction", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/player/EntityPlayerMP;motionY:D")) 15 | public double getElytraFlyingMotion(EntityPlayerMP player) { 16 | 17 | // 1.15 change for easier elytra takeoff 18 | return ConfigHandler.MovementConfig.easyElytraTakeoff ? -1.0 : player.motionY; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/mixin/accessor/FluidAccessor.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.mixin.accessor; 2 | 3 | import net.minecraft.util.ResourceLocation; 4 | import net.minecraftforge.fluids.Fluid; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.Mutable; 7 | import org.spongepowered.asm.mixin.gen.Accessor; 8 | 9 | @Mixin(Fluid.class) 10 | public interface FluidAccessor { 11 | @Accessor(value = "still", remap = false) 12 | @Mutable 13 | void setStillTexture(ResourceLocation rl); 14 | @Accessor(value = "flowing", remap = false) 15 | @Mutable 16 | void setFlowingTexture(ResourceLocation rl); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/mixin/accessor/IEventBusAccessor.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.mixin.accessor; 2 | 3 | import net.minecraftforge.fml.common.eventhandler.EventBus; 4 | import net.minecraftforge.fml.common.eventhandler.IEventListener; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.gen.Accessor; 7 | 8 | import java.util.ArrayList; 9 | import java.util.concurrent.ConcurrentHashMap; 10 | 11 | @SuppressWarnings("unused") 12 | @Mixin(EventBus.class) 13 | public interface IEventBusAccessor { 14 | 15 | @Accessor(remap = false) 16 | ConcurrentHashMap> getListeners(); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/mixin/client/BlockAliasesBubbleColumnMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.mixin.client; 2 | 3 | import com.fuzs.aquaacrobatics.config.ConfigHandler; 4 | import com.fuzs.aquaacrobatics.core.AquaAcrobaticsCore; 5 | import com.fuzs.aquaacrobatics.optifine.OptifineHelper; 6 | import net.minecraft.block.Block; 7 | import net.minecraft.init.Blocks; 8 | import net.minecraft.util.ResourceLocation; 9 | import net.minecraftforge.fml.common.registry.ForgeRegistries; 10 | import org.spongepowered.asm.mixin.Mixin; 11 | import org.spongepowered.asm.mixin.Pseudo; 12 | import org.spongepowered.asm.mixin.injection.At; 13 | import org.spongepowered.asm.mixin.injection.Inject; 14 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 15 | 16 | import java.io.InputStream; 17 | import java.util.List; 18 | import java.util.stream.Collectors; 19 | 20 | @Pseudo 21 | @Mixin(targets = {"net/optifine/shaders/BlockAliases"}) 22 | public class BlockAliasesBubbleColumnMixin { 23 | /** 24 | * @author embeddedt 25 | * @reason inject the bubble column into the block aliases 26 | */ 27 | @Inject(method = "loadBlockAliases", at = @At("RETURN"), remap = false) 28 | private static void injectAABubbleColumn(InputStream in, String path, List> listBlockAliases, CallbackInfo ci) { 29 | if (!ConfigHandler.MiscellaneousConfig.bubbleColumns) { 30 | return; 31 | } 32 | 33 | Block targetBlock = ForgeRegistries.BLOCKS.getValue(new ResourceLocation("aquaacrobatics", "bubble_column")); 34 | 35 | if (targetBlock == null) { 36 | AquaAcrobaticsCore.LOGGER.error("Bubble column block not found"); 37 | return; 38 | } 39 | 40 | int targetId = Block.getIdFromBlock(targetBlock); 41 | int waterId = Block.getIdFromBlock(Blocks.WATER); 42 | 43 | if (waterId >= listBlockAliases.size()) { 44 | AquaAcrobaticsCore.LOGGER.error("Shader does not have block ID for water"); 45 | return; 46 | } 47 | 48 | List waterMappings = listBlockAliases.get(waterId); 49 | List bubbleColumnMappings = waterMappings.stream() 50 | .map(a -> OptifineHelper.rewriteBlockAliasForNewId(targetId, a)).collect(Collectors.toList()); 51 | 52 | while (listBlockAliases.size() <= targetId) { 53 | listBlockAliases.add(null); 54 | } 55 | 56 | listBlockAliases.set(targetId, bubbleColumnMappings); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/mixin/client/BlockFluidRendererMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.mixin.client; 2 | 3 | import com.fuzs.aquaacrobatics.config.ConfigHandler; 4 | import net.minecraft.block.material.Material; 5 | import net.minecraft.block.state.IBlockState; 6 | import net.minecraft.client.renderer.BlockFluidRenderer; 7 | import net.minecraft.client.renderer.BufferBuilder; 8 | import net.minecraft.client.renderer.color.BlockColors; 9 | import net.minecraft.util.math.BlockPos; 10 | import net.minecraft.world.IBlockAccess; 11 | import org.spongepowered.asm.mixin.Final; 12 | import org.spongepowered.asm.mixin.Mixin; 13 | import org.spongepowered.asm.mixin.Shadow; 14 | import org.spongepowered.asm.mixin.injection.*; 15 | import org.spongepowered.asm.mixin.injection.invoke.arg.Args; 16 | 17 | @Mixin(BlockFluidRenderer.class) 18 | public class BlockFluidRendererMixin { 19 | @Shadow @Final private BlockColors blockColors; 20 | 21 | 22 | @ModifyConstant( 23 | method = "initAtlasSprites", 24 | constant = @Constant(stringValue = "minecraft:blocks/water_still") 25 | ) 26 | private String getWaterStillTexture(String old) { 27 | if(ConfigHandler.BlocksConfig.newWaterColors) 28 | return "aquaacrobatics:blocks/water_still"; 29 | else 30 | return old; 31 | } 32 | 33 | @ModifyConstant( 34 | method = "initAtlasSprites", 35 | constant = @Constant(stringValue = "minecraft:blocks/water_flow") 36 | ) 37 | private String getWaterFlowTexture(String old) { 38 | if(ConfigHandler.BlocksConfig.newWaterColors) 39 | return "aquaacrobatics:blocks/water_flow"; 40 | else 41 | return old; 42 | } 43 | 44 | 45 | @ModifyArgs( 46 | method = "renderFluid", at = @At( 47 | value = "INVOKE", 48 | target = "Lnet/minecraft/client/renderer/BufferBuilder;color(FFFF)Lnet/minecraft/client/renderer/BufferBuilder;" 49 | ), 50 | slice = @Slice( 51 | from = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/BlockPos;down()Lnet/minecraft/util/math/BlockPos;", ordinal = 0), 52 | to = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/BlockPos;add(III)Lnet/minecraft/util/math/BlockPos;", ordinal = 0) 53 | ), 54 | expect = 4, 55 | require = 4 56 | ) 57 | private void overrideColorForBottomFace(Args args, IBlockAccess blockAccess, IBlockState blockStateIn, BlockPos blockPosIn, BufferBuilder bufferBuilderIn) { 58 | if(blockStateIn.getMaterial() == Material.WATER && ((Float)args.get(1)) == 0.5f && ((Float)args.get(2)) == 0.5f) { 59 | int i = blockColors.colorMultiplier(blockStateIn, blockAccess, blockPosIn, 0); 60 | float f = (float)(i >> 16 & 255) / 255.0F; 61 | float f1 = (float)(i >> 8 & 255) / 255.0F; 62 | float f2 = (float)(i & 255) / 255.0F; 63 | args.set(0, f); 64 | args.set(1, f1); 65 | args.set(2, f2); 66 | args.set(3, 1.0f); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/mixin/client/EntityRendererMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.mixin.client; 2 | 3 | import com.fuzs.aquaacrobatics.integration.IntegrationManager; 4 | import com.fuzs.aquaacrobatics.util.math.MathHelperNew; 5 | import net.minecraft.entity.player.EntityPlayer; 6 | import net.minecraft.util.math.MathHelper; 7 | import net.minecraft.block.material.Material; 8 | import net.minecraft.client.Minecraft; 9 | import net.minecraft.client.renderer.EntityRenderer; 10 | import net.minecraft.entity.Entity; 11 | import org.spongepowered.asm.mixin.Final; 12 | import org.spongepowered.asm.mixin.Mixin; 13 | import org.spongepowered.asm.mixin.Shadow; 14 | import org.spongepowered.asm.mixin.injection.*; 15 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 16 | 17 | @SuppressWarnings("unused") 18 | @Mixin(EntityRenderer.class) 19 | public abstract class EntityRendererMixin { 20 | 21 | @Shadow 22 | @Final 23 | private Minecraft mc; 24 | 25 | private float eyeHeight; 26 | private float previousEyeHeight; 27 | private float entityEyeHeight; 28 | private float partialTicks; 29 | 30 | @Inject(method = "orientCamera", at = @At("HEAD")) 31 | private void orientCamera(float partialTicks, CallbackInfo callbackInfo) { 32 | 33 | // field for passing on partialTicks, workaround as @ModifyVariable is unable to handle method arguments in Mixin <0.8 34 | this.partialTicks = partialTicks; 35 | } 36 | 37 | @ModifyVariable(method = "orientCamera", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/Entity;prevPosX:D", ordinal = 0), ordinal = 1) 38 | public float getEyeHeight(float eyeHeight) { 39 | Entity entity = this.mc.getRenderViewEntity(); 40 | 41 | // Do not apply eye height patch if the camera is not a player, or if Random Patches is installed 42 | if (!(entity instanceof EntityPlayer) || IntegrationManager.isRandomPatchesEnabled()) { 43 | return eyeHeight; 44 | } 45 | 46 | // need to do it like this to prevent crash with wings mod 47 | this.entityEyeHeight = eyeHeight; 48 | return MathHelperNew.lerp(this.partialTicks, this.previousEyeHeight, this.eyeHeight); 49 | } 50 | 51 | @Inject(method = "updateRenderer", at = @At("TAIL")) 52 | public void updateRenderer(CallbackInfo callbackInfo) { 53 | 54 | this.interpolateHeight(); 55 | } 56 | 57 | private void interpolateHeight() { 58 | 59 | this.previousEyeHeight = this.eyeHeight; 60 | this.eyeHeight += (this.entityEyeHeight - this.eyeHeight) * 0.5F; 61 | } 62 | 63 | /** 64 | * This mixin is marked as not required, as some mods patch this themselves. 65 | */ 66 | @Redirect( 67 | method = "renderWorldPass", 68 | at = @At( 69 | value = "INVOKE", 70 | target = "Lnet/minecraft/entity/Entity;isInsideOfMaterial(Lnet/minecraft/block/material/Material;)Z", 71 | ordinal = 0 72 | ), 73 | require = 0, 74 | expect = 0 75 | ) 76 | private boolean ignoreWater(Entity entity, Material material) { 77 | /* 1.13 removed this check */ 78 | if(material == Material.WATER) 79 | return false; 80 | return entity.isInsideOfMaterial(material); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/mixin/client/ItemRendererMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.mixin.client; 2 | 3 | import com.fuzs.aquaacrobatics.config.ConfigHandler; 4 | import net.minecraft.client.renderer.ItemRenderer; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.injection.At; 7 | import org.spongepowered.asm.mixin.injection.ModifyArg; 8 | 9 | @Mixin(ItemRenderer.class) 10 | public abstract class ItemRendererMixin { 11 | @ModifyArg(method = "renderWaterOverlayTexture", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/GlStateManager;color(FFFF)V", ordinal = 0), index = 3) 12 | private float replaceOpacity(float originalOpacity) { 13 | if(ConfigHandler.BlocksConfig.newWaterColors) 14 | return 0.1f; 15 | else 16 | return originalOpacity; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/mixin/client/ModelFluidMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.mixin.client; 2 | 3 | import com.fuzs.aquaacrobatics.config.ConfigHandler; 4 | import net.minecraft.util.ResourceLocation; 5 | import net.minecraftforge.client.model.ModelFluid; 6 | import net.minecraftforge.fluids.Fluid; 7 | import net.minecraftforge.fluids.FluidRegistry; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.injection.At; 10 | import org.spongepowered.asm.mixin.injection.Redirect; 11 | 12 | @Mixin(ModelFluid.class) 13 | public class ModelFluidMixin { 14 | private ResourceLocation aqua$getRealStill(Fluid fluid) { 15 | if(ConfigHandler.BlocksConfig.newWaterColors && fluid == FluidRegistry.WATER) 16 | return new ResourceLocation("aquaacrobatics:blocks/water_still"); 17 | else 18 | return fluid.getStill(); 19 | } 20 | 21 | private ResourceLocation aqua$getRealFlowing(Fluid fluid) { 22 | if(ConfigHandler.BlocksConfig.newWaterColors && fluid == FluidRegistry.WATER) 23 | return new ResourceLocation("aquaacrobatics:blocks/water_flow"); 24 | else 25 | return fluid.getFlowing(); 26 | } 27 | 28 | @Redirect(method = "getTextures", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fluids/Fluid;getStill()Lnet/minecraft/util/ResourceLocation;"), remap = false) 29 | private ResourceLocation getTextures_RealStill(Fluid fluid) { 30 | return aqua$getRealStill(fluid); 31 | } 32 | 33 | @Redirect(method = "getTextures", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fluids/Fluid;getFlowing()Lnet/minecraft/util/ResourceLocation;"), remap = false) 34 | private ResourceLocation getTextures_RealFlowing(Fluid fluid) { 35 | return aqua$getRealFlowing(fluid); 36 | } 37 | 38 | @Redirect(method = "bake", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fluids/Fluid;getStill()Lnet/minecraft/util/ResourceLocation;"), remap = false) 39 | private ResourceLocation bake_RealStill(Fluid fluid) { 40 | return aqua$getRealStill(fluid); 41 | } 42 | 43 | @Redirect(method = "bake", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fluids/Fluid;getFlowing()Lnet/minecraft/util/ResourceLocation;"), remap = false) 44 | private ResourceLocation bake_RealFlowing(Fluid fluid) { 45 | return aqua$getRealFlowing(fluid); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/mixin/client/PlayerControllerMPMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.mixin.client; 2 | 3 | import com.fuzs.aquaacrobatics.client.entity.IPlayerSPSwimming; 4 | import net.minecraft.client.entity.EntityPlayerSP; 5 | import net.minecraft.client.multiplayer.PlayerControllerMP; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Redirect; 9 | 10 | @SuppressWarnings("unused") 11 | @Mixin(PlayerControllerMP.class) 12 | public abstract class PlayerControllerMPMixin { 13 | 14 | @Redirect(method = "processRightClickBlock", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/entity/EntityPlayerSP;isSneaking()Z")) 15 | public boolean isSneaking(EntityPlayerSP playerIn) { 16 | 17 | return ((IPlayerSPSwimming) playerIn).isActuallySneaking(); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/mixin/client/RenderBoatMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.mixin.client; 2 | 3 | import com.fuzs.aquaacrobatics.entity.IRockableBoat; 4 | import net.minecraft.client.renderer.GlStateManager; 5 | import net.minecraft.client.renderer.entity.RenderBoat; 6 | import net.minecraft.entity.item.EntityBoat; 7 | import net.minecraft.util.math.MathHelper; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.injection.At; 10 | import org.spongepowered.asm.mixin.injection.Inject; 11 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 12 | 13 | @Mixin(RenderBoat.class) 14 | public class RenderBoatMixin { 15 | @Inject(method = "setupRotation", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/GlStateManager;scale(FFF)V", shift = At.Shift.BEFORE)) 16 | private void addRockingRotation(EntityBoat boat, float entityYaw, float partialTicks, CallbackInfo ci) { 17 | float f2 = ((IRockableBoat)boat).getRockingAngle(partialTicks); 18 | if (!MathHelper.epsilonEquals(f2, 0.0F)) { 19 | GlStateManager.rotate(f2, 1.0F, 0.0F, 1.0F); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/mixin/client/RenderPlayerMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.mixin.client; 2 | 3 | import com.fuzs.aquaacrobatics.integration.IntegrationManager; 4 | import com.fuzs.aquaacrobatics.integration.mobends.MoBendsIntegration; 5 | import com.fuzs.aquaacrobatics.client.model.IModelBipedSwimming; 6 | import com.fuzs.aquaacrobatics.entity.player.IPlayerResizeable; 7 | import com.fuzs.aquaacrobatics.util.math.MathHelperNew; 8 | import net.minecraft.util.math.MathHelper; 9 | import net.minecraft.client.entity.AbstractClientPlayer; 10 | import net.minecraft.client.model.ModelBase; 11 | import net.minecraft.client.model.ModelPlayer; 12 | import net.minecraft.client.renderer.GlStateManager; 13 | import net.minecraft.client.renderer.entity.RenderLivingBase; 14 | import net.minecraft.client.renderer.entity.RenderManager; 15 | import net.minecraft.client.renderer.entity.RenderPlayer; 16 | import org.spongepowered.asm.mixin.Mixin; 17 | import org.spongepowered.asm.mixin.injection.At; 18 | import org.spongepowered.asm.mixin.injection.Inject; 19 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 20 | 21 | @SuppressWarnings("unused") 22 | @Mixin(RenderPlayer.class) 23 | public abstract class RenderPlayerMixin extends RenderLivingBase { 24 | 25 | public RenderPlayerMixin(RenderManager renderManagerIn, ModelBase modelBaseIn, float shadowSizeIn) { 26 | 27 | super(renderManagerIn, modelBaseIn, shadowSizeIn); 28 | } 29 | 30 | @Inject(method = "renderRightArm", at = @At("HEAD")) 31 | public void renderRightArm(AbstractClientPlayer clientPlayer, CallbackInfo callbackInfo) { 32 | 33 | ModelPlayer modelplayer = (ModelPlayer) this.getMainModel(); 34 | ((IModelBipedSwimming) modelplayer).setSwimAnimation(0.0F); 35 | } 36 | 37 | @Inject(method = "renderLeftArm", at = @At("HEAD")) 38 | public void renderLeftArm(AbstractClientPlayer clientPlayer, CallbackInfo callbackInfo) { 39 | 40 | ModelPlayer modelplayer = (ModelPlayer) this.getMainModel(); 41 | ((IModelBipedSwimming) modelplayer).setSwimAnimation(0.0F); 42 | } 43 | 44 | @SuppressWarnings("ConstantConditions") 45 | @Inject(method = "applyRotations", at = @At("TAIL")) 46 | protected void applyRotations(AbstractClientPlayer entityLiving, float p_77043_2_, float rotationYaw, float partialTicks, CallbackInfo callbackInfo) { 47 | 48 | if (!entityLiving.isElytraFlying()) { 49 | 50 | if (!IntegrationManager.isMoBendsEnabled()) { 51 | 52 | float f = ((IPlayerResizeable) entityLiving).getSwimAnimation(partialTicks); 53 | float f3 = entityLiving.isInWater() ? -90.0F - entityLiving.rotationPitch : -90.0F; 54 | float f4 = MathHelperNew.lerp(f, 0.0F, f3); 55 | GlStateManager.rotate(f4, 1.0F, 0.0F, 0.0F); 56 | } 57 | 58 | if (((IPlayerResizeable) entityLiving).isActuallySwimming()) { 59 | 60 | if (!IntegrationManager.isMoBendsEnabled()) { 61 | 62 | GlStateManager.translate(0.0F, -1.0F, 0.3F); 63 | } else { 64 | 65 | MoBendsIntegration.applyRotations((RenderPlayer) (Object) this, entityLiving); 66 | } 67 | } 68 | } 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/thaumcraft/mixin/client/TileCrucibleRendererMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.thaumcraft.mixin.client; 2 | 3 | import net.minecraft.block.state.IBlockState; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.client.renderer.BlockModelShapes; 6 | import net.minecraft.client.renderer.texture.TextureAtlasSprite; 7 | import net.minecraft.init.Blocks; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.injection.At; 10 | import org.spongepowered.asm.mixin.injection.Redirect; 11 | import thaumcraft.client.renderers.tile.TileCrucibleRenderer; 12 | 13 | @Mixin(TileCrucibleRenderer.class) 14 | public class TileCrucibleRendererMixin { 15 | @Redirect(method = "renderFluid", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/BlockModelShapes;getTexture(Lnet/minecraft/block/state/IBlockState;)Lnet/minecraft/client/renderer/texture/TextureAtlasSprite;")) 16 | private TextureAtlasSprite getLegacyWaterTexture(BlockModelShapes instance, IBlockState state) { 17 | if(state == Blocks.WATER.getDefaultState()) 18 | return Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite("minecraft:blocks/water_still"); 19 | return instance.getTexture(state); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/core/xaerosminimap/mixin/client/MinimapWriterMixin.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.core.xaerosminimap.mixin.client; 2 | 3 | import com.fuzs.aquaacrobatics.config.ConfigHandler; 4 | import net.minecraft.block.Block; 5 | import net.minecraft.block.state.IBlockState; 6 | import net.minecraft.client.renderer.BlockModelShapes; 7 | import net.minecraft.client.renderer.texture.TextureAtlasSprite; 8 | import net.minecraft.init.Blocks; 9 | import net.minecraftforge.fml.client.FMLClientHandler; 10 | import org.spongepowered.asm.mixin.Mixin; 11 | import org.spongepowered.asm.mixin.injection.At; 12 | import org.spongepowered.asm.mixin.injection.Redirect; 13 | import xaero.common.minimap.write.MinimapWriter; 14 | 15 | @Mixin(MinimapWriter.class) 16 | public class MinimapWriterMixin { 17 | @Redirect(method = "loadBlockColourFromTexture", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/BlockModelShapes;getTexture(Lnet/minecraft/block/state/IBlockState;)Lnet/minecraft/client/renderer/texture/TextureAtlasSprite;")) 18 | private TextureAtlasSprite useWaterTexture(BlockModelShapes instance, IBlockState state) { 19 | Block block = state.getBlock(); 20 | if(ConfigHandler.BlocksConfig.newWaterColors && (block == Blocks.WATER || block == Blocks.FLOWING_WATER)) 21 | return FMLClientHandler.instance().getClient().getTextureMapBlocks().getAtlasSprite("aquaacrobatics:blocks/water_still"); 22 | else 23 | return instance.getTexture(state); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/entity/EntitySize.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.entity; 2 | 3 | @SuppressWarnings("unused") 4 | public class EntitySize { 5 | 6 | public final float width; 7 | public final float height; 8 | public final boolean fixed; 9 | 10 | public EntitySize(float widthIn, float heightIn, boolean fixedIn) { 11 | 12 | this.width = widthIn; 13 | this.height = heightIn; 14 | this.fixed = fixedIn; 15 | } 16 | 17 | public EntitySize scale(float factor) { 18 | 19 | return this.scale(factor, factor); 20 | } 21 | 22 | public EntitySize scale(float widthFactor, float heightFactor) { 23 | 24 | return !this.fixed && (widthFactor != 1.0F || heightFactor != 1.0F) ? flexible(this.width * widthFactor, this.height * heightFactor) : this; 25 | } 26 | 27 | public static EntitySize flexible(float widthIn, float heightIn) { 28 | 29 | return new EntitySize(widthIn, heightIn, false); 30 | } 31 | 32 | public static EntitySize fixed(float widthIn, float heightIn) { 33 | 34 | return new EntitySize(widthIn, heightIn, true); 35 | } 36 | 37 | @Override 38 | public boolean equals(Object obj) { 39 | 40 | if (obj == this) { 41 | 42 | return true; 43 | } else if (obj instanceof EntitySize) { 44 | 45 | return this.width == ((EntitySize) obj).width && this.height == ((EntitySize) obj).height; 46 | } 47 | 48 | return false; 49 | } 50 | 51 | @Override 52 | public String toString() { 53 | 54 | return "EntityDimensions w=" + this.width + ", h=" + this.height + ", fixed=" + this.fixed; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/entity/IBubbleColumnInteractable.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.entity; 2 | 3 | public interface IBubbleColumnInteractable { 4 | void onEnterBubbleColumnWithAirAbove(boolean downwards); 5 | void onEnterBubbleColumn(boolean downwards); 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/entity/IRockableBoat.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.entity; 2 | 3 | public interface IRockableBoat { 4 | float getRockingAngle(float partialTicks); 5 | 6 | void aqua$doRegisterData(); 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/entity/Pose.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.entity; 2 | 3 | public enum Pose { 4 | 5 | STANDING, 6 | FALL_FLYING, 7 | SLEEPING, 8 | SWIMMING, 9 | SPIN_ATTACK, 10 | CROUCHING, 11 | DYING 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/entity/player/IPlayerResizeable.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.entity.player; 2 | 3 | import com.fuzs.aquaacrobatics.entity.EntitySize; 4 | import com.fuzs.aquaacrobatics.entity.Pose; 5 | import net.minecraftforge.fml.relauncher.Side; 6 | import net.minecraftforge.fml.relauncher.SideOnly; 7 | 8 | public interface IPlayerResizeable { 9 | 10 | boolean canSwim(); 11 | 12 | void updateSwimming(); 13 | 14 | boolean getEyesInWaterPlayer(); 15 | 16 | float getWaterVision(); 17 | 18 | float getWidth(); 19 | 20 | float getHeight(); 21 | 22 | EntitySize getSize(Pose poseIn); 23 | 24 | void recalculateSize(); 25 | 26 | boolean isResizingAllowed(); 27 | 28 | boolean isActuallySneaking(); 29 | 30 | float getStandingEyeHeight(Pose poseIn, EntitySize sizeIn); 31 | 32 | void setPose(Pose poseIn); 33 | 34 | Pose getPose(); 35 | 36 | boolean isPoseClear(Pose poseIn); 37 | 38 | boolean getShouldBeDead(); 39 | 40 | boolean isSwimming(); 41 | 42 | boolean isActuallySwimming(); 43 | 44 | @SideOnly(Side.CLIENT) 45 | boolean isVisuallySwimming(); 46 | 47 | void setSwimming(boolean flag); 48 | 49 | float getSwimAnimation(float partialTicks); 50 | 51 | boolean canForceCrawling(); 52 | 53 | boolean isForcingCrawling(); 54 | 55 | void setForcingCrawling(boolean flag); 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/handler/CommonHandler.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.handler; 2 | 3 | import com.fuzs.aquaacrobatics.config.ConfigHandler; 4 | import com.fuzs.aquaacrobatics.entity.IRockableBoat; 5 | import net.minecraft.entity.item.EntityBoat; 6 | import net.minecraft.network.datasync.DataParameter; 7 | import net.minecraft.network.datasync.DataSerializers; 8 | import net.minecraft.network.datasync.EntityDataManager; 9 | import net.minecraftforge.event.entity.EntityEvent; 10 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 11 | 12 | public class CommonHandler { 13 | @SubscribeEvent 14 | public void onEntityConstructing(EntityEvent.EntityConstructing event) { 15 | if(event.getEntity() instanceof EntityBoat) { 16 | if(ConfigHandler.MiscellaneousConfig.bubbleColumns) 17 | ((IRockableBoat)event.getEntity()).aqua$doRegisterData(); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/integration/IElytraOpenHook.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.integration; 2 | 3 | import net.minecraft.client.entity.EntityPlayerSP; 4 | 5 | public interface IElytraOpenHook { 6 | void openElytra(EntityPlayerSP player); 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/integration/IntegrationManager.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.integration; 2 | 3 | import com.fuzs.aquaacrobatics.config.ConfigHandler; 4 | import net.minecraftforge.fml.common.Loader; 5 | 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | 9 | public class IntegrationManager { 10 | 11 | private static boolean isBetweenlandsLoaded; 12 | private static boolean isChiseledMeLoaded; 13 | private static boolean isEnderIoLoaded; 14 | private static boolean isRandomPatchesLoaded; 15 | private static boolean isMoBendsLoaded; 16 | private static boolean isWingsLoaded; 17 | private static boolean isArtemisLibLoaded; 18 | private static boolean isMorphLoaded; 19 | private static boolean isHatsLoaded; 20 | private static boolean isThaumicAugmentationLoaded; 21 | private static boolean isTrinketsAndBaublesLoaded; 22 | private static boolean isWitcheryResurrectedLoaded; 23 | 24 | private static boolean isAE2Loaded; 25 | 26 | public static List elytraOpenHooks = new LinkedList<>(); 27 | 28 | public static void loadCompat() { 29 | isAE2Loaded = Loader.isModLoaded("appliedenergistics2"); 30 | isBetweenlandsLoaded = Loader.isModLoaded("thebetweenlands"); 31 | isChiseledMeLoaded = Loader.isModLoaded("chiseled_me"); 32 | isEnderIoLoaded = Loader.isModLoaded("enderio"); 33 | isRandomPatchesLoaded = Loader.isModLoaded("randompatches"); 34 | isMoBendsLoaded = Loader.isModLoaded("mobends"); 35 | isWingsLoaded = Loader.isModLoaded("wings"); 36 | isArtemisLibLoaded = Loader.isModLoaded("artemislib"); 37 | isMorphLoaded = Loader.isModLoaded("morph"); 38 | isHatsLoaded = Loader.isModLoaded("hats"); 39 | isThaumicAugmentationLoaded = Loader.isModLoaded("thaumicaugmentation"); 40 | isTrinketsAndBaublesLoaded = Loader.isModLoaded("xat"); 41 | isWitcheryResurrectedLoaded = Loader.isModLoaded("witchery"); 42 | } 43 | 44 | public static boolean isAE2Enabled() { 45 | 46 | return isAE2Loaded && ConfigHandler.IntegrationConfig.ae2Integration; 47 | } 48 | 49 | public static boolean isBetweenlandsEnabled() { 50 | 51 | return isBetweenlandsLoaded && ConfigHandler.IntegrationConfig.betweenlandsIntegration; 52 | } 53 | 54 | public static boolean isChiseledMeEnabled() { 55 | 56 | return isChiseledMeLoaded && ConfigHandler.IntegrationConfig.chiseledMeIntegration; 57 | } 58 | 59 | public static boolean isEnderIoEnabled() { 60 | 61 | return isEnderIoLoaded && ConfigHandler.IntegrationConfig.enderIoIntegration; 62 | } 63 | 64 | public static boolean isRandomPatchesEnabled() { 65 | 66 | return isRandomPatchesLoaded && ConfigHandler.IntegrationConfig.randomPatchesIntegration; 67 | } 68 | 69 | public static boolean isMoBendsEnabled() { 70 | 71 | return isMoBendsLoaded && ConfigHandler.IntegrationConfig.moBendsIntegration; 72 | } 73 | 74 | public static boolean isWingsEnabled() { 75 | 76 | return isWingsLoaded && ConfigHandler.IntegrationConfig.wingsIntegration; 77 | } 78 | 79 | public static boolean isArtemisLibEnabled() { 80 | 81 | return isArtemisLibLoaded && ConfigHandler.IntegrationConfig.artemisLibIntegration; 82 | } 83 | 84 | public static boolean isMorphEnabled() { 85 | 86 | return isMorphLoaded && ConfigHandler.IntegrationConfig.morphIntegration; 87 | } 88 | 89 | public static boolean isHatsEnabled() { 90 | 91 | return isHatsLoaded && ConfigHandler.IntegrationConfig.hatsIntegration; 92 | } 93 | 94 | public static boolean isThaumicAugmentationEnabled() { 95 | 96 | return isThaumicAugmentationLoaded && ConfigHandler.IntegrationConfig.thaumicAugmentationIntegration; 97 | } 98 | 99 | public static boolean isTrinketsAndBaublesEnabled() { 100 | 101 | return isTrinketsAndBaublesLoaded && ConfigHandler.IntegrationConfig.trinketsAndBaublesIntegration; 102 | } 103 | 104 | public static boolean isWitcheryResurrectedEnabled() 105 | { 106 | return isWitcheryResurrectedLoaded && ConfigHandler.IntegrationConfig.witcheryResurrectedIntegration; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/integration/ae2/AE2Integration.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.integration.ae2; 2 | 3 | import appeng.api.implementations.items.IGrowableCrystal; 4 | import net.minecraft.entity.item.EntityItem; 5 | 6 | public class AE2Integration { 7 | public static boolean isGrowingCrystal(EntityItem item) { 8 | return item.getItem().getItem() instanceof IGrowableCrystal; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/integration/artemislib/ArtemisLibIntegration.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.integration.artemislib; 2 | 3 | import com.artemis.artemislib.util.AttachAttributes; 4 | import com.artemis.artemislib.util.attributes.ArtemisLibAttributes; 5 | import com.fuzs.aquaacrobatics.core.mixin.accessor.IEventBusAccessor; 6 | import com.fuzs.aquaacrobatics.entity.Pose; 7 | import com.fuzs.aquaacrobatics.entity.player.IPlayerResizeable; 8 | import net.minecraft.entity.ai.attributes.AttributeModifier; 9 | import net.minecraft.entity.ai.attributes.IAttributeInstance; 10 | import net.minecraft.entity.player.EntityPlayer; 11 | import net.minecraftforge.common.MinecraftForge; 12 | 13 | import java.util.Optional; 14 | import java.util.UUID; 15 | 16 | public class ArtemisLibIntegration { 17 | 18 | private static final UUID SWIMMING_HEIGHT_ID = UUID.fromString("F5ED4D20-4DAB-11EB-AE93-0242AC130002"); 19 | private static final AttributeModifier SWIMMING_HEIGHT = new AttributeModifier(SWIMMING_HEIGHT_ID, "Swimming height modifier", -2.0 / 3.0, 2); 20 | 21 | public static void register() { 22 | 23 | Optional optional = ((IEventBusAccessor) MinecraftForge.EVENT_BUS).getListeners().keySet().stream() 24 | .filter(key -> key instanceof AttachAttributes).findFirst(); 25 | if (optional.isPresent()) { 26 | 27 | MinecraftForge.EVENT_BUS.unregister(optional.get()); 28 | MinecraftForge.EVENT_BUS.register(new AttachAttributesFix()); 29 | } 30 | } 31 | 32 | public static void updateSwimmingSize(EntityPlayer player, Pose pose) { 33 | 34 | IAttributeInstance iattributeinstance = player.getEntityAttribute(ArtemisLibAttributes.ENTITY_HEIGHT); 35 | if (iattributeinstance.getModifier(SWIMMING_HEIGHT_ID) != null) { 36 | 37 | iattributeinstance.removeModifier(SWIMMING_HEIGHT); 38 | } 39 | 40 | if (pose == Pose.SWIMMING) { 41 | iattributeinstance.applyModifier(SWIMMING_HEIGHT); 42 | } 43 | } 44 | 45 | public static float getEyeFactor(EntityPlayer player) { 46 | if(((IPlayerResizeable)player).getPose() == Pose.SWIMMING) { 47 | double heightAttribute = player.getAttributeMap().getAttributeInstance(ArtemisLibAttributes.ENTITY_HEIGHT).getAttributeValue(); 48 | return (float)(heightAttribute * 3); 49 | } 50 | return 1f; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/integration/artemislib/AttachAttributesFix.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.integration.artemislib; 2 | 3 | import com.artemis.artemislib.compatibilities.sizeCap.ISizeCap; 4 | import com.artemis.artemislib.compatibilities.sizeCap.SizeCapPro; 5 | import com.artemis.artemislib.util.AttachAttributes; 6 | import com.artemis.artemislib.util.attributes.ArtemisLibAttributes; 7 | import com.fuzs.aquaacrobatics.entity.Pose; 8 | import com.fuzs.aquaacrobatics.entity.player.IPlayerResizeable; 9 | import net.minecraft.client.renderer.GlStateManager; 10 | import net.minecraft.entity.EntityLivingBase; 11 | import net.minecraftforge.client.event.RenderLivingEvent; 12 | import net.minecraftforge.event.entity.EntityEvent; 13 | import net.minecraftforge.event.entity.living.LivingEvent; 14 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 15 | import net.minecraftforge.fml.common.gameevent.TickEvent; 16 | 17 | public class AttachAttributesFix extends AttachAttributes { 18 | 19 | private boolean isResizingRequired; 20 | 21 | @Override 22 | @SubscribeEvent 23 | public void attachAttributes(final EntityEvent.EntityConstructing evt) { 24 | 25 | super.attachAttributes(evt); 26 | } 27 | 28 | @Override 29 | @SubscribeEvent 30 | public void onPlayerTick(final TickEvent.PlayerTickEvent evt) { 31 | 32 | super.onPlayerTick(evt); 33 | } 34 | 35 | @Override 36 | @SubscribeEvent 37 | public void onLivingUpdate(final LivingEvent.LivingUpdateEvent evt) { 38 | 39 | super.onLivingUpdate(evt); 40 | } 41 | 42 | @Override 43 | @SubscribeEvent 44 | public void onEntityRenderPre(final RenderLivingEvent.Pre evt) { 45 | 46 | EntityLivingBase entity = evt.getEntity(); 47 | this.updateResizingFlag(entity); 48 | if (this.isResizingRequired) { 49 | 50 | double widthAttribute = entity.getAttributeMap().getAttributeInstance(ArtemisLibAttributes.ENTITY_WIDTH).getAttributeValue(); 51 | double heightAttribute = entity.getAttributeMap().getAttributeInstance(ArtemisLibAttributes.ENTITY_HEIGHT).getAttributeValue(); 52 | // prevent flicker when starting to swim by also checking the animation 53 | if (entity instanceof IPlayerResizeable && ((IPlayerResizeable) entity).getPose() == Pose.SWIMMING && ((IPlayerResizeable) entity).getSwimAnimation(evt.getPartialRenderTick()) > 0.0F) { 54 | 55 | heightAttribute *= 3.0; 56 | } 57 | 58 | widthAttribute = Math.max(widthAttribute, 0.15F); 59 | heightAttribute = Math.max(heightAttribute, 0.25F); 60 | GlStateManager.pushMatrix(); 61 | GlStateManager.scale(widthAttribute, heightAttribute, widthAttribute); 62 | GlStateManager.translate(evt.getX() / widthAttribute - evt.getX(), evt.getY() / heightAttribute - evt.getY(), evt.getZ() / widthAttribute - evt.getZ()); 63 | } 64 | } 65 | 66 | @Override 67 | @SubscribeEvent 68 | public void onLivingRenderPost(final RenderLivingEvent.Post evt) { 69 | 70 | if (this.isResizingRequired) { 71 | 72 | GlStateManager.popMatrix(); 73 | } 74 | } 75 | 76 | private void updateResizingFlag(EntityLivingBase entity) { 77 | 78 | if (entity.hasCapability(SizeCapPro.sizeCapability, null)) { 79 | 80 | ISizeCap cap = entity.getCapability(SizeCapPro.sizeCapability, null); 81 | if (cap != null && cap.getTrans()) { 82 | 83 | boolean isWidthModified = !entity.getAttributeMap().getAttributeInstance(ArtemisLibAttributes.ENTITY_WIDTH).getModifiers().isEmpty(); 84 | boolean isHeightModified = !entity.getAttributeMap().getAttributeInstance(ArtemisLibAttributes.ENTITY_HEIGHT).getModifiers().isEmpty(); 85 | this.isResizingRequired = isWidthModified || isHeightModified; 86 | 87 | return; 88 | } 89 | } 90 | 91 | this.isResizingRequired = false; 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/integration/betweenlands/BetweenlandsIntegration.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.integration.betweenlands; 2 | 3 | import net.minecraft.entity.player.EntityPlayer; 4 | import net.minecraft.item.ItemStack; 5 | import thebetweenlands.common.capability.collision.RingOfDispersionEntityCapability; 6 | 7 | public class BetweenlandsIntegration { 8 | /** 9 | * Checks if the player is potentially able to phase at some point. 10 | */ 11 | public static boolean couldPlayerPhase(EntityPlayer player) { 12 | ItemStack ring = RingOfDispersionEntityCapability.getRing(player); 13 | if(ring == ItemStack.EMPTY) 14 | return false; 15 | return ring.getItemDamage() < ring.getMaxDamage() && !player.isSpectator(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/integration/chiseledme/ChiseledMeIntegration.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.integration.chiseledme; 2 | 3 | import dev.necauqua.mods.cm.api.ISized; 4 | import net.minecraft.entity.player.EntityPlayer; 5 | 6 | public class ChiseledMeIntegration { 7 | public static float getResizeFactor(EntityPlayer player) { 8 | return (float)((ISized)player).getSizeCM(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/integration/enderio/EnderIOIntegration.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.integration.enderio; 2 | 3 | import com.fuzs.aquaacrobatics.integration.IntegrationManager; 4 | import crazypants.enderio.base.handler.darksteel.StateController; 5 | import crazypants.enderio.base.item.darksteel.upgrade.elytra.ElytraUpgrade; 6 | 7 | public class EnderIOIntegration { 8 | public static void register() { 9 | IntegrationManager.elytraOpenHooks.add(player -> { 10 | if(!StateController.isActive(player, ElytraUpgrade.INSTANCE)) { 11 | StateController.setActive(player, ElytraUpgrade.INSTANCE, true); 12 | } 13 | }); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/integration/hats/HatsIntegration.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.integration.hats; 2 | 3 | import com.fuzs.aquaacrobatics.entity.player.IPlayerResizeable; 4 | import me.ichun.mods.hats.client.render.helper.HelperPlayer; 5 | import me.ichun.mods.hats.common.core.ApiHandler; 6 | import net.minecraft.entity.EntityLivingBase; 7 | 8 | public class HatsIntegration { 9 | 10 | public static void register() { 11 | 12 | ApiHandler.registerHelper(new HelperPlayer() { 13 | 14 | @Override 15 | public float getHatScale(EntityLivingBase entityIn) { 16 | 17 | if (entityIn instanceof IPlayerResizeable) { 18 | 19 | if (((IPlayerResizeable) entityIn).getSwimAnimation(1.0F) > 0.0F) { 20 | 21 | return 0.0F; 22 | } 23 | } 24 | 25 | return super.getHatScale(entityIn); 26 | } 27 | 28 | }); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/integration/mobends/MoBendsIntegration.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.integration.mobends; 2 | 3 | import goblinbob.mobends.core.bender.EntityBender; 4 | import goblinbob.mobends.core.bender.EntityBenderRegistry; 5 | import goblinbob.mobends.core.data.IEntityDataFactory; 6 | import goblinbob.mobends.core.data.LivingEntityData; 7 | import goblinbob.mobends.core.mutators.Mutator; 8 | import goblinbob.mobends.standard.PlayerBender; 9 | import net.minecraft.client.entity.AbstractClientPlayer; 10 | import net.minecraft.client.renderer.GlStateManager; 11 | import net.minecraft.client.renderer.entity.RenderPlayer; 12 | 13 | public class MoBendsIntegration { 14 | 15 | public static void register() { 16 | 17 | EntityBenderRegistry.instance.registerBender(new PlayerBender() { 18 | 19 | @Override 20 | public IEntityDataFactory getDataFactory() { 21 | 22 | return SwimmingPlayerData::new; 23 | } 24 | 25 | }); 26 | } 27 | 28 | @SuppressWarnings({"rawtypes", "unchecked"}) 29 | public static void applyRotations(RenderPlayer renderer, AbstractClientPlayer entityLiving) { 30 | 31 | EntityBender entityBender = EntityBenderRegistry.instance.getForEntity(entityLiving); 32 | if (entityBender != null && entityBender.isAnimated()) { 33 | 34 | Mutator mutator = entityBender.getMutator(renderer); 35 | LivingEntityData entityData = mutator.getData(entityLiving); 36 | if (!entityData.isStillHorizontally() && !entityData.isDrawingBow() && !(entityData.getTicksAfterAttack() < 10) && entityData.isUnderwater()) { 37 | 38 | GlStateManager.translate(0.0F, 0.2F, -0.9F); 39 | } 40 | } 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/integration/mobends/SwimmingPlayerData.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.integration.mobends; 2 | 3 | import com.fuzs.aquaacrobatics.entity.player.IPlayerResizeable; 4 | import com.fuzs.aquaacrobatics.client.entity.IPlayerSPSwimming; 5 | import goblinbob.mobends.standard.animation.controller.PlayerController; 6 | import goblinbob.mobends.standard.data.PlayerData; 7 | import net.minecraft.client.entity.AbstractClientPlayer; 8 | 9 | import java.util.ArrayList; 10 | import java.util.Collection; 11 | import java.util.List; 12 | 13 | public class SwimmingPlayerData extends PlayerData { 14 | 15 | private final PlayerController controller = new PlayerController() { 16 | 17 | @Override 18 | public Collection perform(PlayerData data) { 19 | 20 | final AbstractClientPlayer player = data.getEntity(); 21 | if (!(player.isEntityAlive() && player.isPlayerSleeping())) { 22 | 23 | if (!player.isRiding()) { 24 | 25 | if (data.isUnderwater() || (!data.isOnGround() || data.getTicksAfterTouchdown() < 1) && data.isFlying()) { 26 | 27 | this.layerCape.playOrContinueBit(this.bitCape, data); 28 | if (data.isUnderwater()) { 29 | 30 | // make swimming animation play when crawling on land 31 | this.layerBase.playOrContinueBit(this.bitSwimming, data); 32 | this.layerSneak.clearAnimation(); 33 | this.layerTorch.clearAnimation(); 34 | } else if ((!data.isOnGround() || data.getTicksAfterTouchdown() < 1) && data.isFlying()) { 35 | 36 | // enable flying animation in water 37 | this.layerBase.playOrContinueBit(this.bitFlying, data); 38 | } 39 | 40 | this.performActionAnimations(data, player); 41 | 42 | final List actions = new ArrayList<>(); 43 | this.layerBase.perform(data, actions); 44 | this.layerSneak.perform(data, actions); 45 | this.layerTorch.perform(data, actions); 46 | this.layerCape.perform(data, actions); 47 | 48 | return actions; 49 | } 50 | } 51 | } 52 | 53 | return super.perform(data); 54 | } 55 | 56 | }; 57 | 58 | public SwimmingPlayerData(AbstractClientPlayer entity) { 59 | 60 | super(entity); 61 | } 62 | 63 | @Override 64 | public PlayerController getController() { 65 | 66 | return this.controller; 67 | } 68 | 69 | @Override 70 | public boolean isStillHorizontally() { 71 | 72 | if (this.entity instanceof IPlayerSPSwimming) { 73 | 74 | return !this.isSwimming() && super.isStillHorizontally(); 75 | } 76 | 77 | return super.isStillHorizontally(); 78 | } 79 | 80 | @Override 81 | public boolean isUnderwater() { 82 | 83 | return this.isSwimming(); 84 | } 85 | 86 | private boolean isSwimming() { 87 | 88 | return ((IPlayerResizeable) this.entity).isActuallySwimming(); 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/integration/morph/MorphIntegration.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.integration.morph; 2 | 3 | import me.ichun.mods.morph.api.IApi; 4 | import me.ichun.mods.morph.api.MorphApi; 5 | import net.minecraft.entity.player.EntityPlayer; 6 | import net.minecraftforge.fml.relauncher.Side; 7 | 8 | public class MorphIntegration { 9 | 10 | public static boolean isMorphing(EntityPlayer player) { 11 | 12 | IApi api = MorphApi.getApiImpl(); 13 | if (api.isMorphApi()) { 14 | 15 | return api.morphProgress(player.getName(), getSide(player.world.isRemote)) < 1.0F; 16 | } 17 | 18 | return false; 19 | } 20 | 21 | private static Side getSide(boolean isRemote) { 22 | 23 | return isRemote ? Side.CLIENT : Side.SERVER; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/integration/thaumicaugmentation/ThaumicAugmentationIntegration.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.integration.thaumicaugmentation; 2 | 3 | import com.fuzs.aquaacrobatics.integration.IntegrationManager; 4 | import thecodex6824.thaumicaugmentation.client.internal.TAHooksClient; 5 | 6 | public class ThaumicAugmentationIntegration { 7 | public static void register() { 8 | IntegrationManager.elytraOpenHooks.add(TAHooksClient::checkElytra); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/integration/trinketsandbaubles/TrinketsAndBaublesIntegration.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.integration.trinketsandbaubles; 2 | 3 | import net.minecraft.entity.player.EntityPlayer; 4 | import xzeroair.trinkets.capabilities.Capabilities; 5 | import xzeroair.trinkets.capabilities.race.EntityProperties; 6 | 7 | public class TrinketsAndBaublesIntegration { 8 | public static float getResizeFactor(EntityPlayer player) { 9 | EntityProperties props = Capabilities.getEntityRace(player); 10 | if(props != null) 11 | return (float)props.getSize() / 100f; 12 | else 13 | return 1f; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/integration/wings/WingsIntegration.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.integration.wings; 2 | 3 | import me.paulf.wings.server.asm.PlayerFlightCheckEvent; 4 | import net.minecraft.entity.player.EntityPlayer; 5 | import net.minecraftforge.common.MinecraftForge; 6 | import net.minecraftforge.fml.common.eventhandler.Event; 7 | 8 | public class WingsIntegration { 9 | 10 | public static boolean onFlightCheck(EntityPlayer player, boolean isElytraFlying) { 11 | 12 | PlayerFlightCheckEvent evt = new PlayerFlightCheckEvent(player); 13 | MinecraftForge.EVENT_BUS.post(evt); 14 | return evt.getResult() == Event.Result.ALLOW || evt.getResult() == Event.Result.DEFAULT && isElytraFlying; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/integration/witchery/WitcheryResurrectedIntegration.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.integration.witchery; 2 | 3 | import com.fuzs.aquaacrobatics.integration.IntegrationManager; 4 | import net.minecraft.entity.player.EntityPlayer; 5 | import net.msrandom.witchery.init.WitcheryCreatureTraits; 6 | import net.msrandom.witchery.init.data.WitcheryAlternateForms; 7 | import net.msrandom.witchery.transformation.CreatureForm; 8 | import net.msrandom.witchery.util.WitcheryUtils; 9 | 10 | public class WitcheryResurrectedIntegration 11 | { 12 | public static boolean HAS_TRANSFORMED = false; 13 | 14 | private static Transformation currentTransformation = Transformation.PLAYER; 15 | 16 | public static void register() { 17 | CreatureForm.PLAYER_TRANSFORM_EVENT.subscribe((sender, args) -> { 18 | if (args.getCurrentForm() == WitcheryAlternateForms.BAT) { 19 | currentTransformation = Transformation.BAT; 20 | } else if (args.getCurrentForm() == WitcheryAlternateForms.WOLFMAN) { 21 | currentTransformation = Transformation.WOLFMAN; 22 | } else if (args.getCurrentForm() == WitcheryAlternateForms.WOLF) { 23 | currentTransformation = Transformation.WOLF; 24 | } else if (args.getCurrentForm() == WitcheryAlternateForms.TOAD) { 25 | currentTransformation = Transformation.TOAD; 26 | } else { 27 | currentTransformation = Transformation.PLAYER; 28 | } 29 | HAS_TRANSFORMED = true; 30 | }); 31 | } 32 | 33 | public static Transformation getCurrentTransformation() 34 | { 35 | return currentTransformation; 36 | } 37 | 38 | public enum Transformation { 39 | PLAYER, 40 | WOLF, 41 | WOLFMAN, 42 | BAT, 43 | TOAD; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/network/NetworkHandler.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.network; 2 | 3 | import com.fuzs.aquaacrobatics.network.message.PacketSendKey; 4 | import net.minecraftforge.fml.common.network.NetworkRegistry; 5 | import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper; 6 | import net.minecraftforge.fml.relauncher.Side; 7 | 8 | public class NetworkHandler { 9 | private static int packetId = 0; 10 | 11 | public static SimpleNetworkWrapper INSTANCE = null; 12 | 13 | public NetworkHandler() { 14 | } 15 | 16 | public static int nextID() { 17 | return packetId++; 18 | } 19 | 20 | public static void registerMessages(String channelName) { 21 | INSTANCE = NetworkRegistry.INSTANCE.newSimpleChannel(channelName); 22 | registerMessages(); 23 | } 24 | 25 | public static void registerMessages() { 26 | INSTANCE.registerMessage(PacketSendKey.Handler.class, PacketSendKey.class, nextID(), Side.SERVER); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/network/datasync/PoseSerializer.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.network.datasync; 2 | 3 | import com.fuzs.aquaacrobatics.entity.Pose; 4 | import net.minecraft.network.PacketBuffer; 5 | import net.minecraft.network.datasync.DataParameter; 6 | import net.minecraft.network.datasync.DataSerializer; 7 | import net.minecraft.network.datasync.DataSerializers; 8 | 9 | @SuppressWarnings({"NullableProblems", "deprecation"}) 10 | public class PoseSerializer { 11 | 12 | public static final DataSerializer POSE = new DataSerializer() { 13 | 14 | public void write(PacketBuffer buf, Pose value) { 15 | 16 | buf.writeEnumValue(value); 17 | } 18 | 19 | public Pose read(PacketBuffer buf) { 20 | 21 | return buf.readEnumValue(Pose.class); 22 | } 23 | 24 | public DataParameter createKey(int id) { 25 | 26 | return new DataParameter<>(id, this); 27 | } 28 | 29 | public Pose copyValue(Pose value) { 30 | 31 | return value; 32 | } 33 | 34 | }; 35 | 36 | static { 37 | 38 | DataSerializers.registerSerializer(POSE); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/network/message/PacketSendKey.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.network.message; 2 | 3 | import com.fuzs.aquaacrobatics.entity.player.IPlayerResizeable; 4 | import io.netty.buffer.ByteBuf; 5 | import net.minecraft.entity.player.EntityPlayerMP; 6 | import net.minecraftforge.fml.common.FMLCommonHandler; 7 | import net.minecraftforge.fml.common.network.simpleimpl.IMessage; 8 | import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; 9 | import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; 10 | 11 | public class PacketSendKey implements IMessage { 12 | public enum KeybindPacket { 13 | UNKNOWN, 14 | TOGGLE_CRAWLING 15 | } 16 | private KeybindPacket keybind = KeybindPacket.UNKNOWN; 17 | 18 | @Override 19 | public void fromBytes(ByteBuf buf) { 20 | int idx = buf.readInt(); 21 | if(idx >= KeybindPacket.values().length) 22 | keybind = KeybindPacket.UNKNOWN; 23 | else 24 | keybind = KeybindPacket.values()[idx]; 25 | } 26 | 27 | @Override 28 | public void toBytes(ByteBuf buf) { 29 | buf.writeInt(keybind.ordinal()); 30 | } 31 | 32 | public PacketSendKey() { 33 | 34 | } 35 | 36 | public PacketSendKey(KeybindPacket keybind) { 37 | this.keybind = keybind; 38 | } 39 | 40 | public static class Handler implements IMessageHandler { 41 | @Override 42 | public IMessage onMessage(PacketSendKey message, MessageContext ctx) { 43 | // Always use a construct like this to actually handle your message. This ensures that 44 | // your 'handle' code is run on the main Minecraft thread. 'onMessage' itself 45 | // is called on the networking thread so it is not safe to do a lot of things 46 | // here. 47 | FMLCommonHandler.instance().getWorldThread(ctx.netHandler).addScheduledTask(() -> handle(message, ctx)); 48 | return null; 49 | } 50 | 51 | private void handle(PacketSendKey message, MessageContext ctx) { 52 | EntityPlayerMP playerEntity = ctx.getServerHandler().player; 53 | if(message.keybind == KeybindPacket.TOGGLE_CRAWLING) { 54 | IPlayerResizeable resizeable = (IPlayerResizeable)playerEntity; 55 | resizeable.setForcingCrawling(!resizeable.isForcingCrawling()); 56 | } 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/optifine/OptifineHelper.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.optifine; 2 | 3 | import com.fuzs.aquaacrobatics.AquaAcrobatics; 4 | 5 | import java.lang.reflect.Array; 6 | import java.lang.reflect.Constructor; 7 | import java.lang.reflect.Field; 8 | import java.lang.reflect.Method; 9 | 10 | public class OptifineHelper { 11 | public static boolean isOFPresent; 12 | 13 | public static void init() { 14 | Class reflectorMainClass; 15 | try { 16 | reflectorMainClass = Class.forName("net.optifine.reflect.Reflector"); 17 | } catch(ClassNotFoundException e) { 18 | return; 19 | } 20 | AquaAcrobatics.LOGGER.info("OptiFine detected. Performing highly invasive tweaks to fix water issues."); 21 | try { 22 | Class reflectorMethod = Class.forName("net.optifine.reflect.ReflectorMethod"); 23 | Object newReflectorMethod = reflectorMethod.getConstructor(Class.forName("net.optifine.reflect.ReflectorClass"), String.class).newInstance(reflectorMainClass.getDeclaredField("ForgeBiome").get(null), "aqua$waterColorMultiplier"); 24 | Field biomeMethodField = reflectorMainClass.getDeclaredField("ForgeBiome_getWaterColorMultiplier"); 25 | biomeMethodField.setAccessible(true); 26 | biomeMethodField.set(null, newReflectorMethod); 27 | } catch(ReflectiveOperationException e) { 28 | AquaAcrobatics.LOGGER.error("An error occured while patching OptiFine", e); 29 | return; 30 | } 31 | 32 | isOFPresent = true; 33 | } 34 | 35 | /** 36 | * Force a reload of the block aliases when FML ID mappings change. 37 | */ 38 | public static void reloadBlockAliases() { 39 | try { 40 | Class blockAliasesClass = Class.forName("net.optifine.shaders.BlockAliases"); 41 | Class shadersClass = Class.forName("net.optifine.shaders.Shaders"); 42 | Method getShaderPackMethod = shadersClass.getDeclaredMethod("getShaderPack"); 43 | Method updateMethod = blockAliasesClass.getDeclaredMethod("update", Class.forName("net.optifine.shaders.IShaderPack")); 44 | updateMethod.invoke(null, getShaderPackMethod.invoke(null)); 45 | } catch (Exception e) { 46 | AquaAcrobatics.LOGGER.error("Error reloading OptiFine block aliases", e); 47 | } 48 | } 49 | 50 | /** 51 | * Rewrite an OptiFine shader block alias to use the same metadata filters but a different main block ID. 52 | */ 53 | public static Object rewriteBlockAliasForNewId(int mainId, Object blockAlias) { 54 | if (blockAlias == null) { 55 | return null; 56 | } 57 | try { 58 | Field blockAliasIdField = blockAlias.getClass().getDeclaredField("blockAliasId"); 59 | blockAliasIdField.setAccessible(true); 60 | int blockAliasId = blockAliasIdField.getInt(blockAlias); 61 | Field matchField = blockAlias.getClass().getDeclaredField("matchBlocks"); 62 | matchField.setAccessible(true); 63 | Object matchArray = matchField.get(blockAlias); 64 | int numMatches = Array.getLength(matchArray); 65 | Class matchBlockClass = Class.forName("net.optifine.config.MatchBlock"); 66 | Constructor matchBlockConstructor = matchBlockClass.getDeclaredConstructor(int.class, int[].class); 67 | Field blockIdField = matchBlockClass.getDeclaredField("blockId"); 68 | blockIdField.setAccessible(true); 69 | Field metadatasField = matchBlockClass.getDeclaredField("metadatas"); 70 | metadatasField.setAccessible(true); 71 | Object newMatchArray = Array.newInstance(matchBlockClass, numMatches); 72 | for (int i = 0; i < numMatches; i++) { 73 | Object match = Array.get(matchArray, i); 74 | int[] metadatas = (int[])metadatasField.get(match); 75 | Object newMatch = matchBlockConstructor.newInstance(mainId, metadatas); 76 | Array.set(newMatchArray, i, newMatch); 77 | } 78 | Constructor blockAliasConstructor = blockAlias.getClass().getDeclaredConstructor(int.class, newMatchArray.getClass()); 79 | return blockAliasConstructor.newInstance(blockAliasId, newMatchArray); 80 | } catch(Exception e) { 81 | AquaAcrobatics.LOGGER.error("An error occured while patching OptiFine", e); 82 | return blockAlias; 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/proxy/ClientProxy.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.proxy; 2 | 3 | import com.fuzs.aquaacrobatics.block.BlockBubbleColumn; 4 | import com.fuzs.aquaacrobatics.client.handler.AirMeterHandler; 5 | import com.fuzs.aquaacrobatics.client.handler.FogHandler; 6 | import com.fuzs.aquaacrobatics.client.model.WaterResourcePack; 7 | import com.fuzs.aquaacrobatics.config.ConfigHandler; 8 | import com.fuzs.aquaacrobatics.entity.player.IPlayerResizeable; 9 | import com.fuzs.aquaacrobatics.integration.IntegrationManager; 10 | import com.fuzs.aquaacrobatics.integration.artemislib.ArtemisLibIntegration; 11 | import com.fuzs.aquaacrobatics.integration.enderio.EnderIOIntegration; 12 | import com.fuzs.aquaacrobatics.integration.mobends.MoBendsIntegration; 13 | import com.fuzs.aquaacrobatics.integration.thaumicaugmentation.ThaumicAugmentationIntegration; 14 | import com.fuzs.aquaacrobatics.network.NetworkHandler; 15 | import com.fuzs.aquaacrobatics.network.message.PacketSendKey; 16 | import com.fuzs.aquaacrobatics.optifine.OptifineHelper; 17 | import com.fuzs.aquaacrobatics.util.Keybindings; 18 | import net.minecraft.block.BlockLiquid; 19 | import net.minecraft.client.Minecraft; 20 | import net.minecraft.client.entity.EntityPlayerSP; 21 | import net.minecraft.client.renderer.block.statemap.StateMap; 22 | import net.minecraft.client.renderer.texture.TextureMap; 23 | import net.minecraft.client.resources.IResourcePack; 24 | import net.minecraft.util.ResourceLocation; 25 | import net.minecraft.util.text.TextComponentTranslation; 26 | import net.minecraftforge.client.event.ModelRegistryEvent; 27 | import net.minecraftforge.client.event.TextureStitchEvent; 28 | import net.minecraftforge.client.model.ModelLoader; 29 | import net.minecraftforge.client.resource.VanillaResourceType; 30 | import net.minecraftforge.common.MinecraftForge; 31 | import net.minecraftforge.fml.client.FMLClientHandler; 32 | import net.minecraftforge.fml.common.Mod; 33 | import net.minecraftforge.fml.common.ObfuscationReflectionHelper; 34 | import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; 35 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 36 | import net.minecraftforge.fml.common.gameevent.InputEvent; 37 | import net.minecraftforge.fml.relauncher.Side; 38 | 39 | import java.util.List; 40 | import java.util.Map; 41 | 42 | @SuppressWarnings("unused") 43 | @Mod.EventBusSubscriber(Side.CLIENT) 44 | public class ClientProxy extends CommonProxy { 45 | 46 | @Override 47 | public void onPreInit(FMLPreInitializationEvent event) { 48 | 49 | super.onPreInit(event); 50 | MinecraftForge.EVENT_BUS.register(new AirMeterHandler()); 51 | MinecraftForge.EVENT_BUS.register(new FogHandler()); 52 | 53 | if(ConfigHandler.BlocksConfig.newWaterColors) { 54 | List packs = ObfuscationReflectionHelper.getPrivateValue(Minecraft.class, Minecraft.getMinecraft(), "field_110449_ao"); 55 | packs.add(new WaterResourcePack(event.getSourceFile())); 56 | FMLClientHandler.instance().refreshResources(VanillaResourceType.TEXTURES); 57 | OptifineHelper.init(); 58 | } 59 | } 60 | 61 | 62 | @Override 63 | public void onInit() { 64 | Keybindings.register(); 65 | } 66 | 67 | @Override 68 | public void onMappings() { 69 | if (OptifineHelper.isOFPresent) { 70 | OptifineHelper.reloadBlockAliases(); 71 | } 72 | } 73 | 74 | @SubscribeEvent 75 | public static void registerModels(ModelRegistryEvent event) { 76 | if(ConfigHandler.MiscellaneousConfig.bubbleColumns) 77 | ModelLoader.setCustomStateMapper(CommonProxy.BUBBLE_COLUMN, new StateMap.Builder().ignore(BlockLiquid.LEVEL, BlockBubbleColumn.DRAG).build()); 78 | } 79 | 80 | @SubscribeEvent 81 | public static void registerTextures(TextureStitchEvent.Pre event) { 82 | if(ConfigHandler.BlocksConfig.newWaterColors) { 83 | TextureMap map = event.getMap(); 84 | /* Register the custom 1.13-style texture used by most in-world renderers */ 85 | map.registerSprite(new ResourceLocation("aquaacrobatics:blocks/water_still")); 86 | map.registerSprite(new ResourceLocation("aquaacrobatics:blocks/water_flow")); 87 | } 88 | } 89 | 90 | @SubscribeEvent 91 | public static void onKeyPress(InputEvent.KeyInputEvent event) { 92 | if(ConfigHandler.MovementConfig.enableToggleCrawling && Keybindings.forceCrawling.isPressed()) { 93 | IPlayerResizeable player = (IPlayerResizeable) Minecraft.getMinecraft().player; 94 | if(player != null) { 95 | if(player.canForceCrawling()) 96 | NetworkHandler.INSTANCE.sendToServer(new PacketSendKey(PacketSendKey.KeybindPacket.TOGGLE_CRAWLING)); 97 | else { 98 | ((EntityPlayerSP)player).sendMessage(new TextComponentTranslation("chat.aquaacrobatics.cannot_toggle_crawling")); 99 | } 100 | } 101 | } 102 | } 103 | 104 | @Override 105 | public void onPostInit() { 106 | 107 | super.onPostInit(); 108 | FogHandler.recomputeBlacklist(); 109 | if (IntegrationManager.isMoBendsEnabled()) { 110 | 111 | MoBendsIntegration.register(); 112 | } 113 | 114 | if (IntegrationManager.isArtemisLibEnabled()) { 115 | 116 | ArtemisLibIntegration.register(); 117 | } 118 | 119 | if(IntegrationManager.isEnderIoEnabled()) { 120 | EnderIOIntegration.register(); 121 | } 122 | 123 | if(IntegrationManager.isThaumicAugmentationEnabled()) { 124 | ThaumicAugmentationIntegration.register(); 125 | } 126 | } 127 | 128 | } 129 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/proxy/CommonProxy.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.proxy; 2 | 3 | import com.fuzs.aquaacrobatics.AquaAcrobatics; 4 | import com.fuzs.aquaacrobatics.biome.BiomeWaterFogColors; 5 | import com.fuzs.aquaacrobatics.block.BlockBubbleColumn; 6 | import com.fuzs.aquaacrobatics.config.ConfigHandler; 7 | import com.fuzs.aquaacrobatics.core.AquaAcrobaticsCore; 8 | import com.fuzs.aquaacrobatics.core.mixin.accessor.FluidAccessor; 9 | import com.fuzs.aquaacrobatics.handler.CommonHandler; 10 | import com.fuzs.aquaacrobatics.integration.IntegrationManager; 11 | import com.fuzs.aquaacrobatics.integration.hats.HatsIntegration; 12 | import com.fuzs.aquaacrobatics.integration.witchery.WitcheryResurrectedIntegration; 13 | import com.fuzs.aquaacrobatics.network.NetworkHandler; 14 | import net.minecraft.block.Block; 15 | import net.minecraft.item.Item; 16 | import net.minecraft.item.ItemBlock; 17 | import net.minecraft.launchwrapper.Launch; 18 | import net.minecraft.util.ResourceLocation; 19 | import net.minecraft.world.biome.Biome; 20 | import net.minecraftforge.common.MinecraftForge; 21 | import net.minecraftforge.event.RegistryEvent; 22 | import net.minecraftforge.event.terraingen.BiomeEvent; 23 | import net.minecraftforge.fluids.FluidRegistry; 24 | import net.minecraftforge.fml.common.Mod; 25 | import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; 26 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 27 | import net.minecraftforge.fml.common.registry.GameRegistry; 28 | 29 | @Mod.EventBusSubscriber 30 | public class CommonProxy { 31 | @GameRegistry.ObjectHolder("aquaacrobatics:bubble_column") 32 | public static BlockBubbleColumn BUBBLE_COLUMN; 33 | 34 | private boolean needNetworking() { 35 | return ConfigHandler.MovementConfig.enableToggleCrawling; 36 | } 37 | 38 | public void onPreInit(FMLPreInitializationEvent event) { 39 | IntegrationManager.loadCompat(); 40 | if(needNetworking()) 41 | NetworkHandler.registerMessages(AquaAcrobatics.MODID); 42 | MinecraftForge.EVENT_BUS.register(new CommonHandler()); 43 | } 44 | 45 | public void onInit() { 46 | 47 | } 48 | 49 | public void onMappings() { 50 | 51 | } 52 | 53 | @SubscribeEvent 54 | public static void registerBlocks(RegistryEvent.Register event) { 55 | if(ConfigHandler.MiscellaneousConfig.bubbleColumns) 56 | event.getRegistry().register(new BlockBubbleColumn()); 57 | } 58 | 59 | 60 | public void onPostInit() { 61 | 62 | if (IntegrationManager.isHatsEnabled()) { 63 | 64 | HatsIntegration.register(); 65 | } 66 | 67 | if (IntegrationManager.isWitcheryResurrectedEnabled()) 68 | WitcheryResurrectedIntegration.register(); 69 | 70 | if(!AquaAcrobaticsCore.isModCompatLoaded) 71 | AquaAcrobatics.LOGGER.error("Please consider installing MixinBooter to ensure compatibility with more mods"); 72 | 73 | BiomeWaterFogColors.recomputeColors(); 74 | // This code will print a warning if we don't have a color mapping for the biome 75 | /* 76 | for(Biome biome : Biome.REGISTRY) { 77 | biome.getWaterColor(); 78 | } 79 | */ 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/util/Keybindings.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.util; 2 | 3 | import com.fuzs.aquaacrobatics.config.ConfigHandler; 4 | import net.minecraft.client.settings.KeyBinding; 5 | import net.minecraftforge.fml.client.registry.ClientRegistry; 6 | import org.lwjgl.input.Keyboard; 7 | 8 | public class Keybindings 9 | { 10 | public static KeyBinding forceCrawling = null; 11 | 12 | public static void register() 13 | { 14 | if(ConfigHandler.MovementConfig.enableToggleCrawling) { 15 | forceCrawling = new KeyBinding("key.aquaacrobatics.toggle_crawling", Keyboard.KEY_C, "key.aquaacrobatics.category"); 16 | ClientRegistry.registerKeyBinding(forceCrawling); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/util/MovementInputStorage.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.util; 2 | 3 | import net.minecraft.client.settings.GameSettings; 4 | import net.minecraft.util.MovementInput; 5 | 6 | public class MovementInputStorage extends MovementInput { 7 | 8 | public int sprintToggleTimer; 9 | public boolean isFlying; 10 | public boolean isSprinting; 11 | public boolean isStartingToFly; 12 | 13 | public void copyFrom(MovementInput movement) { 14 | 15 | this.moveStrafe = movement.moveStrafe; 16 | this.moveForward = movement.moveForward; 17 | this.forwardKeyDown = movement.forwardKeyDown; 18 | this.backKeyDown = movement.backKeyDown; 19 | this.leftKeyDown = movement.leftKeyDown; 20 | this.rightKeyDown = movement.rightKeyDown; 21 | this.jump = movement.jump; 22 | this.sneak = movement.sneak; 23 | } 24 | 25 | public static void updatePlayerMoveState(MovementInput movement, GameSettings gameSettings, boolean isCrouching) { 26 | 27 | movement.forwardKeyDown = gameSettings.keyBindForward.isKeyDown(); 28 | movement.backKeyDown = gameSettings.keyBindBack.isKeyDown(); 29 | movement.leftKeyDown = gameSettings.keyBindLeft.isKeyDown(); 30 | movement.rightKeyDown = gameSettings.keyBindRight.isKeyDown(); 31 | movement.moveForward = movement.forwardKeyDown == movement.backKeyDown ? 0.0F : (movement.forwardKeyDown ? 1.0F : -1.0F); 32 | movement.moveStrafe = movement.leftKeyDown == movement.rightKeyDown ? 0.0F : (movement.leftKeyDown ? 1.0F : -1.0F); 33 | movement.jump = gameSettings.keyBindJump.isKeyDown(); 34 | movement.sneak = gameSettings.keyBindSneak.isKeyDown(); 35 | if (isCrouching) { 36 | 37 | movement.moveStrafe = (float) ((double) movement.moveStrafe * 0.3); 38 | movement.moveForward = (float) ((double) movement.moveForward * 0.3); 39 | } 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/util/math/AxisAlignedBBSpliterator.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.util.math; 2 | 3 | import com.google.common.collect.Lists; 4 | import net.minecraft.block.Block; 5 | import net.minecraft.block.state.IBlockState; 6 | import net.minecraft.entity.Entity; 7 | import net.minecraft.init.Blocks; 8 | import net.minecraft.util.math.AxisAlignedBB; 9 | import net.minecraft.util.math.BlockPos; 10 | import net.minecraft.util.math.MathHelper; 11 | import net.minecraft.world.World; 12 | import net.minecraft.world.border.WorldBorder; 13 | 14 | import javax.annotation.Nullable; 15 | import java.util.List; 16 | import java.util.Objects; 17 | import java.util.Spliterator; 18 | import java.util.Spliterators; 19 | import java.util.function.BiPredicate; 20 | import java.util.function.Consumer; 21 | 22 | public class AxisAlignedBBSpliterator extends Spliterators.AbstractSpliterator { 23 | 24 | @Nullable 25 | private final Entity entity; 26 | private final AxisAlignedBB aabb; 27 | private final CubeCoordinateIterator cubeCoordinateIterator; 28 | private final World reader; 29 | private boolean isEntityPresent; 30 | private final BiPredicate statePositionPredicate; 31 | 32 | public AxisAlignedBBSpliterator(World reader, @Nullable Entity entity, AxisAlignedBB aabb) { 33 | 34 | this(reader, entity, aabb, (state, pos) -> true); 35 | } 36 | 37 | public AxisAlignedBBSpliterator(World reader, @Nullable Entity entity, AxisAlignedBB aabb, BiPredicate statePositionPredicate) { 38 | 39 | super(Long.MAX_VALUE, Spliterator.NONNULL | Spliterator.IMMUTABLE); 40 | this.reader = reader; 41 | this.isEntityPresent = entity != null; 42 | this.entity = entity; 43 | this.aabb = aabb; 44 | this.statePositionPredicate = statePositionPredicate; 45 | int startX = MathHelper.floor(aabb.minX - 1.0E-7D) - 1; 46 | int endX = MathHelper.floor(aabb.maxX + 1.0E-7D) + 1; 47 | int startY = MathHelper.floor(aabb.minY - 1.0E-7D) - 1; 48 | int heightY = MathHelper.floor(aabb.maxY + 1.0E-7D) + 1; 49 | int startZ = MathHelper.floor(aabb.minZ - 1.0E-7D) - 1; 50 | int endZ = MathHelper.floor(aabb.maxZ + 1.0E-7D) + 1; 51 | this.cubeCoordinateIterator = new CubeCoordinateIterator(startX, startY, startZ, endX, heightY, endZ); 52 | } 53 | 54 | public boolean tryAdvance(Consumer consumer) { 55 | 56 | return this.isEntityPresent && this.isEntityOutsideOfBorder(consumer) || this.isAABBColliding(consumer); 57 | } 58 | 59 | private boolean isAABBColliding(Consumer consumer) { 60 | 61 | BlockPos.PooledMutableBlockPos mutablePos = BlockPos.PooledMutableBlockPos.retain(); 62 | while (this.cubeCoordinateIterator.hasNext()) { 63 | 64 | int x = this.cubeCoordinateIterator.getX(); 65 | int y = this.cubeCoordinateIterator.getY(); 66 | int z = this.cubeCoordinateIterator.getZ(); 67 | 68 | int boundariesTouched = this.cubeCoordinateIterator.numBoundariesTouched(); 69 | if (boundariesTouched == 3) { 70 | 71 | continue; 72 | } 73 | 74 | mutablePos.setPos(x, y, z); 75 | if (!this.reader.isBlockLoaded(mutablePos)) { 76 | 77 | continue; 78 | } 79 | 80 | // piston check is new, not sure if it really helps in this version 81 | IBlockState blockstate = this.reader.getBlockState(mutablePos); 82 | if (!this.statePositionPredicate.test(blockstate, mutablePos) || boundariesTouched == 2 && blockstate.getBlock() != Blocks.PISTON_EXTENSION) { 83 | 84 | continue; 85 | } 86 | 87 | // check full blocks first as they're easier to handle 88 | AxisAlignedBB collisionBoundingBox = blockstate.getCollisionBoundingBox(this.reader, mutablePos); 89 | if (collisionBoundingBox == Block.FULL_BLOCK_AABB && blockstate.isFullCube()) { 90 | 91 | // second check probably not necessary 92 | AxisAlignedBB aabbOffset = collisionBoundingBox.offset(x, y, z); 93 | if (!this.aabb.intersects(aabbOffset) || this.entity != null && !this.entity.getEntityBoundingBox().intersects(aabbOffset)) { 94 | 95 | continue; 96 | } 97 | 98 | consumer.accept(collisionBoundingBox); 99 | mutablePos.release(); 100 | return true; 101 | } 102 | 103 | List collidingBoxes = Lists.newArrayList(); 104 | this.getCollisionBoxList(collidingBoxes, blockstate, mutablePos); 105 | if (collidingBoxes.isEmpty()) { 106 | 107 | continue; 108 | } 109 | 110 | consumer.accept(collisionBoundingBox); 111 | mutablePos.release(); 112 | return true; 113 | } 114 | 115 | mutablePos.release(); 116 | return false; 117 | } 118 | 119 | private void getCollisionBoxList(List collidingBoxes, IBlockState blockstate, BlockPos.PooledMutableBlockPos mutablePos) { 120 | 121 | // only retain boxes colliding with both the area of interest and the current entity if present 122 | blockstate.addCollisionBoxToList(this.reader, mutablePos, this.aabb, collidingBoxes, this.entity, false); 123 | if (this.entity != null) { 124 | 125 | List entityCollidingBoxes = Lists.newArrayList(); 126 | blockstate.addCollisionBoxToList(this.reader, mutablePos, this.entity.getEntityBoundingBox(), entityCollidingBoxes, this.entity, false); 127 | collidingBoxes.retainAll(entityCollidingBoxes); 128 | } 129 | } 130 | 131 | private boolean isEntityOutsideOfBorder(Consumer consumer) { 132 | 133 | Objects.requireNonNull(this.entity); 134 | this.isEntityPresent = false; 135 | WorldBorder worldborder = this.reader.getWorldBorder(); 136 | AxisAlignedBB axisalignedbb = this.entity.getEntityBoundingBox(); 137 | if (!isBoundingBoxWithinBorder(worldborder, axisalignedbb)) { 138 | 139 | AxisAlignedBB borderShape = new AxisAlignedBB(worldborder.minX(), Double.NEGATIVE_INFINITY, worldborder.minZ(), worldborder.maxX(), Double.POSITIVE_INFINITY, worldborder.maxZ()); 140 | consumer.accept(borderShape); 141 | return true; 142 | } 143 | 144 | return false; 145 | } 146 | 147 | public static boolean isBoundingBoxWithinBorder(WorldBorder worldBorder, AxisAlignedBB entityBoundingBox) { 148 | 149 | double minX = MathHelper.floor(worldBorder.minX()); 150 | double minZ = MathHelper.floor(worldBorder.minZ()); 151 | double maxX = MathHelper.ceil(worldBorder.maxX()); 152 | double maxZ = MathHelper.ceil(worldBorder.maxZ()); 153 | return entityBoundingBox.minX > minX && entityBoundingBox.minX < maxX && entityBoundingBox.minZ > minZ && entityBoundingBox.minZ < maxZ && entityBoundingBox.maxX > minX && entityBoundingBox.maxX < maxX && entityBoundingBox.maxZ > minZ && entityBoundingBox.maxZ < maxZ; 154 | } 155 | 156 | } 157 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/util/math/CubeCoordinateIterator.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.util.math; 2 | 3 | public class CubeCoordinateIterator { 4 | 5 | private final int startX; 6 | private final int startY; 7 | private final int startZ; 8 | private final int xWidth; 9 | private final int yHeight; 10 | private final int zWidth; 11 | private final int totalAmount; 12 | private int currentAmount; 13 | private int x; 14 | private int y; 15 | private int z; 16 | 17 | public CubeCoordinateIterator(int startX, int startY, int startZ, int endX, int yHeight, int endZ) { 18 | 19 | this.startX = startX; 20 | this.startY = startY; 21 | this.startZ = startZ; 22 | this.xWidth = endX - startX + 1; 23 | this.yHeight = yHeight - startY + 1; 24 | this.zWidth = endZ - startZ + 1; 25 | this.totalAmount = this.xWidth * this.yHeight * this.zWidth; 26 | } 27 | 28 | public boolean hasNext() { 29 | 30 | if (this.currentAmount == this.totalAmount) { 31 | 32 | return false; 33 | } else { 34 | 35 | this.x = this.currentAmount % this.xWidth; 36 | int i = this.currentAmount / this.xWidth; 37 | this.y = i % this.yHeight; 38 | this.z = i / this.yHeight; 39 | ++this.currentAmount; 40 | 41 | return true; 42 | } 43 | } 44 | 45 | public int getX() { 46 | 47 | return this.startX + this.x; 48 | } 49 | 50 | public int getY() { 51 | 52 | return this.startY + this.y; 53 | } 54 | 55 | public int getZ() { 56 | 57 | return this.startZ + this.z; 58 | } 59 | 60 | public int numBoundariesTouched() { 61 | 62 | int i = 0; 63 | if (this.x == 0 || this.x == this.xWidth - 1) { 64 | 65 | ++i; 66 | } 67 | 68 | if (this.y == 0 || this.y == this.yHeight - 1) { 69 | 70 | ++i; 71 | } 72 | 73 | if (this.z == 0 || this.z == this.zWidth - 1) { 74 | 75 | ++i; 76 | } 77 | 78 | return i; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/com/fuzs/aquaacrobatics/util/math/MathHelperNew.java: -------------------------------------------------------------------------------- 1 | package com.fuzs.aquaacrobatics.util.math; 2 | 3 | public class MathHelperNew { 4 | 5 | public static float lerp(float pct, float start, float end) { 6 | return start + pct * (end - start); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/mixins.aquaacrobatics.galacticraft.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "minVersion": "0.8", 4 | "compatibilityLevel": "JAVA_8", 5 | "package": "com.fuzs.aquaacrobatics.core.galacticraft.mixin", 6 | "refmap": "mixins.aquaacrobatics.refmap.json", 7 | "plugin": "com.fuzs.aquaacrobatics.core.AquaAcrobaticsMixinPlugin", 8 | "mixins": [ 9 | "GCEntityClientPlayerMPMixin", 10 | "GalacticraftCoreMixin" 11 | ], 12 | "injectors": { 13 | "defaultRequire": 1 14 | } 15 | } -------------------------------------------------------------------------------- /src/main/resources/META-INF/mixins.aquaacrobatics.journeymap55.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "minVersion": "0.8", 4 | "compatibilityLevel": "JAVA_8", 5 | "package": "com.fuzs.aquaacrobatics.core.journeymap55.mixin", 6 | "refmap": "mixins.aquaacrobatics.refmap.json", 7 | "plugin": "com.fuzs.aquaacrobatics.core.AquaAcrobaticsMixinPlugin", 8 | "client": [ 9 | "client.VanillaBlockSpriteProxyMixin" 10 | ], 11 | "injectors": { 12 | "defaultRequire": 1 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/resources/META-INF/mixins.aquaacrobatics.journeymap57.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "minVersion": "0.8", 4 | "compatibilityLevel": "JAVA_8", 5 | "package": "com.fuzs.aquaacrobatics.core.journeymap57.mixin", 6 | "refmap": "mixins.aquaacrobatics.refmap.json", 7 | "plugin": "com.fuzs.aquaacrobatics.core.AquaAcrobaticsMixinPlugin", 8 | "client": [ 9 | "client.VanillaBlockSpriteProxyMixin" 10 | ], 11 | "injectors": { 12 | "defaultRequire": 1 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/resources/META-INF/mixins.aquaacrobatics.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "minVersion": "0.7", 4 | "compatibilityLevel": "JAVA_8", 5 | "package": "com.fuzs.aquaacrobatics.core.mixin", 6 | "refmap": "mixins.aquaacrobatics.refmap.json", 7 | "plugin": "com.fuzs.aquaacrobatics.core.AquaAcrobaticsMixinPlugin", 8 | "mixins": [ 9 | "EntityBoatMixin", 10 | "EntityItemMixin", 11 | "EntityPlayerMixin", 12 | "EntityPlayerMPMixin", 13 | "EntityMixin", 14 | "EntityLivingBaseMixin", 15 | "EntityThrowableMixin", 16 | "NetHandlerPlayServerMixin", 17 | "BiomeMixin", 18 | "BiomeColorHelperMixin", 19 | "BlockGrassMixin", 20 | "BlockLiquidMixin", 21 | "BlockMagmaMixin", 22 | "BlockMyceliumMixin", 23 | "BlockSoulSandMixin", 24 | "accessor.FluidAccessor", 25 | "accessor.IEventBusAccessor" 26 | ], 27 | "client": [ 28 | "client.BlockFluidRendererMixin", 29 | "client.BlockAliasesBubbleColumnMixin", 30 | "client.EntityPlayerSPMixin", 31 | "client.EntityRendererMixin", 32 | "client.ItemRendererMixin", 33 | "client.ModelBipedMixin", 34 | "client.ModelFluidMixin", 35 | "client.RenderBoatMixin", 36 | "client.RenderPlayerMixin", 37 | "client.PlayerControllerMPMixin" 38 | ], 39 | "injectors": { 40 | "defaultRequire": 1 41 | } 42 | } -------------------------------------------------------------------------------- /src/main/resources/META-INF/mixins.aquaacrobatics.thaumcraft.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "minVersion": "0.8", 4 | "compatibilityLevel": "JAVA_8", 5 | "package": "com.fuzs.aquaacrobatics.core.thaumcraft.mixin", 6 | "refmap": "mixins.aquaacrobatics.refmap.json", 7 | "plugin": "com.fuzs.aquaacrobatics.core.AquaAcrobaticsMixinPlugin", 8 | "client": [ 9 | "client.TileCrucibleRendererMixin" 10 | ], 11 | "injectors": { 12 | "defaultRequire": 1 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/resources/META-INF/mixins.aquaacrobatics.xaerosminimap.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "minVersion": "0.8", 4 | "compatibilityLevel": "JAVA_8", 5 | "package": "com.fuzs.aquaacrobatics.core.xaerosminimap.mixin", 6 | "refmap": "mixins.aquaacrobatics.refmap.json", 7 | "plugin": "com.fuzs.aquaacrobatics.core.AquaAcrobaticsMixinPlugin", 8 | "client": [ 9 | "client.MinimapWriterMixin" 10 | ], 11 | "injectors": { 12 | "defaultRequire": 1 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/resources/assets/aquaacrobatics/blockstates/bubble_column.json: -------------------------------------------------------------------------------- 1 | { 2 | "forge_marker": 1, 3 | "variants": { 4 | "normal": [{ 5 | "model": "forge:fluid", 6 | "transform": "forge:default-item", 7 | "custom": { 8 | "fluid": "water" 9 | } 10 | }] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/resources/assets/aquaacrobatics/lang/en_us.lang: -------------------------------------------------------------------------------- 1 | chat.aquaacrobatics.cannot_toggle_crawling=Cannot toggle crawling right now! 2 | 3 | key.aquaacrobatics.category=Aqua Acrobatics 4 | key.aquaacrobatics.toggle_crawling=Toggle Crawling -------------------------------------------------------------------------------- /src/main/resources/assets/aquaacrobatics/lang/zh_cn.lang: -------------------------------------------------------------------------------- 1 | chat.aquaacrobatics.cannot_toggle_crawling=现在不能切换爬行! 2 | 3 | key.aquaacrobatics.category=水游技艺 4 | key.aquaacrobatics.toggle_crawling=切换爬行 -------------------------------------------------------------------------------- /src/main/resources/assets/aquaacrobatics/overrides/textures/blocks/water_flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/embeddedt/aquaacrobatics/4c96ac731c837979abc329942bb0d59df5ce5d96/src/main/resources/assets/aquaacrobatics/overrides/textures/blocks/water_flow.png -------------------------------------------------------------------------------- /src/main/resources/assets/aquaacrobatics/overrides/textures/blocks/water_flow.png.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "animation": {} 3 | } -------------------------------------------------------------------------------- /src/main/resources/assets/aquaacrobatics/overrides/textures/blocks/water_overlay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/embeddedt/aquaacrobatics/4c96ac731c837979abc329942bb0d59df5ce5d96/src/main/resources/assets/aquaacrobatics/overrides/textures/blocks/water_overlay.png -------------------------------------------------------------------------------- /src/main/resources/assets/aquaacrobatics/overrides/textures/blocks/water_still.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/embeddedt/aquaacrobatics/4c96ac731c837979abc329942bb0d59df5ce5d96/src/main/resources/assets/aquaacrobatics/overrides/textures/blocks/water_still.png -------------------------------------------------------------------------------- /src/main/resources/assets/aquaacrobatics/overrides/textures/blocks/water_still.png.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "animation": { 3 | "frametime": 2 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/main/resources/assets/aquaacrobatics/textures/blocks/water_flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/embeddedt/aquaacrobatics/4c96ac731c837979abc329942bb0d59df5ce5d96/src/main/resources/assets/aquaacrobatics/textures/blocks/water_flow.png -------------------------------------------------------------------------------- /src/main/resources/assets/aquaacrobatics/textures/blocks/water_flow.png.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "animation": {} 3 | } -------------------------------------------------------------------------------- /src/main/resources/assets/aquaacrobatics/textures/blocks/water_still.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/embeddedt/aquaacrobatics/4c96ac731c837979abc329942bb0d59df5ce5d96/src/main/resources/assets/aquaacrobatics/textures/blocks/water_still.png -------------------------------------------------------------------------------- /src/main/resources/assets/aquaacrobatics/textures/blocks/water_still.png.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "animation": { 3 | "frametime": 2 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/main/resources/mcmod.info: -------------------------------------------------------------------------------- 1 | [{ 2 | "modid": "${mod_id}", 3 | "name": "${mod_name}", 4 | "description": "${mod_description}", 5 | "version": "${mod_version}", 6 | "mcversion": "${mc_version}", 7 | "url": "${mod_url}", 8 | "authorList": ["${mod_author}", "embeddedt"] 9 | }] 10 | -------------------------------------------------------------------------------- /src/main/resources/pack.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "pack": { 3 | "description": "${mod_description}", 4 | "pack_format": 3 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/water_pack.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "pack": { 3 | "description": "${mod_description}", 4 | "pack_format": 3 5 | } 6 | } 7 | --------------------------------------------------------------------------------