summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDico200 <dico.karssiens@gmail.com>2015-10-20 18:05:40 +0200
committerDico200 <dico.karssiens@gmail.com>2015-10-20 18:05:40 +0200
commitce4fa316d9dbc61868650fc927e0eb23827c5938 (patch)
tree83bb7ff81ada388780728a6eaf4c7b0ce58cb9de
parent9119c3d1500a02b49d078a8a0d01a271e630092b (diff)
Added the signalstrength.py file.
-rw-r--r--signalstrength.py159
1 files changed, 159 insertions, 0 deletions
diff --git a/signalstrength.py b/signalstrength.py
new file mode 100644
index 0000000..b264143
--- /dev/null
+++ b/signalstrength.py
@@ -0,0 +1,159 @@
+from helpers import *
+import org.bukkit.inventory.ItemStack as ItemStack
+import org.bukkit.Material as Material
+from math import ceil
+from basecommands import simplecommand, Validate, CommandException
+
+""" Suggestion by Armadillo28, see thread: http://redstoner.com/forums/threads/2213?page=1#reply-14507 """
+
+disallowed_item_types = (
+ Material.getMaterial(0),
+ Material.getMaterial(175),
+ Material.getMaterial(383),
+)
+
+default_args = open_json_file("signalstrengthdefaults", {})
+
+def save_defaults():
+ save_json_file("signalstrengthdefaults", default_args)
+
+
+def item_name(item_type, remove_underscores = True):
+ typ = str(item_type).lower()
+ return typ.replace("_", "") if remove_underscores else typ
+
+
+def item_type_allowed(item_type):
+ return not item_type in disallowed_item_types
+
+
+def required_item_count(strength, stack_size, slot_count):
+ if strength == 0:
+ item_count = 0
+ elif strength == 1:
+ item_count = 1
+ else:
+ item_count = int(ceil(slot_count * stack_size / 14.0 * (strength - 1)))
+
+ resulting_strength = 0 if item_count == 0 else int(1 + 14.0 * item_count / stack_size / slot_count)
+ #Clarification on these formulas at http://minecraft.gamepedia.com/Redstone_Comparator#Containers
+
+ return item_count if resulting_strength == strength else None
+
+
+def get_data(player, args):
+ uuid = uid(player)
+ if uuid in default_args:
+ strength, item_type, item_data = default_args[uuid]
+ item_type = Material.getMaterial(item_type)
+ else:
+ strength = 1
+ item_type = Material.REDSTONE
+ item_data = 0
+
+ if len(args) > 0:
+ Validate.isTrue(args[0].isdigit() and 0 <= int(args[0]) <= 15, "&cThe signal strength has to be a value from 0 to 15")
+ strength = int(args[0])
+
+ if len(args) > 1:
+ if args[1].isdigit():
+ item_type = Material.getMaterial(int(args[1]))
+ else:
+ item_type = Material.matchMaterial(args[1])
+ Validate.notNone(item_type, "&cThat item type could not be found")
+ Validate.isTrue(item_type not in disallowed_item_types, "&cThat item type may not be used")
+
+ if len(args) > 2:
+ Validate.isTrue(args[2].isdigit() and 0 <= int(args[2]) <= 15, "&cThe data has to be a value from 0 to 15")
+ item_data = int(args[2])
+
+ return (strength, item_type, item_data)
+
+
+def get_inventory(block):
+ try:
+ return block.getState().getInventory()
+ except AttributeError:
+ return None
+
+
+def get_entire_container(container):
+ container_blocks = [container]
+ container_type = container.getType()
+ if container_type in (Material.CHEST, Material.TRAPPED_CHEST):
+ loc = container.getLocation()
+ x = loc.getBlockX()
+ y = loc.getBlockY()
+ z = loc.getBlockZ()
+ world = loc.getWorld()
+
+ container_blocks += [
+ block for block in (
+ world.getBlockAt(x + 1, y, z),
+ world.getBlockAt(x - 1, y, z),
+ world.getBlockAt(x, y, z + 1),
+ world.getBlockAt(x, y, z - 1),
+ ) if block.getType() == target_type
+ ]
+
+ return container_blocks
+
+
+
+@simplecommand("signalstrength",
+ usage = "(<signal strength> [item] [data]) or (default <item> [data])",
+ aliases = ["ss", "level"],
+ description = "Fills the targeted container with the correct amount of items to achieve the desired signal strength.",
+ amin = 0,
+ amax = 4,
+ helpSubcmd = True,
+ senderLimit = 0)
+def on_signalstrength_command(sender, command, label, args):
+
+ if len(args) > 0 and args[0].lower() in ("default", "defaults", "setdefaults"):
+ strength, item_type, item_data = get_data(sender, args[1:])
+
+ uuid = uid(sender)
+ if strength == 1 and item_type == Material.REDSTONE and item_data == 0:
+ if uuid in default_args:
+ del default_args[uuid]
+ save_defaults()
+ else:
+ default_args[uuid] = (strength, str(item_type), item_data)
+ save_defaults()
+
+ return "&aSet your signal strength defaults to (%s, %s, %s)" % (strength, item_name(item_type, False), item_data)
+
+ Validate.isTrue(len(args) <= 3, "&cExpected at most 3 arguments")
+
+ target_block = sender.getTargetBlock(None, 5)
+ Validate.notNone(target_block, "&cThat command can only be used when a container is targeted")
+
+ inventory = get_inventory(target_block)
+ Validate.notNone(inventory, "&cThat command can only be used if a container is targeted")
+
+ strength, item_type, item_data = get_data(sender, args)
+
+ #--------Get the stack size and required amount of items to achieve the desired signal strength---------
+ stack_size = item_type.getMaxStackSize()
+ slot_count = inventory.getSize()
+
+ item_count = required_item_count(strength, stack_size, slot_count)
+ Validate.notNone(item_count, "&cThe desired signal strength could not be achieved with the requested item type")
+
+ #--------Add the other side of the chest if target is a double chest and check if player can build---------
+ container_blocks = get_entire_container(target_block)
+ for block in container_blocks:
+ Validate.isTrue(can_build(sender, block), "&cYou do not have permission to do that here")
+
+ #----------------Insert items-------------
+ full_stack_count, remaining = divmod(item_count, stack_size)
+ for block in container_blocks:
+ inv = block.getState().getInventory()
+ inv.clear()
+ for i in range(full_stack_count):
+ inv.setItem(i, ItemStack(item_type, stack_size, item_data))
+ if remaining > 0:
+ inv.setItem(full_stack_count, ItemStack(item_type, remaining, item_data))
+
+ return "&aComparators attached to that %s will now put out a signal strength of %s" % (item_name(target_block.getType()), strength)