Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Splitted config option generate_snow_ice #351

Open
wants to merge 1 commit into
base: SS-1.16.x-4.x.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/main/java/sereneseasons/config/SeasonsConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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;
Expand Down
28 changes: 26 additions & 2 deletions src/main/java/sereneseasons/season/SeasonHooks.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
113 changes: 105 additions & 8 deletions src/main/resources/transformers/temperature.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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);
}
}

Expand Down Expand Up @@ -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--) {
Expand Down