Move handling of hanging entities into ExtentEntityCopy.

This commit is contained in:
sk89q 2014-07-15 12:09:11 -07:00
parent cf6fa98525
commit 1f709b9cc3
4 changed files with 75 additions and 32 deletions

View File

@ -55,28 +55,9 @@ class ForgeEntity implements Entity {
@Override @Override
public Location getLocation() { public Location getLocation() {
Vector position; Vector position = new Vector(entity.posX, entity.posY, entity.posZ);
float pitch; float yaw = (float) Math.toRadians(entity.rotationYaw);
float yaw; float pitch = (float) Math.toRadians(entity.rotationPitch);
if (entity instanceof EntityHanging) {
EntityHanging hanging = (EntityHanging) entity;
position = new Vector(hanging.xPosition, hanging.yPosition, hanging.zPosition);
Direction direction = MCDirections.fromHanging(hanging.hangingDirection);
if (direction != null) {
yaw = direction.toVector().toYaw();
pitch = direction.toVector().toPitch();
} else {
yaw = (float) Math.toRadians(entity.rotationYaw);
pitch = (float) Math.toRadians(entity.rotationPitch);
}
} else {
position = new Vector(entity.posX, entity.posY, entity.posZ);
yaw = (float) Math.toRadians(entity.rotationYaw);
pitch = (float) Math.toRadians(entity.rotationPitch);
}
return new Location(ForgeAdapter.adapt(entity.worldObj), position, yaw, pitch); return new Location(ForgeAdapter.adapt(entity.worldObj), position, yaw, pitch);
} }

View File

@ -551,16 +551,6 @@ public class ForgeWorld extends AbstractWorld {
createdEntity.setLocationAndAngles(location.getX(), location.getY(), location.getZ(), (float) Math.toDegrees(location.getYaw()), (float) Math.toDegrees(location.getPitch())); createdEntity.setLocationAndAngles(location.getX(), location.getY(), location.getZ(), (float) Math.toDegrees(location.getYaw()), (float) Math.toDegrees(location.getPitch()));
// Special handling for hanging entities
if (createdEntity instanceof EntityHanging) {
EntityHanging hanging = (EntityHanging) createdEntity;
hanging.xPosition = location.getBlockX();
hanging.yPosition = location.getBlockY();
hanging.zPosition = location.getBlockZ();
Direction direction = Direction.findClosest(location.getDirection(), Flag.CARDINAL);
hanging.setDirection(MCDirections.toHanging(direction));
}
world.spawnEntityInWorld(createdEntity); world.spawnEntityInWorld(createdEntity);
return new ForgeEntity(createdEntity); return new ForgeEntity(createdEntity);
} else { } else {

View File

@ -19,13 +19,18 @@
package com.sk89q.worldedit.function.entity; package com.sk89q.worldedit.function.entity;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.CompoundTagBuilder;
import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.EntityFunction; import com.sk89q.worldedit.function.EntityFunction;
import com.sk89q.worldedit.internal.helper.MCDirections;
import com.sk89q.worldedit.math.transform.Transform; import com.sk89q.worldedit.math.transform.Transform;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.Direction.Flag;
import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.Location;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
@ -87,6 +92,10 @@ public class ExtentEntityCopy implements EntityFunction {
Vector newPosition = transform.apply(location.toVector().subtract(from)); Vector newPosition = transform.apply(location.toVector().subtract(from));
Vector newDirection = transform.apply(location.getDirection()).subtract(transform.apply(Vector.ZERO)).normalize(); Vector newDirection = transform.apply(location.getDirection()).subtract(transform.apply(Vector.ZERO)).normalize();
Location newLocation = new Location(destination, newPosition.add(to), newDirection); Location newLocation = new Location(destination, newPosition.add(to), newDirection);
// Some entities store their position data in NBT
state = transformNbtData(state);
boolean success = destination.createEntity(newLocation, state) != null; boolean success = destination.createEntity(newLocation, state) != null;
// Remove // Remove
@ -100,4 +109,49 @@ public class ExtentEntityCopy implements EntityFunction {
} }
} }
/**
* Transform NBT data in the given entity state and return a new instance
* if the NBT data needs to be transformed.
*
* @param state the existing state
* @return a new state or the existing one
*/
private BaseEntity transformNbtData(BaseEntity state) {
CompoundTag tag = state.getNbtData();
if (tag != null) {
// Handle hanging entities (paintings, item frames, etc.)
boolean hasTilePosition = tag.containsKey("TileX") && tag.containsKey("TileY") && tag.containsKey("TileZ");
boolean hasDirection = tag.containsKey("Direction");
boolean hasLegacyDirection = tag.containsKey("Dir");
if (hasTilePosition) {
Vector tilePosition = new Vector(tag.asInt("TileX"), tag.asInt("TileY"), tag.asInt("TileZ"));
Vector newTilePosition = transform.apply(tilePosition.subtract(from)).add(to);
CompoundTagBuilder builder = tag.createBuilder()
.putInt("TileX", newTilePosition.getBlockX())
.putInt("TileY", newTilePosition.getBlockY())
.putInt("TileZ", newTilePosition.getBlockZ());
if (hasDirection || hasLegacyDirection) {
int d = hasDirection ? tag.asInt("Direction") : MCDirections.fromLegacyHanging((byte) tag.asInt("Dir"));
Direction direction = MCDirections.fromHanging(d);
if (direction != null) {
Vector vector = transform.apply(direction.toVector()).subtract(transform.apply(Vector.ZERO)).normalize();
Direction newDirection = Direction.findClosest(vector, Flag.CARDINAL);
builder.putByte("Direction", (byte) MCDirections.toHanging(newDirection));
builder.putByte("Dir", MCDirections.toLegacyHanging(MCDirections.toHanging(newDirection)));
}
}
return new BaseEntity(state.getTypeId(), builder.build());
}
}
return state;
}
} }

View File

@ -59,4 +59,22 @@ public final class MCDirections {
} }
} }
public static int fromLegacyHanging(byte i) {
switch (i) {
case 0: return 2;
case 1: return 1;
case 2: return 0;
default: return 3;
}
}
public static byte toLegacyHanging(int i) {
switch (i) {
case 0: return (byte) 2;
case 1: return (byte) 1;
case 2: return (byte) 0;
default: return (byte) 3;
}
}
} }