Commanding multiple actors at the same time

Okay, this was much messier than I had expected it to be. But here’s an implementation that parses each command separately. If you include my extension “Modified Timekeeping” a multi-command takes only one turn, as it ought to, rather than one turn for each actor.

Include Editable Stored Actions by Ron Newcomb.

Commanding it to is an action out of world applying to one visible thing and one topic. Understand "tell [things] to [text]" or "command [things] to [text]" as commanding it to.

The multicommand text is text that varies. The multicommand actor list is a list of objects that varies. The multicommand action list is a list of stored actions that varies. The multicommand flag is initially false. The multicommand disambiguation flag is initially false. The multicommand stored actor is initially nothing.

Check commanding someone to a topic when the multicommand flag is true (this is the multicommand mutex rule): stop the action.

Carry out commanding someone to a topic when the multicommand flag is false (this is the set up multicommand list rule):
	if the multiple object list is empty: [This is empty if only one noun was specified.]
		now the multicommand actor list is {};
		add the noun to the multicommand actor list;
	otherwise:
		now the multicommand actor list is the multiple object list;
	now the multicommand text is the substituted form of "[topic understood]";
	now the multicommand stored actor is the player;
	now the multicommand flag is true.

[Rule for reading a command when the multicommand flag is true (this is the replace command with multicommand rule):
	let T be text;
	repeat with the subject running through the multicommand list:
		let U be T; [Store it separately for a moment.]
		let T be the substituted form of "[U][subject], [multicommand text]. "; [Add the subject to the command, so "TELL ALICE AND BOB TO PUSH THE BUTTON" turns into "ALICE, PUSH THE BUTTON. BOB, PUSH THE BUTTON. "]
	change the text of the player's command to T;
	say "([T])[command clarification break]";
	now the multicommand flag is false.]

Rule for reading a command when the multicommand flag is true and the multicommand disambiguation flag is false (this is the replace command with multicommand rule):
[	say "DBG: changing to [entry 1 in the multicommand actor list].";	]
	now the player is entry 1 in the multicommand actor list;
[	say "DBG: changing command to [multicommand text].";	]
	change the text of the player's command to the multicommand text.

Before asking which do you mean when the multicommand flag is true (this is the multicommand begin disambiguation rule): [So as not to replace commands while disambiguation is in progress...]
	say "(for [the printed name of player])[command clarification break]";
	now the multicommand disambiguation flag is true.

After reading a command when the multicommand disambiguation flag is true (this is the multicommand end disambiguation rule):
	now the multicommand disambiguation flag is false.

First before doing anything when the multicommand flag is true (this is the cut off multicommand actions rule):
	let the parse result be a stored action;
	now the parse result is the current action;
	now the actor part of the parse result is entry 1 in the multicommand actor list;
	now the request part of the parse result is true;
	add the parse result to the multicommand action list;
[	say "DBG: removing [entry 1 in the multicommand actor list].";	]
	remove entry 1 from the multicommand actor list;
[	say "DBG: changing back to [multicommand stored actor].";	]
	now the player is the multicommand stored actor;
	if the multicommand actor list is empty: [Time to execute these actions!]
		repeat with the order running through the multicommand action list:
		[	say "DBG: trying [the order].";	]
			try the order;
		now the multicommand actor list is {};
		now the multicommand flag is false;
		silently try waiting; [To make one turn go by.]
[	say "DBG: stopping.";	]
	stop the action.

The announce items from multiple object lists rule does nothing when the multicommand flag is true.

Note that this is 6L02 code, but it would be much the same in 6G60. My first attempt is commented out; it would have been much easier, but Inform parses a command like “ALICE, JUMP. BOB, JUMP.” as “asking alice to try jumping” followed by “answering alice that ‘bob, jump’”.