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 WEST_DOOR_METADATA = 2;
private final static int NORTH_DOOR_METADATA = 3; private final static int NORTH_DOOR_METADATA = 3;
public int transMeta;
private DDProperties properties = DDProperties.instance(); private DDProperties properties = DDProperties.instance();
public SchematicLoader() { } 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) public void generateSchematic(int riftX, int riftY, int riftZ, int orientation, int destDimID, int originDimID, String schematicPath)
{ {
short width=0; short width = 0;
short height=0; short height = 0;
short length=0; short length = 0;
//list of combined blockIds //list of combined blockIds
short[] blocks = new short[0]; short[] blocks = new short[0];
@@ -703,7 +701,7 @@ public class SchematicLoader
NBTTagList entities; NBTTagList entities;
//the wooden door leading into the pocket //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 //the iron dim doors leading to more pockets
ArrayList<Point3D> sideLinks = new ArrayList<Point3D>(); ArrayList<Point3D> sideLinks = new ArrayList<Point3D>();
@@ -717,9 +715,8 @@ public class SchematicLoader
//load the schematic from disk //load the schematic from disk
try try
{ {
InputStream input; InputStream input;
String fname= schematicPath ; String fname = schematicPath ;
if(!(new File(fname).exists())) if(!(new File(fname).exists()))
{ {
@@ -745,7 +742,7 @@ public class SchematicLoader
addId = nbtdata.getByteArray("AddBlocks"); addId = nbtdata.getByteArray("AddBlocks");
//create combined block list //create combined block list
blocks=new short[blockId.length]; blocks = new short[blockId.length];
//load ticking things //load ticking things
tileEntities = nbtdata.getTagList("TileEntities"); tileEntities = nbtdata.getTagList("TileEntities");
@@ -804,15 +801,18 @@ public class SchematicLoader
long factorB = rand.nextLong() / 2L * 2L + 1L; long factorB = rand.nextLong() / 2L * 2L + 1L;
rand.setSeed((riftX >> 4) * factorA + (riftZ >> 4) * factorB ^ world.getSeed()); 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; int x, y, z;
//The real coordinates where a block will be placed //The real point where a block will be placed
int realX = 0; int realX, realY, realZ;
int realY = 0; Point3D pocketPoint = new Point3D(0, 0, 0);
int realZ = 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. //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 //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; //NBTTagList tileEntity = tileEntities;
//int size = tileEntity.tagCount(); //int size = tileEntity.tagCount();
if (currentBlock == Block.doorIron.blockID && indexBelow >= 0 && blocks[indexBelow] == Block.doorIron.blockID) if (currentBlock == Block.doorIron.blockID && indexBelow >= 0 && blocks[indexBelow] == Block.doorIron.blockID)
{ {
sideLinks.add(new Point3D(x, y, z)); sideLinks.add(new Point3D(x, y, z));
@@ -845,7 +844,7 @@ public class SchematicLoader
} }
else if (indexBelow >= 0 && blocks[indexBelow] == Block.doorWood.blockID) 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. 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.
} }
} }
@@ -856,104 +855,66 @@ public class SchematicLoader
} }
} }
} }
//Compute the Y-axis translation that places our structure correctly
int offsetY = riftY - entrance.getY();
//TODO: HAX REMOVE THIS! //TODO: HAX REMOVE THIS!
schematicDoorMeta = NORTH_DOOR_METADATA; 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 //Loop to actually place the blocks
for (x = 0; x < width; x++) for (x = 0; x < width; x++)
{ {
for (z = 0; z < length; z++) 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++) for (y = 0; y < height; y++)
{ {
int index = y * width * length + z * width + x; //Reinitialize pocketPoint with the current schematic coordinate system
realY = y + offsetY; 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 index = y * width * length + z * width + x;
int blockMetaData=blockData[index]; int currentBlock = blocks[index];
int blockMetadata = blockData[index];
NBTTagList tileEntity = tileEntities; NBTTagList tileEntity = tileEntities;
//replace tagging blocks with air, and mob blocks with FoR //replace tagging blocks with air, and mod blocks with FoR
if(blockToReplace==Block.endPortalFrame.blockID) 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 //Place blocks and set metadata
if(blockToReplace>0) if (currentBlock > 0)
{ {
//rotate the metaData blocks //Calculate new metadata for blocks that have orientations (e.g. doors, pistons)
this.transMeta=this.transformMetadata(blockMetaData, orientation, blockToReplace); int fixedMetadata = transformMetadata(blockMetadata, orientation, currentBlock);
//convert vanilla doors to dim doors, then place vanilla blocks //Convert vanilla doors to dim doors or place blocks
if(blockToReplace==Block.doorIron.blockID) 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 else
{ {
setBlockDirectly(world,realX, realY, realZ,blockToReplace, transMeta ); setBlockDirectly(world, realX, realY, realZ, currentBlock, fixedMetadata);
} }
//generate container inventories //Fill containers (e.g. chests, dispensers)
if(Block.blocksList[blockToReplace] instanceof BlockContainer) if(Block.blocksList[currentBlock] instanceof BlockContainer)
{ {
/** /**
TileEntity tile = world.getBlockTileEntity(i+xCooe, j+yCooe, k+zCooe); TileEntity tile = world.getBlockTileEntity(i+xCooe, j+yCooe, k+zCooe);
@@ -964,43 +925,55 @@ public class SchematicLoader
} }
**/ **/
//fill chests //Fill chests
if(world.getBlockTileEntity(realX, realY, realZ) instanceof TileEntityChest) if (world.getBlockTileEntity(realX, realY, realZ) instanceof TileEntityChest)
{ {
TileEntityChest chest = (TileEntityChest) world.getBlockTileEntity(realX, realY, realZ); TileEntityChest chest = (TileEntityChest) world.getBlockTileEntity(realX, realY, realZ);
ChestGenHooks info = DDLoot.DungeonChestInfo; 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 //Fill dispensers
if(world.getBlockTileEntity(realX, realY, realZ) instanceof TileEntityDispenser) if (world.getBlockTileEntity(realX, realY, realZ) instanceof TileEntityDispenser)
{ {
TileEntityDispenser dispenser = (TileEntityDispenser) world.getBlockTileEntity(realX, realY, realZ); TileEntityDispenser dispenser = (TileEntityDispenser) world.getBlockTileEntity(realX, realY, realZ);
dispenser.addItem(new ItemStack(Item.arrow, 64)); dispenser.addItem(new ItemStack(Item.arrow, 64));
} }
} }
} }
} }
} }
} }
//Set up variables to use transformPoint() //We'll use an extra block here to restrict the scope of these variables to just inside the block
Point3D pocketOrigin = new Point3D(riftX, riftY, riftZ); //This is to avoid conflicts with the loops below
Point3D zeroPoint = new Point3D(0, 0, 0); {
//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 //Generate the LinkData defined by the door placement, Iron Dim doors first
for(Point3D point : sideLinks) for(Point3D point : sideLinks)
{ {
int depth = dimHelper.instance.getDimDepth(originDimID); int depth = dimHelper.instance.getDimDepth(originDimID) + 1;
int forwardNoise = MathHelper.getRandomIntegerInRange(rand, -50 * (depth + 1), 150 * (depth + 1)); int forwardNoise = MathHelper.getRandomIntegerInRange(rand, -50 * depth, 150 * depth);
int sidewaysNoise = MathHelper.getRandomIntegerInRange(rand, -10 * (depth + 1), 10 * (depth + 1)); 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(); 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()); 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 //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 //and add it to the door's location. Use EAST as the reference orientation since linkDestination
//is constructed as if pointing East. //is constructed as if pointing East.
@@ -1019,24 +992,18 @@ public class SchematicLoader
dimHelper.instance.createPocket(sideLink, true, true); 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) for(Point3D point : exitLinks)
{ {
try try
{ {
//Transform doorLocation to the pocket coordinate system. //Transform doorLocation to the pocket coordinate system.
Point3D doorLocation = point.clone(); 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()); 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, LinkData sideLink = new LinkData(destDimID,
dimHelper.dimList.get(originDimID).exitDimLink.destDimID, dimHelper.dimList.get(originDimID).exitDimLink.destDimID,
doorLocation.getX(), doorLocation.getX(),
@@ -1047,22 +1014,21 @@ public class SchematicLoader
linkDestination.getZ(), linkDestination.getZ(),
true, blockDirection); 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; sideLink.destDimID = randomLink.locDimID;
// System.out.println("randomLink");
} }
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);
dimHelper.instance.createLink(sideLink.destDimID , dimHelper.instance.createLink(sideLink.destDimID ,
@@ -1075,7 +1041,7 @@ public class SchematicLoader
sideLink.locZCoord, sideLink.locZCoord,
dimHelper.instance.flipDoorMetadata(sideLink.linkOrientation)); 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); setBlockDirectly(world,linkDestination.getX(),linkDestination.getY()-2,linkDestination.getZ(),Block.stoneBrick.blockID,0);
} }
@@ -1092,27 +1058,23 @@ public class SchematicLoader
linkDestination.getZ())); linkDestination.getZ()));
} }
} }
catch(Exception E) catch (Exception E)
{ {
E.printStackTrace(); E.printStackTrace();
} }
} }
//spawn monoliths //Spawn monoliths
for(Point3D point : monolithSpawns) for(Point3D point : monolithSpawns)
{ {
//Transform the frame block's location to the pocket coordinate system //Transform the frame block's location to the pocket coordinate system
Point3D frameLocation = point.clone(); Point3D frameLocation = point.clone();
transformPoint(frameLocation, entrance, orientation - schematicDoorMeta, pocketOrigin); transformPoint(frameLocation, schematicEntrance, orientation - schematicDoorMeta, pocketCenter);
Entity mob = new MobObelisk(world); Entity mob = new MobObelisk(world);
mob.setLocationAndAngles(frameLocation.getX(), frameLocation.getY(), frameLocation.getZ(), 1, 1); //TODO: Why not set the angles to 0? @.@ ~SenseiKiwi mob.setLocationAndAngles(frameLocation.getX(), frameLocation.getY(), frameLocation.getZ(), 1, 1); //TODO: Why not set the angles to 0? @.@ ~SenseiKiwi
world.spawnEntityInWorld(mob); 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) private void transformPoint(Point3D position, Point3D srcOrigin, int angle, Point3D destOrigin)
@@ -1155,7 +1117,7 @@ public class SchematicLoader
rx = tx; rx = tx;
rz = tz; rz = tz;
break; break;
case 1: //270 degrees counterclockwise case 1: //90 degrees clockwise
rx = -tz; rx = -tz;
rz = tx; rz = tx;
break; break;
@@ -1163,7 +1125,7 @@ public class SchematicLoader
rx = -tx; rx = -tx;
rz = -tz; rz = -tz;
break; break;
case 3: //90 degrees counterclockwise case 3: //270 degrees clockwise
rx = tz; rx = tz;
rz = -tx; rz = -tx;