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 #!/usr/bin/env python
from evennia import Command, CmdSet 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): class CmdDrinkTea(Command):
""" """
@ -16,15 +48,19 @@ class CmdDrinkTea(Command):
def func(self): def func(self):
self.obj.do_drink(self.caller) self.obj.do_drink(self.caller)
class CmdMakeTea(Command): class CmdMakeTea(Command):
""" """
make [tea-type] 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" key = "make"
aliases = ["make tea"] aliases = "brew"
locks = "cmd:all()"
def func(self): def func(self):
""" """
@ -32,6 +68,7 @@ class CmdMakeTea(Command):
""" """
self.obj.do_make_tea(self.caller, self.args.strip()) self.obj.do_make_tea(self.caller, self.args.strip())
class CmdFillTeacup(Command): class CmdFillTeacup(Command):
""" """
Fill the teacup with whatever tea is in the teapot. Fill the teacup with whatever tea is in the teapot.
@ -40,16 +77,30 @@ class CmdFillTeacup(Command):
""" """
key = "fill" key = "fill"
aliases = "pour" aliases = "pour"
locks = "holds(teacup)"
def func(self): def func(self):
self.obj.do_fill(self.caller) 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): class CmdGetTeacup(Command):
""" """
Get a teacup from the trolley. Get a teacup from the trolley.
Each cup is special, but not necessarily unique. Each cup is special, but not necessarily unique.
""" """
auto_help = False
key = "get teacup" key = "get teacup"
aliases = ["get cup", "pickup cup", "pickup teacup", "take cup", "take teacup"] aliases = ["get cup", "pickup cup", "pickup teacup", "take cup", "take teacup"]
locks = "cmd:all()" locks = "cmd:all()"
@ -61,15 +112,20 @@ class CmdGetTeacup(Command):
""" """
self.obj.produce_teacup(self.caller) self.obj.produce_teacup(self.caller)
class CmdSetTeacup(CmdSet):
def at_cmdset_creation(self):
self.add(CmdDrinkTea)
class CmdSetTeapot(CmdSet): class CmdMakeScone(Command):
def at_cmdset_creation(self): """
self.add(CmdMakeTea) Generate a new thing and give it to the caller.
self.add(CmdFillTeacup) """
auto_help = False
key = "get scone"
aliases = "grab scone"
def func(self):
self.obj.do_make(self.caller, self.args)
class CmdSetTrolley(CmdSet): class CmdSetTrolley(CmdSet):
def at_cmdset_creation(self): def at_cmdset_creation(self):
self.add(CmdGetTeacup) self.add(CmdGetTeacup)
self.add(CmdMakeScone)

View file

@ -5,10 +5,11 @@ from evennia import CmdSet
class CmdFeed(Command): 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" key = "feed"
aliases = ["give"]
def func(self): def func(self):
args = self.args.strip() args = self.args.strip()
@ -16,6 +17,7 @@ class CmdFeed(Command):
self.caller.msg("Feed what?") self.caller.msg("Feed what?")
return return
print(self.obj.key)
self.obj.feed(self.caller, self.args) self.obj.feed(self.caller, self.args)
class CmdFeedSet(CmdSet): class CmdFeedSet(CmdSet):

View file

@ -2,6 +2,27 @@
from .command import Command from .command import Command
from evennia import CmdSet 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): class CmdJump(Command):
@ -25,6 +46,7 @@ class CmdThrow(Command):
Jump or play in or around puddles. Jump or play in or around puddles.
""" """
key = "throw" key = "throw"
locks = "holds(stick)"
def func(self): def func(self):
self.obj.do_throw(self.caller) self.obj.do_throw(self.caller)

View file

@ -1,8 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
from commands.command import Command from commands.command import Command
from evennia import CmdSet
from evennia.utils import logger
class CmdTake(Command): class CmdTake(Command):
""" """
@ -10,7 +9,7 @@ class CmdTake(Command):
Added to the default_cmdsets. Added to the default_cmdsets.
""" """
key = "take" key = "take"
aliases = ["remove"] aliases = ["steal"]
# only allow this command if command.obj is carried by caller. # only allow this command if command.obj is carried by caller.
# locks = "cmd:holds()" # locks = "cmd:holds()"
@ -21,21 +20,3 @@ class CmdTake(Command):
""" """
# logger.log_info(f"Dealing with {self.caller.key}") # logger.log_info(f"Dealing with {self.caller.key}")
self.caller.do_take(self.args) 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 #!/usr/bin/env python
from evennia import Command, CmdSet from evennia import Command, CmdSet, TICKER_HANDLER
from evennia.prototypes.spawner import spawn from evennia.prototypes.spawner import spawn
from commands.consumables import (
CmdSetEat, CmdSetTrolley, CmdSetMakeConsumable
)
from typeclasses.objects import Object from typeclasses.objects import Object
from utils.word_list import routput from utils.word_list import routput
from datetime import date from datetime import date
from re import match
import random 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): class Consumable(Object):
""" """
Create with a command: Create with a command:
@ -71,22 +59,6 @@ class Consumable(Object):
self.delete() 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): class Producer(Object):
""" """
An object that produces a Consumable object. An object that produces a Consumable object.
@ -142,21 +114,13 @@ class Producer(Object):
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
class CmdMakeScone(Command): TEACUP_DESCS = [
""" "A rustic, clay teacup carefully crafted on a wheel. Beautiful [dark red|olive green|navy blue] glaze.",
Generate a new thing and give it to the caller. "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.",
key = "get scone" "A dark brown Yixing clay teacup. Perfect for an Oolong tea.",
# aliases = "take scone" "A light jade green handle-less teacup. A good choice for a green tea.",
]
def func(self):
self.obj.do_make(self.caller, self.args)
class CmdSetMakeScone(CmdSet):
def at_cmdset_creation(self):
self.add(CmdMakeScone)
class Trolley(Producer): 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): 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): def do_bake(self):
""" """
@ -233,3 +216,5 @@ class Trolley(Producer):
self.db.make_eat_msgs = msgs self.db.make_eat_msgs = msgs
self.db.make_finish_msg = "That was [delicious|great|really good]." 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 #!/usr/bin/env python
from typeclasses.objects import Object from typeclasses.objects import Object
from commands.drinkables import CmdSetTeapot, CmdSetTeacup from commands.consumables import CmdSetTeapot, CmdSetTeacup
from utils.word_list import routput, Token from utils.word_list import routput, Token
import random import random
@ -28,14 +28,6 @@ TEA_TYPES = {
# Why limit to teas ... sure, this tea pot could make coffee ... # 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 = [ FILL_MSGS = [
"You fill your [teacup|cup] with {1}.", "You fill your [teacup|cup] with {1}.",
"You pour [some|] {0} tea into your [teacup|cup].", "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 evennia.objects.objects import DefaultExit
from .objects import ObjectParent from .objects import ObjectParent
from commands.take import CmdSetKnock from commands.misc import CmdSetKnock
class Exit(ObjectParent, DefaultExit): class Exit(ObjectParent, DefaultExit):
""" """
@ -26,16 +27,7 @@ class Exit(ObjectParent, DefaultExit):
pre_check = traveler.at_pre_move(destination) pre_check = traveler.at_pre_move(destination)
if pre_check: if pre_check:
if self.db.traverse_msg: 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) return super().at_traverse(traveler, destination)
else: else:
return False 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. A helper can escort the fish to the nearest body of water if you aren't adjacent to one.
""" """
key = "throw" key = "throw"
locks = "holds(fish)"
def func(self): def func(self):
self.obj.do_delete(self.caller) self.obj.do_delete(self.caller)
@ -48,6 +49,7 @@ class CmdCast(Command):
Cast the pole. Cast the pole.
""" """
key = "cast" key = "cast"
locks = "holds(pole)"
def func(self): def func(self):
self.obj.do_cast(self.caller) self.obj.do_cast(self.caller)
@ -58,6 +60,7 @@ class CmdReel(Command):
Reel the pole. Reel the pole.
""" """
key = "reel" key = "reel"
locks = "holds(pole)"
def func(self): def func(self):
self.obj.do_reel(self.caller) 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.objects import Object
from typeclasses.characters import Character
# from typeclasses.lightables import LightSource # from typeclasses.lightables import LightSource
from commands.feedables import CmdFeed, CmdFeedSet from commands.feedables import CmdFeedSet
from utils.word_list import squish from utils.word_list import squish
from evennia import ( from evennia import TICKER_HANDLER
TICKER_HANDLER,
CmdSet,
Command,
create_object,
default_cmds,
search_object,
syscmdkeys,
utils,
)
from enum import Enum from enum import Enum
from time import time from time import time
@ -83,7 +75,6 @@ class Pet(Object):
Called when object is first created. Called when object is first created.
We set up a ticker to update hunger levels regularly. We set up a ticker to update hunger levels regularly.
""" """
super().at_object_creation()
self.db.hunger_level = Hunger.FULL.value self.db.hunger_level = Hunger.FULL.value
self.cmdset.add_default(CmdFeedSet) 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. # so as to not have all weather rooms update at the same time.
self.db.interval = random.randint(70, 90) self.db.interval = random.randint(70, 90)
TICKER_HANDLER.add(interval=self.db.interval, callback=self.update_hunger) TICKER_HANDLER.add(interval=self.db.interval, callback=self.update_hunger)
super().at_object_creation()
def update_hunger(self, *args, **kwargs): def update_hunger(self, *args, **kwargs):
""" """
@ -105,7 +97,9 @@ class Pet(Object):
curr = self.hunger() curr = self.hunger()
amount = kwargs.get('amount', self.hungry_rate) 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 self.db.hunger_level = self.db.hunger_level + amount
if self.db.hunger_level < 0: if self.db.hunger_level < 0:
@ -119,7 +113,7 @@ class Pet(Object):
self.location.msg_contents("|w%s|n\n" % self.hunger_appearance()) self.location.msg_contents("|w%s|n\n" % self.hunger_appearance())
try: try:
self.location.check_light_state() self.location.check_light_state()
except AttributeError as e: except AttributeError:
pass pass
def return_appearance(self, looker, **kwargs): def return_appearance(self, looker, **kwargs):
@ -134,6 +128,7 @@ class Pet(Object):
""" """
return f"{self.db.desc} {self.hunger_appearance()}" return f"{self.db.desc} {self.hunger_appearance()}"
# ------------------------------------------------------------ # ------------------------------------------------------------
# Fireplace, both a pet that is hungry and consumes food, # Fireplace, both a pet that is hungry and consumes food,
# but also emits light when it isn't starving. # but also emits light when it isn't starving.
@ -192,3 +187,4 @@ class Fire(Pet):
exclude=feeder) exclude=feeder)
self.update_hunger(feeder=feeder, amount=300) self.update_hunger(feeder=feeder, amount=300)

View file

@ -71,23 +71,26 @@ class CmdLookBook(Command):
""" """
Respond with a new book to look at. Respond with a new book to look at.
""" """
priority = 3 auto_help = False
key = "look book" key = "look book"
aliases = "l book" aliases = "l book"
def func(self): def func(self):
self.obj.do_look(self.caller) self.obj.do_look(self.caller)
class CmdTakeBook(Command): class CmdTakeBook(Command):
""" """
Generate a new book to store it with the reader. Generate a new book to store it with the reader.
""" """
auto_help = False
key = "get book" key = "get book"
aliases = "take book" aliases = "take book"
def func(self): def func(self):
self.obj.do_take(self.caller) self.obj.do_take(self.caller)
class CmdReadBook(Command): class CmdReadBook(Command):
""" """
Return the inside contents of the book. Return the inside contents of the book.
@ -96,16 +99,17 @@ class CmdReadBook(Command):
def func(self): def func(self):
self.obj.do_read(self.caller) self.obj.do_read(self.caller)
class CmdBurnBook(Command): class CmdBurnBook(Command):
""" """
Destroy the instance of the book Destroy the instance of the book
""" """
key = "burn" key = "burn"
aliases = "throw"
def func(self): def func(self):
self.obj.do_burn(self.caller) self.obj.do_burn(self.caller)
class CmdDropBook(Command): class CmdDropBook(Command):
""" """
Drop the instance of the book Drop the instance of the book
@ -116,10 +120,12 @@ class CmdDropBook(Command):
def func(self): def func(self):
self.obj.do_burn(self.caller, drop=True) self.obj.do_burn(self.caller, drop=True)
class CmdSetRead(CmdSet): class CmdSetRead(CmdSet):
def at_cmdset_creation(self): def at_cmdset_creation(self):
self.add(CmdReadBook) self.add(CmdReadBook)
class CmdSetBook(CmdSet): class CmdSetBook(CmdSet):
priority = 2 priority = 2
@ -128,11 +134,13 @@ class CmdSetBook(CmdSet):
self.add(CmdBurnBook) self.add(CmdBurnBook)
self.add(CmdDropBook) self.add(CmdDropBook)
class CmdSetShelf(CmdSet): class CmdSetShelf(CmdSet):
def at_cmdset_creation(self): def at_cmdset_creation(self):
self.add(CmdLookBook) self.add(CmdLookBook)
self.add(CmdTakeBook) self.add(CmdTakeBook)
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
class Readable(Object): class Readable(Object):
@ -180,12 +188,14 @@ class Letter(Readable):
class Book(Readable): class Book(Readable):
def do_read(self, reader): def do_read(self, reader):
super().do_read(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): def do_burn(self, reader, drop=False):
if isinstance(reader.location, DabblersRoom): if isinstance(reader.location, DabblersRoom):
if drop: 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: 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.") 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) 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.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 django.conf import settings
from evennia import ( # from .objects import LightSource
TICKER_HANDLER, from .pets import Hunger
CmdSet, from .objects import ObjectParent
Command,
DefaultExit,
DefaultRoom,
create_object,
default_cmds,
search_object,
syscmdkeys,
utils,
)
_SEARCH_AT_RESULT = utils.object_from_module(settings.SEARCH_AT_RESULT) _SEARCH_AT_RESULT = utils.object_from_module(settings.SEARCH_AT_RESULT)
from .objects import ObjectParent
class Room(ObjectParent, ExtendedRoom): class Room(ObjectParent, ExtendedRoom):
@ -55,29 +32,6 @@ class Room(ObjectParent, ExtendedRoom):
class DabblersRoom(Room): 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): def get_display_desc(self, looker):
fire = self.search("fire") fire = self.search("fire")
full_desc = self.db.initial_desc full_desc = self.db.initial_desc

View file

@ -3,22 +3,8 @@
import random import random
from .rooms import Room from .rooms import Room
from commands.take import CmdSetKnock from evennia import TICKER_HANDLER
from .scripts import Script, KnockScript
from evennia import (
TICKER_HANDLER,
CmdSet,
Command,
DefaultExit,
DefaultRoom,
create_object,
default_cmds,
search_object,
syscmdkeys,
utils,
create_script,
)
# ------------------------------------------------------------- # -------------------------------------------------------------
# #
@ -27,7 +13,7 @@ from evennia import (
# ------------------------------------------------------------- # -------------------------------------------------------------
# Need the time of day ... # Need the time of day ...
from datetime import datetime, date, time, timedelta from datetime import datetime
from pytz import timezone from pytz import timezone
TIMEBASE_WEATHER_MSGS = [ TIMEBASE_WEATHER_MSGS = [
@ -90,6 +76,7 @@ TIMEBASE_WEATHER_MSGS = [
], ],
] ]
def watches(now=None): def watches(now=None):
""" """
Would be nice to get the sunrise/sunset of my area. Would be nice to get the sunrise/sunset of my area.
@ -110,9 +97,11 @@ def watches(now=None):
return 3 # Afternoon return 3 # Afternoon
return 4 # Evening return 4 # Evening
def choose_weather_message(): def choose_weather_message():
return random.choice(TIMEBASE_WEATHER_MSGS[watches()]) return random.choice(TIMEBASE_WEATHER_MSGS[watches()])
class TimeWeatherRoom(Room): class TimeWeatherRoom(Room):
""" """
This sets up an outdoor room typeclass. At irregular intervals, This sets up an outdoor room typeclass. At irregular intervals,
@ -138,8 +127,6 @@ class TimeWeatherRoom(Room):
TICKER_HANDLER.add( TICKER_HANDLER.add(
interval=self.db.interval, callback=self.update_weather 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): def update_weather(self, *args, **kwargs):
""" """
@ -155,28 +142,3 @@ class TimeWeatherRoom(Room):
if self.db.previous_weather != msg: if self.db.previous_weather != msg:
self.db.previous_weather = msg self.db.previous_weather = msg
self.msg_contents(f"|w{msg}|n\n") 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 pass
class KnockScript(Script): class KnockScript(Script):
""" """
A script to wake the dead. A script to wake the dead.
@ -110,12 +111,13 @@ class KnockScript(Script):
def at_start(self): def at_start(self):
knocker = self.attributes.get("knocker") knocker = self.attributes.get("knocker")
if knocker: if knocker:
room = knocker.global_search("mp03") room = knocker.global_search(self.attributes.get("room"))
if room: if room:
room.msg_contents("Someone is knocking on the door...") room.msg_contents("Someone is knocking on the door...")
god_msg(f"With your seer stone, you see the knocker is {knocker.key}.") god_msg(f"With your seer stone, you see the knocker is {knocker.key}.")
def at_repeat(self): def at_repeat(self):
if self.db.waker: waker = self.attributes.get("waker")
self.db.waker.knocked_timed_out() if waker:
waker.knocked_timed_out()
self.stop() self.stop()

View file

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

View file

@ -1,20 +1,11 @@
#!/usr/bin/env python #!/usr/bin/env python
""" from evennia import create_script
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.utils import logger from evennia.utils import logger
from .scripts import KnockScript
from .objects import Object from .objects import Object
from .characters import Character from commands.misc import CmdSetPuddle, CmdSetStick, CmdSetKnock
from commands.misc import CmdSetPuddle, CmdSetStick
from utils.word_list import routput from utils.word_list import routput
from random import choice, random from random import choice, random
@ -26,18 +17,19 @@ class Stick(Object):
self.cmdset.add_default(CmdSetStick) self.cmdset.add_default(CmdSetStick)
def do_throw(self, thrower): def do_throw(self, thrower):
player.db.thrown_times = (player.db.thrown_times or 0) + 1 thrower.db.thrown_times = (thrower.db.thrown_times or 0) + 1
if player.db.jumped_times == 1: if thrower.db.jumped_times == 1:
player.msg("The stick flies through the air, and just as you thought, it comes back to you!") thrower.msg("The stick flies through the air, and just as you thought, it comes back to you!")
else: else:
player.msg(routput(choice([ thrower.msg(routput(choice([
"Yer a wizard, {thrower.name.capitalize()}!", f"Yer a wizard, {thrower.name.capitalize()}!",
"Did you see that? It clipped the leaf on that tree before returning.", "[Did you see that?|] It clipped the leaf on that tree before returning.",
"This is a fun game.", "This is a [fun|pleasant|nice] [past-time|game].",
"Maybe we should get a pet beastie in here who would love to play.", "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.", self.location.msg_contents(f"{thrower.name} throws a stick.",
exclude=player) exclude=thrower)
class Puddle(Object): class Puddle(Object):
def at_object_creation(self): def at_object_creation(self):
@ -67,11 +59,14 @@ class Puddle(Object):
self.location.msg_contents(f"{player.name} jumps in the puddle.", self.location.msg_contents(f"{player.name} jumps in the puddle.",
exclude=player) exclude=player)
class Knocker(Object): 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 Special object that listens to what is said in the room, and
attempts to a _real_ NPC. attempts to a _real_ NPC.
""" """
muffled_responses = [ muffled_responses = [
"Mmmuufffmm", "Mmmuufffmm",
@ -191,6 +186,37 @@ class Knocker(Object):
"I'll say, [we have had|that is] a spell of weather.", "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): def at_heard_say(self, message, from_obj):
""" """
A simple listener and response. This makes it easy to change for A simple listener and response. This makes it easy to change for
@ -228,13 +254,13 @@ class Knocker(Object):
# time, so we store in the database a setting to keep # time, so we store in the database a setting to keep
# track and alternate the responses: # track and alternate the responses:
elif self.db.hard: elif self.db.hard:
self.db.hard = False; self.db.hard = False
if from_obj.tags.get(key="open_red_door", category="mp"): if from_obj.tags.get(key="open_red_door", category="mp"):
return routput(choice(self.after_unlocked_responses)) return routput(choice(self.after_unlocked_responses))
else: else:
return routput(choice(self.unknown_responses)) return routput(choice(self.unknown_responses))
else: else:
self.db.hard = True; self.db.hard = True
return routput(choice(self.cant_hear_responses)) return routput(choice(self.cant_hear_responses))
def get_display_desc(self, looker, **kwargs): def get_display_desc(self, looker, **kwargs):
@ -275,7 +301,7 @@ class Knocker(Object):
# First get the response (if any) # First get the response (if any)
response = self.at_heard_say(say_text, from_obj) response = self.at_heard_say(say_text, from_obj)
# If there is a response # If there is a response
if response != None: if response is not None:
self.at_say(response) self.at_say(response)
# this is needed if anyone ever puppets this NPC - without it you would never # this is needed if anyone ever puppets this NPC - without it you would never
@ -288,9 +314,3 @@ class Knocker(Object):
else: else:
self.at_say("Umph") self.at_say("Umph")
return True 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.")