Open trptmx opened 10 years ago
This seems to be the same with weapons when you enter a vehicle and get out of it. The bonemerged clientside models will detach when you leave the vehicle.
This is not really a bug. When entities go out of PVS they become dormant or rather half-removed. If a "fullupdate" happens they actually become removed as far as the client is concerned, until you see the entity again that is. Hook NetworkEntityCreated to see when entities reappear and for when entities become dormant hook for example NotifyShouldTransmit and remove/hide your clientside model.
I think I found part of the issue. When normal entities are removed because of a full update or from becoming dormant C_BaseEntity::UnlinkFromHierarchy
is called (fullupdate, dormant), which causes their children to be unlinked as well. Normally this would be fine because the parenting is fixed here using m_hNetworkMoveParent
after an update; however, because clientside entities aren't affected by full updates or pvs C_BaseEntity::PostDataUpdate
is never called.
test code for cl_fullupdate fix:
hook.Add("NotifyShouldTransmit", "test", function(ent, transmit)
if ent == LocalPlayer() then
local tbl = ents.GetAll()
for i=1, #tbl do
local v = tbl[i]
if v:EntIndex() == -1 then
v:SetParent(v:GetInternalVariable("m_hNetworkMoveParent"))
end
end
end
end)
test code for cl_fullupdate + pvs fix:
local parentLookup = {}
local function cacheParents()
parentLookup = {}
local tbl = ents.GetAll()
for i=1, #tbl do
local v = tbl[i]
if v:EntIndex() == -1 then
local parent = v:GetInternalVariable("m_hNetworkMoveParent")
local children = parentLookup[parent]
if not children then children = {}; parentLookup[parent] = children end
children[#children + 1] = v
end
end
end
local function fixChildren(parent, transmit)
local tbl = parentLookup[parent]
if tbl then
for i=1, #tbl do
local child = tbl[i]
if transmit then
print("parented " .. tostring(child) .. " to " .. tostring(parent))
child:SetNoDraw(false)
child:SetParent(parent)
fixChildren(child, transmit)
else
print("parent " .. tostring(parent) .. " is dorment. hiding " .. tostring(child))
child:SetNoDraw(true)
fixChildren(child, transmit)
end
end
end
end
local lastTime = 0
hook.Add("NotifyShouldTransmit", "test", function(ent, transmit)
local time = RealTime()
if lastTime < time then
cacheParents()
lastTime = time
end
fixChildren(ent, transmit)
end)
When leaving the PVS of a SENT (all that I've tested with) any parented clientside models will permanently lose their parenting and float detached from the entity. It'll still say it's parented when running GetParent making it difficult to detect.
I've gotten around it using
function ENT:UpdateTransmitState()
return TRANSMIT_ALWAYS end