MovePlayer
MovePlayer
is a routine specifically written for moving the player to
another location, saving us the trouble of updating the
[location global, among other things. For
instance, it also checks to checks that the new location has a light
source and runs DarkWarning
, if necessary. Let’s break it down:
The first argument (loc
or dir
) is either the location object we are
moving the player to or a direction object (n_to, e_to, etc.). If it’s
the latter, MovePlayer
only moves the player if it’s a valid
direction.
The second argument (silent
) determines whether
DescribePlace should be executed after we
move the player, giving the name and description of the new location.
The last argument (ignore
) determines whether we want to run any
player.before
or player.after
code. Imagine a game where moving the
player (such as the wand or >XYZZY in Adventure) gives him an odd
feeling:
player_character you "you"
{
before
{
actor MovePlayer
{
"Your whole body tingles."
return false ! so the player still is moved by MovePlayer
}
}
after
{
actor MovePlayer
{
"The odd tingling subsides."
return true
}
}
}
Having an ignore
value would skip both of those statements.
Ta-da!
the code
For the sake of browsing, here is the routine itself:
!----------------------------------------------------------------------------
! MovePlayer(location[, silent])
! moves the player to the object <location>, with no description if <silent>
! is true
!
! MovePlayer(direction[, silent[, ignore]])
! moves player in <direction>, where <direction> is a direction object.
! If <ignore> is true, before/after routines relating to the move are
! not checked.
!
! MovePlayer calls DarkWarning when there is no light source in the new
! location; replace it with a new DarkWarning routine for a more elaborate
! response, such as the possible demise of the player
routine MovePlayer(loc, silent, ignore)
{
local v, obj, xobj, act, ret
#ifclear NO_OBJLIB
if loc.type = direction
{
local l
l = location.(loc.dir_to)
if l > 1 ! since a message always returns 1
loc = l
else
return
}
#endif
#ifset USE_ATTACHABLES
if ObjectisAttached(player, location, loc)
return
#endif
! Check if there's a before routine for MovePlayer in the new
! location. Note that the (potential) new location and the old
! location are stored in object and xobject, respectively.
!
v = verbroutine
obj = object
xobj = xobject
act = actor
verbroutine = &MovePlayer
object = loc
xobject = location
actor = player
if not ignore
{
ret = player.before
if ret: jump LeaveMovePlayer
ret = location.before
if ret: jump LeaveMovePlayer
ret = loc.before
if ret: jump LeaveMovePlayer
}
move player to loc
old_location = location
if parent(loc) = 0 ! if it's likely a room object
location = loc
else ! if it's an enterable object
location = parent(loc) ! (noting that the object must be
! in a room, not inside another
! non-room object)
#ifset USE_ATTACHABLES
MoveAllAttachables(player, old_location, location)
#endif
PrintStatusline
:LeaveMovePlayer
if not ret
{
if not FindLight(location)
DarkWarning
elseif not silent
{
DescribePlace(location)
event_flag = true
location is visited
}
! Check if there's an after routine for MovePlayer in the new
! location:
!
if not ignore
{
ret = player.after
if not ret
ret = location.after
}
}
verbroutine = v
object = obj
xobject = xobj
actor = act
return ret
}