Can make pets into familiars

Refactor get_name to a top-level place on the Object.
This commit is contained in:
Howard Abrams 2026-02-24 21:44:09 -08:00
parent cbfb79256c
commit b33f6ca7df
5 changed files with 79 additions and 34 deletions

View file

@ -305,6 +305,33 @@ class CmdSetFrog(CmdSet):
self.add(CmdFrog)
class CmdAntic(Command):
"""Have your familiar do some antic.
Usage:
antic <phrase>
Or:
antic's <phrase>
Will announce your familiar's antics to the room.
You can target another character by preceding the character's
description with a |w/|n, as in |w/elf|n or |w/blonde elf|n.
"""
key = "antic"
def func(self):
self.obj.at_do(self.caller, self.args.strip())
class CmdSetAntic(CmdSet):
def at_cmdset_creation(self):
self.add(CmdAntic)
class CmdRoll(MuxCommand):
"""
Roll the dice in your inventory.

View file

@ -4,6 +4,7 @@ from random import random
from re import match, split, sub, MULTILINE
from evennia.contrib.rpg.rpsystem import send_emote
from evennia.utils import logger
from evennia.utils.verb_conjugation.pronouns import PRONOUN_MAPPING
from commands.command import Command

View file

@ -88,39 +88,10 @@ class Familiar(NPC):
"""
Issue a 'send_emote' into the room with a antic.
"""
def name_and_adjs(name):
"""
Split a long name into its parts.
"""
return list(filter(lambda s: s != "", split(r"[, ]+", name)))
def new_name(parts):
"""
Take a long name, like: fat, black cat
And return _part_ of the name, like:
- fat, black cat
- black cat
- cat
"""
num_adjs = len(parts)-1
lst_adjs = parts[randint(0, num_adjs):num_adjs]
noun = parts[-1]
adjs = ', '.join(lst_adjs)
return f"{adjs} {noun}" if len(adjs) > 0 else noun
parts = name_and_adjs(self.db._sdesc or self.name)
# The familiar's name:
if not alias or alias == parts[-1]:
name = new_name(parts)
else:
name = alias
if antics.startswith("'"):
owner.announce_action(f"$Your() {name}{antics}")
owner.announce_action(f"$Your() {self.get_name(alias)}{antics}")
else:
owner.announce_action(f"$Your() {name} {antics}")
owner.announce_action(f"$Your() {self.get_name(alias)} {antics}")
class Cat(Familiar):
@ -145,7 +116,7 @@ class Frog(Familiar):
A puppetable 'frog' that acts based on that 'command'.
"""
def at_object_creation(self):
"Called when a octopus is first created."
"Called when this frog is first created."
self.cmdset.add(CmdSetFrog, persistent=True)

View file

@ -10,6 +10,7 @@ with a location in the game world (like Characters, Rooms, Exits).
"""
from re import split, match, sub, IGNORECASE
from random import randint
from django.conf import settings
@ -47,6 +48,36 @@ class ObjectParent:
"""True if this object has a method of a particular name."""
return hasattr(self, method_name) and callable(getattr(self, method_name))
def get_name(self, alias=None):
def name_and_adjs(name):
"""
Split a long name into its parts.
"""
return list(filter(lambda s: s != "", split(r"[, ]+", name)))
def new_name(parts):
"""
Take a long name, like: fat, black cat
And return _part_ of the name, like:
- fat, black cat
- black cat
- cat
"""
num_adjs = len(parts)-1
lst_adjs = parts[randint(0, num_adjs):num_adjs]
noun = parts[-1]
adjs = ', '.join(lst_adjs)
return f"{adjs} {noun}" if len(adjs) > 0 else noun
parts = name_and_adjs(self.db._sdesc or self.name)
# The familiar's name:
if not alias or alias == parts[-1]:
return new_name(parts)
else:
return alias
def has(self, item):
"""
Return true if object has an item.

View file

@ -20,9 +20,11 @@ from evennia.utils import logger
from evennia.utils.gametime import schedule
from evennia.utils.search import search_object
from typeclasses.objects import Object
from typeclasses.objects import Object, Listener
from typeclasses.characters import Character
from typeclasses.npcs import Familiar
from commands.pets import CmdPetSet
from commands.misc import CmdSetAntic
from utils.scoring import Scores
from utils.word_list import squish, choices
@ -467,10 +469,23 @@ class Friendly(Pet):
petter.announce_action(f"$You() $conj(pet) {self.name}.")
class WeeBeastie(Friendly):
# The key attribute is the Listener mixin:
class WeeBeastie(Friendly, Familiar, Listener):
"""
The stoat that lives in Dabbler's house, is a finicky eater.
"""
def at_object_creation(self):
"Called when this pet is first created."
self.cmdset.add(CmdSetAntic, persistent=True)
def other_sayto(self, speaker, message):
"Override to return a string in response to message."
owner = self.search("Dabbler")
if owner:
owner.announce_action(f"$Your() {name} purrs.")
else:
self.execute_cmd(f"emote /me purrs.")
def feed(self, feeder, item=None):
"""
Feeding the beast. If item is None, we choose something