adv3Lite: Evaluating the TravelConnector

I have an NPC who is going to prevent the PC from visiting a variety of locations. Because these are spread out over the map, it would be a bit impractical (or at least untidy) to give all of the TravelConnectors travelBarrier code (though I could do this by making them all inherit from a user-defined class). I’d rather have the beforeAction method in the NPC’s ActorState intervene before the Travel action is carried out, because that would put the list of forbidden TravelConnectors all in one place, where it can more easily be debugged.

In order to do this, though, I need to know what TravelConnector the PC is about to traverse. I’m sure there’s a way to determine this, but I don’t know what it is.

Extra points if you provide the answer before Eric gets around to it!

From the LRM for the beforeTravel method of ActorState:

     *   The beforeTravel notification triggered when the Actor is in this
     *   ActorState and traveler is just about to travel via connector. By
     *   default we do nothing.
    beforeTravel(traveler, connector) {}

In other words, you want to use the beforeTravel() method rather than the beforeAction() method. The connector the actor is about to travel is then passed to the beforeTravel() method as its first parameter.

With apologies to anyone else who was about to claim the extra points!

This coding challenge is turning out to be trickier than I had originally thought. My first idea about how to tackle it is, “Ahh – I can write a Scene.” But I’m not sure that will work. A Scene has an eachTurn() routine, but I don’t know where in the command loop that routine is called. The Library Manual says of eachTurn only, “A method that executes every turn that the scene is active.” (I would infer that it’s executed by a call to sceneManager.execute, except that that code is found nowhere in the library…)

But no matter when it executes, it’s likely to be wrong for some of what I need. Sometimes I need to have something happen before the PC travels. Sometimes I need it to happen after the PC travels. And in each case, I need to know not just the room the PC is departing from, but also the room in which she is arriving, both before AND after she travels (or attempts to travel and fails), so that I can insert messages and move other objects as needed at either point in the process (or at both points).

There’s not much point in describing the details of the game scenario, as it’s complex. Basically, an NPC is following the PC around like a little puppy-dog, but there are certain locations the NPC won’t go to – and the PC can loop around the outside and re-enter from a different direction the region where the NPC does follow. In those cases, the NPC needs to appear to arrive in the room after the PC’s travel action – but not by following. The messages printed out have to know about the origin point of the travel action, but they have to be printed out after the room description. Yet the NPC has to arrive in the new room before the room description is printed, so that her specialDesc will show up.

At the moment, I’m baffled.

It’s a bit difficult for me to give any very specific solution here, but one thing to look at might be the travelerEntering(traveler, origin) method of Room: this is invoked on the room when traveler is about to enter it from another origin (another room). You could use this method to set up a zero-length Fuse which could then be used to display some text later on the same term (after the room description).

Alternatively you could use the beforeTravel(traveler, connector) method on the ActorState. The room traveled from would then be given by traveler.getOutermostRoom and the room to be traveled to by connector.destination. You could once again set up a Fuse in the method to display text at the end of the turn (i.e. after the room description in the destination room).

I think you’re probably right that Scenes won’t be much help here. To answer your query, the eachTurn() method is indeed driven from the executeEvent() method of sceneManager, and that in turn is driven by the executeTurn() method of eventManager, which is in turn driven by the turnSequence() method of the current Action. I douhbt, however, whether knowing this will help very much with the problem you’re trying to solve.