Getting a multiple dobj list (adv3Lite)

This is a tricky one. If the player drops something in a room belonging to a certain class, I want the thing to disappear. I can do that fine if the player drops one thing. But my code only works with one gDobj. If the player types DROP SCISSORS AND NUTCRACKER, for instance (there is no nutcracker in the game, so this is not a spoiler), the nutcracker won’t be removed. Here’s what I have so far

    roomAfterAction() {
        if (gActionIs(Drop)) {
            "A smallish entity riding some sort of rodent scampers past you. With
            a little <q>Yippee!</q>, the entity scoops up what you dropped and
            rides off into the foliage with it. ";
            local r = rand(9) + 1;
            local room = PM1;
            // Lists are 1-indexed.
            local roomList = [PM1, PM2, PM3, PM4, PM5, PM6, PM7, PM8, PM9];
            for (local i = 1; i < 10; i++) {
                room = roomList[i];
                // Do a quick reset if the little guy is about to redistribute
                // what you dropped to the room you're already in:
                if (room == gPlayerChar.getOutermostRoom) {
                    r = rand(9) + 1;
                    i = 1;
                    continue;
                }
                if (i == r) {
                    gDobj.moveInto(room);
                    break;
                }
            }
        }

I’ve tried iterating through the contents list of the room and ignoring the player character and any scenery that I’ve deployed there, but apparently there’s a defaultGround object in every room, and when I try to avoid that I’m still running afoul of something with the name “body,” which I have no idea what it is – possibly an invisible decoration of the player character.

So I’m hoping to be able to access directly a list of the objects that were just dropped. Suggestions would be welcome!

I think gAction.actionList will give you want you want.

Could be, but that would be a list of actions, not of objects. After tearing my hair out for a while because I was doing a stupid programmer bad thing (removing stuff from a list while iterating through it), I found the solution. For those who are curious:

    roomAfterAction() {
        if (gActionIs(Drop) || gActionIs(GoTo)) {
            "A smallish entity riding some sort of rodent scampers past you. With
            a little <q>Yippee!</q>, the entity scoops up whatever looks interesting and
            rides off into the foliage with it. ";
            local foundOne = nil;
            local len = self.contents.length() + 1;
            local objList = [];
            // First we make an object list of anything portable that's in the room's contents:
            for (local i = 1; i < len; i++) {
                // "Test: Now attempting <<self.contents[i].name>>. ";
                if (self.contents[i].ofKind(PDportable)) {
                    foundOne = self.contents[i];
                    objList = objList.append(foundOne);
                }
            }
            local len2 = objList.length();
            if (len2 == 0) return;
            // Now we'll redistribute whatever is in the object list:
            for (local j = 1; j <= len2; j++)
            {
                relocate (objList[j]);
            }
        }          
    }
    relocate(obj) {
        local roomList = [PM1, PM2, PM3, PM4, PM5, PM6, PM7, PM8, PM9];
        local room = PM1;
        local r = rand(9) + 1;
        room = roomList[r];
        // Do a quick reset if the little guy is about to redistribute
        // what you dropped to the room you're already in:
        while (room == gPlayerChar.getOutermostRoom) {
            r = rand(9) + 1;
            room = roomList[r];
            }
        obj.moveInto(room);
    }

This works because I’ve defined all of the portable in-game objects using my own very thin subclass of Thing. So I can test for my portables without having to worry about the fact that the room’s scenery is also a Thing.

1 Like

The code in action.t for TAction is pretty explicit:

    /* 
     *   A list of the direct objects of this action that make it to the action
     *   stage.
     */
    actionList = []

The reason I’m sure this works is that I use it in the game I’m developing for similar reasons: I have a room with a dropLocation specified, and I use roomAfterAction() to describe the object(s) being moved to the other location:

  dropLocation = nextRoom
  roomAfterAction() {
    if (!gAction.ofKind(Drop))
      return;

    local isSingular = gAction.actionList.length == 1;
    local names = andList(gAction.actionList.mapAll({ thing: thing.theName }));
    local slides = isSingular ? 'slides' : 'slide';

    "You watch as <<names>> <<slides>> away...";
  }

Works great.

3 Likes