From e78b8258751d3b7d3f554d2fe192a7a9e1a399f8 Mon Sep 17 00:00:00 2001 From: LexManos Date: Mon, 24 Dec 2012 01:29:33 -0800 Subject: [PATCH] Re-write/Deprecated DungeonHooks loot tables, now uses ChestGenHooks like the rest of the world gen. Also fixes issue #330 by adding in enchanted books. Should be API compatible. --- .../minecraftforge/common/ChestGenHooks.java | 45 +++- .../minecraftforge/common/DungeonHooks.java | 244 +++++------------- .../WeightedRandomChestContent.java.patch | 33 ++- .../gen/feature/WorldGenDungeons.java.patch | 50 ++-- 4 files changed, 164 insertions(+), 208 deletions(-) diff --git a/common/net/minecraftforge/common/ChestGenHooks.java b/common/net/minecraftforge/common/ChestGenHooks.java index 1f90a69db..c3bfe7cac 100644 --- a/common/net/minecraftforge/common/ChestGenHooks.java +++ b/common/net/minecraftforge/common/ChestGenHooks.java @@ -4,6 +4,7 @@ import java.util.*; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.util.WeightedRandom; import net.minecraft.util.WeightedRandomChestContent; import net.minecraft.world.WorldServer; import net.minecraft.world.gen.structure.*; @@ -20,6 +21,7 @@ public class ChestGenHooks public static final String STRONGHOLD_CROSSING = "strongholdCrossing"; public static final String VILLAGE_BLACKSMITH = "villageBlacksmith"; public static final String BONUS_CHEST = "bonusChest"; + public static final String DUNGEON_CHEST = "dungeonChest"; private static final HashMap chestInfo = new HashMap(); private static boolean hasInit = false; @@ -52,6 +54,30 @@ public class ChestGenHooks getInfo(STRONGHOLD_CORRIDOR ).addItem(tmp); getInfo(STRONGHOLD_LIBRARY ).addItem(new WeightedRandomChestContent(book, 1, 5, 2)); getInfo(STRONGHOLD_CROSSING ).addItem(tmp); + + //Wish Dungeons would get on the same wave length as other world gen... + ChestGenHooks d = new ChestGenHooks(DUNGEON_CHEST); + d.countMin = 8; + d.countMax = 8; + chestInfo.put(DUNGEON_CHEST, d); + addDungeonLoot(d, new ItemStack(Item.saddle), 100, 1, 1); + addDungeonLoot(d, new ItemStack(Item.ingotIron), 100, 1, 4); + addDungeonLoot(d, new ItemStack(Item.bread), 100, 1, 1); + addDungeonLoot(d, new ItemStack(Item.wheat), 100, 1, 4); + addDungeonLoot(d, new ItemStack(Item.gunpowder), 100, 1, 4); + addDungeonLoot(d, new ItemStack(Item.silk), 100, 1, 4); + addDungeonLoot(d, new ItemStack(Item.bucketEmpty), 100, 1, 1); + addDungeonLoot(d, new ItemStack(Item.appleGold), 001, 1, 1); + addDungeonLoot(d, new ItemStack(Item.redstone), 050, 1, 4); + addDungeonLoot(d, new ItemStack(Item.record13), 005, 1, 1); + addDungeonLoot(d, new ItemStack(Item.recordCat), 005, 1, 1); + addDungeonLoot(d, new ItemStack(Item.dyePowder, 1, 3), 100, 1, 1); + addDungeonLoot(d, book, 100, 1, 1); + } + + static void addDungeonLoot(ChestGenHooks dungeon, ItemStack item, int weight, int min, int max) + { + dungeon.addItem(new WeightedRandomChestContent(item, weight, max, max)); } private static void addInfo(String category, WeightedRandomChestContent[] items, int min, int max) @@ -117,11 +143,13 @@ public class ChestGenHooks public static int getCount(String category, Random rand){ return getInfo(category).getCount(rand); } public static void addItem(String category, WeightedRandomChestContent item){ getInfo(category).addItem(item); } public static void removeItem(String category, ItemStack item){ getInfo(category).removeItem(item); } + public static ItemStack getOneItem(String category, Random rand){ return getInfo(category).getOneItem(rand); } private String category; private int countMin = 0; private int countMax = 0; - private ArrayList contents = new ArrayList(); + //TO-DO: Privatize this once again when we remove the Deprecated stuff in DungeonHooks + ArrayList contents = new ArrayList(); public ChestGenHooks(String category) { @@ -204,6 +232,21 @@ public class ChestGenHooks { return countMin < countMax ? countMin + rand.nextInt(countMax - countMin) : countMin; } + + /** + * Returns a single ItemStack from the possible items in this registry, + * Useful if you just want a quick and dirty random Item. + * + * @param rand A Random Number gen + * @return A single ItemStack, or null if it could not get one. + */ + public ItemStack getOneItem(Random rand) + { + WeightedRandomChestContent[] items = getItems(rand); + WeightedRandomChestContent item = (WeightedRandomChestContent)WeightedRandom.getRandomItem(rand, items); + ItemStack[] stacks = ChestGenHooks.generateStacks(rand, item.theItemId, item.theMinimumChanceToGenerateItem, item.theMaximumChanceToGenerateItem); + return (stacks.length > 0 ? stacks[0] : null); + } //Accessors public int getMin(){ return countMin; } diff --git a/common/net/minecraftforge/common/DungeonHooks.java b/common/net/minecraftforge/common/DungeonHooks.java index 17d93e1aa..582a83bf8 100644 --- a/common/net/minecraftforge/common/DungeonHooks.java +++ b/common/net/minecraftforge/common/DungeonHooks.java @@ -6,30 +6,14 @@ import java.util.Random; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.WeightedRandom; +import net.minecraft.util.WeightedRandomChestContent; import net.minecraft.util.WeightedRandomItem; +import static net.minecraftforge.common.ChestGenHooks.DUNGEON_CHEST; + public class DungeonHooks { - private static int dungeonLootAttempts = 8; private static ArrayList dungeonMobs = new ArrayList(); - private static ArrayList dungeonLoot = new ArrayList(); - /** - * Set the number of item stacks that will be attempted to be added to each Dungeon chest. - * Note: Due to random number generation, you will not always get this amount per chest. - * @param number The maximum number of item stacks to add to a chest. - */ - public static void setDungeonLootTries(int number) - { - dungeonLootAttempts = number; - } - - /** - * @return The max number of item stacks found in each dungeon chest. - */ - public static int getDungeonLootTries() - { - return dungeonLootAttempts; - } /** * Adds a mob to the possible list of creatures the spawner will create. @@ -98,150 +82,6 @@ public class DungeonHooks return mob.type; } - /** - * Adds a item stack to the dungeon loot list with a stack size - * of 1. - * - * @param item The ItemStack to be added to the loot list - * @param rarity The relative chance that this item will spawn, Vanilla has - * most of its items set to 1. Like the saddle, bread, silk, wheat, etc.. - * Rarer items are set to lower values, EXA: Golden Apple 0.01 - */ - public static void addDungeonLoot(ItemStack item, int rarity) - { - addDungeonLoot(item, rarity, 1, 1); - } - - /** - * Adds a item stack, with a range of sizes, to the dungeon loot list. - * If a stack matching the same item, and size range, is already in the list - * the rarities will be added together making the item more common. - * - * @param item The ItemStack to be added to the loot list - * @param rarity The relative chance that this item will spawn, Vanilla has - * most of its items set to 1. Like the saddle, bread, silk, wheat, etc.. - * Rarer items are set to lower values, EXA: Golden Apple 0.01 - * @param minCount When this item does generate, the minimum number that is in the stack - * @param maxCount When this item does generate, the maximum number that can bein the stack - * @return The new rarity of the loot. - */ - public static float addDungeonLoot(ItemStack item, int rarity, int minCount, int maxCount) - { - for (DungeonLoot loot : dungeonLoot) - { - if (loot.equals(item, minCount, maxCount)) - { - return loot.itemWeight += rarity; - } - } - - dungeonLoot.add(new DungeonLoot(rarity, item, minCount, maxCount)); - return rarity; - } - /** - * Removes a item stack from the dungeon loot list, this will remove all items - * as long as the item stack matches, it will not care about matching the stack - * size ranges perfectly. - * - * @param item The item stack to remove - */ - public static void removeDungeonLoot(ItemStack item) - { - removeDungeonLoot(item, -1, 0); - } - - /** - * Removes a item stack from the dungeon loot list. If 'minCount' parameter - * is greater then 0, it will only remove loot items that have the same exact - * stack size range as passed in by parameters. - * - * @param item The item stack to remove - * @param minCount The minimum count for the match check, if less then 0, - * the size check is skipped - * @param maxCount The max count used in match check when 'minCount' is >= 0 - */ - public static void removeDungeonLoot(ItemStack item, int minCount, int maxCount) - { - ArrayList lootTmp = (ArrayList)dungeonLoot.clone(); - if (minCount < 0) - { - for (DungeonLoot loot : lootTmp) - { - if (loot.equals(item)) - { - dungeonLoot.remove(loot); - } - } - } - else - { - for (DungeonLoot loot : lootTmp) - { - if (loot.equals(item, minCount, maxCount)) - { - dungeonLoot.remove(loot); - } - } - } - } - - /** - * Gets a random item stack to place in a dungeon chest during world generation - * @param rand World generation random number generator - * @return The item stack - */ - public static ItemStack getRandomDungeonLoot(Random rand) - { - DungeonLoot ret = (DungeonLoot)WeightedRandom.getRandomItem(rand, dungeonLoot); - if (ret != null) - { - return ret.generateStack(rand); - } - return null; - } - - public static class DungeonLoot extends WeightedRandomItem - { - private ItemStack itemStack; - private int minCount = 1; - private int maxCount = 1; - - /** - * @param item A item stack - * @param min Minimum stack size when randomly generating - * @param max Maximum stack size when randomly generating - */ - public DungeonLoot(int weight, ItemStack item, int min, int max) - { - super(weight); - this.itemStack = item; - minCount = min; - maxCount = max; - } - - /** - * Grabs a ItemStack ready to be added to the dungeon chest, - * the stack size will be between minCount and maxCount - * @param rand World gen random number generator - * @return The ItemStack to be added to the chest - */ - public ItemStack generateStack(Random rand) - { - ItemStack ret = this.itemStack.copy(); - ret.stackSize = minCount + (rand.nextInt(maxCount - minCount + 1)); - return ret; - } - - public boolean equals(ItemStack item, int min, int max) - { - return (min == minCount && max == maxCount && item.isItemEqual(this.itemStack) && ItemStack.areItemStackTagsEqual(item, this.itemStack)); - } - - public boolean equals(ItemStack item) - { - return item.isItemEqual(this.itemStack) && ItemStack.areItemStackTagsEqual(item, this.itemStack); - } - } public static class DungeonMob extends WeightedRandomItem { @@ -263,33 +103,67 @@ public class DungeonHooks } } - public void addDungeonLoot(DungeonLoot loot) - { - dungeonLoot.add(loot); - } - - public boolean removeDungeonLoot(DungeonLoot loot) - { - return dungeonLoot.remove(loot); - } - static { addDungeonMob("Skeleton", 100); addDungeonMob("Zombie", 200); addDungeonMob("Spider", 100); + } - addDungeonLoot(new ItemStack(Item.saddle), 100 ); - addDungeonLoot(new ItemStack(Item.ingotIron), 100, 1, 4); - addDungeonLoot(new ItemStack(Item.bread), 100 ); - addDungeonLoot(new ItemStack(Item.wheat), 100, 1, 4); - addDungeonLoot(new ItemStack(Item.gunpowder), 100, 1, 4); - addDungeonLoot(new ItemStack(Item.silk), 100, 1, 4); - addDungeonLoot(new ItemStack(Item.bucketEmpty), 100 ); - addDungeonLoot(new ItemStack(Item.appleGold), 001 ); - addDungeonLoot(new ItemStack(Item.redstone), 050, 1, 4); - addDungeonLoot(new ItemStack(Item.record13), 005 ); - addDungeonLoot(new ItemStack(Item.recordCat), 005 ); - addDungeonLoot(new ItemStack(Item.dyePowder, 1, 3), 100 ); + + @Deprecated //Moved to ChestGenHooks + public static void setDungeonLootTries(int number) + { + ChestGenHooks.getInfo(DUNGEON_CHEST).setMax(number); + ChestGenHooks.getInfo(DUNGEON_CHEST).setMin(number); + } + @Deprecated //Moved to ChestGenHooks + public static int getDungeonLootTries() { return ChestGenHooks.getInfo(DUNGEON_CHEST).getMax(); } + @Deprecated //Moved to ChestGenHooks + public void addDungeonLoot(DungeonLoot loot){ ChestGenHooks.getInfo(DUNGEON_CHEST).addItem(loot); } + @Deprecated //Moved to ChestGenHooks + public boolean removeDungeonLoot(DungeonLoot loot){ return ChestGenHooks.getInfo(DUNGEON_CHEST).contents.remove(loot); } + @Deprecated //Moved to ChestGenHooks + public static void addDungeonLoot(ItemStack item, int rarity){ addDungeonLoot(item, rarity, 1, 1); } + @Deprecated //Moved to ChestGenHooks + public static float addDungeonLoot(ItemStack item, int rarity, int minCount, int maxCount) + { + ChestGenHooks.addDungeonLoot(ChestGenHooks.getInfo(DUNGEON_CHEST), item, rarity, minCount, maxCount); + return rarity; + } + @Deprecated //Moved to ChestGenHooks + public static void removeDungeonLoot(ItemStack item){ ChestGenHooks.removeItem(DUNGEON_CHEST, item); } + @Deprecated //Moved to ChestGenHooks + public static void removeDungeonLoot(ItemStack item, int minCount, int maxCount){ ChestGenHooks.removeItem(DUNGEON_CHEST, item); } + @Deprecated //Moved to ChestGenHooks + public static ItemStack getRandomDungeonLoot(Random rand){ return ChestGenHooks.getOneItem(DUNGEON_CHEST, rand); } + + @Deprecated //Moved to ChestGenHooks + public static class DungeonLoot extends WeightedRandomChestContent + { + @Deprecated + public DungeonLoot(int weight, ItemStack item, int min, int max) + { + super(item, weight, min, max); + } + + @Deprecated + public ItemStack generateStack(Random rand) + { + int min = theMinimumChanceToGenerateItem; + int max = theMaximumChanceToGenerateItem; + + ItemStack ret = this.theItemId.copy(); + ret.stackSize = min + (rand.nextInt(max - min + 1)); + return ret; + } + + public boolean equals(ItemStack item, int min, int max) + { + int minCount = theMinimumChanceToGenerateItem; + int maxCount = theMaximumChanceToGenerateItem; + return (min == minCount && max == maxCount && item.isItemEqual(theItemId) && ItemStack.areItemStackTagsEqual(item, theItemId)); + } + public boolean equals(ItemStack item){ return item.isItemEqual(theItemId) && ItemStack.areItemStackTagsEqual(item, theItemId); } } } diff --git a/patches/minecraft/net/minecraft/util/WeightedRandomChestContent.java.patch b/patches/minecraft/net/minecraft/util/WeightedRandomChestContent.java.patch index 77aaca2b7..caca7b31f 100644 --- a/patches/minecraft/net/minecraft/util/WeightedRandomChestContent.java.patch +++ b/patches/minecraft/net/minecraft/util/WeightedRandomChestContent.java.patch @@ -1,29 +1,48 @@ --- ../src_base/minecraft/net/minecraft/util/WeightedRandomChestContent.java +++ ../src_work/minecraft/net/minecraft/util/WeightedRandomChestContent.java -@@ -4,6 +4,7 @@ +@@ -1,9 +1,13 @@ + package net.minecraft.util; + + import java.util.Random; ++ ++import cpw.mods.fml.common.FMLLog; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntityChest; import net.minecraft.tileentity.TileEntityDispenser; +import net.minecraftforge.common.ChestGenHooks; ++import net.minecraftforge.common.DungeonHooks; public class WeightedRandomChestContent extends WeightedRandomItem { -@@ -40,22 +41,11 @@ +@@ -35,27 +39,26 @@ + /** + * Generates the Chest contents. + */ ++ @SuppressWarnings("deprecation") + public static void generateChestContents(Random par0Random, WeightedRandomChestContent[] par1ArrayOfWeightedRandomChestContent, TileEntityChest par2TileEntityChest, int par3) + { for (int var4 = 0; var4 < par3; ++var4) { WeightedRandomChestContent var5 = (WeightedRandomChestContent)WeightedRandom.getRandomItem(par0Random, par1ArrayOfWeightedRandomChestContent); - int var6 = var5.theMinimumChanceToGenerateItem + par0Random.nextInt(var5.theMaximumChanceToGenerateItem - var5.theMinimumChanceToGenerateItem + 1); -+ ItemStack[] stacks = ChestGenHooks.generateStacks(par0Random, var5.theItemId, var5.theMinimumChanceToGenerateItem, var5.theMaximumChanceToGenerateItem); - if (var5.theItemId.getMaxStackSize() >= var6) -+ for (ItemStack item : stacks) ++ if (var5 instanceof DungeonHooks.DungeonLoot) { - ItemStack var7 = var5.theItemId.copy(); - var7.stackSize = var6; - par2TileEntityChest.setInventorySlotContents(par0Random.nextInt(par2TileEntityChest.getSizeInventory()), var7); -- } ++ DungeonHooks.DungeonLoot loot = (DungeonHooks.DungeonLoot)var5; ++ par2TileEntityChest.setInventorySlotContents(par0Random.nextInt(par2TileEntityChest.getSizeInventory()), loot.generateStack(par0Random)); ++ FMLLog.warning("Some mod is still using DungeonHooks.DungonLoot, tell them to stop! %s", loot); ++ continue; + } - else -- { ++ ++ ItemStack[] stacks = ChestGenHooks.generateStacks(par0Random, var5.theItemId, var5.theMinimumChanceToGenerateItem, var5.theMaximumChanceToGenerateItem); ++ ++ for (ItemStack item : stacks) + { - for (int var9 = 0; var9 < var6; ++var9) - { - ItemStack var8 = var5.theItemId.copy(); @@ -34,7 +53,7 @@ } } } -@@ -68,22 +58,11 @@ +@@ -68,22 +71,11 @@ for (int var4 = 0; var4 < par3; ++var4) { WeightedRandomChestContent var5 = (WeightedRandomChestContent)WeightedRandom.getRandomItem(par0Random, par1ArrayOfWeightedRandomChestContent); diff --git a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenDungeons.java.patch b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenDungeons.java.patch index b2be14dbb..b73319808 100644 --- a/patches/minecraft/net/minecraft/world/gen/feature/WorldGenDungeons.java.patch +++ b/patches/minecraft/net/minecraft/world/gen/feature/WorldGenDungeons.java.patch @@ -1,33 +1,53 @@ --- ../src_base/minecraft/net/minecraft/world/gen/feature/WorldGenDungeons.java +++ ../src_work/minecraft/net/minecraft/world/gen/feature/WorldGenDungeons.java -@@ -8,6 +8,9 @@ +@@ -7,7 +7,13 @@ + import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntityChest; import net.minecraft.tileentity.TileEntityMobSpawner; ++import net.minecraft.util.WeightedRandom; ++import net.minecraft.util.WeightedRandomChestContent; import net.minecraft.world.World; + ++import net.minecraftforge.common.ChestGenHooks; +import net.minecraftforge.common.DungeonHooks; +import net.minecraftforge.common.MinecraftForge; public class WorldGenDungeons extends WorldGenerator { -@@ -124,9 +127,9 @@ +@@ -124,15 +130,8 @@ if (var16 != null) { - for (int var17 = 0; var17 < 8; ++var17) -+ for (int var17 = 0; var17 < DungeonHooks.getDungeonLootTries(); ++var17) - { +- { - ItemStack var18 = this.pickCheckLootItem(par2Random); -+ ItemStack var18 = DungeonHooks.getRandomDungeonLoot(par2Random); +- +- if (var18 != null) +- { +- var16.setInventorySlotContents(par2Random.nextInt(var16.getSizeInventory()), var18); +- } +- } ++ ChestGenHooks info = ChestGenHooks.getInfo(ChestGenHooks.DUNGEON_CHEST); ++ WeightedRandomChestContent.generateChestContents(par2Random, info.getItems(par2Random), var16, info.getCount(par2Random)); + } - if (var18 != null) - { -@@ -154,7 +157,7 @@ + break label210; +@@ -174,8 +173,7 @@ + */ + private ItemStack pickCheckLootItem(Random par1Random) + { +- int var2 = par1Random.nextInt(12); +- return var2 == 0 ? new ItemStack(Item.saddle) : (var2 == 1 ? new ItemStack(Item.ingotIron, par1Random.nextInt(4) + 1) : (var2 == 2 ? new ItemStack(Item.bread) : (var2 == 3 ? new ItemStack(Item.wheat, par1Random.nextInt(4) + 1) : (var2 == 4 ? new ItemStack(Item.gunpowder, par1Random.nextInt(4) + 1) : (var2 == 5 ? new ItemStack(Item.silk, par1Random.nextInt(4) + 1) : (var2 == 6 ? new ItemStack(Item.bucketEmpty) : (var2 == 7 && par1Random.nextInt(100) == 0 ? new ItemStack(Item.appleGold) : (var2 == 8 && par1Random.nextInt(2) == 0 ? new ItemStack(Item.redstone, par1Random.nextInt(4) + 1) : (var2 == 9 && par1Random.nextInt(10) == 0 ? new ItemStack(Item.itemsList[Item.record13.shiftedIndex + par1Random.nextInt(2)]) : (var2 == 10 ? new ItemStack(Item.dyePowder, 1, 3) : (var2 == 11 ? Item.field_92053_bW.func_92055_a(par1Random) : null))))))))))); ++ return ChestGenHooks.getOneItem(ChestGenHooks.DUNGEON_CHEST, par1Random); + } - if (var19 != null) - { -- var19.setMobID(this.pickMobSpawner(par2Random)); -+ var19.setMobID(DungeonHooks.getRandomDungeonMob(par2Random)); - } - else - { + /** +@@ -183,7 +181,6 @@ + */ + private String pickMobSpawner(Random par1Random) + { +- int var2 = par1Random.nextInt(4); +- return var2 == 0 ? "Skeleton" : (var2 == 1 ? "Zombie" : (var2 == 2 ? "Zombie" : (var2 == 3 ? "Spider" : ""))); ++ return DungeonHooks.getRandomDungeonMob(par1Random); + } + }