Login
Remember
IF Answers
Ask a Question

# Stopping a message from being said multiple times (Inform 7)?

0 votes
191 views
asked Apr 30 in Authoring by Leah

My code is probably pretty atrocious because I'm just learning Inform 7 and messing around by expanding some of the examples in the documentation, so pardon that.

I have a case which contains multiple fishing rods and I don't want the player to be able to take a second one if they've already got one in their inventory, so this is the code I've written:

    Before taking a fishing rod:
        if the player carries a fishing rod:
            say "You only need one fishing rod.";
            stop the action.

This works really well unless the player wants to take more than one fishing rod at once. If, for instance, the player types "take all fishing rods", it will only place one in their inventory, but it will print out one success message and then a message of "You only need one fishing rod" for each remaining fishing rod in the case.

    fishing rod: Taken.
    fishing rod: You only need one fishing rod.
    fishing rod: You only need one fishing rod.
    fishing rod: You only need one fishing rod.
    fishing rod: You only need one fishing rod.
    fishing rod: You only need one fishing rod.

This isn't world-ending, especially since there are only six, but it is a little sloppy. Is there a way to stop it after one print and/or a better way around it? The examples in the documentation about dispensers weren't very helpful because I want the case to have a finite number of fishing rods.

- inventory
- inform7
- programming
- messages

## 3 Answers

+1 vote
answered Apr 30 by bg (692 points)
edited May 9 by bg

I would suggest checking out the extension Consolidated Multiple Actions by John Clemens, which was recently updated for version 6L38 of Inform 7. In the list of extensions that you see if you click on the extensions tab, then the public library tab in the Inform IDE, this extension is listed under the "§5.7 Remembering, Converting and Combining Actions" subcategory, which is under the Commands category.

Here's one way of doing the failure messages, also using Ron Newcomb's "After Not Doing Something" extension (also in the §5.7 subcategory of the extensions list).

    "Tackle Shop"

    Include Consolidated Multiple Actions by John Clemens.
    Include After Not Doing Something by Ron Newcomb.

    Tackle Shop is a room.

    A fishing rod is a kind of thing.
    6 fishing rods are here.

    Instead of taking a fishing rod when the player carries a fishing rod:
        indicate noteworthy consolidation.

    Rod-Failure-Printed is a truth state that varies. Rod-Failure-Printed is false.

    After not taking a fishing rod when Rod-Failure-Printed is false:
            say "You only need one fishing rod.";
            now Rod-Failure-Printed is true;
            say conditional paragraph break.

    Every turn when Rod-Failure-Printed is true:
        now Rod-Failure-Printed is false.

If you don't need all the fishing rods to function as separate objects, you could try doing it in a less literal way, along the lines of what The Pixie suggested:

    "Tackle Shop 2"

    Tackle Shop is a room.

    A case is a fixed in place thing in Tackle Shop. The printed name of the case is "case of fishing rods". The description of the case is "A case containing several fishing rods." Understand "fishing" and "rods" and "rod" and "case of fishing rods" as the case.

    A new fishing rod is nowhere. The new fishing rod can be cased or uncased. The new fishing rod is cased.

    Does the player mean taking the new fishing rod: it is likely.

    Instead of taking the case:
        if the new fishing rod is cased:
            now the player carries the new fishing rod;
            now the new fishing rod is uncased;
            say "You take a fishing rod from the case.";
        otherwise:
            say "You only need one fishing rod."

commented May 2 by chronoimp (1 point)
I installed the extension and was trying to implement it, but because I have the failure message created before the action of taking the rod and then it stops the action, it doesn't get far enough along in the execution for the multiple action code to take over. Which is to say, it still printed six messages.
I was trying to figure out how to move the failure message into a report or after rule, but then I couldn't figure out how to get it to print at all. I almost had success with using the "the number of multiple actions so far this turn" variable to stop printing messages after the first, but then I couldn't find a way to just make it print if the player tries to take one extra rod instead of all of them, because that variable doesn't reset to zero until the start of the next multiple action.
I feel like I should be able to do it with this extension, but I can't quite get it to work.
commented May 8 by bg (692 points)
I've edited the answer to add some more info and examples.
+1 vote
answered May 21 by mattweiner (121 points)
edited May 25 by mattweiner

The issue here is that when you have a command on multiple items, it's processed as an action on each item--so a taking action is generated for each fishing rod, with its appropriate messages.

Since all these actions take place in the same turn, we can use a flag (which we reset every turn) to keep track of whether we've already printed the "You only need one" message once this turn. But there's also an "announce items from multiple object lists" rule, which is what prints "fishing rod:" for each of the multiple items--and that works outside of the action machinery, so we have to modify that too.

So:

    Tackle Box is a room.

    A fishing rod is a kind of thing. There are six fishing rods in Tackle Box. A rock is in Tackle Box.

    Already printed the fishing rod message is a truth state that varies.

    Last every turn: now already printed the fishing rod message is false.

    This is the modified announce items from multiple object lists rule:
        if the current item from the multiple object list is not nothing:
            if the current item from the multiple object list is not a fishing rod or already printed the fishing rod message is false:
                say "[current item from the multiple object list]: [run paragraph on]".

    The modified announce items from multiple object lists rule is listed instead of the announce items from multiple object lists rule in the action-processing rules.

    Before taking a fishing rod when the player carries a fishing rod:
        if already printed the fishing rod message is false:
            say "You only need one fishing rod.";
            now already printed the fishing rod message is true;
        stop the action.

This is based on code from the examples in the Inform documentation "The Left Hand of Autumn" and "The Facts Were These." (Also, when you try "take all rods" it doesn't print a blank line before the command prompt. Someone who understands I7's line spacing might be able to help with that.)

0 votes
answered May 2 by The Pixie (121 points)

I do not know Inform at all, but a possible approach might be to just have one fishing rod in the case, but set up the description of the case so it says there are six before the rod is removed, and five after it is removed.

## Related questions

- Is there a way to reduce the right margin for a play-in-browser website released by Inform 7?
- how do I print a message on the Xth turn in inform 7?
- In Inform 7, is there a way to detect which interpreter is being used?
- Inform 7: Multiple instances of a kind of thing where some (but not all) change properties
- How to make a thing that can be seen from every room?

...