Jump to content

TLHPoE

Members
  • Posts

    638
  • Joined

  • Last visited

Everything posted by TLHPoE

  1. You can modify the noise a lot in LibNoise Hopefully you'll port to Java in the future, it seems like it would help a lot with people who are new to noise, like myself.
  2. Since I'm all alone in my world of noise, I might as well keep this thread as a journal to help other people. I have generated this beautiful image here: Using this code here: package terrarium.util; import java.awt.Color; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.Random; import javax.imageio.ImageIO; import net.minecraft.world.gen.NoiseGeneratorPerlin; public class NoiseTesting { public static void init() { Random random = new Random(1L); double[][] noise1 = generateNoise(random, 1, 0, 0, 25, 25); double[][] noise2 = generateNoise(random, 1, 0, 0, 50, 50); double[][] noise3 = generateNoise(random, 1, 0, 0, 100, 100); double[][] noise4 = generateNoise(random, 1, 0, 0, 200, 200); BufferedImage img1 = noiseToImage(noise1, 25, 25); BufferedImage img2 = noiseToImage(noise2, 50, 50); BufferedImage img3 = noiseToImage(noise3, 100, 100); BufferedImage img4 = noiseToImage(noise4, 200, 200); setAlpha(img4, 64); setAlpha(img3, 64); setAlpha(img2, 64); setAlpha(img1, 64); Graphics2D g = (Graphics2D) img4.getGraphics(); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY); g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); g.drawImage(img3, 0, 0, 200, 200, null); g.drawImage(img2, 0, 0, 200, 200, null); g.drawImage(img1, 0, 0, 200, 200, null); g.dispose(); setAlpha(img4, 255); try { saveImage(img1, "./", "img1"); saveImage(img2, "./", "img2"); saveImage(img3, "./", "img3"); saveImage(img4, "./", "img4"); } catch(IOException e) { e.printStackTrace(); } } public static double[][] generateNoise(Random random, int idk, int x, int y, int width, int height) { NoiseGeneratorPerlin noiseGenerator = new NoiseGeneratorPerlin(random, idk); double[][] noiseArray = new double[width][height]; for(int i = 0; i < width; i++) { for(int j = 0; j < height; j++) { noiseArray[i][j] = noiseGenerator.func_151601_a(x + i, y + j); } } return noiseArray; } public static BufferedImage noiseToImage(double[][] noise, int width, int height) { BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); for(int i = 0; i < width; i++) { for(int j = 0; j < height; j++) { int hue = (int) (255 * ((1D + noise[i][j]) / 2)); img.setRGB(i, j, new Color(hue, hue, hue).getRGB()); } } return img; } public static void saveImage(BufferedImage img, String directory, String name) throws IOException { ImageIO.write(img, "png", new File(directory + name + ".png")); } public static void setAlpha(BufferedImage img, int alpha) { for(int i = 0; i < img.getWidth(); i++) { for(int j = 0; j < img.getHeight(); j++) { Color currentColor = new Color(img.getRGB(i, j)); Color newColor = new Color(currentColor.getRed(), currentColor.getGreen(), currentColor.getBlue(), alpha); img.setRGB(i, j, newColor.getRGB()); } } } } Please don't assassinate me because I used Graphics2D and BufferedImages to mix the noises, I have no clue on how to interpolate a 2 dimensional array.
  3. Ok, I've been messing around with the perlin noise class and was able to create this beautiful piece of art: Here's the code I used to generate it: package terrarium.util; import java.awt.Color; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.Random; import javax.imageio.ImageIO; import net.minecraft.world.gen.NoiseGeneratorOctaves; import net.minecraft.world.gen.NoiseGeneratorPerlin; public class NoiseTesting { public static void init() { NoiseGeneratorPerlin noise = new NoiseGeneratorPerlin(new Random(1L), 1); double[][] noiseArray = new double[100][100]; for(int i = 0; i < 100; i++) { for(int j = 0; j < 100; j++) { noiseArray[i][j] = noise.func_151601_a(i, j); } } BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB); for(int i = 0; i < 100; i++) { for(int j = 0; j < 100; j++) { int n2 = (int) (255 * ((1D + noiseArray[i][j]) / 2)); img.setRGB(i, j, new Color(n2, n2, n2).getRGB()); } } File file = new File("./image.png"); try { ImageIO.write(img, "png", file); } catch(IOException e) { e.printStackTrace(); } } } One problem though, you probably notice that it doesn't seem as smooth. My question is, how does Minecraft interpolate the original noise to a state that is satisfactory? I know how to interpolate a 1 dimensional array, but not a 2 dimensional array.
  4. Use the LivingFallEvent and set the fall distance field to 0. There might be some other field in the event, though I'm not sure.
  5. When you register your packet, the Side argument is which side you're sending the message to. So you should handle the client side in your on onMessage method.
  6. I would check if motionX or motionZ are not equal to 0. I'm pretty sure there was another field in EntityPlayer that had the word strafe in it. That may might help out.
  7. The client proxy location you provided in your SidedProxy annotation is not correct.
  8. I'm currently attempting to scale the item when it's rendered. How do I get the default renderer for each type? ItemRenderer: package terrarium.render; import net.minecraft.client.renderer.ItemRenderer; import net.minecraft.client.renderer.Tessellator; import net.minecraft.item.ItemStack; import net.minecraftforge.client.IItemRenderer; public class SizedItemRenderer implements IItemRenderer { public double scaleX, scaleY, scaleZ; public SizedItemRenderer(double scaleX, double scaleY, double scaleZ) { this.scaleX = scaleX; this.scaleY = scaleY; this.scaleZ = scaleZ; } @Override public boolean handleRenderType(ItemStack item, ItemRenderType type) { return true; } @Override public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper) { return true; } @Override public void renderItem(ItemRenderType type, ItemStack item, Object... data) { ItemRenderer.renderItemIn2D(Tessellator.instance, 0F, 0F, 1F, 1F, 255, 255, 0.0625F); } } ItemRenderer.renderItemIn2D doesn't really work out, this is what happens:
  9. I have no clue what I'm doing any more :'( Every is an ocean biome, except for the block at 0, 0, which is a plains biome. WorldChunkManager: package terrarium.world; import java.lang.reflect.Field; import net.minecraft.world.biome.WorldChunkManager; import net.minecraft.world.gen.layer.GenLayer; import net.minecraft.world.gen.layer.GenLayerIsland; import terrarium.util.LogUtil; public class WorldChunkManagerT extends WorldChunkManager { public WorldChunkManagerT(long seed, WorldTypeT worldType) { super(seed, worldType); GenLayer genLayer = GenLayerBiomeT.init(seed, worldType); replaceField("genBiomes", genLayer); replaceField("biomeIndexLayer", genLayer); } private void replaceField(String fieldName, Object value) { Field field = null; try { field = this.getClass().getSuperclass().getDeclaredField(fieldName); } catch(NoSuchFieldException e) { e.printStackTrace(); } catch(SecurityException e) { e.printStackTrace(); } if(field != null) { LogUtil.info(fieldName + " field found, replacing"); field.setAccessible(true); try { field.set(this, new GenLayerIsland(1000L)); } catch(IllegalArgumentException e) { e.printStackTrace(); } catch(IllegalAccessException e) { e.printStackTrace(); } } } } GenLayerBiomeT: package terrarium.world; import net.minecraft.world.biome.BiomeGenBase; import net.minecraft.world.gen.layer.GenLayer; import net.minecraft.world.gen.layer.GenLayerBiome; import net.minecraft.world.gen.layer.GenLayerFuzzyZoom; import net.minecraft.world.gen.layer.GenLayerSmooth; import net.minecraft.world.gen.layer.GenLayerVoronoiZoom; import net.minecraft.world.gen.layer.GenLayerZoom; import net.minecraft.world.gen.layer.IntCache; import terrarium.ServerProxy; import terrarium.util.MathUtil; public class GenLayerBiomeT extends GenLayerBiome { public int size; public GenLayerBiomeT(long seed, WorldTypeT worldType) { super(seed, null, worldType); this.size = worldType.size; } @Override public int[] getInts(int chunkX, int chunkZ, int par3, int par4) { int[] current = IntCache.getIntCache(par3 * par4); int realX; int realZ; double distance; for(int z = 0; z < par4; z++) { for(int x = 0; x < par3; x++) { realX = x + chunkX; realZ = z + chunkZ; this.initChunkSeed((long) realX, (long) realZ); distance = MathUtil.getDistance2D(0, 0, realX, realZ); if(distance > 24 * size) { current[x + z * par3] = BiomeGenBase.deepOcean.biomeID; } else if(distance > 12 * size) { current[x + z * par3] = BiomeGenBase.ocean.biomeID; } else if(distance > 9 * size) { current[x + z * par3] = BiomeGenBase.taigaHills.biomeID; } else if(distance > 6 * size) { current[x + z * par3] = BiomeGenBase.desert.biomeID; } else if(distance > 3 * size) { current[x + z * par3] = BiomeGenBase.forest.biomeID; } else { current[x + z * par3] = ServerProxy.forest.biomeID; } } } return current; } public static GenLayer init(long seed, WorldTypeT worldType) { GenLayer genLayerT = new GenLayerBiomeT(1L, worldType); GenLayer genLayerFuzzyZoom1 = new GenLayerFuzzyZoom(2000L, genLayerT); GenLayer genLayerFuzzyZoom2 = new GenLayerFuzzyZoom(2001L, genLayerFuzzyZoom1); GenLayer genLayerFuzzyZoom3 = new GenLayerFuzzyZoom(2002L, genLayerFuzzyZoom2); GenLayer genLayerMagnify = GenLayerZoom.magnify(1000L, genLayerFuzzyZoom3, 0); GenLayer genLayerSmooth1 = new GenLayerSmooth(1000L, genLayerMagnify); GenLayer genLayerVoronoiZoom = new GenLayerVoronoiZoom(10L, genLayerSmooth1); GenLayer genLayerSmooth2 = new GenLayerSmooth(1000L, genLayerVoronoiZoom); return genLayerSmooth2; } }
  10. Ok, I got the private field problem out of the way, thanks to reflection <3 Current problem is that the world is just a big ocean ATM. I have my own GenLayer in my world type, but it doesn't seem to affect the world. WorldChunkManager: package terrarium.world; import java.lang.reflect.Field; import net.minecraft.world.WorldType; import net.minecraft.world.biome.WorldChunkManager; import net.minecraft.world.gen.layer.GenLayerIsland; import terrarium.util.LogUtil; public class WorldChunkManagerT extends WorldChunkManager { public WorldChunkManagerT(long seed, WorldType worldType) { super(seed, worldType); replaceField("genBiomes", new GenLayerIsland(1000L)); replaceField("biomeIndexLayer", new GenLayerIsland(1000L)); } private void replaceField(String fieldName, Object value) { Field field = null; try { field = this.getClass().getSuperclass().getDeclaredField(fieldName); } catch(NoSuchFieldException e) { e.printStackTrace(); } catch(SecurityException e) { e.printStackTrace(); } if(field != null) { LogUtil.info(fieldName + " field found, replacing"); field.setAccessible(true); try { field.set(this, new GenLayerIsland(1000L)); } catch(IllegalArgumentException e) { e.printStackTrace(); } catch(IllegalAccessException e) { e.printStackTrace(); } } } }
  11. I already have my own chunk manager, it's just that the fields are private. Should I override the methods that use those fields and use my own gen layer?
  12. I think you star out with the base GenLayer, and then you pass it on to other GenLayers to modify? I tried it earlier, and the 2 GenLayer fields in WorldChunkManager are private.
  13. Is there anyway to stop the river biome from generating in my custom world type? I have my own GenLayerBiome class, but it's still generating the river. WorldType: package terrarium.world; import net.minecraft.world.World; import net.minecraft.world.WorldType; import net.minecraft.world.biome.WorldChunkManager; import net.minecraft.world.gen.layer.GenLayer; import net.minecraft.world.gen.layer.GenLayerIsland; public class WorldTypeT extends WorldType { public int size; public WorldTypeT(int size) { super("SIZE" + size); this.size = size; } @Override public WorldChunkManager getChunkManager(World world) { return new WorldChunkManagerT(world.getSeed(), this); } @Override public GenLayer getBiomeLayer(long worldSeed, GenLayer parentLayer) { return new GenLayerBiomeT(200L, parentLayer, this); } } GenLayerBiome: package terrarium.world; import net.minecraft.world.WorldType; import net.minecraft.world.biome.BiomeGenBase; import net.minecraft.world.gen.layer.GenLayer; import net.minecraft.world.gen.layer.GenLayerBiome; import net.minecraft.world.gen.layer.GenLayerIsland; import net.minecraft.world.gen.layer.GenLayerSmooth; import net.minecraft.world.gen.layer.GenLayerVoronoiZoom; import net.minecraft.world.gen.layer.IntCache; import terrarium.ServerProxy; import terrarium.util.MathUtil; public class GenLayerBiomeT extends GenLayerBiome { public int size; public GenLayerBiomeT(long seed, GenLayer layer, WorldTypeT worldType) { super(seed, layer, worldType); this.size = worldType.size; } @Override public int[] getInts(int chunkX, int chunkZ, int par3, int par4) { int[] current = IntCache.getIntCache(par3 * par4); int realX; int realZ; double distance; for(int z = 0; z < par4; z++) { for(int x = 0; x < par3; x++) { realX = x + chunkX; realZ = z + chunkZ; this.initChunkSeed((long) realX, (long) realZ); distance = MathUtil.getDistance2D(0, 0, realX, realZ); if(distance > 24 * size) { current[x + z * par3] = BiomeGenBase.deepOcean.biomeID; } else if(distance > 12 * size) { current[x + z * par3] = BiomeGenBase.ocean.biomeID; } else if(distance > 9 * size) { current[x + z * par3] = BiomeGenBase.taigaHills.biomeID; } else if(distance > 6 * size) { current[x + z * par3] = BiomeGenBase.desert.biomeID; } else if(distance > 3 * size) { current[x + z * par3] = BiomeGenBase.forest.biomeID; } else { current[x + z * par3] = ServerProxy.forest.biomeID; } } } return current; } } WorldChunkManager: [code} package terrarium.world; import java.lang.reflect.Field; import net.minecraft.world.WorldType; import net.minecraft.world.biome.WorldChunkManager; import net.minecraft.world.gen.layer.GenLayer; import terrarium.util.LogUtil; public class WorldChunkManagerT extends WorldChunkManager { public WorldChunkManagerT(long seed, WorldType worldType) { super(seed, worldType); } } [/code]
  14. Is there any tutorial or documentary on how to use the Minecraft noise generator classes? The classes are very... cryptic with what they're doing.
  15. Could you show us your code?
  16. I've run into a problem similar to this before, and it's definitely not your fault. You need to set the entity's angles too. e.setLocationAndAngles(player.posX, player.posY, player.posZ, 0, 0);
  17. Ok, I haven't found anything yet. Can someone at least point me to where Minecraft decides what biome to generate?
  18. I found out how to make the world generate only 1 specific biome, but how would I make the world generate a specific biome at a specific chunk coordinate? Overriding getBiomeGenAt does nothing, I think it's only for seeing what biome is at that chunk coordinate. My Chunk Manager Class: package ttm.world; import java.util.Arrays; import java.util.List; import java.util.Random; import net.minecraft.world.ChunkPosition; import net.minecraft.world.biome.BiomeGenBase; import net.minecraft.world.biome.WorldChunkManager; public class WorldChunkManagerTtM extends WorldChunkManager { @Override public BiomeGenBase getBiomeGenAt(int x, int y) { return BiomeGenBase.desertHills; } @Override public BiomeGenBase[] getBiomesForGeneration(BiomeGenBase[] biomes, int par2, int par3, int par4, int par5) { if(biomes == null || biomes.length < par4 * par5) { biomes = new BiomeGenBase[par4 * par5]; } Arrays.fill(biomes, 0, par4 * par5, BiomeGenBase.desertHills); return biomes; } @Override public float[] getRainfall(float[] rain, int par2, int par3, int par4, int par5) { if(rain == null || rain.length < par4 * par5) { rain = new float[par4 * par5]; } Arrays.fill(rain, 0, par4 * par5, BiomeGenBase.desertHills.rainfall); return rain; } @Override public BiomeGenBase[] loadBlockGeneratorData(BiomeGenBase[] biomes, int par2, int par3, int par4, int par5) { if(biomes == null || biomes.length < par4 * par5) { biomes = new BiomeGenBase[par4 * par5]; } Arrays.fill(biomes, 0, par4 * par5, BiomeGenBase.desertHills); return biomes; } @Override public ChunkPosition findBiomePosition(int x, int y, int p_150795_3_, List p_150795_4_, Random p_150795_5_) { return p_150795_4_.contains(BiomeGenBase.desertHills) ? new ChunkPosition(x - p_150795_3_ + p_150795_5_.nextInt(p_150795_3_ * 2 + 1), 0, y - p_150795_3_ + p_150795_5_.nextInt(p_150795_3_ * 2 + 1)) : null; } @Override public boolean areBiomesViable(int par1, int par2, int par3, List par4List) { return par4List.contains(BiomeGenBase.desertHills); } }
  19. Ohhhhhhhhhhhhhhhhhhh Thanks for catching that.
  20. Ok, I only had the IDs because that message class was only for short messages. None of my other messages are being received either. Mod: package ttm; import static ttm.Reference.ID; import static ttm.Reference.NAME; import static ttm.Reference.VERSION; import ttm.handler.GuiHandler; import ttm.network.MessageJump; import ttm.network.MessageOpenGui; import ttm.network.MessageQuickStack; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.Mod.EventHandler; import cpw.mods.fml.common.Mod.Instance; import cpw.mods.fml.common.SidedProxy; import cpw.mods.fml.common.event.FMLPreInitializationEvent; import cpw.mods.fml.common.network.NetworkRegistry; import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper; import cpw.mods.fml.relauncher.Side; @Mod(name = NAME, modid = ID, version = VERSION) public class TtM { @Instance(ID) public static TtM instance; @SidedProxy(serverSide = ID + ".ServerProxy", clientSide = ID + ".ClientProxy") public static ServerProxy proxy; public static GuiHandler guiHandler = new GuiHandler(); public static SimpleNetworkWrapper networkChannel; @EventHandler public void preInit(FMLPreInitializationEvent event) { NetworkRegistry.INSTANCE.registerGuiHandler(this, guiHandler); networkChannel = NetworkRegistry.INSTANCE.newSimpleChannel("TtM"); loadPackets(); proxy.loadServer(); proxy.loadClient(); } public void loadPackets() { networkChannel.registerMessage(MessageJump.Handler.class, MessageJump.class, 0, Side.SERVER); networkChannel.registerMessage(MessageOpenGui.Handler.class, MessageOpenGui.class, 0, Side.SERVER); networkChannel.registerMessage(MessageQuickStack.Handler.class, MessageQuickStack.class, 0, Side.SERVER); } } Message: package ttm.network; import io.netty.buffer.ByteBuf; import net.minecraft.entity.player.EntityPlayer; import ttm.TtM; import cpw.mods.fml.common.network.simpleimpl.IMessage; import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; import cpw.mods.fml.common.network.simpleimpl.MessageContext; public class MessageOpenGui extends BasicMessage { public int guiID; public MessageOpenGui(int guiID) { super(); this.guiID = guiID; } public MessageOpenGui() { this(0); } @Override public void toBytes(ByteBuf buf) { buf.writeInt(guiID); System.err.println("HI2"); } @Override public void fromBytes(ByteBuf buf) { guiID = buf.readInt(); System.err.println("HI"); } public static class Handler implements IMessageHandler<MessageOpenGui, IMessage> { public IMessage onMessage(MessageOpenGui message, MessageContext ctx) { EntityPlayer player = ctx.getServerHandler().playerEntity; player.openGui(TtM.instance, message.guiID, player.worldObj, (int) player.posX, (int) player.posY, (int) player.posZ); return null; } } } BasicMessage: package ttm.network; import io.netty.buffer.ByteBuf; import net.minecraft.entity.player.EntityPlayerMP; import ttm.TtM; import cpw.mods.fml.common.network.simpleimpl.IMessage; import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; import cpw.mods.fml.common.network.simpleimpl.MessageContext; public abstract class BasicMessage implements IMessage { @Override public abstract void fromBytes(ByteBuf buf); @Override public abstract void toBytes(ByteBuf buf); public void sendToAll() { TtM.networkChannel.sendToAll(this); } public void sendTo(EntityPlayerMP player) { TtM.networkChannel.sendTo(this, player); } public void sendToServer() { TtM.networkChannel.sendToServer(this); System.err.println("TO THE SERVER!"); } }
  21. I've run into a problem. Whenever I send the message to the server, it never arrives. It only writes to the byte buffer. Message: package ttm.network; import io.netty.buffer.ByteBuf; import net.minecraftforge.common.ForgeHooks; import ttm.Reference; import cpw.mods.fml.common.network.simpleimpl.IMessage; import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; import cpw.mods.fml.common.network.simpleimpl.MessageContext; public class SimpleServerMessage extends AbstractMessage { public int msgID; public SimpleServerMessage(int msgID) { super(); this.msgID = msgID; } public SimpleServerMessage() { this(0); } @Override public void toBytes(ByteBuf buf) { buf.writeInt(msgID); } @Override public void fromBytes(ByteBuf buf) { msgID = buf.readInt(); } public static class Handler implements IMessageHandler<SimpleServerMessage, IMessage> { public IMessage onMessage(SimpleServerMessage message, MessageContext ctx) { switch(message.msgID) { case Reference.PacketMessages.JUMP: { ForgeHooks.onLivingJump(ctx.getServerHandler().playerEntity); break; } } return null; } } } Basic Message: package ttm.network; import io.netty.buffer.ByteBuf; import net.minecraft.entity.player.EntityPlayerMP; import ttm.TtM; import cpw.mods.fml.common.network.simpleimpl.IMessage; import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; import cpw.mods.fml.common.network.simpleimpl.MessageContext; public abstract class BasicMessage implements IMessage { @Override public abstract void fromBytes(ByteBuf buf); @Override public abstract void toBytes(ByteBuf buf); public void sendToAll() { TtM.networkChannel.sendToAll(this); } public void sendTo(EntityPlayerMP player) { TtM.networkChannel.sendTo(this, player); } public void sendToServer() { TtM.networkChannel.sendToServer(this); System.err.println("TO THE SERVER!"); } }
  22. I'm getting this in my console: [09:55:14] [server thread/ERROR] [FML]: Detected ongoing potential memory leak. 100 packets have leaked. Top offenders [09:55:14] [server thread/ERROR] [FML]: ttm : 100 I'm partially worried, because this packet is from the client to the server, and is gonna be sent a lot. Packet: package ttm.network; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import net.minecraft.entity.player.EntityPlayer; import net.minecraftforge.common.ForgeHooks; import ttm.Reference; public class PacketMessage extends AbstractPacket { public int msgID; public PacketMessage(int msgID) { super(); this.msgID = msgID; } public PacketMessage() { this(0); } @Override public void encodeInto(ChannelHandlerContext ctx, ByteBuf buffer) { buffer.writeInt(msgID); } @Override public void decodeInto(ChannelHandlerContext ctx, ByteBuf buffer) { msgID = buffer.readInt(); } @Override public void handleClientSide(EntityPlayer player) { } @Override public void handleServerSide(EntityPlayer player) { switch(msgID) { case Reference.PacketMessages.JUMP: { ForgeHooks.onLivingJump(player); break; } } } } Should I be worried about this?
  23. Is there a way on the client side to check if the player is typing in the chat?
  24. 1. ITickHandler was replaced by TickEvent. Register the events in the FMLCommonHandler.instance().bus(). 2. Why are you using integers as booleans? Also, you could get away with just 1 boolean anyways. 3. Can't help you with the out of bounds array error, you need to post the full class and the crash log.
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.