This works.
lab is room.
Dummying is an action applying to nothing.
clone-action is initially the action of dummying.
setting action variables when not looking after going:
if the actor is the player begin;
now the actor is the clone;
now clone-action is the current action;
now the actor is the player;
else;
now the clone-action is the action of dummying;
end if.
clone is a person in the lab.
every turn when the action name part of the clone-action is not dummying action:
try the clone-action.
parlor is east of lab.
Include (-
Global looking_after_going = 0;
[ LookAfterGoing;
looking_after_going = 1;
GoingLookBreak();
AbbreviatedRoomDescription();
looking_after_going = 0;
];
-) replacing "LookAfterGoing".
to decide if looking after going: (- looking_after_going -).
It was a pain in the butt for me to figure this out. There’s a lot of stuff that isn’t documented and can’t even be found in the Standard Rules, but takes delving through the Inform 6 code in the kits to find. (And sometimes it’s not even there and you have to look at the Inform 7 compiler itself to try to figure something out.)
Report going implicitly invokes a look action to print a new room description. At the I6 level this is mostly a real action, but it’s not the equivalent of saying try looking
in I7. So without the looking_after_going
tracking above, the sequence would be:
beginning of player going east action
setting action variables sets clone-action to clone going east
carry out player going east: the player is actually moved east
report the player going east: invoke the implicit look action
beginning of player looking action
setting action variables sets clone-action to clone looking
carry out the player looking
end of player looking
end of player going east action
[...]
and now when we get to the every turn rule, clone-action is set to clone looking but it’s also the case that noun
is still set to east
from the player going east action. So ActionPrimitive (in Actions.i6t) balks with the Action Processing Rule Response ‘K’ because it knows that looking is an action applying to nothing, so something must be wrong if noun isn’t nothing, 'cause it expects the parser would have prevented this situation from coming about.
This happens before the before rules, before even the setting action variable rules, so there’s no good way to intervene at the I7 level. From Actions.i6t:
@h Abbreviated Room Description.
This is used when we want a room description with the same abbreviation
conventions as after a going action, and we don’t quite want a looking
action fully to take place. We nevertheless want to be sure that the
action variables for looking exist, and in particular, we want to set the
“room-describing action” variable to the action which was prevailing
when the room description was called for. We also set “abbreviated form
allowed” to “true”: when the ordinary looking action is running, this
is “false”.
The actual description occurs during |LookSub|, which is the specific
action processing stage for the “looking” action: thus, we use the
check, carry out, after and report rules as if we were “looking”, but
are unaffected by before or instead rules.
Uniquely, this pseudo-action does not use |BeginAction|: it works only
through the specific action processing rules, not the main action-processing
ones, though that is not easy to see from the code below because it is
hidden in the call to |LookSub|.
Edited: actually there’s still a big problem here for other player actions that invoke actions within them. What we could really use is the same action nesting level we get from the actions
command, but that doesn’t exist when compiling for release. So we replace ActionPrimitive just to add a couple lines to track nesting level:
Include (-
Global action_nesting_level = 0;
[ ActionPrimitive rv p1 p2 p3 p4 p5 frame_id;
MStack_CreateRBVars(ACTION_PROCESSING_RB);
if ((keep_silent == false) && (multiflag == false)) DivideParagraphPoint();
reason_the_action_failed = 0;
frame_id = -1;
p1 = FindAction(action);
if ((p1) && (ActionData-->(p1+AD_VARIABLES_CREATOR))) {
frame_id = ActionData-->(p1+AD_VARIABLES_ID);
Mstack_Create_Frame(ActionData-->(p1+AD_VARIABLES_CREATOR), frame_id);
}
if (ActionVariablesNotTypeSafe()) {
if (actor ~= player) { ACTION_PROCESSING_INTERNAL_RM('K'); new_line; }
if (frame_id ~= -1)
Mstack_Destroy_Frame(ActionData-->(p1+AD_VARIABLES_CREATOR), frame_id);
MStack_DestroyRBVars(ACTION_PROCESSING_RB);
return;
}
FollowRulebook(SETTING_ACTION_VARIABLES_RB);
if (actor == player) action_nesting_level++;
#IFDEF DEBUG;
if ((trace_actions) && (FindAction(-1)) && (action ~= ##ActionsOn) && (action ~= ##ActionsOff)) {
print "["; p1=actor; p2=act_requester; p3=action; p4=noun; p5=second;
DB_Action(p1,p2,p3,p4,p5);
print "]^"; ClearParagraphing(5);
}
++debug_rule_nesting;
#ENDIF;
TrackActions(false, meta);
if ((meta) && (actor ~= player)) {
ACTION_PROCESSING_INTERNAL_RM('A', actor); new_line; rv = RS_FAILS; }
else if (meta) { DESCEND_TO_SPECIFIC_ACTION_R(); rv = RulebookOutcome(); }
else { FollowRulebook(ACTION_PROCESSING_RB); rv = RulebookOutcome(); }
if (actor == player) action_nesting_level--;
#IFDEF DEBUG;
--debug_rule_nesting;
if ((trace_actions) && (FindAction(-1)) && (action ~= ##ActionsOn) && (action ~= ##ActionsOff)) {
print "["; DB_Action(p1,p2,p3,p4,p5); print " - ";
switch (rv) {
RS_SUCCEEDS: print "succeeded";
RS_FAILS: print "failed";
if (reason_the_action_failed)
print " the ",
(RulePrintingRule) reason_the_action_failed;
default: print "ended without result";
}
print "]^"; say__p = 1;
}
print "]^"; say__p = 1;
SetRulebookOutcome(rv); ! In case disturbed by printing activities
}
#ENDIF;
if (rv == RS_SUCCEEDS) UpdateActionBitmap();
if (frame_id ~= -1) {
p1 = FindAction(action);
Mstack_Destroy_Frame(ActionData-->(p1+AD_VARIABLES_CREATOR), frame_id);
}
MStack_DestroyRBVars(ACTION_PROCESSING_RB);
if ((keep_silent == false) && (multiflag == false)) DivideParagraphPoint();
if (rv == RS_SUCCEEDS) rtrue;
rfalse;
];
-) replacing "ActionPrimitive".
and then this is a better, more general approach – we no longer need to track look after going.
lab is room.
Dummying is an action applying to nothing.
clone-action is initially the action of dummying.
setting action variables when top level action:
if the actor is the player begin;
now the actor is the clone;
now clone-action is the current action;
now the actor is the player;
else;
now the clone-action is the action of dummying;
end if.
clone is a person in the lab.
every turn when the clone-action is not dummying:
try the clone-action.
parlor is east of lab.
to decide if top level action: (- ~~action_nesting_level -).