package net.aufdemrand.denizen.scripts.commands.npc; import net.aufdemrand.denizen.BukkitScriptEntryData; import net.aufdemrand.denizen.objects.dLocation; import net.aufdemrand.denizen.objects.dMaterial; import net.aufdemrand.denizen.objects.dNPC; import net.aufdemrand.denizen.utilities.DenizenAPI; import net.aufdemrand.denizen.utilities.debugging.dB; 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.dObject; import net.aufdemrand.denizencore.scripts.ScriptEntry; import net.aufdemrand.denizencore.scripts.commands.AbstractCommand; import net.aufdemrand.denizencore.scripts.commands.Holdable; import net.citizensnpcs.api.ai.tree.BehaviorStatus; import net.citizensnpcs.api.npc.BlockBreaker; import org.bukkit.Bukkit; import java.util.HashMap; public class BreakCommand extends AbstractCommand implements Holdable { @Override public void parseArgs(ScriptEntry scriptEntry) throws InvalidArgumentsException { for (aH.Argument arg : aH.interpret(scriptEntry.getArguments())) { if (!scriptEntry.hasObject("location") && arg.matchesArgumentType(dLocation.class)) { scriptEntry.addObject("location", arg.asType(dLocation.class)); } else if (!scriptEntry.hasObject("npc") && arg.matchesArgumentType(dNPC.class)) { scriptEntry.addObject("npc", arg.asType(dNPC.class)); } else if (!scriptEntry.hasObject("radius") && arg.matchesPrimitive(aH.PrimitiveType.Double)) { scriptEntry.addObject("radius", arg.asElement()); } else { arg.reportUnhandled(); } } // Make sure location and entity were fulfilled if (!scriptEntry.hasObject("location")) { throw new InvalidArgumentsException("Must specify a location!"); } // Use the NPC or the Player as the default entity if (!scriptEntry.hasObject("npc")) { if (((BukkitScriptEntryData) scriptEntry.entryData).hasNPC()) { scriptEntry.addObject("npc", ((BukkitScriptEntryData) scriptEntry.entryData).getNPC()); } else { throw new InvalidArgumentsException("Must specify a valid NPC!"); } } scriptEntry.defaultObject("radius", new Element(2)); } // <--[action] // @Actions // dig // // @Triggers when the NPC breaks a block with the Break Command // // @Context // <context.location> returns the location the NPC Dug // <context.material> Returns the Block dug // // --> @Override public void execute(ScriptEntry scriptEntry) throws CommandExecutionException { final dLocation location = (dLocation) scriptEntry.getObject("location"); final dNPC npc = (dNPC) scriptEntry.getObject("entity"); Element radius = scriptEntry.getElement("radius"); final HashMap<String, dObject> context = new HashMap<String, dObject>(); dMaterial material = dMaterial.getMaterialFrom(location.getBlock().getType(), location.getBlock().getData()); context.put("location", location); context.put("material", material); dB.report(scriptEntry, getName(), location.debug() + npc.debug() + radius.debug()); final ScriptEntry se = scriptEntry; BlockBreaker.BlockBreakerConfiguration config = new BlockBreaker.BlockBreakerConfiguration(); config.item(npc.getLivingEntity().getEquipment().getItemInHand()); config.radius(radius.asDouble()); config.callback(new Runnable() { @Override public void run() { npc.action("dig", null, context); se.setFinished(true); } }); BlockBreaker breaker = npc.getCitizen().getBlockBreaker(location.getBlock(), config); if (breaker.shouldExecute()) { TaskRunnable run = new TaskRunnable(breaker); run.taskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(DenizenAPI.getCurrentInstance(), run, 0, 1); } } private static class TaskRunnable implements Runnable { private int taskId; private final BlockBreaker breaker; public TaskRunnable(BlockBreaker breaker) { this.breaker = breaker; } @Override public void run() { if (breaker.run() != BehaviorStatus.RUNNING) { Bukkit.getScheduler().cancelTask(taskId); breaker.reset(); } } } }