@@ -72,84 +72,99 @@ type gameEventHandlerFunc func(map[string]*msg.CSVCMsg_GameEventKeyT)
72
72
func newGameEventHandler (parser * Parser ) gameEventHandler {
73
73
geh := gameEventHandler {parser : parser }
74
74
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
75
78
delay := func (f gameEventHandlerFunc ) gameEventHandlerFunc {
76
79
return func (data map [string ]* msg.CSVCMsg_GameEventKeyT ) {
77
80
parser .delayedEventHandlers = append (parser .delayedEventHandlers , func () {
78
81
f (data )
79
82
})
80
83
}
81
84
}
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
+
82
97
geh .gameEventNameToHandler = map [string ]gameEventHandlerFunc {
83
98
// 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
127
142
128
143
// Player changed team. Delayed for two reasons
129
144
// - team IDs of other players changing teams in the same tick might not have changed yet
130
145
// - player entities might not have been re-created yet after a reconnect
131
146
"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
153
168
}
154
169
155
170
return geh
0 commit comments