Moved /signalstrength to its own file, added default configurability, added basecommands documentation, added can_build() to helpers
This commit is contained in:
@@ -1,13 +1,66 @@
|
|||||||
from helpers import *
|
from helpers import *
|
||||||
|
|
||||||
to_see_permission = "utils.showpermission" # See cmd permission in help
|
"""
|
||||||
|
@simplecommand is a decorator which is meant to replace @hook.command in redstoner-utils, where useful.
|
||||||
|
It takes care of checks such as whether the sender is a player, whether they have permission,
|
||||||
|
whether there are enough argumens, and also takes care of a help message.
|
||||||
|
On top of that, it makes the code shorter and easier to write with features like Validate, and returning a message instead of a boolean value.
|
||||||
|
@simplecommand has an inbuilt tracing feature, so you won't have to put all your code in a try/except statement anymore.
|
||||||
|
Make sure to `from basecommands import simplecommand` before using this decorator.
|
||||||
|
|
||||||
|
The arguments are as follows:
|
||||||
|
* cmd: the command, self explanatory (required);
|
||||||
|
|
||||||
|
* aliases: A list containing any aliases for the command, like shortcuts;
|
||||||
|
|
||||||
|
* usage: a String defining the expected arguments for the command. Example:
|
||||||
|
Let's say I have a command /tp <player_to_teleport> <destination_player>. The usage is: "<player_to_teleport> <destination_player>".
|
||||||
|
I suggest we use the same format throughout redstoner-utils:
|
||||||
|
- Separate arguments by spaces;
|
||||||
|
- Use <> if the argument is required, and [] if the argument is optional;
|
||||||
|
- Add .. to the argument's identifier (name) if it is for example a message (containing spaces).
|
||||||
|
for example in /msg, the usage would be "<player> <msg..>"
|
||||||
|
|
||||||
|
* description: a description of what the command does. Defaults to "Handles cmd".
|
||||||
|
This is used for the help message, where the description is (meant to be) indented. To keep this indentation
|
||||||
|
with longer descriptions, call the help message (with the command, ingame) and add '\n'
|
||||||
|
when it jumps to a new line in the chat. The decorator will take care of the indentation after that.
|
||||||
|
|
||||||
|
* senderLimit: an integer resembling the accepted sender type. Defaults to -1. Use:
|
||||||
|
-1 for console as well as players;
|
||||||
|
0 for players only;
|
||||||
|
1 for console only.
|
||||||
|
|
||||||
|
* amin: an integer resembling the minimum amount of arguments. Defaults to 0
|
||||||
|
|
||||||
|
* amax: an integer resembling the maximum amount of arguments. Defaults to -1, which means that there is no maximum.
|
||||||
|
|
||||||
|
* helpNoargs: a boolean value resembling whether the help message should be displayed when no arguments are given.
|
||||||
|
Defaults to False.
|
||||||
|
|
||||||
|
* helpSubcmd: a boolean value resembling whether the help message should be displayed when the first argument.lower() equals "help".
|
||||||
|
Defaults to False.
|
||||||
|
|
||||||
|
Comments on the function added to the decorator:
|
||||||
|
It should return a message to send to the player. Color codes are translated automatically. It can return None or an empty string to send nothing.
|
||||||
|
|
||||||
|
Inside the function, calls to static methods in the class Validate can be used to make the code shorter and easier to write (maybe not easier to read).
|
||||||
|
For example, to make sure that a condition is met, use Validate.isTrue(condition, message to send to the player if the condition is not met)
|
||||||
|
Don't forget to `from basecommands import Validate` if you wish to make use of this.
|
||||||
|
For all other Validate checks, see the code below. Feel free to add your own.
|
||||||
|
|
||||||
|
Instead of returning a message mid-code to describe an error, you can also use raise CommandException(msg), but it is almost always possible
|
||||||
|
to replace this return statement with a call to one of the functions in the Validate class. Once again, if you use raise CommandException(msg),
|
||||||
|
don't forget to `from basecommands import CommandException`.
|
||||||
|
"""
|
||||||
|
|
||||||
|
to_see_permission = "utils.showpermission" # See cmd permission in help
|
||||||
|
|
||||||
def isSenderValid(senderLimit, isPlayer):
|
def isSenderValid(senderLimit, isPlayer):
|
||||||
return True if senderLimit == -1 else senderLimit != isPlayer
|
return True if senderLimit == -1 else senderLimit != isPlayer
|
||||||
|
|
||||||
def invalidSenderMsg(isPlayer):
|
def invalidSenderMsg(isPlayer):
|
||||||
return "&cThat command can only be run from the console" if isPlayer else "&cThat command can only be run by players"
|
return "&cThat command can only be used by " + ("the console" if isPlayer else "players")
|
||||||
|
|
||||||
def helpMsg(sender, cmd, description, usage, aliases, permission):
|
def helpMsg(sender, cmd, description, usage, aliases, permission):
|
||||||
help_msg = "&aInformation about command /%s:\n &9%s" % (cmd, description.replace("\n", "\n "))
|
help_msg = "&aInformation about command /%s:\n &9%s" % (cmd, description.replace("\n", "\n "))
|
||||||
@@ -65,7 +118,7 @@ def simplecommand(cmd,
|
|||||||
except CommandException, e:
|
except CommandException, e:
|
||||||
return e.message
|
return e.message
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
error(e.message, trace())
|
error(trace())
|
||||||
return "&cAn internal error occurred while attempting to perform this command"
|
return "&cAn internal error occurred while attempting to perform this command"
|
||||||
|
|
||||||
return call
|
return call
|
||||||
|
|||||||
10
helpers.py
10
helpers.py
@@ -6,6 +6,7 @@ import org.bukkit as bukkit
|
|||||||
import org.bukkit.Location as Location
|
import org.bukkit.Location as Location
|
||||||
import org.bukkit.entity.Player as Player
|
import org.bukkit.entity.Player as Player
|
||||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause as TeleportCause
|
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause as TeleportCause
|
||||||
|
import org.bukkit.event.block.BlockBreakEvent as BlockBreakEvent
|
||||||
import org.bukkit.block as bblock
|
import org.bukkit.block as bblock
|
||||||
import org.bukkit.event.entity as entity
|
import org.bukkit.event.entity as entity
|
||||||
import org.bukkit.command.ConsoleCommandSender
|
import org.bukkit.command.ConsoleCommandSender
|
||||||
@@ -143,6 +144,15 @@ def is_player(obj):
|
|||||||
return (isinstance(obj, Player))
|
return (isinstance(obj, Player))
|
||||||
|
|
||||||
|
|
||||||
|
def can_build(player, block):
|
||||||
|
"""
|
||||||
|
return True if the player can change/build at the location of given block
|
||||||
|
"""
|
||||||
|
event = BlockBreakEvent(block, player)
|
||||||
|
server.getPluginManager().callEvent(event)
|
||||||
|
return not event.isCancelled()
|
||||||
|
|
||||||
|
|
||||||
def checkargs(sender, args, amin, amax):
|
def checkargs(sender, args, amin, amax):
|
||||||
"""
|
"""
|
||||||
check if a command has a valid amount of args, otherwise notify the sender
|
check if a command has a valid amount of args, otherwise notify the sender
|
||||||
|
|||||||
2
main.py
2
main.py
@@ -54,6 +54,8 @@ shared["load_modules"] = [
|
|||||||
"webtoken",
|
"webtoken",
|
||||||
# Adds /lol, broadcasts random funyy messages. A bit like the splash text in the menu
|
# Adds /lol, broadcasts random funyy messages. A bit like the splash text in the menu
|
||||||
"saylol",
|
"saylol",
|
||||||
|
# Adds /signalstrength, lets you request a signal strength and an amount of items will be inserted into target container to meet that strength.
|
||||||
|
"signalstrength",
|
||||||
# Shows the owner of a skull when right-clicked
|
# Shows the owner of a skull when right-clicked
|
||||||
"skullclick",
|
"skullclick",
|
||||||
# Adds /listen, highlights chat and plays a sound when your name was mentioned
|
# Adds /listen, highlights chat and plays a sound when your name was mentioned
|
||||||
|
|||||||
91
misc.py
91
misc.py
@@ -4,11 +4,7 @@ from time import time as now
|
|||||||
from time import sleep
|
from time import sleep
|
||||||
from sys import exc_info
|
from sys import exc_info
|
||||||
import thread
|
import thread
|
||||||
|
|
||||||
import org.bukkit.inventory.ItemStack as ItemStack
|
import org.bukkit.inventory.ItemStack as ItemStack
|
||||||
import org.bukkit.Material as Material
|
|
||||||
from math import ceil
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit as Bukkit
|
import org.bukkit.Bukkit as Bukkit
|
||||||
from basecommands import simplecommand, Validate
|
from basecommands import simplecommand, Validate
|
||||||
|
|
||||||
@@ -145,93 +141,6 @@ def on_sudo_command(sender, command, label, args):
|
|||||||
return "&cPlayer %s not found!" % target
|
return "&cPlayer %s not found!" % target
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
Suggestion by Armadillo28, see thread: http://redstoner.com/forums/threads/2213?page=1#reply-14507
|
|
||||||
|
|
||||||
Clarification on these formulas on http://minecraft.gamepedia.com/Redstone_Comparator#Containers
|
|
||||||
"""
|
|
||||||
|
|
||||||
def required_item_count(strength, slots, stack):
|
|
||||||
if strength == 0:
|
|
||||||
count = 0
|
|
||||||
elif strength == 1:
|
|
||||||
count = 1
|
|
||||||
else:
|
|
||||||
count = int(ceil(slots * stack / 14.0 * (strength - 1)))
|
|
||||||
|
|
||||||
resulting_strength = int(1 + 14.0 * count / stack / slots)
|
|
||||||
|
|
||||||
return count if resulting_strength == strength else None
|
|
||||||
|
|
||||||
@simplecommand("signalstrength",
|
|
||||||
usage = "<signal strength> [item] [data]",
|
|
||||||
aliases = ["ss", "level"],
|
|
||||||
description = "Fills the targeted container with the correct amount of items to achieve the desired signal strength.",
|
|
||||||
amin = 1,
|
|
||||||
amax = 3,
|
|
||||||
helpNoargs = True,
|
|
||||||
helpSubcmd = True,
|
|
||||||
senderLimit = 0)
|
|
||||||
def on_signalstrength_command(sender, command, label, args):
|
|
||||||
|
|
||||||
target_block = sender.getTargetBlock(None, 5)
|
|
||||||
Validate.notNone(target_block, "&cThat command can only be used when a container is targeted")
|
|
||||||
|
|
||||||
try:
|
|
||||||
inv = target_block.getState().getInventory()
|
|
||||||
except AttributeError:
|
|
||||||
return "&cThat command can only be used when a container is targeted"
|
|
||||||
|
|
||||||
#---------Define the requested strength, item type and item data----------
|
|
||||||
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])
|
|
||||||
|
|
||||||
item_type = Material.REDSTONE if len(args) < 2 else Material.getMaterial(int(args[1]) if args[1].isdigit() else args[1])
|
|
||||||
Validate.notNone(item_type, "&cThat item id does not exist")
|
|
||||||
|
|
||||||
item_data = 0 if len(args) < 3 else int(args[2]) if args[2].isdigit() else -1
|
|
||||||
Validate.isTrue(0 <= item_data <= 15, "&cThe data has to be a value from 0 to 15")
|
|
||||||
|
|
||||||
#--------Get the stack size and required amount of items to achieve the desired signal strength---------
|
|
||||||
stack_size = item_type.getMaxStackSize()
|
|
||||||
item_count = required_item_count(strength, inv.getSize(), stack_size)
|
|
||||||
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--------------
|
|
||||||
target_blocks = [target_block]
|
|
||||||
target_type = target_block.getType()
|
|
||||||
if target_type in (Material.CHEST, Material.TRAPPED_CHEST):
|
|
||||||
loc = target_block.getLocation()
|
|
||||||
x = loc.getBlockX()
|
|
||||||
y = loc.getBlockY()
|
|
||||||
z = loc.getBlockZ()
|
|
||||||
world = loc.getWorld()
|
|
||||||
|
|
||||||
target_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
|
|
||||||
]
|
|
||||||
|
|
||||||
#----------------Insert items-------------
|
|
||||||
full_stack_count, remaining = divmod(item_count, stack_size)
|
|
||||||
|
|
||||||
inv.clear()
|
|
||||||
for block in target_blocks:
|
|
||||||
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 "&aSuccesfully edited the targeted %s to give out a signal strenth of %s to comparators" % (
|
|
||||||
str(target_type).lower().replace("_", " "), strength)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@simplecommand("me",
|
@simplecommand("me",
|
||||||
usage = "[message..]",
|
usage = "[message..]",
|
||||||
|
|||||||
Reference in New Issue
Block a user