@@ -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,44 +72,23 @@ 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void generateChestContents(ChestGenHooks chestInfo, IInventory inventory, Random random)
|
private static void fillChest(ArrayList<ItemStack> stacks, IInventory inventory, Random random)
|
||||||
{
|
{
|
||||||
//This is a custom version of net.minecraft.util.WeightedRandomChestContent.generateChestContents()
|
// This custom chest-filling function avoids overwriting item stacks
|
||||||
//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
|
|
||||||
//2. If multiple enchanted books appear, then they will have the same enchantment
|
|
||||||
|
|
||||||
//The prime number below is used for choosing chest slots in a seemingly-random pattern. Its value
|
// 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.
|
// 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
|
// 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.
|
// means we'll cover all the slots before repeating any. This is mathematically guaranteed.
|
||||||
final int primeOffset = 239333;
|
final int primeOffset = 239333;
|
||||||
|
|
||||||
int count = chestInfo.getCount(random);
|
|
||||||
int size = inventory.getSizeInventory();
|
int size = inventory.getSizeInventory();
|
||||||
WeightedRandomChestContent[] content = chestInfo.getItems(random);
|
|
||||||
|
|
||||||
for (int k = 0; k < count; k++)
|
|
||||||
{
|
|
||||||
WeightedRandomChestContent selection = (WeightedRandomChestContent)WeightedRandom.getRandomItem(random, content);
|
|
||||||
|
|
||||||
//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
|
|
||||||
//we don't know if other mods might add items that also need to be regenerated.
|
|
||||||
selection = selection.theItemId.getItem().getChestGenBase(chestInfo, random, selection);
|
|
||||||
|
|
||||||
ItemStack[] stacks = ChestGenHooks.generateStacks(random, selection.theItemId, selection.theMinimumChanceToGenerateItem, selection.theMaximumChanceToGenerateItem);
|
|
||||||
|
|
||||||
for (ItemStack item : stacks)
|
for (ItemStack item : stacks)
|
||||||
{
|
{
|
||||||
int limit = size;
|
int limit = size;
|
||||||
@@ -208,5 +103,160 @@ public class DDLoot {
|
|||||||
inventory.setInventorySlotContents(index, item);
|
inventory.setInventorySlotContents(index, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void generateChestContents(ChestGenHooks chestInfo, IInventory inventory, Random random)
|
||||||
|
{
|
||||||
|
// This is a custom version of net.minecraft.util.WeightedRandomChestContent.generateChestContents()
|
||||||
|
// It's designed to avoid the following bugs in MC 1.5:
|
||||||
|
// 1. 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
|
||||||
|
|
||||||
|
int count = chestInfo.getCount(random);
|
||||||
|
WeightedRandomChestContent[] content = chestInfo.getItems(random);
|
||||||
|
ArrayList<ItemStack> allStacks = new ArrayList<ItemStack>();
|
||||||
|
|
||||||
|
for (int k = 0; k < count; k++)
|
||||||
|
{
|
||||||
|
WeightedRandomChestContent selection = (WeightedRandomChestContent)WeightedRandom.getRandomItem(random, content);
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// we don't know if other mods might add items that also need to be regenerated.
|
||||||
|
selection = selection.theItemId.getItem().getChestGenBase(chestInfo, random, selection);
|
||||||
|
|
||||||
|
ItemStack[] stacks = ChestGenHooks.generateStacks(random, selection.theItemId, selection.theMinimumChanceToGenerateItem, selection.theMaximumChanceToGenerateItem);
|
||||||
|
for (int h = 0; h < stacks.length; h++)
|
||||||
|
{
|
||||||
|
allStacks.add(stacks[h]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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))
|
||||||
|
{
|
||||||
|
// 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);
|
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;
|
||||||
|
|||||||
@@ -191,7 +191,14 @@ public class DungeonPack
|
|||||||
return getRandomDungeon(random, candidates);
|
return getRandomDungeon(random, candidates);
|
||||||
}
|
}
|
||||||
//If we've reached this point, then a dungeon was not selected. Discard the type and try again.
|
//If we've reached this point, then a dungeon was not selected. Discard the type and try again.
|
||||||
products.remove(nextType);
|
for (index = 0; index < products.size(); index++)
|
||||||
|
{
|
||||||
|
if (products.get(index).getData().equals(nextType))
|
||||||
|
{
|
||||||
|
products.remove(index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (nextType != null);
|
while (nextType != null);
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ public class DungeonPackConfigReader extends BaseConfigurationProcessor<DungeonP
|
|||||||
|
|
||||||
public DungeonPackConfigReader() { }
|
public DungeonPackConfigReader() { }
|
||||||
|
|
||||||
@SuppressWarnings("resource")
|
|
||||||
@Override
|
@Override
|
||||||
public DungeonPackConfig readFromStream(InputStream inputStream) throws ConfigurationProcessingException
|
public DungeonPackConfig readFromStream(InputStream inputStream) throws ConfigurationProcessingException
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -283,6 +283,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();
|
||||||
}
|
}
|
||||||
@@ -292,9 +295,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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user