Table of Contents |
Goldskull > Making things
happen
Making things happen
There are basically two things we need to make happen in this game:
- Killing the player character if he springs the trap (while letting him take the skull if he solves the puzzle)
- Ending the game in victory if the player character succeeds in making off with the skull unharmed.
We’ll now deal with each in turn.
Springing the Trap
The trap is sprung if the player character removes the gold skull from
the pedestal when the rock isn’t already on it. The most convenient
place to put the code for this is probably in the
notifyRemove(obj)
method of the pedestal
object, since this is called whenever the
actionMoveInto()
method of an object being
moved is called. This, incidentally, is one of those notifications we
were talking about towards the end of the last chapter, and explains why
it’s a good idea to use actionMoveInto()
rather than just plain moveInto()
when
implementing the direct response to a player’s command. By using
notifyRemove() we should ensure that the trap is sprung whatever method
the player contrives to remove the skull from the pedestal, as we shall
see.
We’ll try to make the code as general as possible, since if the player
puts the rock on the pedestal, then removes the skull, but then goes on
to remove the rock, the trap should still be sprung. Since
notifyRemove(obj)
is called just before obj
is moved, we thus want to check whether there are fewer than two objects
on the pedestal at that point. If there are, then the object being moved
must be the only object on the pedestal, so the trap should be sprung
when it’s moved. We can get at the number of objects on the pedestal
with the expression contents.length()
, i.e.
the number of items in the list that constitutes the
contents
property of the
pedestal
object. Since obj is the object
being moved, we can use obj.theName
in an
embedded expression to print the name of the right object, whether it’s
the skull or the rock that’s just been removed from the pedestal. The
resulting code looks like this:
+ pedestal: Thing 'stone pedestal; smooth'
"The smooth stone pedestal is artfully positioned to catch the sunlight at
just this time of day. "
isFixed = true
contType = On
notifyRemove(obj)
{
if(contents.length < 2)
{
"As <<obj.theName>> leaves the pedestal, a volley of poisonous
arrows is shot from the walls! You try to dodge the arrows, but
they take you by surprise!";
finishGameMsg(ftDeath, [finishOptionUndo]);
}
}
;
We’ve already encountered the use of the
finishGameMsg()
function to end the game. The
only difference here is the use of ftDeath
to
make the game end displaying the message *** YOU HAVE DIED ***
instead of *** YOU HAVE WON ***. We once again supply the
finishOptionUndo
option so that the player can
UNDO the fatal move. If only that were possible in real life!
Try compiling and running the game to ensure that everything works as expected.
Letting the Player Win
Although the player can take the gold skull safely, there’s currently still no way to reach a winning ending. We said that we’d announce victory when the player character heads back to camp carrying the gold skull. We can implement that by defining a method on the appropriate direction property of startroom (yes, you can put methods on direction properties too!) that disallows travel if the player character isn’t carrying the gold skull but announces victory if he is. This involves making a couple of additions to the startroom object:
startroom: Room 'Outside Cave'
desc = "You're standing in the bright sunlight just outside of a large,
dark, foreboding cave, which lies to the north. The path back to your
camp winds roughly southeast through the dense foliage. "
north = cave
southeast()
{
if(goldSkull.isIn(me))
{
"Your mission complete, you head triumphantly back to your camp. ";
finishGameMsg(ftVictory, [finishOptionUndo]);
}
else
"You've no intention of leaving till you've got what you came for.
";
}
;
There really isn’t anything that’s new here, beyond the fact that you can attach a method to a direction property and that the method will be executed when the player character tries to move in the associated direction (incidentally you can also do this in TADS 2, but not in adv3). While we’re at it, note that since we’re testing for goldSkull.isIn(me), which tests for direct or indirect containment, the test would still pass even if the explorer placed the gold skull in a knapsack and carried the knapsack (as we shall see).
If you try compiling and running the game now you should notice something else. The southeast exit now appears in the exit lister, even though we haven’t defined it as actually going anywhere. The default behaviour of the exit lister is to list the directions associated with Rooms, TravelConnectors (which includes doors and stairways) and methods, but not those associated with single-quoted or double-quoted strings. The reasoning is that a method is likely to do something (as here) whereas a string property is likely to just display a message explaining why travel isn’t possible. A method on a direction property is thus treated as a kind of simulated exit, which is fully appropriate here.
In the next section we’ll start adding all sorts of little tweaks and improvements to this game, and introduce several new features of adv3Lite in the process.
adv3Lite Library Tutorial
Table of Contents |
Goldskull > Making things
happen