diff --git a/build.sh b/build.sh deleted file mode 100755 index d57ac6949..000000000 --- a/build.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -python build.py "$@" diff --git a/client/net/minecraftforge/client/ForgeHooksClient.java b/client/net/minecraftforge/client/ForgeHooksClient.java index 203f38455..1b01330b4 100644 --- a/client/net/minecraftforge/client/ForgeHooksClient.java +++ b/client/net/minecraftforge/client/ForgeHooksClient.java @@ -24,6 +24,7 @@ import net.minecraft.client.renderer.RenderBlocks; import net.minecraft.client.renderer.RenderEngine; import net.minecraft.client.renderer.RenderGlobal; import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.entity.RenderItem; import net.minecraftforge.client.event.DrawBlockHighlightEvent; import net.minecraftforge.client.event.RenderWorldLastEvent; import net.minecraftforge.client.event.TextureLoadEvent; @@ -234,6 +235,13 @@ public class ForgeHooksClient int renderType = Block.blocksList[item.itemID].getRenderType(); float scale = (renderType == 1 || renderType == 19 || renderType == 12 || renderType == 2 ? 0.5F : 0.25F); + if (RenderItem.field_82407_g) + { + GL11.glScalef(1.25F, 1.25F, 1.25F); + GL11.glTranslatef(0.0F, 0.05F, 0.0F); + GL11.glRotatef(-90.0F, 0.0F, 1.0F, 0.0F); + } + GL11.glScalef(scale, scale, scale); int size = item.stackSize; @@ -397,4 +405,9 @@ public class ForgeHooksClient } } } + + public static void setRenderPass(int pass) + { + renderPass = pass; + } } diff --git a/common/net/minecraftforge/common/Configuration.java b/common/net/minecraftforge/common/Configuration.java index 70a651d75..b3911a8ca 100644 --- a/common/net/minecraftforge/common/Configuration.java +++ b/common/net/minecraftforge/common/Configuration.java @@ -440,6 +440,7 @@ public class Configuration } BufferedReader buffer = null; + UnicodeInputStreamReader input = null; try { if (file.getParentFile() != null) @@ -454,7 +455,7 @@ public class Configuration if (file.canRead()) { - UnicodeInputStreamReader input = new UnicodeInputStreamReader(new FileInputStream(file), defaultEncoding); + input = new UnicodeInputStreamReader(new FileInputStream(file), defaultEncoding); defaultEncoding = input.getEncoding(); buffer = new BufferedReader(input); @@ -638,6 +639,13 @@ public class Configuration buffer.close(); } catch (IOException e){} } + if (input != null) + { + try + { + input.close(); + } catch (IOException e){} + } } } @@ -666,8 +674,7 @@ public class Configuration FileOutputStream fos = new FileOutputStream(file); BufferedWriter buffer = new BufferedWriter(new OutputStreamWriter(fos, defaultEncoding)); - buffer.write("# Configuration file" + NEW_LINE); - buffer.write("# Generated on " + DateFormat.getInstance().format(new Date()) + NEW_LINE + NEW_LINE); + buffer.write("# Configuration file" + NEW_LINE + NEW_LINE); if (children.isEmpty()) { diff --git a/common/net/minecraftforge/common/DimensionManager.java b/common/net/minecraftforge/common/DimensionManager.java index 8cf50502d..14e4f062c 100644 --- a/common/net/minecraftforge/common/DimensionManager.java +++ b/common/net/minecraftforge/common/DimensionManager.java @@ -2,16 +2,25 @@ package net.minecraftforge.common; import java.io.File; import java.util.ArrayList; +import java.util.Arrays; import java.util.BitSet; +import java.util.HashSet; import java.util.Hashtable; +import java.util.List; +import java.util.ListIterator; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.ConcurrentMap; import java.util.logging.Level; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ImmutableListMultimap; import com.google.common.collect.ListMultimap; +import com.google.common.collect.Lists; +import com.google.common.collect.MapMaker; import com.google.common.collect.Maps; +import com.google.common.collect.Sets; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.FMLLog; @@ -40,9 +49,10 @@ public class DimensionManager private static Hashtable worlds = new Hashtable(); private static boolean hasInit = false; private static Hashtable dimensions = new Hashtable(); - private static Map> persistentChunkStore = Maps.newHashMap(); //FIXME: Unused? private static ArrayList unloadQueue = new ArrayList(); private static BitSet dimensionMap = new BitSet(Long.SIZE << 4); + private static ConcurrentMap weakWorldMap = new MapMaker().weakKeys().weakValues().makeMap(); + private static Set leakedWorlds = Sets.newHashSet(); public static boolean registerProviderType(int id, Class provider, boolean keepLoaded) { @@ -55,6 +65,38 @@ public class DimensionManager return true; } + /** + * Unregisters a Provider type, and returns a array of all dimensions that are + * registered to this provider type. + * If the return size is greater then 0, it is required that the caller either + * change those dimensions's registered type, or replace this type before the + * world is attempted to load, else the loader will throw an exception. + * + * @param id The provider type ID to unreigster + * @return An array containing all dimension IDs still registered to this provider type. + */ + public static int[] unregisterProviderType(int id) + { + if (!providers.containsKey(id)) + { + return new int[0]; + } + providers.remove(id); + spawnSettings.remove(id); + + int[] ret = new int[dimensions.size()]; + int x = 0; + for (Map.Entry ent : dimensions.entrySet()) + { + if (ent.getValue() == id) + { + ret[x++] = ent.getKey(); + } + } + + return Arrays.copyOf(ret, x); + } + public static void init() { if (hasInit) @@ -115,6 +157,34 @@ public class DimensionManager return getWorld(dim).provider; } + public static Integer[] getIDs(boolean check) + { + if (check) + { + List allWorlds = Lists.newArrayList(weakWorldMap.keySet()); + allWorlds.removeAll(worlds.values()); + Set newLeaks = Sets.newHashSet(); + for (ListIterator li = allWorlds.listIterator(); li.hasNext(); ) + { + World w = li.next(); + if (leakedWorlds.contains(System.identityHashCode(w))) + { + li.remove(); + } + newLeaks.add(System.identityHashCode(w)); + } + leakedWorlds = newLeaks; + if (allWorlds.size() > 0) + { + FMLLog.severe("Detected leaking worlds in memory. There are %d worlds that appear to be persisting. A mod is likely caching the world incorrectly\n", allWorlds.size() + leakedWorlds.size()); + for (World w : allWorlds) + { + FMLLog.severe("The world %x (%s) has leaked.\n", System.identityHashCode(w), w.getWorldInfo().getWorldName()); + } + } + } + return getIDs(); + } public static Integer[] getIDs() { return worlds.keySet().toArray(new Integer[worlds.size()]); //Only loaded dims, since usually used to cycle through loaded worlds @@ -124,6 +194,7 @@ public class DimensionManager { if (world != null) { worlds.put(id, world); + weakWorldMap.put(world, world); MinecraftServer.getServer().worldTickTimes.put(id, new long[100]); FMLLog.info("Loading dimension %d (%s) (%s)", id, world.getWorldInfo().getWorldName(), world.getMinecraftServer()); } else { diff --git a/common/net/minecraftforge/common/DungeonHooks.java b/common/net/minecraftforge/common/DungeonHooks.java index bc1965aa2..09f6ff6db 100644 --- a/common/net/minecraftforge/common/DungeonHooks.java +++ b/common/net/minecraftforge/common/DungeonHooks.java @@ -3,6 +3,9 @@ package net.minecraftforge.common; import java.util.ArrayList; import java.util.Random; +import cpw.mods.fml.common.FMLLog; + +import net.minecraft.inventory.IInventory; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.WeightedRandom; @@ -148,12 +151,18 @@ public class DungeonHooks { int min = theMinimumChanceToGenerateItem; int max = theMaximumChanceToGenerateItem; - + ItemStack ret = this.theItemId.copy(); ret.stackSize = min + (rand.nextInt(max - min + 1)); return ret; } + @Override + protected final ItemStack[] generateChestContent(Random random, IInventory newInventory) + { + FMLLog.warning("Some mod is still using DungeonHooks.DungonLoot, tell them to stop! %s", this); + return new ItemStack[] { generateStack(random) }; + } public boolean equals(ItemStack item, int min, int max) { int minCount = theMinimumChanceToGenerateItem; diff --git a/common/net/minecraftforge/common/ForgeChunkManager.java b/common/net/minecraftforge/common/ForgeChunkManager.java index 4794f53b2..ae45c5a73 100644 --- a/common/net/minecraftforge/common/ForgeChunkManager.java +++ b/common/net/minecraftforge/common/ForgeChunkManager.java @@ -653,10 +653,13 @@ public class ForgeChunkManager int allowedCount = ticketConstraints.containsKey(modId) ? ticketConstraints.get(modId) : defaultMaxCount; - if (tickets.get(world).get(modId).size() >= allowedCount && !warnedMods.contains(modId)) + if (tickets.get(world).get(modId).size() >= allowedCount) { - FMLLog.info("The mod %s has attempted to allocate a chunkloading ticket beyond it's currently allocated maximum : %d", modId, allowedCount); - warnedMods.add(modId); + if (!warnedMods.contains(modId)) + { + FMLLog.info("The mod %s has attempted to allocate a chunkloading ticket beyond it's currently allocated maximum : %d", modId, allowedCount); + warnedMods.add(modId); + } return null; } Ticket ticket = new Ticket(modId, type, world); @@ -933,7 +936,7 @@ public class ForgeChunkManager Property dormantChunkCacheSizeProperty = config.get("defaults", "dormantChunkCacheSize", 0); dormantChunkCacheSizeProperty.comment = "Unloaded chunks can first be kept in a dormant cache for quicker\n" + - "loading times. Specify the size of that cache here"; + "loading times. Specify the size (in chunks) of that cache here"; dormantChunkCacheSize = dormantChunkCacheSizeProperty.getInt(0); FMLLog.info("Configured a dormant chunk cache size of %d", dormantChunkCacheSizeProperty.getInt(0)); diff --git a/common/net/minecraftforge/common/ForgeDummyContainer.java b/common/net/minecraftforge/common/ForgeDummyContainer.java index e3db4f8d5..8a3dffe0e 100644 --- a/common/net/minecraftforge/common/ForgeDummyContainer.java +++ b/common/net/minecraftforge/common/ForgeDummyContainer.java @@ -25,7 +25,7 @@ import static net.minecraftforge.common.ForgeVersion.*; public class ForgeDummyContainer extends DummyModContainer implements WorldAccessContainer { - public static int clumpingThreshold; + public static int clumpingThreshold = 64; public ForgeDummyContainer() { diff --git a/common/net/minecraftforge/common/MinecraftForge.java b/common/net/minecraftforge/common/MinecraftForge.java index 3af29f725..48a6d22fa 100644 --- a/common/net/minecraftforge/common/MinecraftForge.java +++ b/common/net/minecraftforge/common/MinecraftForge.java @@ -35,7 +35,6 @@ public class MinecraftForge public static final EventBus ORE_GEN_BUS = new EventBus(); @Deprecated //Vanilla feature now public static boolean SPAWNER_ALLOW_ON_INVERTED = false; - public static final int clumpingThreshold = ForgeDummyContainer.clumpingThreshold; private static final ForgeInternalHandler INTERNAL_HANDLER = new ForgeInternalHandler(); diff --git a/common/net/minecraftforge/event/ServerChatEvent.java b/common/net/minecraftforge/event/ServerChatEvent.java index b5a150fa0..0d7f6aaf7 100644 --- a/common/net/minecraftforge/event/ServerChatEvent.java +++ b/common/net/minecraftforge/event/ServerChatEvent.java @@ -3,7 +3,8 @@ package net.minecraftforge.event; import net.minecraft.entity.player.EntityPlayerMP; @Cancelable -public class ServerChatEvent extends Event { +public class ServerChatEvent extends Event +{ public final String message, username; public final EntityPlayerMP player; public String line; @@ -13,6 +14,6 @@ public class ServerChatEvent extends Event { this.message = message; this.player = player; this.username = player.username; - this.line = "<" + username + "> " + message; + this.line = line; } } diff --git a/common/net/minecraftforge/liquids/LiquidDictionary.java b/common/net/minecraftforge/liquids/LiquidDictionary.java index 9cf6835e5..8e300f076 100644 --- a/common/net/minecraftforge/liquids/LiquidDictionary.java +++ b/common/net/minecraftforge/liquids/LiquidDictionary.java @@ -3,10 +3,9 @@ package net.minecraftforge.liquids; import java.util.HashMap; import java.util.Map; -import net.minecraft.item.ItemStack; +import net.minecraft.block.Block; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.Event; -import net.minecraftforge.oredict.OreDictionary.OreRegisterEvent; import com.google.common.collect.ImmutableMap; @@ -87,4 +86,10 @@ public abstract class LiquidDictionary this.Liquid = liquid.copy(); } } + + static + { + getOrCreateLiquid("Water", new LiquidStack(Block.waterStill, LiquidContainerRegistry.BUCKET_VOLUME)); + getOrCreateLiquid("Lava", new LiquidStack(Block.lavaStill, LiquidContainerRegistry.BUCKET_VOLUME)); + } } diff --git a/common/net/minecraftforge/liquids/LiquidStack.java b/common/net/minecraftforge/liquids/LiquidStack.java index 50d0a76f6..345dfdf0d 100644 --- a/common/net/minecraftforge/liquids/LiquidStack.java +++ b/common/net/minecraftforge/liquids/LiquidStack.java @@ -75,7 +75,17 @@ public class LiquidStack */ public boolean isLiquidEqual(ItemStack other) { - return other != null && itemID == other.itemID && itemMeta == other.getItemDamage(); + if (other == null) + { + return false; + } + + if (itemID == other.itemID && itemMeta == other.getItemDamage()) + { + return true; + } + + return isLiquidEqual(LiquidContainerRegistry.getLiquidForFilledItem(other)); } /** diff --git a/common/net/minecraftforge/oredict/OreDictionary.java b/common/net/minecraftforge/oredict/OreDictionary.java index 911a8ebe4..b3faa098d 100644 --- a/common/net/minecraftforge/oredict/OreDictionary.java +++ b/common/net/minecraftforge/oredict/OreDictionary.java @@ -184,15 +184,19 @@ public class OreDictionary */ public static int getOreID(ItemStack itemStack) { - if( itemStack == null ) - return -1; - - for(int oreID : oreStacks.keySet()) + if (itemStack == null) { - for(ItemStack target : oreStacks.get(oreID)) + return -1; + } + + for(Entry> ore : oreStacks.entrySet()) + { + for(ItemStack target : ore.getValue()) { if(itemStack.itemID == target.itemID && (target.getItemDamage() == -1 || itemStack.getItemDamage() == target.getItemDamage())) - return oreID; + { + return ore.getKey(); + } } } return -1; // didn't find it. diff --git a/common/net/minecraftforge/oredict/ShapedOreRecipe.java b/common/net/minecraftforge/oredict/ShapedOreRecipe.java index c3409309f..cdf86574f 100644 --- a/common/net/minecraftforge/oredict/ShapedOreRecipe.java +++ b/common/net/minecraftforge/oredict/ShapedOreRecipe.java @@ -251,4 +251,14 @@ public class ShapedOreRecipe implements IRecipe mirrored = mirror; return this; } + + /** + * Returns the input for this recipe, any mod accessing this value should never + * manipulate the values in this array as it will effect the recipe itself. + * @return The recipes input vales. + */ + public Object[] getInput() + { + return this.input; + } } diff --git a/common/net/minecraftforge/oredict/ShapelessOreRecipe.java b/common/net/minecraftforge/oredict/ShapelessOreRecipe.java index db3e605f0..18e3d8912 100644 --- a/common/net/minecraftforge/oredict/ShapelessOreRecipe.java +++ b/common/net/minecraftforge/oredict/ShapelessOreRecipe.java @@ -139,4 +139,14 @@ public class ShapelessOreRecipe implements IRecipe { return (target.itemID == input.itemID && (target.getItemDamage() == -1 || target.getItemDamage() == input.getItemDamage())); } + + /** + * Returns the input for this recipe, any mod accessing this value should never + * manipulate the values in this array as it will effect the recipe itself. + * @return The recipes input vales. + */ + public ArrayList getInput() + { + return this.input; + } } diff --git a/common/net/minecraftforge/transformers/EventTransformer.java b/common/net/minecraftforge/transformers/EventTransformer.java index ebe50087d..ae04b08e4 100644 --- a/common/net/minecraftforge/transformers/EventTransformer.java +++ b/common/net/minecraftforge/transformers/EventTransformer.java @@ -22,7 +22,7 @@ public class EventTransformer implements IClassTransformer @Override public byte[] transform(String name, byte[] bytes) { - if (name.equals("net.minecraftforge.event.Event") || name.startsWith("net.minecraft.") || name.indexOf('.') == -1) + if (bytes == null || name.equals("net.minecraftforge.event.Event") || name.startsWith("net.minecraft.") || name.indexOf('.') == -1) { return bytes; } diff --git a/patches/minecraft/net/minecraft/block/Block.java.patch b/patches/minecraft/net/minecraft/block/Block.java.patch index aaa441c04..456e7233a 100644 --- a/patches/minecraft/net/minecraft/block/Block.java.patch +++ b/patches/minecraft/net/minecraft/block/Block.java.patch @@ -150,7 +150,22 @@ { ItemStack itemstack = this.createStackedBlock(par6); -@@ -1398,4 +1418,846 @@ +@@ -1097,12 +1117,13 @@ + } + } + ++ private int silk_check_meta = -1; //Dirty hack to stop us from needing to special case the silk check hook. + /** + * Return true if a player with Silk Touch can harvest this block directly, and not its normal drops. + */ + protected boolean canSilkHarvest() + { +- return this.renderAsNormalBlock() && !this.isBlockContainer; ++ return this.renderAsNormalBlock() && !this.hasTileEntity(silk_check_meta); + } + + /** +@@ -1398,4 +1419,870 @@ canBlockGrass[0] = true; StatList.initBreakableStats(); } @@ -399,11 +414,11 @@ + { + if (blockID == Block.netherrack.blockID && side == UP) + { -+ return true; ++ return true; + } + if ((world.provider instanceof WorldProviderEnd) && blockID == Block.bedrock.blockID && side == UP) + { -+ return true; ++ return true; + } + return false; + } @@ -484,7 +499,7 @@ + int count = quantityDropped(metadata, fortune, world.rand); + for(int i = 0; i < count; i++) + { -+ int id = idDropped(metadata, world.rand, 0); ++ int id = idDropped(metadata, world.rand, fortune); + if (id > 0) + { + ret.add(new ItemStack(id, 1, damageDropped(metadata))); @@ -506,11 +521,10 @@ + */ + public boolean canSilkHarvest(World world, EntityPlayer player, int x, int y, int z, int metadata) + { -+ if (this instanceof BlockGlass || this instanceof BlockEnderChest) -+ { -+ return true; -+ } -+ return renderAsNormalBlock() && !hasTileEntity(metadata); ++ silk_check_meta = metadata; ++ boolean ret = this.canSilkHarvest(); ++ silk_check_meta = 0; ++ return ret; + } + + /** @@ -687,7 +701,7 @@ + * @param x X Position + * @param y Y Position + * @param z Z Position -+ * @param target The generic target block the gen is looking for, Standards define stone ++ * @param target The generic target block the gen is looking for, Standards define stone + * for overworld generation, and neatherack for the nether. + * @return True to allow this block to be replaced by a ore + */ @@ -926,6 +940,31 @@ + } + + /** ++ * Called when a plant grows on this block, only implemented for saplings using the WorldGen*Trees classes right now. ++ * Modder may implement this for custom plants. ++ * This does not use ForgeDirection, because large/huge trees can be located in non-representable direction, ++ * so the source location is specified. ++ * Currently this just changes the block to dirt if it was grass. ++ * ++ * Note: This happens DURING the generation, the generation may not be complete when this is called. ++ * ++ * @param world Current world ++ * @param x Soil X ++ * @param y Soil Y ++ * @param z Soil Z ++ * @param sourceX Plant growth location X ++ * @param sourceY Plant growth location Y ++ * @param sourceZ Plant growth location Z ++ */ ++ public void onPlantGrow(World world, int x, int y, int z, int sourceX, int sourceY, int sourceZ) ++ { ++ if (blockID == grass.blockID) ++ { ++ world.func_94575_c(x, y, z, dirt.blockID); ++ } ++ } ++ ++ /** + * Checks if this soil is fertile, typically this means that growth rates + * of plants on this soil will be slightly sped up. + * Only vanilla case is tilledField when it is within range of water. diff --git a/patches/minecraft/net/minecraft/client/renderer/OpenGlHelper.java.patch b/patches/minecraft/net/minecraft/client/renderer/OpenGlHelper.java.patch new file mode 100644 index 000000000..4cddf89ef --- /dev/null +++ b/patches/minecraft/net/minecraft/client/renderer/OpenGlHelper.java.patch @@ -0,0 +1,25 @@ +--- ../src_base/minecraft/net/minecraft/client/renderer/OpenGlHelper.java ++++ ../src_work/minecraft/net/minecraft/client/renderer/OpenGlHelper.java +@@ -25,6 +25,10 @@ + * True if the renderer supports multitextures and the OpenGL version != 1.3 + */ + private static boolean useMultitextureARB = false; ++ ++ /* Stores the last values sent into setLightmapTextureCoords */ ++ public static float lastBrightnessX = 0.0f; ++ public static float lastBrightnessY = 0.0f; + + /** + * Initializes the texture constants to be used when rendering lightmap values +@@ -88,5 +92,11 @@ + { + GL13.glMultiTexCoord2f(par0, par1, par2); + } ++ ++ if (par0 == lightmapTexUnit) ++ { ++ lastBrightnessX = par1; ++ lastBrightnessY = par2; ++ } + } + } diff --git a/patches/minecraft/net/minecraft/client/renderer/tileentity/TileEntityChestRenderer.java.patch b/patches/minecraft/net/minecraft/client/renderer/tileentity/TileEntityChestRenderer.java.patch new file mode 100644 index 000000000..e4ea6237b --- /dev/null +++ b/patches/minecraft/net/minecraft/client/renderer/tileentity/TileEntityChestRenderer.java.patch @@ -0,0 +1,26 @@ +--- ../src_base/minecraft/net/minecraft/client/renderer/tileentity/TileEntityChestRenderer.java ++++ ../src_work/minecraft/net/minecraft/client/renderer/tileentity/TileEntityChestRenderer.java +@@ -1,5 +1,6 @@ + package net.minecraft.client.renderer.tileentity; + ++import cpw.mods.fml.common.FMLLog; + import cpw.mods.fml.relauncher.Side; + import cpw.mods.fml.relauncher.SideOnly; + import java.util.Calendar; +@@ -50,7 +51,15 @@ + + if (block instanceof BlockChest && i == 0) + { +- ((BlockChest)block).unifyAdjacentChests(par1TileEntityChest.getWorldObj(), par1TileEntityChest.xCoord, par1TileEntityChest.yCoord, par1TileEntityChest.zCoord); ++ try ++ { ++ ((BlockChest)block).unifyAdjacentChests(par1TileEntityChest.getWorldObj(), par1TileEntityChest.xCoord, par1TileEntityChest.yCoord, par1TileEntityChest.zCoord); ++ } ++ catch (ClassCastException e) ++ { ++ FMLLog.severe("Attempted to render a chest at %d, %d, %d that was not a chest", ++ par1TileEntityChest.xCoord, par1TileEntityChest.yCoord, par1TileEntityChest.zCoord); ++ } + i = par1TileEntityChest.getBlockMetadata(); + } + diff --git a/patches/minecraft/net/minecraft/entity/player/EntityPlayer.java.patch b/patches/minecraft/net/minecraft/entity/player/EntityPlayer.java.patch index ce3fdf053..84a847569 100644 --- a/patches/minecraft/net/minecraft/entity/player/EntityPlayer.java.patch +++ b/patches/minecraft/net/minecraft/entity/player/EntityPlayer.java.patch @@ -350,3 +350,19 @@ } /** +@@ -2176,7 +2292,14 @@ + */ + public void setCurrentItemOrArmor(int par1, ItemStack par2ItemStack) + { +- this.inventory.armorInventory[par1] = par2ItemStack; ++ if (par1 == 0) ++ { ++ this.inventory.mainInventory[this.inventory.currentItem] = par2ItemStack; ++ } ++ else ++ { ++ this.inventory.armorInventory[par1 - 1] = par2ItemStack; ++ } + } + + public ItemStack[] getLastActiveItems() diff --git a/patches/minecraft/net/minecraft/entity/player/InventoryPlayer.java.patch b/patches/minecraft/net/minecraft/entity/player/InventoryPlayer.java.patch new file mode 100644 index 000000000..73de1c915 --- /dev/null +++ b/patches/minecraft/net/minecraft/entity/player/InventoryPlayer.java.patch @@ -0,0 +1,17 @@ +--- ../src_base/minecraft/net/minecraft/entity/player/InventoryPlayer.java ++++ ../src_work/minecraft/net/minecraft/entity/player/InventoryPlayer.java +@@ -337,6 +337,14 @@ + this.mainInventory[i].updateAnimation(this.player.worldObj, this.player, i, this.currentItem == i); + } + } ++ ++ for (int i = 0; i < this.armorInventory.length; i++) ++ { ++ if (this.armorInventory[i] != null) ++ { ++ this.armorInventory[i].getItem().onArmorTickUpdate(this.player.worldObj, this.player, this.armorInventory[i]); ++ } ++ } + } + + /** diff --git a/patches/minecraft/net/minecraft/inventory/SlotArmor.java.patch b/patches/minecraft/net/minecraft/inventory/SlotArmor.java.patch new file mode 100644 index 000000000..31aba7ffb --- /dev/null +++ b/patches/minecraft/net/minecraft/inventory/SlotArmor.java.patch @@ -0,0 +1,12 @@ +--- ../src_base/minecraft/net/minecraft/inventory/SlotArmor.java ++++ ../src_work/minecraft/net/minecraft/inventory/SlotArmor.java +@@ -41,7 +41,8 @@ + */ + public boolean isItemValid(ItemStack par1ItemStack) + { +- return par1ItemStack == null ? false : (par1ItemStack.getItem() instanceof ItemArmor ? ((ItemArmor)par1ItemStack.getItem()).armorType == this.armorType : (par1ItemStack.getItem().itemID != Block.pumpkin.blockID && par1ItemStack.getItem().itemID != Item.skull.itemID ? false : this.armorType == 0)); ++ Item item = (par1ItemStack == null ? null : par1ItemStack.getItem()); ++ return item != null && item.isValidArmor(par1ItemStack, armorType); + } + + @SideOnly(Side.CLIENT) diff --git a/patches/minecraft/net/minecraft/inventory/SlotBrewingStandIngredient.java.patch b/patches/minecraft/net/minecraft/inventory/SlotBrewingStandIngredient.java.patch new file mode 100644 index 000000000..83a474dd9 --- /dev/null +++ b/patches/minecraft/net/minecraft/inventory/SlotBrewingStandIngredient.java.patch @@ -0,0 +1,11 @@ +--- ../src_base/minecraft/net/minecraft/inventory/SlotBrewingStandIngredient.java ++++ ../src_work/minecraft/net/minecraft/inventory/SlotBrewingStandIngredient.java +@@ -19,7 +19,7 @@ + */ + public boolean isItemValid(ItemStack par1ItemStack) + { +- return par1ItemStack != null ? Item.itemsList[par1ItemStack.itemID].isPotionIngredient() : false; ++ return par1ItemStack != null ? Item.itemsList[par1ItemStack.itemID].isPotionIngredient(par1ItemStack) : false; + } + + /** diff --git a/patches/minecraft/net/minecraft/item/Item.java.patch b/patches/minecraft/net/minecraft/item/Item.java.patch index a14e837d0..9682bed50 100644 --- a/patches/minecraft/net/minecraft/item/Item.java.patch +++ b/patches/minecraft/net/minecraft/item/Item.java.patch @@ -47,7 +47,7 @@ Vec3 vec31 = vec3.addVector((double)f7 * d3, (double)f6 * d3, (double)f8 * d3); return par1World.rayTraceBlocks_do_do(vec3, vec31, par3, !par3); } -@@ -705,4 +715,266 @@ +@@ -705,4 +715,324 @@ { StatList.initStats(); } @@ -313,4 +313,62 @@ + { + return false; + } ++ ++ ++ /** ++ * Called to tick armor in the armor slot. Override to do something ++ * ++ * @param world ++ * @param player ++ * @param itemStack ++ */ ++ public void onArmorTickUpdate(World world, EntityPlayer player, ItemStack itemStack) ++ { ++ ++ } ++ ++ /** ++ * Determines if the specific ItemStack can be placed in the specified armor slot. ++ * ++ * @param stack The ItemStack ++ * @param armorType Armor slot ID: 0: Helmet, 1: Chest, 2: Legs, 3: Boots ++ * @return True if the given ItemStack can be inserted in the slot ++ */ ++ public boolean isValidArmor(ItemStack stack, int armorType) ++ { ++ if (this instanceof ItemArmor) ++ { ++ return ((ItemArmor)this).armorType == armorType; ++ } ++ ++ if (armorType == 0) ++ { ++ return itemID == Block.pumpkin.blockID || itemID == Item.skull.itemID; ++ } ++ ++ return false; ++ } ++ ++ /** ++ * ItemStack sensitive version of isPotionIngredient ++ * ++ * @param stack The item stack ++ * @return True if this stack can be used as a potion ingredient ++ */ ++ public boolean isPotionIngredient(ItemStack stack) ++ { ++ return isPotionIngredient(); ++ } ++ ++ /** ++ * ItemStack sensitive version of getPotionEffect ++ * ++ * @param stack The item stack ++ * @return A string containing the bit manipulation to apply the the potion. ++ */ ++ public String getPotionEffect(ItemStack stack) ++ { ++ return getPotionEffect(); ++ } ++ } diff --git a/patches/minecraft/net/minecraft/network/NetServerHandler.java.patch b/patches/minecraft/net/minecraft/network/NetServerHandler.java.patch index 6b608728e..8af2109ea 100644 --- a/patches/minecraft/net/minecraft/network/NetServerHandler.java.patch +++ b/patches/minecraft/net/minecraft/network/NetServerHandler.java.patch @@ -26,18 +26,31 @@ } this.mcServer.getConfigurationManager().serverUpdateMountedMovingPlayer(this.playerEntity); -@@ -327,6 +339,11 @@ - this.playerEntity.addExhaustion(0.2F); - } +@@ -307,9 +319,9 @@ + d4 = d1 - this.playerEntity.posX; + double d6 = d2 - this.playerEntity.posY; + double d7 = d3 - this.playerEntity.posZ; +- double d8 = Math.min(Math.abs(d4), Math.abs(this.playerEntity.motionX)); +- double d9 = Math.min(Math.abs(d6), Math.abs(this.playerEntity.motionY)); +- double d10 = Math.min(Math.abs(d7), Math.abs(this.playerEntity.motionZ)); ++ double d8 = Math.max(Math.abs(d4), Math.abs(this.playerEntity.motionX)); ++ double d9 = Math.max(Math.abs(d6), Math.abs(this.playerEntity.motionY)); ++ double d10 = Math.max(Math.abs(d7), Math.abs(this.playerEntity.motionZ)); + double d11 = d8 * d8 + d9 * d9 + d10 * d10; + if (d11 > 100.0D && (!this.mcServer.isSinglePlayer() || !this.mcServer.getServerOwner().equals(this.playerEntity.username))) +@@ -325,6 +337,11 @@ + if (this.playerEntity.onGround && !par1Packet10Flying.onGround && d6 > 0.0D) + { + this.playerEntity.addExhaustion(0.2F); ++ } ++ + if (!this.hasMoved) //Fixes "Moved Too Fast" kick when being teleported while moving + { + return; -+ } -+ + } + this.playerEntity.moveEntity(d4, d6, d7); - this.playerEntity.onGround = par1Packet10Flying.onGround; - this.playerEntity.addMovementStat(d4, d6, d7); @@ -349,10 +366,15 @@ logger.warning(this.playerEntity.username + " moved wrongly!"); } @@ -144,3 +157,12 @@ } } } +@@ -1233,7 +1274,7 @@ + } + } + } +- ++ + + @Override + diff --git a/patches/minecraft/net/minecraft/network/packet/Packet52MultiBlockChange.java.patch b/patches/minecraft/net/minecraft/network/packet/Packet52MultiBlockChange.java.patch index 75bd5217b..f41088123 100644 --- a/patches/minecraft/net/minecraft/network/packet/Packet52MultiBlockChange.java.patch +++ b/patches/minecraft/net/minecraft/network/packet/Packet52MultiBlockChange.java.patch @@ -1,19 +1,23 @@ --- ../src_base/minecraft/net/minecraft/network/packet/Packet52MultiBlockChange.java +++ ../src_work/minecraft/net/minecraft/network/packet/Packet52MultiBlockChange.java -@@ -6,6 +6,7 @@ +@@ -6,6 +6,8 @@ import java.io.IOException; import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; ++import net.minecraftforge.common.ForgeDummyContainer; +import net.minecraftforge.common.MinecraftForge; public class Packet52MultiBlockChange extends Packet { -@@ -38,7 +39,7 @@ +@@ -38,10 +40,8 @@ try { - if (par4 >= 64) -+ if (par4 >= MinecraftForge.clumpingThreshold) ++ if (par4 >= ForgeDummyContainer.clumpingThreshold) { - System.out.println("ChunkTilesUpdatePacket compress " + par4); - +- System.out.println("ChunkTilesUpdatePacket compress " + par4); +- + if (field_73449_e.length < l) + { + field_73449_e = new byte[l]; diff --git a/patches/minecraft/net/minecraft/server/MinecraftServer.java.patch b/patches/minecraft/net/minecraft/server/MinecraftServer.java.patch index 12bd0f609..661f95cf6 100644 --- a/patches/minecraft/net/minecraft/server/MinecraftServer.java.patch +++ b/patches/minecraft/net/minecraft/server/MinecraftServer.java.patch @@ -117,7 +117,7 @@ - for (i = 0; i < this.worldServers.length; ++i) - { -+ Integer[] ids = DimensionManager.getIDs(); ++ Integer[] ids = DimensionManager.getIDs(this.tickCounter % 200 == 0); + for (int x = 0; x < ids.length; x++) + { + int id = ids[x]; diff --git a/patches/minecraft/net/minecraft/server/management/PlayerInstance.java.patch b/patches/minecraft/net/minecraft/server/management/PlayerInstance.java.patch index f8b213dc0..de24ee48f 100644 --- a/patches/minecraft/net/minecraft/server/management/PlayerInstance.java.patch +++ b/patches/minecraft/net/minecraft/server/management/PlayerInstance.java.patch @@ -8,10 +8,11 @@ import java.util.List; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.network.packet.Packet; -@@ -10,9 +11,12 @@ +@@ -10,9 +11,13 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.world.ChunkCoordIntPair; ++import net.minecraftforge.common.ForgeDummyContainer; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.world.ChunkWatchEvent; + @@ -22,7 +23,7 @@ /** note: this is final */ private final ChunkCoordIntPair chunkLocation; -@@ -56,6 +60,8 @@ +@@ -56,6 +61,8 @@ this.playersInChunk.remove(par1EntityPlayerMP); par1EntityPlayerMP.loadedChunks.remove(this.chunkLocation); @@ -31,7 +32,7 @@ if (this.playersInChunk.isEmpty()) { long i = (long)this.chunkLocation.chunkXPos + 2147483647L | (long)this.chunkLocation.chunkZPos + 2147483647L << 32; -@@ -80,20 +86,21 @@ +@@ -80,20 +87,21 @@ this.field_73260_f |= 1 << (par2 >> 4); @@ -64,12 +65,12 @@ } public void sendToAllPlayersWatchingChunk(Packet par1Packet) -@@ -133,40 +140,26 @@ +@@ -133,40 +141,26 @@ { int l; - if (this.numberOfTilesToUpdate == 64) -+ if (this.numberOfTilesToUpdate >= MinecraftForge.clumpingThreshold) ++ if (this.numberOfTilesToUpdate >= ForgeDummyContainer.clumpingThreshold) { i = this.chunkLocation.chunkXPos * 16; j = this.chunkLocation.chunkZPos * 16; diff --git a/patches/minecraft/net/minecraft/tileentity/TileEntity.java.patch b/patches/minecraft/net/minecraft/tileentity/TileEntity.java.patch index 7020a9b5f..1f0c18984 100644 --- a/patches/minecraft/net/minecraft/tileentity/TileEntity.java.patch +++ b/patches/minecraft/net/minecraft/tileentity/TileEntity.java.patch @@ -1,20 +1,22 @@ --- ../src_base/minecraft/net/minecraft/tileentity/TileEntity.java +++ ../src_work/minecraft/net/minecraft/tileentity/TileEntity.java -@@ -11,7 +11,9 @@ +@@ -11,7 +11,10 @@ import net.minecraft.block.TileEntityRecordPlayer; import net.minecraft.crash.CrashReportCategory; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.INetworkManager; import net.minecraft.network.packet.Packet; +import net.minecraft.network.packet.Packet132TileEntityData; ++import net.minecraft.util.AxisAlignedBB; import net.minecraft.world.World; public class TileEntity -@@ -300,4 +302,52 @@ +@@ -300,4 +303,93 @@ addMapping(TileEntityDaylightDetector.class, "DLDetector"); addMapping(TileEntityHopper.class, "Hopper"); } + ++ // -- BEGIN FORGE PATCHES -- + /** + * Determines if this TileEntity requires update calls. + * @return True if you want updateEntity() to be called, false if not @@ -27,10 +29,10 @@ + /** + * Called when you receive a TileEntityData packet for the location this + * TileEntity is currently in. On the client, the NetworkManager will always -+ * be the remote server. On the server, it will be whomever is responsible for ++ * be the remote server. On the server, it will be whomever is responsible for + * sending the packet. -+ * -+ * @param net The NetworkManager the packet originated from ++ * ++ * @param net The NetworkManager the packet originated from + * @param pkt The data packet + */ + public void onDataPacket(INetworkManager net, Packet132TileEntityData pkt) @@ -47,12 +49,12 @@ + /** + * Called from Chunk.setBlockIDWithMetadata, determines if this tile entity should be re-created when the ID, or Metadata changes. + * Use with caution as this will leave straggler TileEntities, or create conflicts with other TileEntities if not used properly. -+ * ++ * + * @param oldID The old ID of the block + * @param newID The new ID of the block (May be the same) + * @param oldMeta The old metadata of the block + * @param newMeta The new metadata of the block (May be the same) -+ * @param world Current world ++ * @param world Current world + * @param x X Postion + * @param y Y Position + * @param z Z Position @@ -61,5 +63,45 @@ + public boolean shouldRefresh(int oldID, int newID, int oldMeta, int newMeta, World world, int x, int y, int z) + { + return true; ++ } ++ ++ public boolean shouldRenderInPass(int pass) ++ { ++ return pass == 0; ++ } ++ /** ++ * Sometimes default render bounding box: infinite in scope. Used to control rendering on {@link TileEntitySpecialRenderer}. ++ */ ++ public static final AxisAlignedBB INFINITE_EXTENT_AABB = AxisAlignedBB.getBoundingBox(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY); ++ ++ /** ++ * Return an {@link AxisAlignedBB} that controls the visible scope of a {@link TileEntitySpecialRenderer} associated with this {@link TileEntity} ++ * Defaults to the collision bounding box {@link Block#getCollisionBoundingBoxFromPool(World, int, int, int)} associated with the block ++ * at this location. ++ * ++ * @return an appropriately size {@link AxisAlignedBB} for the {@link TileEntity} ++ */ ++ @SideOnly(Side.CLIENT) ++ public AxisAlignedBB getRenderBoundingBox() ++ { ++ AxisAlignedBB bb = INFINITE_EXTENT_AABB; ++ Block type = getBlockType(); ++ if (type == Block.enchantmentTable) ++ { ++ bb = AxisAlignedBB.getAABBPool().addOrModifyAABBInPool(xCoord, yCoord, zCoord, xCoord + 1, yCoord + 1, zCoord + 1); ++ } ++ else if (type == Block.chest) ++ { ++ bb = AxisAlignedBB.getAABBPool().addOrModifyAABBInPool(xCoord - 1, yCoord, zCoord - 1, xCoord + 2, yCoord + 1, zCoord + 2); ++ } ++ else if (type != null && type != Block.beacon) ++ { ++ AxisAlignedBB cbb = getBlockType().getCollisionBoundingBoxFromPool(worldObj, xCoord, yCoord, zCoord); ++ if (cbb != null) ++ { ++ bb = cbb; ++ } ++ } ++ return bb; + } } diff --git a/patches/minecraft/net/minecraft/util/WeightedRandomChestContent.java.patch b/patches/minecraft/net/minecraft/util/WeightedRandomChestContent.java.patch index 16c64ca53..333e3cc71 100644 --- a/patches/minecraft/net/minecraft/util/WeightedRandomChestContent.java.patch +++ b/patches/minecraft/net/minecraft/util/WeightedRandomChestContent.java.patch @@ -61,3 +61,22 @@ } } } +@@ -109,4 +92,18 @@ + + return aweightedrandomchestcontent1; + } ++ ++ // -- Forge hooks ++ /** ++ * Allow a mod to submit a custom implementation that can delegate item stack generation beyond simple stack lookup ++ * ++ * @param random The current random for generation ++ * @param newInventory The inventory being generated (do not populate it, but you can refer to it) ++ * @return An array of {@link ItemStack} to put into the chest ++ */ ++ protected ItemStack[] generateChestContent(Random random, IInventory newInventory) ++ { ++ return ChestGenHooks.generateStacks(random, theItemId, theMinimumChanceToGenerateItem, theMaximumChanceToGenerateItem); ++ } ++ + } diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenBigTree.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenBigTree.java.patch new file mode 100644 index 000000000..dd6518e72 --- /dev/null +++ b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenBigTree.java.patch @@ -0,0 +1,26 @@ +--- ../src_base/minecraft/net/minecraft/world/gen/feature/WorldGenBigTree.java ++++ ../src_work/minecraft/net/minecraft/world/gen/feature/WorldGenBigTree.java +@@ -1,9 +1,12 @@ + package net.minecraft.world.gen.feature; + + import java.util.Random; ++ + import net.minecraft.block.Block; ++import net.minecraft.block.BlockSapling; + import net.minecraft.util.MathHelper; + import net.minecraft.world.World; ++import net.minecraftforge.common.ForgeDirection; + + public class WorldGenBigTree extends WorldGenerator + { +@@ -442,7 +445,9 @@ + int[] aint1 = new int[] {this.basePos[0], this.basePos[1] + this.heightLimit - 1, this.basePos[2]}; + int i = this.worldObj.getBlockId(this.basePos[0], this.basePos[1] - 1, this.basePos[2]); + +- if (i != 2 && i != 3) ++ Block soil = Block.blocksList[i]; ++ boolean isValidSoil = (soil != null && soil.canSustainPlant(worldObj, basePos[0], basePos[1] - 1, basePos[2], ForgeDirection.UP, (BlockSapling)Block.sapling)); ++ if (!isValidSoil) + { + return false; + } diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenForest.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenForest.java.patch index 6958203b9..0eefce6c0 100644 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenForest.java.patch +++ b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenForest.java.patch @@ -1,6 +1,18 @@ --- ../src_base/minecraft/net/minecraft/world/gen/feature/WorldGenForest.java +++ ../src_work/minecraft/net/minecraft/world/gen/feature/WorldGenForest.java -@@ -45,7 +45,9 @@ +@@ -1,8 +1,11 @@ + package net.minecraft.world.gen.feature; + + import java.util.Random; ++ + import net.minecraft.block.Block; ++import net.minecraft.block.BlockSapling; + import net.minecraft.world.World; ++import net.minecraftforge.common.ForgeDirection; + + public class WorldGenForest extends WorldGenerator + { +@@ -45,7 +48,9 @@ { l1 = par1World.getBlockId(j1, i1, k1); @@ -11,19 +23,34 @@ { flag = false; } -@@ -84,7 +86,10 @@ +@@ -65,10 +70,12 @@ + else + { + i1 = par1World.getBlockId(par3, par4 - 1, par5); ++ Block soil = Block.blocksList[i1]; ++ boolean isValidSoil = soil != null && soil.canSustainPlant(par1World, par3, par4 - 1, par5, ForgeDirection.UP, (BlockSapling)Block.sapling); + +- if ((i1 == Block.grass.blockID || i1 == Block.dirt.blockID) && par4 < 256 - l - 1) ++ if (isValidSoil && par4 < 256 - l - 1) + { +- this.setBlock(par1World, par3, par4 - 1, par5, Block.dirt.blockID); ++ soil.onPlantGrow(par1World, par3, par4 - 1, par5, par3, par4, par5); + int i2; + + for (i2 = par4 - 3 + l; i2 <= par4 + l; ++i2) +@@ -84,7 +91,10 @@ { int l2 = k2 - par5; - if ((Math.abs(j2) != k1 || Math.abs(l2) != k1 || par2Random.nextInt(2) != 0 && j1 != 0) && !Block.opaqueCubeLookup[par1World.getBlockId(l1, i2, k2)]) + Block block = Block.blocksList[par1World.getBlockId(l1, i2, k2)]; -+ -+ if ((Math.abs(j2) != k1 || Math.abs(l2) != k1 || par2Random.nextInt(2) != 0 && j1 != 0) && ++ ++ if ((Math.abs(j2) != k1 || Math.abs(l2) != k1 || par2Random.nextInt(2) != 0 && j1 != 0) && + (block == null || block.canBeReplacedByLeaves(par1World, l1, i2, k2))) { this.setBlockAndMetadata(par1World, l1, i2, k2, Block.leaves.blockID, 2); } -@@ -96,7 +101,9 @@ +@@ -96,7 +106,9 @@ { j1 = par1World.getBlockId(par3, par4 + i2, par5); diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenHugeTrees.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenHugeTrees.java.patch index 3bc16541b..0683b7ef8 100644 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenHugeTrees.java.patch +++ b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenHugeTrees.java.patch @@ -1,20 +1,53 @@ --- ../src_base/minecraft/net/minecraft/world/gen/feature/WorldGenHugeTrees.java +++ ../src_work/minecraft/net/minecraft/world/gen/feature/WorldGenHugeTrees.java -@@ -58,7 +58,12 @@ +@@ -2,8 +2,10 @@ + + import java.util.Random; + import net.minecraft.block.Block; ++import net.minecraft.block.BlockSapling; + import net.minecraft.util.MathHelper; + import net.minecraft.world.World; ++import net.minecraftforge.common.ForgeDirection; + + public class WorldGenHugeTrees extends WorldGenerator + { +@@ -58,7 +60,12 @@ { l1 = par1World.getBlockId(j1, i1, k1); - if (l1 != 0 && l1 != Block.leaves.blockID && l1 != Block.grass.blockID && l1 != Block.dirt.blockID && l1 != Block.wood.blockID && l1 != Block.sapling.blockID) -+ if (l1 != 0 && -+ (Block.blocksList[l1] != null && !Block.blocksList[l1].isLeaves(par1World, j1, i1, k1)) && -+ l1 != Block.grass.blockID && -+ l1 != Block.dirt.blockID && ++ if (l1 != 0 && ++ (Block.blocksList[l1] != null && !Block.blocksList[l1].isLeaves(par1World, j1, i1, k1)) && ++ l1 != Block.grass.blockID && ++ l1 != Block.dirt.blockID && + (Block.blocksList[l1] != null && !Block.blocksList[l1].isWood(par1World, j1, i1, k1)) && + l1 != Block.sapling.blockID) { flag = false; } -@@ -106,7 +111,7 @@ +@@ -79,12 +86,15 @@ + { + i1 = par1World.getBlockId(par3, par4 - 1, par5); + +- if ((i1 == Block.grass.blockID || i1 == Block.dirt.blockID) && par4 < 256 - l - 1) +- { +- par1World.setBlockAndMetadataWithNotify(par3, par4 - 1, par5, Block.dirt.blockID, 0, 4); +- par1World.setBlockAndMetadataWithNotify(par3 + 1, par4 - 1, par5, Block.dirt.blockID, 0, 4); +- par1World.setBlockAndMetadataWithNotify(par3, par4 - 1, par5 + 1, Block.dirt.blockID, 0, 4); +- par1World.setBlockAndMetadataWithNotify(par3 + 1, par4 - 1, par5 + 1, Block.dirt.blockID, 0, 4); ++ Block soil = Block.blocksList[i1]; ++ boolean isValidSoil = soil != null && soil.canSustainPlant(par1World, par3, par4 - 1, par5, ForgeDirection.UP, (BlockSapling)Block.sapling); ++ ++ if (isValidSoil && par4 < 256 - l - 1) ++ { ++ onPlantGrow(par1World, par3, par4 - 1, par5, par3, par4, par5); ++ onPlantGrow(par1World, par3 + 1, par4 - 1, par5, par3, par4, par5); ++ onPlantGrow(par1World, par3, par4 - 1, par5 + 1, par3, par4, par5); ++ onPlantGrow(par1World, par3 + 1, par4 - 1, par5 + 1, par3, par4, par5); + this.growLeaves(par1World, par3, par5, par4 + l, 2, par2Random); + + for (int i2 = par4 + l - 2 - par2Random.nextInt(4); i2 > par4 + l / 2; i2 -= 2 + par2Random.nextInt(4)) +@@ -106,7 +116,7 @@ { k1 = par1World.getBlockId(par3, par4 + j1, par5); @@ -23,7 +56,7 @@ { this.setBlockAndMetadata(par1World, par3, par4 + j1, par5, Block.wood.blockID, this.woodMetadata); -@@ -128,7 +133,7 @@ +@@ -128,7 +138,7 @@ { k1 = par1World.getBlockId(par3 + 1, par4 + j1, par5); @@ -32,7 +65,7 @@ { this.setBlockAndMetadata(par1World, par3 + 1, par4 + j1, par5, Block.wood.blockID, this.woodMetadata); -@@ -148,7 +153,7 @@ +@@ -148,7 +158,7 @@ k1 = par1World.getBlockId(par3 + 1, par4 + j1, par5 + 1); @@ -41,7 +74,7 @@ { this.setBlockAndMetadata(par1World, par3 + 1, par4 + j1, par5 + 1, Block.wood.blockID, this.woodMetadata); -@@ -168,7 +173,7 @@ +@@ -168,7 +178,7 @@ k1 = par1World.getBlockId(par3, par4 + j1, par5 + 1); @@ -50,17 +83,31 @@ { this.setBlockAndMetadata(par1World, par3, par4 + j1, par5 + 1, Block.wood.blockID, this.woodMetadata); -@@ -219,7 +224,12 @@ +@@ -219,7 +229,12 @@ { int k2 = j2 - par3; - if ((i2 >= 0 || k2 >= 0 || i2 * i2 + k2 * k2 <= k1 * k1) && (i2 <= 0 && k2 <= 0 || i2 * i2 + k2 * k2 <= (k1 + 1) * (k1 + 1)) && (par6Random.nextInt(4) != 0 || i2 * i2 + k2 * k2 <= (k1 - 1) * (k1 - 1)) && !Block.opaqueCubeLookup[par1World.getBlockId(l1, i1, j2)]) + Block block = Block.blocksList[par1World.getBlockId(l1, i1, j2)]; + -+ if ((i2 >= 0 || k2 >= 0 || i2 * i2 + k2 * k2 <= k1 * k1) && -+ (i2 <= 0 && k2 <= 0 || i2 * i2 + k2 * k2 <= (k1 + 1) * (k1 + 1)) && -+ (par6Random.nextInt(4) != 0 || i2 * i2 + k2 * k2 <= (k1 - 1) * (k1 - 1)) && ++ if ((i2 >= 0 || k2 >= 0 || i2 * i2 + k2 * k2 <= k1 * k1) && ++ (i2 <= 0 && k2 <= 0 || i2 * i2 + k2 * k2 <= (k1 + 1) * (k1 + 1)) && ++ (par6Random.nextInt(4) != 0 || i2 * i2 + k2 * k2 <= (k1 - 1) * (k1 - 1)) && + (block == null || block.canBeReplacedByLeaves(par1World, l1, i1, j2))) { this.setBlockAndMetadata(par1World, l1, i1, j2, Block.leaves.blockID, this.leavesMetadata); } +@@ -227,4 +242,13 @@ + } + } + } ++ ++ private void onPlantGrow(World world, int x, int y, int z, int sourceX, int sourceY, int sourceZ) ++ { ++ Block block = Block.blocksList[world.getBlockId(x, y, z)]; ++ if (block != null) ++ { ++ block.onPlantGrow(world, x, y, z, sourceX, sourceY, sourceZ); ++ } ++ } + } diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenTaiga2.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenTaiga2.java.patch index 2860eb1cb..bc5800d54 100644 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenTaiga2.java.patch +++ b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenTaiga2.java.patch @@ -1,6 +1,16 @@ --- ../src_base/minecraft/net/minecraft/world/gen/feature/WorldGenTaiga2.java +++ ../src_work/minecraft/net/minecraft/world/gen/feature/WorldGenTaiga2.java -@@ -47,7 +47,9 @@ +@@ -2,7 +2,9 @@ + + import java.util.Random; + import net.minecraft.block.Block; ++import net.minecraft.block.BlockSapling; + import net.minecraft.world.World; ++import net.minecraftforge.common.ForgeDirection; + + public class WorldGenTaiga2 extends WorldGenerator + { +@@ -47,7 +49,9 @@ { j2 = par1World.getBlockId(i2, l1, l2); @@ -11,19 +21,34 @@ { flag = false; } -@@ -89,7 +91,10 @@ +@@ -67,10 +71,12 @@ + else + { + l1 = par1World.getBlockId(par3, par4 - 1, par5); ++ Block soil = Block.blocksList[l1]; ++ boolean isValidSoil = soil != null && soil.canSustainPlant(par1World, par3, par4 - 1, par5, ForgeDirection.UP, (BlockSapling)Block.sapling); + +- if ((l1 == Block.grass.blockID || l1 == Block.dirt.blockID) && par4 < 256 - l - 1) ++ if (isValidSoil && par4 < 256 - l - 1) + { +- this.setBlock(par1World, par3, par4 - 1, par5, Block.dirt.blockID); ++ soil.onPlantGrow(par1World, par3, par4 - 1, par5, par3, par4, par5); + k2 = par2Random.nextInt(2); + i2 = 1; + byte b0 = 0; +@@ -89,7 +95,10 @@ { int i4 = l3 - par5; - if ((Math.abs(k3) != k2 || Math.abs(i4) != k2 || k2 <= 0) && !Block.opaqueCubeLookup[par1World.getBlockId(i3, j3, l3)]) + Block block = Block.blocksList[par1World.getBlockId(i3, j3, l3)]; + -+ if ((Math.abs(k3) != k2 || Math.abs(i4) != k2 || k2 <= 0) && ++ if ((Math.abs(k3) != k2 || Math.abs(i4) != k2 || k2 <= 0) && + (block == null || block.canBeReplacedByLeaves(par1World, i3, j3, l3))) { this.setBlockAndMetadata(par1World, i3, j3, l3, Block.leaves.blockID, 1); } -@@ -119,7 +124,9 @@ +@@ -119,7 +128,9 @@ { i3 = par1World.getBlockId(par3, par4 + j3, par5); diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenTrees.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenTrees.java.patch index 154b0f192..367b5ce64 100644 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenTrees.java.patch +++ b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenTrees.java.patch @@ -1,6 +1,17 @@ --- ../src_base/minecraft/net/minecraft/world/gen/feature/WorldGenTrees.java +++ ../src_work/minecraft/net/minecraft/world/gen/feature/WorldGenTrees.java -@@ -67,7 +67,13 @@ +@@ -2,8 +2,10 @@ + + import java.util.Random; + import net.minecraft.block.Block; ++import net.minecraft.block.BlockSapling; + import net.minecraft.util.Direction; + import net.minecraft.world.World; ++import net.minecraftforge.common.ForgeDirection; + + public class WorldGenTrees extends WorldGenerator + { +@@ -67,7 +69,13 @@ { k1 = par1World.getBlockId(l1, i1, j1); @@ -15,7 +26,24 @@ { flag = false; } -@@ -110,7 +116,10 @@ +@@ -87,10 +95,12 @@ + else + { + i1 = par1World.getBlockId(par3, par4 - 1, par5); +- +- if ((i1 == Block.grass.blockID || i1 == Block.dirt.blockID) && par4 < 256 - l - 1) +- { +- this.setBlock(par1World, par3, par4 - 1, par5, Block.dirt.blockID); ++ Block soil = Block.blocksList[i1]; ++ boolean isSoil = (soil != null && soil.canSustainPlant(par1World, par3, par4 - 1, par5, ForgeDirection.UP, (BlockSapling)Block.sapling)); ++ ++ if (isSoil && par4 < 256 - l - 1) ++ { ++ soil.onPlantGrow(par1World, par3, par4 - 1, par5, par3, par4, par5); + b0 = 3; + byte b1 = 0; + int i2; +@@ -110,7 +120,10 @@ { int i3 = l2 - par5; @@ -27,7 +55,7 @@ { this.setBlockAndMetadata(par1World, j2, j1, l2, Block.leaves.blockID, this.metaLeaves); } -@@ -122,7 +131,9 @@ +@@ -122,7 +135,9 @@ { k1 = par1World.getBlockId(par3, par4 + j1, par5); @@ -38,7 +66,7 @@ { this.setBlockAndMetadata(par1World, par3, par4 + j1, par5, Block.wood.blockID, this.metaWood); -@@ -162,7 +173,8 @@ +@@ -162,7 +177,8 @@ { for (k2 = par5 - i2; k2 <= par5 + i2; ++k2) { diff --git a/setup.sh b/setup.sh old mode 100755 new mode 100644 diff --git a/update_patches.sh b/update_patches.sh deleted file mode 100755 index 4f579cc04..000000000 --- a/update_patches.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -python update_patches.py "$@" \ No newline at end of file