Hell guys and girls, been awhile since I was on this side of the forum. I have something that has really been bothering me, I have my seasons set up, (Autumn, Spring, Summer, Winter) but my Winter season has no snowfall. I have a way to melt ice and snow after the fact, but it just doesn't want to fall in the first place. Have no fear about me not using reflection, I have already setup an AccessTransformer to get the vanilla methods I needed. I use commands to set the weather and season, so no worries about that. Here is the code I have, that I at least think is affected: (If you want to see the AccessTransformer code, just ask, but it is a lot of files, here is my season code)
SeasonASMHelper:
</span>
package com.stormarmory.season;
import java.lang.reflect.Method;
import com.stormarmory.MBlocks;
import com.stormarmory.handler.SeasonHandler;
import com.stormarmory.util.config.SeasonsOption;
import com.stormarmory.util.config.SyncedConfig;
import com.stormarmory.util.season.Season;
import com.stormarmory.util.season.SeasonHelper;
import net.minecraft.block.Block;
import net.minecraft.block.BlockLiquid;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.init.Biomes;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.EnumSkyBlock;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
public class SeasonASMHelper
{
///////////////////
// World methods //
///////////////////
public static boolean canSnowAtInSeason(World world, BlockPos pos, boolean checkLight, Season season)
{
Biome biome = world.getBiome(pos);
float temperature = biome.getFloatTemperature(pos);
//If we're in winter, the temperature can be anything equal to or below 0.7
if (!SeasonHelper.canSnowAtTempInSeason(season, temperature))
{
return false;
}
else if (biome == Biomes.RIVER || biome == Biomes.OCEAN || biome == Biomes.DEEP_OCEAN)
{
return false;
}
else if (checkLight)
{
if (pos.getY() >= 0 && pos.getY() < 256 && world.getLightFor(EnumSkyBlock.BLOCK, pos) < 10)
{
IBlockState state = world.getBlockState(pos);
if (state.getBlock().isAir(state, world, pos) && Blocks.SNOW_LAYER.canPlaceBlockAt(world, pos))
{
return true;
}
}
return false;
}
return true;
}
public static boolean canBlockFreezeInSeason(World world, BlockPos pos, boolean noWaterAdj, Season season)
{
Biome Biome = world.getBiome(pos);
float temperature = Biome.getFloatTemperature(pos);
//If we're in winter, the temperature can be anything equal to or below 0.7
if (!SeasonHelper.canSnowAtTempInSeason(season, temperature))
{
return false;
}
else if (Biome == Biomes.RIVER || Biome == Biomes.OCEAN || Biome == Biomes.DEEP_OCEAN)
{
return false;
}
else
{
if (pos.getY() >= 0 && pos.getY() < 256 && world.getLightFor(EnumSkyBlock.BLOCK, pos) < 10)
{
IBlockState iblockstate = world.getBlockState(pos);
Block block = iblockstate.getBlock();
if ((block == Blocks.WATER || block == Blocks.FLOWING_WATER) && ((Integer)iblockstate.getValue(BlockLiquid.LEVEL)).intValue() == 0)
{
if (!noWaterAdj)
{
return true;
}
boolean flag = world.isWater(pos.west()) && world.isWater(pos.east()) && world.isWater(pos.north()) && world.isWater(pos.south());
if (!flag)
{
return true;
}
}
}
return false;
}
}
public static boolean isRainingAtInSeason(World world, BlockPos pos, Season season)
{
Biome biome = world.getBiome(pos);
return biome.getEnableSnow() && season != Season.WINTER ? false : (world.canSnowAt(pos, false) ? false : biome.canRain());
}
///////////////////
// Biome methods //
///////////////////
public static float getFloatTemperature(Biome biome, BlockPos pos)
{
Season season = new SeasonTime(SeasonHandler.clientSeasonCycleTicks).getSubSeason().getSeason();
if (biome.getTemperature() <= 0.7F && season == Season.WINTER && SyncedConfig.getBooleanValue(SeasonsOption.ENABLE_SEASONS))
{
return 0.0F;
}
else
{
return biome.getFloatTemperature(pos);
}
}
}
<span style="font-family: impact,sans-serif;">
SeasonHelper:
[/p]
[p]package com.stormarmory.util.season;[/p]
[p]import com.stormarmory.util.config.SeasonsOption;
import com.stormarmory.util.config.SyncedConfig;[/p]
[p]import net.minecraft.world.World;[/p]
[p]public class SeasonHelper
{
public static ISeasonDataProvider dataProvider;[/p]
[p]/**
* Obtains data about the state of the season cycle in the world. This works both on
* the client and the server.
*/
public static ISeasonData getSeasonData(World world)
{
ISeasonData data;[/p]
[p]if (!world.isRemote)
{
data = dataProvider.getServerSeasonData(world);
}
else
{
data = dataProvider.getClientSeasonData();
}[/p]
[p]return data;
}
/**
* Checks if the season provided allows snow to fall at a certain
* biome temperature.
*
* @param season The season to check
* @param temperature The biome temperature to check
* @return True if suitable, otherwise false
*/
public static boolean canSnowAtTempInSeason(Season season, float temperature)
{
//If we're in winter, the temperature can be anything equal to or below 0.7
return temperature < 0.15F || (season == Season.WINTER && temperature <= 0.7F && SyncedConfig.getBooleanValue(SeasonsOption.ENABLE_SEASONS));
}[/p]
[p]public interface ISeasonDataProvider
{
ISeasonData getServerSeasonData(World world);
ISeasonData getClientSeasonData();
}
}[/p]
[p]
MMain:
[/p]
[p]package com.stormarmory;[/p]
[p]import java.io.File;
import java.util.Iterator;[/p]
[p]import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;[/p]
[p]import com.stormarmory.command.TANCommand;
import com.stormarmory.proxy.IProxy;[/p]
[p]import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.CraftingManager;
import net.minecraft.item.crafting.IRecipe;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.Mod.Instance;
import net.minecraftforge.fml.common.SidedProxy;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
import net.minecraftforge.fml.common.registry.GameRegistry;[/p]
[p]@Mod(modid = MMain.MODID, name = MMain.MODNAME, version = MMain.VERSION)
public class MMain {[/p]
[p]public static final String MODID = "stormarmory";
public static final String MODNAME = "Nature's Revenge";
public static final String VERSION = "1.0";[/p]
[p]@Instance
public static MMain instance = new MMain();[/p]
[p]@SidedProxy(clientSide = "com.stormarmory.proxy.ClientProxy", serverSide = "com.stormarmory.proxy.CommonProxy")
public static IProxy proxy;
public static Logger logger = LogManager.getLogger(MODID);
public static File configDirectory;[/p]
[p]@EventHandler
public void preInit(FMLPreInitializationEvent e) {
configDirectory = new File(e.getModConfigurationDirectory(), "stormarmory");
MConfig.init(configDirectory);
MHandlers.init();
MItems.init();
MBlocks.init();
this.proxy.preInit();
System.out.println("Preinitialization Done");
}[/p]
[p]@EventHandler
public void init(FMLInitializationEvent e) {
this.proxy.init();
System.out.println("Initialization Done");
}[/p]
[p]@EventHandler
public void postInit(FMLPostInitializationEvent e) {
this.proxy.postInit();
System.out.println("Postinitialization Done");
}
@EventHandler
public void serverStarting(FMLServerStartingEvent event)
{
event.registerServerCommand(new TANCommand());
}
}[/p]
[p]
MHandler
</span></strong>
package com.stormarmory;
import com.stormarmory.config.SyncedConfigHandler;
import com.stormarmory.handler.PacketHandler;
import com.stormarmory.handler.ProviderIceHandler;
import com.stormarmory.handler.RandomUpdateHandler;
import com.stormarmory.handler.SeasonHandler;
import com.stormarmory.handler.SeasonSleepHandler;
import com.stormarmory.handler.StopSpawnHandler;
import com.stormarmory.handler.WeatherFrequencyHandler;
import com.stormarmory.season.SeasonTime;
import com.stormarmory.util.SeasonColourUtil;
import com.stormarmory.util.season.SeasonHelper;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.BiomeColorHelper;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class MHandlers
{
private static final SeasonHandler SEASON_HANDLER = new SeasonHandler();
public static void init()
{
PacketHandler.init();
MinecraftForge.EVENT_BUS.register(new SyncedConfigHandler());
//Handlers for functionality related to seasons
MinecraftForge.EVENT_BUS.register(SEASON_HANDLER);
SeasonHelper.dataProvider = SEASON_HANDLER;
MinecraftForge.EVENT_BUS.register(new RandomUpdateHandler());
MinecraftForge.TERRAIN_GEN_BUS.register(new ProviderIceHandler());
MinecraftForge.EVENT_BUS.register(new SeasonSleepHandler());
MinecraftForge.EVENT_BUS.register(new WeatherFrequencyHandler());
if (!(MConfig.seasons.winterAnimalSpawns))
{
StopSpawnHandler stopSpawnHandler = new StopSpawnHandler();
MinecraftForge.EVENT_BUS.register(stopSpawnHandler);
MinecraftForge.TERRAIN_GEN_BUS.register(stopSpawnHandler);
}
if (FMLCommonHandler.instance().getEffectiveSide() == Side.CLIENT)
{
registerSeasonColourHandlers();
}
}
@SideOnly(Side.CLIENT)
private static void registerSeasonColourHandlers()
{
BiomeColorHelper.GRASS_COLOR = new BiomeColorHelper.ColorResolver()
{
@Override
public int getColorAtPos(Biome biome, BlockPos blockPosition)
{
SeasonTime calendar = new SeasonTime(SeasonHandler.clientSeasonCycleTicks);
return SeasonColourUtil.applySeasonalGrassColouring(calendar.getSubSeason(), biome.getGrassColorAtPos(blockPosition));
}
};
BiomeColorHelper.FOLIAGE_COLOR = new BiomeColorHelper.ColorResolver()
{
@Override
public int getColorAtPos(Biome biome, BlockPos blockPosition)
{
SeasonTime calendar = new SeasonTime(SeasonHandler.clientSeasonCycleTicks);
return SeasonColourUtil.applySeasonalFoliageColouring(calendar.getSubSeason(), biome.getFoliageColorAtPos(blockPosition));
}
};
}
}
<strong><span style="font-family: impact,sans-serif;">
package com.stormarmory.season;[/p]
[p]import com.stormarmory.util.season.Season;[/p]
[p]import net.minecraft.util.math.BlockPos;[/p]
[p]/** Now with extra seasoning*/
public interface ISeasonedWorld
{
boolean canSnowAtInSeason(BlockPos pos, boolean checkLight, Season season);
boolean canBlockFreezeInSeason(BlockPos pos, boolean noWaterAdj, Season season);
}[/p]
[p]
BiomeUtils
package com.stormarmory.util;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.biome.Biome;
public class BiomeUtils
{
/**Get biome temperature on a scale of 0 to 1, 0 freezing and 1 boiling hot**/
public static float getBiomeTempNorm(Biome biome)
{
return MathHelper.clamp_float(biome.getTemperature(), 0.0F, 1.35F) / 1.35F;
}
/**Get the biome temperature's level of extremity from 0 to 1, 0 least extreme and 1 most extreme*/
public static float getBiomeTempExtremity(Biome biome)
{
return Math.abs(getBiomeTempNorm(biome) * 2.0F - 1.0F);
}
}
WorldHooks
</span></strong>
package com.stormarmory.util.season;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class WorldHooks
{
/**
* An override of {@link World#canSnowAt(BlockPos, boolean)}
*/
public static boolean canSnowAtInSeason(World world, BlockPos pos, boolean checkLight, Season season)
{
try
{
return (Boolean)Class.forName("stormarmory.season.SeasonASMHelper").getMethod("canSnowAtInSeason", World.class, BlockPos.class, Boolean.class, Season.class).invoke(null, world, pos, checkLight, season);
}
catch (Exception e)
{
throw new RuntimeException("An error occurred calling canSnowAtInSeason", e);
}
}
/**
* An override of {@link World#canBlockFreeze(BlockPos, boolean)}
*/
public static boolean canBlockFreezeInSeason(World world, BlockPos pos, boolean noWaterAdj, Season season)
{
try
{
return (Boolean)Class.forName("stormarmory.season.SeasonASMHelper").getMethod("canBlockFreezeInSeason", World.class, BlockPos.class, Boolean.class, Season.class).invoke(null, world, pos, noWaterAdj, season);
}
catch (Exception e)
{
throw new RuntimeException("An error occurred calling canBlockFreezeInSeason", e);
}
}
/**
* An override of {@link World#isRainingAt(BlockPos)}
*/
public static boolean isRainingAtInSeason(World world, BlockPos pos, Season season)
{
try
{
return (Boolean)Class.forName("stormarmory.season.SeasonASMHelper").getMethod("isRainingAtInSeason", World.class, BlockPos.class, Season.class).invoke(null, world, pos, season);
}
catch (Exception e)
{
throw new RuntimeException("An error occurred calling isRainingAtInSeason", e);
}
}
}
<strong><span style="font-family: impact,sans-serif;">
WorldTransformer
package com.stormarmory.util.transformer;
import java.util.List;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.VarInsnNode;
import com.google.common.collect.Lists;
import com.stormarmory.util.asm.ASMHelper;
import com.stormarmory.util.asm.ObfHelper;
import net.minecraft.launchwrapper.IClassTransformer;
public class WorldTransformer implements IClassTransformer
{
private static final String[] CAN_SNOW_AT_NAMES = new String[] { "canSnowAt", "func_175708_f", "f" };
private static final String[] CAN_BLOCK_FREEZE_NAMES = new String[] { "canBlockFreeze", "func_175670_e", "e" };
private static final String[] IS_RAINING_AT_NAMES = new String[] { "isRainingAt", "func_175727_C", "B" };
private static final String[] GET_BIOME_GEN_FOR_COORDS_NAMES = new String[] { "getBiome", "func_180494_b", "b" };
@Override
public byte[] transform(String name, String transformedName, byte[] basicClass)
{
if (transformedName.equals("net.minecraft.world.World"))
{
return transformWorld(basicClass, !transformedName.equals(name));
}
return basicClass;
}
private byte[] transformWorld(byte[] bytes, boolean obfuscatedClass)
{
//Decode the class from bytes
ClassNode classNode = new ClassNode();
ClassReader classReader = new ClassReader(bytes);
classReader.accept(classNode, 0);
List<String> successfulTransformations = Lists.newArrayList();
//Iterate over the methods in the class
for (MethodNode methodNode : classNode.methods)
{
if (ASMHelper.methodEquals(methodNode, CAN_SNOW_AT_NAMES, ObfHelper.createMethodDescriptor(obfuscatedClass, "Z", "net/minecraft/util/math/BlockPos", "Z")))
{
InsnList insnList = new InsnList();
//Get the current season
insnList.add(new VarInsnNode(Opcodes.ALOAD, 0));
insnList.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "stormarmory/util/season/SeasonHelper", "getSeasonData", ObfHelper.createMethodDescriptor(obfuscatedClass, "stormarmory/util/season/ISeasonData", "net/minecraft/world/World"), false));
insnList.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE, "stormarmory/util/season/ISeasonData", "getSubSeason", "()Lstormarmory/util/season/Season$SubSeason;", true));
insnList.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "stormarmory/util/season/Season$SubSeason", "getSeason", "()Lstormarmory/util/season/Season;", false));
insnList.add(new VarInsnNode(Opcodes.ASTORE, 3));
//Invoke our replacement method
insnList.add(new VarInsnNode(Opcodes.ALOAD, 0));
insnList.add(new VarInsnNode(Opcodes.ALOAD, 1));
insnList.add(new VarInsnNode(Opcodes.ILOAD, 2));
insnList.add(new VarInsnNode(Opcodes.ALOAD, 3));
insnList.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "stormarmory/season/SeasonASMHelper", "canSnowAtInSeason", ObfHelper.createMethodDescriptor(obfuscatedClass, "Z", "net/minecraft/world/World", "net/minecraft/util/math/BlockPos", "Z", "stormarmory/util/season/Season"), false));
insnList.add(new InsnNode(Opcodes.IRETURN));
//Substitute existing instructions with our new ones
methodNode.instructions.clear();
methodNode.instructions.insert(insnList);
successfulTransformations.add(methodNode.name + " " + methodNode.desc);
}
else if (ASMHelper.methodEquals(methodNode, CAN_BLOCK_FREEZE_NAMES, ObfHelper.createMethodDescriptor(obfuscatedClass, "Z", "net/minecraft/util/math/BlockPos", "Z")))
{
InsnList insnList = new InsnList();
//Get the current season
insnList.add(new VarInsnNode(Opcodes.ALOAD, 0));
insnList.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "stormarmory/util/season/SeasonHelper", "getSeasonData", ObfHelper.createMethodDescriptor(obfuscatedClass, "stormarmory/util/season/ISeasonData", "net/minecraft/world/World"), false));
insnList.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE, "stormarmory/util/season/ISeasonData", "getSubSeason", "()Lstormarmory/util/season/Season$SubSeason;", true));
insnList.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "stormarmory/util/season/Season$SubSeason", "getSeason", "()Lstormarmory/util/season/Season;", false));
insnList.add(new VarInsnNode(Opcodes.ASTORE, 3));
//Invoke our replacement method
insnList.add(new VarInsnNode(Opcodes.ALOAD, 0));
insnList.add(new VarInsnNode(Opcodes.ALOAD, 1));
insnList.add(new VarInsnNode(Opcodes.ILOAD, 2));
insnList.add(new VarInsnNode(Opcodes.ALOAD, 3));
insnList.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "stormarmory/season/SeasonASMHelper", "canBlockFreezeInSeason", ObfHelper.createMethodDescriptor(obfuscatedClass, "Z", "net/minecraft/world/World", "net/minecraft/util/math/BlockPos", "Z", "stormarmory/util/season/Season"), false));
insnList.add(new InsnNode(Opcodes.IRETURN));
//Substitute existing instructions with our new ones
methodNode.instructions.clear();
methodNode.instructions.insert(insnList);
successfulTransformations.add(methodNode.name + " " + methodNode.desc);
}
else if (ASMHelper.methodEquals(methodNode, IS_RAINING_AT_NAMES, ObfHelper.createMethodDescriptor(obfuscatedClass, "Z", "net/minecraft/util/math/BlockPos")))
{
InsnList insnList = new InsnList();
//Get the current season
insnList.add(new VarInsnNode(Opcodes.ALOAD, 0));
insnList.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "stormarmory/util/season/SeasonHelper", "getSeasonData", ObfHelper.createMethodDescriptor(obfuscatedClass, "stormarmory/util/season/ISeasonData", "net/minecraft/world/World"), false));
insnList.add(new MethodInsnNode(Opcodes.INVOKEINTERFACE, "stormarmory/util/season/ISeasonData", "getSubSeason", "()Lstormarmory/util/season/Season$SubSeason;", true));
insnList.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "stormarmory/util/season/Season$SubSeason", "getSeason", "()Lstormarmory/util/season/Season;", false));
insnList.add(new VarInsnNode(Opcodes.ASTORE, 2));
//Invoke our replacement method
insnList.add(new VarInsnNode(Opcodes.ALOAD, 0));
insnList.add(new VarInsnNode(Opcodes.ALOAD, 1));
insnList.add(new VarInsnNode(Opcodes.ALOAD, 2));
insnList.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "stormarmory/season/SeasonASMHelper", "isRainingAtInSeason", ObfHelper.createMethodDescriptor(obfuscatedClass, "Z", "net/minecraft/world/World", "net/minecraft/util/math/BlockPos", "stormarmory/util/season/Season"), false));
insnList.add(new InsnNode(Opcodes.IRETURN));
MethodInsnNode invokeMethodNode = ASMHelper.getUniqueMethodInsnNode(methodNode, Opcodes.INVOKEVIRTUAL, ObfHelper.unmapType(obfuscatedClass, "net/minecraft/world/World"), GET_BIOME_GEN_FOR_COORDS_NAMES, ObfHelper.createMethodDescriptor(obfuscatedClass, "net/minecraft/world/biome/Biome", "net/minecraft/util/math/BlockPos"));
AbstractInsnNode insertionPoint = methodNode.instructions.get(methodNode.instructions.indexOf(invokeMethodNode) - 2);
//Insert our new instructions before the insertion point
methodNode.instructions.insertBefore(insertionPoint, insnList);
ASMHelper.clearNextInstructions(methodNode, insertionPoint);
successfulTransformations.add(methodNode.name + " " + methodNode.desc);
}
}
if (successfulTransformations.size() != 3) throw new RuntimeException("An error occurred transforming World. Applied transformations: " + successfulTransformations.toString());
//Encode the altered class back into bytes
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
classNode.accept(writer);
bytes = writer.toByteArray();
return bytes;
}
}
Please help us out, me and my current team are clueless as to how to fix this issue, and I've tried messing with it as well. Any help is appreciated.
Have you looked at Tough As Nails mod to see how they did seasons? Also, it's a bit hard to read code in the mcforums thread display, maybe showing a github link to all your code you are requiring help with, it might be easier to read?
Rollback Post to RevisionRollBack
If you would like to get a hold of me somehow, then my discord is @Alex Couch#5275.
Have you looked at Tough As Nails mod to see how they did seasons? Also, it's a bit hard to read code in the mcforums thread display, maybe showing a github link to all your code you are requiring help with, it might be easier to read?
I have. It is almost an exact mirror of it.
Here is my code, please use the 'Experimental' Branch, that's the one where it's all located.
By the way, don't know if this is bordering the topic of this section of the forum- But if any of you want to join my team for this mod, I got a Private Chat and GitHub ^ that you could join. Just give me a PM and you'll be set.
I pulled your code to have a look to see if I could work out what the problem was, but I got 20 build errors from your project. Most of them are because the mappings in your build.gradle don't match the mappings in your code, but you're referencing an undeclared variable on line 97 of EntitySnowflakeFX.java as well.
Ah, the EntitySnowflakeFX has 'isCollided' at line 97, it is used in Vanilla's rain particles the same way, so I don't see why there would be an error, doesn't appear on my side. As for the mapping in my 'build.gradle'... Never had that error before actually, please explain how I could fix it. The 'mapping' is "snapshot_20161111", would I have to pick a different mapping that equates to this mc version?, and if so, please show me where I can find a list of these mappings. For some reason I get no errors.
The mappings that you have in the build.gradle on your GitHub are snapshot_20161220, so I guess something's gone awry between what you have locally and what you've pushed to GitHub.
There are stable mappings for 1.11 available now, so I'd recommend updating to stable_32, although it probably doesn't matter too much.
EDIT: I changed the mappings to snapshot_20161111 and all the build errors have gone away.
I'll change the mappings on GitHub to their correct number, but other than that- What exactly effect does this have on the biome not using snow?
So in your SeasonASMHelper you have two methods - canSnowAtInSeason and canBlockFreezeInSeason. Whenever those methods are called, the season parameter is null. That's causing your SeasonHelper#canSnowAtTempInSeason method to always return false.
When you're calling the SeasonASMHelper methods from the onPopulateChunkEvent handler the variables being passed in are null so I guess that's deliberate, but when they're called from the WorldTransformer it looks like there's an attempt to get a season but it's never passed into the SeasonASMHelper methods.
Could that be the problem?
That indeed seems to be the problem. I'll look over my code to see how to fix it, didn't even know they were returning false like that.
So in your SeasonASMHelper you have two methods - canSnowAtInSeason and canBlockFreezeInSeason. Whenever those methods are called, the season parameter is null. That's causing your SeasonHelper#canSnowAtTempInSeason method to always return false.
When you're calling the SeasonASMHelper methods from the onPopulateChunkEvent handler the variables being passed in are null so I guess that's deliberate, but when they're called from the WorldTransformer it looks like there's an attempt to get a season but it's never passed into the SeasonASMHelper methods.
Could that be the problem?
Just changed my ProviderIceHandler to this:
</div>
<div>
public class ProviderIceHandler
{
/**Handle our own ice generation to ignore winter*/
@SubscribeEvent(priority = EventPriority.HIGHEST)
public void onPopulateChunkEvent(PopulateChunkEvent.Populate event)
{
World world = event.getWorld();
BlockPos pos = new BlockPos(event.getChunkX() * 16, 0, event.getChunkZ() * 16).add(8, 0, 8);
if (event.getType() == EventType.ICE)
{
for (int k2 = 0; k2 < 16; ++k2)
{
for (int j3 = 0; j3 < 16; ++j3)
{
BlockPos blockpos1 = world.getPrecipitationHeight(pos.add(k2, 0, j3));
BlockPos blockpos2 = blockpos1.down();
if (SeasonASMHelper.canBlockFreezeInSeason(world, blockpos2, false, Season.WINTER))
{
world.setBlockState(blockpos2, Blocks.ICE.getDefaultState(), 2);
}
if (SeasonASMHelper.canSnowAtInSeason(world, blockpos1, true, Season.WINTER))
{
world.setBlockState(blockpos1, Blocks.SNOW_LAYER.getDefaultState(), 2);
}
}
}
event.setResult(Result.DENY);
}
}
}
At winter, snow is generated with new chunks. Much better actually.
It still rains in those chunks though, so of course it's a one-time thing. Any other methods I need to look out for that isn't making it snow?
Also, I find it a little weird that ToughAsNails works with the 'null' in place of those fields, what's up with that?
Ah man, I had no idea it was under a license like that....
I told my team I was going to heavily modify it as much as I could, and I removed EVERYTHING from the mod except the Seasonal system, which I am going to add more sub seasons and change the colors of the foliage, use different assets, ect. If I must get permission even after doing all this, then I will write the creator immediately. This was the only mod I could find with seasonal code that I could understand though, so it'd be a bummer, everybody was telling me to adapt this code... Maybe they could check my Github or the like.
I'd not looked at ToughAsNails until you mentioned it, but now that I have I've realised that there are large chunks of code in your mod which are taken directly from that mod.
Before I help you any further, I have to ask - do you have permission to use that code? ToughAsNails is licensed under the Attribution-NonCommercial-NoDerivatives 4.0 license, which means that you're only allowed to use their code for personal use, and aren't allowed to distribute a work which contains adapted material from that work.
I'd start by sending Glitchfiend a PM either here or on CurseForge - they log in regularly so they should see it.
Alright. Thank you so much, I'm afraid I'll end up in a lawsuit or something. xD
Hopefully I can use this. I literally didn't even know you could copyright code.
I'll get the permission and I'll be back here.
Even though he says not to PM that account because he doesn't use it for PMs, should I do it anyway?
I think a lawsuit is unlikely, but yes you can copyright code (and if you look at the header from the ProviderIceHandler.java file you borrowed, it actually says "Copyright 2016, the Biomes O' Plenty Team" at the top of it), and it's better to be sure now than to release your mod and have them find out later - I've seen mods get pulled from Curse for using other people's code without permission. A lot of people just assume that because it's on GitHub it's fair game, but it always pays to check the license - and if you can't find a license, the default position is "All Rights Reserved".
If they say they don't use it for PMs then they might not see it, but it does no harm to try. I'm not sure of any other contact methods for them - they might have Twitter or something?
I'm going to write both on Curseforge right now. I was going to write them on their Discord Server.... But that would just feel awkward.
SeasonASMHelper:
SeasonHelper:
MMain:
MHandler
ProviderIceHandler
ISeasonedWorld
BiomeUtils
WorldHooks
WorldTransformer
Please help us out, me and my current team are clueless as to how to fix this issue, and I've tried messing with it as well. Any help is appreciated.
Have you looked at Tough As Nails mod to see how they did seasons? Also, it's a bit hard to read code in the mcforums thread display, maybe showing a github link to all your code you are requiring help with, it might be easier to read?
If you would like to get a hold of me somehow, then my discord is @Alex Couch#5275.
I have. It is almost an exact mirror of it.
Here is my code, please use the 'Experimental' Branch, that's the one where it's all located.
https://github.com/Arrowstorm606/Natures-Revenge/tree/Experimental
By the way, don't know if this is bordering the topic of this section of the forum- But if any of you want to join my team for this mod, I got a Private Chat and GitHub ^ that you could join. Just give me a PM and you'll be set.
Ah, the EntitySnowflakeFX has 'isCollided' at line 97, it is used in Vanilla's rain particles the same way, so I don't see why there would be an error, doesn't appear on my side. As for the mapping in my 'build.gradle'... Never had that error before actually, please explain how I could fix it. The 'mapping' is "snapshot_20161111", would I have to pick a different mapping that equates to this mc version?, and if so, please show me where I can find a list of these mappings. For some reason I get no errors.
I'll change the mappings on GitHub to their correct number, but other than that- What exactly effect does this have on the biome not using snow?
Oh, sorry if that sounded rude, I was just wondering.
That indeed seems to be the problem. I'll look over my code to see how to fix it, didn't even know they were returning false like that.
Just changed my ProviderIceHandler to this:
At winter, snow is generated with new chunks. Much better actually.
It still rains in those chunks though, so of course it's a one-time thing. Any other methods I need to look out for that isn't making it snow?
Also, I find it a little weird that ToughAsNails works with the 'null' in place of those fields, what's up with that?
Ah man, I had no idea it was under a license like that....
I told my team I was going to heavily modify it as much as I could, and I removed EVERYTHING from the mod except the Seasonal system, which I am going to add more sub seasons and change the colors of the foliage, use different assets, ect. If I must get permission even after doing all this, then I will write the creator immediately. This was the only mod I could find with seasonal code that I could understand though, so it'd be a bummer, everybody was telling me to adapt this code... Maybe they could check my Github or the like.
How would I go about getting permission?
Alright. Thank you so much, I'm afraid I'll end up in a lawsuit or something. xD
Hopefully I can use this. I literally didn't even know you could copyright code.
I'll get the permission and I'll be back here.
Even though he says not to PM that account because he doesn't use it for PMs, should I do it anyway?
Maybe I should write both devs of the mod.
I'm going to write both on Curseforge right now. I was going to write them on their Discord Server.... But that would just feel awkward.
Alright, they have been written. Hopefully me and the Devs will come to an agreement on which code should and shouldn't be in the mod.