the-infocom-files / witness

The Witness
3 stars 4 forks source link

Searching Monica isn't working as intended #3

Open eriktorbjorn opened 5 years ago

eriktorbjorn commented 5 years ago

Note: This is a condensed version of https://github.com/AlexProudfoot/The-ZIL-Files/issues/77

I'm still a bit unclear if bugfixing is within the scope of this project, but this one should apply regardless. When you reach the end of the game, where you can cuff and search Monica, it doesn't work as intended:

>CUFF MONICA
(to the lounge)
She puts up a struggle, but you manage to do it.

>SEARCH MONICA
Monica grudgingly allows you to search. You find nothing whatsoever of interest.

>SEARCH MONICA FOR GUN
You find a hand gun in Monica's pocket and take it.

>SEARCH MONICA FOR KEY
You find a single key in Monica's pocket and take it.

You're supposed to find the key and gun regardless of whether you explicitly search for them.

The problem is apparently in the way SET works. The MONICA-F routine handles both "SEARCH MONICA" and "SEARCH MONICA FOR ":

       (<OR <AND <DOBJ? MONICA> <SET OBJ ,PRSI>
         <VERB? SEARCH SEARCH-OBJECT-FOR>>
        <AND <IOBJ? MONICA> <SET OBJ ,PRSO>
         <VERB? TAKE>>>
    <FSET ,MONICA ,TOUCHBIT>
    <COND (<NOT ,MONICA-TIED-TO> <MONICA-PUSHES>)
          (<AND <IN? ,CLOCK-KEY ,MONICA>
            <OR <VERB? SEARCH> <EQUAL? .OBJ ,GENERIC-KEY ,CLOCK-KEY>>>
           <MOVE ,CLOCK-KEY ,PLAYER>
           <FCLEAR ,CLOCK-KEY ,INVISIBLE>
           <FSET ,CLOCK-KEY ,TOUCHBIT>
           <TELL
"You find a single key in Monica's pocket and take it." CR> ;"? better")
          (<AND <IN? ,INSIDE-GUN ,MONICA>
            <OR <VERB? SEARCH><EQUAL? .OBJ ,GENERIC-GUN ,INSIDE-GUN>>>
           <SETG SEEN-MONICA-AT-CLOCK T>
           <MOVE ,INSIDE-GUN ,PLAYER>
           <FCLEAR ,INSIDE-GUN ,INVISIBLE>
           <FSET ,INSIDE-GUN ,TOUCHBIT>
           <TELL
"You find a hand gun in Monica's pocket and take it." CR> ;"? better")
          (T <RFALSE>)>)

Apparently the problem is that in the "SEARCH MONICA" case, PRSI is 0. In Zilf, <SET OBJ ,PRSI> will then also be 0, so the code is never triggered.

Interestingly, the compiled version of Release 23 has the same bug, so presumably later versions of Infocom's compiler behaved the same way as Zilf.

A suggestion I got in the bug report mentioned above was to change <SET OBJ ,PRSI> to <PROG () <SET OBJ ,PRSI> T>. Elegant, perhaps, though not something you see much of in the rest of the Infocom source code, outside of macros...

(By the way, another thing I just noticed is that you can "TAKE KEY FROM MONICA" even without cuffing her. Probably because the key (but not the gun) is made visible when you see her unlocking the clock. Since you see her holding the key, but don't see what she's removing from the clock, I'm guessing this is deliberate.)

AlexProudfoot commented 5 years ago

I just updated my project list. Yes, bug fixes will be handled in two phases. The alpha phase will deal with bugs introduced since the last commercial release (or development release in the case of unreleased works) and will hopefully flush out issues with the compiler and my processes. The beta phase will deal with existing issues such as the Infocom Bugs Lists and your spelling corrections. I believe this issue belongs in the alpha phase. Any observations or suggestions would be very welcome.

eriktorbjorn commented 5 years ago

Well... The PROG() trick works, and seemed to produce code similar to the original, if that's even a priority. But if we want to stick with how Infocom themselves handled this in later games, I guess this fragment from Cutthroats's MCGINTY-F could be a hint:

           (<OR <AND <VERB? TAKE>
                 <PRSI? ,MCGINTY>>
            <AND <VERB? ASK-FOR>
             <PRSO? ,MCGINTY>>>
        <COND (<PRSO? ,MCGINTY> <SET OBJ ,PRSI>)
              (T <SET OBJ ,PRSO>)>

Following that example, the setting of OBJ should be moved into a separate condition, like so:

       (<OR <AND <DOBJ? MONICA>
         <VERB? SEARCH SEARCH-OBJECT-FOR>>
        <AND <IOBJ? MONICA>
         <VERB? TAKE>>>
    <COND (<DOBJ? MONICA> <SET OBJ ,PRSI>)
          (T <SET OBJ ,PRSO>)>

Which seemed to work fine when I tried it. Hopefully this is the only instance of this particular problem. Hopefully.