We can knock on a door.

And a number of bugs squashed.
This commit is contained in:
Howard Abrams 2025-02-11 21:09:23 -08:00
parent fabb5a0d00
commit 0850301c65
9 changed files with 100 additions and 26 deletions

View file

@ -10,7 +10,7 @@ class CmdTake(Command):
Added to the default_cmdsets.
"""
key = "take"
aliases = ["get", "remove"]
aliases = ["remove"]
# only allow this command if command.obj is carried by caller.
# locks = "cmd:holds()"
@ -19,5 +19,23 @@ class CmdTake(Command):
Implements the take command. Since this command is designed
to work on the object, we operate only on self.obj.
"""
logger.log_info(f"Dealing with {self.caller.key}")
# 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

@ -11,10 +11,10 @@ creation commands.
from evennia.objects.objects import DefaultCharacter
from utils.word_list import Token, routput
from .objects import ObjectParent
from .objects import Object
class Character(ObjectParent, DefaultCharacter):
class Character(Object, DefaultCharacter):
"""
The Character just re-implements some of the Object's methods and hooks
to represent a Character entity in-game.

View file

@ -10,7 +10,7 @@ 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
class Exit(ObjectParent, DefaultExit):
"""
@ -30,3 +30,12 @@ class Exit(ObjectParent, DefaultExit):
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

@ -4,7 +4,7 @@ from typeclasses.objects import Object
from typeclasses.rooms import DabblersRoom
from evennia import Command, CmdSet
from evennia.prototypes.spawner import spawn
from utils.word_list import routput, character_has, Token
from utils.word_list import routput, Token
import random

View file

@ -3,6 +3,9 @@
import random
from .rooms import Room
from commands.take import CmdSetKnock
from .scripts import Script, KnockScript
from evennia import (
TICKER_HANDLER,
CmdSet,
@ -14,10 +17,9 @@ from evennia import (
search_object,
syscmdkeys,
utils,
create_script,
)
print("Loading the weather...")
# -------------------------------------------------------------
#
# Weather room - room with a ticker
@ -153,3 +155,27 @@ 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
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

@ -13,6 +13,8 @@ just overloads its hooks to have it perform its function.
"""
from evennia.scripts.scripts import DefaultScript
from evennia.utils import logger
from utils.support import god_msg
class Script(DefaultScript):
@ -99,5 +101,18 @@ class Script(DefaultScript):
at_server_start()
"""
pass
class KnockScript(Script):
"""
A script to wake the dead.
"""
def at_start(self):
knocker = self.attributes.get("knocker")
if knocker:
god_msg(f"{knocker.key} stands at the door, and knocks.")
def at_repeat(self):
if self.db.waker:
self.db.waker.knocked_timed_out()
self.stop()

View file

@ -71,12 +71,12 @@ class Sittables(Sittable):
def sit_msg(self):
adjective = self.db.adjective or "on"
article = self.db.article or "the"
default = f"{article} {self.db.name}"
name = aliases[-1] # Last alias is singular
default = f"{article} {name}"
singular = self.db.singular or default
extra = self.db.extra or ""
aliases = self.aliases.all()
name = aliases[1] # Second alias is singular
return routput(f"You sit {adjective} {singular}. {extra}")

View file

@ -51,14 +51,14 @@ class Knocker(Object):
[r"knocker|goblin", [
"[Sorry.|What was that?|Did you say something?] I'm hard of hearing on account of the brass ears.",
"Yes, I suppose I'm this amazing puzzle you get to in Chapter Three. Wait, does that mean I'm just an NPC?",
"Who me? I thought you were talking to the goblin in the bushes."
"Who me? I thought you were talking to the goblin in the bushes.",
"Why yes, I am hard of hearing.",
]],
["password", [
"Of course this door is protected by a super complicated encrypted password.",
"If I tell you, it wouldn't be a secret now.",
"The password? You just have to guess.",
"Well, I suppose I could give you a hint."
"Well, I suppose I could give you a |bhint|n.",
]],
["hint", [
"A hint does sound fair. [Should I|I should] come up with a |briddle|n[|, huh]?"
@ -83,7 +83,7 @@ class Knocker(Object):
things out, wait, where was I?
"""
]],
["hello|greet", [
[r"\bhello|\bgreet|\bhey\b", [
"How's it going?",
"How's it?",
"'Sup.",
@ -107,14 +107,14 @@ class Knocker(Object):
So, you see, if you speak the |bpassword|n, wait, I've said too much.
"""
]],
["\byes|yeah|yah\b", [
[r"\byes|yeah|yah\b", [
"Really? You agree?",
"Excellent",
]],
["\bno|nope\b", [
[r"\bno|nope\b", [
"Well, it's true. Just ask the [raven|trees|gnome].",
]],
["\?$", [
[r"\?$", [
"What about [me|it|'im]?",
"I dunno...",
]],
@ -163,7 +163,8 @@ class Knocker(Object):
# Let's see if a keyword gives a good response:
for idx, [regex, responses] in enumerate(self.all_responses):
if re.match(r".*" + regex + r".*", message):
full_regex = r".*" + regex + r".*"
if re.match(full_regex, message):
# The first match is the password, so we set a tag on
# the character, so that they can go through the door:
if idx == 0:
@ -248,3 +249,9 @@ 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.")

View file

@ -20,12 +20,11 @@ def character_has(holder, item):
elif i == item:
return i
def god_msg(msg, sender=None, location=None):
dabbler = Character.objects.search_object("#1")[0]
dabbler.msg(f"{msg} {'from ' + sender if sender else ''} {'at ' + location if location else ''}")
def debug(msg, sender=None, location=None):
dabbler = Character.objects.search_object("Dabbler")[0]
full_msg = "DEBUG:"
if sender:
full_msg += f" (from {sender})"
if location:
full_msg += f" (at {location})"
full_msg += f" {msg}"
dabbler.msg(full_msg)
god_msg(f"DEBUG: {msg}", sender, location)
# py from typeclasses.characters import Character; god = Character.objects.search_object("#1")[0]