BANNED
|
03-26-2017
, 01:51
[TF2] tf_ragdoll -> issues with m_flModelScale, also general loadout change issues
|
#1
|
I've been screwing around with ragdolls. I've got what I set out to create working beautifully, other than two issues (one minor, one major).
The minor issue is that I can't seem to set m_flModelScale on a tf_ragdoll entity I've created.
- SetEntPropFloat results in "tf_ragdoll doesn't have m_flModelScale" nonsense which Google has shown me may be a result of something to do with EntIndexToEntRef
- Using AcceptEntityInput to set SetModelScale results in "Entity is not a CBaseEntity"
The major issue is that for some reason, loadout changes completely stop functioning on my test server after a while. With a lot of help from Pelipoika, I figured out m_hRagWearables and have been successfully spawning ragdolls that have the same cosmetics as the player and also respect the player's current hand/torso/head scale (m_flModelScale was the last thing I wanted to get working).
So those are my 2 problems.
Spoiler below contains my testing plugin. I figure it'll potentially help someone out with something. For example, that "unused burning death animations" plugin that was created from a snippet I put out, the wearables stuff would be perfect for that plugin. Aside from the aforementioned 2 issues, the plugin works like a charm. I've already got plans for this code including using it to update the tf_ragdolls in my Roll The Dice to respect the player's wearables/scale for "Freeze" and my custom "Midas Touch" RTD perk. It'd also be useful for the sm_freeze command as a better alternative to "color the player blue" and it'd definitely be useful for this plugin.
Please don't be too harsh on my formatting style and how I did things. It's just a private testing plugin that is acting as the launchpad for a few ideas I have.
NOTE: The "sm_rag" command in the plugin below doesn't just create a ragdoll where you are with your cosmetics; it turns you entirely invisible, blocks all attacking and sets you to MOVETYPE_NONE. Think of it as a TF2 version of a Garry's Mod "Ragdoll a player" command. The firstperson view when you're "ragdolled" isn't the best (you're practically inside the ragdoll). Probably because of my stupid fuckin' usage of SetClientViewEntity and AcceptEntityInput on "SetForcedTauntCam" at the same time.
Spoiler
PHP Code:
#include <sourcemod>
#include <tf2_stocks>
#include <sdktools>
#pragma semicolon 1
#pragma newdecls required
int g_iPlayerBodyGroups[MAXPLAYERS + 1];
int g_hPlayerWearables[MAXPLAYERS + 1];
int g_iOffsetDecaps;
public void OnPluginStart()
{
RegAdminCmd("sm_rag", Command_CreateRagdoll, ADMFLAG_CHEATS, "sm_rag");
HookEvent("post_inventory_application", Event_Setup);
for(int i = 1; i <= MaxClients; i++)
{
if(IsClientInGame(i))
{
g_iPlayerBodyGroups[i] = 0;
g_hPlayerWearables[i] = 0;
}
}
}
public Action Event_Setup(Event hEvent, const char[] strName, bool bDontBroadcast)
{
int iClient = GetClientOfUserId(hEvent.GetInt("userid"));
if(IsClientInGame(iClient))
{
g_iPlayerBodyGroups[iClient] = GetEntPropEnt(iClient, Prop_Send, "m_nBody");
g_hPlayerWearables[iClient] = GetEntPropEnt(iClient, Prop_Send, "m_hMyWearables", 1);
}
return Plugin_Handled;
}
public void OnClientDisconnect(int iClient)
{
g_iPlayerBodyGroups[iClient] = 0;
g_hPlayerWearables[iClient] = 0;
}
public Action Command_CreateRagdoll(int iClient, int iArguments)
{
if(iClient != 0)
{
CreateRagdoll(iClient);
}
return Plugin_Handled;
}
int CreateRagdoll(int iClient, float flSelfDestruct = 18.0, int iDeathType = 3)
{
int iRagdoll = CreateEntityByName("tf_ragdoll");
if(iRagdoll > MaxClients && IsValidEntity(iRagdoll))
{
float fPosition[3];
float fAngle[3];
float fVelocity[3];
GetClientAbsOrigin(iClient, fPosition);
GetClientAbsAngles(iClient, fAngle);
SetPlayerVisibility(iClient, true);
SetEntityMoveType(iClient, MOVETYPE_NONE);
// Lalalala this is fucking dumb why did i do this it doesn't even work right.
// I want it to put the player in thirdperson and focus on the ragdoll
SetClientViewEntity(iClient, iRagdoll);
AcceptEntityInput(iClient, "SetForcedTauntCam", 1);
for(int iSlot = 0; iSlot <= 5; iSlot++)
{
int iWeapon = GetPlayerWeaponSlot(iClient, iSlot);
if(iWeapon && IsValidEdict(iWeapon))
{
SetEntPropFloat(iWeapon, Prop_Send, "m_flNextPrimaryAttack", GetGameTime() + flSelfDestruct);
}
}
SetEntPropFloat(iClient, Prop_Send, "m_flNextAttack", GetGameTime() + flSelfDestruct);
if(TF2_GetPlayerClass(iClient) == TFClass_Spy)
{
SetEntPropFloat(iClient, Prop_Send, "m_flStealthNextChangeTime", GetGameTime() + flSelfDestruct);
}
if(GetDecaps(iClient) > 0 && TF2_IsPlayerInCondition(iClient, TFCond_DemoBuff))
{
TF2_RemoveCondition(iClient, TFCond_DemoBuff);
}
SetEntProp(iRagdoll, Prop_Send, "m_iPlayerIndex", iClient);
// Was doing testing of this stuff.
switch(iDeathType)
{
case 0: SetEntProp(iRagdoll, Prop_Send, "m_bGoldRagdoll", 1);
case 1: SetEntProp(iRagdoll, Prop_Send, "m_bIceRagdoll", 1);
case 2: SetEntProp(iRagdoll, Prop_Send, "m_bBurning", 1);
case 3: SetEntProp(iRagdoll, Prop_Send, "m_bElectrocuted", 1);
case 4: SetEntProp(iRagdoll, Prop_Send, "m_bBecomeAsh", 1);
case 5: SetEntProp(iRagdoll, Prop_Send, "m_bFeignDeath", 1);
case 6: SetEntProp(iRagdoll, Prop_Send, "m_bCloaked", 1);
case 7: SetEntProp(iRagdoll, Prop_Send, "m_bWasDisguised", 1);
case 8: SetEntProp(iRagdoll, Prop_Send, "m_bGib", 1);
case -1: { }
}
SetEntProp(iRagdoll, Prop_Send, "m_iTeam", TF2_GetClientTeam(iClient));
SetEntProp(iRagdoll, Prop_Send, "m_iClass", TF2_GetPlayerClass(iClient));
SetEntProp(iRagdoll, Prop_Send, "m_bOnGround", 1);
g_iPlayerBodyGroups[iClient] = GetEntPropEnt(iClient, Prop_Send, "m_nBody");
AcceptEntityInput(iRagdoll, "SetBodyGroups", g_iPlayerBodyGroups[iClient]);
// This seems to fuck up somehow and causes my loadout to be unchangable.
g_hPlayerWearables[iClient] = GetEntPropEnt(iClient, Prop_Send, "m_hMyWearables", 1);
int iElementCount = GetEntPropArraySize(iClient, Prop_Send, "m_hMyWearables");
for (int i = 0; i < iElementCount; i++)
{
if(g_hPlayerWearables[iClient] > 0)
{
SetEntPropEnt(iRagdoll, Prop_Send, "m_hRagWearables", g_hPlayerWearables[iClient], i);
}
}
// Can't get m_flModelScale to fuckin' work.
// SetEntPropFloat results in "tf_ragdoll doesn't have m_flModelScale" nonsense
// AcceptEntityInput results in "Entity is not a CBaseEntity"
// So fuck it.
SetEntPropFloat(iRagdoll, Prop_Send, "m_flHeadScale", GetEntPropFloat(iClient, Prop_Send, "m_flHeadScale"));
SetEntPropFloat(iRagdoll, Prop_Send, "m_flTorsoScale", GetEntPropFloat(iClient, Prop_Send, "m_flTorsoScale"));
SetEntPropFloat(iRagdoll, Prop_Send, "m_flHandScale", GetEntPropFloat(iClient, Prop_Send, "m_flHandScale"));
DispatchSpawn(iRagdoll);
TeleportEntity(iRagdoll, fPosition, fAngle, fVelocity);
ActivateEntity(iRagdoll);
if(flSelfDestruct > 0.0)
{
DataPack hClient = new DataPack();
hClient.Reset();
hClient.WriteCell(GetClientUserId(iClient));
hClient.WriteCell(EntIndexToEntRef(iRagdoll));
CreateTimer(flSelfDestruct, Timer_DeleteRagdoll, hClient);
}
return iRagdoll;
}
return 0;
}
void SetPlayerVisibility(int iClient, bool bIsHidden)
{
SetEntityRenderMode(iClient, RENDER_TRANSCOLOR);
SetEntityRenderColor(iClient, 255, 255, 255, (bIsHidden ? 0 : 255));
for(int i = 0; i <= 5; i++)
{
int iWeapon = GetPlayerWeaponSlot(iClient, i);
if(iWeapon > MaxClients && IsValidEntity(iWeapon))
{
SetEntityRenderMode(iWeapon, RENDER_TRANSCOLOR);
SetEntityRenderColor(iWeapon, 255, 255, 255, (bIsHidden ? 0 : 255));
}
}
char strClass[20];
for(int i = MaxClients + 1; i < GetMaxEntities(); i++)
{
if(IsValidEntity(i))
{
GetEdictClassname(i, strClass, sizeof(strClass));
if((strncmp(strClass, "tf_wearable", 11) == 0 || strncmp(strClass, "tf_powerup", 10) == 0) && GetEntPropEnt(i, Prop_Send, "m_hOwnerEntity") == iClient)
{
SetEntityRenderMode(i, RENDER_TRANSCOLOR);
SetEntityRenderColor(i, 255, 255, 255, (bIsHidden ? 0 : 255));
}
}
}
int iDisguiseWeapon = GetEntPropEnt(iClient, Prop_Send, "m_hDisguiseWeapon");
if(iDisguiseWeapon > MaxClients && IsValidEntity(iDisguiseWeapon))
{
SetEntityRenderMode(iDisguiseWeapon, RENDER_TRANSCOLOR);
SetEntityRenderColor(iDisguiseWeapon, 255, 255, 255, (bIsHidden ? 0 : 255));
}
}
int GetDecaps(int iClient)
{
g_iOffsetDecaps = FindSendPropInfo("CTFPlayer", "m_iDecapitations");
return GetEntData(iClient, g_iOffsetDecaps);
}
public Action Timer_DeleteRagdoll(Handle hTimer, any hClient)
{
DataPack dClient = hClient;
dClient.Reset();
int iClient = GetClientOfUserId(dClient.ReadCell());
int iEntity = EntRefToEntIndex(dClient.ReadCell());
if(iEntity > MaxClients)
{
AcceptEntityInput(iEntity, "Kill");
SetPlayerVisibility(iClient, false);
SetEntityMoveType(iClient, MOVETYPE_WALK);
// Lalalala this is fucking dumb why did i do this it doesn't even work right.
SetClientViewEntity(iClient, iClient);
AcceptEntityInput(iClient, "SetForcedTauntCam", 0);
if(GetDecaps(iClient) > 0 && !TF2_IsPlayerInCondition(iClient, TFCond_DemoBuff))
{
TF2_AddCondition(iClient, TFCond_DemoBuff, 1000.0);
}
}
return Plugin_Handled;
}
Last edited by 404UserNotFound; 04-02-2018 at 13:03.
|
|