fix clipboard rotation

This commit is contained in:
Sen 2025-06-26 18:07:57 +02:00
parent 66d1b9befe
commit 1c6939d61f
Signed by: sen
GPG key ID: 3AC50A6F47D1B722
13 changed files with 252 additions and 1243 deletions

View file

@ -9,22 +9,18 @@ import common.model.Model;
import common.model.ModelProvider; import common.model.ModelProvider;
import common.model.ModelRotation; import common.model.ModelRotation;
import common.properties.Property; import common.properties.Property;
import common.properties.PropertyEnum;
import common.util.BlockPos; import common.util.BlockPos;
import common.util.Facing; import common.util.Facing;
import common.util.Identifyable;
import common.world.State; import common.world.State;
import common.world.World; import common.world.World;
import common.world.AWorldServer; import common.world.AWorldServer;
public class BlockLog extends BlockRotatedPillar public class BlockLog extends BlockRotatedPillar
{ {
public static final PropertyEnum<BlockLog.EnumAxis> LOG_AXIS = PropertyEnum.<BlockLog.EnumAxis>create("axis", BlockLog.EnumAxis.class);
public BlockLog() public BlockLog()
{ {
super(Material.WOOD); super(Material.WOOD);
this.setDefaultState(this.getBaseState().withProperty(LOG_AXIS, BlockLog.EnumAxis.Y)); this.setDefaultState(this.getBaseState().withProperty(AXIS, Facing.Axis.Y));
this.setTab(CheatTab.WOOD); this.setTab(CheatTab.WOOD);
this.setHardness(2.0F); this.setHardness(2.0F);
this.setStepSound(SoundType.WOOD); this.setStepSound(SoundType.WOOD);
@ -33,34 +29,30 @@ public class BlockLog extends BlockRotatedPillar
public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state) public void onBlockRemoved(AWorldServer worldIn, BlockPos pos, State state)
{ {
int i = 4; int r = 4;
int j = i + 1; int l = r + 1;
if (worldIn.isAreaLoaded(pos.add(-j, -j, -j), pos.add(j, j, j))) if (worldIn.isAreaLoaded(pos.add(-l, -l, -l), pos.add(l, l, l)))
{ {
for (BlockPos blockpos : BlockPos.getAllInBox(pos.add(-i, -i, -i), pos.add(i, i, i))) for (BlockPos bpos : BlockPos.getAllInBox(pos.add(-r, -r, -r), pos.add(r, r, r)))
{ {
State iblockstate = worldIn.getState(blockpos); State blk = worldIn.getState(bpos);
if (iblockstate.getBlock().getMaterial() == Material.LEAVES && !((Boolean)iblockstate.getValue(BlockLeaves.DECAY)).booleanValue()) if (blk.getBlock().getMaterial() == Material.LEAVES && !((Boolean)blk.getValue(BlockLeaves.DECAY)).booleanValue())
{ {
worldIn.setState(blockpos, iblockstate.withProperty(BlockLeaves.DECAY, Boolean.valueOf(true)), 4); worldIn.setState(bpos, blk.withProperty(BlockLeaves.DECAY, Boolean.valueOf(true)), 4);
} }
} }
} }
} }
/**
* Called by ItemBlocks just before a block is actually set in the world, to allow for adjustments to the
* IBlockstate
*/
public State onBlockPlaced(World worldIn, BlockPos pos, Facing facing, float hitX, float hitY, float hitZ, EntityLiving placer) public State onBlockPlaced(World worldIn, BlockPos pos, Facing facing, float hitX, float hitY, float hitZ, EntityLiving placer)
{ {
return super.onBlockPlaced(worldIn, pos, facing, hitX, hitY, hitZ, placer).withProperty(LOG_AXIS, BlockLog.EnumAxis.fromFacingAxis(facing.getAxis())); return super.onBlockPlaced(worldIn, pos, facing, hitX, hitY, hitZ, placer).withProperty(AXIS, facing.getAxis());
} }
public Model getModel(ModelProvider provider, String name, State state) { public Model getModel(ModelProvider provider, String name, State state) {
switch(state.getValue(LOG_AXIS)) { switch(state.getValue(AXIS)) {
case X: case X:
return provider.getModel(name + "_bark").add().d().rot(180).u() return provider.getModel(name + "_bark").add().d().rot(180).u()
.n(name + "_top").rot(180).s(name + "_top").w().rot(270) .n(name + "_top").rot(180).s(name + "_top").w().rot(270)
@ -72,114 +64,51 @@ public class BlockLog extends BlockRotatedPillar
return provider.getModel(name + "_bark").add().d().rot(180).u() return provider.getModel(name + "_bark").add().d().rot(180).u()
.n(name + "_top").rot(180).s(name + "_top").w().rot(270) .n(name + "_top").rot(180).s(name + "_top").w().rot(270)
.e().rot(90); .e().rot(90);
case NONE:
return provider.getModel(name + "_bark").add().all();
} }
} }
public State getStateFromMeta(int meta) public State getStateFromMeta(int meta)
{ {
State iblockstate = this.getState(); State state = this.getState();
switch (meta & 3) switch (meta & 3)
{ {
default: default:
iblockstate = iblockstate.withProperty(LOG_AXIS, BlockLog.EnumAxis.Y); state = state.withProperty(AXIS, Facing.Axis.Y);
break; break;
case 1: case 1:
iblockstate = iblockstate.withProperty(LOG_AXIS, BlockLog.EnumAxis.X); state = state.withProperty(AXIS, Facing.Axis.X);
break; break;
case 2: case 2:
iblockstate = iblockstate.withProperty(LOG_AXIS, BlockLog.EnumAxis.Z); state = state.withProperty(AXIS, Facing.Axis.Z);
break; break;
case 3:
iblockstate = iblockstate.withProperty(LOG_AXIS, BlockLog.EnumAxis.NONE);
} }
return iblockstate; return state;
} }
/**
* Convert the BlockState into the correct metadata value
*/
public int getMetaFromState(State state) public int getMetaFromState(State state)
{ {
int i = 0; int meta = 0;
switch ((BlockLog.EnumAxis)state.getValue(LOG_AXIS)) switch ((Facing.Axis)state.getValue(AXIS))
{ {
case X: case X:
i = 1; meta = 1;
break; break;
case Z: case Z:
i = 2; meta = 2;
break; break;
case NONE:
i = 3;
} }
return i; return meta;
} }
protected Property[] getProperties() protected Property[] getProperties()
{ {
return new Property[] {LOG_AXIS}; return new Property[] {AXIS};
}
public static enum EnumAxis implements Identifyable
{
X("x", Facing.Axis.X),
Y("y", Facing.Axis.Y),
Z("z", Facing.Axis.Z),
NONE("none", null);
private final String name;
private final Facing.Axis axis;
private EnumAxis(String name, Facing.Axis axis)
{
this.name = name;
this.axis = axis;
}
public String toString()
{
return this.name;
}
public static BlockLog.EnumAxis fromFacingAxis(Facing.Axis axis)
{
switch (axis)
{
case X:
return X;
case Y:
return Y;
case Z:
return Z;
default:
return NONE;
}
}
public String getName()
{
return this.name;
}
public Facing.Axis getAxis()
{
return this.axis;
}
} }
} }

View file

@ -16,6 +16,7 @@ import common.properties.PropertyBool;
import common.properties.PropertyEnum; import common.properties.PropertyEnum;
import common.util.BlockPos; import common.util.BlockPos;
import common.util.BoundingBox; import common.util.BoundingBox;
import common.util.DirectionVec;
import common.util.Facing; import common.util.Facing;
import common.util.Identifyable; import common.util.Identifyable;
import common.world.IWorldAccess; import common.world.IWorldAccess;
@ -322,7 +323,7 @@ public class BlockLever extends Block
return new ItemBlock(this, "lever", false); return new ItemBlock(this, "lever", false);
} }
public static enum EnumOrientation implements Identifyable public static enum EnumOrientation implements Identifyable, DirectionVec<EnumOrientation>
{ {
DOWN_X(0, "down_x", Facing.DOWN), DOWN_X(0, "down_x", Facing.DOWN),
EAST(1, "east", Facing.EAST), EAST(1, "east", Facing.EAST),
@ -422,6 +423,18 @@ public class BlockLever extends Block
return this.name; return this.name;
} }
public Facing getVector() {
return this == DOWN_Z || this == UP_Z ? Facing.SOUTH : (this == DOWN_X || this == UP_X ? Facing.EAST : this.facing);
}
public boolean isAxis() {
return this.facing.getAxis().isVertical();
}
public boolean canApply(EnumOrientation dir) {
return this.facing.getAxis().isVertical() == dir.facing.getAxis().isVertical();
}
static { static {
for (BlockLever.EnumOrientation blocklever$enumorientation : values()) for (BlockLever.EnumOrientation blocklever$enumorientation : values())
{ {

View file

@ -14,6 +14,7 @@ import common.model.ModelRotation;
import common.properties.Property; import common.properties.Property;
import common.util.BlockPos; import common.util.BlockPos;
import common.util.BoundingBox; import common.util.BoundingBox;
import common.util.DirectionVec;
import common.util.Facing; import common.util.Facing;
import common.util.HitPosition; import common.util.HitPosition;
import common.util.Identifyable; import common.util.Identifyable;
@ -230,29 +231,35 @@ public abstract class BlockRailBase extends Block
public abstract Property<BlockRailBase.EnumRailDirection> getShapeProperty(); public abstract Property<BlockRailBase.EnumRailDirection> getShapeProperty();
public static enum EnumRailDirection implements Identifyable private static enum BaseShape {
STRAIGHT, ASCENDING, TURNED;
}
public static enum EnumRailDirection implements Identifyable, DirectionVec<EnumRailDirection>
{ {
NORTH_SOUTH(0, "north_south", Facing.SOUTH), NORTH_SOUTH(0, "north_south", Facing.SOUTH, BaseShape.STRAIGHT),
EAST_WEST(1, "east_west", Facing.EAST), EAST_WEST(1, "east_west", Facing.EAST, BaseShape.STRAIGHT),
ASCENDING_EAST(2, "ascending_east", Facing.EAST), ASCENDING_EAST(2, "ascending_east", Facing.EAST, BaseShape.ASCENDING),
ASCENDING_WEST(3, "ascending_west", Facing.WEST), ASCENDING_WEST(3, "ascending_west", Facing.WEST, BaseShape.ASCENDING),
ASCENDING_NORTH(4, "ascending_north", Facing.NORTH), ASCENDING_NORTH(4, "ascending_north", Facing.NORTH, BaseShape.ASCENDING),
ASCENDING_SOUTH(5, "ascending_south", Facing.DOWN), ASCENDING_SOUTH(5, "ascending_south", Facing.DOWN, BaseShape.ASCENDING),
SOUTH_EAST(6, "south_east", Facing.EAST), SOUTH_EAST(6, "south_east", Facing.EAST, BaseShape.TURNED),
SOUTH_WEST(7, "south_west", Facing.SOUTH), SOUTH_WEST(7, "south_west", Facing.SOUTH, BaseShape.TURNED),
NORTH_WEST(8, "north_west", Facing.NORTH), NORTH_WEST(8, "north_west", Facing.NORTH, BaseShape.TURNED),
NORTH_EAST(9, "north_east", Facing.WEST); NORTH_EAST(9, "north_east", Facing.WEST, BaseShape.TURNED);
private static final BlockRailBase.EnumRailDirection[] META_LOOKUP = new BlockRailBase.EnumRailDirection[values().length]; private static final BlockRailBase.EnumRailDirection[] META_LOOKUP = new BlockRailBase.EnumRailDirection[values().length];
private final int meta; private final int meta;
private final String name; private final String name;
private final Facing facing; private final Facing facing;
private final BaseShape shape;
private EnumRailDirection(int meta, String name, Facing facing) private EnumRailDirection(int meta, String name, Facing facing, BaseShape shape)
{ {
this.meta = meta; this.meta = meta;
this.name = name; this.name = name;
this.facing = facing; this.facing = facing;
this.shape = shape;
} }
public int getMetadata() public int getMetadata()
@ -290,6 +297,18 @@ public abstract class BlockRailBase extends Block
return this.facing; return this.facing;
} }
public Facing getVector() {
return this.facing;
}
public boolean isAxis() {
return false;
}
public boolean canApply(EnumRailDirection dir) {
return this.shape == dir.shape;
}
static { static {
for (BlockRailBase.EnumRailDirection blockrailbase$enumraildirection : values()) for (BlockRailBase.EnumRailDirection blockrailbase$enumraildirection : values())
{ {

View file

@ -0,0 +1,9 @@
package common.util;
public interface DirectionVec<T> {
public Facing getVector();
public boolean isAxis();
default boolean canApply(T other) {
return true;
}
}

View file

@ -8,7 +8,7 @@ import common.collect.Iterators;
import common.collect.Maps; import common.collect.Maps;
import common.rng.Random; import common.rng.Random;
public enum Facing implements Identifyable public enum Facing implements Identifyable, DirectionVec<Facing>
{ {
DOWN(0, 2, 1, -1, "down", Facing.AxisDirection.NEGATIVE, Facing.Axis.Y, new Vec3i(0, -1, 0)), DOWN(0, 2, 1, -1, "down", Facing.AxisDirection.NEGATIVE, Facing.Axis.Y, new Vec3i(0, -1, 0)),
UP(1, 3, 0, -1, "up", Facing.AxisDirection.POSITIVE, Facing.Axis.Y, new Vec3i(0, 1, 0)), UP(1, 3, 0, -1, "up", Facing.AxisDirection.POSITIVE, Facing.Axis.Y, new Vec3i(0, 1, 0)),
@ -354,6 +354,14 @@ public enum Facing implements Identifyable
return this.directionVec; return this.directionVec;
} }
public Facing getVector() {
return this.axis.isVertical() ? null : this;
}
public boolean isAxis() {
return false;
}
static { static {
for (Facing enumfacing : values()) for (Facing enumfacing : values())
{ {
@ -368,7 +376,7 @@ public enum Facing implements Identifyable
} }
} }
public static enum Axis implements Predicate<Facing>, Identifyable { public static enum Axis implements Predicate<Facing>, Identifyable, DirectionVec<Axis> {
X("x", Facing.Plane.HORIZONTAL), X("x", Facing.Plane.HORIZONTAL),
Y("y", Facing.Plane.VERTICAL), Y("y", Facing.Plane.VERTICAL),
Z("z", Facing.Plane.HORIZONTAL); Z("z", Facing.Plane.HORIZONTAL);
@ -423,6 +431,14 @@ public enum Facing implements Identifyable
return this.name; return this.name;
} }
public Facing getVector() {
return this == Y ? null : (this == X ? EAST : SOUTH);
}
public boolean isAxis() {
return true;
}
static { static {
for (Facing.Axis enumfacing$axis : values()) for (Facing.Axis enumfacing$axis : values())
{ {

View file

@ -1,111 +1,63 @@
package server.clipboard; package server.clipboard;
public class BlockTransform { public class BlockTransform {
private double m00, m01, m02, m03; private final int xx;
private double m10, m11, m12, m13; private final int zx;
private double m20, m21, m22, m23; private final int xz;
private final int zz;
public BlockTransform() { public BlockTransform(int theta, boolean x, boolean z) {
m00 = m11 = m22 = 1; int cot = dCos(theta);
m01 = m02 = m03 = 0; int sit = dSin(theta);
m10 = m12 = m13 = 0; this.xx = cot * (x ? -1 : 1);
m20 = m21 = m23 = 0; this.zx = sit * (z ? -1 : 1);
this.xz = -sit * (x ? -1 : 1);
this.zz = cot * (z ? -1 : 1);
} }
private BlockTransform(double xx, double yx, double zx, double tx, public int applyX(int x, int z) {
double xy, double yy, double zy, double ty, double xz, double yz, return x * this.xx + z * this.zx;
double zz, double tz) {
m00 = xx;
m01 = yx;
m02 = zx;
m03 = tx;
m10 = xy;
m11 = yy;
m12 = zy;
m13 = ty;
m20 = xz;
m21 = yz;
m22 = zz;
m23 = tz;
} }
private BlockTransform concatenate(BlockTransform that) { public int applyZ(int x, int z) {
double n00 = m00 * that.m00 + m01 * that.m10 + m02 * that.m20; return x * this.xz + z * this.zz;
double n01 = m00 * that.m01 + m01 * that.m11 + m02 * that.m21;
double n02 = m00 * that.m02 + m01 * that.m12 + m02 * that.m22;
double n03 = m00 * that.m03 + m01 * that.m13 + m02 * that.m23 + m03;
double n10 = m10 * that.m00 + m11 * that.m10 + m12 * that.m20;
double n11 = m10 * that.m01 + m11 * that.m11 + m12 * that.m21;
double n12 = m10 * that.m02 + m11 * that.m12 + m12 * that.m22;
double n13 = m10 * that.m03 + m11 * that.m13 + m12 * that.m23 + m13;
double n20 = m20 * that.m00 + m21 * that.m10 + m22 * that.m20;
double n21 = m20 * that.m01 + m21 * that.m11 + m22 * that.m21;
double n22 = m20 * that.m02 + m21 * that.m12 + m22 * that.m22;
double n23 = m20 * that.m03 + m21 * that.m13 + m22 * that.m23 + m23;
return new BlockTransform(
n00, n01, n02, n03,
n10, n11, n12, n13,
n20, n21, n22, n23);
} }
public BlockTransform rotateY(int theta) { private static int dSin(int degrees) {
double cot = dCos(theta); if(degrees % 90 == 0) {
double sit = dSin(theta);
return concatenate(
new BlockTransform(
cot, 0, sit, 0,
0, 1, 0, 0,
-sit, 0, cot, 0));
}
public BlockTransform scale(Vector vec) {
return concatenate(new BlockTransform(vec.getX(), 0, 0, 0, 0, vec.getY(), 0, 0, 0, 0, vec.getZ(), 0));
}
public Vector apply(Vector vector) {
return new Vector(
vector.getX() * m00 + vector.getY() * m01 + vector.getZ() * m02 + m03,
vector.getX() * m10 + vector.getY() * m11 + vector.getZ() * m12 + m13,
vector.getX() * m20 + vector.getY() * m21 + vector.getZ() * m22 + m23);
}
private static double dSin(int degrees) {
if (degrees % 90 == 0) {
degrees %= 360; degrees %= 360;
if (degrees < 0) { if(degrees < 0)
degrees += 360; degrees += 360;
} switch(degrees) {
switch (degrees) {
case 0: case 0:
return 0.0; return 0;
case 90: case 90:
return 1.0; return 1;
case 180: case 180:
return 0.0; return 0;
case 270: case 270:
return -1.0; return -1;
} }
} }
return Math.cos(Math.toRadians(degrees)); throw new IllegalArgumentException();
} }
private static double dCos(int degrees) { private static int dCos(int degrees) {
if (degrees % 90 == 0) { if(degrees % 90 == 0) {
degrees %= 360; degrees %= 360;
if (degrees < 0) { if(degrees < 0)
degrees += 360; degrees += 360;
} switch(degrees) {
switch (degrees) {
case 0: case 0:
return 1.0; return 1;
case 90: case 90:
return 0.0; return 0;
case 180: case 180:
return -1.0; return -1;
case 270: case 270:
return 0.0; return 0;
} }
} }
return Math.cos(Math.toRadians(degrees)); throw new IllegalArgumentException();
} }
} }

View file

@ -1,43 +0,0 @@
package server.clipboard;
import java.util.function.Predicate;
public class Rotation {
private final RotationValue[] values;
private final boolean[] dirFlags = new boolean[16];
public Rotation(RotationValue[] values, Predicate<Integer> predicate) {
this.values = values;
for(int z = 0; z < 16; z++) {
if(predicate != null && !predicate.test(z)) {
this.dirFlags[z] = false;
continue;
}
boolean flag = false;
for(RotationValue value : values) {
if(value.getDirection() != null) {
flag = true;
break;
}
}
this.dirFlags[z] = flag;
}
}
public RotationValue[] getValues() {
return this.values;
}
public RotationValue getValue(int meta) {
for (RotationValue value : this.values) {
if (value.isSet(meta)) {
return value;
}
}
return null;
}
public boolean hasDirection(int meta) {
return this.dirFlags[meta & 15];
}
}

View file

@ -3,121 +3,41 @@ package server.clipboard;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Predicate;
import common.block.Block; import common.block.Block;
import common.block.BlockRotatedPillar;
import common.block.artificial.BlockDoor;
import common.block.artificial.BlockPortal;
import common.block.foliage.BlockLog;
import common.block.tech.BlockLever;
import common.block.tech.BlockRail;
import common.block.tech.BlockRailBase;
import common.block.tech.BlockRailDetector;
import common.block.tech.BlockRailPowered;
import common.collect.Lists; import common.collect.Lists;
import common.collect.Maps;
import common.properties.Property; import common.properties.Property;
import common.util.DirectionVec;
import common.util.Facing; import common.util.Facing;
import common.util.Vec3i; import common.util.Vec3i;
import common.world.State;
public abstract class RotationRegistry { public abstract class RotationRegistry {
private static final Map<Block, Rotation> MAP = new HashMap<Block, Rotation>(); private static final Map<Block, RotationValue[]> MAP = new HashMap<Block, RotationValue[]>();
public static void register() { public static void register() {
List<RotationValue> values = Lists.newArrayList();
for(Block block : common.init.BlockRegistry.REGISTRY) { for(Block block : common.init.BlockRegistry.REGISTRY) {
for(Property<?> prop : block.getPropertyMap()) { for(Property<?> prop : block.getPropertyMap()) {
Predicate<Integer> predicate = null; for(Comparable v : prop.getStates()) {
if(prop == BlockDoor.FACING) { if(!(v instanceof DirectionVec vec))
predicate = new Predicate<Integer>() { continue;
@Override Facing dir = vec.getVector();
public boolean test(Integer meta) { if(dir != null) {
return (meta & 8) == 0; Vec3i dv = dir.getDirectionVec();
values.add(new RotationValue(prop, v, vec, dv.getX(), dv.getZ()));
if(vec.isAxis())
values.add(new RotationValue(prop, v, vec, -dv.getX(), -dv.getZ()));
} }
};
} }
List<RotationValue> values = Lists.newArrayList(); if(values.size() > 1)
Map<Object, Byte> map = Maps.newHashMap(); MAP.put(block, values.toArray(new RotationValue[values.size()]));
for(int z = 15; z >= 0; z--) { if(!values.isEmpty())
State st = block.getStateFromMeta(z); break;
if(st.getProperties().containsKey(prop)) { }
map.put(st.getProperties().get(prop), (byte)z); values.clear();
} }
} }
byte mask = 0; public static RotationValue[] getRotation(Block block) {
for(Object v : prop.getStates()) {
if(map.get(v) == null) {
continue;
}
mask |= map.get(v);
}
if(mask == 0) {
continue;
}
for(Object v : prop.getStates()) {
if(map.get(v) == null) {
continue;
}
Vec3i dv = null;
Facing.Axis axis = null;
if(v instanceof Facing face) {
dv = face.getDirectionVec();
}
else if(prop == BlockRotatedPillar.AXIS) {
axis = ((Facing.Axis)v);
}
else if(prop == BlockPortal.AXIS) {
axis = ((Facing.Axis)v);
}
else if(prop == BlockLog.LOG_AXIS) {
axis = ((BlockLog.EnumAxis)v).getAxis();
}
else if(prop == BlockLever.FACING) {
dv = ((BlockLever.EnumOrientation)v).getFacing().getDirectionVec();
}
else if(prop == BlockRail.SHAPE || prop == BlockRailDetector.SHAPE || prop == BlockRailPowered.SHAPE) {
dv = ((BlockRailBase.EnumRailDirection)v).getFacing().getDirectionVec();
}
// else if(prop == BlockDoor.HINGE) {
// dv = ((BlockDoor.EnumHingePosition)v) == BlockDoor.EnumHingePosition.LEFT ? new Vec3i(-1, 0, 0) : new Vec3i(1, 0, 0);
// }
if(axis != null) {
switch(axis) {
case X:
dv = new Vec3i(1, 0, 0);
break;
case Y:
dv = new Vec3i(0, 1, 0);
break;
case Z:
dv = new Vec3i(0, 0, 1);
break;
}
}
if(dv == null) {
continue;
}
values.add(new RotationValue(mask, (byte)(map.get(v) & mask), new Vector(dv.getX(), dv.getY(), dv.getZ())));
if(axis != null) {
values.add(new RotationValue(mask, (byte)(map.get(v) & mask), new Vector(-dv.getX(), -dv.getY(), -dv.getZ())));
}
}
if(!values.isEmpty()) {
Rotation state = new Rotation(values.toArray(new RotationValue[values.size()]), predicate);
// Log.CONFIG.debug("Block " + game.init.BlockRegistry.getNameFromBlock(block) + "/" + legacyId + " mask = " + String.format("0x%x", mask));
// for(RotationValue value : values) {
// Log.CONFIG.debug(" meta " + value.data + " -> " + value.direction.toString());
// }
MAP.put(block, state);
}
}
}
}
public static Rotation getRotation(Block block) {
return MAP.get(block); return MAP.get(block);
} }
} }

View file

@ -1,25 +1,41 @@
package server.clipboard; package server.clipboard;
public class RotationValue { import common.properties.Property;
public final byte mask; import common.util.DirectionVec;
public final byte data; import common.world.State;
public final Vector direction;
public RotationValue(byte mask, byte data, Vector direction) { public class RotationValue<T extends Comparable<T>> {
this.mask = mask; private final Property<T> property;
this.data = data; private final T value;
this.direction = direction; private final DirectionVec vec;
private final int dirX;
private final int dirZ;
public RotationValue(Property property, T value, DirectionVec vec, int x, int z) {
this.property = property;
this.value = value;
this.vec = vec;
this.dirX = x;
this.dirZ = z;
} }
public boolean isSet(int meta) { public boolean isSet(State state) {
return (meta & mask) == data; return state.getValue(this.property) == this.value;
} }
public int set(int meta) { public State set(State state) {
return ((meta & ~mask) | data); return state.withProperty(this.property, this.value);
} }
public Vector getDirection() { public boolean canTransform(RotationValue other) {
return direction; return this.vec.canApply(other.vec);
}
public int getX() {
return this.dirX;
}
public int getZ() {
return this.dirZ;
} }
} }

View file

@ -1,802 +0,0 @@
package server.clipboard;
public class Vector implements Comparable<Vector> {
public static final Vector ZERO = new Vector(0, 0, 0);
protected final double x, y, z;
public Vector(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
// /**
// * Construct an instance.
// *
// * @param x the X coordinate
// * @param y the Y coordinate
// * @param z the Z coordinate
// */
// public Vector(int x, int y, int z) {
// this.x = (double) x;
// this.y = (double) y;
// this.z = (double) z;
// }
// /**
// * Construct an instance.
// *
// * @param x the X coordinate
// * @param y the Y coordinate
// * @param z the Z coordinate
// */
// public Vector(float x, float y, float z) {
// this.x = (double) x;
// this.y = (double) y;
// this.z = (double) z;
// }
// /**
// * Copy another vector.
// *
// * @param other another vector to make a copy of
// */
// public Vector(Vector other) {
// this.x = other.x;
// this.y = other.y;
// this.z = other.z;
// }
/**
* Construct a new instance with X, Y, and Z coordinates set to 0.
*
* <p>One can also refer to a static {@link #ZERO}.</p>
*/
public Vector() {
this.x = 0;
this.y = 0;
this.z = 0;
}
/**
* Get the X coordinate.
*
* @return the x coordinate
*/
public double getX() {
return x;
}
/**
* Get the X coordinate rounded.
*
* @return the x coordinate
*/
public int getBlockX() {
return (int) Math.round(x);
}
// /**
// * Set the X coordinate.
// *
// * @param x the new X
// * @return a new vector
// */
// public Vector setX(double x) {
// return new Vector(x, y, z);
// }
// /**
// * Set the X coordinate.
// *
// * @param x the X coordinate
// * @return new vector
// */
// public Vector setX(int x) {
// return new Vector(x, y, z);
// }
/**
* Get the Y coordinate.
*
* @return the y coordinate
*/
public double getY() {
return y;
}
/**
* Get the Y coordinate rounded.
*
* @return the y coordinate
*/
public int getBlockY() {
return (int) Math.round(y);
}
// /**
// * Set the Y coordinate.
// *
// * @param y the new Y
// * @return a new vector
// */
// public Vector setY(double y) {
// return new Vector(x, y, z);
// }
// /**
// * Set the Y coordinate.
// *
// * @param y the new Y
// * @return a new vector
// */
// public Vector setY(int y) {
// return new Vector(x, y, z);
// }
/**
* Get the Z coordinate.
*
* @return the z coordinate
*/
public double getZ() {
return z;
}
/**
* Get the Z coordinate rounded.
*
* @return the z coordinate
*/
public int getBlockZ() {
return (int) Math.round(z);
}
// /**
// * Set the Z coordinate.
// *
// * @param z the new Z
// * @return a new vector
// */
// public Vector setZ(double z) {
// return new Vector(x, y, z);
// }
// /**
// * Set the Z coordinate.
// *
// * @param z the new Z
// * @return a new vector
// */
// public Vector setZ(int z) {
// return new Vector(x, y, z);
// }
// /**
// * Add another vector to this vector and return the result as a new vector.
// *
// * @param other the other vector
// * @return a new vector
// */
// public Vector add(Vector other) {
// return new Vector(x + other.x, y + other.y, z + other.z);
// }
// /**
// * Add another vector to this vector and return the result as a new vector.
// *
// * @param x the value to add
// * @param y the value to add
// * @param z the value to add
// * @return a new vector
// */
// public Vector add(double x, double y, double z) {
// return new Vector(this.x + x, this.y + y, this.z + z);
// }
// /**
// * Add another vector to this vector and return the result as a new vector.
// *
// * @param x the value to add
// * @param y the value to add
// * @param z the value to add
// * @return a new vector
// */
// public Vector add(int x, int y, int z) {
// return new Vector(this.x + x, this.y + y, this.z + z);
// }
// /**
// * Add a list of vectors to this vector and return the
// * result as a new vector.
// *
// * @param others an array of vectors
// * @return a new vector
// */
// public Vector add(Vector... others) {
// double newX = x, newY = y, newZ = z;
//
// for (Vector other : others) {
// newX += other.x;
// newY += other.y;
// newZ += other.z;
// }
//
// return new Vector(newX, newY, newZ);
// }
/**
* Subtract another vector from this vector and return the result
* as a new vector.
*
* @param other the other vector
* @return a new vector
*/
public Vector subtract(Vector other) {
return new Vector(x - other.x, y - other.y, z - other.z);
}
// /**
// * Subtract another vector from this vector and return the result
// * as a new vector.
// *
// * @param x the value to subtract
// * @param y the value to subtract
// * @param z the value to subtract
// * @return a new vector
// */
// public Vector subtract(double x, double y, double z) {
// return new Vector(this.x - x, this.y - y, this.z - z);
// }
// /**
// * Subtract another vector from this vector and return the result
// * as a new vector.
// *
// * @param x the value to subtract
// * @param y the value to subtract
// * @param z the value to subtract
// * @return a new vector
// */
// public Vector subtract(int x, int y, int z) {
// return new Vector(this.x - x, this.y - y, this.z - z);
// }
//
// /**
// * Subtract a list of vectors from this vector and return the result
// * as a new vector.
// *
// * @param others an array of vectors
// * @return a new vector
// */
// public Vector subtract(Vector... others) {
// double newX = x, newY = y, newZ = z;
//
// for (Vector other : others) {
// newX -= other.x;
// newY -= other.y;
// newZ -= other.z;
// }
//
// return new Vector(newX, newY, newZ);
// }
// /**
// * Multiply this vector by another vector on each component.
// *
// * @param other the other vector
// * @return a new vector
// */
// public Vector multiply(Vector other) {
// return new Vector(x * other.x, y * other.y, z * other.z);
// }
// /**
// * Multiply this vector by another vector on each component.
// *
// * @param x the value to multiply
// * @param y the value to multiply
// * @param z the value to multiply
// * @return a new vector
// */
// public Vector multiply(double x, double y, double z) {
// return new Vector(this.x * x, this.y * y, this.z * z);
// }
//
// /**
// * Multiply this vector by another vector on each component.
// *
// * @param x the value to multiply
// * @param y the value to multiply
// * @param z the value to multiply
// * @return a new vector
// */
// public Vector multiply(int x, int y, int z) {
// return new Vector(this.x * x, this.y * y, this.z * z);
// }
//
// /**
// * Multiply this vector by zero or more vectors on each component.
// *
// * @param others an array of vectors
// * @return a new vector
// */
// public Vector multiply(Vector... others) {
// double newX = x, newY = y, newZ = z;
//
// for (Vector other : others) {
// newX *= other.x;
// newY *= other.y;
// newZ *= other.z;
// }
//
// return new Vector(newX, newY, newZ);
// }
// /**
// * Perform scalar multiplication and return a new vector.
// *
// * @param n the value to multiply
// * @return a new vector
// */
// public Vector multiply(double n) {
// return new Vector(this.x * n, this.y * n, this.z * n);
// }
// /**
// * Perform scalar multiplication and return a new vector.
// *
// * @param n the value to multiply
// * @return a new vector
// */
// public Vector multiply(float n) {
// return new Vector(this.x * n, this.y * n, this.z * n);
// }
// /**
// * Perform scalar multiplication and return a new vector.
// *
// * @param n the value to multiply
// * @return a new vector
// */
// public Vector multiply(int n) {
// return new Vector(this.x * n, this.y * n, this.z * n);
// }
//
// /**
// * Divide this vector by another vector on each component.
// *
// * @param other the other vector
// * @return a new vector
// */
// public Vector divide(Vector other) {
// return new Vector(x / other.x, y / other.y, z / other.z);
// }
// /**
// * Divide this vector by another vector on each component.
// *
// * @param x the value to divide by
// * @param y the value to divide by
// * @param z the value to divide by
// * @return a new vector
// */
// public Vector divide(double x, double y, double z) {
// return new Vector(this.x / x, this.y / y, this.z / z);
// }
//
// /**
// * Divide this vector by another vector on each component.
// *
// * @param x the value to divide by
// * @param y the value to divide by
// * @param z the value to divide by
// * @return a new vector
// */
// public Vector divide(int x, int y, int z) {
// return new Vector(this.x / x, this.y / y, this.z / z);
// }
// /**
// * Perform scalar division and return a new vector.
// *
// * @param n the value to divide by
// * @return a new vector
// */
// public Vector divide(int n) {
// return new Vector(x / n, y / n, z / n);
// }
/**
* Perform scalar division and return a new vector.
*
* @param n the value to divide by
* @return a new vector
*/
public Vector divide(double n) {
return new Vector(x / n, y / n, z / n);
}
// /**
// * Perform scalar division and return a new vector.
// *
// * @param n the value to divide by
// * @return a new vector
// */
// public Vector divide(float n) {
// return new Vector(x / n, y / n, z / n);
// }
/**
* Get the length of the vector.
*
* @return length
*/
public double length() {
return Math.sqrt(x * x + y * y + z * z);
}
// /**
// * Get the length, squared, of the vector.
// *
// * @return length, squared
// */
// public double lengthSq() {
// return x * x + y * y + z * z;
// }
// /**
// * Get the distance between this vector and another vector.
// *
// * @param other the other vector
// * @return distance
// */
// public double distance(Vector other) {
// return Math.sqrt(Math.pow(other.x - x, 2) +
// Math.pow(other.y - y, 2) +
// Math.pow(other.z - z, 2));
// }
// /**
// * Get the distance between this vector and another vector, squared.
// *
// * @param other the other vector
// * @return distance
// */
// public double distanceSq(Vector other) {
// return Math.pow(other.x - x, 2) +
// Math.pow(other.y - y, 2) +
// Math.pow(other.z - z, 2);
// }
/**
* Get the normalized vector, which is the vector divided by its
* length, as a new vector.
*
* @return a new vector
*/
public Vector normalize() {
return divide(length());
}
/**
* Gets the dot product of this and another vector.
*
* @param other the other vector
* @return the dot product of this and the other vector
*/
public double dot(Vector other) {
return x * other.x + y * other.y + z * other.z;
}
// /**
// * Gets the cross product of this and another vector.
// *
// * @param other the other vector
// * @return the cross product of this and the other vector
// */
// public Vector cross(Vector other) {
// return new Vector(
// y * other.z - z * other.y,
// z * other.x - x * other.z,
// x * other.y - y * other.x
// );
// }
//
// /**
// * Checks to see if a vector is contained with another.
// *
// * @param min the minimum point (X, Y, and Z are the lowest)
// * @param max the maximum point (X, Y, and Z are the lowest)
// * @return true if the vector is contained
// */
// public boolean containedWithin(Vector min, Vector max) {
// return x >= min.x && x <= max.x && y >= min.y && y <= max.y && z >= min.z && z <= max.z;
// }
//
// /**
// * Checks to see if a vector is contained with another, comparing
// * using discrete comparisons, inclusively.
// *
// * @param min the minimum point (X, Y, and Z are the lowest)
// * @param max the maximum point (X, Y, and Z are the lowest)
// * @return true if the vector is contained
// */
// public boolean containedWithinBlock(Vector min, Vector max) {
// return getBlockX() >= min.getBlockX() && getBlockX() <= max.getBlockX()
// && getBlockY() >= min.getBlockY() && getBlockY() <= max.getBlockY()
// && getBlockZ() >= min.getBlockZ() && getBlockZ() <= max.getBlockZ();
// }
/**
* Clamp the Y component.
*
* @param min the minimum value
* @param max the maximum value
* @return a new vector
*/
public Vector clampY(int min, int max) {
return new Vector(x, Math.max(min, Math.min(max, y)), z);
}
// /**
// * Floors the values of all components.
// *
// * @return a new vector
// */
// public Vector floor() {
// return new Vector(Math.floor(x), Math.floor(y), Math.floor(z));
// }
//
// /**
// * Rounds all components up.
// *
// * @return a new vector
// */
// public Vector ceil() {
// return new Vector(Math.ceil(x), Math.ceil(y), Math.ceil(z));
// }
//
// /**
// * Rounds all components to the closest integer.
// *
// * <p>Components &lt; 0.5 are rounded down, otherwise up.</p>
// *
// * @return a new vector
// */
// public Vector round() {
// return new Vector(Math.floor(x + 0.5), Math.floor(y + 0.5), Math.floor(z + 0.5));
// }
// /**
// * Returns a vector with the absolute values of the components of
// * this vector.
// *
// * @return a new vector
// */
// public Vector positive() {
// return new Vector(Math.abs(x), Math.abs(y), Math.abs(z));
// }
// /**
// * Perform a 2D transformation on this vector and return a new one.
// *
// * @param angle in degrees
// * @param aboutX about which x coordinate to rotate
// * @param aboutZ about which z coordinate to rotate
// * @param translateX what to add after rotation
// * @param translateZ what to add after rotation
// * @return a new vector
// * @see AffineTransform another method to transform vectors
// */
// public Vector transform2D(double angle, double aboutX, double aboutZ, double translateX, double translateZ) {
// angle = Math.toRadians(angle);
// double x = this.x - aboutX;
// double z = this.z - aboutZ;
// double x2 = x * Math.cos(angle) - z * Math.sin(angle);
// double z2 = x * Math.sin(angle) + z * Math.cos(angle);
//
// return new Vector(
// x2 + aboutX + translateX,
// y,
// z2 + aboutZ + translateZ
// );
// }
//
// /**
// * Returns whether this vector is collinear with another vector.
// *
// * @param other the other vector
// * @return true if collinear
// */
// public boolean isCollinearWith(Vector other) {
// if (x == 0 && y == 0 && z == 0) {
// // this is a zero vector
// return true;
// }
//
// final double otherX = other.x;
// final double otherY = other.y;
// final double otherZ = other.z;
//
// if (otherX == 0 && otherY == 0 && otherZ == 0) {
// // other is a zero vector
// return true;
// }
//
// if ((x == 0) != (otherX == 0)) return false;
// if ((y == 0) != (otherY == 0)) return false;
// if ((z == 0) != (otherZ == 0)) return false;
//
// final double quotientX = otherX / x;
// if (!Double.isNaN(quotientX)) {
// return other.equals(multiply(quotientX));
// }
//
// final double quotientY = otherY / y;
// if (!Double.isNaN(quotientY)) {
// return other.equals(multiply(quotientY));
// }
//
// final double quotientZ = otherZ / z;
// if (!Double.isNaN(quotientZ)) {
// return other.equals(multiply(quotientZ));
// }
//
// throw new RuntimeException("This should not happen");
// }
// /**
// * Get this vector's pitch as used within the game.
// *
// * @return pitch in radians
// */
// public float toPitch() {
// double x = getX();
// double z = getZ();
//
// if (x == 0 && z == 0) {
// return getY() > 0 ? -90 : 90;
// } else {
// double x2 = x * x;
// double z2 = z * z;
// double xz = Math.sqrt(x2 + z2);
// return (float) Math.toDegrees(Math.atan(-getY() / xz));
// }
// }
// /**
// * Get this vector's yaw as used within the game.
// *
// * @return yaw in radians
// */
// public float toYaw() {
// double x = getX();
// double z = getZ();
//
// double t = Math.atan2(-x, z);
// double _2pi = 2 * Math.PI;
//
// return (float) Math.toDegrees(((t + _2pi) % _2pi));
// }
// /**
// * Create a new {@code BlockVector} using the given components.
// *
// * @param x the X coordinate
// * @param y the Y coordinate
// * @param z the Z coordinate
// * @return a new {@code BlockVector}
// */
// public static BlockVector toBlockPoint(double x, double y, double z) {
// return new BlockVector(
// Math.floor(x),
// Math.floor(y),
// Math.floor(z)
// );
// }
// /**
// * Create a new {@code BlockVector} from this vector.
// *
// * @return a new {@code BlockVector}
// */
// public BlockVector toBlockVector() {
// return new BlockVector(this);
// }
// /**
// * Creates a 2D vector by dropping the Y component from this vector.
// *
// * @return a new {@code Vector2D}
// */
// public Vector2D toVector2D() {
// return new Vector2D(x, z);
// }
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Vector)) {
return false;
}
Vector other = (Vector) obj;
return other.x == this.x && other.y == this.y && other.z == this.z;
}
@Override
public int compareTo(Vector other) {
if (other == null) {
throw new IllegalArgumentException("null not supported");
}
if (y != other.y) return Double.compare(y, other.y);
if (z != other.z) return Double.compare(z, other.z);
if (x != other.x) return Double.compare(x, other.x);
return 0;
}
@Override
public int hashCode() {
int hash = 7;
hash = 79 * hash + (int) (Double.doubleToLongBits(this.x) ^ (Double.doubleToLongBits(this.x) >>> 32));
hash = 79 * hash + (int) (Double.doubleToLongBits(this.y) ^ (Double.doubleToLongBits(this.y) >>> 32));
hash = 79 * hash + (int) (Double.doubleToLongBits(this.z) ^ (Double.doubleToLongBits(this.z) >>> 32));
return hash;
}
@Override
public String toString() {
return x + ", " + y + ", " + z;
}
// /**
// * Gets the minimum components of two vectors.
// *
// * @param v1 the first vector
// * @param v2 the second vector
// * @return minimum
// */
// public static Vector getMinimum(Vector v1, Vector v2) {
// return new Vector(
// Math.min(v1.x, v2.x),
// Math.min(v1.y, v2.y),
// Math.min(v1.z, v2.z)
// );
// }
//
// /**
// * Gets the maximum components of two vectors.
// *
// * @param v1 the first vector
// * @param v2 the second vector
// * @return maximum
// */
// public static Vector getMaximum(Vector v1, Vector v2) {
// return new Vector(
// Math.max(v1.x, v2.x),
// Math.max(v1.y, v2.y),
// Math.max(v1.z, v2.z)
// );
// }
// /**
// * Gets the midpoint of two vectors.
// *
// * @param v1 the first vector
// * @param v2 the second vector
// * @return maximum
// */
// public static Vector getMidpoint(Vector v1, Vector v2) {
// return new Vector(
// (v1.x + v2.x) / 2,
// (v1.y + v2.y) / 2,
// (v1.z + v2.z) / 2
// );
// }
// public BlockPos toBlockPos() {
// return new BlockPos(x, y, z);
// }
}

View file

@ -124,10 +124,8 @@ import server.Server;
import server.clipboard.BlockTransform; import server.clipboard.BlockTransform;
import server.clipboard.ClipboardBlock; import server.clipboard.ClipboardBlock;
import server.clipboard.ClipboardPlacer; import server.clipboard.ClipboardPlacer;
import server.clipboard.Rotation;
import server.clipboard.RotationRegistry; import server.clipboard.RotationRegistry;
import server.clipboard.RotationValue; import server.clipboard.RotationValue;
import server.clipboard.Vector;
import server.command.Executor; import server.command.Executor;
import server.util.Form; import server.util.Form;
import server.vars.SVars; import server.vars.SVars;
@ -1423,11 +1421,7 @@ public class Player extends User implements ICrafting, Executor, IPlayer
ClipboardPlacer placer = new ClipboardPlacer(this.getEntityWorld()); ClipboardPlacer placer = new ClipboardPlacer(this.getEntityWorld());
BlockTransform transform = null; BlockTransform transform = null;
if(this.rotation != 0 || this.flipX || this.flipZ) { if(this.rotation != 0 || this.flipX || this.flipZ) {
transform = new BlockTransform(); transform = new BlockTransform(-this.rotation, this.flipX, this.flipZ);
if(this.rotation != 0)
transform = transform.rotateY(-this.rotation);
if(this.flipX || this.flipZ)
transform = transform.scale(new Vector(this.flipX ? -1.0 : 1.0, 1.0, this.flipZ ? -1.0 : 1.0));
} }
else { else {
to = to.add(this.selOffset); to = to.add(this.selOffset);
@ -1440,15 +1434,14 @@ public class Player extends User implements ICrafting, Executor, IPlayer
} }
else { else {
ClipboardBlock block = transformBlock(transform, this.clipboard[x][y][z]); ClipboardBlock block = transformBlock(transform, this.clipboard[x][y][z]);
Vector tf = transform.apply(new Vector(x + this.selOffset.getX(), y + this.selOffset.getY(), z + this.selOffset.getZ())); placer.setBlock(to.add(transform.applyX(x + this.selOffset.getX(), z + this.selOffset.getZ()), y + this.selOffset.getY(),
placer.setBlock(to.add(tf.getBlockX(), tf.getBlockY(), tf.getBlockZ()), block); transform.applyZ(x + this.selOffset.getX(), z + this.selOffset.getZ())), block);
} }
} }
} }
} }
if(transform != null) { if(transform != null) {
Vector tf = transform.apply(new Vector(this.selOffset.getX(), this.selOffset.getY(), this.selOffset.getZ())); to = to.add(transform.applyX(this.selOffset.getX(), this.selOffset.getZ()), this.selOffset.getY(), transform.applyZ(this.selOffset.getX(), this.selOffset.getZ()));
to = to.add(tf.getBlockX(), tf.getBlockY(), tf.getBlockZ());
} }
placer.commit(); placer.commit();
this.addHotbar(TextColor.YELLOW + "Zwischenablage wurde bei %d, %d, %d eingefügt", to.getX(), to.getY(), to.getZ()); this.addHotbar(TextColor.YELLOW + "Zwischenablage wurde bei %d, %d, %d eingefügt", to.getX(), to.getY(), to.getZ());
@ -1456,49 +1449,41 @@ public class Player extends User implements ICrafting, Executor, IPlayer
} }
private static ClipboardBlock transformBlock(BlockTransform transform, ClipboardBlock block) { private static ClipboardBlock transformBlock(BlockTransform transform, ClipboardBlock block) {
Rotation state = RotationRegistry.getRotation(block.getState().getBlock()); RotationValue[] state = RotationRegistry.getRotation(block.getState().getBlock());
if(state == null)
if (state == null) { return block;
for(RotationValue value : state) {
if(value.isSet(block.getState())) {
RotationValue newValue = getNewRotation(transform, state, value);
if(newValue != null)
block.setState(newValue.set(block.getState()));
break;
}
}
return block; return block;
} }
int meta = block.getState().getBlock().getMetaFromState(block.getState()); private static double dot(double x1, double z1, double x2, double z2) {
double l1 = Math.sqrt(x1 * x1 + z1 * z1);
if (state.hasDirection(meta)) { double l2 = Math.sqrt(x2 * x2 + z2 * z2);
RotationValue value = state.getValue(meta); return (x1 / l1) * (x2 / l2) + (z1 / l1) * (z2 / l2);
if (value != null && value.getDirection() != null) {
RotationValue newValue = getNewRotation(transform, state, value.getDirection());
if (newValue != null) {
block.setState(block.getState().getBlock().getStateFromMeta(newValue.set(meta)));
}
}
} }
return block; private static RotationValue getNewRotation(BlockTransform transform, RotationValue[] state, RotationValue value) {
} int x = transform.applyX(value.getX(), value.getZ());
int z = transform.applyZ(value.getX(), value.getZ());
private static RotationValue getNewRotation(BlockTransform transform, Rotation state, Vector oldDirection) {
Vector newDirection = transform.apply(oldDirection).subtract(transform.apply(Vector.ZERO)).normalize();
RotationValue newValue = null; RotationValue newValue = null;
double closest = -2; double closest = -2;
boolean found = false; for(RotationValue v : state) {
if(v.canTransform(value)) {
for (RotationValue v : state.getValues()) { double dot = dot(v.getX(), v.getZ(), x, z);
if (v.getDirection() != null) { if(dot >= closest) {
double dot = v.getDirection().normalize().dot(newDirection);
if (dot >= closest) {
closest = dot; closest = dot;
newValue = v; newValue = v;
found = true;
} }
} }
} }
if (found) {
return newValue; return newValue;
} else {
return null;
}
} }
private boolean copyClipboard() { private boolean copyClipboard() {

View file

@ -435,22 +435,18 @@ public abstract class Converter {
mapBlock(Blocks.gold_ore, 14); mapBlock(Blocks.gold_ore, 14);
mapBlock(Blocks.iron_ore, 15); mapBlock(Blocks.iron_ore, 15);
mapBlock(Blocks.coal_ore, 16); mapBlock(Blocks.coal_ore, 16);
mapBlock(Blocks.oak_log.getState().withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.Y), 17); mapBlock(Blocks.oak_log.getState().withProperty(BlockLog.AXIS, Axis.Y), 17);
mapBlock(Blocks.oak_log.getState().withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.X), 17, 4); mapBlock(Blocks.oak_log.getState().withProperty(BlockLog.AXIS, Axis.X), 17, 4);
mapBlock(Blocks.oak_log.getState().withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.Z), 17, 8); mapBlock(Blocks.oak_log.getState().withProperty(BlockLog.AXIS, Axis.Z), 17, 8);
mapBlock(Blocks.oak_log.getState().withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.NONE), 17, 12); mapBlock(Blocks.spruce_log.getState().withProperty(BlockLog.AXIS, Axis.Y), 17, 1, 13);
mapBlock(Blocks.spruce_log.getState().withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.Y), 17, 1); mapBlock(Blocks.spruce_log.getState().withProperty(BlockLog.AXIS, Axis.X), 17, 5);
mapBlock(Blocks.spruce_log.getState().withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.X), 17, 5); mapBlock(Blocks.spruce_log.getState().withProperty(BlockLog.AXIS, Axis.Z), 17, 9);
mapBlock(Blocks.spruce_log.getState().withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.Z), 17, 9); mapBlock(Blocks.birch_log.getState().withProperty(BlockLog.AXIS, Axis.Y), 17, 2, 14);
mapBlock(Blocks.spruce_log.getState().withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.NONE), 17, 13); mapBlock(Blocks.birch_log.getState().withProperty(BlockLog.AXIS, Axis.X), 17, 6);
mapBlock(Blocks.birch_log.getState().withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.Y), 17, 2); mapBlock(Blocks.birch_log.getState().withProperty(BlockLog.AXIS, Axis.Z), 17, 10);
mapBlock(Blocks.birch_log.getState().withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.X), 17, 6); mapBlock(Blocks.jungle_log.getState().withProperty(BlockLog.AXIS, Axis.Y), 17, 3, 15);
mapBlock(Blocks.birch_log.getState().withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.Z), 17, 10); mapBlock(Blocks.jungle_log.getState().withProperty(BlockLog.AXIS, Axis.X), 17, 7);
mapBlock(Blocks.birch_log.getState().withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.NONE), 17, 14); mapBlock(Blocks.jungle_log.getState().withProperty(BlockLog.AXIS, Axis.Z), 17, 11);
mapBlock(Blocks.jungle_log.getState().withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.Y), 17, 3);
mapBlock(Blocks.jungle_log.getState().withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.X), 17, 7);
mapBlock(Blocks.jungle_log.getState().withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.Z), 17, 11);
mapBlock(Blocks.jungle_log.getState().withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.NONE), 17, 15);
mapBlock(Blocks.oak_leaves_spring.getState() mapBlock(Blocks.oak_leaves_spring.getState()
.withProperty(BlockLeaves.DECAY, false), 18); .withProperty(BlockLeaves.DECAY, false), 18);
mapBlock(Blocks.oak_leaves_spring.getState() mapBlock(Blocks.oak_leaves_spring.getState()
@ -1400,14 +1396,12 @@ public abstract class Converter {
.withProperty(BlockLeaves.DECAY, true), 161, 9); .withProperty(BlockLeaves.DECAY, true), 161, 9);
mapBlock(Blocks.dark_oak_leaves_spring.getState() mapBlock(Blocks.dark_oak_leaves_spring.getState()
.withProperty(BlockLeaves.DECAY, true), 161, 13); .withProperty(BlockLeaves.DECAY, true), 161, 13);
mapBlock(Blocks.acacia_log.getState().withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.Y), 162); mapBlock(Blocks.acacia_log.getState().withProperty(BlockLog.AXIS, Axis.Y), 162);
mapBlock(Blocks.acacia_log.getState().withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.X), 162, 4); mapBlock(Blocks.acacia_log.getState().withProperty(BlockLog.AXIS, Axis.X), 162, 4);
mapBlock(Blocks.acacia_log.getState().withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.Z), 162, 8); mapBlock(Blocks.acacia_log.getState().withProperty(BlockLog.AXIS, Axis.Z), 162, 8);
mapBlock(Blocks.acacia_log.getState().withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.NONE), 162, 12); mapBlock(Blocks.dark_oak_log.getState().withProperty(BlockLog.AXIS, Axis.Y), 162, 1, 13);
mapBlock(Blocks.dark_oak_log.getState().withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.Y), 162, 1); mapBlock(Blocks.dark_oak_log.getState().withProperty(BlockLog.AXIS, Axis.X), 162, 5);
mapBlock(Blocks.dark_oak_log.getState().withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.X), 162, 5); mapBlock(Blocks.dark_oak_log.getState().withProperty(BlockLog.AXIS, Axis.Z), 162, 9);
mapBlock(Blocks.dark_oak_log.getState().withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.Z), 162, 9);
mapBlock(Blocks.dark_oak_log.getState().withProperty(BlockLog.LOG_AXIS, BlockLog.EnumAxis.NONE), 162, 13);
mapBlock(Blocks.acacia_stairs.getState().withProperty(BlockStairs.FACING, Facing.EAST).withProperty(BlockStairs.HALF, EnumHalf.BOTTOM), 163, 0, 8); mapBlock(Blocks.acacia_stairs.getState().withProperty(BlockStairs.FACING, Facing.EAST).withProperty(BlockStairs.HALF, EnumHalf.BOTTOM), 163, 0, 8);
mapBlock(Blocks.acacia_stairs.getState().withProperty(BlockStairs.FACING, Facing.WEST).withProperty(BlockStairs.HALF, EnumHalf.BOTTOM), 163, 1, 9); mapBlock(Blocks.acacia_stairs.getState().withProperty(BlockStairs.FACING, Facing.WEST).withProperty(BlockStairs.HALF, EnumHalf.BOTTOM), 163, 1, 9);
mapBlock(Blocks.acacia_stairs.getState().withProperty(BlockStairs.FACING, Facing.SOUTH).withProperty(BlockStairs.HALF, EnumHalf.BOTTOM), 163, 2, 10); mapBlock(Blocks.acacia_stairs.getState().withProperty(BlockStairs.FACING, Facing.SOUTH).withProperty(BlockStairs.HALF, EnumHalf.BOTTOM), 163, 2, 10);

View file

@ -12,6 +12,7 @@ import common.init.WoodType;
import common.rng.Random; import common.rng.Random;
import common.util.BlockPos; import common.util.BlockPos;
import common.util.ExtMath; import common.util.ExtMath;
import common.util.Facing;
import common.world.State; import common.world.State;
import server.world.WorldServer; import server.world.WorldServer;
@ -192,8 +193,8 @@ public class WorldGenBigTree extends WorldGenTree
for (int j = 0; j <= i; ++j) for (int j = 0; j <= i; ++j)
{ {
BlockPos blockpos1 = p_175937_1_.add((double)(0.5F + (float)j * f), (double)(0.5F + (float)j * f1), (double)(0.5F + (float)j * f2)); BlockPos blockpos1 = p_175937_1_.add((double)(0.5F + (float)j * f), (double)(0.5F + (float)j * f1), (double)(0.5F + (float)j * f2));
BlockLog.EnumAxis blocklog$enumaxis = this.func_175938_b(p_175937_1_, blockpos1); Facing.Axis blocklog$enumaxis = this.func_175938_b(p_175937_1_, blockpos1);
this.setBlockAndNotifyAdequately(this.world, blockpos1, this.logBase.withProperty(BlockLog.LOG_AXIS, blocklog$enumaxis)); this.setBlockAndNotifyAdequately(this.world, blockpos1, this.logBase.withProperty(BlockLog.AXIS, blocklog$enumaxis));
} }
} }
@ -208,9 +209,9 @@ public class WorldGenBigTree extends WorldGenTree
return k > i && k > j ? k : (j > i ? j : i); return k > i && k > j ? k : (j > i ? j : i);
} }
private BlockLog.EnumAxis func_175938_b(BlockPos p_175938_1_, BlockPos p_175938_2_) private Facing.Axis func_175938_b(BlockPos p_175938_1_, BlockPos p_175938_2_)
{ {
BlockLog.EnumAxis blocklog$enumaxis = BlockLog.EnumAxis.Y; Facing.Axis blocklog$enumaxis = Facing.Axis.Y;
int i = Math.abs(p_175938_2_.getX() - p_175938_1_.getX()); int i = Math.abs(p_175938_2_.getX() - p_175938_1_.getX());
int j = Math.abs(p_175938_2_.getZ() - p_175938_1_.getZ()); int j = Math.abs(p_175938_2_.getZ() - p_175938_1_.getZ());
int k = Math.max(i, j); int k = Math.max(i, j);
@ -219,11 +220,11 @@ public class WorldGenBigTree extends WorldGenTree
{ {
if (i == k) if (i == k)
{ {
blocklog$enumaxis = BlockLog.EnumAxis.X; blocklog$enumaxis = Facing.Axis.X;
} }
else if (j == k) else if (j == k)
{ {
blocklog$enumaxis = BlockLog.EnumAxis.Z; blocklog$enumaxis = Facing.Axis.Z;
} }
} }