Skip to content

Commit

Permalink
Update RUN command to enable local script support.
Browse files Browse the repository at this point in the history
  • Loading branch information
aufdemrand committed Sep 8, 2013
1 parent 8f2d64f commit d18cccd
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 83 deletions.
Expand Up @@ -19,22 +19,89 @@
* @author Jeremy Schroeder
*
*/

public class RunCommand extends AbstractCommand {

// <--[example]
// @Title Using Local Scripts tutorial
// @Description
// Use local scripts as a way to avoid making unnessecary script containers
// or to group together utility task scripts.
//
// @Code
// # +--------------------
// # | Using Local Scripts tutorial
//
// # | Since Script Containers are stored inside Denizen on a global level,
// # | the problem of duplicate container names can become a problem.
//
// # | Using local scripts can be a good way to avoid situations by cutting
// # | down on the amount of total script containers needed by allowing task utility
// # | scripts to be included in other containers, or grouped together in a single
// # | container.
//
// Local Script Tutorial:
// type: task
//
// # As you probably already know, to run a 'base script' inside a task script
// # the 'run' or 'inject' commands can be used. This requires the name of the
// # script container as an argument in the commands. For example, type
// # /ex run 's@Local Script Tutorial' .. to run the script
// # below.
//
// script:
// - narrate "This is the 'base script' of this task script container."
// - narrate "The current time is <util.date.time>!"
//
//
// # Local Script support by Denizen allows you to stash more scripts. Just specify
// # a new node. To run this script from other containers, specify a path as well as
// # the local script name node. For example, to run the script below, type
// # /ex run 's@Local Script Tutorial' 'subscript_1'
//
// subscript_1:
// - narrate "This is a 'local script' in the task script container 'Local
// Script Tutorial'."
//
//
// # But wait, there's more! If wanting to run a local script that is within the
// # same container, the run command can be even simpler by specifying 'local'
// # in place of the script name. Take a look at the next two local scripts. Type
// # /ex run 's@Local Script Tutorial' 'subscript_2' .. to run the script below
// # which will in turn run 'subscript_3' locally.
//
// subscript_2:
// - narrate "This is the second 'local script' in this task script container."
// - narrate "This script will now run 'subscript_3'."
// - run locally 'subscript_3'
//
// subscript_3:
// - narrate "Done. This has been a message from subscript_3!"
//
//
// # There you have it! Three seperate scripts inside a single task script container!
// # Both the 'run' command and 'inject' command support local scripts.
//
// -->

@Override
public void parseArgs(ScriptEntry scriptEntry) throws InvalidArgumentsException {

for (aH.Argument arg : aH.interpret(scriptEntry.getArguments())) {

if (!scriptEntry.hasObject("script")
&& arg.matchesArgumentType(dScript.class))
scriptEntry.addObject("script", arg.asType(dScript.class));

else if (arg.matchesPrefix("i, id"))
if (arg.matchesPrefix("i, id"))
scriptEntry.addObject("id", arg.asElement());

else if (arg.matchesPrefix("p, path"))
scriptEntry.addObject("path", arg.asElement());
else if (arg.matchesPrefix("a, as")
&& arg.matchesArgumentType(dPlayer.class))
scriptEntry.setPlayer((dPlayer) arg.asType(dPlayer.class));

else if (arg.matchesPrefix("a, as")
&& arg.matchesArgumentType(dNPC.class))
scriptEntry.setNPC((dNPC) arg.asType(dNPC.class));

else if (arg.matchesPrefix("d, def, define, c, context"))
scriptEntry.addObject("definitions", arg.asType(dList.class));

else if (arg.matches("instant, instantly"))
scriptEntry.addObject("instant", new Element(true));
Expand All @@ -43,57 +110,59 @@ else if (arg.matchesPrefix("delay")
&& arg.matchesArgumentType(Duration.class))
scriptEntry.addObject("delay", arg.asType(Duration.class));

else if (arg.matches("loop"))
scriptEntry.addObject("loop", new Element(true));
else if (arg.matches("local, locally"))
scriptEntry.addObject("local", new Element(true));

else if (arg.matchesPrefix("q, quantity")
&& arg.matchesPrimitive(aH.PrimitiveType.Integer))
scriptEntry.addObject("quantity", arg.asElement());

else if (arg.matchesPrefix("a, as")
&& arg.matchesArgumentType(dPlayer.class))
scriptEntry.setPlayer((dPlayer) arg.asType(dPlayer.class));
else if (!scriptEntry.hasObject("script")
&& arg.matchesArgumentType(dScript.class))
scriptEntry.addObject("script", arg.asType(dScript.class));

else if (arg.matchesPrefix("a, as")
&& arg.matchesArgumentType(dNPC.class))
scriptEntry.setNPC((dNPC) arg.asType(dNPC.class));
else if (!scriptEntry.hasObject("path"))
scriptEntry.addObject("path", arg.asElement());

else if (arg.matchesPrefix("d, def, define, c, context"))
scriptEntry.addObject("definitions", arg.asType(dList.class));
}

if (!scriptEntry.hasObject("script"))
if (!scriptEntry.hasObject("script") && !scriptEntry.hasObject("local"))
throw new InvalidArgumentsException("Must define a SCRIPT to be run.");

if (!scriptEntry.hasObject("path") && scriptEntry.hasObject("local"))
throw new InvalidArgumentsException("Must specify a PATH.");

}

@Override
public void execute(ScriptEntry scriptEntry) throws CommandExecutionException {

dB.report(getName(), scriptEntry.getdObject("script").debug()
+ (scriptEntry.hasObject("instant") ? scriptEntry.getdObject("instant").debug() : ""));

// definitions
// loop
// quantity
// delay
// instant
dB.report(getName(),
(scriptEntry.hasObject("script") ? scriptEntry.getdObject("script").debug() : scriptEntry.getScript().debug())
+ (scriptEntry.hasObject("instant") ? scriptEntry.getdObject("instant").debug() : "")
+ (scriptEntry.hasObject("path") ? scriptEntry.getElement("path").debug() : "")
+ (scriptEntry.hasObject("local") ? scriptEntry.getElement("local").debug() : "")
+ (scriptEntry.hasObject("delay") ? scriptEntry.getdObject("delay").debug() : ""));

// Get the script
dScript script = (dScript) scriptEntry.getObject("script");

// Get the entries
List<ScriptEntry> entries;
// If a path is specified
if (scriptEntry.hasObject("path"))
// If it's local
if (scriptEntry.hasObject("local"))
entries = scriptEntry.getScript().getContainer().getEntries(
scriptEntry.getPlayer(),
scriptEntry.getNPC(),
scriptEntry.getElement("path").asString());

// If it has a path
else if (scriptEntry.hasObject("path"))
entries = script.getContainer().getEntries(
scriptEntry.getPlayer(),
scriptEntry.getNPC(),
scriptEntry.getElement("path").asString());

// Else, assume standard path
// Else, assume standard path
else entries = script.getContainer().getBaseEntries(
scriptEntry.getPlayer(),
scriptEntry.getNPC());
scriptEntry.getPlayer(),
scriptEntry.getNPC());

// Get the 'id' if specified
String id = (scriptEntry.hasObject("id") ?
Expand All @@ -115,10 +184,10 @@ public void execute(ScriptEntry scriptEntry) throws CommandExecutionException {
dList definitions = (dList) scriptEntry.getObject("definitions");
String[] definition_names = null;
try { definition_names = script.getContainer().getString("definitions").split("\\|"); }
catch (Exception e) { }
catch (Exception e) { }
for (String definition : definitions) {
queue.addDefinition(definition_names != null && definition_names.length >= x ?
definition_names[x - 1].trim() : String.valueOf(x), definition);
definition_names[x - 1].trim() : String.valueOf(x), definition);
x++;
}
}
Expand Down
Expand Up @@ -1777,52 +1777,51 @@ public void playerBucketFill(PlayerBucketFillEvent event) {
}
}

// <--[example]
// @Title On Command Event tutorial
// @Description
// Denizen contains the ability to run script entries in the form
// of a bukkit /command. Here's an example script that shows basic usage.
//
// @Code
// # +--------------------
// # | On Command Event tutorial
//
// # | Denizen contains the ability to run script entries in the form
// # | of a bukkit /command. Here's an example script that shows basic usage.
//
//
// Example On Command Event Tutorial Script:
// type: world
//
// # +-- EVENTS: Node --+
// # To 'hook' into the on command event, just create a 'on <command_name> command'
// # node as a child of the events node in any world script. Change out <command_name>
// # with the desired name of the command. This can only be one word.
//
// events:
//
// # The following example will trigger on the use of '/testcommand'
// on testcommand command:
//
// # Why not state the obvious? Just to be sure!
// - narrate 'You just use the /testcommand command!'
//
// # You can utilize any arguments that come along with the command, too!
// # <c.args> returns a list of the arguments, run through the Denizen argument
// # interpreter. Using quotes will allow the use of multiple word arguments,
// # just like Denizen!
// # Just need what was typed after the command? Use <c.raw_args> for a String
// # Element containing the uninterpreted arguments.
// - define arg_size <c.args.size>
// - narrate "'%arg_size%' arguments were used."
// - if %arg_size% > 0 {
// - narrate "'<c.args.get[1]>' was the first argument."
// - narrate "Here's a list of all the arguments: <c.args.as_cslist>"
// }
//
// # When a command isn't found, Bukkit reports an error. To let bukkit know
// # that the command was handled, use the 'determine fulfilled' command/arg.
// - determine fulfilled
// <--[example]
// @Title On Command Event tutorial
// @Description
// Denizen contains the ability to run script entries in the form
// of a bukkit /command. Here's an example script that shows basic usage.
//
// @Code
// # +--------------------
// # | On Command Event tutorial
//
// # | Denizen contains the ability to run script entries in the form
// # | of a bukkit /command. Here's an example script that shows basic usage.
//
// On Command Event Tutorial:
// type: world
//
// # +-- EVENTS: Node --+
// # To 'hook' into the on command event, just create a 'on <command_name> command'
// # node as a child of the events node in any world script. Change out <command_name>
// # with the desired name of the command. This can only be one word.
//
// events:
//
// # The following example will trigger on the use of '/testcommand'
// on testcommand command:
//
// # Why not state the obvious? Just to be sure!
// - narrate 'You just use the /testcommand command!'
//
// # You can utilize any arguments that come along with the command, too!
// # <c.args> returns a list of the arguments, run through the Denizen argument
// # interpreter. Using quotes will allow the use of multiple word arguments,
// # just like Denizen!
// # Just need what was typed after the command? Use <c.raw_args> for a String
// # Element containing the uninterpreted arguments.
// - define arg_size <c.args.size>
// - narrate "'%arg_size%' arguments were used."
// - if %arg_size% > 0 {
// - narrate "'<c.args.get[1]>' was the first argument."
// - narrate "Here's a list of all the arguments<&co> <c.args.as_cslist>"
// }
//
// # When a command isn't found, Bukkit reports an error. To let bukkit know
// # that the command was handled, use the 'determine fulfilled' command/arg.
// - determine fulfilled
//
// -->

Expand Down

1 comment on commit d18cccd

@spaceemotion
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wow, that's awesome - nice job ;)

Please sign in to comment.