use of com.sk89q.worldedit.util.Direction in project FastAsyncWorldEdit by IntellectualSites.
the class BlockTransformExtent method transformState.
private static int transformState(BlockState state, Transform transform) {
int newMaskedId = state.getInternalId();
BlockType type = state.getBlockType();
// Rotate North, East, South, West
if (type.hasProperty(PropertyKey.NORTH) && type.hasProperty(PropertyKey.EAST) && type.hasProperty(PropertyKey.SOUTH) && type.hasProperty(PropertyKey.WEST)) {
BlockState tmp = state;
for (Map.Entry<Direction, PropertyKey> entry : directionMap.entrySet()) {
Direction newDir = findClosest(transform.apply(entry.getKey().toVector()), Flag.CARDINAL);
if (newDir != null) {
Object dirState = state.getState(entry.getValue());
tmp = tmp.with(directionMap.get(newDir), dirState);
}
}
newMaskedId = tmp.getInternalId();
}
// True if relying on two different "directions" for the result, e.g. stairs with both facing and shape
for (AbstractProperty property : (List<AbstractProperty<?>>) type.getProperties()) {
if (isDirectional(property)) {
long[] directions = getDirections(property);
if (directions != null) {
int oldIndex = property.getIndex(state.getInternalId());
if (oldIndex >= directions.length) {
if (Settings.settings().ENABLED_COMPONENTS.DEBUG) {
LOGGER.warn(String.format("Index outside direction array length found for block:{%s} property:{%s}", state.getBlockType().getId(), property.getName()));
}
continue;
}
Integer newIndex = getNewStateIndex(transform, directions, oldIndex);
if (newIndex != null) {
newMaskedId = property.modifyIndex(newMaskedId, newIndex);
}
}
}
}
return newMaskedId;
}
use of com.sk89q.worldedit.util.Direction in project FastAsyncWorldEdit by IntellectualSites.
the class BlockTransformExtent method getNewStateIndex.
@Nullable
private static Integer getNewStateIndex(Transform transform, long[] directions, int oldIndex) {
long oldDirMask = directions[oldIndex];
if (oldDirMask == 0) {
return null;
}
Integer newIndex = null;
for (Direction oldDirection : values()) {
if (!hasDirection(oldDirMask, oldDirection)) {
continue;
}
Vector3 oldVector = oldDirection.toVector();
Vector3 newVector = transform.apply(oldVector).subtract(transform.apply(Vector3.ZERO)).normalize();
boolean flip = false;
if (transform instanceof AffineTransform) {
flip = ((AffineTransform) transform).isScaled(oldVector);
}
// If we're flipping, it is possible for the old and new vectors to be equal
if (!flip && oldVector.equalsFuzzy(newVector)) {
continue;
}
double closest = oldVector.normalize().dot(newVector);
for (int i = 0; i < directions.length; i++) {
int j = (oldIndex + i) % directions.length;
long newDirMask = directions[j];
// Check if the old mask excludes it
if (!hasIndex(oldDirMask, j)) {
continue;
}
for (Direction v : Direction.values()) {
// Check if it's one of the current directions
if (!hasDirection(newDirMask, v)) {
continue;
}
double dot = v.toVector().normalize().dot(newVector);
if (dot > closest || (flip && dot >= closest)) {
//
closest = dot;
newIndex = j;
}
}
}
if (newIndex != null) {
return newIndex;
}
}
return newIndex;
}
use of com.sk89q.worldedit.util.Direction in project FastAsyncWorldEdit by IntellectualSites.
the class BlockTransformExtent method transformBaseBlockNBT.
private static BaseBlock transformBaseBlockNBT(BlockState transformed, CompoundTag tag, Transform transform) {
if (tag != null) {
if (tag.containsKey("Rot")) {
int rot = tag.asInt("Rot");
Direction direction = MCDirections.fromRotation(rot);
if (direction != null) {
Vector3 applyAbsolute = transform.apply(direction.toVector());
Vector3 applyOrigin = transform.apply(Vector3.ZERO);
applyAbsolute.mutX(applyAbsolute.getX() - applyOrigin.getX());
applyAbsolute.mutY(applyAbsolute.getY() - applyOrigin.getY());
applyAbsolute.mutZ(applyAbsolute.getZ() - applyOrigin.getZ());
Direction newDirection = Direction.findClosest(applyAbsolute, Direction.Flag.CARDINAL | Direction.Flag.ORDINAL | Direction.Flag.SECONDARY_ORDINAL);
if (newDirection != null) {
Map<String, Tag> values = new HashMap<>(tag.getValue());
values.put("Rot", new ByteTag((byte) MCDirections.toRotation(newDirection)));
tag = new CompoundTag(values);
}
}
}
return new BaseBlock(transformed, tag);
}
return transformed.toBaseBlock();
}
use of com.sk89q.worldedit.util.Direction in project FastAsyncWorldEdit by IntellectualSites.
the class BlockTransformExtent method getDirections.
private static long[] getDirections(AbstractProperty property) {
if (property instanceof DirectionalProperty) {
DirectionalProperty directional = (DirectionalProperty) property;
return adapt(directional.getValues().toArray(new Direction[0]));
} else {
List values = property.getValues();
PropertyKey key = property.getKey();
switch(key.getName().toLowerCase()) {
case "half":
{
return adapt(UP, DOWN);
}
case "type":
{
return adapt(combine(UP), combine(DOWN), 0L);
}
case "rotation":
{
List<Direction> directions = new ArrayList<>();
for (Object value : values) {
directions.add(Direction.fromRotationIndex((Integer) value).get());
}
return adapt(directions.toArray(new Direction[0]));
}
case "axis":
{
switch(property.getValues().size()) {
case 3:
return adapt(combine(EAST, WEST), combine(UP, DOWN), combine(SOUTH, NORTH));
case 2:
return adapt(combine(EAST, WEST), combine(SOUTH, NORTH));
default:
LOGGER.error("Invalid {} {}", property.getName(), property.getValues());
return null;
}
}
case "facing":
{
List<Direction> directions = new ArrayList<>();
for (Object value : values) {
directions.add(Direction.valueOf(value.toString().toUpperCase(Locale.ROOT)));
}
return adapt(directions.toArray(new Direction[0]));
}
case "face":
{
if (values.size() == 3) {
return adapt(combine(UP), combine(NORTH, EAST, SOUTH, WEST), combine(DOWN));
}
return null;
}
case "hinge":
{
return adapt(combine(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST), combine(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST));
}
case "shape":
{
if (values.contains("left")) {
return adapt(combine(EAST, WEST), combine(NORTH, SOUTH));
}
if (values.contains("straight")) {
ArrayList<Long> result = new ArrayList<>();
for (Object value : values) {
// [straight, inner_left, inner_right, outer_left, outer_right]
switch(value.toString()) {
case "straight":
result.add(combine(NORTH, EAST, SOUTH, WEST));
continue;
case "inner_left":
result.add(orIndex(combine(NORTHEAST, NORTHWEST, SOUTHWEST, SOUTHEAST), property.getIndexFor("outer_right"), property.getIndexFor("outer_left")));
continue;
case "inner_right":
result.add(orIndex(combine(NORTHEAST, NORTHWEST, SOUTHWEST, SOUTHEAST), property.getIndexFor("outer_right"), property.getIndexFor("outer_left")));
continue;
case "outer_left":
result.add(orIndex(combine(NORTHEAST, NORTHWEST, SOUTHWEST, SOUTHEAST), property.getIndexFor("inner_left"), property.getIndexFor("inner_right")));
continue;
case "outer_right":
result.add(orIndex(combine(NORTHEAST, NORTHWEST, SOUTHWEST, SOUTHEAST), property.getIndexFor("inner_left"), property.getIndexFor("inner_right")));
continue;
default:
LOGGER.warn("Unknown direction {}", value);
result.add(0L);
}
}
return adapt(result.toArray(new Long[0]));
} else {
List<Long> directions = new ArrayList<>();
for (Object value : values) {
switch(value.toString()) {
case "north_south":
directions.add(combine(NORTH, SOUTH));
break;
case "east_west":
directions.add(combine(EAST, WEST));
break;
case "ascending_east":
directions.add(combine(ASCENDING_EAST));
break;
case "ascending_west":
directions.add(combine(ASCENDING_WEST));
break;
case "ascending_north":
directions.add(combine(ASCENDING_NORTH));
break;
case "ascending_south":
directions.add(combine(ASCENDING_SOUTH));
break;
case "south_east":
directions.add(combine(SOUTHEAST));
break;
case "south_west":
directions.add(combine(SOUTHWEST));
break;
case "north_west":
directions.add(combine(NORTHWEST));
break;
case "north_east":
directions.add(combine(NORTHEAST));
break;
default:
LOGGER.warn("Unknown direction {}", value);
directions.add(0L);
}
}
return adapt(directions.toArray(new Long[0]));
}
}
}
}
return null;
}
use of com.sk89q.worldedit.util.Direction in project FastAsyncWorldEdit by IntellectualSites.
the class BannerBlockCompatibilityHandler method updateNBT.
@Override
public <B extends BlockStateHolder<B>> BlockStateHolder<?> updateNBT(B block, Map<String, Tag> values) {
Tag typeTag = values.get("Base");
if (typeTag instanceof IntTag) {
boolean isWall = block.getBlockType() == BlockTypes.WHITE_WALL_BANNER;
String bannerType = convertBannerType(((IntTag) typeTag).getValue(), isWall);
if (bannerType != null) {
BlockType type = BlockTypes.get("minecraft:" + bannerType);
if (type != null) {
BlockState state = type.getDefaultState();
if (isWall) {
Property<Direction> facingProp = type.getProperty("facing");
state = state.with(facingProp, block.getState(FacingProperty));
} else {
Property<Integer> rotationProp = type.getProperty("rotation");
state = state.with(rotationProp, block.getState(RotationProperty));
}
values.remove("Base");
Tag patternsTag = values.get("Patterns");
if (patternsTag instanceof ListTag) {
List<Tag> tempList = new ArrayList<>();
for (Tag pattern : ((ListTag) patternsTag).getValue()) {
if (pattern instanceof CompoundTag) {
Map<String, Tag> patternMap = ((CompoundTag) pattern).getValue();
Tag colorTag = patternMap.get("Color");
CompoundTagBuilder builder = CompoundTagBuilder.create();
builder.putAll(patternMap);
if (colorTag instanceof IntTag) {
builder.putInt("Color", 15 - ((IntTag) colorTag).getValue());
}
tempList.add(builder.build());
} else {
tempList.add(pattern);
}
}
values.put("Patterns", new ListTag(((ListTag) patternsTag).getType(), tempList));
}
return state;
}
}
}
return block;
}
Aggregations