Search in sources :

Example 16 with ScriptEntry

use of com.denizenscript.denizencore.scripts.ScriptEntry in project Denizen-For-Bukkit by DenizenScript.

the class AttachCommand method execute.

@Override
public void execute(final ScriptEntry scriptEntry) {
    LocationTag offset = scriptEntry.getObjectTag("offset");
    List<EntityTag> entities = (List<EntityTag>) scriptEntry.getObject("entities");
    EntityTag target = scriptEntry.getObjectTag("to");
    List<PlayerTag> forPlayers = (List<PlayerTag>) scriptEntry.getObject("for");
    ElementTag cancel = scriptEntry.getElement("cancel");
    ElementTag relative = scriptEntry.getElement("relative");
    ElementTag sync_server = scriptEntry.getElement("sync_server");
    ElementTag no_rotate = scriptEntry.getElement("no_rotate");
    ElementTag no_pitch = scriptEntry.getElement("no_pitch");
    ElementTag yaw_offset = scriptEntry.getElement("yaw_offset");
    ElementTag pitch_offset = scriptEntry.getElement("pitch_offset");
    boolean shouldCancel = cancel.asBoolean();
    if (scriptEntry.dbCallShouldDebug()) {
        Debug.report(scriptEntry, getName(), db("entities", entities), shouldCancel ? cancel : target, relative, offset, yaw_offset, pitch_offset, sync_server, no_rotate, no_pitch, db("for", forPlayers));
    }
    BiConsumer<EntityTag, UUID> procPlayer = (entity, player) -> {
        if (shouldCancel) {
            EntityAttachmentHelper.removeAttachment(entity.getUUID(), player);
        } else {
            EntityAttachmentHelper.AttachmentData attachment = new EntityAttachmentHelper.AttachmentData();
            attachment.attached = entity;
            attachment.to = target;
            attachment.positionalOffset = offset == null ? null : offset.clone();
            attachment.offsetRelative = relative.asBoolean();
            attachment.yawAngleOffset = yaw_offset.asFloat();
            attachment.pitchAngleOffset = pitch_offset.asFloat();
            attachment.syncServer = sync_server.asBoolean();
            attachment.forPlayer = player;
            attachment.noRotate = no_rotate.asBoolean();
            attachment.noPitch = no_pitch.asBoolean();
            EntityAttachmentHelper.registerAttachment(attachment);
        }
    };
    for (EntityTag entity : entities) {
        if (!entity.isSpawned() && !entity.isFake && !shouldCancel) {
            Debug.echoError("Cannot attach entity '" + entity + "': entity is not spawned.");
            continue;
        }
        if (forPlayers == null) {
            procPlayer.accept(entity, null);
        } else {
            for (PlayerTag player : forPlayers) {
                procPlayer.accept(entity, player.getUUID());
            }
        }
    }
}
Also used : ListTag(com.denizenscript.denizencore.objects.core.ListTag) LocationTag(com.denizenscript.denizen.objects.LocationTag) UUID(java.util.UUID) PlayerTag(com.denizenscript.denizen.objects.PlayerTag) InvalidArgumentsException(com.denizenscript.denizencore.exceptions.InvalidArgumentsException) Argument(com.denizenscript.denizencore.objects.Argument) List(java.util.List) BiConsumer(java.util.function.BiConsumer) EntityTag(com.denizenscript.denizen.objects.EntityTag) ScriptEntry(com.denizenscript.denizencore.scripts.ScriptEntry) Debug(com.denizenscript.denizen.utilities.debugging.Debug) AbstractCommand(com.denizenscript.denizencore.scripts.commands.AbstractCommand) ElementTag(com.denizenscript.denizencore.objects.core.ElementTag) EntityAttachmentHelper(com.denizenscript.denizen.utilities.entity.EntityAttachmentHelper) PlayerTag(com.denizenscript.denizen.objects.PlayerTag) LocationTag(com.denizenscript.denizen.objects.LocationTag) EntityTag(com.denizenscript.denizen.objects.EntityTag) List(java.util.List) EntityAttachmentHelper(com.denizenscript.denizen.utilities.entity.EntityAttachmentHelper) ElementTag(com.denizenscript.denizencore.objects.core.ElementTag) UUID(java.util.UUID)

Example 17 with ScriptEntry

use of com.denizenscript.denizencore.scripts.ScriptEntry in project Denizen-For-Bukkit by DenizenScript.

the class EnchantmentScriptContainer method runSubScript.

public void runSubScript(String pathName, Entity attacker, Entity victim, Entity primary, int level) {
    validateThread();
    List<ScriptEntry> entries = getEntries(new BukkitScriptEntryData(new EntityTag(primary)), pathName);
    if (entries == null || entries.isEmpty()) {
        return;
    }
    InstantQueue queue = new InstantQueue(getName());
    queue.addEntries(entries);
    ContextSource.SimpleMap src = new ContextSource.SimpleMap();
    src.contexts = new HashMap<>();
    if (attacker != null) {
        src.contexts.put("attacker", new EntityTag(attacker));
    }
    if (victim != null) {
        src.contexts.put("victim", new EntityTag(victim));
    }
    src.contexts.put("level", new ElementTag(level));
    queue.contextSource = src;
    queue.start();
}
Also used : BukkitScriptEntryData(com.denizenscript.denizen.utilities.implementation.BukkitScriptEntryData) ContextSource(com.denizenscript.denizencore.scripts.queues.ContextSource) ScriptEntry(com.denizenscript.denizencore.scripts.ScriptEntry) EntityTag(com.denizenscript.denizen.objects.EntityTag) InstantQueue(com.denizenscript.denizencore.scripts.queues.core.InstantQueue) ElementTag(com.denizenscript.denizencore.objects.core.ElementTag)

Example 18 with ScriptEntry

use of com.denizenscript.denizencore.scripts.ScriptEntry in project Denizen-For-Bukkit by DenizenScript.

the class InventoryScriptContainer method getInventoryFrom.

public InventoryTag getInventoryFrom(TagContext context) {
    InventoryTag inventory;
    context = (context == null ? CoreUtilities.basicContext : context).clone();
    ScriptTag thisScript = new ScriptTag(this);
    context.script = thisScript;
    context.debug = context.debug && shouldDebug();
    try {
        InventoryType type = InventoryType.CHEST;
        if (contains("inventory", String.class)) {
            try {
                type = InventoryType.valueOf(getString("inventory").toUpperCase());
            } catch (IllegalArgumentException ex) {
                Debug.echoError(this, "Invalid inventory type specified. Assuming \"CHEST\" (" + ex.getMessage() + ")");
            }
        } else {
            Debug.echoError(this, "Inventory script '" + getName() + "' does not specify an inventory type. Assuming \"CHEST\".");
        }
        if (type == InventoryType.PLAYER) {
            Debug.echoError(this, "Inventory type 'player' is not valid for inventory scripts - defaulting to 'CHEST'.");
            type = InventoryType.CHEST;
        }
        int size = 0;
        if (contains("size", String.class)) {
            if (type != InventoryType.CHEST) {
                Debug.echoError(this, "You can only set the size of chest inventories!");
            } else {
                String sizeText = TagManager.tag(getString("size"), context);
                if (!ArgumentHelper.matchesInteger(sizeText)) {
                    Debug.echoError(this, "Invalid (not-a-number) size value.");
                } else {
                    size = Integer.parseInt(sizeText);
                }
                if (size == 0) {
                    Debug.echoError(this, "Inventory size can't be 0. Assuming default of inventory type...");
                }
                if (size % 9 != 0) {
                    size = (int) Math.ceil(size / 9.0) * 9;
                    Debug.echoError(this, "Inventory size must be a multiple of 9! Rounding up to " + size + "...");
                }
                if (size < 0) {
                    size = size * -1;
                    Debug.echoError(this, "Inventory size must be a positive number! Inverting to " + size + "...");
                }
            }
        }
        if (size == 0) {
            if (contains("slots", List.class) && type == InventoryType.CHEST) {
                size = getStringList("slots").size() * 9;
            } else {
                size = type.getDefaultSize();
            }
        }
        String title = contains("title", String.class) ? TagManager.tag(getString("title"), context) : null;
        if (type == InventoryType.CHEST) {
            inventory = new InventoryTag(size, title != null ? title : "Chest");
        } else {
            if (title == null) {
                inventory = new InventoryTag(type);
            } else {
                inventory = new InventoryTag(type, title);
            }
        }
        inventory.idType = "script";
        inventory.idHolder = thisScript;
        boolean[] filledSlots = new boolean[size];
        if (contains("slots", List.class)) {
            ItemStack[] finalItems = new ItemStack[size];
            int itemsAdded = 0;
            for (String items : getStringList("slots")) {
                items = TagManager.tag(items, context).trim();
                if (items.isEmpty()) {
                    continue;
                }
                if (!items.startsWith("[") || !items.endsWith("]")) {
                    Debug.echoError(this, "Invalid slots line: [" + items + "]... Ignoring it");
                    continue;
                }
                String[] itemsInLine = items.substring(1, items.length() - 1).split("\\[?\\]?\\s+\\[", -1);
                for (String item : itemsInLine) {
                    if (item.isEmpty()) {
                        finalItems[itemsAdded++] = new ItemStack(Material.AIR);
                        continue;
                    }
                    filledSlots[itemsAdded] = true;
                    if (contains("definitions." + item, String.class)) {
                        ItemTag def = ItemTag.valueOf(TagManager.tag(getString("definitions." + item), context), context);
                        if (def == null) {
                            Debug.echoError(this, "Invalid definition '" + item + "'... Ignoring it and assuming 'AIR'");
                            finalItems[itemsAdded] = new ItemStack(Material.AIR);
                        } else {
                            finalItems[itemsAdded] = def.getItemStack();
                        }
                    } else {
                        try {
                            ItemTag itemTag = ItemTag.valueOf(item, context);
                            if (itemTag == null) {
                                finalItems[itemsAdded] = new ItemStack(Material.AIR);
                                Debug.echoError(this, "Invalid slot item: [" + item + "]... ignoring it and assuming 'AIR'");
                            } else {
                                finalItems[itemsAdded] = itemTag.getItemStack();
                            }
                        } catch (Exception ex) {
                            Debug.echoError(this, "Invalid slot item: [" + item + "]...");
                            Debug.echoError(ex);
                        }
                    }
                    itemsAdded++;
                }
            }
            inventory.setContents(finalItems);
        }
        if (containsScriptSection("procedural items")) {
            List<ScriptEntry> entries = getEntries(context.getScriptEntryData(), "procedural items");
            if (!entries.isEmpty()) {
                InstantQueue queue = new InstantQueue("INV_SCRIPT_ITEM_PROC");
                queue.addEntries(entries);
                if (contains("definitions", Map.class)) {
                    YamlConfiguration section = getConfigurationSection("definitions");
                    for (StringHolder string : section.getKeys(false)) {
                        String definition = string.str;
                        queue.addDefinition(definition, section.getString(definition));
                    }
                }
                queue.procedural = true;
                queue.start();
                if (queue.determinations != null) {
                    ListTag list = ListTag.getListFor(queue.determinations.getObject(0), context);
                    if (list != null) {
                        int x = 0;
                        for (ItemTag item : list.filter(ItemTag.class, context, true)) {
                            while (x < filledSlots.length && filledSlots[x]) {
                                x++;
                            }
                            if (x >= filledSlots.length || filledSlots[x]) {
                                break;
                            }
                            inventory.setSlots(x, item.getItemStack());
                            filledSlots[x] = true;
                        }
                    }
                }
            }
        }
    } catch (Exception e) {
        Debug.echoError(this, "Woah! An exception has been called while building this inventory script!");
        Debug.echoError(e);
        inventory = null;
    }
    if (inventory != null) {
        InventoryTag.trackTemporaryInventory(inventory);
    }
    return inventory;
}
Also used : InventoryType(org.bukkit.event.inventory.InventoryType) ScriptEntry(com.denizenscript.denizencore.scripts.ScriptEntry) YamlConfiguration(com.denizenscript.denizencore.utilities.YamlConfiguration) ListTag(com.denizenscript.denizencore.objects.core.ListTag) StringHolder(com.denizenscript.denizencore.utilities.text.StringHolder) ScriptTag(com.denizenscript.denizencore.objects.core.ScriptTag) List(java.util.List) InstantQueue(com.denizenscript.denizencore.scripts.queues.core.InstantQueue) ItemStack(org.bukkit.inventory.ItemStack) ItemTag(com.denizenscript.denizen.objects.ItemTag) InventoryTag(com.denizenscript.denizen.objects.InventoryTag)

Example 19 with ScriptEntry

use of com.denizenscript.denizencore.scripts.ScriptEntry in project Denizen-For-Bukkit by DenizenScript.

the class TakeCommand method execute.

@Override
public void execute(ScriptEntry scriptEntry) {
    InventoryTag inventory = scriptEntry.getObjectTag("inventory");
    ElementTag quantity = scriptEntry.getElement("quantity");
    ListTag displayNameList = scriptEntry.getObjectTag("displayname");
    List<ItemTag> scriptItemList = scriptEntry.getObjectTag("scriptitem");
    ListTag slotList = scriptEntry.getObjectTag("slot");
    ListTag titleAuthor = scriptEntry.getObjectTag("cover");
    ElementTag nbtKey = scriptEntry.getElement("nbt_key");
    ElementTag matcherText = scriptEntry.getElement("matcher_text");
    ListTag flagList = scriptEntry.getObjectTag("flag_name");
    List<MaterialTag> materialList = scriptEntry.getObjectTag("material");
    Type type = (Type) scriptEntry.getObject("type");
    List<ItemTag> items = scriptEntry.getObjectTag("items");
    if (scriptEntry.dbCallShouldDebug()) {
        Debug.report(scriptEntry, getName(), db("Type", type.name()), quantity, inventory, displayNameList, db("scriptname", scriptItemList), db("Items", items), slotList, nbtKey, flagList, matcherText, db("material", materialList), titleAuthor);
    }
    switch(type) {
        case INVENTORY:
            {
                inventory.clear();
                break;
            }
        case ITEMINHAND:
            {
                Player player = Utilities.getEntryPlayer(scriptEntry).getPlayerEntity();
                int inHandAmt = player.getEquipment().getItemInMainHand().getAmount();
                int theAmount = (int) quantity.asDouble();
                ItemStack newHandItem = new ItemStack(Material.AIR);
                if (theAmount > inHandAmt) {
                    Debug.echoDebug(scriptEntry, "...player did not have enough of the item in hand, taking all...");
                    player.getEquipment().setItemInMainHand(newHandItem);
                } else {
                    // amount is just right!
                    if (theAmount == inHandAmt) {
                        player.getEquipment().setItemInMainHand(newHandItem);
                    } else {
                        // amount is less than what's in hand, need to make a new itemstack of what's left...
                        newHandItem = player.getEquipment().getItemInMainHand().clone();
                        newHandItem.setAmount(inHandAmt - theAmount);
                        player.getEquipment().setItemInMainHand(newHandItem);
                        player.updateInventory();
                    }
                }
                break;
            }
        case CURSORITEM:
            {
                Player player = Utilities.getEntryPlayer(scriptEntry).getPlayerEntity();
                int currentAmount = player.getItemOnCursor().getAmount();
                int takeAmount = (int) quantity.asDouble();
                ItemStack newItem = new ItemStack(Material.AIR);
                if (takeAmount > currentAmount) {
                    Debug.echoDebug(scriptEntry, "...player did not have enough of the item on cursor, taking all...");
                    player.setItemOnCursor(newItem);
                } else {
                    if (takeAmount == currentAmount) {
                        player.setItemOnCursor(newItem);
                    } else {
                        newItem = player.getItemOnCursor().clone();
                        newItem.setAmount(currentAmount - takeAmount);
                        player.setItemOnCursor(newItem);
                        player.updateInventory();
                    }
                }
                break;
            }
        case MONEY:
            {
                if (Depends.economy == null) {
                    Debug.echoError(scriptEntry, "No economy loaded! Have you installed Vault and a compatible economy plugin?");
                    return;
                }
                Depends.economy.withdrawPlayer(Utilities.getEntryPlayer(scriptEntry).getOfflinePlayer(), quantity.asDouble());
                break;
            }
        case XP:
            {
                Utilities.getEntryPlayer(scriptEntry).getPlayerEntity().giveExp(-quantity.asInt());
                break;
            }
        case RAWEXACT:
            {
                if (items == null) {
                    Debug.echoError(scriptEntry, "Must specify item/items!");
                    return;
                }
                for (ItemTag targetItem : items) {
                    takeByMatcher(inventory, (item) -> targetItem.matchesRawExact(new ItemTag(item)), quantity.asInt());
                }
                break;
            }
        case ITEM:
            {
                if (items == null) {
                    Debug.echoError(scriptEntry, "Must specify item/items!");
                    return;
                }
                for (ItemTag item : items) {
                    ItemStack is = item.getItemStack().clone();
                    is.setAmount(quantity.asInt());
                    if (!removeItem(inventory.getInventory(), item, item.getAmount())) {
                        Debug.echoDebug(scriptEntry, "Inventory does not contain at least " + quantity.asInt() + " of " + item.identify() + "... Taking all...");
                    }
                }
                break;
            }
        case BYDISPLAY:
            {
                if (displayNameList == null) {
                    Debug.echoError(scriptEntry, "Must specify a displayname!");
                    return;
                }
                for (String name : displayNameList) {
                    takeByMatcher(inventory, (item) -> item.hasItemMeta() && item.getItemMeta().hasDisplayName() && item.getItemMeta().getDisplayName().equalsIgnoreCase(name), quantity.asInt());
                }
                break;
            }
        case BYCOVER:
            {
                if (titleAuthor == null) {
                    Debug.echoError(scriptEntry, "Must specify a cover!");
                    return;
                }
                takeByMatcher(inventory, (item) -> item.hasItemMeta() && item.getItemMeta() instanceof BookMeta && equalOrNull(titleAuthor.get(0), ((BookMeta) item.getItemMeta()).getTitle()) && (titleAuthor.size() == 1 || equalOrNull(titleAuthor.get(1), ((BookMeta) item.getItemMeta()).getAuthor())), quantity.asInt());
                break;
            }
        case FLAGGED:
            {
                if (flagList == null) {
                    Debug.echoError(scriptEntry, "Must specify a flag name!");
                    return;
                }
                for (String flag : flagList) {
                    takeByMatcher(inventory, (item) -> new ItemTag(item).getFlagTracker().hasFlag(flag), quantity.asInt());
                }
                break;
            }
        case NBT:
            {
                if (nbtKey == null) {
                    Debug.echoError(scriptEntry, "Must specify an NBT key!");
                    return;
                }
                takeByMatcher(inventory, (item) -> CustomNBT.hasCustomNBT(item, nbtKey.asString(), CustomNBT.KEY_DENIZEN), quantity.asInt());
                break;
            }
        case SCRIPTNAME:
            {
                if (scriptItemList == null) {
                    Debug.echoError(scriptEntry, "Must specify a valid script name!");
                    return;
                }
                for (ItemTag scriptedItem : scriptItemList) {
                    String script = scriptedItem.getScriptName();
                    if (script == null) {
                        Debug.echoError(scriptEntry, "Item '" + scriptedItem.debuggable() + "' is not a scripted item, cannot take by scriptname.");
                        continue;
                    }
                    takeByMatcher(inventory, (item) -> script.equalsIgnoreCase(new ItemTag(item).getScriptName()), quantity.asInt());
                }
                break;
            }
        case MATERIAL:
            {
                if (materialList == null) {
                    Debug.echoError(scriptEntry, "Must specify a valid material!");
                    return;
                }
                for (MaterialTag material : materialList) {
                    takeByMatcher(inventory, (item) -> item.getType() == material.getMaterial() && !(new ItemTag(item).isItemscript()), quantity.asInt());
                }
                break;
            }
        case MATCHER:
            {
                if (matcherText == null) {
                    Debug.echoError(scriptEntry, "Must specify an item matcher!");
                    return;
                }
                takeByMatcher(inventory, (item) -> BukkitScriptEvent.tryItem(new ItemTag(item), matcherText.asString()), quantity.asInt());
                break;
            }
        case SLOT:
            {
                for (String slot : slotList) {
                    int slotId = SlotHelper.nameToIndexFor(slot, inventory.getInventory().getHolder());
                    if (slotId == -1 || slotId >= inventory.getSize()) {
                        Debug.echoError(scriptEntry, "The input '" + slot + "' is not a valid slot!");
                        return;
                    }
                    ItemStack original = inventory.getInventory().getItem(slotId);
                    if (original != null && original.getType() != Material.AIR) {
                        if (original.getAmount() > quantity.asInt()) {
                            original.setAmount(original.getAmount() - quantity.asInt());
                            inventory.setSlots(slotId, original);
                        } else {
                            inventory.setSlots(slotId, new ItemStack(Material.AIR));
                        }
                    }
                }
                break;
            }
    }
}
Also used : MaterialTag(com.denizenscript.denizen.objects.MaterialTag) Utilities(com.denizenscript.denizen.utilities.Utilities) Arrays(java.util.Arrays) BookMeta(org.bukkit.inventory.meta.BookMeta) NMSHandler(com.denizenscript.denizen.nms.NMSHandler) ItemTag(com.denizenscript.denizen.objects.ItemTag) Player(org.bukkit.entity.Player) InvalidArgumentsException(com.denizenscript.denizencore.exceptions.InvalidArgumentsException) Function(java.util.function.Function) Argument(com.denizenscript.denizencore.objects.Argument) Inventory(org.bukkit.inventory.Inventory) HashSet(java.util.HashSet) MaterialTag(com.denizenscript.denizen.objects.MaterialTag) ScriptEntry(com.denizenscript.denizencore.scripts.ScriptEntry) ElementTag(com.denizenscript.denizencore.objects.core.ElementTag) Material(org.bukkit.Material) ListTag(com.denizenscript.denizencore.objects.core.ListTag) Depends(com.denizenscript.denizen.utilities.depends.Depends) CustomNBT(com.denizenscript.denizen.utilities.nbt.CustomNBT) BukkitScriptEvent(com.denizenscript.denizen.events.BukkitScriptEvent) ItemStack(org.bukkit.inventory.ItemStack) SlotHelper(com.denizenscript.denizen.utilities.inventory.SlotHelper) List(java.util.List) Deprecations(com.denizenscript.denizencore.utilities.Deprecations) Debug(com.denizenscript.denizen.utilities.debugging.Debug) AbstractCommand(com.denizenscript.denizencore.scripts.commands.AbstractCommand) CoreUtilities(com.denizenscript.denizencore.utilities.CoreUtilities) ItemScriptHelper(com.denizenscript.denizen.scripts.containers.core.ItemScriptHelper) InventoryTag(com.denizenscript.denizen.objects.InventoryTag) Player(org.bukkit.entity.Player) ListTag(com.denizenscript.denizencore.objects.core.ListTag) ElementTag(com.denizenscript.denizencore.objects.core.ElementTag) ItemTag(com.denizenscript.denizen.objects.ItemTag) ItemStack(org.bukkit.inventory.ItemStack) InventoryTag(com.denizenscript.denizen.objects.InventoryTag) BookMeta(org.bukkit.inventory.meta.BookMeta)

Example 20 with ScriptEntry

use of com.denizenscript.denizencore.scripts.ScriptEntry in project Denizen-For-Bukkit by DenizenScript.

the class ShootCommand method execute.

@Override
public void execute(final ScriptEntry scriptEntry) {
    EntityTag originEntity = scriptEntry.getObjectTag("origin_entity");
    LocationTag originLocation = scriptEntry.hasObject("origin_location") ? (LocationTag) scriptEntry.getObject("origin_location") : new LocationTag(originEntity.getEyeLocation().add(originEntity.getEyeLocation().getDirection()));
    boolean no_rotate = scriptEntry.hasObject("no_rotate") && scriptEntry.getElement("no_rotate").asBoolean();
    // If there is no destination set, but there is a shooter, get a point
    // in front of the shooter and set it as the destination
    final LocationTag destination = scriptEntry.hasObject("destination") ? (LocationTag) scriptEntry.getObject("destination") : (originEntity != null ? new LocationTag(originEntity.getEyeLocation().clone().add(originEntity.getEyeLocation().clone().getDirection().multiply(30))) : (originLocation != null ? new LocationTag(originLocation.clone().add(originLocation.getDirection().multiply(30))) : null));
    // TODO: Same as PUSH -- is this the place to do this?
    if (destination == null) {
        Debug.echoError("No destination specified!");
        return;
    }
    final List<EntityTag> entities = (List<EntityTag>) scriptEntry.getObject("entities");
    final ScriptTag script = scriptEntry.getObjectTag("script");
    final ElementTag subPath = scriptEntry.getElement("path");
    final ListTag definitions = scriptEntry.getObjectTag("definitions");
    EntityTag shooter = scriptEntry.getObjectTag("shooter");
    ElementTag height = scriptEntry.getElement("height");
    ElementTag gravity = scriptEntry.getElement("gravity");
    ElementTag speed = scriptEntry.getElement("speed");
    ElementTag spread = scriptEntry.getElement("spread");
    LocationTag lead = scriptEntry.getObjectTag("lead");
    if (scriptEntry.dbCallShouldDebug()) {
        Debug.report(scriptEntry, getName(), originEntity, originLocation, db("entities", entities), destination, height, gravity, speed, script, subPath, shooter, spread, lead, (no_rotate ? db("no_rotate", "true") : ""), definitions);
    }
    final ListTag entityList = new ListTag();
    if (!no_rotate) {
        originLocation = new LocationTag(NMSHandler.getEntityHelper().faceLocation(originLocation, destination));
    }
    for (EntityTag entity : entities) {
        if (!entity.isSpawned() || !no_rotate) {
            entity.spawnAt(originLocation);
        }
        entityList.addObject(entity);
        if (entity.isProjectile()) {
            if (shooter != null || originEntity != null) {
                entity.setShooter(shooter != null ? shooter : originEntity);
            }
            if (script != null || scriptEntry.shouldWaitFor()) {
                arrows.put(entity.getUUID(), null);
            }
        }
    }
    scriptEntry.addObject("shot_entities", entityList);
    if (entityList.size() == 1) {
        scriptEntry.addObject("shot_entity", entityList.getObject(0));
    }
    if (spread == null) {
        Position.mount(Conversion.convertEntities(entities));
    }
    final EntityTag lastEntity = entities.get(entities.size() - 1);
    if (speed == null) {
        if (gravity == null) {
            gravity = new ElementTag(lastEntity.getEntityType().getGravity());
        }
        Vector v1 = lastEntity.getLocation().toVector();
        Vector v2 = destination.toVector();
        Vector v3 = Velocity.calculate(v1, v2, gravity.asDouble(), height.asDouble());
        lastEntity.setVelocity(v3);
    } else if (lead == null) {
        Vector relative = destination.clone().subtract(originLocation).toVector();
        lastEntity.setVelocity(relative.normalize().multiply(speed.asDouble()));
    } else {
        double g = 20;
        double v = speed.asDouble();
        Vector relative = destination.clone().subtract(originLocation).toVector();
        double testAng = Velocity.launchAngle(originLocation, destination.toVector(), v, relative.getY(), g);
        double hangTime = Velocity.hangtime(testAng, v, relative.getY(), g);
        Vector to = destination.clone().add(lead.clone().multiply(hangTime)).toVector();
        relative = to.clone().subtract(originLocation.toVector());
        double dist = Math.sqrt(relative.getX() * relative.getX() + relative.getZ() * relative.getZ());
        if (dist == 0) {
            dist = 0.1d;
        }
        testAng = Velocity.launchAngle(originLocation, to, v, relative.getY(), g);
        relative.setY(Math.tan(testAng) * dist);
        relative = relative.normalize();
        v = v + (1.188 * Math.pow(hangTime, 2));
        relative = relative.multiply(v / 20.0d);
        lastEntity.setVelocity(relative);
    }
    if (spread != null) {
        Vector base = lastEntity.getVelocity().clone();
        float sf = spread.asFloat();
        for (EntityTag entity : entities) {
            Vector newvel = Velocity.spread(base, (CoreUtilities.getRandom().nextDouble() > 0.5f ? 1 : -1) * Math.toRadians(CoreUtilities.getRandom().nextDouble() * sf), (CoreUtilities.getRandom().nextDouble() > 0.5f ? 1 : -1) * Math.toRadians(CoreUtilities.getRandom().nextDouble() * sf));
            entity.setVelocity(newvel);
        }
    }
    final LocationTag start = new LocationTag(lastEntity.getLocation());
    // A task used to trigger a script if the entity is no longer
    // being shot, when the script argument is used
    BukkitRunnable task = new BukkitRunnable() {

        boolean flying = true;

        LocationTag lastLocation = null;

        Vector lastVelocity = null;

        public void run() {
            // If the entity is no longer spawned, stop the task
            if (!lastEntity.isSpawned()) {
                if (Debug.verbose) {
                    Debug.log("Shoot ended because entity not spawned");
                }
                flying = false;
            } else // the air, stop the task
            if (lastLocation != null && lastVelocity != null && !(lastEntity.getBukkitEntity() instanceof Projectile)) {
                if (lastLocation.getWorld() != lastEntity.getBukkitEntity().getWorld() || (lastLocation.distanceSquared(lastEntity.getBukkitEntity().getLocation()) < 0.1 && lastVelocity.distanceSquared(lastEntity.getBukkitEntity().getVelocity()) < 0.1)) {
                    if (Debug.verbose) {
                        Debug.log("Shoot ended because distances short - locations: " + (lastLocation.distanceSquared(lastEntity.getBukkitEntity().getLocation())) + ", velocity: " + (lastVelocity.distanceSquared(lastEntity.getBukkitEntity().getVelocity()) < 0.1));
                    }
                    flying = false;
                }
            }
            if (!arrows.containsKey(lastEntity.getUUID()) || arrows.get(lastEntity.getUUID()) != null) {
                if (Debug.verbose) {
                    Debug.log("Shoot ended because uuid was updated (hit entity?)");
                }
                flying = false;
            }
            // are met
            if (!flying) {
                this.cancel();
                ListTag hitEntities = new ListTag();
                for (EntityTag entity : entities) {
                    if (arrows.containsKey(entity.getUUID())) {
                        EntityTag hit = arrows.get(entity.getUUID());
                        arrows.remove(entity.getUUID());
                        if (hit != null) {
                            hitEntities.addObject(hit);
                        }
                    }
                }
                if (lastLocation == null) {
                    lastLocation = start;
                }
                scriptEntry.addObject("location", new LocationTag(lastLocation));
                scriptEntry.addObject("hit_entities", hitEntities);
                if (script != null) {
                    Consumer<ScriptQueue> configure = (queue) -> {
                        queue.addDefinition("location", new LocationTag(lastLocation));
                        queue.addDefinition("shot_entities", entityList);
                        queue.addDefinition("last_entity", lastEntity);
                        queue.addDefinition("hit_entities", hitEntities);
                    };
                    ScriptUtilities.createAndStartQueue(script.getContainer(), subPath == null ? null : subPath.asString(), scriptEntry.entryData, null, configure, null, null, definitions, scriptEntry);
                }
                scriptEntry.setFinished(true);
            } else {
                // Record its position in case the entity dies
                lastLocation = lastEntity.getLocation();
                lastVelocity = lastEntity.getVelocity();
            }
        }
    };
    if (script != null || scriptEntry.shouldWaitFor()) {
        task.runTaskTimer(Denizen.getInstance(), 1, 2);
    }
}
Also used : Utilities(com.denizenscript.denizen.utilities.Utilities) LocationTag(com.denizenscript.denizen.objects.LocationTag) NMSHandler(com.denizenscript.denizen.nms.NMSHandler) Projectile(org.bukkit.entity.Projectile) HashMap(java.util.HashMap) Debug(com.denizenscript.denizencore.utilities.debugging.Debug) InvalidArgumentsException(com.denizenscript.denizencore.exceptions.InvalidArgumentsException) Holdable(com.denizenscript.denizencore.scripts.commands.Holdable) EventHandler(org.bukkit.event.EventHandler) ScriptQueue(com.denizenscript.denizencore.scripts.queues.ScriptQueue) Map(java.util.Map) ScriptEntry(com.denizenscript.denizencore.scripts.ScriptEntry) ElementTag(com.denizenscript.denizencore.objects.core.ElementTag) EntityDamageByEntityEvent(org.bukkit.event.entity.EntityDamageByEntityEvent) Bukkit(org.bukkit.Bukkit) Listener(org.bukkit.event.Listener) ListTag(com.denizenscript.denizencore.objects.core.ListTag) Velocity(com.denizenscript.denizen.utilities.entity.Velocity) Entity(org.bukkit.entity.Entity) BukkitRunnable(org.bukkit.scheduler.BukkitRunnable) UUID(java.util.UUID) Position(com.denizenscript.denizen.utilities.entity.Position) Denizen(com.denizenscript.denizen.Denizen) Vector(org.bukkit.util.Vector) Consumer(java.util.function.Consumer) List(java.util.List) ScriptUtilities(com.denizenscript.denizencore.utilities.ScriptUtilities) EventPriority(org.bukkit.event.EventPriority) EntityTag(com.denizenscript.denizen.objects.EntityTag) com.denizenscript.denizencore.objects(com.denizenscript.denizencore.objects) ScriptTag(com.denizenscript.denizencore.objects.core.ScriptTag) AbstractCommand(com.denizenscript.denizencore.scripts.commands.AbstractCommand) CoreUtilities(com.denizenscript.denizencore.utilities.CoreUtilities) Conversion(com.denizenscript.denizen.utilities.Conversion) TaskScriptContainer(com.denizenscript.denizencore.scripts.containers.core.TaskScriptContainer) ProjectileHitEvent(org.bukkit.event.entity.ProjectileHitEvent) BukkitRunnable(org.bukkit.scheduler.BukkitRunnable) ListTag(com.denizenscript.denizencore.objects.core.ListTag) Projectile(org.bukkit.entity.Projectile) LocationTag(com.denizenscript.denizen.objects.LocationTag) ScriptTag(com.denizenscript.denizencore.objects.core.ScriptTag) EntityTag(com.denizenscript.denizen.objects.EntityTag) List(java.util.List) ElementTag(com.denizenscript.denizencore.objects.core.ElementTag) Vector(org.bukkit.util.Vector) ScriptQueue(com.denizenscript.denizencore.scripts.queues.ScriptQueue)

Aggregations

ScriptEntry (com.denizenscript.denizencore.scripts.ScriptEntry)23 ElementTag (com.denizenscript.denizencore.objects.core.ElementTag)11 EntityTag (com.denizenscript.denizen.objects.EntityTag)10 InvalidArgumentsException (com.denizenscript.denizencore.exceptions.InvalidArgumentsException)9 NPCTag (com.denizenscript.denizen.objects.NPCTag)8 PlayerTag (com.denizenscript.denizen.objects.PlayerTag)8 ListTag (com.denizenscript.denizencore.objects.core.ListTag)8 AbstractCommand (com.denizenscript.denizencore.scripts.commands.AbstractCommand)8 List (java.util.List)8 Debug (com.denizenscript.denizen.utilities.debugging.Debug)7 BukkitScriptEntryData (com.denizenscript.denizen.utilities.implementation.BukkitScriptEntryData)7 ScriptQueue (com.denizenscript.denizencore.scripts.queues.ScriptQueue)7 InstantQueue (com.denizenscript.denizencore.scripts.queues.core.InstantQueue)7 NMSHandler (com.denizenscript.denizen.nms.NMSHandler)6 Utilities (com.denizenscript.denizen.utilities.Utilities)6 Argument (com.denizenscript.denizencore.objects.Argument)6 ContextSource (com.denizenscript.denizencore.scripts.queues.ContextSource)5 Player (org.bukkit.entity.Player)5 Denizen (com.denizenscript.denizen.Denizen)4 LocationTag (com.denizenscript.denizen.objects.LocationTag)4