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;
|
|
} |