2023-01-01 23:39:45 +01:00
|
|
|
#include <sourcemod>
|
2023-01-04 22:22:44 +01:00
|
|
|
#include <sdktools>
|
2023-01-01 23:39:45 +01:00
|
|
|
#include <zombiereloaded>
|
|
|
|
int g_bBlockRespawn[MAXPLAYERS+1];
|
2023-01-04 22:22:44 +01:00
|
|
|
int client_target[MAXPLAYERS + 1];
|
2023-01-01 23:39:45 +01:00
|
|
|
ConVar g_hRespawnTreshold;
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
|
|
// Purpose:
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
|
|
public Plugin myinfo =
|
|
|
|
{
|
|
|
|
name = "zh stop zm respawn",
|
|
|
|
author = "jenz",
|
|
|
|
description = "Disables respawning on zombie hunting maps after some deaths",
|
|
|
|
version = "1.0.0",
|
|
|
|
url = "www.unloze.com"
|
|
|
|
};
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
|
|
// Purpose:
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
|
|
public void OnPluginStart()
|
|
|
|
{
|
|
|
|
g_hRespawnTreshold = CreateConVar("zh_respawn_count", "5.0", "zombie hunting respawn count", 0, true, 0.0, true, 100.0);
|
|
|
|
for (int client; client < MaxClients; client++)
|
|
|
|
g_bBlockRespawn[client] = 0;
|
|
|
|
|
|
|
|
HookEvent("round_start", OnRoundStart);
|
|
|
|
HookEvent("player_death", OnClientDeath);
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
|
|
// Purpose:
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
|
|
public void OnClientDisconnect(int client)
|
|
|
|
{
|
2023-01-04 22:22:44 +01:00
|
|
|
client_target[client] = 0;
|
|
|
|
g_bBlockRespawn[client] = 0;
|
2023-01-01 23:39:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
|
|
// Purpose:
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
|
|
public void OnRoundStart(Event hEvent, const char[] sEvent, bool bDontBroadcast)
|
|
|
|
{
|
|
|
|
for (int client; client < MaxClients; client++)
|
|
|
|
g_bBlockRespawn[client] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
|
|
// Purpose:
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
|
|
public void OnClientDeath(Event hEvent, const char[] sEvent, bool bDontBroadcast)
|
|
|
|
{
|
|
|
|
int victim = GetClientOfUserId(hEvent.GetInt("userid"));
|
|
|
|
if (g_bBlockRespawn[victim] > g_hRespawnTreshold.FloatValue)
|
|
|
|
return;
|
|
|
|
PrintToChat(victim, "\x04[ZR]\x01 You have %f respawns left for this round.", g_hRespawnTreshold.FloatValue - g_bBlockRespawn[victim]);
|
|
|
|
g_bBlockRespawn[victim]++;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
|
|
// Purpose:
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
2023-01-04 22:22:44 +01:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2023-01-01 23:39:45 +01:00
|
|
|
public Action ZR_OnClientRespawn(&client, &ZR_RespawnCondition:condition)
|
|
|
|
{
|
2023-01-04 22:22:44 +01:00
|
|
|
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++)
|
|
|
|
{
|
2023-01-09 22:33:51 +01:00
|
|
|
//if player would get stuck being teleported dont teleport them to this player
|
|
|
|
if (!IsValidClient(i) || !IsPlayerAlive(i))
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (IsPlayerStuck(i) != -1)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2023-01-04 22:22:44 +01:00
|
|
|
float nearestdistance = -1.0;
|
|
|
|
int nearest = -1;
|
|
|
|
for (int j = 1; j <= MaxClients; j++)
|
2023-01-09 22:33:51 +01:00
|
|
|
if (IsValidClient(j) && IsPlayerAlive(j) && GetClientTeam(i) != GetClientTeam(j) && GetClientTeam(i) == 3)
|
2023-01-04 22:22:44 +01:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2023-01-09 22:33:51 +01:00
|
|
|
//the closest enemy to this player is further away than previous players closest enemy
|
2023-01-04 22:22:44 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2023-01-09 22:33:51 +01:00
|
|
|
stock int IsPlayerStuck(int client) {
|
|
|
|
float vecMin[3];
|
|
|
|
float vecMax[3];
|
|
|
|
float vecOrigin[3];
|
|
|
|
|
|
|
|
GetClientMins(client, vecMin);
|
|
|
|
GetClientMaxs(client, vecMax);
|
|
|
|
vecMax[2] = 63.0;
|
|
|
|
vecMin[2] += 1.0;
|
|
|
|
GetClientAbsOrigin(client, vecOrigin);
|
|
|
|
|
|
|
|
TR_TraceHullFilter(vecOrigin, vecOrigin, vecMin, vecMax, MASK_PLAYERSOLID, TraceRayDontHitPlayerAndWorld);
|
|
|
|
return TR_GetEntityIndex();
|
|
|
|
}
|
|
|
|
|
|
|
|
public bool TraceRayDontHitPlayerAndWorld(int entityhit, int mask) {
|
|
|
|
return entityhit>MaxClients
|
|
|
|
}
|
|
|
|
public bool TraceRayHitOnlyEnt(int entityhit, int mask, any data) {
|
|
|
|
return entityhit==data;
|
|
|
|
}
|
|
|
|
|
2023-01-04 22:22:44 +01:00
|
|
|
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;
|
|
|
|
}
|
2023-01-01 23:39:45 +01:00
|
|
|
}
|