File tree Expand file tree Collapse file tree 5 files changed +82
-4
lines changed Expand file tree Collapse file tree 5 files changed +82
-4
lines changed Original file line number Diff line number Diff line change @@ -245,3 +245,22 @@ func (inf Inferno) ConvexHull3D() *s2.Loop {
245245func NewInferno () * Inferno {
246246 return & Inferno {uniqueID : rand .Int63 ()}
247247}
248+
249+ // Bomb tracks the bomb's position, and the player carrying it, if any.
250+ type Bomb struct {
251+ // Intended for internal use only. Use Position() instead.
252+ // Contains the last location of the dropped or planted bomb.
253+ LastOnGroundPosition r3.Vector
254+ Carrier * Player
255+ }
256+
257+ // Position returns the current position of the bomb.
258+ // This is either the position of the player holding it
259+ // or LastOnGroundPosition if it's dropped or planted.
260+ func (b Bomb ) Position () r3.Vector {
261+ if b .Carrier != nil {
262+ return b .Carrier .Position
263+ }
264+
265+ return b .LastOnGroundPosition
266+ }
Original file line number Diff line number Diff line change @@ -65,6 +65,40 @@ func (p *Parser) bindEntities() {
6565 p .bindBombSites ()
6666 p .bindPlayers ()
6767 p .bindWeapons ()
68+ p .bindBomb ()
69+ }
70+
71+ func (p * Parser ) bindBomb () {
72+ bomb := & p .gameState .bomb
73+
74+ // Track bomb when it is not held by a player
75+ scDroppedC4 := p .stParser .ServerClasses ().FindByName ("CC4" )
76+ scDroppedC4 .OnEntityCreated (func (bomb * st.Entity ) {
77+ bomb .OnPositionUpdate (func (pos r3.Vector ) {
78+ // Bomb only has a position when not held by a player
79+ p .gameState .bomb .Carrier = nil
80+
81+ p .gameState .bomb .LastOnGroundPosition = pos
82+ })
83+ })
84+
85+ // Track bomb when it has been planted
86+ scPlantedC4 := p .stParser .ServerClasses ().FindByName ("CPlantedC4" )
87+ scPlantedC4 .OnEntityCreated (func (bombEntity * st.Entity ) {
88+ // Player can't hold the bomb when it has been planted
89+ p .gameState .bomb .Carrier = nil
90+
91+ bomb .LastOnGroundPosition = bombEntity .Position ()
92+ })
93+
94+ // Track bomb when it is being held by a player
95+ scPlayerC4 := p .stParser .ServerClasses ().FindByName ("CC4" )
96+ scPlayerC4 .OnEntityCreated (func (bombEntity * st.Entity ) {
97+ bombEntity .FindProperty ("m_hOwner" ).OnUpdate (func (val st.PropertyValue ) {
98+ ownerEntityID := val .IntVal & entityHandleIndexMask
99+ bomb .Carrier = p .gameState .playersByEntityID [ownerEntityID ]
100+ })
101+ })
68102}
69103
70104func (p * Parser ) bindTeamScores () {
Original file line number Diff line number Diff line change @@ -271,6 +271,17 @@ type BombBeginDefuseEvent struct {
271271 HasKit bool
272272}
273273
274+ // BombDropEvent signals that the bomb (C4) has been dropped.
275+ type BombDropEvent struct {
276+ Player * common.Player
277+ EntityID int
278+ }
279+
280+ // BombPickupEvent signals that the bomb (C4) has been picked up.
281+ type BombPickupEvent struct {
282+ Player * common.Player
283+ }
284+
274285func (BombBeginDefuseEvent ) implementsBombEventIf () {}
275286
276287// HitGroup is the type for the various HitGroupXYZ constants.
Original file line number Diff line number Diff line change @@ -352,6 +352,18 @@ func (p *Parser) handleGameEvent(ge *msg.CSVCMsg_GameEvent) {
352352 Weapon : weapon ,
353353 })
354354 }
355+ case "bomb_dropped" : // Bomb dropped
356+ player := p .gameState .playersByUserID [int (data ["userid" ].GetValShort ())]
357+ entityID := int (data ["entityid" ].GetValShort ())
358+
359+ p .eventDispatcher .Dispatch (events.BombDropEvent {
360+ Player : player ,
361+ EntityID : entityID ,
362+ })
363+ case "bomb_pickup" : // Bomb picked up
364+ p .eventDispatcher .Dispatch (events.BombPickupEvent {
365+ Player : p .gameState .playersByUserID [int (data ["userid" ].GetValShort ())],
366+ })
355367
356368 // TODO: Might be interesting:
357369 case "player_connect_full" : // Connecting finished
@@ -362,10 +374,6 @@ func (p *Parser) handleGameEvent(ge *msg.CSVCMsg_GameEvent) {
362374 fallthrough
363375 case "weapon_reload" : // Weapon reloaded
364376 fallthrough
365- case "bomb_dropped" : // Bomb dropped
366- fallthrough
367- case "bomb_pickup" : // Bomb picked up
368- fallthrough
369377 case "round_time_warning" : // Round time warning
370378 fallthrough
371379 case "round_announce_match_point" : // Match point announcement
Original file line number Diff line number Diff line change @@ -15,6 +15,7 @@ type GameState struct {
1515 grenadeProjectiles map [int ]* common.GrenadeProjectile // Maps entity-IDs to active nade-projectiles. That's grenades that have been thrown, but have not yet detonated.
1616 infernos map [int ]* common.Inferno // Maps entity-IDs to active infernos.
1717 entities map [int ]* st.Entity // Maps entity IDs to entities
18+ bomb common.Bomb
1819}
1920
2021type ingameTickNumber int
@@ -72,6 +73,11 @@ func (gs GameState) Entities() map[int]*st.Entity {
7273 return gs .entities
7374}
7475
76+ // Bomb returns the current bomb state.
77+ func (gs GameState ) Bomb () * common.Bomb {
78+ return & gs .bomb
79+ }
80+
7581func newGameState () GameState {
7682 return GameState {
7783 playersByEntityID : make (map [int ]* common.Player ),
You can’t perform that action at this time.
0 commit comments