Skip to content

Commit f795d03

Browse files
authored
Merge pull request #249 from markus-wa/issue-241/Player.IsDucking-accuracy
common: try to improve accuracy of Player.IsDucking()
2 parents bb5093e + 39d42b1 commit f795d03

File tree

3 files changed

+100
-4
lines changed

3 files changed

+100
-4
lines changed

.golangci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ linters:
1515
- lll
1616
- typecheck
1717
- gomnd
18+
- exhaustivestruct
19+
- godot
1820
issues:
1921
exclude-rules:
2022
# Exclude some linters from running on tests files.

pkg/demoinfocs/common/player.go

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,9 +186,28 @@ func (p *Player) IsScoped() bool {
186186
return getBool(p.Entity, "m_bIsScoped")
187187
}
188188

189-
// IsDucking returns true if the player is currently crouching.
189+
// IsDucking returns true if the player is currently fully crouching.
190+
// See also: Flags().Ducking() & Flags().DuckingKeyPressed()
190191
func (p *Player) IsDucking() bool {
191-
return getBool(p.Entity, "localdata.m_Local.m_bDucking")
192+
return p.Flags().Ducking() && p.Flags().DuckingKeyPressed()
193+
}
194+
195+
// IsDuckingInProgress returns true if the player is currently in the progress of going from standing to crouched.
196+
// See also: Flags().Ducking() & Flags().DuckingKeyPressed()
197+
func (p *Player) IsDuckingInProgress() bool {
198+
return !p.Flags().Ducking() && p.Flags().DuckingKeyPressed()
199+
}
200+
201+
// IsUnDuckingInProgress returns true if the player is currently in the progress of going from crouched to standing.
202+
// See also: Flags().Ducking() & Flags().DuckingKeyPressed()
203+
func (p *Player) IsUnDuckingInProgress() bool {
204+
return p.Flags().Ducking() && !p.Flags().DuckingKeyPressed()
205+
}
206+
207+
// IsStaning returns true if the player is currently fully standing upright.
208+
// See also: Flags().Ducking() & Flags().DuckingKeyPressed()
209+
func (p *Player) IsStanding() bool {
210+
return !p.Flags().Ducking() && !p.Flags().DuckingKeyPressed()
192211
}
193212

194213
// HasDefuseKit returns true if the player currently has a defuse kit in his inventory.
@@ -284,6 +303,51 @@ func (p *Player) Velocity() r3.Vector {
284303
}
285304
}
286305

306+
// see https://github.com/ValveSoftware/source-sdk-2013/blob/master/mp/src/public/const.h#L146-L188
307+
const (
308+
flOnGround = 1 << iota
309+
flDucking
310+
flAnimDucking
311+
)
312+
313+
// PlayerFlags wraps m_fFlags and provides accessors for the various known flags a player may have set.
314+
type PlayerFlags uint32
315+
316+
func (pf PlayerFlags) Get(f PlayerFlags) bool {
317+
return pf&f != 0
318+
}
319+
320+
// OnGround returns true if the player is touching the ground.
321+
// See m_fFlags FL_ONGROUND https://github.com/ValveSoftware/source-sdk-2013/blob/master/mp/src/public/const.h#L146-L188
322+
func (pf PlayerFlags) OnGround() bool {
323+
return pf.Get(flOnGround)
324+
}
325+
326+
// Ducking returns true if the player is/was fully crouched.
327+
// Fully ducked: Ducking() && DuckingKeyPressed()
328+
// Previously fully ducked, unducking in progress: Ducking() && !DuckingKeyPressed()
329+
// Fully unducked: !Ducking() && !DuckingKeyPressed()
330+
// Previously fully unducked, ducking in progress: !Ducking() && DuckingKeyPressed()
331+
// See m_fFlags FL_DUCKING https://github.com/ValveSoftware/source-sdk-2013/blob/master/mp/src/public/const.h#L146-L188
332+
func (pf PlayerFlags) Ducking() bool {
333+
return pf.Get(flDucking)
334+
}
335+
336+
// DuckingKeyPressed returns true if the player is holding the crouch key pressed.
337+
// Fully ducked: Ducking() && DuckingKeyPressed()
338+
// Previously fully ducked, unducking in progress: Ducking() && !DuckingKeyPressed()
339+
// Fully unducked: !Ducking() && !DuckingKeyPressed()
340+
// Previously fully unducked, ducking in progress: !Ducking() && DuckingKeyPressed()
341+
// See m_fFlags FL_ANIMDUCKING https://github.com/ValveSoftware/source-sdk-2013/blob/master/mp/src/public/const.h#L146-L188
342+
func (pf PlayerFlags) DuckingKeyPressed() bool {
343+
return pf.Get(flAnimDucking)
344+
}
345+
346+
// Flags returns flags currently set on m_fFlags.
347+
func (p *Player) Flags() PlayerFlags {
348+
return PlayerFlags(getInt(p.Entity, "m_fFlags"))
349+
}
350+
287351
/////////////////////////////
288352
// CCSPlayerResource stuff //
289353
/////////////////////////////

pkg/demoinfocs/common/player_test.go

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,13 +209,43 @@ func TestPlayer_IsAirborne(t *testing.T) {
209209
}
210210

211211
func TestPlayer_IsDucking(t *testing.T) {
212-
pl := playerWithProperty("localdata.m_Local.m_bDucking", st.PropertyValue{IntVal: 0})
212+
pl := playerWithProperty("m_fFlags", st.PropertyValue{IntVal: 0})
213213

214214
assert.False(t, pl.IsDucking())
215+
assert.True(t, pl.IsStanding())
216+
assert.False(t, pl.IsDuckingInProgress())
217+
assert.False(t, pl.IsUnDuckingInProgress())
215218

216-
pl = playerWithProperty("localdata.m_Local.m_bDucking", st.PropertyValue{IntVal: 1})
219+
pl = playerWithProperty("m_fFlags", st.PropertyValue{IntVal: 1 << 1})
220+
221+
assert.False(t, pl.IsDucking())
222+
assert.False(t, pl.IsStanding())
223+
assert.False(t, pl.IsDuckingInProgress())
224+
assert.True(t, pl.IsUnDuckingInProgress())
225+
226+
pl = playerWithProperty("m_fFlags", st.PropertyValue{IntVal: 1 << 2})
227+
228+
assert.False(t, pl.IsDucking())
229+
assert.False(t, pl.IsStanding())
230+
assert.True(t, pl.IsDuckingInProgress())
231+
assert.False(t, pl.IsUnDuckingInProgress())
232+
233+
pl = playerWithProperty("m_fFlags", st.PropertyValue{IntVal: 1<<1 | 1<<2})
217234

218235
assert.True(t, pl.IsDucking())
236+
assert.False(t, pl.IsStanding())
237+
assert.False(t, pl.IsDuckingInProgress())
238+
assert.False(t, pl.IsUnDuckingInProgress())
239+
}
240+
241+
func TestPlayerFlags_OnGround(t *testing.T) {
242+
pl := playerWithProperty("m_fFlags", st.PropertyValue{IntVal: 0})
243+
244+
assert.False(t, pl.Flags().OnGround())
245+
246+
pl = playerWithProperty("m_fFlags", st.PropertyValue{IntVal: 1})
247+
248+
assert.True(t, pl.Flags().OnGround())
219249
}
220250

221251
func TestPlayer_HasDefuseKit(t *testing.T) {

0 commit comments

Comments
 (0)