projects-jenz/zombie_hunting_respawn/zh_respawn_stop.sp

1324 lines
43 KiB
SourcePawn
Raw Permalink Normal View History

2023-01-01 23:39:45 +01:00
#include <sourcemod>
#include <sdktools>
2023-11-08 22:09:42 +01:00
#include <unloze_zones>
2024-05-05 00:47:27 +02:00
#include <sdkhooks>
2023-11-08 22:09:42 +01:00
#include <cstrike>
#include <PlayerRankings>
#include <hlstatsx_loghelper>
#include <mapchooser_extended>
2023-11-08 22:09:42 +01:00
#define MAXZONES 66
#define ZONENAMELENGTH 256
2023-01-01 23:39:45 +01:00
int g_bBlockRespawn[MAXPLAYERS+1];
2023-11-08 22:09:42 +01:00
char g_cZones[MAXZONES][ZONENAMELENGTH];
int g_cZones_CT_count[MAXZONES];
int g_cZones_ZM_count[MAXZONES];
int g_client_in_zone[MAXPLAYERS + 1];
int g_iCT_Damage_in_zone[MAXPLAYERS + 1];
int g_iZone_fought_or_ct_controlled[MAXZONES];
int g_iLast_Client_In_Zone[MAXPLAYERS + 1];
int ping_ents[MAXPLAYERS + 1];
int g_iAnnounce_zone_controll = 0;
bool g_permit_zone_benefits = false;
2023-11-08 22:09:42 +01:00
bool g_is_zh_map = false;
bool round_start_delay;
bool ran_out_of_time = false;
2023-11-08 22:09:42 +01:00
//spawning the markers
float ping_coorindates[MAXZONES][3];
int zone_pings[MAXZONES];
static char g_cConfigZones[PLATFORM_MAX_PATH];
int g_zoneCount = 0;
int client_target[MAXPLAYERS + 1];
2023-11-08 22:09:42 +01:00
float g_fStartPos[MAXZONES][3];
float g_fEndPos[MAXZONES][3];
2024-05-05 00:47:27 +02:00
float g_human_damage_addition;
2023-01-01 23:39:45 +01:00
ConVar g_hRespawnTreshold;
2023-11-08 22:09:42 +01:00
ConVar g_hHealthRegenZM;
ConVar g_hHealthRegenAmount;
Handle hText;
Handle g_hZMZoneTimer = null;
2024-05-05 00:47:27 +02:00
Handle g_hZoneCounter = null;
Handle g_hZoneBenefits = null;
2023-11-08 22:09:42 +01:00
2023-01-01 23:39:45 +01:00
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public Plugin myinfo =
{
2023-11-08 22:09:42 +01:00
name = "zombie hunting plugin",
2023-01-01 23:39:45 +01:00
author = "jenz",
2023-11-08 22:09:42 +01:00
description = "Disables respawning on zombie hunting maps after some deaths, adds zoning",
version = "2.0.0",
2023-01-01 23:39:45 +01:00
url = "www.unloze.com"
};
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnPluginStart()
{
2023-11-08 22:09:42 +01:00
OnMapStart();
g_hRespawnTreshold = CreateConVar("zh_respawn_count", "5.0", "zombie hunting respawn count", 0, true, 0.0, true, 100.0);
g_hHealthRegenZM = CreateConVar("zh_regenMaxHealth", "2000", "zombie hunting zombie max health for regen", 0, true, 0.0, true, 5000.0);
g_hHealthRegenAmount = CreateConVar("zh_regenAmount", "100", "zombie hunting zombie max health for regen", 0, true, 0.0, true, 5000.0);
for (int client; client < MaxClients; client++)
g_bBlockRespawn[client] = 0;
ReadZoneFile();
HookEvent("round_start", OnRoundStart);
HookEvent("round_end", OnRoundEnd, EventHookMode_Pre);
HookEvent("player_death", OnClientDeath);
hText = CreateHudSynchronizer();
round_start_delay = true;
2023-11-08 22:09:42 +01:00
//timer for ZM zone benefits
g_hZMZoneTimer = CreateTimer(5.0, give_zm_zone_boosts, _, TIMER_REPEAT);
2024-05-10 16:07:26 +02:00
g_hZoneCounter = CreateTimer(5.0, announce_zone_controlls, _, TIMER_REPEAT);
2024-05-05 00:47:27 +02:00
}
public Action announce_zone_controlls(Handle hTimer)
{
if (g_is_zh_map)
2024-05-05 00:47:27 +02:00
{
float fought_zone = 0.0;
float ct_controlled_zone = 0.0;
float zm_controlled_zone = 0.0;
if (g_zoneCount == 0 || !g_permit_zone_benefits)
2024-05-08 22:17:54 +02:00
{
g_human_damage_addition = 1.0; //indicating no damage buffs
for (int i = 0; i < MaxClients; i++)
2024-05-08 22:17:54 +02:00
{
if (IsValidClient(i) && IsPlayerAlive(i))
{
SetEntityGravity(i, 1.0);
}
2024-05-08 22:17:54 +02:00
}
return Plugin_Handled;
2024-05-08 22:17:54 +02:00
}
for (int i = 0; i < g_zoneCount; i++)
2024-05-05 00:47:27 +02:00
{
if (g_iZone_fought_or_ct_controlled[i] == 1) //fought over zone
{
fought_zone++;
}
if (g_iZone_fought_or_ct_controlled[i] == 2) //CT zone
{
ct_controlled_zone++;
}
if (g_iZone_fought_or_ct_controlled[i] == 3) //ZM zone
{
zm_controlled_zone++;
}
2024-05-05 00:47:27 +02:00
}
g_iAnnounce_zone_controll++;
int ct_control_percentage = RoundToFloor((ct_controlled_zone/ g_zoneCount) * 100);
int zm_control_percentage = RoundToFloor((zm_controlled_zone/ g_zoneCount) * 100);
int fought_percentage = RoundToFloor((fought_zone/ g_zoneCount) * 100);
if (g_iAnnounce_zone_controll >= 3)
2024-05-05 00:47:27 +02:00
{
PrintToChatAll("CT controll %i%s of zones. ZM controll %i%s of zones. %i%s of zones are fought over",
ct_control_percentage, "%", zm_control_percentage, "%", fought_percentage, "%");
2024-05-05 00:47:27 +02:00
}
if (zm_control_percentage > 70)
{
for (int i = 0; i < MaxClients; i++)
{
if (IsValidClient(i) && IsPlayerAlive(i))
{
if (GetClientTeam(i) == CS_TEAM_T)
{
SetEntityGravity(i, 0.7);
}
else
{
SetEntityGravity(i, 1.0);
}
}
}
if (g_iAnnounce_zone_controll >= 3)
{
PrintToChatAll("ZM controll over 70%s of zones. Applying 30%s low grav", "%", "%");
}
}
else
{
for (int i = 0; i < MaxClients; i++)
{
if (IsValidClient(i) && IsPlayerAlive(i))
{
SetEntityGravity(i, 1.0);
}
}
}
if (ct_control_percentage > 90)
{
g_human_damage_addition = 0.6;
if (g_iAnnounce_zone_controll >= 3)
{
PrintToChatAll("CT controll over 90%s of zones. Applying 60%s extra damage", "%", "%");
}
}
else if (ct_control_percentage > 70)
{
g_human_damage_addition = 0.40;
if (g_iAnnounce_zone_controll >= 3)
{
PrintToChatAll("CT controll over 70%s of zones. Applying 40%s extra damage", "%", "%");
}
}
else if (ct_control_percentage > 50)
{
g_human_damage_addition = 0.2;
if (g_iAnnounce_zone_controll >= 3)
{
PrintToChatAll("CT controll over 50%s of zones. Applying 20%s extra damage", "%", "%");
}
}
else
{
g_human_damage_addition = 1.0; //indicating no damage buffs
}
if (g_iAnnounce_zone_controll >= 3)
{
g_iAnnounce_zone_controll = 0;
}
2024-05-05 00:47:27 +02:00
}
return Plugin_Handled;
}
public void OnClientPutInServer(int client)
{
if (g_is_zh_map)
{
SDKHook(client, SDKHook_OnTakeDamage, OnTakeDamage);
}
2024-05-05 00:47:27 +02:00
}
public Action OnTakeDamage(int client, int &attacker, int &inflictor, float &damage, int &damagetype)
{
if (g_is_zh_map)
2024-05-05 00:47:27 +02:00
{
if (IsValidClient(attacker) && GetClientTeam(attacker) == CS_TEAM_CT && g_human_damage_addition != 1.0)
{
damage += (g_human_damage_addition * damage);
return Plugin_Changed;
}
2024-05-05 00:47:27 +02:00
}
2024-05-05 00:47:27 +02:00
return Plugin_Continue;
2023-11-08 22:09:42 +01:00
}
public Action give_zm_zone_boosts(Handle hTimer)
{
if (!g_is_zh_map)
{
return Plugin_Handled;
}
2023-11-08 22:09:42 +01:00
for (int client; client < MaxClients; client++)
{
if (IsValidClient(client) && IsPlayerAlive(client) && GetClientTeam(client) == CS_TEAM_T)
{
int index = g_client_in_zone[client];
//the player is zm, inside a zone and the zone has no humans present, so its a zm zone where he should get extra healed
if (index != -1 && g_cZones_CT_count[index] == 0)
{
//giving zm inside of zm controlled zone extra health regeneration
int client_health = GetEntData(client, FindDataMapInfo(client, "m_iHealth"));
if (client_health < g_hHealthRegenZM.IntValue)
{
SetEntProp(client, Prop_Send, "m_iHealth", client_health + g_hHealthRegenAmount.IntValue, 1);
}
}
}
}
return Plugin_Handled;
}
public void OnPluginEnd()
{
CloseHandle(hText);
if (g_hZMZoneTimer != null)
delete g_hZMZoneTimer;
2024-05-05 00:47:27 +02:00
if (g_hZoneCounter != null)
delete g_hZoneCounter;
if (g_hZoneBenefits != null)
2024-11-27 12:00:45 +01:00
{
delete g_hZoneBenefits;
2024-11-27 12:00:45 +01:00
g_hZoneBenefits = INVALID_HANDLE;
}
2023-01-01 23:39:45 +01:00
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnClientDisconnect(int client)
{
if (g_is_zh_map)
{
g_iCT_Damage_in_zone[client] = 0;
client_target[client] = 0;
g_client_in_zone[client] = -1;
adjust_clients(); //calling GetClientTeam inside adjust_clients complaints that client already disconnected.
g_bBlockRespawn[client] = 0;
SDKUnhook(client, SDKHook_OnTakeDamage, OnTakeDamage);
}
2023-01-01 23:39:45 +01:00
}
2023-11-08 22:09:42 +01:00
public void adjust_clients()
{
if (!g_is_zh_map)
{
return;
}
2023-11-08 22:09:42 +01:00
for (int i = 0; i < MAXZONES; i++)
{
g_cZones_CT_count[i] = 0;
g_cZones_ZM_count[i] = 0;
}
for (int i = 0; i <= g_zoneCount; i++)
{
for (int client; client < MaxClients; client++)
{
if (IsValidClient(client) && IsPlayerAlive(client) && g_client_in_zone[client] == i)
{
if (GetClientTeam(client) == CS_TEAM_CT)
{
g_cZones_CT_count[i]++;
}
else
{
g_cZones_ZM_count[i]++;
}
}
}
}
UpdateMarkers();
}
public void OnRoundEnd(Event hEvent, const char[] sEvent, bool bDontBroadcast)
{
if (g_is_zh_map)
2023-11-08 22:09:42 +01:00
{
if(g_hZoneBenefits != INVALID_HANDLE)
2023-11-08 22:09:42 +01:00
{
2024-11-27 12:00:45 +01:00
delete g_hZoneBenefits;
g_hZoneBenefits = INVALID_HANDLE;
2023-11-08 22:09:42 +01:00
}
round_start_delay = true;
bool found_alive_zm = false;
2023-11-08 22:09:42 +01:00
for (int client = 0; client < MaxClients; client++)
{
if (IsValidClient(client) && GetClientTeam(client) == CS_TEAM_T && IsPlayerAlive(client))
2023-11-08 22:09:42 +01:00
{
found_alive_zm = true;
}
}
if (found_alive_zm)
{
for (int client = 0; client < MaxClients; client++)
{
if (IsValidClient(client) && GetClientTeam(client) == CS_TEAM_CT)
{
ForcePlayerSuicide(client);
}
2023-11-08 22:09:42 +01:00
}
PrintToChatAll("Humans failed!");
PrintToChatAll("Humans failed!");
PrintToChatAll("Humans failed!");
2023-11-08 22:09:42 +01:00
}
for (int i = 0; i <= g_zoneCount; i++)
{
for (int j = zone_pings[i]; j < zone_pings[i + 1]; j++)
{
RemovePing(j);
}
}
}
}
public void OnMapEnd()
{
if (g_is_zh_map)
{
for (int i = 0; i <= g_zoneCount; i++)
{
for (int j = zone_pings[i]; j < zone_pings[i + 1]; j++)
{
RemovePing(j);
/* Should hopefully help prevent these crashes
L 11/26/2024 - 16:59:11: (70.62%) 1447 prop_dynamic
Nov 26 16:59:11 unloze script[1920069]: L 11/26/2024 - 16:59:11: Total edicts: 2049
Nov 26 16:59:11 unloze script[1920069]: ED_Alloc: no free edicts
Nov 26 16:59:11 unloze script[1920069]: L 11/26/2024 - 16:59:11: Engine error: ED_Alloc: no free edicts
*/
}
}
2023-11-08 22:09:42 +01:00
}
}
public Action permit_zone_benefits(Handle hTimer)
{
if (!g_is_zh_map)
{
return Plugin_Handled;
}
g_permit_zone_benefits = true;
return Plugin_Handled;
}
2023-01-01 23:39:45 +01:00
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnRoundStart(Event hEvent, const char[] sEvent, bool bDontBroadcast)
{
if (g_is_zh_map)
2023-11-08 22:09:42 +01:00
{
g_permit_zone_benefits = false;
g_hZoneBenefits = CreateTimer(35.0, permit_zone_benefits);
g_human_damage_addition = 1.0;
for (int client = 0; client < MaxClients; client++)
2023-11-08 22:09:42 +01:00
{
g_bBlockRespawn[client] = 0;
if (IsValidClient(client))
{
g_iCT_Damage_in_zone[client] = 0;
}
g_client_in_zone[client] = -1;
2023-11-08 22:09:42 +01:00
}
for (int i = 0; i < MAXZONES; i++)
{
g_cZones_CT_count[i] = 0;
g_cZones_ZM_count[i] = 0;
g_iZone_fought_or_ct_controlled[i] = -1;
g_iLast_Client_In_Zone[i] = 0;
}
round_start_delay = true;
CreateTimer(5.0, enable_pings);
2023-11-08 22:09:42 +01:00
}
}
public Action enable_pings(Handle timer, any data)
{
if (!g_is_zh_map)
{
return Plugin_Handled;
}
round_start_delay = false;
return Plugin_Handled;
2023-01-01 23:39:45 +01:00
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void OnClientDeath(Event hEvent, const char[] sEvent, bool bDontBroadcast)
{
if (g_is_zh_map)
{
int victim = GetClientOfUserId(hEvent.GetInt("userid"));
g_client_in_zone[victim] = -1;
adjust_clients();
SetEntityRenderColor(victim, 255, 255, 255, 255);
if (g_bBlockRespawn[victim] > g_hRespawnTreshold.IntValue)
return;
PrintToChat(victim, "\x04[ZR]\x01 You have %i respawns left for this round.", g_hRespawnTreshold.IntValue - g_bBlockRespawn[victim]);
g_bBlockRespawn[victim]++;
}
2023-01-01 23:39:45 +01:00
}
2023-11-08 22:09:42 +01:00
public void ZR_OnClientInfected(int client, int attacker, bool motherInfect, bool respawnOverride, bool respawn)
{
if (g_is_zh_map)
2023-11-08 22:09:42 +01:00
{
int index = g_client_in_zone[client];
if (index != -1)
2023-11-08 22:09:42 +01:00
{
//client got infected inside a specific zone, reduce human count inside that specific zone by 1
if (g_cZones_CT_count[index] > 0)
{
g_cZones_CT_count[index]--;
}
g_cZones_ZM_count[index]++;
UpdateMarkers();
2023-11-08 22:09:42 +01:00
}
}
}
2023-01-01 23:39:45 +01:00
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
stock bool IsValidClient(int client)
{
if (client > 0 && client <= MaxClients && IsClientConnected(client) && IsClientInGame(client))
return true;
return false;
}
2023-11-08 22:09:42 +01:00
public float get_power_distance(int target_player, float pos[3])
{
if (!g_is_zh_map)
{
return 0.0;
}
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)
{
if (g_is_zh_map)
{
if (g_bBlockRespawn[client] > g_hRespawnTreshold.IntValue)
return Plugin_Handled;
find_teleport_target(client);
}
2024-05-05 00:47:27 +02:00
return Plugin_Continue;
}
2024-05-05 00:47:27 +02:00
public void find_teleport_target(int client)
{
if (!g_is_zh_map)
{
return;
}
//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++)
2023-11-08 22:09:42 +01:00
if (IsValidClient(j) && IsPlayerAlive(j) && GetClientTeam(i) != GetClientTeam(j) && GetClientTeam(i) == CS_TEAM_CT)
{
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);
}
}
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)
{
if (g_is_zh_map)
{
g_iCT_Damage_in_zone[client] = 0;
client_target[client] = 0;
g_client_in_zone[client] = -1;
}
}
public Action tp_client(Handle timer, int client)
{
if (!g_is_zh_map)
{
return Plugin_Handled;
}
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-11-08 22:09:42 +01:00
return Plugin_Handled;
}
public void unloze_zoneLeave(int client, char[] zone)
{
if (g_is_zh_map)
{
int index = g_client_in_zone[client];
if (index < 0)
{
return;
}
g_client_in_zone[client] = -1;
g_iCT_Damage_in_zone[client] = 0;
if (GetClientTeam(client) == CS_TEAM_CT)
2023-11-08 22:09:42 +01:00
{
if (g_cZones_CT_count[index] > 0)
{
g_cZones_CT_count[index]--;
}
2023-11-08 22:09:42 +01:00
}
else
2023-11-08 22:09:42 +01:00
{
if (g_cZones_ZM_count[index] > 0)
{
g_cZones_ZM_count[index]--;
}
2023-11-08 22:09:42 +01:00
}
SetEntityRenderColor(client, 255, 255, 255, 255);
UpdateMarkers();
2023-11-08 22:09:42 +01:00
}
}
public void unloze_zoneCreated()
{
if (g_is_zh_map)
{
ReadZoneFile();
}
2023-11-08 22:09:42 +01:00
}
public Action retry_zoneEntry(Handle timer, DataPack data)
{
if (!g_is_zh_map)
{
return Plugin_Handled;
}
2023-11-08 22:09:42 +01:00
ResetPack(data);
char zone[256];
data.ReadString(zone, sizeof(zone));
int client_serial = data.ReadCell();
delete data;
int client;
if ((client = GetClientFromSerial(client_serial)) != 0)
{
//by the time its recalled should the player have left the previous zone already
unloze_zoneEntry(client, zone);
}
return Plugin_Handled;
}
public void unloze_zoneEntry(int client, char[] zone)
{
if (g_is_zh_map)
2023-11-08 22:09:42 +01:00
{
int index = -1;
//unfortunately it can happen that a zone is entered before the current one is left, which can lead to -1 index
//when leaving the zone again.
//example: Enter new zone before old is left -> leave old zone -> index is -1 -> leave current zone -> leave forward is called before entering new zone is called ->
//tries to do -- on a array index where the index is -1
if (g_client_in_zone[client] != -1)
2023-11-08 22:09:42 +01:00
{
//the previous zone has to be left before we recognize the client entering the new zone
//only special cases are roundstart/respawning
DataPack hDataPack = new DataPack();
hDataPack.WriteString(zone);
hDataPack.WriteCell(GetClientSerial(client));
CreateTimer(0.2, retry_zoneEntry, hDataPack);
return;
2023-11-08 22:09:42 +01:00
}
for (int i = 0; i < g_zoneCount; i++)
{
if (StrEqual(g_cZones[i], zone))
{
index = i;
break;
}
}
g_client_in_zone[client] = index;
2023-11-08 22:09:42 +01:00
g_iCT_Damage_in_zone[client] = PlayerRankings_GetClientDamage(client);
if (GetClientTeam(client) == CS_TEAM_CT)
{
g_cZones_CT_count[index]++;
}
else
{
g_cZones_ZM_count[index]++;
}
g_iLast_Client_In_Zone[index] = client;
display_hud_text(index, client);
UpdateMarkers();
2023-11-08 22:09:42 +01:00
}
}
2023-11-08 22:09:42 +01:00
public void handle_pings(int i, int pingtype)
{
if (!g_is_zh_map)
{
return;
}
if (round_start_delay)
{
return; //preventing pings from spawning exactly on roundStart as it might cause too many entities
}
2023-11-08 22:09:42 +01:00
for (int j = zone_pings[i]; j < zone_pings[i + 1]; j++)
{
//the ping is atm not the skull, will be changed to skull.
RemovePing(j);
if (!ran_out_of_time)
{
int timeleft = 0;
GetMapTimeLeft(timeleft);
if (timeleft <= 0)
{
ran_out_of_time = true;
}
}
//these jewish tricks should stop the crashing when switching map because the prop_dynamics are not around anymore.
//its not the last round because timeleft is not 0
//there is also atm no nextmap set for the server through mapchooser. This confirms that the mapvote did not set it and an
//admin also did not set it yet.
//just checking GetNextmap will not suffice because we always have a nextmap set.
if (!HasEndOfMapVoteFinished() && !ran_out_of_time)
2023-11-08 22:09:42 +01:00
{
SpawnPing(pingtype, ping_coorindates[j], j);
for (int client = 0; client < MaxClients; client++)
2023-11-08 22:09:42 +01:00
{
if (IsValidClient(client) && g_client_in_zone[client] == i)
{
display_hud_text(i, client);
}
2023-11-08 22:09:42 +01:00
}
}
}
}
public void display_hud_text(int index, int client)
{
if (!g_is_zh_map)
{
return;
}
2023-11-08 22:09:42 +01:00
if (hText != INVALID_HANDLE)
{
char msg[256];
if (g_cZones_CT_count[index] > 0 && g_cZones_ZM_count[index] > 0)
{
Format(msg, sizeof(msg), "Contested zone");
2023-11-08 22:09:42 +01:00
SetHudTextParams(0.35, 0.85, 2.5, 255, 255, 255, 85);
ShowSyncHudText(client, hText, msg);
}
else if (g_cZones_CT_count[index] > 0)
{
Format(msg, sizeof(msg), "Human controlled zone");
SetHudTextParams(0.35, 0.85, 2.5, 0, 0, 255, 85);
ShowSyncHudText(client, hText, msg);
SetEntityRenderColor(client, 0, 0, 255, 255);
}
else
{
Format(msg, sizeof(msg), "Zombie controlled zone");
SetHudTextParams(0.35, 0.85, 2.5, 255, 0, 0, 85);
ShowSyncHudText(client, hText, msg);
SetEntityRenderColor(client, 255, 0, 0, 255);
}
}
}
//----------------------------------------------------------------------------------------------------
// Purpose: Reads from file
//----------------------------------------------------------------------------------------------------
public Action ReadZoneFile()
{
if (g_is_zh_map)
2023-11-08 22:09:42 +01:00
{
int i_zoneTemp;
char l_cMapName[MAXZONES];
GetCurrentMap(l_cMapName, sizeof(l_cMapName));
Handle l_hZoneFile = INVALID_HANDLE;
char l_cLine[ZONENAMELENGTH];
char sPart[4][32];
BuildPath(Path_SM, g_cConfigZones, sizeof(g_cConfigZones), "configs/unloze_zones/%s.zones.txt", l_cMapName);
l_hZoneFile = OpenFile(g_cConfigZones, "r");
if (l_hZoneFile == INVALID_HANDLE)
2023-11-08 22:09:42 +01:00
{
Handle kv = CreateKeyValues("Zones");
KeyValuesToFile(kv, g_cConfigZones);
CloseHandle(kv);
delete l_hZoneFile;
return Plugin_Handled;
2023-11-08 22:09:42 +01:00
}
while (!IsEndOfFile(l_hZoneFile) && ReadFileLine(l_hZoneFile, l_cLine, sizeof(l_cLine)))
2023-11-08 22:09:42 +01:00
{
if (StrContains(l_cLine, "name", false) > -1)
{
ReplaceStrings(l_cLine, "name");
Format(g_cZones[i_zoneTemp], sizeof(g_cZones), l_cLine);
}
if (StrContains(l_cLine, "cordinate_a", false) >= 0)
{
ReplaceString(l_cLine, sizeof(l_cLine), "\"", "", true);
ReplaceString(l_cLine, sizeof(l_cLine), "cordinate_a", "", true);
ExplodeString(l_cLine, " ", sPart, 4, 32);
g_fStartPos[i_zoneTemp][0] = StringToFloat(sPart[0]);//reading first vector
g_fStartPos[i_zoneTemp][1] = StringToFloat(sPart[1]);//reading second vector
g_fStartPos[i_zoneTemp][2] = StringToFloat(sPart[2]);//reading third vector
}
if (StrContains(l_cLine, "cordinate_b", false) >= 0)
{
ReplaceString(l_cLine, sizeof(l_cLine), "\"", "", true);
ReplaceString(l_cLine, sizeof(l_cLine), "cordinate_b", "", true);
ExplodeString(l_cLine, " ", sPart, 4, 32);
g_fEndPos[i_zoneTemp][0] = StringToFloat(sPart[0]);
g_fEndPos[i_zoneTemp][1] = StringToFloat(sPart[1]);
g_fEndPos[i_zoneTemp][2] = StringToFloat(sPart[2]);
i_zoneTemp++;
}
2023-11-08 22:09:42 +01:00
}
g_zoneCount = i_zoneTemp;
delete l_hZoneFile;
2023-11-08 22:09:42 +01:00
}
return Plugin_Handled;
}
public void OnMapStart()
{
ran_out_of_time = false;
g_is_zh_map = false;
char sConfigFile[PLATFORM_MAX_PATH];
BuildPath(Path_SM, sConfigFile, sizeof(sConfigFile), "configs/zh_maps.cfg");
if(!FileExists(sConfigFile))
{
LogMessage("Could not find config: \"%s\"", sConfigFile);
return;
}
char map[PLATFORM_MAX_PATH];
GetCurrentMap(map, PLATFORM_MAX_PATH);
new Handle:fileHandle = OpenFile(sConfigFile, "r" );
char lineBuffer[256];
while( !IsEndOfFile( fileHandle ) && ReadFileLine( fileHandle, lineBuffer, sizeof( lineBuffer ) ) )
{
TrimString( lineBuffer );
if (StrEqual(lineBuffer, map, false))
{
g_is_zh_map = true;
break;
}
}
CloseHandle( fileHandle );
if (!g_is_zh_map)
{
return;
}
ReadZoneFile();
2024-05-05 00:47:27 +02:00
g_human_damage_addition = 1.0;
2023-11-08 22:09:42 +01:00
//resetting coordinates and setup.
for (int i = 0; i < MAXZONES; i++)
{
ping_coorindates[i][0] = 0.0;
ping_coorindates[i][1] = 0.0;
ping_coorindates[i][2] = 0.0;
zone_pings[i] = 0;
}
char g_cMapname[ZONENAMELENGTH];
GetCurrentMap(g_cMapname, sizeof(g_cMapname));
if (StrEqual(g_cMapname, "zm_cbble_b3", false))
{
ping_coorindates[0][0] = -1321.18;
ping_coorindates[0][1] = 635.93;
ping_coorindates[0][2] = 15.00;
ping_coorindates[1][0] = -1228.51;
ping_coorindates[1][1] = 1097.70;
ping_coorindates[1][2] = 15.00;
zone_pings[1] = 2; //first zone thats iterated.
ping_coorindates[2][0] = -1313.29;
ping_coorindates[2][1] = 481.83;
ping_coorindates[2][2] = 15.00;
ping_coorindates[3][0] = -1026.88;
ping_coorindates[3][1] = -543.23;
ping_coorindates[3][2] = 15.00 + 48.0; //higher terrain.
zone_pings[2] = 4; //second zone thats iterated, and so on and so on.
ping_coorindates[4][0] = -857.17;
ping_coorindates[4][1] = -549.33;
ping_coorindates[4][2] = 15.00 + 48.0;
ping_coorindates[5][0] = -319.23;
ping_coorindates[5][1] = -1091.23;
ping_coorindates[5][2] = 15.00 + 48.0; //higher terrain.
zone_pings[3] = 6;
ping_coorindates[6][0] = -178.41;
ping_coorindates[6][1] = -1096.69;
ping_coorindates[6][2] = 15.00 + 48.0;
ping_coorindates[7][0] = 135.89;
ping_coorindates[7][1] = 262.61;
ping_coorindates[7][2] = 15.00 + 48.0; //higher terrain.
zone_pings[4] = 8;
ping_coorindates[8][0] = 149.52;
ping_coorindates[8][1] = 477.08;
ping_coorindates[8][2] = 15.00 + 48.0;
ping_coorindates[9][0] = 144.99;
ping_coorindates[9][1] = 927.54;
ping_coorindates[9][2] = 15.00 + 48.0; //higher terrain.
zone_pings[5] = 10;
ping_coorindates[10][0] = 146.94;
ping_coorindates[10][1] = 1083.88;
ping_coorindates[10][2] = 15.00 + 48.0;
ping_coorindates[11][0] = -1074.73;
ping_coorindates[11][1] = 1087.19;
ping_coorindates[11][2] = 15.00;
zone_pings[6] = 12;
}
else if (StrEqual(g_cMapname, "cs_office", false))
{
//not the actual values atm
2023-11-09 23:35:05 +01:00
ping_coorindates[0][0] = 1454.83;
ping_coorindates[0][1] = 585.43;
ping_coorindates[0][2] = -160.96; //-95.00
zone_pings[1] = 1;
ping_coorindates[1][0] = 1405.29;
ping_coorindates[1][1] = 927.91;
ping_coorindates[1][2] = -160.96; //-95.00
ping_coorindates[2][0] = 890.47;
ping_coorindates[2][1] = 953.11;
ping_coorindates[2][2] = -160.96; //-95.00
zone_pings[2] = 3;
ping_coorindates[3][0] = 710.38;
ping_coorindates[3][1] = 958.05;
ping_coorindates[3][2] = -160.96; //-95.00
ping_coorindates[4][0] = 661.59;
ping_coorindates[4][1] = 117.65;
ping_coorindates[4][2] = -160.96; //-95.00
zone_pings[3] = 5;
ping_coorindates[5][0] = 108.23;
ping_coorindates[5][1] = 92.75;
ping_coorindates[5][2] = -160.96; //-95.00
ping_coorindates[6][0] = 96.99;
ping_coorindates[6][1] = -330.89;
ping_coorindates[6][2] = -160.96; //-95.00
zone_pings[4] = 7;
ping_coorindates[7][0] = -224.44;
ping_coorindates[7][1] = -499.20;
ping_coorindates[7][2] = -160.96; //-95.00
ping_coorindates[8][0] = 96.99;
ping_coorindates[8][1] = -501.89;
ping_coorindates[8][2] = -160.96; //-95.00
ping_coorindates[9][0] = 670.37;
ping_coorindates[9][1] = -512.63;
ping_coorindates[9][2] = -160.96; //-95.00
ping_coorindates[10][0] = 957.84;
ping_coorindates[10][1] = -506.23;
ping_coorindates[10][2] = -160.96; //-95.00
zone_pings[5] = 11;
ping_coorindates[11][0] = 673.70;
ping_coorindates[11][1] = -212.05;
ping_coorindates[11][2] = -160.96; //-95.00
zone_pings[6] = 12;
ping_coorindates[12][0] = 972.64;
ping_coorindates[12][1] = -151.94;
ping_coorindates[12][2] = -160.96; //-95.00
ping_coorindates[13][0] = 972.64;
ping_coorindates[13][1] = 98.05;
ping_coorindates[13][2] = -160.96; //-95.00
zone_pings[7] = 14;
ping_coorindates[14][0] = 1215.49;
ping_coorindates[14][1] = 526.93;
ping_coorindates[14][2] = -160.96; //-95.00
zone_pings[8] = 15;
ping_coorindates[15][0] = 1374.12;
ping_coorindates[15][1] = 171.48;
ping_coorindates[15][2] = -160.96; //-95.00
zone_pings[9] = 16;
ping_coorindates[16][0] = 1775.58;
ping_coorindates[16][1] = 151.76;
ping_coorindates[16][2] = -160.96; //-95.00
ping_coorindates[17][0] = 1769.61;
ping_coorindates[17][1] = -462.40;
ping_coorindates[17][2] = -160.96; //-95.00
zone_pings[10] = 18;
ping_coorindates[18][0] = 1461.20;
ping_coorindates[18][1] = -480.59;
ping_coorindates[18][2] = -160.96; //-95.00
zone_pings[11] = 19;
ping_coorindates[19][0] = 1388.60;
ping_coorindates[19][1] = -178.14;
ping_coorindates[19][2] = -160.96; //-95.00
zone_pings[12] = 20;
ping_coorindates[20][0] = 966.46;
ping_coorindates[20][1] = -893.44;
ping_coorindates[20][2] = -160.96; //-95.00
zone_pings[13] = 21;
ping_coorindates[21][0] = 945.39;
ping_coorindates[21][1] = -1136.16;
ping_coorindates[21][2] = -190.96; //-95.00
ping_coorindates[22][0] = 716.53;
ping_coorindates[22][1] = -1882.94;
ping_coorindates[22][2] = -325.00; //-95.00
ping_coorindates[23][0] = 645.86;
ping_coorindates[23][1] = -1426.71;
ping_coorindates[23][2] = -280.00; //-95.00
zone_pings[14] = 24;
ping_coorindates[24][0] = 426.91;
ping_coorindates[24][1] = -891.43;
ping_coorindates[24][2] = -225.00; //-95.00
zone_pings[15] = 25;
ping_coorindates[25][0] = 421.71;
ping_coorindates[25][1] = -1408.24;
ping_coorindates[25][2] = -280.00; //-95.00
zone_pings[16] = 26;
ping_coorindates[26][0] = -1211.93;
ping_coorindates[26][1] = -1842.44;
ping_coorindates[26][2] = -335.00; //-95.00
ping_coorindates[27][0] = 401.20;
ping_coorindates[27][1] = -1872.70;
ping_coorindates[27][2] = -335.00; //-95.00
zone_pings[17] = 28;
ping_coorindates[28][0] = -1197.14;
ping_coorindates[28][1] = -1292.59;
ping_coorindates[28][2] = -335.00; //-95.00
zone_pings[18] = 29;
ping_coorindates[29][0] = -1603.39;
ping_coorindates[29][1] = -1383.98;
2023-11-10 15:11:54 +01:00
ping_coorindates[29][2] = -325.00; //-95.00
zone_pings[19] = 30;
ping_coorindates[30][0] = -1565.33;
ping_coorindates[30][1] = -648.76;
ping_coorindates[30][2] = -240.00; //-95.00
ping_coorindates[31][0] = -1578.84;
ping_coorindates[31][1] = -234.01;
ping_coorindates[31][2] = -240.00; //-95.00
zone_pings[20] = 32;
ping_coorindates[32][0] = -896.58;
ping_coorindates[32][1] = -1404.99;
2023-11-10 15:11:54 +01:00
ping_coorindates[32][2] = -325.00; //-95.00
zone_pings[21] = 33;
ping_coorindates[33][0] = -974.14;
ping_coorindates[33][1] = 249.19;
ping_coorindates[33][2] = -175.00; //-95.00
ping_coorindates[34][0] = -1061.58;
ping_coorindates[34][1] = -30.77;
ping_coorindates[34][2] = -335.00; //-95.00
ping_coorindates[35][0] = -1174.68;
ping_coorindates[35][1] = -738.16;
2023-11-10 15:11:54 +01:00
ping_coorindates[35][2] = -325.00; //-95.00
zone_pings[22] = 36;
2023-11-10 15:00:25 +01:00
ping_coorindates[36][0] = -319.48;
ping_coorindates[36][1] = -790.84;
ping_coorindates[36][2] = -280.00; //-95.00
ping_coorindates[37][0] = 91.64;
ping_coorindates[37][1] = -843.01;
ping_coorindates[37][2] = -225.00; //-95.00
zone_pings[23] = 38;
ping_coorindates[38][0] = -561.65;
ping_coorindates[38][1] = -267.70;
ping_coorindates[38][2] = -160.00; //-95.00
ping_coorindates[39][0] = -184.50;
ping_coorindates[39][1] = 100.97;
2023-11-10 15:11:54 +01:00
ping_coorindates[39][2] = -160.00; //-95.00
2023-11-10 15:00:25 +01:00
ping_coorindates[40][0] = -855.69;
ping_coorindates[40][1] = 250.49;
2023-11-10 15:11:54 +01:00
ping_coorindates[40][2] = -160.00; //-95.00
2023-11-10 15:00:25 +01:00
zone_pings[24] = 41;
ping_coorindates[41][0] = -589.94;
ping_coorindates[41][1] = 614.19;
2023-11-10 15:11:54 +01:00
ping_coorindates[41][2] = -160.00; //-95.00
2023-11-10 15:00:25 +01:00
zone_pings[25] = 42;
ping_coorindates[42][0] = -1131.05;
ping_coorindates[42][1] = 533.00;
ping_coorindates[42][2] = -325.00; //-95.00
ping_coorindates[43][0] = -960.03;
ping_coorindates[43][1] = 555.42;
ping_coorindates[43][2] = -175.00; //-95.00
zone_pings[26] = 44;
ping_coorindates[44][0] = -728.83;
ping_coorindates[44][1] = 535.22;
ping_coorindates[44][2] = -360.00; //-95.00
ping_coorindates[45][0] = -728.83;
ping_coorindates[45][1] = -32.00;
ping_coorindates[45][2] = -360.00; //-95.00
zone_pings[27] = 46;
2023-11-08 22:09:42 +01:00
}
}
stock void ReplaceStrings(char[] str, char[] strReplace)
{
char l_cstrFix[MAXZONES];
Format(l_cstrFix, sizeof(l_cstrFix), str);
ReplaceString(l_cstrFix, sizeof(l_cstrFix), "\"", "");
ReplaceString(l_cstrFix, sizeof(l_cstrFix), strReplace, "");
TrimString(l_cstrFix);
Format(str, sizeof(l_cstrFix), l_cstrFix);
}
public void SpawnPing(int skin, float pos[3], int index)
{
if (!g_is_zh_map)
{
return;
}
2023-11-08 22:09:42 +01:00
int Ent = CreateEntityByName("prop_dynamic");
SetEntityModel(Ent, "models/unloze/unloze_ping.mdl");
DispatchKeyValue(Ent, "modelscale", "1.5");
if (skin == 1) //fought over (skull)
SetVariantString("1");
else if (skin == 2) //CT controlled (moon)
SetVariantString("2");
else if (skin == 3) //ZM controlled (cross)
SetVariantString("3");
AcceptEntityInput(Ent, "Skin");
DispatchSpawn(Ent);
TeleportEntity(Ent, pos, NULL_VECTOR, NULL_VECTOR);
ping_ents[index] = Ent;
}
//----------------------------------------------------------------------------------------------------
// Purpose:
//----------------------------------------------------------------------------------------------------
public void RemovePing(int index)
{
if (!g_is_zh_map)
{
return;
}
2023-11-08 22:09:42 +01:00
if (ping_ents[index] != -1 && IsValidEdict(ping_ents[index]))
{
char m_szClassname[64];
GetEdictClassname(ping_ents[index], m_szClassname, sizeof(m_szClassname));
if (strcmp("prop_dynamic", m_szClassname)==0)
{
AcceptEntityInput(ping_ents[index], "Kill");
}
}
ping_ents[index] = -1;
}
public void UpdateMarkers()
{
if (!g_is_zh_map)
{
return;
}
2023-11-08 22:09:42 +01:00
//this only works because of knowing that order of ping coordinates match with zone order.
for (int i = 0; i <= g_zoneCount; i++)
{
//PrintToChatAll("g_cZones_CT_count[i]: %i", g_cZones_CT_count[i]);
//PrintToChatAll("g_cZones_ZM_count[i]: %i", g_cZones_ZM_count[i]);
if (g_cZones_CT_count[i] > 0 && g_cZones_ZM_count[i] > 0)
{
//both humans and ZM in zone.
if (g_iZone_fought_or_ct_controlled[i] != 1)
{
handle_pings(i, 1);
g_iZone_fought_or_ct_controlled[i] = 1; //indicating zone is fought over
}
}
else if (g_cZones_CT_count[i] > 0)
{
//only humans in zone
//the zone just went from white (humans and zm in zone) to blue (only humans now in zone)
if (g_iZone_fought_or_ct_controlled[i] != 2)
{
g_iZone_fought_or_ct_controlled[i] = 2;
reward_ct_zone_points(i);
handle_pings(i, 2);
}
}
else if (g_cZones_ZM_count[i] > 0)
{
if (g_iZone_fought_or_ct_controlled[i] != 3)
{
g_iZone_fought_or_ct_controlled[i] = 3;
//zm controlled zone
2024-05-05 00:47:27 +02:00
reward_zm_zone_points(i);
2023-11-08 22:09:42 +01:00
handle_pings(i, 3);
}
}
else
{
if (g_iLast_Client_In_Zone[i] != 0)
{
int last_client_in_zone = g_iLast_Client_In_Zone[i];
if (IsValidClient(last_client_in_zone) && IsPlayerAlive(last_client_in_zone) && GetClientTeam(last_client_in_zone) == CS_TEAM_CT)
{
//last guy was a CT
g_iZone_fought_or_ct_controlled[i] = 2;
handle_pings(i, 2);
}
else if (IsValidClient(last_client_in_zone) && IsPlayerAlive(last_client_in_zone) && GetClientTeam(last_client_in_zone) == CS_TEAM_T)
{
//last guy was a ZM
g_iZone_fought_or_ct_controlled[i] = 3;
handle_pings(i, 3);
}
else
{
//the client who was last here might have left or went spectate.
handle_pings(i, 1);
g_iZone_fought_or_ct_controlled[i] = 1; //indicating zone is fought over
}
}
else
{
//no client was in the zone in this round yet. setting it to the skull ping.
handle_pings(i, 1);
g_iZone_fought_or_ct_controlled[i] = 1; //indicating zone is fought over
}
}
}
}
2024-05-05 00:47:27 +02:00
public void reward_zm_zone_points(int i)
{
if (!g_is_zh_map)
{
return;
}
2024-05-05 00:47:27 +02:00
for (int j = 0; j < MaxClients; j++)
{
//is validclient, is ct, is alive, is inside the zone that just changed from fought to T controlled
if (IsValidClient(j) && GetClientTeam(j) == CS_TEAM_T && IsPlayerAlive(j) && g_client_in_zone[j] == i)
{
LH_LogPlayerEvent(j, "triggered", "zh_h_zone_take_over_simple", false);
//rewarding empty zone take over with at least 1 frag
int frags = GetClientFrags(j);
SetEntProp(j, Prop_Data, "m_iFrags", frags + 1);
}
}
}
2023-11-08 22:09:42 +01:00
public void reward_ct_zone_points(int i)
{
if (!g_is_zh_map)
{
return;
}
2023-11-08 22:09:42 +01:00
for (int j = 0; j < MaxClients; j++)
{
//is validclient, is ct, is alive, is inside the zone that just changed from fought to CT controlled
if (IsValidClient(j) && GetClientTeam(j) == CS_TEAM_CT && IsPlayerAlive(j) && g_client_in_zone[j] == i)
{
int damage_done_inside_fought_zone = PlayerRankings_GetClientDamage(j) - g_iCT_Damage_in_zone[j];
g_iCT_Damage_in_zone[j] = PlayerRankings_GetClientDamage(j);
//so uh, lets say the zone becomes CT, then fought over again, then CT again without the guy ever leaving it.
//this should ensure it only counts for what the guy did in damage since the takeover
if (damage_done_inside_fought_zone > 0)
{
2024-05-05 00:47:27 +02:00
int frags = GetClientFrags(j);
2023-11-08 22:09:42 +01:00
// Damage 0-1000 inside Zone
2024-05-05 00:47:27 +02:00
if (damage_done_inside_fought_zone < 200)
2023-11-08 22:09:42 +01:00
{
LH_LogPlayerEvent(j, "triggered", "zh_h_zone_take_over_1", false);
2024-05-05 00:47:27 +02:00
SetEntProp(j, Prop_Data, "m_iFrags", frags + 5);
2023-11-08 22:09:42 +01:00
}
2024-05-05 00:47:27 +02:00
else if (damage_done_inside_fought_zone < 400)
2023-11-08 22:09:42 +01:00
{
LH_LogPlayerEvent(j, "triggered", "zh_h_zone_take_over_2", false);
2024-05-05 00:47:27 +02:00
SetEntProp(j, Prop_Data, "m_iFrags", frags + 10);
2023-11-08 22:09:42 +01:00
}
2024-05-05 00:47:27 +02:00
else if (damage_done_inside_fought_zone < 800)
2023-11-08 22:09:42 +01:00
{
LH_LogPlayerEvent(j, "triggered", "zh_h_zone_take_over_3", false);
2024-05-05 00:47:27 +02:00
SetEntProp(j, Prop_Data, "m_iFrags", frags + 15);
2023-11-08 22:09:42 +01:00
}
2024-05-05 00:47:27 +02:00
else if (damage_done_inside_fought_zone < 1200)
2023-11-08 22:09:42 +01:00
{
LH_LogPlayerEvent(j, "triggered", "zh_h_zone_take_over_4", false);
2024-05-05 00:47:27 +02:00
SetEntProp(j, Prop_Data, "m_iFrags", frags + 20);
2023-11-08 22:09:42 +01:00
}
2024-05-05 00:47:27 +02:00
else if (damage_done_inside_fought_zone < 1500)
2023-11-08 22:09:42 +01:00
{
LH_LogPlayerEvent(j, "triggered", "zh_h_zone_take_over_5", false);
2024-05-05 00:47:27 +02:00
SetEntProp(j, Prop_Data, "m_iFrags", frags + 25);
2023-11-08 22:09:42 +01:00
}
else
{
LH_LogPlayerEvent(j, "triggered", "zh_h_zone_take_over_6", false);
2024-05-05 00:47:27 +02:00
SetEntProp(j, Prop_Data, "m_iFrags", frags + 30);
2023-11-08 22:09:42 +01:00
}
}
2024-05-05 00:47:27 +02:00
//this change might be very bad. it might overspam people with points if a zone constantly switches from controlled by CT
//to instead be fought over back and forth. but at least it makes it worth it to take over zones.
LH_LogPlayerEvent(j, "triggered", "zh_h_zone_take_over_simple", false);
//rewarding empty zone take over with at least 1 frag
int frags = GetClientFrags(j);
SetEntProp(j, Prop_Data, "m_iFrags", frags + 1);
2023-11-08 22:09:42 +01:00
}
}
2023-01-01 23:39:45 +01:00
}