Person pops back into existence for a frame after being killed
17 replies, posted
I am working on a ragdoll mode script (As you might've seen in my post in What are you working on) and one thing that bothered me since the beginning is that for some reason the frame you kill someone they appear out of nowhere. Now normally when someone is in ragdoll mode they are set to no draw and only after they respawn they go back into being drawn, problem is for some reason when they are killed they just pop in for no reason at all and then pop back out.
I checked anything I could think of, I overwrote SetNoDraw, AddEffects, RemoveEffects to print what's using them with debug.Trace and if they are being used to make the player visible and I got nothing. I put in debug.Trace into all kind of death hooks and spawn hooks and they all return nothing important, it seems like it's happening after the PlayerDeath hook and before the PostPlayerDeath hook. setting no draw inside of the PostPlayerDeath hook will do nothing at all for like 3 ticks. I even tried using a Tick hook to always make the person invisible but it still didn't work. I also tried on the clientside to avoid drawing a player if he's inside ragdoll mode but still got nothing out of it. Here's a video of it in action:
https://streamable.com/zwhcp
We need the code?
I might be wrong, but I think I have seen such behaviour before and there probably is no way to fix it, since it probably is not broken in the first place. What you could do, is after ragdolling the player, set his model to something invisible, or rather his material and try if he wil not pop back anymore. Then just reset to default material on unragdoll
No need to post the code, I did describe what I was doing and what the problem was.
Yup, I was afraid that was the answer. I am also afraid that maybe that frame everything gets reset for the player, including material etc... I will try other stuff like setting the render bounds or just teleport him under ground if I am desperate. I'll wait 12 more hours just in case I get lucky and a developer knows an answer for me.
Have you tried using GM/PrePlayerDraw on clients?
Yup, it's one of the things I tried. For some reason that hook doesn't get called at all during the whole thing. I guess it doesn't have a lot to do with drawing the player since I did try overriding the SetNoDraw and AddEffects to print out any hooks using them. I guess it's an engine thing and I'll have to get hacky to fix it. Damn source can't wait for S&box
Tell me more about how your script works. Are you accomplishing this by making them spectate the ragdoll? While they're in ragdoll mode, codewise, are they alive or dead? It's almost like they're being respawned before they get a spectate entity set.
They have SetNotSolid and SetNoDraw turned to true. I then just teleport them where the ragdoll is so any script that wants to find their position will return the ragdoll's. I also have any input from them ignored unless it's to respawn when they are dead and their view is changed to the ragdoll's view.
If the client is aware that a ragdoll belongs to a certain player, you could just detour GetPos with a little logic to just return the ragdoll's position if it exists. That could make your problem a bit less glaring. And, double check to make sure they aren't being respawned at all after dying. If pl:Alive() returns true at any point after you make the ragdoll, your problem is almost certainly there.
https://files.facepunch.com/forum/upload/788/29d50545-22f3-4b72-9ef1-648778ce4231/image.png
It is returning that the player is alive on DoPlayerDeath and PlayerDeath, but that is normal because those are called before he actually dies.
I still think something is respawning them - the client wouldn't draw their model if it knew they were dead. Maybe put a think hook on the client to notify you whenever their alive status changes? Something like this:
local cache = {}
local chatcol = Color(100, 100, 255)
hook.Add("Think", "TrackAliveStatus", function()
for k, v in ipairs(player.GetAll()) do
cache[v] = cache[v] or v:Alive()
if (cache[v] == true and !v:Alive()) then
chat.AddText(chatcol, tostring(SysTime()), " ", v, " is now dead")
cache[v] = false
end
if (cache[v] == false and v:Alive()) then
chat.AddText(chatcol, tostring(SysTime()), " ", v, " is now alive")
cache[v] = true
end
end
end)
No hack we tried is working... The only one that I tried that is working right now is where I have it so whenever he takes damage it teleports him away for 1 frame. That's the only thing that works unfortunately. I'll try some more stuff and I'll keep this open hoping some developer come rescue me.
Did you run that hook I posted? It's not to fix anything - it's for debugging. Like I said the client should only draw the model if the player is alive, so I'm suspicious that something is respawning them and messing with your goal. That hook should confirm if that's happening or not.
https://streamable.com/adwqf
So the player is still alive while in ragdoll mode - that explains this a bit better. You could KillSilent them when you create their ragdoll - cache their weapons/armor/etc beforehand, and then respawn them in the correct location and give their things back to them if/when they come out of ragdoll mode. If your ragdolls are meant to affect their health when taking damage, you could implement a pseudo health system for that.
Some weapons check the player if he's alive before dealing the damage and doing what you said would mean redoing most of what I've done now. I think I'll stick with this hack for now. Darn gmod.
I know this isn't helpful, but...
weapon_dick
Yeah I forgot why it's there, but it's useful. It's literally what happens if you don't set a PrimaryAttack and SecondaryAttack, it will just shoot a projectile that does 150 damage, useful sometimes.
Sorry, you need to Log In to post a reply to this thread.