saul / demofile

Node.js library for parsing Counter-Strike: Global Offensive demo files
https://demofile.dev
MIT License
485 stars 53 forks source link

Is there an intuitive way of knowing who was flashed by a flashbang? #67

Closed n1c closed 3 years ago

n1c commented 6 years ago

I was hoping there would be some way of tying together player_blind and flashbang_detonate but I can't figure it out.

I know you can see the flashDuration on a player; but that also has no connection back to which flashbang and who threw it.

(also if there is a way - does it work for knowing who was damaged by a hegrenade_detonate?)

Thanks! 🙏

n1c commented 6 years ago

Doing some more digging, this might be a solution: https://github.com/akiver/CSGO-Demos-Manager/blob/198a4f81a8ccac7ad6d944d4b705be5a66a8d021/demoinfo/DemoInfo/DP/Handler/GameEventHandler.cs#L200

So they build a list of all players hit with a player_blind and send that list down with their flashbang_detonate handler, then flush the list.

How do you feel about that approach?

saul commented 6 years ago

I don’t think you’ve got much choice - I think it’s extremely unlikely for two flashbangs to detonate on the exact same tick. It depends if the detonate event fires before the blind event - I think you’d be better off doing the reconciling at tickend.

n1c commented 6 years ago

Ok cool I'll experiment with grabbing them in tickend.

Do you know if the player_blind and flashbang_detonate events will all be in the same tick?

saul commented 6 years ago

They should be fired in the same tick, yes.

n1c commented 6 years ago

This code is a little contrived because I ripped out a bunch of not-important-for-this-discussion stuff but to me it's working and hopefully what you had in mind as well?

The idea is "catch all blind and detonate events then consolidate on tickend". So we're hard assuming that there won't ever be 2 detonates on the same tick and that all the blind events happen at the same tick as the detonate :holdingthumbs:

let demo: any;
let tickFlashbangDetonate: any = undefined;
let tickPlayersBlind: any[];
let events: any[];

demo.on('tickend', () => {
  if (tickFlashbangDetonate) {
    tickFlashbangDetonate.players_blind = tickPlayersBlind;
    events.push(tickFlashbangDetonate);
  }

  tickFlashbangDetonate = undefined;
  tickPlayersBlind = [];
});

demo.gameEvents.on('flashbang_detonate', (e: any) => {
  tickFlashbangDetonate = e;
});

demo.gameEvents.on('player_blind', (e: any) => {
  tickPlayersBlind.push(e);
});
saul commented 6 years ago

I think that's fine - if you want to be extra safe, you could throw an exception if you see more than one flashbang_detonate on the same tick. If that occurs, then you could probably do it by range to see who got blinded by which flashbang (and hope that two flashbangs don't occur in close proximity on the same tick).

Has this answered your question? Sorry there isn't a cleaner solution.

n1c commented 6 years ago

Yeah that's a good plan & seems to solve the problem!

Thanks again!