dkmud/typeclasses/exits.py
Francesco Cappelli 043cdfc230 commit iniziale.
2022-01-10 14:42:13 +01:00

171 lines
6.2 KiB
Python

"""
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