package net.aufdemrand.denizen.scripts.commands.item;
import net.aufdemrand.denizen.BukkitScriptEntryData;
import net.aufdemrand.denizen.objects.dInventory;
import net.aufdemrand.denizen.objects.dItem;
import net.aufdemrand.denizen.utilities.debugging.dB;
import net.aufdemrand.denizen.utilities.depends.Depends;
import net.aufdemrand.denizencore.exceptions.CommandExecutionException;
import net.aufdemrand.denizencore.exceptions.InvalidArgumentsException;
import net.aufdemrand.denizencore.objects.Element;
import net.aufdemrand.denizencore.objects.aH;
import net.aufdemrand.denizencore.objects.dList;
import net.aufdemrand.denizencore.scripts.ScriptEntry;
import net.aufdemrand.denizencore.scripts.commands.AbstractCommand;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import java.util.List;
public class TakeCommand extends AbstractCommand {
private enum Type {MONEY, ITEMINHAND, ITEM, INVENTORY, BYDISPLAY, SLOT, BYCOVER}
@Override
public void parseArgs(ScriptEntry scriptEntry) throws InvalidArgumentsException {
for (aH.Argument arg : aH.interpret(scriptEntry.getArguments())) {
if (!scriptEntry.hasObject("type")
&& arg.matches("money", "coins")) {
scriptEntry.addObject("type", Type.MONEY);
}
else if (!scriptEntry.hasObject("type")
&& arg.matches("item_in_hand", "iteminhand")) {
scriptEntry.addObject("type", Type.ITEMINHAND);
}
else if (!scriptEntry.hasObject("qty")
&& arg.matchesPrefix("q", "qty", "quantity")
&& arg.matchesPrimitive(aH.PrimitiveType.Double)) {
scriptEntry.addObject("qty", arg.asElement());
}
else if (!scriptEntry.hasObject("items")
&& arg.matchesPrefix("bydisplay")
&& !scriptEntry.hasObject("type")) {
scriptEntry.addObject("type", Type.BYDISPLAY);
scriptEntry.addObject("displayname", arg.asElement());
}
else if (!scriptEntry.hasObject("type")
&& !scriptEntry.hasObject("items")
&& arg.matchesPrefix("bycover")) {
scriptEntry.addObject("type", Type.BYCOVER);
scriptEntry.addObject("cover", arg.asType(dList.class));
}
else if (!scriptEntry.hasObject("slot")
&& !scriptEntry.hasObject("type")
&& arg.matchesPrefix("slot")
&& arg.matchesPrimitive(aH.PrimitiveType.Integer)) {
scriptEntry.addObject("type", Type.SLOT);
scriptEntry.addObject("slot", arg.asElement());
}
else if (!scriptEntry.hasObject("items")
&& !scriptEntry.hasObject("type")
&& arg.matchesArgumentList(dItem.class)) {
scriptEntry.addObject("items", dList.valueOf(arg.raw_value.replace("item:", "")).filter(dItem.class, scriptEntry));
}
else if (!scriptEntry.hasObject("inventory")
&& arg.matchesPrefix("f", "from")
&& arg.matchesArgumentType(dInventory.class)) {
scriptEntry.addObject("inventory", arg.asType(dInventory.class));
}
else if (!scriptEntry.hasObject("type")
&& arg.matches("inventory")) {
scriptEntry.addObject("type", Type.INVENTORY);
}
else if (!scriptEntry.hasObject("inventory")
&& arg.matches("npc")) {
scriptEntry.addObject("inventory", ((BukkitScriptEntryData) scriptEntry.entryData).getNPC().getDenizenEntity().getInventory());
}
}
scriptEntry.defaultObject("type", Type.ITEM)
.defaultObject("qty", new Element(1));
Type type = (Type) scriptEntry.getObject("type");
if (type != Type.MONEY && scriptEntry.getObject("inventory") == null) {
scriptEntry.addObject("inventory", ((BukkitScriptEntryData) scriptEntry.entryData).hasPlayer() ? ((BukkitScriptEntryData) scriptEntry.entryData).getPlayer().getInventory() : null);
}
if (!scriptEntry.hasObject("inventory") && type != Type.MONEY) {
throw new InvalidArgumentsException("Must specify an inventory to take from!");
}
if (type == Type.ITEM && scriptEntry.getObject("items") == null) {
throw new InvalidArgumentsException("Must specify item/items!");
}
}
@Override
public void execute(ScriptEntry scriptEntry) throws CommandExecutionException {
dInventory inventory = (dInventory) scriptEntry.getObject("inventory");
Element qty = scriptEntry.getElement("qty");
Element displayname = scriptEntry.getElement("displayname");
Element slot = scriptEntry.getElement("slot");
dList titleAuthor = scriptEntry.getdObject("cover");
Type type = (Type) scriptEntry.getObject("type");
Object items_object = scriptEntry.getObject("items");
List<dItem> items = null;
if (items_object != null) {
items = (List<dItem>) items_object;
}
dB.report(scriptEntry, getName(),
aH.debugObj("Type", type.name())
+ qty.debug()
+ (inventory != null ? inventory.debug() : "")
+ (displayname != null ? displayname.debug() : "")
+ aH.debugObj("Items", items)
+ (slot != null ? slot.debug() : "")
+ (titleAuthor != null ? titleAuthor.debug() : ""));
switch (type) {
case INVENTORY:
inventory.clear();
break;
case ITEMINHAND:
int inHandAmt = ((BukkitScriptEntryData) scriptEntry.entryData).getPlayer().getPlayerEntity().getItemInHand().getAmount();
int theAmount = (int) qty.asDouble();
ItemStack newHandItem = new ItemStack(0);
if (theAmount > inHandAmt) {
dB.echoDebug(scriptEntry, "...player did not have enough of the item in hand, so Denizen just took as many as it could. To avoid this situation, use an IF <PLAYER.ITEM_IN_HAND.QTY>.");
((BukkitScriptEntryData) scriptEntry.entryData).getPlayer().getPlayerEntity().setItemInHand(newHandItem);
}
else {
// amount is just right!
if (theAmount == inHandAmt) {
((BukkitScriptEntryData) scriptEntry.entryData).getPlayer().getPlayerEntity().setItemInHand(newHandItem);
}
else {
// amount is less than what's in hand, need to make a new itemstack of what's left...
newHandItem = new ItemStack(((BukkitScriptEntryData) scriptEntry.entryData).getPlayer().getPlayerEntity().getItemInHand().getType(),
inHandAmt - theAmount, ((BukkitScriptEntryData) scriptEntry.entryData).getPlayer().getPlayerEntity().getItemInHand().getData().getData());
newHandItem.setItemMeta(((BukkitScriptEntryData) scriptEntry.entryData).getPlayer().getPlayerEntity().getItemInHand().getItemMeta());
((BukkitScriptEntryData) scriptEntry.entryData).getPlayer().getPlayerEntity().setItemInHand(newHandItem);
((BukkitScriptEntryData) scriptEntry.entryData).getPlayer().getPlayerEntity().updateInventory();
}
}
break;
case MONEY:
if (Depends.economy != null) {
Depends.economy.withdrawPlayer(((BukkitScriptEntryData) scriptEntry.entryData).getPlayer().getOfflinePlayer(), qty.asDouble());
}
else {
dB.echoError(scriptEntry.getResidingQueue(), "No economy loaded! Have you installed Vault and a compatible economy plugin?");
}
break;
case ITEM:
for (dItem item : items) {
ItemStack is = item.getItemStack();
is.setAmount(qty.asInt());
if (!inventory.removeItem(item, item.getAmount())) {
dB.echoDebug(scriptEntry, "Inventory does not contain at least "
+ qty.asInt() + " of " + item.getFullString() +
"... Taking as much as possible...");
}
}
break;
case BYDISPLAY:
int found_items = 0;
if (displayname == null) {
dB.echoError(scriptEntry.getResidingQueue(), "Must specify a displayname!");
return;
}
for (ItemStack it : inventory.getContents()) {
if (found_items < qty.asInt() && it != null && it.hasItemMeta() && it.getItemMeta().hasDisplayName() &&
it.getItemMeta().getDisplayName().equalsIgnoreCase(displayname.identify())) {
int amt = it.getAmount();
if (found_items + it.getAmount() <= qty.asInt()) {
inventory.getInventory().removeItem(it);
}
else {
it.setAmount(it.getAmount() - (qty.asInt() - found_items));
break;
}
found_items += amt;
}
}
break;
case SLOT:
inventory.setSlots(slot.asInt() - 1, new ItemStack(Material.AIR));
break;
case BYCOVER:
inventory.removeBook(titleAuthor.get(0),
titleAuthor.size() > 1 ? titleAuthor.get(1) : null,
qty.asInt());
break;
}
}
}