projects-jenz/zombie_hunting_respawn/zh_respawn_stop.sp

167 lines
5.7 KiB
SourcePawn

#include <sourcemod>
#include <sdktools>
#include <zombiereloaded>
int g_bBlockRespawn[MAXPLAYERS+1];
int client_target[MAXPLAYERS + 1];
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)
{
client_target[client] = 0;
g_bBlockRespawn[client] = 0;
}
//----------------------------------------------------------------------------------------------------
// 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:
//----------------------------------------------------------------------------------------------------
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;
//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++)
{
//if player would get stuck being teleported dont teleport them to this player
if (!IsValidClient(i) || !IsPlayerAlive(i))
{
continue;
}
if (IsPlayerStuck(i) != -1)
{
continue;
}
float nearestdistance = -1.0;
int nearest = -1;
for (int j = 1; j <= MaxClients; j++)
if (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 players closest enemy
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;
}
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;
}
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;
}
}