954 lines
33 KiB
SourcePawn
954 lines
33 KiB
SourcePawn
#include <sourcemod>
|
|
#include <sdktools>
|
|
#include <unloze_zones>
|
|
#include <cstrike>
|
|
#include <PlayerRankings>
|
|
#include <hlstatsx_loghelper>
|
|
#define MAXZONES 66
|
|
#define ZONENAMELENGTH 256
|
|
int g_bBlockRespawn[MAXPLAYERS+1];
|
|
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];
|
|
|
|
bool round_start_delay;
|
|
|
|
//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];
|
|
float g_fStartPos[MAXZONES][3];
|
|
float g_fEndPos[MAXZONES][3];
|
|
ConVar g_hRespawnTreshold;
|
|
ConVar g_hHealthRegenZM;
|
|
ConVar g_hHealthRegenAmount;
|
|
Handle hText;
|
|
Handle g_hZMZoneTimer = null;
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public Plugin myinfo =
|
|
{
|
|
name = "zombie hunting plugin",
|
|
author = "jenz",
|
|
description = "Disables respawning on zombie hunting maps after some deaths, adds zoning",
|
|
version = "2.0.0",
|
|
url = "www.unloze.com"
|
|
};
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void OnPluginStart()
|
|
{
|
|
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;
|
|
//timer for ZM zone benefits
|
|
g_hZMZoneTimer = CreateTimer(5.0, give_zm_zone_boosts, _, TIMER_REPEAT);
|
|
}
|
|
|
|
public Action give_zm_zone_boosts(Handle hTimer)
|
|
{
|
|
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;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void OnClientDisconnect(int client)
|
|
{
|
|
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;
|
|
}
|
|
|
|
public void adjust_clients()
|
|
{
|
|
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)
|
|
{
|
|
round_start_delay = true;
|
|
bool found_alive_zm = false;
|
|
for (int client = 0; client < MaxClients; client++)
|
|
{
|
|
if (IsValidClient(client) && GetClientTeam(client) == CS_TEAM_T && IsPlayerAlive(client))
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
PrintToChatAll("Humans failed!");
|
|
PrintToChatAll("Humans failed!");
|
|
PrintToChatAll("Humans failed!");
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void OnRoundStart(Event hEvent, const char[] sEvent, bool bDontBroadcast)
|
|
{
|
|
for (int client = 0; client < MaxClients; client++)
|
|
{
|
|
g_bBlockRespawn[client] = 0;
|
|
if (IsValidClient(client))
|
|
{
|
|
g_iCT_Damage_in_zone[client] = 0;
|
|
}
|
|
g_client_in_zone[client] = -1;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
public Action enable_pings(Handle timer, any data)
|
|
{
|
|
round_start_delay = false;
|
|
return Plugin_Handled;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// Purpose:
|
|
//----------------------------------------------------------------------------------------------------
|
|
public void OnClientDeath(Event hEvent, const char[] sEvent, bool bDontBroadcast)
|
|
{
|
|
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]++;
|
|
}
|
|
|
|
public void ZR_OnClientInfected(int client, int attacker, bool motherInfect, bool respawnOverride, bool respawn)
|
|
{
|
|
int index = g_client_in_zone[client];
|
|
if (index != -1)
|
|
{
|
|
//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();
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
// 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 pos[3])
|
|
{
|
|
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.IntValue)
|
|
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) == 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);
|
|
}
|
|
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)
|
|
{
|
|
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 (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;
|
|
}
|
|
return Plugin_Handled;
|
|
}
|
|
|
|
public void unloze_zoneLeave(int client, char[] zone)
|
|
{
|
|
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)
|
|
{
|
|
if (g_cZones_CT_count[index] > 0)
|
|
{
|
|
g_cZones_CT_count[index]--;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (g_cZones_ZM_count[index] > 0)
|
|
{
|
|
g_cZones_ZM_count[index]--;
|
|
}
|
|
}
|
|
SetEntityRenderColor(client, 255, 255, 255, 255);
|
|
UpdateMarkers();
|
|
}
|
|
|
|
public void unloze_zoneCreated()
|
|
{
|
|
ReadZoneFile();
|
|
}
|
|
|
|
public Action retry_zoneEntry(Handle timer, DataPack data)
|
|
{
|
|
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)
|
|
{
|
|
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)
|
|
{
|
|
//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;
|
|
}
|
|
for (int i = 0; i < g_zoneCount; i++)
|
|
{
|
|
if (StrEqual(g_cZones[i], zone))
|
|
{
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
g_client_in_zone[client] = index;
|
|
|
|
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();
|
|
}
|
|
|
|
public void handle_pings(int i, int pingtype)
|
|
{
|
|
if (round_start_delay)
|
|
{
|
|
return; //preventing pings from spawning exactly on roundStart as it might cause too many entities
|
|
}
|
|
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);
|
|
SpawnPing(pingtype, ping_coorindates[j], j);
|
|
for (int client = 0; client < MaxClients; client++)
|
|
{
|
|
if (IsValidClient(client) && g_client_in_zone[client] == i)
|
|
{
|
|
display_hud_text(i, client);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void display_hud_text(int index, int client)
|
|
{
|
|
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");
|
|
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()
|
|
{
|
|
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)
|
|
{
|
|
Handle kv = CreateKeyValues("Zones");
|
|
KeyValuesToFile(kv, g_cConfigZones);
|
|
CloseHandle(kv);
|
|
delete l_hZoneFile;
|
|
return Plugin_Handled;
|
|
}
|
|
while (!IsEndOfFile(l_hZoneFile) && ReadFileLine(l_hZoneFile, l_cLine, sizeof(l_cLine)))
|
|
{
|
|
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++;
|
|
}
|
|
}
|
|
g_zoneCount = i_zoneTemp;
|
|
delete l_hZoneFile;
|
|
return Plugin_Handled;
|
|
}
|
|
|
|
public void OnMapStart()
|
|
{
|
|
//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
|
|
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;
|
|
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;
|
|
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;
|
|
ping_coorindates[35][2] = -325.00; //-95.00
|
|
zone_pings[22] = 36;
|
|
|
|
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;
|
|
ping_coorindates[39][2] = -160.00; //-95.00
|
|
ping_coorindates[40][0] = -855.69;
|
|
ping_coorindates[40][1] = 250.49;
|
|
ping_coorindates[40][2] = -160.00; //-95.00
|
|
zone_pings[24] = 41;
|
|
|
|
ping_coorindates[41][0] = -589.94;
|
|
ping_coorindates[41][1] = 614.19;
|
|
ping_coorindates[41][2] = -160.00; //-95.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;
|
|
}
|
|
}
|
|
|
|
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)
|
|
{
|
|
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 (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()
|
|
{
|
|
//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
|
|
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
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//change to points for zone taker over simply, add gamescore +5 points for zone takeover.
|
|
public void reward_ct_zone_points(int i)
|
|
{
|
|
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)
|
|
{
|
|
// Damage 0-1000 inside Zone
|
|
if (damage_done_inside_fought_zone < 1000)
|
|
{
|
|
LH_LogPlayerEvent(j, "triggered", "zh_h_zone_take_over_1", false);
|
|
}
|
|
else if (damage_done_inside_fought_zone < 3000)
|
|
{
|
|
LH_LogPlayerEvent(j, "triggered", "zh_h_zone_take_over_2", false);
|
|
}
|
|
else if (damage_done_inside_fought_zone < 6000)
|
|
{
|
|
LH_LogPlayerEvent(j, "triggered", "zh_h_zone_take_over_3", false);
|
|
}
|
|
else if (damage_done_inside_fought_zone < 9000)
|
|
{
|
|
LH_LogPlayerEvent(j, "triggered", "zh_h_zone_take_over_4", false);
|
|
}
|
|
else if (damage_done_inside_fought_zone < 15000)
|
|
{
|
|
LH_LogPlayerEvent(j, "triggered", "zh_h_zone_take_over_5", false);
|
|
}
|
|
else
|
|
{
|
|
LH_LogPlayerEvent(j, "triggered", "zh_h_zone_take_over_6", false);
|
|
}
|
|
int frags = GetClientFrags(j);
|
|
SetEntProp(j, Prop_Data, "m_iFrags", frags + 5);
|
|
LH_LogPlayerEvent(j, "triggered", "zh_h_zone_take_over_simple", false);
|
|
}
|
|
}
|
|
}
|
|
}
|