adv3Lite vocab not working if obj has subcomponents

I have two lockers, locker A and locker B.

Each locker has an interior space, plus a label on the exterior. Because I want to refer both to the label on the locker and the shelf in the locker, I have defined remapIn and remapOn subcomponents for each locker.

Works find, I can read the label on the locker and take the space helmet out of the locker.

But there is a vocab glitch.

The name of the objects are locker A and locker B. According to the documentation, I can suppress the leading the from game-generated text by preceding the name with an empty parenthesis pair, as i locker A[/i].

This works when I remove the remapping components from a locker object, but when the subcomponents are included, the game refers to them as the locker A/B instead of just locker A/B.

Here’s the game output with the subcomponents removed from locker A but present in locker B…

Here’s the code…

#charset "us-ascii"

#include <tads.h>
#include "advlite.h"

versionInfo: GameID
    IFID = '445C38A3-AD1B-4729-957A-F584600DE5C1'
    name = 'test'
    byline = 'by Jerry Ford'
    htmlByline = 'by <a href="mailto:jerry.o.ford@gmail.com">
                  Jerry Ford</a>'
    version = '1'
    authorEmail = 'Jerry Ford <jerry.o.ford@gmail.com>'
    desc = 'Testing three person conversation.'
    htmlDesc = 'Testing three person conversation.'

;

gameMain: GameMainDef
    initialPlayerChar = me
    paraBrksBtwnSubcontents = nil
   
;

me: Actor 'me' @lockerRoom
    "The main man.<.p>"
    isHim = true
    person = 2
;

saturnExplorer: Actor 'Saturn explorer'
    isHim = true
    person = 3
    firstName = 'John'
    lastName = 'Smith'
;
otherSaturnExplorer: Actor 'other Saturn explorer'
    isHim = true
    person = 3
    firstName = 'Jack'
    lastName = 'Sprat'
;


lockerRoom: Room 'locker room'
    "The locker room, the room where the lockers are. <.p>"
;

+ cmdrLocker: Thing, Fixture '() locker A;;locker'
    "Locker A is one of two lockers on either side of the landing module entry
    hatch.  Just below the large red <b>A</b> painted on the front door panel, 
    there is a label with smaller lettering. <.p>"
    
;

+ majorLocker: Thing, Fixture '() locker B;;locker'
    "Locker B is one of two lockers on either side of the landing module entry
    hatch. Just below the large red <b>B</b> painted on the front door panel, 
    there is a label with smaller lettering. <.p>"
    
    remapIn: SubComponent 
    {
        isOpenable = true 
        dobjFor(Open)
        {
            action()
            {
                inherited;
//              if(majorSpaceHelmet.isIn(topShelfLockerB))
                    "A space helmet rests on a shelf. <.p>";
            }
        }
    }
    remapOn: SubComponent { }
;
++ majorLockerLabel: Thing, Fixture '() label B;;label'
    "The label is yellow with black lettering. <.p>"

    isListed = nil
    isReadable = true
    readDesc = "<center>
        <font size=+2 color=red bgcolor=white>B</font>
        <table>
        <tr><td bgcolor=yellow align=center><font color=black>MAJOR
        <<otherSaturnExplorer.lastName>>\bUSAF</font></td></tr>
        </table>
        </center>"

    subLocation = &remapOn
;

How can I fix this?

Jerry

Have you tried manually defining theName on the locker objects rather than relying on the compiler to do the definitions? That would be my first thought – untested, however.

I just tried this with an object in my WIP, and using () in the vocab, in conjunction with a remapIn: Subcomponent for the same object, works properly. My setup is not identical to yours – I’m just poking around here. When I copy and run your code, I get the same results you do.

Adding theName = ‘locker B’ to the locker object has no affect. Still get You see nothing interesting in the locker B.

I think I can see why this is happening, though I’m not at home now, so I can’t try it out.

I think the following should probably more or less fix it (although I’ll need to put a proper and better fix in the library):

modify SubComponent
  initializeSubComponent(parent)
    {
       inherited(parent);
       theName = parent.theName;
       aName = parent.aName;
     }
;

Partial fix.

In the parenthetical (first opening…) line, the fix works.

But in the generated response—You see nothing—it does not.

I also see that I have some work to do in suppressing the initial report of the locker’s contents before the (first opening…) parenthetical message and then a see nothing message after just having been told there is a space helmet there, but I can probably fix that with some amazingly deft juggling of text blocks. :slight_smile:

Jerry

Okay, try this variant (still a temporary fix that needs more work):

modify SubComponent
  initializeSubComponent(parent)
    {
       inherited(parent);
       theName = parent.theName;
        theObjName = parent.theObjName;
       aName = parent.aName;
     }
;

I have tried this with your code and it seems to cure the immediate problem.

That said, I don’t quite understand what you’re trying to do with your Locker B code. You’d get a better output (and you’d be working more with the grain of the system) with something like:

+ majorLocker: Thing, Fixture '() locker B;;locker'
    "Locker B is one of two lockers on either side of the landing module entry
    hatch. Just below the large red <b>B</b> painted on the front door panel, 
    there is a label with smaller lettering. <.p>"
    
    remapIn: SubComponent 
    {
        isOpenable = true 
    }
    remapOn: SubComponent { }
;

++ spaceHelmet: Thing 'space helmet'
    initSpecialDesc = "A space helmet rests on a shelf. "
    subLocation = &remapIn
;

Ah, yes, I can see why that would be confusing :slight_smile:. In paring down the locker room for an example I could post in this forum, I took out the items (shelf and helmet) that are associated with the remapIn subcomponent, which is the cause of my grief, and left in the item associated with the remapOn subcomponent (label) which is not part of the current discussion.

Further down in this reply is a more complete implementation of the two lockers.

In summary, I have two lockers, locker A and locker B. There is a label on the front which identifies the locker’s owner—this is the remapOn subcomponent.

Inside each locker, there are two spaces—the locker proper, in which there is a spacesuit, and a top shelf, on which rests a space helmet. (I’ve left the spacesuits out of the example code because they just make the code long and complex; they work okay, so there isn’t any need for them here.)

The shelf is the remapIn subcomponent, and the helmet is located in (on) the shelf object.

I want to be able to manipulate both spaces—shelf where the helmet is and locker proper where the space suit is—independently, for each of the two lockers.

I’ve had numerous iterations of these lockers, and I sometimes get one thing that I want and lose another. When I fix that, the first thing goes away.

The current behavior is getting closer, thanks in part to your fix, but there is still at least one problem.

(Frankly, I forget why I put the dobjFor(Open) inside the remapIn object code, though look in does force an open first; just not sure why I thought I needed to change the text. So I
've commented that code out in this new example.)

With or without the dobjFor(Open) code, the lingering problem is, if the shelf is empty the game does not generate any text for it…

So here’s the code as it currently stands (note that I added a roomBeforeAction() method so that I can empty the locker A top shelf as needed while testing)…

#charset "us-ascii"

#include <tads.h>
#include "advlite.h"

versionInfo: GameID
    IFID = '445C38A3-AD1B-4729-957A-F584600DE5C1'
    name = 'test'
    byline = 'by Jerry Ford'
    htmlByline = 'by <a href="mailto:jerry.o.ford@gmail.com">
                  Jerry Ford</a>'
    version = '1'
    authorEmail = 'Jerry Ford <jerry.o.ford@gmail.com>'
    desc = 'Testing three person conversation.'
    htmlDesc = 'Testing three person conversation.'

;

gameMain: GameMainDef
    initialPlayerChar = me
    paraBrksBtwnSubcontents = nil
   
;

me: Actor 'me' @lockerRoom
    "The main man.<.p>"
    isHim = true
    person = 2
;

saturnExplorer: Actor 'Saturn explorer'
    isHim = true
    person = 3
    firstName = 'John'
    lastName = 'Smith'
;
otherSaturnExplorer: Actor 'other Saturn explorer'
    isHim = true
    person = 3
    firstName = 'Jack'
    lastName = 'Sprat'
;


lockerRoom: Room 'locker room'
    "The locker room, the room where the lockers are. <.p>"
    roomBeforeAction()
    {
        if(cmdrSpaceHelmet.isIn(topShelfLockerA))
            cmdrSpaceHelmet.moveInto(nil);
    }
;

+ cmdrLocker: Thing, Fixture '() locker A;;locker'
    "Locker A is one of two lockers on either side of the landing module entry
    hatch.  Just below the large red <b>A</b> painted on the front door panel, 
    there is a label with smaller lettering. <.p>"
    
    
    remapIn: SubComponent 
    {
        isOpenable = true 
        /*
        dobjFor(Open)
        {
            action()
            {
                inherited;
                if(cmdrSpaceHelmet.isIn(topShelfLockerA))
                    "A space helmet rests on a shelf. <.p>";
            }
        }
         */
    }
    remapOn: SubComponent { }
;
++ cmdrLockerLabel: Thing, Fixture '() label A;;label'
    "The label is yellow with black lettering. <.p>"

    isListed = nil
    isReadable = true
    readDesc = "<center>
        <font size=+2 color=red bgcolor=white>A</font>
        <table>
        <tr><td bgcolor=yellow align=center><font color=black>LTCDR
        <<saturnExplorer.lastName>>\bUSN</font></td></tr>
        </table>
        </center>"
    
    subLocation = &remapOn
;

++ topShelfLockerA: Surface, Fixture 'top shelf;locker A'
    "A shelf about shoulder high divides the locker into two spaces. <.p>"

    disambigName = 'Locker A top shelf'
    
    subLocation = &remapIn
;
+++ cmdrSpaceHelmet: Wearable 'space helmet;commander\'s' 
    "The spheroid helmet's backside is made of material similar to the hard pieces
    of the space suit; the entire front half is a gold-tinted clear material.
    <.p>"
    
    disambigName = 'commander\'s helmet'
    isTakeable = true
    
    dobjFor(PutOn)
    {
        action()
        {
            inherited;
            cmdrSpaceHelmet.moveInto(topShelfLockerA);
        }
    }
;


+ majorLocker: Thing, Fixture '() locker B;;locker'
    "Locker B is one of two lockers on either side of the landing module entry
    hatch. Just below the large red <b>B</b> painted on the front door panel, 
    there is a label with smaller lettering. <.p>"

    theName = 'locker B'
    
    remapIn: SubComponent 
    {
        isOpenable = true 
        /*
        dobjFor(Open)
        {
            action()
            {
              inherited;
              if(majorSpaceHelmet.isIn(topShelfLockerB))
                    "A space helmet rests on a shelf. <.p>";
            }
        }
        */
    }

    remapOn: SubComponent { }
;
++ majorLockerLabel: Thing, Fixture '() label B;;label'
    "The label is yellow with black lettering. <.p>"

    isListed = nil
    isReadable = true
    readDesc = "<center>
        <font size=+2 color=red bgcolor=white>B</font>
        <table>
        <tr><td bgcolor=yellow align=center><font color=black>MAJOR
        <<otherSaturnExplorer.lastName>>\bUSAF</font></td></tr>
        </table>
        </center>"

    subLocation = &remapOn
;
++ topShelfLockerB: Surface, Fixture 'top shelf;Locker B'
    "A shelf about shoulder high divides the locker into two spaces. <.p>"

    disambigName = 'Locker B top shelf'
    subLocation = &remapIn
;
+++ majorSpaceHelmet: Wearable 'space helmet;major\'s'
    "The spheroid helmet's backside is made of material similar to the hard pieces
    of the space suit; the entire front half is a gold-tinted clear material.
    <.p>"
    
    disambigName = 'major\'s helmet'
    
    isTakeable = true
    
    dobjFor(Wear)
    {
        check()
        {
            "You start to put the helmet on, but it does not
            fit. Space suits are tailored to precise measurements and cannot be
            shared. You cannot wear the Major's helmet.";
        }
    }
;

modify SubComponent
  initializeSubComponent(parent)
    {
       inherited(parent);
       theName = parent.theName;
       theObjName = parent.theObjName;
       aName = parent.aName;
    }
;

Jerry

Okay, got it.

Adding this…

dobjFor(LookIn) { action() { if(topShelfLockerA.contents.length == 0) reportAfter('<.p>The shelf is empty.<.p>'); } }

…inside the remapIn object seems to do the trick…

Jerry