Senior Member
Join Date: Sep 2015
Location: Location:
06-10-2019
, 06:46
[L4D2] Fixing body_yaw when incapped? / Set pose parameters?
#1
Imgur post
Although I couldn't quite manage it correctly, I made the
commentary_dummy parented to Coach look back while incapacitated, thus giving us the impossible sight of a character looking back while incapped in L4D2.
(Also for some reason, the angles for the dummy always stay at 0 even though it's supposed to set them to the client's existing angles already.)
What I planned to do was to make the player's model invisible, parent a dummy model and set that model's pose parameters instead.
(A bug I encountered is that the pose parameters
don't change while active for the dummy.)
The new version with atleast
some functionality is attached below, the old version is in the original description.
Original Description
I attempted to fix it myself, but turns out that setting the pose parameter on a think hook does not appear to work.
For those that don't know, Valve managed to screw it up in-game, so incapacitated survivors face the front when the actual person's looking at the opposite direction.
The pose parameter I found that manipulated the bugged direction is
body_yaw .
Here's some test code that prints out information and is
supposed to set the pose parameter in a debuggy way:
Spoiler
Code:
#define PLUGIN_NAME "[L4D2] Incap Body Yaw Fix"
#define PLUGIN_AUTHOR "Shadowysn"
#define PLUGIN_DESC "W.I.P. Fixes incapped body yaw rotation."
#define PLUGIN_VERSION "1.0"
#define PLUGIN_URL "tobeadded"
#include <sourcemod>
#include <sdktools>
#include <sdkhooks>
#define GAMEDATA "l4d2_incap_yaw_fix"
#define THINK_HOOK SDKHook_PostThinkPost
#define SURVIVORTEAM 2
#define SURVIVORTEAM_PASSING 4
#pragma semicolon 1
#pragma newdecls required
//int body_Yaw[MAXPLAYERS+1] = -1;
//bool is_AnglesChanging[MAXPLAYERS+1] = false;
float old_Angles[MAXPLAYERS+1] = 0.0;
/*Handle hConf = null;
static Handle hGetPoseParameter = null;
#define NAME_GETPOSEPARAMETER "CBaseAnimating::GetPoseParameter"
#define SIG_GETPOSEPARAMETER_LINUX "@_ZN14CBaseAnimating16GetPoseParameterEPKc"
#define SIG_GETPOSEPARAMETER_WINDOWS "\x55\x8B\x2A\x56\x8B\x2A\x83\x2A\x2A\x2A\x2A\x2A\x2A\x75\x2A\xE8\xDC\xAE\x2A\x2A"*/
ConVar version_cvar;
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
{
if(GetEngineVersion() == Engine_Left4Dead2)
{
return APLRes_Success;
}
strcopy(error, err_max, "Plugin only supports Left 4 Dead 2");
return APLRes_SilentFailure;
}
public Plugin myinfo =
{
name = PLUGIN_NAME,
author = PLUGIN_AUTHOR,
description = PLUGIN_DESC,
version = PLUGIN_VERSION,
url = PLUGIN_URL
}
public void OnPluginStart()
{
version_cvar = CreateConVar("sm_l4d2_incapfix_version", PLUGIN_VERSION, "Version of the L4D2 Incap Body-Yaw fix.", 0|FCVAR_NOTIFY|FCVAR_REPLICATED|FCVAR_DONTRECORD);
if(version_cvar != null)
SetConVarString(version_cvar, PLUGIN_VERSION);
/*hConf = LoadGameConfigFile(GAMEDATA);
if (hConf == null)
{
PrintToServer("[SM] L4D Incap Body-Yaw Fix plugin unable to get %i.txt gamedata file. Generating...", GAMEDATA);
char filePath[PLATFORM_MAX_PATH];
BuildPath(Path_SM, filePath, sizeof(filePath), "gamedata/%s.txt", GAMEDATA);
Handle fileHandle = OpenFile(filePath, "a+");
if (fileHandle == null)
{ SetFailState("[SM] Couldn't generate gamedata file!"); }
WriteFileLine(fileHandle, "\"Games\"");
WriteFileLine(fileHandle, "{");
WriteFileLine(fileHandle, " \"left4dead2\"");
WriteFileLine(fileHandle, " {");
WriteFileLine(fileHandle, " \"Signatures\"");
WriteFileLine(fileHandle, " {");
WriteFileLine(fileHandle, " \"%s\"", NAME_GETPOSEPARAMETER);
WriteFileLine(fileHandle, " {");
WriteFileLine(fileHandle, " \"library\" \"server\"");
WriteFileLine(fileHandle, " \"linux\" \"%s\"", SIG_GETPOSEPARAMETER_LINUX);
WriteFileLine(fileHandle, " \"windows\" \"%s\"", SIG_GETPOSEPARAMETER_WINDOWS);
WriteFileLine(fileHandle, " \"mac\" \"%s\"", SIG_GETPOSEPARAMETER_LINUX);
WriteFileLine(fileHandle, " }");
WriteFileLine(fileHandle, " }");
WriteFileLine(fileHandle, " }");
WriteFileLine(fileHandle, "}");
CloseHandle(fileHandle);
hConf = LoadGameConfigFile(GAMEDATA);
if (hConf == null)
{ SetFailState("[SM] Failed to load auto-generated gamedata file!"); }
}
StartPrepSDKCall(SDKCall_Entity);
if (!PrepSDKCall_SetFromConf(hConf, SDKConf_Signature, NAME_GETPOSEPARAMETER))
{
// if (!PrepSDKCall_SetSignature(SDKLibrary_Server, SIG_GETPOSEPARAMETER_LINUX, 42))
// {
// if (!PrepSDKCall_SetSignature(SDKLibrary_Server, SIG_GETPOSEPARAMETER_WINDOWS, 20))
// { SetFailState("[SM] Failed to set %s signature from config + hardcoded cfg!", NAME_GETPOSEPARAMETER); }
// }
SetFailState("[SM] Failed to set %s signature from config + hardcoded cfg!", NAME_GETPOSEPARAMETER);
}
PrepSDKCall_AddParameter(SDKType_String, SDKPass_Pointer);
PrepSDKCall_SetReturnInfo(SDKType_PlainOldData, SDKPass_Plain);
hGetPoseParameter = EndPrepSDKCall();
if (hGetPoseParameter == null)
{ SetFailState("[SM] Can't get %s SDKCall!", NAME_GETPOSEPARAMETER); }*/
HookEvent("player_incapacitated", player_incapacitated, EventHookMode_Post);
}
public void OnPluginEnd()
{
for (int loopclient = 1; loopclient <= MaxClients; loopclient++)
{
if (!IsValidClient(loopclient)) return;
if (!IsSurvivor(loopclient) || !L4D_IsPlayerAlive(loopclient)) return;
HookThink(loopclient, false);
}
}
void HookThink(int client, bool boolean = true)
{
if (!IsValidClient(client)) return;
if (!IsSurvivor(client) || !L4D_IsPlayerAlive(client)) return;
//is_AnglesChanging[client] = false;
if (boolean)
{
SDKHook(client, THINK_HOOK, Hook_OnThinkPost);
}
else
{
SDKUnhook(client, THINK_HOOK, Hook_OnThinkPost);
}
}
void Hook_OnThinkPost(int client) {
if (!IsValidClient(client))
{ HookThink(client, false); }
int GetIsIncap = GetEntProp(client, Prop_Send, "m_isIncapacitated");
if (!IsSurvivor(client) || !L4D_IsPlayerAlive(client) || IsClientObserver(client) || !GetIsIncap)
{ HookThink(client, false); }
float angles[3];
GetClientAbsAngles(client, angles);
/*if (is_AnglesChanging[client] && GetEntProp(client, Prop_Send, "m_hGroundEntity") > 0)
{
is_AnglesChanging[client] = false;
if (angles[1] > old_Angles[client]+90 || angles[1] < old_Angles[client])
{
if (old_Angles[client] <= 0)
old_Angles[client] += 180;
else if (old_Angles[client] > 0)
old_Angles[client] -= 180;
}
}
else if (!is_AnglesChanging[client] && GetEntProp(client, Prop_Send, "m_hGroundEntity") <= 0)
{ is_AnglesChanging[client] = true; }*/
int body_yaw = 1;
//PrintToServer("%i", body_yaw);
if (body_yaw > -1)
{
float old_body_yaw = GetEntPropFloat(client, Prop_Send, "m_flPoseParameter", body_yaw);
PrintToChatAll("body_yaw: %f old_ang: %f angles: %f", old_body_yaw, old_Angles[client], angles[1]);
if (angles[1] > old_Angles[client]+90 || angles[1] < old_Angles[client]-90)
{
PrintToChatAll("Backwards!");
SetEntPropFloat(client, Prop_Send, "m_flPoseParameter", 1.0, body_yaw);
}
}
}
void player_incapacitated(Handle event, const char[] name, bool dontBroadcast)
{
int clientID = GetEventInt(event, "userid");
int client = GetClientOfUserId(clientID);
if (!IsValidClient(client))
{ return; }
int GetIsIncap = GetEntProp(client, Prop_Send, "m_isIncapacitated");
if (!IsSurvivor(client) || !L4D_IsPlayerAlive(client) || !GetIsIncap)
{ return; }
//body_Yaw[client] = SDKCall(hGetPoseParameter, client, "body_yaw");
//PrintToServer("%i", body_Yaw[client]);
float angles[3];
GetClientAbsAngles(client, angles);
old_Angles[client] = angles[1];
HookThink(client);
}
bool L4D_IsPlayerAlive(int client)
{
if (!IsValidClient(client)) return false;
if (IsPlayerAlive(client) || GetEntProp(client, Prop_Send, "m_lifeState") != 1) return true;
return false;
}
bool IsSurvivor(int client)
{
if (!IsValidClient(client)) return false;
if (GetClientTeam(client) == SURVIVORTEAM || GetClientTeam(client) == SURVIVORTEAM_PASSING) return true;
return false;
}
bool IsValidClient(int client, bool replaycheck = true)
//IsValidClient(client)
{
if (!IsValidEntity(client)) return false;
if (client <= 0 || client > MaxClients) return false;
if (!IsClientInGame(client)) return false;
//if (GetEntProp(client, Prop_Send, "m_bIsCoaching")) return false;
if (replaycheck)
{
if (IsClientSourceTV(client) || IsClientReplay(client)) return false;
}
return true;
}
__________________
Last edited by Shadowysn; 01-22-2020 at 01:33 .