760 lines
26 KiB
Python
760 lines
26 KiB
Python
"""
|
|
Commands
|
|
|
|
Commands describe the input the account can do to the game.
|
|
|
|
"""
|
|
import re
|
|
import random
|
|
|
|
from evennia import utils, default_cmds, create_script, logger
|
|
from evennia.utils import evtable
|
|
from evennia.contrib.health_bar import display_meter
|
|
from evennia.utils import inherits_from
|
|
from evennia.utils.utils import list_to_string
|
|
from evennia.utils.eveditor import EvEditor
|
|
|
|
from utils.building import create_exit
|
|
from utils.utils import has_tag, fmt_light, fmt_dark, toggle_effect, has_effect, indefinite_article
|
|
from typeclasses.exits import BaseDoor
|
|
from typeclasses.rooms import IndoorRoom
|
|
from typeclasses.objects import Item, EquippableItem
|
|
from typeclasses.scripts import Script, CmdActionScript
|
|
|
|
CMD_SEARCH_TIME = 5
|
|
|
|
|
|
class Command(default_cmds.MuxCommand):
|
|
"""
|
|
Inherit from this if you want to create your own command styles
|
|
from scratch. Note that Evennia's default commands inherits from
|
|
MuxCommand instead.
|
|
|
|
Note that the class's `__doc__` string (this text) is
|
|
used by Evennia to create the automatic help entry for
|
|
the command, so make sure to document consistently here.
|
|
|
|
Each Command implements the following methods, called
|
|
in this order (only func() is actually required):
|
|
- at_pre_cmd(): If this returns anything truthy, execution is aborted.
|
|
- parse(): Should perform any extra parsing needed on self.args
|
|
and store the result on self.
|
|
- func(): Performs the actual work.
|
|
- at_post_cmd(): Extra actions, often things done after
|
|
every command, like prompts.
|
|
|
|
"""
|
|
|
|
def parse(self):
|
|
"""
|
|
We need to expand the default parsing to get all
|
|
the cases, see the module doc.
|
|
"""
|
|
# get all the normal parsing done (switches etc)
|
|
super().parse()
|
|
|
|
obj_defs = ([], []) # stores left- and right-hand side of '='
|
|
obj_attrs = ([], []) # "
|
|
|
|
for iside, arglist in enumerate((self.lhslist, self.rhslist)):
|
|
# lhslist/rhslist is already split by ',' at this point
|
|
for objdef in arglist:
|
|
aliases, option, attrs = [], None, []
|
|
if ":" in objdef:
|
|
objdef, option = [part.strip() for part in objdef.rsplit(":", 1)]
|
|
if ";" in objdef:
|
|
objdef, aliases = [part.strip() for part in objdef.split(";", 1)]
|
|
aliases = [alias.strip() for alias in aliases.split(";") if alias.strip()]
|
|
if "/" in objdef:
|
|
objdef, attrs = [part.strip() for part in objdef.split("/", 1)]
|
|
attrs = [part.strip().lower() for part in attrs.split("/") if part.strip()]
|
|
# store data
|
|
obj_defs[iside].append({"name": objdef, "option": option, "aliases": aliases})
|
|
obj_attrs[iside].append({"name": objdef, "attrs": attrs})
|
|
|
|
# store for future access
|
|
self.lhs_objs = obj_defs[0]
|
|
self.rhs_objs = obj_defs[1]
|
|
self.lhs_objattr = obj_attrs[0]
|
|
self.rhs_objattr = obj_attrs[1]
|
|
|
|
def at_post_cmd(self):
|
|
caller = self.caller
|
|
prompt = "|_|/°|w%s|n°: " % (caller.location)
|
|
caller.msg(prompt=prompt)
|
|
|
|
|
|
# overloading the look command with our custom MuxCommand with at_post_cmd hook
|
|
class CmdLook(default_cmds.CmdLook, Command):
|
|
pass
|
|
|
|
|
|
class CmdDrop(default_cmds.CmdDrop, Command):
|
|
pass
|
|
|
|
|
|
class CmdGet(Command):
|
|
"""
|
|
pick up something
|
|
|
|
Usage:
|
|
get <obj> [from <container>]
|
|
|
|
Picks up an object from your location and puts it in
|
|
your inventory.
|
|
"""
|
|
|
|
key = "get"
|
|
aliases = "grab"
|
|
locks = "cmd:all()"
|
|
arg_regex = r"\s|$"
|
|
|
|
def parse(self):
|
|
"""
|
|
Handle parsing of:
|
|
<object> [FROM <container>]
|
|
"""
|
|
self.args = args = self.args.strip().lower()
|
|
|
|
if "from" in args:
|
|
obj, *rest = args.split(" from ", 1)
|
|
container = rest[0] if rest else ""
|
|
else:
|
|
obj = self.args
|
|
container = ""
|
|
|
|
self.obj_name = obj.strip()
|
|
self.container_name = container.strip()
|
|
|
|
def func(self):
|
|
"""implements the command."""
|
|
caller = self.caller
|
|
|
|
if not self.args or not self.obj_name:
|
|
caller.msg("Get what?")
|
|
return
|
|
|
|
if inherits_from(caller.location, IndoorRoom) and not caller.location.db.is_lit and not caller.is_superuser:
|
|
caller.msg("Its too dark to get anything.")
|
|
return
|
|
|
|
if self.container_name:
|
|
container = caller.search(self.container_name, location=caller.location)
|
|
obj = caller.search(self.obj_name, location=container)
|
|
else:
|
|
obj = caller.search(self.obj_name, location=caller.location)
|
|
|
|
if not obj:
|
|
return
|
|
if caller == obj:
|
|
caller.msg("You can't get yourself.")
|
|
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
|
|
|
|
# calling at_before_get hook method
|
|
if not obj.at_before_get(caller):
|
|
return
|
|
|
|
success = obj.move_to(caller, quiet=True)
|
|
if not success:
|
|
caller.msg("This can't be picked up.")
|
|
else:
|
|
caller.msg("You pick up %s." % obj.name)
|
|
caller.location.msg_contents(
|
|
"%s picks up %s." % (caller.name, obj.name), exclude=caller
|
|
)
|
|
# calling at_get hook method
|
|
obj.at_get(caller)
|
|
|
|
|
|
class CmdCharacter(Command):
|
|
"""
|
|
Show character sheet.
|
|
|
|
Usage:
|
|
character
|
|
|
|
Displays a list of your current ability values.
|
|
"""
|
|
key = "character"
|
|
aliases = ["char"]
|
|
lock = "cmd:all()"
|
|
help_category = "General"
|
|
|
|
def func(self):
|
|
self.caller.msg(
|
|
'\u250B|w' + " {0:27}".format(self.caller.name,) + '|n\u250B|/')
|
|
|
|
self.caller.msg('-HEALTH' + '-' * 23)
|
|
meter = display_meter(self.caller.get_health(), 100,
|
|
empty_color="222", align="center", fill_color=["R"])
|
|
self.caller.msg(meter)
|
|
self.caller.msg('-MANA' + '-' * 25)
|
|
meter = display_meter(self.caller.get_mana(), 100,
|
|
empty_color="222", align="center", fill_color=["B"])
|
|
self.caller.msg(meter + '|/')
|
|
str, agi, intel = self.caller.get_abilities()
|
|
table = evtable.EvTable(border="tablecols")
|
|
table.add_column("STRENGTH", "AGILITY",
|
|
"INTELLECT", header="Attributes")
|
|
table.add_column("|g%03d|n/100" % str, "|g%03d|n/100" %
|
|
agi, "|g%03d|n/100" % intel, header="")
|
|
self.caller.msg(table)
|
|
|
|
|
|
class CmdLight(Command):
|
|
"""
|
|
A command to light objects that support it.
|
|
|
|
Usage:
|
|
light <someone>
|
|
|
|
Light an object in your inventory.
|
|
"""
|
|
|
|
key = "light"
|
|
aliases = []
|
|
lock = "cmd:all()"
|
|
help_category = "General"
|
|
arg_regex = r"(?:^(?:\s+|\/).*$)|^$"
|
|
|
|
def func(self):
|
|
caller = self.caller
|
|
if not self.args:
|
|
self.msg("Light what?")
|
|
return
|
|
else:
|
|
target = caller.search(self.args)
|
|
if not target:
|
|
self.msg("Light what?")
|
|
return
|
|
|
|
if not target.access(caller, 'light'):
|
|
self.msg("You cannot do that.")
|
|
return
|
|
|
|
if not has_effect(target, "emit_light"):
|
|
toggle_effect(target, "emit_light")
|
|
self.msg("You light {}.".format(target.name))
|
|
else:
|
|
toggle_effect(target, "emit_light")
|
|
self.msg("You put off {}.".format(target.name))
|
|
|
|
if caller.location and inherits_from(caller.location, IndoorRoom):
|
|
caller.location.check_light_state()
|
|
|
|
|
|
class CmdSearch(Command):
|
|
"""
|
|
"""
|
|
|
|
key = "search"
|
|
aliases = ["ss"]
|
|
locks = "cmd:all()"
|
|
help_category = "General"
|
|
arg_regex = r"(?:^(?:\s+|\/).*$)|^$"
|
|
|
|
def func(self):
|
|
caller = self.caller
|
|
|
|
if has_effect(caller, "is_busy"):
|
|
caller.msg("You are already busy {}.".format(caller.db.current_action.busy_msg()))
|
|
return
|
|
|
|
if not self.args:
|
|
target = caller.location
|
|
if not target:
|
|
caller.msg("You have no location to search!")
|
|
return
|
|
else:
|
|
target = caller.search(self.args)
|
|
if not target:
|
|
caller.msg("You cannot search {}!".format(self.args))
|
|
return
|
|
if target.access(caller, "search"):
|
|
toggle_effect(caller, "is_busy")
|
|
caller.msg("You search {}.".format(target.get_display_name(caller)))
|
|
action_script = create_script("commands.command.CmdSearchComplete", obj=caller, interval=CMD_SEARCH_TIME, attributes=[("target", self.args)])
|
|
caller.db.current_action = action_script
|
|
else:
|
|
caller.msg("You cannot search {}!".format(target.get_display_name(caller)))
|
|
|
|
|
|
class CmdSearchComplete(CmdActionScript):
|
|
def at_script_creation(self):
|
|
super().at_script_creation()
|
|
|
|
self.key = "cmd_search_complete"
|
|
self.desc = ""
|
|
self.db.target = ""
|
|
|
|
def at_repeat(self):
|
|
caller = self.obj
|
|
target_string = self.db.target
|
|
|
|
if has_effect(caller, "is_busy"):
|
|
toggle_effect(caller, "is_busy")
|
|
|
|
if not target_string:
|
|
target = caller.location
|
|
if not target:
|
|
caller.msg("You have no location to search!")
|
|
return
|
|
else:
|
|
target = caller.search(target_string)
|
|
if not target:
|
|
caller.msg("You cannot search {} anymore!".format(target_string))
|
|
return
|
|
if target.access(caller, "search"):
|
|
items = []
|
|
for con in target.contents:
|
|
if inherits_from(con, Item) and con.access(caller, "get"):
|
|
items.append(con)
|
|
|
|
if items:
|
|
found_item_idx = random.randrange(0, len(items))
|
|
found_item = items[found_item_idx]
|
|
found_item_name = found_item.get_numbered_name(1, caller)[0]
|
|
caller.msg("You find {}.".format(found_item_name))
|
|
|
|
if not found_item.access(caller, "get"):
|
|
if found_item.db.get_err_msg:
|
|
caller.msg(found_item.db.get_err_msg)
|
|
else:
|
|
caller.msg("You can't get that.")
|
|
return
|
|
|
|
# calling at_before_get hook method
|
|
if not found_item.at_before_get(caller):
|
|
return
|
|
|
|
success = found_item.move_to(caller, quiet=True)
|
|
if not success:
|
|
caller.msg("This can't be picked up.")
|
|
else:
|
|
caller.msg("You pick up %s." % found_item_name)
|
|
caller.location.msg_contents(
|
|
"%s picks up %s." % (caller.name, found_item_name), exclude=caller
|
|
)
|
|
# calling at_get hook method
|
|
found_item.at_get(caller)
|
|
else:
|
|
caller.msg("There is nothing to be found here.")
|
|
else:
|
|
caller.msg("You cannot search {} anymore!".format(target.get_display_name(caller)))
|
|
|
|
def busy_msg(self):
|
|
return "searching {}".format(self.db.target)
|
|
|
|
|
|
class CmdPut(Command):
|
|
"""
|
|
Put an item inside a container
|
|
|
|
Usage:
|
|
put <item> in <container>
|
|
"""
|
|
|
|
key = "put"
|
|
locks = "cmd:all()"
|
|
help_category = "General"
|
|
|
|
def parse(self):
|
|
"""
|
|
Handle parsing of:
|
|
<item> in <container>
|
|
"""
|
|
self.args = args = self.args.strip().lower()
|
|
item_name, container_name = "", ""
|
|
|
|
if " in " in args:
|
|
item_name, *rest = args.split(" in ", 1)
|
|
container_name = rest[0] if rest else ""
|
|
|
|
self.item_name = item_name.strip()
|
|
self.container_name = container_name.strip()
|
|
|
|
def func(self):
|
|
caller = self.caller
|
|
|
|
if not self.args or not self.item_name or not self.container_name:
|
|
caller.msg("Usage: put <item> in <container>")
|
|
return
|
|
|
|
item = caller.search(self.item_name, typeclass="typeclasses.objects.Item")
|
|
if not item:
|
|
return
|
|
|
|
container = caller.search(self.container_name, typeclass="typeclasses.objects.ContainerFeature")
|
|
if not container:
|
|
return
|
|
|
|
if not item.access(caller, "get"):
|
|
caller.msg("You cannot do that with {}.".format(item.name))
|
|
return
|
|
|
|
if not container.access(caller, "put"):
|
|
caller.msg("You cannot access {}.".format(container.name))
|
|
return
|
|
|
|
if has_tag(item, "equipped", "general"):
|
|
caller.msg("{} is equipped. Remove it first.".format(item.name))
|
|
return
|
|
|
|
item.move_to(container, use_destination=False)
|
|
|
|
caller.msg("You put {} inside {}.".format(item.name, container.name))
|
|
|
|
|
|
|
|
class CmdOpenCloseDoor(Command):
|
|
"""
|
|
Open and close a door
|
|
|
|
Usage:
|
|
open <door>
|
|
close <door>
|
|
|
|
"""
|
|
|
|
key = "op"
|
|
aliases = ["close"]
|
|
locks = "cmd:all()"
|
|
help_category = "General"
|
|
|
|
def func(self):
|
|
if not self.args:
|
|
self.caller.msg("Usage: open||close <door>")
|
|
return
|
|
|
|
door = self.caller.search(self.args)
|
|
if not door:
|
|
return
|
|
if not inherits_from(door, BaseDoor):
|
|
self.caller.msg("This is not a door.")
|
|
return
|
|
|
|
if self.cmdstring == "op":
|
|
if door.locks.check(self.caller, "traverse"):
|
|
self.caller.msg("%s is already open." % door.key)
|
|
else:
|
|
door.setlock("traverse:true()")
|
|
self.caller.msg("You open %s." % door.key)
|
|
else: # close
|
|
if not door.locks.check(self.caller, "traverse"):
|
|
self.caller.msg("%s is already closed." % door.key)
|
|
else:
|
|
door.setlock("traverse:false()")
|
|
self.caller.msg("You close %s." % door.key)
|
|
|
|
|
|
class CmdEquip(Command):
|
|
key = "equip"
|
|
aliases = ["eq", "remove"]
|
|
lock = "cmd:all()"
|
|
help_category = "General"
|
|
arg_regex = r"\s.+|$"
|
|
|
|
def func(self):
|
|
caller = self.caller
|
|
|
|
if not self.args:
|
|
caller.msg("You cannot do that.")
|
|
return
|
|
|
|
item = caller.search(self.args, location=caller, nofound_string="")
|
|
if not item:
|
|
caller.msg("You don't have any {}".format(self.args))
|
|
return
|
|
|
|
if inherits_from(item, EquippableItem) and item.access(caller, "equip"):
|
|
if self.cmdstring == "remove":
|
|
if has_tag(item, "equipped", "general"):
|
|
if item.at_unequip(caller, ""):
|
|
self.remove(caller, item)
|
|
else:
|
|
return
|
|
else:
|
|
caller.msg("{} is not equipped.".format(item.name))
|
|
return
|
|
else:
|
|
if has_tag(item, "equipped", "general"):
|
|
caller.msg("{} is already equipped.".format(item.name))
|
|
return
|
|
|
|
slots = [slot for slot in caller.db.equipment.keys() if item.db.slot in slot]
|
|
if not slots:
|
|
caller.msg("You don't have {} {}".format(indefinite_article(item.db.slot), item.db.slot))
|
|
return
|
|
|
|
selected_slot = slots[0]
|
|
|
|
# find an empty slot
|
|
empty_slots = [slot for slot in slots if not caller.db.equipment[slot]]
|
|
if empty_slots:
|
|
selected_slot = empty_slots[0]
|
|
|
|
# remove equipment if slot is already in use
|
|
if caller.db.equipment[selected_slot]:
|
|
old_equipment = caller.search(caller.db.equipment[selected_slot], location=caller, quiet=True)
|
|
if old_equipment:
|
|
if old_equipment[0].at_unequip(caller, selected_slot):
|
|
self.remove(caller, old_equipment[0])
|
|
else:
|
|
return
|
|
|
|
if item.at_equip(caller, selected_slot):
|
|
caller.db.equipment[selected_slot] = item.dbref
|
|
item.tags.add("equipped", category="general")
|
|
|
|
caller.msg("You equip |w{}|n on |w{}|n".format(item.name, selected_slot))
|
|
caller.location.msg_contents("{} equips |w{}|n on {}".format(caller.name, item.name, selected_slot), exclude=caller)
|
|
|
|
else:
|
|
caller.msg("You cannot equip {}".format(item.name))
|
|
|
|
def remove(self, caller, item):
|
|
selected_slot = [slot for slot in caller.db.equipment.keys() if caller.db.equipment[slot] == item.dbref][0]
|
|
caller.msg("You remove {} from {}".format(item, selected_slot))
|
|
caller.db.equipment[selected_slot] = None
|
|
item.tags.remove("equipped", category="general")
|
|
|
|
|
|
class CmdInventory(Command):
|
|
"""
|
|
view inventory
|
|
|
|
Usage:
|
|
inventory
|
|
inv
|
|
|
|
Shows your inventory.
|
|
"""
|
|
|
|
key = "inventory"
|
|
aliases = ["inv", "i"]
|
|
locks = "cmd:all()"
|
|
arg_regex = r"$"
|
|
|
|
def func(self):
|
|
"""check inventory"""
|
|
items = self.caller.contents
|
|
if not items:
|
|
string = "You are not carrying anything."
|
|
else:
|
|
from evennia.utils.ansi import raw as raw_ansi
|
|
|
|
table = self.styled_table()
|
|
for item in items:
|
|
effect_string = ""
|
|
|
|
if has_tag(item, 'equipped', 'general'):
|
|
effect_string += "|w⚒|n"
|
|
else:
|
|
effect_string += "|=a⚒|n"
|
|
|
|
if has_effect(item, 'emit_light'):
|
|
effect_string += "|y☀|n"
|
|
else:
|
|
effect_string += "|=a☀|n"
|
|
|
|
table.add_row(
|
|
f"|w{item.name}|n",
|
|
effect_string,
|
|
"{}|n".format(utils.crop(raw_ansi(item.db.desc), width=50) or ""),
|
|
)
|
|
string = f"|wYou are carrying:\n{table}"
|
|
self.caller.msg(string)
|
|
|
|
|
|
class CmdTestPy(Command):
|
|
key = "testpy"
|
|
aliases = ["testpy"]
|
|
lock = "cmd:false()"
|
|
help_category = "General"
|
|
arg_regex = r"\s.+|$"
|
|
|
|
def func(self):
|
|
caller = self.caller
|
|
|
|
caller.msg(self.lhs_objs)
|
|
|
|
pattern = re.compile(r'''((?:[^ "']|"[^"]*"|'[^']*')+)''')
|
|
self.args = pattern.split(self.lhs)[1::2]
|
|
|
|
# room = create_room(self.args[0].strip(" \"'"), int(self.args[1].strip(" \"'")), int(self.args[2].strip(" \"'")), self.args[3].strip(" \"'"))
|
|
# caller.msg(room)
|
|
|
|
# exit = create_exit("exit_empty", caller.location, "north")
|
|
# caller.msg(exit)
|
|
|
|
# caller.msg(dkmud_oob=({"testarg": "valuetestarg"}))
|
|
|
|
# if not self.args:
|
|
# target = caller.location
|
|
# if not target:
|
|
# caller.msg("You have no location to test!")
|
|
# return
|
|
# else:
|
|
# target = caller.search(self.args)
|
|
# if not target:
|
|
# return
|
|
|
|
|
|
# -------------------------------------------------------------
|
|
#
|
|
# The default commands inherit from
|
|
#
|
|
# evennia.commands.default.muxcommand.MuxCommand.
|
|
#
|
|
# If you want to make sweeping changes to default commands you can
|
|
# uncomment this copy of the MuxCommand parent and add
|
|
#
|
|
# COMMAND_DEFAULT_CLASS = "commands.command.MuxCommand"
|
|
#
|
|
# to your settings file. Be warned that the default commands expect
|
|
# the functionality implemented in the parse() method, so be
|
|
# careful with what you change.
|
|
#
|
|
# -------------------------------------------------------------
|
|
|
|
# from evennia.utils import utils
|
|
#
|
|
#
|
|
# class MuxCommand(Command):
|
|
# """
|
|
# This sets up the basis for a MUX command. The idea
|
|
# is that most other Mux-related commands should just
|
|
# inherit from this and don't have to implement much
|
|
# parsing of their own unless they do something particularly
|
|
# advanced.
|
|
#
|
|
# Note that the class's __doc__ string (this text) is
|
|
# used by Evennia to create the automatic help entry for
|
|
# the command, so make sure to document consistently here.
|
|
# """
|
|
# def has_perm(self, srcobj):
|
|
# """
|
|
# This is called by the cmdhandler to determine
|
|
# if srcobj is allowed to execute this command.
|
|
# We just show it here for completeness - we
|
|
# are satisfied using the default check in Command.
|
|
# """
|
|
# return super().has_perm(srcobj)
|
|
#
|
|
# def at_pre_cmd(self):
|
|
# """
|
|
# This hook is called before self.parse() on all commands
|
|
# """
|
|
# pass
|
|
#
|
|
# def at_post_cmd(self):
|
|
# """
|
|
# This hook is called after the command has finished executing
|
|
# (after self.func()).
|
|
# """
|
|
# pass
|
|
#
|
|
# def parse(self):
|
|
# """
|
|
# This method is called by the cmdhandler once the command name
|
|
# has been identified. It creates a new set of member variables
|
|
# that can be later accessed from self.func() (see below)
|
|
#
|
|
# The following variables are available for our use when entering this
|
|
# method (from the command definition, and assigned on the fly by the
|
|
# cmdhandler):
|
|
# self.key - the name of this command ('look')
|
|
# self.aliases - the aliases of this cmd ('l')
|
|
# self.permissions - permission string for this command
|
|
# self.help_category - overall category of command
|
|
#
|
|
# self.caller - the object calling this command
|
|
# self.cmdstring - the actual command name used to call this
|
|
# (this allows you to know which alias was used,
|
|
# for example)
|
|
# self.args - the raw input; everything following self.cmdstring.
|
|
# self.cmdset - the cmdset from which this command was picked. Not
|
|
# often used (useful for commands like 'help' or to
|
|
# list all available commands etc)
|
|
# self.obj - the object on which this command was defined. It is often
|
|
# the same as self.caller.
|
|
#
|
|
# A MUX command has the following possible syntax:
|
|
#
|
|
# name[ with several words][/switch[/switch..]] arg1[,arg2,...] [[=|,] arg[,..]]
|
|
#
|
|
# The 'name[ with several words]' part is already dealt with by the
|
|
# cmdhandler at this point, and stored in self.cmdname (we don't use
|
|
# it here). The rest of the command is stored in self.args, which can
|
|
# start with the switch indicator /.
|
|
#
|
|
# This parser breaks self.args into its constituents and stores them in the
|
|
# following variables:
|
|
# self.switches = [list of /switches (without the /)]
|
|
# self.raw = This is the raw argument input, including switches
|
|
# self.args = This is re-defined to be everything *except* the switches
|
|
# self.lhs = Everything to the left of = (lhs:'left-hand side'). If
|
|
# no = is found, this is identical to self.args.
|
|
# self.rhs: Everything to the right of = (rhs:'right-hand side').
|
|
# If no '=' is found, this is None.
|
|
# self.lhslist - [self.lhs split into a list by comma]
|
|
# self.rhslist - [list of self.rhs split into a list by comma]
|
|
# self.arglist = [list of space-separated args (stripped, including '=' if it exists)]
|
|
#
|
|
# All args and list members are stripped of excess whitespace around the
|
|
# strings, but case is preserved.
|
|
# """
|
|
# raw = self.args
|
|
# args = raw.strip()
|
|
#
|
|
# # split out switches
|
|
# switches = []
|
|
# if args and len(args) > 1 and args[0] == "/":
|
|
# # we have a switch, or a set of switches. These end with a space.
|
|
# switches = args[1:].split(None, 1)
|
|
# if len(switches) > 1:
|
|
# switches, args = switches
|
|
# switches = switches.split('/')
|
|
# else:
|
|
# args = ""
|
|
# switches = switches[0].split('/')
|
|
# arglist = [arg.strip() for arg in args.split()]
|
|
#
|
|
# # check for arg1, arg2, ... = argA, argB, ... constructs
|
|
# lhs, rhs = args, None
|
|
# lhslist, rhslist = [arg.strip() for arg in args.split(',')], []
|
|
# if args and '=' in args:
|
|
# lhs, rhs = [arg.strip() for arg in args.split('=', 1)]
|
|
# lhslist = [arg.strip() for arg in lhs.split(',')]
|
|
# rhslist = [arg.strip() for arg in rhs.split(',')]
|
|
#
|
|
# # save to object properties:
|
|
# self.raw = raw
|
|
# self.switches = switches
|
|
# self.args = args.strip()
|
|
# self.arglist = arglist
|
|
# self.lhs = lhs
|
|
# self.lhslist = lhslist
|
|
# self.rhs = rhs
|
|
# self.rhslist = rhslist
|
|
#
|
|
# # if the class has the account_caller property set on itself, we make
|
|
# # sure that self.caller is always the account if possible. We also create
|
|
# # a special property "character" for the puppeted object, if any. This
|
|
# # is convenient for commands defined on the Account only.
|
|
# if hasattr(self, "account_caller") and self.account_caller:
|
|
# if utils.inherits_from(self.caller, "evennia.objects.objects.DefaultObject"):
|
|
# # caller is an Object/Character
|
|
# self.character = self.caller
|
|
# self.caller = self.caller.account
|
|
# elif utils.inherits_from(self.caller, "evennia.accounts.accounts.DefaultAccount"):
|
|
# # caller was already an Account
|
|
# self.character = self.caller.get_puppet(self.session)
|
|
# else:
|
|
# self.character = None
|