Skip to content

Commit ecd8903

Browse files
Michael Bangmarkus-wa
authored andcommitted
Add GameState.Bomb() (#41)
1 parent de045ae commit ecd8903

File tree

5 files changed

+82
-4
lines changed

5 files changed

+82
-4
lines changed

common/structs.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,3 +245,22 @@ func (inf Inferno) ConvexHull3D() *s2.Loop {
245245
func 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+
}

datatables.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff 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

70104
func (p *Parser) bindTeamScores() {

events/events.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff 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+
274285
func (BombBeginDefuseEvent) implementsBombEventIf() {}
275286

276287
// HitGroup is the type for the various HitGroupXYZ constants.

game_events.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff 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

game_state.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff 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

2021
type 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+
7581
func newGameState() GameState {
7682
return GameState{
7783
playersByEntityID: make(map[int]*common.Player),

0 commit comments

Comments
 (0)