Open eriktorbjorn opened 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.
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
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)>>)>>
It must have something to do with this part of the code:
It took me a while to spot it but... If the verb is "THROW", the
COND
evaluates toPRSI
, the the object you threw something at, i.e. the robot. Otherwise, ifPRSO
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.