diff --git a/patches.mcp/minecraft/net/minecraft/client/gui/achievement/GuiStats.java.patch b/patches.mcp/minecraft/net/minecraft/client/gui/achievement/GuiStats.java.patch deleted file mode 100644 index d120f752da..0000000000 --- a/patches.mcp/minecraft/net/minecraft/client/gui/achievement/GuiStats.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- ../src-base/minecraft/net/minecraft/client/gui/achievement/GuiStats.java -+++ ../src-work/minecraft/net/minecraft/client/gui/achievement/GuiStats.java -@@ -877,7 +877,7 @@ - super(mcIn, GuiStats.this.width, GuiStats.this.height, 32, GuiStats.this.height - 64, GuiStats.this.fontRendererObj.FONT_HEIGHT * 4); - this.setShowSelectionBox(false); - -- for (EntityList.EntityEggInfo entitylist$entityegginfo : EntityList.entityEggs.values()) -+ for (EntityList.EntityEggInfo entitylist$entityegginfo : com.google.common.collect.Iterables.concat(EntityList.entityEggs.values(), net.minecraftforge.fml.common.registry.EntityRegistry.getEggs().values())) - { - if (GuiStats.this.field_146546_t.readStat(entitylist$entityegginfo.field_151512_d) > 0 || GuiStats.this.field_146546_t.readStat(entitylist$entityegginfo.field_151513_e) > 0) - { diff --git a/patches.mcp/minecraft/net/minecraft/world/WorldServer.java.patch b/patches.mcp/minecraft/net/minecraft/world/WorldServer.java.patch index 3e6d94c700..606ef18568 100644 --- a/patches.mcp/minecraft/net/minecraft/world/WorldServer.java.patch +++ b/patches.mcp/minecraft/net/minecraft/world/WorldServer.java.patch @@ -1,6 +1,48 @@ --- ../src-base/minecraft/net/minecraft/world/WorldServer.java +++ ../src-work/minecraft/net/minecraft/world/WorldServer.java -@@ -214,6 +214,10 @@ +@@ -97,30 +97,39 @@ + private int blockEventCacheIndex; + private List pendingTickListEntriesThisTick = Lists.newArrayList(); + ++ /** Stores the recently processed (lighting) chunks */ ++ protected Set doneChunks = new java.util.HashSet(); ++ public List customTeleporters = new ArrayList(); ++ + public WorldServer(MinecraftServer server, ISaveHandler saveHandlerIn, WorldInfo info, int dimensionId, Profiler profilerIn) + { + super(saveHandlerIn, info, DimensionType.func_186069_a(dimensionId).func_186070_d(), profilerIn, false); + this.mcServer = server; + this.theEntityTracker = new EntityTracker(this); + this.thePlayerManager = new PlayerManager(this); ++ // Guarantee the dimension ID was not reset by the provider ++ int providerDim = this.provider.dimensionId; + this.provider.registerWorld(this); ++ this.provider.dimensionId = providerDim; + this.chunkProvider = this.createChunkProvider(); ++ perWorldStorage = new MapStorage(new net.minecraftforge.common.WorldSpecificSaveHandler((WorldServer)this, saveHandlerIn)); + this.worldTeleporter = new Teleporter(this); + this.calculateInitialSkylight(); + this.calculateInitialWeather(); + this.getWorldBorder().setSize(server.getMaxWorldSize()); ++ net.minecraftforge.common.DimensionManager.setWorld(dimensionId, this); + } + + public World init() + { + this.mapStorage = new MapStorage(this.saveHandler); + String s = VillageCollection.fileNameForProvider(this.provider); +- VillageCollection villagecollection = (VillageCollection)this.mapStorage.loadData(VillageCollection.class, s); ++ VillageCollection villagecollection = (VillageCollection)this.perWorldStorage.loadData(VillageCollection.class, s); + + if (villagecollection == null) + { + this.villageCollectionObj = new VillageCollection(this); +- this.mapStorage.setData(s, this.villageCollectionObj); ++ this.perWorldStorage.setData(s, this.villageCollectionObj); + } + else + { +@@ -214,6 +223,10 @@ this.villageSiege.tick(); this.theProfiler.endStartSection("portalForcer"); this.worldTeleporter.removeStalePortalLocations(this.getTotalWorldTime()); @@ -11,7 +53,7 @@ this.theProfiler.endSection(); this.sendQueuedBlockEvents(); } -@@ -221,12 +225,14 @@ +@@ -221,12 +234,14 @@ public BiomeGenBase.SpawnListEntry getSpawnListEntryForTypeAt(EnumCreatureType creatureType, BlockPos pos) { List list = this.getChunkProvider().getPossibleCreatures(creatureType, pos); @@ -26,7 +68,7 @@ return list != null && !list.isEmpty() ? list.contains(spawnListEntry) : false; } -@@ -272,10 +278,7 @@ +@@ -272,10 +287,7 @@ private void resetRainAndThunder() { @@ -38,7 +80,16 @@ } public boolean areAllPlayersAsleep() -@@ -409,7 +412,7 @@ +@@ -380,7 +392,7 @@ + chunk.func_150804_b(false); + this.theProfiler.endStartSection("thunder"); + +- if (flag && flag1 && this.rand.nextInt(100000) == 0) ++ if (this.provider.canDoLightning(chunk) && flag && flag1 && this.rand.nextInt(100000) == 0) + { + this.updateLCG = this.updateLCG * 3 + 1013904223; + int l = this.updateLCG >> 2; +@@ -409,7 +421,7 @@ this.theProfiler.endStartSection("iceandsnow"); @@ -47,7 +98,7 @@ { this.updateLCG = this.updateLCG * 3 + 1013904223; int j2 = this.updateLCG >> 2; -@@ -527,6 +530,9 @@ +@@ -527,6 +539,9 @@ if (blockIn.requiresUpdates()) { i = 8; @@ -57,7 +108,7 @@ if (this.isAreaLoaded(pos.add(-i, -i, -i), pos.add(i, i, i))) { -@@ -588,7 +594,7 @@ +@@ -588,7 +603,7 @@ public void updateEntities() { @@ -66,7 +117,7 @@ { if (this.updateEntityTick++ >= 300) { -@@ -712,6 +718,9 @@ +@@ -712,6 +727,9 @@ { NextTickListEntry nextticklistentry1 = (NextTickListEntry)iterator.next(); iterator.remove(); @@ -76,7 +127,7 @@ int k = 0; if (this.isAreaLoaded(nextticklistentry1.position.add(-k, -k, -k), nextticklistentry1.position.add(k, k, k))) -@@ -838,22 +847,40 @@ +@@ -838,22 +856,40 @@ { List list = Lists.newArrayList(); @@ -124,7 +175,7 @@ return !this.mcServer.isBlockProtected(this, pos, player) && this.getWorldBorder().contains(pos); } -@@ -919,6 +946,7 @@ +@@ -919,6 +955,7 @@ } else { @@ -132,7 +183,15 @@ this.findingSpawnPoint = true; BiomeProvider biomeprovider = this.provider.getWorldChunkManager(); List list = biomeprovider.getBiomesToSpawnIn(); -@@ -1047,6 +1075,7 @@ +@@ -1003,6 +1040,7 @@ + } + + chunkproviderserver.func_186027_a(p_73044_1_); ++ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Save(this)); + + for (Chunk chunk : Lists.newArrayList(chunkproviderserver.func_152380_a())) + { +@@ -1047,6 +1085,7 @@ this.worldInfo.setBorderLerpTime(this.getWorldBorder().getTimeUntilTarget()); this.saveHandler.saveWorldInfoWithPlayer(this.worldInfo, this.mcServer.func_184103_al().getHostPlayerData()); this.mapStorage.saveAllData(); @@ -140,7 +199,7 @@ } public boolean spawnEntityInWorld(Entity entityIn) -@@ -1161,6 +1190,7 @@ +@@ -1161,6 +1200,7 @@ public Explosion newExplosion(Entity entityIn, double x, double y, double z, float strength, boolean isFlaming, boolean isSmoking) { Explosion explosion = new Explosion(this, entityIn, x, y, z, strength, isFlaming, isSmoking); @@ -148,7 +207,35 @@ explosion.doExplosionA(); explosion.doExplosionB(false); -@@ -1329,6 +1359,11 @@ +@@ -1240,19 +1280,23 @@ + this.mcServer.func_184103_al().sendPacketToAllPlayersInDimension(new SPacketChangeGameState(8, this.thunderingStrength), this.provider.func_186058_p().func_186068_a()); + } + ++ /* The function in use here has been replaced in order to only send the weather info to players in the correct dimension, ++ * rather than to all players on the server. This is what causes the client-side rain, as the ++ * client believes that it has started raining locally, rather than in another dimension. ++ */ + if (flag != this.isRaining()) + { + if (flag) + { +- this.mcServer.func_184103_al().sendPacketToAllPlayers(new SPacketChangeGameState(2, 0.0F)); ++ this.mcServer.func_184103_al().sendPacketToAllPlayersInDimension(new SPacketChangeGameState(2, 0.0F), this.provider.dimensionId); + } + else + { +- this.mcServer.func_184103_al().sendPacketToAllPlayers(new SPacketChangeGameState(1, 0.0F)); ++ this.mcServer.func_184103_al().sendPacketToAllPlayersInDimension(new SPacketChangeGameState(1, 0.0F), this.provider.dimensionId); + } + +- this.mcServer.func_184103_al().sendPacketToAllPlayers(new SPacketChangeGameState(7, this.rainingStrength)); +- this.mcServer.func_184103_al().sendPacketToAllPlayers(new SPacketChangeGameState(8, this.thunderingStrength)); ++ this.mcServer.func_184103_al().sendPacketToAllPlayersInDimension(new SPacketChangeGameState(7, this.rainingStrength), this.provider.dimensionId); ++ this.mcServer.func_184103_al().sendPacketToAllPlayersInDimension(new SPacketChangeGameState(8, this.thunderingStrength), this.provider.dimensionId); + } + } + +@@ -1329,6 +1373,11 @@ return this.mcServer.isCallingFromMinecraftThread(); } diff --git a/rejects/minecraft/net/minecraft/client/gui/achievement/GuiStats.java.patch.rej b/rejects/minecraft/net/minecraft/client/gui/achievement/GuiStats.java.patch.rej deleted file mode 100644 index 52c077ed65..0000000000 --- a/rejects/minecraft/net/minecraft/client/gui/achievement/GuiStats.java.patch.rej +++ /dev/null @@ -1,62 +0,0 @@ -++++ REJECTED PATCH 1 - import java.util.Collections; - import java.util.Comparator; - import java.util.List; -+ -+import net.minecraft.block.Block; - import net.minecraft.client.Minecraft; - import net.minecraft.client.audio.PositionedSoundRecord; - import net.minecraft.client.gui.GuiButton; -++++ END PATCH -++++ REJECTED PATCH 2 - for (StatCrafting statcrafting : StatList.objectMineStats) - { - boolean flag = false; -- int i = Item.getIdFromItem(statcrafting.func_150959_a()); -+ int i = Block.getIdFromBlock(Block.getBlockFromItem(statcrafting.func_150959_a())); -+ int itemId = Item.getIdFromItem(statcrafting.func_150959_a()); - - if (GuiStats.this.field_146546_t.readStat(statcrafting) > 0) - { - flag = true; - } -- else if (StatList.objectUseStats[i] != null && GuiStats.this.field_146546_t.readStat(StatList.objectUseStats[i]) > 0) -+ else if (StatList.objectUseStats[itemId] != null && GuiStats.this.field_146546_t.readStat(StatList.objectUseStats[itemId]) > 0) - { - flag = true; - } -- else if (StatList.objectCraftStats[i] != null && GuiStats.this.field_146546_t.readStat(StatList.objectCraftStats[i]) > 0) -+ else if (StatList.objectCraftStats[itemId] != null && GuiStats.this.field_146546_t.readStat(StatList.objectCraftStats[itemId]) > 0) - { - flag = true; - } -++++ END PATCH -++++ REJECTED PATCH 3 - { - public int compare(StatCrafting p_compare_1_, StatCrafting p_compare_2_) - { -- int j = Item.getIdFromItem(p_compare_1_.func_150959_a()); -- int k = Item.getIdFromItem(p_compare_2_.func_150959_a()); -+ int j; -+ int k; -+ if (StatsBlock.this.field_148217_o == 2) { -+ j = Block.getIdFromBlock(Block.getBlockFromItem(p_compare_1_.func_150959_a())); -+ k = Block.getIdFromBlock(Block.getBlockFromItem(p_compare_2_.func_150959_a())); -+ } else { -+ j = Item.getIdFromItem(p_compare_1_.func_150959_a()); -+ k = Item.getIdFromItem(p_compare_2_.func_150959_a()); -+ } - StatBase statbase = null; - StatBase statbase1 = null; - -++++ END PATCH -++++ REJECTED PATCH 5 - protected void drawSlot(int entryID, int p_180791_2_, int p_180791_3_, int p_180791_4_, int mouseXIn, int mouseYIn) - { - EntityList.EntityEggInfo entitylist$entityegginfo = (EntityList.EntityEggInfo)this.field_148222_l.get(entryID); -- String s = I18n.format("entity." + EntityList.getStringFromID(entitylist$entityegginfo.spawnedID) + ".name", new Object[0]); -+ String s = I18n.format("entity." + entitylist$entityegginfo.name + ".name", new Object[0]); - int i = GuiStats.this.field_146546_t.readStat(entitylist$entityegginfo.field_151512_d); - int j = GuiStats.this.field_146546_t.readStat(entitylist$entityegginfo.field_151513_e); - String s1 = I18n.format("stat.entityKills", new Object[] {Integer.valueOf(i), s}); -++++ END PATCH diff --git a/rejects/minecraft/net/minecraft/world/WorldServer.java.patch.rej b/rejects/minecraft/net/minecraft/world/WorldServer.java.patch.rej deleted file mode 100644 index 217fa3a260..0000000000 --- a/rejects/minecraft/net/minecraft/world/WorldServer.java.patch.rej +++ /dev/null @@ -1,108 +0,0 @@ -++++ REJECTED PATCH 1 - private static final List bonusChestContent = Lists.newArrayList(new WeightedRandomChestContent[] {new WeightedRandomChestContent(Items.stick, 0, 1, 3, 10), new WeightedRandomChestContent(Item.getItemFromBlock(Blocks.planks), 0, 1, 3, 10), new WeightedRandomChestContent(Item.getItemFromBlock(Blocks.log), 0, 1, 3, 10), new WeightedRandomChestContent(Items.stone_axe, 0, 1, 1, 3), new WeightedRandomChestContent(Items.wooden_axe, 0, 1, 1, 5), new WeightedRandomChestContent(Items.stone_pickaxe, 0, 1, 1, 3), new WeightedRandomChestContent(Items.wooden_pickaxe, 0, 1, 1, 5), new WeightedRandomChestContent(Items.apple, 0, 2, 3, 5), new WeightedRandomChestContent(Items.bread, 0, 2, 3, 3), new WeightedRandomChestContent(Item.getItemFromBlock(Blocks.log2), 0, 1, 3, 10)}); - private List pendingTickListEntriesThisTick = Lists.newArrayList(); - -+ /** Stores the recently processed (lighting) chunks */ -+ protected Set doneChunks = new java.util.HashSet(); -+ public List customTeleporters = new ArrayList(); -+ private static boolean initChest = false; -+ public static void fillChestHook() -+ { -+ if (!initChest) -+ net.minecraftforge.common.ChestGenHooks.init(net.minecraftforge.common.ChestGenHooks.BONUS_CHEST, bonusChestContent, 10, 10); -+ initChest = true; -+ } -+ - public WorldServer(MinecraftServer server, ISaveHandler saveHandlerIn, WorldInfo info, int dimensionId, Profiler profilerIn) - { - super(saveHandlerIn, info, WorldProvider.getProviderForDimension(dimensionId), profilerIn, false); - this.mcServer = server; - this.theEntityTracker = new EntityTracker(this); - this.thePlayerManager = new PlayerManager(this); -+ // Guarantee the dimension ID was not reset by the provider -+ int providerDim = this.provider.dimensionId; - this.provider.registerWorld(this); -+ this.provider.dimensionId = providerDim; - this.chunkProvider = this.createChunkProvider(); -+ perWorldStorage = new MapStorage(new net.minecraftforge.common.WorldSpecificSaveHandler((WorldServer)this, saveHandlerIn)); - this.worldTeleporter = new Teleporter(this); - this.calculateInitialSkylight(); - this.calculateInitialWeather(); - this.getWorldBorder().setSize(server.getMaxWorldSize()); -+ net.minecraftforge.common.DimensionManager.setWorld(dimensionId, this); - } - - public World init() - { - this.mapStorage = new MapStorage(this.saveHandler); - String s = VillageCollection.fileNameForProvider(this.provider); -- VillageCollection villagecollection = (VillageCollection)this.mapStorage.loadData(VillageCollection.class, s); -+ VillageCollection villagecollection = (VillageCollection)this.perWorldStorage.loadData(VillageCollection.class, s); - - if (villagecollection == null) - { - this.villageCollectionObj = new VillageCollection(this); -- this.mapStorage.setData(s, this.villageCollectionObj); -+ this.perWorldStorage.setData(s, this.villageCollectionObj); - } - else - { -++++ END PATCH -++++ REJECTED PATCH 5 - chunk.func_150804_b(false); - this.theProfiler.endStartSection("thunder"); - -- if (this.rand.nextInt(100000) == 0 && this.isRaining() && this.isThundering()) -+ if (this.provider.canDoLightning(chunk) && this.rand.nextInt(100000) == 0 && this.isRaining() && this.isThundering()) - { - this.updateLCG = this.updateLCG * 3 + 1013904223; - int i1 = this.updateLCG >> 2; -++++ END PATCH -++++ REJECTED PATCH 12 - - protected void createBonusChest() - { -- WorldGeneratorBonusChest worldgeneratorbonuschest = new WorldGeneratorBonusChest(bonusChestContent, 10); -+ WorldGeneratorBonusChest worldgeneratorbonuschest = net.minecraftforge.common.ForgeHooks.getBonusChest(rand); - - for (int i = 0; i < 10; ++i) - { -++++ END PATCH -++++ REJECTED PATCH 13 - } - - this.chunkProvider.saveChunks(p_73044_1_, progressCallback); -+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.WorldEvent.Save(this)); - - for (Chunk chunk : Lists.newArrayList(this.theChunkProviderServer.func_152380_a())) - { -++++ END PATCH -++++ REJECTED PATCH 16 - this.mcServer.getConfigurationManager().sendPacketToAllPlayersInDimension(new S2BPacketChangeGameState(8, this.thunderingStrength), this.provider.getDimensionId()); - } - -+ /* The function in use here has been replaced in order to only send the weather info to players in the correct dimension, -+ * rather than to all players on the server. This is what causes the client-side rain, as the -+ * client believes that it has started raining locally, rather than in another dimension. -+ */ - if (flag != this.isRaining()) - { - if (flag) - { -- this.mcServer.getConfigurationManager().sendPacketToAllPlayers(new S2BPacketChangeGameState(2, 0.0F)); -+ this.mcServer.getConfigurationManager().sendPacketToAllPlayersInDimension(new S2BPacketChangeGameState(2, 0.0F), this.provider.dimensionId); - } - else - { -- this.mcServer.getConfigurationManager().sendPacketToAllPlayers(new S2BPacketChangeGameState(1, 0.0F)); -+ this.mcServer.getConfigurationManager().sendPacketToAllPlayersInDimension(new S2BPacketChangeGameState(1, 0.0F), this.provider.dimensionId); - } - -- this.mcServer.getConfigurationManager().sendPacketToAllPlayers(new S2BPacketChangeGameState(7, this.rainingStrength)); -- this.mcServer.getConfigurationManager().sendPacketToAllPlayers(new S2BPacketChangeGameState(8, this.thunderingStrength)); -+ this.mcServer.getConfigurationManager().sendPacketToAllPlayersInDimension(new S2BPacketChangeGameState(7, this.rainingStrength), this.provider.dimensionId); -+ this.mcServer.getConfigurationManager().sendPacketToAllPlayersInDimension(new S2BPacketChangeGameState(8, this.thunderingStrength), this.provider.dimensionId); - } - } - -++++ END PATCH diff --git a/src/main/java/net/minecraftforge/fml/common/registry/EntityRegistry.java b/src/main/java/net/minecraftforge/fml/common/registry/EntityRegistry.java index 7a6506ca03..51fb8e02a0 100644 --- a/src/main/java/net/minecraftforge/fml/common/registry/EntityRegistry.java +++ b/src/main/java/net/minecraftforge/fml/common/registry/EntityRegistry.java @@ -198,6 +198,34 @@ public class EntityRegistry entityRegistrations.put(mc, er); } + /** + * Registers a spawn egg for the specified entity class. + * The class must already be registered in the EntityList.classToStringMapping. + * This can be done either by using the global ID system, or preferably the registerModEntity functions above. + * Once registered mob eggs can be created by using minecraft:spawn_egg with NBT entry 'entity_name' with + * value of the name this class is registered in the classToStringMapping with. + * + * @param entityClass The entity class + * @param primary Primary egg color + * @param secondary Secondary egg color + * + * @throws IllegalArgumentException if entityClass is not registered in classToStringMapping. + * + */ + + public static void registerEgg(Class entityClass, int primary, int secondary) + { + if (EntityList.classToStringMapping.containsKey(entityClass)) + { + String name = EntityList.classToStringMapping.get(entityClass); + EntityList.entityEggs.put(name, new EntityList.EntityEggInfo(name, primary, secondary)); + FMLLog.fine("Registering entity egg '%s' for %s", name, entityClass); + } + else + { + FMLLog.fine("Failed registering entity egg %s (No entity found)", entityClass.getName()); + } + } /** * Registers in the minecraft Entity ID list. This is generally not a good idea and shouldn't be used. * Simply use {@link #registerModEntity(Class, String, int, Object, int, int, boolean, int, int)} instead.