mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
Fixed the ending of the tutorial and a bug in the spawner.
This commit is contained in:
parent
d1cd9da6bf
commit
3db3d83d4c
7 changed files with 467 additions and 456 deletions
|
|
@ -171,8 +171,8 @@ def get_and_merge_cmdsets(caller, session, player, obj,
|
|||
# Gather all cmdsets stored on objects in the room and
|
||||
# also in the caller's inventory and the location itself
|
||||
local_objlist = yield (location.contents_get(exclude=obj) +
|
||||
obj.contents +
|
||||
[location])
|
||||
obj.contents + [location])
|
||||
local_objlist = [o for o in local_objlist if not o._is_deleted]
|
||||
for lobj in local_objlist:
|
||||
try:
|
||||
# call hook in case we need to do dynamic changing to cmdset
|
||||
|
|
@ -205,6 +205,8 @@ def get_and_merge_cmdsets(caller, session, player, obj,
|
|||
yield obj.at_cmdset_get()
|
||||
except Exception:
|
||||
logger.log_trace()
|
||||
_msg_err(caller, _ERROR_CMDSETS)
|
||||
raise ErrorReported
|
||||
try:
|
||||
returnValue(obj.cmdset.current)
|
||||
except AttributeError:
|
||||
|
|
|
|||
|
|
@ -38,14 +38,14 @@
|
|||
# | +--------+ +--------+ +--------+ +---+----+
|
||||
# | \ |
|
||||
# ++---------+ \ +--------+ +--------+ +---+----+
|
||||
# |intro | \ |cell | |trap/ |temple |
|
||||
# o--+ 01 | \| 08 +----+ fall | | 13 |
|
||||
# | | | | /| 15 | | |
|
||||
# |intro | \ |cell | | | |temple |
|
||||
# o--+ 01 | \| 08 +----+ trap | | 13 |
|
||||
# | | | | /| | | |
|
||||
# +----+-----+ +--------+ / +--+-+-+-+ +---+----+
|
||||
# | / | | | |
|
||||
# +----+-----+ +--------+/ +--+-+-+---------+----+
|
||||
# |outro | |tomb | |antechamber |
|
||||
# o--+ 17 +----------+ 16 | | 14 |
|
||||
# o--+ 16 +----------+ 15 | | 14 |
|
||||
# | | | | | |
|
||||
# +----------+ +--------+ +---------------------+
|
||||
#
|
||||
|
|
@ -826,8 +826,11 @@ archway
|
|||
#
|
||||
@set obelisk/get_err_msg = It's way too heavy for anyone to move.
|
||||
#
|
||||
# (the obelisk describes itself, so we need no do it here)
|
||||
# Set the puzzle clues on the obelisk. The order should correspond
|
||||
# to the ids later checked by the antechamber puzzle.
|
||||
#
|
||||
@set obelisk/puzzle_descs = ("You can briefly make out the image of {ba woman with a blue bird{n.", "You for a moment see the visage of {ba woman on a horse{n.", "For the briefest moment you make out an engraving of {ba regal woman wearing a crown{n.", "You think you can see the outline of {ba flaming shield{n in the stone.", "The surface for a moment seems to portray {ba sharp-faced woman with white hair{n.")
|
||||
|
||||
# Create the mobile. This is its start location.
|
||||
@create/drop Ghostly apparition;ghost;apparition;fog : tutorial_world.mob.Mob
|
||||
#
|
||||
|
|
@ -874,6 +877,7 @@ archway
|
|||
#
|
||||
@set ghost/hit_msg =
|
||||
The ghostly apparition howls and writhes, shifts and shivers.
|
||||
#
|
||||
@set ghost/death_msg =
|
||||
After the last strike, the ghostly apparition seems to collapse
|
||||
inwards. It fades and becomes one with the mist. Its howls rise to a
|
||||
|
|
@ -1028,7 +1032,7 @@ stairs down
|
|||
#
|
||||
@dig Blue bird tomb
|
||||
: tutorial_world.rooms.TeleportRoom
|
||||
= Tomb with stone bird;bird;blue;stone
|
||||
= Blue bird tomb;bird;blue;stone
|
||||
#
|
||||
@desc Blue bird tomb =
|
||||
The entrance to this tomb is decorated with a very lifelike blue bird.
|
||||
|
|
@ -1037,9 +1041,9 @@ Blue bird tomb
|
|||
#
|
||||
@set here/puzzle_value = 0
|
||||
#
|
||||
@set here/failure_teleport_to = tut#15
|
||||
@set here/failure_teleport_to = tut#08
|
||||
#
|
||||
@set here/success_teleport_to = tut#16
|
||||
@set here/success_teleport_to = tut#15
|
||||
#
|
||||
@set here/failure_teleport_msg =
|
||||
The tomb is dark. You fumble your way through it. You think you can
|
||||
|
|
@ -1059,7 +1063,7 @@ Blue bird tomb
|
|||
|
||||
The air is damp. Where are you?
|
||||
#
|
||||
@set here/success_teleport_to =
|
||||
@set here/success_teleport_msg =
|
||||
The tomb is dark. You fumble your way through it. You think you can
|
||||
make out a coffin in front of you in the gloom.
|
||||
|
||||
|
|
@ -1072,7 +1076,7 @@ Blue bird tomb
|
|||
#
|
||||
@dig Tomb of woman on horse
|
||||
: tutorial_world.rooms.TeleportRoom
|
||||
= Tomb with statue of riding woman;horse;riding;
|
||||
= Tomb of woman on horse;horse;riding;
|
||||
#
|
||||
@desc Tomb of woman on horse =
|
||||
The entrance to this tomb depicts a scene of a strong
|
||||
|
|
@ -1084,9 +1088,9 @@ Tomb of woman on horse
|
|||
#
|
||||
@set here/puzzle_value = 1
|
||||
#
|
||||
@set here/failure_teleport_to = tut#15
|
||||
@set here/failure_teleport_to = tut#08
|
||||
#
|
||||
@set here/success_teleport_to = tut#16
|
||||
@set here/success_teleport_to = tut#15
|
||||
#
|
||||
@set here/failure_teleport_msg =
|
||||
The tomb is dark. You fumble your way through it. You think you can
|
||||
|
|
@ -1106,7 +1110,7 @@ Tomb of woman on horse
|
|||
|
||||
The air is damp. Where are you?
|
||||
#
|
||||
@set here/success_teleport_to =
|
||||
@set here/success_teleport_msg =
|
||||
The tomb is dark. You fumble your way through it. You think you can
|
||||
make out a coffin in front of you in the gloom.
|
||||
|
||||
|
|
@ -1119,7 +1123,7 @@ Tomb of woman on horse
|
|||
#
|
||||
@dig Tomb of the crowned queen
|
||||
: tutorial_world.rooms.TeleportRoom
|
||||
= Tomb with statue of a crowned queen;crown;queen
|
||||
= Tomb of the crowned queen;crown;queen
|
||||
#
|
||||
@desc Tomb of the crowned queen =
|
||||
The entrance to this tomb shows a beautiful mural of a queen ruling
|
||||
|
|
@ -1130,9 +1134,9 @@ Tomb of the crowned queen
|
|||
#
|
||||
@set here/puzzle_value = 2
|
||||
#
|
||||
@set here/failure_teleport_to = tut#15
|
||||
@set here/failure_teleport_to = tut#08
|
||||
#
|
||||
@set here/success_teleport_to = tut#16
|
||||
@set here/success_teleport_to = tut#15
|
||||
#
|
||||
@set here/failure_teleport_msg =
|
||||
The tomb is dark. You fumble your way through it. You think you can
|
||||
|
|
@ -1152,7 +1156,7 @@ Tomb of the crowned queen
|
|||
|
||||
The air is damp. Where are you?
|
||||
#
|
||||
@set here/success_teleport_to =
|
||||
@set here/success_teleport_msg =
|
||||
The tomb is dark. You fumble your way through it. You think you can
|
||||
make out a coffin in front of you in the gloom.
|
||||
|
||||
|
|
@ -1165,9 +1169,7 @@ Tomb of the crowned queen
|
|||
#
|
||||
@dig Tomb of the shield
|
||||
: tutorial_world.rooms.TeleportRoom
|
||||
= Tomb with shield of arms;shield
|
||||
#
|
||||
Tomb of the shield
|
||||
= Tomb of the shield;shield
|
||||
#
|
||||
@desc Tomb of the shield =
|
||||
This tomb shows a warrior woman fighting shadowy creatures from the
|
||||
|
|
@ -1175,11 +1177,13 @@ top of a hill. Her sword lies broken on the ground before her but she
|
|||
fights on with her battered shield - the scene depicts her just as she
|
||||
rams the shield into an enemy in wild desperation.
|
||||
#
|
||||
Tomb of the shield
|
||||
#
|
||||
@set here/puzzle_value = 3
|
||||
#
|
||||
@set here/failure_teleport_to = tut#15
|
||||
@set here/failure_teleport_to = tut#08
|
||||
#
|
||||
@set here/success_teleport_to = tut#16
|
||||
@set here/success_teleport_to = tut#15
|
||||
#
|
||||
@set here/failure_teleport_msg =
|
||||
The tomb is dark. You fumble your way through it. You think you can
|
||||
|
|
@ -1199,7 +1203,7 @@ rams the shield into an enemy in wild desperation.
|
|||
|
||||
The air is damp. Where are you?
|
||||
#
|
||||
@set here/success_teleport_to =
|
||||
@set here/success_teleport_msg =
|
||||
The tomb is dark. You fumble your way through it. You think you can
|
||||
make out a coffin in front of you in the gloom.
|
||||
|
||||
|
|
@ -1212,7 +1216,7 @@ rams the shield into an enemy in wild desperation.
|
|||
#
|
||||
@dig Tomb of the hero
|
||||
: tutorial_world.rooms.TeleportRoom
|
||||
= Tomb depicting a heroine fighting a monster;knight;hero;monster;beast
|
||||
= Tomb of the hero;knight;hero;monster;beast
|
||||
#
|
||||
@desc Tomb of the hero =
|
||||
The entrance to this tomb shows a mural of an aging woman in a
|
||||
|
|
@ -1225,9 +1229,9 @@ Tomb of the hero
|
|||
#
|
||||
@set here/puzzle_value = 4
|
||||
#
|
||||
@set here/failure_teleport_to = tut#15
|
||||
@set here/failure_teleport_to = tut#08
|
||||
#
|
||||
@set here/success_teleport_to = tut#16
|
||||
@set here/success_teleport_to = tut#15
|
||||
#
|
||||
@set here/failure_teleport_msg =
|
||||
The tomb is dark. You fumble your way through it. You think you can
|
||||
|
|
@ -1247,7 +1251,7 @@ Tomb of the hero
|
|||
|
||||
The air is damp. Where are you?
|
||||
#
|
||||
@set here/success_teleport_to =
|
||||
@set here/success_teleport_msg =
|
||||
The tomb is dark. You fumble your way through it. You think you can
|
||||
make out a coffin in front of you in the gloom.
|
||||
|
||||
|
|
@ -1269,14 +1273,14 @@ Tomb of the hero
|
|||
#
|
||||
#------------------------------------------------------------
|
||||
#
|
||||
@dig/teleport Ancient tomb;tut#16
|
||||
@dig/teleport Ancient tomb;tut#15
|
||||
: tutorial_world.rooms.TutorialRoom
|
||||
= ,back to antechamber;antechamber;back
|
||||
#
|
||||
@desc
|
||||
Apart from the ornate sarcophagus, the tomb is bare from extra decorations.
|
||||
This is the resting place of a warrior with little patience for
|
||||
glamour and trinkets.
|
||||
glamour and trinkets. You have reached the end of your quest.
|
||||
#
|
||||
@set here/tutorial_info =
|
||||
Congratulations, you have reached the end of this little tutorial
|
||||
|
|
@ -1330,7 +1334,7 @@ Tomb of the hero
|
|||
#
|
||||
#------------------------------------------------------------
|
||||
#
|
||||
@dig End of tutorial;end;tut#17
|
||||
@dig End of tutorial;end;tut#16
|
||||
: tutorial_world.rooms.OutroRoom
|
||||
= Exit tutorial;exit;end
|
||||
#
|
||||
|
|
@ -1341,7 +1345,7 @@ Tomb of the hero
|
|||
@lock Exit tutorial = view:holds(rack_sarcophagus) ; traverse:holds(rack_sarcophagus)
|
||||
#
|
||||
# to tutorial outro
|
||||
@tel tut#17
|
||||
@tel tut#16
|
||||
#
|
||||
# we want to clear the weapon-rack ids on the character when exiting.
|
||||
@set here/wracklist = ["rack_barrel", "rack_sarcophagus"]
|
||||
|
|
|
|||
|
|
@ -52,7 +52,6 @@ class TutorialObject(DefaultObject):
|
|||
"Called when the object is first created."
|
||||
super(TutorialObject, self).at_object_creation()
|
||||
self.db.tutorial_info = "No tutorial info is available for this object."
|
||||
#self.db.last_reset = time.time()
|
||||
|
||||
def reset(self):
|
||||
"Resets the object, whatever that may mean."
|
||||
|
|
@ -171,7 +170,7 @@ class CmdClimb(Command):
|
|||
ostring = "You climb %s. Having looked around, you climb down again." % self.obj.name
|
||||
self.caller.msg(ostring)
|
||||
# set a tag on the caller to remember that we climbed.
|
||||
self.caller.tags.add("tutorial_climbed_tree")
|
||||
self.caller.tags.add("tutorial_climbed_tree", category="tutorial_world")
|
||||
|
||||
|
||||
class CmdSetClimbable(CmdSet):
|
||||
|
|
@ -205,21 +204,22 @@ class Climbable(TutorialObject):
|
|||
#
|
||||
#------------------------------------------------------------
|
||||
|
||||
OBELISK_DESCS = ("You can briefly make out the image of {ba woman with a blue bird{n.",
|
||||
"You for a moment see the visage of {ba woman on a horse{n.",
|
||||
"For the briefest moment you make out an engraving of {ba regal woman wearing a crown{n.",
|
||||
"You think you can see the outline of {ba flaming shield{n in the stone.",
|
||||
"The surface for a moment seems to portray {ba woman fighting a beast{n.")
|
||||
|
||||
class Obelisk(TutorialObject):
|
||||
"""
|
||||
This object changes its description randomly.
|
||||
This object changes its description randomly, and which is shown
|
||||
determines which order "clue id" is stored on the Character for
|
||||
future puzzles.
|
||||
|
||||
Important Attribute:
|
||||
puzzle_descs (list): list of descriptions. One of these is
|
||||
|
||||
"""
|
||||
|
||||
def at_object_creation(self):
|
||||
"Called when object is created."
|
||||
super(Obelisk, self).at_object_creation()
|
||||
self.db.tutorial_info = "This object changes its desc randomly, and makes sure to remember which one you saw."
|
||||
self.db.puzzle_descs = ["You see a normal stone slab"]
|
||||
# make sure this can never be picked up
|
||||
self.locks.add("get:false()")
|
||||
|
||||
|
|
@ -229,11 +229,12 @@ class Obelisk(TutorialObject):
|
|||
of the object. We overload it with our own version.
|
||||
"""
|
||||
# randomly get the index for one of the descriptions
|
||||
clueindex = random.randint(0, len(OBELISK_DESCS) - 1)
|
||||
descs = self.db.puzzle_descs
|
||||
clueindex = random.randint(0, len(descs) - 1)
|
||||
# set this description, with the random extra
|
||||
string = "The surface of the obelisk seem to waver, shift and writhe under your gaze, with " \
|
||||
"different scenes and structures appearing whenever you look at it. "
|
||||
self.db.desc = string + OBELISK_DESCS[clueindex]
|
||||
self.db.desc = string + descs[clueindex]
|
||||
# remember that this was the clue we got. The Puzzle room will
|
||||
# look for this later to determine if you should be teleported
|
||||
# or not.
|
||||
|
|
@ -1051,13 +1052,13 @@ class WeaponRack(TutorialObject):
|
|||
pulling weapons from it indefinitely.
|
||||
"""
|
||||
rack_id = self.db.rack_id
|
||||
if caller.tags.get(rack_id):
|
||||
if caller.tags.get(rack_id, category="tutorial_world"):
|
||||
caller.msg(self.db.no_more_weapons_msg)
|
||||
else:
|
||||
prototype = random.choice(self.db.available_weapons)
|
||||
# use the spawner to create a new Weapon from the
|
||||
# spawner dictionary, tag the caller
|
||||
wpn = spawn(WEAPON_PROTOTYPES[prototype], prototype_parents=WEAPON_PROTOTYPES)[0]
|
||||
caller.tags.add(rack_id)
|
||||
caller.tags.add(rack_id, category="tutorial_world")
|
||||
wpn.location = caller
|
||||
caller.msg(self.db.get_weapon_msg % wpn.key)
|
||||
|
|
|
|||
|
|
@ -265,10 +265,6 @@ class TutorialRoom(DefaultRoom):
|
|||
else:
|
||||
self.db.details = {detailkey.lower(): description}
|
||||
|
||||
def reset(self):
|
||||
"Can be called by the tutorial runner."
|
||||
pass
|
||||
|
||||
|
||||
#------------------------------------------------------------
|
||||
#
|
||||
|
|
@ -331,6 +327,347 @@ class WeatherRoom(TutorialRoom):
|
|||
self.msg_contents("{w%s{n" % random.choice(WEATHER_STRINGS))
|
||||
|
||||
|
||||
|
||||
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" \
|
||||
|
||||
|
||||
#-----------------------------------------------------------
|
||||
#
|
||||
# Intro Room - unique room
|
||||
#
|
||||
# This room marks the start of the tutorial. It sets up properties on
|
||||
# the player char that is needed for the tutorial.
|
||||
#
|
||||
#------------------------------------------------------------
|
||||
|
||||
class IntroRoom(TutorialRoom):
|
||||
"""
|
||||
Intro room
|
||||
|
||||
properties to customize:
|
||||
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):
|
||||
"""
|
||||
Assign properties on characters
|
||||
"""
|
||||
|
||||
# setup character for the tutorial
|
||||
health = self.db.char_health or 20
|
||||
|
||||
if character.has_player:
|
||||
character.db.health = health
|
||||
character.db.health_max = health
|
||||
|
||||
if character.is_superuser:
|
||||
string = "-"*78 + SUPERUSER_WARNING + "-"*78
|
||||
character.msg("{r%s{n" % string.format(name=character.key, quell="{w@quell{r"))
|
||||
|
||||
|
||||
#------------------------------------------------------------
|
||||
#
|
||||
# Bridge - unique room
|
||||
#
|
||||
# Defines a special west-eastward "bridge"-room, a large room it takes
|
||||
# several steps to cross. It is complete with custom commands and a
|
||||
# chance of falling off the bridge. This room has no regular exits,
|
||||
# instead the exiting are handled by custom commands set on the player
|
||||
# upon first entering the room.
|
||||
#
|
||||
# Since one can enter the bridge room from both ends, it is
|
||||
# divided into five steps:
|
||||
# westroom <- 0 1 2 3 4 -> eastroom
|
||||
#
|
||||
#------------------------------------------------------------
|
||||
|
||||
|
||||
class CmdEast(Command):
|
||||
"""
|
||||
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 Attributes
|
||||
- tutorial_bridge_posistion: the current position on
|
||||
on the bridge, 0 - 4.
|
||||
|
||||
"""
|
||||
key = "east"
|
||||
aliases = ["e"]
|
||||
locks = "cmd:all()"
|
||||
help_category = "TutorialWorld"
|
||||
|
||||
def func(self):
|
||||
"move one step eastwards"
|
||||
caller = self.caller
|
||||
|
||||
bridge_step = min(5, caller.db.tutorial_bridge_position + 1)
|
||||
|
||||
if bridge_step > 4:
|
||||
# we have reached the far east end of the bridge.
|
||||
# Move to the east room.
|
||||
eexit = search_object(self.obj.db.east_exit)
|
||||
if eexit:
|
||||
caller.move_to(eexit[0])
|
||||
else:
|
||||
caller.msg("No east exit was found for this room. Contact an admin.")
|
||||
return
|
||||
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.execute_cmd("look")
|
||||
|
||||
|
||||
# go back across the bridge
|
||||
class CmdWest(Command):
|
||||
"""
|
||||
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"
|
||||
aliases = ["w"]
|
||||
locks = "cmd:all()"
|
||||
help_category = "TutorialWorld"
|
||||
|
||||
def func(self):
|
||||
"move one step westwards"
|
||||
caller = self.caller
|
||||
|
||||
bridge_step = max(-1, caller.db.tutorial_bridge_position - 1)
|
||||
|
||||
if bridge_step < 0:
|
||||
# we have reached the far west end of the bridge.
|
||||
# Move to the west room.
|
||||
wexit = search_object(self.obj.db.west_exit)
|
||||
if wexit:
|
||||
caller.move_to(wexit[0])
|
||||
else:
|
||||
caller.msg("No west exit was found for this room. Contact an admin.")
|
||||
return
|
||||
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 westwards across the bridge." % caller.name, exclude=caller)
|
||||
caller.execute_cmd("look")
|
||||
|
||||
|
||||
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 ...",
|
||||
"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.",
|
||||
"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 ...")
|
||||
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.",
|
||||
"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.",
|
||||
"Far below you the ocean roars and throws its waves against the cliff, as if trying its best to reach you.",
|
||||
"Parts of the bridge come loose behind you, falling into the chasm far below!",
|
||||
"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 ...",
|
||||
"The section of rope you hold onto crumble in your hands, parts of it breaking apart. You sway trying to regain balance.")
|
||||
|
||||
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.contents_get(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)
|
||||
|
||||
# there is a chance that we fall if we are on the western or central
|
||||
# part of the bridge.
|
||||
if bridge_position < 3 and random.random() < 0.05 and not self.caller.is_superuser:
|
||||
# we fall 5% of time.
|
||||
fall_exit = search_object(self.obj.db.fall_exit)
|
||||
if fall_exit:
|
||||
self.caller.msg("{r%s{n" % FALL_MESSAGE)
|
||||
self.caller.move_to(fall_exit[0], quiet=True)
|
||||
# inform others on the bridge
|
||||
self.obj.msg_contents("A plank gives way under %s's feet and " \
|
||||
"they fall from the bridge!" % self.caller.key)
|
||||
|
||||
|
||||
# custom help command
|
||||
class CmdBridgeHelp(Command):
|
||||
"""
|
||||
Overwritten help command while on the bridge.
|
||||
"""
|
||||
key = "help"
|
||||
aliases = ["h"]
|
||||
locks = "cmd:all()"
|
||||
help_category = "Tutorial world"
|
||||
|
||||
def func(self):
|
||||
"Implements the command."
|
||||
string = "You are trying hard not to fall off the bridge ..."
|
||||
string += "\n\nWhat you can do is trying to cross the bridge {weast{n "
|
||||
string += "or try to get back to the mainland {wwest{n)."
|
||||
self.caller.msg(string)
|
||||
|
||||
|
||||
class BridgeCmdSet(CmdSet):
|
||||
"This groups the bridge commands. We will store it on the room."
|
||||
key = "Bridge commands"
|
||||
priority = 1 # this gives it precedence over the normal look/help commands.
|
||||
def at_cmdset_creation(self):
|
||||
"Called at first cmdset creation"
|
||||
self.add(CmdTutorial())
|
||||
self.add(CmdEast())
|
||||
self.add(CmdWest())
|
||||
self.add(CmdLookBridge())
|
||||
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(WeatherRoom):
|
||||
"""
|
||||
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.
|
||||
|
||||
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 take several steps to cross it, despite it being represented
|
||||
by only a single room.
|
||||
|
||||
We divide the bridge into steps:
|
||||
|
||||
self.db.west_exit - - | - - self.db.east_exit
|
||||
0 1 2 3 4
|
||||
|
||||
The position is handled by a variable stored on the character
|
||||
when entering and giving special move commands will
|
||||
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):
|
||||
"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()
|
||||
# this identifies the exits from the room (should be the command
|
||||
# needed to leave through that exit). These are defaults, but you
|
||||
# could of course also change them after the room has been created.
|
||||
self.db.west_exit = "cliff"
|
||||
self.db.east_exit = "gate"
|
||||
self.db.fall_exit = "cliffledge"
|
||||
# add the cmdset on the room.
|
||||
self.cmdset.add_default(BridgeCmdSet)
|
||||
|
||||
def update_weather(self, *args, **kwargs):
|
||||
"""
|
||||
This is called at irregular intervals and makes the passage
|
||||
over the bridge a little more interesting.
|
||||
"""
|
||||
if random.random() < 80:
|
||||
# send a message most of the time
|
||||
self.msg_contents("{w%s{n" % random.choice(BRIDGE_WEATHER))
|
||||
|
||||
def at_object_receive(self, character, source_location):
|
||||
"""
|
||||
This hook is called by the engine whenever the player is moved
|
||||
into this room.
|
||||
"""
|
||||
if character.has_player:
|
||||
# we only run this if the entered object is indeed a player object.
|
||||
# check so our east/west exits are correctly defined.
|
||||
wexit = search_object(self.db.west_exit)
|
||||
eexit = search_object(self.db.east_exit)
|
||||
fexit = search_object(self.db.fall_exit)
|
||||
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.db.tutorial_bridge_position = 0
|
||||
return
|
||||
if source_location == eexit[0]:
|
||||
# we assume we enter from the same room we will exit to
|
||||
character.db.tutorial_bridge_position = 4
|
||||
else:
|
||||
# if not from the east, then from the west!
|
||||
character.db.tutorial_bridge_position = 0
|
||||
|
||||
def at_object_leave(self, character, target_location):
|
||||
"""
|
||||
This is triggered when the player leaves the bridge room.
|
||||
"""
|
||||
if character.has_player:
|
||||
# clean up the position attribute
|
||||
del character.db.tutorial_bridge_position
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Dark Room - a room with states
|
||||
|
|
@ -341,6 +678,7 @@ class WeatherRoom(TutorialRoom):
|
|||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
|
||||
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!",
|
||||
|
|
@ -357,6 +695,7 @@ ALREADY_LIGHTSOURCE = "You don't want to stumble around in blindness anymore. Yo
|
|||
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):
|
||||
"""
|
||||
Look around in darkness
|
||||
|
|
@ -542,9 +881,10 @@ class DarkRoom(TutorialRoom):
|
|||
"""
|
||||
self.check_light_state()
|
||||
|
||||
|
||||
#------------------------------------------------------------
|
||||
#
|
||||
# Teleport room - puzzle room
|
||||
# Teleport room - puzzles solution
|
||||
#
|
||||
# This is a sort of puzzle room that requires a certain
|
||||
# attribute on the entering character to be the same as
|
||||
|
|
@ -557,6 +897,7 @@ class DarkRoom(TutorialRoom):
|
|||
#
|
||||
#------------------------------------------------------------
|
||||
|
||||
|
||||
class TeleportRoom(TutorialRoom):
|
||||
"""
|
||||
Teleporter - puzzle room.
|
||||
|
|
@ -592,7 +933,7 @@ class TeleportRoom(TutorialRoom):
|
|||
# only act on player characters.
|
||||
return
|
||||
# determine if the puzzle is a success or not
|
||||
is_success = character.db.puzzle_clue == self.db.puzzle_value
|
||||
is_success = str(character.db.puzzle_clue) == str(self.db.puzzle_value)
|
||||
teleport_to = self.db.success_teleport_to if is_success else self.db.failure_teleport_to
|
||||
# note that this returns a list
|
||||
results = search_object(teleport_to)
|
||||
|
|
@ -600,7 +941,7 @@ class TeleportRoom(TutorialRoom):
|
|||
# we cannot move anywhere since no valid target was found.
|
||||
print "no valid teleport target for %s was found." % teleport_to
|
||||
return
|
||||
if character.player.is_superuser:
|
||||
if character.is_superuser:
|
||||
# superusers don't get teleported
|
||||
character.msg("Superuser block: You would have been teleported to %s." % results[0])
|
||||
return
|
||||
|
|
@ -610,347 +951,12 @@ class TeleportRoom(TutorialRoom):
|
|||
else:
|
||||
character.msg(self.db.failure_teleport_msg)
|
||||
# teleport quietly to the new place
|
||||
character.move_to(results[0], quiet=True)
|
||||
character.move_to(results[0], quiet=True, move_hooks=False)
|
||||
|
||||
|
||||
#------------------------------------------------------------
|
||||
#
|
||||
# Bridge - unique room
|
||||
#
|
||||
# Defines a special west-eastward "bridge"-room, a large room it takes
|
||||
# several steps to cross. It is complete with custom commands and a
|
||||
# chance of falling off the bridge. This room has no regular exits,
|
||||
# instead the exiting are handled by custom commands set on the player
|
||||
# upon first entering the room.
|
||||
#
|
||||
# Since one can enter the bridge room from both ends, it is
|
||||
# divided into five steps:
|
||||
# westroom <- 0 1 2 3 4 -> eastroom
|
||||
#
|
||||
#------------------------------------------------------------
|
||||
|
||||
|
||||
class CmdEast(Command):
|
||||
"""
|
||||
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 Attributes
|
||||
- tutorial_bridge_posistion: the current position on
|
||||
on the bridge, 0 - 4.
|
||||
|
||||
"""
|
||||
key = "east"
|
||||
aliases = ["e"]
|
||||
locks = "cmd:all()"
|
||||
help_category = "TutorialWorld"
|
||||
|
||||
def func(self):
|
||||
"move one step eastwards"
|
||||
caller = self.caller
|
||||
|
||||
bridge_step = min(5, caller.db.tutorial_bridge_position + 1)
|
||||
|
||||
if bridge_step > 4:
|
||||
# we have reached the far east end of the bridge.
|
||||
# Move to the east room.
|
||||
eexit = search_object(self.obj.db.east_exit)
|
||||
if eexit:
|
||||
caller.move_to(eexit[0])
|
||||
else:
|
||||
caller.msg("No east exit was found for this room. Contact an admin.")
|
||||
return
|
||||
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.execute_cmd("look")
|
||||
|
||||
|
||||
# go back across the bridge
|
||||
class CmdWest(Command):
|
||||
"""
|
||||
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"
|
||||
aliases = ["w"]
|
||||
locks = "cmd:all()"
|
||||
help_category = "TutorialWorld"
|
||||
|
||||
def func(self):
|
||||
"move one step westwards"
|
||||
caller = self.caller
|
||||
|
||||
bridge_step = max(-1, caller.db.tutorial_bridge_position - 1)
|
||||
|
||||
if bridge_step < 0:
|
||||
# we have reached the far west end of the bridge.
|
||||
# Move to the west room.
|
||||
wexit = search_object(self.obj.db.west_exit)
|
||||
if wexit:
|
||||
caller.move_to(wexit[0])
|
||||
else:
|
||||
caller.msg("No west exit was found for this room. Contact an admin.")
|
||||
return
|
||||
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 westwards across the bridge." % caller.name, exclude=caller)
|
||||
caller.execute_cmd("look")
|
||||
|
||||
|
||||
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 ...",
|
||||
"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.",
|
||||
"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 ...")
|
||||
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.",
|
||||
"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.",
|
||||
"Far below you the ocean roars and throws its waves against the cliff, as if trying its best to reach you.",
|
||||
"Parts of the bridge come loose behind you, falling into the chasm far below!",
|
||||
"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 ...",
|
||||
"The section of rope you hold onto crumble in your hands, parts of it breaking apart. You sway trying to regain balance.")
|
||||
|
||||
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.contents_get(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)
|
||||
|
||||
# there is a chance that we fall if we are on the western or central
|
||||
# part of the bridge.
|
||||
if bridge_position < 3 and random.random() < 0.05 and not self.caller.is_superuser:
|
||||
# we fall 5% of time.
|
||||
fall_exit = search_object(self.obj.db.fall_exit)
|
||||
if fall_exit:
|
||||
self.caller.msg("{r%s{n" % FALL_MESSAGE)
|
||||
self.caller.move_to(fall_exit[0], quiet=True)
|
||||
# inform others on the bridge
|
||||
self.obj.msg_contents("A plank gives way under %s's feet and " \
|
||||
"they fall from the bridge!" % self.caller.key)
|
||||
|
||||
|
||||
# custom help command
|
||||
class CmdBridgeHelp(Command):
|
||||
"""
|
||||
Overwritten help command while on the bridge.
|
||||
"""
|
||||
key = "help"
|
||||
aliases = ["h"]
|
||||
locks = "cmd:all()"
|
||||
help_category = "Tutorial world"
|
||||
|
||||
def func(self):
|
||||
"Implements the command."
|
||||
string = "You are trying hard not to fall off the bridge ..."
|
||||
string += "\n\nWhat you can do is trying to cross the bridge {weast{n "
|
||||
string += "or try to get back to the mainland {wwest{n)."
|
||||
self.caller.msg(string)
|
||||
|
||||
|
||||
class BridgeCmdSet(CmdSet):
|
||||
"This groups the bridge commands. We will store it on the room."
|
||||
key = "Bridge commands"
|
||||
priority = 1 # this gives it precedence over the normal look/help commands.
|
||||
def at_cmdset_creation(self):
|
||||
"Called at first cmdset creation"
|
||||
self.add(CmdTutorial())
|
||||
self.add(CmdEast())
|
||||
self.add(CmdWest())
|
||||
self.add(CmdLookBridge())
|
||||
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(WeatherRoom):
|
||||
"""
|
||||
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.
|
||||
|
||||
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 take several steps to cross it, despite it being represented
|
||||
by only a single room.
|
||||
|
||||
We divide the bridge into steps:
|
||||
|
||||
self.db.west_exit - - | - - self.db.east_exit
|
||||
0 1 2 3 4
|
||||
|
||||
The position is handled by a variable stored on the character
|
||||
when entering and giving special move commands will
|
||||
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):
|
||||
"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()
|
||||
# this identifies the exits from the room (should be the command
|
||||
# needed to leave through that exit). These are defaults, but you
|
||||
# could of course also change them after the room has been created.
|
||||
self.db.west_exit = "cliff"
|
||||
self.db.east_exit = "gate"
|
||||
self.db.fall_exit = "cliffledge"
|
||||
# add the cmdset on the room.
|
||||
self.cmdset.add_default(BridgeCmdSet)
|
||||
|
||||
def update_weather(self, *args, **kwargs):
|
||||
"""
|
||||
This is called at irregular intervals and makes the passage
|
||||
over the bridge a little more interesting.
|
||||
"""
|
||||
if random.random() < 80:
|
||||
# send a message most of the time
|
||||
self.msg_contents("{w%s{n" % random.choice(BRIDGE_WEATHER))
|
||||
|
||||
def at_object_receive(self, character, source_location):
|
||||
"""
|
||||
This hook is called by the engine whenever the player is moved
|
||||
into this room.
|
||||
"""
|
||||
if character.has_player:
|
||||
# we only run this if the entered object is indeed a player object.
|
||||
# check so our east/west exits are correctly defined.
|
||||
wexit = search_object(self.db.west_exit)
|
||||
eexit = search_object(self.db.east_exit)
|
||||
fexit = search_object(self.db.fall_exit)
|
||||
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.db.tutorial_bridge_position = 0
|
||||
return
|
||||
if source_location == eexit[0]:
|
||||
# we assume we enter from the same room we will exit to
|
||||
character.db.tutorial_bridge_position = 4
|
||||
else:
|
||||
# if not from the east, then from the west!
|
||||
character.db.tutorial_bridge_position = 0
|
||||
|
||||
def at_object_leave(self, character, target_location):
|
||||
"""
|
||||
This is triggered when the player leaves the bridge room.
|
||||
"""
|
||||
if character.has_player:
|
||||
# clean up the position attribute
|
||||
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" \
|
||||
|
||||
#-----------------------------------------------------------
|
||||
#
|
||||
# Intro Room - unique room
|
||||
#
|
||||
# This room marks the start of the tutorial. It sets up properties on
|
||||
# the player char that is needed for the tutorial.
|
||||
#
|
||||
#------------------------------------------------------------
|
||||
|
||||
class IntroRoom(TutorialRoom):
|
||||
"""
|
||||
Intro room
|
||||
|
||||
properties to customize:
|
||||
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):
|
||||
"""
|
||||
Assign properties on characters
|
||||
"""
|
||||
|
||||
# setup character for the tutorial
|
||||
health = self.db.char_health or 20
|
||||
|
||||
if character.has_player:
|
||||
character.db.health = health
|
||||
character.db.health_max = health
|
||||
|
||||
if character.is_superuser:
|
||||
string = "-"*78 + SUPERUSER_WARNING + "-"*78
|
||||
character.msg("{r%s{n" % string.format(name=character.key, quell="{w@quell{r"))
|
||||
|
||||
|
||||
#------------------------------------------------------------
|
||||
#
|
||||
# Outro room - unique room
|
||||
# Outro room - unique exit room
|
||||
#
|
||||
# Cleans up the character from all tutorial-related properties.
|
||||
#
|
||||
|
|
@ -989,6 +995,4 @@ class OutroRoom(TutorialRoom):
|
|||
del character.db.puzzle_clue
|
||||
del character.db.combat_parry_mode
|
||||
del character.db.tutorial_bridge_position
|
||||
for tut_obj in [obj for obj in character.contents
|
||||
if utils.inherits_from(obj, TutorialObject)]:
|
||||
tut_obj.reset()
|
||||
character.tags.clear(category="tutorial_world")
|
||||
|
|
|
|||
|
|
@ -557,7 +557,7 @@ class DefaultObject(ObjectDB):
|
|||
obj.msg(message, from_obj=from_obj, **kwargs)
|
||||
|
||||
def move_to(self, destination, quiet=False,
|
||||
emit_to_obj=None, use_destination=True, to_none=False):
|
||||
emit_to_obj=None, use_destination=True, to_none=False, move_hooks=True):
|
||||
"""
|
||||
Moves this object to a new location.
|
||||
|
||||
|
|
@ -568,23 +568,26 @@ class DefaultObject(ObjectDB):
|
|||
function, such things are assumed to have been handled before calling
|
||||
move_to.
|
||||
|
||||
destination: (Object) Reference to the object to move to. This
|
||||
can also be an exit object, in which case the destination
|
||||
property is used as destination.
|
||||
quiet: (bool) If true, don't emit left/arrived messages.
|
||||
emit_to_obj: (Object) object to receive error messages
|
||||
use_destination (bool): Default is for objects to use the "destination"
|
||||
property of destinations as the target to move to.
|
||||
Turning off this keyword allows objects to move
|
||||
"inside" exit objects.
|
||||
to_none - allow destination to be None. Note that no hooks are run when
|
||||
moving to a None location. If you want to run hooks,
|
||||
run them manually (and make sure they can manage None
|
||||
locations).
|
||||
Args:
|
||||
destination (Object): Reference to the object to move to. This
|
||||
can also be an exit object, in which case the
|
||||
destination property is used as destination.
|
||||
quiet (bool): If true, turn off the calling of the emit hooks
|
||||
(announce_move_to/from etc)
|
||||
emit_to_obj (Object): object to receive error messages
|
||||
use_destination (bool): Default is for objects to use the "destination"
|
||||
property of destinations as the target to move to. Turning off this
|
||||
keyword allows objects to move "inside" exit objects.
|
||||
to_none (bool): Allow destination to be None. Note that no hooks are run when
|
||||
moving to a None location. If you want to run hooks, run them manually
|
||||
(and make sure they can manage None locations).
|
||||
move_hooks (bool): If False, turn off the calling of move-related hooks (at_before/after_move etc)
|
||||
with quiet=True, this is as quiet a move as can be done.
|
||||
|
||||
Returns True/False depending on if there were problems with the move.
|
||||
This method may also return various error messages to the
|
||||
emit_to_obj.
|
||||
Returns:
|
||||
result (bool): True/False depending on if there were problems with the move.
|
||||
This method may also return various error messages to the
|
||||
emit_to_obj.
|
||||
"""
|
||||
def logerr(string=""):
|
||||
trc = traceback.format_exc()
|
||||
|
|
@ -609,14 +612,15 @@ class DefaultObject(ObjectDB):
|
|||
destination = destination.destination
|
||||
|
||||
# Before the move, call eventual pre-commands.
|
||||
try:
|
||||
if not self.at_before_move(destination):
|
||||
return
|
||||
except Exception:
|
||||
logerr(errtxt % "at_before_move()")
|
||||
#emit_to_obj.msg(errtxt % "at_before_move()")
|
||||
#logger.log_trace()
|
||||
return False
|
||||
if move_hooks:
|
||||
try:
|
||||
if not self.at_before_move(destination):
|
||||
return
|
||||
except Exception:
|
||||
logerr(errtxt % "at_before_move()")
|
||||
#emit_to_obj.msg(errtxt % "at_before_move()")
|
||||
#logger.log_trace()
|
||||
return False
|
||||
|
||||
# Save the old location
|
||||
source_location = self.location
|
||||
|
|
@ -630,13 +634,14 @@ class DefaultObject(ObjectDB):
|
|||
source_location = default_home
|
||||
|
||||
# Call hook on source location
|
||||
try:
|
||||
source_location.at_object_leave(self, destination)
|
||||
except Exception:
|
||||
logerr(errtxt % "at_object_leave()")
|
||||
#emit_to_obj.msg(errtxt % "at_object_leave()")
|
||||
#logger.log_trace()
|
||||
return False
|
||||
if move_hooks:
|
||||
try:
|
||||
source_location.at_object_leave(self, destination)
|
||||
except Exception:
|
||||
logerr(errtxt % "at_object_leave()")
|
||||
#emit_to_obj.msg(errtxt % "at_object_leave()")
|
||||
#logger.log_trace()
|
||||
return False
|
||||
|
||||
if not quiet:
|
||||
#tell the old room we are leaving
|
||||
|
|
@ -667,25 +672,27 @@ class DefaultObject(ObjectDB):
|
|||
#logger.log_trace()
|
||||
return False
|
||||
|
||||
# Perform eventual extra commands on the receiving location
|
||||
# (the object has already arrived at this point)
|
||||
try:
|
||||
destination.at_object_receive(self, source_location)
|
||||
except Exception:
|
||||
logerr(errtxt % "at_object_receive()")
|
||||
#emit_to_obj.msg(errtxt % "at_object_receive()")
|
||||
#logger.log_trace()
|
||||
return False
|
||||
if move_hooks:
|
||||
# Perform eventual extra commands on the receiving location
|
||||
# (the object has already arrived at this point)
|
||||
try:
|
||||
destination.at_object_receive(self, source_location)
|
||||
except Exception:
|
||||
logerr(errtxt % "at_object_receive()")
|
||||
#emit_to_obj.msg(errtxt % "at_object_receive()")
|
||||
#logger.log_trace()
|
||||
return False
|
||||
|
||||
# Execute eventual extra commands on this object after moving it
|
||||
# (usually calling 'look')
|
||||
try:
|
||||
self.at_after_move(source_location)
|
||||
except Exception:
|
||||
logerr(errtxt % "at_after_move")
|
||||
#emit_to_obj.msg(errtxt % "at_after_move()")
|
||||
#logger.log_trace()
|
||||
return False
|
||||
if move_hooks:
|
||||
try:
|
||||
self.at_after_move(source_location)
|
||||
except Exception:
|
||||
logerr(errtxt % "at_after_move")
|
||||
#emit_to_obj.msg(errtxt % "at_after_move()")
|
||||
#logger.log_trace()
|
||||
return False
|
||||
return True
|
||||
|
||||
def clear_exits(self):
|
||||
|
|
@ -810,12 +817,6 @@ class DefaultObject(ObjectDB):
|
|||
|
||||
for script in _ScriptDB.objects.get_all_scripts_on_obj(self):
|
||||
script.stop()
|
||||
#for script in _GA(self, "scripts").all():
|
||||
# script.stop()
|
||||
|
||||
# if self.player:
|
||||
# self.player.user.is_active = False
|
||||
# self.player.user.save(
|
||||
|
||||
# Destroy any exits to and from this room, if any
|
||||
self.clear_exits()
|
||||
|
|
@ -828,7 +829,6 @@ class DefaultObject(ObjectDB):
|
|||
# Perform the deletion of the object
|
||||
super(ObjectDB, self).delete()
|
||||
return True
|
||||
# methods inherited from the typeclass system
|
||||
|
||||
|
||||
def __eq__(self, other):
|
||||
|
|
@ -892,7 +892,6 @@ class DefaultObject(ObjectDB):
|
|||
if cdict.get("location"):
|
||||
cdict["location"].at_object_receive(self, None)
|
||||
self.at_after_move(None)
|
||||
|
||||
if cdict.get("attributes"):
|
||||
# this should be a dict of attrname:value
|
||||
keys, values = cdict["attributes"].keys(), cdict["attributes"].values()
|
||||
|
|
|
|||
|
|
@ -446,7 +446,6 @@ class TypedObject(SharedMemoryModel):
|
|||
self.aliases.clear()
|
||||
if hasattr(self, "nicks"):
|
||||
self.nicks.clear()
|
||||
self.flush_from_cache()
|
||||
|
||||
# scrambling properties
|
||||
self.delete = self._deleted
|
||||
|
|
|
|||
|
|
@ -128,25 +128,27 @@ def _batch_create_object(*objparams):
|
|||
creation/add handlers in the following order:
|
||||
(create, permissions, locks, aliases, nattributes, attributes)
|
||||
Returns:
|
||||
A list of created objects
|
||||
objects (list): A list of created objects
|
||||
|
||||
"""
|
||||
|
||||
# bulk create all objects in one go
|
||||
dbobjs = [ObjectDB(**objparam[0]) for objparam in objparams]
|
||||
# unfortunately this doesn't work since bulk_create don't creates pks;
|
||||
|
||||
# unfortunately this doesn't work since bulk_create doesn't creates pks;
|
||||
# the result are double objects at the next stage
|
||||
#dbobjs = _ObjectDB.objects.bulk_create(dbobjs)
|
||||
|
||||
dbobjs = [ObjectDB(**objparam[0]) for objparam in objparams]
|
||||
objs = []
|
||||
for iobj, obj in enumerate(dbobjs):
|
||||
# call all setup hooks on each object
|
||||
objparam = objparams[iobj]
|
||||
# setup
|
||||
obj._createdict = {"pernmissions": objparam[1],
|
||||
obj._createdict = {"permissions": objparam[1],
|
||||
"locks": objparam[2],
|
||||
"aliases": objparam[3],
|
||||
"attributes": objparam[4],
|
||||
"nattributes": objparam[5]}
|
||||
"nattributes": objparam[4],
|
||||
"attributes": objparam[5]}
|
||||
# this triggers all hooks
|
||||
obj.save()
|
||||
objs.append(obj)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue