Not a Dispenser (adv3Lite)

I have a situation where the player needs to be able to take random items of clothing from a rack of clothing in a store. Creating new items dynamically, giving them random characteristics, and moving them to the player is not difficult. The difficulty is what happens after that, specifically with reference to inventory manipulation.

If the items were tucked away (notionally) in a dispensing machine until they were created, the vocabWords that refer to them would always refer to a newly created member of the class. But there’s no dispensing machine. What I have instead is a Fixture called randomDress, which has its own vocabWords. ‘take dress’ causes this Fixture to create a new item and hand it to the player. But if the player happens to drop a newly created item, the parser gets confused. Perhaps a transcript will illustrate this better:

The main problem here is that the player doesn’t need to know and should not know that there’s anything in scope called the random dress. The secondary problem is that since the random dress object is a Fixture, the parser certainly shouldn’t be complaining that you’re not holding it when you say ‘drop dresses’.

But wait – it gets worse. After taking (creating) several dresses, dropping them, and then taking two more random dresses, I’m seeing this output:

Yes, there are two gowns there that have (randomly) a burgundy color; that’s not a bug. But why the heck is the parser listing the things that are not carried in response to a ‘drop’ command, when there are matching items that are carried?

Sadly, there’s a plot reason why I need to be able to generate a few random dresses; it’s not just window dressing. But I’m rather at a loss how to arm-wrestle the parser into understanding what the player most likely means. Suggestions would be welcome.

Here’s an even deeper perplexity. The newly created dresses are distinguishable, via their color adjectives. To each of them is attached a magnetic anti-shoplifting tag – and the tags are indistinguishable, because there’s no need for them to be distinguishable, and because that’s realistic. So we now have a transcript that looks like this:

The parser is inviting the player to distinguish between the two shoplifting tags by specifying the location of a tag … and yet it can’t use the location information that the player enters. That may be a parser bug. Here’s why I think that:

[code]>x tag
Which do you mean, the magnetic anti-shoplifting tag on the pink gown or the magnetic anti-shoplifting tag on the aquamarine gown?

pink
The tag is firmly clipped to the hem of the gown.

x tag
Which do you mean, the magnetic anti-shoplifting tag on the pink gown or the magnetic anti-shoplifting tag on the aquamarine gown?

pink gown
The tag is firmly clipped to the hem of the gown.[/code]
The anti-shoplifting tag can be disambiguated if the player doesn’t mention its location – but if the location is mentioned, the parser can’t cope.

I have a similar situation, where the PC takes a food packet out of the pantry. There are three different types of food—steak, potatoes and vegetables. The player can take an unlimited number of packets, which are served up in random order.

I defined a foodPackage Thing as the item in scope, but to avoid the situation you describe (where the parser says there is no random item then lists the items you do hold) I also created a FoodPouch class with subclasses for each of the three food types.

Then, in the action() code for the foodPackage object, instead of putting a foodPackage in the inventory, I put one of the subclassed objects into inventory…

[code]

  • foodPackage: Thing ‘pouch;food;package’
    “A packet of food.”

    isListed = nil

    dobjFor(Take)
    {
    action()
    {
    "You pick a pouch from the shelf and read its label: ";

        do
            foodPouchDescription.doScript();
        while(pouchNeeded(labelText) == nil);
        say(prepInstructionsText + pouchNeededText);
        if(labelText.find('vegetables'))
        {
            local veggiePouch = new VegPouch;
            veggiePouch.moveInto(saturnExplorer);
        }
        if(labelText.find('steak'))
        {
            local steakPouch = new SteakPouch;
            steakPouch.moveInto(saturnExplorer);
        }
        if(labelText.find('potatoes'))
        {
            local potatoPouch = new PotatoPouch;
            potatoPouch.moveInto(saturnExplorer);
        }
    }
    

    }
    }[/code]

When you take a pouch from the pantry shelf, the description of the package comes from a random list…

// food pouch descriptions
foodPouchDescription: RandomEventList
{
    eventList = 
    [
        {:
            foodPackage.prepInstructionsText = '<i>Filet Mignon,</i> the label proclaims. <i>Fill pouch with water, 
            microwave for 10 minutes at 20 percent power to rehydrate, then
            1 minute at full power to heat. </i><.p>',
            foodPackage.setLabelText('steak')
        },
        
        {:
            foodPackage.prepInstructionsText = '<i>Potatoes, Scalloped</i> reads the label. <i>Add one cup water,
            rehydrate in microwave for 5 minutes at 20 percent power, then cook for
            1 minute at full power.</i> <.p>',
            foodPackage.setLabelText('potatoes')
        },
        
        {:
            foodPackage.prepInstructionsText = '<i>Vegetable Medley</i> reads the label somewhat optimistically.
            <i>Rehydrate for 1 minute at half power in microwave, then heat for 30
            seconds at full power.</i> <.p>',
            foodPackage.setLabelText('vegetables')
        }
    ]

…which produces this in the game window…

Jerry

I’m not sure that would work for me, Jerry. I notice you’re automatically closing the doors of the pantry (although you don’t seem to have included that in the code you posted). Closing the pantry doors would automatically put the source of food packets out of scope, I’d guess.

In any event, I think I’m going to do it a different way. I think I’m going to get rid of the dynamic creation entirely, thereby solving my immediate problem as well as a related problem that I haven’t even started fiddling with yet.

The standard adv3Lite way to deal with your original problem is simply to give your random dress object a plural vocab that won’t match “dresses” or anything else the player is likely to type, like so:

+ randomDress: Fixture 'dress{-zz}'
    dobjFor(Take)
    {
        verify() {}
        action()
        {
           /* Whatever you have in here */
        }
    }
    
;

The disambiguation problem you refer to may simply be a limitation of the Mercury parser. I’ll try to remember to look at it in due course, but I don’t promise anything!