Updated the tutorial world's rooms.
This commit is contained in:
parent
a77d56c7e1
commit
0029232ab0
1 changed files with 332 additions and 261 deletions
|
|
@ -2,12 +2,18 @@
|
||||||
|
|
||||||
Room Typeclasses for the TutorialWorld.
|
Room Typeclasses for the TutorialWorld.
|
||||||
|
|
||||||
|
This defines special types of Rooms available in the tutorial. To keep
|
||||||
|
everything in one place we define them together with custom commands
|
||||||
|
to control them, those commands could also have been in a separate
|
||||||
|
module (e.g. if they could have been re-used elsewhere.)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import random
|
import random
|
||||||
from evennia import CmdSet, DefaultScript, Command, DefaultRoom
|
from evennia import TICKER_HANDLER
|
||||||
|
from evennia import CmdSet, Command, DefaultRoom
|
||||||
from evennia import utils, create_object, search_object
|
from evennia import utils, create_object, search_object
|
||||||
from evennia.contrib.tutorial_world import scripts as tut_scripts
|
from evennia import syscmdkeys, default_cmds
|
||||||
from evennia.contrib.tutorial_world.objects import LightSource, TutorialObject
|
from evennia.contrib.tutorial_world.objects import LightSource, TutorialObject
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -21,6 +27,10 @@ from evennia.contrib.tutorial_world.objects import LightSource, TutorialObject
|
||||||
#
|
#
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
|
|
||||||
|
#
|
||||||
|
# Special command avaiable in all tutorial rooms
|
||||||
|
#
|
||||||
|
|
||||||
class CmdTutorial(Command):
|
class CmdTutorial(Command):
|
||||||
"""
|
"""
|
||||||
Get help during the tutorial
|
Get help during the tutorial
|
||||||
|
|
@ -39,7 +49,7 @@ class CmdTutorial(Command):
|
||||||
|
|
||||||
def func(self):
|
def func(self):
|
||||||
"""
|
"""
|
||||||
All we do is to scan the current location for an attribute
|
All we do is to scan the current location for an Attribute
|
||||||
called `tutorial_info` and display that.
|
called `tutorial_info` and display that.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -59,7 +69,9 @@ class CmdTutorial(Command):
|
||||||
|
|
||||||
|
|
||||||
class TutorialRoomCmdSet(CmdSet):
|
class TutorialRoomCmdSet(CmdSet):
|
||||||
"Implements the simple tutorial cmdset"
|
"""
|
||||||
|
Implements the simple tutorial cmdset
|
||||||
|
"""
|
||||||
key = "tutorial_cmdset"
|
key = "tutorial_cmdset"
|
||||||
|
|
||||||
def at_cmdset_creation(self):
|
def at_cmdset_creation(self):
|
||||||
|
|
@ -84,35 +96,12 @@ class TutorialRoom(DefaultRoom):
|
||||||
|
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# Weather room - scripted room
|
# Weather room - room with a ticker
|
||||||
#
|
|
||||||
# The weather room is called by a script at
|
|
||||||
# irregular intervals. The script is generally useful
|
|
||||||
# and so is split out into tutorialworld.scripts.
|
|
||||||
#
|
#
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
|
|
||||||
class WeatherRoom(TutorialRoom):
|
# These are rainy weather strings
|
||||||
"""
|
WEATHER_STRINGS = (
|
||||||
This should probably better be called a rainy room...
|
|
||||||
|
|
||||||
This sets up an outdoor room typeclass. At irregular intervals,
|
|
||||||
the effects of weather will show in the room. Outdoor rooms should
|
|
||||||
inherit from this.
|
|
||||||
|
|
||||||
"""
|
|
||||||
def at_object_creation(self):
|
|
||||||
"Called when object is first created."
|
|
||||||
super(WeatherRoom, self).at_object_creation()
|
|
||||||
|
|
||||||
# we use the imported IrregularEvent script
|
|
||||||
self.scripts.add(tut_scripts.IrregularEvent)
|
|
||||||
self.db.tutorial_info = \
|
|
||||||
"This room has a Script running that has it echo a weather-related message at irregular intervals."
|
|
||||||
|
|
||||||
def update_irregular(self):
|
|
||||||
"create a tuple of possible texts to return."
|
|
||||||
strings = (
|
|
||||||
"The rain coming down from the iron-grey sky intensifies.",
|
"The rain coming down from the iron-grey sky intensifies.",
|
||||||
"A gush of wind throws the rain right in your face. Despite your cloak you shiver.",
|
"A gush of wind throws the rain right in your face. Despite your cloak you shiver.",
|
||||||
"The rainfall eases a bit and the sky momentarily brightens.",
|
"The rainfall eases a bit and the sky momentarily brightens.",
|
||||||
|
|
@ -125,24 +114,71 @@ class WeatherRoom(TutorialRoom):
|
||||||
"You hear the distant howl of what sounds like some sort of dog or wolf.",
|
"You hear the distant howl of what sounds like some sort of dog or wolf.",
|
||||||
"Large clouds rush across the sky, throwing their load of rain over the world.")
|
"Large clouds rush across the sky, throwing their load of rain over the world.")
|
||||||
|
|
||||||
# get a random value so we can select one of the strings above.
|
class WeatherRoom(TutorialRoom):
|
||||||
# Send this to the room.
|
"""
|
||||||
irand = random.randint(0, 15)
|
This should probably better be called a rainy room...
|
||||||
if irand > 10:
|
|
||||||
return # don't return anything, to add more randomness
|
This sets up an outdoor room typeclass. At irregular intervals,
|
||||||
self.msg_contents("{w%s{n" % strings[irand])
|
the effects of weather will show in the room. Outdoor rooms should
|
||||||
|
inherit from this.
|
||||||
|
|
||||||
|
"""
|
||||||
|
def at_object_creation(self):
|
||||||
|
"""
|
||||||
|
Called when object is first created.
|
||||||
|
We set up a ticker to update this room regularly.
|
||||||
|
|
||||||
|
Note that we could in principle also use a Script to manage
|
||||||
|
the ticking of the room, the TickerHandler is works fine for
|
||||||
|
simple things like this though.
|
||||||
|
"""
|
||||||
|
super(WeatherRoom, self).at_object_creation()
|
||||||
|
# subscribe ourselves to a ticker to repeatedly call the hook
|
||||||
|
# "update_weather" on this object. The interval is randomized
|
||||||
|
# so as to not have all weather rooms update at the same time.
|
||||||
|
interval = random.randint(50, 70)
|
||||||
|
TICKER_HANDLER.add(self, interval, idstring="tutorial", hook_key="update_weather")
|
||||||
|
# this is parsed by the 'tutorial' command on TutorialRooms.
|
||||||
|
self.db.tutorial_info = \
|
||||||
|
"This room has a Script running that has it echo a weather-related message at irregular intervals."
|
||||||
|
|
||||||
|
def update_weather(self):
|
||||||
|
"""
|
||||||
|
Called by the tickerhandler at regular intervals. Even so, we
|
||||||
|
only update 20% of the time, picking a random weather message
|
||||||
|
when we do.
|
||||||
|
"""
|
||||||
|
if random.random() < 0.2:
|
||||||
|
# only update 20 % of the time
|
||||||
|
self.msg_contents("{w%s{n" % random.choice(WEATHER_STRINGS))
|
||||||
|
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# Dark Room - a scripted room
|
# Dark Room - a scripted room
|
||||||
#
|
#
|
||||||
# This room limits the movemenets of its denizens unless they carry a and active
|
# This room limits the movemenets of its denizens unless they carry an active
|
||||||
# LightSource object (LightSource is defined in
|
# LightSource object (LightSource is defined in
|
||||||
# tutorialworld.objects.LightSource)
|
# tutorialworld.objects.LightSource)
|
||||||
#
|
#
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
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.")
|
||||||
|
|
||||||
|
ALREADY_LIGHTSOURCE = "You don't want to stumble around in blindness anymore. You already " \
|
||||||
|
"found what you need. Let's get light already!"
|
||||||
|
|
||||||
|
FOUND_LIGHTSOURCE = "Your fingers bump against a splinter of wood in a corner. It smells of resin and seems dry enough to burn! " \
|
||||||
|
"You pick it up, holding it firmly. Now you just need to {wlight{n it using the flint and steel you carry with you."
|
||||||
|
|
||||||
class CmdLookDark(Command):
|
class CmdLookDark(Command):
|
||||||
"""
|
"""
|
||||||
Look around in darkness
|
Look around in darkness
|
||||||
|
|
@ -150,48 +186,35 @@ class CmdLookDark(Command):
|
||||||
Usage:
|
Usage:
|
||||||
look
|
look
|
||||||
|
|
||||||
Looks in darkness
|
Look around in the darkness, trying
|
||||||
|
to find something.
|
||||||
"""
|
"""
|
||||||
key = "look"
|
key = "look"
|
||||||
aliases = ["l", 'feel', 'feel around', 'fiddle']
|
aliases = ["l", 'feel', 'search', 'feel around', 'fiddle']
|
||||||
locks = "cmd:all()"
|
locks = "cmd:all()"
|
||||||
help_category = "TutorialWorld"
|
help_category = "TutorialWorld"
|
||||||
|
|
||||||
def func(self):
|
def func(self):
|
||||||
"Implement the command."
|
"""
|
||||||
|
Implement the command.
|
||||||
|
|
||||||
|
This works both as a look and a search command; there is a
|
||||||
|
random chance of eventually finding a light source.
|
||||||
|
"""
|
||||||
caller = self.caller
|
caller = self.caller
|
||||||
# we don't have light, grasp around blindly.
|
|
||||||
messages = ("It's pitch black. You fumble around but cannot find anything.",
|
if random.random() < 0.8:
|
||||||
"You don't see a thing. You feel around, managing to bump your fingers hard against something. Ouch!",
|
# we don't find anything
|
||||||
"You don't see a thing! Blindly grasping the air around you, you find nothing.",
|
caller.msg(random.choice(DARK_MESSAGES))
|
||||||
"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.")
|
|
||||||
irand = random.randint(0, 10)
|
|
||||||
if irand < len(messages):
|
|
||||||
caller.msg(messages[irand])
|
|
||||||
else:
|
else:
|
||||||
# check so we don't already carry a lightsource.
|
# we could have found something!
|
||||||
carried_lights = [obj for obj in caller.contents
|
if any(obj for obj in caller.contents if utils.inherits_from(obj, LightSource)):
|
||||||
if utils.inherits_from(obj, LightSource)]
|
# we already carry a LightSource object.
|
||||||
if carried_lights:
|
caller.msg(ALREADY_LIGHTSOURCE)
|
||||||
string = "You don't want to stumble around in blindness anymore. You already found what you need. Let's get light already!"
|
|
||||||
caller.msg(string)
|
|
||||||
return
|
|
||||||
#if we are lucky, we find the light source.
|
|
||||||
lightsources = [obj for obj in self.obj.contents
|
|
||||||
if utils.inherits_from(obj, LightSource)]
|
|
||||||
if lightsources:
|
|
||||||
lightsource = lightsources[0]
|
|
||||||
else:
|
else:
|
||||||
# create the light source from scratch.
|
# don't have a light source, create a new one.
|
||||||
lightsource = create_object(LightSource, key="splinter")
|
create_object(LightSource, key="splinter", location=caller)
|
||||||
lightsource.location = caller
|
caller.msg(FOUND_LIGHTSOURCE)
|
||||||
string = "Your fingers bump against a splinter of wood in a corner. It smells of resin and seems dry enough to burn!"
|
|
||||||
string += "\nYou pick it up, holding it firmly. Now you just need to {wlight{n it using the flint and steel you carry with you."
|
|
||||||
caller.msg(string)
|
|
||||||
|
|
||||||
|
|
||||||
class CmdDarkHelp(Command):
|
class CmdDarkHelp(Command):
|
||||||
|
|
@ -203,20 +226,23 @@ class CmdDarkHelp(Command):
|
||||||
help_category = "TutorialWorld"
|
help_category = "TutorialWorld"
|
||||||
|
|
||||||
def func(self):
|
def func(self):
|
||||||
"Implements the help command."
|
"""
|
||||||
string = "Can't help you until you find some light! Try feeling around for something to burn."
|
Replace the the help command with a not-so-useful help
|
||||||
string += " You cannot give up even if you don't find anything right away."
|
"""
|
||||||
|
string = "Can't help you until you find some light! Try looking/feeling around for something to burn. " \
|
||||||
|
"You shouldn't give up even if you don't find anything right away."
|
||||||
self.caller.msg(string)
|
self.caller.msg(string)
|
||||||
|
|
||||||
# the nomatch system command will give a suitable error when we cannot find
|
|
||||||
# the normal commands.
|
|
||||||
from evennia.commands.default.syscommands import CMD_NOMATCH
|
|
||||||
from evennia.commands.default.general import CmdSay
|
|
||||||
|
|
||||||
|
|
||||||
class CmdDarkNoMatch(Command):
|
class CmdDarkNoMatch(Command):
|
||||||
"This is called when there is no match"
|
"""
|
||||||
key = CMD_NOMATCH
|
This is a system command. Commands with special keys are used to
|
||||||
|
override special sitations in the game. The CMD_NOMATCH is used
|
||||||
|
when the given command is not found in the current command set (it
|
||||||
|
replaces Evennia's default behavior or offering command
|
||||||
|
suggestions)
|
||||||
|
"""
|
||||||
|
key = syscmdkeys.CMD_NOMATCH
|
||||||
locks = "cmd:all()"
|
locks = "cmd:all()"
|
||||||
|
|
||||||
def func(self):
|
def func(self):
|
||||||
|
|
@ -225,79 +251,25 @@ class CmdDarkNoMatch(Command):
|
||||||
|
|
||||||
|
|
||||||
class DarkCmdSet(CmdSet):
|
class DarkCmdSet(CmdSet):
|
||||||
"Groups the commands."
|
"""
|
||||||
|
Groups the commands of the dark room together. We also import the
|
||||||
|
default say command here so that players can still talk in the
|
||||||
|
darkness.
|
||||||
|
|
||||||
|
We give the cmdset the mergetype "Replace" to make sure it
|
||||||
|
completely replaces whichever command set it is merged onto
|
||||||
|
(usually the default cmdset)
|
||||||
|
"""
|
||||||
key = "darkroom_cmdset"
|
key = "darkroom_cmdset"
|
||||||
mergetype = "Replace" # completely remove all other commands
|
mergetype = "Replace"
|
||||||
|
|
||||||
def at_cmdset_creation(self):
|
def at_cmdset_creation(self):
|
||||||
"populates the cmdset."
|
"populate the cmdset."
|
||||||
self.add(CmdTutorial())
|
self.add(CmdTutorial())
|
||||||
self.add(CmdLookDark())
|
self.add(CmdLookDark())
|
||||||
self.add(CmdDarkHelp())
|
self.add(CmdDarkHelp())
|
||||||
self.add(CmdDarkNoMatch())
|
self.add(CmdDarkNoMatch())
|
||||||
self.add(CmdSay)
|
self.add(default_cmds.CmdSay)
|
||||||
|
|
||||||
#
|
|
||||||
# Darkness room two-state system
|
|
||||||
#
|
|
||||||
|
|
||||||
class DarkState(DefaultScript):
|
|
||||||
"""
|
|
||||||
The darkness state is a script that keeps tabs on when
|
|
||||||
a player in the room carries an active light source. It places
|
|
||||||
a new, very restrictive cmdset (DarkCmdSet) on all the players
|
|
||||||
in the room whenever there is no light in it. Upon turning on
|
|
||||||
a light, the state switches off and moves to LightState.
|
|
||||||
"""
|
|
||||||
def at_script_creation(self):
|
|
||||||
"This setups the script"
|
|
||||||
self.key = "tutorial_darkness_state"
|
|
||||||
self.desc = "A dark room"
|
|
||||||
self.persistent = True
|
|
||||||
|
|
||||||
def at_start(self):
|
|
||||||
"called when the script is first starting up."
|
|
||||||
for char in [char for char in self.obj.contents if char.has_player]:
|
|
||||||
if char.is_superuser:
|
|
||||||
char.msg("You are Superuser, so you are not affected by the dark state.")
|
|
||||||
else:
|
|
||||||
char.cmdset.add(DarkCmdSet)
|
|
||||||
char.msg("The room is pitch dark! You are likely to be eaten by a Grue.")
|
|
||||||
|
|
||||||
def is_valid(self):
|
|
||||||
"is valid only as long as noone in the room has lit the lantern."
|
|
||||||
return not self.obj.is_lit()
|
|
||||||
|
|
||||||
def at_stop(self):
|
|
||||||
"Someone turned on a light. This state dies. Switch to LightState."
|
|
||||||
for char in [char for char in self.obj.contents if char.has_player]:
|
|
||||||
char.cmdset.delete(DarkCmdSet)
|
|
||||||
self.obj.db.is_dark = False
|
|
||||||
self.obj.scripts.add(LightState)
|
|
||||||
|
|
||||||
|
|
||||||
class LightState(DefaultScript):
|
|
||||||
"""
|
|
||||||
This is the counterpart to the Darkness state. It is active when the
|
|
||||||
lantern is on.
|
|
||||||
"""
|
|
||||||
def at_script_creation(self):
|
|
||||||
"Called when script is first created."
|
|
||||||
self.key = "tutorial_light_state"
|
|
||||||
self.desc = "A room lit up"
|
|
||||||
self.persistent = True
|
|
||||||
|
|
||||||
def is_valid(self):
|
|
||||||
"""
|
|
||||||
This state is only valid as long as there is an active light
|
|
||||||
source in the room.
|
|
||||||
"""
|
|
||||||
return self.obj.is_lit()
|
|
||||||
|
|
||||||
def at_stop(self):
|
|
||||||
"Light disappears. This state dies. Return to DarknessState."
|
|
||||||
self.obj.db.is_dark = True
|
|
||||||
self.obj.scripts.add(DarkState)
|
|
||||||
|
|
||||||
|
|
||||||
class DarkRoom(TutorialRoom):
|
class DarkRoom(TutorialRoom):
|
||||||
|
|
@ -305,52 +277,86 @@ class DarkRoom(TutorialRoom):
|
||||||
A dark room. This tries to start the DarkState script on all
|
A dark room. This tries to start the DarkState script on all
|
||||||
objects entering. The script is responsible for making sure it is
|
objects entering. The script is responsible for making sure it is
|
||||||
valid (that is, that there is no light source shining in the room).
|
valid (that is, that there is no light source shining in the room).
|
||||||
"""
|
|
||||||
def is_lit(self):
|
|
||||||
"""
|
|
||||||
Helper method to check if the room is lit up. It checks all
|
|
||||||
characters in room to see if they carry an active object of
|
|
||||||
type LightSource.
|
|
||||||
"""
|
|
||||||
return any([any([True for obj in char.contents
|
|
||||||
if utils.inherits_from(obj, LightSource) and obj.db.is_active])
|
|
||||||
for char in self.contents if char.has_player])
|
|
||||||
|
|
||||||
|
The is_lit Attribute is used to define if the room is currently lit
|
||||||
|
or not, so as to properly echo state changes.
|
||||||
|
|
||||||
|
Since this room (in the tutorial) is meant as a sort of catch-all,
|
||||||
|
we also make sure to heal characters ending up here, since they
|
||||||
|
may have been beaten up by the ghostly apparition at this point.
|
||||||
|
|
||||||
|
"""
|
||||||
def at_object_creation(self):
|
def at_object_creation(self):
|
||||||
"Called when object is first created."
|
"""
|
||||||
|
Called when object is first created.
|
||||||
|
"""
|
||||||
super(DarkRoom, self).at_object_creation()
|
super(DarkRoom, self).at_object_creation()
|
||||||
self.db.tutorial_info = "This is a room with custom command sets on itself."
|
self.db.tutorial_info = "This is a room with custom command sets on itself."
|
||||||
# this variable is set by the scripts. It makes for an easy flag to
|
|
||||||
# look for by other game elements (such as the crumbling wall in
|
|
||||||
# the tutorial)
|
|
||||||
self.db.is_dark = True
|
|
||||||
# the room starts dark.
|
# the room starts dark.
|
||||||
self.scripts.add(DarkState)
|
self.db.is_lit = False
|
||||||
|
|
||||||
def at_object_receive(self, character, source_location):
|
def _carries_light(self, obj):
|
||||||
"""
|
"""
|
||||||
Called when an object enters the room. We crank the wheels to make
|
Checks if the given object carries anything that gives light.
|
||||||
sure scripts are synced.
|
|
||||||
|
Note that we do NOT look for a specific LightSource typeclass,
|
||||||
|
but for the Attribute is_giving_light - this makes it easy to
|
||||||
|
later add other types of light-giving items.
|
||||||
"""
|
"""
|
||||||
if character.has_player:
|
return any(obj for obj in obj.contents if obj.db.is_giving_light)
|
||||||
if not self.is_lit() and not character.is_superuser:
|
|
||||||
character.cmdset.add(DarkCmdSet)
|
def _heal(self, character):
|
||||||
if character.db.health and character.db.health <= 0:
|
"""
|
||||||
# heal character coming here from being defeated by mob.
|
Heal a character.
|
||||||
health = character.db.health_max
|
"""
|
||||||
if not health:
|
health = character.db.health_max or 20
|
||||||
health = 20
|
|
||||||
character.db.health = health
|
character.db.health = health
|
||||||
self.scripts.validate()
|
|
||||||
|
|
||||||
def at_object_leave(self, character, target_location):
|
def check_light_state(self):
|
||||||
"""
|
"""
|
||||||
In case people leave with the light, we make sure to update the
|
This method checks if there are any light sources in the room.
|
||||||
states accordingly.
|
If there isn't it makes sure to add the dark cmdset to all
|
||||||
|
characters in the room. It is called whenever characters enter
|
||||||
|
the room and also by the Light sources when they turn on.
|
||||||
"""
|
"""
|
||||||
character.cmdset.delete(DarkCmdSet) # in case we are teleported away
|
if any(self._carries_light(obj) for obj in self.contents):
|
||||||
self.scripts.validate()
|
# people are carrying lights
|
||||||
|
if not self.db.is_lit:
|
||||||
|
self.db.is_lit = True
|
||||||
|
for char in (obj for obj in self.contents if obj.has_player):
|
||||||
|
# this won't do anything if it is already removed
|
||||||
|
char.cmdset.delete(DarkCmdSet)
|
||||||
|
char.msg("The room is lit up.")
|
||||||
|
else:
|
||||||
|
# noone is carrying light - darken the room
|
||||||
|
for char in (obj for obj in self.contents if obj.has_player):
|
||||||
|
if self.db.is_lit:
|
||||||
|
self.db.is_lit = False
|
||||||
|
if char.is_superuser:
|
||||||
|
char.msg("You are Superuser, so you are not affected by the dark state.")
|
||||||
|
else:
|
||||||
|
# put players in darkness
|
||||||
|
char.cmdset.add(DarkCmdSet)
|
||||||
|
char.msg("The room is completely dark.")
|
||||||
|
|
||||||
|
def at_object_receive(self, obj, source_location):
|
||||||
|
"""
|
||||||
|
Called when an object enters the room.
|
||||||
|
"""
|
||||||
|
if obj.has_player:
|
||||||
|
# a puppeted object, that is, a Character
|
||||||
|
self._heal(obj)
|
||||||
|
# in case the new guy carries light with them
|
||||||
|
self.check_light_state()
|
||||||
|
|
||||||
|
def at_object_leave(self, obj, target_location):
|
||||||
|
"""
|
||||||
|
In case people leave with the light, we make sure to clear the
|
||||||
|
DarkCmdSet if necessary. This also works if they are
|
||||||
|
teleported away.
|
||||||
|
"""
|
||||||
|
obj.cmdset.delete(DarkCmdSet)
|
||||||
|
self.check_light_state()
|
||||||
|
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
#
|
#
|
||||||
|
|
@ -413,10 +419,11 @@ class TeleportRoom(TutorialRoom):
|
||||||
# superusers don't get teleported
|
# superusers don't get teleported
|
||||||
character.msg("Superuser block: You would have been teleported to %s." % results[0])
|
character.msg("Superuser block: You would have been teleported to %s." % results[0])
|
||||||
return
|
return
|
||||||
# teleport
|
# the teleporter room's desc should give the 'teleporting message'.
|
||||||
character.execute_cmd("look")
|
character.execute_cmd("look")
|
||||||
character.location = results[0] # stealth move
|
# teleport quietly to the new place
|
||||||
character.location.at_object_receive(character, self)
|
character.move_to(results[0], quiet=True)
|
||||||
|
|
||||||
|
|
||||||
#------------------------------------------------------------
|
#------------------------------------------------------------
|
||||||
#
|
#
|
||||||
|
|
@ -437,7 +444,19 @@ class TeleportRoom(TutorialRoom):
|
||||||
|
|
||||||
class CmdEast(Command):
|
class CmdEast(Command):
|
||||||
"""
|
"""
|
||||||
Try to cross the bridge eastwards.
|
Go eastwards across the bridge.
|
||||||
|
|
||||||
|
Tutorial info:
|
||||||
|
This command relies on the caller having two Attributes
|
||||||
|
(assigned by the room when entering):
|
||||||
|
- east_exit: a unique name or dbref to the room to go to
|
||||||
|
when exiting east.
|
||||||
|
- west_exit: a unique name or dbref to the room to go to
|
||||||
|
when exiting west.
|
||||||
|
The room must also have the following property:
|
||||||
|
- tutorial_bridge_posistion: the current position on
|
||||||
|
on the bridge, 0 - 4.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
key = "east"
|
key = "east"
|
||||||
aliases = ["e"]
|
aliases = ["e"]
|
||||||
|
|
@ -445,7 +464,7 @@ class CmdEast(Command):
|
||||||
help_category = "TutorialWorld"
|
help_category = "TutorialWorld"
|
||||||
|
|
||||||
def func(self):
|
def func(self):
|
||||||
"move forward"
|
"move one step eastwards"
|
||||||
caller = self.caller
|
caller = self.caller
|
||||||
|
|
||||||
bridge_step = min(5, caller.db.tutorial_bridge_position + 1)
|
bridge_step = min(5, caller.db.tutorial_bridge_position + 1)
|
||||||
|
|
@ -460,6 +479,8 @@ class CmdEast(Command):
|
||||||
caller.msg("No east exit was found for this room. Contact an admin.")
|
caller.msg("No east exit was found for this room. Contact an admin.")
|
||||||
return
|
return
|
||||||
caller.db.tutorial_bridge_position = bridge_step
|
caller.db.tutorial_bridge_position = bridge_step
|
||||||
|
# since we are really in one room, we have to notify others
|
||||||
|
# in the room when we move.
|
||||||
caller.location.msg_contents("%s steps eastwards across the bridge." % caller.name, exclude=caller)
|
caller.location.msg_contents("%s steps eastwards across the bridge." % caller.name, exclude=caller)
|
||||||
caller.execute_cmd("look")
|
caller.execute_cmd("look")
|
||||||
|
|
||||||
|
|
@ -467,7 +488,19 @@ class CmdEast(Command):
|
||||||
# go back across the bridge
|
# go back across the bridge
|
||||||
class CmdWest(Command):
|
class CmdWest(Command):
|
||||||
"""
|
"""
|
||||||
Go back across the bridge westwards.
|
Go westwards across the bridge.
|
||||||
|
|
||||||
|
Tutorial info:
|
||||||
|
This command relies on the caller having two Attributes
|
||||||
|
(assigned by the room when entering):
|
||||||
|
- east_exit: a unique name or dbref to the room to go to
|
||||||
|
when exiting east.
|
||||||
|
- west_exit: a unique name or dbref to the room to go to
|
||||||
|
when exiting west.
|
||||||
|
The room must also have the following property:
|
||||||
|
- tutorial_bridge_posistion: the current position on
|
||||||
|
on the bridge, 0 - 4.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
key = "west"
|
key = "west"
|
||||||
aliases = ["w"]
|
aliases = ["w"]
|
||||||
|
|
@ -475,13 +508,13 @@ class CmdWest(Command):
|
||||||
help_category = "TutorialWorld"
|
help_category = "TutorialWorld"
|
||||||
|
|
||||||
def func(self):
|
def func(self):
|
||||||
"move forward"
|
"move one step westwards"
|
||||||
caller = self.caller
|
caller = self.caller
|
||||||
|
|
||||||
bridge_step = max(-1, caller.db.tutorial_bridge_position - 1)
|
bridge_step = max(-1, caller.db.tutorial_bridge_position - 1)
|
||||||
|
|
||||||
if bridge_step < 0:
|
if bridge_step < 0:
|
||||||
# we have reached the far west end of the bridge.#
|
# we have reached the far west end of the bridge.
|
||||||
# Move to the west room.
|
# Move to the west room.
|
||||||
wexit = search_object(self.obj.db.west_exit)
|
wexit = search_object(self.obj.db.west_exit)
|
||||||
if wexit:
|
if wexit:
|
||||||
|
|
@ -490,30 +523,18 @@ class CmdWest(Command):
|
||||||
caller.msg("No west exit was found for this room. Contact an admin.")
|
caller.msg("No west exit was found for this room. Contact an admin.")
|
||||||
return
|
return
|
||||||
caller.db.tutorial_bridge_position = bridge_step
|
caller.db.tutorial_bridge_position = bridge_step
|
||||||
caller.location.msg_contents("%s steps westwartswards across the bridge." % caller.name, exclude=caller)
|
# since we are really in one room, we have to notify others
|
||||||
|
# in the room when we move.
|
||||||
|
caller.location.msg_contents("%s steps westwards across the bridge." % caller.name, exclude=caller)
|
||||||
caller.execute_cmd("look")
|
caller.execute_cmd("look")
|
||||||
|
|
||||||
|
|
||||||
class CmdLookBridge(Command):
|
BRIDGE_POS_MESSAGES = ("You are standing {wvery close to the the bridge's western foundation{n. If you go west you will be back on solid ground ...",
|
||||||
"""
|
|
||||||
looks around at the bridge.
|
|
||||||
"""
|
|
||||||
key = 'look'
|
|
||||||
aliases = ["l"]
|
|
||||||
locks = "cmd:all()"
|
|
||||||
help_category = "TutorialWorld"
|
|
||||||
|
|
||||||
def func(self):
|
|
||||||
"Looking around, including a chance to fall."
|
|
||||||
bridge_position = self.caller.db.tutorial_bridge_position
|
|
||||||
|
|
||||||
|
|
||||||
messages =("You are standing {wvery close to the the bridge's western foundation{n. If you go west you will be back on solid ground ...",
|
|
||||||
"The bridge slopes precariously where it extends eastwards towards the lowest point - the center point of the hang bridge.",
|
"The bridge slopes precariously where it extends eastwards towards the lowest point - the center point of the hang bridge.",
|
||||||
"You are {whalfways{n out on the unstable bridge.",
|
"You are {whalfways{n out on the unstable bridge.",
|
||||||
"The bridge slopes precariously where it extends westwards towards the lowest point - the center point of the hang bridge.",
|
"The bridge slopes precariously where it extends westwards towards the lowest point - the center point of the hang bridge.",
|
||||||
"You are standing {wvery close to the bridge's eastern foundation{n. If you go east you will be back on solid ground ...")
|
"You are standing {wvery close to the bridge's eastern foundation{n. If you go east you will be back on solid ground ...")
|
||||||
moods = ("The bridge sways in the wind.", "The hanging bridge creaks dangerously.",
|
BRIDGE_MOODS = ("The bridge sways in the wind.", "The hanging bridge creaks dangerously.",
|
||||||
"You clasp the ropes firmly as the bridge sways and creaks under you.",
|
"You clasp the ropes firmly as the bridge sways and creaks under you.",
|
||||||
"From the castle you hear a distant howling sound, like that of a large dog or other beast.",
|
"From the castle you hear a distant howling sound, like that of a large dog or other beast.",
|
||||||
"The bridge creaks under your feet. Those planks does not seem very sturdy.",
|
"The bridge creaks under your feet. Those planks does not seem very sturdy.",
|
||||||
|
|
@ -522,37 +543,60 @@ class CmdLookBridge(Command):
|
||||||
"A gust of wind causes the bridge to sway precariously.",
|
"A gust of wind causes the bridge to sway precariously.",
|
||||||
"Under your feet a plank comes loose, tumbling down. For a moment you dangle over the abyss ...",
|
"Under your feet a plank comes loose, tumbling down. For a moment you dangle over the abyss ...",
|
||||||
"The section of rope you hold onto crumble in your hands, parts of it breaking apart. You sway trying to regain balance.")
|
"The section of rope you hold onto crumble in your hands, parts of it breaking apart. You sway trying to regain balance.")
|
||||||
message = "{c%s{n\n" % self.obj.key + messages[bridge_position] + "\n" + moods[random.randint(0, len(moods) - 1)]
|
|
||||||
chars = [obj for obj in self.obj.contents if obj != self.caller and obj.has_player]
|
|
||||||
if chars:
|
|
||||||
message += "\n You see: %s" % ", ".join("{c%s{n" % char.key for char in chars)
|
|
||||||
|
|
||||||
|
FALL_MESSAGE = "Suddenly the plank you stand on gives way under your feet! You fall!" \
|
||||||
|
"\nYou try to grab hold of an adjoining plank, but all you manage to do is to " \
|
||||||
|
"divert your fall westwards, towards the cliff face. This is going to hurt ... " \
|
||||||
|
"\n ... The world goes dark ...\n\n" \
|
||||||
|
|
||||||
|
class CmdLookBridge(Command):
|
||||||
|
"""
|
||||||
|
looks around at the bridge.
|
||||||
|
|
||||||
|
Tutorial info:
|
||||||
|
This command assumes that the room has an Attribute
|
||||||
|
"fall_exit", a unique name or dbref to the place they end upp
|
||||||
|
if they fall off the bridge.
|
||||||
|
"""
|
||||||
|
key = 'look'
|
||||||
|
aliases = ["l"]
|
||||||
|
locks = "cmd:all()"
|
||||||
|
help_category = "TutorialWorld"
|
||||||
|
|
||||||
|
def func(self):
|
||||||
|
"Looking around, including a chance to fall."
|
||||||
|
caller = self.caller
|
||||||
|
bridge_position = self.caller.db.tutorial_bridge_position
|
||||||
|
# this command is defined on the room, so we get it through self.obj
|
||||||
|
location = self.obj
|
||||||
|
# randomize the look-echo
|
||||||
|
message = "{c%s{n\n%s\n%s" % (location.key,
|
||||||
|
BRIDGE_POS_MESSAGES[bridge_position],
|
||||||
|
random.choice(BRIDGE_MOODS))
|
||||||
|
|
||||||
|
chars = [obj for obj in self.obj.get_contents(exclude=caller) if obj.has_player]
|
||||||
|
if chars:
|
||||||
|
# we create the You see: message manually here
|
||||||
|
message += "\n You see: %s" % ", ".join("{c%s{n" % char.key for char in chars)
|
||||||
self.caller.msg(message)
|
self.caller.msg(message)
|
||||||
|
|
||||||
# there is a chance that we fall if we are on the western or central
|
# there is a chance that we fall if we are on the western or central
|
||||||
# part of the bridge.
|
# part of the bridge.
|
||||||
if bridge_position < 3 and random.random() < 0.05 and not self.caller.is_superuser:
|
if bridge_position < 3 and random.random() < 0.05 and not self.caller.is_superuser:
|
||||||
# we fall on 5% of the times.
|
# we fall 5% of time.
|
||||||
fexit = search_object(self.obj.db.fall_exit)
|
fall_exit = search_object(self.obj.db.fall_exit)
|
||||||
if fexit:
|
if fall_exit:
|
||||||
string = "\n Suddenly the plank you stand on gives way under your feet! You fall!"
|
self.caller.msg("{r%s{n" % FALL_MESSAGE)
|
||||||
string += "\n You try to grab hold of an adjoining plank, but all you manage to do is to "
|
self.caller.move_to(fall_exit, quiet=True)
|
||||||
string += "divert your fall westwards, towards the cliff face. This is going to hurt ... "
|
# inform others on the bridge
|
||||||
string += "\n ... The world goes dark ...\n"
|
self.obj.msg_contents("A plank gives way under %s's feet and " \
|
||||||
# note that we move silently so as to not call look hooks (this is a little trick to leave
|
"they fall from the bridge!" % self.caller.key)
|
||||||
# the player with the "world goes dark ..." message, giving them ample time to read it. They
|
|
||||||
# have to manually call look to find out their new location). Thus we also call the
|
|
||||||
# at_object_leave hook manually (otherwise this is done by move_to()).
|
|
||||||
self.caller.msg("{r%s{n" % string)
|
|
||||||
self.obj.at_object_leave(self.caller, fexit)
|
|
||||||
self.caller.location = fexit[0] # stealth move, without any other hook calls.
|
|
||||||
self.obj.msg_contents("A plank gives way under %s's feet and they fall from the bridge!" % self.caller.key)
|
|
||||||
|
|
||||||
|
|
||||||
# custom help command
|
# custom help command
|
||||||
class CmdBridgeHelp(Command):
|
class CmdBridgeHelp(Command):
|
||||||
"""
|
"""
|
||||||
Overwritten help command
|
Overwritten help command while on the bridge.
|
||||||
"""
|
"""
|
||||||
key = "help"
|
key = "help"
|
||||||
aliases = ["h"]
|
aliases = ["h"]
|
||||||
|
|
@ -579,33 +623,47 @@ class BridgeCmdSet(CmdSet):
|
||||||
self.add(CmdLookBridge())
|
self.add(CmdLookBridge())
|
||||||
self.add(CmdBridgeHelp())
|
self.add(CmdBridgeHelp())
|
||||||
|
|
||||||
|
BRIDGE_WEATHER = (
|
||||||
|
"The rain intensifies, making the planks of the bridge even more slippery.",
|
||||||
|
"A gush of wind throws the rain right in your face.",
|
||||||
|
"The rainfall eases a bit and the sky momentarily brightens.",
|
||||||
|
"The bridge shakes under the thunder of a closeby thunder strike.",
|
||||||
|
"The rain pummels you with large, heavy drops. You hear the distinct howl of a large hound in the distance.",
|
||||||
|
"The wind is picking up, howling around you and causing the bridge to sway from side to side.",
|
||||||
|
"Some sort of large bird sweeps by overhead, giving off an eery screech. Soon it has disappeared in the gloom.",
|
||||||
|
"The bridge sways from side to side in the wind.",
|
||||||
|
"Below you a particularly large wave crashes into the rocks.",
|
||||||
|
"From the ruin you hear a distant, otherwordly howl. Or maybe it was just the wind.")
|
||||||
|
|
||||||
class BridgeRoom(TutorialRoom):
|
class BridgeRoom(WeatherRoom):
|
||||||
"""
|
"""
|
||||||
The bridge room implements an unsafe bridge. It also enters the player into
|
The bridge room implements an unsafe bridge. It also enters the player into
|
||||||
a state where they get new commands so as to try to cross the bridge.
|
a state where they get new commands so as to try to cross the bridge.
|
||||||
|
|
||||||
We want this to result in the player getting a special set of
|
We want this to result in the player getting a special set of
|
||||||
commands related to crossing the bridge. The result is that it will
|
commands related to crossing the bridge. The result is that it
|
||||||
take several steps to cross it, despite it being represented by only a
|
will take several steps to cross it, despite it being represented
|
||||||
single room.
|
by only a single room.
|
||||||
|
|
||||||
We divide the bridge into steps:
|
We divide the bridge into steps:
|
||||||
|
|
||||||
self.db.west_exit - - | - - self.db.east_exit
|
self.db.west_exit - - | - - self.db.east_exit
|
||||||
0 1 2 3 4
|
0 1 2 3 4
|
||||||
|
|
||||||
The position is handled by a variable stored on the player when entering
|
The position is handled by a variable stored on the character
|
||||||
and giving special move commands will increase/decrease the counter
|
when entering and giving special move commands will
|
||||||
until the bridge is crossed.
|
increase/decrease the counter until the bridge is crossed.
|
||||||
|
|
||||||
|
We also has self.db.fall_exit, which points to a gathering
|
||||||
|
location to end up if we happen to fall off the bridge (used by
|
||||||
|
the CmdLookBridge command).
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def at_object_creation(self):
|
def at_object_creation(self):
|
||||||
"Setups the room"
|
"Setups the room"
|
||||||
|
# this will start the weather room's ticker and tell
|
||||||
|
# it to call update_weather regularly.
|
||||||
super(BridgeRoom, self).at_object_creation()
|
super(BridgeRoom, self).at_object_creation()
|
||||||
|
|
||||||
# at irregular intervals, this will call self.update_irregular()
|
|
||||||
self.scripts.add(tut_scripts.IrregularEvent)
|
|
||||||
# this identifies the exits from the room (should be the command
|
# this identifies the exits from the room (should be the command
|
||||||
# needed to leave through that exit). These are defaults, but you
|
# needed to leave through that exit). These are defaults, but you
|
||||||
# could of course also change them after the room has been created.
|
# could of course also change them after the room has been created.
|
||||||
|
|
@ -614,25 +672,20 @@ class BridgeRoom(TutorialRoom):
|
||||||
self.db.fall_exit = "cliffledge"
|
self.db.fall_exit = "cliffledge"
|
||||||
# add the cmdset on the room.
|
# add the cmdset on the room.
|
||||||
self.cmdset.add_default(BridgeCmdSet)
|
self.cmdset.add_default(BridgeCmdSet)
|
||||||
|
# information for those using the tutorial command
|
||||||
self.db.tutorial_info = \
|
self.db.tutorial_info = \
|
||||||
"""The bridge seem large but is actually only a single room that assigns custom west/east commands."""
|
"The bridge seems large but is actually only a " \
|
||||||
|
"single room that assigns custom west/east commands " \
|
||||||
|
"and a counter to determine how far across you are."
|
||||||
|
|
||||||
def update_irregular(self):
|
def update_weather(self):
|
||||||
"""
|
"""
|
||||||
This is called at irregular intervals and makes the passage
|
This is called at irregular intervals and makes the passage
|
||||||
over the bridge a little more interesting.
|
over the bridge a little more interesting.
|
||||||
"""
|
"""
|
||||||
strings = (
|
if random.random() < 80:
|
||||||
"The rain intensifies, making the planks of the bridge even more slippery.",
|
# send a message most of the time
|
||||||
"A gush of wind throws the rain right in your face.",
|
self.msg_contents("{w%s{n" % random.choice(BRIDGE_WEATHER))
|
||||||
"The rainfall eases a bit and the sky momentarily brightens.",
|
|
||||||
"The bridge shakes under the thunder of a closeby thunder strike.",
|
|
||||||
"The rain pummels you with large, heavy drops. You hear the distinct howl of a large hound in the distance.",
|
|
||||||
"The wind is picking up, howling around you and causing the bridge to sway from side to side.",
|
|
||||||
"Some sort of large bird sweeps by overhead, giving off an eery screech. Soon it has disappeared in the gloom.",
|
|
||||||
"The bridge sways from side to side in the wind.")
|
|
||||||
self.msg_contents("{w%s{n" % strings[random.randint(0, 7)])
|
|
||||||
|
|
||||||
def at_object_receive(self, character, source_location):
|
def at_object_receive(self, character, source_location):
|
||||||
"""
|
"""
|
||||||
|
|
@ -645,13 +698,16 @@ class BridgeRoom(TutorialRoom):
|
||||||
wexit = search_object(self.db.west_exit)
|
wexit = search_object(self.db.west_exit)
|
||||||
eexit = search_object(self.db.east_exit)
|
eexit = search_object(self.db.east_exit)
|
||||||
fexit = search_object(self.db.fall_exit)
|
fexit = search_object(self.db.fall_exit)
|
||||||
if not wexit or not eexit or not fexit:
|
if not (wexit and eexit and fexit):
|
||||||
character.msg("The bridge's exits are not properly configured. Contact an admin. Forcing west-end placement.")
|
character.msg("The bridge's exits are not properly configured. "\
|
||||||
|
"Contact an admin. Forcing west-end placement.")
|
||||||
character.db.tutorial_bridge_position = 0
|
character.db.tutorial_bridge_position = 0
|
||||||
return
|
return
|
||||||
if source_location == eexit[0]:
|
if source_location == eexit[0]:
|
||||||
|
# we assume we enter from the same room we will exit to
|
||||||
character.db.tutorial_bridge_position = 4
|
character.db.tutorial_bridge_position = 4
|
||||||
else:
|
else:
|
||||||
|
# if not from the east, then from the west!
|
||||||
character.db.tutorial_bridge_position = 0
|
character.db.tutorial_bridge_position = 0
|
||||||
|
|
||||||
def at_object_leave(self, character, target_location):
|
def at_object_leave(self, character, target_location):
|
||||||
|
|
@ -662,6 +718,10 @@ class BridgeRoom(TutorialRoom):
|
||||||
# clean up the position attribute
|
# clean up the position attribute
|
||||||
del character.db.tutorial_bridge_position
|
del character.db.tutorial_bridge_position
|
||||||
|
|
||||||
|
SUPERUSER_WARNING = "\nWARNING: You are playing as a superuser ({name}). Use the {quell} command to\n" \
|
||||||
|
"play without superuser privileges (many functions and puzzles ignore the \n" \
|
||||||
|
"presence of a superuser, making this mode useful for exploring things behind \n" \
|
||||||
|
"the scenes later).\n" \
|
||||||
|
|
||||||
#-----------------------------------------------------------
|
#-----------------------------------------------------------
|
||||||
#
|
#
|
||||||
|
|
@ -679,28 +739,29 @@ class IntroRoom(TutorialRoom):
|
||||||
properties to customize:
|
properties to customize:
|
||||||
char_health - integer > 0 (default 20)
|
char_health - integer > 0 (default 20)
|
||||||
"""
|
"""
|
||||||
|
def at_object_creation(self):
|
||||||
|
"""
|
||||||
|
Called when the room is first created.
|
||||||
|
"""
|
||||||
|
super(IntroRoom, self).at_object_creation()
|
||||||
|
self.db_tutorial_info = "The first room of the tutorial. " \
|
||||||
|
"This assigns the health Attribute to "\
|
||||||
|
"the player."
|
||||||
|
|
||||||
def at_object_receive(self, character, source_location):
|
def at_object_receive(self, character, source_location):
|
||||||
"""
|
"""
|
||||||
Assign properties on characters
|
Assign properties on characters
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# setup
|
# setup character for the tutorial
|
||||||
health = self.db.char_health
|
health = self.db.char_health or 20
|
||||||
if not health:
|
|
||||||
health = 20
|
|
||||||
|
|
||||||
if character.has_player:
|
if character.has_player:
|
||||||
character.db.health = health
|
character.db.health = health
|
||||||
character.db.health_max = health
|
character.db.health_max = health
|
||||||
|
|
||||||
if character.is_superuser:
|
if character.is_superuser:
|
||||||
string = "-"*78 + "\n" \
|
string = "-"*78 + SUPERUSER_WARNING + "-"*78
|
||||||
"WARNING: You are playing as a superuser ({name}). Use the {quell} command to\n" \
|
|
||||||
"play without superuser privileges (many functions and puzzles ignore the \n" \
|
|
||||||
"presence of a superuser, making this mode useful for exploring things behind \n" \
|
|
||||||
"the scenes later).\n" \
|
|
||||||
+ "-"*78
|
|
||||||
character.msg("{r%s{n" % string.format(name=character.key, quell="{w@quell{r"))
|
character.msg("{r%s{n" % string.format(name=character.key, quell="{w@quell{r"))
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -716,11 +777,21 @@ class OutroRoom(TutorialRoom):
|
||||||
"""
|
"""
|
||||||
Outro room.
|
Outro room.
|
||||||
|
|
||||||
One can set an attribute list "wracklist" with weapon-rack ids
|
Called when exiting the tutorial, cleans the
|
||||||
in order to clear all weapon rack ids from the character.
|
character of tutorial-related attributes.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def at_object_creation(self):
|
||||||
|
"""
|
||||||
|
Called when the room is first created.
|
||||||
|
"""
|
||||||
|
super(IntroRoom, self).at_object_creation()
|
||||||
|
self.db_tutorial_info = "The last room of the tutorial. " \
|
||||||
|
"This cleans up all temporary Attributes " \
|
||||||
|
"the tutorial may have assigned to the "\
|
||||||
|
"character."
|
||||||
|
|
||||||
def at_object_receive(self, character, source_location):
|
def at_object_receive(self, character, source_location):
|
||||||
"""
|
"""
|
||||||
Do cleanup.
|
Do cleanup.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue