Search in sources :

Example 1 with AbstractProperty

use of com.sk89q.worldedit.registry.state.AbstractProperty 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 AbstractProperty

use of com.sk89q.worldedit.registry.state.AbstractProperty in project FastAsyncWorldEdit by IntellectualSites.

the class BlockState method get.

/**
 * Returns a temporary BlockState for a given type and string.
 *
 * <p>It's faster if a BlockType is provided compared to parsing the string.</p>
 *
 * @param type  BlockType e.g., BlockTypes.STONE (or null)
 * @param state String e.g., minecraft:water[level=4]
 * @return BlockState
 */
public static BlockState get(@Nullable BlockType type, String state, BlockState defaultState) throws InputParseException {
    int propStrStart = state.indexOf('[');
    if (type == null) {
        CharSequence key;
        if (propStrStart == -1) {
            key = state;
        } else {
            MutableCharSequence charSequence = MutableCharSequence.getTemporal();
            charSequence.setString(state);
            charSequence.setSubstring(0, propStrStart);
            key = charSequence;
        }
        type = BlockTypes.get(key);
        if (type == null) {
            String input = key.toString();
            throw new SuggestInputParseException("Does not match a valid block type: " + input, input, () -> Stream.of(BlockTypesCache.values).map(BlockType::getId).filter(id -> StringMan.blockStateMatches(input, id)).sorted(StringMan.blockStateComparator(input)).collect(Collectors.toList()));
        }
    }
    if (propStrStart == -1) {
        return type.getDefaultState();
    }
    List<? extends Property<?>> propList = type.getProperties();
    if (state.charAt(state.length() - 1) != ']') {
        state = state + "]";
    }
    MutableCharSequence charSequence = MutableCharSequence.getTemporal();
    charSequence.setString(state);
    if (propList.size() == 1) {
        AbstractProperty<?> property = (AbstractProperty<?>) propList.get(0);
        String name = property.getName();
        charSequence.setSubstring(propStrStart + name.length() + 2, state.length() - 1);
        int index = charSequence.length() <= 0 ? -1 : property.getIndexFor(charSequence);
        if (index != -1) {
            return type.withPropertyId(index);
        }
    }
    int stateId;
    if (defaultState != null) {
        stateId = defaultState.getInternalId();
    } else {
        stateId = type.getDefaultState().getInternalId();
    }
    int length = state.length();
    AbstractProperty<?> property = null;
    int last = propStrStart + 1;
    for (int i = last; i < length; i++) {
        char c = state.charAt(i);
        switch(c) {
            case ']':
            case ',':
                {
                    charSequence.setSubstring(last, i);
                    if (property != null) {
                        int index = property.getIndexFor(charSequence);
                        if (index == -1) {
                            throw SuggestInputParseException.of(charSequence.toString(), (List<Object>) property.getValues());
                        }
                        stateId = property.modifyIndex(stateId, index);
                    } else {
                        // suggest
                        PropertyKey key = PropertyKey.getByName(charSequence);
                        if (key == null || !type.hasProperty(key)) {
                            // Suggest property
                            String input = charSequence.toString();
                            BlockType finalType = type;
                            throw new SuggestInputParseException("Invalid property " + key + ":" + input + " for type " + type, input, () -> finalType.getProperties().stream().map(Property::getName).filter(p -> StringMan.blockStateMatches(input, p)).sorted(StringMan.blockStateComparator(input)).collect(Collectors.toList()));
                        } else {
                            throw new SuggestInputParseException("No operator for " + state, "", () -> Collections.singletonList("="));
                        }
                    }
                    property = null;
                    last = i + 1;
                    break;
                }
            case '=':
                {
                    charSequence.setSubstring(last, i);
                    property = (AbstractProperty) type.getPropertyMap().get(charSequence);
                    last = i + 1;
                    break;
                }
            default:
                continue;
        }
    }
    return type.withPropertyId(stateId >> BlockTypesCache.BIT_OFFSET);
}
Also used : SuggestInputParseException(com.fastasyncworldedit.core.command.SuggestInputParseException) Property(com.sk89q.worldedit.registry.state.Property) BlockVector3(com.sk89q.worldedit.math.BlockVector3) SingleBlockStateMask(com.fastasyncworldedit.core.function.mask.SingleBlockStateMask) BlanketBaseBlock(com.fastasyncworldedit.core.world.block.BlanketBaseBlock) LazyReference(com.sk89q.worldedit.util.concurrency.LazyReference) StringMan(com.fastasyncworldedit.core.util.StringMan) WorldEditException(com.sk89q.worldedit.WorldEditException) InputParseException(com.sk89q.worldedit.extension.input.InputParseException) Map(java.util.Map) PropertyKey(com.fastasyncworldedit.core.registry.state.PropertyKey) WorldEdit(com.sk89q.worldedit.WorldEdit) CompoundBinaryTag(com.sk89q.worldedit.util.nbt.CompoundBinaryTag) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) Function(com.google.common.base.Function) NullExtent(com.sk89q.worldedit.extent.NullExtent) MutableCharSequence(com.fastasyncworldedit.core.util.MutableCharSequence) OutputExtent(com.sk89q.worldedit.extent.OutputExtent) AbstractProperty(com.sk89q.worldedit.registry.state.AbstractProperty) Maps(com.google.common.collect.Maps) Collectors(java.util.stream.Collectors) List(java.util.List) Stream(java.util.stream.Stream) Capability(com.sk89q.worldedit.extension.platform.Capability) CompoundInput(com.fastasyncworldedit.core.world.block.CompoundInput) CompoundTag(com.sk89q.jnbt.CompoundTag) Mask(com.sk89q.worldedit.function.mask.Mask) ITileInput(com.fastasyncworldedit.core.queue.ITileInput) Pattern(com.sk89q.worldedit.function.pattern.Pattern) Collections(java.util.Collections) Extent(com.sk89q.worldedit.extent.Extent) BlockMaterial(com.sk89q.worldedit.world.registry.BlockMaterial) SuggestInputParseException(com.fastasyncworldedit.core.command.SuggestInputParseException) MutableCharSequence(com.fastasyncworldedit.core.util.MutableCharSequence) AbstractProperty(com.sk89q.worldedit.registry.state.AbstractProperty) MutableCharSequence(com.fastasyncworldedit.core.util.MutableCharSequence) List(java.util.List) PropertyKey(com.fastasyncworldedit.core.registry.state.PropertyKey)

Example 3 with AbstractProperty

use of com.sk89q.worldedit.registry.state.AbstractProperty in project FastAsyncWorldEdit by IntellectualSites.

the class BlockType method getState.

/**
 * Gets a state of this BlockType with the given properties.
 *
 * @return The state, if it exists
 * @deprecated Not working. Not necessarily for removal, but WARNING DO NOT USE FOR NOW
 */
@Deprecated(forRemoval = true)
public BlockState getState(Map<Property<?>, Object> key) {
    // FAWE start - use ids & btp (block type property)
    int id = getInternalId();
    for (Map.Entry<Property<?>, Object> iter : key.entrySet()) {
        Property<?> prop = iter.getKey();
        Object value = iter.getValue();
        /*
             * TODO:
             * This is likely wrong. The only place this seems to currently (Dec 23 2018)
             * be invoked is via ForgeWorld, and value is a String when invoked there...
             */
        AbstractProperty btp = this.settings.propertiesMap.get(prop.getName());
        checkArgument(btp != null, "%s has no property named %s", this, prop.getName());
        id = btp.modify(id, btp.getValueFor((String) value));
    }
    return withStateId(id);
// FAWE end
}
Also used : AbstractProperty(com.sk89q.worldedit.registry.state.AbstractProperty) Map(java.util.Map) Property(com.sk89q.worldedit.registry.state.Property) AbstractProperty(com.sk89q.worldedit.registry.state.AbstractProperty)

Example 4 with AbstractProperty

use of com.sk89q.worldedit.registry.state.AbstractProperty in project FastAsyncWorldEdit by IntellectualSites.

the class MinecraftStructure method write.

public void write(Clipboard clipboard, String owner) throws IOException {
    Region region = clipboard.getRegion();
    int width = region.getWidth();
    int height = region.getHeight();
    int length = region.getLength();
    if (width > WARN_SIZE || height > WARN_SIZE || length > WARN_SIZE) {
        LOGGER.info("A structure longer than 32 is unsupported by minecraft (but probably still works)");
    }
    Map<String, Object> structure = FaweCache.INSTANCE.asMap("version", 1, "author", owner);
    // ignored: version / owner
    Int2ObjectArrayMap<Integer> indexes = new Int2ObjectArrayMap<>();
    // Size
    structure.put("size", Arrays.asList(width, height, length));
    // Palette
    ArrayList<HashMap<String, Object>> palette = new ArrayList<>();
    for (BlockVector3 point : region) {
        BlockState block = clipboard.getBlock(point);
        int combined = block.getInternalId();
        BlockType type = block.getBlockType();
        if (type == BlockTypes.STRUCTURE_VOID || indexes.containsKey(combined)) {
            continue;
        }
        indexes.put(combined, (Integer) palette.size());
        HashMap<String, Object> paletteEntry = new HashMap<>();
        paletteEntry.put("Name", type.getId());
        if (block.getInternalId() != type.getInternalId()) {
            Map<String, Object> properties = null;
            for (AbstractProperty property : (List<AbstractProperty<?>>) type.getProperties()) {
                int propIndex = property.getIndex(block.getInternalId());
                if (propIndex != 0) {
                    if (properties == null) {
                        properties = new HashMap<>();
                    }
                    Object value = property.getValues().get(propIndex);
                    properties.put(property.getName(), value.toString());
                }
            }
            if (properties != null) {
                paletteEntry.put("Properties", properties);
            }
        }
        palette.add(paletteEntry);
    }
    if (!palette.isEmpty()) {
        structure.put("palette", palette);
    }
    // Blocks
    ArrayList<Map<String, Object>> blocks = new ArrayList<>();
    BlockVector3 min = region.getMinimumPoint();
    for (BlockVector3 point : region) {
        BaseBlock block = clipboard.getFullBlock(point);
        if (block.getBlockType() != BlockTypes.STRUCTURE_VOID) {
            int combined = block.getInternalId();
            int index = indexes.get(combined);
            List<Integer> pos = Arrays.asList(point.getX() - min.getX(), point.getY() - min.getY(), point.getZ() - min.getZ());
            if (!block.hasNbtData()) {
                blocks.add(FaweCache.INSTANCE.asMap("state", index, "pos", pos));
            } else {
                blocks.add(FaweCache.INSTANCE.asMap("state", index, "pos", pos, "nbt", block.getNbtData()));
            }
        }
    }
    if (!blocks.isEmpty()) {
        structure.put("blocks", blocks);
    }
    // Entities
    ArrayList<Map<String, Object>> entities = new ArrayList<>();
    for (Entity entity : clipboard.getEntities()) {
        Location loc = entity.getLocation();
        List<Double> pos = Arrays.asList(loc.getX(), loc.getY(), loc.getZ());
        List<Integer> blockPos = Arrays.asList(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
        BaseEntity state = entity.getState();
        if (state != null) {
            CompoundTag nbt = state.getNbtData();
            Map<String, Tag> nbtMap = nbt.getValue();
            // Replace rotation data
            nbtMap.put("Rotation", writeRotation(entity.getLocation()));
            nbtMap.put("id", new StringTag(state.getType().getId()));
            Map<String, Object> entityMap = FaweCache.INSTANCE.asMap("pos", pos, "blockPos", blockPos, "nbt", nbt);
            entities.add(entityMap);
        }
    }
    if (!entities.isEmpty()) {
        structure.put("entities", entities);
    }
    out.writeNamedTag("", FaweCache.INSTANCE.asTag(structure));
    close();
}
Also used : StringTag(com.sk89q.jnbt.StringTag) BaseEntity(com.sk89q.worldedit.entity.BaseEntity) Entity(com.sk89q.worldedit.entity.Entity) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) BaseBlock(com.sk89q.worldedit.world.block.BaseBlock) ArrayList(java.util.ArrayList) List(java.util.List) CompoundTag(com.sk89q.jnbt.CompoundTag) Int2ObjectArrayMap(it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap) BaseEntity(com.sk89q.worldedit.entity.BaseEntity) AbstractProperty(com.sk89q.worldedit.registry.state.AbstractProperty) BlockVector3(com.sk89q.worldedit.math.BlockVector3) BlockState(com.sk89q.worldedit.world.block.BlockState) BlockType(com.sk89q.worldedit.world.block.BlockType) CuboidRegion(com.sk89q.worldedit.regions.CuboidRegion) Region(com.sk89q.worldedit.regions.Region) StringTag(com.sk89q.jnbt.StringTag) ListTag(com.sk89q.jnbt.ListTag) IntTag(com.sk89q.jnbt.IntTag) NamedTag(com.sk89q.jnbt.NamedTag) CompoundTag(com.sk89q.jnbt.CompoundTag) Tag(com.sk89q.jnbt.Tag) HashMap(java.util.HashMap) Map(java.util.Map) Int2ObjectArrayMap(it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap) Location(com.sk89q.worldedit.util.Location)

Example 5 with AbstractProperty

use of com.sk89q.worldedit.registry.state.AbstractProperty in project FastAsyncWorldEdit by IntellectualSites.

the class BlockTransformExtent method cache.

private void cache() {
    BLOCK_ROTATION_BITMASK = new int[BlockTypes.size()];
    BLOCK_TRANSFORM = new int[BlockTypes.size()][];
    BLOCK_TRANSFORM_INVERSE = new int[BlockTypes.size()][];
    for (int i = 0; i < BLOCK_TRANSFORM.length; i++) {
        BLOCK_TRANSFORM[i] = ALL;
        BLOCK_TRANSFORM_INVERSE[i] = ALL;
        BlockType type = BlockTypes.get(i);
        int bitMask = 0;
        for (AbstractProperty property : (Collection<AbstractProperty>) (Collection) type.getProperties()) {
            if (isDirectional(property)) {
                BLOCK_TRANSFORM[i] = null;
                BLOCK_TRANSFORM_INVERSE[i] = null;
                bitMask |= property.getBitMask();
            }
        }
        if (bitMask != 0) {
            BLOCK_ROTATION_BITMASK[i] = bitMask;
        }
    }
}
Also used : BlockType(com.sk89q.worldedit.world.block.BlockType) Collection(java.util.Collection) AbstractProperty(com.sk89q.worldedit.registry.state.AbstractProperty)

Aggregations

AbstractProperty (com.sk89q.worldedit.registry.state.AbstractProperty)5 Map (java.util.Map)4 BlockType (com.sk89q.worldedit.world.block.BlockType)3 List (java.util.List)3 PropertyKey (com.fastasyncworldedit.core.registry.state.PropertyKey)2 CompoundTag (com.sk89q.jnbt.CompoundTag)2 BlockVector3 (com.sk89q.worldedit.math.BlockVector3)2 Property (com.sk89q.worldedit.registry.state.Property)2 BlockState (com.sk89q.worldedit.world.block.BlockState)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 SuggestInputParseException (com.fastasyncworldedit.core.command.SuggestInputParseException)1 SingleBlockStateMask (com.fastasyncworldedit.core.function.mask.SingleBlockStateMask)1 ITileInput (com.fastasyncworldedit.core.queue.ITileInput)1 MutableCharSequence (com.fastasyncworldedit.core.util.MutableCharSequence)1 StringMan (com.fastasyncworldedit.core.util.StringMan)1 BlanketBaseBlock (com.fastasyncworldedit.core.world.block.BlanketBaseBlock)1 CompoundInput (com.fastasyncworldedit.core.world.block.CompoundInput)1 Function (com.google.common.base.Function)1 ImmutableMap (com.google.common.collect.ImmutableMap)1