""" Exits Exits are connectors between Rooms. An exit always has a destination property set and has a single command defined on itself with the same name as its key, for allowing Characters to traverse the exit to its destination. """ import random from evennia import DefaultExit from utils.utils import has_effect class Exit(DefaultExit): """ Exits are connectors between rooms. Exits are normal Objects except they defines the `destination` property. It also does work in the following methods: basetype_setup() - sets default exit locks (to change, use `at_object_creation` instead). at_cmdset_get(**kwargs) - this is called when the cmdset is accessed and should rebuild the Exit cmdset along with a command matching the name of the Exit object. Conventionally, a kwarg `force_init` should force a rebuild of the cmdset, this is triggered by the `@alias` command when aliases are changed. at_failed_traverse() - gives a default error message ("You cannot go there") if exit traversal fails and an attribute `err_traverse` is not defined. Relevant hooks to overload (compared to other types of Objects): at_traverse(traveller, target_loc) - called to do the actual traversal and calling of the other hooks. If overloading this, consider using super() to use the default movement implementation (and hook-calling). at_after_traverse(traveller, source_loc) - called by at_traverse just after traversing. at_failed_traverse(traveller) - called by at_traverse if traversal failed for some reason. Will not be called if the attribute `err_traverse` is defined, in which case that will simply be echoed. """ def at_traverse(self, traversing_object, target_location, **kwargs): if has_effect(traversing_object, "is_busy"): traversing_object.msg("You are already busy {}.".format(traversing_object.db.current_action.busy_msg())) else: super().at_traverse(traversing_object, target_location, **kwargs) def delete(self): if self.location and self.location.db.zone: self.location.db.zone.remove_room_exit(self) return super().delete() """ BaseDoor Contribution - Griatch 2016 A simple two-way exit that represents a door that can be opened and closed. Can easily be expanded from to make it lockable, destroyable etc. To try it out, `@dig` a new room and then use the (overloaded) `@open` command to open a new doorway to it like this: @open doorway:contrib.simpledoor.SimpleDoor = otherroom You can then use `open doorway' and `close doorway` to change the open state. If you are not superuser (`@quell` yourself) you'll find you cannot pass through either side of the door once it's closed from the other side. """ class BaseDoor(Exit): """ A two-way exit "door" with some methods for affecting both "sides" of the door at the same time. For example, set a lock on either of the two sides using `exitname.setlock("traverse:false())` """ DARK_MESSAGES = ( "It is pitch black. You are likely to be eaten by a grue.", "It's pitch black. You fumble around but cannot find anything.", "You don't see a thing. You feel around, managing to bump your fingers hard against something. Ouch!", "You don't see a thing! Blindly grasping the air around you, you find nothing.", "It's totally dark here. You almost stumble over some un-evenness in the ground.", "You are completely blind. For a moment you think you hear someone breathing nearby ... " "\n ... surely you must be mistaken.", "Blind, you think you find some sort of object on the ground, but it turns out to be just a stone.", "Blind, you bump into a wall. The wall seems to be covered with some sort of vegetation," " but its too damp to burn.", "You can't see anything, but the air is damp. It feels like you are far underground.", ) def at_object_creation(self): """ Called the very first time the door is created. """ self.db.dark_desc = "" self.db.return_exit = None def setlock(self, lockstring): """ Sets identical locks on both sides of the door. Args: lockstring (str): A lockstring, like `"traverse:true()"`. """ self.locks.add(lockstring) self.db.return_exit.locks.add(lockstring) def setdesc(self, description): """ Sets identical descs on both sides of the door. Args: setdesc (str): A description. """ self.db.desc = description self.db.return_exit.db.desc = description def delete(self): """ Deletes both sides of the door. """ # we have to be careful to avoid a delete-loop. if self.db.return_exit: super().delete() super().delete() return True def at_failed_traverse(self, traversing_object): """ Called when door traverse: lock fails. Args: traversing_object (Typeclassed entity): The object attempting the traversal. """ traversing_object.msg("%s is closed." % self.key) def return_appearance(self, looker, **kwargs): """ This formats a description. It is the hook a 'look' command should call. Args: looker (Object): Object doing the looking. **kwargs (dict): Arbitrary, optional arguments for users overriding the call (unused by default). """ if not looker: return "" string = "{}\n".format(self.get_display_name(looker)) string += "-" * 100 string += "|/" if not self.db.is_lit and not looker.is_superuser: desc = self.db.dark_desc if self.db.dark_desc else random.choice(self.DARK_MESSAGES) else: desc = self.db.desc if desc: string += "{}".format(desc) return string