Improved and Integrated DungeonSchematic

Improved DungeonSchematic to the point that it can replace
SchematicLoader as our method of loading dungeons. Some of the code was
copied over rather than refactored to save time. It's been subdivided so
make it much more readable. Also, we can reimplement portions of it as
WorldOperations later on further remove redudancy. Testing shows that
there is one problem left to fix: door blocks are not being set up
correctly at the moment. Rifts are being set up properly and attaching
doors to rifts will show that dungeons continue to generate fine.

Added classes to support DungeonSchematic and its additional filtering
logic on import and export. SpecialBlockFinder handles listing the
entrance, other doors in the dungeon, and end portal frames.
FillContainersOperation is a WorldOperation that fills chests and
dispensers. BlockRotator is a temporary class to hold
transformMetadata() and transformPoint() until we rewrite that code
later.

Stripped out most of the code from SchematicLoader to ensure it's no
longer used. The only remaining function sets up dungeon pockets. We can
phase it out in a later version so as not to delay our release. Removed
references to SchematicLoader in mod_pocketDim since it no longer needs
to be instantiated.
This commit is contained in:
SenseiKiwi
2013-07-30 13:58:14 -04:00
parent 877678c945
commit f4653d0522
11 changed files with 1338 additions and 1273 deletions

View File

@@ -0,0 +1,755 @@
package StevenDimDoors.mod_pocketDim.schematic;
import net.minecraft.block.Block;
import net.minecraft.block.BlockComparator;
import net.minecraft.block.BlockDoor;
import net.minecraft.block.BlockRedstoneRepeater;
import net.minecraft.block.BlockStairs;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper;
public class BlockRotator
{
//This class is temporary. It's just a place in which to hold the old block rotation and transformation code
//until we can rewrite it.
public final static int EAST_DOOR_METADATA = 0;
private final static int SOUTH_DOOR_METADATA = 1;
private final static int WEST_DOOR_METADATA = 2;
public final static int NORTH_DOOR_METADATA = 3;
public static int transformMetadata(int metadata, int orientation, int blockID)
{
//TODO: Replace this horrible function with something prettier. We promise we will for the next version,
//after switching to MC 1.6.
//Hax to fix negative orientations
orientation += 1 << 16;
orientation %= 4;
if (DungeonHelper.instance().metadataFlipList.contains(blockID))
{
switch (orientation)
{
case EAST_DOOR_METADATA:
if (blockID == Block.hopperBlock.blockID)
{
switch (metadata)
{
case 2:
metadata = 5;
break;
case 3:
metadata = 4;
break;
case 4:
metadata = 2;
break;
case 5:
metadata = 3;
break;
}
}
if(Block.blocksList[blockID] instanceof BlockStairs)
{
switch (metadata)
{
case 0:
metadata = 2;
break;
case 1:
metadata = 3;
break;
case 2:
metadata = 1;
break;
case 3:
metadata = 0;
break;
case 7:
metadata = 4;
break;
case 6:
metadata = 5;
break;
case 5:
metadata = 7;
break;
case 4:
metadata = 6;
break;
}
}
else if(blockID== Block.chest.blockID||blockID== Block.chestTrapped.blockID||blockID== Block.ladder.blockID)
{
switch (metadata)
{
case 2:
metadata = 5;
break;
case 3:
metadata = 4;
break;
case 4:
metadata = 2;
break;
case 5:
metadata = 3;
break;
}
}
else if (blockID==Block.vine.blockID)
{
switch (metadata)
{
case 1:
metadata = 2;
break;
case 2:
metadata = 4;
break;
case 4:
metadata = 8;
break;
case 8:
metadata = 1;
break;
}
}
else if(blockID== Block.lever.blockID||blockID== Block.stoneButton.blockID||blockID== Block.woodenButton.blockID||blockID== Block.torchWood.blockID||blockID== Block.torchRedstoneIdle.blockID||blockID== Block.torchRedstoneActive.blockID)
{
switch (metadata)
{
case 12:
metadata = 9;
break;
case 11:
metadata = 10;
break;
case 10:
metadata = 12;
break;
case 9:
metadata = 11;
break;
case 2:
metadata = 4;
break;
case 3:
metadata = 2;
break;
case 1:
metadata = 3;
break;
case 4:
metadata = 1;
break;
}
}
else if(blockID== Block.pistonBase.blockID||blockID==Block.pistonExtension.blockID||blockID==Block.pistonStickyBase.blockID||blockID==Block.dispenser.blockID||blockID==Block.dropper.blockID)
{
switch (metadata)
{
case 4:
metadata = 2;
break;
case 5:
metadata = 3;
break;
case 13:
metadata = 11;
break;
case 12:
metadata = 10;
break;
case 3:
metadata = 4;
break;
case 2:
metadata = 5;
break;
case 11:
metadata = 12;
break;
case 10:
metadata = 13;
break;
}
}
else if(Block.blocksList[blockID] instanceof BlockRedstoneRepeater ||Block.blocksList[blockID] instanceof BlockDoor ||blockID== Block.tripWireSource.blockID||Block.blocksList[blockID] instanceof BlockComparator)
{
switch (metadata)
{
case 0:
metadata = 1;
break;
case 1:
metadata = 2;
break;
case 2:
metadata = 3;
break;
case 3:
metadata = 0;
break;
case 4:
metadata = 5;
break;
case 5:
metadata = 6;
break;
case 6:
metadata = 7;
break;
case 7:
metadata = 4;
break;
case 8:
metadata = 9;
break;
case 9:
metadata = 10;
break;
case 10:
metadata = 11;
break;
case 11:
metadata = 8;
break;
case 12:
metadata = 13;
break;
case 13:
metadata = 14;
break;
case 14:
metadata = 15;
break;
case 15:
metadata = 12;
break;
}
}
break;
case SOUTH_DOOR_METADATA:
if (blockID == Block.hopperBlock.blockID)
{
switch (metadata)
{
case 2:
metadata = 3;
break;
case 3:
metadata = 2;
break;
case 4:
metadata = 5;
break;
case 5:
metadata = 4;
break;
}
}
if(Block.blocksList[blockID] instanceof BlockStairs)
{
switch (metadata)
{
case 0:
metadata = 1;
break;
case 1:
metadata = 0;
break;
case 2:
metadata = 3;
break;
case 3:
metadata = 2;
break;
case 7:
metadata = 6;
break;
case 6:
metadata = 7;
break;
case 5:
metadata = 4;
break;
case 4:
metadata = 5;
break;
}
}
else if(blockID== Block.chest.blockID||blockID== Block.chestTrapped.blockID||blockID==Block.ladder.blockID)
{
switch (metadata)
{
case 2:
metadata = 3;
break;
case 3:
metadata = 2;
break;
case 4:
metadata = 5;
break;
case 5:
metadata = 4;
break;
}
}
else if(blockID==Block.vine.blockID)
{
switch (metadata)
{
case 1:
metadata = 4;
break;
case 2:
metadata = 8;
break;
case 4:
metadata = 1;
break;
case 8:
metadata = 2;
break;
}
}
else if(blockID== Block.lever.blockID||blockID== Block.torchWood.blockID||blockID== Block.torchRedstoneIdle.blockID||blockID== Block.torchRedstoneActive.blockID)
{
switch (metadata)
{
case 12:
metadata = 11;
break;
case 11:
metadata = 12;
break;
case 10:
metadata = 9;
break;
case 9:
metadata = 10;
break;
case 2:
metadata = 1;
break;
case 3:
metadata = 4;
break;
case 1:
metadata = 2;
break;
case 4:
metadata = 3;
break;
}
}
else if(blockID== Block.pistonBase.blockID||blockID==Block.pistonStickyBase.blockID||blockID==Block.dispenser.blockID||blockID==Block.dropper.blockID)
{
switch (metadata)
{
case 4:
metadata = 5;
break;
case 5:
metadata = 4;
break;
case 13:
metadata = 12;
break;
case 12:
metadata = 13;
break;
case 3:
metadata = 2;
break;
case 2:
metadata = 3;
break;
case 11:
metadata = 10;
break;
case 10:
metadata = 11;
break;
}
}
else if(Block.blocksList[blockID] instanceof BlockRedstoneRepeater ||Block.blocksList[blockID] instanceof BlockDoor ||blockID== Block.tripWireSource.blockID||Block.blocksList[blockID] instanceof BlockComparator)
{
switch (metadata)
{
case 0:
metadata = 2;
break;
case 1:
metadata = 3;
break;
case 2:
metadata = 0;
break;
case 3:
metadata = 1;
break;
case 4:
metadata = 6;
break;
case 5:
metadata = 7;
break;
case 6:
metadata = 4;
break;
case 7:
metadata = 5;
break;
case 8:
metadata = 10;
break;
case 9:
metadata = 11;
break;
case 10:
metadata = 8;
break;
case 11:
metadata = 9;
break;
case 12:
metadata = 14;
break;
case 13:
metadata = 15;
break;
case 14:
metadata = 12;
break;
case 15:
metadata = 13;
break;
}
}
break;
case WEST_DOOR_METADATA:
if (blockID == Block.hopperBlock.blockID)
{
switch (metadata)
{
case 2:
metadata = 4;
break;
case 3:
metadata = 5;
break;
case 4:
metadata = 3;
break;
case 5:
metadata = 2;
break;
}
}
if(Block.blocksList[blockID] instanceof BlockStairs)
{
switch (metadata)
{
case 2:
metadata = 0;
break;
case 3:
metadata = 1;
break;
case 1:
metadata = 2;
break;
case 0:
metadata = 3;
break;
case 4:
metadata = 7;
break;
case 5:
metadata = 6;
break;
case 7:
metadata = 5;
break;
case 6:
metadata = 4;
break;
}
}
else if(blockID== Block.chest.blockID||blockID== Block.chestTrapped.blockID||blockID==Block.ladder.blockID)
{
switch (metadata)
{
case 2:
metadata = 4;
break;
case 3:
metadata = 5;
break;
case 4:
metadata = 3;
break;
case 5:
metadata = 2;
break;
}
}
else if(blockID==Block.vine.blockID)
{
switch (metadata)
{
case 1:
metadata = 8;
break;
case 2:
metadata = 1;
break;
case 4:
metadata = 2;
break;
case 8:
metadata = 4;
break;
}
}
else if(blockID== Block.lever.blockID||blockID== Block.torchWood.blockID||blockID== Block.torchRedstoneIdle.blockID||blockID== Block.torchRedstoneActive.blockID)
{
switch (metadata)
{
case 9:
metadata = 12;
break;
case 10:
metadata = 11;
break;
case 12:
metadata = 10;
break;
case 11:
metadata = 9;
break;
case 4:
metadata = 2;
break;
case 2:
metadata = 3;
break;
case 3:
metadata = 1;
break;
case 1:
metadata = 4;
break;
}
}
else if(blockID== Block.pistonBase.blockID||blockID==Block.pistonStickyBase.blockID||blockID==Block.dispenser.blockID||blockID==Block.dropper.blockID)
{
switch (metadata)
{
case 2:
metadata = 4;
break;
case 3:
metadata = 5;
break;
case 11:
metadata = 13;
break;
case 10:
metadata = 12;
break;
case 4:
metadata = 3;
break;
case 5:
metadata = 2;
break;
case 12:
metadata = 11;
break;
case 13:
metadata = 10;
break;
}
}
else if(Block.blocksList[blockID] instanceof BlockRedstoneRepeater ||Block.blocksList[blockID] instanceof BlockDoor ||blockID== Block.tripWireSource.blockID||Block.blocksList[blockID] instanceof BlockComparator)
{
switch (metadata)
{
case 1:
metadata = 0;
break;
case 2:
metadata = 1;
break;
case 3:
metadata = 2;
break;
case 0:
metadata = 3;
break;
case 5:
metadata = 4;
break;
case 6:
metadata = 5;
break;
case 7:
metadata = 6;
break;
case 4:
metadata = 7;
break;
case 9:
metadata = 8;
break;
case 10:
metadata = 9;
break;
case 11:
metadata = 10;
break;
case 8:
metadata = 11;
break;
case 13:
metadata = 12;
break;
case 14:
metadata = 13;
break;
case 15:
metadata = 14;
break;
case 12:
metadata = 15;
break;
}
}
break;
case NORTH_DOOR_METADATA:
/**
* this is the default case- never need to change anything here
*
*/
break;
}
}
return metadata;
}
public static void transformPoint(Point3D position, Point3D srcOrigin, int angle, Point3D destOrigin)
{
//This function receives a position (e.g. point in schematic space), translates it relative
//to a source coordinate system (e.g. the point that will be the center of a schematic),
//then rotates and translates it to obtain the corresponding point in a destination
//coordinate system (e.g. the location of the entry rift in the pocket being generated).
//The result is returned by overwriting the original position so that new object references
//aren't needed. That way, repeated use of this function will not incur as much overhead.
//Position is only overwritten at the end, so it's okay to provide it as srcOrigin or destOrigin as well.
int tx = position.getX() - srcOrigin.getX();
int ty = position.getY() - srcOrigin.getY();
int tz = position.getZ() - srcOrigin.getZ();
//"int angle" specifies a rotation consistent with Minecraft's orientation system.
//That means each increment of 1 in angle would be a 90-degree clockwise turn.
//Given a starting direction A and a destination direction B, the rotation would be
//calculated by (B - A).
//Adjust angle into the expected range
if (angle < 0)
{
int correction = -(angle / 4);
angle = angle + 4 * (correction + 1);
}
angle = angle % 4;
int rx;
int rz;
switch (angle)
{
case 0: //No rotation
rx = tx;
rz = tz;
break;
case 1: //90 degrees clockwise
rx = -tz;
rz = tx;
break;
case 2: //180 degrees
rx = -tx;
rz = -tz;
break;
case 3: //270 degrees clockwise
rx = tz;
rz = -tx;
break;
default: //This should never happen
throw new IllegalStateException("Invalid angle value. This should never happen!");
}
position.setX( rx + destOrigin.getX() );
position.setY( ty + destOrigin.getY() );
position.setZ( rz + destOrigin.getZ() );
}
}

View File

@@ -53,7 +53,7 @@ public class Schematic {
this.tileEntities = source.tileEntities;
}
protected int calculateIndex(int x, int y, int z)
public int calculateIndex(int x, int y, int z)
{
if (x < 0 || x >= width)
throw new IndexOutOfBoundsException("x must be non-negative and less than width");
@@ -64,7 +64,38 @@ public class Schematic {
return (y * width * length + z * width + x);
}
public Point3D calculatePoint(int index)
{
int y = index / (width * length);
index -= y * width * length;
int z = index / width;
index -= z * width;
int x = index;
return new Point3D(x, y, z);
}
public int calculateIndexBelow(int index)
{
return index - (width * length);
}
public short getWidth()
{
return width;
}
public short getHeight()
{
return height;
}
public short getLength()
{
return length;
}
public short getBlockID(int x, int y, int z)
{
return blocks[calculateIndex(x, y, z)];

View File

@@ -1,5 +1,6 @@
package StevenDimDoors.mod_pocketDim.schematic;
import StevenDimDoors.mod_pocketDim.Point3D;
import net.minecraft.world.World;
public abstract class WorldOperation {
@@ -23,6 +24,17 @@ public abstract class WorldOperation {
return true;
}
public boolean apply(World world, Point3D minCorner, Point3D maxCorner)
{
int x = minCorner.getX();
int y = minCorner.getY();
int z = minCorner.getZ();
int width = maxCorner.getX() - x + 1;
int height = maxCorner.getY() - y + 1;
int length = maxCorner.getZ() - z + 1;
return apply(world, x, y, z, width, height, length);
}
public boolean apply(World world, int x, int y, int z, int width, int height, int length)
{
if (!initialize(world, x, y, z, width, height, length))