Skip to content

Commit

Permalink
Update 'scribe' command, add book script example meta.
Browse files Browse the repository at this point in the history
  • Loading branch information
aufdemrand committed Oct 5, 2013
1 parent c15bb6d commit 1b3bcf3
Show file tree
Hide file tree
Showing 2 changed files with 169 additions and 125 deletions.
Expand Up @@ -75,6 +75,8 @@ public void registerCoreMembers() {
// @Usage
// Use to make an ageable entity a permanant baby.
// - age e@50 baby lock
// ...or a mature adult.
// - age e@50 adult lock

// @Usage
// Use to make a baby entity an adult.
Expand Down Expand Up @@ -1708,9 +1710,77 @@ public void registerCoreMembers() {
"SCOREBOARD", "scoreboard [set/remove/show/hide] [<name>] [value:<name>] (priority:<#>)", 1);


/**
* <p>Scribes information to a Book from a dScript 'Book-type Script' or a Book ItemStack.</p>
*
* <b>dScript Usage:</b><br>
* <pre>Scribe [SCRIPT:book_script] (GIVE|{DROP}|EQUIP) (LOCATION:x,y,z,world) (ITEM:ITEMSTACK.name)</pre>
*
* <ol><tt>Arguments: [] - Required () - Optional {} - Default</ol></tt>
*
* <ol><tt>[SCRIPT:book_script]</tt><br>
* The name of the 'Book Script'. See below for format.</ol>
*
* <ol><tt>[GIVE|{DROP}|EQUIP]</tt><br>
* What to do with the book after it is written. If not specified, it will default
* to dropping the book near the NPC. Note: When using BOOK with an 'ITEMSTACK.name',
* no default action is set allowing other commands to modify the book.</ol>
*
* <ol><tt>(LOCATION:x,y,z,world)</tt><br>
* When using DROP, a location may be specified. Default location, if unspecified,
* is the attached NPC.</ol>
*
* <ol><tt>(ITEM:ITEMSTACK.name)</tt><br>
* Allows the use of a specific BOOK created with a 'saved ITEMSTACK' from the NEW
* command. If not specified, a new book will be used.</ol>
*
*
* <br><b>Sample Book Script:</b><br>
* <ol><pre>
* "Cosmos Book":<br>
* Type: Book<br>
* Title: Cosmos, a Personal Voyage<br>
* Author: Carl Sagan<br>
* Text:<br>
* - Every one of us is, in the cosmic perspective, precious. If a human disagrees with<br>
* you, let him live. In a hundred billion galaxies, you will not find another<br>
* - The nitrogen in our DNA, the calcium in our teeth, the iron in our blood, the <br>
* carbon in our apple pies were made in the interiors of collapsing stars. We are <br>
* made of starstuff.<br>
* </pre></ol>
*
* <p>Note: ScribeCommand also implements a replaceable tag for &#60;P>, which creates a new
* paragraph in a written book's text.</p>
*
* <br><b>Example Usage:</b><br>
* <ol><tt>
* - SCRIBE SCRIPT:Cosmos DROP<br>
* - SCRIBE ITEM:ITEMSTACK.ImportantBook 'SCRIPT:Spellbook of Haste'<br>
* </ol></tt>
*
* <br><b>Extended Usage:</b><br>
* <ol><tt>
* Script: <br>
* - ENGAGE NOW DURATION:10 <br>
* - LOOKCLOSE TOGGLE:TRUE DURATION:10 <br>
* - CHAT 'Use this book with care, as it is very powerful and could cause great harm<br>
* if put into the wrong hands!' <br>
* - WAIT 2 <br>
* - ^ANIMATE ANIMATION:ARM_SWING <br>
* - ^NEW ITEMSTACK ITEM:book ID:&#60;PLAYER.NAME>s_enchanted_spellbook<br>
* - ^SCRIBE ITEM:ITEMSTACK.&#60;PLAYER.NAME>s_enchanted_spellbook SCRIPT:silk_touch_description <br>
* - ^ENCHANT ITEM:ITEMSTACK.&#60;PLAYER.NAME>s_enchanted_spellbook ENCHANTMENT:SILKTOUCH<br>
* - ^LORE ADD ITEM:ITEMSTACK.&#60;PLAYER.NAME>s_enchanted_spellbook 'A spell of Silk-touch, level 1'<br>
* - DROP ITEM:ITEMSTACK.&#60;PLAYER.NAME>s_enchanted_spellbook<br>
* - NARRATE '&#60;NPC.NAME> drops an old book.' <br>
* </ol></tt>
*
* @author Mason Adkins
*/

// <--[command]
// @Name Scribe
// @Usage scribe [script:<name>] (give/drop/equip) (<item>) (<location>)
// @Usage scribe [script:<name>] (give/drop <location>/equip/<item>)
// @Required 1
// @Stable Todo
// @Short Writes to a book.
Expand All @@ -1723,7 +1793,7 @@ public void registerCoreMembers() {
// Todo
// -->
registerCoreMember(ScribeCommand.class,
"SCRIBE", "scribe [script:<name>] (give/drop/equip) (<item>) (<location>)", 1);
"SCRIBE", "scribe [<script>] (<item>/give/equip/{drop <location>})", 1);


// <--[command]
Expand Down
Expand Up @@ -3,14 +3,11 @@
import net.aufdemrand.denizen.events.ReplaceableTagEvent;
import net.aufdemrand.denizen.exceptions.CommandExecutionException;
import net.aufdemrand.denizen.exceptions.InvalidArgumentsException;
import net.aufdemrand.denizen.objects.dNPC;
import net.aufdemrand.denizen.objects.dPlayer;
import net.aufdemrand.denizen.objects.*;
import net.aufdemrand.denizen.scripts.ScriptEntry;
import net.aufdemrand.denizen.scripts.ScriptRegistry;
import net.aufdemrand.denizen.scripts.commands.AbstractCommand;
import net.aufdemrand.denizen.scripts.containers.core.BookScriptContainer;
import net.aufdemrand.denizen.objects.dItem;
import net.aufdemrand.denizen.objects.aH;
import net.aufdemrand.denizen.utilities.debugging.dB;
import net.aufdemrand.denizen.utilities.debugging.dB.Messages;
import org.bukkit.Location;
Expand All @@ -21,75 +18,69 @@
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;

/**
* <p>Scribes information to a Book from a dScript 'Book-type Script' or a Book ItemStack.</p>
*
* <b>dScript Usage:</b><br>
* <pre>Scribe [SCRIPT:book_script] (GIVE|{DROP}|EQUIP) (LOCATION:x,y,z,world) (ITEM:ITEMSTACK.name)</pre>
*
* <ol><tt>Arguments: [] - Required () - Optional {} - Default</ol></tt>
*
* <ol><tt>[SCRIPT:book_script]</tt><br>
* The name of the 'Book Script'. See below for format.</ol>
*
* <ol><tt>[GIVE|{DROP}|EQUIP]</tt><br>
* What to do with the book after it is written. If not specified, it will default
* to dropping the book near the NPC. Note: When using BOOK with an 'ITEMSTACK.name',
* no default action is set allowing other commands to modify the book.</ol>
*
* <ol><tt>(LOCATION:x,y,z,world)</tt><br>
* When using DROP, a location may be specified. Default location, if unspecified,
* is the attached NPC.</ol>
*
* <ol><tt>(ITEM:ITEMSTACK.name)</tt><br>
* Allows the use of a specific BOOK created with a 'saved ITEMSTACK' from the NEW
* command. If not specified, a new book will be used.</ol>
*
*
* <br><b>Sample Book Script:</b><br>
* <ol><pre>
* "Cosmos Book":<br>
* Type: Book<br>
* Title: Cosmos, a Personal Voyage<br>
* Author: Carl Sagan<br>
* Text:<br>
* - Every one of us is, in the cosmic perspective, precious. If a human disagrees with<br>
* you, let him live. In a hundred billion galaxies, you will not find another<br>
* - The nitrogen in our DNA, the calcium in our teeth, the iron in our blood, the <br>
* carbon in our apple pies were made in the interiors of collapsing stars. We are <br>
* made of starstuff.<br>
* </pre></ol>
*
* <p>Note: ScribeCommand also implements a replaceable tag for &#60;P>, which creates a new
* paragraph in a written book's text.</p>
*
* <br><b>Example Usage:</b><br>
* <ol><tt>
* - SCRIBE SCRIPT:Cosmos DROP<br>
* - SCRIBE ITEM:ITEMSTACK.ImportantBook 'SCRIPT:Spellbook of Haste'<br>
* </ol></tt>
*
* <br><b>Extended Usage:</b><br>
* <ol><tt>
* Script: <br>
* - ENGAGE NOW DURATION:10 <br>
* - LOOKCLOSE TOGGLE:TRUE DURATION:10 <br>
* - CHAT 'Use this book with care, as it is very powerful and could cause great harm<br>
* if put into the wrong hands!' <br>
* - WAIT 2 <br>
* - ^ANIMATE ANIMATION:ARM_SWING <br>
* - ^NEW ITEMSTACK ITEM:book ID:&#60;PLAYER.NAME>s_enchanted_spellbook<br>
* - ^SCRIBE ITEM:ITEMSTACK.&#60;PLAYER.NAME>s_enchanted_spellbook SCRIPT:silk_touch_description <br>
* - ^ENCHANT ITEM:ITEMSTACK.&#60;PLAYER.NAME>s_enchanted_spellbook ENCHANTMENT:SILKTOUCH<br>
* - ^LORE ADD ITEM:ITEMSTACK.&#60;PLAYER.NAME>s_enchanted_spellbook 'A spell of Silk-touch, level 1'<br>
* - DROP ITEM:ITEMSTACK.&#60;PLAYER.NAME>s_enchanted_spellbook<br>
* - NARRATE '&#60;NPC.NAME> drops an old book.' <br>
* </ol></tt>
*
* @author Mason Adkins
*/

public class ScribeCommand extends AbstractCommand implements Listener{
public class ScribeCommand extends AbstractCommand implements Listener {

// <--[example]
// @Name Book scripts and the scribe command example
// @Description
// Use the following example to get the basics on book scripts, tags, and
// the scribe command.

// @Code
// # +-----------------------------------
// # | Book Meta Tester
//
// # | Use /gettestbook, then /testbook to check if you are holding the book.
//
// Book Meta Tester:
// type: world
//
// events:
// on gettestbook command:
// # Use the scribe command to create a book, and drop it on the ground.
// - scribe drop 'script:Example book script' location:<player.location>
// - narrate 'Hey look, a book on the ground! Pick it up and use /testbook.'
// # Let bukkit know we handled the 'gettestbook' command.
// - determine fulfilled
//
// on testbook command:
// - define item player.item_in_hand
// - if '<pr:example book script checker>' {
// - narrate 'This is the book!'
// - narrate "This is the title<&co> <%item%.book.title>"
// - narrate "It has <%item%.book.page_count> pages."
// - narrate "It was written by <%item%.book.author>!"
// } else narrate 'The item in your hand is not the test book.'
//
// - determine fulfilled
//
//
// Example book script:
// type: book
//
// title: This is an example title.
// author: aufdemrand
// text:
// - page 1 is pretty short.
// - page 2 is kind of short, but longer than page 1.
// - page 3 is super short.
//
//
// # We'll use this in the if statement to test if the book has the title
// # we are looking for.
// # Want to use something like this in interact script requirements?
// # Just add an entry like so: - valueof '<pr:Example book script checker>'
//
// Example book script checker:
// type: procedure
//
// script:
// - if <player.item_in_hand.book.title> == 'This is an example title.'
// determine true
// else determine false

// -->


private enum BookAction { GIVE, DROP, EQUIP, NONE }

Expand All @@ -100,70 +91,51 @@ public void onEnable() {

@Override
public void parseArgs(ScriptEntry scriptEntry) throws InvalidArgumentsException {
// Initialize required fields
boolean savedItem = false; // Used in determining if a 'saved ItemStack' is being used
BookAction action = BookAction.NONE;

dItem book = null;
Player player = scriptEntry.getPlayer().getPlayerEntity();
String scriptName = null;
Location location = null;
dNPC npc = scriptEntry.getNPC();

if (npc != null)
location = npc.getLocation();
for (aH.Argument arg : aH.interpret(scriptEntry.getArguments())) {

for (String arg : scriptEntry.getArguments()) {
if (aH.matchesArg("DROP, GIVE, EQUIP", arg))
action = BookAction.valueOf(arg.toUpperCase());
if (arg.matchesEnum(BookAction.values())
&& !scriptEntry.hasObject("action"))
scriptEntry.addObject("action", BookAction.valueOf(arg.getValue().toUpperCase()));

else if (aH.matchesScript(arg))
scriptName = aH.getStringFrom(arg);
else if (!scriptEntry.hasObject("script")
&& arg.matchesArgumentType(dScript.class))
scriptEntry.addObject("script", arg.asType(dScript.class));

else if (aH.matchesLocation(arg)) {
location = aH.getLocationFrom(arg);
action = BookAction.DROP;
else if (!scriptEntry.hasObject("location")
&& arg.matchesArgumentType(dLocation.class)) {
scriptEntry.addObject("location", arg.asType(dLocation.class));
scriptEntry.addObject("action", BookAction.DROP);
}

else if (aH.matchesItem(arg)) {
book = aH.getItemFrom(arg);
if (book.getItemStack().getType() == Material.BOOK_AND_QUILL || book.getItemStack().getType() == Material.WRITTEN_BOOK) {
savedItem = true;
} else {
book = null;
}
else if (!scriptEntry.hasObject("item")
&& arg.matchesArgumentType(dItem.class)) {
scriptEntry.addObject("item", arg.asType(dItem.class));

} else throw new InvalidArgumentsException(Messages.ERROR_UNKNOWN_ARGUMENT, arg);
} else arg.reportUnhandled();
}

if (action == BookAction.NONE && !savedItem) action = BookAction.GIVE;
if (scriptName == null) throw new InvalidArgumentsException("Missing SCRIPT argument!");
if (book == null) book = new dItem(387);

// Save objects to ScriptEntry for usage in execute
scriptEntry.addObject("action", action);
scriptEntry.addObject("book", book);
scriptEntry.addObject("script", scriptName);
scriptEntry.addObject("player", player);
scriptEntry.addObject("location", location);
scriptEntry.addObject("npc", npc);
scriptEntry.defaultObject("action", BookAction.GIVE);
scriptEntry.defaultObject("item", new dItem(Material.WRITTEN_BOOK));

// Must contain a book script
if (!scriptEntry.hasObject("script"))
throw new InvalidArgumentsException("Missing SCRIPT argument!");

}

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

// Retrieve objects from ScriptEntry
BookAction action = (BookAction) scriptEntry.getObject("action");
dItem book = (dItem) scriptEntry.getObject("book");
String scriptName = (String) scriptEntry.getObject("script");
Player player = (Player) scriptEntry.getObject("player");
Location location = (Location) scriptEntry.getObject("location");
dNPC npc = (dNPC) scriptEntry.getObject("npc");
dItem book = (dItem) scriptEntry.getObject("item");
dScript script = (dScript) scriptEntry.getObject("script");
dLocation location = (dLocation) scriptEntry.getObject("location");

BookScriptContainer bookScript = ScriptRegistry.getScriptContainerAs(scriptName, BookScriptContainer.class);
BookScriptContainer bookScript = (BookScriptContainer) script.getContainer();

book = bookScript.writeBookTo(book, dPlayer.mirrorBukkitPlayer(player), npc);
book = bookScript.writeBookTo(book, scriptEntry.getPlayer(), scriptEntry.getNPC());

// Post-write action? Can be NONE.
switch (action) {
Expand All @@ -172,19 +144,21 @@ public void execute(ScriptEntry scriptEntry) throws CommandExecutionException {
break;

case GIVE:
giveBook(player, book.getItemStack());
giveBook(scriptEntry.getPlayer().getPlayerEntity(), book.getItemStack());
// Update player's inventory
scriptEntry.getPlayer().getPlayerEntity().updateInventory();
break;

case EQUIP:
equipBook(player, book.getItemStack());
equipBook(scriptEntry.getPlayer().getPlayerEntity(), book.getItemStack());
// Update player's inventory
scriptEntry.getPlayer().getPlayerEntity().updateInventory();
break;

case NONE:
break;
}

// Update player's inventory
player.updateInventory();
}

private void giveBook(Player player, ItemStack book) {
Expand Down

0 comments on commit 1b3bcf3

Please sign in to comment.