Search in sources :

Example 1 with Direction

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;
}
Also used : BlockState(com.sk89q.worldedit.world.block.BlockState) BlockType(com.sk89q.worldedit.world.block.BlockType) AbstractProperty(com.sk89q.worldedit.registry.state.AbstractProperty) List(java.util.List) ArrayList(java.util.ArrayList) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) HashMap(java.util.HashMap) Direction(com.sk89q.worldedit.util.Direction) PropertyKey(com.fastasyncworldedit.core.registry.state.PropertyKey)

Example 2 with Direction

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;
}
Also used : AffineTransform(com.sk89q.worldedit.math.transform.AffineTransform) BlockVector3(com.sk89q.worldedit.math.BlockVector3) Vector3(com.sk89q.worldedit.math.Vector3) Direction(com.sk89q.worldedit.util.Direction) Nullable(javax.annotation.Nullable)

Example 3 with Direction

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();
}
Also used : HashMap(java.util.HashMap) ByteTag(com.sk89q.jnbt.ByteTag) BlockVector3(com.sk89q.worldedit.math.BlockVector3) Vector3(com.sk89q.worldedit.math.Vector3) CompoundTag(com.sk89q.jnbt.CompoundTag) ByteTag(com.sk89q.jnbt.ByteTag) Tag(com.sk89q.jnbt.Tag) Direction(com.sk89q.worldedit.util.Direction) BaseBlock(com.sk89q.worldedit.world.block.BaseBlock) CompoundTag(com.sk89q.jnbt.CompoundTag)

Example 4 with Direction

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;
}
Also used : ArrayList(java.util.ArrayList) DirectionalProperty(com.sk89q.worldedit.registry.state.DirectionalProperty) List(java.util.List) ArrayList(java.util.ArrayList) Direction(com.sk89q.worldedit.util.Direction) PropertyKey(com.fastasyncworldedit.core.registry.state.PropertyKey)

Example 5 with Direction

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;
}
Also used : ArrayList(java.util.ArrayList) Direction(com.sk89q.worldedit.util.Direction) ListTag(com.sk89q.jnbt.ListTag) CompoundTagBuilder(com.sk89q.jnbt.CompoundTagBuilder) BlockState(com.sk89q.worldedit.world.block.BlockState) BlockType(com.sk89q.worldedit.world.block.BlockType) ListTag(com.sk89q.jnbt.ListTag) IntTag(com.sk89q.jnbt.IntTag) CompoundTag(com.sk89q.jnbt.CompoundTag) Tag(com.sk89q.jnbt.Tag) IntTag(com.sk89q.jnbt.IntTag) CompoundTag(com.sk89q.jnbt.CompoundTag)

Aggregations

Direction (com.sk89q.worldedit.util.Direction)19 BlockVector3 (com.sk89q.worldedit.math.BlockVector3)6 Tag (com.sk89q.jnbt.Tag)5 DirectionalProperty (com.sk89q.worldedit.registry.state.DirectionalProperty)5 BlockState (com.sk89q.worldedit.world.block.BlockState)5 BlockType (com.sk89q.worldedit.world.block.BlockType)5 Map (java.util.Map)5 Vector3 (com.sk89q.worldedit.math.Vector3)4 BooleanProperty (com.sk89q.worldedit.registry.state.BooleanProperty)4 EnumProperty (com.sk89q.worldedit.registry.state.EnumProperty)4 IntegerProperty (com.sk89q.worldedit.registry.state.IntegerProperty)4 Property (com.sk89q.worldedit.registry.state.Property)4 ArrayList (java.util.ArrayList)4 HashMap (java.util.HashMap)4 CompoundTag (com.sk89q.jnbt.CompoundTag)3 CompoundTagBuilder (com.sk89q.jnbt.CompoundTagBuilder)3 Location (com.sk89q.worldedit.util.Location)3 List (java.util.List)3 PropertyKey (com.fastasyncworldedit.core.registry.state.PropertyKey)2 ByteTag (com.sk89q.jnbt.ByteTag)2