the-infocom-files / zork2

Zork II: The Wizard of Frobozz
8 stars 4 forks source link

"DESTROY ROBOT WITH SWORD" doesn't actually destroy the robot #17

Open eriktorbjorn opened 5 years ago

eriktorbjorn commented 5 years ago
>DESTROY ROBOT WITH SWORD
The robot falls to the ground and (being of shoddy construction) disintegrates
before your eyes.

>LOOK
Low Room
You are in a circular room with a low ceiling. There are exits to the east and
southeast.
There is a green piece of paper here.
There is a robot here.

>THROW SWORD AT ROBOT
The robot falls to the ground and (being of shoddy construction) disintegrates
before your eyes.

>LOOK
Low Room
You are in a circular room with a low ceiling. There are exits to the east and
southeast.
There is a green piece of paper here.

It must have something to do with this part of the code:

          (<VERB? THROW MUNG>
           <TELL
"The robot falls to the ground and (being of shoddy construction)
disintegrates before your eyes." CR>
           <REMOVE <COND (<VERB? THROW> ,PRSI) (,PRSO)>>)>>

It took me a while to spot it but... If the verb is "THROW", the COND evaluates to PRSI, the the object you threw something at, i.e. the robot. Otherwise, if PRSO is non-zero it evaluates to 1. That's the compass object. Testing with "frotz -o" confirms that this is the object that is removed.

So it should probably be <REMOVE <COND (<VERB? THROW> ,PRSI) (T ,PRSO)>>)>> instead, though I don't understand why it doesn't just do <REMOVE ,ROBOT> instead.

taradinoc commented 5 years ago

Interesting - this could be a bug in ZILF. Does it repro in the original game?

In MDL, a COND clause with only one element will evaluate it and return its value if it's non-false (or even if it is false, if it's the last clause). If there are other examples of doing this in ZIL, where a one-item COND clause is used for its value and not just as a Boolean, we should check the behavior there too.

eriktorbjorn commented 5 years ago

I'm just going to copy what I wrote on Facebook earlier:

"I just went through all of the known surviving Zork II data files in Zarf's repository. In all of them "DESTROY ROBOT WITH SWORD" removes object 1 rather than the robot, so that bug is definitely in the released versions."

The only difference is that object 1 isn't the same object across versions.

I checked in Zarf's repository, and some of the original .zap files:

From the mac-r22 version:

?ELS43: EQUAL?  PRSA,V?MUNG,V?THROW \FALSE
        PRINTI  "The robot is injured (being of shoddy construction) and falls to the floor in a pile of garbage, which disintegrates before your eyes."
        CRLF    
        EQUAL?  PRSA,V?THROW \?ELS56
        PUSH    PRSI
        JUMP    ?CND52
?ELS56: ZERO?   PRSO /?PRD54
        PUSH    1
        JUMP    ?CND52
?PRD54: PUSH    0
?CND52: REMOVE  STACK

From the r63 version:

?ELS85: EQUAL?  PRSA,V?MUNG,V?THROW \FALSE
        PRINTI  "The robot falls to the ground and (being of shoddy construction) disintegrates before your eyes."
        CRLF    
        EQUAL?  PRSA,V?THROW \?ELS98
        PUSH    PRSI
        JUMP    ?CND94
?ELS98: ZERO?   PRSO /?PRD96
        PUSH    1
        JUMP    ?CND94
?PRD96: PUSH    0
?CND94: REMOVE  STACK

From ZILF, when compiling this version:

?L54:   EQUAL? PRSA,V?MUNG,V?THROW \FALSE
        PRINTI "The robot falls to the ground and (being of shoddy construction) disintegrates before your eyes."
        CRLF
        EQUAL? PRSA,V?THROW \?L60
        PUSH PRSI
        JUMP ?L61
?L60:   ZERO? PRSO /?L62
        PUSH 1
        JUMP ?L61
?L62:   PUSH 0
?L61:   REMOVE STACK
eriktorbjorn commented 3 years ago

Interestingly, this bug appears to have been fixed in Mini-Zork II:

          (<VERB? THROW MUNG>
           <TELL
"The robot (being of shoddy construction) disintegrates before your eyes." CR>
           <REMOVE <COND (<VERB? THROW> ,PRSI)
                 (T ,PRSO)>>)>>