Fixed PocketBuilder and More
1. Changed DungeonSchematic to use an external instance of Random rather than initializing its own. 2. Created the Pair class, a strongly-typed tuple that was needed in PocketBuilder. 3. Added a missing calculation in NewDimData for setting the packDepth field during dungeon initialization. 4. Finished code missing in PocketBuilder. Changes listed above were needed for this.
This commit is contained in:
parent
8e8346864e
commit
9930068775
4 changed files with 122 additions and 54 deletions
|
@ -9,6 +9,7 @@ import java.util.TreeMap;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import StevenDimDoors.mod_pocketDim.DDProperties;
|
import StevenDimDoors.mod_pocketDim.DDProperties;
|
||||||
import StevenDimDoors.mod_pocketDim.dungeon.DungeonData;
|
import StevenDimDoors.mod_pocketDim.dungeon.DungeonData;
|
||||||
|
import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonPack;
|
||||||
import StevenDimDoors.mod_pocketDim.util.Point4D;
|
import StevenDimDoors.mod_pocketDim.util.Point4D;
|
||||||
|
|
||||||
public abstract class NewDimData implements Serializable
|
public abstract class NewDimData implements Serializable
|
||||||
|
@ -460,6 +461,39 @@ public abstract class NewDimData implements Serializable
|
||||||
this.origin = link.destination();
|
this.origin = link.destination();
|
||||||
this.orientation = orientation;
|
this.orientation = orientation;
|
||||||
this.dungeon = dungeon;
|
this.dungeon = dungeon;
|
||||||
|
this.packDepth = calculatePackDepth(parent, dungeon);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int calculatePackDepth(NewDimData parent, DungeonData current)
|
||||||
|
{
|
||||||
|
DungeonData predecessor = parent.dungeon();
|
||||||
|
if (current == null)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("current cannot be null.");
|
||||||
|
}
|
||||||
|
if (predecessor == null)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DungeonPack predOwner = predecessor.dungeonType().Owner;
|
||||||
|
DungeonPack currentOwner = current.dungeonType().Owner;
|
||||||
|
if (currentOwner == null)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (predOwner == null)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (predOwner == currentOwner)
|
||||||
|
{
|
||||||
|
return parent.packDepth + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initializePocket(int originX, int originY, int originZ, int orientation, IDimLink link)
|
public void initializePocket(int originX, int originY, int originZ, int orientation, IDimLink link)
|
||||||
|
|
|
@ -167,15 +167,14 @@ 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 dungeonOrientation, IDimLink entryLink)
|
public void copyToWorld(World world, Point3D pocketCenter, int dungeonOrientation, IDimLink entryLink, Random random)
|
||||||
{
|
{
|
||||||
//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,
|
||||||
//then just use that support from DungeonSchematic instead of making this local fix.
|
//then just use that support from DungeonSchematic instead of making this local fix.
|
||||||
//It might be easiest to support transformations using a WorldOperation
|
//It might be easiest to support transformations using a WorldOperation
|
||||||
|
|
||||||
final int turnAngle = dungeonOrientation - orientation;
|
final int turnAngle = dungeonOrientation - orientation;
|
||||||
|
|
||||||
|
|
||||||
int index;
|
int index;
|
||||||
int count;
|
int count;
|
||||||
|
@ -222,18 +221,11 @@ 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);
|
setUpDungeon(PocketManager.getDimensionData(world), world, pocketCenter, turnAngle, entryLink, random);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpDungeon(NewDimData dimension, World world, Point3D pocketCenter, int turnAngle, IDimLink entryLink)
|
private void setUpDungeon(NewDimData dimension, World world, Point3D pocketCenter, int turnAngle, IDimLink entryLink, Random random)
|
||||||
{
|
{
|
||||||
//The following Random initialization code is based on code from ChunkProviderGenerate.
|
|
||||||
//It makes our generation depend on the world seed.
|
|
||||||
Random random = new Random(world.getSeed());
|
|
||||||
long factorA = random.nextLong() / 2L * 2L + 1L;
|
|
||||||
long factorB = random.nextLong() / 2L * 2L + 1L;
|
|
||||||
random.setSeed(pocketCenter.getX() * factorB + pocketCenter.getZ() * factorA ^ world.getSeed());
|
|
||||||
|
|
||||||
//Transform dungeon corners
|
//Transform dungeon corners
|
||||||
Point3D minCorner = new Point3D(0, 0, 0);
|
Point3D minCorner = new Point3D(0, 0, 0);
|
||||||
Point3D maxCorner = new Point3D(width - 1, height - 1, length - 1);
|
Point3D maxCorner = new Point3D(width - 1, height - 1, length - 1);
|
||||||
|
|
26
StevenDimDoors/mod_pocketDim/util/Pair.java
Normal file
26
StevenDimDoors/mod_pocketDim/util/Pair.java
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
package StevenDimDoors.mod_pocketDim.util;
|
||||||
|
|
||||||
|
public class Pair<P, Q>
|
||||||
|
{
|
||||||
|
//Pair is an implementation of a 2-tuple with generic parameters for strongly-typed elements.
|
||||||
|
//It's used instead of Minecraft's Tuple type because Tuple doesn't have strongly-typed elements.
|
||||||
|
|
||||||
|
private P first;
|
||||||
|
private Q second;
|
||||||
|
|
||||||
|
public Pair(P first, Q second)
|
||||||
|
{
|
||||||
|
this.first = first;
|
||||||
|
this.second = second;
|
||||||
|
}
|
||||||
|
|
||||||
|
public P getFirst()
|
||||||
|
{
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Q getSecond()
|
||||||
|
{
|
||||||
|
return second;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,9 @@
|
||||||
package StevenDimDoors.mod_pocketDim.world;
|
package StevenDimDoors.mod_pocketDim.world;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.util.MathHelper;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.chunk.Chunk;
|
import net.minecraft.world.chunk.Chunk;
|
||||||
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||||
|
@ -19,6 +19,7 @@ import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonPackConfig;
|
||||||
import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper;
|
import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper;
|
||||||
import StevenDimDoors.mod_pocketDim.helpers.yCoordHelper;
|
import StevenDimDoors.mod_pocketDim.helpers.yCoordHelper;
|
||||||
import StevenDimDoors.mod_pocketDim.schematic.BlockRotator;
|
import StevenDimDoors.mod_pocketDim.schematic.BlockRotator;
|
||||||
|
import StevenDimDoors.mod_pocketDim.util.Pair;
|
||||||
import StevenDimDoors.mod_pocketDim.util.Point4D;
|
import StevenDimDoors.mod_pocketDim.util.Point4D;
|
||||||
|
|
||||||
public class PocketBuilder
|
public class PocketBuilder
|
||||||
|
@ -35,25 +36,6 @@ public class PocketBuilder
|
||||||
|
|
||||||
private PocketBuilder() { }
|
private PocketBuilder() { }
|
||||||
|
|
||||||
public static boolean initializeDestination(IDimLink link, DDProperties properties)
|
|
||||||
{
|
|
||||||
if (link.hasDestination())
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Check the destination type and respond accordingly
|
|
||||||
switch (link.linkType())
|
|
||||||
{
|
|
||||||
case IDimLink.TYPE_DUNGEON:
|
|
||||||
return generateNewDungeonPocket(link, properties);
|
|
||||||
case IDimLink.TYPE_POCKET:
|
|
||||||
return generateNewPocket(link, properties);
|
|
||||||
default:
|
|
||||||
throw new IllegalArgumentException("link has an unrecognized link type.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean generateNewDungeonPocket(IDimLink link, DDProperties properties)
|
public static boolean generateNewDungeonPocket(IDimLink link, DDProperties properties)
|
||||||
{
|
{
|
||||||
if (link == null)
|
if (link == null)
|
||||||
|
@ -93,31 +75,35 @@ public class PocketBuilder
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This code is currently wrong. It's missing the following things:
|
|
||||||
* 1. Calculate the destination point for real. That includes adding door noise if needed.
|
|
||||||
* 2. Receive the DungeonData from selectDungeon()
|
|
||||||
* 3. The function signature for DungeonSchematic.copyToWorld() has to be rewritten.
|
|
||||||
*/
|
|
||||||
|
|
||||||
//Choose a dungeon to generate
|
//Choose a dungeon to generate
|
||||||
DungeonSchematic schematic = selectDungeon(dimension, random, properties);
|
Pair<DungeonData, DungeonSchematic> pair = selectDungeon(dimension, random, properties);
|
||||||
|
if (pair == null)
|
||||||
if (schematic == null)
|
|
||||||
{
|
{
|
||||||
System.err.println("Could not select a dungeon for generation!");
|
System.err.println("Could not select a dungeon for generation!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
DungeonData dungeon = pair.getFirst();
|
||||||
|
DungeonSchematic schematic = pair.getSecond();
|
||||||
|
|
||||||
//Calculate the destination point
|
//Calculate the destination point
|
||||||
|
DungeonPackConfig packConfig = dungeon.dungeonType().Owner != null ? dungeon.dungeonType().Owner.getConfig() : null;
|
||||||
Point4D source = link.source();
|
Point4D source = link.source();
|
||||||
int destinationY = yCoordHelper.adjustDestinationY(destination, world.getHeight(), schematic.getEntranceDoorLocation().getY(), schematic.getHeight());
|
int orientation = getDoorOrientation(source, properties);
|
||||||
int orientation = getDestinationOrientation(source);
|
Point3D destination;
|
||||||
destination.setY(destinationY);
|
|
||||||
|
if (packConfig != null && packConfig.doDistortDoorCoordinates())
|
||||||
|
{
|
||||||
|
destination = calculateNoisyDestination(source, dimension, orientation);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
destination = new Point3D(source.getX(), source.getY(), source.getZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
destination.setY( yCoordHelper.adjustDestinationY(destination.getY(), world.getHeight(), schematic.getEntranceDoorLocation().getY(), schematic.getHeight()) );
|
||||||
|
|
||||||
//Generate the dungeon
|
//Generate the dungeon
|
||||||
DungeonPackConfig packConfig = dungeon.dungeonType().Owner != null ? dungeon.dungeonType().Owner.getConfig() : null;
|
schematic.copyToWorld(world, destination, orientation, link, random);
|
||||||
|
|
||||||
schematic.copyToWorld(world, link, packConfig.doDistortDoorCoordinates());
|
|
||||||
|
|
||||||
//Finish up destination initialization
|
//Finish up destination initialization
|
||||||
dimension.initializePocket(destination.getX(), destination.getY(), destination.getZ(), orientation, link);
|
dimension.initializePocket(destination.getX(), destination.getY(), destination.getZ(), orientation, link);
|
||||||
|
@ -131,7 +117,23 @@ public class PocketBuilder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DungeonSchematic selectDungeon(NewDimData dimension, Random random, DDProperties properties)
|
private static Point3D calculateNoisyDestination(Point4D source, NewDimData dimension, int orientation)
|
||||||
|
{
|
||||||
|
int depth = dimension.packDepth();
|
||||||
|
int forwardNoise = MathHelper.getRandomIntegerInRange(random, -50 * depth, 150 * depth);
|
||||||
|
int sidewaysNoise = MathHelper.getRandomIntegerInRange(random, -10 * depth, 10 * depth);
|
||||||
|
|
||||||
|
//Rotate the link destination noise to point in the same direction as the door exit
|
||||||
|
//and add it to the door's location. Use EAST as the reference orientation since linkDestination
|
||||||
|
//is constructed as if pointing East.
|
||||||
|
Point3D linkDestination = new Point3D(forwardNoise, 0, sidewaysNoise);
|
||||||
|
Point3D sourcePoint = new Point3D(source.getX(), source.getY(), source.getZ());
|
||||||
|
Point3D zeroPoint = new Point3D(0, 0, 0);
|
||||||
|
BlockRotator.transformPoint(linkDestination, zeroPoint, orientation - BlockRotator.EAST_DOOR_METADATA, sourcePoint);
|
||||||
|
return linkDestination;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Pair<DungeonData, DungeonSchematic> selectDungeon(NewDimData dimension, Random random, DDProperties properties)
|
||||||
{
|
{
|
||||||
//We assume the dimension doesn't have a dungeon assigned
|
//We assume the dimension doesn't have a dungeon assigned
|
||||||
if (dimension.dungeon() != null)
|
if (dimension.dungeon() != null)
|
||||||
|
@ -157,7 +159,6 @@ public class PocketBuilder
|
||||||
{
|
{
|
||||||
//TODO: In the future, remove this dungeon from the generation lists altogether.
|
//TODO: In the future, remove this dungeon from the generation lists altogether.
|
||||||
//That will have to wait until our code is updated to support that more easily.
|
//That will have to wait until our code is updated to support that more easily.
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
System.err.println("Loading the default error dungeon instead...");
|
System.err.println("Loading the default error dungeon instead...");
|
||||||
|
@ -170,7 +171,7 @@ public class PocketBuilder
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return schematic;
|
return new Pair<DungeonData, DungeonSchematic>(dungeon, schematic);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DungeonSchematic loadAndValidateDungeon(DungeonData dungeon, DDProperties properties)
|
private static DungeonSchematic loadAndValidateDungeon(DungeonData dungeon, DDProperties properties)
|
||||||
|
@ -218,10 +219,25 @@ public class PocketBuilder
|
||||||
return generateNewPocket(link, DEFAULT_POCKET_SIZE, DEFAULT_POCKET_WALL_THICKNESS, properties);
|
return generateNewPocket(link, DEFAULT_POCKET_SIZE, DEFAULT_POCKET_WALL_THICKNESS, properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getDestinationOrientation(Point4D source)
|
private static int getDoorOrientation(Point4D source, DDProperties properties)
|
||||||
{
|
{
|
||||||
// TODO Auto-generated method stub
|
World world = DimensionManager.getWorld(source.getDimension());
|
||||||
return 0;
|
if (world == null)
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("The link's source world should be loaded!");
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check if the block at that point is actually a door
|
||||||
|
int blockID = world.getBlockId(source.getX(), source.getY(), source.getZ());
|
||||||
|
if (blockID != properties.DimensionalDoorID && blockID != properties.WarpDoorID &&
|
||||||
|
blockID != properties.TransientDoorID)
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("The link's source is not a door block. It should be impossible to traverse a rift without a door!");
|
||||||
|
}
|
||||||
|
|
||||||
|
//Return the orientation portion of its metadata
|
||||||
|
int orientation = world.getBlockMetadata(source.getX(), source.getY(), source.getZ()) & 3;
|
||||||
|
return orientation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean generateNewPocket(IDimLink link, int size, int wallThickness, DDProperties properties)
|
public static boolean generateNewPocket(IDimLink link, int size, int wallThickness, DDProperties properties)
|
||||||
|
@ -283,7 +299,7 @@ public class PocketBuilder
|
||||||
//Calculate the destination point
|
//Calculate the destination point
|
||||||
Point4D source = link.source();
|
Point4D source = link.source();
|
||||||
int destinationY = yCoordHelper.adjustDestinationY(source.getY(), world.getHeight(), wallThickness + 1, size);
|
int destinationY = yCoordHelper.adjustDestinationY(source.getY(), world.getHeight(), wallThickness + 1, size);
|
||||||
int orientation = getDestinationOrientation(source);
|
int orientation = getDoorOrientation(source, properties);
|
||||||
|
|
||||||
//Build the actual pocket area
|
//Build the actual pocket area
|
||||||
buildPocket(world, source.getX(), destinationY, source.getZ(), orientation, size, wallThickness, properties);
|
buildPocket(world, source.getX(), destinationY, source.getZ(), orientation, size, wallThickness, properties);
|
||||||
|
|
Loading…
Reference in a new issue