Skip to content

Commit 51057b9

Browse files
authored
Merge pull request #147 from markus-wa/issue/145-grenades-ammo
common: add new ammo functions to Equipment for grenades - AmmoInMagazine2() returns 1 for grenades - AmmoReserve2() returns 'Owner.LeftAmmo[AmmoType] - 1' for grenades
2 parents a13ce5d + 6b817db commit 51057b9

File tree

6 files changed

+115
-6
lines changed

6 files changed

+115
-6
lines changed

common/equipment.go

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ type Equipment struct {
274274
Weapon EquipmentElement // The type of weapon which the equipment instantiates.
275275
Owner *Player // The player carrying the equipment, not necessarily the buyer.
276276
AmmoType int // TODO: Remove this? doesn't seem applicable to CS:GO
277-
AmmoInMagazine int // Amount of bullets in the weapon's magazine
277+
AmmoInMagazine int // Amount of bullets in the weapon's magazine. Deprecated, use AmmoInMagazine2() instead.
278278
AmmoReserve int // Amount of reserve bullets
279279
OriginalString string // E.g. 'models/weapons/w_rif_m4a1_s.mdl'. Used internally to differentiate alternative weapons (M4A4 / M4A1-S etc.).
280280
ZoomLevel int // How far the player has zoomed in on the weapon. 0=no zoom, 1=first level, 2=maximum zoom
@@ -295,6 +295,32 @@ func (e Equipment) UniqueID() int64 {
295295
return e.uniqueID
296296
}
297297

298+
// AmmoInMagazine2 returns the ammo left in the magazine.
299+
// Returns CWeaponCSBase.m_iClip1 for most weapons and 1 for grenades.
300+
func (e Equipment) AmmoInMagazine2() int {
301+
if e.Class() == EqClassGrenade {
302+
return 1
303+
}
304+
305+
return e.AmmoInMagazine
306+
}
307+
308+
// AmmoReserve2 returns the ammo left available for reloading.
309+
// Returns CWeaponCSBase.m_iPrimaryReserveAmmoCount for most weapons and 'Owner.AmmoLeft[AmmoType] - 1' for grenades.
310+
// Use AmmoInMagazine2() + AmmoReserve2() to quickly get the amount of grenades a player owns.
311+
func (e Equipment) AmmoReserve2() int {
312+
if e.Class() == EqClassGrenade {
313+
if e.Owner != nil {
314+
// minus one for 'InMagazine'
315+
return e.Owner.AmmoLeft[e.AmmoType] - 1
316+
}
317+
318+
return 0
319+
}
320+
321+
return e.AmmoReserve
322+
}
323+
298324
// NewEquipment creates a new Equipment and sets the UniqueID.
299325
//
300326
// Intended for internal use only.

common/equipment_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,46 @@ func TestEquipment_Class(t *testing.T) {
3535
func TestEquipment_UniqueID(t *testing.T) {
3636
assert.NotEqual(t, NewEquipment(EqAK47).UniqueID(), NewEquipment(EqAK47).UniqueID(), "UniqueIDs of different equipment instances should be different")
3737
}
38+
39+
func TestEquipment_AmmoInMagazine2_Default(t *testing.T) {
40+
wep := &Equipment{AmmoInMagazine: 1}
41+
42+
assert.Equal(t, 1, wep.AmmoInMagazine2())
43+
}
44+
45+
func TestEquipment_AmmoInMagazine2_Grenade(t *testing.T) {
46+
wep := &Equipment{
47+
Weapon: EqFlash,
48+
}
49+
50+
assert.Equal(t, 1, wep.AmmoInMagazine2())
51+
}
52+
53+
func TestEquipment_AmmoReserve2_Default(t *testing.T) {
54+
wep := &Equipment{
55+
AmmoReserve: 1,
56+
}
57+
58+
assert.Equal(t, 1, wep.AmmoReserve2())
59+
}
60+
61+
func TestEquipment_AmmoReserve2_Grenade(t *testing.T) {
62+
owner := new(Player)
63+
owner.AmmoLeft[1] = 2
64+
wep := &Equipment{
65+
Weapon: EqFlash,
66+
AmmoInMagazine: -1,
67+
Owner: owner,
68+
AmmoType: 1,
69+
}
70+
71+
assert.Equal(t, 1, wep.AmmoReserve2())
72+
}
73+
74+
func TestEquipment_AmmoReserve2_Grenade_OwnerNil(t *testing.T) {
75+
wep := &Equipment{
76+
Weapon: EqFlash,
77+
}
78+
79+
assert.Equal(t, 0, wep.AmmoReserve2())
80+
}

common/player.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"time"
55

66
"github.com/golang/geo/r3"
7+
78
st "github.com/markus-wa/demoinfocs-golang/sendtables"
89
)
910

@@ -26,7 +27,7 @@ type Player struct {
2627
RoundStartEquipmentValue int
2728
ActiveWeaponID int // Used internally to set the active weapon, see ActiveWeapon()
2829
RawWeapons map[int]*Equipment // All weapons the player is currently carrying
29-
AmmoLeft [32]int // Ammo left in the various weapons, index corresponds to key of RawWeapons
30+
AmmoLeft [32]int // Ammo left for special weapons (e.g. grenades), index corresponds Equipment.AmmoType
3031
Entity st.IEntity
3132
AdditionalPlayerInformation *AdditionalPlayerInformation // Mostly scoreboard information such as kills, deaths, etc.
3233
ViewDirectionX float32

datatables.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,8 +276,14 @@ func (p *Parser) bindNewPlayer(playerEntity st.IEntity) {
276276
}
277277
cache[i2] = entityID
278278

279-
// Attribute weapon to player
280279
wep := &p.weapons[entityID]
280+
281+
// Clear previous owner
282+
if wep.Owner != nil {
283+
delete(wep.Owner.RawWeapons, wep.EntityID)
284+
}
285+
286+
// Attribute weapon to player
281287
wep.Owner = pl
282288
pl.RawWeapons[entityID] = wep
283289
} else {
@@ -411,8 +417,10 @@ func (p *Parser) nadeProjectileDestroyed(proj *common.GrenadeProjectile) {
411417

412418
func (p *Parser) bindWeapon(entity *st.Entity, wepType common.EquipmentElement) {
413419
entityID := entity.ID()
420+
currentOwner := p.weapons[entityID].Owner
414421
p.weapons[entityID] = common.NewEquipment(wepType)
415422
eq := &p.weapons[entityID]
423+
eq.Owner = currentOwner
416424
eq.EntityID = entityID
417425
eq.AmmoInMagazine = -1
418426

game_events.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -545,9 +545,7 @@ func mapGameEventData(d *msg.CSVCMsg_GameEventListDescriptorT, e *msg.CSVCMsg_Ga
545545

546546
// Returns the players instance of the weapon if applicable or a new instance otherwise.
547547
func getPlayerWeapon(player *common.Player, wepType common.EquipmentElement) *common.Equipment {
548-
class := wepType.Class()
549-
isSpecialWeapon := class == common.EqClassGrenade || (class == common.EqClassEquipment && wepType != common.EqKnife)
550-
if !isSpecialWeapon && player != nil {
548+
if player != nil {
551549
for _, wep := range player.Weapons() {
552550
if wep.Weapon == wepType {
553551
return wep

game_events_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,36 @@ func TestRoundEnd_LoserState_Score(t *testing.T) {
5353

5454
assert.Equal(t, 1, eventOccurred)
5555
}
56+
57+
func TestGetPlayerWeapon_NilPlayer(t *testing.T) {
58+
wep := getPlayerWeapon(nil, common.EqAK47)
59+
60+
assert.NotNil(t, wep)
61+
assert.Equal(t, common.EqAK47, wep.Weapon)
62+
}
63+
64+
func TestGetPlayerWeapon_Found(t *testing.T) {
65+
ak := &common.Equipment{Weapon: common.EqAK47}
66+
pl := &common.Player{
67+
RawWeapons: map[int]*common.Equipment{
68+
1: ak,
69+
},
70+
}
71+
72+
wep := getPlayerWeapon(pl, common.EqAK47)
73+
74+
assert.True(t, wep == ak)
75+
}
76+
77+
func TestGetPlayerWeapon_NotFound(t *testing.T) {
78+
ak := &common.Equipment{Weapon: common.EqAK47}
79+
pl := &common.Player{
80+
RawWeapons: map[int]*common.Equipment{
81+
1: ak,
82+
},
83+
}
84+
85+
wep := getPlayerWeapon(pl, common.EqM4A1)
86+
87+
assert.Equal(t, common.EqM4A1, wep.Weapon)
88+
}

0 commit comments

Comments
 (0)