building a better DoGo, DoEnter, etc.
Posted: Mon Dec 31, 2012 6:21 pm
So, while working on Clockwork Boy 2, I had the show_commands option on my undolib extension enabled. When the player undo's, the command being undone is printed for the player, along the lines of "[ undoing >GO NORTH ]".
Anyhow, I picked up some odd behavior with DoEnter. Eventually, I noticed that DoEnter has this code:
Now, I've done a handful of little changes to DoGo that I'm not even sure if the above is still a problem. Plus, I think parts of DoEnter and DoGo are so old that they predate hugolib additions like SetupDirectionObjects.
My feeling is that in DoEnter, DoGo, and possibly even DoExit (well, my main feeling for DoExit is that maybe in some cases, it should call DescribePlace after a successful exit) have unnecessary or unrefined code and could use a good looking-over.
Like my checkheld post, this is just a call for people to do what they can to break these routines or make suggestions.
Here is my latest version of DoEnter:(I don't think much is changed with that one)
And DoGo:
Most recently, I added code to properly direct to the "you're already there"-type when you type "in" while already in an enterable object. I also added some code so that having a room exit like "in_to wardrobe", where wardrobe is an enterable object and not a room, calls DoEnter and doesn't just use MovePlayer to move the player.
Anyhow, I picked up some odd behavior with DoEnter. Eventually, I noticed that DoEnter has this code:
Code: Select all
! To prevent endless loops if the player_character class
! automatically resets the object to in_obj if word[1] = "in"
word[1] = ""
My feeling is that in DoEnter, DoGo, and possibly even DoExit (well, my main feeling for DoExit is that maybe in some cases, it should call DescribePlace after a successful exit) have unnecessary or unrefined code and could use a good looking-over.
Like my checkheld post, this is just a call for people to do what they can to break these routines or make suggestions.
Here is my latest version of DoEnter:
Code: Select all
replace DoEnter
{
#ifclear NO_OBJLIB
if not object or object in direction
#else
if not object
#endif
{
local i, obj, count
for i in location
{
if i is enterable
{
obj = i
count++
if count = 2
break
}
}
if count = 1
{
object = obj
}
else
{
VMessage(&DoEnter, 1) ! "Be a little more specific..."
return false
}
return Perform(&DoEnter, object)
}
! To prevent endless loops if the player_character class
! automatically resets the object to in_obj if word[1] = "in"
! word[1] = "" ! causing problems
if &object.door_to
return Perform(&DoGo, object) ! routine
elseif object.door_to
return Perform(&DoGo, object) ! object
if object is not enterable or Contains(player, object)
VMessage(&DoEnter, 2) ! "You can't enter that."
elseif player in object
VMessage(&DoEnter, 3) ! already in it
elseif player not in location
VMessage(&DoGo, 3) ! "You'll have to get up..."
elseif object is openable, not open
VMessage(&DoLookIn, 1) ! "X is closed."
else
{
move player to object
if not object.after
VMessage(&DoEnter, 4) ! "You get in..."
object is not quiet
DescribePlace(location)
return true
}
return
}
And DoGo:
Code: Select all
replace DoGo
{
local moveto, JumpToEnd
#ifset NO_OBJLIB
local wordnum, m
#endif
if player not in location ! sitting on or in an obj.
{
#ifclear NO_OBJLIB
if (object ~= parent(player) and not (object in direction and
parent(player) = location.(object.dir_to))) and
((object ~= u_obj and parent(player) is platform) or
(object ~= out_obj and parent(player) is container))
{
VMessage(&DoGo, 3) ! "You'll have to get up..."
return false
}
#endif
local b
b = parent(player).before ! i.e., a vehicle, etc.
if b > 1 ! is b a direction?
return Perform(&DoExit,parent(player))
elseif b
return false ! so the error message doesn't take up a turn
}
elseif obstacle
{
#ifclear NO_OBJLIB
VMessage(&DoGo, 1) ! "X stops you from going..."
return true
#endif
}
#ifclear NO_OBJLIB
! See if the object is one of the current direction set
if object.type = direction and object in direction
{
moveto = object
JumpToEnd = true
}
#endif
if not JumpToEnd
{
#ifclear NO_OBJLIB
if not moveto
{
#else
wordnum = 1 ! various phrasings
if words > 1 and word[2] ~= ""
wordnum = 2
if word[2] = "to", "through"
wordnum = 3
elseif (word[2] = "in" or word[2] = "inside") and words > 2
wordnum = 3
select word[wordnum]
case "north", "n": m = n_to
case "south", "s": m = s_to
case "east", "e": m = e_to
case "west", "w": m = w_to
case "northwest", "nw": m = nw_to
case "northeast", "ne": m = ne_to
case "southeast", "se": m = se_to
case "southwest", "sw": m = sw_to
case "up", "u": m = u_to
case "down", "d": m = d_to
case "in", "inside": m = in_to
case "out", "outside": m = out_to
if not m
{
#endif
if not object
{
! ParseError(6) ! doesn't make any sense
VMessage(&DoGo, 4) ! "Which way...?"
return
}
if not &object.door_to
{
if not object.door_to and object is enterable
return Perform(&DoEnter, object)
}
moveto = object.door_to
if not moveto
{
VMessage(&DoEnter, 2) ! "You can't enter..."
return
}
if moveto = 1
return true
}
} ! if not JumpToEnd bracket
#ifclear NO_OBJLIB
if moveto.type = direction and moveto in direction
{
if player not in location and object = out_obj
{
if parent(player) is platform
{
VMessage(&DoGo, 3)
return false
}
else
return Perform(&DoExit)
}
elseif player not in location and object = u_obj
{
if parent(player) is container
{
VMessage(&DoGo, 3)
return false
}
else
return Perform(&DoExit, parent(player))
}
if not object
{
object = moveto
if object.before
return true
}
! else: object = moveto
moveto = location.(moveto.dir_to)
if &moveto.door_to or moveto.type = door
{
moveto = moveto.door_to
}
elseif moveto is enterable and
((moveto is platform) or (moveto is container)) and
player in location
return Perform(&DoEnter, moveto)
}
#else
if m
{
if player not in location and m = out_to
{
if parent(player) is platform
{
VMessage(&DoGo, 3)
return false
}
else
return Perform(&DoExit)
}
elseif player not in location and m = u_to
{
if parent(player) is container
{
VMessage(&DoGo, 3)
return false
}
else
return Perform(&DoExit, parent(player))
}
moveto = location.m
if moveto.door_to
moveto = moveto.door_to
}
#endif
if moveto = false
{
if not location.cant_go
VMessage(&DoGo, 2) ! "You can't go that way."
return false
}
elseif moveto = true ! already printed message
return true ! (moveto is never 1)
elseif player not in location ! sitting on or in an obj.
{
if parent(player) = moveto
VMessage(&DoEnter, 3) ! already in it
else
VMessage(&DoGo, 3) ! "You'll have to get up..."
}
else
{
!\ Recursive call issues
m = verbroutine ! check room exiting
verbroutine = &DoExit
if location.before
return true
verbroutine = m
\!
MovePlayer(moveto)
return true
}
}