Actions register as successful if persuasion succeeds but action fails?

In the following scenario, the every turn rule indicates that the ball has been waved, even though no actor has done so.

"Success?"

Place is a room.

Bob is a man in Place.

A persuasion rule:
    persuasion succeeds.

A ball is in Place.

Every turn:
    if we have waved the ball:
	    say "Yep.";
    otherwise:
	    say "Nope."

Test me with "z / bob, wave ball".

With actions on, the output is:

>BOB, WAVE BALL
[asking Bob to try waving the ball]
[(1) Bob waving the ball]
[(1) Bob waving the ball - failed the can't wave what's not held rule]

Bob is unable to do that.

[asking Bob to try waving the ball - succeeded]

Yep.

Is this expected behavior?

1 Like

It looks like the issue is arising in ActionPrimitive(), which contains the line:

if (rv == RS_SUCCEEDS) UpdateActionBitmap();

It seems that UpdateActionBitmap() is being executed in response to the success of the outer asking Bob to try waving the ball action.

A modification of the line to

if (rv == RS_SUCCEEDS && (~~act_requester)) UpdateActionBitmap(); ! MODIFIED

seems to correct the issue. The following block can be added to any project.

replacement code
Include (-

! ==== ==== ==== ==== ==== ==== ==== ==== ==== ====
! Actions.i6t: Action Primitive (modified)
! ==== ==== ==== ==== ==== ==== ==== ==== ==== ====

[ 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);

    #IFDEF DEBUG;
    if ((trace_actions) && (FindAction(-1))) {
	    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(); }
    #IFDEF DEBUG;
    --debug_rule_nesting;
    if ((trace_actions) && (FindAction(-1))) {
	    print "["; DB_Action(p1,p2,p3,p4,p5); print " - ";
	    switch (rv) {
		    RS_SUCCEEDS: print "succeeded";
		    RS_FAILS: print "failed";
			    #IFNDEF MEMORY_ECONOMY;
			    if (reason_the_action_failed)
				    print " the ",
					    (RulePrintingRule) reason_the_action_failed;
		        #ENDIF;
		    default: print "ended without result";
	    }
	    print "]^"; say__p = 1;
	    SetRulebookOutcome(rv); ! In case disturbed by printing activities
    }
    #ENDIF;
    if (rv == RS_SUCCEEDS && (~~act_requester)) UpdateActionBitmap(); ! MODIFIED
    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;
];
-) instead of "Action Primitive" in "Actions.i6t".
3 Likes