Refactored code

Cleaned up flake8 warnings
This commit is contained in:
Howard Abrams 2025-03-05 21:54:41 -08:00
parent cff8a5176d
commit 245a1bb389
15 changed files with 249 additions and 271 deletions

View file

@ -1,8 +1,40 @@
#!/usr/bin/env python
from evennia import Command, CmdSet
from re import match
class CmdMakeConsumable(Command):
"""
Generate a new thing and give it to the caller.
"""
key = "pick"
# aliases = "pick"
def func(self):
self.obj.do_make(self.caller, self.args)
class CmdSetMakeConsumable(CmdSet):
def at_cmdset_creation(self):
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)
import random
class CmdDrinkTea(Command):
"""
@ -16,15 +48,19 @@ class CmdDrinkTea(Command):
def func(self):
self.obj.do_drink(self.caller)
class CmdMakeTea(Command):
"""
make [tea-type]
Make a pot of magical tea. If you do not specify a particular type of tea (or if it doesn't know what type of tea you suggest), the pot will choose something special for the occasion.
Make a pot of magical tea. If you do not specify a particular type
of tea (or if it doesn't know what type of tea you suggest), the
pot will choose something special for the occasion.
"""
priority = 3
key = "make"
aliases = ["make tea"]
locks = "cmd:all()"
aliases = "brew"
def func(self):
"""
@ -32,6 +68,7 @@ class CmdMakeTea(Command):
"""
self.obj.do_make_tea(self.caller, self.args.strip())
class CmdFillTeacup(Command):
"""
Fill the teacup with whatever tea is in the teapot.
@ -40,16 +77,30 @@ class CmdFillTeacup(Command):
"""
key = "fill"
aliases = "pour"
locks = "holds(teacup)"
def func(self):
self.obj.do_fill(self.caller)
class CmdSetTeacup(CmdSet):
def at_cmdset_creation(self):
self.add(CmdDrinkTea)
class CmdSetTeapot(CmdSet):
def at_cmdset_creation(self):
self.add(CmdMakeTea)
self.add(CmdFillTeacup)
class CmdGetTeacup(Command):
"""
Get a teacup from the trolley.
Each cup is special, but not necessarily unique.
"""
auto_help = False
key = "get teacup"
aliases = ["get cup", "pickup cup", "pickup teacup", "take cup", "take teacup"]
locks = "cmd:all()"
@ -61,15 +112,20 @@ class CmdGetTeacup(Command):
"""
self.obj.produce_teacup(self.caller)
class CmdSetTeacup(CmdSet):
def at_cmdset_creation(self):
self.add(CmdDrinkTea)
class CmdSetTeapot(CmdSet):
def at_cmdset_creation(self):
self.add(CmdMakeTea)
self.add(CmdFillTeacup)
class CmdMakeScone(Command):
"""
Generate a new thing and give it to the caller.
"""
auto_help = False
key = "get scone"
aliases = "grab scone"
def func(self):
self.obj.do_make(self.caller, self.args)
class CmdSetTrolley(CmdSet):
def at_cmdset_creation(self):
self.add(CmdGetTeacup)
self.add(CmdMakeScone)

View file

@ -5,10 +5,11 @@ from evennia import CmdSet
class CmdFeed(Command):
"""
Feed or give.
Feed or give something to an object that can eat.
Typically this is used to feed wood to a fire, or
berries to a beast.
"""
key = "feed"
aliases = ["give"]
def func(self):
args = self.args.strip()
@ -16,6 +17,7 @@ class CmdFeed(Command):
self.caller.msg("Feed what?")
return
print(self.obj.key)
self.obj.feed(self.caller, self.args)
class CmdFeedSet(CmdSet):

View file

@ -2,6 +2,27 @@
from .command import Command
from evennia import CmdSet
from evennia.utils import logger
class CmdKnock(Command):
"""
The ability to knock on something, like a door.
While it would be great if it could be attached to a door or some
other exit, we need to attach this to the room.
"""
key = "knock"
def func(self):
logger.log_info(f"Seems like {self.caller.key} wants to knock on me.")
self.obj.do_knock(self.caller)
class CmdSetKnock(CmdSet):
def at_cmdset_creation(self):
self.add(CmdKnock)
class CmdJump(Command):
@ -25,6 +46,7 @@ class CmdThrow(Command):
Jump or play in or around puddles.
"""
key = "throw"
locks = "holds(stick)"
def func(self):
self.obj.do_throw(self.caller)

View file

@ -1,8 +1,7 @@
#!/usr/bin/env python
from commands.command import Command
from evennia import CmdSet
from evennia.utils import logger
class CmdTake(Command):
"""
@ -10,7 +9,7 @@ class CmdTake(Command):
Added to the default_cmdsets.
"""
key = "take"
aliases = ["remove"]
aliases = ["steal"]
# only allow this command if command.obj is carried by caller.
# locks = "cmd:holds()"
@ -21,21 +20,3 @@ class CmdTake(Command):
"""
# logger.log_info(f"Dealing with {self.caller.key}")
self.caller.do_take(self.args)
class CmdKnock(Command):
"""
The ability to knock on something, like a door.
While it would be great if it could be attached to a door or some
other exit, we need to attach this to the room.
"""
key = "knock"
def func(self):
logger.log_info(f"Seems like {self.caller.key} wants to knock on me.")
self.obj.do_knock(self.caller)
class CmdSetKnock(CmdSet):
def at_cmdset_creation(self):
self.add(CmdKnock)

View file

@ -1,31 +1,19 @@
#!/usr/bin/env python
from evennia import Command, CmdSet
from evennia import Command, CmdSet, TICKER_HANDLER
from evennia.prototypes.spawner import spawn
from commands.consumables import (
CmdSetEat, CmdSetTrolley, CmdSetMakeConsumable
)
from typeclasses.objects import Object
from utils.word_list import routput
from datetime import date
from re import match
import random
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 Consumable(Object):
"""
Create with a command:
@ -71,22 +59,6 @@ class Consumable(Object):
self.delete()
class CmdMakeConsumable(Command):
"""
Generate a new thing and give it to the caller.
"""
key = "pick"
# aliases = "pick"
def func(self):
self.obj.do_make(self.caller, self.args)
class CmdSetMakeConsumable(CmdSet):
def at_cmdset_creation(self):
self.add(CmdMakeConsumable)
class Producer(Object):
"""
An object that produces a Consumable object.
@ -142,21 +114,13 @@ class Producer(Object):
# ----------------------------------------------------------------------
class CmdMakeScone(Command):
"""
Generate a new thing and give it to the caller.
"""
key = "get scone"
# aliases = "take scone"
def func(self):
self.obj.do_make(self.caller, self.args)
class CmdSetMakeScone(CmdSet):
def at_cmdset_creation(self):
self.add(CmdMakeScone)
TEACUP_DESCS = [
"A rustic, clay teacup carefully crafted on a wheel. Beautiful [dark red|olive green|navy blue] glaze.",
"A fine example of Royal Albert teacup, sporting a design of violet azaleas. Perfect for a black tea.",
"A Wings of Grace style teacup with blue butterflies. Perfect for some Earl Grey.",
"A dark brown Yixing clay teacup. Perfect for an Oolong tea.",
"A light jade green handle-less teacup. A good choice for a green tea.",
]
class Trolley(Producer):
"""
@ -204,8 +168,27 @@ class Trolley(Producer):
},
]
teacup_prototype = {
"typeclass": "typeclasses.drinkables.TeaCup",
"key": "teacup",
"desc": "A nice teacup.",
}
def at_object_creation(self):
self.cmdset.add_default(CmdSetMakeScone)
self.cmdset.add_default(CmdSetTrolley)
TICKER_HANDLER.add(interval=60 * 60 * 24,
callback=self.do_bake)
def produce_teacup(self, caller):
if caller.has("teacup"):
caller.msg("You already have a teacup.")
else:
cuptype = self.teacup_prototype
cuptype['desc'] = routput(random.choice(TEACUP_DESCS))
cup = spawn(cuptype)[0]
cup.location = caller
caller.msg("You pick up a teacup.")
def do_bake(self):
"""
@ -233,3 +216,5 @@ class Trolley(Producer):
self.db.make_eat_msgs = msgs
self.db.make_finish_msg = "That was [delicious|great|really good]."
self.location.msg_contents(routput("[New|Aromatic|Fresh|Freshly baked] scones [magically|suddenly|mystically|enchantingly|] appear [on a plate|on plates|] on the trolley."))

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python
from typeclasses.objects import Object
from commands.drinkables import CmdSetTeapot, CmdSetTeacup
from commands.consumables import CmdSetTeapot, CmdSetTeacup
from utils.word_list import routput, Token
import random
@ -28,14 +28,6 @@ TEA_TYPES = {
# Why limit to teas ... sure, this tea pot could make coffee ...
}
TEACUP_DESCS = [
"A rustic, clay teacup carefully crafted on a wheel. Beautiful [dark red|olive green|navy blue] glaze.",
"A fine example of Royal Albert teacup, sporting a design of violet azaleas. Perfect for a black tea.",
"A Wings of Grace style teacup with blue butterflies. Perfect for some Earl Grey.",
"A dark brown Yixing clay teacup. Perfect for an Oolong tea.",
"A light jade green handle-less teacup. A good choice for a green tea.",
]
FILL_MSGS = [
"You fill your [teacup|cup] with {1}.",
"You pour [some|] {0} tea into your [teacup|cup].",

View file

@ -10,7 +10,8 @@ for allowing Characters to traverse the exit to its destination.
from evennia.objects.objects import DefaultExit
from .objects import ObjectParent
from commands.take import CmdSetKnock
from commands.misc import CmdSetKnock
class Exit(ObjectParent, DefaultExit):
"""
@ -26,16 +27,7 @@ class Exit(ObjectParent, DefaultExit):
pre_check = traveler.at_pre_move(destination)
if pre_check:
if self.db.traverse_msg:
traveler.msg(f"\n{self.db.traverse_msg}\n\n")
traveler.msg(f"\n{self.db.traverse_msg}\n")
return super().at_traverse(traveler, destination)
else:
return False
class KnockableExit(Exit):
def at_object_creation(self):
self.cmdset.add_default(CmdSetKnock)
def do_knock(self, knocker):
knocker.msg("You knock.")
self.location.msg_contents(f"{knocker.name} knocks on {self.key}.",
exclude=knocker)

View file

@ -33,6 +33,7 @@ class CmdThrowFish(Command):
A helper can escort the fish to the nearest body of water if you aren't adjacent to one.
"""
key = "throw"
locks = "holds(fish)"
def func(self):
self.obj.do_delete(self.caller)
@ -48,6 +49,7 @@ class CmdCast(Command):
Cast the pole.
"""
key = "cast"
locks = "holds(pole)"
def func(self):
self.obj.do_cast(self.caller)
@ -58,6 +60,7 @@ class CmdReel(Command):
Reel the pole.
"""
key = "reel"
locks = "holds(pole)"
def func(self):
self.obj.do_reel(self.caller)

View file

@ -8,20 +8,12 @@ Each level of pet requires more aspects for interaction.
"""
from typeclasses.objects import Object
from typeclasses.characters import Character
# from typeclasses.lightables import LightSource
from commands.feedables import CmdFeed, CmdFeedSet
from commands.feedables import CmdFeedSet
from utils.word_list import squish
from evennia import (
TICKER_HANDLER,
CmdSet,
Command,
create_object,
default_cmds,
search_object,
syscmdkeys,
utils,
)
from evennia import TICKER_HANDLER
from enum import Enum
from time import time
@ -41,8 +33,8 @@ class Pet(Object):
This is a base class for Pets.
"""
fullname = None
pers_pronoun = "it" # or he/she/they
poss_pronoun = "its" # or his/her/them
pers_pronoun = "it" # or he/she/they
poss_pronoun = "its" # or his/her/them
# Feed about once a day:
hungry_rate = -.7
@ -83,7 +75,6 @@ class Pet(Object):
Called when object is first created.
We set up a ticker to update hunger levels regularly.
"""
super().at_object_creation()
self.db.hunger_level = Hunger.FULL.value
self.cmdset.add_default(CmdFeedSet)
@ -93,6 +84,7 @@ class Pet(Object):
# so as to not have all weather rooms update at the same time.
self.db.interval = random.randint(70, 90)
TICKER_HANDLER.add(interval=self.db.interval, callback=self.update_hunger)
super().at_object_creation()
def update_hunger(self, *args, **kwargs):
"""
@ -105,7 +97,9 @@ class Pet(Object):
curr = self.hunger()
amount = kwargs.get('amount', self.hungry_rate)
# self.location.msg_contents(f"Feeding a pet: {amount} {isinstance(amount, str)}-> {self.db.hunger_level} / {self.hungry_rate}")
# self.location.msg_contents(f"Feeding a pet: {amount}
# {isinstance(amount, str)}-> {self.db.hunger_level} /
# {self.hungry_rate}")
self.db.hunger_level = self.db.hunger_level + amount
if self.db.hunger_level < 0:
@ -119,7 +113,7 @@ class Pet(Object):
self.location.msg_contents("|w%s|n\n" % self.hunger_appearance())
try:
self.location.check_light_state()
except AttributeError as e:
except AttributeError:
pass
def return_appearance(self, looker, **kwargs):
@ -134,6 +128,7 @@ class Pet(Object):
"""
return f"{self.db.desc} {self.hunger_appearance()}"
# ------------------------------------------------------------
# Fireplace, both a pet that is hungry and consumes food,
# but also emits light when it isn't starving.
@ -189,6 +184,7 @@ class Fire(Pet):
feeder.msg(squish(f"You {get_up} put {adj} wood on the "
f"fire in the fireplace."))
self.location.msg_contents(squish(f"{feeder.name} {gets_up} puts {adj} wood on the fire."),
exclude=feeder)
exclude=feeder)
self.update_hunger(feeder=feeder, amount=300)

View file

@ -71,23 +71,26 @@ class CmdLookBook(Command):
"""
Respond with a new book to look at.
"""
priority = 3
auto_help = False
key = "look book"
aliases = "l book"
def func(self):
self.obj.do_look(self.caller)
class CmdTakeBook(Command):
"""
Generate a new book to store it with the reader.
"""
auto_help = False
key = "get book"
aliases = "take book"
def func(self):
self.obj.do_take(self.caller)
class CmdReadBook(Command):
"""
Return the inside contents of the book.
@ -96,16 +99,17 @@ class CmdReadBook(Command):
def func(self):
self.obj.do_read(self.caller)
class CmdBurnBook(Command):
"""
Destroy the instance of the book
"""
key = "burn"
aliases = "throw"
def func(self):
self.obj.do_burn(self.caller)
class CmdDropBook(Command):
"""
Drop the instance of the book
@ -116,10 +120,12 @@ class CmdDropBook(Command):
def func(self):
self.obj.do_burn(self.caller, drop=True)
class CmdSetRead(CmdSet):
def at_cmdset_creation(self):
self.add(CmdReadBook)
class CmdSetBook(CmdSet):
priority = 2
@ -128,11 +134,13 @@ class CmdSetBook(CmdSet):
self.add(CmdBurnBook)
self.add(CmdDropBook)
class CmdSetShelf(CmdSet):
def at_cmdset_creation(self):
self.add(CmdLookBook)
self.add(CmdTakeBook)
# ----------------------------------------------------------------------
class Readable(Object):
@ -180,12 +188,14 @@ class Letter(Readable):
class Book(Readable):
def do_read(self, reader):
super().do_read(reader)
reader.location.msg_contents(routput(f"{reader.name} reads a book. You notice the title, |b{0}|n.".format(self.db.title)), exclude=reader)
reader.location.msg_contents(routput(f"{reader.name} reads a book. You notice the title, |b{self.db.title}|n."),
exclude=reader)
def do_burn(self, reader, drop=False):
if isinstance(reader.location, DabblersRoom):
if drop:
reader.msg("You drop the book, and it flaps its pages, and flies back to a section on the shelf. Gotta keep the room organized.")
reader.msg("""You drop the book, and it flaps its pages, and flies back to a section on the shelf.
Gotta keep the room organized.""")
else:
reader.msg("You throw the book in the fireplace. It immediately yelps, flaps its pages, and flies back to a section on the shelf.")
self.location.msg_contents(routput(f"{reader.name} throws a book in the fireplace! It immediately yelps, flaps it pages, and flies back to a shelf."), exclude=reader)

View file

@ -5,39 +5,16 @@ Rooms are simple containers that has no location of their own.
"""
from evennia.objects.objects import DefaultRoom
from evennia import utils
from evennia.contrib.grid.extended_room import ExtendedRoom
from evennia.prototypes.spawner import spawn
# from .objects import LightSource
from .drinkables import TEACUP_DESCS
from .pets import Hunger
from commands.drinkables import CmdSetTrolley
from utils.word_list import routput, Token
import random
# the system error-handling module is defined in the settings. We load the
# given setting here using utils.object_from_module. This way we can use
# it regardless of if we change settings later.
from django.conf import settings
from evennia import (
TICKER_HANDLER,
CmdSet,
Command,
DefaultExit,
DefaultRoom,
create_object,
default_cmds,
search_object,
syscmdkeys,
utils,
)
# from .objects import LightSource
from .pets import Hunger
from .objects import ObjectParent
_SEARCH_AT_RESULT = utils.object_from_module(settings.SEARCH_AT_RESULT)
from .objects import ObjectParent
class Room(ObjectParent, ExtendedRoom):
@ -55,29 +32,6 @@ class Room(ObjectParent, ExtendedRoom):
class DabblersRoom(Room):
teacup_prototype = {
"typeclass": "typeclasses.drinkables.TeaCup",
"key": "teacup",
"desc": "A nice teacup.",
}
def at_object_creation(self):
"""
called at creation
"""
self.cmdset.add_default(CmdSetTrolley, persistent=True)
def produce_teacup(self, caller):
if caller.has("teacup"):
caller.msg("You already have a teacup.")
else:
cuptype = self.teacup_prototype
cuptype['desc'] = routput(random.choice(TEACUP_DESCS))
cup = spawn(cuptype)[0]
cup.location = caller
caller.msg("You pick up a teacup.")
def get_display_desc(self, looker):
fire = self.search("fire")
full_desc = self.db.initial_desc

View file

@ -3,22 +3,8 @@
import random
from .rooms import Room
from commands.take import CmdSetKnock
from .scripts import Script, KnockScript
from evennia import TICKER_HANDLER
from evennia import (
TICKER_HANDLER,
CmdSet,
Command,
DefaultExit,
DefaultRoom,
create_object,
default_cmds,
search_object,
syscmdkeys,
utils,
create_script,
)
# -------------------------------------------------------------
#
@ -27,12 +13,12 @@ from evennia import (
# -------------------------------------------------------------
# Need the time of day ...
from datetime import datetime, date, time, timedelta
from datetime import datetime
from pytz import timezone
TIMEBASE_WEATHER_MSGS = [
# Night
[ # Clear
[ # Clear
"The clouds part and you can see stars glitter against the black velvet night.",
"You hear distant howls as the moon appears.",
# Cloudy
@ -90,6 +76,7 @@ TIMEBASE_WEATHER_MSGS = [
],
]
def watches(now=None):
"""
Would be nice to get the sunrise/sunset of my area.
@ -101,18 +88,20 @@ def watches(now=None):
now = datetime.now(local_tz)
if now.hour < 4 or now.hour > 22:
return 0 # Night
return 0 # Night
if now.hour < 10:
return 1 # Morning
return 1 # Morning
if now.hour < 13:
return 2 # Noon
return 2 # Noon
if now.hour < 18:
return 3 # Afternoon
return 4 # Evening
return 3 # Afternoon
return 4 # Evening
def choose_weather_message():
return random.choice(TIMEBASE_WEATHER_MSGS[watches()])
class TimeWeatherRoom(Room):
"""
This sets up an outdoor room typeclass. At irregular intervals,
@ -138,8 +127,6 @@ class TimeWeatherRoom(Room):
TICKER_HANDLER.add(
interval=self.db.interval, callback=self.update_weather
)
# this is parsed by the 'tutorial' command on TutorialRooms.
self.db.tutorial_info = "This room has a Script running that has it echo a weather-related message at irregular intervals."
def update_weather(self, *args, **kwargs):
"""
@ -155,28 +142,3 @@ class TimeWeatherRoom(Room):
if self.db.previous_weather != msg:
self.db.previous_weather = msg
self.msg_contents(f"|w{msg}|n\n")
class KnockableOutsideRoom(TimeWeatherRoom):
def at_object_creation(self):
super().at_object_creation()
self.cmdset.add_default(CmdSetKnock)
def do_knock(self, knocker):
door = self.search("knocker")
if door.has("ring"):
knock_script = create_script(key="knocking",
typeclass=KnockScript,
interval=10, # seconds <=0 means off
start_delay=True, # wait interval before first call
autostart=True,
attributes=[("knocker", knocker)])
knock_script.db.waker = door
# This is the _character_ that does the knocking, not the door knocker:
knock_script.db.knocker = knocker
knocker.msg("You grab the ring and knock firmly on the door.")
self.msg_contents(f"{knocker.name} grabs the ring and knocks firmly on the door.",
exclude=knocker)
else:
knocker.msg("This door knocker is defective, as it doesn't have a ring to...er, do the knockin'.")

View file

@ -103,6 +103,7 @@ class Script(DefaultScript):
"""
pass
class KnockScript(Script):
"""
A script to wake the dead.
@ -110,12 +111,13 @@ class KnockScript(Script):
def at_start(self):
knocker = self.attributes.get("knocker")
if knocker:
room = knocker.global_search("mp03")
room = knocker.global_search(self.attributes.get("room"))
if room:
room.msg_contents("Someone is knocking on the door...")
god_msg(f"With your seer stone, you see the knocker is {knocker.key}.")
def at_repeat(self):
if self.db.waker:
self.db.waker.knocked_timed_out()
waker = self.attributes.get("waker")
if waker:
waker.knocked_timed_out()
self.stop()

View file

@ -4,6 +4,7 @@ from typeclasses.objects import Object
from commands.sittables import CmdSetSit
from utils.word_list import routput
class Sittable(Object):
multiple = False
@ -32,14 +33,14 @@ class Sittable(Object):
article = self.db.article or "the"
current = self.db.sitter
if current:
if current == sitter:
sitter.msg(f"You are already sitting {adjective} {article} {self.key}.")
return
elif not self.multiple:
sitter.msg(f"You can't sit {adjective} {article} {self.key} "
f"- {current.key} is already sitting there!")
return
if sitter.db.is_sitting:
sitter.msg(f"You are already sitting {adjective} {article} {self.key}.")
return
if self.db.sitter and not self.multiple:
sitter.msg(f"You can't sit {adjective} {article} {self.key} "
f"- {current.key} is already sitting there!")
return
self.db.sitter = sitter
sitter.db.is_sitting = self
@ -47,7 +48,6 @@ class Sittable(Object):
self.location.msg_contents(f"{sitter.name} sits {adjective} {article} {self.key}.",
exclude=sitter)
def do_stand(self, stander):
"""
Called when trying to stand from this object.
@ -65,6 +65,7 @@ class Sittable(Object):
del stander.db.is_sitting
stander.msg(self.stand_msg())
class Sittables(Sittable):
multiple = True

View file

@ -1,20 +1,11 @@
#!/usr/bin/env python
"""
Knocker
The Object is the class for gatekeepers between rooms.
Use the ObjectParent class to implement common features for *all* entities
with a location in the game world (like Characters, Rooms, Exits).
"""
from evennia import create_script
from evennia.utils import logger
from .scripts import KnockScript
from .objects import Object
from .characters import Character
from commands.misc import CmdSetPuddle, CmdSetStick
from commands.misc import CmdSetPuddle, CmdSetStick, CmdSetKnock
from utils.word_list import routput
from random import choice, random
@ -26,18 +17,19 @@ class Stick(Object):
self.cmdset.add_default(CmdSetStick)
def do_throw(self, thrower):
player.db.thrown_times = (player.db.thrown_times or 0) + 1
if player.db.jumped_times == 1:
player.msg("The stick flies through the air, and just as you thought, it comes back to you!")
thrower.db.thrown_times = (thrower.db.thrown_times or 0) + 1
if thrower.db.jumped_times == 1:
thrower.msg("The stick flies through the air, and just as you thought, it comes back to you!")
else:
player.msg(routput(choice([
"Yer a wizard, {thrower.name.capitalize()}!",
"Did you see that? It clipped the leaf on that tree before returning.",
"This is a fun game.",
"Maybe we should get a pet beastie in here who would love to play.",
thrower.msg(routput(choice([
f"Yer a wizard, {thrower.name.capitalize()}!",
"[Did you see that?|] It clipped the leaf on that tree before returning.",
"This is a [fun|pleasant|nice] [past-time|game].",
"Maybe we should get a pet [or beast|beastie] in here who would love to play.",
])))
self.location.msg_contents(f"{player.name} jumps in the puddle.",
exclude=player)
self.location.msg_contents(f"{thrower.name} throws a stick.",
exclude=thrower)
class Puddle(Object):
def at_object_creation(self):
@ -67,11 +59,14 @@ class Puddle(Object):
self.location.msg_contents(f"{player.name} jumps in the puddle.",
exclude=player)
class Knocker(Object):
"""
Knocker
The Object is the class for gatekeepers between rooms.
Special object that listens to what is said in the room, and
attempts to a _real_ NPC.
"""
muffled_responses = [
"Mmmuufffmm",
@ -191,6 +186,37 @@ class Knocker(Object):
"I'll say, [we have had|that is] a spell of weather.",
]
def at_object_creation(self):
super().at_object_creation()
self.cmdset.add(CmdSetKnock)
def do_knock(self, knocker):
if self.has("ring"):
knock_script = create_script(key="knocking",
typeclass=KnockScript,
interval=10, # seconds <=0 means off
start_delay=True, # wait interval before first call
autostart=True,
# This is the _character_
# that does the knocking, not
# the door knocker:
attributes=[("knocker", knocker),
# Waker is the door knocker
("waker", self),
("room", self.db.room_to_msg)
])
knocker.msg("You grab the ring and knock firmly on the door.")
self.msg_contents(f"{knocker.name} grabs the ring and knocks firmly on the door.",
exclude=knocker)
else:
knocker.msg("This door knocker is defective, as it doesn't have a ring to...er, do the knockin'.")
def knocked_timed_out(self):
if self.has("brass ring"):
self.at_say(choice(self.muffled_responses))
else:
self.at_say("Doesn't appear that anyone is home.")
def at_heard_say(self, message, from_obj):
"""
A simple listener and response. This makes it easy to change for
@ -228,28 +254,28 @@ class Knocker(Object):
# time, so we store in the database a setting to keep
# track and alternate the responses:
elif self.db.hard:
self.db.hard = False;
self.db.hard = False
if from_obj.tags.get(key="open_red_door", category="mp"):
return routput(choice(self.after_unlocked_responses))
else:
return routput(choice(self.unknown_responses))
else:
self.db.hard = True;
self.db.hard = True
return routput(choice(self.cant_hear_responses))
def get_display_desc(self, looker, **kwargs):
# Use this for random information instead of self.db.desc
response = "In a shape of a bald goblin, the brass door knocker in the center of the red door"
if self.has("brass ring"):
response += " holds a ring in its mouth. "
response += "[You think it|You are sure it|You could've sworn it|It] [just|] winked at you."
response += " holds a ring in its mouth. "
response += "[You think it|You are sure it|You could've sworn it|It] [just|] winked at you."
else:
response += " [smiles|looks] at you expectantly. "
response += " [smiles|looks] at you expectantly. "
return routput(response)
def at_desc(self, looker):
return "what" # self.get_display_desc(looker)
return "what" # self.get_display_desc(looker)
def get_display_things(self, looker):
return ""
@ -275,7 +301,7 @@ class Knocker(Object):
# First get the response (if any)
response = self.at_heard_say(say_text, from_obj)
# If there is a response
if response != None:
if response is not None:
self.at_say(response)
# this is needed if anyone ever puppets this NPC - without it you would never
@ -288,9 +314,3 @@ class Knocker(Object):
else:
self.at_say("Umph")
return True
def knocked_timed_out(self):
if self.has("brass ring"):
self.at_say(choice(self.muffled_responses))
else:
self.at_say("Doesn't appear that anyone is home.")