@@ -20,6 +20,12 @@ const (
2020
2121func (p * Parser ) mapEquipment () {
2222 for _ , sc := range p .stParser .ServerClasses () {
23+ for _ , bc := range sc .BaseClasses {
24+ if bc .Name == "CBaseGrenade" { // Grenades projectiles, i.e. thrown by player
25+ p .equipmentMapping [sc ] = common .MapEquipment (strings .ToLower (sc .DTName [3 :]))
26+ }
27+ }
28+
2329 if len (sc .BaseClasses ) > 6 && sc .BaseClasses [6 ].Name == "CWeaponCSBase" {
2430 if len (sc .BaseClasses ) > 7 {
2531 switch sc .BaseClasses [7 ].Name {
@@ -36,7 +42,6 @@ func (p *Parser) mapEquipment() {
3642 switch sc .Name {
3743 case "CC4" :
3844 p .equipmentMapping [sc ] = common .EqBomb
39-
4045 case "CWeaponNOVA" :
4146 fallthrough
4247 case "CWeaponSawedoff" :
@@ -253,18 +258,18 @@ func (p *Parser) bindNewPlayer(playerEntity *st.Entity) {
253258 for i := range cache {
254259 i2 := i // Copy for passing to handler
255260 playerEntity .FindProperty (wepPrefix + fmt .Sprintf ("%03d" , i )).RegisterPropertyUpdateHandler (func (val st.PropValue ) {
256- idx := val .IntVal & indexMask
257- if idx != indexMask {
261+ entityID := val .IntVal & indexMask
262+ if entityID != indexMask {
258263 if cache [i2 ] != 0 {
259264 // Player already has a weapon in this slot.
260265 pl.RawWeapons [cache [i2 ]] = nil
261266 }
262- cache [i2 ] = idx
267+ cache [i2 ] = entityID
263268
264269 // Attribute weapon to player
265- wep := & p .weapons [idx ]
270+ wep := & p .weapons [entityID ]
266271 wep .Owner = pl
267- pl .RawWeapons [idx ] = wep
272+ pl .RawWeapons [entityID ] = wep
268273 } else {
269274 if cache [i2 ] != 0 && pl.RawWeapons [cache [i2 ]] != nil {
270275 pl.RawWeapons [cache [i2 ]].Owner = nil
@@ -290,11 +295,60 @@ func (p *Parser) bindWeapons() {
290295
291296 for _ , sc := range p .stParser .ServerClasses () {
292297 for _ , bc := range sc .BaseClasses {
293- if bc .Name == "CWeaponCSBase" {
298+ switch bc .Name {
299+ case "CWeaponCSBase" :
294300 sc .RegisterEntityCreatedHandler (p .bindWeapon )
301+ case "CBaseGrenade" : // Grenade that has been thrown by player.
302+ sc .RegisterEntityCreatedHandler (p .bindGrenadeProjectiles )
303+ case "CBaseCSGrenade" :
304+ // @micvbang TODO: handle grenades dropped by dead player.
305+ // Grenades that were dropped by a dead player (and can be picked up by other players).
295306 }
296307 }
297308 }
309+
310+ }
311+
312+ // bindGrenadeProjectiles keeps track of the location of live grenades, actively thrown by players.
313+ // It does track the location of grenades lying on the ground, i.e. that were dropped by dead players.
314+ //
315+ // NOTE: Parser.gameState.grenadeProjectiles is updated here. We rely on code during the handling of the game events
316+ // "[nade]_detonate" and "[nade]_started" to remove projectiles from Parser.gameState.grenadeProjectiles once they detonate.
317+ func (p * Parser ) bindGrenadeProjectiles (event st.EntityCreatedEvent ) {
318+ if _ , ok := p .gameState .grenadeProjectiles [event .Entity .ID ]; ! ok {
319+ p .gameState .grenadeProjectiles [event .Entity .ID ] = common .NewGrenadeProjectile ()
320+ }
321+
322+ proj := p .gameState .grenadeProjectiles [event .Entity .ID ]
323+ proj .EntityID = event .Entity .ID
324+
325+ event .Entity .FindProperty ("m_nModelIndex" ).RegisterPropertyUpdateHandler (func (val st.PropValue ) {
326+ proj .Weapon = p .grenadeModelIndicies [val .IntVal ]
327+ })
328+
329+ // @micvbang: not quite sure what the difference between Thrower and Owner is.
330+ event .Entity .FindProperty ("m_hThrower" ).RegisterPropertyUpdateHandler (func (val st.PropValue ) {
331+ throwerID := val .IntVal & indexMask
332+ throwerIndex := throwerID - 1
333+
334+ thrower := p .entityIDToPlayers [throwerIndex ]
335+ proj .Thrower = thrower
336+
337+ if proj .Thrower == nil && thrower != nil {
338+ proj .Position = thrower .Position
339+ }
340+ })
341+
342+ event .Entity .FindProperty ("m_hOwnerEntity" ).RegisterPropertyUpdateHandler (func (val st.PropValue ) {
343+ ownerID := val .IntVal & indexMask
344+ ownerIndex := ownerID - 1
345+ player := p .entityIDToPlayers [ownerIndex ]
346+ proj .Owner = player
347+ })
348+
349+ event .Entity .FindProperty ("m_vecOrigin" ).RegisterPropertyUpdateHandler (func (val st.PropValue ) {
350+ proj .Position = event .Entity .Position ()
351+ })
298352}
299353
300354func (p * Parser ) bindWeapon (event st.EntityCreatedEvent ) {
0 commit comments