Mainly, the issue is this: especially when an author is new to Hugo, one of the most appealing ways to give special responses is to use the before property routine system. In some of these cases, the author will want to do something like a "You can't get pass the rubble." message. "You can't go that way." messages normally don't use up a turn, so it's kind of jarring when there's no easy way to use a before property routine and have a matching behavior.
So, today, I attempted to allow for cases like this. Here is the necessary code:
Code: Select all
global force_false
replace Perform(action, obj, xobj, queue, isxverb)
{
local r
local objtemp, xobjtemp, verbtemp, actortemp, first_call
#ifclear NO_XVERBS
local restoring
if verbroutine = &DoRestore: restoring = true
#endif
if action = verbroutine and obj = object and xobj = xobject
first_call = true
#ifset DEBUG
if debug_flags & D_PARSE
{
print "\B[Perform("; number action; ", "; obj.name;
if (debug_flags & D_OBJNUM) or queue = -1
print " ["; number obj; "]";
print ", "; xobj.name;
if (debug_flags & D_OBJNUM) or queue = -1
print " ["; number xobj; "]";
if queue
print ", "; number queue;
print ")]\b"
}
#endif
if queue
parser_data[PARSER_STATUS] |= PERFORM_QUEUE
if not queue and object
parser_data[LAST_SINGLE_OBJECT] = object
else
parser_data[LAST_SINGLE_OBJECT] = 0
parser_data[VERB_IS_XVERB] = isxverb
! These temp objects guarantee we go back to whatever the previous
! settings were before Perform was called
objtemp = object
xobjtemp = xobject
verbtemp = verbroutine
actortemp = actor
object = obj
xobject = xobj
verbroutine = action
actor = player
! some stuff we do when Perform is called by the engine
if (parser_data[PARSER_STATUS] & PARSER_ACTIVE) and not isxverb
DeactivateParser
#ifclear NO_OBJLIB
if verbroutine = &DoGo and not object
SetupDirectionObjects
#endif
! Itemize each object in a list of multiple objects
if queue > 0 and object > display
{
#ifset USE_CHECKHELD
! Check if an ImplicitTakeForDrop was just done, meaning we
! need a newline before printing the next "object:"
if checkheld is workflag
print ""
checkheld is not workflag
#endif
print object.name; ": ";
}
r = BeforeRoutines(queue)
if not r ! if action not stopped by before routines
{
r = call action ! object.after and xobject.after
! run by verbroutine
#ifclear NO_XVERBS
if restoring
verbroutine = &DoRestore
#endif
if r ! if action was successful, run after routines
{
AfterRoutines
}
}
!:DonePerform area
#ifset USE_CHECKHELD
ResetCheckHeld
#endif
last_object = object
verbroutine = verbtemp
object = objtemp
xobject = xobjtemp
actor = actortemp
if queue = -1
last_object = -1
parser_data[PARSER_STATUS] = PARSER_RESET
if force_false and first_call
{
force_false = 0
if not queue
return false
}
return r
}
So then we could have code like this for, say, a mine shaft or something:
Code: Select all
before
{
object DoGo
{
if rubble in location
{
"You can't get past the rubble."
force_false = true
return true
}
else
return false
}
}