#pragma semicolon 1 #include #include #include #include #include #include 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; }