001 package net.minecraftforge.common; 002 003 import java.util.ArrayList; 004 import java.util.Random; 005 006 import net.minecraft.item.Item; 007 import net.minecraft.item.ItemStack; 008 import net.minecraft.util.WeightedRandom; 009 import net.minecraft.util.WeightedRandomItem; 010 011 public class DungeonHooks 012 { 013 private static int dungeonLootAttempts = 8; 014 private static ArrayList<DungeonMob> dungeonMobs = new ArrayList<DungeonMob>(); 015 private static ArrayList<DungeonLoot> dungeonLoot = new ArrayList<DungeonLoot>(); 016 /** 017 * Set the number of item stacks that will be attempted to be added to each Dungeon chest. 018 * Note: Due to random number generation, you will not always get this amount per chest. 019 * @param number The maximum number of item stacks to add to a chest. 020 */ 021 public static void setDungeonLootTries(int number) 022 { 023 dungeonLootAttempts = number; 024 } 025 026 /** 027 * @return The max number of item stacks found in each dungeon chest. 028 */ 029 public static int getDungeonLootTries() 030 { 031 return dungeonLootAttempts; 032 } 033 034 /** 035 * Adds a mob to the possible list of creatures the spawner will create. 036 * If the mob is already in the spawn list, the rarity will be added to the existing one, 037 * causing the mob to be more common. 038 * 039 * @param name The name of the monster, use the same name used when registering the entity. 040 * @param rarity The rarity of selecting this mob over others. Must be greater then 0. 041 * Vanilla Minecraft has the following mobs: 042 * Spider 100 043 * Skeleton 100 044 * Zombie 200 045 * Meaning, Zombies are twice as common as spiders or skeletons. 046 * @return The new rarity of the monster, 047 */ 048 public static float addDungeonMob(String name, int rarity) 049 { 050 if (rarity <= 0) 051 { 052 throw new IllegalArgumentException("Rarity must be greater then zero"); 053 } 054 055 for (DungeonMob mob : dungeonMobs) 056 { 057 if (name.equals(mob.type)) 058 { 059 return mob.itemWeight += rarity; 060 } 061 } 062 063 dungeonMobs.add(new DungeonMob(rarity, name)); 064 return rarity; 065 } 066 067 /** 068 * Will completely remove a Mob from the dungeon spawn list. 069 * 070 * @param name The name of the mob to remove 071 * @return The rarity of the removed mob, prior to being removed. 072 */ 073 public static int removeDungeonMob(String name) 074 { 075 for (DungeonMob mob : dungeonMobs) 076 { 077 if (name.equals(mob.type)) 078 { 079 dungeonMobs.remove(mob); 080 return mob.itemWeight; 081 } 082 } 083 return 0; 084 } 085 086 /** 087 * Gets a random mob name from the list. 088 * @param rand World generation random number generator 089 * @return The mob name 090 */ 091 public static String getRandomDungeonMob(Random rand) 092 { 093 DungeonMob mob = (DungeonMob)WeightedRandom.getRandomItem(rand, dungeonMobs); 094 if (mob == null) 095 { 096 return ""; 097 } 098 return mob.type; 099 } 100 101 /** 102 * Adds a item stack to the dungeon loot list with a stack size 103 * of 1. 104 * 105 * @param item The ItemStack to be added to the loot list 106 * @param rarity The relative chance that this item will spawn, Vanilla has 107 * most of its items set to 1. Like the saddle, bread, silk, wheat, etc.. 108 * Rarer items are set to lower values, EXA: Golden Apple 0.01 109 */ 110 public static void addDungeonLoot(ItemStack item, int rarity) 111 { 112 addDungeonLoot(item, rarity, 1, 1); 113 } 114 115 /** 116 * Adds a item stack, with a range of sizes, to the dungeon loot list. 117 * If a stack matching the same item, and size range, is already in the list 118 * the rarities will be added together making the item more common. 119 * 120 * @param item The ItemStack to be added to the loot list 121 * @param rarity The relative chance that this item will spawn, Vanilla has 122 * most of its items set to 1. Like the saddle, bread, silk, wheat, etc.. 123 * Rarer items are set to lower values, EXA: Golden Apple 0.01 124 * @param minCount When this item does generate, the minimum number that is in the stack 125 * @param maxCount When this item does generate, the maximum number that can bein the stack 126 * @return The new rarity of the loot. 127 */ 128 public static float addDungeonLoot(ItemStack item, int rarity, int minCount, int maxCount) 129 { 130 for (DungeonLoot loot : dungeonLoot) 131 { 132 if (loot.equals(item, minCount, maxCount)) 133 { 134 return loot.itemWeight += rarity; 135 } 136 } 137 138 dungeonLoot.add(new DungeonLoot(rarity, item, minCount, maxCount)); 139 return rarity; 140 } 141 /** 142 * Removes a item stack from the dungeon loot list, this will remove all items 143 * as long as the item stack matches, it will not care about matching the stack 144 * size ranges perfectly. 145 * 146 * @param item The item stack to remove 147 */ 148 public static void removeDungeonLoot(ItemStack item) 149 { 150 removeDungeonLoot(item, -1, 0); 151 } 152 153 /** 154 * Removes a item stack from the dungeon loot list. If 'minCount' parameter 155 * is greater then 0, it will only remove loot items that have the same exact 156 * stack size range as passed in by parameters. 157 * 158 * @param item The item stack to remove 159 * @param minCount The minimum count for the match check, if less then 0, 160 * the size check is skipped 161 * @param maxCount The max count used in match check when 'minCount' is >= 0 162 */ 163 public static void removeDungeonLoot(ItemStack item, int minCount, int maxCount) 164 { 165 ArrayList<DungeonLoot> lootTmp = (ArrayList<DungeonLoot>)dungeonLoot.clone(); 166 if (minCount < 0) 167 { 168 for (DungeonLoot loot : lootTmp) 169 { 170 if (loot.equals(item)) 171 { 172 dungeonLoot.remove(loot); 173 } 174 } 175 } 176 else 177 { 178 for (DungeonLoot loot : lootTmp) 179 { 180 if (loot.equals(item, minCount, maxCount)) 181 { 182 dungeonLoot.remove(loot); 183 } 184 } 185 } 186 } 187 188 /** 189 * Gets a random item stack to place in a dungeon chest during world generation 190 * @param rand World generation random number generator 191 * @return The item stack 192 */ 193 public static ItemStack getRandomDungeonLoot(Random rand) 194 { 195 DungeonLoot ret = (DungeonLoot)WeightedRandom.getRandomItem(rand, dungeonLoot); 196 if (ret != null) 197 { 198 return ret.generateStack(rand); 199 } 200 return null; 201 } 202 203 public static class DungeonLoot extends WeightedRandomItem 204 { 205 private ItemStack itemStack; 206 private int minCount = 1; 207 private int maxCount = 1; 208 209 /** 210 * @param item A item stack 211 * @param min Minimum stack size when randomly generating 212 * @param max Maximum stack size when randomly generating 213 */ 214 public DungeonLoot(int weight, ItemStack item, int min, int max) 215 { 216 super(weight); 217 this.itemStack = item; 218 minCount = min; 219 maxCount = max; 220 } 221 222 /** 223 * Grabs a ItemStack ready to be added to the dungeon chest, 224 * the stack size will be between minCount and maxCount 225 * @param rand World gen random number generator 226 * @return The ItemStack to be added to the chest 227 */ 228 public ItemStack generateStack(Random rand) 229 { 230 ItemStack ret = this.itemStack.copy(); 231 ret.stackSize = minCount + (rand.nextInt(maxCount - minCount + 1)); 232 return ret; 233 } 234 235 public boolean equals(ItemStack item, int min, int max) 236 { 237 return (min == minCount && max == maxCount && item.isItemEqual(this.itemStack)); 238 } 239 240 public boolean equals(ItemStack item) 241 { 242 return item.isItemEqual(this.itemStack); 243 } 244 } 245 246 public static class DungeonMob extends WeightedRandomItem 247 { 248 public String type; 249 public DungeonMob(int weight, String type) 250 { 251 super(weight); 252 this.type = type; 253 } 254 255 @Override 256 public boolean equals(Object target) 257 { 258 if (target instanceof DungeonMob) 259 { 260 return this.type.equals(((DungeonMob)target).type); 261 } 262 return false; 263 } 264 } 265 266 public void addDungeonLoot(DungeonLoot loot) 267 { 268 dungeonLoot.add(loot); 269 } 270 271 public boolean removeDungeonLoot(DungeonLoot loot) 272 { 273 return dungeonLoot.remove(loot); 274 } 275 276 static 277 { 278 addDungeonMob("Skeleton", 100); 279 addDungeonMob("Zombie", 200); 280 addDungeonMob("Spider", 100); 281 282 addDungeonLoot(new ItemStack(Item.saddle), 100 ); 283 addDungeonLoot(new ItemStack(Item.ingotIron), 100, 1, 4); 284 addDungeonLoot(new ItemStack(Item.bread), 100 ); 285 addDungeonLoot(new ItemStack(Item.wheat), 100, 1, 4); 286 addDungeonLoot(new ItemStack(Item.gunpowder), 100, 1, 4); 287 addDungeonLoot(new ItemStack(Item.silk), 100, 1, 4); 288 addDungeonLoot(new ItemStack(Item.bucketEmpty), 100 ); 289 addDungeonLoot(new ItemStack(Item.appleGold), 001 ); 290 addDungeonLoot(new ItemStack(Item.redstone), 050, 1, 4); 291 addDungeonLoot(new ItemStack(Item.record13), 005 ); 292 addDungeonLoot(new ItemStack(Item.recordCat), 005 ); 293 addDungeonLoot(new ItemStack(Item.dyePowder, 1, 3), 100 ); 294 } 295 }