diff --git a/StuckRequest/scripting/StuckRequest.sp b/StuckRequest/scripting/StuckRequest.sp new file mode 100644 index 00000000..3314137a --- /dev/null +++ b/StuckRequest/scripting/StuckRequest.sp @@ -0,0 +1,336 @@ +#pragma semicolon 1 + +#include +#include +#include +#include +#include +#include + +bool g_bStuckRequestAuto; +bool g_bStuckRequest; + +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, "Accept 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 = -1; +} + +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")); + + if(g_iStuckRequester == client) + { + 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 = -1; + g_bStuckRequest = false; + KillTimer(StuckRequestTimer); + } +} + +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.", g_iStuckRequester); + } + } + + g_iStuckRequester = -1; + g_bStuckRequest = false; + KillTimer(StuckRequestTimer); + } +} +public Action Command_StuckRequest(int client, int args) +{ + if(client == 0) + { + ReplyToCommand(client, "[SM] Cannot use this from Console."); + return Plugin_Handled; + } + + if(IsAdmin(client)) + { + CReplyToCommand(client, "{lightgreen}[StuckRequest]{yellow} Don't be silly! Teleport yourself."); + return Plugin_Handled; + } + + if(g_iStuckRequester == client) + { + CReplyToCommand(client, "{lightgreen}[StuckRequest]{yellow} Your Request is pending!"); + return Plugin_Handled; + } + + if(g_bStuckRequest) + { + CReplyToCommand(client, "{lightgreen}[StuckRequest]{yellow} Another Request is pending! Try again in couple seconds."); + return Plugin_Handled; + } + + if(BaseComm_IsClientGagged(client)) + { + ReplyToCommand(client, "{lightgreen}[StuckRequest]{yellow} Cannot use while being gagged."); + 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; + } + + CReplyToCommand(client, "{lightgreen}[StuckRequest]{yellow} Sent your Request to Admins!"); + g_iStuckRequester = client; + g_bStuckRequest = true; + 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 = -1; + 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 = -1; + g_bStuckRequest = false; + + 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 = -1; + g_bStuckRequest = false; + + 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_bStuckRequest) + { + 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 = -1; + 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 = -1; + g_bStuckRequest = false; + KillTimer(StuckRequestTimer); + + 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 = -1; + g_bStuckRequest = false; + KillTimer(StuckRequestTimer); + + return Plugin_Handled; +} + +public Action Command_DenyRequest(int client, int args) +{ + if(!g_bStuckRequest) + { + 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 = -1; + g_bStuckRequest = false; + KillTimer(StuckRequestTimer); + + 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; +} \ No newline at end of file