Moved 'eat' command from food to people

This handles better error messages.

Also, cleaned up code warnings.
This commit is contained in:
Howard Abrams 2025-05-31 08:47:56 -07:00
parent ddcb0f0306
commit 167e8f356f
5 changed files with 106 additions and 49 deletions

View file

@ -20,22 +20,6 @@ class CmdSetMakeConsumable(CmdSet):
self.add(CmdMakeConsumable)
class CmdEat(Command):
"""
Eat something
"""
key = "eat"
aliases = "bite"
def func(self):
self.obj.do_eat(self.caller)
class CmdSetEat(CmdSet):
def at_cmdset_creation(self):
self.add(CmdEat)
class CmdMakeTea(Command):
"""
make [tea-type]

View file

@ -20,7 +20,7 @@ from evennia.contrib.game_systems.gendersub import SetGender
from evennia.contrib.rpg.rpsystem import RPSystemCmdSet
from evennia.contrib.rpg.character_creator.character_creator import ContribChargenCmdSet
from commands.sittables import CmdNoSitStand
from commands.everyone import CmdTake, CmdThink, CmdSay, CmdWhisper, CmdRead, CmdDrink
from commands.everyone import CmdTake, CmdThink, CmdSay, CmdWhisper, CmdRead, CmdEat, CmdDrink
from commands.wizards import CmdGM, CmdSpell, CmdGMTrigger, CmdMakeCocktail
class CharacterCmdSet(default_cmds.CharacterCmdSet):
@ -38,6 +38,7 @@ class CharacterCmdSet(default_cmds.CharacterCmdSet):
"""
super().at_cmdset_creation()
self.add(CmdNoSitStand)
self.add(CmdEat)
self.add(CmdDrink)
self.add(CmdTake)
self.add(CmdThink)

View file

@ -13,9 +13,12 @@ from typeclasses.readables import find_book
from typeclasses.characters import Character
from utils.word_list import routput, paragraph, choices
def speech_effect(speech, verb, target, effects):
"""
Returns a tuple for what a user thinks he said, and what
Return speech after applying 'effects'.
Return a tuple for what a user thinks he said, and what
others actually here. If no effect, just return speech twice.
Effects:
@ -38,7 +41,7 @@ def speech_effect(speech, verb, target, effects):
class CmdWhisper(MuxCommand):
"""
Speak privately as your character to another
Speak privately as your character to another.
Usage:
whisper <character> = <message>
@ -47,15 +50,14 @@ class CmdWhisper(MuxCommand):
Talk privately to one or more characters in your current location, without
others in the room being informed.
"""
key = "whisper"
priority = 0
locks = "cmd:all()"
rhs_split = ("=")
def func(self):
"""
Implements the new 'whisper' command.
"""
"""Implement the new 'whisper' command."""
if not self.args:
self.caller.msg("What are you whispering?")
return
@ -75,7 +77,9 @@ class CmdWhisper(MuxCommand):
class CmdSay(MuxCommand):
"""
Say something to the characters in the same area. For instance:
Say something to the characters in the same area.
For instance:
|gsay Good evening!|n
@ -114,16 +118,15 @@ class CmdSay(MuxCommand):
"""
key = "say"
aliases = ["says", "speak", "shout", "yell", "exclaim", "scream", "ask", "reply", "respond", "\"", "'"]
aliases = ["says", "speak", "shout", "yell", "exclaim", "scream", "ask",
"reply", "respond", "\"", "'"]
priority = 0
locks = "cmd:all()"
rhs_split = ("=")
arg_regex = None
def func(self):
"""
Implements the new 'say' command with switches.
"""
"""Implement the new 'say' command with switches."""
speaker = self.caller
if not self.args:
@ -220,9 +223,11 @@ class CmdSay(MuxCommand):
if verb == 'reply':
verb = 'replie'
targets = [item for item in speaker.location.contents if item != speaker]
targets = [item for item in speaker.location.contents
if item != speaker]
full_speech = f"/me {adverb}{verb}s{to_whom}, \"{for_others}\""
send_emote(speaker, targets, full_speech, msg_type="say", anonymous_add=None)
send_emote(speaker, targets, full_speech, msg_type="say",
anonymous_add=None)
class CmdThink(Command):
@ -234,21 +239,21 @@ class CmdThink(Command):
Similar to the 'say' or 'pose' commands, this communicates an
inner monologue to other players on the 'public' channel.
"""
key = "think"
aliases = ["thinks", "("]
arg_regex = None
def func(self):
"""
Implements the think out loud command.
"""
"""Implement the think out loud command."""
if not self.args:
self.caller.msg("What do you want to think out loud?")
else:
thought = self.args.strip()
if (self.caller.db.thinking_count or 0) < 3 or random() < 0.4:
msg = routput(
f"<< thinks ^ wonders >> << out loud ^ aloud >> ... o O ( {thought} )"
f"<< thinks ^ wonders >> << out loud ^ aloud >> "
f"... o O ( {thought} )"
)
else:
msg = f". o O ( {thought} )"
@ -269,11 +274,11 @@ class CmdRead(Command):
@set <target>/inside = 'This is the text to read.'
"""
key = "read"
def func(self):
"""Return the 'inside' attribute."""
target_str = self.args.strip()
if target_str == "":
self.caller.msg("Usage: |gread <object>|n")
@ -294,14 +299,17 @@ class CmdTake(Command, NumberedTargetCommand):
Note that only some things can be stolen.
For instance, the brass ring from the door knocker.
"""
key = "take"
aliases = ["steal"]
rhs_split = ("=", " from ")
def func(self):
"""
Implements the take command. Since this command is designed
to work on the object, we operate only on self.obj.
Implement the take command.
Since this command is designed to work on the object, we
operate only on self.obj.
"""
if not self.args:
self.caller.msg("What do you want to take?")
@ -324,37 +332,99 @@ class CmdDrink(Command):
This doesn't tell others of this particular activity.
"""
key = "drink"
aliases = ["sip", "quaff"]
def drinkable(self, item):
return hasattr(item, 'do_drink') and callable(item.do_drink)
def not_empty(self, item):
"""Return true is the cup has some drink left in it."""
return (item.db.amount or 0) > 0
def drink_item(self, name):
"""Find item in inventory, name, and call 'do_drink' on it."""
notfound = f"You don't have {name} in your inventory."
item = self.caller.search(name, location=self.caller,
nofound_string=f"You don't have {name} in your inventory.")
nofound_string=notfound)
if item:
if self.drinkable(item):
if item.has_method('do_drink'):
item.do_drink(self.caller)
else:
self.caller.msg(f"The {item.name} is not drinkable.")
def drink_anything(self):
"""Drink anything in your inventory, but only if you have one thing."""
containers = [item for item in self.caller.contents
if self.drinkable(item) and self.not_empty(item)]
if item.has_method('do_drink') and self.not_empty(item)]
if len(containers) == 1:
containers[0].do_drink(self.caller)
elif len(containers) > 1:
self.caller.msg("You have two many things you can drink. Which one do you want?")
self.caller.msg("You have two many things you can drink. "
"Which one do you want?")
else:
self.caller.msg("You have nothing to drink.")
def func(self):
"""
If given the name of something to drink, find and drink it.
Otherwise, drink the first item you find in your inventory.
"""
goal = self.args.strip()
if goal and goal != "":
self.drink_item(goal)
else:
self.drink_anything()
class CmdEat(Command):
"""
Eat something edible in your inventory.
Usage:
eat [ food-item ]
This doesn't tell others of this particular activity.
"""
key = "eat"
aliases = ["consume", "bite"]
def not_gone(self, item):
"""Return true is the cup has some eat left in it."""
return (item.db.amount or 0) > 0
def eat_item(self, name):
"""Find item in inventory, name, and call 'do_eat' on it."""
notfound = f"You don't have {name} in your inventory."
item = self.caller.search(name, location=self.caller,
nofound_string=notfound)
if item:
if item.has_method('do_eat'):
item.do_eat(self.caller)
else:
self.caller.msg(f"The {item.name} is not edible.")
def eat_anything(self):
"""Eat something in your inventory, but only if you have one thing."""
items = [item for item in self.caller.contents
if item.has_method('do_eat') and self.not_gone(item)]
if len(items) == 1:
items[0].do_eat(self.caller)
elif len(items) > 1:
self.caller.msg("You have too many things to eat. "
"Which one do you want?")
else:
self.caller.msg("You have nothing to eat.")
def func(self):
"""
If given the name of something to eat, find and eat it.
Otherwise, eat the first item you find in your inventory.
"""
goal = self.args.strip()
if goal and goal != "":
self.eat_item(goal)
else:
self.eat_anything()

View file

@ -6,9 +6,8 @@ import random
from evennia import TICKER_HANDLER
from evennia.prototypes.spawner import spawn
from commands.consumables import (
CmdSetEat, CmdSetTrolley, CmdSetMakeConsumable
)
from commands.consumables import CmdSetTrolley, CmdSetMakeConsumable
from typeclasses.objects import Object
from utils.word_list import routput # , choices
@ -30,7 +29,6 @@ class Consumable(Object):
eat_amount = 1
def at_object_creation(self):
self.cmdset.add_default(CmdSetEat)
self.db.amount = self.amount
self.db.eat_amount = self.eat_amount

View file

@ -250,6 +250,10 @@ class Object(ObjectParent, ContribRPObject):
return None
def has_method(self, method_name):
"""True if this object has a method of a particular name."""
return hasattr(self, method_name) and callable(getattr(self, method_name))
def delay_sequence(self, sequence_str, time_delay=1, *args):
"""Run a sequence of messages or commands with a delay.