Taking the contents of a container

I’m trying to make it so that when the player tries to take a particular container (or a type of container), they instead take the contents. I have tried several ways of doing this, but Inform7 is not understanding “the items held by slot 1” as anything, which was the most promising attempt so far. Does anyone know of how to refer to the contents of a container? Or how to teach Inform to recognize the contents as something? (I tried that, but it didn’t like it.)
Thank you in advance.

I don’t think you can piggyback off the ‘GET ALL’ mechanism for this. i.e. The internal mechanism Inform uses if the player types GET ALL, or GET ALL FROM (BLAH). I think you need to program your game to run through all the items in the container one by one and to try to take each one.

I’ve made an example below that does this. The container type is ‘vending machine’. I put one non-gettable thing inside it as well as three gettable things. I mean practically, my example is kind of silly (I don’t expect to get the lollies from a machine if I type GET MACHINE) but it does what you want, which is take the contents of a kind of container instead of the container itself.

The thing you were trying to get at with ‘the items held by slot 1’ is the list of things CONTENTS, which I create based on what’s in the vending machine at the time. Then the ‘repeat through…’ bit applies its code to each item in the machine in turn. There’s also a clause that makes sure something is printed if nothing is in the machine and we type GET MACHINE, but its message won’t go be seen in this example because the lodestone is always in the machine.

If you don’t want the list of resulting taking actions to be so spaced out as this example’s, we would have to do some more work to print out one sentence at the end of the mass-taking action instead of all these separate messages.

Lab is a room. the player is in the lab.

a vending machine is a kind of container.

a sweets machine is a vending machine in lab.

a lolly is in sweets machine.
a candy is in sweets machine.
a chocolate is in sweets machine.
a lodestone is in sweets machine.

Instead of taking a vending machine (called THE SOURCE):
	let CONTENTS be the list of things held by THE SOURCE;
	if the number of entries in CONTENTS is 0:
		instead say "The machine is empty.";
	repeat with Z running through contents:
		say "[The Z]: ";
		try taking Z;
	rule succeeds;

Instead of taking lodestone:
	say "That's too heavy.";

Test me with "get machine".

-Wade

2 Likes
Slot one is a container in the Lab. The magazine is in slot one. The LP is in slot one.

A thing can be from slot one.

Definition: a container is empty if the first thing held by it is nothing.

Carry out taking something when the noun is in slot one:
    now the noun is from slot one;

After taking something from slot one:
    now the noun is not from slot one;
    say "[The noun]: taken.";

Instead of taking slot one:
  if slot one is empty, instead say "There's nothing in slot one.";
  repeat with obj running through things in slot one begin;
    try taking obj;
  end repeat;

This is much the same as Wade’s, but sets a flag in the Carry out rule that exists just to trigger the subsequent After rule which unsets it and outputs a message. I hadn’t known you couldn’t do, e.g., Report taking something when the noun was in Slot One – apparently you can only use conditionals about the past with literal things, not object variables. This avoids having say "[The noun]: " in the Instead rule, but that has a downside: it means you’d have to think about customizing any failure messages related to taking things from Slot One, like Wade’s lodestone above.

Thank you both! These are perfect.

1 Like