Overhauled Loot

Changed our loot generation. Instead of relying on Minecraft's built-in
loot categories, we now have our own static loot category. There are two
types of chests now. Regular chests contain randomly-picked coal, iron,
gold, diamonds, emeralds, quartz, enchanted books, and golden apples
(very rare). We also have a function for filling out "grave chests",
which occur in 1 out of every 7 chests. Those contain rotten flesh,
bones, and some armor pieces and equipment that are assigned random
damage values and occasionally also get level 1 enchantments. Small
changes were made to various files to incorporate this update.
This commit is contained in:
SenseiKiwi
2013-12-22 18:30:16 -04:00
parent 75e103aa65
commit a6048c6c29
5 changed files with 221 additions and 158 deletions

View File

@@ -1,145 +1,61 @@
package StevenDimDoors.mod_pocketDim; package StevenDimDoors.mod_pocketDim;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random; import java.util.Random;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.inventory.IInventory; import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.MathHelper;
import net.minecraft.util.WeightedRandom; import net.minecraft.util.WeightedRandom;
import net.minecraft.util.WeightedRandomChestContent; import net.minecraft.util.WeightedRandomChestContent;
import net.minecraftforge.common.ChestGenHooks; import net.minecraftforge.common.ChestGenHooks;
import StevenDimDoors.mod_pocketDim.util.WeightedContainer;
/* /*
* Registers a category of loot chests for Dimensional Doors in Forge. * Registers a category of loot chests for Dimensional Doors in Forge.
*/ */
public class DDLoot { public class DDLoot {
//These are the categories of loot to be merged into our chests private static final double MIN_ITEM_DAMAGE = 0.3;
static final String[] chestSources = new String[] { private static final double MAX_ITEM_DAMAGE = 0.9;
ChestGenHooks.MINESHAFT_CORRIDOR, private static final int ITEM_ENCHANTMENT_CHANCE = 50;
ChestGenHooks.PYRAMID_DESERT_CHEST, private static final int MAX_ITEM_ENCHANTMENT_CHANCE = 100;
ChestGenHooks.PYRAMID_JUNGLE_CHEST,
ChestGenHooks.STRONGHOLD_CORRIDOR,
ChestGenHooks.STRONGHOLD_CROSSING,
ChestGenHooks.VILLAGE_BLACKSMITH,
ChestGenHooks.DUNGEON_CHEST
};
public static final String DIMENSIONAL_DUNGEON_CHEST = "dimensionalDungeonChest"; public static final String DIMENSIONAL_DUNGEON_CHEST = "dimensionalDungeonChest";
public static ChestGenHooks DungeonChestInfo = null; public static ChestGenHooks DungeonChestInfo = null;
private static final int CHEST_SIZE = 5; private static final int CHEST_SIZE = 5;
private static final int COMMON_LOOT_WEIGHT = 9; //1 less than weight of iron ingots
private static final int UNCOMMON_LOOT_WEIGHT = 4; //1 less than weight of iron armor
private static final int RARE_LOOT_WEIGHT = 1; //Same weight as music discs, golden apple
private static final int DUNGEON_CHEST_WEIGHT_INFLATION = 10; // (weight of iron ingots in dungeon) / (weight of iron ingots in other chests)
private DDLoot() { } private DDLoot() { }
public static void registerInfo() public static void registerInfo(DDProperties properties)
{ {
DDProperties properties = DDProperties.instance(); // Register the dimensional dungeon chest with ChestGenHooks. This isn't necessary, but allows
// other mods to add their own loot to our chests if they know our loot category, without having
//Register the dimensional dungeon chest with ChestGenHooks. This isn't necessary, but allows // to interface with our code.
//other mods to add their own loot to our chests if they know our loot category, without having
//to interface with our code.
DungeonChestInfo = ChestGenHooks.getInfo(DIMENSIONAL_DUNGEON_CHEST); DungeonChestInfo = ChestGenHooks.getInfo(DIMENSIONAL_DUNGEON_CHEST);
DungeonChestInfo.setMin(CHEST_SIZE); DungeonChestInfo.setMin(CHEST_SIZE);
DungeonChestInfo.setMax(CHEST_SIZE); DungeonChestInfo.setMax(CHEST_SIZE);
//Merge the item lists from source chests ArrayList<WeightedRandomChestContent> items = new ArrayList<WeightedRandomChestContent>();
//This means chests will include future loot as Minecraft updates! ^_^
ArrayList<WeightedRandomChestContent> items = mergeCategories(chestSources);
//Add any enabled DD loot to the list of items addContent(true, items, Item.ingotIron.itemID, 160, 1, 3);
addContent(properties.FabricOfRealityLootEnabled, items, mod_pocketDim.blockDimWall.blockID, 8, 32, COMMON_LOOT_WEIGHT); addContent(true, items, Item.coal.itemID, 120, 1, 3);
addContent(true, items, Item.netherQuartz.itemID, 120, 1, 3);
addContent(true, items, Item.enchantedBook.itemID, 100);
addContent(true, items, Item.ingotGold.itemID, 80, 1, 3);
addContent(true, items, Item.diamond.itemID, 40, 1, 2);
addContent(true, items, Item.emerald.itemID, 20, 1, 2);
addContent(true, items, Item.appleGold.itemID, 10);
addContent(properties.DimensionalDoorLootEnabled, items, mod_pocketDim.itemDimDoor.itemID, UNCOMMON_LOOT_WEIGHT); addContent(properties.FabricOfRealityLootEnabled, items, mod_pocketDim.blockDimWall.blockID, 80, 4, 16);
addContent(properties.WarpDoorLootEnabled, items, mod_pocketDim.itemExitDoor.itemID, UNCOMMON_LOOT_WEIGHT); addContent(properties.StableFabricLootEnabled, items, mod_pocketDim.itemStableFabric.itemID, 40);
addContent(properties.TransTrapdoorLootEnabled, items, mod_pocketDim.transTrapdoor.blockID, UNCOMMON_LOOT_WEIGHT);
addContent(properties.RiftSignatureLootEnabled, items, mod_pocketDim.itemLinkSignature.itemID, UNCOMMON_LOOT_WEIGHT);
addContent(properties.StableFabricLootEnabled, items, mod_pocketDim.itemStableFabric.itemID, UNCOMMON_LOOT_WEIGHT);
addContent(properties.RiftRemoverLootEnabled, items, mod_pocketDim.itemRiftRemover.itemID, UNCOMMON_LOOT_WEIGHT);
addContent(properties.UnstableDoorLootEnabled, items, mod_pocketDim.itemChaosDoor.itemID, RARE_LOOT_WEIGHT); // Add all the items to our dungeon chest
addContent(properties.StabilizedRiftSignatureLootEnabled, items, mod_pocketDim.itemStabilizedLinkSignature.itemID, RARE_LOOT_WEIGHT);
addContent(properties.RiftBladeLootEnabled, items, mod_pocketDim.itemRiftBlade.itemID, RARE_LOOT_WEIGHT);
//Add all the items to our dungeon chest
addItemsToContainer(DungeonChestInfo, items); addItemsToContainer(DungeonChestInfo, items);
} }
private static ArrayList<WeightedRandomChestContent> mergeCategories(String[] categories)
{
//Retrieve the items of each container category and merge the lists together. If two matching items
//are found, choose the item with the minimum weight. Special checks are included for DUNGEON_CHEST
//because the items in that category have strange weights that are incompatible with all other
//chest categories.
Random random = new Random();
HashMap<Integer, WeightedRandomChestContent> container = new HashMap<Integer, WeightedRandomChestContent>();
for (String category : categories)
{
WeightedRandomChestContent[] items = ChestGenHooks.getItems(category, random);
for (WeightedRandomChestContent item : items)
{
ItemStack stack = item.theItemId;
int id = stack.itemID;
int subtype = stack.getItem().getHasSubtypes() ? stack.getItemDamage() : 0;
//Correct the weights of Vanilla dungeon chests (DUNGEON_CHEST)
//Comparing by String references is valid here since they should match!
if (category == ChestGenHooks.DUNGEON_CHEST)
{
//It's okay to modify the weights directly. These are copies of instances,
//not direct references. It won't affect Vanilla chests.
item.itemWeight /= DUNGEON_CHEST_WEIGHT_INFLATION;
if (item.itemWeight == 0)
item.itemWeight = 1;
}
//Generate an identifier for this item using its item ID and damage value,
//if it has subtypes. This solves the issue of matching items that have
//the same item ID but different subtypes (e.g. wood planks, dyes).
int key = ((subtype & 0xFFFF) << 16) + ((id & 0xFFFF) << 16);
WeightedRandomChestContent other = container.get(key);
if (other == null)
{
//This item has not been seen before. Simply add it to the container.
container.put(key, item);
}
else
{
//This item conflicts with an existing entry. Replace that entry
//if our current item has a lower weight.
if (item.itemWeight < other.itemWeight)
{
container.put(key, item);
}
}
}
}
//I've added a minor hack here to make enchanted books more common
//If this is necessary for more items, create an override table and use that
//rather than hardcoding the changes below
final int enchantedBookID = Item.enchantedBook.itemID;
for (WeightedRandomChestContent item : container.values())
{
if (item.theItemId.itemID == enchantedBookID)
{
item.itemWeight = 4;
break;
}
}
//Return merged list
return new ArrayList<WeightedRandomChestContent>( container.values() );
}
private static void addContent(boolean include, ArrayList<WeightedRandomChestContent> items, private static void addContent(boolean include, ArrayList<WeightedRandomChestContent> items,
int itemID, int weight) int itemID, int weight)
{ {
@@ -148,7 +64,7 @@ public class DDLoot {
} }
private static void addContent(boolean include, ArrayList<WeightedRandomChestContent> items, private static void addContent(boolean include, ArrayList<WeightedRandomChestContent> items,
int itemID, int minAmount, int maxAmount, int weight) int itemID, int weight, int minAmount, int maxAmount)
{ {
if (include) if (include)
items.add(new WeightedRandomChestContent(itemID, 0, minAmount, maxAmount, weight)); items.add(new WeightedRandomChestContent(itemID, 0, minAmount, maxAmount, weight));
@@ -156,57 +72,191 @@ public class DDLoot {
private static void addItemsToContainer(ChestGenHooks container, ArrayList<WeightedRandomChestContent> items) private static void addItemsToContainer(ChestGenHooks container, ArrayList<WeightedRandomChestContent> items)
{ {
//System.out.println("Preparing Chest Stuff");
for (WeightedRandomChestContent item : items) for (WeightedRandomChestContent item : items)
{ {
container.addItem(item); container.addItem(item);
//Uncomment this code to print out loot and weight pairs
//System.out.println(item.theItemId.getDisplayName() + "\t" + item.itemWeight);
} }
} }
private static void fillChest(ArrayList<ItemStack> stacks, IInventory inventory, Random random)
{
// This custom chest-filling function avoids overwriting item stacks
// The prime number below is used for choosing chest slots in a seemingly-random pattern. Its value
// was selected specifically to achieve a spread-out distribution for chests with up to 104 slots.
// Choosing a prime number ensures that our increments are relatively-prime to the chest size, which
// means we'll cover all the slots before repeating any. This is mathematically guaranteed.
final int primeOffset = 239333;
int size = inventory.getSizeInventory();
for (ItemStack item : stacks)
{
int limit = size;
int index = random.nextInt(size);
while (limit > 0 && inventory.getStackInSlot(index) != null)
{
limit--;
index = (index + primeOffset) % size;
}
inventory.setInventorySlotContents(index, item);
}
}
public static void generateChestContents(ChestGenHooks chestInfo, IInventory inventory, Random random) public static void generateChestContents(ChestGenHooks chestInfo, IInventory inventory, Random random)
{ {
//This is a custom version of net.minecraft.util.WeightedRandomChestContent.generateChestContents() // This is a custom version of net.minecraft.util.WeightedRandomChestContent.generateChestContents()
//It's designed to avoid the following bugs in MC 1.5: // It's designed to avoid the following bugs in MC 1.5:
//1. The randomized filling algorithm will sometimes overwrite item stacks with other stacks // 1. If multiple enchanted books appear, then they will have the same enchantment
//2. If multiple enchanted books appear, then they will have the same enchantment // 2. The randomized filling algorithm will sometimes overwrite item stacks with other stacks
//The prime number below is used for choosing chest slots in a seemingly-random pattern. Its value
//was selected specifically to achieve a spread-out distribution for chests with up to 104 slots.
//Choosing a prime number ensures that our increments are relatively-prime to the chest size, which
//means we'll cover all the slots before repeating any. This is mathematically guaranteed.
final int primeOffset = 239333;
int count = chestInfo.getCount(random); int count = chestInfo.getCount(random);
int size = inventory.getSizeInventory();
WeightedRandomChestContent[] content = chestInfo.getItems(random); WeightedRandomChestContent[] content = chestInfo.getItems(random);
ArrayList<ItemStack> allStacks = new ArrayList<ItemStack>();
for (int k = 0; k < count; k++) for (int k = 0; k < count; k++)
{ {
WeightedRandomChestContent selection = (WeightedRandomChestContent)WeightedRandom.getRandomItem(random, content); WeightedRandomChestContent selection = (WeightedRandomChestContent)WeightedRandom.getRandomItem(random, content);
//Call getChestGenBase() to make sure we generate a different enchantment for books. // Call getChestGenBase() to make sure we generate a different enchantment for books.
//Don't just use a condition to check if the item is an instance of ItemEnchantedBook because // Don't just use a condition to check if the item is an instance of ItemEnchantedBook because
//we don't know if other mods might add items that also need to be regenerated. // we don't know if other mods might add items that also need to be regenerated.
selection = selection.theItemId.getItem().getChestGenBase(chestInfo, random, selection); selection = selection.theItemId.getItem().getChestGenBase(chestInfo, random, selection);
ItemStack[] stacks = ChestGenHooks.generateStacks(random, selection.theItemId, selection.theMinimumChanceToGenerateItem, selection.theMaximumChanceToGenerateItem); ItemStack[] stacks = ChestGenHooks.generateStacks(random, selection.theItemId, selection.theMinimumChanceToGenerateItem, selection.theMaximumChanceToGenerateItem);
for (int h = 0; h < stacks.length; h++)
for (ItemStack item : stacks)
{ {
int limit = size; allStacks.add(stacks[h]);
int index = random.nextInt(size);
while (limit > 0 && inventory.getStackInSlot(index) != null)
{
limit--;
index = (index + primeOffset) % size;
}
inventory.setInventorySlotContents(index, item);
} }
} }
fillChest(allStacks, inventory, random);
} }
public static void fillGraveChest(IInventory inventory, Random random, DDProperties properties)
{
// This function fills "grave chests", which are chests for dungeons that
// look like a player died in the area and his remains were gathered in
// a chest. Doing this properly requires fine control of loot generation,
// so we use our own function rather than Minecraft's functions.
int k;
int count;
ArrayList<ItemStack> stacks = new ArrayList<ItemStack>();
ArrayList<WeightedContainer<Item>> selection = new ArrayList<WeightedContainer<Item>>();
// Insert bones and rotten flesh
// Make stacks of single items to spread them out
count = MathHelper.getRandomIntegerInRange(random, 2, 5);
for (k = 0; k < count; k++)
{
stacks.add( new ItemStack(Item.bone, 1) );
}
count = MathHelper.getRandomIntegerInRange(random, 2, 4);
for (k = 0; k < count; k++)
{
stacks.add( new ItemStack(Item.rottenFlesh, 1) );
}
// Insert tools
// 30% chance of adding a pickaxe
if (random.nextInt(100) < 30)
{
addModifiedTool(Item.pickaxeIron, stacks, random);
}
// 30% chance of adding a bow and some arrows
if (random.nextInt(100) < 30)
{
addModifiedBow(stacks, random);
stacks.add( new ItemStack(Item.arrow, MathHelper.getRandomIntegerInRange(random, 8, 32)) );
}
// 10% chance of adding a Rift Blade (no enchants)
if (properties.RiftBladeLootEnabled && random.nextInt(100) < 10)
{
stacks.add( new ItemStack(mod_pocketDim.itemRiftBlade, 1) );
}
else
{
// 20% of adding an iron sword, 10% of adding a stone sword
addModifiedSword( getRandomItem(Item.swordIron, Item.swordStone, null, 20, 10, random) , stacks, random);
}
// Insert equipment
// For each piece, 25% of an iron piece, 10% of a chainmail piece
addModifiedEquipment( getRandomItem(Item.helmetIron, Item.helmetChain, null, 25, 10, random) , stacks, random);
addModifiedEquipment( getRandomItem(Item.plateIron, Item.plateChain, null, 25, 10, random) , stacks, random);
addModifiedEquipment( getRandomItem(Item.legsIron, Item.legsChain, null, 25, 10, random) , stacks, random);
addModifiedEquipment( getRandomItem(Item.bootsIron, Item.bootsChain, null, 25, 10, random) , stacks, random);
// Insert other random stuff
// 40% chance for a name tag, 35% chance for a glass bottle, and 5% chance for record 11
addItemWithChance(stacks, random, 40, Item.nameTag, 1);
addItemWithChance(stacks, random, 35, Item.glassBottle, 1);
addItemWithChance(stacks, random, 5, Item.record11, 1);
fillChest(stacks, inventory, random);
}
private static void addModifiedEquipment(Item item, ArrayList<ItemStack> stacks, Random random)
{
if (item == null)
return;
stacks.add( getModifiedItem(item, random, new Enchantment[] { Enchantment.blastProtection, Enchantment.fireProtection, Enchantment.protection, Enchantment.projectileProtection }) );
}
private static void addModifiedSword(Item item, ArrayList<ItemStack> stacks, Random random)
{
if (item == null)
return;
stacks.add( getModifiedItem(item, random, new Enchantment[] { Enchantment.fireAspect, Enchantment.knockback, Enchantment.sharpness }) );
}
private static void addModifiedTool(Item tool, ArrayList<ItemStack> stacks, Random random)
{
if (tool == null)
return;
stacks.add( getModifiedItem(tool, random, new Enchantment[] { Enchantment.efficiency, Enchantment.unbreaking }) );
}
private static void addModifiedBow(ArrayList<ItemStack> stacks, Random random)
{
stacks.add( getModifiedItem(Item.bow, random, new Enchantment[] { Enchantment.flame, Enchantment.power, Enchantment.punch }) );
}
private static ItemStack getModifiedItem(Item item, Random random, Enchantment[] enchantments)
{
ItemStack result = applyRandomDamage(item, random);
if (enchantments.length > 0 && random.nextInt(MAX_ITEM_ENCHANTMENT_CHANCE) < ITEM_ENCHANTMENT_CHANCE)
{
result.addEnchantment(enchantments[ random.nextInt(enchantments.length) ], 1);
}
return result;
}
private static Item getRandomItem(Item a, Item b, Item c, int weightA, int weightB, Random random)
{
int roll = random.nextInt(100);
if (roll < weightA)
return a;
if (roll < weightA + weightB)
return b;
return c;
}
private static void addItemWithChance(ArrayList<ItemStack> stacks, Random random, int chance, Item item, int count)
{
if (random.nextInt(100) < chance)
{
stacks.add(new ItemStack(item, count));
}
}
private static ItemStack applyRandomDamage(Item item, Random random)
{
int damage = (int) (item.getMaxDamage() * MathHelper.getRandomDoubleInRange(random, MIN_ITEM_DAMAGE, MAX_ITEM_DAMAGE));
return new ItemStack(item, 1, damage);
}
} }

View File

@@ -170,7 +170,7 @@ public class DungeonSchematic extends Schematic {
return new DungeonSchematic(Schematic.copyFromWorld(world, x, y, z, width, height, length, doCompactBounds)); return new DungeonSchematic(Schematic.copyFromWorld(world, x, y, z, width, height, length, doCompactBounds));
} }
public void copyToWorld(World world, Point3D pocketCenter, int targetOrientation, DimLink entryLink, Random random) public void copyToWorld(World world, Point3D pocketCenter, int targetOrientation, DimLink entryLink, Random random, DDProperties properties)
{ {
//TODO: This function is an improvised solution so we can get the release moving. In the future, //TODO: This function is an improvised solution so we can get the release moving. In the future,
//we should generalize block transformations and implement support for them at the level of Schematic, //we should generalize block transformations and implement support for them at the level of Schematic,
@@ -224,10 +224,10 @@ public class DungeonSchematic extends Schematic {
world.setBlockTileEntity(pocketPoint.getX(), pocketPoint.getY(), pocketPoint.getZ(), TileEntity.createAndLoadEntity(tileTag)); world.setBlockTileEntity(pocketPoint.getX(), pocketPoint.getY(), pocketPoint.getZ(), TileEntity.createAndLoadEntity(tileTag));
} }
setUpDungeon(PocketManager.getDimensionData(world), world, pocketCenter, turnAngle, entryLink, random); setUpDungeon(PocketManager.getDimensionData(world), world, pocketCenter, turnAngle, entryLink, random, properties);
} }
private void setUpDungeon(NewDimData dimension, World world, Point3D pocketCenter, int turnAngle, DimLink entryLink, Random random) private void setUpDungeon(NewDimData dimension, World world, Point3D pocketCenter, int turnAngle, DimLink entryLink, Random random, DDProperties properties)
{ {
//Transform dungeon corners //Transform dungeon corners
Point3D minCorner = new Point3D(0, 0, 0); Point3D minCorner = new Point3D(0, 0, 0);
@@ -235,7 +235,7 @@ public class DungeonSchematic extends Schematic {
transformCorners(entranceDoorLocation, pocketCenter, turnAngle, minCorner, maxCorner); transformCorners(entranceDoorLocation, pocketCenter, turnAngle, minCorner, maxCorner);
//Fill empty chests and dispensers //Fill empty chests and dispensers
FillContainersOperation filler = new FillContainersOperation(random); FillContainersOperation filler = new FillContainersOperation(random, properties);
filler.apply(world, minCorner, maxCorner); filler.apply(world, minCorner, maxCorner);
//Set up entrance door rift //Set up entrance door rift
@@ -302,7 +302,7 @@ public class DungeonSchematic extends Schematic {
Point3D location = point.clone(); Point3D location = point.clone();
BlockRotator.transformPoint(location, entrance, rotation, pocketCenter); BlockRotator.transformPoint(location, entrance, rotation, pocketCenter);
int orientation = world.getBlockMetadata(location.getX(), location.getY()-1, location.getZ()); int orientation = world.getBlockMetadata(location.getX(), location.getY()-1, location.getZ());
dimension.createLink(location.getX(), location.getY(), location.getZ(), LinkTypes.DUNGEON_EXIT,orientation); dimension.createLink(location.getX(), location.getY(), location.getZ(), LinkTypes.DUNGEON_EXIT, orientation);
//Replace the sandstone block under the exit door with the same block as the one underneath it //Replace the sandstone block under the exit door with the same block as the one underneath it
int x = location.getX(); int x = location.getX();
int y = location.getY() - 3; int y = location.getY() - 3;
@@ -322,7 +322,7 @@ public class DungeonSchematic extends Schematic {
BlockRotator.transformPoint(location, entrance, rotation, pocketCenter); BlockRotator.transformPoint(location, entrance, rotation, pocketCenter);
int orientation = world.getBlockMetadata(location.getX(), location.getY()-1, location.getZ()); int orientation = world.getBlockMetadata(location.getX(), location.getY()-1, location.getZ());
dimension.createLink(location.getX(), location.getY(), location.getZ(), LinkTypes.DUNGEON,orientation); dimension.createLink(location.getX(), location.getY(), location.getZ(), LinkTypes.DUNGEON, orientation);
} }
private static void spawnMonolith(World world, Point3D point, Point3D entrance, int rotation, Point3D pocketCenter, boolean canSpawn) private static void spawnMonolith(World world, Point3D point, Point3D entrance, int rotation, Point3D pocketCenter, boolean canSpawn)

View File

@@ -12,16 +12,22 @@ import net.minecraft.tileentity.TileEntityChest;
import net.minecraft.tileentity.TileEntityDispenser; import net.minecraft.tileentity.TileEntityDispenser;
import net.minecraft.world.World; import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.DDLoot; import StevenDimDoors.mod_pocketDim.DDLoot;
import StevenDimDoors.mod_pocketDim.DDProperties;
import StevenDimDoors.mod_pocketDim.schematic.WorldOperation; import StevenDimDoors.mod_pocketDim.schematic.WorldOperation;
public class FillContainersOperation extends WorldOperation public class FillContainersOperation extends WorldOperation
{ {
private Random random; private Random random;
private DDProperties properties;
public FillContainersOperation(Random random) private static final int GRAVE_CHEST_CHANCE = 100;
private static final int MAX_GRAVE_CHEST_CHANCE = 700;
public FillContainersOperation(Random random, DDProperties properties)
{ {
super("FillContainersOperation"); super("FillContainersOperation");
this.random = random; this.random = random;
this.properties = properties;
} }
@Override @Override
@@ -29,22 +35,30 @@ public class FillContainersOperation extends WorldOperation
{ {
int blockID = world.getBlockId(x, y, z); int blockID = world.getBlockId(x, y, z);
//Fill empty chests and dispensers // Fill empty chests and dispensers
if (Block.blocksList[blockID] instanceof BlockContainer) if (Block.blocksList[blockID] instanceof BlockContainer)
{ {
TileEntity tileEntity = world.getBlockTileEntity(x, y, z); TileEntity tileEntity = world.getBlockTileEntity(x, y, z);
//Fill chests // Fill chests
if (tileEntity instanceof TileEntityChest) if (tileEntity instanceof TileEntityChest)
{ {
TileEntityChest chest = (TileEntityChest) tileEntity; TileEntityChest chest = (TileEntityChest) tileEntity;
if (isInventoryEmpty(chest)) if (isInventoryEmpty(chest))
{ {
DDLoot.generateChestContents(DDLoot.DungeonChestInfo, chest, random); // Randomly choose whether this will be a regular dungeon chest or a grave chest
if (random.nextInt(MAX_GRAVE_CHEST_CHANCE) < GRAVE_CHEST_CHANCE)
{
DDLoot.fillGraveChest(chest, random, properties);
}
else
{
DDLoot.generateChestContents(DDLoot.DungeonChestInfo, chest, random);
}
} }
} }
//Fill dispensers // Fill dispensers
if (tileEntity instanceof TileEntityDispenser) if (tileEntity instanceof TileEntityDispenser)
{ {
TileEntityDispenser dispenser = (TileEntityDispenser) tileEntity; TileEntityDispenser dispenser = (TileEntityDispenser) tileEntity;

View File

@@ -279,6 +279,9 @@ public class mod_pocketDim
CraftingManager.registerRecipies(); CraftingManager.registerRecipies();
DungeonHelper.initialize(); DungeonHelper.initialize();
// Register loot chests
DDLoot.registerInfo(properties);
proxy.loadTextures(); proxy.loadTextures();
proxy.registerRenderers(); proxy.registerRenderers();
} }
@@ -288,9 +291,8 @@ public class mod_pocketDim
public void onPostInitialization(FMLPostInitializationEvent event) public void onPostInitialization(FMLPostInitializationEvent event)
{ {
ForgeChunkManager.setForcedChunkLoadingCallback(instance, new ChunkLoaderHelper()); ForgeChunkManager.setForcedChunkLoadingCallback(instance, new ChunkLoaderHelper());
//Register loot chests
DDLoot.registerInfo();
} }
@EventHandler @EventHandler
public void onServerStopping(FMLServerStoppingEvent event) public void onServerStopping(FMLServerStoppingEvent event)
{ {

View File

@@ -78,7 +78,6 @@ public class PocketBuilder
dimension.createLink(oldLinkPos, LinkTypes.SAFE_EXIT, (orientation+2)%4); dimension.createLink(oldLinkPos, LinkTypes.SAFE_EXIT, (orientation+2)%4);
return false; return false;
} }
@SuppressWarnings("unused") // ?
NewDimData parent = PocketManager.getDimensionData(incomingLink.source().getDimension()); NewDimData parent = PocketManager.getDimensionData(incomingLink.source().getDimension());
if (!dimension.isDungeon()) if (!dimension.isDungeon())
@@ -106,7 +105,7 @@ public class PocketBuilder
} }
Point3D destination = new Point3D(incomingLink.destination()); Point3D destination = new Point3D(incomingLink.destination());
loadAndValidateDungeon(dimension.dungeon(),properties).copyToWorld(world, destination, originLink.orientation(), incomingLink, random); loadAndValidateDungeon(dimension.dungeon(), properties).copyToWorld(world, destination, originLink.orientation(), incomingLink, random, properties);
dimension.setFilled(true); dimension.setFilled(true);
return true; return true;
} }
@@ -115,8 +114,6 @@ public class PocketBuilder
e.printStackTrace(); e.printStackTrace();
return false; return false;
} }
} }
private static boolean buildDungeonPocket(DungeonData dungeon, NewDimData dimension, DimLink link, DungeonSchematic schematic,World world, DDProperties properties) private static boolean buildDungeonPocket(DungeonData dungeon, NewDimData dimension, DimLink link, DungeonSchematic schematic,World world, DDProperties properties)
@@ -140,7 +137,7 @@ public class PocketBuilder
destination.setY( yCoordHelper.adjustDestinationY(destination.getY(), world.getHeight(), schematic.getEntranceDoorLocation().getY(), schematic.getHeight()) ); destination.setY( yCoordHelper.adjustDestinationY(destination.getY(), world.getHeight(), schematic.getEntranceDoorLocation().getY(), schematic.getHeight()) );
//Generate the dungeon //Generate the dungeon
schematic.copyToWorld(world, destination, orientation, link, random); schematic.copyToWorld(world, destination, orientation, link, random, properties);
//Finish up destination initialization //Finish up destination initialization
dimension.initializeDungeon(destination.getX(), destination.getY(), destination.getZ(), orientation, link, dungeon); dimension.initializeDungeon(destination.getX(), destination.getY(), destination.getZ(), orientation, link, dungeon);