Skip to content

Commit 8b03342

Browse files
committed
common: add Inferno.Owner() to retreive thrower (#131)
1 parent 3bbd4e2 commit 8b03342

File tree

8 files changed

+105
-59
lines changed

8 files changed

+105
-59
lines changed

common/common_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import (
66

77
"github.com/golang/geo/r3"
88
"github.com/stretchr/testify/assert"
9+
10+
st "github.com/markus-wa/demoinfocs-golang/sendtables"
11+
stfake "github.com/markus-wa/demoinfocs-golang/sendtables/fake"
912
)
1013

1114
func TestBombPosition(t *testing.T) {
@@ -75,3 +78,37 @@ func TestTeamState_FreezeTimeEndEquipmentValue(t *testing.T) {
7578

7679
assert.Equal(t, 300, state.FreezeTimeEndEquipmentValue())
7780
}
81+
82+
type demoInfoProviderMock struct {
83+
tickRate float64
84+
ingameTick int
85+
playersByHandle map[int]*Player
86+
}
87+
88+
func (p demoInfoProviderMock) TickRate() float64 {
89+
return p.tickRate
90+
}
91+
92+
func (p demoInfoProviderMock) IngameTick() int {
93+
return p.ingameTick
94+
}
95+
96+
func (p demoInfoProviderMock) FindPlayerByHandle(handle int) *Player {
97+
return p.playersByHandle[handle]
98+
}
99+
100+
func mockDemoInfoProvider(tickRate float64, tick int) demoInfoProvider {
101+
return demoInfoProviderMock{
102+
tickRate: tickRate,
103+
ingameTick: tick,
104+
}
105+
}
106+
107+
func entityWithProperty(propName string, value st.PropertyValue) st.IEntity {
108+
entity := new(stfake.Entity)
109+
entity.On("ID").Return(1)
110+
prop := new(stfake.Property)
111+
prop.On("Value").Return(value)
112+
entity.On("FindPropertyI", propName).Return(prop)
113+
return entity
114+
}

common/inferno.go

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,25 @@ import (
44
"math/rand"
55
"sort"
66

7-
r2 "github.com/golang/geo/r2"
8-
r3 "github.com/golang/geo/r3"
9-
quickhull "github.com/markus-wa/quickhull-go"
7+
"github.com/golang/geo/r2"
8+
"github.com/golang/geo/r3"
9+
"github.com/markus-wa/quickhull-go"
10+
11+
st "github.com/markus-wa/demoinfocs-golang/sendtables"
1012
)
1113

1214
// Inferno is a list of Fires with helper functions.
1315
// Also contains already extinguished fires.
1416
//
1517
// See also: Inferno.Active() and Fire.IsBurning
1618
type Inferno struct {
17-
EntityID int
19+
Entity st.IEntity
20+
EntityID int // Same as Entity.ID(), use Entity.ID() instead
1821
Fires []*Fire
1922

2023
// uniqueID is used to distinguish different infernos (which potentially have the same, reused entityID) from each other.
21-
uniqueID int64
24+
uniqueID int64
25+
demoInfoProvider demoInfoProvider
2226
}
2327

2428
// Fire is a component of an Inferno.
@@ -133,13 +137,23 @@ func (inf Inferno) ConvexHull3D() quickhull.ConvexHull {
133137
return convexHull(pointCloud)
134138
}
135139

140+
// Owner returns the player who threw the fire grenade.
141+
func (inf Inferno) Owner() *Player {
142+
return inf.demoInfoProvider.FindPlayerByHandle(inf.Entity.FindPropertyI("m_hOwnerEntity").Value().IntVal)
143+
}
144+
136145
func convexHull(pointCloud []r3.Vector) quickhull.ConvexHull {
137146
return new(quickhull.QuickHull).ConvexHull(pointCloud, false, false, 0)
138147
}
139148

140149
// NewInferno creates a inferno and sets the Unique-ID.
141150
//
142151
// Intended for internal use only.
143-
func NewInferno() *Inferno {
144-
return &Inferno{uniqueID: rand.Int63()}
152+
func NewInferno(demoInfoProvider demoInfoProvider, entity st.IEntity) *Inferno {
153+
return &Inferno{
154+
Entity: entity,
155+
EntityID: entity.ID(),
156+
uniqueID: rand.Int63(),
157+
demoInfoProvider: demoInfoProvider,
158+
}
145159
}

common/inferno_test.go

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,19 @@ package common
33
import (
44
"testing"
55

6-
r2 "github.com/golang/geo/r2"
7-
r3 "github.com/golang/geo/r3"
8-
assert "github.com/stretchr/testify/assert"
6+
"github.com/golang/geo/r2"
7+
"github.com/golang/geo/r3"
8+
"github.com/stretchr/testify/assert"
9+
10+
st "github.com/markus-wa/demoinfocs-golang/sendtables"
911
)
1012

11-
func TestInfernoUniqueID(t *testing.T) {
12-
assert.NotEqual(t, NewInferno().UniqueID(), NewInferno().UniqueID(), "UniqueIDs of different infernos should be different")
13+
func TestInferno_UniqueID(t *testing.T) {
14+
entity := new(st.Entity)
15+
assert.NotEqual(t, NewInferno(nil, entity).UniqueID(), NewInferno(nil, entity).UniqueID(), "UniqueIDs of different infernos should be different")
1316
}
1417

15-
func TestInfernoActive(t *testing.T) {
18+
func TestInferno_Active(t *testing.T) {
1619
inf := Inferno{
1720
Fires: []*Fire{
1821
{
@@ -39,7 +42,7 @@ func TestInfernoActive(t *testing.T) {
3942
assert.Equal(t, activeFires, inf.Active().Fires, "Active inferno should contain active fires")
4043
}
4144

42-
func TestInfernoConvexHull2D(t *testing.T) {
45+
func TestInferno_ConvexHull2D(t *testing.T) {
4346
// Construct a Inferno that looks roughly like this.
4447
// D should be inside the 2D Convex Hull but a corner of the 3D Convex Hull
4548
//
@@ -79,7 +82,7 @@ func TestInfernoConvexHull2D(t *testing.T) {
7982
}
8083

8184
// Just check that all fires are passed to quickhull.ConvexHull()
82-
func TestInfernoConvexHull3D(t *testing.T) {
85+
func TestInferno_ConvexHull3D(t *testing.T) {
8386
inf := Inferno{
8487
Fires: []*Fire{
8588
{
@@ -106,3 +109,14 @@ func TestInfernoConvexHull3D(t *testing.T) {
106109

107110
assert.ElementsMatch(t, expectedHull, inf.ConvexHull3D().Vertices, "ConvexHull3D should contain all fire locations")
108111
}
112+
113+
func TestInferno_Owner(t *testing.T) {
114+
entity := entityWithProperty("m_hOwnerEntity", st.PropertyValue{IntVal: 1})
115+
116+
player := new(Player)
117+
provider := demoInfoProviderMock{
118+
playersByHandle: map[int]*Player{1: player},
119+
}
120+
121+
assert.Equal(t, player, NewInferno(provider, entity).Owner())
122+
}

common/player.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ type AdditionalPlayerInformation struct {
188188
type demoInfoProvider interface {
189189
IngameTick() int // current in-game tick, used for IsBlinded()
190190
TickRate() float64 // in-game tick rate, used for Player.IsBlinded()
191+
FindPlayerByHandle(handle int) *Player
191192
}
192193

193194
// NewPlayer creates a *Player with an initialized equipment map.

common/player_test.go

Lines changed: 10 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ import (
66

77
"github.com/stretchr/testify/assert"
88

9-
"github.com/markus-wa/demoinfocs-golang/sendtables"
10-
"github.com/markus-wa/demoinfocs-golang/sendtables/fake"
9+
st "github.com/markus-wa/demoinfocs-golang/sendtables"
1110
)
1211

1312
func TestPlayerActiveWeapon(t *testing.T) {
@@ -125,7 +124,7 @@ func TestPlayer_FlashDurationTimeRemaining_Fallback(t *testing.T) {
125124
}
126125

127126
func TestPlayer_IsSpottedBy_HasSpotted_True(t *testing.T) {
128-
pl := playerWithProperty("m_bSpottedByMask.000", sendtables.PropertyValue{IntVal: 2})
127+
pl := playerWithProperty("m_bSpottedByMask.000", st.PropertyValue{IntVal: 2})
129128
pl.EntityID = 1
130129

131130
other := newPlayer(0)
@@ -136,7 +135,7 @@ func TestPlayer_IsSpottedBy_HasSpotted_True(t *testing.T) {
136135
}
137136

138137
func TestPlayer_IsSpottedBy_HasSpotted_False(t *testing.T) {
139-
pl := playerWithProperty("m_bSpottedByMask.000", sendtables.PropertyValue{IntVal: 0})
138+
pl := playerWithProperty("m_bSpottedByMask.000", st.PropertyValue{IntVal: 0})
140139
pl.EntityID = 1
141140

142141
other := newPlayer(0)
@@ -147,7 +146,7 @@ func TestPlayer_IsSpottedBy_HasSpotted_False(t *testing.T) {
147146
}
148147

149148
func TestPlayer_IsSpottedBy_HasSpotted_BitOver32(t *testing.T) {
150-
pl := playerWithProperty("m_bSpottedByMask.001", sendtables.PropertyValue{IntVal: 1})
149+
pl := playerWithProperty("m_bSpottedByMask.001", st.PropertyValue{IntVal: 1})
151150
pl.EntityID = 1
152151

153152
other := newPlayer(0)
@@ -168,25 +167,25 @@ func TestPlayer_IsSpottedBy_EntityNull(t *testing.T) {
168167
}
169168

170169
func TestPlayer_IsInBombZone(t *testing.T) {
171-
pl := playerWithProperty("m_bInBombZone", sendtables.PropertyValue{IntVal: 1})
170+
pl := playerWithProperty("m_bInBombZone", st.PropertyValue{IntVal: 1})
172171

173172
assert.True(t, pl.IsInBombZone())
174173
}
175174

176175
func TestPlayer_IsInBuyZone(t *testing.T) {
177-
pl := playerWithProperty("m_bInBuyZone", sendtables.PropertyValue{IntVal: 1})
176+
pl := playerWithProperty("m_bInBuyZone", st.PropertyValue{IntVal: 1})
178177

179178
assert.True(t, pl.IsInBuyZone())
180179
}
181180

182181
func TestPlayer_IsWalking(t *testing.T) {
183-
pl := playerWithProperty("m_bIsWalking", sendtables.PropertyValue{IntVal: 1})
182+
pl := playerWithProperty("m_bIsWalking", st.PropertyValue{IntVal: 1})
184183

185184
assert.True(t, pl.IsWalking())
186185
}
187186

188187
func TestPlayer_IsScoped(t *testing.T) {
189-
pl := playerWithProperty("m_bIsScoped", sendtables.PropertyValue{IntVal: 1})
188+
pl := playerWithProperty("m_bIsScoped", st.PropertyValue{IntVal: 1})
190189

191190
assert.True(t, pl.IsScoped())
192191
}
@@ -195,31 +194,6 @@ func newPlayer(tick int) *Player {
195194
return NewPlayer(mockDemoInfoProvider(128, tick))
196195
}
197196

198-
type demoInfoProviderMock struct {
199-
tickRate float64
200-
ingameTick int
201-
}
202-
203-
func (p demoInfoProviderMock) TickRate() float64 {
204-
return p.tickRate
205-
}
206-
207-
func (p demoInfoProviderMock) IngameTick() int {
208-
return p.ingameTick
209-
}
210-
211-
func mockDemoInfoProvider(tickRate float64, tick int) demoInfoProvider {
212-
return demoInfoProviderMock{
213-
tickRate: tickRate,
214-
ingameTick: tick,
215-
}
216-
}
217-
218-
func playerWithProperty(propName string, value sendtables.PropertyValue) *Player {
219-
entity := new(fake.Entity)
220-
prop := new(fake.Property)
221-
prop.On("Value").Return(value)
222-
entity.On("FindPropertyI", propName).Return(prop)
223-
pl := &Player{Entity: entity}
224-
return pl
197+
func playerWithProperty(propName string, value st.PropertyValue) *Player {
198+
return &Player{Entity: entityWithProperty(propName, value)}
225199
}

datatables.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -457,10 +457,8 @@ func (p *Parser) bindWeapon(entity *st.Entity, wepType common.EquipmentElement)
457457
}
458458

459459
func (p *Parser) bindNewInferno(entity *st.Entity) {
460-
entityID := entity.ID()
461-
inf := common.NewInferno()
462-
inf.EntityID = entityID
463-
p.gameState.infernos[entityID] = inf
460+
inf := common.NewInferno(p.demoInfoProvider, entity)
461+
p.gameState.infernos[entity.ID()] = inf
464462

465463
entity.OnCreateFinished(func() {
466464
p.eventDispatcher.Dispatch(events.InfernoStart{

events/events_test.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
)
1111

1212
func TestPlayerFlashed_FlashDuration(t *testing.T) {
13-
p := common.NewPlayer(demoInfoProvider{})
13+
p := common.NewPlayer(demoInfoProviderMock{})
1414
e := PlayerFlashed{Player: p}
1515

1616
assert.Equal(t, time.Duration(0), e.FlashDuration())
@@ -81,13 +81,17 @@ func TestItemPickup_WeaponTraceable_WeaponNotFound(t *testing.T) {
8181
assert.Equal(t, e.Weapon, *e.WeaponTraceable())
8282
}
8383

84-
type demoInfoProvider struct {
84+
type demoInfoProviderMock struct {
8585
}
8686

87-
func (p demoInfoProvider) IngameTick() int {
87+
func (p demoInfoProviderMock) IngameTick() int {
8888
return 0
8989
}
9090

91-
func (p demoInfoProvider) TickRate() float64 {
91+
func (p demoInfoProviderMock) TickRate() float64 {
9292
return 128
9393
}
94+
95+
func (p demoInfoProviderMock) FindPlayerByHandle(handle int) *common.Player {
96+
return nil
97+
}

parser.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,3 +281,7 @@ func (p demoInfoProvider) IngameTick() int {
281281
func (p demoInfoProvider) TickRate() float64 {
282282
return p.parser.header.TickRate()
283283
}
284+
285+
func (p demoInfoProvider) FindPlayerByHandle(handle int) *common.Player {
286+
return p.parser.gameState.Participants().FindByHandle(handle)
287+
}

0 commit comments

Comments
 (0)