adv3lite: TIAction that takes multiple indirect objects for crafting system

Normally when an action is given multiple objects, the action is naturally performed multiple times, one time for each object. But suppose you want an action to be done to a group of objects collectively. Like suppose you want a command like this:

> glue together the key, the arrow, and the battery

The idea here is these three objects will be attached to each other. This is not three actions, each with one object, but rather it is one action that has three direct objects. This is not how actions normally work in adv3lite, but how could an action be made to work this way?

In particular, consider a crafting system where various recipes produce various results, and some objects can be produced by multiple recipes.

You could say > make sword but if there are multiple recipes available and you have the materials to make a sword in multiple ways then this action would be ambiguous. What you might want to say would be > make sword from silver and oak to specify which recipe should be used. This isn’t making two swords, one silver sword and one oak sword. This is one action that has two indirect objects that will both be used in creating one sword.

Further, one would also want to be able to say things like > make sword and axe from silver and oak, which is two actions, making a sword and making an axe, each using the appropriate recipe involving silver and oak. So we want to iterate through the direct objects as usual but not iterate through the list of indirect objects.

Is there a standard way to implement these sorts of actions?

1 Like

Currently out and about and struggling to remember if there’s a quick way to handle lists of objects in a command.


The fallback strategy that could be used, if lists aren’t viable here, is to treat the list of “ingredients” as a text input block, split the input into item names, and then do something like:

  1. Begin crafting for Product P.
  2. Add ingredient 0 to crafting for Product P.
  3. Add ingredient 1 to crafting for Product P.
  4. Etc
  5. Etc
  6. Evaluate validity of crafting for Product P.

For steps 2-5, you’d be sending/injecting a new command into the parser like substep-add iron to crafting for axe, to utilize the native noun-matching capabilities of the parser.

This would require you to have an action created to match substep-add <noun> to crafting for <noun>.

For step 6, if any steps 2-5 failed, then just evaluate crafting as a failure.

2 Likes

Okay so it looks like multiDobj and multiIobj are supported, but I think that just iterates the command for the nouns in the list, so I still think it might be good to have a way of doing the following:

  1. Start crafting activity (register there being an ongoing crafting activity somewhere, and do not register a new one if there is already one started)
  2. Start adding items to the crafting activity (with the individual commands to each noun)
  3. End the crafting activity with an evaluation, if the command has been attempted for the correct number of nouns

I think there’s a way to check how many nouns are going to be used in a multi-obj command…?

But steps 1-3 will be run for all objects in the recipe, and ideally steps 1 and 3 only kick in for the first and last item that gets the command, respectively. For all items in the middle, steps 1 and 3 will be opted out.

Hope any fraction of this is useful. It’s been a long time, so I have a vague feeling of what is viable, but not enough awareness to write specific code at this point.

I don’t think you can have a multiDobj and multiIobj on the same action, but if you want to have an action acting on multiple direct objects in one operation you can use the action’s execGroup(cmd) method, which runs before the parser starts iterating over each direct object in the normal manner. The cmd parameter is the current Command object. cmd.dobjs contains a list of the direct objects as NPMatch objects, whose obj` property contains the actual direct object.

So, if you had a GlueTogether action, you could define its execGroup method along the following lines:

GlueTogether: TAction
   execGroup(cmd)
   {
      /* Obtain a list of the direct objects */
      local objs = cmd.dobjs.mapAll({d: d.obj });
      // objs might then be [key, arrow, battery]
      
      // write whatever code you need here to join these three objects together
      
      // when you're done, empty out the cmd.dobjs list to tell the action
      // you're done with it.
      cmd.dobjs = [];
   }
;

That’s only a skeletal outline, of course. but it shows how you could in principle code an action to work on a number of direct objects together as a group rather than individually one at time.

3 Likes