Merge pull request #74 from SenseiKiwi/master
Improved Dungeon Loot and Selection
This commit is contained in:
commit
928b7d4cba
4 changed files with 92 additions and 31 deletions
|
@ -4,7 +4,10 @@ import java.util.ArrayList;
|
|||
import java.util.HashMap;
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.WeightedRandom;
|
||||
import net.minecraft.util.WeightedRandomChestContent;
|
||||
import net.minecraftforge.common.ChestGenHooks;
|
||||
|
||||
|
@ -33,6 +36,8 @@ public class DDLoot {
|
|||
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() { }
|
||||
|
||||
public static void registerInfo()
|
||||
{
|
||||
DDProperties properties = DDProperties.instance();
|
||||
|
@ -156,4 +161,48 @@ public class DDLoot {
|
|||
//System.out.println(item.theItemId.getDisplayName() + "\t" + item.itemWeight);
|
||||
}
|
||||
}
|
||||
|
||||
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. 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
|
||||
//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 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)
|
||||
{
|
||||
int limit = size;
|
||||
int index = random.nextInt(size);
|
||||
|
||||
while (limit > 0 && inventory.getStackInSlot(index) != null)
|
||||
{
|
||||
limit--;
|
||||
index = (index + primeOffset) % size;
|
||||
}
|
||||
|
||||
inventory.setInventorySlotContents(index, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ public class SchematicLoader
|
|||
if (dimList.get(destDimID).dungeonGenerator == null)
|
||||
{
|
||||
//TODO: We should centralize RNG initialization and world-seed modifiers for each specific application.
|
||||
final long localSeed = world.getSeed() ^ 0x2F50DB9B4A8057E4L ^ computeDestinationHash(link);
|
||||
final long localSeed = world.getSeed() ^ 0x2F50DB9B4A8057E4L ^ calculateDestinationSeed(link);
|
||||
final Random random = new Random(localSeed);
|
||||
|
||||
dungeonHelper.generateDungeonLink(link, dungeonHelper.getDimDungeonPack(originDimID), random);
|
||||
|
@ -155,43 +155,50 @@ public class SchematicLoader
|
|||
return dungeon;
|
||||
}
|
||||
|
||||
private static long computeDestinationHash(LinkData link)
|
||||
private static long calculateDestinationSeed(LinkData link)
|
||||
{
|
||||
//Time for some witchcraft.
|
||||
//The code here is inspired by a discussion on Stack Overflow regarding hash codes for 3D.
|
||||
//Source: http://stackoverflow.com/questions/9858376/hashcode-for-3d-integer-coordinates-with-high-spatial-coherence
|
||||
|
||||
//Use 8 bits from Y and 24 bits from X and Z. Mix in 8 bits from the destination dim ID too - that means
|
||||
//Use 8 bits from Y and 16 bits from X and Z. Mix in 8 bits from the destination dim ID too - that means
|
||||
//even if you aligned two doors perfectly between two pockets, it's unlikely they would lead to the same dungeon.
|
||||
//We map bits in reverse order to produce more varied RNG output for nearly-identical points. The reason is
|
||||
//that Java's Random outputs the 32 MSBs of its internal state to produce its output. If the differences
|
||||
//between two seeds are small (i.e. in the LSBs), then they will tend to produce similar random outputs anyway!
|
||||
|
||||
//Only bother to assign the 48 least-significant bits since Random only takes those bits from its seed.
|
||||
//NOTE: The casts to long are necessary to get the right results from the bit shifts!!!
|
||||
|
||||
int bit;
|
||||
int index;
|
||||
long hash;
|
||||
int w = link.destDimID;
|
||||
int x = link.destXCoord;
|
||||
int y = link.destYCoord;
|
||||
int z = link.destZCoord;
|
||||
final int w = link.destDimID;
|
||||
final int x = link.destXCoord;
|
||||
final int y = link.destYCoord;
|
||||
final int z = link.destZCoord;
|
||||
|
||||
hash = 0;
|
||||
index = 0;
|
||||
index = 48;
|
||||
for (bit = 0; bit < 8; bit++)
|
||||
{
|
||||
hash |= ((w >> bit) & 1) << index;
|
||||
index++;
|
||||
hash |= ((x >> bit) & 1) << index;
|
||||
index++;
|
||||
hash |= ((y >> bit) & 1) << index;
|
||||
index++;
|
||||
hash |= ((z >> bit) & 1) << index;
|
||||
index++;
|
||||
hash |= (long) ((w >> bit) & 1) << index;
|
||||
index--;
|
||||
hash |= (long) ((x >> bit) & 1) << index;
|
||||
index--;
|
||||
hash |= (long) ((y >> bit) & 1) << index;
|
||||
index--;
|
||||
hash |= (long) ((z >> bit) & 1) << index;
|
||||
index--;
|
||||
}
|
||||
for (; bit < 24; bit++)
|
||||
for (; bit < 16; bit++)
|
||||
{
|
||||
hash |= ((x >> bit) & 1) << index;
|
||||
index++;
|
||||
hash |= ((z >> bit) & 1) << index;
|
||||
index++;
|
||||
hash |= (long) ((x >> bit) & 1) << index;
|
||||
index--;
|
||||
hash |= (long) ((z >> bit) & 1) << index;
|
||||
index--;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
}
|
|
@ -10,9 +10,7 @@ import net.minecraft.item.ItemStack;
|
|||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityChest;
|
||||
import net.minecraft.tileentity.TileEntityDispenser;
|
||||
import net.minecraft.util.WeightedRandomChestContent;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.ChestGenHooks;
|
||||
import StevenDimDoors.mod_pocketDim.DDLoot;
|
||||
import StevenDimDoors.mod_pocketDim.schematic.WorldOperation;
|
||||
|
||||
|
@ -42,8 +40,7 @@ public class FillContainersOperation extends WorldOperation
|
|||
TileEntityChest chest = (TileEntityChest) tileEntity;
|
||||
if (isInventoryEmpty(chest))
|
||||
{
|
||||
ChestGenHooks info = DDLoot.DungeonChestInfo;
|
||||
WeightedRandomChestContent.generateChestContents(random, info.getItems(random), chest, info.getCount(random));
|
||||
DDLoot.generateChestContents(DDLoot.DungeonChestInfo, chest, random);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,14 +22,22 @@ Exit -> DeadEnd Exit
|
|||
|
||||
DeadEnd -> DeadEnd Exit
|
||||
|
||||
? ? ? ? ? ? ? ? -> Trap#20 SimpleHall#40 ComplexHall#10 Exit#20 DeadEnd#10
|
||||
? ? ? ? ? ? ? ? ? -> DeadEnd#10 Exit#11 SimpleHall#24 ComplexHall#16 Trap#23 Maze#11
|
||||
|
||||
? ? ? ? -> Trap#18 SimpleHall#40 ComplexHall#10 Exit#18 DeadEnd#10 Hub#4
|
||||
? ? ? ? ? ? ? ? -> DeadEnd#9 Exit#10 SimpleHall#24 ComplexHall#16 Trap#23 Maze#11 Hub#6
|
||||
|
||||
? ? ? -> ComplexHall Hub Trap SimpleHall Maze
|
||||
? ? ? ? ? ? ? -> DeadEnd#8 Exit#9 SimpleHall#25 ComplexHall#17 Trap#23 Maze#11 Hub#7
|
||||
|
||||
? ? -> ComplexHall Hub Trap SimpleHall Maze
|
||||
? ? ? ? ? ? -> DeadEnd#7 Exit#8 SimpleHall#26 ComplexHall#17 Trap#23 Maze#11 Hub#8
|
||||
|
||||
? -> ComplexHall#40 Hub#30 Trap#10 SimpleHall#10 Maze#10
|
||||
? ? ? ? ? -> DeadEnd#6 Exit#6 SimpleHall#27 ComplexHall#18 Trap#23 Maze#11 Hub#9
|
||||
|
||||
-> ComplexHall#40 Hub#30 Trap#10 SimpleHall#10 Maze#10
|
||||
? ? ? ? -> DeadEnd#5 Exit#5 SimpleHall#28 ComplexHall#18 Trap#23 Maze#11 Hub#10
|
||||
|
||||
? ? ? -> DeadEnd#3 Exit#3 SimpleHall#29 ComplexHall#19 Trap#23 Maze#11 Hub#11
|
||||
|
||||
? ? -> SimpleHall#9 ComplexHall#8 Trap#17 Maze#23 Hub#44
|
||||
|
||||
? -> SimpleHall#9 ComplexHall#8 Trap#17 Maze#23 Hub#44
|
||||
|
||||
-> SimpleHall#2 ComplexHall#54 Trap#2 Maze#2 Hub#41
|
||||
|
|
Loading…
Reference in a new issue