OnActionWith Block
OnActionWith Block

OnActionWith Block

OnActionWith ( ACTION, OBJECT )

A block that describes what to do when an object is the target of a valid ditransitive or transitive action with another specific object, or when a transitive action is unhandled by the target object (falling through to the current room/player).

Valid on Elements

Parameters

ACTION A DITRANSITIVE or DITRANSITIVE action. The action that this block handles.
OBJECT A non-archetype object. The other object resolved in the interpreter (not the one this block appears on).

When it is Called

Ditransitive Actions

The onActionWith() block is called when a ditransitive action needs to be handled at a target object with another object.

DITRANSITIVE action handling is a little tricky - depending on whether or not the action is labelled strict, it will try both combinations of "object 1 on-action-with object 2" and "object 2 on-action-with object 1", stopping after it finds a qualifying block. Only the first interpreted object is used as the target element (including the "ancestor" and "other" handling blocks) if the action is strict, and only the second interpreted object is used as the target element (including the "ancestor" and "other" handling blocks) if the action is strict and reversed.

If a valid onActionWith() block for a ditransitive action and target object is not found, TAME looks for an onActionWithAncestor() block to call that matches. If that does not exist, it calls onActionWithOther(). And if that does not exist, TAME looks for onUnhandledAction() blocks to call on the current player, if any, and then the world.

Then if that is not found, an ERROR cue is added to the Response.

Transitive Actions

The onActionWith() block is called on a room, player, or world when a transitive action needs to handle a target object, but an onAction() block does not exist on the target object.

If an onAction() block is not found on the target object, TAME looks for onActionWith(), onActionWithAncestor(), then onActionWithOther() blocks on the current room, if any, the current player, if any, and then the world. And if that does not exist, TAME looks for onUnhandledAction() blocks to call (on the current player, if any, and then the world).

Then if that is not found, an ERROR cue is added to the Response.

Inheritance rules apply when searching for callable blocks, always!

If this block is executed, it counts as a "successful command", so this will execute the afterSuccessfulCommand() block after the initial action handling and queued actions.

Example

Ditransitive Action Example


action general a_quit named "quit", "exit";

action transitive a_talk named "talk to";
action transitive a_examine named "examine", "look at", "x";

action strict ditransitive a_mix named "mix", "combine" uses conjunctions "with", "and";
action strict reversed ditransitive a_give named "give" uses conjunctions "to";

module
{
	title = "Paint Delivery";
}

/********************************** All paint. *******************************/

object archetype o_paint
{
	// Override this!
	function getColor()
	{
		return false;
	}

	// On mix with any other paint-category item.
	onActionWithAncestor(a_mix, o_paint)
	{
		textln("I think these don't need any more mixing.");
	}

	// On mix with anything else.
	onActionWithOther(a_mix)
	{
		textln("I can't mix these together.");
	}
	
	onAction(a_examine)
	{
		textln("Looks like a can of " + getColor() + " paint.");
	}
	
	onWorldBrowse()
	{
		textln("A can of " + getColor() + " paint is here.");
	}
	
}

object o_paint_orange : o_paint named "paint", "orange paint"
{
	override function getColor()
	{
		return "orange";
	}

}

object o_paint_purple : o_paint named "paint", "purple paint"
{
	override function getColor()
	{
		return "purple";
	}
	
}

object o_paint_green : o_paint named "paint", "green paint"
{
	override function getColor()
	{
		return "green";
	}
}

object o_paint_blue : o_paint named "paint", "blue paint"
{
	override function getColor()
	{
		return "blue";
	}
}

object o_paint_yellow : o_paint named "paint", "yellow paint"
{
	override function getColor()
	{
		return "yellow";
	}
	
	onActionWith(a_mix, o_paint_blue)
	{
		textln("Hey, it made green paint!");
		giveObject(world, o_paint_green);
	}

}

object o_paint_red : o_paint named "paint", "red paint"
{
	override function getColor()
	{
		return "red";
	}
	
	onActionWith(a_mix, o_paint_yellow)
	{
		textln("Hey, it made orange paint!");
		giveObject(world, o_paint_orange);
	}
	
	onActionWith(a_mix, o_paint_blue)
	{
		textln("Hey, it made purple paint!");
		giveObject(world, o_paint_purple);
	}
	
}


/********************************** All people. *******************************/

object archetype o_person
{
	init()
	{
		talkedto = false;
	}

	// fallback on wrong paint.
	onActionWithAncestor(a_give, o_paint)
	{
		textln("\"I don't want that color of paint!\"");
	}

	onActionWithOther(a_give)
	{
		textln("I don't think they want that.");
	}
	
}

// It's a person named Bob!
object o_bob : o_person named "bob", "guy", "man"
{
	onAction(a_talk)
	{
		if (!talkedto)
		{
			textln("Bob says, \"I want orange paint.\"");
			talkedto = true;
		}
		else
		{
			textln("Bob says, \"I still want orange paint.\"");
		}
	}

	onAction(a_examine)
	{
		textln("It's a guy named Bob.");
		if (talkedto)
			textln("He wants orange paint.");
	}
	
	onWorldBrowse()
	{
		textln("A guy named Bob is here.");
	}

	onActionWith(a_give, o_paint_orange)
	{
		textln("Bob says \"thank you\" and disappears.");
		removeObject(o_paint_orange);
		removeObject(o_bob);
	}

}

// It's a woman named Susan!
object o_susan : o_person named "susan", "gal", "woman"
{
	onAction(a_talk)
	{
		if (!talkedto)
		{
			textln("Susan says, \"I want purple paint.\"");
			talkedto = true;
		}
		else
		{
			textln("Susan says, \"I still want purple paint.\"");
		}
	}

	onAction(a_examine)
	{
		textln("It's a gal named Susan.");
		if (talkedto)
			textln("She wants purple paint.");
	}
	
	onWorldBrowse()
	{
		textln("A gal named Susan is here.");
	}

	onActionWith(a_give, o_paint_purple)
	{
		textln("Susan says \"thank you\" and disappears.");
		removeObject(o_paint_purple);
		removeObject(o_susan);
	}

}

world
{
	function winCheck()
	{
		textln("");
		// check if Bob and Susan have absconded.
		if (objectHasNoOwner(o_bob) & objectHasNoOwner(o_susan))
		{
			textln("Everyone is happy!");
			quit;
		}
		else
		{
			browse(world);
		}
	}

	start()
	{
		giveObject(world, o_bob);
		giveObject(world, o_susan);
		giveObject(world, o_paint_red);
		giveObject(world, o_paint_yellow);
		giveObject(world, o_paint_blue);
		textln("These people need a color of paint.");
		textln("TALK TO them to figure out what they want.");
		textln("MIX the paint to make different colors, then GIVE the paint to them.");
		winCheck();
	}

	onAction(a_quit)
	{
		quit;
	}
	
	onUnhandledAction(a_give)
	{
		textln("I can't give that to somebody.");
	}

	onUnhandledAction(a_mix)
	{
		textln("I can't mix those things together.");
	}

	onIncompleteCommand(a_give)
	{
		textln("What do you want to give to whom?");
	}

	onIncompleteCommand(a_mix)
	{
		textln("What do you want to mix with what?");
	}

	onIncompleteCommand(a_examine)
	{
		textln("What do you want to examine?");
	}

	onIncompleteCommand(a_talk)
	{
		textln("Who do you want to talk to?");
	}

	onAmbiguousCommand()
	{
		textln("Be more specific.");
	}

	onMalformedCommand(a_talk)
	{
		textln("I can't talk to that.");
	}

	onMalformedCommand()
	{
		textln("I don't understand.");
	}

	onUnknownCommand()
	{
		textln("I can't do that.");
	}

	afterSuccessfulCommand()
	{
		winCheck();
	}
	
}

See Also

OnAction() — Called to handle an action with another object, or a general action on the current player or room.
OnActionWithAncestor() — Called by ditransitive actions for handling an action with another non-specific object.
OnActionWithOther() — Called by ditransitive actions for handling an action with another object after no specific entry points exist.
OnUnhandledAction() — Called if a command is valid, but an action is unhandled.

Additional Technical Notes

The "first" and "second" objects are determined by the interpreter. The order still matters even if the action is not strict. This stops when it finds a single relevant block.

If not strict, the object test order is always first-onActionWith-second, then second-onActionWith-first.

For transitive actions, the onActionWith() block is context sensitive involving the current player or the current room. This is assessed when finding the relevant block to execute for the current action being processed. This will affect program flow if rooms and players change.

×

Modal Header