Package net.aufdemrand.denizen.tags.core

Source Code of net.aufdemrand.denizen.tags.core.ProcedureScriptTag

package net.aufdemrand.denizen.tags.core;

import net.aufdemrand.denizen.BukkitScriptEntryData;
import net.aufdemrand.denizen.Denizen;
import net.aufdemrand.denizen.events.bukkit.ReplaceableTagEvent;
import net.aufdemrand.denizen.objects.ObjectFetcher;
import net.aufdemrand.denizen.objects.dList;
import net.aufdemrand.denizen.objects.dScript;
import net.aufdemrand.denizen.scripts.ScriptBuilder;
import net.aufdemrand.denizen.scripts.ScriptEntry;
import net.aufdemrand.denizen.scripts.queues.ScriptQueue;
import net.aufdemrand.denizen.scripts.commands.core.DetermineCommand;
import net.aufdemrand.denizen.scripts.queues.core.InstantQueue;
import net.aufdemrand.denizen.tags.Attribute;
import net.aufdemrand.denizen.utilities.debugging.dB;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;

import java.util.List;

public class ProcedureScriptTag implements Listener {

    public ProcedureScriptTag(Denizen denizen) {
        denizen.getServer().getPluginManager().registerEvents(this, denizen);
    }

    // <--[example]
    // @Title Using Procedure Scripts
    // @Description
    // Use procedure scripts to quickly place advanced calculations
    // in multiple scripts.
    //
    // @Code
    // # +--------------------
    // # | Using Procedure Scripts
    // # |
    // # | Sometimes you need a huge chunk of scriptwork just to decide
    // # | what to do with something.
    // # | EG, is your NPC a member of an army? Well, you have 20 different armies to check!
    // # |
    // # | Procedure scripts allow you to run an entire script and get the result from
    // # | it, without even taking a single extra line in the script it's being used in.
    //
    // # +-- The Procedure Script --+
    // ProcedureTutorial:
    //   type: procedure
    //
    //   # You can define variables to insert into the procedure, named here and separated by the |pipe| symbol.
    //   # You can have as many as you want - anywhere from none to several thousand.
    //   # Note: If you don't name the definitions but they are given anyway, they will be added as
    //   # %1%, %2%, and so on.
    //   definitions: price|moneysign
    //   # (For the purposes of this example, assume price = 3 dollars, and moneysign holds the '&' symbol)
    //
    //   script:
    //   # The procedure script is much like a task script
    //   # Except it must contain a Determine command
    //
    //   # In this example, we're checking if the player can buy a heal
    //   # So first check if the player has at least $3
    //   # If the player has less than 3 dollars, determine false
    //   - if <player.money> < %price% determine false
    //   # The determine above will immediately end the procedure and return false
    //
    //   # If the player has more than 80% health, he doesn't need a heal so determine false
    //   - if <player.health.percentage> > 80 determine false
    //
    //   # This example shouldn't get too complex, so
    //   # If it passed the money and health requirements:
    //   # First, take the $3
    //   - take money qty:%price%
    //
    //   # Tell the player they paid, to be nice
    //   - narrate "You lost %moneysign%%price%!"
    //   # Remember that due to the definitions this script requres, %moneysign% becomes '&' and price becomes '3'
    //
    //   # And, finally, determine true, to inform the calling script that it passed
    //   - determine true
    //
    // # +-- The NPC Assignment --+
    // ProcedureNPC:
    //   type: assignment
    //   actions:
    //     # Using an assignment 'on click' action only because an interact would take too much space
    //     on click:
    //
    //     # This will run the procedure script, and run the commands inside the { braces }
    //     # If it returned true. You could also compare any other value, EG <proc[whatever]> == 3
    //     # Depending on the determine command. Remember not to return different types of things in one procedure script
    //     # If one determine returns "true", the other shouldn't return "3"
    //
    //     # the .context[3|$] adds the two definitions: 'price' as '3', and 'moneysign' as '&'
    //     # Remember that if you don't need context, you can just entirely remove the '.context[]' portion
    //     - if <proc[ProcedureTutorial].context[3|&]> {
    //       - heal
    //       - chat "All patched up!"
    //       }
    //       else {
    //       - chat "You need $3 for a heal!"
    //       }
    //     # The 'else' braced section will be run if the procedure returned 'false'.
    //
    // -->

    @EventHandler
    public void procedureTag(ReplaceableTagEvent event) {

        // <--[tag]
        // @attribute <proc[ProcedureScript].Context[<element>|...]>
        // @returns dObject
        // @description
        // Returns the 'determine' result of a procedure script with the given context.
        // See <@link example Using Procedure Scripts>.
        // -->

        // <--[tag]
        // @attribute <proc[ProcedureScript]>
        // @returns dObject
        // @description
        // Returns the 'determine' result of a procedure script.
        // See <@link example Using Procedure Scripts>.
        // -->
        if (!event.matches("proc", "pr")) return;

        Attribute attr = event.getAttributes();
        int attribs = 1;

        dScript script = null;
        String path = null;

        if (event.hasNameContext()) {
            if (event.getNameContext().indexOf('.') > 0) {
                String[] split = event.getNameContext().split("\\.", 2);
                path = split[1];
                script = dScript.valueOf(split[0]);

            } else script = dScript.valueOf(event.getNameContext());

        } else if (event.getValue() != null) {
            script = dScript.valueOf(event.getValue());

        } else {
            dB.echoError("Invalid procedure script tag '" + event.getValue() + "'!");
            return;
        }

        if (script == null) {
            dB.echoError("Missing script for procedure script tag '" + event.getValue() + "'!");
            return;
        }

        // Build script entries
        List<ScriptEntry> entries;
        if (path != null)
            entries = script.getContainer().getEntries(new BukkitScriptEntryData(event.getPlayer(), event.getNPC()), path);
        else
            entries = script.getContainer().getBaseEntries(new BukkitScriptEntryData(event.getPlayer(), event.getNPC()));

        // Return if no entries built
        if (entries.isEmpty()) return;

        // Create new ID -- this is what we will look for when determining an outcome
        long id = DetermineCommand.getNewId();

        // Add the reqId to each of the entries for referencing
        ScriptBuilder.addObjectToEntries(entries, "ReqId", id);

        InstantQueue queue = InstantQueue.getQueue(ScriptQueue.getNextId(script.getContainer().getName()));
        queue.addEntries(entries);
        queue.setReqId(id);
        if (event.hasType() &&
                event.getType().equalsIgnoreCase("context") &&
                event.hasTypeContext()) {
            attribs = 2;
            int x = 1;
            dList definitions = new dList(event.getTypeContext());
            String[] definition_names = null;

            try { definition_names = script.getContainer().getString("definitions").split("\\|");
            } catch (Exception e) { }

            for (String definition : definitions) {
                String name = definition_names != null && definition_names.length >= x ?
                        definition_names[x - 1].trim() : String.valueOf(x);
                queue.addDefinition(name, definition);
                dB.echoDebug(event.getScriptEntry(), "Adding definition %" + name + "% as " + definition);
                x++;
            }
        }

        queue.start();

        if (DetermineCommand.hasOutcome(id)) {
            event.setReplaced(ObjectFetcher.pickObjectFor(DetermineCommand.getOutcome(id))
                    .getAttribute(attr.fulfill(attribs)));
        }
    }
}
TOP

Related Classes of net.aufdemrand.denizen.tags.core.ProcedureScriptTag

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.