Skip to content

Commit

Permalink
HUD: Fixed OHI Desync (#1513)
Browse files Browse the repository at this point in the history
Sometimes overhead icons stayed stuck in the world. This is due to the
way GMod/source handles player positions. If a player is far enough
away, their position is no longer updated (as can be seen with wallhacks
for example).

While `:GetPos()` still returns a position that at least represents a
rough estimate of their position, the bone position stays at the last
updated place. This means that the overhead icon stays floating in
random places.

This pullrequest fixes this by introducing a check that uses the
fallback position if the player position and the bone position diverge
too much.

While I tested this, it would probably be good if @mexikoedi could
confirm this as well.

---------

Co-authored-by: Histalek <16392835+Histalek@users.noreply.github.com>
  • Loading branch information
TimGoll and Histalek committed May 19, 2024
1 parent 2e6ae91 commit c49529f
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 12 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,18 @@ All notable changes to TTT2 will be documented here. Inspired by [keep a changel
- Fixed Roundendscreen showing karma changes even if karma is disabled
- Fixed the player's FOV staying zoomed in if their weapon is removed while scoped in (by @TW1STaL1CKY)
- Fixed weapon unscoping (or generally any time FOV is set back to default) being delayed due to the player's lag (by @TW1STaL1CKY)
- Fixed overhead icons sometimes being stuck at random places (by @TimGoll)
- Fixed a null entity error in the ShootBullet function in weapon_tttbase (by @mexikoedi)
- Fixed a nil compare error in the DrawHUD function in weapon_tttbasegrenade (by @mexikoedi)

### Removed

- Removed radio tab in shop UI

### Breaking Changes

- Renamed `ply:GetHeightVector()` to `ply:GetHeadPosition()`

## [v0.13.1b](https://github.com/TTT-2/TTT2/tree/v0.13.1b) (2024-02-27)

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion gamemodes/terrortown/gamemode/client/cl_targetid.lua
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ local sizeIconOverHeadIcon = 0.7 * sizeOverHeadIcon
-- @realm client
function DrawOverheadRoleIcon(client, ply, iconRole, colorRole)
local ang = client:EyeAngles()
local pos = ply:GetPos() + ply:GetHeightVector()
local pos = ply:GetPos() + ply:GetHeadPosition()
pos.z = pos.z + offsetOverHeadIcon

local shift = Vector(0, shiftOverHeadIcon, 0)
Expand Down
30 changes: 19 additions & 11 deletions gamemodes/terrortown/gamemode/shared/sh_player_ext.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1234,10 +1234,12 @@ end
-- @note Respects the model scale for the height calculation
-- @return vector The player height
-- @realm shared
function plymeta:GetHeightVector()
local matrix
function plymeta:GetHeadPosition()
local matrix, posHeadBone
local bone = self:LookupBone("ValveBiped.Bip01_Head1")

local posPlayer = self:GetPos()

-- if the bone is defined, the bone matrix is defined as well;
-- however on hot reloads this can momentarily break before it
-- fixes itself again after a short time
Expand All @@ -1246,23 +1248,29 @@ function plymeta:GetHeightVector()
end

if matrix then
local pos = matrix:GetTranslation()
posHeadBone = matrix:GetTranslation()
end

-- If a player is too far away, their head-bone position is only updated
-- sporadically.
-- In that case we want to fall back to the highest corner of the players bounding
-- box position.
if posHeadBone and not self:IsDormant() then
-- note: the 8 is the assumed height of the head after the head bone
-- this might not work for every model
pos.z = pos.z + 8 * self:GetModelScale() * self:GetManipulateBoneScale(bone).z
posHeadBone.z = posHeadBone.z
+ 8 * self:GetModelScale() * self:GetManipulateBoneScale(bone).z

return pos - self:GetPos()
return posHeadBone - posPlayer
end

-- if the model has no head bone for some reason, use the player
-- position as a fallback
else
local obbmMaxs = self:OBBMaxs()
obbmMaxs.x = 0
obbmMaxs.y = 0
local obbmMaxs = self:OBBMaxs()
obbmMaxs.x = 0
obbmMaxs.y = 0

return obbmMaxs * self:GetModelScale()
end
return obbmMaxs * self:GetModelScale()
end

-- to make it hotreload safe, we have to make sure it is not
Expand Down

0 comments on commit c49529f

Please sign in to comment.