Raised This Month: $12 Target: $400
 3% 

Solved [L4D2] cs_ragdoll usage?


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Shadowysn
Senior Member
Join Date: Sep 2015
Location: Location:
Old 06-01-2019 , 01:29   [L4D2] cs_ragdoll usage?
Reply With Quote #1

I wanted to attempt spawning survivor ragdolls without removing the original death model. So far, I got the ragdoll death to an extent.
I have no idea how to make cs_ragdoll:
* use the position of the bones of it's owner. (Right now, it uses the t-pose.)
* apply damage taken as force from it's owner. (Movement is solved.)

I did see something about clientside ragdolls from the vtable dumper, but I have no idea how to use it.

EDIT: Just realized this shouldn't include L4D1 at all.

Last edited by Shadowysn; 11-20-2019 at 03:12.
Shadowysn is offline
backwards
AlliedModders Donor
Join Date: Feb 2014
Location: USA
Old 06-01-2019 , 03:15   Re: [L4D2] cs_ragdoll usage?
Reply With Quote #2

You have to utilize the netprops of the CSRagdoll entity:

PHP Code:
CCSRagdoll (type DT_CSRagdoll)
 
Memberm_vecOrigin (offset 732) (type vector) (bits 0) (Coord|ChangesOften)
 
Memberm_vecRagdollOrigin (offset 1272) (type vector) (bits 0) (Coord)
 
Memberm_hPlayer (offset 1256) (type integer) (bits 21) (Unsigned|NoScale)
 
Memberm_nModelIndex (offset 198) (type integer) (bits 13) ()
 
Memberm_nForceBone (offset 924) (type integer) (bits 8) ()
 
Memberm_vecForce (offset 928) (type vector) (bits 0) (NoScale)
 
Memberm_vecRagdollVelocity (offset 1260) (type vector) (bits 0) (NoScale)
 
Memberm_iDeathPose (offset 1284) (type integer) (bits 12) (Unsigned)
 
Memberm_iDeathFrame (offset 1288) (type integer) (bits 5) ()
 
Memberm_iTeamNum (offset 788) (type integer) (bits 6) ()
 
Memberm_bClientSideAnimation (offset 1132) (type integer) (bits 1) (Unsigned)
 
Memberm_flDeathYaw (offset 1292) (type float) (bits 0) (NoScale)
 
Memberm_flAbsYaw (offset 1296) (type float) (bits 0) (NoScale
m_iDeathPose and m_iDeathFrame would be the values used for setting the bone positions\rotations. Although i'm unsure exactly how they convert the info into a two values passed to the netprop.

The sdk utilizes this function to convert the bones in a matrix array into the int values here:
https://github.com/ValveSoftware/sou...senpc.cpp#L159

https://github.com/ValveSoftware/sou...h_pose.cpp#L12

Setting the velocity you would use the m_vecForce and m_nForceBone to set the bone which sufferd the impact and then the force direction which will apply to the ragdoll. Also theres this for normal ragdolls velocity before impact m_vecRagdollVelocity (I think)
__________________
I highly recommend joining the SourceMod Discord Server for real time support.
backwards is offline
Shadowysn
Senior Member
Join Date: Sep 2015
Location: Location:
Old 06-01-2019 , 03:39   Re: [L4D2] cs_ragdoll usage?
Reply With Quote #3

Quote:
Originally Posted by 1337norway View Post
You have to utilize the netprops of the CSRagdoll entity:

PHP Code:
CCSRagdoll (type DT_CSRagdoll)
 
Memberm_vecOrigin (offset 732) (type vector) (bits 0) (Coord|ChangesOften)
 
Memberm_vecRagdollOrigin (offset 1272) (type vector) (bits 0) (Coord)
 
Memberm_hPlayer (offset 1256) (type integer) (bits 21) (Unsigned|NoScale)
 
Memberm_nModelIndex (offset 198) (type integer) (bits 13) ()
 
Memberm_nForceBone (offset 924) (type integer) (bits 8) ()
 
Memberm_vecForce (offset 928) (type vector) (bits 0) (NoScale)
 
Memberm_vecRagdollVelocity (offset 1260) (type vector) (bits 0) (NoScale)
 
Memberm_iDeathPose (offset 1284) (type integer) (bits 12) (Unsigned)
 
Memberm_iDeathFrame (offset 1288) (type integer) (bits 5) ()
 
Memberm_iTeamNum (offset 788) (type integer) (bits 6) ()
 
Memberm_bClientSideAnimation (offset 1132) (type integer) (bits 1) (Unsigned)
 
Memberm_flDeathYaw (offset 1292) (type float) (bits 0) (NoScale)
 
Memberm_flAbsYaw (offset 1296) (type float) (bits 0) (NoScale
m_iDeathPose and m_iDeathFrame would be the values used for setting the bone positions\rotations. Although i'm unsure exactly how they convert the info into a two values passed to the netprop.

The sdk utilizes this function to convert the bones in a matrix array into the int values here:
https://github.com/ValveSoftware/sou...senpc.cpp#L159

https://github.com/ValveSoftware/sou...h_pose.cpp#L12

Setting the velocity you would use the m_vecForce and m_nForceBone to set the bone which sufferd the impact and then the force direction which will apply to the ragdoll. Also theres this for normal ragdolls velocity before impact m_vecRagdollVelocity (I think)
Well, thanks for your info. I've started with velocity first, and figure out the positions later.

Unfortunately, I seem to have run into a newbie problem. I have no idea how to convert float arrays to a vector. The sourcemod wiki doesn't help, it tends to be very confusing.

Last edited by Shadowysn; 06-01-2019 at 03:53.
Shadowysn is offline
Silvers
SourceMod Plugin Approver
Join Date: Aug 2010
Location: SpaceX
Old 06-01-2019 , 03:58   Re: [L4D2] cs_ragdoll usage?
Reply With Quote #4

PHP Code:
float vPos[3];
vPos view_as<float>({ 0.01.02.0 });

SetEntPropVector(entity"m_vecOrigin"vPos); 
__________________
Silvers is offline
Shadowysn
Senior Member
Join Date: Sep 2015
Location: Location:
Old 06-01-2019 , 04:10   Re: [L4D2] cs_ragdoll usage?
Reply With Quote #5

Quote:
Originally Posted by Silvers View Post
PHP Code:
float vPos[3];
vPos view_as<float>({ 0.01.02.0 });

SetEntPropVector(entity"m_vecOrigin"vPos); 
HTML Code:
C:\Program Files (x86)\Steam\steamapps\common\Left 4 Dead 2\left4dead2\addons\sourcemod\scripting\L4D2CSRagdoll.sp(91) : error 008: must be a constant expression; assumed zero
PHP Code:
velfloat view_as<float>({ velfloat[0], velfloat[1], velfloat[2] }) // Troublesome line 
I used the float's arrays to set the view_as values. Didn't work.
I used seperate values to set the view_as values. Caused more problems.

Last edited by Shadowysn; 06-01-2019 at 04:12.
Shadowysn is offline
CliptonHeist
Senior Member
Join Date: Feb 2016
Old 06-01-2019 , 05:11   Re: [L4D2] cs_ragdoll usage?
Reply With Quote #6

If velfloat already has assigned values you can just pass it into SetEntPropVector directly.
CliptonHeist is offline
Shadowysn
Senior Member
Join Date: Sep 2015
Location: Location:
Old 06-01-2019 , 06:57   Re: [L4D2] cs_ragdoll usage?
Reply With Quote #7

Quote:
Originally Posted by CliptonHeist View Post
If velfloat already has assigned values you can just pass it into SetEntPropVector directly.
Uh... thanks for pointing that out. I feel dumb.

I've gotten the velocity on player movement working. I'd like to get force from damage, but I don't know how.
Here's my code that applied the velocity:
PHP Code:
// This is the value initialized + hook
float g_saveVelocity[MAXPLAYERS+1][3];
HookEvent("player_hurt"Player_Hurt_PreEventHookMode_Pre);

// Below code is in the ragdoll spawning function.
if (!IsPlayerAlive(client))
    {
        
float multiply[3];
        
multiply[0] = g_saveVelocity[client][0]*25;
        
multiply[1] = g_saveVelocity[client][1]*25;
        
multiply[2] = g_saveVelocity[client][2]*25;
        
SetEntPropVector(RagdollProp_Send"m_vecForce"multiply);
        
//PrintToChatAll("Applied force!");
        
g_saveVelocity[client][0] = 0.0
        g_saveVelocity
[client][1] = 0.0
        g_saveVelocity
[client][2] = 0.0
    
}
    else
    {
        
float velfloat[3];
        
velfloat[0] = GetEntPropFloat(clientProp_Send"m_vecVelocity[0]")*25
        velfloat
[1] = GetEntPropFloat(clientProp_Send"m_vecVelocity[1]")*25
        velfloat
[2] = GetEntPropFloat(clientProp_Send"m_vecVelocity[2]")*25
        SetEntPropVector
(RagdollProp_Send"m_vecForce"velfloat);
    }

// Below code is the hooked damage event, which prepares the g_saveVelocity for the above code.
public void Player_Hurt_Pre(Handle event, const char[] namebool dontbroadcast)
{
    
int userID GetEventInt(event"userid");
    
int user GetClientOfUserId(userID);
    if (
user <= 0)
    return;
    
    
int health GetEventInt(event"health");
    if (
health 0)
    {
        return;
    }
    
    if(!
g_IsSequel || !g_RagdollModeEnabled)
        return;
    
    if (
GetClientTeam(user) != && GetClientTeam(user) != 4)
    return;
    
    
float velfloat[3];
    
velfloat[0] = GetEntPropFloat(userProp_Send"m_vecVelocity[0]")
    
velfloat[1] = GetEntPropFloat(userProp_Send"m_vecVelocity[1]")
    
velfloat[2] = GetEntPropFloat(userProp_Send"m_vecVelocity[2]")
    
g_saveVelocity[user] = velfloat;


Last edited by Shadowysn; 06-01-2019 at 06:57.
Shadowysn is offline
Dragokas
Veteran Member
Join Date: Nov 2017
Location: Ukraine on fire
Old 06-03-2019 , 11:14   Re: [L4D2] cs_ragdoll usage?
Reply With Quote #8

Quote:
Originally Posted by Shadowysn View Post
I wanted to attempt spawning survivor ragdolls without removing the original death model. So far, I got the ragdoll death to an extent.
I'm not compeletely sure what do you try to accomplish ... "convert" client sided ragdoll to server-sided?

In L4D1 (not sure about L4d2) ragdoll entity is valid for a very small amount of time: "player_death" with EventHookMode_Pre and no more valid on Post-event.

A trick is to kill it right there and create your own by reproducing original preperties, something like this:
PHP Code:
#pragma semicolon 1
#pragma newdecls required

#include <sourcemod>
#include <sdktools>
#tryinclude <LMCCore>

public void OnPluginStart()
{
    
HookEvent("player_death"player_deathEventHookMode_Pre);
}

public 
Action player_death(Event event, const char [] namebool dontBroadcast)
{
    static 
char Tank_Model[PLATFORM_MAX_PATH];
    
int client GetClientOfUserId(event.GetInt("userid"));    
    
    
//required checks
    //if (client && IsClientInGame(client) && IsInfected(client, ZOMBIECLASS_TANK))
    
{
        
// note: tank_killed event is too late here to retrieve ragdoll entity!
        
int ragdoll GetEntPropEnt(clientProp_Send"m_hRagdoll"); // CCSRagdoll
        
if (ragdoll && IsValidEntity(ragdoll)) {
            
AcceptEntityInput(ragdoll"Kill");
        }
        
        
int r,g,b,a;
        
float vOrigin[3];
        
char sColor[16];
        
GetClientAbsOrigin(clientvOrigin);
        
GetEntityRenderColor(clientr,g,b,a);
        
Format(sColorsizeof(sColor), "%i %i %i"rgb);
        
        
/*
        int iOverlayModel = -1;
        
        #if defined _LMCCore_included
            if( bLMC_Available )
                iOverlayModel = LMC_GetClientOverlayModel(client);    
        #endif
        */
        
        //GetEntPropString(iOverlayModel < 1 ? client : iOverlayModel, Prop_Data, "m_ModelName", Tank_Model, sizeof(Tank_Model));
        
GetEntPropString(clientProp_Data"m_ModelName"Tank_Modelsizeof(Tank_Model));
        
        
CreateTankRagdoll(vOriginTank_ModelsColor);
    }
}

void CreateTankRagdoll(float pos[3], char[] sModelchar[] sColor)
{
    static 
int body;
    
body CreateEntityByName("prop_ragdoll");
    if (
body != -1) {
        
DispatchKeyValue(body"model"sModel);
        
DispatchKeyValue(body"RenderColor"sColor);
        
DispatchKeyValue(body"spawnflags""4");
        
DispatchSpawn(body);
        
TeleportEntity(bodyposNULL_VECTORNULL_VECTOR);
        
SetEntityKillTimer(body60.0);
    }
}

stock void SetEntityKillTimer(int entfloat time)
{
    
char sRemove[64];
    
Format(sRemovesizeof(sRemove), "OnUser1 !self:Kill::%f:1"time);
    
SetVariantString(sRemove);
    
AcceptEntityInput(ent"AddOutput");
    
AcceptEntityInput(ent"FireUser1");

Apply original velocity and direction is the only required to add to finish what you want.
This sample was for my tank plugin.
__________________
Expert of CMD/VBS/VB6. Malware analyst. L4D fun (Bloody Witch & FreeZone)
[My plugins] [My tools] [GitHub] [Articles] [HiJackThis+] [Donate]

Last edited by Dragokas; 06-03-2019 at 11:16.
Dragokas is offline
Shadowysn
Senior Member
Join Date: Sep 2015
Location: Location:
Old 06-05-2019 , 23:52   Re: [L4D2] cs_ragdoll usage?
Reply With Quote #9

Quote:
Originally Posted by Dragokas View Post
I'm not compeletely sure what do you try to accomplish ... "convert" client sided ragdoll to server-sided?

In L4D1 (not sure about L4d2) ragdoll entity is valid for a very small amount of time: "player_death" with EventHookMode_Pre and no more valid on Post-event.

A trick is to kill it right there and create your own by reproducing original preperties, something like this:
PHP Code:
#pragma semicolon 1
#pragma newdecls required

#include <sourcemod>
#include <sdktools>
#tryinclude <LMCCore>

public void OnPluginStart()
{
    
HookEvent("player_death"player_deathEventHookMode_Pre);
}

public 
Action player_death(Event event, const char [] namebool dontBroadcast)
{
    static 
char Tank_Model[PLATFORM_MAX_PATH];
    
int client GetClientOfUserId(event.GetInt("userid"));    
    
    
//required checks
    //if (client && IsClientInGame(client) && IsInfected(client, ZOMBIECLASS_TANK))
    
{
        
// note: tank_killed event is too late here to retrieve ragdoll entity!
        
int ragdoll GetEntPropEnt(clientProp_Send"m_hRagdoll"); // CCSRagdoll
        
if (ragdoll && IsValidEntity(ragdoll)) {
            
AcceptEntityInput(ragdoll"Kill");
        }
        
        
int r,g,b,a;
        
float vOrigin[3];
        
char sColor[16];
        
GetClientAbsOrigin(clientvOrigin);
        
GetEntityRenderColor(clientr,g,b,a);
        
Format(sColorsizeof(sColor), "%i %i %i"rgb);
        
        
/*
        int iOverlayModel = -1;
        
        #if defined _LMCCore_included
            if( bLMC_Available )
                iOverlayModel = LMC_GetClientOverlayModel(client);    
        #endif
        */
        
        //GetEntPropString(iOverlayModel < 1 ? client : iOverlayModel, Prop_Data, "m_ModelName", Tank_Model, sizeof(Tank_Model));
        
GetEntPropString(clientProp_Data"m_ModelName"Tank_Modelsizeof(Tank_Model));
        
        
CreateTankRagdoll(vOriginTank_ModelsColor);
    }
}

void CreateTankRagdoll(float pos[3], char[] sModelchar[] sColor)
{
    static 
int body;
    
body CreateEntityByName("prop_ragdoll");
    if (
body != -1) {
        
DispatchKeyValue(body"model"sModel);
        
DispatchKeyValue(body"RenderColor"sColor);
        
DispatchKeyValue(body"spawnflags""4");
        
DispatchSpawn(body);
        
TeleportEntity(bodyposNULL_VECTORNULL_VECTOR);
        
SetEntityKillTimer(body60.0);
    }
}

stock void SetEntityKillTimer(int entfloat time)
{
    
char sRemove[64];
    
Format(sRemovesizeof(sRemove), "OnUser1 !self:Kill::%f:1"time);
    
SetVariantString(sRemove);
    
AcceptEntityInput(ent"AddOutput");
    
AcceptEntityInput(ent"FireUser1");

Apply original velocity and direction is the only required to add to finish what you want.
This sample was for my tank plugin.
Basically, what I'm trying to do is make dead survivors create a client ragdoll like in the Restore Ragdolls plugin, while keeping the original death model albeit making it invisible.

Reasons:
* I wanted to try out something (almost) on my own.
* Death models created with CreateEntityByName aren't affected by gravity.
Sorry if what I wanted wasn't all that clear with you.

The problem was that the client ragdolls didn't automatically assume the velocity + bone positions of their owner. So far only velocity from owner itself was finished.

And yes, in L4D2 cs_ragdoll behaves similarly like in L4D1.

Last edited by Shadowysn; 06-06-2019 at 00:01.
Shadowysn is offline
Dragokas
Veteran Member
Join Date: Nov 2017
Location: Ukraine on fire
Old 06-06-2019 , 14:14   Re: [L4D2] cs_ragdoll usage?
Reply With Quote #10

Lux made many plugins related to ragdolls. See, if any could be useful for you.
__________________
Expert of CMD/VBS/VB6. Malware analyst. L4D fun (Bloody Witch & FreeZone)
[My plugins] [My tools] [GitHub] [Articles] [HiJackThis+] [Donate]
Dragokas is offline
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 22:12.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode