001 package net.minecraftforge.common;
002
003 import java.util.ArrayList;
004 import java.util.Random;
005
006 import net.minecraft.src.Item;
007 import net.minecraft.src.ItemStack;
008 import net.minecraft.src.WeightedRandom;
009 import net.minecraft.src.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 }