package com.massivecraft.factions.cmd.tnt; import com.massivecraft.factions.FPlayer; import com.massivecraft.factions.FactionsPlugin; import com.massivecraft.factions.cmd.CommandContext; import com.massivecraft.factions.cmd.CommandRequirements; import com.massivecraft.factions.cmd.FCommand; import com.massivecraft.factions.struct.Permission; import com.massivecraft.factions.zcore.fperms.PermissableAction; import com.massivecraft.factions.zcore.util.TL; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockState; import org.bukkit.block.Dispenser; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; import java.util.ArrayList; import java.util.HashMap; import java.util.List; public class CmdTntFill extends FCommand { public CmdTntFill() { super(); this.aliases.add("tntfill"); this.requiredArgs.add("radius"); this.requiredArgs.add("amount"); this.requirements = new CommandRequirements.Builder(Permission.TNTFILL) .playerOnly() .memberOnly() .withAction(PermissableAction.TNTFILL) .build(); } @Override public void perform(CommandContext context) { if (!FactionsPlugin.getInstance().getConfig().getBoolean("Tntfill.enabled")) { context.msg(TL.GENERIC_DISABLED); return; } // Don't do I/O unless necessary try { Integer.parseInt(context.args.get(0)); Integer.parseInt(context.args.get(1)); } catch (NumberFormatException e) { context.msg(TL.COMMAND_TNT_INVALID_NUM); return; } context.msg(TL.COMMAND_TNTFILL_HEADER); int radius = context.argAsInt(0, 0); // We don't know the max yet, so let's not assume. int amount = context.argAsInt(1, 0); // We don't know the max yet, so let's not assume. if (amount < 0) { context.msg(TL.COMMAND_TNT_POSITIVE); return; } if (radius > FactionsPlugin.getInstance().getConfig().getInt("Tntfill.max-radius")) { context.msg(TL.COMMAND_TNTFILL_RADIUSMAX.toString().replace("{max}", FactionsPlugin.getInstance().getConfig().getInt("Tntfill.max-radius") + "")); return; } if (amount > FactionsPlugin.getInstance().getConfig().getInt("Tntfill.max-amount")) { context.msg(TL.COMMAND_TNTFILL_AMOUNTMAX.toString().replace("{max}", FactionsPlugin.getInstance().getConfig().getInt("Tntfill.max-amount") + "")); return; } // How many dispensers are we to fill in? Location start = context.player.getLocation(); // Keep it on the stack for CPU saving. List opDispensers = new ArrayList<>(); Block startBlock = start.getBlock(); for (int x = -radius; x <= radius; x++) for (int y = -radius; y <= radius; y++) for (int z = -radius; z <= radius; z++) { Block block = startBlock.getRelative(x, y, z); if (block == null) continue; BlockState blockState = block.getState(); if (!(blockState instanceof Dispenser)) continue; opDispensers.add((Dispenser) blockState); } if (opDispensers.isEmpty()) { context.fPlayer.msg(TL.COMMAND_TNTFILL_NODISPENSERS.toString().replace("{radius}", radius + "")); return; } // What's the required amount of resources int requiredTnt = (opDispensers.size() * amount); // Do I have enough tnt in my inventory? int playerTnt = inventoryItemCount(context.player.getInventory(), Material.TNT); if (playerTnt < requiredTnt) { // How much TNT will I take from bank? int getFactionTnt = requiredTnt - playerTnt; // Do I have enough tnt in bank? if ((context.faction.getTnt() < getFactionTnt)) { context.fPlayer.msg(TL.COMMAND_TNT_WIDTHDRAW_NOTENOUGH_TNT.toString()); return; } // Take TNT from the bank. removeFromBank(context, getFactionTnt); } fillDispensers(context.fPlayer, opDispensers, amount); // Remove used TNT from player inventory. context.sendMessage(TL.COMMAND_TNTFILL_SUCCESS.toString().replace("{amount}", requiredTnt + "").replace("{dispensers}", opDispensers.size() + "")); } // Actually fill every dispenser with the precise amount. private void fillDispensers(FPlayer fPlayer, List dispensers, int count) { for (Dispenser dispenser : dispensers) { takeTnt(fPlayer, count); dispenser.getInventory().addItem(new ItemStack(Material.TNT, count)); } } private void removeFromBank(CommandContext context, int amount) { try { Integer.parseInt(context.args.get(1)); } catch (NumberFormatException e) { context.fPlayer.msg(TL.COMMAND_TNT_INVALID_NUM.toString()); return; } if (amount < 0) { context.fPlayer.msg(TL.COMMAND_TNT_POSITIVE.toString()); return; } if (context.faction.getTnt() < amount) { context.fPlayer.msg(TL.COMMAND_TNT_WIDTHDRAW_NOTENOUGH_TNT.toString()); return; } int fullStacks = amount / 64; int remainderAmt = amount % 64; if ((remainderAmt == 0 && getEmptySlots(context.player) <= fullStacks)) { context.fPlayer.msg(TL.COMMAND_TNT_WIDTHDRAW_NOTENOUGH_TNT.toString()); return; } if (getEmptySlots(context.player) + 1 <= fullStacks) { context.fPlayer.msg(TL.COMMAND_TNT_WIDTHDRAW_NOTENOUGH_TNT.toString()); return; } ItemStack tnt64 = new ItemStack(Material.TNT, 64); for (int i = 0; i <= fullStacks - 1; i++) { context.player.getInventory().addItem(tnt64); } if (remainderAmt != 0) { ItemStack tnt = new ItemStack(Material.TNT, remainderAmt); context.player.getInventory().addItem(tnt); } context.faction.takeTnt(amount); context.player.updateInventory(); } private void takeTnt(FPlayer fme, int amount) { Inventory inv = fme.getPlayer().getInventory(); int invTnt = 0; for (int i = 0; i <= inv.getSize(); i++) { if (inv.getItem(i) == null) { continue; } if (inv.getItem(i).getType() == Material.TNT) { invTnt += inv.getItem(i).getAmount(); } } if (amount > invTnt) { fme.msg(TL.COMMAND_TNTFILL_NOTENOUGH.toString()); return; } ItemStack tnt = new ItemStack(Material.TNT, amount); if (fme.getFaction().getTnt() + amount > FactionsPlugin.getInstance().getConfig().getInt("ftnt.Bank-Limit")) { fme.msg(TL.COMMAND_TNT_EXCEEDLIMIT.toString()); return; } removeFromInventory(fme.getPlayer().getInventory(), tnt); } // Counts the item type available in the inventory. private int inventoryItemCount(Inventory inventory, Material mat) { int count = 0; HashMap items = inventory.all(mat); for (int item : items.keySet()) count += inventory.getItem(item).getAmount(); return count; } private void removeFromInventory(Inventory inventory, ItemStack item) { int amt = item.getAmount(); ItemStack[] items = inventory.getContents(); for (int i = 0; i < items.length; i++) { if (items[i] != null && items[i].getType() == item.getType() && items[i].getDurability() == item.getDurability()) { if (items[i].getAmount() > amt) { items[i].setAmount(items[i].getAmount() - amt); break; } else if (items[i].getAmount() == amt) { items[i] = null; break; } else { amt -= items[i].getAmount(); items[i] = null; } } } inventory.setContents(items); } private int getEmptySlots(Player p) { PlayerInventory inventory = p.getInventory(); ItemStack[] cont = inventory.getContents(); int i = 0; for (ItemStack item : cont) if (item != null && item.getType() != Material.AIR) { i++; } return 36 - i; } @Override public TL getUsageTranslation() { return TL.COMMAND_TNTFILL_DESCRIPTION; } }