Skip to content

Commit 6f36fec

Browse files
committed
delay some events only if data is not available
these only need to be delayed at the start of the demo until player data is available - player_death (Kill) - player_footstep (PlayerFootstep) - weapon_fire (WeaponFire)
1 parent 88ba5b8 commit 6f36fec

File tree

1 file changed

+79
-64
lines changed

1 file changed

+79
-64
lines changed

game_events.go

Lines changed: 79 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -72,84 +72,99 @@ type gameEventHandlerFunc func(map[string]*msg.CSVCMsg_GameEventKeyT)
7272
func newGameEventHandler(parser *Parser) gameEventHandler {
7373
geh := gameEventHandler{parser: parser}
7474

75+
// some events need to be delayed until their data is available
76+
// some events can't be delayed because the required state is lost by the end of the tick
77+
// TODO: maybe we're supposed to delay all of them and store the data we need until the end of the tick
7578
delay := func(f gameEventHandlerFunc) gameEventHandlerFunc {
7679
return func(data map[string]*msg.CSVCMsg_GameEventKeyT) {
7780
parser.delayedEventHandlers = append(parser.delayedEventHandlers, func() {
7881
f(data)
7982
})
8083
}
8184
}
85+
86+
// some events only need to be delayed at the start of the demo until players are connected
87+
delayIfNoPlayers := func(f gameEventHandlerFunc) gameEventHandlerFunc {
88+
return func(data map[string]*msg.CSVCMsg_GameEventKeyT) {
89+
if len(parser.gameState.playersByUserID) == 0 {
90+
delay(f)
91+
} else {
92+
f(data)
93+
}
94+
}
95+
}
96+
8297
geh.gameEventNameToHandler = map[string]gameEventHandlerFunc{
8398
// sorted alphabetically
84-
"announce_phase_end": nil, // Dunno
85-
"begin_new_match": geh.beginNewMatch, // Match started
86-
"bomb_beep": nil, // Bomb beep
87-
"bomb_begindefuse": geh.bombBeginDefuse, // Defuse started
88-
"bomb_beginplant": geh.bombBeginPlant, // Plant started
89-
"bomb_defused": geh.bombDefused, // Defuse finished
90-
"bomb_dropped": geh.bombDropped, // Bomb dropped
91-
"bomb_exploded": geh.bombExploded, // Bomb exploded
92-
"bomb_pickup": geh.bombPickup, // Bomb picked up
93-
"bomb_planted": geh.bombPlanted, // Plant finished
94-
"bot_takeover": geh.botTakeover, // Bot got taken over
95-
"buytime_ended": nil, // Not actually end of buy time, seems to only be sent once per game at the start
96-
"cs_match_end_restart": nil, // Yawn
97-
"cs_pre_restart": nil, // Not sure, doesn't seem to be important
98-
"cs_round_final_beep": nil, // Final beep
99-
"cs_round_start_beep": nil, // Round start beeps
100-
"cs_win_panel_match": geh.csWinPanelMatch, // Not sure, maybe match end event???
101-
"cs_win_panel_round": nil, // Win panel, (==end of match?)
102-
"decoy_detonate": geh.decoyDetonate, // Decoy exploded/expired
103-
"decoy_started": delay(geh.decoyStarted), // Decoy started. Delayed because projectile entity is not yet created
104-
"endmatch_cmm_start_reveal_items": nil, // Drops
105-
"flashbang_detonate": geh.flashBangDetonate, // Flash exploded
106-
"hegrenade_detonate": geh.heGrenadeDetonate, // HE exploded
107-
"hltv_chase": nil, // Don't care
108-
"hltv_fixed": nil, // Dunno
109-
"hltv_status": nil, // Don't know
110-
"inferno_expire": geh.infernoExpire, // Incendiary expired
111-
"inferno_startburn": delay(geh.infernoStartBurn), // Incendiary exploded/started. Delayed because inferno entity is not yet created
112-
"item_equip": delay(geh.itemEquip), // Equipped / weapon swap, I think. Delayed because of #142 - Bot entity possibly not yet created
113-
"item_pickup": delay(geh.itemPickup), // Picked up or bought? Delayed because of #119 - Equipment.UniqueID()
114-
"item_remove": geh.itemRemove, // Dropped?
115-
"other_death": nil, // Dunno
116-
"player_blind": delay(geh.playerBlind), // Player got blinded by a flash. Delayed because Player.FlashDuration hasn't been updated yet
117-
"player_changename": nil, // Name change
118-
"player_connect": geh.playerConnect, // Bot connected or player reconnected, players normally come in via string tables & data tables
119-
"player_connect_full": nil, // Connecting finished
120-
"player_death": geh.playerDeath, // Player died
121-
"player_disconnect": geh.playerDisconnect, // Player disconnected (kicked, quit, timed out etc.)
122-
"player_falldamage": nil, // Falldamage
123-
"player_footstep": geh.playerFootstep, // Footstep sound
124-
"player_hurt": geh.playerHurt, // Player got hurt
125-
"player_jump": geh.playerJump, // Player jumped
126-
"player_spawn": nil, // Player spawn
99+
"announce_phase_end": nil, // Dunno
100+
"begin_new_match": geh.beginNewMatch, // Match started
101+
"bomb_beep": nil, // Bomb beep
102+
"bomb_begindefuse": geh.bombBeginDefuse, // Defuse started
103+
"bomb_beginplant": geh.bombBeginPlant, // Plant started
104+
"bomb_defused": geh.bombDefused, // Defuse finished
105+
"bomb_dropped": geh.bombDropped, // Bomb dropped
106+
"bomb_exploded": geh.bombExploded, // Bomb exploded
107+
"bomb_pickup": geh.bombPickup, // Bomb picked up
108+
"bomb_planted": geh.bombPlanted, // Plant finished
109+
"bot_takeover": geh.botTakeover, // Bot got taken over
110+
"buytime_ended": nil, // Not actually end of buy time, seems to only be sent once per game at the start
111+
"cs_match_end_restart": nil, // Yawn
112+
"cs_pre_restart": nil, // Not sure, doesn't seem to be important
113+
"cs_round_final_beep": nil, // Final beep
114+
"cs_round_start_beep": nil, // Round start beeps
115+
"cs_win_panel_match": geh.csWinPanelMatch, // Not sure, maybe match end event???
116+
"cs_win_panel_round": nil, // Win panel, (==end of match?)
117+
"decoy_detonate": geh.decoyDetonate, // Decoy exploded/expired
118+
"decoy_started": delay(geh.decoyStarted), // Decoy started. Delayed because projectile entity is not yet created
119+
"endmatch_cmm_start_reveal_items": nil, // Drops
120+
"flashbang_detonate": geh.flashBangDetonate, // Flash exploded
121+
"hegrenade_detonate": geh.heGrenadeDetonate, // HE exploded
122+
"hltv_chase": nil, // Don't care
123+
"hltv_fixed": nil, // Dunno
124+
"hltv_status": nil, // Don't know
125+
"inferno_expire": geh.infernoExpire, // Incendiary expired
126+
"inferno_startburn": delay(geh.infernoStartBurn), // Incendiary exploded/started. Delayed because inferno entity is not yet created
127+
"item_equip": delay(geh.itemEquip), // Equipped / weapon swap, I think. Delayed because of #142 - Bot entity possibly not yet created
128+
"item_pickup": delay(geh.itemPickup), // Picked up or bought? Delayed because of #119 - Equipment.UniqueID()
129+
"item_remove": geh.itemRemove, // Dropped?
130+
"other_death": nil, // Dunno
131+
"player_blind": delay(geh.playerBlind), // Player got blinded by a flash. Delayed because Player.FlashDuration hasn't been updated yet
132+
"player_changename": nil, // Name change
133+
"player_connect": geh.playerConnect, // Bot connected or player reconnected, players normally come in via string tables & data tables
134+
"player_connect_full": nil, // Connecting finished
135+
"player_death": delayIfNoPlayers(geh.playerDeath), // Player died
136+
"player_disconnect": geh.playerDisconnect, // Player disconnected (kicked, quit, timed out etc.)
137+
"player_falldamage": nil, // Falldamage
138+
"player_footstep": delayIfNoPlayers(geh.playerFootstep), // Footstep sound.- Delayed because otherwise Player might be nil
139+
"player_hurt": geh.playerHurt, // Player got hurt
140+
"player_jump": geh.playerJump, // Player jumped
141+
"player_spawn": nil, // Player spawn
127142

128143
// Player changed team. Delayed for two reasons
129144
// - team IDs of other players changing teams in the same tick might not have changed yet
130145
// - player entities might not have been re-created yet after a reconnect
131146
"player_team": delay(geh.playerTeam),
132-
"round_announce_final": geh.roundAnnounceFinal, // 30th round for normal de_, not necessarily matchpoint
133-
"round_announce_last_round_half": geh.roundAnnounceLastRoundHalf, // Last round of the half
134-
"round_announce_match_point": nil, // Match point announcement
135-
"round_announce_match_start": nil, // Special match start announcement
136-
"round_announce_warmup": nil, // Dunno
137-
"round_end": geh.roundEnd, // Round ended and the winner was announced
138-
"round_freeze_end": geh.roundFreezeEnd, // Round start freeze ended
139-
"round_mvp": geh.roundMVP, // Round MVP was announced
140-
"round_officially_ended": geh.roundOfficiallyEnded, // The event after which you get teleported to the spawn (=> You can still walk around between round_end and this event)
141-
"round_poststart": nil, // Ditto
142-
"round_prestart": nil, // Ditto
143-
"round_start": geh.roundStart, // Round started
144-
"round_time_warning": nil, // Round time warning
145-
"server_cvar": nil, // Dunno
146-
"smokegrenade_detonate": geh.smokeGrenadeDetonate, // Smoke popped
147-
"smokegrenade_expired": geh.smokeGrenadeExpired, // Smoke expired
148-
"tournament_reward": nil, // Dunno
149-
"weapon_fire": geh.weaponFire, // Weapon was fired
150-
"weapon_fire_on_empty": nil, // Sounds boring
151-
"weapon_reload": geh.weaponReload, // Weapon reloaded
152-
"weapon_zoom": nil, // Zooming in
147+
"round_announce_final": geh.roundAnnounceFinal, // 30th round for normal de_, not necessarily matchpoint
148+
"round_announce_last_round_half": geh.roundAnnounceLastRoundHalf, // Last round of the half
149+
"round_announce_match_point": nil, // Match point announcement
150+
"round_announce_match_start": nil, // Special match start announcement
151+
"round_announce_warmup": nil, // Dunno
152+
"round_end": geh.roundEnd, // Round ended and the winner was announced
153+
"round_freeze_end": geh.roundFreezeEnd, // Round start freeze ended
154+
"round_mvp": geh.roundMVP, // Round MVP was announced
155+
"round_officially_ended": geh.roundOfficiallyEnded, // The event after which you get teleported to the spawn (=> You can still walk around between round_end and this event)
156+
"round_poststart": nil, // Ditto
157+
"round_prestart": nil, // Ditto
158+
"round_start": geh.roundStart, // Round started
159+
"round_time_warning": nil, // Round time warning
160+
"server_cvar": nil, // Dunno
161+
"smokegrenade_detonate": geh.smokeGrenadeDetonate, // Smoke popped
162+
"smokegrenade_expired": geh.smokeGrenadeExpired, // Smoke expired
163+
"tournament_reward": nil, // Dunno
164+
"weapon_fire": delayIfNoPlayers(geh.weaponFire), // Weapon was fired
165+
"weapon_fire_on_empty": nil, // Sounds boring
166+
"weapon_reload": geh.weaponReload, // Weapon reloaded
167+
"weapon_zoom": nil, // Zooming in
153168
}
154169

155170
return geh

0 commit comments

Comments
 (0)