336 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			SourcePawn
		
	
	
	
	
	
			
		
		
	
	
			336 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			SourcePawn
		
	
	
	
	
	
| #pragma semicolon 1
 | |
| 
 | |
| #include <sourcemod>
 | |
| #include <cstrike>
 | |
| #include <multicolors>
 | |
| #include <zombiereloaded>
 | |
| #include <basecomm>
 | |
| #include <sdktools>
 | |
| 
 | |
| bool g_bStuckRequestAuto;
 | |
| 
 | |
| int g_iStuckRequester;
 | |
| 
 | |
| float g_fStuckRequestTimer;
 | |
| 
 | |
| Handle StuckRequestTimer;
 | |
| 
 | |
| public Plugin myinfo =
 | |
| {
 | |
| 	name = "Stuck Request",
 | |
| 	author = "Dogan",
 | |
| 	description = "Very simple Plugin to handle Humans being stuck in ZE",
 | |
| 	version = "1.0.0",
 | |
| 	url = ""
 | |
| };
 | |
| 
 | |
| public void OnPluginStart()
 | |
| {
 | |
| 	RegConsoleCmd("sm_stuck", Command_StuckRequest, "Send a request to admins for being stuck");
 | |
| 	RegConsoleCmd("sm_zstuck", Command_StuckRequest, "Send a request to admins for being stuck");
 | |
| 	RegAdminCmd("sm_acc", Command_AcceptRequest, ADMFLAG_GENERIC, "Accepts the current stuck-request");
 | |
| 	RegAdminCmd("sm_deny", Command_DenyRequest, ADMFLAG_GENERIC, "Denies the current stuck-request");
 | |
| 
 | |
| 	HookEvent("player_death", OnPlayerDeath);
 | |
| 
 | |
| 	ConVar cvar;
 | |
| 	HookConVarChange((cvar = CreateConVar("sm_stuckrequest_auto", "1", "1 = automatically accept stuck requests when timer runs out, 0 = decline by default", FCVAR_NONE, true, 0.0, true, 1.0)), g_cvStuckRequestAuto);
 | |
| 	g_bStuckRequestAuto = cvar.BoolValue;
 | |
| 	HookConVarChange((cvar = CreateConVar("sm_stuckrequest_timer", "6.0", "timer until a stuck request runs out")), g_cvStuckRequestTimer);
 | |
| 	g_fStuckRequestTimer = cvar.FloatValue;
 | |
| 	delete cvar;
 | |
| 
 | |
| 	AutoExecConfig(true, "plugin.StuckRequest");
 | |
| 
 | |
| 	g_iStuckRequester = 0;
 | |
| }
 | |
| 
 | |
| public void g_cvStuckRequestAuto(ConVar convar, const char[] oldValue, const char[] newValue)
 | |
| {
 | |
| 	g_bStuckRequestAuto = convar.BoolValue;
 | |
| }
 | |
| 
 | |
| public void g_cvStuckRequestTimer(ConVar convar, const char[] oldValue, const char[] newValue)
 | |
| {
 | |
| 	g_fStuckRequestTimer = convar.FloatValue;
 | |
| }
 | |
| 
 | |
| public Action OnPlayerDeath(Event event, const char[] name, bool dontBroadcast)
 | |
| {
 | |
| 	int client = GetClientOfUserId(GetEventInt(event, "userid"));
 | |
| 
 | |
| 	char sWepName[64];
 | |
| 	GetEventString(event, "weapon", sWepName, sizeof(sWepName));
 | |
| 
 | |
| 	if(g_iStuckRequester == client && !StrEqual(sWepName, "knife"))
 | |
| 	{
 | |
| 		CPrintToChat(client, "{lightgreen}[StuckRequest]{yellow} You died while the Request was pending! Request aborted.");
 | |
| 
 | |
| 		for(int i = 1; i <= MaxClients; i++)
 | |
| 		{
 | |
| 			if(IsAdmin(i))
 | |
| 			{
 | |
| 				CPrintToChat(i, "{lightgreen}[StuckRequest]{yellow} %N died while the Request was pending! Request aborted.", g_iStuckRequester);
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		g_iStuckRequester = 0;
 | |
| 		KillTimer(StuckRequestTimer);
 | |
| 		StuckRequestTimer = INVALID_HANDLE;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| public void OnClientDisconnect(int client)
 | |
| {
 | |
| 	if(g_iStuckRequester == client)
 | |
| 	{
 | |
| 		for(int i = 1; i <= MaxClients; i++)
 | |
| 		{
 | |
| 			if(IsAdmin(i))
 | |
| 			{
 | |
| 				CPrintToChat(i, "{lightgreen}[StuckRequest]{yellow} %N left the Server while having a Request open. Request aborted.", g_iStuckRequester);
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		g_iStuckRequester = 0;
 | |
| 		KillTimer(StuckRequestTimer);
 | |
| 		StuckRequestTimer = INVALID_HANDLE;
 | |
| 	}
 | |
| }
 | |
| public Action Command_StuckRequest(int client, int args)
 | |
| {
 | |
| 	if(client == 0)
 | |
| 	{
 | |
| 		ReplyToCommand(client, "[SM] Cannot use this from Console.");
 | |
| 		return Plugin_Handled;
 | |
| 	}
 | |
| 
 | |
| 	if(BaseComm_IsClientGagged(client))
 | |
| 	{
 | |
| 		ReplyToCommand(client, "{lightgreen}[StuckRequest]{yellow} Cannot use this while being gagged.");
 | |
| 		return Plugin_Handled;
 | |
| 	}
 | |
| 
 | |
| 	if(g_iStuckRequester == client)
 | |
| 	{
 | |
| 		CReplyToCommand(client, "{lightgreen}[StuckRequest]{yellow} Your Request is pending!");
 | |
| 		return Plugin_Handled;
 | |
| 	}
 | |
| 
 | |
| 	if(g_iStuckRequester != 0)
 | |
| 	{
 | |
| 		CReplyToCommand(client, "{lightgreen}[StuckRequest]{yellow} Another Request is pending! Try again in couple seconds.");
 | |
| 		return Plugin_Handled;
 | |
| 	}
 | |
| 
 | |
| 	if(!IsPlayerAlive(client))
 | |
| 	{
 | |
| 		CReplyToCommand(client, "{lightgreen}[StuckRequest]{yellow} Cannot use this while being dead.");
 | |
| 		return Plugin_Handled;
 | |
| 	}
 | |
| 
 | |
| 	if(ZR_IsClientZombie(client))
 | |
| 	{
 | |
| 		CReplyToCommand(client, "{lightgreen}[StuckRequest]{yellow} This feature is only available for Humans! Use !ztele as Zombie.");
 | |
| 		return Plugin_Handled;
 | |
| 	}
 | |
| 
 | |
| 	if(IsAdmin(client))
 | |
| 	{
 | |
| 		CReplyToCommand(client, "{lightgreen}[StuckRequest]{yellow} Don't be silly! Teleport yourself.");
 | |
| 		return Plugin_Handled;
 | |
| 	}
 | |
| 
 | |
| 	CReplyToCommand(client, "{lightgreen}[StuckRequest]{yellow} Sent your Request to Admins!");
 | |
| 	g_iStuckRequester = client;
 | |
| 	SendRequestToAdmin(g_iStuckRequester);
 | |
| 	StuckRequestTimer = CreateTimer(g_fStuckRequestTimer, OnStuckRequest);
 | |
| 
 | |
| 	return Plugin_Handled;
 | |
| }
 | |
| 
 | |
| public Action OnStuckRequest(Handle timer)
 | |
| {
 | |
| 	if(g_bStuckRequestAuto)
 | |
| 	{
 | |
| 		if(ZR_IsClientZombie(g_iStuckRequester))
 | |
| 			ZR_HumanClient(g_iStuckRequester, false, false);
 | |
| 
 | |
| 		int iRandomHuman = 0;
 | |
| 		int PotentialTPCount;
 | |
| 		int PotentialTPClient[64];
 | |
| 
 | |
| 		for(int i = 1; i <= MaxClients; i++)
 | |
| 		{
 | |
| 			if(IsClientInGame(i) && !IsFakeClient(i) && IsPlayerAlive(i) && ZR_IsClientHuman(i) && i != g_iStuckRequester)
 | |
| 			{
 | |
| 				PotentialTPClient[PotentialTPCount] = i;
 | |
| 				PotentialTPCount++;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		if(PotentialTPCount < 1)//round ended meanwhile or no humans
 | |
| 		{
 | |
| 			CPrintToChat(g_iStuckRequester, "{lightgreen}[StuckRequest]{yellow} Round ended while the Request was pending! Request aborted.");
 | |
| 
 | |
| 			g_iStuckRequester = 0;
 | |
| 
 | |
| 			for(int i = 1; i <= MaxClients; i++)
 | |
| 			{
 | |
| 				if(IsAdmin(i))
 | |
| 				{
 | |
| 					CPrintToChat(i, "{lightgreen}[StuckRequest]{yellow} Round ended while the Request was pending! Request aborted.");
 | |
| 				}
 | |
| 
 | |
| 			}
 | |
| 
 | |
| 			return Plugin_Handled;
 | |
| 		}
 | |
| 
 | |
| 		iRandomHuman = PotentialTPClient[GetRandomInt(0, PotentialTPCount - 1)];
 | |
| 
 | |
| 		float vecTargetPos[3];
 | |
| 		GetClientAbsOrigin(iRandomHuman, vecTargetPos);
 | |
| 		TeleportEntity(g_iStuckRequester, vecTargetPos, NULL_VECTOR, NULL_VECTOR);
 | |
| 
 | |
| 		CPrintToChat(g_iStuckRequester, "{lightgreen}[StuckRequest]{yellow} Request accepted and teleported to a random Human.");
 | |
| 		LogAction(0, -1, "[StuckRequest] Automatically accepted Stuck-Request of %N.", g_iStuckRequester);
 | |
| 		LogToFile("addons/sourcemod/logs/stuckresquests.log", "Automatically accepted Stuck-Request of %N.", g_iStuckRequester);
 | |
| 
 | |
| 		for(int i = 1; i <= MaxClients; i++)
 | |
| 		{
 | |
| 		if(IsAdmin(i))
 | |
| 			{
 | |
| 				CPrintToChat(i, "{lightgreen}[StuckRequest]{yellow} Automatically accepted Stuck-Request of %N, because timer ran out.", g_iStuckRequester);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		CPrintToChat(g_iStuckRequester, "{lightgreen}[StuckRequest]{yellow} Request left open. Probably Admins AFK. Sorry!");
 | |
| 		for(int i = 1; i <= MaxClients; i++)
 | |
| 		{
 | |
| 			if(IsAdmin(i))
 | |
| 			{
 | |
| 				CPrintToChat(i, "{lightgreen}[StuckRequest]{yellow} Automatically denied Stuck-Request of %N, because timer ran out.", g_iStuckRequester);
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	g_iStuckRequester = 0;
 | |
| 
 | |
| 	return Plugin_Handled;
 | |
| }
 | |
| 
 | |
| public Action SendRequestToAdmin(int client)
 | |
| {
 | |
| 	for(int i = 1; i <= MaxClients; i++)
 | |
| 	{
 | |
| 		if(IsAdmin(i))
 | |
| 		{
 | |
| 			CPrintToChat(i, "{lightgreen}[StuckRequest]{yellow} %N sent a Request! Type {red}!acc{white} to accept or {red}!deny{white} to deny.", client);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return Plugin_Handled;
 | |
| }
 | |
| 
 | |
| public Action Command_AcceptRequest(int client, int args)
 | |
| {
 | |
| 	if(g_iStuckRequester == 0)
 | |
| 	{
 | |
| 		CReplyToCommand(client, "{lightgreen}[StuckRequest]{yellow} There is no Request pending!");
 | |
| 		return Plugin_Handled;
 | |
| 	}
 | |
| 
 | |
| 	if(ZR_IsClientZombie(g_iStuckRequester))
 | |
| 		ZR_HumanClient(g_iStuckRequester, false, false);
 | |
| 
 | |
| 	int iRandomHuman = 0;
 | |
| 	int PotentialTPCount;
 | |
| 	int PotentialTPClient[64];
 | |
| 
 | |
| 	for(int i = 1; i <= MaxClients; i++)
 | |
| 	{
 | |
| 		if(IsClientInGame(i) && !IsFakeClient(i) && IsPlayerAlive(i) && ZR_IsClientHuman(i) && i != g_iStuckRequester)
 | |
| 		{
 | |
| 			PotentialTPClient[PotentialTPCount] = i;
 | |
| 			PotentialTPCount++;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if(PotentialTPCount < 1)//round ended meanwhile or no humans
 | |
| 	{
 | |
| 		CPrintToChat(g_iStuckRequester, "{lightgreen}[StuckRequest]{yellow} Round ended while the Request was pending! Request aborted.");
 | |
| 
 | |
| 		g_iStuckRequester = 0;
 | |
| 		KillTimer(StuckRequestTimer);
 | |
| 		StuckRequestTimer = INVALID_HANDLE;
 | |
| 
 | |
| 		for(int i = 1; i <= MaxClients; i++)
 | |
| 		{
 | |
| 			if(IsAdmin(i))
 | |
| 			{
 | |
| 				CPrintToChat(i, "{lightgreen}[StuckRequest]{yellow} Round ended while the Request was pending! Request aborted.");
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		return Plugin_Handled;
 | |
| 	}
 | |
| 
 | |
| 	iRandomHuman = PotentialTPClient[GetRandomInt(0, PotentialTPCount - 1)];
 | |
| 
 | |
| 	float vecTargetPos[3];
 | |
| 	GetClientAbsOrigin(iRandomHuman, vecTargetPos);
 | |
| 	TeleportEntity(g_iStuckRequester, vecTargetPos, NULL_VECTOR, NULL_VECTOR);
 | |
| 
 | |
| 	CPrintToChat(g_iStuckRequester, "{lightgreen}[StuckRequest]{yellow} Request accepted and teleported to a random Human.");
 | |
| 	LogAction(client, -1, "[StuckRequest] %N accepted Stuck-Request of %N.", client, g_iStuckRequester);
 | |
| 
 | |
| 	for(int i = 1; i <= MaxClients; i++)
 | |
| 	{
 | |
| 		if(IsAdmin(i))
 | |
| 		{
 | |
| 			CPrintToChat(i, "{lightgreen}[StuckRequest]{yellow} %N accepted the Request of %N.", client, g_iStuckRequester);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	g_iStuckRequester = 0;
 | |
| 	KillTimer(StuckRequestTimer);
 | |
| 	StuckRequestTimer = INVALID_HANDLE;
 | |
| 
 | |
| 	return Plugin_Handled;
 | |
| }
 | |
| 
 | |
| public Action Command_DenyRequest(int client, int args)
 | |
| {
 | |
| 	if(g_iStuckRequester == 0)
 | |
| 	{
 | |
| 		CReplyToCommand(client, "{lightgreen}[StuckRequest]{yellow} There is no Request pending!");
 | |
| 		return Plugin_Handled;
 | |
| 	}
 | |
| 
 | |
| 	CPrintToChat(g_iStuckRequester, "{lightgreen}[StuckRequest]{yellow} Admins denied your Request.");
 | |
| 
 | |
| 	for(int i = 1; i <= MaxClients; i++)
 | |
| 	{
 | |
| 		if(IsAdmin(i))
 | |
| 		{
 | |
| 			CPrintToChat(i, "{lightgreen}[StuckRequest]{yellow} %N denied the Request of %N.", client, g_iStuckRequester);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	g_iStuckRequester = 0;
 | |
| 	KillTimer(StuckRequestTimer);
 | |
| 	StuckRequestTimer = INVALID_HANDLE;
 | |
| 
 | |
| 	return Plugin_Handled;
 | |
| }
 | |
| 
 | |
| static stock bool IsAdmin(int client)
 | |
| {
 | |
| 	if (client > 0 && client <= MaxClients && IsClientInGame(client) && CheckCommandAccess(client, "", ADMFLAG_GENERIC))
 | |
| 		return true;
 | |
| 	else
 | |
| 		return false;
 | |
| } |