[Scummvm-tracker] [ScummVM] #10860: QFG4: Lock up when casting Trigger after Summon Staff

ScummVM trac at scummvm.org
Tue Jan 8 18:56:43 CET 2019


#10860: QFG4: Lock up when casting Trigger after Summon Staff
--------------------------------+----------------------------
  Reporter:  tomasz89           |      Owner:  (none)
      Type:  defect             |     Status:  new
  Priority:  normal             |  Component:  Engine: SCI
Resolution:                     |   Keywords:  SCI32 original
      Game:  Quest for Glory 4  |
--------------------------------+----------------------------

Comment (by Vhati):

 Here's what's going on with the cursor.

 handsOff() was intended to never cache the cursor when the current event
 message is from Open, Trigger, or Fetch. Sometimes it doesn't recognize
 them.
 \\
 * At every moment, User::doit() recycles "curEvent" and passes that to
 User::handleEvent().
   * User's "curEvent" property is a vEvt object.
   * vEvt::new() calls
 [http://scicompanion.com/Documentation/Kernels/GetEvent.html kGetEvent] to
 clobber all its own properties with new values.
     * Among them are: type, message, modifiers, x, y.
     * When idle, the coords match the cursor's position at each moment,
 and the rest are 0.
 * The event is passed around until it reaches aGate, which inherits
 Feature::handleEvent().
 \\
 \\
 script 64950 - Feature::handleEvent()
 {{{
 (method (handleEvent param1 &tmp temp0)
         (cond
                 ((param1 claimed?) (return 1))
                 (
                         (and
                                 (& (param1 type?) $4000)
                                 (self onMe: param1)
                                 (self isNotHidden:)
                         )
 # Important.
                         (CueObj
                                 state: 0
                                 cycles: 0
                                 client: self
                                 theVerb: (param1 message?)
                         )
                         (= temp0 (param1 claimed: 1))
                         (if
                                 (and
                                         (g80_User canControl:)
                                         (& (g0_hero state?) $0002)
                                         (>
                                                 (GetDistance
                                                         (g0_hero x?)
                                                         (g0_hero y?)
                                                         approachX
                                                         approachY
                                                 )
                                                 approachDist
                                         )
                                         g66_gloryApproachCode
                                         (& _approachVerbs (global66 doit:
 (param1 message?)))
                                 )
                                 (g0_hero
                                         setMotion: PolyPath approachX (+
 (global0 z?) approachY) CueObj
                                 )
                         else
                                 (g0_hero setMotion: 0)
 # Important.
                                 (if (self facingMe:) (CueObj changeState:
 3))
                         )
                 )
         )
         (return temp0)
 )
 }}}
 \\
 \\
 * CueObj is a Script that holds the message (82) until state 3, when it
 has aGate call self::doVerb(82).

 * If hero is already facing aGate, that happens immediately.
   * CueObj is skipped directly to state 3.
   * doVerb() schedules castTriggerScript.
   * handsOff() checks if ((User curEvent?) message?) is 82.
   * The cursor is not cached. This seems to be intended behavior.

 * However, if hero is not facing aGate, there is a delay.
   * CueObj state 1 adjusts hero's heading to face aGate.
   * In that extra time, User::doit() resets the event, zeroing out
 "message".
   * CueObj reaches state 3. Yadda yadda yadda...
   * handsOff() sees ((User curEvent?) message?) is 0. It WILL cache the
 cursor.
 \\
 \\
 Bonus confusion: hero::normalize() doesn't reset "heading".

 After the first casting, hero appears to face north, but technically still
 faces aGate.
 So the next casting will not cache the cursor.
 \\
 \\
 That's more or less what's going on. aside from one case I don't
 understand... If hero stands below the gate facing north and casts at a
 spot directly overhead, all castings cache the cursor.
 \\
 \\
 I'm not confident about messing with handsOff and the event system to fix
 it.
 I'll leave it be.

-- 
Ticket URL: <https://bugs.scummvm.org/ticket/10860#comment:14>
ScummVM <https://bugs.scummvm.org>
ScummVM


More information about the Scummvm-tracker mailing list