Skip to content

Commit f162b78

Browse files
committed
events: add Attacker & FlashDuration() to PlayerFlashed event
Also fixes the issue of events.PlayerFlashed.Player.FlashDuration being 0 in most cases by waiting with dispatching the events until the end of the tick. See #70 & #71
1 parent 75e489d commit f162b78

File tree

6 files changed

+49
-2
lines changed

6 files changed

+49
-2
lines changed

events/events.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
package events
77

88
import (
9+
"time"
10+
911
r3 "github.com/golang/geo/r3"
1012

1113
common "github.com/markus-wa/demoinfocs-golang/common"
@@ -220,7 +222,14 @@ type GrenadeProjectileDestroy struct {
220222

221223
// PlayerFlashed signals that a player was flashed.
222224
type PlayerFlashed struct {
223-
Player *common.Player
225+
Player *common.Player
226+
Attacker *common.Player
227+
}
228+
229+
// FlashDuration returns the duration of the blinding effect.
230+
// This is just a shortcut for Player.FlashDurationTime().
231+
func (e PlayerFlashed) FlashDuration() time.Duration {
232+
return e.Player.FlashDurationTime()
224233
}
225234

226235
// BombEventIf is the interface for all the bomb events. Like GrenadeEventIf for GrenadeEvents.

events/events_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package events
2+
3+
import (
4+
"testing"
5+
"time"
6+
7+
"github.com/stretchr/testify/assert"
8+
9+
"github.com/markus-wa/demoinfocs-golang/common"
10+
)
11+
12+
func TestPlayerFlashed_FlashDuration(t *testing.T) {
13+
p := common.NewPlayer()
14+
e := PlayerFlashed{Player: p}
15+
16+
assert.Equal(t, time.Duration(0), e.FlashDuration())
17+
18+
p.FlashDuration = 2.3
19+
20+
assert.Equal(t, 2300*time.Millisecond, e.FlashDuration())
21+
}

game_events.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,13 @@ func (p *Parser) handleGameEvent(ge *msg.CSVCMsg_GameEvent) {
167167

168168
case "player_blind": // Player got blinded by a flash
169169
data = mapGameEventData(d, ge)
170-
p.eventDispatcher.Dispatch(events.PlayerFlashed{Player: p.gameState.playersByUserID[int(data["userid"].GetValShort())]})
170+
171+
// Player.FlashDuration hasn't been updated yet,
172+
// so we need to wait until the end of the tick before dispatching
173+
p.currentFlashEvents = append(p.currentFlashEvents, events.PlayerFlashed{
174+
Player: p.gameState.playersByUserID[int(data["userid"].GetValShort())],
175+
Attacker: p.gameState.lastFlasher,
176+
})
171177

172178
case "flashbang_detonate": // Flash exploded
173179
fallthrough
@@ -195,6 +201,7 @@ func (p *Parser) handleGameEvent(ge *msg.CSVCMsg_GameEvent) {
195201

196202
switch d.Name {
197203
case "flashbang_detonate": // Flash exploded
204+
p.gameState.lastFlasher = thrower
198205
p.eventDispatcher.Dispatch(events.FlashExplode{GrenadeEvent: buildNadeEvent(common.EqFlash, thrower, position, nadeEntityID)})
199206

200207
case "hegrenade_detonate": // HE exploded

game_state.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ type GameState struct {
2323
gamePhase common.GamePhase
2424
isWarmupPeriod bool
2525
isMatchStarted bool
26+
lastFlasher *common.Player // Last player whose flash exploded, used to find the attacker for player_blind events
2627
}
2728

2829
type ingameTickNumber int

parser.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010

1111
bit "github.com/markus-wa/demoinfocs-golang/bitread"
1212
common "github.com/markus-wa/demoinfocs-golang/common"
13+
events "github.com/markus-wa/demoinfocs-golang/events"
1314
msg "github.com/markus-wa/demoinfocs-golang/msg"
1415
st "github.com/markus-wa/demoinfocs-golang/sendtables"
1516
)
@@ -68,6 +69,7 @@ type Parser struct {
6869
gameEventDescs map[int32]*msg.CSVCMsg_GameEventListDescriptorT // Maps game-event IDs to descriptors
6970
grenadeModelIndices map[int]common.EquipmentElement // Used to map model indices to grenades (used for grenade projectiles)
7071
stringTables []*msg.CSVCMsg_CreateStringTable // Contains all created sendtables, needed when updating them
72+
currentFlashEvents []events.PlayerFlashed // Contains flash events that need to be dispatched at the end of a tick
7173
}
7274

7375
type bombsite struct {

parsing.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,13 @@ func (p *Parser) handleFrameParsed(*frameParsedTokenType) {
273273
}
274274
}
275275

276+
// PlayerFlashed events need to be dispatched at the end of the tick
277+
// because Player.FlashDuration is updated after the game-events are parsed.
278+
for _, e := range p.currentFlashEvents {
279+
p.eventDispatcher.Dispatch(e)
280+
}
281+
p.currentFlashEvents = p.currentFlashEvents[:0]
282+
276283
p.currentFrame++
277284
p.eventDispatcher.Dispatch(events.TickDone{})
278285
}

0 commit comments

Comments
 (0)