Skip to content

Commit 33abbfb

Browse files
authored
Merge pull request #478 from micvbang/micvbang/simplify-weapon-inventory
datatables cs2: rewrite player equipment tracking
2 parents ea35647 + 42c7b7e commit 33abbfb

File tree

1 file changed

+65
-28
lines changed

1 file changed

+65
-28
lines changed

pkg/demoinfocs/datatables.go

+65-28
Original file line numberDiff line numberDiff line change
@@ -688,46 +688,83 @@ func (p *parser) bindPlayerWeapons(playerEntity st.Entity, pl *common.Player) {
688688
}
689689

690690
func (p *parser) bindPlayerWeaponsS2(pawnEntity st.Entity, pl *common.Player) {
691-
var cache [maxWeapons]uint64
692-
for i := range cache {
693-
i2 := i // Copy for passing to handler
691+
const inventoryCapacity = 64
692+
693+
var inventorySize uint64 = 64
694+
695+
type eq struct {
696+
*common.Equipment
697+
entityID int
698+
}
699+
700+
playerInventory := make(map[int]eq)
701+
702+
getWep := func(wepSlotPropertyValue st.PropertyValue) (uint64, *common.Equipment) {
703+
entityID := wepSlotPropertyValue.S2UInt64() & constants.EntityHandleIndexMaskSource2
704+
wep := p.gameState.weapons[int(entityID)]
705+
706+
if wep == nil {
707+
// sometimes a weapon is assigned to a player before the weapon entity is created
708+
wep = common.NewEquipment(common.EqUnknown)
709+
p.gameState.weapons[int(entityID)] = wep
710+
}
711+
712+
return entityID, wep
713+
}
714+
715+
setPlayerInventory := func() {
716+
inventory := make(map[int]*common.Equipment, inventorySize)
717+
718+
for i := uint64(0); i < inventorySize; i++ {
719+
val := pawnEntity.Property(playerWeaponPrefixS2 + fmt.Sprintf("%04d", i)).Value()
720+
if val.Any == nil {
721+
continue
722+
}
723+
724+
entityID, wep := getWep(val)
725+
inventory[int(entityID)] = wep
726+
}
727+
728+
pl.Inventory = inventory
729+
}
730+
731+
pawnEntity.Property("m_pWeaponServices.m_hMyWeapons").OnUpdate(func(pv st.PropertyValue) {
732+
inventorySize = pv.S2UInt64()
733+
setPlayerInventory()
734+
})
735+
736+
for i := 0; i < inventoryCapacity; i++ {
737+
i := i
694738
updateWeapon := func(val st.PropertyValue) {
695739
if val.Any == nil {
696740
return
697741
}
698-
entityID := val.S2UInt64() & constants.EntityHandleIndexMaskSource2
699-
if entityID != constants.EntityHandleIndexMaskSource2 {
700-
if cache[i2] != 0 {
701-
// Player already has a weapon in this slot.
702-
delete(pl.Inventory, int(cache[i2]))
703-
}
704-
cache[i2] = entityID
705742

706-
wep := p.gameState.weapons[int(entityID)]
743+
entityID, wep := getWep(val)
744+
wep.Owner = pl
707745

708-
if wep == nil {
709-
// sometimes a weapon is assigned to a player before the weapon entity is created
710-
wep = common.NewEquipment(common.EqUnknown)
711-
p.gameState.weapons[int(entityID)] = wep
712-
}
746+
entityWasCreated := entityID != constants.EntityHandleIndexMaskSource2
713747

714-
// Clear previous owner
715-
if wep.Owner != nil && wep.Entity != nil {
716-
delete(wep.Owner.Inventory, wep.Entity.ID())
717-
}
748+
if uint64(i) < inventorySize {
749+
if entityWasCreated {
750+
existingWeapon, exists := playerInventory[i]
751+
if exists {
752+
delete(pl.Inventory, existingWeapon.entityID)
753+
}
718754

719-
// Attribute weapon to player
720-
wep.Owner = pl
721-
pl.Inventory[int(entityID)] = wep
722-
} else {
723-
if cache[i2] != 0 && pl.Inventory[int(cache[i2])] != nil {
724-
pl.Inventory[int(cache[i2])].Owner = nil
755+
pl.Inventory[int(entityID)] = wep
756+
playerInventory[i] = eq{
757+
Equipment: wep,
758+
entityID: int(entityID),
759+
}
760+
} else {
761+
delete(pl.Inventory, int(entityID))
725762
}
726-
delete(pl.Inventory, int(cache[i2]))
727763

728-
cache[i2] = 0
764+
setPlayerInventory()
729765
}
730766
}
767+
731768
property := pawnEntity.Property(playerWeaponPrefixS2 + fmt.Sprintf("%04d", i))
732769
updateWeapon(property.Value())
733770
property.OnUpdate(updateWeapon)

0 commit comments

Comments
 (0)