___BRAIN___
Участник
- Сообщения
- 13
- Реакции
- 4
C-подобный:
#pragma semicolon 1
#include <sourcemod>
#include <sdktools>
#include <sdkhooks>
#include <clientprefs>
#define PLUGIN_VERSION "1.6_L4D1_Stable"
static Handle:hCvar_TpMode = INVALID_HANDLE;
static Handle:hCvar_TpDefault = INVALID_HANDLE;
static bool:bClientPov[MAXPLAYERS+1] = {true, ...};
static Handle:hCookie_PovPerf = INVALID_HANDLE;
static Handle:hClientDisableView[MAXPLAYERS+1] = {INVALID_HANDLE, ...};
static int iTpMode = 1;
static bool:bTpModeDefault = true;
static int iCamRef[MAXPLAYERS+1];
public Plugin myinfo =
{
name = "ThirdPerson_To_POV",
author = "Lux & BRAIN",
description = "POV on grabs/ledge/tank/healing for L4D1",
version = PLUGIN_VERSION,
url = "https://forums.alliedmods.net/showthread.php?p=2518781"
};
public void OnPluginStart()
{
hCookie_PovPerf = RegClientCookie("tp_to_pov_cookie", "", CookieAccess_Protected);
CreateConVar("thirdperson_to_pov_version", PLUGIN_VERSION, "Version", FCVAR_NOTIFY|FCVAR_SPONLY);
hCvar_TpMode = CreateConVar("tp_pov_mode", "1", "0 = disable, 1 = auto POV on events", FCVAR_NOTIFY, true, 0.0, true, 1.0);
hCvar_TpDefault = CreateConVar("tp_pov_default_mode", "1", "Default mode for new players: 1 = on, 0 = off", FCVAR_NOTIFY, true, 0.0, true, 1.0);
RegConsoleCmd("sm_povoff", PovOff, "Disable auto POV");
RegConsoleCmd("sm_povon", PovOn, "Enable auto POV");
HookEvent("round_start", eRoundStart);
HookEvent("player_death", Event_PlayerDeath);
HookEvent("player_spawn", Event_PlayerSpawn);
HookConVarChange(hCvar_TpMode, eConvarChanged);
HookConVarChange(hCvar_TpDefault, eConvarChanged);
AutoExecConfig(true, "ThirdPerson_To_POV_L4D1_Stable");
CvarsChanged();
}
public void eConvarChanged(Handle hCvar, const char[] sOldVal, const char[] sNewVal)
{
CvarsChanged();
}
void CvarsChanged()
{
iTpMode = GetConVarInt(hCvar_TpMode);
bTpModeDefault = GetConVarInt(hCvar_TpDefault) > 0;
}
public void eRoundStart(Event hEvent, const char[] sEventName, bool bDontBroadcast)
{
for (int i = 1; i <= MaxClients; i++)
{
CancelClientTimer(i);
RemoveCamera(i);
}
}
public void OnClientPutInServer(int client)
{
if (IsFakeClient(client))
return;
SDKHook(client, SDKHook_PostThinkPost, Hook_OnPostThinkPost);
}
public void OnClientDisconnect(int client)
{
CancelClientTimer(client);
RemoveCamera(client);
}
void CancelClientTimer(int client)
{
if (hClientDisableView[client] != INVALID_HANDLE)
{
KillTimer(hClientDisableView[client]);
hClientDisableView[client] = INVALID_HANDLE;
}
}
public void OnClientCookiesCached(int client)
{
if (client < 1 || !IsClientConnected(client))
return;
char sCookie[3];
GetClientCookie(client, hCookie_PovPerf, sCookie, sizeof(sCookie));
if (sCookie[0] == '\0')
{
bClientPov[client] = bTpModeDefault;
}
else
{
bClientPov[client] = (sCookie[0] == '1');
}
}
public void Hook_OnPostThinkPost(int client)
{
if (!AreClientCookiesCached(client))
return;
bool aliveAndTeam = IsPlayerAlive(client) && GetClientTeam(client) == 2;
bool povEnabled = bClientPov[client] && iTpMode != 0;
bool shouldBePov = ShouldBePov(client);
if (aliveAndTeam && povEnabled && shouldBePov)
{
if (!IsValidEntRef(iCamRef[client]))
{
if (!CreateCamera(client))
return;
}
int cam = EntRefToEntIndex(iCamRef[client]);
if (cam != INVALID_ENT_REFERENCE)
{
float eyeAng[3];
GetClientEyeAngles(client, eyeAng);
TeleportEntity(cam, NULL_VECTOR, eyeAng, NULL_VECTOR);
}
EnableCam(client);
if (hClientDisableView[client] != INVALID_HANDLE)
{
KillTimer(hClientDisableView[client]);
hClientDisableView[client] = INVALID_HANDLE;
}
}
else
{
if (IsValidEntRef(iCamRef[client]) && hClientDisableView[client] == INVALID_HANDLE)
{
DisableCam(client);
hClientDisableView[client] = CreateTimer(1.0, Timer_RemoveCamera, GetClientUserId(client), TIMER_FLAG_NO_MAPCHANGE);
}
}
}
public Action Timer_RemoveCamera(Handle timer, int userID)
{
int client = GetClientOfUserId(userID);
if (client == 0)
return Plugin_Stop;
if (IsPlayerAlive(client) && GetClientTeam(client) == 2 && ShouldBePov(client))
{
hClientDisableView[client] = INVALID_HANDLE;
return Plugin_Stop;
}
RemoveCamera(client);
hClientDisableView[client] = INVALID_HANDLE;
return Plugin_Stop;
}
bool CreateCamera(int client)
{
int entity = CreateEntityByName("point_viewcontrol_survivor");
if (entity < 1)
return false;
DispatchSpawn(entity);
SetEntProp(entity, Prop_Data, "m_spawnflags", 72);
ActivateEntity(entity);
int lifeState = GetEntProp(client, Prop_Send, "m_lifeState");
SetEntProp(client, Prop_Send, "m_lifeState", 0);
SetVariantString("!activator");
AcceptEntityInput(entity, "SetParent", client);
SetVariantString("eyes");
AcceptEntityInput(entity, "SetParentAttachment");
SetEntProp(client, Prop_Send, "m_lifeState", lifeState);
float pos[3] = {0.0, 0.0, 0.0};
TeleportEntity(entity, pos, NULL_VECTOR, NULL_VECTOR);
iCamRef[client] = EntIndexToEntRef(entity);
return true;
}
void DisableCam(int client)
{
int cam = EntRefToEntIndex(iCamRef[client]);
if (cam != INVALID_ENT_REFERENCE && IsValidEntity(cam))
{
char classname[32];
GetEntityClassname(cam, classname, sizeof(classname));
if (strcmp(classname, "point_viewcontrol_survivor") == 0 || strcmp(classname, "point_viewcontrol") == 0)
{
AcceptEntityInput(cam, "Disable", client);
}
}
}
void EnableCam(int client)
{
int cam = EntRefToEntIndex(iCamRef[client]);
if (cam != INVALID_ENT_REFERENCE && IsValidEntity(cam))
{
char classname[32];
GetEntityClassname(cam, classname, sizeof(classname));
if (strcmp(classname, "point_viewcontrol_survivor") == 0 || strcmp(classname, "point_viewcontrol") == 0)
{
AcceptEntityInput(cam, "Enable", client);
}
}
}
void RemoveCamera(int client)
{
int cam = EntRefToEntIndex(iCamRef[client]);
if (cam != INVALID_ENT_REFERENCE && IsValidEntity(cam))
{
char classname[32];
GetEntityClassname(cam, classname, sizeof(classname));
if (strcmp(classname, "point_viewcontrol_survivor") == 0 || strcmp(classname, "point_viewcontrol") == 0)
{
AcceptEntityInput(cam, "Disable", client);
AcceptEntityInput(cam, "Kill");
}
}
iCamRef[client] = 0;
}
bool ShouldBePov(int client)
{
if (GetEntPropEnt(client, Prop_Send, "m_pounceAttacker") > 0)
return true;
if (GetEntPropEnt(client, Prop_Send, "m_tongueOwner") > 0)
return true;
if (GetEntProp(client, Prop_Send, "m_isHangingFromTongue") > 0)
return true;
if (GetEntProp(client, Prop_Send, "m_reachedTongueOwner") > 0)
return true;
if (GetEntProp(client, Prop_Send, "m_isHangingFromLedge") > 0)
return true;
if (GetEntPropFloat(client, Prop_Send, "m_staggerTimer", 1) > -1.0)
return true;
if (GetEntProp(client, Prop_Send, "m_usingMedkit") > 0)
return true;
return false;
}
bool IsValidEntRef(int ref)
{
return (ref != 0 && EntRefToEntIndex(ref) != INVALID_ENT_REFERENCE);
}
public void Event_PlayerDeath(Event event, const char[] name, bool dontBroadcast)
{
int client = GetClientOfUserId(event.GetInt("userid"));
if (client && IsValidEntRef(iCamRef[client]))
{
CancelClientTimer(client);
DisableCam(client);
hClientDisableView[client] = CreateTimer(0.5, Timer_RemoveCamera, GetClientUserId(client), TIMER_FLAG_NO_MAPCHANGE);
}
}
public void Event_PlayerSpawn(Event event, const char[] name, bool dontBroadcast)
{
int client = GetClientOfUserId(event.GetInt("userid"));
if (client)
{
CancelClientTimer(client);
RemoveCamera(client);
}
}
public Action PovOff(int client, int args)
{
if (client < 1 || !IsClientInGame(client) || IsFakeClient(client))
return Plugin_Continue;
if (AreClientCookiesCached(client))
SetClientCookie(client, hCookie_PovPerf, "0");
bClientPov[client] = false;
PrintToChat(client, "[POV] Auto mode \x04disabled\x01.");
return Plugin_Continue;
}
public Action PovOn(int client, int args)
{
if (client < 1 || !IsClientInGame(client) || IsFakeClient(client))
return Plugin_Continue;
if (AreClientCookiesCached(client))
SetClientCookie(client, hCookie_PovPerf, "1");
bClientPov[client] = true;
PrintToChat(client, "[POV] Auto mode \x04enabled\x01.");
return Plugin_Continue;
}
Вложения
Последнее редактирование модератором:

