From d5dae5c04585b6cab6c0751cb73cad092e502323 Mon Sep 17 00:00:00 2001 From: jenz Date: Wed, 4 Jan 2023 22:22:44 +0100 Subject: [PATCH] added feature so respawning at human with largest distance to any zm --- zombie_hunting_respawn/zh_respawn_stop.sp | 77 +++++++++++++++++++++-- 1 file changed, 72 insertions(+), 5 deletions(-) diff --git a/zombie_hunting_respawn/zh_respawn_stop.sp b/zombie_hunting_respawn/zh_respawn_stop.sp index a57c767f..3b537a39 100644 --- a/zombie_hunting_respawn/zh_respawn_stop.sp +++ b/zombie_hunting_respawn/zh_respawn_stop.sp @@ -1,6 +1,8 @@ #include +#include #include int g_bBlockRespawn[MAXPLAYERS+1]; +int client_target[MAXPLAYERS + 1]; ConVar g_hRespawnTreshold; //---------------------------------------------------------------------------------------------------- // Purpose: @@ -32,7 +34,8 @@ public void OnPluginStart() //---------------------------------------------------------------------------------------------------- public void OnClientDisconnect(int client) { - g_bBlockRespawn[client] = 0; + client_target[client] = 0; + g_bBlockRespawn[client] = 0; } //---------------------------------------------------------------------------------------------------- @@ -59,10 +62,74 @@ public void OnClientDeath(Event hEvent, const char[] sEvent, bool bDontBroadcast //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- + +stock bool IsValidClient(int client) +{ + if (client > 0 && client <= MaxClients && IsClientConnected(client) && IsClientInGame(client)) + return true; + return false; +} + +public float get_power_distance(int target_player, float [3]pos) +{ + float vec[3]; + GetClientAbsOrigin(target_player, vec); + return GetVectorDistance(vec, pos); +} + public Action ZR_OnClientRespawn(&client, &ZR_RespawnCondition:condition) { - if (g_bBlockRespawn[client] > g_hRespawnTreshold.FloatValue) - return Plugin_Handled; - - return Plugin_Continue; + if (g_bBlockRespawn[client] > g_hRespawnTreshold.FloatValue) + return Plugin_Handled; + + //teleport player to team members with farthest distance to enemy just. + //checking all alive clients to determine which client has highest dist_target to its closest enemy + float total_furthest_distance = -1.0; + int total_nearest = -1; + for (int i = 1; i <= MaxClients; i++) + { + float nearestdistance = -1.0; + int nearest = -1; + for (int j = 1; j <= MaxClients; j++) + if (IsValidClient(i) && IsPlayerAlive(i) && IsValidClient(j) && IsPlayerAlive(j) && GetClientTeam(i) != GetClientTeam(j) && GetClientTeam(i) == 3) + { + float pos[3]; + GetEntPropVector(i, Prop_Send, "m_vecOrigin", pos); + float dist_target = get_power_distance(j, pos); + if (nearestdistance < 0 || dist_target < nearestdistance) + { + nearest = i; + nearestdistance = dist_target; + } + } + //the closest enemy to this player is further away than previous player + if (nearestdistance > total_furthest_distance) + { + total_furthest_distance = nearestdistance; + total_nearest = nearest; + } + } + if (IsValidClient(total_nearest)) + { + client_target[client] = total_nearest; + CreateTimer(0.0, tp_client, client); + } + return Plugin_Continue; +} + +public void OnClientPostAdminCheck(int client) +{ + client_target[client] = 0; +} + +public Action tp_client(Handle timer, int client) +{ + if (IsValidClient(client) && IsValidClient(client_target[client])) + { + float posd[3]; + GetEntPropVector(client_target[client], Prop_Send, "m_vecOrigin", posd); + TeleportEntity(client, posd, NULL_VECTOR, NULL_VECTOR); + PrintToChat(client, "Respawned you at player: %N", client_target[client]); + client_target[client] = 0; + } }