PlayerVisibility: Improved and fixed bugs.
This commit is contained in:
		
							parent
							
								
									34e17ed6d2
								
							
						
					
					
						commit
						69c13e42bb
					
				| @ -1,6 +1,9 @@ | |||||||
| #include <sourcemod> | #include <sourcemod> | ||||||
| #include <sdkhooks> | #include <sdkhooks> | ||||||
|  | #include <dhooks> | ||||||
|  | #undef REQUIRE_PLUGIN | ||||||
| #include <zombiereloaded> | #include <zombiereloaded> | ||||||
|  | #define REQUIRE_PLUGIN | ||||||
| 
 | 
 | ||||||
| #pragma semicolon 1 | #pragma semicolon 1 | ||||||
| #pragma newdecls required | #pragma newdecls required | ||||||
| @ -10,22 +13,45 @@ public Plugin myinfo = | |||||||
| 	name 			= "PlayerVisibility", | 	name 			= "PlayerVisibility", | ||||||
| 	author 			= "BotoX", | 	author 			= "BotoX", | ||||||
| 	description 	= "Fades players away when you get close to them.", | 	description 	= "Fades players away when you get close to them.", | ||||||
| 	version 		= "1.1", | 	version 		= "1.2", | ||||||
| 	url 			= "" | 	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_MaxDistance; | ||||||
| ConVar g_CVar_MinFactor; | ConVar g_CVar_MinFactor; | ||||||
| ConVar g_CVar_MinAlpha; | ConVar g_CVar_MinAlpha; | ||||||
|  | ConVar g_CVar_MinPlayers; | ||||||
| 
 | 
 | ||||||
| float g_fMaxDistance; | float g_fMaxDistance; | ||||||
| float g_fMinFactor; | float g_fMinFactor; | ||||||
| float g_fMinAlpha; | float g_fMinAlpha; | ||||||
|  | int g_iMinPlayers; | ||||||
| 
 | 
 | ||||||
| int g_Client_Alpha[MAXPLAYERS + 1] = {255, ...}; | int g_Client_Alpha[MAXPLAYERS + 1] = {255, ...}; | ||||||
|  | bool g_Client_bEnabled[MAXPLAYERS + 1] = {false, ...}; | ||||||
| 
 | 
 | ||||||
| public void OnPluginStart() | 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_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_fMaxDistance = g_CVar_MaxDistance.FloatValue; | ||||||
| 	g_CVar_MaxDistance.AddChangeHook(OnConVarChanged); | 	g_CVar_MaxDistance.AddChangeHook(OnConVarChanged); | ||||||
| @ -38,13 +64,31 @@ public void OnPluginStart() | |||||||
| 	g_fMinAlpha = g_CVar_MinAlpha.FloatValue; | 	g_fMinAlpha = g_CVar_MinAlpha.FloatValue; | ||||||
| 	g_CVar_MinAlpha.AddChangeHook(OnConVarChanged); | 	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++) | 	for(int client = 1; client <= MaxClients; client++) | ||||||
| 	{ | 	{ | ||||||
| 		if(IsClientInGame(client)) | 		if(IsClientInGame(client)) | ||||||
| 			OnClientPutInServer(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) | 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) | 	else if(convar == g_CVar_MinAlpha) | ||||||
| 		g_fMinAlpha = g_CVar_MinAlpha.FloatValue; | 		g_fMinAlpha = g_CVar_MinAlpha.FloatValue; | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| public void OnPluginEnd() | 	else if(convar == g_CVar_MinPlayers) | ||||||
| { | 		g_iMinPlayers = g_CVar_MinPlayers.IntValue; | ||||||
| 	for(int client = 1; client <= MaxClients; client++) |  | ||||||
| 	{ |  | ||||||
| 		if(IsClientInGame(client)) |  | ||||||
| 		{ |  | ||||||
| 			if(g_Client_Alpha[client] != 255.0) |  | ||||||
| 				SetEntityRenderMode(client, RENDER_NORMAL); |  | ||||||
| 
 |  | ||||||
| 			OnClientDisconnect(client); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| public void OnClientPutInServer(int client) | public void OnClientPutInServer(int client) | ||||||
| { | { | ||||||
| 	g_Client_Alpha[client] = 255; | 	g_Client_Alpha[client] = 255; | ||||||
|  | 	g_Client_bEnabled[client] = true; | ||||||
|  | 
 | ||||||
| 	SDKHook(client, SDKHook_PostThinkPost, OnPostThinkPost); | 	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_Alpha[client] = 255; | ||||||
| 	SDKUnhook(client, SDKHook_PostThinkPost, OnPostThinkPost); | 				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; | ||||||
|  | 	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) | public void OnPostThinkPost(int client) | ||||||
| { | { | ||||||
| 	if(!IsPlayerAlive(client)) | 	if(!g_Client_bEnabled[client]) | ||||||
| 	{ |  | ||||||
| 		if(g_Client_Alpha[client] != 255) |  | ||||||
| 		{ |  | ||||||
| 			g_Client_Alpha[client] = 255; |  | ||||||
| 			ToolsSetEntityAlpha(client, 255); |  | ||||||
| 		} |  | ||||||
| 		return; | 		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; | 	float fAlpha = 255.0; | ||||||
| 	for(int i = 1; i <= MaxClients; i++) | 	for(int i = 1; i <= MaxClients; i++) | ||||||
| 	{ | 	{ | ||||||
| @ -140,6 +263,8 @@ public void OnPostThinkPost(int client) | |||||||
| 		float fDistance = GetVectorDistance(fVec1, fVec2, false); | 		float fDistance = GetVectorDistance(fVec1, fVec2, false); | ||||||
| 		if(fDistance <= g_fMaxDistance) | 		if(fDistance <= g_fMaxDistance) | ||||||
| 		{ | 		{ | ||||||
|  | 			PlayersInRange++; | ||||||
|  | 
 | ||||||
| 			float fFactor = fDistance / g_fMaxDistance; | 			float fFactor = fDistance / g_fMaxDistance; | ||||||
| 			if(fFactor < g_fMinFactor) | 			if(fFactor < g_fMinFactor) | ||||||
| 				fFactor = g_fMinFactor; | 				fFactor = g_fMinFactor; | ||||||
| @ -151,13 +276,15 @@ public void OnPostThinkPost(int client) | |||||||
| 	if(fAlpha < g_fMinAlpha) | 	if(fAlpha < g_fMinAlpha) | ||||||
| 		fAlpha = g_fMinAlpha; | 		fAlpha = g_fMinAlpha; | ||||||
| 
 | 
 | ||||||
| 	int Alpha = RoundToNearest(fAlpha); | 	if(PlayersInRange < g_iMinPlayers) | ||||||
| 	int LastAlpha = g_Client_Alpha[client]; | 		fAlpha = 255.0; | ||||||
| 	g_Client_Alpha[client] = Alpha; |  | ||||||
| 
 | 
 | ||||||
| 	if(Alpha == LastAlpha) | 	int Alpha = RoundToNearest(fAlpha); | ||||||
|  | 
 | ||||||
|  | 	if(Alpha == g_Client_Alpha[client]) | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
|  | 	g_Client_Alpha[client] = Alpha; | ||||||
| 	ToolsSetEntityAlpha(client, Alpha); | 	ToolsSetEntityAlpha(client, Alpha); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user