qoala / InvisibleInc-CommunityBugFixes

1 stars 0 forks source link

Ambush doesn't fire on a movement that breaks disguise #42

Open qoala opened 3 years ago

qoala commented 3 years ago

https://www.twitch.tv/videos/944213691 @ 06:33:50 Tony is on ambush. Prism is disguised.
The inspector runs into the tile next to both of them.

Expected: Inspector breaks Prism's cloak, then is ambushed by Tony.

Actual: Inspector breaks Prism's cloak and goes on overwatch. Tony does nothing.

qoala commented 3 years ago

When a unit is moving (sim:moveUnit), the usual order is:

  1. sim:moveUnit>sim:warpUnit TRG_UNIT_WARP_PRE (can stop the unit from moving)
  2. sim:moveUnit>sim:warpUnit unit is moved into new tile
  3. sim:moveUnit>sim:warpUnit TRG_UNIT_WARP (immediate effects from the unit being in the new tile)
  4. sim:moveUnit abort if unit has been interrupted
  5. sim:moveUnit>sim:processReactions(unit) TRG_OVERWATCH (ambush/overwatch fires on the moving unit)
  6. sim:moveUnit>sim:processReactions(unit)>aiplayer:processReactions(unit) (the unit reacts to interests/targets it may have acquired as a result of the recent move)
  7. sim:moveUnit continues (with more "abort if interrupted" checks)

So with a normal ambush scenario, the guard is ambushed at step 5 and never shouts, even if he sees an agent.

The disguise is broken by simdisguiseitem:onTrigger on TRG_UNIT_WARP/TRG_UNIT_USE_DOOR.
unit:setDisguise calls sim:processReactions(unit) with Prism, causing all guards to react to their updated interests/targets. ​ The moving guard has a new target, which interrupts its move., and the movement is cancelled at step 4, before ambush can trigger.


A related bug occurs if a guard opens a door with disguised prism on the other side. Any ambush/overwatch that should have hit the guard for opening the door are cancelled, because sim:modifyExit doesn't call sim:processReactions(unit) if the unit was already interrupted.


Possible fix: if a unit is currently in the process of modifying an exit or moving (and not yet interrupted), it should be omitted from bulk aiplayer:processReactions calls that are run off of intervening triggers. That unit will get to process reactions as part of its action, but the overwatches should get to fire before it does so.