AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Scripting (https://forums.alliedmods.net/forumdisplay.php?f=107)
-   -   Solved [L4D2] cs_ragdoll usage? (https://forums.alliedmods.net/showthread.php?t=316614)

Shadowysn 06-01-2019 01:29

[L4D2] cs_ragdoll usage?
 
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.

backwards 06-01-2019 03:15

Re: [L4D2] cs_ragdoll usage?
 
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)

Shadowysn 06-01-2019 03:39

Re: [L4D2] cs_ragdoll usage?
 
Quote:

Originally Posted by 1337norway (Post 2653913)
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.

Silvers 06-01-2019 03:58

Re: [L4D2] cs_ragdoll usage?
 
PHP Code:

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

SetEntPropVector(entity"m_vecOrigin"vPos); 


Shadowysn 06-01-2019 04:10

Re: [L4D2] cs_ragdoll usage?
 
Quote:

Originally Posted by Silvers (Post 2653918)
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.

CliptonHeist 06-01-2019 05:11

Re: [L4D2] cs_ragdoll usage?
 
If velfloat already has assigned values you can just pass it into SetEntPropVector directly.

Shadowysn 06-01-2019 06:57

Re: [L4D2] cs_ragdoll usage?
 
Quote:

Originally Posted by CliptonHeist (Post 2653926)
If velfloat already has assigned values you can just pass it into SetEntPropVector directly.

Uh... thanks for pointing that out. I feel dumb. :stupid:

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;



Dragokas 06-03-2019 11:14

Re: [L4D2] cs_ragdoll usage?
 
Quote:

Originally Posted by Shadowysn (Post 2653908)
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.

Shadowysn 06-05-2019 23:52

Re: [L4D2] cs_ragdoll usage?
 
Quote:

Originally Posted by Dragokas (Post 2654212)
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.

Dragokas 06-06-2019 14:14

Re: [L4D2] cs_ragdoll usage?
 
Lux made many plugins related to ragdolls. See, if any could be useful for you.


All times are GMT -4. The time now is 13:48.

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