fgsfdsfgs / perfect_dark

work in progress port of n64decomp/perfect_dark to modern platforms
MIT License
1.22k stars 75 forks source link

Guards not reacting correctly in Air Base #96

Open Graslu opened 1 year ago

Graslu commented 1 year ago

In the original game, you don't get instantly detected after dealing with the first guard or even the patrolling one if you're quick enough. In the port, it seems like they detect their dying friends through walls and from their back.

Here's the port vs 1964 GEPD: https://github.com/fgsfdsfgs/perfect_dark/assets/34986384/c32e11fe-2e41-4e52-97c5-cd534ed86d75

tmyqlfpir commented 1 year ago

I can confirm this issue. The problem is somewhere within chrAlertOthersOfInjury() which is used to handle character reactions to dead/injured enemies. It appears that the line of sight check used by chrHasLosToPos() returns a different result compared to N64.

Phnod commented 1 year ago

Hey @Graslu, let me know if #134 feels right to you.

Graslu commented 1 year ago

Seems about right! Does this affect any other level I should test?

Phnod commented 1 year ago

Good to hear! This also affects Chicago's first few moments, previously the FBI agent would be alerted way too soon, but that seems to be fixed now too. Any instance where neutralizing a guard behind another one not looking should not alert them anymore though, but I'm not sure what other levels that could change behaviors.

Phnod commented 1 year ago

I suppose this should be reopened.

Phnod commented 1 year ago

I spent a while testing out a maybe solution. Though it still seems slightly inconsistent of the original behavior, it's better than the current behavior. I did a lot of testing and recorded a little bit of it so there's something to reference it against, though I want to test and make sure there's no other regressions elsewhere.

perfect_dark_pc_guard_sight.patch

GE1964 guard behavior: GE1964 VIDEO

PC patch guard behavior: PC PATCH VIDEO

I'm really curious what is going behind the scenes to make it vary so differently with the original issue compared to the N64 version.

Graslu commented 1 year ago

So unrelated to Air Base but I assume it's a similar issue. The Blonde guards at the end of Deep Sea will target Caroll. Don't think they can damage him, but after you alert then by killing one he'll try to slap him.

Also on Chicago, similar issue to Air Base where they see you from behind. Noticeable on PA after you slap the first FBI Agent.

fgsfdsfgs commented 1 year ago

This sure seems like the LOS check sometimes goes through solid collision geometry, or maybe through seams in it or something. If that is the case, then the FOV check on the guards is unrelated to this issue and fixing it just happens to fix the guards in Air Base because I guess they're looking away from the bodies of the guards you kill outside. I don't know why it would fail, but that would explain a lot of LOS-related issues.

Edit: Oh, this happens with the other guards that are outside. That's more interesting. Wonder how the fuck this is even supposed to work in the original game.

Edit 2: Wonder if it's related to this crash fix. Could be that by fixing that I accidentally made chrAlertOthersOfInjury function "correctly", because it doesn't check random out of bounds garbage anymore. Or the fix just broke something else.

fgsfdsfgs commented 1 year ago

An explanation from Ryan Dwyer:

There's two factors at play:

  1. On N64, it takes longer to draw your crossbow due to lag, thus it takes longer to kill the guard around the corner, which means the patrolling guard genuinely is out of sight and fails the LOS check.
  2. On N64, notifychrindex is -1, which makes it read garbage data while the guard is in his dying animation. The garbage value is > the chr count, so the notify loop doesn't execute while he's dying. On the final frame of death, it sets his notifychrindex to 0, and it finds the patrolling guard. But he's out of sight by that point.

The biggest issue is the second one, as the N64 has to wait for the guard to finish his anim before the notify is done, and that takes a second or two

Point (2) was changed as the result of the crash fix mentioned above, so the death animation starts alerting immediately and not upon completion. I pushed a different fix that should match the original behavior now, so maybe now it'll be a bit closer to that. Not much can be done about (1).

As it turns out, there never really was a working FOV check for this particular case, so the guards should spot bodies with their backs even on N64, it will just take them a few seconds longer to react. Whether #179 should be merged to fix the FOV check I don't know, since that will make it different from the OG behavior in that there actually will be a working FOV check.

Phnod commented 1 year ago

It's a good question, I have to wonder what the original intended design was, they had this FOV logic that just wasn't used at all, I'm really curious how it ended up that way in development. Maybe changes like this could be merged in with an ini toggle for original game behavior? I could imagine cases like this popping up for future AI/etc fixes/improvements.

tunbridgep commented 9 months ago

The FOV check might be cool as an additional gameplay option. Like "More realistic guard vision" or something. It would be a shame to let that work go to waste.