From 14c83855890576b33052a6292350a03bbff829d2 Mon Sep 17 00:00:00 2001 From: Howard Abrams Date: Fri, 11 Jul 2025 22:06:50 -0700 Subject: [PATCH] Create a Secret Room under the Cozy House A sconce, both a producer of long-lasting candles, as well as an "opener" that when pulled opens a secret passage. --- typeclasses/consumables.py | 20 +++++++- typeclasses/exits.py | 28 +++++++++- typeclasses/lightables.py | 40 +++++++++++++-- world/version1.ev | 101 +++++++++++++++++++++++++------------ 4 files changed, 153 insertions(+), 36 deletions(-) diff --git a/typeclasses/consumables.py b/typeclasses/consumables.py index c781c3e..f3624f8 100755 --- a/typeclasses/consumables.py +++ b/typeclasses/consumables.py @@ -4,10 +4,11 @@ from datetime import date import random from evennia import TICKER_HANDLER +from evennia.utils import delay from evennia.prototypes.spawner import spawn from commands.consumables import CmdSetTrolley, CmdSetMakeConsumable - +from typeclasses.exits import Opener from typeclasses.objects import Object from utils.word_list import routput # , choices @@ -255,3 +256,20 @@ class Trolley(Producer): self.db.make_finish_msg = "That was <>." self.location.msg_contents(routput("<> scones <> appear <> on the trolley.")) + + +class Sconce(Producer, Opener): + """ + A producer that also implements a Push in order to open a door. + """ + def do_pull(self, puller): + """ + Opens a door, and sets a timer to close it. + """ + puller.announce_action(f"$You() $conj(pull) on the {self.name}.") + if self.db.exit: + if self.db.pull_msg: + self.location.msg_contents(self.db.pull_msg) + self.do_open() + delay(15, self.do_close) + delay(16, self.db.room.msg_contents, "The bookshelf slams shut.") diff --git a/typeclasses/exits.py b/typeclasses/exits.py index 466c97a..26d9ae1 100644 --- a/typeclasses/exits.py +++ b/typeclasses/exits.py @@ -79,11 +79,37 @@ class Exit(ObjectParent, DefaultExit): traveler.ndb.currently_moving = t +class Opener(): + """ + A mixin that can open or close an exit. + Done by moving an Exit to/from None and a Room. + """ + def do_open(self, room_obj=None, exit_obj=None): + """ + Move a stored exit into a room. + """ + if not room_obj: + room_obj = self.db.room + if not exit_obj: + exit_obj = self.db.exit + # Do the move: + if exit_obj and room_obj: + exit_obj.location = room_obj + + def do_close(self, exit_obj=None): + """ + Remove an exit. + """ + if not exit_obj: + exit_obj = self.db.exit + # Do the move: + if exit_obj: + exit_obj.location = None + # # set speed - command # - class CmdSetSpeed(Command): """ set your movement speed diff --git a/typeclasses/lightables.py b/typeclasses/lightables.py index 0a36bab..11bc73b 100755 --- a/typeclasses/lightables.py +++ b/typeclasses/lightables.py @@ -59,7 +59,10 @@ class LightSource(Object): self.db.is_giving_light = False try: owner = self.location - owner.announce_action(f"$Your() {self.key} flickers and dies.") + if self.db.desc_end: + owner.announce_action(self.db.desc_end) + else: + owner.announce_action(f"$Your() {self.key} flickers and dies.") self.location.location.check_light_state() except AttributeError: try: @@ -81,8 +84,10 @@ class LightSource(Object): else: owner.announce_action(f"$You() $conj(light) $pron(your) {self.key}.") - # burn for 3 minutes before calling _burnout self.db.is_giving_light = True + if self.db.desc_lit: + self.db.desc = self.db.desc_lit + # if we are in a dark room, trigger its light check try: owner.location.check_light_state() @@ -97,5 +102,34 @@ class LightSource(Object): # start the burn timer. When it runs out, self._burnout # will be called. We store the deferred so it can be # killed in unittesting. - self.deferred = delay(60 * 3, self._burnout) + self.deferred = delay(self.burntime, self._burnout) return True + + +class Torch(LightSource): + """ + A LightSource that lasts longer than the default. + """ + def at_object_creation(self): + """Called when object is first created.""" + super().at_object_creation() + + self.db.is_giving_light = False + self.db.burntime = 60 * 20 # 20 minutes + self.db.desc = "Crafted from twisted branches." + self.db.desc_lit = "Burns with a green flame." + self.db.desc_end = "$Your() torch burns down to the nub and goes out." + + +class Candle(LightSource): + """ + A LightSource that lasts longer than the default. + """ + def at_object_creation(self): + """Called when object is first created.""" + super().at_object_creation() + + self.db.is_giving_light = True + self.db.burntime = 60 * 60 # An hour + self.db.desc = "Tapered and made from shimmering blue wax." + self.db.desc_end = "$Your() candle pops and explodes into a burst of octarine sparks." diff --git a/world/version1.ev b/world/version1.ev index b8cc5ca..93a7382 100644 --- a/world/version1.ev +++ b/world/version1.ev @@ -1314,10 +1314,10 @@ py timed_script = evennia.create_script(key="Create Sticks", -# This one is optional as it defaults to Consumable: +# The torches are special in that they last longer. # [[file:../../../projects/mud.org::*Torches][Torches:6]] -@set bucket/make_class = "typeclasses.lightables.LightSource" +@set bucket/make_class = "typeclasses.lightables.Torch" # Torches:6 ends here @@ -1714,7 +1714,7 @@ Someone has set a nice chair for viewing. # And the bush needs to know the /description/ of the Consumable, so that it can attach that: # [[file:../../../projects/mud.org::*Berry Bush][Berry Bush:8]] -@set bush/make_desc = "Bright red berry with flecks of <>." +@set bush/make_desc = "Bright red with flecks of orange, about grape-sized" # Berry Bush:8 ends here @@ -1722,7 +1722,7 @@ Someone has set a nice chair for viewing. # How many berries are there when you pick them? # [[file:../../../projects/mud.org::*Berry Bush][Berry Bush:9]] -@set bush/make_amount = 10 +@set bush/make_amount = 1 # Berry Bush:9 ends here @@ -1730,7 +1730,7 @@ Someone has set a nice chair for viewing. # How many berries do you eat at a time: # [[file:../../../projects/mud.org::*Berry Bush][Berry Bush:10]] -@set bush/make_eat_amount = 3 +@set bush/make_eat_amount = 1 # Berry Bush:10 ends here @@ -1746,7 +1746,7 @@ Someone has set a nice chair for viewing. # Or many messages that can be randomly selected: # [[file:../../../projects/mud.org::*Berry Bush][Berry Bush:12]] -@set bush/make_eat_msgs = [ "Sweet and slightly tart.", "<>.", "Ooo...that one was sour.", "That was a bit ripe, but still good.", "So sweet with a hint of <>." ] +@set bush/make_eat_msgs = [ "Sweet and slightly tart.", "<>.", "Ooo...quite sour.", "A bit ripe, but still good.", "So sweet with a hint of <>." ] # Berry Bush:12 ends here @@ -1754,7 +1754,8 @@ Someone has set a nice chair for viewing. # Let the user know when they consumed them all. # [[file:../../../projects/mud.org::*Berry Bush][Berry Bush:13]] -@set bush/make_finish_msg = "Those were <>." +@set bush/make_finish_msg = +#"Those were <>." # Berry Bush:13 ends here # Knocker @@ -2385,7 +2386,7 @@ pose gnome/default = smoking his pipe # [[file:../../../projects/mud.org::*Secret Room][Secret Room:1]] -@dig Secret Room;mp10:typeclases.rooms_dark.DarkRoom = dark stairs behind bookcase;stairs,up the stairs;stairs +@dig Secret Room;mp10:typeclasses.rooms_dark.DarkRoom = stairs behind bookcase;stairs,up the stairs;stairs # Secret Room:1 ends here @@ -2396,7 +2397,7 @@ pose gnome/default = smoking his pipe # [[file:../../../projects/mud.org::*Secret Room][Secret Room:2]] @desc stairs = Behind the protruding bookcase, you see a staircase leading down into the darkness. # -@set stairs/traverse_msg = "You carefully creep down the stairs behind the bookcase, lit by the candle in its holder. You hear the bookcase shut, leaving you in darkness..." +@set stairs/traverse_msg = "You carefully creep down the stairs behind the bookcase, lit by the candle in its holder. You hear the bookcase shut behind you." # Secret Room:2 ends here # Sconce @@ -2404,52 +2405,79 @@ pose gnome/default = smoking his pipe # [[file:../../../projects/mud.org::*Sconce][Sconce:1]] -@create/drop sconce;candle holder: typeclasses.consumables.Producer +@create/drop sconce;candle holder: typeclasses.consumables.Sconce # Sconce:1 ends here # [[file:../../../projects/mud.org::*Sconce][Sconce:2]] @desc sconce = A black iron sconce holding a single lit candle. On closer examination, the bottom of this fixture appears to have a hinge? # Sconce:2 ends here + + +# Connect the exit: + + # [[file:../../../projects/mud.org::*Sconce][Sconce:3]] -@set sconce/make_name = "candle" +@set sconce/exit = $search(stairs behind bookcase) +# +@set sconce/room = $search(Cozy House) # Sconce:3 ends here +# Hide it a bit? + + +# [[file:../../../projects/mud.org::*Sconce][Sconce:4]] +@set sconce/hidden_tag = "hidden_sconce" +# +@lock sconce = view:tag(hidden_sconce) +# Sconce:4 ends here + + + +# We can =get= an endless supply of candles here: + + +# [[file:../../../projects/mud.org::*Sconce][Sconce:5]] +@set sconce/make_name = "candle" +# Sconce:5 ends here + + + # And a verb when they /get/ the consumable: -# [[file:../../../projects/mud.org::*Sconce][Sconce:4]] +# [[file:../../../projects/mud.org::*Sconce][Sconce:6]] @set sconce/make_verb = "$conj(take) the" # -@set sconce/make_note = ", but another appears in its place" -# Sconce:4 ends here +@set sconce/make_note = ", but another magically appears in its place" +# Sconce:6 ends here # This one is optional as it defaults to Consumable: -# [[file:../../../projects/mud.org::*Sconce][Sconce:5]] -@set sconce/make_class = "typeclasses.lightables.LightSource" -# Sconce:5 ends here +# [[file:../../../projects/mud.org::*Sconce][Sconce:7]] +@set sconce/make_class = "typeclasses.lightables.Candle" +# Sconce:7 ends here # And the sconce needs to know the /description/ of the Consumable, so that it can attach that: -# [[file:../../../projects/mud.org::*Sconce][Sconce:6]] -@set sconce/make_desc = "Curious." -# Sconce:6 ends here +# [[file:../../../projects/mud.org::*Sconce][Sconce:8]] +@set sconce/make_desc = "Curiously shaped taper with scales like a snake." +# Sconce:8 ends here # How much is there when you pick them? -# [[file:../../../projects/mud.org::*Sconce][Sconce:7]] +# [[file:../../../projects/mud.org::*Sconce][Sconce:9]] @set sconce/make_amount = 1 -# Sconce:7 ends here +# Sconce:9 ends here # Pulling Sconce # Temporarily move the exit into the room. @@ -2458,7 +2486,7 @@ pose gnome/default = smoking his pipe # [[file:../../../projects/mud.org::*Pulling Sconce][Pulling Sconce:1]] -@teleport/tonone stairs +@set sconce/pull_msg = "You hear a click, and the bookcase next to the candle swings forward revealing a secret passage." # Pulling Sconce:1 ends here # Inside the Secret Room @@ -2472,39 +2500,50 @@ pose gnome/default = smoking his pipe -# And details to make this room feel intentional as well. +# Add aliases that make sense: # [[file:../../../projects/mud.org::*Inside the Secret Room][Inside the Secret Room:2]] -@detail table = Made from a black wood. Dusty on the edges. +@alias up the stairs = up +# +@set stairs/traverse_msg = "You climb the stone stairs back to the cozy room." # Inside the Secret Room:2 ends here +# And details to make this room feel intentional as well. + + +# [[file:../../../projects/mud.org::*Inside the Secret Room][Inside the Secret Room:3]] +@detail table = Made from a black wood. Dusty on the edges. +# Inside the Secret Room:3 ends here + + + # Are the equipment stuff we could =use=? -# [[file:../../../projects/mud.org::*Inside the Secret Room][Inside the Secret Room:3]] +# [[file:../../../projects/mud.org::*Inside the Secret Room][Inside the Secret Room:4]] @detail equipment = pipes, beakers, tubes ... -# Inside the Secret Room:3 ends here +# Inside the Secret Room:4 ends here # Should the jars be objects that could be picked up? -# [[file:../../../projects/mud.org::*Inside the Secret Room][Inside the Secret Room:4]] +# [[file:../../../projects/mud.org::*Inside the Secret Room][Inside the Secret Room:5]] @detail jars = Hrm. Newt eyes, bat wings... interesting contents. -# Inside the Secret Room:4 ends here +# Inside the Secret Room:5 ends here # Bottles same as jars? -# [[file:../../../projects/mud.org::*Inside the Secret Room][Inside the Secret Room:5]] +# [[file:../../../projects/mud.org::*Inside the Secret Room][Inside the Secret Room:6]] @detail bottles = Four bottles contain clear liquids and are labeled: DA, KI, ON, and SU -# Inside the Secret Room:5 ends here +# Inside the Secret Room:6 ends here # Stool # A stool to sit while working