-329 Removals
+275 Additions
#pragma semicolon 1#pragma semicolon 1
#include <sourcemod>
#include <sdktools>
#include <sdkhooks>
#define DEBUG#define DEBUG
#define PLUGIN_AUTHOR "DeathChaos25"static const String:MODEL_NICK[] = "models/survivors/survivor_gambler.mdl";
#define PLUGIN_VERSION "1.00"static const String:MODEL_ROCHELLE[] = "models/survivors/survivor_producer.mdl";
static const String:MODEL_COACH[] = "models/survivors/survivor_coach.mdl";
static const String:MODEL_NICK_LEGS[] = "models/survivors/survivor_gambler_legs.mdl";static const String:MODEL_ELLIS[] = "models/survivors/survivor_mechanic.mdl";
static const String:MODEL_ROCHELLE_LEGS[] = "models/survivors/survivor_producer_legs.mdl";static const String:MODEL_BILL[] = "models/survivors/survivor_namvet.mdl";
static const String:MODEL_COACH_LEGS[] = "models/survivors/survivor_coach_legs.mdl";static const String:MODEL_ZOEY[] = "models/survivors/survivor_teenangst.mdl";
static const String:MODEL_ELLIS_LEGS[] = "models/survivors/survivor_mechanic_legs.mdl";static const String:MODEL_FRANCIS[] = "models/survivors/survivor_biker.mdl";
static const String:MODEL_BILL_LEGS[] = "models/survivors/survivor_namvet_legs.mdl";static const String:MODEL_LOUIS[] = "models/survivors/survivor_manager.mdl";
static const String:MODEL_ZOEY_LEGS[] = "models/survivors/survivor_teenangst_legs.mdl";
static const String:MODEL_FRANCIS_LEGS[] = "models/survivors/survivor_biker_legs.mdl";
static const String:MODEL_LOUIS_LEGS[] = "models/survivors/survivor_manager_legs.mdl";
static PreviousAnimation[MAXPLAYERS + 1] = -1;static PreviousAnimation[MAXPLAYERS + 1] = -1;
static CloneModel[MAXPLAYERS + 1] = -1;static CloneModel[MAXPLAYERS + 1] = -1;
static CloneProp[MAXPLAYERS + 1] = -1;
static bool:ThirdPerson[MAXPLAYERS + 1] = false;static bool:ThirdPerson[MAXPLAYERS + 1] = false;
new PropOff_nSequence;new PropOff_nSequence;
new Handle:hSequenceSet;public Plugin myinfo =
static clienthook[MAXPLAYERS + 1] = -1;
#include <sourcemod>
#include <sdktools>
#include <sdkhooks>
#include <dhooks>
public Plugin myinfo =
{{
name = "[L4D2] Clone", name = "[L4D2] View Legs",
author = PLUGIN_AUTHOR, author = "[†×Ą]AYA SUPAY[Ļ×Ø]/DeathChaos",
description = "", description = "Show legs in first person",
version = PLUGIN_VERSION, version = "1.0",
url = "" url = "http://steamcommunity.com/id/AyaSupay/"
};};
public void OnPluginStart()public void OnPluginStart()
{{
PropOff_nSequence = FindSendPropInfo("CTerrorPlayer", "m_nSequence"); PropOff_nSequence = FindSendPropInfo("CTerrorPlayer", "m_nSequence");
CreateTimer(GetRandomFloat(0.1, 0.3), CheckClients, _, TIMER_REPEAT); CreateTimer(GetRandomFloat(0.1, 0.3), CheckClients, _, TIMER_REPEAT);
RegConsoleCmd("sm_view", ViewAngles); RegConsoleCmd("sm_view", ViewAngles);
RegConsoleCmd("sm_ang", ChangeAngles); RegConsoleCmd("sm_ang", ChangeAngles);
RegConsoleCmd("sm_pos", ChangePosition); RegConsoleCmd("sm_pos", ChangePosition);
LoadOffset();
}
public OnPluginEnd()
{
for (new i = 0; i <= MAXPLAYERS; i++)
{
if (CloneProp[i] > 0)
{
AcceptEntityInput(CloneProp[i], "Kill");
}
if (CloneModel[i] > 0)
{
AcceptEntityInput(CloneModel[i], "Kill");
}
}
}}
public OnMapStart()public OnMapStart()
{{
CheckModelPreCache(MODEL_NICK_LEGS); CheckModelPreCache(MODEL_NICK);
CheckModelPreCache(MODEL_ROCHELLE_LEGS); CheckModelPreCache(MODEL_ROCHELLE);
CheckModelPreCache(MODEL_COACH_LEGS); CheckModelPreCache(MODEL_COACH);
CheckModelPreCache(MODEL_ELLIS_LEGS); CheckModelPreCache(MODEL_ELLIS);
CheckModelPreCache(MODEL_BILL_LEGS); CheckModelPreCache(MODEL_BILL);
CheckModelPreCache(MODEL_ZOEY_LEGS); CheckModelPreCache(MODEL_ZOEY);
CheckModelPreCache(MODEL_FRANCIS_LEGS); CheckModelPreCache(MODEL_FRANCIS);
CheckModelPreCache(MODEL_LOUIS_LEGS); CheckModelPreCache(MODEL_LOUIS);
}}
stock CheckModelPreCache(const String:Modelfile[])stock CheckModelPreCache(const String:Modelfile[])
{{
if (!IsModelPrecached(Modelfile)) if (!IsModelPrecached(Modelfile))
{ {
PrecacheModel(Modelfile, true); PrecacheModel(Modelfile, true);
PrintToServer("Precaching Model:%s", Modelfile); PrintToServer("Precaching Model:%s", Modelfile);
} }
}}
public void OnGameFrame()
public MRESReturn:OnSequenceSet(pThis, Handle:hReturn, Handle:hParams)
{{
new client = pThis; for (new client = 1; client <= MaxClients; client++)
if (IsSurvivor(client) && IsPlayerAlive(client) && !IsPlayerHeld(client) && !IsFakeClient(client)) {
{ if (IsSurvivor(client) && !IsFakeClient(client) && IsPlayerAlive(client))
new sequence = DHookGetReturn(hReturn); {
new sequence = GetEntData(client, PropOff_nSequence);
/*if (CloneProp[client] > 0 && IsValidEntity(CloneProp[client])) if (CloneModel[client] <= 0 || !IsValidEntity(CloneModel[client]))
{ {
new Float:Origin[3], Float:Angle[3]; new clone = CreateEntityByName("prop_dynamic_override");
GetClientAbsOrigin(client, Origin); decl String:model[64];
GetClientAbsAngles(client, Angle); GetEntPropString(client, Prop_Data, "m_ModelName", model, sizeof(model));
TeleportEntity(CloneProp[client], Origin, Angle, NULL_VECTOR); if (StrContains(model, "gambler", false) != -1)
}*/ {
if (CloneModel[client] <= 0 || !IsValidEntity(CloneModel[client])) SetEntityModel(clone, MODEL_NICK);
{ }
new clone = CreateEntityByName("prop_dynamic_override"); else if (StrContains(model, "coach", false) != -1)
decl String:model[64]; {
GetEntPropString(client, Prop_Data, "m_ModelName", model, sizeof(model)); SetEntityModel(clone, MODEL_COACH);
if (StrContains(model, "gambler", false) != -1) }
{ else if (StrContains(model, "producer", false) != -1)
SetEntityModel(clone, MODEL_NICK_LEGS); {
} SetEntityModel(clone, MODEL_ROCHELLE);
else if (StrContains(model, "coach", false) != -1) }
{ else if (StrContains(model, "mechanic", false) != -1)
SetEntityModel(clone, MODEL_COACH_LEGS); {
} SetEntityModel(clone, MODEL_ELLIS);
else if (StrContains(model, "producer", false) != -1) }
{ else if (StrContains(model, "namvet", false) != -1)
SetEntityModel(clone, MODEL_ROCHELLE_LEGS); {
} SetEntityModel(clone, MODEL_BILL);
else if (StrContains(model, "mechanic", false) != -1) }
{ else if (StrContains(model, "teenangst", false) != -1)
SetEntityModel(clone, MODEL_ELLIS_LEGS); {
} SetEntityModel(clone, MODEL_ZOEY);
else if (StrContains(model, "namvet", false) != -1) }
{ else if (StrContains(model, "biker", false) != -1)
SetEntityModel(clone, MODEL_BILL_LEGS); {
} SetEntityModel(clone, MODEL_FRANCIS);
else if (StrContains(model, "teenangst", false) != -1) }
{ else if (StrContains(model, "manager", false) != -1)
SetEntityModel(clone, MODEL_ZOEY_LEGS); {
} SetEntityModel(clone, MODEL_LOUIS);
else if (StrContains(model, "biker", false) != -1) }
{ else
SetEntityModel(clone, MODEL_FRANCIS_LEGS); {
} AcceptEntityInput(clone, "Kill");
else if (StrContains(model, "manager", false) != -1) LogError("Player Model %s is not supported!", model);
{ }
SetEntityModel(clone, MODEL_LOUIS_LEGS); decl Float:vAngles[3];
} decl Float:vOrigin[3];
else GetClientAbsOrigin(client, vOrigin);
{ GetClientAbsAngles(client, vAngles);
AcceptEntityInput(clone, "Kill");
LogError("Player Model %s is not supported!", model); SetEntProp(clone, Prop_Data, "m_CollisionGroup", 2);
} decl String:sTemp[16];
decl Float:vAngles[3]; Format(sTemp, sizeof(sTemp), "target%d", client);
decl Float:vOrigin[3]; DispatchKeyValue(client, "targetname", sTemp);
GetClientAbsOrigin(client, vOrigin); SetVariantString(sTemp);
GetClientAbsAngles(client, vAngles); AcceptEntityInput(clone, "SetParent", clone, clone, 0);
SetEntProp(clone, Prop_Data, "m_CollisionGroup", 2); SetVariantString("bleedout");
decl String:sTemp[16]; AcceptEntityInput(clone, "SetParentAttachment");
Format(sTemp, sizeof(sTemp), "target%d", client);
DispatchKeyValue(client, "targetname", sTemp); SetEntPropFloat(clone, Prop_Send, "m_flPlaybackRate", GetEntPropFloat(client, Prop_Send, "m_flPlaybackRate"));
SetVariantString(sTemp); SetEntData(clone, PropOff_nSequence, sequence);
AcceptEntityInput(clone, "SetParent", clone, clone, 0);
CloneModel[client] = clone;
SetVariantString("bleedout"); //ang -80 0 -90
AcceptEntityInput(clone, "SetParentAttachment"); //pos -10 -40 -20
new Float:pos[3], Float:ang[3];
SetEntPropFloat(clone, Prop_Send, "m_flPlaybackRate", GetEntPropFloat(client, Prop_Send, "m_flPlaybackRate")); ang[0] = -80.0;
SetEntData(clone, PropOff_nSequence, sequence); ang[1] = 0.0;
ang[2] = -90.0;
CloneModel[client] = clone;
//ang -80 0 -90 pos[0] = -10.0;
//pos -10 -40 -20 pos[1] = -40.0;
new Float:pos[3], Float:ang[3]; pos[2] = -20.0;
ang[0] = -80.0; TeleportEntity(CloneModel[client], pos, ang, NULL_VECTOR);
ang[1] = 0.0; SDKHook(clone, SDKHook_SetTransmit, Hook_SetTransmit);
ang[2] = -90.0; }
pos[0] = -10.0; if (!PreviousAnimation[client])
pos[1] = -40.0; {
pos[2] = -20.0; PreviousAnimation[client] = sequence;
TeleportEntity(CloneModel[client], pos, ang, NULL_VECTOR); }
SDKHook(clone, SDKHook_SetTransmit, Hook_SetTransmit); else if (PreviousAnimation[client] != sequence && PreviousAnimation[client] > 0)
} {
new Float:angs[3];
else if (PreviousAnimation[client] != sequence) GetEntPropVector(client, Prop_Send, "m_angRotation", angs);
{ SetEntPropFloat(CloneModel[client], Prop_Send, "m_flPlaybackRate", GetEntPropFloat(client, Prop_Send, "m_flPlaybackRate"));
SetEntPropFloat(CloneModel[client], Prop_Send, "m_flPlaybackRate", GetEntPropFloat(client, Prop_Send, "m_flPlaybackRate")); SetEntData(CloneModel[client], PropOff_nSequence, sequence);
SetEntData(CloneModel[client], PropOff_nSequence, sequence); for (new i = 0; i < 92; i += 4)
for (new i = 0; i < 92; i += 4) {
{ new prop = FindSendPropInfo("CTerrorPlayer", "m_flPoseParameter");
new prop = FindSendPropInfo("CTerrorPlayer", "m_flPoseParameter"); new prop2 = FindSendPropInfo("CDynamicProp", "m_flPoseParameter");
new prop2 = FindSendPropInfo("CDynamicProp", "m_flPoseParameter"); new value = GetEntData(client, prop + (i));
new value = GetEntData(client, prop + (i));
SetEntData(CloneModel[client], prop2 + (i), value);
SetEntData(CloneModel[client], prop2 + (i), value); }
} SetEntPropFloat(CloneModel[client], Prop_Send, "m_flCycle", GetEntPropFloat(client, Prop_Send, "m_flCycle"));
SetEntPropFloat(CloneModel[client], Prop_Send, "m_flCycle", GetEntPropFloat(client, Prop_Send, "m_flCycle")); }
} }
} }
return MRES_Ignored;
}}
LoadOffset()
{
new Handle:temp = LoadGameConfigFile("l4d2_sequence");
if (temp == INVALID_HANDLE)
{
SetFailState("Error: Gamedata not found");
}
new offset;
offset = GameConfGetOffset(temp, "CTerrorPlayer::SelectWeightedSequence");
if (offset == -1)
{
CloseHandle(temp);
LogError("Unable to get offset for CTerrorPlayer::SelectWeightedSequence");
return;
}
hSequenceSet = DHookCreate(offset, HookType_Entity, ReturnType_Int, ThisPointer_CBaseEntity, OnSequenceSet);
DHookAddParam(hSequenceSet, HookParamType_Int);
}
stock bool:IsSurvivor(client)stock bool:IsSurvivor(client)
{{
return client > 0 && client <= MaxClients && IsClientInGame(client) && GetClientTeam(client) == 2; return client > 0 && client <= MaxClients && IsClientInGame(client) && GetClientTeam(client) == 2;
}}
SetVector(Float:target[3], Float:x, Float:y, Float:z)SetVector(Float:target[3], Float:x, Float:y, Float:z)
{{
target[0] = x; target[0] = x;
target[1] = y; target[1] = y;
target[2] = z; target[2] = z;
}}
public Action:ViewAngles(client, args)public Action:ViewAngles(client, args)
{{
new Float:angles[3]; new Float:angles[3];
GetEntPropVector(CloneModel[client], Prop_Send, "m_vecAngles", angles); GetEntPropVector(CloneModel[client], Prop_Send, "m_vecAngles", angles);
PrintToChatAll("%f %f %f", angles[0], angles[1], angles[2]); PrintToChatAll("%f %f %f", angles[0], angles[1], angles[2]);
}}
public Action:ChangeAngles(client, args)public Action:ChangeAngles(client, args)
{{
new String:buffer[32]; new String:buffer[32];
new Float:x, Float:y, Float:z, Float:ang[3]; new Float:x, Float:y, Float:z, Float:ang[3];
GetCmdArg(1, buffer, sizeof(buffer)); GetCmdArg(1, buffer, sizeof(buffer));
x = StringToFloat(buffer); x = StringToFloat(buffer);
GetCmdArg(2, buffer, sizeof(buffer)); GetCmdArg(2, buffer, sizeof(buffer));
y = StringToFloat(buffer); y = StringToFloat(buffer);
GetCmdArg(3, buffer, sizeof(buffer)); GetCmdArg(3, buffer, sizeof(buffer));
z = StringToFloat(buffer); z = StringToFloat(buffer);
SetVector(ang, x, y, z); SetVector(ang, x, y, z);
if (CloneModel[client] > 0 && IsValidEntS(CloneModel[client], "prop_dynamic_override")) if (CloneModel[client] > 0 && IsValidEntS(CloneModel[client], "prop_dynamic_override"))
{ {
TeleportEntity(CloneModel[client], NULL_VECTOR, ang, NULL_VECTOR); TeleportEntity(CloneModel[client], NULL_VECTOR, ang, NULL_VECTOR);
} }
}}
public Action:ChangePosition(client, args)public Action:ChangePosition(client, args)
{{
new String:buffer[32]; new String:buffer[32];
new Float:x, Float:y, Float:z, Float:ang[3]; new Float:x, Float:y, Float:z, Float:ang[3];
GetCmdArg(1, buffer, sizeof(buffer)); GetCmdArg(1, buffer, sizeof(buffer));
x = StringToFloat(buffer); x = StringToFloat(buffer);
GetCmdArg(2, buffer, sizeof(buffer)); GetCmdArg(2, buffer, sizeof(buffer));
y = StringToFloat(buffer); y = StringToFloat(buffer);
GetCmdArg(3, buffer, sizeof(buffer)); GetCmdArg(3, buffer, sizeof(buffer));
z = StringToFloat(buffer); z = StringToFloat(buffer);
SetVector(ang, x, y, z); SetVector(ang, x, y, z);
if (CloneModel[client] > 0 && IsValidEntS(CloneModel[client], "prop_dynamic_override")) if (CloneModel[client] > 0 && IsValidEntS(CloneModel[client], "prop_dynamic_override"))
{ {
TeleportEntity(CloneModel[client], ang, NULL_VECTOR, NULL_VECTOR); TeleportEntity(CloneModel[client], ang, NULL_VECTOR, NULL_VECTOR);
} }
}}
IsValidEntS(ent, String:classname[64])IsValidEntS(ent, String:classname[64])
{{
if (IsValidEnt(ent)) if (IsValidEnt(ent))
{ {
decl String:name[64]; decl String:name[64];
GetEdictClassname(ent, name, 64); GetEdictClassname(ent, name, 64);
if (StrEqual(classname, name)) if (StrEqual(classname, name))
{ {
return true; return true;
} }
} }
return false; return false;
}}
IsValidEnt(ent)IsValidEnt(ent)
{{
if (ent > 0 && IsValidEdict(ent) && IsValidEntity(ent)) if (ent > 0 && IsValidEdict(ent) && IsValidEntity(ent))
{ {
return true; return true;
} }
return false; return false;
}}
public Action:Hook_SetTransmit(entity, client)public Action:Hook_SetTransmit(entity, client)
{{
if (!IsSurvivor(client)) if(!IsSurvivor(client))
{ {
return Plugin_Handled; return Plugin_Handled;
} }
if (entity != CloneModel[client] || GetEntPropFloat(client, Prop_Send, "m_TimeForceExternalView") > 0.0 if (entity != CloneModel[client] || GetEntPropFloat(client, Prop_Send, "m_TimeForceExternalView") > 0.0
|| GetEntProp(client, Prop_Send, "m_isHangingFromLedge") == 1 || IsPlayerHeld(client) || IsIncapacitated(client) || ThirdPerson[client]) || GetEntProp(client, Prop_Send, "m_isHangingFromLedge") == 1 || IsPlayerHeld(client) || IsIncapacitated(client) || ThirdPerson[client])
{ {
return Plugin_Handled; return Plugin_Handled;
} }
return Plugin_Continue; return Plugin_Continue;
}}
stock bool:IsPlayerHeld(client)stock bool:IsPlayerHeld(client)
{{
new jockey = GetEntPropEnt(client, Prop_Send, "m_jockeyAttacker"); new jockey = GetEntPropEnt(client, Prop_Send, "m_jockeyAttacker");
new charger = GetEntPropEnt(client, Prop_Send, "m_pummelAttacker"); new charger = GetEntPropEnt(client, Prop_Send, "m_pummelAttacker");
new hunter = GetEntPropEnt(client, Prop_Send, "m_pounceAttacker"); new hunter = GetEntPropEnt(client, Prop_Send, "m_pounceAttacker");
new smoker = GetEntPropEnt(client, Prop_Send, "m_tongueOwner"); new smoker = GetEntPropEnt(client, Prop_Send, "m_tongueOwner");
if (jockey > 0 || charger > 0 || hunter > 0 || smoker > 0) if (jockey > 0 || charger > 0 || hunter > 0 || smoker > 0)
{ {
return true; return true;
} }
return false; return false;
}}
stock bool:IsIncapacitated(client)stock bool:IsIncapacitated(client)
{{
if (GetEntProp(client, Prop_Send, "m_isIncapacitated", 1) > 0) if (GetEntProp(client, Prop_Send, "m_isIncapacitated", 1) > 0)
return true; return true;
return false; return false;
}}
public Action:CheckClients(Handle:timer)public Action:CheckClients(Handle:timer)
{{
for (new iClientIndex = 1; iClientIndex <= MaxClients; iClientIndex++) for (new iClientIndex = 1; iClientIndex <= MaxClients; iClientIndex++)
{ {
if (IsClientInGame(iClientIndex) && !IsFakeClient(iClientIndex)) if (IsClientInGame(iClientIndex) && !IsFakeClient(iClientIndex))
{ {
if (GetClientTeam(iClientIndex) == 2 || GetClientTeam(iClientIndex) == 3) // Only query clients on survivor or infected team, ignore spectators. if (GetClientTeam(iClientIndex) == 2 || GetClientTeam(iClientIndex) == 3) // Only query clients on survivor or infected team, ignore spectators.
{ {
QueryClientConVar(iClientIndex, "c_thirdpersonshoulder", QueryClientConVarCallback); QueryClientConVar(iClientIndex, "c_thirdpersonshoulder", QueryClientConVarCallback);
} }
} }
} }
}}
public QueryClientConVarCallback(QueryCookie:cookie, client, ConVarQueryResult:result, const String:cvarName[], const String:cvarValue[])public QueryClientConVarCallback(QueryCookie:cookie, client, ConVarQueryResult:result, const String:cvarName[], const String:cvarValue[])
{{
if (IsClientInGame(client) && !IsClientInKickQueue(client)) if (IsClientInGame(client) && !IsClientInKickQueue(client))
{ {
if (result != ConVarQuery_Okay) if (result != ConVarQuery_Okay)
{ {
ThirdPerson[client] = true; ThirdPerson[client] = true;
} }
else if (!StrEqual(cvarValue, "false") && !StrEqual(cvarValue, "0")) else if (!StrEqual(cvarValue, "false") && !StrEqual(cvarValue, "0"))
{ {
ThirdPerson[client] = true; ThirdPerson[client] = true;
} }
else ThirdPerson[client] = false; else ThirdPerson[client] = false;
} }
}}
public OnAllPluginsLoaded() //late loading
{
for (new client = 1; client <= MaxClients; client++)
{
if (IsSurvivor(client))
{
clienthook[client] = DHookEntity(hSequenceSet, true, client);
}
}
}
public OnClientPutInServer(client)
{
clienthook[client] = DHookEntity(hSequenceSet, true, client);
}
Editor
Original Text
Changed Text