From 35de894a3e0b53c1db681042369667b10d6f8e5a Mon Sep 17 00:00:00 2001 From: Compaszer Date: Sun, 5 Sep 2021 14:40:33 +0200 Subject: [PATCH] Splitted config option generate_snow_ice\n\n- Splitted config option generate_snow_ice into generate_snow and generate_ice\n- Fixed issue https://github.com/Glitchfiend/SereneSeasons/issues/227 --- .../sereneseasons/config/SeasonsConfig.java | 6 +- .../handler/season/RandomUpdateHandler.java | 6 +- .../sereneseasons/season/SeasonHooks.java | 28 ++++- .../resources/transformers/temperature.js | 113 ++++++++++++++++-- 4 files changed, 138 insertions(+), 15 deletions(-) diff --git a/src/main/java/sereneseasons/config/SeasonsConfig.java b/src/main/java/sereneseasons/config/SeasonsConfig.java index fd81b7a0..0c76ebbb 100644 --- a/src/main/java/sereneseasons/config/SeasonsConfig.java +++ b/src/main/java/sereneseasons/config/SeasonsConfig.java @@ -33,7 +33,8 @@ public class SeasonsConfig public static ForgeConfigSpec.BooleanValue progressSeasonWhileOffline; // Weather settings - public static ForgeConfigSpec.BooleanValue generateSnowAndIce; + public static ForgeConfigSpec.BooleanValue generateSnow; + public static ForgeConfigSpec.BooleanValue generateIce; public static ForgeConfigSpec.BooleanValue changeWeatherFrequency; // Aesthetic settings @@ -73,7 +74,8 @@ public class SeasonsConfig BUILDER.pop(); BUILDER.push("weather_settings"); - generateSnowAndIce = BUILDER.comment("Generate snow and ice during the Winter season").define("generate_snow_ice", true); + generateSnow = BUILDER.comment("Generate snow during the Winter season").define("generate_snow", true); + generateIce = BUILDER.comment("Generate ice during the Winter season").define("generate_ice", true); changeWeatherFrequency = BUILDER.comment("Change the frequency of rain/snow/storms based on the season").define("change_weather_frequency", true); BUILDER.pop(); diff --git a/src/main/java/sereneseasons/handler/season/RandomUpdateHandler.java b/src/main/java/sereneseasons/handler/season/RandomUpdateHandler.java index aa6f2219..3de2050f 100644 --- a/src/main/java/sereneseasons/handler/season/RandomUpdateHandler.java +++ b/src/main/java/sereneseasons/handler/season/RandomUpdateHandler.java @@ -121,14 +121,14 @@ private void meltInChunk(ChunkManager chunkManager, Chunk chunkIn, Season.SubSea if (!BiomeConfig.enablesSeasonalEffects(biome)) return; - if (aboveGroundState.getBlock() == Blocks.SNOW) + if (aboveGroundState.getBlock() == Blocks.SNOW && SeasonsConfig.generateSnow.get()) { if (SeasonHooks.getBiomeTemperature(world, biome, topGroundPos) >= 0.15F) { world.setBlockAndUpdate(topAirPos, Blocks.AIR.defaultBlockState()); } } - else if (groundState.getBlock() == Blocks.ICE) + else if (groundState.getBlock() == Blocks.ICE && SeasonsConfig.generateIce.get()) { if (SeasonHooks.getBiomeTemperature(world, biome, topGroundPos) >= 0.15F) { @@ -152,7 +152,7 @@ public void onWorldTick(TickEvent.WorldTickEvent event) if (season != Season.WINTER) { - if (SeasonsConfig.generateSnowAndIce.get() && SeasonsConfig.isDimensionWhitelisted(event.world.dimension())) + if ((SeasonsConfig.generateSnow.get() || SeasonsConfig.generateIce.get()) && SeasonsConfig.isDimensionWhitelisted(event.world.dimension())) { ServerWorld world = (ServerWorld) event.world; ChunkManager chunkManager = world.getChunkSource().chunkMap; diff --git a/src/main/java/sereneseasons/season/SeasonHooks.java b/src/main/java/sereneseasons/season/SeasonHooks.java index 3de5d2ac..55231376 100644 --- a/src/main/java/sereneseasons/season/SeasonHooks.java +++ b/src/main/java/sereneseasons/season/SeasonHooks.java @@ -13,12 +13,10 @@ import net.minecraft.world.IWorldReader; import net.minecraft.world.World; import net.minecraft.world.biome.Biome; -import net.minecraft.world.biome.Biomes; import sereneseasons.api.season.Season; import sereneseasons.api.season.SeasonHelper; import sereneseasons.config.BiomeConfig; import sereneseasons.config.SeasonsConfig; -import sereneseasons.core.SereneSeasons; import sereneseasons.util.biome.BiomeUtil; public class SeasonHooks @@ -36,6 +34,32 @@ public static float getBiomeTemperatureHook(Biome biome, BlockPos pos, IWorldRea return getBiomeTemperature((World)worldReader, biome, pos); } + + public static float getBiomeTemperatureHookICE(Biome biome, BlockPos pos, IWorldReader worldReader) + { + if(!SeasonsConfig.generateIce.get()) { + return 0.15F; + } + if (!(worldReader instanceof World)) + { + return biome.getTemperature(pos); + } + + return getBiomeTemperature((World)worldReader, biome, pos); + } + + public static float getBiomeTemperatureHookSNOW(Biome biome, BlockPos pos, IWorldReader worldReader) + { + if(!SeasonsConfig.generateSnow.get()) { + return 0.15F; + } + if (!(worldReader instanceof World)) + { + return biome.getTemperature(pos); + } + + return getBiomeTemperature((World)worldReader, biome, pos); + } // // General utilities diff --git a/src/main/resources/transformers/temperature.js b/src/main/resources/transformers/temperature.js index 7b56340a..318c0a40 100644 --- a/src/main/resources/transformers/temperature.js +++ b/src/main/resources/transformers/temperature.js @@ -8,11 +8,11 @@ var GET_TEMPERATURE = ASM.mapMethod("func_225486_c"); var GET_BIOME = ASM.mapMethod("func_226691_t_"); var GET_BLOCK_STATE = ASM.mapMethod("func_180495_p"); var TRANSFORMATIONS = { - "net.minecraft.block.CauldronBlock": [ ASM.mapMethod("func_176224_k") ], // fillWithRain - "net.minecraft.client.renderer.WorldRenderer": [ ASM.mapMethod("func_228436_a_"), ASM.mapMethod("func_228438_a_") ], // addRainParticles, renderRainSnow - "net.minecraft.entity.passive.SnowGolemEntity": [ ASM.mapMethod("func_70636_d")], // livingTick - "net.minecraft.world.biome.Biome": [ ASM.mapMethod("func_201854_a"), ASM.mapMethod("func_201850_b") ] // shouldFreeze, shouldSnow -} + "net.minecraft.block.CauldronBlock": [ [ASM.mapMethod("func_176224_k")], [patchGetTemperatureCalls] ], // fillWithRain + "net.minecraft.client.renderer.WorldRenderer": [ [ASM.mapMethod("func_228436_a_"), ASM.mapMethod("func_228438_a_")], [patchGetTemperatureCalls, patchGetTemperatureCalls] ], // addRainParticles, renderRainSnow + "net.minecraft.entity.passive.SnowGolemEntity": [ [ASM.mapMethod("func_70636_d")], [patchGetTemperatureCalls]], // livingTick + "net.minecraft.world.biome.Biome": [ [ASM.mapMethod("func_201854_a"), ASM.mapMethod("func_201850_b")], [patchGetTemperatureCallsIce, patchGetTemperatureCallsSnow] ] // shouldFreeze, shouldSnow +}; function log(message) { @@ -30,10 +30,11 @@ function initializeCoreMod() "transformer": function(classNode) { for each (var method in classNode.methods) { var methodsToTransform = TRANSFORMATIONS[classNode.name.split('/').join('.')]; - - if (~methodsToTransform.indexOf(method.name)) { + + var index = methodsToTransform[0].indexOf(method.name); + if (~index) { log("Transforming " + method.name + " in " + classNode.name); - patchGetTemperatureCalls(method); + methodsToTransform[1][index](method); } } @@ -91,6 +92,102 @@ function patchGetTemperatureCalls(method) } } +function patchGetTemperatureCallsIce(method) +{ + var startIndex = 0; + var patchedCount = 0; + + while (true) { + var getTemperatureCachedCall = ASM.findFirstMethodCallAfter(method, + ASM.MethodType.VIRTUAL, + "net/minecraft/world/biome/Biome", + GET_TEMPERATURE, + "(Lnet/minecraft/util/math/BlockPos;)F", + startIndex); + + if (getTemperatureCachedCall == null) { + break; + } + + startIndex = method.instructions.indexOf(getTemperatureCachedCall); + + // We can't reuse the same world instruction, we must make a clone each iteration + var worldLoad = buildWorldLoad(method); + + if (worldLoad == null) { + log('Failed to find world load in ' + method.name); + return; + } + + var newInstructions = new InsnList(); + newInstructions.add(worldLoad); // Pass the world as an argument to our hook + newInstructions.add(ASM.buildMethodCall( + "sereneseasons/season/SeasonHooks", + "getBiomeTemperatureHookICE", + "(Lnet/minecraft/world/biome/Biome;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/IWorldReader;)F", + ASM.MethodType.STATIC + )); // Replace the existing call with ours + + method.instructions.insertBefore(getTemperatureCachedCall, newInstructions); + method.instructions.remove(getTemperatureCachedCall); + patchedCount++; + } + + if (patchedCount == 0) { + log('Failed to locate call to getTemperature in ' + method.name); + } else { + log('Patched ' + patchedCount + ' calls'); + } +} + +function patchGetTemperatureCallsSnow(method) +{ + var startIndex = 0; + var patchedCount = 0; + + while (true) { + var getTemperatureCachedCall = ASM.findFirstMethodCallAfter(method, + ASM.MethodType.VIRTUAL, + "net/minecraft/world/biome/Biome", + GET_TEMPERATURE, + "(Lnet/minecraft/util/math/BlockPos;)F", + startIndex); + + if (getTemperatureCachedCall == null) { + break; + } + + startIndex = method.instructions.indexOf(getTemperatureCachedCall); + + // We can't reuse the same world instruction, we must make a clone each iteration + var worldLoad = buildWorldLoad(method); + + if (worldLoad == null) { + log('Failed to find world load in ' + method.name); + return; + } + + var newInstructions = new InsnList(); + newInstructions.add(worldLoad); // Pass the world as an argument to our hook + newInstructions.add(ASM.buildMethodCall( + "sereneseasons/season/SeasonHooks", + "getBiomeTemperatureHookSNOW", + "(Lnet/minecraft/world/biome/Biome;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/IWorldReader;)F", + ASM.MethodType.STATIC + )); // Replace the existing call with ours + + method.instructions.insertBefore(getTemperatureCachedCall, newInstructions); + method.instructions.remove(getTemperatureCachedCall); + patchedCount++; + } + + if (patchedCount == 0) { + log('Failed to locate call to getTemperature in ' + method.name); + } else { + log('Patched ' + patchedCount + ' calls'); + } +} + function buildWorldLoad(method) { for (var i = method.instructions.size() - 1; i >= 0; i--) {