#!/usr/bin/env python from evennia.utils import delay from typeclasses.objects import Object # ------------------------------------------------------------- # LightSource # # This object emits light. Once it has been turned on it # cannot be turned off. When it burns out it will delete # itself. # # This could be implemented using a single-repeat Script or by # registering with the TickerHandler. We do it simpler by # using the delay() utility function. This is very simple # to use but does not survive a server @reload. Because of # where the light matters (in the Dark Room where you can # find new light sources easily), this is okay here. # ------------------------------------------------------------- class LightSource(Object): """ This implements a light source object. When burned out, the object will be deleted. """ def at_init(self): """ If this is called with the Attribute is_giving_light already set, we know that the timer got killed by a server reload/reboot before it had time to finish. So we kill it here instead. This is the price we pay for the simplicity of the non-persistent delay() method. """ if self.db.is_giving_light: self.delete() 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 * 3 # 3 minutes # this is the default desc, it can of course be customized # when created. self.db.desc = "A resin-covered splinter of wood." # add the Light command # self.cmdset.add_default(CmdSetLight, persistent=True) def _burnout(self): """ This is called when this light source burns out. We make no use of the return value. """ # delete ourselves from the database self.db.is_giving_light = False try: owner = self.location 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: self.location.msg_contents(f"A {self.key} on the floor flickers and dies.") self.location.location.check_light_state() except AttributeError: # Mainly happens if we happen to be in a None location pass self.delete() def do_light(self, owner): """ Light this object - this is called by Light command. """ if self.db.is_giving_light: owner.msg(f"The {self.key} is already lit.") return False owner.announce_action(f"$You() $conj(light) $pron(your) {self.key}.") self.db.is_giving_light = True if self.db.desc_lit: self.db.desc = self.db.desc_lit if owner.location.db.desc_lit: owner.location.msg_contents(owner.location.db.desc_lit) # if we are in a dark room, trigger its light check try: owner.location.check_light_state() except AttributeError: try: # maybe we are directly in the room owner.check_light_state() except AttributeError: # we are in a None location pass finally: # 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(self.db.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."