package net.aufdemrand.denizen.scripts.commands.item;
import net.aufdemrand.denizen.BukkitScriptEntryData;
import net.aufdemrand.denizen.nms.NMSHandler;
import net.aufdemrand.denizen.nms.interfaces.PacketHelper;
import net.aufdemrand.denizen.objects.dItem;
import net.aufdemrand.denizen.objects.dPlayer;
import net.aufdemrand.denizen.utilities.debugging.dB;
import net.aufdemrand.denizencore.DenizenCore;
import net.aufdemrand.denizencore.exceptions.CommandExecutionException;
import net.aufdemrand.denizencore.exceptions.InvalidArgumentsException;
import net.aufdemrand.denizencore.objects.Duration;
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 net.aufdemrand.denizencore.utilities.scheduling.OneTimeSchedulable;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.Arrays;
import java.util.List;
public class FakeItemCommand extends AbstractCommand {
@Override
public void parseArgs(ScriptEntry scriptEntry) throws InvalidArgumentsException {
/* Match arguments to expected variables */
for (aH.Argument arg : aH.interpret(scriptEntry.getArguments())) {
if (!scriptEntry.hasObject("slot")
&& arg.matchesPrefix("slot")
&& arg.matchesPrimitive(aH.PrimitiveType.Integer)) {
scriptEntry.addObject("slot", arg.asElement());
}
else if (!scriptEntry.hasObject("duration")
&& arg.matchesPrefix("duration")
&& arg.matchesArgumentType(Duration.class)) {
scriptEntry.addObject("duration", arg.asType(Duration.class));
}
else if (!scriptEntry.hasObject("item")
&& arg.matchesArgumentList(dItem.class)) {
scriptEntry.addObject("item", arg.asType(dList.class).filter(dItem.class));
}
else if (!scriptEntry.hasObject("players")
&& arg.matchesArgumentList(dPlayer.class)
&& arg.matchesPrefix("players")) {
scriptEntry.addObject("players", arg.asType(dList.class).filter(dPlayer.class));
}
else if (!scriptEntry.hasObject("player_only")
&& arg.matches("player_only")) {
scriptEntry.addObject("player_only", new Element(true));
}
else {
arg.reportUnhandled();
}
}
if (!scriptEntry.hasObject("item")) {
throw new InvalidArgumentsException("Must specify a valid item to fake!");
}
if (!scriptEntry.hasObject("slot")) {
throw new InvalidArgumentsException("Must specify a valid slot!");
}
scriptEntry.defaultObject("duration", Duration.ZERO).defaultObject("player_only", new Element(false))
.defaultObject("players", Arrays.asList(((BukkitScriptEntryData) scriptEntry.entryData).getPlayer()));
}
@Override
public void execute(ScriptEntry scriptEntry) throws CommandExecutionException {
List<dItem> items = (List<dItem>) scriptEntry.getObject("item");
final Element elSlot = scriptEntry.getElement("slot");
Duration duration = scriptEntry.getdObject("duration");
final List<dPlayer> players = (List<dPlayer>) scriptEntry.getObject("players");
final Element player_only = scriptEntry.getElement("player_only");
dB.report(scriptEntry, getName(), aH.debugList("items", items) + elSlot.debug() + duration.debug()
+ aH.debugList("players", players) + player_only.debug());
int slot = elSlot.asInt() - 1;
final boolean playerOnly = player_only.asBoolean();
final PacketHelper packetHelper = NMSHandler.getInstance().getPacketHelper();
for (dItem item : items) {
if (item == null) {
slot++;
continue;
}
for (dPlayer player : players) {
Player ent = player.getPlayerEntity();
packetHelper.setSlot(ent, translateSlot(ent, slot, playerOnly), item.getItemStack(), playerOnly);
}
final int slotSnapshot = slot;
slot++;
if (duration.getSeconds() > 0) {
DenizenCore.schedule(new OneTimeSchedulable(new Runnable() {
@Override
public void run() {
for (dPlayer player : players) {
Player ent = player.getPlayerEntity();
ItemStack original = ent.getOpenInventory().getItem(translateSlot(ent, slotSnapshot, playerOnly));
packetHelper.setSlot(ent, slotSnapshot, original, playerOnly);
}
}
}, (float) duration.getSeconds()));
}
}
}
static int translateSlot(Player player, int slot, boolean player_only) {
if (slot < 0) {
return 0;
}
int total = player_only ? 46 : player.getOpenInventory().countSlots();
if (total == 46) {
if (slot == 45) {
return slot;
}
else if (slot > 35) {
slot = 8 - (slot - 36);
return slot;
}
total -= 1;
}
if (slot > total) {
return total;
}
return (int) (slot + (total - 9) - (9 * (2 * Math.floor(slot / 9))));
}
}