the-infocom-files/zork3

"CLIMB ROPE" doesn't work as intended

Opened this issue · 0 comments

From Release 17:

>LOOK
Cliff
This is a remarkable spot in the dungeon. Perhaps two hundred feet above you is
a gaping hole in the earth's surface through which pours bright sunshine! A few
seedlings from the world above, nurtured by the sunlight and occasional rains,
have grown into giant trees, making this a virtual oasis in the desert of the
Underground Empire. To the west is a sheer precipice, dropping nearly fifty feet
to jagged rocks below. The way south is barred by a forbidding stone wall,
crumbling from age. There is a jagged opening in the wall to the southwest,
through which leaks a fine mist. The land to the east looks lifeless and barren.
A rope is tied to one of the large trees here and is dangling over the side of
the cliff, reaching down to the shelf below.
It seems as if somebody has been here recently, as there is some fresh bread
lying beneath one of the other trees.

>CLIMB ROPE
Cliff Ledge
This is a rock-strewn ledge near the base of a tall cliff. The bottom of the
cliff is another fifteen feet below. You have little hope of climbing up the
cliff face, but you might be able to scramble down from here (though it's
doubtful you could return).
A long piece of rope is dangling down from the top of the cliff and is within
your reach.
A large chest, closed and locked, is lying among the boulders.

>CLIMB ROPE
Cliff Base
You are at the base of a steep cliff. Directly above you is a wide ledge and far
above that some natural sunlight can be seen. To the northeast is a steeply
climbing path and the ground becomes sandy toward the south.

Here's what happens in this version:

>LOOK
Cliff
This is a remarkable spot in the dungeon. Perhaps two hundred feet above you is
a gaping hole in the earth's surface through which pours bright sunshine! A few
seedlings from the world above, nurtured by the sunlight and occasional rains,
have grown into giant trees, making this a virtual oasis in the desert of the
Underground Empire. To the west is a sheer precipice, dropping nearly fifty feet
to jagged rocks below. The way south is barred by a forbidding stone wall,
crumbling from age. There is a jagged opening in the wall to the southwest,
through which leaks a fine mist. The land to the east looks lifeless and barren.
A rope is tied to one of the large trees here and is dangling over the side of
the cliff, reaching down to the shelf below.
It seems as if somebody has been here recently, as there is some fresh bread
lying beneath one of the other trees.

>CLIMB ROPE
The rope doesn't lead downward.

>DOWN
Cliff Ledge
This is a rock-strewn ledge near the base of a tall cliff. The bottom of the
cliff is another fifteen feet below. You have little hope of climbing up the
cliff face, but you might be able to scramble down from here (though it's
doubtful you could return).
A long piece of rope is dangling down from the top of the cliff and is within
your reach.
A large chest, closed and locked, is lying among the boulders.

>DOWN
The rope doesn't lead downward.

So it tries to go down, just like in the release version, but it doesn't find the way.

There is a Zork III-specific case in V-CLIMB-FOO that handles "CLIMB ROPE":

<ROUTINE V-CLIMB-FOO ()
	 %<COND (<==? ,ZORK-NUMBER 3>
		 '<V-CLIMB-UP <COND (<EQUAL? ,PRSO ,ROPE ,GLOBAL-ROPE>
				     ,P?DOWN)
				    (T ,P?UP)>
			      T>)
		(ELSE
		 '<V-CLIMB-UP ,P?UP ,PRSO>)>>

This is apparently so that "CLIMB ROPE" means "CLIMB DOWN" while in every other case "CLIMB " means "CLIMB UP".

The problem is that zork-substrate's V-CLIMB-UP has some pretty strict rules for when it's working:

<ROUTINE V-CLIMB-UP ("OPTIONAL" (DIR ,P?UP) (OBJ <>) "AUX" X TX)
         <COND (<AND .OBJ <NOT <EQUAL? ,PRSO ,ROOMS>>>
                <SET OBJ ,PRSO>)>
         <COND (<SET TX <GETPT ,HERE .DIR>>
                <COND (.OBJ
                       <SET X <PTSIZE .TX>>
                       <COND (<OR <EQUAL? .X ,NEXIT>
                                  <AND <EQUAL? .X ,CEXIT ,DEXIT ,UEXIT>
                                       <NOT <GLOBAL-IN? ,PRSO <GETB .TX 0>>>>>
                              <TELL "The " D .OBJ " do">
                              <COND (<NOT <EQUAL? .OBJ ,STAIRS>>
                                     <TELL "es">)>
                              <TELL "n't lead ">
                              <COND (<==? .DIR ,P?UP>
                                     <TELL "up">)
                                    (T <TELL "down">)>
                              <TELL "ward." CR>
                              <RTRUE>)>)>
                <DO-WALK .DIR>
                <RTRUE>)

The "DOWN" exit from CLIFF is a CEXIT, (DOWN TO CLIFF-LEDGE IF ROPE-FLAG ELSE "The drop would kill you."). The "DOWN" exit from CLIFF-LEDGE is just a plain UEXIT, (DOWN TO CLIFF-BASE).

So both of these exit types are handled. However, the problem seems to be the call to <NOT <GLOBAL-IN? ,PRSO <GETB .TX 0>>>. It checks if the object you are trying to climb is a local global object in the destination.

When you are in CLIFF, it will check if ROPE is a local global object in CLIFF-LEDGE. When you are in CLIFF-LEDGE it will check if GLOBAL-ROPE is a local global object in CLIFF-BASE.

Both of these checks fail.

In the older Zork III code, it's much simpler:

<ROUTINE V-CLIMB-UP ("OPTIONAL" (DIR ,P?UP) (OBJ <>) "AUX" X)
         #DECL ((DIR) FIX (OBJ) <OR ATOM FALSE> (X) TABLE)
         <COND (<GETPT ,HERE .DIR>
                <DO-WALK .DIR>
                <RTRUE>)
               (<NOT .OBJ>
                <TELL "You can't go that way." CR>)
               (<AND .OBJ
                     <ZMEMQ ,W?WALL
                            <SET X <GETPT ,PRSO ,P?SYNONYM>> <PTSIZE .X>>>
                <TELL "Climbing the walls is to no avail." CR>)
               (ELSE <TELL "Bizarre!" CR>)>>

So apparently it used to be enough that there was any kind of exit down.