Skip to content

Commit 1f08ad2

Browse files
authored
Delete nade projectiles & infernos at end of round (#43)
Sometimes grenade projectiles and infernos wouldn't be deleted at the end of the round. Now we just clean up when we get the game-event round_officially_ended fixes #42
1 parent ecd8903 commit 1f08ad2

File tree

3 files changed

+60
-10
lines changed

3 files changed

+60
-10
lines changed

datatables.go

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -319,11 +319,7 @@ func (p *Parser) bindGrenadeProjectiles(entity *st.Entity) {
319319
})
320320

321321
entity.OnDestroy(func() {
322-
p.eventDispatcher.Dispatch(events.NadeProjectileDestroyedEvent{
323-
Projectile: proj,
324-
})
325-
326-
delete(p.gameState.grenadeProjectiles, entityID)
322+
p.nadeProjectileDestroyed(proj)
327323
})
328324

329325
entity.FindProperty("m_nModelIndex").OnUpdate(func(val st.PropertyValue) {
@@ -365,6 +361,21 @@ func (p *Parser) bindGrenadeProjectiles(entity *st.Entity) {
365361
}
366362
}
367363

364+
// Seperate function because we also use it in round_officially_ended (issue #42)
365+
func (p *Parser) nadeProjectileDestroyed(proj *common.GrenadeProjectile) {
366+
// If the grenade projectile entity is destroyed AFTER round_officially_ended
367+
// we already executed this code when we received that event.
368+
if _, exists := p.gameState.grenadeProjectiles[proj.EntityID]; !exists {
369+
return
370+
}
371+
372+
p.eventDispatcher.Dispatch(events.NadeProjectileDestroyedEvent{
373+
Projectile: proj,
374+
})
375+
376+
delete(p.gameState.grenadeProjectiles, proj.EntityID)
377+
}
378+
368379
func (p *Parser) bindWeapon(entity *st.Entity, wepType common.EquipmentElement) {
369380
entityID := entity.ID()
370381
p.weapons[entityID] = common.NewEquipment("")
@@ -417,10 +428,7 @@ func (p *Parser) bindNewInferno(entity *st.Entity) {
417428
})
418429

419430
entity.OnDestroy(func() {
420-
p.eventDispatcher.Dispatch(events.InfernoExpiredEvent{
421-
Inferno: inf,
422-
})
423-
delete(p.gameState.infernos, entityID)
431+
p.infernoExpired(inf)
424432
})
425433

426434
origin := entity.Position()
@@ -442,3 +450,18 @@ func (p *Parser) bindNewInferno(entity *st.Entity) {
442450
nFires = val.IntVal
443451
})
444452
}
453+
454+
// Seperate function because we also use it in round_officially_ended (issue #42)
455+
func (p *Parser) infernoExpired(inf *common.Inferno) {
456+
// If the inferno entity is destroyed AFTER round_officially_ended
457+
// we already executed this code when we received that event.
458+
if _, exists := p.gameState.infernos[inf.EntityID]; !exists {
459+
return
460+
}
461+
462+
p.eventDispatcher.Dispatch(events.InfernoExpiredEvent{
463+
Inferno: inf,
464+
})
465+
466+
delete(p.gameState.infernos, inf.EntityID)
467+
}

demoinfocs_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ func TestDemoInfoCs(t *testing.T) {
9898
t.Error("Unexprected default value, check output of last round")
9999
}
100100
})
101+
101102
// Check some things at match start
102103
p.RegisterEventHandler(func(events.MatchStartedEvent) {
103104
participants := gs.Participants()
@@ -121,6 +122,17 @@ func TestDemoInfoCs(t *testing.T) {
121122
}
122123
})
123124

125+
// Regression test for grenade projectiles not being deleted at the end of the round (issue #42)
126+
p.RegisterEventHandler(func(events.RoundStartedEvent) {
127+
if nProjectiles := len(p.GameState().GrenadeProjectiles()); nProjectiles > 0 {
128+
t.Error("Expected 0 GrenadeProjectiles at the start of the round, got", nProjectiles)
129+
}
130+
131+
if nInfernos := len(p.GameState().Infernos()); nInfernos > 0 {
132+
t.Error("Expected 0 Infernos at the start of the round, got", nInfernos)
133+
}
134+
})
135+
124136
// Net-message stuff
125137
var netTickHandlerID dispatch.HandlerIdentifier
126138
netTickHandlerID = p.RegisterNetMessageHandler(func(tick *msg.CNETMsg_Tick) {

game_events.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,22 @@ func (p *Parser) handleGameEvent(ge *msg.CSVCMsg_GameEvent) {
7979
Winner: t,
8080
})
8181

82-
case "round_officially_ended": // Round ended. . . probably the event where you get teleported to the spawn (=> You can still walk around between round_end and this?)
82+
case "round_officially_ended": // The event after which you get teleported to the spawn (=> You can still walk around between round_end and this event)
83+
// Issue #42
84+
// Sometimes grenades & infernos aren't deleted / destroyed via entity-updates at the end of the round,
85+
// so we need to do it here for those that weren't.
86+
//
87+
// We're not deleting them from entitites though as that's supposed to be as close to the actual demo data as possible.
88+
// We're also not using Entity.Destroy() because it would - in some cases - be called twice on the same entity
89+
// and it's supposed to be called when the demo actually says so (same case as with GameState.entities).
90+
for _, proj := range p.gameState.grenadeProjectiles {
91+
p.nadeProjectileDestroyed(proj)
92+
}
93+
94+
for _, inf := range p.gameState.infernos {
95+
p.infernoExpired(inf)
96+
}
97+
8398
p.eventDispatcher.Dispatch(events.RoundOfficiallyEndedEvent{})
8499

85100
case "round_mvp": // Round MVP was announced

0 commit comments

Comments
 (0)