Search in sources :

Example 11 with ListTag

use of com.denizenscript.denizencore.objects.core.ListTag in project Denizen-For-Bukkit by DenizenScript.

the class EllipsoidTag method registerTags.

public static void registerTags() {
    AbstractFlagTracker.registerFlagHandlers(tagProcessor);
    AreaContainmentObject.registerTags(EllipsoidTag.class, tagProcessor);
    // <--[tag]
    // @attribute <EllipsoidTag.random>
    // @returns LocationTag
    // @description
    // Returns a random decimal location within the ellipsoid.
    // Note that distribution of results will not be completely even.
    // -->
    tagProcessor.registerTag(LocationTag.class, "random", (attribute, object) -> {
        // This is an awkward hack to try to weight towards the center a bit (to counteract the weight-away-from-center that would otherwise happen).
        double y = (Math.sqrt(CoreUtilities.getRandom().nextDouble()) * 2 - 1) * object.size.getY();
        Vector result = new Vector();
        result.setY(y);
        double yProg = Math.abs(y) / object.size.getY();
        double subWidth = Math.sqrt(1.0 - yProg * yProg);
        double maxX = object.size.getX() * subWidth;
        double maxZ = object.size.getZ() * subWidth;
        result.setX(maxX * (CoreUtilities.getRandom().nextDouble() * 2 - 1));
        result.setZ(maxZ * (CoreUtilities.getRandom().nextDouble() * 2 - 1));
        LocationTag out = object.center.clone();
        out.add(result);
        return out;
    });
    // <--[tag]
    // @attribute <EllipsoidTag.location>
    // @returns LocationTag
    // @description
    // Returns the location of the ellipsoid.
    // -->
    tagProcessor.registerTag(LocationTag.class, "location", (attribute, object) -> {
        return object.center;
    });
    // <--[tag]
    // @attribute <EllipsoidTag.size>
    // @returns LocationTag
    // @description
    // Returns the size of the ellipsoid.
    // -->
    tagProcessor.registerTag(LocationTag.class, "size", (attribute, object) -> {
        return object.size;
    });
    // <--[tag]
    // @attribute <EllipsoidTag.add[<location>]>
    // @returns EllipsoidTag
    // @description
    // Returns a copy of this ellipsoid, shifted by the input location.
    // -->
    tagProcessor.registerTag(EllipsoidTag.class, "add", (attribute, object) -> {
        if (!attribute.hasParam()) {
            attribute.echoError("ellipsoid.add[...] tag must have an input.");
            return null;
        }
        return new EllipsoidTag(object.center.clone().add(attribute.paramAsType(LocationTag.class)), object.size.clone());
    });
    // <--[tag]
    // @attribute <EllipsoidTag.include[<location>]>
    // @returns EllipsoidTag
    // @description
    // Returns a copy of this ellipsoid, with the size value adapted to include the specified world location.
    // -->
    tagProcessor.registerTag(EllipsoidTag.class, "include", (attribute, object) -> {
        if (!attribute.hasParam()) {
            attribute.echoError("ellipsoid.include[...] tag must have an input.");
            return null;
        }
        LocationTag target = attribute.paramAsType(LocationTag.class);
        if (object.contains(target)) {
            return object;
        }
        LocationTag size = object.size.clone();
        Vector relative = target.toVector().subtract(object.center.toVector());
        // Cuboid minimum expansion
        size.setX(Math.max(size.getX(), Math.abs(relative.getX())));
        size.setY(Math.max(size.getY(), Math.abs(relative.getY())));
        size.setZ(Math.max(size.getZ(), Math.abs(relative.getZ())));
        EllipsoidTag result = new EllipsoidTag(object.center.clone(), new LocationTag(size));
        if (result.contains(target)) {
            return result;
        }
        double sizeLen = size.length();
        // Ellipsoid additional expand
        while (!result.contains(target)) {
            // I gave up on figuring out the math for this, so here's an awful loop-hack
            double projX = (relative.getX() * relative.getX()) / (size.getX() * size.getX());
            double projY = (relative.getY() * relative.getY()) / (size.getY() * size.getY());
            double projZ = (relative.getZ() * relative.getZ()) / (size.getZ() * size.getZ());
            double scale = Math.max(projX + projY + projZ, sizeLen * 0.01);
            if (projX >= projY && projX >= projZ) {
                size.setX(size.getX() + scale);
            } else if (projY >= projX && projY >= projZ) {
                size.setY(size.getY() + scale);
            } else if (projZ >= projX && projZ >= projY) {
                size.setZ(size.getZ() + scale);
            } else {
                size = size.add(scale, scale, scale);
            }
            result.size = size;
        }
        return result;
    });
    // <--[tag]
    // @attribute <EllipsoidTag.with_location[<location>]>
    // @returns EllipsoidTag
    // @description
    // Returns a copy of this ellipsoid, set to the specified location.
    // -->
    tagProcessor.registerTag(EllipsoidTag.class, "with_location", (attribute, object) -> {
        if (!attribute.hasParam()) {
            attribute.echoError("ellipsoid.with_location[...] tag must have an input.");
            return null;
        }
        return new EllipsoidTag(attribute.paramAsType(LocationTag.class), object.size.clone());
    });
    // <--[tag]
    // @attribute <EllipsoidTag.with_size[<location>]>
    // @returns EllipsoidTag
    // @description
    // Returns a copy of this ellipsoid, set to the specified size.
    // -->
    tagProcessor.registerTag(EllipsoidTag.class, "with_size", (attribute, object) -> {
        if (!attribute.hasParam()) {
            attribute.echoError("ellipsoid.with_size[...] tag must have an input.");
            return null;
        }
        return new EllipsoidTag(object.center.clone(), attribute.paramAsType(LocationTag.class));
    });
    // <--[tag]
    // @attribute <EllipsoidTag.chunks>
    // @returns ListTag(ChunkTag)
    // @description
    // Returns a list of all chunks that this ellipsoid touches at all (note that no valid ellipsoid tag can ever totally contain a chunk, due to vertical limits and roundness).
    // -->
    tagProcessor.registerTag(ListTag.class, "chunks", (attribute, object) -> {
        ListTag chunks = new ListTag();
        double minPossibleX = object.center.getX() - object.size.getX();
        double minPossibleZ = object.center.getZ() - object.size.getZ();
        double maxPossibleX = object.center.getX() + object.size.getX();
        double maxPossibleZ = object.center.getZ() + object.size.getZ();
        int minChunkX = (int) Math.floor(minPossibleX / 16);
        int minChunkZ = (int) Math.floor(minPossibleZ / 16);
        int maxChunkX = (int) Math.ceil(maxPossibleX / 16);
        int maxChunkZ = (int) Math.ceil(maxPossibleZ / 16);
        ChunkTag testChunk = new ChunkTag(object.center);
        for (int x = minChunkX; x <= maxChunkX; x++) {
            testChunk.chunkX = x;
            for (int z = minChunkZ; z <= maxChunkZ; z++) {
                testChunk.chunkZ = z;
                if (object.intersects(testChunk)) {
                    chunks.addObject(new ChunkTag(testChunk.world, testChunk.chunkX, testChunk.chunkZ));
                }
            }
        }
        return chunks;
    });
    // <--[tag]
    // @attribute <EllipsoidTag.note_name>
    // @returns ElementTag
    // @description
    // Gets the name of a noted EllipsoidTag. If the ellipsoid isn't noted, this is null.
    // -->
    tagProcessor.registerTag(ElementTag.class, "note_name", (attribute, ellipsoid) -> {
        String noteName = NoteManager.getSavedId(ellipsoid);
        if (noteName == null) {
            return null;
        }
        return new ElementTag(noteName);
    });
}
Also used : ElementTag(com.denizenscript.denizencore.objects.core.ElementTag) Vector(org.bukkit.util.Vector) ListTag(com.denizenscript.denizencore.objects.core.ListTag)

Example 12 with ListTag

use of com.denizenscript.denizencore.objects.core.ListTag in project Denizen-For-Bukkit by DenizenScript.

the class EllipsoidTag method getShell.

@Override
public ListTag getShell() {
    ListTag output = new ListTag();
    double yScale = size.getY();
    int maxY = (int) Math.floor(yScale);
    output.addObject(new LocationTag(center.getBlockX(), center.getBlockY() - maxY, center.getBlockZ(), center.getWorldName()));
    if (maxY != 0) {
        output.addObject(new LocationTag(center.getBlockX(), center.getBlockY() + maxY, center.getBlockZ(), center.getWorldName()));
    }
    for (int y = -maxY; y <= maxY; y++) {
        double yProgMin = Math.min(1.0, (Math.abs(y) + 1) / yScale);
        double yProgMax = Math.abs(y) / yScale;
        double minSubWidth = Math.sqrt(1.0 - yProgMin * yProgMin);
        double maxSubWidth = Math.sqrt(1.0 - yProgMax * yProgMax);
        double minX = size.getX() * minSubWidth - 1;
        double minZ = size.getZ() * minSubWidth - 1;
        double maxX = size.getX() * maxSubWidth;
        double maxZ = size.getZ() * maxSubWidth;
        for (int x = 0; x < maxX; x++) {
            for (int z = 0; z < maxZ; z++) {
                double scaleTestMin = (x * x) / (minX * minX) + (z * z) / (minZ * minZ);
                double scaleTestMax = (x * x) / (maxX * maxX) + (z * z) / (maxZ * maxZ);
                if (scaleTestMin >= 1.0 && scaleTestMax <= 1.0) {
                    output.addObject(new LocationTag(center.getBlockX() + x, center.getBlockY() + y, center.getBlockZ() + z, center.getWorldName()));
                    if (x != 0) {
                        output.addObject(new LocationTag(center.getBlockX() - x, center.getBlockY() + y, center.getBlockZ() + z, center.getWorldName()));
                    }
                    if (z != 0) {
                        output.addObject(new LocationTag(center.getBlockX() + x, center.getBlockY() + y, center.getBlockZ() - z, center.getWorldName()));
                    }
                    if (x != 0 && z != 0) {
                        output.addObject(new LocationTag(center.getBlockX() - x, center.getBlockY() + y, center.getBlockZ() - z, center.getWorldName()));
                    }
                }
            }
        }
    }
    return output;
}
Also used : ListTag(com.denizenscript.denizencore.objects.core.ListTag)

Example 13 with ListTag

use of com.denizenscript.denizencore.objects.core.ListTag in project Denizen-For-Bukkit by DenizenScript.

the class InventoryTag method getEquipment.

public ListTag getEquipment() {
    ItemStack[] equipment = null;
    if (inventory instanceof PlayerInventory) {
        equipment = ((PlayerInventory) inventory).getArmorContents();
    } else if (inventory instanceof HorseInventory) {
        equipment = new ItemStack[] { ((HorseInventory) inventory).getSaddle(), ((HorseInventory) inventory).getArmor() };
    }
    if (equipment == null) {
        return null;
    }
    ListTag equipmentList = new ListTag();
    for (ItemStack item : equipment) {
        equipmentList.addObject(new ItemTag(item));
    }
    return equipmentList;
}
Also used : ListTag(com.denizenscript.denizencore.objects.core.ListTag)

Example 14 with ListTag

use of com.denizenscript.denizencore.objects.core.ListTag in project Denizen-For-Bukkit by DenizenScript.

the class LocationTag method adjust.

@Override
public void adjust(Mechanism mechanism) {
    // -->
    if (mechanism.matches("block_facing") && mechanism.requireObject(LocationTag.class)) {
        LocationTag faceVec = mechanism.valueAsType(LocationTag.class);
        Block block = getBlock();
        MaterialTag material = new MaterialTag(block);
        if (!MaterialDirectional.describes(material)) {
            mechanism.echoError("LocationTag.block_facing mechanism failed: block is not directional.");
            return;
        }
        MaterialDirectional.getFrom(material).setFacing(Utilities.faceFor(faceVec.toVector()));
        block.setBlockData(material.getModernData());
    }
    // -->
    if (mechanism.matches("block_type") && mechanism.requireObject(MaterialTag.class)) {
        MaterialTag mat = mechanism.valueAsType(MaterialTag.class);
        getBlock().setBlockData(mat.getModernData(), false);
    }
    // -->
    if (mechanism.matches("biome") && mechanism.requireObject(BiomeTag.class)) {
        mechanism.valueAsType(BiomeTag.class).getBiome().setTo(getBlock());
    }
    // -->
    if (mechanism.matches("spawner_custom_rules") && mechanism.requireObject(MapTag.class) && getBlockState() instanceof CreatureSpawner) {
        CreatureSpawner spawner = ((CreatureSpawner) getBlockState());
        MapTag map = mechanism.valueAsType(MapTag.class);
        ObjectTag skyMin = map.getObject("sky_min"), skyMax = map.getObject("sky_max"), blockMin = map.getObject("block_min"), blockMax = map.getObject("block_max");
        if (skyMin == null || skyMax == null || blockMin == null || blockMax == null) {
            mechanism.echoError("Invalid spawner_custom_rules input, missing map keys.");
            return;
        }
        NMSHandler.getBlockHelper().setSpawnerCustomRules(spawner, Integer.parseInt(skyMin.toString()), Integer.parseInt(skyMax.toString()), Integer.parseInt(blockMin.toString()), Integer.parseInt(blockMax.toString()));
        spawner.update();
    }
    // -->
    if (mechanism.matches("spawner_type") && mechanism.requireObject(EntityTag.class) && getBlockState() instanceof CreatureSpawner) {
        CreatureSpawner spawner = ((CreatureSpawner) getBlockState());
        NMSHandler.getBlockHelper().setSpawnerSpawnedType(spawner, mechanism.valueAsType(EntityTag.class));
        spawner.update();
    }
    // -->
    if (mechanism.matches("spawner_delay_data") && getBlockState() instanceof CreatureSpawner) {
        ListTag list = mechanism.valueAsType(ListTag.class);
        if (list.size() < 3) {
            return;
        }
        CreatureSpawner spawner = ((CreatureSpawner) getBlockState());
        spawner.setDelay(Integer.parseInt(list.get(0)));
        int minDelay = Integer.parseInt(list.get(1));
        int maxDelay = Integer.parseInt(list.get(2));
        // or new min would be higher than the current max
        if (minDelay > spawner.getMaxSpawnDelay()) {
            spawner.setMaxSpawnDelay(maxDelay);
            spawner.setMinSpawnDelay(minDelay);
        } else {
            spawner.setMinSpawnDelay(minDelay);
            spawner.setMaxSpawnDelay(maxDelay);
        }
        spawner.update();
    }
    // -->
    if (mechanism.matches("spawner_max_nearby_entities") && mechanism.requireInteger() && getBlockState() instanceof CreatureSpawner) {
        CreatureSpawner spawner = ((CreatureSpawner) getBlockState());
        spawner.setMaxNearbyEntities(mechanism.getValue().asInt());
        spawner.update();
    }
    // -->
    if (mechanism.matches("spawner_player_range") && mechanism.requireInteger() && getBlockState() instanceof CreatureSpawner) {
        CreatureSpawner spawner = ((CreatureSpawner) getBlockState());
        spawner.setRequiredPlayerRange(mechanism.getValue().asInt());
        spawner.update();
    }
    // -->
    if (mechanism.matches("spawner_range") && mechanism.requireInteger() && getBlockState() instanceof CreatureSpawner) {
        CreatureSpawner spawner = ((CreatureSpawner) getBlockState());
        spawner.setSpawnRange(mechanism.getValue().asInt());
        spawner.update();
    }
    // -->
    if (mechanism.matches("spawner_count") && mechanism.requireInteger() && getBlockState() instanceof CreatureSpawner) {
        CreatureSpawner spawner = ((CreatureSpawner) getBlockState());
        spawner.setSpawnCount(mechanism.getValue().asInt());
        spawner.update();
    }
    // -->
    if (mechanism.matches("lock") && getBlockState() instanceof Lockable) {
        BlockState state = getBlockState();
        ((Lockable) state).setLock(mechanism.hasValue() ? mechanism.getValue().asString() : null);
        state.update();
    }
    // -->
    if (mechanism.matches("sign_contents") && getBlockState() instanceof Sign) {
        Sign state = (Sign) getBlockState();
        for (int i = 0; i < 4; i++) {
            AdvancedTextImpl.instance.setSignLine(state, i, "");
        }
        ListTag list = mechanism.valueAsType(ListTag.class);
        CoreUtilities.fixNewLinesToListSeparation(list);
        if (list.size() > 4) {
            Debug.echoError("Sign can only hold four lines!");
        } else {
            for (int i = 0; i < list.size(); i++) {
                AdvancedTextImpl.instance.setSignLine(state, i, list.get(i));
            }
        }
        state.update();
    }
    // -->
    if (mechanism.matches("skull_skin")) {
        final BlockState blockState = getBlockState();
        Material material = getBlock().getType();
        if (blockState instanceof Skull) {
            ListTag list = mechanism.valueAsType(ListTag.class);
            String idString = list.get(0);
            String texture = null;
            if (list.size() > 1) {
                texture = list.get(1);
            }
            PlayerProfile profile;
            if (idString.contains("-")) {
                UUID uuid = UUID.fromString(idString);
                String name = null;
                if (list.size() > 2) {
                    name = list.get(2);
                }
                profile = new PlayerProfile(name, uuid, texture);
            } else {
                profile = new PlayerProfile(idString, null, texture);
            }
            profile = NMSHandler.getInstance().fillPlayerProfile(profile);
            if (texture != null) {
                // Ensure we didn't get overwritten
                profile.setTexture(texture);
            }
            NMSHandler.getBlockHelper().setPlayerProfile((Skull) blockState, profile);
        } else {
            Debug.echoError("Unable to set skull_skin on block of type " + material.name() + " with state " + blockState.getClass().getCanonicalName());
        }
    }
    // -->
    if (mechanism.matches("hive_max_bees") && mechanism.requireInteger()) {
        Beehive hive = (Beehive) getBlockState();
        hive.setMaxEntities(mechanism.getValue().asInt());
        hive.update();
    }
    // -->
    if (mechanism.matches("release_bees")) {
        Beehive hive = (Beehive) getBlockState();
        hive.releaseEntities();
        hive.update();
    }
    // -->
    if (mechanism.matches("add_bee") && mechanism.requireObject(EntityTag.class)) {
        Beehive hive = (Beehive) getBlockState();
        hive.addEntity((Bee) mechanism.valueAsType(EntityTag.class).getBukkitEntity());
        hive.update();
    }
    // -->
    if (mechanism.matches("command_block_name")) {
        if (getBlock().getState() instanceof CommandBlock) {
            CommandBlock block = ((CommandBlock) getBlockState());
            block.setName(mechanism.getValue().asString());
            block.update();
        }
    }
    // -->
    if (mechanism.matches("command_block")) {
        if (getBlock().getState() instanceof CommandBlock) {
            CommandBlock block = ((CommandBlock) getBlockState());
            block.setCommand(mechanism.getValue().asString());
            block.update();
        }
    }
    // -->
    if (mechanism.matches("custom_name")) {
        if (getBlockState() instanceof Nameable) {
            String title = null;
            if (mechanism.hasValue()) {
                title = mechanism.getValue().asString();
            }
            BlockState state = getBlockState();
            ((Nameable) state).setCustomName(title);
            state.update(true);
        }
    }
    // -->
    if (mechanism.matches("brewing_time")) {
        if (getBlockState() instanceof BrewingStand) {
            BrewingStand stand = (BrewingStand) getBlockState();
            stand.setBrewingTime(mechanism.valueAsType(DurationTag.class).getTicksAsInt());
            stand.update();
        }
    }
    // -->
    if (mechanism.matches("brewing_fuel_level")) {
        if (getBlockState() instanceof BrewingStand) {
            BrewingStand stand = (BrewingStand) getBlockState();
            stand.setFuelLevel(mechanism.getValue().asInt());
            stand.update();
        }
    }
    // -->
    if (mechanism.matches("furnace_burn_duration") && mechanism.requireObject(DurationTag.class)) {
        if (getBlockState() instanceof Furnace) {
            Furnace furnace = (Furnace) getBlockState();
            furnace.setBurnTime((short) mechanism.valueAsType(DurationTag.class).getTicks());
            furnace.update();
        }
    }
    if (mechanism.matches("furnace_burn_time")) {
        Deprecations.furnaceTimeTags.warn(mechanism.context);
        if (getBlockState() instanceof Furnace) {
            Furnace furnace = (Furnace) getBlockState();
            furnace.setBurnTime((short) mechanism.getValue().asInt());
            furnace.update();
        }
    }
    // -->
    if (mechanism.matches("furnace_cook_duration")) {
        if (getBlockState() instanceof Furnace) {
            Furnace furnace = (Furnace) getBlockState();
            furnace.setCookTime((short) mechanism.valueAsType(DurationTag.class).getTicks());
            furnace.update();
        }
    }
    if (mechanism.matches("furnace_cook_time")) {
        Deprecations.furnaceTimeTags.warn(mechanism.context);
        if (getBlockState() instanceof Furnace) {
            Furnace furnace = (Furnace) getBlockState();
            furnace.setCookTime((short) mechanism.getValue().asInt());
            furnace.update();
        }
    }
    // -->
    if (mechanism.matches("furnace_cook_duration_total")) {
        if (getBlockState() instanceof Furnace) {
            Furnace furnace = (Furnace) getBlockState();
            furnace.setCookTimeTotal((short) mechanism.valueAsType(DurationTag.class).getTicks());
            furnace.update();
        }
    }
    if (mechanism.matches("furnace_cook_time_total")) {
        Deprecations.furnaceTimeTags.warn(mechanism.context);
        if (getBlockState() instanceof Furnace) {
            Furnace furnace = (Furnace) getBlockState();
            furnace.setCookTimeTotal((short) mechanism.getValue().asInt());
            furnace.update();
        }
    }
    // -->
    if (mechanism.matches("patterns")) {
        List<org.bukkit.block.banner.Pattern> patterns = new ArrayList<>();
        ListTag list = mechanism.valueAsType(ListTag.class);
        List<String> split;
        for (String string : list) {
            try {
                split = CoreUtilities.split(string, '/', 2);
                patterns.add(new org.bukkit.block.banner.Pattern(DyeColor.valueOf(split.get(0).toUpperCase()), PatternType.valueOf(split.get(1).toUpperCase())));
            } catch (Exception e) {
                Debug.echoError("Could not apply pattern to banner: " + string);
            }
        }
        Banner banner = (Banner) getBlockState();
        banner.setPatterns(patterns);
        banner.update();
    }
    // -->
    if (mechanism.matches("head_rotation") && mechanism.requireInteger()) {
        Skull sk = (Skull) getBlockState();
        sk.setRotation(getSkullBlockFace(mechanism.getValue().asInt() - 1));
        sk.update();
    }
    // -->
    if (mechanism.matches("generate_tree") && mechanism.requireEnum(TreeType.class)) {
        boolean generated = getWorld().generateTree(this, TreeType.valueOf(mechanism.getValue().asString().toUpperCase()));
        if (!generated) {
            Debug.echoError("Could not generate tree at " + identifySimple() + ". Make sure this location can naturally generate a tree!");
        }
    }
    // -->
    if (mechanism.matches("beacon_primary_effect")) {
        Beacon beacon = (Beacon) getBlockState();
        beacon.setPrimaryEffect(PotionEffectType.getByName(mechanism.getValue().asString().toUpperCase()));
        beacon.update();
    }
    // -->
    if (mechanism.matches("beacon_secondary_effect")) {
        Beacon beacon = (Beacon) getBlockState();
        beacon.setSecondaryEffect(PotionEffectType.getByName(mechanism.getValue().asString().toUpperCase()));
        beacon.update();
    }
    // -->
    if (mechanism.matches("activate")) {
        BlockState state = getBlockState();
        if (state instanceof Dispenser) {
            ((Dispenser) state).dispense();
        } else if (state instanceof Dropper) {
            ((Dropper) state).drop();
        } else {
            Debug.echoError("'activate' mechanism does not work for blocks of type: " + state.getType().name());
        }
    }
    // -->
    if (mechanism.matches("lectern_page") && mechanism.requireInteger()) {
        BlockState state = getBlockState();
        if (state instanceof Lectern) {
            ((Lectern) state).setPage(mechanism.getValue().asInt());
            state.update();
        } else {
            Debug.echoError("'lectern_page' mechanism can only be called on a lectern block.");
        }
    }
    // -->
    if (mechanism.matches("clear_loot_table")) {
        BlockState state = getBlockState();
        if (state instanceof Lootable) {
            ((Lootable) state).setLootTable(null);
            state.update();
        } else {
            Debug.echoError("'clear_loot_table' mechanism can only be called on a lootable block (like a chest).");
        }
    }
    // -->
    if (mechanism.matches("jukebox_record")) {
        BlockState state = getBlockState();
        if (state instanceof Jukebox) {
            if (mechanism.hasValue() && mechanism.requireObject(ItemTag.class)) {
                ((Jukebox) state).setRecord(mechanism.valueAsType(ItemTag.class).getItemStack());
            } else {
                NMSHandler.getBlockHelper().makeBlockStateRaw(state);
                ((Jukebox) state).setRecord(null);
            }
            state.update();
        } else {
            Debug.echoError("'jukebox_record' mechanism can only be called on a jukebox block.");
        }
    }
    // -->
    if (mechanism.matches("jukebox_play") && mechanism.requireBoolean()) {
        BlockState state = getBlockState();
        if (state instanceof Jukebox) {
            if (mechanism.getValue().asBoolean()) {
                Material mat = ((Jukebox) state).getRecord().getType();
                if (mat == Material.AIR) {
                    Debug.echoError("'jukebox_play' cannot play nothing.");
                    return;
                }
                ((Jukebox) state).setPlaying(mat);
            } else {
                ((Jukebox) state).stopPlaying();
            }
            state.update();
        } else {
            Debug.echoError("'jukebox_play' mechanism can only be called on a jukebox block.");
        }
    }
    // -->
    if (mechanism.matches("age") && mechanism.requireObject(DurationTag.class)) {
        BlockState state = getBlockState();
        if (state instanceof EndGateway) {
            ((EndGateway) state).setAge(mechanism.valueAsType(DurationTag.class).getTicks());
            state.update();
        } else {
            Debug.echoError("'age' mechanism can only be called on end gateway blocks.");
        }
    }
    // -->
    if (mechanism.matches("is_exact_teleport") && mechanism.requireBoolean()) {
        BlockState state = getBlockState();
        if (state instanceof EndGateway) {
            ((EndGateway) state).setExactTeleport(mechanism.getValue().asBoolean());
            state.update();
        } else {
            Debug.echoError("'is_exact_teleport' mechanism can only be called on end gateway blocks.");
        }
    }
    // -->
    if (mechanism.matches("exit_location") && mechanism.requireObject(LocationTag.class)) {
        BlockState state = getBlockState();
        if (state instanceof EndGateway) {
            ((EndGateway) state).setExitLocation(mechanism.valueAsType(LocationTag.class));
            state.update();
        } else {
            Debug.echoError("'exit_location' mechanism can only be called on end gateway blocks.");
        }
    }
    // -->
    if (mechanism.matches("vanilla_tick")) {
        NMSHandler.getBlockHelper().doRandomTick(this);
    }
    // -->
    if (mechanism.matches("apply_bonemeal") && mechanism.requireEnum(BlockFace.class)) {
        getBlock().applyBoneMeal(BlockFace.valueOf(mechanism.getValue().asString().toUpperCase()));
    }
    // -->
    if (mechanism.matches("campfire_items") && mechanism.requireObject(ListTag.class)) {
        BlockState state = getBlockState();
        if (!(state instanceof Campfire)) {
            Debug.echoError("'campfire_items' mechanism can only be called on campfire blocks.");
        } else {
            Campfire fire = (Campfire) state;
            List<ItemTag> list = mechanism.valueAsType(ListTag.class).filter(ItemTag.class, mechanism.context);
            for (int i = 0; i < list.size(); i++) {
                if (i >= fire.getSize()) {
                    Debug.echoError("Cannot add item for index " + (i + 1) + " as the campfire can only hold " + fire.getSize() + " items.");
                    break;
                }
                fire.setItem(i, list.get(i).getItemStack());
            }
            fire.update();
        }
    }
    // -->
    if (mechanism.matches("ring_bell")) {
        BlockState state = getBlockState();
        if (!(state instanceof Bell)) {
            Debug.echoError("'ring_bell' mechanism can only be called on Bell blocks.");
        } else {
            NMSHandler.getBlockHelper().ringBell((Bell) state);
        }
    }
    // -->
    if (mechanism.matches("sign_glowing") && mechanism.requireBoolean()) {
        BlockState state = getBlockState();
        if (!(state instanceof Sign)) {
            Debug.echoError("'sign_glowing' mechanism can only be called on Sign blocks.");
        } else {
            Sign sign = (Sign) state;
            sign.setGlowingText(mechanism.getValue().asBoolean());
            sign.update();
        }
    }
    // -->
    if (mechanism.matches("sign_glow_color") && mechanism.requireEnum(DyeColor.class)) {
        BlockState state = getBlockState();
        if (!(state instanceof Sign)) {
            Debug.echoError("'sign_glow_color' mechanism can only be called on Sign blocks.");
        } else {
            Sign sign = (Sign) state;
            sign.setColor(mechanism.getValue().asEnum(DyeColor.class));
            sign.update();
        }
    }
    CoreUtilities.autoPropertyMechanism(this, mechanism);
}
Also used : org.bukkit(org.bukkit) Lootable(org.bukkit.loot.Lootable) org.bukkit.block(org.bukkit.block) PlayerProfile(com.denizenscript.denizen.nms.util.PlayerProfile) DurationTag(com.denizenscript.denizencore.objects.core.DurationTag) MapTag(com.denizenscript.denizencore.objects.core.MapTag) ListTag(com.denizenscript.denizencore.objects.core.ListTag)

Example 15 with ListTag

use of com.denizenscript.denizencore.objects.core.ListTag in project Denizen-For-Bukkit by DenizenScript.

the class NPCTag method registerTags.

public static void registerTags() {
    AbstractFlagTracker.registerFlagHandlers(tagProcessor);
    // Defined in EntityTag
    tagProcessor.registerTag(ElementTag.class, "is_npc", (attribute, object) -> {
        return new ElementTag(true);
    });
    // Defined in EntityTag
    tagProcessor.registerTag(ObjectTag.class, "location", (attribute, object) -> {
        if (attribute.startsWith("previous_location", 2)) {
            attribute.fulfill(1);
            Deprecations.npcPreviousLocationTag.warn(attribute.context);
            return NPCTagBase.previousLocations.get(object.getId());
        }
        if (object.isSpawned()) {
            return new EntityTag(object).doLocationTag(attribute);
        }
        return object.getLocation();
    });
    // <--[tag]
    // @attribute <NPCTag.previous_location>
    // @returns LocationTag
    // @description
    // Returns the NPC's previous navigated location.
    // -->
    tagProcessor.registerTag(LocationTag.class, "previous_location", (attribute, object) -> {
        return NPCTagBase.previousLocations.get(object.getId());
    });
    // Defined in EntityTag
    tagProcessor.registerTag(LocationTag.class, "eye_location", (attribute, object) -> {
        return object.getEyeLocation();
    });
    // <--[tag]
    // @attribute <NPCTag.has_nickname>
    // @returns ElementTag(Boolean)
    // @description
    // Returns true if the NPC has a nickname.
    // -->
    tagProcessor.registerTag(ElementTag.class, "has_nickname", (attribute, object) -> {
        NPC citizen = object.getCitizen();
        return new ElementTag(citizen.hasTrait(NicknameTrait.class) && citizen.getOrAddTrait(NicknameTrait.class).hasNickname());
    });
    // <--[tag]
    // @attribute <NPCTag.is_sitting>
    // @returns ElementTag(Boolean)
    // @description
    // Returns true if the NPC is sitting. Relates to <@link command sit>.
    // -->
    tagProcessor.registerTag(ElementTag.class, "is_sitting", (attribute, object) -> {
        NPC citizen = object.getCitizen();
        return new ElementTag(citizen.hasTrait(SittingTrait.class) && citizen.getOrAddTrait(SittingTrait.class).isSitting());
    });
    // <--[tag]
    // @attribute <NPCTag.is_sleeping>
    // @returns ElementTag(Boolean)
    // @description
    // Returns true if the NPC is sleeping. Relates to <@link command sleep>.
    // -->
    tagProcessor.registerTag(ElementTag.class, "is_sleeping", (attribute, object) -> {
        NPC citizen = object.getCitizen();
        return new ElementTag(citizen.hasTrait(SleepingTrait.class) && citizen.getOrAddTrait(SleepingTrait.class).isSleeping());
    });
    // <--[tag]
    // @attribute <NPCTag.nickname>
    // @returns ElementTag
    // @description
    // Returns the NPC's display name, as set by the Nickname trait (or the default NPC name).
    // -->
    tagProcessor.registerTag(ElementTag.class, "nickname", (attribute, object) -> {
        return new ElementTag(object.getCitizen().hasTrait(NicknameTrait.class) ? object.getCitizen().getOrAddTrait(NicknameTrait.class).getNickname() : object.getName());
    });
    // Documented in EntityTag
    tagProcessor.registerTag(ElementTag.class, "name", (attribute, object) -> {
        if (attribute.startsWith("nickname", 2)) {
            Deprecations.npcNicknameTag.warn(attribute.context);
            attribute.fulfill(1);
            return new ElementTag(object.getCitizen().hasTrait(NicknameTrait.class) ? object.getCitizen().getOrAddTrait(NicknameTrait.class).getNickname() : object.getName());
        }
        return new ElementTag(object.getName());
    });
    // <--[tag]
    // @attribute <NPCTag.traits>
    // @returns ListTag
    // @description
    // Returns a list of all of the NPC's traits.
    // -->
    tagProcessor.registerTag(ListTag.class, "traits", (attribute, object) -> {
        List<String> list = new ArrayList<>();
        for (Trait trait : object.getCitizen().getTraits()) {
            list.add(trait.getName());
        }
        return new ListTag(list);
    }, "list_traits");
    // <--[tag]
    // @attribute <NPCTag.has_trait[<trait>]>
    // @returns ElementTag(Boolean)
    // @description
    // Returns whether the NPC has a specified trait.
    // -->
    tagProcessor.registerTag(ElementTag.class, "has_trait", (attribute, object) -> {
        if (attribute.hasParam()) {
            Class<? extends Trait> trait = CitizensAPI.getTraitFactory().getTraitClass(attribute.getParam());
            if (trait != null) {
                return new ElementTag(object.getCitizen().hasTrait(trait));
            }
        }
        return null;
    });
    // <--[tag]
    // @attribute <NPCTag.pushable>
    // @returns ElementTag(Boolean)
    // @description
    // Returns whether the NPC is pushable.
    // -->
    tagProcessor.registerTag(ElementTag.class, "pushable", (attribute, object) -> {
        return new ElementTag(object.getPushableTrait().isPushable());
    }, "is_pushable");
    // <--[tag]
    // @attribute <NPCTag.has_trigger[<trigger>]>
    // @returns ElementTag(Boolean)
    // @description
    // Returns whether the NPC has a specified trigger.
    // -->
    tagProcessor.registerTag(ElementTag.class, "has_trigger", (attribute, object) -> {
        if (!attribute.hasParam()) {
            return null;
        }
        if (!object.getCitizen().hasTrait(TriggerTrait.class)) {
            return new ElementTag(false);
        }
        TriggerTrait trait = object.getCitizen().getOrAddTrait(TriggerTrait.class);
        return new ElementTag(trait.hasTrigger(attribute.getParam()));
    });
    // <--[tag]
    // @attribute <NPCTag.has_anchors>
    // @returns ElementTag(Boolean)
    // @description
    // Returns whether the NPC has anchors assigned.
    // -->
    tagProcessor.registerTag(ElementTag.class, "has_anchors", (attribute, object) -> {
        return (new ElementTag(object.getCitizen().getOrAddTrait(Anchors.class).getAnchors().size() > 0));
    });
    // <--[tag]
    // @attribute <NPCTag.list_anchors>
    // @returns ListTag
    // @description
    // Returns a list of anchor names currently assigned to the NPC.
    // -->
    tagProcessor.registerTag(ListTag.class, "list_anchors", (attribute, object) -> {
        ListTag list = new ListTag();
        for (Anchor anchor : object.getCitizen().getOrAddTrait(Anchors.class).getAnchors()) {
            list.add(anchor.getName());
        }
        return list;
    });
    // <--[tag]
    // @attribute <NPCTag.anchor[<name>]>
    // @returns LocationTag
    // @description
    // Returns the location associated with the specified anchor, or null if it doesn't exist.
    // -->
    tagProcessor.registerTag(ObjectTag.class, "anchor", (attribute, object) -> {
        Anchors trait = object.getCitizen().getOrAddTrait(Anchors.class);
        if (attribute.hasParam()) {
            Anchor anchor = trait.getAnchor(attribute.getParam());
            if (anchor != null) {
                return new LocationTag(anchor.getLocation());
            } else {
                attribute.echoError("NPC Anchor '" + attribute.getParam() + "' is not defined.");
                return null;
            }
        } else if (attribute.startsWith("list", 2)) {
            attribute.fulfill(1);
            Deprecations.npcAnchorListTag.warn(attribute.context);
            ListTag list = new ListTag();
            for (Anchor anchor : trait.getAnchors()) {
                list.add(anchor.getName());
            }
            return list;
        } else {
            attribute.echoError("npc.anchor[...] tag must have an input.");
        }
        return null;
    }, "anchors");
    // <--[tag]
    // @attribute <NPCTag.constant[<constant_name>]>
    // @returns ElementTag
    // @description
    // Returns the specified constant from the NPC.
    // -->
    tagProcessor.registerTag(ElementTag.class, "constant", (attribute, object) -> {
        if (attribute.hasParam()) {
            if (object.getCitizen().hasTrait(ConstantsTrait.class) && object.getCitizen().getOrAddTrait(ConstantsTrait.class).getConstant(attribute.getParam()) != null) {
                return new ElementTag(object.getCitizen().getOrAddTrait(ConstantsTrait.class).getConstant(attribute.getParam()));
            } else {
                return null;
            }
        }
        return null;
    });
    // <--[tag]
    // @attribute <NPCTag.has_pose[<name>]>
    // @returns ElementTag(Boolean)
    // @description
    // Returns true if the NPC has the specified pose, otherwise returns false.
    // -->
    tagProcessor.registerTag(ElementTag.class, "has_pose", (attribute, object) -> {
        if (attribute.hasParam()) {
            return new ElementTag(object.getCitizen().getOrAddTrait(Poses.class).hasPose(attribute.getParam()));
        } else {
            return null;
        }
    });
    // <--[tag]
    // @attribute <NPCTag.pose[<name>]>
    // @returns LocationTag
    // @description
    // Returns the pose as a LocationTag with x, y, and z set to 0, and the world set to the first
    // possible available world Bukkit knows about.
    // -->
    tagProcessor.registerTag(LocationTag.class, "pose", (attribute, object) -> {
        if (attribute.hasParam()) {
            Pose pose = object.getCitizen().getOrAddTrait(Poses.class).getPose(attribute.getParam());
            return new LocationTag(org.bukkit.Bukkit.getWorlds().get(0), 0, 0, 0, pose.getYaw(), pose.getPitch());
        } else {
            return null;
        }
    }, "get_pose");
    // <--[tag]
    // @attribute <NPCTag.name_hologram_npc>
    // @returns NPCTag
    // @description
    // Returns the NPCTag of a hologram attached to this NPC as its nameplate (if any).
    // Note that this can regenerate at any time.
    // -->
    tagProcessor.registerTag(ObjectTag.class, "name_hologram_npc", (attribute, object) -> {
        if (!object.getCitizen().hasTrait(HologramTrait.class)) {
            return null;
        }
        HologramTrait hologram = object.getCitizen().getTraitNullable(HologramTrait.class);
        Entity entity = hologram.getNameEntity();
        if (entity == null) {
            return null;
        }
        return new EntityTag(entity).getDenizenObject();
    });
    // <--[tag]
    // @attribute <NPCTag.hologram_npcs>
    // @returns ListTag(NPCTag)
    // @description
    // Returns the list of hologram NPCs attached to an NPC (if any).
    // Note that these can regenerate at any time.
    // -->
    tagProcessor.registerTag(ListTag.class, "hologram_npcs", (attribute, object) -> {
        if (!object.getCitizen().hasTrait(HologramTrait.class)) {
            return null;
        }
        HologramTrait hologram = object.getCitizen().getTraitNullable(HologramTrait.class);
        Collection<ArmorStand> stands = hologram.getHologramEntities();
        if (stands == null || stands.isEmpty()) {
            return null;
        }
        ListTag output = new ListTag();
        for (ArmorStand stand : stands) {
            output.addObject(new EntityTag(stand).getDenizenObject());
        }
        return output;
    });
    // <--[tag]
    // @attribute <NPCTag.hologram_lines>
    // @returns ListTag
    // @mechanism NPCTag.hologram_lines
    // @description
    // Returns the list of hologram lines attached to an NPC.
    // -->
    tagProcessor.registerTag(ListTag.class, "hologram_lines", (attribute, object) -> {
        if (!object.getCitizen().hasTrait(HologramTrait.class)) {
            return null;
        }
        HologramTrait hologram = object.getCitizen().getTraitNullable(HologramTrait.class);
        return new ListTag(hologram.getLines());
    });
    // <--[tag]
    // @attribute <NPCTag.hologram_direction>
    // @returns ElementTag
    // @mechanism NPCTag.hologram_direction
    // @description
    // Returns the direction of an NPC's hologram as "BOTTOM_UP" or "TOP_DOWN".
    // -->
    tagProcessor.registerTag(ElementTag.class, "hologram_direction", (attribute, object) -> {
        if (!object.getCitizen().hasTrait(HologramTrait.class)) {
            return null;
        }
        HologramTrait hologram = object.getCitizen().getTraitNullable(HologramTrait.class);
        return new ElementTag(hologram.getDirection().name());
    });
    // <--[tag]
    // @attribute <NPCTag.hologram_line_height>
    // @returns ElementTag(Decimal)
    // @mechanism NPCTag.hologram_line_height
    // @description
    // Returns the line height for an NPC's hologram. Can be -1, indicating a default value should be used.
    // -->
    tagProcessor.registerTag(ElementTag.class, "hologram_line_height", (attribute, object) -> {
        if (!object.getCitizen().hasTrait(HologramTrait.class)) {
            return null;
        }
        HologramTrait hologram = object.getCitizen().getTraitNullable(HologramTrait.class);
        return new ElementTag(hologram.getLineHeight());
    });
    // <--[tag]
    // @attribute <NPCTag.is_sneaking>
    // @returns ElementTag(Boolean)
    // @description
    // Returns whether the NPC is currently sneaking. Only works for player-type NPCs.
    // -->
    tagProcessor.registerTag(ElementTag.class, "is_sneaking", (attribute, object) -> {
        if (!object.isSpawned() && object.getEntity() instanceof Player) {
            return null;
        }
        return new ElementTag(((Player) object.getEntity()).isSneaking());
    });
    // <--[tag]
    // @attribute <NPCTag.engaged[(<player>)]>
    // @returns ElementTag(Boolean)
    // @description
    // Returns whether the NPC is currently engaged.
    // See <@link command engage>
    // -->
    tagProcessor.registerTag(ElementTag.class, "engaged", (attribute, object) -> {
        return new ElementTag(EngageCommand.getEngaged(object.getCitizen(), attribute.hasParam() ? attribute.paramAsType(PlayerTag.class) : null));
    }, "is_engaged");
    // <--[tag]
    // @attribute <NPCTag.invulnerable>
    // @returns ElementTag(Boolean)
    // @description
    // Returns whether the NPC is currently invulnerable.
    // See <@link command vulnerable>
    // -->
    tagProcessor.registerTag(ElementTag.class, "invulnerable", (attribute, object) -> {
        return new ElementTag(object.getCitizen().data().get(NPC.DEFAULT_PROTECTED_METADATA, true));
    }, "vulnerable");
    // <--[tag]
    // @attribute <NPCTag.id>
    // @returns ElementTag(Number)
    // @description
    // Returns the NPC's ID number.
    // -->
    tagProcessor.registerTag(ElementTag.class, "id", (attribute, object) -> {
        return new ElementTag(object.getId());
    });
    // <--[tag]
    // @attribute <NPCTag.owner>
    // @returns PlayerTag
    // @mechanism NPCTag.owner
    // @description
    // Returns the owner of the NPC as a PlayerTag, if any.
    // -->
    tagProcessor.registerTag(ObjectTag.class, "owner", (attribute, object) -> {
        UUID owner = object.getOwner();
        if (owner == null) {
            return null;
        }
        OfflinePlayer player = Bukkit.getOfflinePlayer(owner);
        if (player.isOnline() || player.hasPlayedBefore()) {
            return new PlayerTag(player);
        }
        return null;
    });
    // <--[tag]
    // @attribute <NPCTag.has_skin>
    // @returns ElementTag(Boolean)
    // @mechanism NPCTag.skin
    // @description
    // Returns whether the NPC has a custom skin.
    // -->
    tagProcessor.registerTag(ElementTag.class, "has_skin", (attribute, object) -> {
        return new ElementTag(object.getCitizen().hasTrait(SkinTrait.class) && object.getCitizen().getOrAddTrait(SkinTrait.class).getSkinName() != null);
    });
    // <--[tag]
    // @attribute <NPCTag.skin_blob>
    // @returns ElementTag
    // @mechanism NPCTag.skin_blob
    // @description
    // Returns the NPC's custom skin blob, if any.
    // In the format: "texture;signature" (two values separated by a semicolon).
    // See also <@link language Player Entity Skins (Skin Blobs)>.
    // -->
    tagProcessor.registerTag(ElementTag.class, "skin_blob", (attribute, object) -> {
        if (object.getCitizen().hasTrait(SkinTrait.class)) {
            SkinTrait skin = object.getCitizen().getOrAddTrait(SkinTrait.class);
            String tex = skin.getTexture();
            String sign = "";
            if (skin.getSignature() != null) {
                sign = ";" + skin.getSignature();
            }
            return new ElementTag(tex + sign);
        }
        return null;
    });
    // <--[tag]
    // @attribute <NPCTag.skull_skin>
    // @returns ElementTag
    // @description
    // Returns the NPC's current skin blob, formatted for input to a Player Skull item.
    // In the format: "UUID|Texture" (two values separated by pipes).
    // See also <@link language Player Entity Skins (Skin Blobs)>.
    // -->
    tagProcessor.registerTag(ElementTag.class, "skull_skin", (attribute, object) -> {
        if (!object.getCitizen().hasTrait(SkinTrait.class)) {
            return null;
        }
        SkinTrait skin = object.getCitizen().getOrAddTrait(SkinTrait.class);
        return new ElementTag(skin.getSkinName() + "|" + skin.getTexture());
    });
    // <--[tag]
    // @attribute <NPCTag.skin>
    // @returns ElementTag
    // @mechanism NPCTag.skin
    // @description
    // Returns the NPC's custom skin, if any.
    // -->
    tagProcessor.registerTag(ElementTag.class, "skin", (attribute, object) -> {
        if (object.getCitizen().hasTrait(SkinTrait.class)) {
            return new ElementTag(object.getCitizen().getOrAddTrait(SkinTrait.class).getSkinName());
        }
        return null;
    });
    // <--[tag]
    // @attribute <NPCTag.auto_update_skin>
    // @returns ElementTag(Boolean)
    // @mechanism NPCTag.auto_update_skin
    // @description
    // Returns whether the NPC is set to automatically update skins from name.
    // -->
    tagProcessor.registerTag(ElementTag.class, "auto_update_skin", (attribute, object) -> {
        if (object.getCitizen().hasTrait(SkinTrait.class)) {
            return new ElementTag(object.getCitizen().getOrAddTrait(SkinTrait.class).shouldUpdateSkins());
        }
        return null;
    });
    // <--[tag]
    // @attribute <NPCTag.inventory>
    // @returns InventoryTag
    // @description
    // Returns the InventoryTag of the NPC.
    // -->
    tagProcessor.registerTag(InventoryTag.class, "inventory", (attribute, object) -> {
        return object.getDenizenInventory();
    });
    // <--[tag]
    // @attribute <NPCTag.is_spawned>
    // @returns ElementTag(Boolean)
    // @description
    // Returns whether the NPC is spawned.
    // -->
    tagProcessor.registerTag(ElementTag.class, "is_spawned", (attribute, object) -> {
        return new ElementTag(object.isSpawned());
    });
    // <--[tag]
    // @attribute <NPCTag.is_protected>
    // @returns ElementTag(Boolean)
    // @description
    // Returns whether the NPC is protected.
    // -->
    tagProcessor.registerTag(ElementTag.class, "is_protected", (attribute, object) -> {
        return new ElementTag(object.getCitizen().isProtected());
    });
    // <--[tag]
    // @attribute <NPCTag.lookclose>
    // @returns ElementTag(Boolean)
    // @mechanism NPCTag.lookclose
    // @description
    // Returns whether the NPC has lookclose enabled.
    // -->
    tagProcessor.registerTag(ElementTag.class, "lookclose", (attribute, object) -> {
        NPC citizen = object.getCitizen();
        if (citizen.hasTrait(LookClose.class)) {
            // There is no method to check if the NPC has LookClose enabled...
            // LookClose.toString() returns "LookClose{" + enabled + "}"
            String lookclose = citizen.getOrAddTrait(LookClose.class).toString();
            lookclose = lookclose.substring(10, lookclose.length() - 1);
            return new ElementTag(Boolean.valueOf(lookclose));
        }
        return new ElementTag(false);
    });
    // <--[tag]
    // @attribute <NPCTag.controllable>
    // @returns ElementTag(Boolean)
    // @mechanism NPCTag.controllable
    // @description
    // Returns whether the NPC has controllable enabled.
    // -->
    tagProcessor.registerTag(ElementTag.class, "controllable", (attribute, object) -> {
        if (object.getCitizen().hasTrait(Controllable.class)) {
            return new ElementTag(object.getCitizen().getOrAddTrait(Controllable.class).isEnabled());
        }
        return new ElementTag(false);
    });
    // <--[tag]
    // @attribute <NPCTag.targetable>
    // @returns ElementTag(Boolean)
    // @mechanism NPCTag.targetable
    // @description
    // Returns whether the NPC is targetable.
    // -->
    tagProcessor.registerTag(ElementTag.class, "targetable", (attribute, object) -> {
        boolean targetable = object.getCitizen().data().get(NPC.TARGETABLE_METADATA, object.getCitizen().data().get(NPC.DEFAULT_PROTECTED_METADATA, true));
        return new ElementTag(targetable);
    });
    // <--[tag]
    // @attribute <NPCTag.teleport_on_stuck>
    // @returns ElementTag(Boolean)
    // @mechanism NPCTag.teleport_on_stuck
    // @description
    // Returns whether the NPC teleports when it is stuck.
    // -->
    tagProcessor.registerTag(ElementTag.class, "teleport_on_stuck", (attribute, object) -> {
        return new ElementTag(object.getNavigator().getDefaultParameters().stuckAction() == TeleportStuckAction.INSTANCE);
    });
    tagProcessor.registerTag(ElementTag.class, "has_script", (attribute, object) -> {
        Deprecations.hasScriptTags.warn(attribute.context);
        NPC citizen = object.getCitizen();
        return new ElementTag(citizen.hasTrait(AssignmentTrait.class));
    });
    // <--[tag]
    // @attribute <NPCTag.script>
    // @returns ScriptTag
    // @deprecated Use 'NPCTag.scripts' (plural) instead.
    // @description
    // Deprecated variant of <@link tag NPCTag.scripts>.
    // -->
    tagProcessor.registerTag(ScriptTag.class, "script", (attribute, object) -> {
        Deprecations.npcScriptSingle.warn(attribute.context);
        NPC citizen = object.getCitizen();
        if (!citizen.hasTrait(AssignmentTrait.class)) {
            return null;
        } else {
            for (AssignmentScriptContainer container : citizen.getOrAddTrait(AssignmentTrait.class).containerCache) {
                if (container != null) {
                    return new ScriptTag(container);
                }
            }
            return null;
        }
    });
    // <--[tag]
    // @attribute <NPCTag.scripts>
    // @returns ListTag(ScriptTag)
    // @description
    // Returns a list of all assignment scripts on the NPC. Returns null if none.
    // -->
    tagProcessor.registerTag(ListTag.class, "scripts", (attribute, object) -> {
        NPC citizen = object.getCitizen();
        if (!citizen.hasTrait(AssignmentTrait.class)) {
            return null;
        } else {
            ListTag result = new ListTag();
            for (AssignmentScriptContainer container : citizen.getOrAddTrait(AssignmentTrait.class).containerCache) {
                if (container != null) {
                    result.addObject(new ScriptTag(container));
                }
            }
            return result;
        }
    });
    // <--[tag]
    // @attribute <NPCTag.distance_margin>
    // @returns ElementTag(Decimal)
    // @mechanism NPCTag.distance_margin
    // @description
    // Returns the NPC's current pathfinding distance margin. That is, how close it needs to get to its destination (in block-lengths).
    // -->
    tagProcessor.registerTag(ElementTag.class, "distance_margin", (attribute, object) -> {
        return new ElementTag(object.getNavigator().getDefaultParameters().distanceMargin());
    });
    // <--[tag]
    // @attribute <NPCTag.path_distance_margin>
    // @returns ElementTag(Decimal)
    // @mechanism NPCTag.path_distance_margin
    // @description
    // Returns the NPC's current pathfinding distance margin. That is, how close it needs to get to individual points along its path.
    // -->
    tagProcessor.registerTag(ElementTag.class, "path_distance_margin", (attribute, object) -> {
        return new ElementTag(object.getNavigator().getDefaultParameters().pathDistanceMargin());
    });
    // <--[tag]
    // @attribute <NPCTag.is_navigating>
    // @returns ElementTag(Boolean)
    // @description
    // Returns whether the NPC is currently navigating.
    // -->
    tagProcessor.registerTag(ElementTag.class, "is_navigating", (attribute, object) -> {
        return new ElementTag(object.getNavigator().isNavigating());
    });
    // <--[tag]
    // @attribute <NPCTag.speed>
    // @returns ElementTag(Decimal)
    // @mechanism NPCTag.speed
    // @description
    // Returns the current speed of the NPC.
    // -->
    tagProcessor.registerTag(ElementTag.class, "speed", (attribute, object) -> {
        return new ElementTag(object.getNavigator().getLocalParameters().speed());
    });
    // <--[tag]
    // @attribute <NPCTag.range>
    // @returns ElementTag(Decimal)
    // @mechanism NPCTag.range
    // @description
    // Returns the NPC's current maximum pathfinding range.
    // -->
    tagProcessor.registerTag(ElementTag.class, "range", (attribute, object) -> {
        return new ElementTag(object.getNavigator().getLocalParameters().range());
    });
    // <--[tag]
    // @attribute <NPCTag.attack_range>
    // @returns ElementTag(Decimal)
    // @mechanism NPCTag.attack_range
    // @description
    // Returns the NPC's current navigator attack range limit.
    // -->
    tagProcessor.registerTag(ElementTag.class, "attack_range", (attribute, object) -> {
        return new ElementTag(object.getNavigator().getLocalParameters().attackRange());
    });
    // <--[tag]
    // @attribute <NPCTag.attack_strategy>
    // @returns ElementTag
    // @description
    // Returns the NPC's current navigator attack strategy.
    // Not related to Sentinel combat.
    // -->
    tagProcessor.registerTag(ElementTag.class, "attack_strategy", (attribute, object) -> {
        return new ElementTag(object.getNavigator().getLocalParameters().attackStrategy().toString());
    });
    // <--[tag]
    // @attribute <NPCTag.speed_modifier>
    // @returns ElementTag(Decimal)
    // @description
    // Returns the NPC's current movement speed modifier (a multiplier applied over their base speed).
    // -->
    tagProcessor.registerTag(ElementTag.class, "speed_modifier", (attribute, object) -> {
        return new ElementTag(object.getNavigator().getLocalParameters().speedModifier());
    });
    // <--[tag]
    // @attribute <NPCTag.base_speed>
    // @returns ElementTag(Decimal)
    // @description
    // Returns the NPC's base navigation speed.
    // -->
    tagProcessor.registerTag(ElementTag.class, "base_speed", (attribute, object) -> {
        return new ElementTag(object.getNavigator().getLocalParameters().baseSpeed());
    });
    // <--[tag]
    // @attribute <NPCTag.avoid_water>
    // @returns ElementTag(Boolean)
    // @description
    // Returns whether the NPC will avoid water.
    // -->
    tagProcessor.registerTag(ElementTag.class, "avoid_water", (attribute, object) -> {
        return new ElementTag(object.getNavigator().getLocalParameters().avoidWater());
    });
    // <--[tag]
    // @attribute <NPCTag.target_location>
    // @returns LocationTag
    // @description
    // Returns the location the NPC is currently navigating towards (if any).
    // -->
    tagProcessor.registerTag(LocationTag.class, "target_location", (attribute, object) -> {
        if (object.getNavigator().getTargetAsLocation() == null) {
            return null;
        }
        return new LocationTag(object.getNavigator().getTargetAsLocation());
    });
    // <--[tag]
    // @attribute <NPCTag.navigator_look_at>
    // @returns LocationTag
    // @mechanism NPCTag.navigator_look_at
    // @description
    // Returns the location the NPC will currently look at while moving, if any.
    // -->
    tagProcessor.registerTag(LocationTag.class, "navigator_look_at", (attribute, object) -> {
        if (object.getNavigator().getLocalParameters().lookAtFunction() == null) {
            return null;
        }
        Location res = object.getNavigator().getLocalParameters().lookAtFunction().apply(object.getNavigator());
        if (res == null) {
            return null;
        }
        return new LocationTag(res);
    });
    // <--[tag]
    // @attribute <NPCTag.is_fighting>
    // @returns ElementTag(Boolean)
    // @description
    // Returns whether the NPC is currently targeting an entity for the Citizens internal punching pathfinder.
    // Not compatible with Sentinel.
    // -->
    tagProcessor.registerTag(ElementTag.class, "is_fighting", (attribute, object) -> {
        return new ElementTag(object.getNavigator().getEntityTarget() != null && object.getNavigator().getEntityTarget().isAggressive());
    });
    // <--[tag]
    // @attribute <NPCTag.target_type>
    // @returns ElementTag
    // @description
    // Returns the entity type of the NPC's current navigation target (if any).
    // -->
    tagProcessor.registerTag(ElementTag.class, "target_type", (attribute, object) -> {
        if (object.getNavigator().getTargetType() == null) {
            return null;
        }
        return new ElementTag(object.getNavigator().getTargetType().toString());
    });
    // <--[tag]
    // @attribute <NPCTag.target_entity>
    // @returns EntityTag
    // @description
    // Returns the entity being targeted by the NPC's current navigation (if any).
    // -->
    tagProcessor.registerTag(EntityTag.class, "target_entity", (attribute, object) -> {
        if (object.getNavigator().getEntityTarget() == null || object.getNavigator().getEntityTarget().getTarget() == null) {
            return null;
        }
        return new EntityTag(object.getNavigator().getEntityTarget().getTarget());
    });
    // <--[tag]
    // @attribute <NPCTag.registry_name>
    // @returns ElementTag
    // @description
    // Returns the name of the registry this NPC came from.
    // -->
    tagProcessor.registerTag(ElementTag.class, "registry_name", (attribute, object) -> {
        return new ElementTag(object.getCitizen().getOwningRegistry().getName());
    });
    // <--[tag]
    // @attribute <NPCTag.citizens_data[<key>]>
    // @returns ElementTag
    // @description
    // Returns the value of a Citizens NPC metadata key.
    // -->
    tagProcessor.registerTag(ElementTag.class, "citizens_data", (attribute, object) -> {
        if (!attribute.hasParam()) {
            return null;
        }
        Object val = object.getCitizen().data().get(attribute.getParam());
        if (val == null) {
            return null;
        }
        return new ElementTag(val.toString());
    });
    // <--[tag]
    // @attribute <NPCTag.citizens_data_keys>
    // @returns ListTag
    // @description
    // Returns a list of Citizens NPC metadata keys.
    // -->
    tagProcessor.registerTag(ListTag.class, "citizens_data_keys", (attribute, object) -> {
        DataKey holder = new MemoryDataKey();
        object.getCitizen().data().saveTo(holder);
        ListTag result = new ListTag();
        for (DataKey key : holder.getSubKeys()) {
            result.addObject(new ElementTag(key.name(), true));
        }
        return result;
    });
    tagProcessor.registerTag(NPCTag.class, "navigator", (attribute, object) -> {
        Deprecations.oldNPCNavigator.warn(attribute.context);
        return object;
    });
}
Also used : NPC(net.citizensnpcs.api.npc.NPC) SkinnableEntity(net.citizensnpcs.npc.skin.SkinnableEntity) DataKey(net.citizensnpcs.api.util.DataKey) MemoryDataKey(net.citizensnpcs.api.util.MemoryDataKey) AssignmentScriptContainer(com.denizenscript.denizen.scripts.containers.core.AssignmentScriptContainer) Pose(net.citizensnpcs.util.Pose) MemoryDataKey(net.citizensnpcs.api.util.MemoryDataKey) ListTag(com.denizenscript.denizencore.objects.core.ListTag) Anchor(net.citizensnpcs.util.Anchor) ScriptTag(com.denizenscript.denizencore.objects.core.ScriptTag) FlaggableObject(com.denizenscript.denizencore.flags.FlaggableObject) ElementTag(com.denizenscript.denizencore.objects.core.ElementTag) Trait(net.citizensnpcs.api.trait.Trait)

Aggregations

ListTag (com.denizenscript.denizencore.objects.core.ListTag)122 ElementTag (com.denizenscript.denizencore.objects.core.ElementTag)71 MapTag (com.denizenscript.denizencore.objects.core.MapTag)21 ItemStack (org.bukkit.inventory.ItemStack)18 EntityTag (com.denizenscript.denizen.objects.EntityTag)16 ObjectTag (com.denizenscript.denizencore.objects.ObjectTag)14 List (java.util.List)14 ItemTag (com.denizenscript.denizen.objects.ItemTag)13 PlayerTag (com.denizenscript.denizen.objects.PlayerTag)13 Player (org.bukkit.entity.Player)13 DurationTag (com.denizenscript.denizencore.objects.core.DurationTag)12 LocationTag (com.denizenscript.denizen.objects.LocationTag)11 NPCTag (com.denizenscript.denizen.objects.NPCTag)9 InvalidArgumentsException (com.denizenscript.denizencore.exceptions.InvalidArgumentsException)9 ArrayList (java.util.ArrayList)9 ScriptTag (com.denizenscript.denizencore.objects.core.ScriptTag)8 MaterialTag (com.denizenscript.denizen.objects.MaterialTag)7 ScriptEntry (com.denizenscript.denizencore.scripts.ScriptEntry)7 NPC (net.citizensnpcs.api.npc.NPC)7 Entity (org.bukkit.entity.Entity)7