mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 12:56:30 +01:00
add object stacking to get/drop/give
This commit is contained in:
parent
b5239e18c1
commit
829f32f573
1 changed files with 126 additions and 50 deletions
|
|
@ -395,39 +395,64 @@ class CmdGet(COMMAND_DEFAULT_CLASS):
|
|||
locks = "cmd:all()"
|
||||
arg_regex = r"\s|$"
|
||||
|
||||
def parse(self):
|
||||
super().parse()
|
||||
self.number = 0
|
||||
if self.args:
|
||||
# check for numbering
|
||||
count, *args = self.args.split(maxsplit=1)
|
||||
# we only use the first word as a count if it's a number and
|
||||
# there is more text afterwards
|
||||
if args and count.isdecimal():
|
||||
self.number = int(count)
|
||||
self.args = args[0]
|
||||
|
||||
def func(self):
|
||||
"""implements the command."""
|
||||
|
||||
caller = self.caller
|
||||
|
||||
if not self.args:
|
||||
caller.msg("Get what?")
|
||||
self.msg("Get what?")
|
||||
return
|
||||
obj = caller.search(self.args, location=caller.location)
|
||||
if not obj:
|
||||
objs = caller.search(self.args, location=caller.location, stacked=self.number)
|
||||
if not objs:
|
||||
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.")
|
||||
# the 'stacked' search sometimes returns a list, sometimes not, so we make it always a list
|
||||
# NOTE: this behavior may be a bug, see issue #3432
|
||||
objs = utils.make_iter(objs)
|
||||
|
||||
if len(objs) == 1 and caller == objs[0]:
|
||||
self.msg("You can't get yourself.")
|
||||
return
|
||||
|
||||
# calling at_pre_get hook method
|
||||
if not obj.at_pre_get(caller):
|
||||
return
|
||||
# if we aren't allowed to get any of the objects, cancel the get
|
||||
for obj in objs:
|
||||
# check the locks
|
||||
if not obj.access(caller, "get"):
|
||||
if obj.db.get_err_msg:
|
||||
self.msg(obj.db.get_err_msg)
|
||||
else:
|
||||
self.msg("You can't get that.")
|
||||
return
|
||||
# calling at_pre_get hook method
|
||||
if not obj.at_pre_get(caller):
|
||||
return
|
||||
|
||||
success = obj.move_to(caller, quiet=True, move_type="get")
|
||||
if not success:
|
||||
caller.msg("This can't be picked up.")
|
||||
moved = []
|
||||
# attempt to move all of the objects
|
||||
for obj in objs:
|
||||
if obj.move_to(caller, quiet=True, move_type="get"):
|
||||
moved.append(obj)
|
||||
# calling at_get hook method
|
||||
obj.at_get(caller)
|
||||
|
||||
if not moved:
|
||||
# none of the objects were successfully moved
|
||||
self.msg("That can't be picked up.")
|
||||
else:
|
||||
singular, _ = obj.get_numbered_name(1, caller)
|
||||
caller.location.msg_contents(f"$You() $conj(pick) up {singular}.", from_obj=caller)
|
||||
# calling at_get hook method
|
||||
obj.at_get(caller)
|
||||
singular, plural = moved[0].get_numbered_name(len(moved), caller)
|
||||
caller.location.msg_contents(f"$You() $conj(pick) up {plural if len(moved) > 1 else singular}.", from_obj=caller)
|
||||
|
||||
|
||||
class CmdDrop(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -445,6 +470,18 @@ class CmdDrop(COMMAND_DEFAULT_CLASS):
|
|||
locks = "cmd:all()"
|
||||
arg_regex = r"\s|$"
|
||||
|
||||
def parse(self):
|
||||
super().parse()
|
||||
self.number = 0
|
||||
if self.args:
|
||||
# check for numbering
|
||||
count, *args = self.args.split(maxsplit=1)
|
||||
# we only use the first word as a count if it's a number and
|
||||
# there is more text afterwards
|
||||
if args and count.isdecimal():
|
||||
self.number = int(count)
|
||||
self.args = args[0]
|
||||
|
||||
def func(self):
|
||||
"""Implement command"""
|
||||
|
||||
|
|
@ -455,27 +492,39 @@ class CmdDrop(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
# Because the DROP command by definition looks for items
|
||||
# in inventory, call the search function using location = caller
|
||||
obj = caller.search(
|
||||
objs = caller.search(
|
||||
self.args,
|
||||
location=caller,
|
||||
nofound_string=f"You aren't carrying {self.args}.",
|
||||
multimatch_string=f"You carry more than one {self.args}:",
|
||||
stacked=self.number,
|
||||
)
|
||||
if not obj:
|
||||
if not objs:
|
||||
return
|
||||
# the 'stacked' search sometimes returns a list, sometimes not, so we make it always a list
|
||||
# NOTE: this behavior may be a bug, see issue #3432
|
||||
objs = utils.make_iter(objs)
|
||||
|
||||
# Call the object script's at_pre_drop() method.
|
||||
if not obj.at_pre_drop(caller):
|
||||
return
|
||||
# if any objects fail the drop permission check, cancel the drop
|
||||
for obj in objs:
|
||||
# Call the object's at_pre_drop() method.
|
||||
if not obj.at_pre_drop(caller):
|
||||
return
|
||||
|
||||
success = obj.move_to(caller.location, quiet=True, move_type="drop")
|
||||
if not success:
|
||||
caller.msg("This couldn't be dropped.")
|
||||
# do the actual dropping
|
||||
moved = []
|
||||
for obj in objs:
|
||||
if obj.move_to(caller.location, quiet=True, move_type="drop"):
|
||||
moved.append(obj)
|
||||
# Call the object's at_drop() method.
|
||||
obj.at_drop(caller)
|
||||
|
||||
if not moved:
|
||||
# none of the objects were successfully moved
|
||||
self.msg("That can't be dropped.")
|
||||
else:
|
||||
singular, _ = obj.get_numbered_name(1, caller)
|
||||
caller.location.msg_contents(f"$You() $conj(drop) {singular}.", from_obj=caller)
|
||||
# Call the object script's at_drop() method.
|
||||
obj.at_drop(caller)
|
||||
singular, plural = obj.get_numbered_name(len(moved), caller)
|
||||
caller.location.msg_contents(f"$You() $conj(drop) {plural if len(moved) > 1 else singular}.", from_obj=caller)
|
||||
|
||||
|
||||
class CmdGive(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -494,6 +543,18 @@ class CmdGive(COMMAND_DEFAULT_CLASS):
|
|||
locks = "cmd:all()"
|
||||
arg_regex = r"\s|$"
|
||||
|
||||
def parse(self):
|
||||
super().parse()
|
||||
self.number = 0
|
||||
if self.lhs:
|
||||
# check for numbering
|
||||
count, *args = self.lhs.split(maxsplit=1)
|
||||
# we only use the first word as a count if it's a number and
|
||||
# there is more text afterwards
|
||||
if args and count.isdecimal():
|
||||
self.number = int(count)
|
||||
self.lhs = args[0]
|
||||
|
||||
def func(self):
|
||||
"""Implement give"""
|
||||
|
||||
|
|
@ -501,37 +562,52 @@ class CmdGive(COMMAND_DEFAULT_CLASS):
|
|||
if not self.args or not self.rhs:
|
||||
caller.msg("Usage: give <inventory object> = <target>")
|
||||
return
|
||||
# find the thing(s) to give away
|
||||
to_give = caller.search(
|
||||
self.lhs,
|
||||
location=caller,
|
||||
nofound_string=f"You aren't carrying {self.lhs}.",
|
||||
multimatch_string=f"You carry more than one {self.lhs}:",
|
||||
stacked=self.number,
|
||||
)
|
||||
if not to_give:
|
||||
return
|
||||
# find the target to give to
|
||||
target = caller.search(self.rhs)
|
||||
if not (to_give and target):
|
||||
if not target:
|
||||
return
|
||||
|
||||
singular, _ = to_give.get_numbered_name(1, caller)
|
||||
# the 'stacked' search sometimes returns a list, sometimes not, so we make it always a list
|
||||
# NOTE: this behavior may be a bug, see issue #3432
|
||||
to_give = utils.make_iter(to_give)
|
||||
|
||||
|
||||
singular, plural = to_give[0].get_numbered_name(len(to_give), caller)
|
||||
if target == caller:
|
||||
caller.msg(f"You keep {singular} to yourself.")
|
||||
return
|
||||
if not to_give.location == caller:
|
||||
caller.msg(f"You are not holding {singular}.")
|
||||
caller.msg(f"You keep {plural if len(to_give) > 1 else singular} to yourself.")
|
||||
return
|
||||
|
||||
# calling at_pre_give hook method
|
||||
if not to_give.at_pre_give(caller, target):
|
||||
return
|
||||
# if any of the objects aren't allowed to be given, cancel the give
|
||||
for obj in to_give:
|
||||
# calling at_pre_give hook method
|
||||
if not obj.at_pre_give(caller, target):
|
||||
return
|
||||
|
||||
# give object
|
||||
success = to_give.move_to(target, quiet=True, move_type="give")
|
||||
if not success:
|
||||
caller.msg(f"You could not give {singular} to {target.key}.")
|
||||
# do the actual moving
|
||||
moved = []
|
||||
for obj in to_give:
|
||||
if obj.move_to(target, quiet=True, move_type="give"):
|
||||
moved.append(obj)
|
||||
# Call the object's at_give() method.
|
||||
obj.at_give(caller, target)
|
||||
|
||||
if not moved:
|
||||
caller.msg(f"You could not give that to {target.get_display_name(caller)}.")
|
||||
else:
|
||||
caller.msg(f"You give {singular} to {target.key}.")
|
||||
target.msg(f"{caller.key} gives you {singular}.")
|
||||
# Call the object script's at_give() method.
|
||||
to_give.at_give(caller, target)
|
||||
singular, plural = to_give[0].get_numbered_name(len(moved), caller)
|
||||
names = plural if len(moved) > 1 else singular
|
||||
caller.msg(f"You give {names} to {target.get_display_name(caller)}.")
|
||||
target.msg(f"{caller.get_display_name(target)} gives you {names}.")
|
||||
|
||||
|
||||
class CmdSetDesc(COMMAND_DEFAULT_CLASS):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue