Redirect actions break 'for X turn' syntax

In one of my projects, I have some complex action integration where I have one ‘main action’ with two nouns, and some ‘helper actions’ with one noun that redirect onto the main action. This works perfectly, except for one small detail: Any rules that trigger of the main action happening for X turns don’t take into account when the main action was triggered by one of the helper actions. I suspect this is due the previous action variable being updated with the action that finished last. The following is a modified example that should illustrate the issue (it’s not my production code, but it’s the same functionality if not complexity):

[rant=Example]Volume 1 - Concepts

Book 1.1 - Cameras

A camera is a kind of thing.
A camera has a number called picture quality.
Definition: a camera is sharp if its picture quality is 5 or more.

Book 1.2 - Actions

Part 1.2.1 - Photographing With

Photographing it with is an action applying to one visible thing and one touchable thing and requiring light.
Understand "photograph [something] with [something]" as photographing it with.
Does the player mean photographing something with a camera: It is likely.

Check an actor photographing something with (this is the photography requires camera rule):
	Unless the second noun is a camera:
		Say "You can hardly photograph without a camera, now can you?" (A);
		Stop the action;

Check an actor photographing something with (this is the report photography rule):
	Say "[The actor] snaps a photo of [the noun] with [the second noun]." (A);

Part 1.2.2 - Photographing Redirect

Photographing is an action applying to one visible thing and requiring light.

Understand "photograph [something]" as photographing.

Before an actor photographing (this is the photography redirect rule):
	Let C be the sharpest camera which is carried by the actor;
	Try the actor photographing the noun with C instead;

Volume 2 - Testing

Book 2.1 - The World

The Studio is a room.

Sally is a woman in the Studio.
A foam-lined tote bag is in the Studio.

The digital SLR camera is a camera in the tote bag. The picture quality of the digital SLR camera is 10.
The player carries a camera called the instant one-shot camera. The picture quality of the one-shot camera is 2.

Book 2.2 - The Test Breaker

Before photographing something with a camera for more than one turn, say "Try some variety for a change?" instead.
Before photographing something with a camera for more than one time, say "Again?"

Test me with "photograph Sally / g / photograph Sally with one-shot / g"[/rant]

Changing the redirect rule to ‘before’ or ‘instead’ gives the same result.

I’ve tried recreating the logic using various other methods, which have usually ended in “you have to supply a second noun” issues. Does anyone have a good idea on how to get around this without having to resort to intercepting and rearranging the command before it’s parsed?

Drop the “for more than one turn” clauses. Create explicit global flags and write an “every turn” rule that resets the flags.

That was one of the options I was considering, but as this is an extension meant for others to use it bugs me when I have to deviate from the built-in rules syntax. Is there no I6 magic that can help?

It’s not I6 magic, but there is this:

Photographing something with a camera is photography. Photographing is photography.
Instead of photography for more than one turn, say "Try some variety for a change?".
Instead of photography for more than one time, say "Again?".

(But you’d probably do better to follow zarf’s advice…)

It’s not deviating, it’s using a simpler built-in syntax.

“For N turns” is a fancy way of setting up a counter and an every-turn rule. “If we have photographed” is a fancy way of setting up a flag. You don’t have to be fancy.

Thanks for the feedback guys, I’ll probably use the global variable and turn rule, wrapping access to it in a phrase or definition.

On a related note, I’m trying to store the previous action as a stored action in a global variable aptly called the previous action.

The previous action is a stored action that varies.
Every turn, now the previous action is the current action;

This works beautifully, but only while the player is the actor. When persuasion is introduced, the action that gets stored is waiting. Writing with Inform is uncharacteristically silent on the matter, so can I reach the other actor’s action in some way? I was thinking of having a first persuasion rule that just captures actor, action name and the nouns without passing judgment, but that sounds like a crude hack.

What if you try it as a “First before”?

That could work, with some minor adjustments. The before rules are run for all actions, not just the one the player ordered. We’d also need to store it in a temporary variable, swapping around at the end of the turn (to not overwrite the previous action prematurely).

This works for capturing the actual action resulting from the player’s command, with extendable functionality to ignore redirect actions. It includes some debug output you’ll obviously want to remove from the final product.

The previous turn count is initially -1.
The pending previous action is a stored action that varies.
The previous action is a stored action that varies.

[We mark some actions as redirects that we don't want to store]
Photographing is redirecting.

First before an actor doing something:
	Say "DEBUG: [turn count]/[previous turn count]: [the current action]";
	Unless the previous turn count is the turn count:
		Unless the current action is redirecting:
			Increase the previous turn count by 1;
			Now the pending previous action is the current action;
		Otherwise:
			Say " (redirect)";
	Otherwise:
		Say " (multiple)";

Last every turn rule, now the previous action is the pending previous action.