Defeating the ExitLister

In a particular room in my WIP, I need the ExitLister not to function. Specifically:

a) It should not say “There are no obvious exits” when the player tries ‘nw’ or whatever. I’m handling that information myself, in a more interesting way, in the cannotGoThatWay message.

b) Should the player type ‘exits’ while in that room, I will need to provide a special text output. I don’t know where to put it.

c) The status line must not say “Exits: None” while in this room, because that’s not the case. There are indeed exits, but they’re not directional exits. So I need to override that text in this particular room.

So I’m looking at the definition of the Room class in the LRM, and I can’t see where a Room has its own ExitLister object. Thus I don’t know where to intervene in order to override the behavior in this particular room.

Can anyone advise how to manage this? Thanks!

–JA

You could modify the exitLister object itself. Also explicitExitLister is where the “There are no obvious exits.” message lives, which I’ve messed with for my own WIP. Obviously, it would be nice to set this stuff on the Room object, but for a unique case maybe it wouldn’t be too messy to set some exceptions in those places.

The following seems to work for when the player is in startRoom:

modify exitLister
    showExits(actor)
    {
        /* show exits with our standard lister */
        if(actor.getOutermostRoom==startRoom)
            "The only <q>Exit</q> here is a song by U2. ";
        else
            showExitsFrom(actor, actor.location);
    }
    showStatuslineExits()
    {
        /* if statusline exit displays are enabled, show the exit list */
        if (exitsMode.inStatusLine)
        {
            if(gPlayerChar.getOutermostRoom==startRoom)
                "\nExits: musical!";
            else 
                showExitsWithLister(gPlayerChar, gPlayerChar.location,
                                statuslineExitLister,
                                gPlayerChar.location
                                .wouldBeLitFor(gPlayerChar));
        }
    }
;

modify explicitExitLister
    showListEmpty(pov, parent)
    {
        if(gActor.getOutermostRoom==startRoom)
            "Only the power of Bono can help you now. ";
        else
            inherited(pov, parent);
    }
;

Maybe someone has a more elegant solution than this. In particular I worry about using gActor and gPlayerChar in these kinds of methods.

Thanks! That works. I didn’t realize the exitLister was a global preinit object.

If I should happen to implement a maze, I’ll have to modify these modifications further, but now that I have the basic hooks in place, that should be easy.

–JA

Although Pacian’s suggestion should work, it’s sub-optimal because the code that checks for the current location will be executed regardless of the PC’s actual current location. Adding more and more code that gets executed regardless is one of those things that can slow down the game. Remember the weird lag between player input and response time in “Max Blaster and Doris de Lightning” for example? I strongly suspect that this was the result of a lot of code getting executed at all times, even when not needed.

Best is to always keep code localized to places where it’s actually needed. In this case, if you take a look at travel.t, and search in it for the places where gExitLister is used (a simple text search should do), you will find the methods that use gExitLister to perform their work. For example, BasicLocation defines the following method:

/* * Show a list of exits from this room as part of failed travel * ("you can't go that way"). */ cannotGoShowExits(actor) { /* if we have an exit lister, ask it to show exits */ if (gExitLister != nil) gExitLister.cannotGoShowExits(actor, self); }

Instead of modifying BasicLocation itself, you can simply override all the methods that delegate their work to gExitLister with either your custom code, or make them delegate their work to a custom ExitLister that contains Pacian’s modifications. For example, instead of:

if (gExitLister != nil) gExitLister.cannotGoShowExits(actor, self);

your BasicLocation subclass could do:

            gMyCustomExitLister.cannotGoShowExits(actor, self);

That way, no code that checks for the current location needs to be executed every time in all locations.

Of course, you will need to also override the rest of the BasicLocation methods where you need custom behavior. Also note that BasicLocation might not be the only place that needs modifications. A text search for “gExitLister” over all *.t files of the adv3 library should be enough to get an idea of where to override (or modify) the default methods.

Hope that helps.

I think what you’re saying (I may not have a chance to try it out until tonight) is that because Room inherits from BasicLocation, I can search for all of the places where gExitLister is mentioned in classes from which Room inherits, and then override those methods in the particular room I’m creating.

I’ll have to puzzle out whether that will also work with the status line exit list. Probably it will.

Thanks for the nudge. I was sort of vaguely aware of the issue with slowing down the game, but wasn’t sure how to avoid it.

–JA

Another solution (we can keep coming with better mouse traps all day long) would be to not override anything in BasicLocation, but instead replace gExitLister with your customized ExitLister upon entering the room, and restoring it to the default upon leaving it again. This would be quite simpler and perhaps more solid.

As for the speed issue, this one check would not slow anything down by any noticeable amount of time. I just raised the issue since it’s a general one; if more and more similar checks are added, this adds up in the end.

More solid, perhaps, but not, in this particular room, simpler. The entrances and exits from this room are very tricky; that’s why I needed to mess with the exitLister in the first place. There are 11 ways to get in and 2 ways to leave … but the two exits may take you to any of the 11 entrances, depending on what else is going on.

Yeah, I got that. If anyone were actually to write a Javascript T3 VM, however (whimper…), the speed difference would probably become noticeable a lot sooner.

–JA