Adv3Lite remapOn and descriptions

The following example from the Adv3Lite Manual does not give the user a hint that there is anything on top of the cooker. How could this be implemented? Here’s the link and the code in question:

dl.dropboxusercontent.com/u/583 … m#remapxxx

The remapXXX properties and Multiple Containment

+ cooker: Thing 'cooker;blackened;oven stove top'
    "Normally, you keep it in pretty good shape (or your cleaner does) but right
    now it's looking suspiciously blackened, especially round the top. "    
    
    isFixed = true
        
    remapIn: SubComponent  {   isOpenable = true   }
    remapOn: SubComponent  {  }
;

++ saucepan: Thing 'saucepan;;pan'
    "It's absolutely blackened. It was obviously left on the stove too long --
    perhaps that's what started the fire. "
   
    subLocation = &remapOn
;

How can I make saucepan appear in the description of items in room?

TIA,
Rick

This seems to be a weakness in the adv3Lite library. Things sitting in plain view on top of a Fixture that has a remapOn are not listed in room descriptions in the way that things sitting on top of an ordinary Fixture, Surface are. Below is a fix, borrowed from the library code for the Search action and tinkered with a bit, that seems to work in my quick testing. The specialDesc insures that the cooker will always be mentioned in the room description, which is probably useful. My checkStuffOnTop method can be called wherever it’s needed.

[code]+ cooker: Fixture ‘cooker;blackened;oven stove top’
“Normally, you keep it in pretty good shape (or your cleaner does) but right
now it’s looking suspiciously blackened, especially round the top. <<checkStuffOnTop()>>”

specialDesc = "Squatting in the corner is your cooker. <<checkStuffOnTop()>>"

checkStuffOnTop () {
    if(remapOn.hiddenIn.length == 0 
        && remapOn.contents.countWhich({x: x.searchListed}) == 0)
        {
            return;
        }  
    local onList = remapOn.contents.subset({x: x.searchListed});
    if(onList.length > 0)
        listContentsOn(onList);
    if(remapOn.hiddenIn.length > 0)            
        findHidden(&hiddenIn, In);
}
listContentsOn(lst) {
    lookInLister.show(lst, self, true);
} 
    
remapIn: SubComponent  {   isOpenable = true   }
remapOn: SubComponent  {  }

;[/code]

Thank you, Jim, this works brilliantly.

I noticed in Adv3Lite Tutorial following the game code for “Airport” that there are two items (a desk in one room and a cabinet in another) that use remapOn. I’ll try adding your code in these places, as there are items vital to the story on top of each.

Thanks again,
Rick

Your code works well in the Airport tutorial game, Jim, so thanks again for that. Now I’m curious about how a player would discover items on top of a fixture when remapOn is used, if not for your code?

Well, the author could mention the items in the specialDesc of the Fixture … but if the player should put anything new on top of the Fixture, it would not be mentioned in the room description or the desc of the Fixture. Eric has made a number of tweaks to the adv3Lite library as a result of conversations on this forum. I expect he’ll notice this thread within a day or two. His solutions are, I would add, much better than my crude hacks, because he understands the library!

I appreciate your help, Jim, and your website has been a real aid in learning about T3 (and I7 as well!).

I have indeed noticed this discussion and will take a look at this in the library. I’m pretty sure this is a problem I’d have noticed before, so I suspect things on remapOn objects did show up in room descriptions once upon a time but I managed to break that when trying to fix something else. The code that lists objects in room descriptions is one of the more complex parts of the library.

I have now fixed this and uploaded the fixed version to GitHub. If instead you just want to patch your version of adv3Lite manually, first add the following property definition to the Thing class in thing.t:

 /* The list of possible remap props */
    remapProps = [&remapOn, &remapIn, &remapUnder, &remapBehind]

Then modify the Thing method listSubcontentsOf in thing.t (around line 1350 in my contents of the file). After the lines:

 listSubcontentsOf(contList, lister = &examineLister)
    {
       
        /* 
         *   If contList has been passed as a singleton value, convert it to a
         *   list, otherwise retain the list that's been passed.
         */
        contList = valToList(contList);

Insert the following:

 /* 
         *   Ensure the contents of any associated remapXX items are included in
         *   the list of items whose contents are to be listed.
         */
        
        /* Initialize an empty list to collect the remapXXX items. */
        local lst = [];
        
        /* 
         *   Go through every item in the contList to see if it has any remapXXX
         *   objects attached. If so add the remapXXX object to our list.
         */
        foreach(local cur in contList)
        {
            foreach(local prop in remapProps)
            {
                local obj = cur.(prop);
                if(obj != nil)
                    lst += obj;
            }
        }
        
        /*  
         *   Append the list of remapXXX objects to the list of items whose
         *   contents are to be listed.
         */
        contList = contList.appendUnique(lst);

Thanks, Eric, it works perfectly!

Cheers,
Rick