PlayerVisibility: Improved and fixed bugs.
This commit is contained in:
parent
34e17ed6d2
commit
69c13e42bb
@ -1,6 +1,9 @@
|
||||
#include <sourcemod>
|
||||
#include <sdkhooks>
|
||||
#include <dhooks>
|
||||
#undef REQUIRE_PLUGIN
|
||||
#include <zombiereloaded>
|
||||
#define REQUIRE_PLUGIN
|
||||
|
||||
#pragma semicolon 1
|
||||
#pragma newdecls required
|
||||
@ -10,22 +13,45 @@ public Plugin myinfo =
|
||||
name = "PlayerVisibility",
|
||||
author = "BotoX",
|
||||
description = "Fades players away when you get close to them.",
|
||||
version = "1.1",
|
||||
version = "1.2",
|
||||
url = ""
|
||||
};
|
||||
|
||||
// bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator, CBaseEntity *pCaller, variant_t Value, int outputID )
|
||||
Handle g_hAcceptInput;
|
||||
|
||||
ConVar g_CVar_MaxDistance;
|
||||
ConVar g_CVar_MinFactor;
|
||||
ConVar g_CVar_MinAlpha;
|
||||
ConVar g_CVar_MinPlayers;
|
||||
|
||||
float g_fMaxDistance;
|
||||
float g_fMinFactor;
|
||||
float g_fMinAlpha;
|
||||
int g_iMinPlayers;
|
||||
|
||||
int g_Client_Alpha[MAXPLAYERS + 1] = {255, ...};
|
||||
bool g_Client_bEnabled[MAXPLAYERS + 1] = {false, ...};
|
||||
|
||||
public void OnPluginStart()
|
||||
{
|
||||
Handle hGameConf = LoadGameConfigFile("sdktools.games");
|
||||
if(hGameConf == INVALID_HANDLE)
|
||||
{
|
||||
SetFailState("Couldn't load sdktools game config!");
|
||||
return;
|
||||
}
|
||||
|
||||
int Offset = GameConfGetOffset(hGameConf, "AcceptInput");
|
||||
g_hAcceptInput = DHookCreate(Offset, HookType_Entity, ReturnType_Bool, ThisPointer_CBaseEntity, AcceptInput);
|
||||
DHookAddParam(g_hAcceptInput, HookParamType_CharPtr);
|
||||
DHookAddParam(g_hAcceptInput, HookParamType_CBaseEntity);
|
||||
DHookAddParam(g_hAcceptInput, HookParamType_CBaseEntity);
|
||||
DHookAddParam(g_hAcceptInput, HookParamType_Object, 20, DHookPass_ByVal|DHookPass_ODTOR|DHookPass_OCTOR|DHookPass_OASSIGNOP); //varaint_t is a union of 12 (float[3]) plus two int type params 12 + 8 = 20
|
||||
DHookAddParam(g_hAcceptInput, HookParamType_Int);
|
||||
|
||||
CloseHandle(hGameConf);
|
||||
|
||||
g_CVar_MaxDistance = CreateConVar("sm_pvis_maxdistance", "100.0", "Distance at which models stop fading.", 0, true, 0.0);
|
||||
g_fMaxDistance = g_CVar_MaxDistance.FloatValue;
|
||||
g_CVar_MaxDistance.AddChangeHook(OnConVarChanged);
|
||||
@ -38,13 +64,31 @@ public void OnPluginStart()
|
||||
g_fMinAlpha = g_CVar_MinAlpha.FloatValue;
|
||||
g_CVar_MinAlpha.AddChangeHook(OnConVarChanged);
|
||||
|
||||
g_CVar_MinPlayers = CreateConVar("sm_pvis_minplayers", "3.0", "Minimum players within distance to enable fading.", 0, true, 0.0, true, 255.0);
|
||||
g_iMinPlayers = g_CVar_MinPlayers.IntValue;
|
||||
g_CVar_MinPlayers.AddChangeHook(OnConVarChanged);
|
||||
|
||||
AutoExecConfig(true, "plugin.PlayerVisibility");
|
||||
|
||||
HookEvent("player_spawn", Event_Spawn, EventHookMode_Post);
|
||||
|
||||
for(int client = 1; client <= MaxClients; client++)
|
||||
{
|
||||
if(IsClientInGame(client))
|
||||
OnClientPutInServer(client);
|
||||
}
|
||||
}
|
||||
|
||||
AutoExecConfig(true, "plugin.PlayerVisibility");
|
||||
public void OnPluginEnd()
|
||||
{
|
||||
for(int client = 1; client <= MaxClients; client++)
|
||||
{
|
||||
if(IsClientInGame(client))
|
||||
{
|
||||
if(g_Client_bEnabled[client] && g_Client_Alpha[client] != 255.0)
|
||||
SetEntityRenderMode(client, RENDER_NORMAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
|
||||
@ -57,72 +101,151 @@ public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] n
|
||||
|
||||
else if(convar == g_CVar_MinAlpha)
|
||||
g_fMinAlpha = g_CVar_MinAlpha.FloatValue;
|
||||
}
|
||||
|
||||
public void OnPluginEnd()
|
||||
{
|
||||
for(int client = 1; client <= MaxClients; client++)
|
||||
{
|
||||
if(IsClientInGame(client))
|
||||
{
|
||||
if(g_Client_Alpha[client] != 255.0)
|
||||
SetEntityRenderMode(client, RENDER_NORMAL);
|
||||
|
||||
OnClientDisconnect(client);
|
||||
}
|
||||
}
|
||||
else if(convar == g_CVar_MinPlayers)
|
||||
g_iMinPlayers = g_CVar_MinPlayers.IntValue;
|
||||
}
|
||||
|
||||
public void OnClientPutInServer(int client)
|
||||
{
|
||||
g_Client_Alpha[client] = 255;
|
||||
g_Client_bEnabled[client] = true;
|
||||
|
||||
SDKHook(client, SDKHook_PostThinkPost, OnPostThinkPost);
|
||||
DHookEntity(g_hAcceptInput, false, client);
|
||||
}
|
||||
|
||||
public void OnClientDisconnect(int client)
|
||||
// bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator, CBaseEntity *pCaller, variant_t Value, int outputID )
|
||||
public MRESReturn AcceptInput(int pThis, Handle hReturn, Handle hParams)
|
||||
{
|
||||
// Should not happen?
|
||||
if(DHookIsNullParam(hParams, 2))
|
||||
return MRES_Ignored;
|
||||
|
||||
int client = DHookGetParam(hParams, 2);
|
||||
|
||||
if(!g_Client_bEnabled[client])
|
||||
return MRES_Ignored;
|
||||
|
||||
char szInputName[32];
|
||||
DHookGetParamString(hParams, 1, szInputName, sizeof(szInputName));
|
||||
|
||||
if(!StrEqual(szInputName, "addoutput", false))
|
||||
return MRES_Ignored;
|
||||
|
||||
char sValue[128];
|
||||
DHookGetParamObjectPtrString(hParams, 4, 0, ObjectValueType_String, sValue, sizeof(sValue));
|
||||
int iValueLen = strlen(sValue);
|
||||
|
||||
int aArgs[4] = {0, ...};
|
||||
int iArgs = 0;
|
||||
bool bFound = false;
|
||||
|
||||
for(int i = 0; i < iValueLen; i++)
|
||||
{
|
||||
if(sValue[i] == ' ')
|
||||
{
|
||||
if(bFound)
|
||||
{
|
||||
sValue[i] = '\0';
|
||||
bFound = false;
|
||||
|
||||
if(iArgs > sizeof(aArgs))
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!bFound)
|
||||
{
|
||||
aArgs[iArgs++] = i;
|
||||
bFound = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(StrEqual(szInputName, "addoutput", false))
|
||||
{
|
||||
if(StrEqual(sValue[aArgs[0]], "rendermode", false))
|
||||
{
|
||||
RenderMode renderMode = view_as<RenderMode>(StringToInt(sValue[aArgs[1]]) & 0xFF);
|
||||
if(renderMode == RENDER_ENVIRONMENTAL)
|
||||
{
|
||||
ToolsSetEntityAlpha(client, 255);
|
||||
g_Client_Alpha[client] = 255;
|
||||
g_Client_bEnabled[client] = false;
|
||||
}
|
||||
else
|
||||
g_Client_bEnabled[client] = true;
|
||||
}
|
||||
else if(StrEqual(sValue[aArgs[0]], "renderfx", false))
|
||||
{
|
||||
RenderFx renderFx = view_as<RenderFx>(StringToInt(sValue[aArgs[1]]) & 0xFF);
|
||||
if(renderFx != RENDERFX_NONE)
|
||||
{
|
||||
ToolsSetEntityAlpha(client, 255);
|
||||
g_Client_Alpha[client] = 255;
|
||||
g_Client_bEnabled[client] = false;
|
||||
}
|
||||
else
|
||||
g_Client_bEnabled[client] = true;
|
||||
}
|
||||
}
|
||||
else if(StrEqual(szInputName, "alpha", false))
|
||||
{
|
||||
int iAlpha = StringToInt(sValue[aArgs[0]]) & 0xFF;
|
||||
if(iAlpha == 0)
|
||||
{
|
||||
ToolsSetEntityAlpha(client, 255);
|
||||
g_Client_Alpha[client] = 255;
|
||||
g_Client_bEnabled[client] = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_Client_bEnabled[client] = true;
|
||||
return MRES_Supercede;
|
||||
}
|
||||
}
|
||||
|
||||
return MRES_Ignored;
|
||||
}
|
||||
|
||||
public void Event_Spawn(Event event, const char[] name, bool dontBroadcast)
|
||||
{
|
||||
int client = GetClientOfUserId(GetEventInt(event, "userid"));
|
||||
if(!client)
|
||||
return;
|
||||
|
||||
CreateTimer(0.1, Timer_SpawnPost, client, TIMER_FLAG_NO_MAPCHANGE);
|
||||
}
|
||||
|
||||
Action Timer_SpawnPost(Handle timer, int client)
|
||||
{
|
||||
ToolsSetEntityAlpha(client, 255);
|
||||
g_Client_Alpha[client] = 255;
|
||||
SDKUnhook(client, SDKHook_PostThinkPost, OnPostThinkPost);
|
||||
g_Client_bEnabled[client] = true;
|
||||
return Plugin_Stop;
|
||||
}
|
||||
|
||||
public void ZR_OnClientInfected(int client, int attacker, bool motherInfect, bool respawnOverride, bool respawn)
|
||||
{
|
||||
ToolsSetEntityAlpha(client, 255);
|
||||
g_Client_Alpha[client] = 255;
|
||||
g_Client_bEnabled[client] = false;
|
||||
}
|
||||
|
||||
public void ZR_OnClientHumanPost(int client, bool respawn, bool protect)
|
||||
{
|
||||
ToolsSetEntityAlpha(client, 255);
|
||||
g_Client_Alpha[client] = 255;
|
||||
g_Client_bEnabled[client] = true;
|
||||
}
|
||||
|
||||
public void OnPostThinkPost(int client)
|
||||
{
|
||||
if(!IsPlayerAlive(client))
|
||||
{
|
||||
if(g_Client_Alpha[client] != 255)
|
||||
{
|
||||
g_Client_Alpha[client] = 255;
|
||||
ToolsSetEntityAlpha(client, 255);
|
||||
}
|
||||
if(!g_Client_bEnabled[client])
|
||||
return;
|
||||
}
|
||||
|
||||
if(GetEntityRenderMode(client) == RENDER_NONE ||
|
||||
GetEntityRenderMode(client) == RENDER_ENVIRONMENTAL ||
|
||||
GetEntityRenderFx(client) != RENDERFX_NONE)
|
||||
{
|
||||
g_Client_Alpha[client] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
int aColor[4];
|
||||
ToolsGetEntityColor(client, aColor);
|
||||
if(!aColor[3])
|
||||
{
|
||||
g_Client_Alpha[client] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if(!ZR_IsClientHuman(client))
|
||||
{
|
||||
if(g_Client_Alpha[client] != 255)
|
||||
{
|
||||
g_Client_Alpha[client] = 255;
|
||||
ToolsSetEntityAlpha(client, 255);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int PlayersInRange = 0;
|
||||
float fAlpha = 255.0;
|
||||
for(int i = 1; i <= MaxClients; i++)
|
||||
{
|
||||
@ -140,6 +263,8 @@ public void OnPostThinkPost(int client)
|
||||
float fDistance = GetVectorDistance(fVec1, fVec2, false);
|
||||
if(fDistance <= g_fMaxDistance)
|
||||
{
|
||||
PlayersInRange++;
|
||||
|
||||
float fFactor = fDistance / g_fMaxDistance;
|
||||
if(fFactor < g_fMinFactor)
|
||||
fFactor = g_fMinFactor;
|
||||
@ -151,13 +276,15 @@ public void OnPostThinkPost(int client)
|
||||
if(fAlpha < g_fMinAlpha)
|
||||
fAlpha = g_fMinAlpha;
|
||||
|
||||
int Alpha = RoundToNearest(fAlpha);
|
||||
int LastAlpha = g_Client_Alpha[client];
|
||||
g_Client_Alpha[client] = Alpha;
|
||||
if(PlayersInRange < g_iMinPlayers)
|
||||
fAlpha = 255.0;
|
||||
|
||||
if(Alpha == LastAlpha)
|
||||
int Alpha = RoundToNearest(fAlpha);
|
||||
|
||||
if(Alpha == g_Client_Alpha[client])
|
||||
return;
|
||||
|
||||
g_Client_Alpha[client] = Alpha;
|
||||
ToolsSetEntityAlpha(client, Alpha);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user