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.
This commit is contained in:
LexManos 2012-12-24 01:29:33 -08:00
parent dedc02fa22
commit e78b825875
4 changed files with 164 additions and 208 deletions

View file

@ -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<String, ChestGenHooks> chestInfo = new HashMap<String, ChestGenHooks>();
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<WeightedRandomChestContent> contents = new ArrayList<WeightedRandomChestContent>();
//TO-DO: Privatize this once again when we remove the Deprecated stuff in DungeonHooks
ArrayList<WeightedRandomChestContent> contents = new ArrayList<WeightedRandomChestContent>();
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; }

View file

@ -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<DungeonMob> dungeonMobs = new ArrayList<DungeonMob>();
private static ArrayList<DungeonLoot> dungeonLoot = new ArrayList<DungeonLoot>();
/**
* 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<DungeonLoot> lootTmp = (ArrayList<DungeonLoot>)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); }
}
}

View file

@ -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);

View file

@ -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);
}
}