Merge pull request #2 from Waterpicker/1.8.9

I might gone overboard with how deep I went this time.
This commit is contained in:
Zixiken 2016-06-24 12:15:42 -04:00 committed by GitHub
commit 3c94804241
37 changed files with 859 additions and 1541 deletions

View file

@ -175,11 +175,11 @@ public class BlockRift extends Block implements ITileEntityProvider {
private void destroyNearbyBlocks(World world, int x, int y, int z, Random random)
{
// Find reachable blocks that are vulnerable to rift damage (ignoring air, of course)
ArrayList<Point3D> targets = findReachableBlocks(world, x, y, z, BLOCK_DESTRUCTION_RANGE, false);
ArrayList<BlockPos> targets = findReachableBlocks(world, x, y, z, BLOCK_DESTRUCTION_RANGE, false);
// For each block, randomly decide whether to destroy it.
// The randomness makes it so the destroyed area appears "noisy" if the rift is exposed to a large surface.
for (Point3D target : targets)
for (BlockPos target : targets)
{
if (random.nextInt(MAX_BLOCK_DESTRUCTION_CHANCE) < BLOCK_DESTRUCTION_CHANCE)
{
@ -189,20 +189,20 @@ public class BlockRift extends Block implements ITileEntityProvider {
}
}
private ArrayList<Point3D> findReachableBlocks(World world, int x, int y, int z, int range, boolean includeAir)
private ArrayList<BlockPos> findReachableBlocks(World world, int x, int y, int z, int range, boolean includeAir)
{
int searchVolume = (int) Math.pow(2 * range + 1, 3);
HashMap<Point3D, Integer> pointDistances = new HashMap<Point3D, Integer>(searchVolume);
Queue<Point3D> points = new LinkedList<Point3D>();
ArrayList<Point3D> targets = new ArrayList<Point3D>();
HashMap<BlockPos, Integer> pointDistances = new HashMap<BlockPos, Integer>(searchVolume);
Queue<BlockPos> points = new LinkedList<BlockPos>();
ArrayList<BlockPos> targets = new ArrayList<BlockPos>();
// Perform a breadth-first search outwards from the point at which the rift is located.
// Record the distances of the points we visit to stop the search at its maximum range.
pointDistances.put(new Point3D(x, y, z), 0);
pointDistances.put(new BlockPos(x, y, z), 0);
addAdjacentBlocks(x, y, z, 0, pointDistances, points);
while (!points.isEmpty())
{
Point3D current = points.remove();
BlockPos current = points.remove();
int distance = pointDistances.get(current);
// If the current block is air, continue searching. Otherwise, add the block to our list.
@ -241,15 +241,15 @@ public class BlockRift extends Block implements ITileEntityProvider {
}
}
private static void addAdjacentBlocks(int x, int y, int z, int distance, HashMap<Point3D, Integer> pointDistances, Queue<Point3D> points)
private static void addAdjacentBlocks(int x, int y, int z, int distance, HashMap<BlockPos, Integer> pointDistances, Queue<BlockPos> points)
{
Point3D[] neighbors = new Point3D[] {
new Point3D(x - 1, y, z),
new Point3D(x + 1, y, z),
new Point3D(x, y - 1, z),
new Point3D(x, y + 1, z),
new Point3D(x, y, z - 1),
new Point3D(x, y, z + 1)
BlockPos[] neighbors = new BlockPos[] {
new BlockPos(x - 1, y, z),
new BlockPos(x + 1, y, z),
new BlockPos(x, y - 1, z),
new BlockPos(x, y + 1, z),
new BlockPos(x, y, z - 1),
new BlockPos(x, y, z + 1)
};
for (int index = 0; index < neighbors.length; index++)
{
@ -268,13 +268,13 @@ public class BlockRift extends Block implements ITileEntityProvider {
Point4D source = parent.source();
// Find reachable blocks that are vulnerable to rift damage and include air
ArrayList<Point3D> targets = findReachableBlocks(world, source.getX(), source.getY(), source.getZ(),
ArrayList<BlockPos> targets = findReachableBlocks(world, source.getX(), source.getY(), source.getZ(),
RIFT_SPREAD_RANGE, true);
if (!targets.isEmpty())
{
// Choose randomly from among the possible locations where we can spawn a new rift
Point3D target = targets.get( random.nextInt(targets.size()) );
BlockPos target = targets.get( random.nextInt(targets.size()) );
x = target.getX();
y = target.getY();
z = target.getZ();
@ -310,7 +310,7 @@ public class BlockRift extends Block implements ITileEntityProvider {
{
ArrayList<Point3D> targets=findReachableBlocks(world, x, y, z, 2, false);
ArrayList<BlockPos> targets=findReachableBlocks(world, x, y, z, 2, false);
TileEntityRift tile = (TileEntityRift)world.getTileEntity(x, y, z);

View file

@ -4,8 +4,10 @@ import com.zixiken.dimdoors.core.DimLink;
import com.zixiken.dimdoors.core.LinkType;
import com.zixiken.dimdoors.core.PocketManager;
import com.zixiken.dimdoors.DimDoors;
import net.minecraft.block.BlockDoor;
import net.minecraft.block.material.Material;
import net.minecraft.item.Item;
import net.minecraft.util.BlockPos;
import net.minecraft.world.World;
import com.zixiken.dimdoors.core.NewDimData;
@ -19,15 +21,12 @@ public class WarpDoor extends BaseDimDoor {
}
@Override
public void placeLink(World world, int x, int y, int z)
{
if (!world.isRemote && world.getBlock(x, y - 1, z) == this)
{
public void placeLink(World world, BlockPos pos) {
if (!world.isRemote && world.getBlockState(pos.down()) == this) {
NewDimData dimension = PocketManager.createDimensionData(world);
DimLink link = dimension.getLink(x, y, z);
if (link == null && dimension.isPocketDimension())
{
dimension.createLink(x, y, z, LinkType.SAFE_EXIT,world.getBlockMetadata(x, y - 1, z));
DimLink link = dimension.getLink(pos);
if (link == null && dimension.isPocketDimension()) {
dimension.createLink(pos, LinkType.SAFE_EXIT,world. getBlockState(pos.down()).getValue(BlockDoor.FACING));
}
}
}

View file

@ -42,16 +42,12 @@ public class DDLock
/**
* see if we could unlock this door if it where locked.
* @param link
* @param itemStack
* @return
*/
public boolean doesKeyUnlock(ItemStack itemStack)
{
for(int key :getKeys(itemStack))
{
if(this.lockKey == key)
{
public boolean doesKeyUnlock(ItemStack itemStack) {
for(int key :getKeys(itemStack)) {
if(this.lockKey == key) {
return true;
}
}
@ -60,11 +56,10 @@ public class DDLock
/**
* Tries to open this lock
* @param item
* @param itemStack
* @return
*/
public boolean tryToOpen(ItemStack itemStack)
{
public boolean tryToOpen(ItemStack itemStack) {
return (!this.lockState)||this.doesKeyUnlock(itemStack);
}
@ -78,10 +73,8 @@ public class DDLock
* gets all the keys stored on a single key item
* @return
*/
public static int[] getKeys(ItemStack itemStack)
{
if (!itemStack.hasTagCompound())
{
public static int[] getKeys(ItemStack itemStack) {
if (!itemStack.hasTagCompound()) {
initNBTTags(itemStack);
}
return itemStack.getTagCompound().getIntArray("DDKeys");
@ -92,8 +85,7 @@ public class DDLock
* @return
* @return
*/
public static void addKeys(ItemStack itemStack, int[] keysToAdd)
{
public static void addKeys(ItemStack itemStack, int[] keysToAdd) {
int[] oldKeys = DDLock.getKeys(itemStack);
int[] newKeys = new int[keysToAdd.length+oldKeys.length];
System.arraycopy(oldKeys, 0, newKeys, 0, oldKeys.length);
@ -107,10 +99,8 @@ public class DDLock
* @return
* @return
*/
public static void setKeys(ItemStack itemStack, int[] keys)
{
if (!itemStack.hasTagCompound())
{
public static void setKeys(ItemStack itemStack, int[] keys) {
if (!itemStack.hasTagCompound()) {
initNBTTags(itemStack);
}
NBTTagCompound tag = itemStack.getTagCompound();
@ -122,8 +112,7 @@ public class DDLock
* Gives the key a new NBTTag
* @param itemStack
*/
public static void initNBTTags(ItemStack itemStack)
{
public static void initNBTTags(ItemStack itemStack) {
itemStack.setTagCompound(new NBTTagCompound());
NBTTagCompound tag = itemStack.getTagCompound();
tag.setIntArray("DDKeys", new int[0]);
@ -144,20 +133,16 @@ public class DDLock
return false;
}
public static boolean isItemKey(ItemStack key)
{
public static boolean isItemKey(ItemStack key) {
return key.getItem() instanceof ItemDDKey;
}
protected static DDLock generateLockKeyPair(ItemStack itemStack, int lockKey2)
{
protected static DDLock generateLockKeyPair(ItemStack itemStack, int lockKey2) {
itemStack.getTagCompound().setBoolean("HasCreatedLock", true);
DDLock.setKeys(itemStack, new int[]{lockKey2});
return new DDLock(true, lockKey2);
}
}

View file

@ -17,6 +17,8 @@ import com.zixiken.dimdoors.world.PocketBuilder;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.gameevent.PlayerEvent;
import net.minecraft.block.Block;
import net.minecraft.block.BlockDoor;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList;
import net.minecraft.entity.item.EntityMinecart;
@ -30,6 +32,8 @@ import net.minecraft.network.play.server.S1DPacketEntityEffect;
import net.minecraft.network.play.server.S1FPacketSetExperience;
import net.minecraft.potion.PotionEffect;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
@ -37,8 +41,7 @@ import net.minecraftforge.common.DimensionManager;
import com.zixiken.dimdoors.watcher.ClientDimData;
import cpw.mods.fml.common.registry.GameRegistry;
public class DDTeleporter
{
public class DDTeleporter {
private static final Random random = new Random();
private static final int NETHER_DIMENSION_ID = -1;
private static final int OVERWORLD_DIMENSION_ID = 0;
@ -59,50 +62,45 @@ public class DDTeleporter
/**
* Checks if the destination supplied is safe (i.e. filled by any replaceable or non-opaque blocks)
*/
private static boolean checkDestination(WorldServer world, Point4D destination, int orientation)
{
private static boolean checkDestination(WorldServer world, Point4D destination, EnumFacing orientation) {
int x = destination.getX();
int y = destination.getY();
int z = destination.getZ();
Block blockTop;
Block blockBottom;
Point3D point;
BlockPos point;
switch (orientation)
{
case 0:
point = new Point3D(x - 1, y - 1, z);
switch (orientation) {
case SOUTH:
point = new BlockPos(x - 1, y - 1, z);
break;
case 1:
point = new Point3D(x, y - 1, z - 1);
case WEST:
point = new BlockPos(x, y - 1, z - 1);
break;
case 2:
point = new Point3D(x + 1, y - 1, z);
case NORTH:
point = new BlockPos(x + 1, y - 1, z);
break;
case 3:
point = new Point3D(x, y - 1, z + 1);
case EAST:
point = new BlockPos(x, y - 1, z + 1);
break;
default:
point = new Point3D(x, y - 1, z);
point = new BlockPos(x, y - 1, z);
break;
}
blockBottom = world.getBlock(point.getX(), point.getY(), point.getZ());
blockTop = world.getBlock(point.getX(), point.getY() + 1, point.getZ());
if (blockBottom != null)
{
if (!blockBottom.isReplaceable(world, point.getX(), point.getY(), point.getZ()) && world.isBlockNormalCubeDefault(point.getX(), point.getY(), point.getZ(), false))
{
return false;
}
}
if (blockTop != null)
{
if (!blockTop.isReplaceable(world, point.getX(), point.getY() + 1, point.getZ()))
{
blockBottom = world.getBlockState(point).getBlock();
blockTop = world.getBlockState(point.up()).getBlock();
if (blockBottom != null) {
if (!blockBottom.isReplaceable(world, point) && world.isBlockNormalCube(point, false)) {
return false;
}
} if (blockTop != null) {
if (!blockTop.isReplaceable(world, point.up())) {
return false;
}
}
return true;
}
@ -112,16 +110,16 @@ public class DDTeleporter
int y = destination.getY();
int z = destination.getZ();
int orientation;
EnumFacing orientation;
if (checkOrientation)
{
orientation = getDestinationOrientation(destination, properties);
entity.rotationYaw = (orientation * 90) + 90;
entity.rotationYaw = (orientation.getIndex() * 90) + 90;
}
else
{
// Teleport the entity to the precise destination point
orientation = -1;
orientation = EnumFacing.SOUTH;
}
if (entity instanceof EntityPlayer)
@ -148,8 +146,7 @@ public class DDTeleporter
break;
}
}
else
{
else {
player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5);
}
}
@ -217,29 +214,25 @@ public class DDTeleporter
entity.setPosition(x, y, z);
}
private static int getDestinationOrientation(Point4D door, DDProperties properties)
{
private static EnumFacing getDestinationOrientation(Point4D door, DDProperties properties) {
World world = DimensionManager.getWorld(door.getDimension());
if (world == null)
{
if (world == null) {
throw new IllegalStateException("The destination world should be loaded!");
}
//Check if the block below that point is actually a door
Block block = world.getBlock(door.getX(), door.getY() - 1, door.getZ());
if (block==null || !(block instanceof IDimDoor))
{
IBlockState block = world.getBlockState(door.toBlockPos().down());
if (block==null || !(block instanceof IDimDoor)) {
//Return the pocket's orientation instead
return PocketManager.createDimensionData(world).orientation();
}
//Return the orientation portion of its metadata
return world.getBlockMetadata(door.getX(), door.getY() - 1, door.getZ()) & 3;
return world.getBlockState(door.toBlockPos().down()).getValue(BlockDoor.FACING);
}
public static Entity teleportEntity(Entity entity, Point4D destination, boolean checkOrientation)
{
public static Entity teleportEntity(Entity entity, Point4D destination, boolean checkOrientation) {
if (entity == null)
{
throw new IllegalArgumentException("entity cannot be null.");
@ -390,6 +383,7 @@ public class DDTeleporter
// Let's try doing this down here in case this is what's killing NEI.
FMLCommonHandler.instance().firePlayerChangedDimensionEvent((EntityPlayer) entity, oldWorld.provider.dimensionId, newWorld.provider.dimensionId);
}
DDTeleporter.placeInPortal(entity, newWorld, destination, properties, checkOrientation);
return entity;
}
@ -591,7 +585,7 @@ public class DDTeleporter
return false;
}
Point3D destination = yCoordHelper.findDropPoint(world, source.getX(), source.getY() + 1, source.getZ());
BlockPos destination = yCoordHelper.findDropPoint(world, source.getX(), source.getY() + 1, source.getZ());
if (destination != null)
{
current.root().setLinkDestination(link, destination.getX(), destination.getY(), destination.getZ());
@ -707,9 +701,9 @@ public class DDTeleporter
}
int startY = source.getY() - 2;
Point3D destination;
Point3D locationUp = yCoordHelper.findSafeCubeUp(world, source.getX(), startY, source.getZ());
Point3D locationDown = yCoordHelper.findSafeCubeDown(world, source.getX(), startY, source.getZ());
BlockPos destination;
BlockPos locationUp = yCoordHelper.findSafeCubeUp(world, source.getX(), startY, source.getZ());
BlockPos locationDown = yCoordHelper.findSafeCubeDown(world, source.getX(), startY, source.getZ());
if (locationUp == null)
{

View file

@ -3,23 +3,22 @@ package com.zixiken.dimdoors.core;
import java.util.LinkedList;
import java.util.List;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.ChunkCoordIntPair;
import com.zixiken.dimdoors.util.Point4D;
public abstract class DimLink
{
protected Point4D point;
protected int orientation;
protected EnumFacing orientation;
protected DDLock lock;
protected DimLink parent;
protected LinkTail tail;
protected List<DimLink> children;
protected DimLink(Point4D point, int orientation, DDLock lock, DimLink parent)
{
protected DimLink(Point4D point, EnumFacing orientation, DDLock lock, DimLink parent) {
if (parent.point.getDimension() != point.getDimension())
{
if (parent.point.getDimension() != point.getDimension()) {
// Ban having children in other dimensions to avoid serialization issues with cross-dimensional tails
throw new IllegalArgumentException("source and parent.source must have the same dimension.");
}
@ -32,8 +31,7 @@ public abstract class DimLink
parent.children.add(this);
}
protected DimLink(Point4D point, int orientation, DDLock lock, LinkType linkType)
{
protected DimLink(Point4D point, EnumFacing orientation, DDLock lock, LinkType linkType) {
/**This really cant happen anymore, I guess.
*
if ((linkType < LinkTypes.ENUM_MIN || linkType > LinkTypes.ENUM_MAX) && linkType != LinkTypes.CLIENT_SIDE)
@ -50,23 +48,19 @@ public abstract class DimLink
this.children = new LinkedList<DimLink>();
}
public Point4D source()
{
public Point4D source() {
return point;
}
public void clear()
{
public void clear() {
//Release children
for (DimLink child : children)
{
for (DimLink child : children) {
child.parent = null;
}
children.clear();
//Release parent
if (parent != null)
{
if (parent != null) {
parent.children.remove(this);
}
@ -75,48 +69,39 @@ public abstract class DimLink
tail = new LinkTail(LinkType.NORMAL, null);
}
public int orientation()
{
public EnumFacing orientation() {
return orientation;
}
public Point4D destination()
{
public Point4D destination() {
return tail.getDestination();
}
public int getDestinationOrientation()
{
public EnumFacing getDestinationOrientation() {
DimLink destinationLink = PocketManager.getLink(tail.getDestination());
if (destinationLink != null)
{
if (destinationLink != null) {
return destinationLink.orientation();
}
return (orientation + 2) % 4;
return orientation.rotateY().rotateY();
}
public boolean hasDestination()
{
return (tail.getDestination() != null);
public boolean hasDestination() {
return tail.getDestination() != null;
}
public Iterable<DimLink> children()
{
public Iterable<DimLink> children() {
return children;
}
public int childCount()
{
public int childCount() {
return children.size();
}
public DimLink parent()
{
public DimLink parent() {
return parent;
}
public LinkType linkType()
{
public LinkType linkType() {
return tail.getLinkType();
}
@ -125,8 +110,7 @@ public abstract class DimLink
* Tries to open this lock. Returns true if the lock is open or if the key can open it
* @return
*/
public boolean tryToOpen(ItemStack item)
{
public boolean tryToOpen(ItemStack item) {
return lock.tryToOpen(item);
}
@ -134,8 +118,7 @@ public abstract class DimLink
* Tests if the given key item fits this lock
* @return
*/
public boolean doesKeyUnlock(ItemStack item)
{
public boolean doesKeyUnlock(ItemStack item) {
return lock.doesKeyUnlock(item);
}
@ -143,8 +126,7 @@ public abstract class DimLink
* test if there is a lock, regardless if it is locked or not.
* @return
*/
public boolean hasLock()
{
public boolean hasLock() {
return this.lock!=null;
}
@ -152,8 +134,7 @@ public abstract class DimLink
* Tests if the lock is open or not
*
*/
public boolean getLockState()
{
public boolean getLockState() {
return this.hasLock()&&this.lock.getLockState();
}
@ -161,19 +142,16 @@ public abstract class DimLink
* gets the actual lock object
* @return
*/
public DDLock getLock()
{
public DDLock getLock() {
return this.lock;
}
public ChunkCoordIntPair getChunkCoordinates()
{
public ChunkCoordIntPair getChunkCoordinates() {
return new ChunkCoordIntPair(point.getX() >> 4, point.getZ() >> 4);
}
@Override
public String toString()
{
public String toString() {
return point + " -> " + (hasDestination() ? destination() : "()");
}
}

View file

@ -17,6 +17,8 @@ import com.zixiken.dimdoors.dungeon.pack.DungeonPack;
import com.zixiken.dimdoors.util.Point4D;
import com.zixiken.dimdoors.watcher.IUpdateWatcher;
import net.minecraft.item.ItemStack;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.World;
import com.zixiken.dimdoors.saving.IPackable;
@ -25,52 +27,39 @@ import com.zixiken.dimdoors.saving.PackedDungeonData;
import com.zixiken.dimdoors.saving.PackedLinkData;
import com.zixiken.dimdoors.saving.PackedLinkTail;
public abstract class NewDimData implements IPackable<PackedDimData>
{
private static class InnerDimLink extends DimLink
{
public InnerDimLink(Point4D source, DimLink parent, int orientation, DDLock lock)
{
public abstract class NewDimData implements IPackable<PackedDimData> {
private static class InnerDimLink extends DimLink {
public InnerDimLink(Point4D source, DimLink parent, EnumFacing orientation, DDLock lock) {
super(source, orientation, lock, parent);
}
public InnerDimLink(Point4D source, LinkType linkType, int orientation, DDLock lock)
{
public InnerDimLink(Point4D source, LinkType linkType, EnumFacing orientation, DDLock lock) {
super(source, orientation, lock, linkType);
}
public void setDestination(int x, int y, int z, NewDimData dimension)
{
tail.setDestination(new Point4D(x, y, z, dimension.id()));
public void setDestination(BlockPos pos, NewDimData dimension) {
tail.setDestination(new Point4D(pos, dimension.id()));
}
public boolean overwrite(InnerDimLink nextParent,int orientation)
{
if (nextParent == null)
{
public boolean overwrite(InnerDimLink nextParent, EnumFacing orientation) {
if (nextParent == null) {
throw new IllegalArgumentException("nextParent cannot be null.");
}
if (this == nextParent)
{
} if (this == nextParent) {
//Ignore this request silently
return false;
}
if (nextParent.point.getDimension() != point.getDimension())
{
} if (nextParent.point.getDimension() != point.getDimension()) {
// Ban having children in other dimensions to avoid serialization issues with cross-dimensional tails
throw new IllegalArgumentException("source and parent.source must have the same dimension.");
}
//Release children
for (DimLink child : children)
{
for (DimLink child : children) {
((InnerDimLink) child).parent = null;
}
children.clear();
//Release parent
if (parent != null)
{
if (parent != null) {
parent.children.remove(this);
}
@ -82,18 +71,15 @@ public abstract class NewDimData implements IPackable<PackedDimData>
return true;
}
public void overwrite(LinkType linkType, int orientation)
{
public void overwrite(LinkType linkType, EnumFacing orientation) {
//Release children
for (DimLink child : children)
{
for (DimLink child : children) {
((InnerDimLink) child).parent = null;
}
children.clear();
//Release parent
if (parent != null)
{
if (parent != null) {
parent.children.remove(this);
}
@ -108,8 +94,7 @@ public abstract class NewDimData implements IPackable<PackedDimData>
* only use this on the client to update errything
* @param lock
*/
public void setLock(DDLock lock)
{
public void setLock(DDLock lock) {
this.lock = lock;
}
@ -118,20 +103,16 @@ public abstract class NewDimData implements IPackable<PackedDimData>
* @param itemStack
* @return
*/
public boolean createLock(ItemStack itemStack, int lockKey)
{
if(this.hasLock()||DDLock.hasCreatedLock(itemStack))
{
public boolean createLock(ItemStack itemStack, int lockKey) {
if(this.hasLock()||DDLock.hasCreatedLock(itemStack)) {
return false;
}
this.lock = DDLock.generateLockKeyPair(itemStack, lockKey);
return true;
}
public void removeLock(ItemStack itemStack, InnerDimLink link)
{
if(link.doesKeyUnlock(itemStack))
{
public void removeLock(ItemStack itemStack, InnerDimLink link) {
if(link.doesKeyUnlock(itemStack)) {
link.lock = null;
}
}
@ -153,7 +134,7 @@ public abstract class NewDimData implements IPackable<PackedDimData>
protected NewDimData root;
protected List<NewDimData> children;
protected Point4D origin;
protected int orientation;
protected EnumFacing orientation;
protected DungeonData dungeon;
protected boolean modified;
public IUpdateWatcher<ClientLinkData> linkWatcher;
@ -162,10 +143,8 @@ public abstract class NewDimData implements IPackable<PackedDimData>
// Don't write this field to a file - it should be recreated on startup
private Map<ChunkCoordIntPair, List<InnerDimLink>> chunkMapping;
protected NewDimData(int id, NewDimData parent, DimensionType type, IUpdateWatcher<ClientLinkData> linkWatcher)
{
if (type != DimensionType.ROOT && (parent == null))
{
protected NewDimData(int id, NewDimData parent, DimensionType type, IUpdateWatcher<ClientLinkData> linkWatcher) {
if (type != DimensionType.ROOT && (parent == null)) {
throw new NullPointerException("Dimensions can be pocket dimensions if and only if they have a parent dimension.");
}
@ -177,7 +156,7 @@ public abstract class NewDimData implements IPackable<PackedDimData>
this.packDepth = 0;
this.type = type;
this.isFilled = false;
this.orientation = 0;
this.orientation = EnumFacing.SOUTH;
this.origin = null;
this.dungeon = null;
this.linkWatcher = linkWatcher;
@ -185,26 +164,21 @@ public abstract class NewDimData implements IPackable<PackedDimData>
this.modified = true;
//Register with parent
if (parent != null)
{
if (parent != null) {
//We don't need to raise an update event for adding a child because the child's creation will be signaled.
this.root = parent.root;
this.depth = parent.depth + 1;
parent.children.add(this);
parent.modified = true;
}
else
{
} else {
this.root = this;
this.depth = 0;
}
}
protected NewDimData(int id, NewDimData root, DimensionType type)
{
protected NewDimData(int id, NewDimData root, DimensionType type) {
// This constructor is meant for client-side code only
if (root == null)
{
if (root == null) {
throw new IllegalArgumentException("root cannot be null.");
}
@ -216,7 +190,7 @@ public abstract class NewDimData implements IPackable<PackedDimData>
this.packDepth = 0;
this.type = type;
this.isFilled = false;
this.orientation = 0;
this.orientation = EnumFacing.SOUTH;
this.origin = null;
this.dungeon = null;
this.linkWatcher = null;
@ -226,11 +200,9 @@ public abstract class NewDimData implements IPackable<PackedDimData>
}
public DimLink findNearestRift(World world, int range, int x, int y, int z)
{
public DimLink findNearestRift(World world, int range, BlockPos pos) {
// Sanity check...
if (world.provider.dimensionId != id)
{
if (world.provider.getDimensionId() != id) {
throw new IllegalArgumentException("Attempted to search for links in a World instance for a different dimension!");
}
@ -244,18 +216,13 @@ public abstract class NewDimData implements IPackable<PackedDimData>
int minDistance = Integer.MAX_VALUE;
DDProperties properties = DDProperties.instance();
for (i = -range; i <= range; i++)
{
for (j = -range; j <= range; j++)
{
for (k = -range; k <= range; k++)
{
for (i = -range; i <= range; i++) {
for (j = -range; j <= range; j++) {
for (k = -range; k <= range; k++) {
distance = getAbsoluteSum(i, j, k);
if (distance > 0 && distance < minDistance && world.getBlock(x + i, y + j, z + k) == DimDoors.blockRift)
{
link = getLink(x + i, y + j, z + k);
if (link != null)
{
if (distance > 0 && distance < minDistance && world.getBlockState(pos.add(i, j, k)) == DimDoors.blockRift) {
link = getLink(pos.add(i, j, k));
if (link != null) {
nearest = link;
minDistance = distance;
}
@ -267,11 +234,9 @@ public abstract class NewDimData implements IPackable<PackedDimData>
return nearest;
}
public ArrayList<DimLink> findRiftsInRange(World world, int range, int x, int y, int z)
{
public ArrayList<DimLink> findRiftsInRange(World world, int range, BlockPos pos) {
// Sanity check...
if (world.provider.dimensionId != id)
{
if (world.provider.getDimensionId() != id) {
throw new IllegalArgumentException("Attempted to search for links in a World instance for a different dimension!");
}
@ -283,18 +248,13 @@ public abstract class NewDimData implements IPackable<PackedDimData>
DDProperties properties = DDProperties.instance();
ArrayList<DimLink> links = new ArrayList<DimLink>();
for (i = -range; i <= range; i++)
{
for (j = -range; j <= range; j++)
{
for (k = -range; k <= range; k++)
{
for (i = -range; i <= range; i++) {
for (j = -range; j <= range; j++) {
for (k = -range; k <= range; k++) {
distance = getAbsoluteSum(i, j, k);
if (distance > 0 && world.getBlock(x + i, y + j, z + k) == DimDoors.blockRift)
{
link = getLink(x + i, y + j, z + k);
if (link != null)
{
if (distance > 0 && world.getBlockState(pos.add(i, j, k)) == DimDoors.blockRift) {
link = getLink(pos.add(i, j, k));
if (link != null) {
links.add(link);
}
}
@ -310,66 +270,53 @@ public abstract class NewDimData implements IPackable<PackedDimData>
return Math.abs(i) + Math.abs(j) + Math.abs(k);
}
public DimLink createLink(int x, int y, int z, LinkType linkType, int orientation)
{
return createLink(new Point4D(x, y, z, id), linkType, orientation, null);
public DimLink createLink(BlockPos pos, LinkType linkType, EnumFacing orientation) {
return createLink(new Point4D(pos, id), linkType, orientation, null);
}
public DimLink createLink(Point4D source, LinkType linkType, int orientation, DDLock locked)
{
public DimLink createLink(Point4D source, LinkType linkType, EnumFacing orientation, DDLock locked) {
// Return an existing link if there is one to avoid creating multiple links starting at the same point.
InnerDimLink link = linkMapping.get(source);
if (link == null)
{
if (link == null) {
link = new InnerDimLink(source, linkType, orientation, locked);
linkMapping.put(source, link);
linkList.add(link);
// If this code is running on the server side, add this link to chunkMapping.
if (linkType != LinkType.CLIENT)
{
if (linkType != LinkType.CLIENT) {
ChunkCoordIntPair chunk = link.getChunkCoordinates();
List<InnerDimLink> chunkLinks = chunkMapping.get(chunk);
if (chunkLinks == null)
{
if (chunkLinks == null) {
chunkLinks = new ArrayList<InnerDimLink>(EXPECTED_LINKS_PER_CHUNK);
chunkMapping.put(chunk, chunkLinks);
}
chunkLinks.add(link);
}
}
else
{
} else {
link.overwrite(linkType, orientation);
}
modified = true;
//Link created!
if (linkType != LinkType.CLIENT)
{
if (linkType != LinkType.CLIENT) {
linkWatcher.onCreated(new ClientLinkData(link));
}
return link;
}
public DimLink createChildLink(int x, int y, int z, DimLink parent)
{
return createChildLink(new Point4D(x, y, z, id), (InnerDimLink) parent, null);
public DimLink createChildLink(BlockPos pos, DimLink parent) {
return createChildLink(new Point4D(pos, id), (InnerDimLink) parent, null);
}
public DimLink createChildLink(Point4D source, DimLink parent, DDLock locked)
{
public DimLink createChildLink(Point4D source, DimLink parent, DDLock locked) {
// To avoid having multiple links at a single point, if we find an existing link then we overwrite
// its destination data instead of creating a new instance.
if (parent == null)
{
if (parent == null) {
throw new IllegalArgumentException("parent cannot be null.");
}
InnerDimLink link = linkMapping.get(source);
if (link == null)
{
if (link == null) {
link = new InnerDimLink(source, parent, parent.orientation, locked);
linkMapping.put(source, link);
linkList.add(link);
@ -377,12 +324,10 @@ public abstract class NewDimData implements IPackable<PackedDimData>
// If this code is running on the server side, add this link to chunkMapping.
// Granted, the client side code should never create child links anyway...
if (link.linkType() != LinkType.CLIENT)
{
if (link.linkType() != LinkType.CLIENT) {
ChunkCoordIntPair chunk = link.getChunkCoordinates();
List<InnerDimLink> chunkLinks = chunkMapping.get(chunk);
if (chunkLinks == null)
{
if (chunkLinks == null) {
chunkLinks = new ArrayList<InnerDimLink>(EXPECTED_LINKS_PER_CHUNK);
chunkMapping.put(chunk, chunkLinks);
}
@ -391,11 +336,8 @@ public abstract class NewDimData implements IPackable<PackedDimData>
// Link created!
linkWatcher.onCreated(new ClientLinkData(link));
}
else
{
if (link.overwrite((InnerDimLink) parent, parent.orientation))
{
} else {
if (link.overwrite((InnerDimLink) parent, parent.orientation)) {
//Link created!
linkWatcher.onCreated(new ClientLinkData(link));
}
@ -404,24 +346,19 @@ public abstract class NewDimData implements IPackable<PackedDimData>
return link;
}
public boolean deleteLink(DimLink link)
{
if (link.source().getDimension() != id)
{
public boolean deleteLink(DimLink link) {
if (link.source().getDimension() != id) {
throw new IllegalArgumentException("Attempted to delete a link from another dimension.");
}
InnerDimLink target = linkMapping.remove(link.source());
if (target != null)
{
if (target != null) {
linkList.remove(target);
// If this code is running on the server side, remove this link to chunkMapping.
if (link.linkType() != LinkType.CLIENT)
{
if (link.linkType() != LinkType.CLIENT) {
ChunkCoordIntPair chunk = target.getChunkCoordinates();
List<InnerDimLink> chunkLinks = chunkMapping.get(chunk);
if (chunkLinks != null)
{
if (chunkLinks != null) {
chunkLinks.remove(target);
}
}
@ -435,136 +372,104 @@ public abstract class NewDimData implements IPackable<PackedDimData>
return (target != null);
}
public boolean deleteLink(int x, int y, int z)
{
return this.deleteLink(this.getLink(x, y, z));
public boolean deleteLink(BlockPos pos) {
return this.deleteLink(this.getLink(pos));
}
public boolean deleteLink(Point4D location)
{
public boolean deleteLink(Point4D location) {
return this.deleteLink(this.getLink(location));
}
public DimLink getLink(int x, int y, int z)
{
Point4D location = new Point4D(x, y, z, id);
return linkMapping.get(location);
public DimLink getLink(BlockPos location) {
return linkMapping.get(new Point4D(location, this.id));
}
public DimLink getLink(Point3D location)
{
return linkMapping.get(new Point4D(location.getX(), location.getY(), location.getZ(), this.id));
}
public DimLink getLink(Point4D location)
{
public DimLink getLink(Point4D location) {
if (location.getDimension() != id)
return null;
return linkMapping.get(location);
}
public ArrayList<DimLink> getAllLinks()
{
public ArrayList<DimLink> getAllLinks() {
ArrayList<DimLink> results = new ArrayList<DimLink>(linkMapping.size());
results.addAll(linkMapping.values());
return results;
}
public boolean isPocketDimension()
{
public boolean isPocketDimension() {
return (root != this);
}
public DimensionType type()
{
public DimensionType type() {
return this.type;
}
public boolean isFilled()
{
public boolean isFilled() {
return isFilled;
}
public void setFilled(boolean isFilled)
{
public void setFilled(boolean isFilled) {
this.isFilled = isFilled;
this.modified = true;
}
public int id()
{
public int id() {
return id;
}
public int depth()
{
public int depth() {
return depth;
}
public int packDepth()
{
public int packDepth() {
return packDepth;
}
public Point4D origin()
{
public Point4D origin() {
return origin;
}
public NewDimData parent()
{
public NewDimData parent() {
return parent;
}
public NewDimData root()
{
public NewDimData root() {
return root;
}
public int orientation()
{
public EnumFacing orientation() {
return orientation;
}
public DungeonData dungeon()
{
public DungeonData dungeon() {
return dungeon;
}
public boolean isInitialized()
{
public boolean isInitialized() {
return (origin != null);
}
public int linkCount()
{
public int linkCount() {
return linkList.size();
}
public Iterable<NewDimData> children()
{
public Iterable<NewDimData> children() {
return children;
}
public Iterable<? extends DimLink> links()
{
public Iterable<? extends DimLink> links() {
return linkList;
}
public void initializeDungeon(int originX, int originY, int originZ, int orientation, DimLink incoming, DungeonData dungeon)
{
if (this.type != DimensionType.DUNGEON)
{
public void initializeDungeon(BlockPos origin, EnumFacing orientation, DimLink incoming, DungeonData dungeon) {
if (this.type != DimensionType.DUNGEON) {
throw new IllegalStateException("Cannot invoke initializeDungeon() on a non-dungeon dimension.");
}
if (isInitialized())
{
} if (isInitialized()) {
throw new IllegalStateException("The dimension has already been initialized.");
}
if (orientation < 0 || orientation > 3)
{
throw new IllegalArgumentException("orientation must be between 0 and 3, inclusive.");
}
setLinkDestination(incoming, originX, originY, originZ);
setLinkDestination(incoming, origin);
this.origin = incoming.destination();
this.orientation = orientation;
this.dungeon = dungeon;
@ -575,20 +480,19 @@ public abstract class NewDimData implements IPackable<PackedDimData>
/**
* Effectively moves the dungeon to the 'top' of a chain as far as dungeon generation is concerned.
*/
public void setParentToRoot()
{
public void setParentToRoot() {
// Update this dimension's information
if (parent != null)
{
if (parent != null) {
parent.children.remove(this);
}
this.depth = 1;
this.parent = this.root;
this.root.children.add(this);
this.root.modified = true;
this.modified = true;
if (this.type == DimensionType.DUNGEON)
{
if (this.type == DimensionType.DUNGEON) {
this.packDepth = calculatePackDepth(this.parent, this.dungeon);
}
@ -596,149 +500,120 @@ public abstract class NewDimData implements IPackable<PackedDimData>
Stack<NewDimData> ordering = new Stack<NewDimData>();
ordering.addAll(this.children);
while (!ordering.isEmpty())
{
while (!ordering.isEmpty()) {
NewDimData current = ordering.pop();
current.resetDepth();
ordering.addAll(current.children);
}
}
private void resetDepth()
{
private void resetDepth() {
// We assume that this is only applied to dimensions with parents
this.depth = this.parent.depth + 1;
if (this.type == DimensionType.DUNGEON)
{
if (this.type == DimensionType.DUNGEON) {
this.packDepth = calculatePackDepth(this.parent, this.dungeon);
}
this.modified = true;
}
public static int calculatePackDepth(NewDimData parent, DungeonData current)
{
public static int calculatePackDepth(NewDimData parent, DungeonData current) {
DungeonData predecessor = parent.dungeon();
if (current == null)
{
if (current == null) {
throw new IllegalArgumentException("current cannot be null.");
}
if (predecessor == null)
{
} if (predecessor == null) {
return 1;
}
DungeonPack predOwner = predecessor.dungeonType().Owner;
DungeonPack currentOwner = current.dungeonType().Owner;
if (currentOwner == null)
{
if (currentOwner == null) {
return 1;
}
if (predOwner == null)
{
} if (predOwner == null) {
return 1;
}
if (predOwner == currentOwner)
{
} if (predOwner == currentOwner) {
return parent.packDepth + 1;
}
return 1;
}
public void initializePocket(int originX, int originY, int originZ, int orientation, DimLink incoming)
{
if (!isPocketDimension())
{
public void initializePocket(BlockPos origin, EnumFacing orientation, DimLink incoming) {
if (!isPocketDimension()) {
throw new IllegalStateException("Cannot invoke initializePocket() on a non-pocket dimension.");
}
if (isInitialized())
{
} if (isInitialized()) {
throw new IllegalStateException("The dimension has already been initialized.");
}
setLinkDestination(incoming, originX, originY, originZ);
setLinkDestination(incoming, origin);
this.origin = incoming.destination();
this.orientation = orientation;
this.modified = true;
}
public void setLinkDestination(DimLink incoming, int x, int y, int z)
{
public void setLinkDestination(DimLink incoming, BlockPos pos) {
InnerDimLink link = (InnerDimLink) incoming;
link.setDestination(x, y, z, this);
link.setDestination(pos, this);
this.modified = true;
}
public void lock(DimLink link, boolean locked)
{
public void lock(DimLink link, boolean locked) {
InnerDimLink innerLink = (InnerDimLink)link;
innerLink.lock.setLockState(locked);
modified = true;
}
public void setLock(DimLink link, DDLock lock)
{
public void setLock(DimLink link, DDLock lock) {
InnerDimLink innerLink = (InnerDimLink)link;
innerLink.setLock(lock);
modified = true;
}
public void createLock(DimLink link, ItemStack item, int lockKey)
{
public void createLock(DimLink link, ItemStack item, int lockKey) {
InnerDimLink innerLink = (InnerDimLink)link;
innerLink.createLock(item, lockKey);
modified = true;
}
public void removeLock(DimLink link, ItemStack item)
{
public void removeLock(DimLink link, ItemStack item) {
InnerDimLink innerLink = (InnerDimLink)link;
innerLink.removeLock(item, innerLink);
modified = true;
}
public DimLink getRandomLink()
{
if (linkMapping.isEmpty())
{
public DimLink getRandomLink() {
if (linkMapping.isEmpty()) {
throw new IllegalStateException("There are no links to select from in this dimension.");
}
if (linkList.size() > 1)
{
} if (linkList.size() > 1) {
return linkList.get(random.nextInt(linkList.size()));
}
return linkList.get(0);
}
public Iterable<? extends DimLink> getChunkLinks(int chunkX, int chunkZ)
{
public Iterable<? extends DimLink> getChunkLinks(int chunkX, int chunkZ) {
List<InnerDimLink> chunkLinks = chunkMapping.get(new ChunkCoordIntPair(chunkX, chunkZ));
if (chunkLinks != null)
{
if (chunkLinks != null) {
return chunkLinks;
}
return new ArrayList<InnerDimLink>(0);
}
public boolean isModified()
{
public boolean isModified() {
return modified;
}
public void clearModified()
{
public void clearModified() {
this.modified = false;
}
public void clear()
{
public void clear() {
// If this dimension has a parent, remove it from its parent's list of children
if (parent != null)
{
if (parent != null) {
parent.children.remove(this);
}
// Remove this dimension as the parent of its children
for (NewDimData child : children)
{
for (NewDimData child : children) {
child.parent = null;
}
// Clear all fields
@ -754,62 +629,52 @@ public abstract class NewDimData implements IPackable<PackedDimData>
depth = Integer.MIN_VALUE;
packDepth = Integer.MIN_VALUE;
origin = null;
orientation = Integer.MIN_VALUE;
orientation = EnumFacing.SOUTH;
dungeon = null;
linkWatcher = null;
}
public PackedDimData pack()
{
public PackedDimData pack() {
ArrayList<Integer> ChildIDs = new ArrayList<Integer>();
ArrayList<PackedLinkData> Links = new ArrayList<PackedLinkData>();
ArrayList<PackedLinkTail> Tails = new ArrayList<PackedLinkTail>();
PackedDungeonData packedDungeon=null;
if(this.dungeon!=null)
{
if(this.dungeon!=null) {
packedDungeon= new PackedDungeonData(dungeon.weight(), dungeon.isOpen(), dungeon.isInternal(),
dungeon.schematicPath(), dungeon.schematicName(), dungeon.dungeonType().Name,
dungeon.dungeonType().Owner.getName());
}
//Make a list of children
for(NewDimData data : this.children)
{
for(NewDimData data : this.children) {
ChildIDs.add(data.id);
}
for(DimLink link:this.links())
{
ArrayList<Point3D> children = new ArrayList<Point3D>();
Point3D parentPoint = new Point3D(-1,-1,-1);
if(link.parent!=null)
{
parentPoint=link.parent.point.toPoint3D();
for(DimLink link:this.links()) {
ArrayList<BlockPos> children = new ArrayList<BlockPos>();
BlockPos parentPoint = new BlockPos(-1,-1,-1);
if(link.parent!=null) {
parentPoint=link.parent.point.toBlockPos();
}
for(DimLink childLink : link.children)
{
children.add(childLink.source().toPoint3D());
for(DimLink childLink : link.children) {
children.add(childLink.source().toBlockPos());
}
PackedLinkTail tail = new PackedLinkTail(link.tail.getDestination(),link.tail.getLinkType());
Links.add(new PackedLinkData(link.point,parentPoint,tail,link.orientation,children,link.lock));
PackedLinkTail tempTail = new PackedLinkTail(link.tail.getDestination(),link.tail.getLinkType());
if(Tails.contains(tempTail))
{
if(Tails.contains(tempTail)) {
Tails.add(tempTail);
}
}
int parentID=this.id;
Point3D originPoint=new Point3D(0,0,0);
if(this.parent!=null)
{
BlockPos originPoint=new BlockPos(0,0,0);
if(this.parent!=null) {
parentID = this.parent.id;
}
if(this.origin!=null)
{
originPoint=this.origin.toPoint3D();
} if(this.origin!=null) {
originPoint=this.origin.toBlockPos();
}
return new PackedDimData(this.id, depth, this.packDepth, parentID, this.root().id(), orientation,
type, isFilled,packedDungeon, originPoint, ChildIDs, Links, Tails);

View file

@ -8,7 +8,6 @@ import java.util.ArrayList;
import java.util.Random;
import com.zixiken.dimdoors.DimDoors;
import com.zixiken.dimdoors.Point3D;
import com.zixiken.dimdoors.blocks.IDimDoor;
import com.zixiken.dimdoors.config.DDProperties;
import com.zixiken.dimdoors.core.DimLink;
@ -22,6 +21,8 @@ import net.minecraft.init.Blocks;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntitySign;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
import com.zixiken.dimdoors.core.NewDimData;
import com.zixiken.dimdoors.schematic.BlockRotator;
@ -37,15 +38,14 @@ public class DungeonSchematic extends Schematic {
private static final int NETHER_DIMENSION_ID = -1;
private int orientation;
private Point3D entranceDoorLocation;
private ArrayList<Point3D> exitDoorLocations;
private ArrayList<Point3D> dimensionalDoorLocations;
private ArrayList<Point3D> monolithSpawnLocations;
private EnumFacing orientation;
private BlockPos entranceDoorLocation;
private ArrayList<BlockPos> exitDoorLocations;
private ArrayList<BlockPos> dimensionalDoorLocations;
private ArrayList<BlockPos> monolithSpawnLocations;
private ArrayList<Block> modBlockFilterExceptions;
private DungeonSchematic(Schematic source)
{
private DungeonSchematic(Schematic source) {
super(source);
modBlockFilterExceptions = new ArrayList<Block>(5);
modBlockFilterExceptions.add(DimDoors.blockDimWall);
@ -55,54 +55,45 @@ public class DungeonSchematic extends Schematic {
modBlockFilterExceptions.add(DimDoors.transientDoor);
}
public int getOrientation()
{
public EnumFacing getOrientation() {
return orientation;
}
public Point3D getEntranceDoorLocation()
{
return (entranceDoorLocation != null) ? entranceDoorLocation.clone() : null;
public BlockPos getEntranceDoorLocation() {
return (entranceDoorLocation != null) ? entranceDoorLocation : null;
}
private DungeonSchematic()
{
private DungeonSchematic() {
//Used to create a dummy instance for readFromResource()
super((short) 0, (short) 0, (short) 0, null, null, null);
super(BlockPos.ORIGIN, null, null);
}
public static DungeonSchematic readFromFile(String schematicPath) throws FileNotFoundException, InvalidSchematicException
{
public static DungeonSchematic readFromFile(String schematicPath) throws FileNotFoundException, InvalidSchematicException {
return readFromFile(new File(schematicPath));
}
public static DungeonSchematic readFromFile(File schematicFile) throws FileNotFoundException, InvalidSchematicException
{
public static DungeonSchematic readFromFile(File schematicFile) throws FileNotFoundException, InvalidSchematicException {
return readFromStream(new FileInputStream(schematicFile));
}
public static DungeonSchematic readFromResource(String resourcePath) throws InvalidSchematicException
{
public static DungeonSchematic readFromResource(String resourcePath) throws InvalidSchematicException {
//We need an instance of a class in the mod to retrieve a resource
DungeonSchematic empty = new DungeonSchematic();
InputStream schematicStream = empty.getClass().getResourceAsStream(resourcePath);
return readFromStream(schematicStream);
}
public static DungeonSchematic readFromStream(InputStream schematicStream) throws InvalidSchematicException
{
public static DungeonSchematic readFromStream(InputStream schematicStream) throws InvalidSchematicException {
return new DungeonSchematic(Schematic.readFromStream(schematicStream));
}
public void applyImportFilters(DDProperties properties)
{
public void applyImportFilters(DDProperties properties) {
//Search for special blocks (warp doors, dim doors, and end portal frames that mark Monolith spawn points)
SpecialBlockFinder finder = new SpecialBlockFinder(DimDoors.warpDoor, DimDoors.dimensionalDoor,
Blocks.end_portal_frame, Blocks.sandstone);
applyFilter(finder);
Blocks.end_portal_frame, Blocks.sandstone);applyFilter(finder);
//Flip the entrance's orientation to get the dungeon's orientation
orientation = BlockRotator.transformMetadata(finder.getEntranceOrientation(), 2, Blocks.wooden_door);
orientation = BlockRotator.transformMetadata(finder.getEntranceOrientation(), 2, Blocks.oak_door);
entranceDoorLocation = finder.getEntranceDoorLocation();
exitDoorLocations = finder.getExitDoorLocations();
@ -111,8 +102,7 @@ public class DungeonSchematic extends Schematic {
//Filter out mod blocks except some of our own
CompoundFilter standardizer = new CompoundFilter();
standardizer.addFilter(new ModBlockFilter(modBlockFilterExceptions,
DimDoors.blockDimWall, (byte) 0));
standardizer.addFilter(new ModBlockFilter(modBlockFilterExceptions, DimDoors.blockDimWall.getDefaultState()));
//Also convert standard DD block IDs to local versions
applyFilter(standardizer);
@ -126,8 +116,7 @@ public class DungeonSchematic extends Schematic {
//Filter out mod blocks except some of our own
//This comes after ID standardization because the mod block filter relies on standardized IDs
standardizer.addFilter(new ModBlockFilter(modBlockFilterExceptions,
DimDoors.blockDimWall, (byte) 0));
standardizer.addFilter(new ModBlockFilter(modBlockFilterExceptions, DimDoors.blockDimWall.getDefaultState()));
applyFilter(standardizer);
}
@ -137,7 +126,7 @@ public class DungeonSchematic extends Schematic {
return new DungeonSchematic(Schematic.copyFromWorld(world, x, y, z, width, height, length, doCompactBounds));
}
public void copyToWorld(World world, Point3D pocketCenter, int targetOrientation, DimLink entryLink,
public void copyToWorld(World world, BlockPos pocketCenter, int targetOrientation, DimLink entryLink,
Random random, DDProperties properties, boolean notifyClients)
{
if (notifyClients)
@ -150,8 +139,7 @@ public class DungeonSchematic extends Schematic {
}
}
public void copyToWorld(World world, Point3D pocketCenter, int targetOrientation, DimLink entryLink,
Random random, DDProperties properties, IBlockSetter blockSetter)
public void copyToWorld(World world, BlockPos pocketCenter, int targetOrientation, DimLink entryLink, Random random, DDProperties properties, IBlockSetter blockSetter)
{
//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,
@ -165,7 +153,7 @@ public class DungeonSchematic extends Schematic {
Block block;
int blockMeta;
int dx, dy, dz;
Point3D pocketPoint = new Point3D(0, 0, 0);
BlockPos pocketPoint = new BlockPos(0, 0, 0);
//Copy blocks and metadata into the world
index = 0;
@ -208,11 +196,11 @@ public class DungeonSchematic extends Schematic {
setUpDungeon(PocketManager.createDimensionData(world), world, pocketCenter, turnAngle, entryLink, random, properties, blockSetter);
}
private void setUpDungeon(NewDimData dimension, World world, Point3D pocketCenter, int turnAngle, DimLink entryLink, Random random, DDProperties properties, IBlockSetter blockSetter)
private void setUpDungeon(NewDimData dimension, World world, BlockPos pocketCenter, int turnAngle, DimLink entryLink, Random random, DDProperties properties, IBlockSetter blockSetter)
{
//Transform dungeon corners
Point3D minCorner = new Point3D(0, 0, 0);
Point3D maxCorner = new Point3D(width - 1, height - 1, length - 1);
BlockPos minCorner = new BlockPos(0, 0, 0);
BlockPos maxCorner = new BlockPos(width - 1, height - 1, length - 1);
transformCorners(entranceDoorLocation, pocketCenter, turnAngle, minCorner, maxCorner);
//Fill empty chests and dispensers
@ -223,20 +211,20 @@ public class DungeonSchematic extends Schematic {
createEntranceReverseLink(world, dimension, pocketCenter, entryLink);
//Set up link data for dimensional doors
for (Point3D location : dimensionalDoorLocations)
for (BlockPos location : dimensionalDoorLocations)
{
createDimensionalDoorLink(world, dimension, location, entranceDoorLocation, turnAngle, pocketCenter);
}
//Set up link data for exit door
for (Point3D location : exitDoorLocations)
for (BlockPos location : exitDoorLocations)
{
createExitDoorLink(world, dimension, location, entranceDoorLocation, turnAngle, pocketCenter, blockSetter);
}
//Remove end portal frames and spawn Monoliths, if allowed
boolean canSpawn = CustomLimboPopulator.isMobSpawningAllowed();
for (Point3D location : monolithSpawnLocations)
for (BlockPos location : monolithSpawnLocations)
{
spawnMonolith(world, location, entranceDoorLocation, turnAngle, pocketCenter, canSpawn, blockSetter);
}
@ -252,32 +240,26 @@ public class DungeonSchematic extends Schematic {
}
}
private static void transformCorners(Point3D schematicEntrance, Point3D pocketCenter, int turnAngle, Point3D minCorner, Point3D maxCorner)
{
private static void transformCorners(BlockPos schematicEntrance, BlockPos pocketCenter, EnumFacing turnAngle, BlockPos minCorner, BlockPos maxCorner) {
int temp;
BlockRotator.transformPoint(minCorner, schematicEntrance, turnAngle, pocketCenter);
BlockRotator.transformPoint(maxCorner, schematicEntrance, turnAngle, pocketCenter);
if (minCorner.getX() > maxCorner.getX())
{
if (minCorner.getX() > maxCorner.getX()) {
temp = minCorner.getX();
minCorner.setX(maxCorner.getX());
maxCorner.setX(temp);
}
if (minCorner.getY() > maxCorner.getY())
{
minCorner = new BlockPos(maxCorner.getX(), minCorner.getY(), minCorner.getZ());
maxCorner = new BlockPos(temp, maxCorner.getY(), maxCorner.getZ());
} if (minCorner.getY() > maxCorner.getY()) {
temp = minCorner.getY();
minCorner.setY(maxCorner.getY());
maxCorner.setY(temp);
}
if (minCorner.getZ() > maxCorner.getZ())
{
} if (minCorner.getZ() > maxCorner.getZ()) {
temp = minCorner.getZ();
minCorner.setZ(maxCorner.getZ());
maxCorner.setZ(temp);
}
}
private static void createEntranceReverseLink(World world, NewDimData dimension, Point3D pocketCenter, DimLink entryLink)
private static void createEntranceReverseLink(World world, NewDimData dimension, BlockPos pocketCenter, DimLink entryLink)
{
int orientation = world.getBlockMetadata(pocketCenter.getX(), pocketCenter.getY() - 1, pocketCenter.getZ());
DimLink reverseLink = dimension.createLink(pocketCenter.getX(), pocketCenter.getY(), pocketCenter.getZ(), LinkType.REVERSE, orientation);
@ -287,10 +269,10 @@ public class DungeonSchematic extends Schematic {
initDoorTileEntity(world, pocketCenter);
}
private static void createExitDoorLink(World world, NewDimData dimension, Point3D point, Point3D entrance, int rotation, Point3D pocketCenter, IBlockSetter blockSetter)
private static void createExitDoorLink(World world, NewDimData dimension, BlockPos point, BlockPos entrance, EnumFacing rotation, BlockPos pocketCenter, IBlockSetter blockSetter)
{
//Transform the door's location to the pocket coordinate system
Point3D location = point.clone();
BlockPos location = point;
BlockRotator.transformPoint(location, entrance, rotation, pocketCenter);
int orientation = world.getBlockMetadata(location.getX(), location.getY() - 1, location.getZ());
dimension.createLink(location.getX(), location.getY(), location.getZ(), LinkType.DUNGEON_EXIT, orientation);
@ -307,10 +289,10 @@ public class DungeonSchematic extends Schematic {
initDoorTileEntity(world, location);
}
private static void createDimensionalDoorLink(World world, NewDimData dimension, Point3D point, Point3D entrance, int rotation, Point3D pocketCenter)
private static void createDimensionalDoorLink(World world, NewDimData dimension, BlockPos point, BlockPos entrance, int rotation, BlockPos pocketCenter)
{
//Transform the door's location to the pocket coordinate system
Point3D location = point.clone();
BlockPos location = point.clone();
BlockRotator.transformPoint(location, entrance, rotation, pocketCenter);
int orientation = world.getBlockMetadata(location.getX(), location.getY() - 1, location.getZ());
@ -318,10 +300,10 @@ public class DungeonSchematic extends Schematic {
initDoorTileEntity(world, location);
}
private static void spawnMonolith(World world, Point3D point, Point3D entrance, int rotation, Point3D pocketCenter, boolean canSpawn, IBlockSetter blockSetter)
private static void spawnMonolith(World world, BlockPos point, BlockPos entrance, int rotation, BlockPos pocketCenter, boolean canSpawn, IBlockSetter blockSetter)
{
//Transform the frame block's location to the pocket coordinate system
Point3D location = point.clone();
BlockPos location = point.clone();
BlockRotator.transformPoint(location, entrance, rotation, pocketCenter);
//Remove frame block
blockSetter.setBlock(world, location.getX(), location.getY(), location.getZ(), Blocks.air, 0);
@ -334,7 +316,7 @@ public class DungeonSchematic extends Schematic {
}
}
private static void initDoorTileEntity(World world, Point3D point)
private static void initDoorTileEntity(World world, BlockPos point)
{
Block door = world.getBlock(point.getX(), point.getY(), point.getZ());
Block door2 = world.getBlock(point.getX(), point.getY() - 1, point.getZ());
@ -350,7 +332,7 @@ public class DungeonSchematic extends Schematic {
}
}
private static void writeDepthSign(World world, Point3D pocketCenter, int depth)
private static void writeDepthSign(World world, BlockPos pocketCenter, int depth)
{
final int SEARCH_RANGE = 6;

View file

@ -2,42 +2,36 @@ package com.zixiken.dimdoors.dungeon;
import net.minecraft.block.Block;
import com.zixiken.dimdoors.schematic.SchematicFilter;
import net.minecraft.block.state.IBlockState;
import java.util.List;
public class ModBlockFilter extends SchematicFilter {
private List<Block> exceptions;
private Block replacementBlock;
private byte replacementMetadata;
private IBlockState replacementState;
public ModBlockFilter(List<Block> exceptions, Block replacementBlock, byte replacementMetadata)
public ModBlockFilter(List<Block> exceptions, IBlockState state)
{
super("ModBlockFilter");
this.exceptions = exceptions;
this.replacementBlock = replacementBlock;
this.replacementMetadata = replacementMetadata;
this.replacementState = state;
}
@Override
protected boolean applyToBlock(int index, Block[] blocks, byte[] metadata)
{
protected boolean applyToBlock(int index, IBlockState[] state) {
int k;
Block current = blocks[index];
if (!Block.blockRegistry.getNameForObject(current).startsWith("minecraft:"))
{
Block current = state[index].getBlock();
if (!Block.blockRegistry.getNameForObject(current).getResourcePath().startsWith("minecraft:")) {
//This might be a mod block. Check if an exception exists.
for (k = 0; k < exceptions.size(); k++)
{
if (current == exceptions.get(k))
{
for (k = 0; k < exceptions.size(); k++) {
if (current == exceptions.get(k)) {
//Exception found, not considered a mod block
return false;
}
}
//No matching exception found. Replace the block.
blocks[index] = replacementBlock;
metadata[index] = replacementMetadata;
state[index] = replacementState;
return true;
}
return false;

View file

@ -2,10 +2,13 @@ package com.zixiken.dimdoors.dungeon;
import java.util.ArrayList;
import com.zixiken.dimdoors.Point3D;
import com.zixiken.dimdoors.schematic.Schematic;
import com.zixiken.dimdoors.schematic.SchematicFilter;
import net.minecraft.block.Block;
import net.minecraft.block.BlockDoor;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
public class SpecialBlockFinder extends SchematicFilter {
@ -13,94 +16,79 @@ public class SpecialBlockFinder extends SchematicFilter {
private Block dimensionalDoor;
private Block monolithSpawnMarker;
private Block exitMarker;
private int entranceOrientation;
private EnumFacing entranceOrientation;
private Schematic schematic;
private Point3D entranceDoorLocation;
private ArrayList<Point3D> exitDoorLocations;
private ArrayList<Point3D> dimensionalDoorLocations;
private ArrayList<Point3D> monolithSpawnLocations;
private BlockPos entranceDoorLocation;
private ArrayList<BlockPos> exitDoorLocations;
private ArrayList<BlockPos> dimensionalDoorLocations;
private ArrayList<BlockPos> monolithSpawnLocations;
public SpecialBlockFinder(Block warpDoor, Block dimensionalDoor, Block monolithSpawn, Block exitDoor)
{
public SpecialBlockFinder(Block warpDoor, Block dimensionalDoor, Block monolithSpawn, Block exitDoor) {
super("SpecialBlockFinder");
this.warpDoor = warpDoor;
this.dimensionalDoor = dimensionalDoor;
this.monolithSpawnMarker = monolithSpawn;
this.exitMarker = exitDoor;
this.entranceDoorLocation = null;
this.entranceOrientation = 0;
this.exitDoorLocations = new ArrayList<Point3D>();
this.dimensionalDoorLocations = new ArrayList<Point3D>();
this.monolithSpawnLocations = new ArrayList<Point3D>();
this.entranceOrientation = EnumFacing.SOUTH;
this.exitDoorLocations = new ArrayList<BlockPos>();
this.dimensionalDoorLocations = new ArrayList<BlockPos>();
this.monolithSpawnLocations = new ArrayList<BlockPos>();
this.schematic = null;
}
public int getEntranceOrientation() {
public EnumFacing getEntranceOrientation() {
return entranceOrientation;
}
public Point3D getEntranceDoorLocation() {
public BlockPos getEntranceDoorLocation() {
return entranceDoorLocation;
}
public ArrayList<Point3D> getExitDoorLocations() {
public ArrayList<BlockPos> getExitDoorLocations() {
return exitDoorLocations;
}
public ArrayList<Point3D> getDimensionalDoorLocations() {
public ArrayList<BlockPos> getDimensionalDoorLocations() {
return dimensionalDoorLocations;
}
public ArrayList<Point3D> getMonolithSpawnLocations() {
public ArrayList<BlockPos> getMonolithSpawnLocations() {
return monolithSpawnLocations;
}
@Override
protected boolean initialize(Schematic schematic, Block[] blocks, byte[] metadata)
{
protected boolean initialize(Schematic schematic, IBlockState[] state) {
this.schematic = schematic;
return true;
}
@Override
protected boolean applyToBlock(int index, Block[] blocks, byte[] metadata)
{
protected boolean applyToBlock(int index, IBlockState[] state) {
int indexBelow;
int indexDoubleBelow;
if (blocks[index] == monolithSpawnMarker)
{
if (state[index] == monolithSpawnMarker) {
monolithSpawnLocations.add(schematic.calculatePoint(index));
return true;
}
if (blocks[index] == dimensionalDoor)
{
} if (state[index] == dimensionalDoor) {
indexBelow = schematic.calculateIndexBelow(index);
if (indexBelow >= 0 && blocks[indexBelow] == dimensionalDoor)
{
if (indexBelow >= 0 && state[indexBelow] == dimensionalDoor) {
dimensionalDoorLocations.add(schematic.calculatePoint(index));
return true;
}
else
{
} else {
return false;
}
}
if (blocks[index] == warpDoor)
{
} if (state[index] == warpDoor) {
indexBelow = schematic.calculateIndexBelow(index);
if (indexBelow >= 0 && blocks[indexBelow] == warpDoor)
{
if (indexBelow >= 0 && state[indexBelow] == warpDoor) {
indexDoubleBelow = schematic.calculateIndexBelow(indexBelow);
if (indexDoubleBelow >= 0 && blocks[indexDoubleBelow] == exitMarker)
{
if (indexDoubleBelow >= 0 && state[indexDoubleBelow] == exitMarker) {
exitDoorLocations.add(schematic.calculatePoint(index));
return true;
}
else if (entranceDoorLocation == null)
{
} else if (entranceDoorLocation == null) {
entranceDoorLocation = schematic.calculatePoint(index);
entranceOrientation = (metadata[indexBelow] & 3);
entranceOrientation = state[indexBelow].getValue(BlockDoor.FACING);
return true;
}
}
@ -109,8 +97,7 @@ public class SpecialBlockFinder extends SchematicFilter {
}
@Override
protected boolean terminates()
{
protected boolean terminates() {
return false;
}
}

View file

@ -1,58 +1,39 @@
package com.zixiken.dimdoors.experimental;
import com.zixiken.dimdoors.Point3D;
import com.zixiken.dimdoors.helpers.BlockPosHelper;
import net.minecraft.util.BlockPos;
public class BoundingBox
{
protected Point3D minCorner;
protected Point3D maxCorner;
public class BoundingBox {
protected BlockPos minCorner;
protected BlockPos maxCorner;
public BoundingBox(int x, int y, int z, int width, int height, int length)
{
this.minCorner = new Point3D(x, y, z);
this.maxCorner = new Point3D(x + width - 1, y + height - 1, z + length - 1);
public BoundingBox(int x, int y, int z, int width, int height, int length) {
this.minCorner = new BlockPos(x, y, z);
this.maxCorner = new BlockPos(x + width - 1, y + height - 1, z + length - 1);
}
public BoundingBox(Point3D minCorner, Point3D maxCorner)
{
public BoundingBox(BlockPos minCorner, BlockPos maxCorner) {
this.minCorner = minCorner;
this.maxCorner = maxCorner;
}
public int width()
{
return (maxCorner.getX() - minCorner.getX() + 1);
public BlockPos volume() {
return maxCorner.subtract(minCorner).add(1,1,1);
}
public int height()
{
return (maxCorner.getY() - minCorner.getY() + 1);
}
public int length()
{
return (maxCorner.getZ() - minCorner.getZ() + 1);
}
public Point3D minCorner()
{
public BlockPos minCorner() {
return minCorner;
}
public Point3D maxCorner()
{
public BlockPos maxCorner() {
return maxCorner;
}
public boolean contains(int x, int y, int z)
{
return ((minCorner.getX() <= x && x <= maxCorner.getX()) &&
(minCorner.getY() <= y && y <= maxCorner.getY()) &&
(minCorner.getZ() <= z && z <= maxCorner.getZ()));
public boolean contains(BlockPos pos) {
return BlockPosHelper.between(pos, minCorner, maxCorner);
}
public boolean intersects(BoundingBox other)
{
public boolean intersects(BoundingBox other) {
// To be clear, having one box inside another counts as intersecting
boolean xi = (this.minCorner.getX() <= other.minCorner.getX() && other.minCorner.getX() <= this.maxCorner.getX()) ||

View file

@ -1,6 +1,7 @@
package com.zixiken.dimdoors.experimental;
import com.zixiken.dimdoors.Point3D;
import net.minecraft.util.BlockPos;
public class DoorwayData
{
@ -8,23 +9,23 @@ public class DoorwayData
public static final char Y_AXIS = 'Y';
public static final char Z_AXIS = 'Z';
private Point3D minCorner;
private Point3D maxCorner;
private BlockPos minCorner;
private BlockPos maxCorner;
private char axis;
public DoorwayData(Point3D minCorner, Point3D maxCorner, char axis)
public DoorwayData(BlockPos minCorner, BlockPos maxCorner, char axis)
{
this.minCorner = minCorner;
this.maxCorner = maxCorner;
this.axis = axis;
}
public Point3D minCorner()
public BlockPos minCorner()
{
return minCorner;
}
public Point3D maxCorner()
public BlockPos maxCorner()
{
return maxCorner;
}
@ -34,18 +35,7 @@ public class DoorwayData
return axis;
}
public int width()
{
return (maxCorner.getX() - minCorner.getX() + 1);
}
public int height()
{
return (maxCorner.getY() - minCorner.getY() + 1);
}
public int length()
{
return (maxCorner.getZ() - minCorner.getZ() + 1);
public BlockPos volume() {
return maxCorner.subtract(minCorner).add(1,1,1);
}
}

View file

@ -4,19 +4,18 @@ import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.util.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import com.zixiken.dimdoors.Point3D;
public class MazeBuilder
{
public class MazeBuilder {
private MazeBuilder() { }
public static void generate(World world, int x, int y, int z, Random random)
{
public static void generate(World world, int x, int y, int z, Random random) {
MazeDesign design = MazeDesigner.generate(random);
Point3D offset = new Point3D(x - design.width() / 2, y - design.height() - 1, z - design.length() / 2);
BlockPos offset = new BlockPos(x - design.width() / 2, y - design.height() - 1, z - design.length() / 2);
SphereDecayOperation decay = new SphereDecayOperation(random, Blocks.air, 0, Blocks.stonebrick, 2);
buildRooms(design.getRoomGraph(), world, offset);
@ -28,12 +27,12 @@ public class MazeBuilder
}
private static void applyRandomDestruction(MazeDesign design, World world,
Point3D offset, SphereDecayOperation decay, Random random)
BlockPos offset, SphereDecayOperation decay, Random random)
{
//final int DECAY_BOX_SIZE = 8
}
private static void buildRooms(DirectedGraph<PartitionNode, DoorwayData> roomGraph, World world, Point3D offset)
private static void buildRooms(DirectedGraph<PartitionNode, DoorwayData> roomGraph, World world, BlockPos offset)
{
for (IGraphNode<PartitionNode, DoorwayData> node : roomGraph.nodes())
{
@ -43,10 +42,10 @@ public class MazeBuilder
}
private static void carveDoorways(DirectedGraph<PartitionNode, DoorwayData> roomGraph, World world,
Point3D offset, SphereDecayOperation decay, Random random)
BlockPos offset, SphereDecayOperation decay, Random random)
{
char axis;
Point3D lower;
BlockPos lower;
DoorwayData doorway;
for (IGraphNode<PartitionNode, DoorwayData> node : roomGraph.nodes())
@ -168,7 +167,7 @@ public class MazeBuilder
}
private static void buildBox(World world, Point3D offset, Point3D minCorner, Point3D maxCorner, Block block, int metadata)
private static void buildBox(World world, BlockPos offset, BlockPos minCorner, BlockPos maxCorner, Block block, int metadata)
{
int minX = minCorner.getX() + offset.getX();
int minY = minCorner.getY() + offset.getY();

View file

@ -8,8 +8,9 @@ import java.util.Queue;
import java.util.Random;
import java.util.Stack;
import com.zixiken.dimdoors.helpers.BlockPosHelper;
import net.minecraft.util.BlockPos;
import net.minecraft.util.MathHelper;
import com.zixiken.dimdoors.Point3D;
public class MazeDesigner
{
@ -22,8 +23,7 @@ public class MazeDesigner
private MazeDesigner() { }
public static MazeDesign generate(Random random)
{
public static MazeDesign generate(Random random) {
// Construct a random binary space partitioning of our maze volume
PartitionNode root = partitionRooms(MAZE_WIDTH, MAZE_HEIGHT, MAZE_LENGTH, SPLIT_COUNT, random);
@ -48,100 +48,79 @@ public class MazeDesigner
return new MazeDesign(root, rooms, cores);
}
private static void listRoomPartitions(PartitionNode node, ArrayList<PartitionNode> partitions)
{
if (node.isLeaf())
{
private static void listRoomPartitions(PartitionNode node, ArrayList<PartitionNode> partitions) {
if (node.isLeaf()) {
partitions.add(node);
}
else
{
} else {
listRoomPartitions(node.leftChild(), partitions);
listRoomPartitions(node.rightChild(), partitions);
}
}
private static void removeRoomPartitions(PartitionNode node)
{
private static void removeRoomPartitions(PartitionNode node) {
// Remove a node and any of its ancestors that become leaf nodes
PartitionNode parent;
PartitionNode current;
current = node;
while (current != null && current.isLeaf())
{
while (current != null && current.isLeaf()) {
parent = current.parent();
current.remove();
current = parent;
}
}
private static PartitionNode partitionRooms(int width, int height, int length, int maxLevels, Random random)
{
PartitionNode root = new PartitionNode(width, height, length);
private static PartitionNode partitionRooms(int width, int height, int length, int maxLevels, Random random) {
PartitionNode root = new PartitionNode(new BlockPos(width, height, length));
splitByRandomX(root, maxLevels, random);
return root;
}
private static void splitByRandomX(PartitionNode node, int levels, Random random)
{
if (node.width() >= 2 * MIN_SIDE)
{
private static void splitByRandomX(PartitionNode node, int levels, Random random) {
if (node.volume().getX() >= 2 * MIN_SIDE) {
node.splitByX(MathHelper.getRandomIntegerInRange(random,
node.minCorner().getX() + MIN_SIDE, node.maxCorner().getX() - MIN_SIDE + 1));
if (levels > 1)
{
if (levels > 1) {
splitByRandomZ(node.leftChild(), levels - 1, random);
splitByRandomZ(node.rightChild(), levels - 1, random);
}
}
else if (levels > 1)
{
} else if (levels > 1) {
splitByRandomZ(node, levels - 1, random);
}
}
private static void splitByRandomZ(PartitionNode node, int levels, Random random)
{
if (node.length() >= 2 * MIN_SIDE)
{
if (node.volume().getZ() >= 2 * MIN_SIDE) {
node.splitByZ(MathHelper.getRandomIntegerInRange(random,
node.minCorner().getZ() + MIN_SIDE, node.maxCorner().getZ() - MIN_SIDE + 1));
if (levels > 1)
{
if (levels > 1) {
splitByRandomY(node.leftChild(), levels - 1, random);
splitByRandomY(node.rightChild(), levels - 1, random);
}
}
else if (levels > 1)
{
else if (levels > 1) {
splitByRandomY(node, levels - 1, random);
}
}
private static void splitByRandomY(PartitionNode node, int levels, Random random)
{
if (node.height() >= 2 * MIN_HEIGHT)
{
private static void splitByRandomY(PartitionNode node, int levels, Random random) {
if (node.volume().getY() >= 2 * MIN_HEIGHT) {
node.splitByY(MathHelper.getRandomIntegerInRange(random,
node.minCorner().getY() + MIN_HEIGHT, node.maxCorner().getY() - MIN_HEIGHT + 1));
if (levels > 1)
{
if (levels > 1) {
splitByRandomX(node.leftChild(), levels - 1, random);
splitByRandomX(node.rightChild(), levels - 1, random);
}
}
else if (levels > 1)
{
} else if (levels > 1) {
splitByRandomX(node, levels - 1, random);
}
}
private static DirectedGraph<PartitionNode, DoorwayData> createRoomGraph(PartitionNode root, ArrayList<PartitionNode> partitions, Random random)
{
private static DirectedGraph<PartitionNode, DoorwayData> createRoomGraph(PartitionNode root, ArrayList<PartitionNode> partitions, Random random) {
DirectedGraph<PartitionNode, DoorwayData> roomGraph = new DirectedGraph<PartitionNode, DoorwayData>();
HashMap<PartitionNode, IGraphNode<PartitionNode, DoorwayData>> roomsToGraph = new HashMap<PartitionNode, IGraphNode<PartitionNode, DoorwayData>>(2 * partitions.size());
@ -152,14 +131,12 @@ public class MazeDesigner
// Add all rooms to a graph
// Also add them to a map so we can associate rooms with their graph nodes
// The map is needed for linking graph nodes based on adjacent partitions
for (PartitionNode partition : partitions)
{
for (PartitionNode partition : partitions) {
roomsToGraph.put(partition, roomGraph.addNode(partition));
}
// Add edges for each room
for (IGraphNode<PartitionNode, DoorwayData> node : roomGraph.nodes())
{
for (IGraphNode<PartitionNode, DoorwayData> node : roomGraph.nodes()) {
findDoorways(node, root, roomsToGraph, roomGraph);
}
@ -168,8 +145,7 @@ public class MazeDesigner
private static void findDoorways(IGraphNode<PartitionNode, DoorwayData> roomNode, PartitionNode root,
HashMap<PartitionNode, IGraphNode<PartitionNode, DoorwayData>> roomsToGraph,
DirectedGraph<PartitionNode, DoorwayData> roomGraph)
{
DirectedGraph<PartitionNode, DoorwayData> roomGraph) {
// This function finds rooms adjacent to a specified room that could be connected
// to it through a doorway. Edges are added to the room graph to denote rooms that
// could be connected. The areas of their common bounds that could be carved
@ -190,62 +166,43 @@ public class MazeDesigner
int a, b, c;
int p, q, r;
int minXI, minYI, minZI;
int maxXI, maxYI, maxZI;
Point3D otherMin;
Point3D otherMax;
BlockPos minI;
BlockPos maxI;
BlockPos diff;
BlockPos otherMin;
BlockPos otherMax;
DoorwayData doorway;
IGraphNode<PartitionNode, DoorwayData> adjacentNode;
PartitionNode room = roomNode.data();
Point3D minCorner = room.minCorner();
Point3D maxCorner = room.maxCorner();
BlockPos minCorner = room.minCorner();
BlockPos maxCorner = room.maxCorner();
int minX = minCorner.getX();
int minY = minCorner.getY();
int minZ = minCorner.getZ();
BlockPos volume = room.volume();
int maxX = maxCorner.getX();
int maxY = maxCorner.getY();
int maxZ = maxCorner.getZ();
int width = room.width();
int height = room.height();
int length = room.length();
if (maxZ < root.maxCorner().getZ())
{
if (maxCorner.getZ() < root.maxCorner().getZ()) {
// Check for adjacent rooms along the XY plane
detected = new boolean[width][height];
for (a = 0; a < width; a++)
{
for (b = 0; b < height; b++)
{
if (!detected[a][b])
{
adjacent = root.findPoint(minX + a, minY + b, maxZ + 1);
if (adjacent != null)
{
detected = new boolean[volume.getX()][volume.getY()];
for (a = 0; a < volume.getX(); a++) {
for (b = 0; b < volume.getY(); b++) {
if (!detected[a][b]) {
adjacent = root.findPoint(minCorner.add(a, b, 1));
if (adjacent != null) {
// Compute the dimensions available for a doorway
otherMin = adjacent.minCorner();
otherMax = adjacent.maxCorner();
minXI = Math.max(minX, otherMin.getX());
maxXI = Math.min(maxX, otherMax.getX());
minYI = Math.max(minY, otherMin.getY());
maxYI = Math.min(maxY, otherMax.getY());
minI = BlockPosHelper.max(minCorner, adjacent.minCorner());
maxI = BlockPosHelper.min(maxCorner, adjacent.maxCorner());
diff = maxI.subtract(minI);
for (p = 0; p <= maxXI - minXI; p++)
{
for (q = 0; q <= maxYI - minYI; q++)
{
for (p = 0; p <= diff.getX(); p++) {
for (q = 0; q <= diff.getY(); q++) {
detected[p + a][q + b] = true;
}
}
// Check if we meet the minimum dimensions needed for a doorway
if (maxXI - minXI + 1 >= MIN_SIDE && maxYI - minYI + 1 >= MIN_HEIGHT)
if (diff.add(1,0,0).getX() + 1 >= MIN_SIDE && maxYI - minYI + 1 >= MIN_HEIGHT)
{
otherMin = new Point3D(minXI, minYI, maxZ);
otherMax = new Point3D(maxXI, maxYI, maxZ + 1);
otherMin = new BlockPos(minXI, minYI, maxZ);
otherMax = new BlockPos(maxXI, maxYI, maxZ + 1);
doorway = new DoorwayData(otherMin, otherMax, DoorwayData.Z_AXIS);
adjacentNode = roomsToGraph.get(adjacent);
roomGraph.addEdge(roomNode, adjacentNode, doorway);
@ -292,8 +249,8 @@ public class MazeDesigner
// Check if we meet the minimum dimensions needed for a doorway
if (maxYI - minYI + 1 >= MIN_HEIGHT && maxZI - minZI + 1 >= MIN_SIDE)
{
otherMin = new Point3D(maxX, minYI, minZI);
otherMax = new Point3D(maxX + 1, maxYI, maxZI);
otherMin = new BlockPos(maxX, minYI, minZI);
otherMax = new BlockPos(maxX + 1, maxYI, maxZI);
doorway = new DoorwayData(otherMin, otherMax, DoorwayData.X_AXIS);
adjacentNode = roomsToGraph.get(adjacent);
roomGraph.addEdge(roomNode, adjacentNode, doorway);
@ -340,8 +297,8 @@ public class MazeDesigner
// Check if we meet the minimum dimensions needed for a doorway
if (maxXI - minXI + 1 >= MIN_SIDE && maxZI - minZI + 1 >= MIN_SIDE)
{
otherMin = new Point3D(minXI, maxY, minZI);
otherMax = new Point3D(maxXI, maxY + 1, maxZI);
otherMin = new BlockPos(minXI, maxY, minZI);
otherMax = new BlockPos(maxXI, maxY + 1, maxZI);
doorway = new DoorwayData(otherMin, otherMax, DoorwayData.Y_AXIS);
adjacentNode = roomsToGraph.get(adjacent);
roomGraph.addEdge(roomNode, adjacentNode, doorway);

View file

@ -1,91 +1,74 @@
package com.zixiken.dimdoors.experimental;
import com.zixiken.dimdoors.Point3D;
import net.minecraft.util.BlockPos;
import net.minecraft.util.Vec3i;
public class PartitionNode extends BoundingBox
{
public class PartitionNode extends BoundingBox {
private PartitionNode parent;
private PartitionNode leftChild = null;
private PartitionNode rightChild = null;
public PartitionNode(int width, int height, int length)
{
super(new Point3D(0, 0, 0), new Point3D(width - 1, height - 1, length - 1));
public PartitionNode(BlockPos volume) {
super(new BlockPos(0, 0, 0), volume.subtract(new Vec3i(1,1,1)));
parent = null;
}
private PartitionNode(PartitionNode parent, Point3D minCorner, Point3D maxCorner)
private PartitionNode(PartitionNode parent, BlockPos minCorner, BlockPos maxCorner)
{
super(minCorner, maxCorner);
this.parent = parent;
}
public boolean isLeaf()
{
public boolean isLeaf() {
return (leftChild == null && rightChild == null);
}
public PartitionNode leftChild()
{
public PartitionNode leftChild() {
return leftChild;
}
public PartitionNode rightChild()
{
public PartitionNode rightChild() {
return rightChild;
}
public PartitionNode parent()
{
public PartitionNode parent() {
return parent;
}
public void splitByX(int rightStart)
{
if (!this.isLeaf())
{
public void splitByX(int rightStart) {
if (!this.isLeaf()) {
throw new IllegalStateException("This node has already been split.");
} if (rightStart <= minCorner.getX() || rightStart > maxCorner.getX()) {
throw new IllegalArgumentException("The specified cutting plane is invalid.");
}
if (rightStart <= minCorner.getX() || rightStart > maxCorner.getX())
leftChild = new PartitionNode(this, minCorner, new BlockPos(rightStart - 1, maxCorner.getY(), maxCorner.getZ()));
rightChild = new PartitionNode(this, new BlockPos(rightStart, minCorner.getY(), minCorner.getZ()), maxCorner);
}
public void splitByY(int rightStart) {
if (!this.isLeaf()) {
throw new IllegalStateException("This node has already been split.");
} if (rightStart <= minCorner.getY() || rightStart > maxCorner.getY()) {
throw new IllegalArgumentException("The specified cutting plane is invalid.");
}
leftChild = new PartitionNode(this, minCorner, new BlockPos(maxCorner.getX(), rightStart - 1, maxCorner.getZ()));
rightChild = new PartitionNode(this, new BlockPos(minCorner.getX(), rightStart, minCorner.getZ()), maxCorner);
}
public void splitByZ(int rightStart) {
if (!this.isLeaf()) {
throw new IllegalStateException("This node has already been split.");
} if (rightStart <= minCorner.getZ() || rightStart > maxCorner.getZ())
{
throw new IllegalArgumentException("The specified cutting plane is invalid.");
}
leftChild = new PartitionNode(this, minCorner, new Point3D(rightStart - 1, maxCorner.getY(), maxCorner.getZ()));
rightChild = new PartitionNode(this, new Point3D(rightStart, minCorner.getY(), minCorner.getZ()), maxCorner);
leftChild = new PartitionNode(this, minCorner, new BlockPos(maxCorner.getX(), maxCorner.getY(), rightStart - 1));
rightChild = new PartitionNode(this, new BlockPos(minCorner.getX(), minCorner.getY(), rightStart), maxCorner);
}
public void splitByY(int rightStart)
{
if (!this.isLeaf())
{
throw new IllegalStateException("This node has already been split.");
}
if (rightStart <= minCorner.getY() || rightStart > maxCorner.getY())
{
throw new IllegalArgumentException("The specified cutting plane is invalid.");
}
leftChild = new PartitionNode(this, minCorner, new Point3D(maxCorner.getX(), rightStart - 1, maxCorner.getZ()));
rightChild = new PartitionNode(this, new Point3D(minCorner.getX(), rightStart, minCorner.getZ()), maxCorner);
}
public void splitByZ(int rightStart)
{
if (!this.isLeaf())
{
throw new IllegalStateException("This node has already been split.");
}
if (rightStart <= minCorner.getZ() || rightStart > maxCorner.getZ())
{
throw new IllegalArgumentException("The specified cutting plane is invalid.");
}
leftChild = new PartitionNode(this, minCorner, new Point3D(maxCorner.getX(), maxCorner.getY(), rightStart - 1));
rightChild = new PartitionNode(this, new Point3D(minCorner.getX(), minCorner.getY(), rightStart), maxCorner);
}
public void remove()
{
if (parent != null)
{
public void remove() {
if (parent != null) {
if (parent.leftChild == this)
parent.leftChild = null;
else
@ -94,31 +77,21 @@ public class PartitionNode extends BoundingBox
}
}
public PartitionNode findPoint(int x, int y, int z)
{
public PartitionNode findPoint(BlockPos pos) {
// Find the lowest node that contains the specified point or return null
if (this.contains(x, y, z))
{
return this.findPointInternal(x, y, z);
}
else
{
if (this.contains(pos)) {
return this.findPointInternal(pos);
} else {
return null;
}
}
private PartitionNode findPointInternal(int x, int y, int z)
{
if (leftChild != null && leftChild.contains(x, y, z))
{
return leftChild.findPointInternal(x, y, z);
}
else if (rightChild != null && rightChild.contains(x, y, z))
{
return rightChild.findPointInternal(x, y, z);
}
else
{
private PartitionNode findPointInternal(BlockPos pos) {
if (leftChild != null && leftChild.contains(pos)) {
return leftChild.findPointInternal(pos);
} else if (rightChild != null && rightChild.contains(pos)) {
return rightChild.findPointInternal(pos);
} else {
return this;
}
}

View file

@ -0,0 +1,30 @@
package com.zixiken.dimdoors.helpers;
import net.minecraft.util.BlockPos;
/**
* Created by Jared Johnson on 6/22/2016.
*/
public class BlockPosHelper {
public static boolean between(BlockPos pos, BlockPos min, BlockPos max) {
return ((min.getX() <= pos.getX() && pos.getX() <= max.getX()) &&
(min.getY() <= pos.getY() && pos.getY() <= max.getY()) &&
(min.getZ() <= pos.getZ() && pos.getZ() <= max.getZ()));
}
public static BlockPos max(BlockPos a, BlockPos b) {
return new BlockPos(Math.max(a.getX(), b.getX()), Math.max(a.getY(), b.getY()), Math.max(a.getZ(), b.getZ()));
}
public static BlockPos min(BlockPos a, BlockPos b) {
return new BlockPos(Math.min(a.getX(), b.getX()), Math.min(a.getY(), b.getY()), Math.min(a.getZ(), b.getZ()));
}
public static boolean greaterThan(BlockPos a, BlockPos b) {
return (a.getX() > b.getX() && a.getY() > b.getY() && a.getZ() > b.getZ());
}
public static boolean lessThan(BlockPos a, BlockPos b) {
return (a.getX() < b.getX() && a.getY() < b.getY() && a.getZ() < b.getZ());
}
}

View file

@ -65,8 +65,8 @@ public class ChunkLoaderHelper implements LoadingCallback
public static void forcePocketChunks(NewDimData pocket, Ticket ticket)
{
BoundingBox bounds = PocketBuilder.calculateDefaultBounds(pocket);
Point3D minCorner = bounds.minCorner();
Point3D maxCorner = bounds.maxCorner();
BlockPos minCorner = bounds.minCorner();
BlockPos maxCorner = bounds.maxCorner();
int minX = minCorner.getX() >> 4;
int minZ = minCorner.getZ() >> 4;
int maxX = maxCorner.getX() >> 4;

View file

@ -17,8 +17,7 @@ public class Compactor
{
@SuppressWarnings("unused") // ?
private static class DimComparator implements Comparator<NewDimData>
{
private static class DimComparator implements Comparator<NewDimData> {
@Override
public int compare(NewDimData a, NewDimData b)
{
@ -26,18 +25,15 @@ public class Compactor
}
}
public static void write(Collection<? extends NewDimData> values, ByteBuf output) throws IOException
{
public static void write(Collection<? extends NewDimData> values, ByteBuf output) throws IOException {
// SenseiKiwi: Just encode the data straight up for now. I'll implement fancier compression later.
output.writeInt(values.size());
for (NewDimData dimension : values)
{
for (NewDimData dimension : values) {
output.writeInt(dimension.id());
output.writeInt(dimension.root().id());
output.writeInt(dimension.type().index);
output.writeInt(dimension.linkCount());
for (DimLink link : dimension.links())
{
for (DimLink link : dimension.links()) {
(new ClientLinkData(link)).write(output);
}
}
@ -55,29 +51,25 @@ public class Compactor
*/
}
public static void readDimensions(ByteBuf input, IDimRegistrationCallback callback) throws IOException
{
public static void readDimensions(ByteBuf input, IDimRegistrationCallback callback) throws IOException {
// Read in the dimensions one by one. Make sure we register root dimensions before
// attempting to register the dimensions under them.
HashSet<Integer> rootIDs = new HashSet<Integer>();
int dimCount = input.readInt();
for (int k = 0; k < dimCount; k++)
{
for (int k = 0; k < dimCount; k++) {
int id = input.readInt();
int rootID = input.readInt();
DimensionType type = DimensionType.getTypeFromIndex(input.readInt());
if (rootIDs.add(rootID))
{
if (rootIDs.add(rootID)) {
callback.registerDimension(rootID, rootID, type);
}
// Don't check if (id != rootID) - we want to retrieve the reference anyway
NewDimData dimension = callback.registerDimension(id, rootID, type);
int linkCount = input.readInt();
for (int h = 0; h < linkCount; h++)
{
for (int h = 0; h < linkCount; h++) {
ClientLinkData link = ClientLinkData.read(input);
Point4D source = link.point;
dimension.createLink(source.getX(), source.getY(), source.getZ(), LinkType.CLIENT,0);

View file

@ -2,31 +2,21 @@ package com.zixiken.dimdoors.helpers;
import java.io.File;
public class DeleteFolder
{
public static boolean deleteFolder(File directory)
{
try
{
public class DeleteFolder {
public static boolean deleteFolder(File directory) {
try {
File[] contents = directory.listFiles();
if (contents != null)
{
for (File entry : contents)
{
if (entry.isDirectory())
{
if (contents != null) {
for (File entry : contents) {
if (entry.isDirectory()) {
deleteFolder(entry);
}
else
{
} else {
entry.delete();
}
}
}
return directory.delete();
}
catch (Exception e)
{
} catch (Exception e) {
e.printStackTrace();
return false;
}

View file

@ -1,6 +1,5 @@
package com.zixiken.dimdoors.helpers;
public class PersonalPocketHelper
{
public class PersonalPocketHelper {
}

View file

@ -6,12 +6,9 @@ import java.io.OutputStream;
import com.zixiken.dimdoors.DimDoors;
public class copyfile
{
public static boolean copyFile(String ori, String dest)
{
try
{
public class copyfile {
public static boolean copyFile(String ori, String dest) {
try {
//Note: For this to work properly, you must use getClass() on an instance of the class,
//not on the value obtained from .class. That was what caused this code to fail before.
//SchematicLoader didn't have this problem because we used instances of it.
@ -24,9 +21,7 @@ public class copyfile
}
in.close();
out.close();
}
catch (Exception e)
{
} catch (Exception e) {
System.out.println("Unable to get resource: " + ori);
return false;
}

View file

@ -3,6 +3,8 @@ package com.zixiken.dimdoors.helpers;
import com.zixiken.dimdoors.Point3D;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.BlockPos;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
@ -14,14 +16,12 @@ public class yCoordHelper
private yCoordHelper() { }
public static int getFirstUncovered(World world, int x, int yStart, int z)
{
public static int getFirstUncovered(World world, int x, int yStart, int z) {
return getFirstUncovered(world, x, yStart, z, false);
}
public static int getFirstUncovered(World world, int x, int yStart, int z, boolean fromTop)
{
Chunk chunk = world.getChunkProvider().loadChunk(x >> 4, z >> 4);
public static int getFirstUncovered(World world, int x, int yStart, int z, boolean fromTop) {
Chunk chunk = world.getChunkProvider().provideChunk(x >> 4, z >> 4);
int localX = x < 0 ? (x % 16) + 16 : (x % 16);
int localZ = z < 0 ? (z % 16) + 16 : (z % 16);
@ -66,8 +66,7 @@ public class yCoordHelper
return (material.isLiquid() || !material.isReplaceable());
}
public static Point3D findSafeCubeUp(World world, int x, int startY, int z)
{
public static BlockPos findSafeCubeUp(World world, int x, int startY, int z) {
// Search for a 3x2x3 box with solid opaque blocks (without tile entities)
// or replaceable blocks underneath. The box must contain either air and
// non-liquid replaceable blocks only.
@ -84,7 +83,8 @@ public class yCoordHelper
Chunk chunk = initializeChunkArea(world, x >> 4, z >> 4);
int height = world.getActualHeight();
int y, dx, dz, blockID, metadata;
int y, dx, dz, blockID;
IBlockState state;
boolean isSafe;
Block block;
@ -97,39 +97,30 @@ public class yCoordHelper
// Treat non-liquid replaceable blocks like air
// If we find a layer that contains replaceable blocks or solid opaque blocks without
// tile entities, then it can serve as the base where we'll place the player and door.
for (y = Math.max(startY - 1, 0); y < height; y++)
{
for (y = Math.max(startY - 1, 0); y < height; y++) {
isSafe = true;
for (dx = -1; dx <= 1 && isSafe; dx++)
{
for (dz = -1; dz <= 1 && isSafe; dz++)
{
for (dx = -1; dx <= 1 && isSafe; dx++) {
for (dz = -1; dz <= 1 && isSafe; dz++) {
block = chunk.getBlock(localX + dx, y, localZ + dz);
metadata = chunk.getBlockMetadata(localX + dx, y, localZ + dz);
if (!block.isAir(world, x, y, z) && (!block.getMaterial().isReplaceable() || block.getMaterial().isLiquid()))
{
if (!block.getMaterial().isReplaceable() && (!block.isOpaqueCube() || block.hasTileEntity(metadata)))
{
state = chunk.getBlockState(new BlockPos(localX + dx, y, localZ + dz));
if (!block.isAir(world, new BlockPos(x, y, z)) && (!block.getMaterial().isReplaceable() || block.getMaterial().isLiquid())) {
if (!block.getMaterial().isReplaceable() && (!block.isOpaqueCube() || block.hasTileEntity(state))) {
isSafe = false;
}
layers = 0;
}
}
}
if (isSafe)
{
} if (isSafe) {
layers++;
if (layers == 3)
{
return new Point3D(localX + cornerX, y - 2, localZ + cornerZ);
if (layers == 3) {
return new BlockPos(localX + cornerX, y - 2, localZ + cornerZ);
}
}
}
return null;
}
public static Point3D findSafeCubeDown(World world, int x, int startY, int z)
{
public static BlockPos findSafeCubeDown(World world, int x, int startY, int z) {
// Search for a 3x2x3 box with solid opaque blocks (without tile entities)
// or replaceable blocks underneath. The box must contain either air and
// non-liquid replaceable blocks only.
@ -146,7 +137,8 @@ public class yCoordHelper
Chunk chunk = initializeChunkArea(world, x >> 4, z >> 4);
int height = world.getActualHeight();
int y, dx, dz, blockID, metadata;
int y, dx, dz, blockID;
IBlockState state;
boolean isSafe;
boolean hasBlocks;
Block block;
@ -160,34 +152,25 @@ public class yCoordHelper
{
isSafe = true;
hasBlocks = false;
for (dx = -1; dx <= 1 && isSafe; dx++)
{
for (dz = -1; dz <= 1 && isSafe; dz++)
{
for (dx = -1; dx <= 1 && isSafe; dx++) {
for (dz = -1; dz <= 1 && isSafe; dz++) {
block = chunk.getBlock(localX + dx, y, localZ + dz);
metadata = chunk.getBlockMetadata(localX + dx, y, localZ + dz);
if (!block.isAir(world,x,y,z) && (!block.getMaterial().isReplaceable() || block.getMaterial().isLiquid()))
{
if (!block.getMaterial().isReplaceable() && (!block.isOpaqueCube() || block.hasTileEntity(metadata)))
{
if (layers >= 3)
{
return new Point3D(localX + cornerX, y + 1, localZ + cornerZ);
state = chunk.getBlockState(new BlockPos(localX + dx, y, localZ + dz));
if (!block.isAir(world, new BlockPos(x,y,z)) && (!block.getMaterial().isReplaceable() || block.getMaterial().isLiquid())) {
if (!block.getMaterial().isReplaceable() && (!block.isOpaqueCube() || block.hasTileEntity(state))) {
if (layers >= 3) {
return new BlockPos(localX + cornerX, y + 1, localZ + cornerZ);
}
isSafe = false;
}
hasBlocks = true;
}
}
}
if (isSafe)
{
} if (isSafe) {
layers++;
if (hasBlocks)
{
if (layers >= 3)
{
return new Point3D(localX + cornerX, y, localZ + cornerZ);
if (hasBlocks) {
if (layers >= 3) {
return new BlockPos(localX + cornerX, y, localZ + cornerZ);
}
layers = 0;
}
@ -196,26 +179,22 @@ public class yCoordHelper
return null;
}
private static Chunk initializeChunkArea(World world, int chunkX, int chunkZ)
{
private static Chunk initializeChunkArea(World world, int chunkX, int chunkZ) {
// We initialize a 3x3 area of chunks instead of just initializing
// the target chunk because things generated in adjacent chunks
// (e.g. trees) might intrude into the target chunk.
IChunkProvider provider = world.getChunkProvider();
Chunk target = provider.loadChunk(chunkX, chunkZ);
for (int dx = -1; dx <= 1; dx++)
{
for (int dz = -1; dz <= 1; dz++)
{
provider.loadChunk(chunkX, chunkZ);
Chunk target = provider.provideChunk(chunkX, chunkZ);
for (int dx = -1; dx <= 1; dx++) {
for (int dz = -1; dz <= 1; dz++) {
provider.provideChunk(chunkX, chunkZ);
}
}
return target;
}
public static Point3D findDropPoint(World world, int x, int startY, int z)
{
public static BlockPos findDropPoint(World world, int x, int startY, int z) {
// Find a simple 2-block-high air gap
// Search across a 3x3 column
final int GAP_HEIGHT = 2;
@ -234,35 +213,25 @@ public class yCoordHelper
int[] gaps = new int[9];
// Check 3x3 layers of blocks for air spaces
for (y = Math.min(startY, height - 1); y > 0; y--)
{
for (dx = -1, index = 0; dx <= 1; dx++)
{
for (dz = -1; dz <= 1; dz++, index++)
{
if (!chunk.getBlock(localX + dx, y, localZ + dz).isAir(world, x+dx,y,z+dz))
{
for (y = Math.min(startY, height - 1); y > 0; y--) {
for (dx = -1, index = 0; dx <= 1; dx++) {
for (dz = -1; dz <= 1; dz++, index++) {
if (!chunk.getBlock(localX + dx, y, localZ + dz).isAir(world, new BlockPos(x+dx, y, z+dz))) {
gaps[index] = 0;
}
else
{
} else {
gaps[index]++;
}
}
}
// Check if an acceptable gap exists in the center of the search column
if (gaps[index / 2] == GAP_HEIGHT)
{
return new Point3D(localX + cornerX, y + GAP_HEIGHT - 1, localZ + cornerZ);
if (gaps[index / 2] == GAP_HEIGHT) {
return new BlockPos(localX + cornerX, y + GAP_HEIGHT - 1, localZ + cornerZ);
}
// Check the other positions in the column
for (dx = -1, index = 0; dx <= 1; dx++)
{
for (dz = -1; dz <= 1; dz++, index++)
{
if (gaps[index] == GAP_HEIGHT)
{
return new Point3D(localX + cornerX + dx, y + GAP_HEIGHT - 1, localZ + cornerZ + dz);
for (dx = -1, index = 0; dx <= 1; dx++) {
for (dz = -1; dz <= 1; dz++, index++) {
if (gaps[index] == GAP_HEIGHT) {
return new BlockPos(localX + cornerX + dx, y + GAP_HEIGHT - 1, localZ + cornerZ + dz);
}
}
}
@ -270,22 +239,19 @@ public class yCoordHelper
return null;
}
public static int adjustDestinationY(int y, int worldHeight, int entranceY, int dungeonHeight)
{
public static int adjustDestinationY(int y, int worldHeight, int entranceY, int dungeonHeight) {
//The goal here is to guarantee that the dungeon fits within the vertical bounds
//of the world while shifting it as little as possible.
int destY = y;
//Is the top of the dungeon going to be at Y < worldHeight?
int pocketTop = (dungeonHeight - 1) + destY - entranceY;
if (pocketTop >= worldHeight)
{
if (pocketTop >= worldHeight) {
destY = (worldHeight - 1) - (dungeonHeight - 1) + entranceY;
}
//Is the bottom of the dungeon at Y >= 0?
if (destY < entranceY)
{
if (destY < entranceY) {
destY = entranceY;
}
return destY;

View file

@ -199,7 +199,7 @@ public class DDSaveHandler
public static boolean unpackLinkData(List<PackedLinkData> linksToUnpack)
{
Point3D fakePoint = new Point3D(-1,-1,-1);
BlockPos fakePoint = new BlockPos(-1,-1,-1);
List<PackedLinkData> unpackedLinks = new ArrayList<PackedLinkData>();
/**
* sort through the list, unpacking links that do not have parents.

View file

@ -77,9 +77,9 @@ public class OldSaveImporter
Point4D source = new Point4D(link.locXCoord,link.locYCoord,link.locZCoord,link.locDimID);
Point4D destintion = new Point4D(link.destXCoord,link.destYCoord,link.destZCoord,link.destDimID);
PackedLinkTail tail = new PackedLinkTail(destintion, LinkType.NORMAL);
List<Point3D> children = new ArrayList<Point3D>();
List<BlockPos> children = new ArrayList<BlockPos>();
PackedLinkData newPackedLink = new PackedLinkData(source, new Point3D(-1,-1,-1), tail, link.linkOrientation,children, null);
PackedLinkData newPackedLink = new PackedLinkData(source, new BlockPos(-1,-1,-1), tail, link.linkOrientation,children, null);
newPackedLinkData.add(newPackedLink);
allPackedLinks.add(newPackedLink);
@ -104,11 +104,11 @@ public class OldSaveImporter
}
if(data.isPocket)
{
dim = new PackedDimData(data.dimID, data.depth, data.depth, data.exitDimLink.locDimID, data.exitDimLink.locDimID, 0, type, data.hasBeenFilled, null, new Point3D(0,64,0), childDims, newPackedLinkData, null);
dim = new PackedDimData(data.dimID, data.depth, data.depth, data.exitDimLink.locDimID, data.exitDimLink.locDimID, 0, type, data.hasBeenFilled, null, new BlockPos(0,64,0), childDims, newPackedLinkData, null);
}
else
{
dim = new PackedDimData(data.dimID, data.depth, data.depth, data.dimID, data.dimID, 0, type, data.hasBeenFilled, null, new Point3D(0,64,0), childDims, newPackedLinkData, null);
dim = new PackedDimData(data.dimID, data.depth, data.depth, data.dimID, data.dimID, 0, type, data.hasBeenFilled, null, new BlockPos(0,64,0), childDims, newPackedLinkData, null);
}
newPackedDimData.put(dim.ID,dim);
}

View file

@ -4,6 +4,8 @@ import java.util.List;
import com.zixiken.dimdoors.Point3D;
import com.zixiken.dimdoors.core.DimensionType;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
public class PackedDimData
{
@ -18,18 +20,17 @@ public class PackedDimData
public final int ParentID;
public final int RootID;
public final PackedDungeonData DungeonData;
public final Point3D Origin;
public final int Orientation;
public final BlockPos Origin;
public final EnumFacing Orientation;
public final List<Integer> ChildIDs;
public final List<PackedLinkData> Links;
public final List<PackedLinkTail> Tails;
// FIXME Missing dungeon data, not sure how to include it
public PackedDimData(int id, int depth, int packDepth, int parentID, int rootID, int orientation,
DimensionType type, boolean isFilled,PackedDungeonData dungeonData, Point3D origin, List<Integer> childIDs, List<PackedLinkData> links,
List<PackedLinkTail> tails)
{
public PackedDimData(int id, int depth, int packDepth, int parentID, int rootID, EnumFacing orientation,
DimensionType type, boolean isFilled, PackedDungeonData dungeonData, BlockPos origin, List<Integer> childIDs, List<PackedLinkData> links,
List<PackedLinkTail> tails) {
ID = id;
Depth = depth;
PackDepth = packDepth;
@ -46,8 +47,7 @@ public class PackedDimData
}
@Override
public String toString()
{
public String toString() {
return "ID= "+this.ID;
}

View file

@ -5,18 +5,19 @@ import java.util.List;
import com.zixiken.dimdoors.Point3D;
import com.zixiken.dimdoors.core.DDLock;
import com.zixiken.dimdoors.util.Point4D;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
public class PackedLinkData
{
public final Point4D source;
public final Point3D parent;
public final BlockPos parent;
public final PackedLinkTail tail;
public final int orientation;
public final List<Point3D> children;
public final EnumFacing orientation;
public final List<BlockPos> children;
public final DDLock lock;
public PackedLinkData(Point4D source, Point3D parent, PackedLinkTail tail, int orientation, List<Point3D> children, DDLock lock)
{
public PackedLinkData(Point4D source, BlockPos parent, PackedLinkTail tail, EnumFacing orientation, List<BlockPos> children, DDLock lock) {
this.source=source;
this.parent=parent;
this.tail=tail;

View file

@ -3,7 +3,10 @@ package com.zixiken.dimdoors.schematic;
import com.zixiken.dimdoors.DimDoors;
import net.minecraft.block.*;
import com.zixiken.dimdoors.Point3D;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import java.util.HashMap;
import java.util.Map;
@ -75,7 +78,7 @@ public class BlockRotator
hasOrientations.put(DimDoors.personalDimDoor, true);
}
public static int transformMetadata(int metadata, int turns, Block block)
public static IBlockState transformMetadata(IBlockState state, int turns, Block block)
{
//I changed rotations to reduce the monstrous code we had. It might be
//slightly less efficient, but it's easier to maintain for now. ~SenseiKiwi
@ -88,14 +91,14 @@ public class BlockRotator
{
while (turns > 0)
{
metadata = rotateMetadataBy90(metadata, block);
state = rotateMetadataBy90(state, block);
turns--;
}
}
return metadata;
return state;
}
private static int rotateMetadataBy90(int metadata, Block block)
private static IBlockState rotateMetadataBy90(IBlockState state, Block block)
{
//TODO: Replace this horrible function with something prettier. We promise we will for the next version,
//after switching to MC 1.6. PADRE, PLEASE FORGIVE OUR SINS.
@ -501,7 +504,7 @@ public class BlockRotator
return metadata;
}
public static void transformPoint(Point3D position, Point3D srcOrigin, int angle, Point3D destOrigin)
public static void transformPoint(BlockPos position, BlockPos srcOrigin, EnumFacing angle, BlockPos 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),
@ -512,9 +515,7 @@ public class BlockRotator
//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();
BlockPos t = position.subtract(srcOrigin);
//"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.
@ -522,40 +523,32 @@ public class BlockRotator
//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;
switch (angle) {
case SOUTH: //No rotation
rx = t.getX();
rz = t.getZ();
break;
case 1: //90 degrees clockwise
rx = -tz;
rz = tx;
case WEST: //90 degrees clockwise
rx = -t.getZ();
rz = t.getX();
break;
case 2: //180 degrees
rx = -tx;
rz = -tz;
case NORTH: //180 degrees
rx = -t.getX();
rz = -t.getZ();
break;
case 3: //270 degrees clockwise
rx = tz;
rz = -tx;
case EAST: //270 degrees clockwise
rx = t.getZ();
rz = -t.getX();
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() );
position = new BlockPos(rx + destOrigin.getX(), t.getY() + destOrigin.getY(), rz + destOrigin.getZ() );
}
}

View file

@ -1,16 +1,13 @@
package com.zixiken.dimdoors.schematic;
import com.zixiken.dimdoors.helpers.BlockPosHelper;
import net.minecraft.block.Block;
import net.minecraft.util.BlockPos;
import net.minecraft.world.World;
import com.zixiken.dimdoors.Point3D;
public class CompactBoundsOperation extends WorldOperation
{
private int minX;
private int minY;
private int minZ;
private int maxX;
private int maxY;
private int maxZ;
public class CompactBoundsOperation extends WorldOperation {
private BlockPos minCorner;
private BlockPos maxCorner;
public CompactBoundsOperation()
{
@ -18,57 +15,39 @@ public class CompactBoundsOperation extends WorldOperation
}
@Override
protected boolean initialize(World world, int x, int y, int z, int width, int height, int length)
{
minX = Integer.MAX_VALUE;
minY = Integer.MAX_VALUE;
minZ = Integer.MAX_VALUE;
maxX = x;
maxY = y;
maxZ = z;
protected boolean initialize(World world, BlockPos pos, BlockPos volume) {
minCorner = new BlockPos(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
maxCorner = pos;
return true;
}
@Override
protected boolean applyToBlock(World world, int x, int y, int z)
{
protected boolean applyToBlock(World world, BlockPos pos) {
//This could be done more efficiently, but honestly, this is the simplest approach and it
//makes it easy for us to verify that the code is correct.
if (!world.isAirBlock(x, y, z))
{
maxX = x > maxX ? x : maxX;
maxZ = z > maxZ ? z : maxZ;
maxY = y > maxY ? y : maxY;
minX = x < minX ? x : minX;
minZ = z < minZ ? z : minZ;
minY = y < minY ? y : minY;
if (!world.isAirBlock(pos)) {
maxCorner = BlockPosHelper.greaterThan(pos, maxCorner) ? pos : maxCorner;
minCorner = BlockPosHelper.lessThan(pos, minCorner) ? pos : minCorner;
}
return true;
}
@Override
protected boolean finish()
{
if (minX == Integer.MAX_VALUE)
{
protected boolean finish() {
if (minCorner.getX() == Integer.MAX_VALUE) {
//The whole search space was empty!
//Compact the space to a single block.
minX = maxX;
minY = maxY;
minZ = maxZ;
minCorner = maxCorner;
return false;
}
return true;
}
public Point3D getMaxCorner()
{
return new Point3D(maxX, maxY, maxZ);
public BlockPos getMaxCorner() {
return maxCorner;
}
public Point3D getMinCorner()
{
return new Point3D(minX, minY, minZ);
public BlockPos getMinCorner() {
return minCorner;
}
}

View file

@ -1,6 +1,7 @@
package com.zixiken.dimdoors.schematic;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import java.util.ArrayList;
@ -8,8 +9,7 @@ public class CompoundFilter extends SchematicFilter {
private ArrayList<SchematicFilter> filters;
public CompoundFilter()
{
public CompoundFilter() {
super("CompoundFilter");
filters = new ArrayList<SchematicFilter>();
}
@ -20,12 +20,9 @@ public class CompoundFilter extends SchematicFilter {
}
@Override
protected boolean initialize(Schematic schematic,Block[] blocks, byte[] metadata)
{
for (SchematicFilter filter : filters)
{
if (!filter.initialize(schematic, blocks, metadata))
{
protected boolean initialize(Schematic schematic, IBlockState[] metadata) {
for (SchematicFilter filter : filters) {
if (!filter.initialize(schematic, metadata)) {
return false;
}
}
@ -33,12 +30,9 @@ public class CompoundFilter extends SchematicFilter {
}
@Override
protected boolean finish()
{
for (SchematicFilter filter : filters)
{
if (!filter.finish())
{
protected boolean finish() {
for (SchematicFilter filter : filters) {
if (!filter.finish()) {
return false;
}
}
@ -46,12 +40,9 @@ public class CompoundFilter extends SchematicFilter {
}
@Override
protected boolean applyToBlock(int index, Block[] blocks, byte[] metadata)
{
for (SchematicFilter filter : filters)
{
if (filter.applyToBlock(index, blocks, metadata))
{
protected boolean applyToBlock(int index, IBlockState[] state) {
for (SchematicFilter filter : filters) {
if (filter.applyToBlock(index, state)) {
return filter.terminates();
}
}

View file

@ -1,9 +1,11 @@
package com.zixiken.dimdoors.schematic;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.BlockPos;
import net.minecraft.world.World;
public interface IBlockSetter
{
public void setBlock(World world, int x, int y, int z, Block block, int metadata);
public void setBlock(World world, BlockPos pos, IBlockState state);
}

View file

@ -10,12 +10,14 @@ import java.util.LinkedList;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockPos;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import com.zixiken.dimdoors.Point3D;
/**
* Represents an MC schematic and provides functions for loading, storing, and manipulating schematics.
@ -23,162 +25,96 @@ import com.zixiken.dimdoors.Point3D;
*/
public class Schematic {
protected short width;
protected short height;
protected short length;
protected Block[] blocks;
protected byte[] metadata;
protected BlockPos volume;
protected IBlockState[] state;
protected NBTTagList tileEntities;
protected Schematic(short width, short height, short length, String[] blockPalette, short[] blockIds, byte[] metadata, NBTTagList tileEntities)
{
this.width = width;
this.height = height;
this.length = length;
this.metadata = metadata;
this.tileEntities = tileEntities;
if (blockPalette != null)
loadBlockList(blockPalette, blockIds);
}
protected Schematic(short width, short height, short length, Block[] blocks, byte[] metadata, NBTTagList tileEntities) {
this.width = width;
this.height = height;
this.length = length;
this.blocks = blocks;
this.metadata = metadata;
protected Schematic(BlockPos volume, IBlockState[] state, NBTTagList tileEntities) {
this.volume = volume;
this.state = state;
this.tileEntities = tileEntities;
}
protected Schematic(Schematic source)
{
protected Schematic(Schematic source) {
//Shallow copy constructor - critical for code reuse in derived classes since
//source's fields will be inaccessible if the derived class is in another package.
this.width = source.width;
this.height = source.height;
this.length = source.length;
this.blocks = source.blocks;
this.metadata = source.metadata;
this.volume = source.volume;
this.state = source.state;
this.tileEntities = source.tileEntities;
}
private void loadBlockList(String[] blockPalette, short[] blockIds) {
this.blocks = new Block[blockIds.length];
Block[] blockObjPalette = new Block[blockPalette.length];
for (int i = 0; i < blockPalette.length; i++) {
blockObjPalette[i] = (Block)Block.blockRegistry.getObject(blockPalette[i]);
}
for (int i = 0; i < blockIds.length; i++) {
this.blocks[i] = blockObjPalette[blockIds[i]];
}
}
public int calculateIndex(int x, int y, int z)
{
if (x < 0 || x >= width)
public int calculateIndex(BlockPos pos) {
if (pos.getX() < 0 || pos.getX() >= volume.getX())
throw new IndexOutOfBoundsException("x must be non-negative and less than width");
if (y < 0 || y >= height)
if (pos.getY() < 0 || pos.getY() >= volume.getY())
throw new IndexOutOfBoundsException("y must be non-negative and less than height");
if (z < 0 || z >= length)
if (pos.getZ() < 0 || pos.getZ() >= volume.getZ())
throw new IndexOutOfBoundsException("z must be non-negative and less than length");
return (y * width * length + z * width + x);
return (pos.getY() * volume.getX() * volume.getZ() + pos.getZ() * volume.getX() + pos.getX());
}
public Point3D calculatePoint(int index)
{
int y = index / (width * length);
index -= y * width * length;
int z = index / width;
index -= z * width;
public BlockPos calculatePoint(int index) {
int y = index / (volume.getX() * volume.getZ());
index -= y * volume.getX() * volume.getZ();
int z = index / volume.getX();
index -= z * volume.getX();
int x = index;
return new Point3D(x, y, z);
return new BlockPos(x, y, z);
}
public int calculateIndexBelow(int index)
{
return index - (width * length);
public int calculateIndexBelow(int index) {
return index - (volume.getX() * volume.getZ());
}
public short getWidth()
{
return width;
public BlockPos getVolume() {
return volume;
}
public short getHeight()
{
return height;
public Block getBlock(BlockPos pos) {
return state[calculateIndex(pos)].getBlock();
}
public short getLength()
{
return length;
public IBlockState getBlockState(BlockPos pos) {
return state[calculateIndex(pos)];
}
public Block getBlock(int x, int y, int z)
{
return (Block)Block.blockRegistry.getObject(blocks[calculateIndex(x, y, z)]);
}
public byte getBlockMetadata(int x, int y, int z)
{
return metadata[calculateIndex(x, y, z)];
}
public NBTTagList getTileEntities()
{
public NBTTagList getTileEntities() {
return (NBTTagList) tileEntities.copy();
}
public static Schematic readFromFile(String schematicPath) throws FileNotFoundException, InvalidSchematicException
{
public static Schematic readFromFile(String schematicPath) throws FileNotFoundException, InvalidSchematicException {
return readFromFile(new File(schematicPath));
}
public static Schematic readFromFile(File schematicFile) throws FileNotFoundException, InvalidSchematicException
{
public static Schematic readFromFile(File schematicFile) throws FileNotFoundException, InvalidSchematicException {
// There is no resource leak... readFromStream() closes the stream TWICE.
return readFromStream(new FileInputStream(schematicFile));
}
public static Schematic readFromResource(String resourcePath) throws InvalidSchematicException
{
public static Schematic readFromResource(String resourcePath) throws InvalidSchematicException {
InputStream schematicStream = Schematic.class.getResourceAsStream(resourcePath);
return readFromStream(schematicStream);
}
public static Schematic readFromStream(InputStream schematicStream) throws InvalidSchematicException
{
public static Schematic readFromStream(InputStream schematicStream) throws InvalidSchematicException {
short width;
short height;
short length;
int volume;
int pairs;
byte[] metadata = null; //block metadata
byte[] lowBits = null; //first 8 bits of the block IDs
byte[] highBits = null; //additional 4 bits of the block IDs
short[] blockIds = null; //list of combined block IDs
String[] blockPalette = null;
IBlockState[] state = null; //block state
NBTTagList tileEntities = null; //storage for tile entities in NBT form
NBTTagCompound schematicTag; //the NBT data extracted from the schematic file
boolean hasExtendedBlockIDs; //indicates whether the schematic contains extended block IDs
try
{
try
{
try {
try {
schematicTag = CompressedStreamTools.readCompressed(schematicStream);
schematicStream.close(); //readCompressed() probably closes the stream anyway, but close again to be sure.
}
catch (Exception ex)
{
catch (Exception ex) {
ex.printStackTrace();
throw new InvalidSchematicException("The schematic could not be decoded.");
@ -197,68 +133,20 @@ public class Schematic {
if (length < 0)
throw new InvalidSchematicException("The schematic cannot have a negative length.");
NBTTagList nbtPalette = schematicTag.getTagList("Palette", 8);
if (nbtPalette.tagCount() < 1) {
throw new InvalidSchematicException("The schematic must have a valid block palette.");
}
blockPalette = new String[nbtPalette.tagCount()];
for (int i = 0; i < nbtPalette.tagCount(); i++) {
blockPalette[i] = nbtPalette.getStringTagAt(i);
}
//load block info
lowBits = schematicTag.getByteArray("Blocks");
highBits = schematicTag.getByteArray("AddBlocks");
metadata = schematicTag.getByteArray("Data");
hasExtendedBlockIDs = (highBits.length != 0);
int[] temp = schematicTag.getIntArray("Data");
state = new IBlockState[temp.length];
if (volume != lowBits.length)
throw new InvalidSchematicException("The schematic has data for fewer blocks than its dimensions indicate.");
if (volume != metadata.length)
throw new InvalidSchematicException("The schematic has metadata for fewer blocks than its dimensions indicate.");
if (volume > 2 * highBits.length && hasExtendedBlockIDs)
throw new InvalidSchematicException("The schematic has extended block IDs for fewer blocks than its dimensions indicate.");
for(int i = 0; i < temp.length; i++)
state[i] = Block.getStateById(temp[i]);
blockIds = new short[volume];
if (hasExtendedBlockIDs)
{
//Combine the split block IDs into a single value
pairs = volume - (volume & 1);
int index;
for (index = 0; index < pairs; index += 2)
{
blockIds[index] = (short) (((highBits[index >> 1] & 0x0F) << 8) + (lowBits[index] & 0xFF));
blockIds[index + 1] = (short) (((highBits[index >> 1] & 0xF0) << 4) + (lowBits[index + 1] & 0xFF));
}
if (index < volume)
{
blockIds[index] = lowBits[index >> 1];
}
}
else
{
//Copy the blockIDs
for (int index = 0; index < volume; index++)
{
blockIds[index] = (short) (lowBits[index] & 0xFF);
}
}
for (int i = 0; i < blockIds.length; i++) {
int paletteIndex = blockIds[i];
if (paletteIndex < 0 || paletteIndex >= blockPalette.length) {
throw new InvalidSchematicException("Block entry referenced a non-existant palette entry.");
}
}
if (volume != state.length)
throw new InvalidSchematicException("The schematic has IBlockState for fewer blocks than its dimensions indicate.");
//Get the list of tile entities
tileEntities = schematicTag.getTagList("TileEntities", 10);
Schematic result = new Schematic(width, height, length, blockPalette, blockIds, metadata, tileEntities);
Schematic result = new Schematic(new BlockPos(width, height, length), state, tileEntities);
return result;
}
catch (InvalidSchematicException ex)
@ -272,132 +160,71 @@ public class Schematic {
}
}
public static Schematic copyFromWorld(World world, int x, int y, int z, short width, short height, short length, boolean doCompactBounds)
{
if (doCompactBounds)
{
public static Schematic copyFromWorld(World world, BlockPos pos, BlockPos volume, boolean doCompactBounds) {
if (doCompactBounds) {
//Adjust the vertical bounds to reasonable values if necessary
int worldHeight = world.getHeight();
int fixedY = (y < 0) ? 0 : y;
int fixedHeight = height + y - fixedY;
int fixedY = (pos.getY() < 0) ? 0 : pos.getY();
int fixedHeight = volume.getY() + pos.getY() - fixedY;
if (fixedHeight + fixedY >= worldHeight)
{
if (fixedHeight + fixedY >= worldHeight) {
fixedHeight = worldHeight - fixedY;
}
//Compact the area to be copied to remove empty borders
CompactBoundsOperation compactor = new CompactBoundsOperation();
compactor.apply(world, x, fixedY, z, width, fixedHeight, length);
Point3D minCorner = compactor.getMinCorner();
Point3D maxCorner = compactor.getMaxCorner();
compactor.apply(world, new BlockPos(pos.getX(), fixedY, pos.getZ()), new BlockPos(volume.getX(), fixedHeight, volume.getZ()));
BlockPos minCorner = compactor.getMinCorner();
BlockPos maxCorner = compactor.getMaxCorner();
short compactWidth = (short) (maxCorner.getX() - minCorner.getX() + 1);
short compactHeight = (short) (maxCorner.getY() - minCorner.getY() + 1);
short compactLength = (short) (maxCorner.getZ() - minCorner.getZ() + 1);
BlockPos compact = maxCorner.subtract(minCorner).add(1,1,1);
return copyFromWorld(world, minCorner.getX(), minCorner.getY(), minCorner.getZ(),
compactWidth, compactHeight, compactLength);
}
else
{
return copyFromWorld(world, x, y, z, width, height, length);
return copyFromWorld(world, minCorner, compact);
} else {
return copyFromWorld(world, pos, volume);
}
}
private static Schematic copyFromWorld(World world, int x, int y, int z, short width, short height, short length)
{
private static Schematic copyFromWorld(World world, BlockPos pos, BlockPos volume) {
//Short and sweet ^_^
WorldCopyOperation copier = new WorldCopyOperation();
copier.apply(world, x, y, z, width, height, length);
return new Schematic(width, height, length, copier.getBlocks(), copier.getMetadata(), copier.getTileEntities());
copier.apply(world, pos, volume);
return new Schematic(volume, copier.getBlockState(), copier.getTileEntities());
}
private static boolean encodeBlockIDs(short[] blocks, byte[] lowBits, byte[] highBits)
{
int index;
int length = blocks.length - (blocks.length & 1);
boolean hasHighBits = false;
for (index = 0; index < length; index += 2)
{
highBits[index >> 1] = (byte) (((blocks[index] >> 8) & 0x0F) + ((blocks[index + 1] >> 4) & 0xF0));
hasHighBits |= (highBits[index >> 1] != 0);
}
if (index < blocks.length)
{
highBits[index >> 1] = (byte) ((blocks[index] >> 8) & 0x0F);
hasHighBits |= (highBits[index >> 1] != 0);
}
for (index = 0; index < blocks.length; index++)
{
lowBits[index] = (byte) (blocks[index] & 0xFF);
}
return hasHighBits;
}
private static void reduceToPalette(Block[] blocks, List<String> blockPalette, short[] blockIds) {
for (int i = 0; i < blocks.length; i++) {
String blockName = Block.blockRegistry.getNameForObject(blocks[i]);
int blockIndex = blockPalette.indexOf(blockName);
if (blockIndex < 0) {
blockIndex = blockPalette.size();
blockPalette.add(blockName);
}
blockIds[i] = (short)blockIndex;
}
}
public NBTTagCompound writeToNBT()
{
public NBTTagCompound writeToNBT() {
return writeToNBT(true);
}
protected NBTTagCompound writeToNBT(boolean copyTileEntities)
{
return writeToNBT(width, height, length, blocks, metadata, tileEntities, copyTileEntities);
protected NBTTagCompound writeToNBT(boolean copyTileEntities) {
return writeToNBT(volume, state, tileEntities, copyTileEntities);
}
protected static NBTTagCompound writeToNBT(short width, short height, short length, Block[] blocks, byte[] metadata,
NBTTagList tileEntities, boolean copyTileEntities)
{
protected static NBTTagCompound writeToNBT(BlockPos volume, IBlockState[] state, NBTTagList tileEntities, boolean copyTileEntities) {
//This is the main storage function. Schematics are really compressed NBT tags, so if we can generate
//the tags, most of the work is done. All the other storage functions will rely on this one.
NBTTagCompound schematicTag = new NBTTagCompound();
schematicTag.setShort("Width", width);
schematicTag.setShort("Length", length);
schematicTag.setShort("Height", height);
schematicTag.setInteger("Width", volume.getX());
schematicTag.setInteger("Length", volume.getZ());
schematicTag.setInteger("Height", volume.getY());
schematicTag.setTag("Entities", new NBTTagList());
schematicTag.setString("Materials", "Alpha");
List<String> blockPalette = new LinkedList<String>();
short[] blockIds = new short[blocks.length];
reduceToPalette(blocks, blockPalette, blockIds);
int[] temp = new int[state.length];
byte[] lowBits = new byte[blocks.length];
byte[] highBits = new byte[(blocks.length >> 1) + (blocks.length & 1)];
boolean hasExtendedIDs = encodeBlockIDs(blockIds, lowBits, highBits);
for(int i = 0; i < temp.length; i++)
temp[i] = Block.getStateId(state[i]);
schematicTag.setByteArray("Blocks", lowBits);
schematicTag.setByteArray("Data", metadata);
schematicTag.setIntArray("Data", temp);
if (hasExtendedIDs)
{
schematicTag.setByteArray("AddBlocks", highBits);
}
if (copyTileEntities)
{
if (copyTileEntities) {
//Used when the result of this function will be passed outside this class.
//Avoids exposing the private field to external modifications.
schematicTag.setTag("TileEntities", tileEntities.copy());
}
else
{
} else {
//Used when the result of this function is for internal use.
//It's more efficient not to copy the tags unless it's needed.
schematicTag.setTag("TileEntities", tileEntities);
@ -405,13 +232,11 @@ public class Schematic {
return schematicTag;
}
public void writeToFile(String schematicPath) throws IOException
{
public void writeToFile(String schematicPath) throws IOException {
writeToFile(new File(schematicPath));
}
public void writeToFile(File schematicFile) throws IOException
{
public void writeToFile(File schematicFile) throws IOException {
FileOutputStream outputStream = new FileOutputStream(schematicFile);
CompressedStreamTools.writeCompressed(writeToNBT(false), outputStream);
//writeCompressed() probably closes the stream on its own - call close again just in case.
@ -419,25 +244,19 @@ public class Schematic {
outputStream.close();
}
public boolean applyFilter(SchematicFilter filter)
{
return filter.apply(this, this.blocks, this.metadata);
public boolean applyFilter(SchematicFilter filter) {
return filter.apply(this, this.state);
}
public void copyToWorld(World world, int x, int y, int z, boolean notifyClients, boolean ignoreAir)
{
if (notifyClients)
{
copyToWorld(world, x, y, z, new WorldBlockSetter(false, true, ignoreAir));
}
else
{
copyToWorld(world, x, y, z, new ChunkBlockSetter(ignoreAir));
public void copyToWorld(World world, BlockPos pos, boolean notifyClients, boolean ignoreAir) {
if (notifyClients) {
copyToWorld(world, pos, new WorldBlockSetter(false, true, ignoreAir));
} else {
copyToWorld(world, pos, new ChunkBlockSetter(ignoreAir));
}
}
protected void copyToWorld(World world, int x, int y, int z, IBlockSetter blockSetter)
{
protected void copyToWorld(World world, BlockPos pos, IBlockSetter blockSetter) {
//This isn't implemented as a WorldOperation because it doesn't quite fit the structure of those operations.
//It's not worth the trouble in this case.
int index;
@ -446,13 +265,10 @@ public class Schematic {
//Copy blocks and metadata into the world
index = 0;
for (dy = 0; dy < height; dy++)
{
for (dz = 0; dz < length; dz++)
{
for (dx = 0; dx < width; dx++)
{
blockSetter.setBlock(world, x + dx, y + dy, z + dz, blocks[index], metadata[index]);
for (dy = 0; dy < volume.getY(); dy++) {
for (dz = 0; dz < volume.getZ(); dz++) {
for (dx = 0; dx < volume.getX(); dx++) {
blockSetter.setBlock(world, pos.add(dx, dy, dz), state[index]);
index++;
}
}
@ -464,14 +280,14 @@ public class Schematic {
{
NBTTagCompound tileTag = (NBTTagCompound) tileEntities.getCompoundTagAt(index);
//Rewrite its location to be in world coordinates
dx = tileTag.getInteger("x") + x;
dy = tileTag.getInteger("y") + y;
dz = tileTag.getInteger("z") + z;
dx = tileTag.getInteger("x") + pos.getX();
dy = tileTag.getInteger("y") + pos.getY();
dz = tileTag.getInteger("z") + pos.getZ();
tileTag.setInteger("x", dx);
tileTag.setInteger("y", dy);
tileTag.setInteger("z", dz);
//Load the tile entity and put it in the world
world.setTileEntity(dx, dy, dz, TileEntity.createAndLoadEntity(tileTag));
world.setTileEntity(new BlockPos(dx, dy, dz), TileEntity.createAndLoadEntity(tileTag));
}
}
}

View file

@ -1,58 +1,51 @@
package com.zixiken.dimdoors.schematic;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
public class SchematicFilter {
private String name;
protected SchematicFilter(String name)
{
protected SchematicFilter(String name) {
this.name = name;
}
public String getName()
{
public String getName() {
return name;
}
public boolean apply(Schematic schematic, Block[] blocks, byte[] metadata)
public boolean apply(Schematic schematic, IBlockState[] state)
{
if (!initialize(schematic, blocks, metadata))
if (!initialize(schematic, state))
return false;
for (int index = 0; index < blocks.length; index++)
{
if (applyToBlock(index, blocks, metadata) && terminates())
for (int index = 0; index < state.length; index++) {
if (applyToBlock(index, state) && terminates())
return false;
}
return finish();
}
protected boolean initialize(Schematic schematic, Block[] blocks, byte[] metadata)
{
protected boolean initialize(Schematic schematic, IBlockState[] state) {
return true;
}
protected boolean applyToBlock(int index, Block[] blocks, byte[] metadata)
{
protected boolean applyToBlock(int index, IBlockState[] state) {
return true;
}
protected boolean finish()
{
protected boolean finish() {
return true;
}
protected boolean terminates()
{
protected boolean terminates() {
return true;
}
@Override
public String toString()
{
public String toString() {
return name;
}
}

View file

@ -1,77 +1,59 @@
package com.zixiken.dimdoors.schematic;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockPos;
import net.minecraft.world.World;
public class WorldCopyOperation extends WorldOperation
{
private int originX;
private int originY;
private int originZ;
public class WorldCopyOperation extends WorldOperation {
private BlockPos origin;
private int index;
private Block[] blocks;
private byte[] metadata;
private IBlockState[] state;
private NBTTagList tileEntities;
public WorldCopyOperation()
{
public WorldCopyOperation() {
super("WorldCopyOperation");
blocks = null;
metadata = null;
state = null;
tileEntities = null;
}
@Override
protected boolean initialize(World world, int x, int y, int z, int width, int height, int length)
{
protected boolean initialize(World world, BlockPos pos, BlockPos volume) {
index = 0;
originX = x;
originY = y;
originZ = z;
blocks = new Block[width * height * length];
metadata = new byte[width * height * length];
origin = pos;
state = new IBlockState[volume.getX() * volume.getY() * volume.getZ()];
tileEntities = new NBTTagList();
return true;
}
@Override
protected boolean applyToBlock(World world, int x, int y, int z)
{
blocks[index] = world.getBlock(x, y, z);
metadata[index] = (byte) world.getBlockMetadata(x, y, z);
protected boolean applyToBlock(World world, BlockPos pos) {
state[index] = world.getBlockState(pos);
TileEntity tileEntity = world.getTileEntity(x, y, z);
if (tileEntity != null)
{
TileEntity tileEntity = world.getTileEntity(pos);
if (tileEntity != null) {
//Extract tile entity data
NBTTagCompound tileTag = new NBTTagCompound();
tileEntity.writeToNBT(tileTag);
//Translate the tile entity's position from the world's coordinate system
//to the schematic's coordinate system.
tileTag.setInteger("x", x - originX);
tileTag.setInteger("y", y - originY);
tileTag.setInteger("z", z - originZ);
tileTag.setInteger("x", pos.getX() - origin.getX());
tileTag.setInteger("y", pos.getY() - origin.getY());
tileTag.setInteger("z", pos.getZ() - origin.getZ());
tileEntities.appendTag(tileTag);
}
index++; //This works assuming the loops in WorldOperation are done in YZX order
return true;
}
public Block[] getBlocks()
{
return blocks;
public IBlockState[] getBlockState() {
return state;
}
public byte[] getMetadata()
{
return metadata;
}
public NBTTagList getTileEntities()
{
public NBTTagList getTileEntities() {
return tileEntities;
}
}

View file

@ -1,6 +1,6 @@
package com.zixiken.dimdoors.schematic;
import com.zixiken.dimdoors.Point3D;
import net.minecraft.util.BlockPos;
import net.minecraft.world.World;
public abstract class WorldOperation {
@ -12,48 +12,29 @@ public abstract class WorldOperation {
this.name = name;
}
protected boolean initialize(World world, int x, int y, int z, int width, int height, int length)
{
protected boolean initialize(World world, BlockPos pos, BlockPos volume) {
return true;
}
protected abstract boolean applyToBlock(World world, int x, int y, int z);
protected abstract boolean applyToBlock(World world, BlockPos pos);
protected boolean finish()
{
protected boolean finish() {
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))
public boolean apply(World world, BlockPos pos, BlockPos volume) {
if (!initialize(world, pos, volume))
return false;
int cx, cy, cz;
int limitX = x + width;
int limitY = y + height;
int limitZ = z + length;
BlockPos limit = pos.add(volume);
//The order of these loops is important. Don't change it! It's used to avoid calculating
//indeces in some schematic operations. The proper order is YZX.
for (cy = y; cy < limitY; cy++)
{
for (cz = z; cz < limitZ; cz++)
{
for (cx = x; cx < limitX; cx++)
{
if (!applyToBlock(world, cx, cy, cz))
for (cy = pos.getY(); cy < limit.getY(); cy++) {
for (cz = pos.getZ(); cz < limit.getZ(); cz++) {
for (cx = pos.getX(); cx < limit.getX(); cx++) {
if (!applyToBlock(world, new BlockPos(cx, cy, cz)))
return false;
}
}
@ -63,14 +44,12 @@ public abstract class WorldOperation {
}
public String getName()
{
public String getName() {
return name;
}
@Override
public String toString()
{
public String toString() {
return name;
}
}

View file

@ -5,44 +5,39 @@ import java.io.*;
import com.zixiken.dimdoors.Point3D;
import io.netty.buffer.ByteBuf;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.BlockPos;
public final class Point4D implements Comparable<Point4D>
{
private final int x;
private final int y;
private final int z;
private final BlockPos pos;
private final int dimension;
/**
*
* @param x
* @param y
* @param z
* @param pos
* @param dimension
*/
public Point4D(int x, int y, int z, int dimension)
public Point4D(BlockPos pos, int dimension)
{
this.x = x;
this.y = y;
this.z = z;
this.pos = pos;
this.dimension = dimension;
}
public int getX()
{
return x;
return pos.getX();
}
public int getY()
{
return y;
return pos.getY();
}
public int getZ()
{
return z;
return pos.getZ();
}
public int getDimension()
@ -51,8 +46,7 @@ public final class Point4D implements Comparable<Point4D>
}
@Override
public int hashCode()
{
public int hashCode() {
//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
@ -67,153 +61,87 @@ public final class Point4D implements Comparable<Point4D>
hash = 0;
index = 0;
for (bit = 0; bit < 8; bit++)
{
hash |= ((y >> bit) & 1) << index;
for (bit = 0; bit < 8; bit++) {
hash |= ((pos.getY() >> bit) & 1) << index;
index++;
hash |= ((x >> bit) & 1) << index;
hash |= ((pos.getX() >> bit) & 1) << index;
index++;
hash |= ((z >> bit) & 1) << index;
hash |= ((pos.getZ() >> bit) & 1) << index;
index++;
}
for (; bit < 12; bit++)
{
hash |= ((x >> bit) & 1) << index;
for (; bit < 12; bit++) {
hash |= ((pos.getX() >> bit) & 1) << index;
index++;
hash |= ((z >> bit) & 1) << index;
hash |= ((pos.getZ() >> bit) & 1) << index;
index++;
}
return hash;
}
public long toSeed()
{
//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 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;
final int w = this.dimension;
final int x = this.x;
final int y = this.y;
final int z = this.z;
hash = 0;
index = 48;
for (bit = 0; bit < 8; bit++)
{
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 < 16; bit++)
{
hash |= (long) ((x >> bit) & 1) << index;
index--;
hash |= (long) ((z >> bit) & 1) << index;
index--;
}
return hash;
}
@Override
public boolean equals(Object obj)
{
return equals((Point4D) obj);
}
public Point3D toPoint3D()
{
return new Point3D(this.x, this.y, this.z);
public BlockPos toBlockPos() {
return new BlockPos(this.pos);
}
public int[] toIntArray()
{
return new int[] {x, y, z, dimension};
}
public boolean equals(Point4D other)
{
public boolean equals(Point4D other) {
if (this == other)
return true;
if (other == null)
return false;
return (x == other.x && y == other.y && z == other.z && dimension == other.dimension);
return (pos.equals(other.pos) && dimension == other.dimension);
}
@Override
public int compareTo(Point4D other)
{
int diff = x - other.x;
if (diff != 0)
return diff;
diff = y - other.y;
if (diff != 0)
return diff;
diff = z - other.z;
if (diff != 0)
return diff;
public int compareTo(Point4D other) {
BlockPos diff = pos.subtract(other.pos);
if (diff.getX() != 0)
return diff.getX();
if (diff.getY() != 0)
return diff.getZ();
if (diff.getZ() != 0)
return diff.getZ();
return dimension - other.dimension;
}
@Override
public String toString()
{
return "(" + x + ", " + y + ", " + z + ", " + dimension + ")";
return "(" + pos + ", " + dimension + ")";
}
public static void writeToNBT(Point4D point, NBTTagCompound tag) {
if (point != null) {
tag.setInteger("X", point.x);
tag.setInteger("Y", point.y);
tag.setInteger("Z", point.z);
tag.setInteger("X", point.getX());
tag.setInteger("Y", point.getY());
tag.setInteger("Z", point.getZ());
tag.setInteger("Dimension", point.dimension);
}
}
public static void write(Point4D point, ByteBuf stream) throws IOException
{
public static void write(Point4D point, ByteBuf stream) throws IOException {
stream.writeBoolean(point != null);
if (point != null)
{
stream.writeInt(point.x);
stream.writeInt(point.y);
stream.writeInt(point.z);
if (point != null) {
stream.writeInt(point.getX());
stream.writeInt(point.getY());
stream.writeInt(point.getZ());
stream.writeInt(point.dimension);
}
}
public static Point4D read(ByteBuf stream) throws IOException
{
if (stream.readBoolean())
{
return new Point4D( stream.readInt(), stream.readInt(), stream.readInt(), stream.readInt() );
}
else
{
public static Point4D read(ByteBuf stream) throws IOException {
if (stream.readBoolean()) {
return new Point4D(new BlockPos(stream.readInt(), stream.readInt(), stream.readInt()), stream.readInt() );
} else {
return null;
}
}
public static Point4D readFromNBT(NBTTagCompound tag) {
return new Point4D(tag.getInteger("X"), tag.getInteger("Y"), tag.getInteger("Z"), tag.getInteger("Dimension"));
return new Point4D(new BlockPos(tag.getInteger("X"), tag.getInteger("Y"), tag.getInteger("Z")), tag.getInteger("Dimension"));
}
}

View file

@ -7,6 +7,8 @@ import com.zixiken.dimdoors.core.DimLink;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
@ -44,21 +46,17 @@ public class PocketBuilder
private PocketBuilder() { }
private static boolean buildDungeonPocket(DungeonData dungeon, NewDimData dimension, DimLink link, DungeonSchematic schematic, World world, DDProperties properties)
{
private static boolean buildDungeonPocket(DungeonData dungeon, NewDimData dimension, DimLink link, DungeonSchematic schematic, World world, DDProperties properties) {
//Calculate the destination point
DungeonPackConfig packConfig = dungeon.dungeonType().Owner != null ? dungeon.dungeonType().Owner.getConfig() : null;
Point4D source = link.source();
int orientation = link.orientation();
Point3D destination;
EnumFacing orientation = link.orientation();
BlockPos destination;
if (packConfig != null && packConfig.doDistortDoorCoordinates())
{
if (packConfig != null && packConfig.doDistortDoorCoordinates()) {
destination = calculateNoisyDestination(source, dimension, dungeon, orientation);
}
else
{
destination = new Point3D(source.getX(), source.getY(), source.getZ());
} else {
destination = new BlockPos(source.getX(), source.getY(), source.getZ());
}
destination.setY( yCoordHelper.adjustDestinationY(destination.getY(), world.getHeight(), schematic.getEntranceDoorLocation().getY(), schematic.getHeight()) );
@ -67,7 +65,7 @@ public class PocketBuilder
schematic.copyToWorld(world, destination, orientation, link, random, properties, false);
//Finish up destination initialization
dimension.initializeDungeon(destination.getX(), destination.getY(), destination.getZ(), orientation, link, dungeon);
dimension.initializeDungeon(destination, orientation, link, dungeon);
dimension.setFilled(true);
return true;
@ -160,7 +158,7 @@ public class PocketBuilder
}
private static Point3D calculateNoisyDestination(Point4D source, NewDimData dimension, DungeonData dungeon, int orientation)
private static BlockPos calculateNoisyDestination(Point4D source, NewDimData dimension, DungeonData dungeon, int orientation)
{
int depth = NewDimData.calculatePackDepth(dimension.parent(), dungeon);
int forwardNoise = MathHelper.getRandomIntegerInRange(random, 10 * depth, 130 * depth);
@ -169,9 +167,9 @@ public class PocketBuilder
//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);
BlockPos linkDestination = new BlockPos(forwardNoise, 0, sidewaysNoise);
BlockPos sourcePoint = new BlockPos(source.getX(), source.getY(), source.getZ());
BlockPos zeroPoint = new BlockPos(0, 0, 0);
BlockRotator.transformPoint(linkDestination, zeroPoint, orientation - BlockRotator.EAST_DOOR_METADATA, sourcePoint);
return linkDestination;
}
@ -450,8 +448,8 @@ public class PocketBuilder
}
Point3D center = new Point3D(x - wallThickness + 1 + (size / 2), y - wallThickness - 1 + (size / 2), z);
Point3D door = new Point3D(x, y, z);
BlockPos center = new BlockPos(x - wallThickness + 1 + (size / 2), y - wallThickness - 1 + (size / 2), z);
BlockPos door = new BlockPos(x, y, z);
BlockRotator.transformPoint(center, door, orientation - BlockRotator.EAST_DOOR_METADATA, door);
//Build the outer layer of Eternal Fabric

View file

@ -36,7 +36,7 @@ public abstract class BaseSchematicGateway extends BaseGateway
schematic.applyFilter(gatewayFilter);
schematic.applyImportFilters(properties);
Point3D doorLocation = gatewayFilter.getEntranceDoorLocation();
BlockPos doorLocation = gatewayFilter.getEntranceDoorLocation();
int orientation = gatewayFilter.getEntranceOrientation();
// Build the gateway into the world

View file

@ -1,10 +1,10 @@
package com.zixiken.dimdoors.world.gateways;
import com.zixiken.dimdoors.Point3D;
import com.zixiken.dimdoors.DimDoors;
import com.zixiken.dimdoors.schematic.Schematic;
import com.zixiken.dimdoors.schematic.SchematicFilter;
import net.minecraft.block.Block;
import net.minecraft.util.BlockPos;
public class GatewayBlockFilter extends SchematicFilter {
@ -14,7 +14,7 @@ public class GatewayBlockFilter extends SchematicFilter {
private int entranceOrientation;
private Schematic schematic;
private Point3D entranceDoorLocation;
private BlockPos entranceDoorLocation;
public GatewayBlockFilter()
{
@ -28,7 +28,7 @@ public class GatewayBlockFilter extends SchematicFilter {
return entranceOrientation;
}
public Point3D getEntranceDoorLocation() {
public BlockPos getEntranceDoorLocation() {
return entranceDoorLocation;
}