Repository: markus-wa/demoinfocs-golang
Pull request #273 (2021-03-16 20:21:09)

common: fix active Player.ActiveWeapon() sometimes being off after buy


Patch:
diff --git a/pkg/demoinfocs/common/player.go b/pkg/demoinfocs/common/player.go
index ec5ebc1..cb3e738 100644
--- a/pkg/demoinfocs/common/player.go
+++ b/pkg/demoinfocs/common/player.go
@@ -127,7 +127,7 @@ func (p *Player) activeWeaponID() int {
 
 // ActiveWeapon returns the currently active / equipped weapon of the player.
 func (p *Player) ActiveWeapon() *Equipment {
-	return p.Inventory[p.activeWeaponID()]
+	return p.demoInfoProvider.FindWeaponByEntityID(p.activeWeaponID())
 }
 
 // Weapons returns all weapons in the player's possession.
@@ -425,6 +425,7 @@ type demoInfoProvider interface {
 	TickRate() float64 // in-game tick rate, used for Player.IsBlinded()
 	FindPlayerByHandle(handle int) *Player
 	PlayerResourceEntity() st.Entity
+	FindWeaponByEntityID(id int) *Equipment
 }
 
 // NewPlayer creates a *Player with an initialized equipment map.
diff --git a/pkg/demoinfocs/parser.go b/pkg/demoinfocs/parser.go
index 45fe446..cb2f333 100644
--- a/pkg/demoinfocs/parser.go
+++ b/pkg/demoinfocs/parser.go
@@ -363,3 +363,7 @@ func (p demoInfoProvider) FindPlayerByHandle(handle int) *common.Player {
 func (p demoInfoProvider) PlayerResourceEntity() st.Entity {
 	return p.parser.gameState.playerResourceEntity
 }
+
+func (p demoInfoProvider) FindWeaponByEntityID(entityID int) *common.Equipment {
+	return p.parser.gameState.weapons[entityID]
+}


Test patch:
diff --git a/pkg/demoinfocs/common/common_test.go b/pkg/demoinfocs/common/common_test.go
index a9e4b1b..e3e900b 100644
--- a/pkg/demoinfocs/common/common_test.go
+++ b/pkg/demoinfocs/common/common_test.go
@@ -152,6 +152,7 @@ type demoInfoProviderMock struct {
 	ingameTick           int
 	playersByHandle      map[int]*Player
 	playerResourceEntity st.Entity
+	equipment            *Equipment
 }
 
 func (p demoInfoProviderMock) TickRate() float64 {
@@ -170,6 +171,10 @@ func (p demoInfoProviderMock) PlayerResourceEntity() st.Entity {
 	return p.playerResourceEntity
 }
 
+func (p demoInfoProviderMock) FindWeaponByEntityID(id int) *Equipment {
+	return p.equipment
+}
+
 func mockDemoInfoProvider(tickRate float64, tick int) demoInfoProvider {
 	return demoInfoProviderMock{
 		tickRate:   tickRate,
diff --git a/pkg/demoinfocs/common/player_test.go b/pkg/demoinfocs/common/player_test.go
index 02ab231..6a6ae7d 100644
--- a/pkg/demoinfocs/common/player_test.go
+++ b/pkg/demoinfocs/common/player_test.go
@@ -17,9 +17,9 @@ func TestPlayerActiveWeapon(t *testing.T) {
 	ak47 := NewEquipment(EqAK47)
 
 	pl := newPlayer(0)
+	pl.demoInfoProvider = demoInfoProviderMock{equipment: ak47}
 	pl.Inventory[1] = knife
-	pl.Inventory[2] = glock
-	pl.Inventory[3] = ak47
+	pl.Inventory[3] = glock
 	pl.Entity = entityWithProperty("m_hActiveWeapon", st.PropertyValue{IntVal: 3})
 
 	assert.Equal(t, ak47, pl.ActiveWeapon(), "Should have AK-47 equipped")
diff --git a/pkg/demoinfocs/events/events_test.go b/pkg/demoinfocs/events/events_test.go
index 757dcef..a0b4232 100644
--- a/pkg/demoinfocs/events/events_test.go
+++ b/pkg/demoinfocs/events/events_test.go
@@ -73,3 +73,7 @@ func (p demoInfoProviderMock) FindPlayerByHandle(int) *common.Player {
 func (p demoInfoProviderMock) PlayerResourceEntity() st.Entity {
 	return nil
 }
+
+func (p demoInfoProviderMock) FindWeaponByEntityID(int) *common.Equipment {
+	return nil
+}