mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
450 lines
No EOL
13 KiB
Python
450 lines
No EOL
13 KiB
Python
"""
|
|
General Character commands usually availabe to all characters
|
|
"""
|
|
from django.conf import settings
|
|
from src.utils import utils, prettytable
|
|
from src.commands.default.muxcommand import MuxCommand
|
|
|
|
|
|
# limit symbol import for API
|
|
__all__ = ("CmdHome", "CmdLook", "CmdNick",
|
|
"CmdInventory", "CmdGet", "CmdDrop", "CmdGive",
|
|
"CmdSay", "CmdPose", "CmdAccess")
|
|
|
|
AT_SEARCH_RESULT = utils.variable_from_module(*settings.SEARCH_AT_RESULT.rsplit('.', 1))
|
|
|
|
|
|
class CmdHome(MuxCommand):
|
|
"""
|
|
home
|
|
|
|
Usage:
|
|
home
|
|
|
|
Teleports you to your home location.
|
|
"""
|
|
|
|
key = "home"
|
|
locks = "cmd:perm(home) or perm(Builders)"
|
|
|
|
def func(self):
|
|
"Implement the command"
|
|
caller = self.caller
|
|
home = caller.home
|
|
if not home:
|
|
caller.msg("You have no home!")
|
|
elif home == caller.location:
|
|
caller.msg("You are already home!")
|
|
else:
|
|
caller.move_to(home)
|
|
caller.msg("There's no place like home ...")
|
|
|
|
|
|
class CmdLook(MuxCommand):
|
|
"""
|
|
look
|
|
|
|
Usage:
|
|
look
|
|
look <obj>
|
|
look *<player>
|
|
|
|
Observes your location or objects in your vicinity.
|
|
"""
|
|
key = "look"
|
|
aliases = ["l", "ls"]
|
|
locks = "cmd:all()"
|
|
arg_regex = r"\s.*?|$"
|
|
|
|
def func(self):
|
|
"""
|
|
Handle the looking.
|
|
"""
|
|
caller = self.caller
|
|
args = self.args
|
|
if args:
|
|
# Use search to handle duplicate/nonexistant results.
|
|
looking_at_obj = caller.search(args, use_nicks=True)
|
|
if not looking_at_obj:
|
|
return
|
|
else:
|
|
looking_at_obj = caller.location
|
|
if not looking_at_obj:
|
|
caller.msg("You have no location to look at!")
|
|
return
|
|
|
|
if not hasattr(looking_at_obj, 'return_appearance'):
|
|
# this is likely due to us having a player instead
|
|
looking_at_obj = looking_at_obj.character
|
|
if not looking_at_obj.access(caller, "view"):
|
|
caller.msg("Could not find '%s'." % args)
|
|
return
|
|
# get object's appearance
|
|
caller.msg(looking_at_obj.return_appearance(caller))
|
|
# the object's at_desc() method.
|
|
looking_at_obj.at_desc(looker=caller)
|
|
|
|
|
|
class CmdNick(MuxCommand):
|
|
"""
|
|
Define a personal alias/nick
|
|
|
|
Usage:
|
|
nick[/switches] <nickname> = [<string>]
|
|
alias ''
|
|
|
|
Switches:
|
|
object - alias an object
|
|
player - alias a player
|
|
clearall - clear all your aliases
|
|
list - show all defined aliases (also "nicks" works)
|
|
|
|
Examples:
|
|
nick hi = say Hello, I'm Sarah!
|
|
nick/object tom = the tall man
|
|
|
|
A 'nick' is a personal shortcut you create for your own use. When
|
|
you enter the nick, the alternative string will be sent instead.
|
|
The switches control in which situations the substitution will
|
|
happen. The default is that it will happen when you enter a
|
|
command. The 'object' and 'player' nick-types kick in only when
|
|
you use commands that requires an object or player as a target -
|
|
you can then use the nick to refer to them.
|
|
|
|
Note that no objects are actually renamed or changed by this
|
|
command - the nick is only available to you. If you want to
|
|
permanently add keywords to an object for everyone to use, you
|
|
need build privileges and to use the @alias command.
|
|
"""
|
|
key = "nick"
|
|
aliases = ["nickname", "nicks", "@nick", "alias"]
|
|
locks = "cmd:all()"
|
|
|
|
def func(self):
|
|
"Create the nickname"
|
|
|
|
caller = self.caller
|
|
switches = self.switches
|
|
nicks = caller.nicks.get(category="channel")
|
|
|
|
if 'list' in switches:
|
|
table = prettytable.PrettyTable(["{wNickType",
|
|
"{wNickname",
|
|
"{wTranslates-to"])
|
|
for nick in nicks:
|
|
table.add_row([nick.db_category, nick.db_key, nick.db_data])
|
|
string = "{wDefined Nicks:{n\n%s" % table
|
|
caller.msg(string)
|
|
return
|
|
if 'clearall' in switches:
|
|
caller.nicks.clear()
|
|
caller.msg("Cleared all aliases.")
|
|
return
|
|
if not self.args or not self.lhs:
|
|
caller.msg("Usage: nick[/switches] nickname = [realname]")
|
|
return
|
|
nick = self.lhs
|
|
real = self.rhs
|
|
|
|
if real == nick:
|
|
caller.msg("No point in setting nick same as the string to replace...")
|
|
return
|
|
|
|
# check so we have a suitable nick type
|
|
if not any(True for switch in switches if switch in ("object", "player", "inputline")):
|
|
switches = ["inputline"]
|
|
string = ""
|
|
for switch in switches:
|
|
oldnick = caller.nicks.get(key=nick, category=switch)
|
|
#oldnick = Nick.objects.filter(db_obj=caller.dbobj, db_nick__iexact=nick, db_type__iexact=switch)
|
|
if not real:
|
|
# removal of nick
|
|
if oldnick:
|
|
# clear the alias
|
|
string += "\nNick '%s' (= '%s') was cleared." % (nick, oldnick[0].db_real)
|
|
caller.nicks.delete(nick, category=switch)
|
|
else:
|
|
string += "\nNo nick '%s' found, so it could not be removed." % nick
|
|
else:
|
|
# creating new nick
|
|
if oldnick:
|
|
string += "\nNick %s changed from '%s' to '%s'." % (nick, oldnick[0].db_real, real)
|
|
else:
|
|
string += "\nNick set: '%s' = '%s'." % (nick, real)
|
|
caller.nicks.add(nick, real, category=switch)
|
|
caller.msg(string)
|
|
|
|
|
|
class CmdInventory(MuxCommand):
|
|
"""
|
|
inventory
|
|
|
|
Usage:
|
|
inventory
|
|
inv
|
|
|
|
Shows your inventory.
|
|
"""
|
|
key = "inventory"
|
|
aliases = ["inv", "i"]
|
|
locks = "cmd:all()"
|
|
|
|
def func(self):
|
|
"check inventory"
|
|
items = self.caller.contents
|
|
if not items:
|
|
string = "You are not carrying anything."
|
|
else:
|
|
table = prettytable.PrettyTable(["name", "desc"])
|
|
table.header = False
|
|
table.border = False
|
|
for item in items:
|
|
table.add_row(["{C%s{n" % item.name, item.db.desc and item.db.desc or ""])
|
|
string = "{wYou are carrying:\n%s" % table
|
|
self.caller.msg(string)
|
|
|
|
|
|
class CmdGet(MuxCommand):
|
|
"""
|
|
get
|
|
|
|
Usage:
|
|
get <obj>
|
|
|
|
Picks up an object from your location and puts it in
|
|
your inventory.
|
|
"""
|
|
key = "get"
|
|
aliases = "grab"
|
|
locks = "cmd:all()"
|
|
|
|
def func(self):
|
|
"implements the command."
|
|
|
|
caller = self.caller
|
|
|
|
if not self.args:
|
|
caller.msg("Get what?")
|
|
return
|
|
#print "general/get:", caller, caller.location, self.args, caller.location.contents
|
|
obj = caller.search(self.args, location=caller.location)
|
|
if not obj:
|
|
return
|
|
if caller == obj:
|
|
caller.msg("You can't get yourself.")
|
|
return
|
|
#print obj, obj.location, caller, caller==obj.location
|
|
if caller == obj.location:
|
|
caller.msg("You already hold that.")
|
|
return
|
|
if not obj.access(caller, 'get'):
|
|
if obj.db.get_err_msg:
|
|
caller.msg(obj.db.get_err_msg)
|
|
else:
|
|
caller.msg("You can't get that.")
|
|
return
|
|
|
|
obj.move_to(caller, quiet=True)
|
|
caller.msg("You pick up %s." % obj.name)
|
|
caller.location.msg_contents("%s picks up %s." %
|
|
(caller.name,
|
|
obj.name),
|
|
exclude=caller)
|
|
# calling hook method
|
|
obj.at_get(caller)
|
|
|
|
|
|
class CmdDrop(MuxCommand):
|
|
"""
|
|
drop
|
|
|
|
Usage:
|
|
drop <obj>
|
|
|
|
Lets you drop an object from your inventory into the
|
|
location you are currently in.
|
|
"""
|
|
|
|
key = "drop"
|
|
locks = "cmd:all()"
|
|
|
|
def func(self):
|
|
"Implement command"
|
|
|
|
caller = self.caller
|
|
if not self.args:
|
|
caller.msg("Drop what?")
|
|
return
|
|
|
|
# Because the DROP command by definition looks for items
|
|
# in inventory, call the search function using location = caller
|
|
results = caller.search(self.args, location=caller, quiet=True)
|
|
|
|
# now we send it into the error handler (this will output consistent
|
|
# error messages if there are problems).
|
|
obj = AT_SEARCH_RESULT(caller, self.args, results, False,
|
|
nofound_string="You don't carry %s." % self.args,
|
|
multimatch_string="You carry more than one %s:" % self.args)
|
|
if not obj:
|
|
return
|
|
|
|
obj.move_to(caller.location, quiet=True)
|
|
caller.msg("You drop %s." % (obj.name,))
|
|
caller.location.msg_contents("%s drops %s." %
|
|
(caller.name, obj.name),
|
|
exclude=caller)
|
|
# Call the object script's at_drop() method.
|
|
obj.at_drop(caller)
|
|
|
|
|
|
class CmdGive(MuxCommand):
|
|
"""
|
|
give away things
|
|
|
|
Usage:
|
|
give <inventory obj> = <target>
|
|
|
|
Gives an items from your inventory to another character,
|
|
placing it in their inventory.
|
|
"""
|
|
key = "give"
|
|
locks = "cmd:all()"
|
|
|
|
def func(self):
|
|
"Implement give"
|
|
|
|
caller = self.caller
|
|
if not self.args or not self.rhs:
|
|
caller.msg("Usage: give <inventory object> = <target>")
|
|
return
|
|
to_give = caller.search(self.lhs)
|
|
target = caller.search(self.rhs)
|
|
if not (to_give and target):
|
|
return
|
|
if target == caller:
|
|
caller.msg("You keep %s to yourself." % to_give.key)
|
|
return
|
|
if not to_give.location == caller:
|
|
caller.msg("You are not holding %s." % to_give.key)
|
|
return
|
|
# give object
|
|
to_give.location = target
|
|
caller.msg("You give %s to %s." % (to_give.key, target.key))
|
|
target.msg("%s gives you %s." % (caller.key, to_give.key))
|
|
|
|
|
|
class CmdSay(MuxCommand):
|
|
"""
|
|
say
|
|
|
|
Usage:
|
|
say <message>
|
|
|
|
Talk to those in your current location.
|
|
"""
|
|
|
|
key = "say"
|
|
aliases = ['"', "'"]
|
|
locks = "cmd:all()"
|
|
|
|
def func(self):
|
|
"Run the say command"
|
|
|
|
caller = self.caller
|
|
|
|
if not self.args:
|
|
caller.msg("Say what?")
|
|
return
|
|
|
|
speech = self.args
|
|
|
|
# calling the speech hook on the location
|
|
speech = caller.location.at_say(caller, speech)
|
|
|
|
# Feedback for the object doing the talking.
|
|
caller.msg('You say, "%s{n"' % speech)
|
|
|
|
# Build the string to emit to neighbors.
|
|
emit_string = '{c%s{n says, "%s{n"' % (caller.name,
|
|
speech)
|
|
caller.location.msg_contents(emit_string,
|
|
exclude=caller)
|
|
|
|
|
|
class CmdPose(MuxCommand):
|
|
"""
|
|
pose - strike a pose
|
|
|
|
Usage:
|
|
pose <pose text>
|
|
pose's <pose text>
|
|
|
|
Example:
|
|
pose is standing by the wall, smiling.
|
|
-> others will see:
|
|
Tom is standing by the wall, smiling.
|
|
|
|
Describe an action being taken. The pose text will
|
|
automatically begin with your name.
|
|
"""
|
|
key = "pose"
|
|
aliases = [":", "emote"]
|
|
locks = "cmd:all()"
|
|
|
|
def parse(self):
|
|
"""
|
|
Custom parse the cases where the emote
|
|
starts with some special letter, such
|
|
as 's, at which we don't want to separate
|
|
the caller's name and the emote with a
|
|
space.
|
|
"""
|
|
args = self.args
|
|
if args and not args[0] in ["'", ",", ":"]:
|
|
args = " %s" % args.strip()
|
|
self.args = args
|
|
|
|
def func(self):
|
|
"Hook function"
|
|
if not self.args:
|
|
msg = "What do you want to do?"
|
|
self.caller.msg(msg)
|
|
else:
|
|
msg = "%s%s" % (self.caller.name, self.args)
|
|
self.caller.location.msg_contents(msg)
|
|
|
|
|
|
class CmdAccess(MuxCommand):
|
|
"""
|
|
access - show access groups
|
|
|
|
Usage:
|
|
access
|
|
|
|
This command shows you the permission hierarchy and
|
|
which permission groups you are a member of.
|
|
"""
|
|
key = "access"
|
|
aliases = ["groups", "hierarchy"]
|
|
locks = "cmd:all()"
|
|
|
|
def func(self):
|
|
"Load the permission groups"
|
|
|
|
caller = self.caller
|
|
hierarchy_full = settings.PERMISSION_HIERARCHY
|
|
string = "\n{wPermission Hierarchy{n (climbing):\n %s" % ", ".join(hierarchy_full)
|
|
#hierarchy = [p.lower() for p in hierarchy_full]
|
|
|
|
if self.caller.player.is_superuser:
|
|
cperms = "<Superuser>"
|
|
pperms = "<Superuser>"
|
|
else:
|
|
cperms = ", ".join(caller.permissions.all())
|
|
pperms = ", ".join(caller.player.permissions.all())
|
|
|
|
string += "\n{wYour access{n:"
|
|
string += "\nCharacter {c%s{n: %s" % (caller.key, cperms)
|
|
if hasattr(caller, 'player'):
|
|
string += "\nPlayer {c%s{n: %s" % (caller.player.key, pperms)
|
|
caller.msg(string) |