From 0a21b48b15b4403fb4e1107083039589253c40a2 Mon Sep 17 00:00:00 2001 From: Pepich Date: Sun, 11 Jun 2017 19:39:09 +0200 Subject: [PATCH] Signalstrength (#8) * Added SignalStrength module --- .../modules/signalstrength/SignalStrength.cmd | 14 ++ .../signalstrength/SignalStrength.java | 135 ++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 src/com/redstoner/modules/signalstrength/SignalStrength.cmd create mode 100644 src/com/redstoner/modules/signalstrength/SignalStrength.java diff --git a/src/com/redstoner/modules/signalstrength/SignalStrength.cmd b/src/com/redstoner/modules/signalstrength/SignalStrength.cmd new file mode 100644 index 0000000..1cfb0fd --- /dev/null +++ b/src/com/redstoner/modules/signalstrength/SignalStrength.cmd @@ -0,0 +1,14 @@ +command signalstrength { + alias ss; + perm utils.signalstrength; + [int:strength] { + run ss strength; + type player; + help "Sets the amount of items in a container to achieve the given signal strength. Uses redstone dust."; + } + [int:strength] [string:material] { + run ssm strength material; + type player; + help "Sets the amount of itmes in a container to achieve the given signal strength. Uses the material specified."; + } +} \ No newline at end of file diff --git a/src/com/redstoner/modules/signalstrength/SignalStrength.java b/src/com/redstoner/modules/signalstrength/SignalStrength.java new file mode 100644 index 0000000..bca8f49 --- /dev/null +++ b/src/com/redstoner/modules/signalstrength/SignalStrength.java @@ -0,0 +1,135 @@ +package com.redstoner.modules.signalstrength; + +import java.util.ArrayList; +import java.util.HashSet; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; + +import com.nemez.cmdmgr.Command; +import com.nemez.cmdmgr.CommandManager; +import com.redstoner.annotations.Version; +import com.redstoner.misc.Main; +import com.redstoner.misc.Utils; +import com.redstoner.modules.Module; + +@Version(major = 3, minor = 0, revision = 0, compatible = 3) +public class SignalStrength implements Module +{ + @Override + public void postEnable() + { + CommandManager.registerCommand(this.getClass().getResourceAsStream("SignalStrength.cmd"), this, Main.plugin); + } + + @Command(hook = "ss") + public boolean ss(CommandSender sender, int strength) + { + return ssm(sender, strength, Material.REDSTONE_WIRE.toString()); + } + + @Command(hook = "ssm") + public boolean ssm(CommandSender sender, int strength, String material) + { + Material item_type = Material.getMaterial(material); + Player player = (Player) sender; + Block target_block = player.getTargetBlock(new HashSet(), 5); + if (target_block == null) + { + Utils.sendErrorMessage(sender, null, "That command can only be used if a container is targeted!"); + return true; + } + Inventory inventory = getInventory(target_block); + if (inventory == null) + { + Utils.sendErrorMessage(sender, null, "That command can only be used if a container is targeted!"); + return true; + } + // --------Get the stack size and required amount of items to achieve the desired signal strength--------- + int stack_size = item_type.getMaxStackSize(); + int slot_count = inventory.getSize(); + int item_count = required_item_count(strength, stack_size, slot_count); + if (item_count == -1) + { + Utils.sendErrorMessage(sender, null, + "The desired signal strength could not be achieved with the requested item type"); + return true; + } + // #--------Add the other side of the chest if target is a double chest and check if player can build--------- + ArrayList container_blocks = getAllContainers(target_block); + for (Block b : container_blocks) + { + if (!canBuild(player, b)) + { + Utils.sendErrorMessage(sender, "", "You can not build here!"); + return true; + } + } + // #----------------Insert items------------- + int full_stack_count = item_count / stack_size; + int remaining = item_count % stack_size; + for (Block b : container_blocks) + { + Inventory inv = getInventory(b); + inv.clear(); + for (int i = 0; i < full_stack_count; i++) + inv.setItem(i, new ItemStack(item_type, stack_size)); + if (remaining > 0) + inv.setItem(full_stack_count, new ItemStack(item_type, remaining)); + } + Utils.sendMessage(sender, null, + "Comparators attached to this Inventory will now put out a signal strength of" + strength); + return true; + } + + private int required_item_count(int strength, int stack_size, int slot_count) + { + int item_count = -1; + if (strength == 0) + item_count = 0; + else if (strength == 1) + item_count = 1; + else + item_count = (int) Math.ceil(slot_count * stack_size / 14.0 * (strength - 1)); + int resulting_strength = item_count == 0 ? 0 : (int) Math.ceil(1 + 14.0 * item_count / stack_size / slot_count); + // Clarification on these formulas at https://minecraft.gamepedia.com/Redstone_Comparator#Containers + return resulting_strength == strength ? item_count : -1; + } + + private Inventory getInventory(Block b) + { + BlockState state = b.getState(); + if (state instanceof InventoryHolder) + return ((InventoryHolder) state).getInventory(); + return null; + } + + private boolean canBuild(Player p, Block b) + { + BlockPlaceEvent e = new BlockPlaceEvent(b, b.getState(), b.getRelative(BlockFace.DOWN), + p.getInventory().getItemInMainHand(), p, true, EquipmentSlot.HAND); + return e.isCancelled(); + } + + private ArrayList getAllContainers(Block b) + { + ArrayList result = new ArrayList(); + result.add(b); + for (BlockFace face : BlockFace.values()) + { + Block b2 = b.getRelative(face); + if (getInventory(b2) != null) + result.add(b2); + } + return result; + } +}