diff --git a/fml b/fml index 13ac015f0c..31cf2a9cab 160000 --- a/fml +++ b/fml @@ -1 +1 @@ -Subproject commit 13ac015f0c36b8e2091ae332c556be315429f4c8 +Subproject commit 31cf2a9cab6d1977d31436220d9612eaa13d4e0f diff --git a/patches/minecraft/net/minecraft/client/gui/achievement/GuiAchievements.java.patch b/patches/minecraft/net/minecraft/client/gui/achievement/GuiAchievements.java.patch index 7fc8d0e2f5..9313947d25 100644 --- a/patches/minecraft/net/minecraft/client/gui/achievement/GuiAchievements.java.patch +++ b/patches/minecraft/net/minecraft/client/gui/achievement/GuiAchievements.java.patch @@ -61,7 +61,18 @@ } } -@@ -339,11 +365,12 @@ +@@ -260,7 +286,9 @@ + GL11.glDepthFunc(GL11.GL_GEQUAL); + GL11.glPushMatrix(); + GL11.glTranslatef((float)k1, (float)l1, -200.0F); +- GL11.glScalef(1.0F / this.field_146570_r, 1.0F / this.field_146570_r, 0.0F); ++ // FIXES models rendering weirdly in the acheivements pane ++ // see https://github.com/MinecraftForge/MinecraftForge/commit/1b7ce7592caafb760ec93066184182ae0711e793#commitcomment-10512284 ++ GL11.glScalef(1.0F / this.field_146570_r, 1.0F / this.field_146570_r, 1.0F); + GL11.glEnable(GL11.GL_TEXTURE_2D); + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glEnable(GL12.GL_RESCALE_NORMAL); +@@ -339,11 +367,12 @@ int j4; int l4; @@ -77,7 +88,7 @@ { j3 = achievement1.field_75993_a * 24 - k + 11; k3 = achievement1.field_75991_b * 24 - l + 11; -@@ -400,9 +427,9 @@ +@@ -400,9 +429,9 @@ int i5; int j5; @@ -89,7 +100,7 @@ i5 = achievement2.field_75993_a * 24 - k; j5 = achievement2.field_75991_b * 24 - l; -@@ -444,6 +471,7 @@ +@@ -444,6 +473,7 @@ this.field_146297_k.func_110434_K().func_110577_a(field_146561_C); @@ -97,7 +108,7 @@ if (achievement2.func_75984_f()) { this.func_73729_b(i5 - 2, j5 - 2, 26, 202, 26, 26); -@@ -452,6 +480,7 @@ +@@ -452,6 +482,7 @@ { this.func_73729_b(i5 - 2, j5 - 2, 0, 202, 26, 26); } @@ -105,7 +116,7 @@ if (!this.field_146556_E.func_77442_b(achievement2)) { -@@ -460,7 +489,7 @@ +@@ -460,7 +491,7 @@ renderitem.field_77024_a = false; } diff --git a/patches/minecraft/net/minecraft/world/WorldProvider.java.patch b/patches/minecraft/net/minecraft/world/WorldProvider.java.patch index 047326f7c5..72b9ef57b0 100644 --- a/patches/minecraft/net/minecraft/world/WorldProvider.java.patch +++ b/patches/minecraft/net/minecraft/world/WorldProvider.java.patch @@ -51,11 +51,11 @@ + private IRenderHandler skyRenderer = null; + private IRenderHandler cloudRenderer = null; + private IRenderHandler weatherRenderer = null; -+ ++ + /** + * Sets the providers current dimension ID, used in default getSaveFolder() + * Added to allow default providers to be registered for multiple dimensions. -+ * ++ * + * @param dim Dimension ID + */ + public void setDimension(int dim) @@ -105,7 +105,7 @@ + else if (this instanceof WorldProviderHell) + { + return "Leaving the Nether"; -+ } ++ } + return null; + } + @@ -168,7 +168,7 @@ + int spawnFuzz = field_76577_b.getSpawnFuzz(); + int spawnFuzzHalf = spawnFuzz / 2; + -+ if (!field_76576_e && !isAdventure) ++ if (!field_76576_e && !isAdventure && net.minecraftforge.common.ForgeModContainer.defaultHasSpawnFuzz) + { + chunkcoordinates.field_71574_a += this.field_76579_a.field_73012_v.nextInt(spawnFuzz) - spawnFuzzHalf; + chunkcoordinates.field_71573_c += this.field_76579_a.field_73012_v.nextInt(spawnFuzz) - spawnFuzzHalf; @@ -177,10 +177,10 @@ + + return chunkcoordinates; + } -+ ++ + /** + * Determine if the cusor on the map should 'spin' when rendered, like it does for the player in the nether. -+ * ++ * + * @param entity The entity holding the map, playername, or frame-ENTITYID + * @param x X Position + * @param y Y Position @@ -194,7 +194,7 @@ + + /** + * Determines the dimension the player will be respawned in, typically this brings them back to the overworld. -+ * ++ * + * @param player The player that is respawning + * @return The dimension to respawn the player in + */ @@ -214,20 +214,20 @@ + { + return field_76579_a.field_73008_k < 4; + } -+ ++ + /** + * The current sun brightness factor for this dimension. + * 0.0f means no light at all, and 1.0f means maximum sunlight. + * This will be used for the "calculateSkylightSubtracted" + * which is for Sky light value calculation. -+ * ++ * + * @return The current brightness factor + * */ + public float getSunBrightnessFactor(float par1) + { + return field_76579_a.getSunBrightnessFactor(par1); + } -+ ++ + /** + * Calculates the current moon phase factor. + * This factor is effective for slimes. @@ -258,7 +258,7 @@ + { + return field_76579_a.getSunBrightnessBody(par1); + } -+ ++ + /** + * Gets the Star Brightness for rendering sky. + * */ diff --git a/src/main/java/net/minecraftforge/classloading/FMLForgePlugin.java b/src/main/java/net/minecraftforge/classloading/FMLForgePlugin.java index 35e0cdf689..cc03664025 100644 --- a/src/main/java/net/minecraftforge/classloading/FMLForgePlugin.java +++ b/src/main/java/net/minecraftforge/classloading/FMLForgePlugin.java @@ -13,7 +13,7 @@ public class FMLForgePlugin implements IFMLLoadingPlugin @Override public String[] getASMTransformerClass() { - return new String[0]; + return new String[] { "net.minecraftforge.classloading.FluidIdTransformer" }; } @Override diff --git a/src/main/java/net/minecraftforge/classloading/FluidIdTransformer.java b/src/main/java/net/minecraftforge/classloading/FluidIdTransformer.java new file mode 100644 index 0000000000..a1dfb21d04 --- /dev/null +++ b/src/main/java/net/minecraftforge/classloading/FluidIdTransformer.java @@ -0,0 +1,56 @@ +package net.minecraftforge.classloading; + +import java.util.ListIterator; + +import net.minecraft.launchwrapper.IClassTransformer; + +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.FieldInsnNode; +import org.objectweb.asm.tree.FieldNode; +import org.objectweb.asm.tree.MethodInsnNode; +import org.objectweb.asm.tree.MethodNode; + +import cpw.mods.fml.common.FMLLog; + +public class FluidIdTransformer implements IClassTransformer { + private static final String FLUID_TYPE = "net/minecraftforge/fluids/FluidStack"; + private static final String GETID_NAME = "getFluidID"; + private static final String LEGACY_FIELDNAME = "fluidID"; + private static final String GETID_DESC = "()I"; + + @Override + public byte[] transform(String name, String transformedName, byte[] basicClass) { + if (basicClass == null) + return null; + ClassNode classNode = new ClassNode(); + ClassReader classReader = new ClassReader(basicClass); + classReader.accept(classNode, 0); + + for (MethodNode m: classNode.methods) + { + for (ListIterator it = m.instructions.iterator(); it.hasNext(); ) + { + AbstractInsnNode insnNode = it.next(); + if (insnNode.getType() == AbstractInsnNode.FIELD_INSN) + { + FieldInsnNode fi = (FieldInsnNode)insnNode; + if (FLUID_TYPE.equals(fi.owner) && LEGACY_FIELDNAME.equals(fi.name) && fi.getOpcode() == Opcodes.GETFIELD) + { + FMLLog.fine("Method %s.%s%s: Replacing GETFIELD fluidID with INVOKEVIRTUAL getFluidID", name, m.name, m.desc); + it.remove(); + MethodInsnNode replace = new MethodInsnNode(Opcodes.INVOKEVIRTUAL, FLUID_TYPE, GETID_NAME, GETID_DESC, false); + it.add(replace); + } + } + } + } + ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); + classNode.accept(writer); + return writer.toByteArray(); + } + +} diff --git a/src/main/java/net/minecraftforge/common/ForgeModContainer.java b/src/main/java/net/minecraftforge/common/ForgeModContainer.java index dcff0959a7..fe9459c1c2 100644 --- a/src/main/java/net/minecraftforge/common/ForgeModContainer.java +++ b/src/main/java/net/minecraftforge/common/ForgeModContainer.java @@ -60,7 +60,6 @@ public class ForgeModContainer extends DummyModContainer implements WorldAccessC public static boolean removeErroringEntities = false; public static boolean removeErroringTileEntities = false; public static boolean disableStitchedFileSaving = false; - public static boolean forceDuplicateFluidBlockCrash = true; public static boolean fullBoundingBoxLadders = false; public static double zombieSummonBaseChance = 0.1; public static int[] blendRanges = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34 }; @@ -68,6 +67,7 @@ public class ForgeModContainer extends DummyModContainer implements WorldAccessC public static boolean shouldSortRecipies = true; public static boolean disableVersionCheck = false; public static int defaultSpawnFuzz = 20; + public static boolean defaultHasSpawnFuzz = true; private static Configuration config; @@ -157,17 +157,6 @@ public class ForgeModContainer extends DummyModContainer implements WorldAccessC shouldSortRecipies = prop.getBoolean(shouldSortRecipies); propOrder.add(prop.getName()); - prop = config.get(Configuration.CATEGORY_GENERAL, "forceDuplicateFluidBlockCrash", true); - prop.comment = "Set this to true to force a crash if more than one block attempts to link back to the same Fluid. Enabled by default."; - prop.setLanguageKey("forge.configgui.forceDuplicateFluidBlockCrash").setRequiresMcRestart(true); - forceDuplicateFluidBlockCrash = prop.getBoolean(true); - propOrder.add(prop.getName()); - - if (!forceDuplicateFluidBlockCrash) - { - FMLLog.warning("Disabling forced crashes on duplicate Fluid Blocks - USE AT YOUR OWN RISK"); - } - prop = config.get(Configuration.CATEGORY_GENERAL, "removeErroringEntities", false); prop.comment = "Set this to true to remove any Entity that throws an error in its update method instead of closing the server and reporting a crash log. BE WARNED THIS COULD SCREW UP EVERYTHING USE SPARINGLY WE ARE NOT RESPONSIBLE FOR DAMAGES."; prop.setLanguageKey("forge.configgui.removeErroringEntities").setRequiresWorldRestart(true); @@ -225,6 +214,12 @@ public class ForgeModContainer extends DummyModContainer implements WorldAccessC defaultSpawnFuzz = prop.getInt(20); propOrder.add(prop.getName()); + prop = config.get(Configuration.CATEGORY_GENERAL, "spawnHasFuzz", Boolean.TRUE, + "If the overworld has ANY spawn fuzz at all. If not, the spawn will always be the exact same location."); + prop.setLanguageKey("forge.configgui.hasspawnfuzz").setRequiresWorldRestart(false); + defaultHasSpawnFuzz = prop.getBoolean(Boolean.TRUE); + propOrder.add(prop.getName()); + config.setCategoryPropertyOrder(CATEGORY_GENERAL, propOrder); if (config.hasChanged()) @@ -253,7 +248,7 @@ public class ForgeModContainer extends DummyModContainer implements WorldAccessC } } } - + @SubscribeEvent public void playerLogin(PlayerEvent.PlayerLoggedInEvent event) { @@ -280,7 +275,7 @@ public class ForgeModContainer extends DummyModContainer implements WorldAccessC MinecraftForge.EVENT_BUS.register(MinecraftForge.INTERNAL_HANDLER); ForgeChunkManager.captureConfig(evt.getModConfigurationDirectory()); FMLCommonHandler.instance().bus().register(this); - + if (!ForgeModContainer.disableVersionCheck) { ForgeVersion.startVersionCheck(); diff --git a/src/main/java/net/minecraftforge/common/ForgeVersion.java b/src/main/java/net/minecraftforge/common/ForgeVersion.java index 88ec7b55d4..b8dacccf9a 100644 --- a/src/main/java/net/minecraftforge/common/ForgeVersion.java +++ b/src/main/java/net/minecraftforge/common/ForgeVersion.java @@ -23,7 +23,7 @@ public class ForgeVersion //This number is incremented every minecraft release, never reset public static final int minorVersion = 13; //This number is incremented every time a interface changes or new major feature is added, and reset every Minecraft version - public static final int revisionVersion = 2; + public static final int revisionVersion = 3; //This number is incremented every time Jenkins builds Forge, and never reset. Should always be 0 in the repo code. public static final int buildVersion = 0; diff --git a/src/main/java/net/minecraftforge/common/MinecraftForge.java b/src/main/java/net/minecraftforge/common/MinecraftForge.java index c0f0414cbd..93692ed9f0 100644 --- a/src/main/java/net/minecraftforge/common/MinecraftForge.java +++ b/src/main/java/net/minecraftforge/common/MinecraftForge.java @@ -1,8 +1,14 @@ package net.minecraftforge.common; +import java.util.concurrent.Callable; + +import com.google.common.collect.ObjectArrays; + +import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.eventhandler.EventBus; +import cpw.mods.fml.relauncher.Side; import net.minecraft.crash.CrashReport; import net.minecraft.item.ItemStack; import net.minecraftforge.common.ForgeHooks.SeedEntry; @@ -47,11 +53,113 @@ public class MinecraftForge OreDictionary.getOreName(0); //Force these classes to be defined, Should prevent derp error hiding. - new CrashReport("ThisIsFake", new Exception("Not real")); - + CrashReport fake = new CrashReport("ThisIsFake", new Exception("Not real")); + //Lets init World's crash report inner classes to prevent them from hiding errors. + String[] handlers = { + "net.minecraft.world.World$1", + "net.minecraft.world.World$2", + "net.minecraft.world.World$3", + "net.minecraft.world.World$4", + "net.minecraft.world.chunk.Chunk$1", + "net.minecraft.crash.CrashReportCategory$1", + "net.minecraft.crash.CrashReportCategory$2", + "net.minecraft.crash.CrashReportCategory$3", + "net.minecraft.entity.Entity$1", + "net.minecraft.entity.Entity$2", + "net.minecraft.entity.EntityTracker$1", + "net.minecraft.world.gen.layer.GenLayer$1", + "net.minecraft.world.gen.layer.GenLayer$2", + "net.minecraft.entity.player.InventoryPlayer$1", + "net.minecraft.world.gen.structure.MapGenStructure$1", + "net.minecraft.world.gen.structure.MapGenStructure$2", + "net.minecraft.world.gen.structure.MapGenStructure$3", + "net.minecraft.server.MinecraftServer$3", + "net.minecraft.server.MinecraftServer$4", + "net.minecraft.server.MinecraftServer$5", + "net.minecraft.nbt.NBTTagCompound$1", + "net.minecraft.nbt.NBTTagCompound$2", + "net.minecraft.network.NetHandlerPlayServer$2", + "net.minecraft.network.NetworkSystem$3", + "net.minecraft.tileentity.TileEntity$1", + "net.minecraft.tileentity.TileEntity$2", + "net.minecraft.tileentity.TileEntity$3", + "net.minecraft.world.storage.WorldInfo$1", + "net.minecraft.world.storage.WorldInfo$2", + "net.minecraft.world.storage.WorldInfo$3", + "net.minecraft.world.storage.WorldInfo$4", + "net.minecraft.world.storage.WorldInfo$5", + "net.minecraft.world.storage.WorldInfo$6", + "net.minecraft.world.storage.WorldInfo$7", + "net.minecraft.world.storage.WorldInfo$8", + "net.minecraft.world.storage.WorldInfo$9" + }; + String[] client = { + "net.minecraft.client.Minecraft$3", + "net.minecraft.client.Minecraft$4", + "net.minecraft.client.Minecraft$5", + "net.minecraft.client.Minecraft$6", + "net.minecraft.client.Minecraft$7", + "net.minecraft.client.Minecraft$8", + "net.minecraft.client.Minecraft$9", + "net.minecraft.client.Minecraft$10", + "net.minecraft.client.Minecraft$11", + "net.minecraft.client.Minecraft$12", + "net.minecraft.client.Minecraft$13", + "net.minecraft.client.Minecraft$14", + "net.minecraft.client.Minecraft$15", + "net.minecraft.client.multiplayer.WorldClient$1", + "net.minecraft.client.multiplayer.WorldClient$2", + "net.minecraft.client.multiplayer.WorldClient$3", + "net.minecraft.client.multiplayer.WorldClient$4", + "net.minecraft.client.particle,EffectRenderer$1", + "net.minecraft.client.particle,EffectRenderer$2", + "net.minecraft.client.particle,EffectRenderer$3", + "net.minecraft.client.particle,EffectRenderer$4", + "net.minecraft.client.renderer.EntityRenderer$1", + "net.minecraft.client.renderer.EntityRenderer$2", + "net.minecraft.client.renderer.EntityRenderer$3", + "net.minecraft.server.integrated.IntegratedServer$1", + "net.minecraft.server.integrated.IntegratedServer$2", + "net.minecraft.client.renderer.RenderGlobal$1", + "net.minecraft.client.renderer.entity.RenderItem$1", + "net.minecraft.client.renderer.entity.RenderItem$2", + "net.minecraft.client.renderer.entity.RenderItem$3", + "net.minecraft.client.renderer.entity.RenderItem$4", + "net.minecraft.client.renderer.texture.TextureAtlasSprite$1", + "net.minecraft.client.renderer.texture.TextureManager$1", + "net.minecraft.client.renderer.texture.TextureMap$1", + "net.minecraft.client.renderer.texture.TextureMap$2", + "net.minecraft.client.renderer.texture.TextureMap$3" + }; + String[] server = { + "net.minecraft.server.dedicated.DedicatedServer$3", + "net.minecraft.server.dedicated.DedicatedServer$4" + }; + if (FMLCommonHandler.instance().getSide() == Side.CLIENT) + handlers = ObjectArrays.concat(handlers, client, String.class); + else + handlers = ObjectArrays.concat(handlers, server, String.class); + + FMLLog.info("Preloading CrashReport classes", ForgeVersion.getVersion()); + for (String s : handlers) + { + FMLLog.info("\t" + s); + try + { + Class cls = Class.forName(s, false, MinecraftForge.class.getClassLoader()); + if (cls != null && !Callable.class.isAssignableFrom(cls)) + { + FMLLog.info("\t% s is not a instance of callable!", s); + } + } + catch (Exception e){} + } + UsernameCache.load(); } + + public static String getBrandingVersion() { return "Minecraft Forge "+ ForgeVersion.getVersion(); diff --git a/src/main/java/net/minecraftforge/common/network/ForgeMessage.java b/src/main/java/net/minecraftforge/common/network/ForgeMessage.java index 72f44d79e8..17f6ff0c42 100644 --- a/src/main/java/net/minecraftforge/common/network/ForgeMessage.java +++ b/src/main/java/net/minecraftforge/common/network/ForgeMessage.java @@ -1,12 +1,10 @@ package net.minecraftforge.common.network; import java.util.Map; - +import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidRegistry; - import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; - import cpw.mods.fml.common.network.ByteBufUtils; import io.netty.buffer.ByteBuf; @@ -16,14 +14,14 @@ public abstract class ForgeMessage { int dimensionId; /** The provider ID to register with dimension on client */ int providerId; - + public DimensionRegisterMessage(){} public DimensionRegisterMessage(int dimensionId, int providerId) { this.dimensionId = dimensionId; this.providerId = providerId; } - + @Override void toBytes(ByteBuf bytes) { @@ -40,15 +38,15 @@ public abstract class ForgeMessage { } public static class FluidIdMapMessage extends ForgeMessage { - BiMap fluidIds = HashBiMap.create(); + BiMap fluidIds = HashBiMap.create(); @Override void toBytes(ByteBuf bytes) { - Map ids = FluidRegistry.getRegisteredFluidIDs(); + Map ids = FluidRegistry.getRegisteredFluidIDsByFluid(); bytes.writeInt(ids.size()); - for (Map.Entry entry : ids.entrySet()) + for (Map.Entry entry : ids.entrySet()) { - ByteBufUtils.writeUTF8String(bytes,entry.getKey()); + ByteBufUtils.writeUTF8String(bytes,entry.getKey().getName()); bytes.writeInt(entry.getValue()); } } @@ -60,7 +58,7 @@ public abstract class ForgeMessage { for (int i = 0; i < listSize; i++) { String fluidName = ByteBufUtils.readUTF8String(bytes); int fluidId = bytes.readInt(); - fluidIds.put(fluidName, fluidId); + fluidIds.put(FluidRegistry.getFluid(fluidName), fluidId); } } } diff --git a/src/main/java/net/minecraftforge/fluids/BlockFluidBase.java b/src/main/java/net/minecraftforge/fluids/BlockFluidBase.java index 014fec0411..7e36157b23 100644 --- a/src/main/java/net/minecraftforge/fluids/BlockFluidBase.java +++ b/src/main/java/net/minecraftforge/fluids/BlockFluidBase.java @@ -42,7 +42,7 @@ public abstract class BlockFluidBase extends Block implements IFluidBlock protected float quantaPerBlockFloat = 8F; protected int density = 1; protected int densityDir = -1; - protected int temperature = 295; + protected int temperature = 300; protected int tickRate = 20; protected int renderPass = 1; @@ -135,18 +135,18 @@ public abstract class BlockFluidBase extends Block implements IFluidBlock } int density = getDensity(world, x, y, z); - if (density == Integer.MAX_VALUE) + if (density == Integer.MAX_VALUE) { - return true; + return true; } - + if (this.density > density) { - return true; + return true; } else { - return false; + return false; } } @@ -183,19 +183,19 @@ public abstract class BlockFluidBase extends Block implements IFluidBlock } int density = getDensity(world, x, y, z); - if (density == Integer.MAX_VALUE) + if (density == Integer.MAX_VALUE) { - block.dropBlockAsItem(world, x, y, z, world.getBlockMetadata(x, y, z), 0); - return true; + block.dropBlockAsItem(world, x, y, z, world.getBlockMetadata(x, y, z), 0); + return true; } - + if (this.density > density) { - return true; + return true; } else { - return false; + return false; } } @@ -226,6 +226,12 @@ public abstract class BlockFluidBase extends Block implements IFluidBlock return false; } + @Override + public boolean canPlaceBlockAt(World world, int x, int y, int z) + { + return canDisplace(world, x, y, z); + } + @Override public boolean getBlocksMovement(IBlockAccess world, int x, int y, int z) { @@ -303,7 +309,7 @@ public abstract class BlockFluidBase extends Block implements IFluidBlock float lightUp = world.getLightBrightness(x, y + 1, z); return lightThis > lightUp ? lightThis : lightUp; } - */ + */ @Override public int getMixedBrightnessForBlock(IBlockAccess world, int x, int y, int z) @@ -315,7 +321,7 @@ public abstract class BlockFluidBase extends Block implements IFluidBlock int lightThisExt = lightThis >> 16 & 255; int lightUpExt = lightUp >> 16 & 255; return (lightThisBase > lightUpBase ? lightThisBase : lightUpBase) | - ((lightThisExt > lightUpExt ? lightThisExt : lightUpExt) << 16); + ((lightThisExt > lightUpExt ? lightThisExt : lightUpExt) << 16); } @Override @@ -345,7 +351,7 @@ public abstract class BlockFluidBase extends Block implements IFluidBlock } return ((BlockFluidBase)block).density; } - + public static final int getTemperature(IBlockAccess world, int x, int y, int z) { Block block = world.getBlock(x, y, z); @@ -405,10 +411,10 @@ public abstract class BlockFluidBase extends Block implements IFluidBlock switch (side) { - case 0: --x2; break; - case 1: --z2; break; - case 2: ++x2; break; - case 3: ++z2; break; + case 0: --x2; break; + case 1: --z2; break; + case 2: ++x2; break; + case 3: ++z2; break; } int otherDecay = quantaPerBlock - getQuantaValue(world, x2, y, z2); @@ -434,14 +440,14 @@ public abstract class BlockFluidBase extends Block implements IFluidBlock if (world.getBlock(x, y + 1, z) == this) { boolean flag = - isBlockSolid(world, x, y, z - 1, 2) || - isBlockSolid(world, x, y, z + 1, 3) || - isBlockSolid(world, x - 1, y, z, 4) || - isBlockSolid(world, x + 1, y, z, 5) || - isBlockSolid(world, x, y + 1, z - 1, 2) || - isBlockSolid(world, x, y + 1, z + 1, 3) || - isBlockSolid(world, x - 1, y + 1, z, 4) || - isBlockSolid(world, x + 1, y + 1, z, 5); + isBlockSolid(world, x, y, z - 1, 2) || + isBlockSolid(world, x, y, z + 1, 3) || + isBlockSolid(world, x - 1, y, z, 4) || + isBlockSolid(world, x + 1, y, z, 5) || + isBlockSolid(world, x, y + 1, z - 1, 2) || + isBlockSolid(world, x, y + 1, z + 1, 3) || + isBlockSolid(world, x - 1, y + 1, z, 4) || + isBlockSolid(world, x + 1, y + 1, z, 5); if (flag) { diff --git a/src/main/java/net/minecraftforge/fluids/Fluid.java b/src/main/java/net/minecraftforge/fluids/Fluid.java index 8ef8b9b59d..fed6e88664 100644 --- a/src/main/java/net/minecraftforge/fluids/Fluid.java +++ b/src/main/java/net/minecraftforge/fluids/Fluid.java @@ -62,16 +62,20 @@ public class Fluid /** * Temperature of the fluid - completely arbitrary; higher temperature indicates that the fluid is * hotter than air. - * + * * Default value is approximately the real-life room temperature of water in degrees Kelvin. */ - protected int temperature = 295; + protected int temperature = 300; /** * Viscosity ("thickness") of the fluid - completely arbitrary; negative values are not * permissible. * * Default value is approximately the real-life density of water in m/s^2 (x10^-3). + * + * Higher viscosity means that a fluid flows more slowly, like molasses. + * Lower viscosity means that a fluid flows more quickly, like helium. + * */ protected int viscosity = 1000; @@ -116,17 +120,10 @@ public class Fluid { this.block = block; } - else if (!ForgeModContainer.forceDuplicateFluidBlockCrash) - { - FMLLog.warning("A mod has attempted to assign Block " + block + " to the Fluid '" + fluidName + "' but this Fluid has already been linked to BlockID " - + this.block + ". Configure your mods to prevent this from happening."); - } else { - FMLLog.severe("A mod has attempted to assign BlockID " + block + " to the Fluid '" + fluidName + "' but this Fluid has already been linked to BlockID " - + this.block + ". Configure your mods to prevent this from happening."); - throw new LoaderException(new RuntimeException("A mod has attempted to assign BlockID " + block + " to the Fluid '" + fluidName - + "' but this Fluid has already been linked to BlockID " + this.block + ". Configure your mods to prevent this from happening.")); + FMLLog.warning("A mod has attempted to assign Block " + block + " to the Fluid '" + fluidName + "' but this Fluid has already been linked to the Block " + + this.block + ". You may have duplicate Fluid Blocks as a result. It *may* be possible to configure your mods to avoid this."); } return this; } @@ -194,7 +191,7 @@ public class Fluid { return getLocalizedName(); } - + /** * Use the FluidStack sensitive version above */ @@ -254,7 +251,7 @@ public class Fluid { return this.isGaseous; } - + public EnumRarity getRarity() { return rarity; @@ -318,19 +315,4 @@ public class Fluid public int getColor(World world, int x, int y, int z){ return getColor(); } public IIcon getIcon(World world, int x, int y, int z){ return getIcon(); } - private static Map legacyNames = Maps.newHashMap(); - static String convertLegacyName(String fluidName) - { - return fluidName != null && legacyNames.containsKey(fluidName) ? legacyNames.get(fluidName) : fluidName; - } - - /** - * Register a legacy liquid name with the Fluids system - * @param legacyName The legacy name to recognize - * @param canonicalName The canonical fluid name it will become - */ - public static void registerLegacyName(String legacyName, String canonicalName) - { - legacyNames.put(legacyName.toLowerCase(Locale.ENGLISH), canonicalName); - } } diff --git a/src/main/java/net/minecraftforge/fluids/FluidContainerRegistry.java b/src/main/java/net/minecraftforge/fluids/FluidContainerRegistry.java index 043267c186..33c47f24e7 100644 --- a/src/main/java/net/minecraftforge/fluids/FluidContainerRegistry.java +++ b/src/main/java/net/minecraftforge/fluids/FluidContainerRegistry.java @@ -20,29 +20,29 @@ import net.minecraftforge.common.MinecraftForge; /** * Register simple items that contain fluids here. Useful for buckets, bottles, and things that have * ID/metadata mappings. - * + * * For more complex items, use {@link IFluidContainerItem} instead. - * + * * @author King Lemming - * + * */ public abstract class FluidContainerRegistry { - // Holder object that implements HashCode for an ItemStack, - // the local maps are not guaranteed to have the same internal generic structure, + // Holder object that implements HashCode for an ItemStack, + // the local maps are not guaranteed to have the same internal generic structure, // but the external interface for checking ItemStacks will still exist. private static class ContainerKey { ItemStack container; - FluidStack fluid; + FluidStack stack; private ContainerKey(ItemStack container) { this.container = container; } - private ContainerKey(ItemStack container, FluidStack fluid) + private ContainerKey(ItemStack container, FluidStack stack) { this(container); - this.fluid = fluid; + this.stack = stack; } @Override public int hashCode() @@ -50,8 +50,8 @@ public abstract class FluidContainerRegistry int code = 1; code = 31*code + container.getItem().hashCode(); code = 31*code + container.getItemDamage(); - if (fluid != null) - code = 31*code + fluid.fluidID; + if (stack != null) + code = 31*code + stack.hashCode(); return code; } @Override @@ -61,10 +61,10 @@ public abstract class FluidContainerRegistry ContainerKey ck = (ContainerKey)o; if (container.getItem() != ck.container.getItem()) return false; if (container.getItemDamage() != ck.container.getItemDamage()) return false; - if (fluid == null && ck.fluid != null) return false; - if (fluid != null && ck.fluid == null) return false; - if (fluid == null && ck.fluid == null) return true; - if (fluid.fluidID != ck.fluid.fluidID) return false; + if (stack == null && ck.stack != null) return false; + if (stack != null && ck.stack == null) return false; + if (stack == null && ck.stack == null) return true; + if (stack.fluid != ck.stack.fluid) return false; return true; } } @@ -89,7 +89,7 @@ public abstract class FluidContainerRegistry /** * Register a new fluid containing item. - * + * * @param stack * FluidStack containing the type and amount of the fluid stored in the item. * @param filledContainer @@ -106,7 +106,7 @@ public abstract class FluidContainerRegistry /** * Register a new fluid containing item. The item is assumed to hold 1000 mB of fluid. Also * registers the Fluid if possible. - * + * * @param fluid * Fluid type that is stored in the item. * @param filledContainer @@ -126,7 +126,7 @@ public abstract class FluidContainerRegistry /** * Register a new fluid containing item that does not have an empty container. - * + * * @param stack * FluidStack containing the type and amount of the fluid stored in the item. * @param filledContainer @@ -141,7 +141,7 @@ public abstract class FluidContainerRegistry /** * Register a new fluid containing item that does not have an empty container. The item is * assumed to hold 1000 mB of fluid. Also registers the Fluid if possible. - * + * * @param fluid * Fluid type that is stored in the item. * @param filledContainer @@ -159,7 +159,7 @@ public abstract class FluidContainerRegistry /** * Register a new fluid containing item. - * + * * @param data * See {@link FluidContainerData}. * @return True if container was successfully registered; false if it already is. @@ -184,7 +184,7 @@ public abstract class FluidContainerRegistry /** * Determines the fluid type and amount inside a container. - * + * * @param container * The fluid container. * @return FluidStack representing stored fluid. @@ -202,9 +202,9 @@ public abstract class FluidContainerRegistry /** * Attempts to fill an empty container with a fluid. - * + * * NOTE: Returns null on fail, NOT the empty container. - * + * * @param fluid * FluidStack containing the type and amount of fluid to fill. * @param container @@ -228,7 +228,7 @@ public abstract class FluidContainerRegistry /** * Attempts to empty a full container. - * + * * @param container * ItemStack representing the full container. * @return Empty container if successful, otherwise null. @@ -251,7 +251,7 @@ public abstract class FluidContainerRegistry /** * Determines the capacity of a full container. - * + * * @param container * The full container. * @return The containers capacity, or 0 if the ItemStack does not represent @@ -264,7 +264,7 @@ public abstract class FluidContainerRegistry /** * Determines the capacity of a container. - * + * * @param fluid * FluidStack containing the type of fluid the capacity should be * determined for (ignored for full containers). @@ -361,7 +361,6 @@ public abstract class FluidContainerRegistry public final ItemStack filledContainer; public final ItemStack emptyContainer; - public FluidContainerData(FluidStack stack, ItemStack filledContainer, ItemStack emptyContainer) { this(stack, filledContainer, emptyContainer, false); diff --git a/src/main/java/net/minecraftforge/fluids/FluidRegistry.java b/src/main/java/net/minecraftforge/fluids/FluidRegistry.java index 4fb50d12f2..cd9ef92921 100644 --- a/src/main/java/net/minecraftforge/fluids/FluidRegistry.java +++ b/src/main/java/net/minecraftforge/fluids/FluidRegistry.java @@ -2,6 +2,7 @@ package net.minecraftforge.fluids; import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; import net.minecraft.block.Block; import net.minecraft.init.Blocks; @@ -13,6 +14,7 @@ import com.google.common.collect.HashBiMap; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; +import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.common.eventhandler.Event; /** @@ -25,17 +27,18 @@ public abstract class FluidRegistry { static int maxID = 0; - static HashMap fluids = Maps.newHashMap(); - static BiMap fluidIDs = HashBiMap.create(); + static BiMap fluids = HashBiMap.create(); + static BiMap fluidIDs = HashBiMap.create(); + static BiMap fluidNames = HashBiMap.create(); //Caching this just makes some other calls faster static BiMap fluidBlocks; - + public static final Fluid WATER = new Fluid("water") { @Override public String getLocalizedName() { return StatCollector.translateToLocal("tile.water.name"); } }.setBlock(Blocks.water).setUnlocalizedName(Blocks.water.getUnlocalizedName()); - + public static final Fluid LAVA = new Fluid("lava") { @Override public String getLocalizedName() { @@ -57,11 +60,14 @@ public abstract class FluidRegistry * Called by Forge to prepare the ID map for server -> client sync. * Modders, DO NOT call this. */ - public static void initFluidIDs(BiMap newfluidIDs) + public static void initFluidIDs(BiMap newfluidIDs) { maxID = newfluidIDs.size(); fluidIDs.clear(); fluidIDs.putAll(newfluidIDs); + fluidNames.clear(); + for (Entry e : fluidIDs.entrySet()) + fluidNames.put(e.getValue(), e.getKey().getName()); } /** @@ -73,12 +79,14 @@ public abstract class FluidRegistry */ public static boolean registerFluid(Fluid fluid) { - if (fluidIDs.containsKey(fluid.getName())) + if (fluids.containsKey(fluid.getName())) { + FMLLog.bigWarning("Duplicate registration attempt for fluid %s (type %s) has occurred. This is not a problem itself, but subsequent failed FluidStacks might be a result if not handled properly", fluid.getName(), fluid.getClass().getName()); return false; } fluids.put(fluid.getName(), fluid); - fluidIDs.put(fluid.getName(), ++maxID); + fluidIDs.put(fluid, ++maxID); + fluidNames.put(maxID, fluid.getName()); MinecraftForge.EVENT_BUS.post(new FluidRegisterEvent(fluid.getName(), maxID)); return true; @@ -86,12 +94,12 @@ public abstract class FluidRegistry public static boolean isFluidRegistered(Fluid fluid) { - return fluidIDs.containsKey(fluid.getName()); + return fluids.containsKey(fluid.getName()); } public static boolean isFluidRegistered(String fluidName) { - return fluidIDs.containsKey(fluidName); + return fluids.containsKey(fluidName); } public static Fluid getFluid(String fluidName) @@ -101,31 +109,42 @@ public abstract class FluidRegistry public static Fluid getFluid(int fluidID) { - return fluids.get(getFluidName(fluidID)); + return fluidIDs.inverse().get(fluidID); } - public static String getFluidName(int fluidID) + public static int getFluidID(Fluid fluid) { - return fluidIDs.inverse().get(fluidID); - } - - public static String getFluidName(FluidStack stack) - { - return getFluidName(stack.fluidID); + return fluidIDs.get(fluid); } public static int getFluidID(String fluidName) { - return fluidIDs.get(fluidName); + return fluidIDs.get(getFluid(fluidName)); + } + + @Deprecated //Remove in 1.8.3 + public static String getFluidName(int fluidID) + { + return fluidNames.get(fluidID); + } + + public static String getFluidName(Fluid fluid) + { + return fluids.inverse().get(fluid); + } + + public static String getFluidName(FluidStack stack) + { + return getFluidName(stack.fluid); } public static FluidStack getFluidStack(String fluidName, int amount) { - if (!fluidIDs.containsKey(fluidName)) + if (!fluids.containsKey(fluidName)) { return null; } - return new FluidStack(getFluidID(fluidName), amount); + return new FluidStack(getFluid(fluidName), amount); } /** @@ -139,7 +158,17 @@ public abstract class FluidRegistry /** * Returns a read-only map containing Fluid Names and their associated IDs. */ + @Deprecated //Change return type to in 1.8.3 public static Map getRegisteredFluidIDs() + { + return ImmutableMap.copyOf(fluidNames.inverse()); + } + + /** + * Returns a read-only map containing Fluid IDs and their associated Fluids. + * In 1.8.3, this will change to just 'getRegisteredFluidIDs' + */ + public static Map getRegisteredFluidIDsByFluid() { return ImmutableMap.copyOf(fluidIDs); } @@ -160,7 +189,7 @@ public abstract class FluidRegistry } return fluidBlocks.get(block); } - + public static class FluidRegisterEvent extends Event { public final String fluidName; diff --git a/src/main/java/net/minecraftforge/fluids/FluidStack.java b/src/main/java/net/minecraftforge/fluids/FluidStack.java index 4de7a2609e..b485170e92 100644 --- a/src/main/java/net/minecraftforge/fluids/FluidStack.java +++ b/src/main/java/net/minecraftforge/fluids/FluidStack.java @@ -2,7 +2,10 @@ package net.minecraftforge.fluids; import java.util.Locale; + import com.google.common.base.Strings; + +import cpw.mods.fml.common.FMLLog; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -18,25 +21,24 @@ import net.minecraft.nbt.NBTTagCompound; */ public class FluidStack { - public int fluidID; + public final Fluid fluid; public int amount; public NBTTagCompound tag; public FluidStack(Fluid fluid, int amount) { - this.fluidID = fluid.getID(); + if (!FluidRegistry.isFluidRegistered(fluid)) + { + FMLLog.bigWarning("Failed attempt to create a FluidStack for an unregistered Fluid %s (type %s)", fluid.getName(), fluid.getClass().getName()); + throw new IllegalArgumentException("Cannot create a fluidstack from an unregistered fluid"); + } + this.fluid = fluid; this.amount = amount; } - public FluidStack(int fluidID, int amount) + public FluidStack(Fluid fluid, int amount, NBTTagCompound nbt) { - this.fluidID = fluidID; - this.amount = amount; - } - - public FluidStack(int fluidID, int amount, NBTTagCompound nbt) - { - this(fluidID, amount); + this(fluid, amount); if (nbt != null) { @@ -46,7 +48,21 @@ public class FluidStack public FluidStack(FluidStack stack, int amount) { - this(stack.fluidID, amount, stack.tag); + this(stack.fluid, amount, stack.tag); + } + + // To be removed in 1.8 + @Deprecated + public FluidStack(int fluidID, int amount) + { + this(FluidRegistry.getFluid(fluidID), amount); + } + + // To be removed in 1.8 + @Deprecated + public FluidStack(int fluidID, int amount, NBTTagCompound nbt) + { + this(FluidRegistry.getFluid(fluidID), amount, nbt); } /** @@ -60,32 +76,23 @@ public class FluidStack return null; } String fluidName = nbt.getString("FluidName"); - if (Strings.isNullOrEmpty(fluidName)) - { - fluidName = nbt.hasKey("LiquidName") ? nbt.getString("LiquidName").toLowerCase(Locale.ENGLISH) : null; - fluidName = Fluid.convertLegacyName(fluidName); - } - if (fluidName ==null || FluidRegistry.getFluid(fluidName) == null) + if (fluidName == null || FluidRegistry.getFluid(fluidName) == null) { return null; } - FluidStack stack = new FluidStack(FluidRegistry.getFluidID(fluidName), nbt.getInteger("Amount")); + FluidStack stack = new FluidStack(FluidRegistry.getFluid(fluidName), nbt.getInteger("Amount")); if (nbt.hasKey("Tag")) { stack.tag = nbt.getCompoundTag("Tag"); } - else if (nbt.hasKey("extra")) - { - stack.tag = nbt.getCompoundTag("extra"); - } return stack; } public NBTTagCompound writeToNBT(NBTTagCompound nbt) { - nbt.setString("FluidName", FluidRegistry.getFluidName(fluidID)); + nbt.setString("FluidName", FluidRegistry.getFluidName(fluid)); nbt.setInteger("Amount", amount); if (tag != null) @@ -97,7 +104,12 @@ public class FluidStack public final Fluid getFluid() { - return FluidRegistry.getFluid(fluidID); + return fluid; + } + + public final int getFluidID() + { + return FluidRegistry.getFluidID(fluid); } public String getLocalizedName() @@ -115,7 +127,7 @@ public class FluidStack */ public FluidStack copy() { - return new FluidStack(fluidID, amount, tag); + return new FluidStack(fluid, amount, tag); } /** @@ -127,7 +139,7 @@ public class FluidStack */ public boolean isFluidEqual(FluidStack other) { - return other != null && fluidID == other.fluidID && isFluidStackTagEqual(other); + return other != null && fluid == other.fluid && isFluidStackTagEqual(other); } private boolean isFluidStackTagEqual(FluidStack other) @@ -192,7 +204,12 @@ public class FluidStack @Override public final int hashCode() { - return fluidID; + int code = 1; + code = 31*code + fluid.hashCode(); + code = 31*code + amount; + if (tag != null) + code = 31*code + tag.hashCode(); + return code; } /**