markus-wa / demoinfocs-golang

A Counter-Strike 2 & CS:GO demo parser for Go (demoinfo)
https://pkg.go.dev/github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs?tab=doc
MIT License
695 stars 93 forks source link

Get client eye position #236

Closed 87andrewh closed 3 years ago

87andrewh commented 4 years ago

Higher goal I would like an Entity.EyePosition() function that accurately returns player eyes' Z coordinates, even when jumping or in the middle of the duck or un-duck animation. I suspect that IsDucking() is not accurate enough for my purposes.

Describe the solution you'd like In SourceMod, I use GetClientEyePosition(), which is accurate. I also think cl_showpos returns an accurate location.

Describe alternatives you've considered None.

Additional context I don't need the position to be extremely accurate in the XY plane, as I don't think there is a simple native way to access precise eye locations for both CT and T models in all animations. But an accurate Z should be obtainable.

markus-wa commented 4 years ago

Would be a nice feature.

Here's some notes, either for my future self or whoever want's to implement it.

SM's GetClientEyePosition() seems to be based on CServerGameClients->ClientEarPosition:

so it looks like it's C_BaseEntity::CalcAbsolutePosition() + localdata.m_vecViewOffset

not sure if this bit here is needed or not: https://github.com/alliedmodders/sourcemod/blob/4bebdc18a2e4820b234a85c3a1e38eb868a84bf2/extensions/sdktools/vnatives.cpp#L711-L715 < it's not needed

87andrewh commented 4 years ago

"not sure if this bit here is needed or not"

The highlighted code writes the position by reference. Without it, GetClientEyePosition() would do nothing.

markus-wa commented 4 years ago

It also seems to do some translation with LocalToPhysAddr() (and sp_ftoc?) Which I didn't look into yet.

87andrewh commented 4 years ago

Oh yeah, SourcePawn is weird. All types are converted to and passed as cell_t, which is int32. sp_ftoc() encodes floats as cell_t. pContext->LocalToPhysAddr(params[2], &addr) links params[2] to &addr, allowing you to edit params[2] through addr, which is the way that information is passed back to the caller.

For some context, a SourcePawn script calls GetClientEyePosition(), which is C++ code. GetClientEyePosition() returns information to the the SourcePawn script by editing the params by reference.

I actually don't think you need to worry too much about SourcePawn details, as it's a modding framework built on top of Source. The demo system should just hook Source stuff directly.

markus-wa commented 4 years ago

Ahh makes sense, cheers for the explanation!

billfreeman44 commented 3 years ago

Maybe this helps? https://github.com/saul/demofile/discussions/290

markus-wa commented 3 years ago

Interesting thread @billfreeman44

I think what we should probably do as a quick win is expose something like EyeHeightOffset(). Then let users do the calc manually.

Calling into source engine code is probably out of scope for this project.

I guess in the meantime people can just use good old Player.Entity.PropertyValueMust(....

markus-wa commented 3 years ago

or we actually may get away with PositionEyes() and just Position() + m_vecViewOffset[2]

markus-wa commented 3 years ago

finally got around to this (really should have done so sooner considering how easy it turned out to be)

we now have Player.PositionEyes()

:partying_face: