Dropping something indirectly held

The following code does what I want:

Before dropping something enclosed by the player:
	if the noun is not held:
		let the noun_container be a random object containing the noun;
		say "(first taking [the noun] out of [the noun_container])";
		try taking the noun;
		say "(and now dropping it)";
		continue the action;

But this seems like the most awkward way possible to discover what the noun is in. Is there a better way? I tried ‘the container of the noun’ and ‘the parent of the noun’, but I7 just didn’t recognize those phrases.

1 Like

Hmm, and a different question: how can I check if ‘try taking the noun’ succeeded? I assumed it would fail out of the whole routine, but it does not. I guess I could just check if the noun is now held? Is that the only way?

I’m on my phone so can’t play with code but I think you do need to use an approach like the one you’re using. That is, if statements to verify a thing is there, followed by ‘a random blah’ to grab hold of it once you’re sure it’s there.

Your current code has a flaw in that parts of people are also enclosed by them. So it could bug out on a command like TAKE HAIR.

Ways to handle the situation in general might involve creating definitions/adjectives that you can include in your preamble, or just in the rule. In my WIP I have a routine which finds the ‘ultraparent’ of a noun. And asking about the ultraparent also pokes variables, telling me what the thing is in, Etc. so my approach to these situations involves less repetition of code.

Edit- to be clear, my ultraparent routine is all code by me, just using If there is a…’s and A random blah’s to narrow down where something is, its containment or incorporation.

-Wade

1 Like

The immediate parent of a thing in the object tree is its “holder”, in I7 terms. This might be a container, but could also be a supporter, e.g. if a key is “on” a key ring held by the player.

Testing whether an action succeeded is a tricky business. I7 provides some machinery for checking that, but basically nothing ever relies on it, because the way it interacts with “instead” rules can be very unintuitive. So I recommend avoiding it if possible.

Instead, the usual idiom is to look for the results of that action—namely, is the noun now held? If not, stop the action.

2 Likes

(For an alternative, consider the way Dialog handles action success and failure. If an action ever doesn’t do what the player wanted, for any reason, it ends not just the action but the turn.

This works great in some cases—to go to the Parlor, try going north, before going north, try opening the door, before opening the door, try unlocking the door, before unlocking the door, try taking the key. If any of these actions fails, the whole turn ends right at that moment, and the failure message is the last thing you see before the next command prompt.

But it also means that, if there’s an important document that makes you say “hmm, better not” when you try to take it, a TAKE ALL might end abruptly partway through the turn, with no way to predict which parts of the action came before the interruption and which didn’t. Very unintuitive!

And thus you can see why Inform doesn’t do this. Easier just to check a second time if the noun is held. That’s what’s really important here, after all!)

1 Like

Got it! So, using ‘holder of’, and avoiding the ‘parts of are not held’:

Before dropping something enclosed by the player:
	if the player is not the holder of the noun:
		say "(first taking [the noun] from [the holder of the noun])";
		try taking the noun;
		if the noun is held:
			say "(and now dropping it)";
			continue the action;
		otherwise:
			stop the action;

which seems to work, at least in the simple cases I’ve tested so far.

1 Like

Yep! That’s basically how I’d do it. With my idioms, it would look something like:

Before dropping something:
    if the noun is enclosed by the player and the noun is not held:
        let the parent be the holder of the noun;
        say "(first removing [the noun] from [the parent])[command clarification break]";
        try taking the noun;
        if the noun is not held, stop the action;
        say "(and now dropping [regarding the noun][them])[command clarification break]".

You could also move part or all of that condition into the preamble, or avoid making “the parent” its own variable, and so on. Rearrange it however feels most readable to you, because you’re the main person who’s going to be reading this code again in the future!

(You can also “carry out the implicit taking activity with the noun” to tap into some existing machinery. I didn’t do that, because—following your example, which I think is a good one here—I wanted to include the parent in the message. A plain “first taking…” sounds odd when you’re trying to drop it!)

2 Likes