Overhauled SchematicLoader (again)

Rotations in SchematicLoader are understandable now. I changed all the
code to use transformPoint() and made sure that the rotations in there
are correct. Testing shows that rooms are being generated correctly. I
also edited portions of the code for clarity and removed some debug
prints. The loading process now allows permafabric to generate - it was
previously converted into regular fabric of reality.  For the moment,
the code is stuck to assume that the entry direction is North. I'll
remove that constraint in the next commit.
This commit is contained in:
SenseiKiwi
2013-07-09 00:50:06 -04:00
parent c3c3611764
commit efe5da2604

View File

@@ -37,8 +37,6 @@ public class SchematicLoader
private final static int WEST_DOOR_METADATA = 2;
private final static int NORTH_DOOR_METADATA = 3;
public int transMeta;
private DDProperties properties = DDProperties.instance();
public SchematicLoader() { }
@@ -682,9 +680,9 @@ public class SchematicLoader
public void generateSchematic(int riftX, int riftY, int riftZ, int orientation, int destDimID, int originDimID, String schematicPath)
{
short width=0;
short height=0;
short length=0;
short width = 0;
short height = 0;
short length = 0;
//list of combined blockIds
short[] blocks = new short[0];
@@ -703,7 +701,7 @@ public class SchematicLoader
NBTTagList entities;
//the wooden door leading into the pocket
Point3D entrance = new Point3D(0,0,0);
Point3D schematicEntrance = new Point3D(0,0,0);
//the iron dim doors leading to more pockets
ArrayList<Point3D> sideLinks = new ArrayList<Point3D>();
@@ -717,9 +715,8 @@ public class SchematicLoader
//load the schematic from disk
try
{
InputStream input;
String fname= schematicPath ;
String fname = schematicPath ;
if(!(new File(fname).exists()))
{
@@ -745,7 +742,7 @@ public class SchematicLoader
addId = nbtdata.getByteArray("AddBlocks");
//create combined block list
blocks=new short[blockId.length];
blocks = new short[blockId.length];
//load ticking things
tileEntities = nbtdata.getTagList("TileEntities");
@@ -804,15 +801,18 @@ public class SchematicLoader
long factorB = rand.nextLong() / 2L * 2L + 1L;
rand.setSeed((riftX >> 4) * factorA + (riftZ >> 4) * factorB ^ world.getSeed());
//coords relative to the schematic, start at 0 and increase up to max height/width/length
//Coordinates relative to the schematic, start at 0 and increase up to max width/height/length
int x, y, z;
//The real coordinates where a block will be placed
int realX = 0;
int realY = 0;
int realZ = 0;
//The real point where a block will be placed
int realX, realY, realZ;
Point3D pocketPoint = new Point3D(0, 0, 0);
int schematicDoorMeta=0;
//The central point of the pocket where we'll be placing the schematic
Point3D pocketCenter = new Point3D(riftX, riftY, riftZ);
Point3D zeroPoint = new Point3D(0, 0, 0);
int schematicDoorMeta = 0;
//first loop through the .schematic to load in all rift locations, and monolith spawn locations.
//also finds the incomingLink location, which determines the final position and orientation of the dungeon
@@ -831,7 +831,6 @@ public class SchematicLoader
//NBTTagList tileEntity = tileEntities;
//int size = tileEntity.tagCount();
if (currentBlock == Block.doorIron.blockID && indexBelow >= 0 && blocks[indexBelow] == Block.doorIron.blockID)
{
sideLinks.add(new Point3D(x, y, z));
@@ -845,7 +844,7 @@ public class SchematicLoader
}
else if (indexBelow >= 0 && blocks[indexBelow] == Block.doorWood.blockID)
{
entrance = new Point3D(x, y, z);
schematicEntrance = new Point3D(x, y, z);
schematicDoorMeta = Math.abs(blockData[indexBelow] + 2) % 4; //TODO: Write a function for extracting a door's orientation from its metadata or at least change this to use bitwise operations.
}
}
@@ -857,103 +856,65 @@ public class SchematicLoader
}
}
//Compute the Y-axis translation that places our structure correctly
int offsetY = riftY - entrance.getY();
//TODO: HAX REMOVE THIS!
schematicDoorMeta = NORTH_DOOR_METADATA;
if (orientation == schematicDoorMeta)
{
System.out.println("Intended Orientation: NORTH");
}
else if (orientation == (schematicDoorMeta + 1) % 4)
{
System.out.println("Intended Orientation: EAST");
}
else if (orientation == (schematicDoorMeta + 2) % 4)
{
System.out.println("Intended Orientation: SOUTH");
}
else if (orientation == (schematicDoorMeta + 3) % 4)
{
System.out.println("Intended Orientation: WEST");
}
//Loop to actually place the blocks
for (x = 0; x < width; x++)
{
for (z = 0; z < length; z++)
{
//Compute the X-axis and Z-axis translations that will shift
//and rotate our structure properly.
if (orientation == schematicDoorMeta)
{
realX = (x - entrance.getX()) + riftX;
realZ = (z - entrance.getZ()) + riftZ;
}
else if (orientation == (schematicDoorMeta + 1) % 4)
{
//270 degree CCW rotation
realX = -(z - entrance.getZ()) + riftX;
realZ = (x - entrance.getX()) + riftZ;
}
else if (orientation == (schematicDoorMeta + 2) % 4)
{
//180 degree rotation
realX = -(x - entrance.getX()) + riftX;
realZ = -(z - entrance.getZ()) + riftZ;
}
else if (orientation == (schematicDoorMeta + 3) % 4)
{
//90 degree CCW rotation
realX = (z - entrance.getZ()) + riftX;
realZ = -(x - entrance.getX()) + riftZ;
}
for (y = 0; y < height; y++)
{
int index = y * width * length + z * width + x;
realY = y + offsetY;
//Reinitialize pocketPoint with the current schematic coordinate system
pocketPoint.setX(x);
pocketPoint.setY(y);
pocketPoint.setZ(z);
//Transform pocketPoint into the pocket coordinate system
transformPoint(pocketPoint, schematicEntrance, orientation - schematicDoorMeta, pocketCenter);
//Store the transformed coordinates
realX = pocketPoint.getX();
realY = pocketPoint.getY();
realZ = pocketPoint.getZ();
int blockToReplace=blocks[index];
int blockMetaData=blockData[index];
int index = y * width * length + z * width + x;
int currentBlock = blocks[index];
int blockMetadata = blockData[index];
NBTTagList tileEntity = tileEntities;
//replace tagging blocks with air, and mob blocks with FoR
if(blockToReplace==Block.endPortalFrame.blockID)
//replace tagging blocks with air, and mod blocks with FoR
if (currentBlock == Block.endPortalFrame.blockID)
{
blockToReplace=0;
currentBlock = 0;
}
else if(Block.blocksList[blockToReplace]==null&&blockToReplace!=0||blockToReplace>158) //TODO- replace 158 with max vanilla block ID
else if ((Block.blocksList[currentBlock] == null && currentBlock != 0) ||
(currentBlock > 158 && currentBlock != mod_pocketDim.blockDimWallPerm.blockID)) //TODO- replace 158 with max vanilla block ID
{
blockToReplace=mod_pocketDim.blockDimWall.blockID;
currentBlock = mod_pocketDim.blockDimWall.blockID;
}
//place blocks and metaData
if(blockToReplace>0)
//Place blocks and set metadata
if (currentBlock > 0)
{
//rotate the metaData blocks
this.transMeta=this.transformMetadata(blockMetaData, orientation, blockToReplace);
//Calculate new metadata for blocks that have orientations (e.g. doors, pistons)
int fixedMetadata = transformMetadata(blockMetadata, orientation, currentBlock);
//convert vanilla doors to dim doors, then place vanilla blocks
if(blockToReplace==Block.doorIron.blockID)
//Convert vanilla doors to dim doors or place blocks
if (currentBlock == Block.doorIron.blockID)
{
setBlockDirectly(world,realX, realY, realZ,properties.DimensionalDoorID, transMeta );
setBlockDirectly(world, realX, realY, realZ, properties.DimensionalDoorID, fixedMetadata);
}
else if(blockToReplace==Block.doorWood.blockID)
else if (currentBlock == Block.doorWood.blockID)
{
setBlockDirectly(world,realX, realY, realZ,properties.WarpDoorID, transMeta );
setBlockDirectly(world, realX, realY, realZ, properties.WarpDoorID, fixedMetadata);
}
else
{
setBlockDirectly(world,realX, realY, realZ,blockToReplace, transMeta );
setBlockDirectly(world, realX, realY, realZ, currentBlock, fixedMetadata);
}
//generate container inventories
if(Block.blocksList[blockToReplace] instanceof BlockContainer)
//Fill containers (e.g. chests, dispensers)
if(Block.blocksList[currentBlock] instanceof BlockContainer)
{
/**
TileEntity tile = world.getBlockTileEntity(i+xCooe, j+yCooe, k+zCooe);
@@ -964,20 +925,19 @@ public class SchematicLoader
}
**/
//fill chests
if(world.getBlockTileEntity(realX, realY, realZ) instanceof TileEntityChest)
//Fill chests
if (world.getBlockTileEntity(realX, realY, realZ) instanceof TileEntityChest)
{
TileEntityChest chest = (TileEntityChest) world.getBlockTileEntity(realX, realY, realZ);
ChestGenHooks info = DDLoot.DungeonChestInfo;
WeightedRandomChestContent.generateChestContents(rand, info.getItems(rand), (TileEntityChest)world.getBlockTileEntity(realX, realY, realZ), info.getCount(rand));
WeightedRandomChestContent.generateChestContents(rand, info.getItems(rand), chest, info.getCount(rand));
}
//fill dispensers
if(world.getBlockTileEntity(realX, realY, realZ) instanceof TileEntityDispenser)
//Fill dispensers
if (world.getBlockTileEntity(realX, realY, realZ) instanceof TileEntityDispenser)
{
TileEntityDispenser dispenser = (TileEntityDispenser) world.getBlockTileEntity(realX, realY, realZ);
dispenser.addItem(new ItemStack(Item.arrow, 64));
}
}
}
@@ -985,20 +945,33 @@ public class SchematicLoader
}
}
//Set up variables to use transformPoint()
Point3D pocketOrigin = new Point3D(riftX, riftY, riftZ);
Point3D zeroPoint = new Point3D(0, 0, 0);
//We'll use an extra block here to restrict the scope of these variables to just inside the block
//This is to avoid conflicts with the loops below
{
//Set the orientation of the rift exit
Point3D entranceRiftLocation = schematicEntrance.clone();
transformPoint(entranceRiftLocation, schematicEntrance, orientation - schematicDoorMeta, pocketCenter);
LinkData sideLink = dimHelper.instance.getLinkDataFromCoords(
entranceRiftLocation.getX(),
entranceRiftLocation.getY(),
entranceRiftLocation.getZ(),
world);
sideLink.linkOrientation = world.getBlockMetadata(
entranceRiftLocation.getX(),
entranceRiftLocation.getY() - 1,
entranceRiftLocation.getZ());
}
//Generate the LinkData defined by the door placement, Iron Dim doors first
for(Point3D point : sideLinks)
{
int depth = dimHelper.instance.getDimDepth(originDimID);
int forwardNoise = MathHelper.getRandomIntegerInRange(rand, -50 * (depth + 1), 150 * (depth + 1));
int sidewaysNoise = MathHelper.getRandomIntegerInRange(rand, -10 * (depth + 1), 10 * (depth + 1));
int depth = dimHelper.instance.getDimDepth(originDimID) + 1;
int forwardNoise = MathHelper.getRandomIntegerInRange(rand, -50 * depth, 150 * depth);
int sidewaysNoise = MathHelper.getRandomIntegerInRange(rand, -10 * depth, 10 * depth);
//Transform doorLocation to the pocket coordinate system.
//Transform doorLocation to the pocket coordinate system
Point3D doorLocation = point.clone();
transformPoint(doorLocation, entrance, orientation - schematicDoorMeta, pocketOrigin);
transformPoint(doorLocation, schematicEntrance, orientation - schematicDoorMeta, pocketCenter);
int blockDirection = world.getBlockMetadata(doorLocation.getX(), doorLocation.getY() - 1, doorLocation.getZ());
//Rotate the link destination noise to point in the same direction as the door exit
@@ -1019,24 +992,18 @@ public class SchematicLoader
dimHelper.instance.createPocket(sideLink, true, true);
}
//generate linkData for wooden dim doors leading to the overworld
//Generate linkData for wooden dim doors leading to the overworld
for(Point3D point : exitLinks)
{
try
{
//Transform doorLocation to the pocket coordinate system.
Point3D doorLocation = point.clone();
transformPoint(doorLocation, entrance, orientation - schematicDoorMeta, pocketOrigin);
transformPoint(doorLocation, schematicEntrance, orientation - schematicDoorMeta, pocketCenter);
int blockDirection = world.getBlockMetadata(doorLocation.getX(), doorLocation.getY() - 1, doorLocation.getZ());
Point3D linkDestination = doorLocation.clone();
//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(0, 0, 0);
transformPoint(linkDestination, zeroPoint, blockDirection - EAST_DOOR_METADATA, doorLocation);
LinkData randomLink=dimHelper.instance.getRandomLinkData(false);
LinkData randomLink = dimHelper.instance.getRandomLinkData(false);
LinkData sideLink = new LinkData(destDimID,
dimHelper.dimList.get(originDimID).exitDimLink.destDimID,
doorLocation.getX(),
@@ -1047,22 +1014,21 @@ public class SchematicLoader
linkDestination.getZ(),
true, blockDirection);
if(sideLink.destDimID==properties.LimboDimensionID)
if (sideLink.destDimID == properties.LimboDimensionID)
{
sideLink.destDimID=0;
sideLink.destDimID = 0;
}
else if((rand.nextBoolean()&&randomLink!=null))
else if ((rand.nextBoolean() && randomLink != null))
{
sideLink.destDimID=randomLink.locDimID;
// System.out.println("randomLink");
sideLink.destDimID = randomLink.locDimID;
}
sideLink.destYCoord=yCoordHelper.getFirstUncovered(sideLink.destDimID, linkDestination.getX(),10,linkDestination.getZ());
sideLink.destYCoord = yCoordHelper.getFirstUncovered(sideLink.destDimID, linkDestination.getX(), 10, linkDestination.getZ());
if(sideLink.destYCoord<5)
if (sideLink.destYCoord < 5)
{
sideLink.destYCoord=70;
sideLink.destYCoord = 70;
}
sideLink.linkOrientation=world.getBlockMetadata(linkDestination.getX(),linkDestination.getY()- 1,linkDestination.getZ());
sideLink.linkOrientation = world.getBlockMetadata(linkDestination.getX(), linkDestination.getY() - 1, linkDestination.getZ());
dimHelper.instance.createLink(sideLink);
dimHelper.instance.createLink(sideLink.destDimID ,
@@ -1075,7 +1041,7 @@ public class SchematicLoader
sideLink.locZCoord,
dimHelper.instance.flipDoorMetadata(sideLink.linkOrientation));
if(world.getBlockId(linkDestination.getX(),linkDestination.getY() -3,linkDestination.getZ()) == properties.FabricBlockID)
if (world.getBlockId(linkDestination.getX(),linkDestination.getY() -3,linkDestination.getZ()) == properties.FabricBlockID)
{
setBlockDirectly(world,linkDestination.getX(),linkDestination.getY()-2,linkDestination.getZ(),Block.stoneBrick.blockID,0);
}
@@ -1092,27 +1058,23 @@ public class SchematicLoader
linkDestination.getZ()));
}
}
catch(Exception E)
catch (Exception E)
{
E.printStackTrace();
}
}
//spawn monoliths
//Spawn monoliths
for(Point3D point : monolithSpawns)
{
//Transform the frame block's location to the pocket coordinate system
Point3D frameLocation = point.clone();
transformPoint(frameLocation, entrance, orientation - schematicDoorMeta, pocketOrigin);
transformPoint(frameLocation, schematicEntrance, orientation - schematicDoorMeta, pocketCenter);
Entity mob = new MobObelisk(world);
mob.setLocationAndAngles(frameLocation.getX(), frameLocation.getY(), frameLocation.getZ(), 1, 1); //TODO: Why not set the angles to 0? @.@ ~SenseiKiwi
world.spawnEntityInWorld(mob);
}
Point3D entranceRiftLocation = entrance.clone();
transformPoint(entranceRiftLocation, entrance, orientation - schematicDoorMeta, pocketOrigin);
dimHelper.instance.getLinkDataFromCoords(entranceRiftLocation.getX(), entranceRiftLocation.getY(), entranceRiftLocation.getZ(), world).linkOrientation=world.getBlockMetadata(entranceRiftLocation.getX(), entranceRiftLocation.getY()-1, entranceRiftLocation.getZ());
}
private void transformPoint(Point3D position, Point3D srcOrigin, int angle, Point3D destOrigin)
@@ -1155,7 +1117,7 @@ public class SchematicLoader
rx = tx;
rz = tz;
break;
case 1: //270 degrees counterclockwise
case 1: //90 degrees clockwise
rx = -tz;
rz = tx;
break;
@@ -1163,7 +1125,7 @@ public class SchematicLoader
rx = -tx;
rz = -tz;
break;
case 3: //90 degrees counterclockwise
case 3: //270 degrees clockwise
rx = tz;
rz = -tx;