Merged heads.
This commit is contained in:
commit
258c839a27
70
cstrike/addons/sourcemod/configs/zr/hitgroups.txt
Normal file
70
cstrike/addons/sourcemod/configs/zr/hitgroups.txt
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
// Hitgroups
|
||||||
|
//
|
||||||
|
// Format
|
||||||
|
//
|
||||||
|
// "hitgroup index" // Index of the hitgroup (listed below)
|
||||||
|
// {
|
||||||
|
// "name" "name of hitgroup" // Redundant as of now, used for readability.
|
||||||
|
// "knockback" "1.0" (default) // The knockback multiplier for the hitgroup
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Notes:
|
||||||
|
//
|
||||||
|
// A missing config setting will be assumed to be its default value (documented above).
|
||||||
|
|
||||||
|
"hitgroups" // Counter-Strike: Source hitgroups
|
||||||
|
{
|
||||||
|
"0"
|
||||||
|
{
|
||||||
|
"name" "Generic"
|
||||||
|
"knockback" "1.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
"1"
|
||||||
|
{
|
||||||
|
"name" "Head"
|
||||||
|
"knockback" "2.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
"2"
|
||||||
|
{
|
||||||
|
"name" "Chest"
|
||||||
|
"knockback" "1.3"
|
||||||
|
}
|
||||||
|
|
||||||
|
"3"
|
||||||
|
{
|
||||||
|
"name" "Stomach"
|
||||||
|
"knockback" "1.2"
|
||||||
|
}
|
||||||
|
|
||||||
|
"4"
|
||||||
|
{
|
||||||
|
"name" "Left Arm"
|
||||||
|
"knockback" "1.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
"5"
|
||||||
|
{
|
||||||
|
"name" "Right Arm"
|
||||||
|
"knockback" "1.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
"6"
|
||||||
|
{
|
||||||
|
"name" "Left Leg"
|
||||||
|
"knockback" "0.9"
|
||||||
|
}
|
||||||
|
|
||||||
|
"7"
|
||||||
|
{
|
||||||
|
"name" "Right Leg"
|
||||||
|
"knockback" "0.9"
|
||||||
|
}
|
||||||
|
|
||||||
|
"10"
|
||||||
|
{
|
||||||
|
"name" "Gear"
|
||||||
|
"knockback" "1.0"
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,12 @@
|
|||||||
"Games"
|
"Games"
|
||||||
{
|
{
|
||||||
"cstrike"
|
"#default"
|
||||||
{
|
{
|
||||||
|
"#supported"
|
||||||
|
{
|
||||||
|
"game" "cstrike"
|
||||||
|
}
|
||||||
|
|
||||||
"Offsets"
|
"Offsets"
|
||||||
{
|
{
|
||||||
"RemoveAllItems"
|
"RemoveAllItems"
|
||||||
@ -9,17 +14,20 @@
|
|||||||
"windows" "283"
|
"windows" "283"
|
||||||
"linux" "284"
|
"linux" "284"
|
||||||
}
|
}
|
||||||
|
|
||||||
"EyePosition"
|
"EyePosition"
|
||||||
{
|
{
|
||||||
"windows" "117"
|
"windows" "117"
|
||||||
"linux" "118"
|
"linux" "118"
|
||||||
}
|
}
|
||||||
|
|
||||||
"EyeAngles"
|
"EyeAngles"
|
||||||
{
|
{
|
||||||
"windows" "206"
|
"windows" "206"
|
||||||
"linux" "207"
|
"linux" "207"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"Signatures"
|
"Signatures"
|
||||||
{
|
{
|
||||||
"TerminateRound"
|
"TerminateRound"
|
||||||
@ -28,6 +36,13 @@
|
|||||||
"windows" "\x83\xEC\x18\x53\x55\x8B\xD9\x8B\x4C\x24\x28\x56\x57\x33\xF6\x8D"
|
"windows" "\x83\xEC\x18\x53\x55\x8B\xD9\x8B\x4C\x24\x28\x56\x57\x33\xF6\x8D"
|
||||||
"linux" "@_ZN12CCSGameRules14TerminateRoundEfi"
|
"linux" "@_ZN12CCSGameRules14TerminateRoundEfi"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"CSWeaponDrop"
|
||||||
|
{
|
||||||
|
"library" "server"
|
||||||
|
"windows" "\x2A\x2A\x2A\x2A\x2A\x2A\x53\x55\x56\x57\x8B\xBC\x24\x40\x01\x00\x00\x32\xDB\x85\xFF\x8B\xF1\x0F"
|
||||||
|
"linux" "@_ZN9CCSPlayer12CSWeaponDropEP17CBaseCombatWeaponbb"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -36,9 +36,15 @@
|
|||||||
// Weapons
|
// Weapons
|
||||||
#include "zr/weapons/weapons"
|
#include "zr/weapons/weapons"
|
||||||
|
|
||||||
|
// Hitgroups
|
||||||
|
#include "zr/hitgroups"
|
||||||
|
|
||||||
// Knockback
|
// Knockback
|
||||||
#include "zr/knockback"
|
#include "zr/knockback"
|
||||||
|
|
||||||
|
// Spawn protect
|
||||||
|
#include "zr/spawnprotect"
|
||||||
|
|
||||||
#include "zr/zadmin"
|
#include "zr/zadmin"
|
||||||
#include "zr/damagecontrol"
|
#include "zr/damagecontrol"
|
||||||
#include "zr/commands"
|
#include "zr/commands"
|
||||||
@ -126,7 +132,8 @@ public OnMapStart()
|
|||||||
|
|
||||||
// Forward event to modules.
|
// Forward event to modules.
|
||||||
ClassLoad();
|
ClassLoad();
|
||||||
WeaponsOnMapStart();
|
WeaponsLoad();
|
||||||
|
HitgroupsLoad();
|
||||||
Anticamp_Startup();
|
Anticamp_Startup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle to keep track of AntiStickTimer
|
* Handle to keep track of AntiStickTimer.
|
||||||
*/
|
*/
|
||||||
new Handle:tAntiStick = INVALID_HANDLE;
|
new Handle:tAntiStick = INVALID_HANDLE;
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ AntiStickReset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a player is currently stuck within another player
|
* Checks if a player is currently stuck within another player.
|
||||||
*
|
*
|
||||||
* @param client The client index.
|
* @param client The client index.
|
||||||
* @return The client index of the other stuck player, -1 when
|
* @return The client index of the other stuck player, -1 when
|
||||||
@ -61,11 +61,11 @@ AntiStickIsStuck(client)
|
|||||||
|
|
||||||
GetClientAbsOrigin(client, clientloc);
|
GetClientAbsOrigin(client, clientloc);
|
||||||
|
|
||||||
// x = client index
|
// x = client index.
|
||||||
new maxplayers = GetMaxClients();
|
new maxplayers = GetMaxClients();
|
||||||
for (new x = 1; x <= maxplayers; x++)
|
for (new x = 1; x <= maxplayers; x++)
|
||||||
{
|
{
|
||||||
// Validate player is in-game, alive, and isn't the player being checked ('client')
|
// Validate player is in-game, alive, and isn't the player being checked. ('client')
|
||||||
if (!IsClientInGame(x) || !IsPlayerAlive(x) || x == client)
|
if (!IsClientInGame(x) || !IsPlayerAlive(x) || x == client)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@ -82,7 +82,7 @@ AntiStickIsStuck(client)
|
|||||||
new Float:eyeloc[3];
|
new Float:eyeloc[3];
|
||||||
GetPlayerEyePosition(client, eyeloc);
|
GetPlayerEyePosition(client, eyeloc);
|
||||||
|
|
||||||
// Get the distance between the eyes and feet and subtract the stack "view crush"
|
// Get the distance between the eyes and feet and subtract the stack "view crush."
|
||||||
new Float:eyedistance = FloatAbs(eyeloc[2] - clientloc[2]) - PLAYER_HULL_STACK_OFFSET;
|
new Float:eyedistance = FloatAbs(eyeloc[2] - clientloc[2]) - PLAYER_HULL_STACK_OFFSET;
|
||||||
new Float:zdistance = FloatAbs(stuckloc[2] - clientloc[2]);
|
new Float:zdistance = FloatAbs(stuckloc[2] - clientloc[2]);
|
||||||
|
|
||||||
@ -107,13 +107,13 @@ public Action:AntiStickTimer(Handle:timer)
|
|||||||
new maxplayers = GetMaxClients();
|
new maxplayers = GetMaxClients();
|
||||||
for (new x = 1; x <= maxplayers; x++)
|
for (new x = 1; x <= maxplayers; x++)
|
||||||
{
|
{
|
||||||
// Validate player is in-game and alive
|
// Validate player is in-game and alive.
|
||||||
if (!IsClientInGame(x) || !IsPlayerAlive(x))
|
if (!IsClientInGame(x) || !IsPlayerAlive(x))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop if the player isn't stuck
|
// Stop if the player isn't stuck.
|
||||||
new stuckindex = AntiStickIsStuck(x);
|
new stuckindex = AntiStickIsStuck(x);
|
||||||
if (stuckindex == -1)
|
if (stuckindex == -1)
|
||||||
{
|
{
|
||||||
@ -138,23 +138,24 @@ public Action:AntiStickTimer(Handle:timer)
|
|||||||
* Repeated timer function.
|
* Repeated timer function.
|
||||||
* Re-solidifies a player being unstuck.
|
* Re-solidifies a player being unstuck.
|
||||||
*
|
*
|
||||||
* @param index The client index.
|
* @param timer The timer handle.
|
||||||
|
* @param client The client index.
|
||||||
*/
|
*/
|
||||||
public Action:AntiStickSolidify(Handle:timer, any:index)
|
public Action:AntiStickSolidify(Handle:timer, any:client)
|
||||||
{
|
{
|
||||||
// Validate player is in-game, alive, and is being unstuck
|
// Validate player is in-game, alive, and is being unstuck.
|
||||||
if (!IsClientInGame(index) || !IsPlayerAlive(index) || CanCollide(index))
|
if (!IsClientInGame(client) || !IsPlayerAlive(client) || CanCollide(client))
|
||||||
{
|
{
|
||||||
return Plugin_Stop;
|
return Plugin_Stop;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop if the player is still stuck
|
// Stop if the player is still stuck.
|
||||||
if (AntiStickIsStuck(index) > -1)
|
if (AntiStickIsStuck(client) > -1)
|
||||||
{
|
{
|
||||||
return Plugin_Continue;
|
return Plugin_Continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
NoCollide(index, false);
|
NoCollide(client, false);
|
||||||
|
|
||||||
return Plugin_Stop;
|
return Plugin_Stop;
|
||||||
}
|
}
|
||||||
|
@ -169,6 +169,7 @@ public Action:PlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast)
|
|||||||
SetPlayerFOV(index, 90);
|
SetPlayerFOV(index, 90);
|
||||||
ClientCommand(index, "r_screenoverlay \"\"");
|
ClientCommand(index, "r_screenoverlay \"\"");
|
||||||
|
|
||||||
|
// Stop here if client isn't on a team.
|
||||||
new team = GetClientTeam(index);
|
new team = GetClientTeam(index);
|
||||||
if (team != CS_TEAM_T && team != CS_TEAM_CT)
|
if (team != CS_TEAM_T && team != CS_TEAM_CT)
|
||||||
{
|
{
|
||||||
@ -186,7 +187,6 @@ public Action:PlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast)
|
|||||||
NightVisionOn(index, false);
|
NightVisionOn(index, false);
|
||||||
NightVision(index, false);
|
NightVision(index, false);
|
||||||
|
|
||||||
pProtect[index] = false;
|
|
||||||
if (zombieSpawned)
|
if (zombieSpawned)
|
||||||
{
|
{
|
||||||
if (team == CS_TEAM_T)
|
if (team == CS_TEAM_T)
|
||||||
@ -194,34 +194,6 @@ public Action:PlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast)
|
|||||||
CS_SwitchTeam(index, CS_TEAM_CT);
|
CS_SwitchTeam(index, CS_TEAM_CT);
|
||||||
CS_RespawnPlayer(index);
|
CS_RespawnPlayer(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
new protect = GetConVarInt(gCvars[CVAR_PROTECT]);
|
|
||||||
if (protect > 0)
|
|
||||||
{
|
|
||||||
decl String:respawnteam[32];
|
|
||||||
GetConVarString(gCvars[CVAR_RESPAWN_TEAM], respawnteam, sizeof(respawnteam));
|
|
||||||
|
|
||||||
if (!StrEqual(respawnteam, "zombie", false) && !(GetConVarBool(gCvars[CVAR_SUICIDE_WORLD_DAMAGE]) && gKilledByWorld[index]))
|
|
||||||
{
|
|
||||||
SetPlayerAlpha(index, 0);
|
|
||||||
SetPlayerSpeed(index, 600.0);
|
|
||||||
pProtect[index] = true;
|
|
||||||
|
|
||||||
ZR_PrintToChat(index, "Spawn protection begin", protect);
|
|
||||||
ZR_PrintCenterText(index, "Spawn protection begin", protect);
|
|
||||||
|
|
||||||
if (tHandles[index][TPROTECT] != INVALID_HANDLE)
|
|
||||||
{
|
|
||||||
KillTimer(tHandles[index][TPROTECT]);
|
|
||||||
}
|
|
||||||
|
|
||||||
pTimeLeft[index] = protect;
|
|
||||||
|
|
||||||
PrintHintText(index, "%d", pTimeLeft[index]);
|
|
||||||
|
|
||||||
tHandles[index][TPROTECT] = CreateTimer(1.0, ProtectTimer, index, TIMER_FLAG_NO_MAPCHANGE|TIMER_REPEAT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -230,6 +202,7 @@ public Action:PlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast)
|
|||||||
|
|
||||||
// Forward event to modules.
|
// Forward event to modules.
|
||||||
ClassOnClientSpawn(index);
|
ClassOnClientSpawn(index);
|
||||||
|
SpawnProtectPlayerSpawn(index);
|
||||||
ZTeleClientSpawned(index);
|
ZTeleClientSpawned(index);
|
||||||
|
|
||||||
ZR_PrintToChat(index, "!zmenu reminder");
|
ZR_PrintToChat(index, "!zmenu reminder");
|
||||||
@ -240,13 +213,15 @@ public Action:PlayerHurt(Handle:event, const String:name[], bool:dontBroadcast)
|
|||||||
new index = GetClientOfUserId(GetEventInt(event, "userid"));
|
new index = GetClientOfUserId(GetEventInt(event, "userid"));
|
||||||
new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
|
new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
|
||||||
|
|
||||||
|
new hitgroup = GetEventInt(event, "hitgroup");
|
||||||
|
|
||||||
new dmg_health = GetEventInt(event, "dmg_health");
|
new dmg_health = GetEventInt(event, "dmg_health");
|
||||||
|
|
||||||
decl String:weapon[32];
|
decl String:weapon[32];
|
||||||
GetEventString(event, "weapon", weapon, sizeof(weapon));
|
GetEventString(event, "weapon", weapon, sizeof(weapon));
|
||||||
|
|
||||||
// Forward event to modules.
|
// Forward event to modules.
|
||||||
KnockbackPlayerHurt(index, attacker, weapon, dmg_health);
|
KnockbackPlayerHurt(index, attacker, weapon, hitgroup, dmg_health);
|
||||||
|
|
||||||
// Check if the attacker is a player.
|
// Check if the attacker is a player.
|
||||||
if (attacker != 0)
|
if (attacker != 0)
|
||||||
|
118
src/zr/hitgroups.inc
Normal file
118
src/zr/hitgroups.inc
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
* ============================================================================
|
||||||
|
*
|
||||||
|
* Zombie:Reloaded
|
||||||
|
*
|
||||||
|
* File: hitgroup.inc
|
||||||
|
* Description: API for loading hitgroup specific settings.
|
||||||
|
* Author: Greyscale, Richard Helgeby
|
||||||
|
*
|
||||||
|
* ============================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array to store keyvalue data.
|
||||||
|
*/
|
||||||
|
new Handle:kvHitgroups = INVALID_HANDLE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @section Player hitgroup values.
|
||||||
|
*/
|
||||||
|
#define HITGROUP_GENERIC 0
|
||||||
|
#define HITGROUP_HEAD 1
|
||||||
|
#define HITGROUP_CHEST 2
|
||||||
|
#define HITGROUP_STOMACH 3
|
||||||
|
#define HITGROUP_LEFTARM 4
|
||||||
|
#define HITGROUP_RIGHTARM 5
|
||||||
|
#define HITGROUP_LEFTLEG 6
|
||||||
|
#define HITGROUP_RIGHTLEG 7
|
||||||
|
#define HITGROUP_GEAR 10
|
||||||
|
/**
|
||||||
|
* @endsection
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears hitgroup data.
|
||||||
|
*/
|
||||||
|
HitgroupsClearData()
|
||||||
|
{
|
||||||
|
// Load hitgroup data.
|
||||||
|
if (kvHitgroups != INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
CloseHandle(kvHitgroups);
|
||||||
|
}
|
||||||
|
|
||||||
|
kvHitgroups = CreateKeyValues("hitgroups");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads hitgroup data from file.
|
||||||
|
*/
|
||||||
|
HitgroupsLoad()
|
||||||
|
{
|
||||||
|
// Clear hitgroup data
|
||||||
|
HitgroupsClearData();
|
||||||
|
|
||||||
|
decl String:path[PLATFORM_MAX_PATH];
|
||||||
|
BuildPath(Path_SM, path, sizeof(path), "configs/zr/hitgroups.txt");
|
||||||
|
|
||||||
|
// If file isn't found, stop plugin.
|
||||||
|
if (!FileToKeyValues(kvHitgroups, path))
|
||||||
|
{
|
||||||
|
if (LogFlagCheck(LOG_CORE_EVENTS, LOG_MODULE_HITGROUPS))
|
||||||
|
{
|
||||||
|
ZR_LogMessageFormatted(-1, "Hitgroups", "Config Validation", "Missing file hitgroups.txt, disabling hitgroup-based modules.", LOG_FORMAT_TYPE_FULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate hitgroups config.
|
||||||
|
HitgroupsValidateConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate hitgroup config file and settings.
|
||||||
|
*/
|
||||||
|
HitgroupsValidateConfig()
|
||||||
|
{
|
||||||
|
// If log flag check fails, don't log.
|
||||||
|
if (!LogFlagCheck(LOG_CORE_EVENTS, LOG_MODULE_HITGROUPS))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
KvRewind(kvHitgroups);
|
||||||
|
if (!KvGotoFirstSubKey(kvHitgroups))
|
||||||
|
{
|
||||||
|
ZR_LogMessageFormatted(-1, "Hitgroups", "Config Validation", "No hitgroups listed in hitgroups.txt, disabling hitgroup-based modules.", LOG_FORMAT_TYPE_FULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve hitgroup knockback value.
|
||||||
|
*
|
||||||
|
* @param hitgroup The hitgroup index.
|
||||||
|
*/
|
||||||
|
Float:HitgroupsGetHitgroupKnockback(hitgroup)
|
||||||
|
{
|
||||||
|
// Reset keyvalue's traversal stack.
|
||||||
|
KvRewind(kvHitgroups);
|
||||||
|
if (KvGotoFirstSubKey(kvHitgroups))
|
||||||
|
{
|
||||||
|
decl String:sHitgroup[4];
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
KvGetSectionName(kvHitgroups, sHitgroup, sizeof(sHitgroup));
|
||||||
|
|
||||||
|
// If this is the right hitgroup, then return knockback for it.
|
||||||
|
if (hitgroup == StringToInt(sHitgroup))
|
||||||
|
{
|
||||||
|
return KvGetFloat(kvHitgroups, "knockback", 1.0);
|
||||||
|
}
|
||||||
|
} while (KvGotoNextKey(kvHitgroups));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0;
|
||||||
|
}
|
@ -6,29 +6,15 @@
|
|||||||
* ====================
|
* ====================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/** Player hurt event.
|
||||||
* @section Player hitgroup values.
|
*
|
||||||
*/
|
|
||||||
#define HITGROUP_GENERIC 0
|
|
||||||
#define HITGROUP_HEAD 1
|
|
||||||
#define HITGROUP_CHEST 2
|
|
||||||
#define HITGROUP_STOMACH 3
|
|
||||||
#define HITGROUP_LEFTARM 4
|
|
||||||
#define HITGROUP_RIGHTARM 5
|
|
||||||
#define HITGROUP_LEFTLEG 6
|
|
||||||
#define HITGROUP_RIGHTLEG 7
|
|
||||||
#define HITGROUP_GEAR 10
|
|
||||||
/**
|
|
||||||
* @endsection
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Player hurt event
|
|
||||||
* @param client The victim index. (zombie)
|
* @param client The victim index. (zombie)
|
||||||
* @param attacker The attacker index. (human)
|
* @param attacker The attacker index. (human)
|
||||||
* @param weapon The weapon used.
|
* @param weapon The weapon used.
|
||||||
|
* @param hitgroup Hitgroup attacker has damaged.
|
||||||
* @param dmg_health Damage done.
|
* @param dmg_health Damage done.
|
||||||
*/
|
*/
|
||||||
KnockbackPlayerHurt(client, attacker, const String:weapon[], dmg_health)
|
KnockbackPlayerHurt(client, attacker, const String:weapon[], hitgroup, dmg_health)
|
||||||
{
|
{
|
||||||
// Check if the attacker is a player.
|
// Check if the attacker is a player.
|
||||||
if (attacker != 0)
|
if (attacker != 0)
|
||||||
@ -68,14 +54,14 @@ KnockbackPlayerHurt(client, attacker, const String:weapon[], dmg_health)
|
|||||||
TR_GetEndPosition(clientloc);
|
TR_GetEndPosition(clientloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply damage knockback multiplier
|
|
||||||
knockback *= float(dmg_health);
|
|
||||||
|
|
||||||
// Retrieve weapon knockback boost.
|
// Retrieve weapon knockback boost.
|
||||||
new Float:boostWeapon = WeaponGetWeaponKnockback(weapon);
|
new Float:boostWeapon = WeaponGetWeaponKnockback(weapon);
|
||||||
|
|
||||||
// Apply weapon knockback multiplier.
|
// Retrieve hitgroup knockback boost.
|
||||||
knockback *= boostWeapon;
|
new Float:boostHitgroup = HitgroupsGetHitgroupKnockback(hitgroup);
|
||||||
|
|
||||||
|
// Apply all knockback multipliers.
|
||||||
|
knockback *= float(dmg_health) * boostWeapon * boostHitgroup;
|
||||||
|
|
||||||
// Apply knockback.
|
// Apply knockback.
|
||||||
KnockbackSetVelocity(client, attackerloc, clientloc, knockback);
|
KnockbackSetVelocity(client, attackerloc, clientloc, knockback);
|
||||||
@ -85,6 +71,7 @@ KnockbackPlayerHurt(client, attacker, const String:weapon[], dmg_health)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets velocity on a player.
|
* Sets velocity on a player.
|
||||||
|
*
|
||||||
* @param client The client index.
|
* @param client The client index.
|
||||||
* @param startpoint The starting coordinate to push from.
|
* @param startpoint The starting coordinate to push from.
|
||||||
* @param endpoint The ending coordinate to push towards.
|
* @param endpoint The ending coordinate to push towards.
|
||||||
@ -108,6 +95,7 @@ KnockbackSetVelocity(client, const Float:startpoint[3], const Float:endpoint[3],
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Trace Ray forward, used as a filter to continue tracing if told so. (See sdktools_trace.inc)
|
* Trace Ray forward, used as a filter to continue tracing if told so. (See sdktools_trace.inc)
|
||||||
|
*
|
||||||
* @param entity The entity index.
|
* @param entity The entity index.
|
||||||
* @param contentsMask The contents mask.
|
* @param contentsMask The contents mask.
|
||||||
* @return True to allow hit, false to continue tracing.
|
* @return True to allow hit, false to continue tracing.
|
||||||
@ -126,6 +114,7 @@ public bool:KnockbackTRFilter(entity, contentsMask)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the location of an exploding grenade (currently inflicting damage in player_hurt).
|
* Find the location of an exploding grenade (currently inflicting damage in player_hurt).
|
||||||
|
*
|
||||||
* @param heLoc The location of the exploding grenade.
|
* @param heLoc The location of the exploding grenade.
|
||||||
* @return The entity index of the grenade.
|
* @return The entity index of the grenade.
|
||||||
*/
|
*/
|
||||||
|
@ -115,25 +115,3 @@ LoadDownloadData()
|
|||||||
CloseHandle(fileDownloads);
|
CloseHandle(fileDownloads);
|
||||||
CloseHandle(arrayDownloads);
|
CloseHandle(arrayDownloads);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*ApplyZombieModel(client)
|
|
||||||
{
|
|
||||||
decl String:modelpath[256];
|
|
||||||
|
|
||||||
new bool:classes = GetConVarBool(gCvars[CVAR_CLASSES]);
|
|
||||||
if (classes)
|
|
||||||
{
|
|
||||||
GetClassModel(pClass[client], modelpath, sizeof(modelpath));
|
|
||||||
if (!StrEqual(modelpath, "default", false))
|
|
||||||
{
|
|
||||||
SetPlayerModel(client, modelpath);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
new randmodel = GetRandomInt(0, GetArraySize(arrayModels) - 1);
|
|
||||||
GetArrayString(arrayModels, randmodel, modelpath, sizeof(modelpath));
|
|
||||||
Format(modelpath, sizeof(modelpath), "%s.mdl", modelpath);
|
|
||||||
|
|
||||||
SetPlayerModel(client, modelpath);
|
|
||||||
}*/
|
|
||||||
|
@ -21,9 +21,10 @@ new offsRender;
|
|||||||
|
|
||||||
new Handle:g_hGameConf = INVALID_HANDLE;
|
new Handle:g_hGameConf = INVALID_HANDLE;
|
||||||
new Handle:g_hRemoveAllItems = INVALID_HANDLE;
|
new Handle:g_hRemoveAllItems = INVALID_HANDLE;
|
||||||
new Handle:g_hTerminateRound = INVALID_HANDLE;
|
|
||||||
new Handle:g_hEyePosition = INVALID_HANDLE;
|
new Handle:g_hEyePosition = INVALID_HANDLE;
|
||||||
new Handle:g_hEyeAngles = INVALID_HANDLE;
|
new Handle:g_hEyeAngles = INVALID_HANDLE;
|
||||||
|
new Handle:g_hTerminateRound = INVALID_HANDLE;
|
||||||
|
new Handle:g_hCSWeaponDrop = INVALID_HANDLE;
|
||||||
|
|
||||||
FindOffsets()
|
FindOffsets()
|
||||||
{
|
{
|
||||||
@ -100,27 +101,61 @@ FindOffsets()
|
|||||||
|
|
||||||
SetupGameData()
|
SetupGameData()
|
||||||
{
|
{
|
||||||
|
// Load game config file.
|
||||||
g_hGameConf = LoadGameConfigFile("plugin.zombiereloaded");
|
g_hGameConf = LoadGameConfigFile("plugin.zombiereloaded");
|
||||||
|
|
||||||
|
//
|
||||||
StartPrepSDKCall(SDKCall_Player);
|
StartPrepSDKCall(SDKCall_Player);
|
||||||
PrepSDKCall_SetFromConf(g_hGameConf, SDKConf_Virtual, "RemoveAllItems");
|
PrepSDKCall_SetFromConf(g_hGameConf, SDKConf_Virtual, "RemoveAllItems");
|
||||||
g_hRemoveAllItems = EndPrepSDKCall();
|
g_hRemoveAllItems = EndPrepSDKCall();
|
||||||
|
|
||||||
|
if(g_hRemoveAllItems == INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
SetFailState("Couldn't find offset \"RemoveAllItems\"!");
|
||||||
|
}
|
||||||
|
|
||||||
StartPrepSDKCall(SDKCall_Player);
|
StartPrepSDKCall(SDKCall_Player);
|
||||||
PrepSDKCall_SetFromConf(g_hGameConf, SDKConf_Virtual, "EyePosition");
|
PrepSDKCall_SetFromConf(g_hGameConf, SDKConf_Virtual, "EyePosition");
|
||||||
PrepSDKCall_SetReturnInfo(SDKType_QAngle, SDKPass_ByValue);
|
PrepSDKCall_SetReturnInfo(SDKType_QAngle, SDKPass_ByValue);
|
||||||
g_hEyePosition = EndPrepSDKCall();
|
g_hEyePosition = EndPrepSDKCall();
|
||||||
|
|
||||||
|
if(g_hEyePosition == INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
SetFailState("Couldn't find offset \"EyePosition\"!");
|
||||||
|
}
|
||||||
|
|
||||||
StartPrepSDKCall(SDKCall_Player);
|
StartPrepSDKCall(SDKCall_Player);
|
||||||
PrepSDKCall_SetFromConf(g_hGameConf, SDKConf_Virtual, "EyeAngles");
|
PrepSDKCall_SetFromConf(g_hGameConf, SDKConf_Virtual, "EyeAngles");
|
||||||
PrepSDKCall_SetReturnInfo(SDKType_QAngle, SDKPass_ByValue);
|
PrepSDKCall_SetReturnInfo(SDKType_QAngle, SDKPass_ByValue);
|
||||||
g_hEyeAngles = EndPrepSDKCall();
|
g_hEyeAngles = EndPrepSDKCall();
|
||||||
|
|
||||||
|
if(g_hEyeAngles == INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
SetFailState("Couldn't find offset \"EyeAngles\"!");
|
||||||
|
}
|
||||||
|
|
||||||
StartPrepSDKCall(SDKCall_GameRules);
|
StartPrepSDKCall(SDKCall_GameRules);
|
||||||
PrepSDKCall_SetFromConf(g_hGameConf, SDKConf_Signature, "TerminateRound");
|
PrepSDKCall_SetFromConf(g_hGameConf, SDKConf_Signature, "TerminateRound");
|
||||||
PrepSDKCall_AddParameter(SDKType_Float, SDKPass_Plain);
|
PrepSDKCall_AddParameter(SDKType_Float, SDKPass_Plain);
|
||||||
PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain);
|
PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain);
|
||||||
g_hTerminateRound = EndPrepSDKCall();
|
g_hTerminateRound = EndPrepSDKCall();
|
||||||
|
|
||||||
|
if(g_hTerminateRound == INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
SetFailState("Couldn't find signature \"CGameRules::TerminateRound\"!");
|
||||||
|
}
|
||||||
|
|
||||||
|
StartPrepSDKCall(SDKCall_Player);
|
||||||
|
PrepSDKCall_SetFromConf(g_hGameConf, SDKConf_Signature, "CSWeaponDrop");
|
||||||
|
PrepSDKCall_AddParameter(SDKType_CBaseEntity, SDKPass_Pointer);
|
||||||
|
PrepSDKCall_AddParameter(SDKType_Bool, SDKPass_Plain);
|
||||||
|
PrepSDKCall_AddParameter(SDKType_Bool, SDKPass_Plain);
|
||||||
|
g_hCSWeaponDrop = EndPrepSDKCall();
|
||||||
|
|
||||||
|
if(g_hCSWeaponDrop == INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
SetFailState("Couldn't find signature \"CBasePlayer::CSWeaponDrop\"!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetPlayerVelocity(client, const Float:vec[3], bool:reset)
|
SetPlayerVelocity(client, const Float:vec[3], bool:reset)
|
||||||
@ -231,13 +266,12 @@ GetPlayerEyeAngles(client, Float:ang[3])
|
|||||||
|
|
||||||
TerminateRound(Float:delay, reason)
|
TerminateRound(Float:delay, reason)
|
||||||
{
|
{
|
||||||
if (g_hTerminateRound == INVALID_HANDLE) return;
|
|
||||||
SDKCall(g_hTerminateRound, delay, reason);
|
SDKCall(g_hTerminateRound, delay, reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetPlayerModel(client, const String:model[])
|
CSDropWeapon(client, weapon)
|
||||||
{
|
{
|
||||||
SetEntityModel(client, model);
|
SDKCall(g_hCSWeaponDrop, client, weapon, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetPlayerAlpha(client, alpha)
|
SetPlayerAlpha(client, alpha)
|
||||||
|
@ -77,7 +77,7 @@ bool:ClassApplyModel(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER)
|
|||||||
|
|
||||||
// TODO: Add support for keeping the default cs model ("default").
|
// TODO: Add support for keeping the default cs model ("default").
|
||||||
|
|
||||||
SetPlayerModel(client, modelpath);
|
SetEntityModel(client, modelpath);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
145
src/zr/spawnprotect.inc
Normal file
145
src/zr/spawnprotect.inc
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
* ============================================================================
|
||||||
|
*
|
||||||
|
* Zombie:Reloaded
|
||||||
|
*
|
||||||
|
* File: spawnprotect.inc
|
||||||
|
* Description: Protects late-joining players from zombies for x seconds.
|
||||||
|
*
|
||||||
|
* ============================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array for storing spawn protect timer handles per client.
|
||||||
|
*/
|
||||||
|
new Handle:tSpawnProtect[MAXPLAYERS + 1];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array for flagging client to be protected.
|
||||||
|
*/
|
||||||
|
new bool:pSpawnProtect[MAXPLAYERS + 1];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array for storing time left for spawn protection per client.
|
||||||
|
*/
|
||||||
|
new pSpawnProtectTime[MAXPLAYERS + 1];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client is joining the server.
|
||||||
|
*
|
||||||
|
* @param client The client index.
|
||||||
|
*/
|
||||||
|
SpawnProtectClientInit(client)
|
||||||
|
{
|
||||||
|
tSpawnProtect[client] = INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Player is spawning into the game.
|
||||||
|
*
|
||||||
|
* @param client The client index.
|
||||||
|
*/
|
||||||
|
SpawnProtectPlayerSpawn(client)
|
||||||
|
{
|
||||||
|
// Disable spawn protection on client.
|
||||||
|
pSpawnProtect[client] = false;
|
||||||
|
|
||||||
|
// If zombie hasn't spawned, then stop.
|
||||||
|
if (!zombieSpawned)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If protect cvar is invalid or 0, then stop.
|
||||||
|
new protect = GetConVarInt(gCvars[CVAR_PROTECT]);
|
||||||
|
if (protect <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get respawn team.
|
||||||
|
decl String:respawnteam[32];
|
||||||
|
GetConVarString(gCvars[CVAR_RESPAWN_TEAM], respawnteam, sizeof(respawnteam));
|
||||||
|
|
||||||
|
// If the respawn team is not set to zombie, and either cvar zr_suicide_world_damage or the client
|
||||||
|
// wasn't killed by world is false, then continue to protect client.
|
||||||
|
if (!StrEqual(respawnteam, "zombie", false) && !(GetConVarBool(gCvars[CVAR_SUICIDE_WORLD_DAMAGE]) && gKilledByWorld[client]))
|
||||||
|
{
|
||||||
|
// Set spawn protect flag on client.
|
||||||
|
pSpawnProtect[client] = true;
|
||||||
|
|
||||||
|
// Set improved attributes
|
||||||
|
// (Move to cvar?)
|
||||||
|
SetPlayerAlpha(client, 0);
|
||||||
|
SetPlayerSpeed(client, 600.0);
|
||||||
|
|
||||||
|
// Set time left to zr_protect's value.
|
||||||
|
pSpawnProtectTime[client] = protect;
|
||||||
|
|
||||||
|
// Tell client they are being protected.
|
||||||
|
ZR_PrintToChat(client, "Spawn protection begin", protect);
|
||||||
|
|
||||||
|
// Send time left in a hud message.
|
||||||
|
ZR_HudHint(client, "Spawn Protect", pSpawnProtectTime[client]);
|
||||||
|
|
||||||
|
// If timer is currently running, kill it.
|
||||||
|
if (tSpawnProtect[client] != INVALID_HANDLE)
|
||||||
|
{
|
||||||
|
KillTimer(tSpawnProtect[client]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start repeating timer.
|
||||||
|
tSpawnProtect[client] = CreateTimer(1.0, SpawnProtectTimer, client, TIMER_FLAG_NO_MAPCHANGE|TIMER_REPEAT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Timer callback function, countdown for spawn protection.
|
||||||
|
*
|
||||||
|
* @param timer The timer handle.
|
||||||
|
* @param client The client index.
|
||||||
|
*/
|
||||||
|
public Action:SpawnProtectTimer(Handle:timer, any:client)
|
||||||
|
{
|
||||||
|
// If client leaves, then stop timer.
|
||||||
|
if (!IsClientInGame(client))
|
||||||
|
{
|
||||||
|
return Plugin_Stop;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If client has become a zombie, then stop timer.
|
||||||
|
if (!IsPlayerHuman(client))
|
||||||
|
{
|
||||||
|
return Plugin_Stop;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decrement time left.
|
||||||
|
pSpawnProtectTime[client]--;
|
||||||
|
|
||||||
|
// Print time left to client.
|
||||||
|
ZR_HudHint(client, "Spawn Protect", pSpawnProtectTime[client]);
|
||||||
|
|
||||||
|
// Time has expired.
|
||||||
|
if (pSpawnProtectTime[client] <= 0)
|
||||||
|
{
|
||||||
|
// Remove protect flag.
|
||||||
|
pSpawnProtect[client] = false;
|
||||||
|
|
||||||
|
// Tell client spawn protection is over.
|
||||||
|
ZR_HudHint(client, "Spawn protection end");
|
||||||
|
|
||||||
|
// Fix attributes.
|
||||||
|
// TODO: Set class attributes.
|
||||||
|
SetPlayerAlpha(client, 255);
|
||||||
|
SetPlayerSpeed(client, 300.0);
|
||||||
|
|
||||||
|
// Clear timer handle.
|
||||||
|
tSpawnProtect[client] = INVALID_HANDLE;
|
||||||
|
|
||||||
|
// Stop timer.
|
||||||
|
return Plugin_Stop;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow timer to continue repeating.
|
||||||
|
return Plugin_Continue;
|
||||||
|
}
|
@ -15,13 +15,13 @@
|
|||||||
*/
|
*/
|
||||||
public bool:Market_OnWeaponSelected(client, String:weaponid[])
|
public bool:Market_OnWeaponSelected(client, String:weaponid[])
|
||||||
{
|
{
|
||||||
// If player is dead or weaponid is invalid, then stop
|
// If player is dead or weaponid is invalid, then stop.
|
||||||
if (!weaponid[0] || !IsPlayerAlive(client))
|
if (!weaponid[0] || !IsPlayerAlive(client))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If player is a zombie, then stop
|
// If player is a zombie, then stop.
|
||||||
if (IsPlayerZombie(client))
|
if (IsPlayerZombie(client))
|
||||||
{
|
{
|
||||||
ZR_PrintToChat(client, "Zombie cant use weapon");
|
ZR_PrintToChat(client, "Zombie cant use weapon");
|
||||||
@ -29,7 +29,7 @@ public bool:Market_OnWeaponSelected(client, String:weaponid[])
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If player is using the rebuy option then allow
|
// If player is using the rebuy option then allow.
|
||||||
if (StrEqual(weaponid, "rebuy"))
|
if (StrEqual(weaponid, "rebuy"))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@ -39,16 +39,16 @@ public bool:Market_OnWeaponSelected(client, String:weaponid[])
|
|||||||
decl String:weapon[WEAPONS_MAX_LENGTH];
|
decl String:weapon[WEAPONS_MAX_LENGTH];
|
||||||
new price;
|
new price;
|
||||||
|
|
||||||
// If the market plugin can't find info about the weapon, then stop
|
// If the market plugin can't find info about the weapon, then stop.
|
||||||
if (!Market_GetWeaponIDInfo(weaponid, display, weapon, price))
|
if (!Market_GetWeaponIDInfo(weaponid, display, weapon, price))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Strip "weapon_" from entity name
|
// Strip "weapon_" from entity name.
|
||||||
ReplaceString(weapon, sizeof(weapon), "weapon_", "");
|
ReplaceString(weapon, sizeof(weapon), "weapon_", "");
|
||||||
|
|
||||||
// If the weapon is restricted, then stop
|
// If the weapon is restricted, then stop.
|
||||||
if (RestrictIsWeaponRestricted(weapon))
|
if (RestrictIsWeaponRestricted(weapon))
|
||||||
{
|
{
|
||||||
ZR_PrintToChat(client, "Weapon is restricted", weapon);
|
ZR_PrintToChat(client, "Weapon is restricted", weapon);
|
||||||
@ -56,7 +56,7 @@ public bool:Market_OnWeaponSelected(client, String:weaponid[])
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if buyzone cvar is enabled, and if the client is in a buyzone
|
// Check if buyzone cvar is enabled, and if the client is in a buyzone.
|
||||||
new bool:buyzone = GetConVarBool(gCvars[CVAR_ZMARKET_BUYZONE]);
|
new bool:buyzone = GetConVarBool(gCvars[CVAR_ZMARKET_BUYZONE]);
|
||||||
if (!IsClientInBuyZone(client) && buyzone)
|
if (!IsClientInBuyZone(client) && buyzone)
|
||||||
{
|
{
|
||||||
@ -76,12 +76,12 @@ public bool:Market_OnWeaponSelected(client, String:weaponid[])
|
|||||||
*/
|
*/
|
||||||
public Market_PostOnWeaponSelected(client, &bool:allowed)
|
public Market_PostOnWeaponSelected(client, &bool:allowed)
|
||||||
{
|
{
|
||||||
// If the purchase wasn't allowed, then stop
|
// If the purchase wasn't allowed, then stop.
|
||||||
if (!allowed)
|
if (!allowed)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resend market menu
|
// Resend market menu.
|
||||||
ZMarket(client);
|
ZMarket(client);
|
||||||
}
|
}
|
@ -16,12 +16,12 @@ enum WeaponsMenu
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Array to store the client's current weapon menu
|
* Array to store the client's current weapon menu.
|
||||||
*/
|
*/
|
||||||
new WeaponsMenu:curMenuWeapons[MAXPLAYERS + 1];
|
new WeaponsMenu:curMenuWeapons[MAXPLAYERS + 1];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Array to store the client's current weapon group menu
|
* Array to store the client's current weapon group menu.
|
||||||
*/
|
*/
|
||||||
new String:curMenuGroup[WEAPONS_MAX_LENGTH][MAXPLAYERS + 1];
|
new String:curMenuGroup[WEAPONS_MAX_LENGTH][MAXPLAYERS + 1];
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ new String:curMenuGroup[WEAPONS_MAX_LENGTH][MAXPLAYERS + 1];
|
|||||||
*/
|
*/
|
||||||
WeaponsMenuMain(client)
|
WeaponsMenuMain(client)
|
||||||
{
|
{
|
||||||
// Create menu handle
|
// Create menu handle.
|
||||||
new Handle:menu_weapons_main = CreateMenu(WeaponsMenuMainHandle);
|
new Handle:menu_weapons_main = CreateMenu(WeaponsMenuMainHandle);
|
||||||
|
|
||||||
SetGlobalTransTarget(client);
|
SetGlobalTransTarget(client);
|
||||||
@ -49,7 +49,7 @@ WeaponsMenuMain(client)
|
|||||||
AddMenuItem(menu_weapons_main, "toggleweaponrestriction", toggleweaponrestriction);
|
AddMenuItem(menu_weapons_main, "toggleweaponrestriction", toggleweaponrestriction);
|
||||||
AddMenuItem(menu_weapons_main, "togglewgrouprestriction", togglewgrouprestriction);
|
AddMenuItem(menu_weapons_main, "togglewgrouprestriction", togglewgrouprestriction);
|
||||||
|
|
||||||
// Disable market option if market isn't installed
|
// Disable market option if market isn't installed.
|
||||||
if (market)
|
if (market)
|
||||||
{
|
{
|
||||||
AddMenuItem(menu_weapons_main, "zmarket", zmarket);
|
AddMenuItem(menu_weapons_main, "zmarket", zmarket);
|
||||||
@ -59,10 +59,10 @@ WeaponsMenuMain(client)
|
|||||||
AddMenuItem(menu_weapons_main, "zmarket", zmarket, ITEMDRAW_DISABLED);
|
AddMenuItem(menu_weapons_main, "zmarket", zmarket, ITEMDRAW_DISABLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a "Back" button to the weapons main menu
|
// Create a "Back" button to the weapons main menu.
|
||||||
SetMenuExitBackButton(menu_weapons_main, true);
|
SetMenuExitBackButton(menu_weapons_main, true);
|
||||||
|
|
||||||
// Send menu
|
// Send menu.
|
||||||
DisplayMenu(menu_weapons_main, client, MENU_TIME_FOREVER);
|
DisplayMenu(menu_weapons_main, client, MENU_TIME_FOREVER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ WeaponsMenuMain(client)
|
|||||||
*/
|
*/
|
||||||
public WeaponsMenuMainHandle(Handle:menu_weapons_main, MenuAction:action, client, slot)
|
public WeaponsMenuMainHandle(Handle:menu_weapons_main, MenuAction:action, client, slot)
|
||||||
{
|
{
|
||||||
// Client selected an option
|
// Client selected an option.
|
||||||
if (action == MenuAction_Select)
|
if (action == MenuAction_Select)
|
||||||
{
|
{
|
||||||
switch(slot)
|
switch(slot)
|
||||||
@ -94,16 +94,16 @@ public WeaponsMenuMainHandle(Handle:menu_weapons_main, MenuAction:action, client
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Client closed the menu
|
// Client closed the menu.
|
||||||
if (action == MenuAction_Cancel)
|
if (action == MenuAction_Cancel)
|
||||||
{
|
{
|
||||||
// Client hit "Back" button
|
// Client hit "Back" button.
|
||||||
if (slot == MenuCancel_ExitBack)
|
if (slot == MenuCancel_ExitBack)
|
||||||
{
|
{
|
||||||
ZRAdminMenu(client);
|
ZRAdminMenu(client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Client hit "Exit" button
|
// Client hit "Exit" button.
|
||||||
else if (action == MenuAction_End)
|
else if (action == MenuAction_End)
|
||||||
{
|
{
|
||||||
CloseHandle(menu_weapons_main);
|
CloseHandle(menu_weapons_main);
|
||||||
@ -116,15 +116,15 @@ public WeaponsMenuMainHandle(Handle:menu_weapons_main, MenuAction:action, client
|
|||||||
*/
|
*/
|
||||||
WeaponsMenuWeapons(client, WeaponsMenu:type)
|
WeaponsMenuWeapons(client, WeaponsMenu:type)
|
||||||
{
|
{
|
||||||
// Set the current action client is performing on a weapon (see enum WeaponsMenu)
|
// Set the current action client is performing on a weapon. (see enum WeaponsMenu)
|
||||||
curMenuWeapons[client] = type;
|
curMenuWeapons[client] = type;
|
||||||
|
|
||||||
// Create menu handle
|
// Create menu handle.
|
||||||
new Handle:menu_weapons_weapons = CreateMenu(WeaponsMenuWeaponsHandle);
|
new Handle:menu_weapons_weapons = CreateMenu(WeaponsMenuWeaponsHandle);
|
||||||
|
|
||||||
SetGlobalTransTarget(client);
|
SetGlobalTransTarget(client);
|
||||||
|
|
||||||
// If client wants to perform an action on a single weapon, show weapon list
|
// If client wants to perform an action on a single weapon, show weapon list.
|
||||||
switch(curMenuWeapons[client])
|
switch(curMenuWeapons[client])
|
||||||
{
|
{
|
||||||
case Weapon:
|
case Weapon:
|
||||||
@ -136,7 +136,7 @@ WeaponsMenuWeapons(client, WeaponsMenu:type)
|
|||||||
new Handle:arrayWeapons = INVALID_HANDLE;
|
new Handle:arrayWeapons = INVALID_HANDLE;
|
||||||
new size = WeaponsCreateWeaponArray(arrayWeapons);
|
new size = WeaponsCreateWeaponArray(arrayWeapons);
|
||||||
|
|
||||||
// x = Array index
|
// x = Array index.
|
||||||
for (new x = 0; x < size; x++)
|
for (new x = 0; x < size; x++)
|
||||||
{
|
{
|
||||||
GetArrayString(arrayWeapons, x, weapon, sizeof(weapon));
|
GetArrayString(arrayWeapons, x, weapon, sizeof(weapon));
|
||||||
@ -148,7 +148,7 @@ WeaponsMenuWeapons(client, WeaponsMenu:type)
|
|||||||
Format(display, sizeof(display), "%s*", weapon);
|
Format(display, sizeof(display), "%s*", weapon);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If weapon restriction is blocked for the menu, disable option
|
// If weapon restriction is blocked for the menu, disable option.
|
||||||
new bool:menu = WeaponsIsWeaponMenu(weapon);
|
new bool:menu = WeaponsIsWeaponMenu(weapon);
|
||||||
|
|
||||||
if (menu)
|
if (menu)
|
||||||
@ -161,7 +161,7 @@ WeaponsMenuWeapons(client, WeaponsMenu:type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there are no weapons, add an "(Empty)" line
|
// If there are no weapons, add an "(Empty)" line.
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
{
|
{
|
||||||
decl String:empty[64];
|
decl String:empty[64];
|
||||||
@ -170,10 +170,10 @@ WeaponsMenuWeapons(client, WeaponsMenu:type)
|
|||||||
AddMenuItem(menu_weapons_weapons, "empty", empty, ITEMDRAW_DISABLED);
|
AddMenuItem(menu_weapons_weapons, "empty", empty, ITEMDRAW_DISABLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kill the array handle
|
// Kill the array handle.
|
||||||
CloseHandle(arrayWeapons);
|
CloseHandle(arrayWeapons);
|
||||||
}
|
}
|
||||||
// If client wants to perform an action on a weapon group, show custom group list
|
// If client wants to perform an action on a weapon group, show custom group list.
|
||||||
case WeaponGroup:
|
case WeaponGroup:
|
||||||
{
|
{
|
||||||
SetMenuTitle(menu_weapons_weapons, "%t\n ", "Weapons menu weapons group title");
|
SetMenuTitle(menu_weapons_weapons, "%t\n ", "Weapons menu weapons group title");
|
||||||
@ -183,7 +183,7 @@ WeaponsMenuWeapons(client, WeaponsMenu:type)
|
|||||||
new Handle:arrayWeaponGroups = INVALID_HANDLE;
|
new Handle:arrayWeaponGroups = INVALID_HANDLE;
|
||||||
new size = RestrictCreateGroupArray(arrayWeaponGroups);
|
new size = RestrictCreateGroupArray(arrayWeaponGroups);
|
||||||
|
|
||||||
// x = Array index
|
// x = Array index.
|
||||||
for (new x = 0; x < size; x++)
|
for (new x = 0; x < size; x++)
|
||||||
{
|
{
|
||||||
GetArrayString(arrayWeaponGroups, x, weapongroup, sizeof(weapongroup));
|
GetArrayString(arrayWeaponGroups, x, weapongroup, sizeof(weapongroup));
|
||||||
@ -202,7 +202,7 @@ WeaponsMenuWeapons(client, WeaponsMenu:type)
|
|||||||
AddMenuItem(menu_weapons_weapons, weapongroup, display);
|
AddMenuItem(menu_weapons_weapons, weapongroup, display);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there are no weapons, add an "(Empty)" line
|
// If there are no weapons, add an "(Empty)" line.
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
{
|
{
|
||||||
decl String:empty[64];
|
decl String:empty[64];
|
||||||
@ -230,7 +230,7 @@ WeaponsMenuWeapons(client, WeaponsMenu:type)
|
|||||||
*/
|
*/
|
||||||
public WeaponsMenuWeaponsHandle(Handle:menu_weapons_weapons, MenuAction:action, client, slot)
|
public WeaponsMenuWeaponsHandle(Handle:menu_weapons_weapons, MenuAction:action, client, slot)
|
||||||
{
|
{
|
||||||
// Client selected an option
|
// Client selected an option.
|
||||||
if (action == MenuAction_Select)
|
if (action == MenuAction_Select)
|
||||||
{
|
{
|
||||||
decl String:weapon[WEAPONS_MAX_LENGTH];
|
decl String:weapon[WEAPONS_MAX_LENGTH];
|
||||||
@ -238,7 +238,7 @@ public WeaponsMenuWeaponsHandle(Handle:menu_weapons_weapons, MenuAction:action,
|
|||||||
|
|
||||||
switch(curMenuWeapons[client])
|
switch(curMenuWeapons[client])
|
||||||
{
|
{
|
||||||
// Client is restricting a single weapon
|
// Client is restricting a single weapon.
|
||||||
case Weapon:
|
case Weapon:
|
||||||
{
|
{
|
||||||
new WpnRestrictQuery:output;
|
new WpnRestrictQuery:output;
|
||||||
@ -254,27 +254,27 @@ public WeaponsMenuWeaponsHandle(Handle:menu_weapons_weapons, MenuAction:action,
|
|||||||
RestrictPrintUnrestrictOutput(client, output, weapon, false);
|
RestrictPrintUnrestrictOutput(client, output, weapon, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resend menu
|
// Resend menu.
|
||||||
WeaponsMenuWeapons(client, curMenuWeapons[client]);
|
WeaponsMenuWeapons(client, curMenuWeapons[client]);
|
||||||
}
|
}
|
||||||
// Client is accessing a weapon group
|
// Client is accessing a weapon group.
|
||||||
case WeaponGroup:
|
case WeaponGroup:
|
||||||
{
|
{
|
||||||
// Send weapon group menu
|
// Send weapon group menu.
|
||||||
WeaponsMenuWeaponGroup(client, weapon);
|
WeaponsMenuWeaponGroup(client, weapon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Client closed the menu
|
// Client closed the menu.
|
||||||
if (action == MenuAction_Cancel)
|
if (action == MenuAction_Cancel)
|
||||||
{
|
{
|
||||||
// Client hit "Back" button
|
// Client hit "Back" button.
|
||||||
if (slot == MenuCancel_ExitBack)
|
if (slot == MenuCancel_ExitBack)
|
||||||
{
|
{
|
||||||
WeaponsMenuMain(client);
|
WeaponsMenuMain(client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Client hit "Exit" button
|
// Client hit "Exit" button.
|
||||||
else if (action == MenuAction_End)
|
else if (action == MenuAction_End)
|
||||||
{
|
{
|
||||||
CloseHandle(menu_weapons_weapons);
|
CloseHandle(menu_weapons_weapons);
|
||||||
@ -285,7 +285,7 @@ WeaponsMenuWeaponGroup(client, const String:weapongroup[])
|
|||||||
{
|
{
|
||||||
strcopy(curMenuGroup[client], WEAPONS_MAX_LENGTH, weapongroup);
|
strcopy(curMenuGroup[client], WEAPONS_MAX_LENGTH, weapongroup);
|
||||||
|
|
||||||
// Create menu handle
|
// Create menu handle.
|
||||||
new Handle:menu_weapons_groupweapon = CreateMenu(WeaponsMenuWeaponGroupHandle);
|
new Handle:menu_weapons_groupweapon = CreateMenu(WeaponsMenuWeaponGroupHandle);
|
||||||
|
|
||||||
SetMenuTitle(menu_weapons_groupweapon, "%t\n ", "Weapons menu weapon group title", weapongroup);
|
SetMenuTitle(menu_weapons_groupweapon, "%t\n ", "Weapons menu weapon group title", weapongroup);
|
||||||
@ -319,7 +319,7 @@ WeaponsMenuWeaponGroup(client, const String:weapongroup[])
|
|||||||
new Handle:arrayGroupWeapons = INVALID_HANDLE;
|
new Handle:arrayGroupWeapons = INVALID_HANDLE;
|
||||||
new size = RestrictCreateGroupWeaponsArray(arrayGroupWeapons, weapongroup);
|
new size = RestrictCreateGroupWeaponsArray(arrayGroupWeapons, weapongroup);
|
||||||
|
|
||||||
// x = Array index
|
// x = Array index.
|
||||||
for (new x = 0; x < size; x++)
|
for (new x = 0; x < size; x++)
|
||||||
{
|
{
|
||||||
GetArrayString(arrayGroupWeapons, x, groupweapon, sizeof(groupweapon));
|
GetArrayString(arrayGroupWeapons, x, groupweapon, sizeof(groupweapon));
|
||||||
@ -334,7 +334,7 @@ WeaponsMenuWeaponGroup(client, const String:weapongroup[])
|
|||||||
AddMenuItem(menu_weapons_groupweapon, groupweapon, display);
|
AddMenuItem(menu_weapons_groupweapon, groupweapon, display);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kill the array handle
|
// Kill the array handle.
|
||||||
CloseHandle(arrayGroupWeapons);
|
CloseHandle(arrayGroupWeapons);
|
||||||
|
|
||||||
SetMenuExitBackButton(menu_weapons_groupweapon, true);
|
SetMenuExitBackButton(menu_weapons_groupweapon, true);
|
||||||
@ -351,7 +351,7 @@ WeaponsMenuWeaponGroup(client, const String:weapongroup[])
|
|||||||
*/
|
*/
|
||||||
public WeaponsMenuWeaponGroupHandle(Handle:menu_weapons_groupweapon, MenuAction:action, client, slot)
|
public WeaponsMenuWeaponGroupHandle(Handle:menu_weapons_groupweapon, MenuAction:action, client, slot)
|
||||||
{
|
{
|
||||||
// Client selected an option
|
// Client selected an option.
|
||||||
if (action == MenuAction_Select)
|
if (action == MenuAction_Select)
|
||||||
{
|
{
|
||||||
switch(slot)
|
switch(slot)
|
||||||
@ -387,19 +387,19 @@ public WeaponsMenuWeaponGroupHandle(Handle:menu_weapons_groupweapon, MenuAction:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resend menu
|
// Resend menu.
|
||||||
WeaponsMenuWeaponGroup(client, curMenuGroup[client]);
|
WeaponsMenuWeaponGroup(client, curMenuGroup[client]);
|
||||||
}
|
}
|
||||||
// Client closed the menu
|
// Client closed the menu.
|
||||||
if (action == MenuAction_Cancel)
|
if (action == MenuAction_Cancel)
|
||||||
{
|
{
|
||||||
// Client hit "Back" button
|
// Client hit "Back" button.
|
||||||
if (slot == MenuCancel_ExitBack)
|
if (slot == MenuCancel_ExitBack)
|
||||||
{
|
{
|
||||||
WeaponsMenuWeapons(client, curMenuWeapons[client]);
|
WeaponsMenuWeapons(client, curMenuWeapons[client]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Client hit "Exit" button
|
// Client hit "Exit" button.
|
||||||
else if (action == MenuAction_End)
|
else if (action == MenuAction_End)
|
||||||
{
|
{
|
||||||
CloseHandle(menu_weapons_groupweapon);
|
CloseHandle(menu_weapons_groupweapon);
|
||||||
@ -412,7 +412,7 @@ public WeaponsMenuWeaponGroupHandle(Handle:menu_weapons_groupweapon, MenuAction:
|
|||||||
*/
|
*/
|
||||||
WeaponsMenuMarket(client)
|
WeaponsMenuMarket(client)
|
||||||
{
|
{
|
||||||
// Create menu handle
|
// Create menu handle.
|
||||||
new Handle:menu_weapons_market = CreateMenu(WeaponsMenuMarketHandle);
|
new Handle:menu_weapons_market = CreateMenu(WeaponsMenuMarketHandle);
|
||||||
|
|
||||||
SetGlobalTransTarget(client);
|
SetGlobalTransTarget(client);
|
||||||
@ -428,7 +428,7 @@ WeaponsMenuMarket(client)
|
|||||||
|
|
||||||
AddMenuItem(menu_weapons_market, "togglebuyzone", togglebuyzone);
|
AddMenuItem(menu_weapons_market, "togglebuyzone", togglebuyzone);
|
||||||
|
|
||||||
// Create a "Back" button to the weapons main menu
|
// Create a "Back" button to the weapons main menu.
|
||||||
SetMenuExitBackButton(menu_weapons_market, true);
|
SetMenuExitBackButton(menu_weapons_market, true);
|
||||||
|
|
||||||
// Send menu
|
// Send menu
|
||||||
@ -444,7 +444,7 @@ WeaponsMenuMarket(client)
|
|||||||
*/
|
*/
|
||||||
public WeaponsMenuMarketHandle(Handle:menu_weapons_market, MenuAction:action, client, slot)
|
public WeaponsMenuMarketHandle(Handle:menu_weapons_market, MenuAction:action, client, slot)
|
||||||
{
|
{
|
||||||
// Client selected an option
|
// Client selected an option.
|
||||||
if (action == MenuAction_Select)
|
if (action == MenuAction_Select)
|
||||||
{
|
{
|
||||||
switch(slot)
|
switch(slot)
|
||||||
@ -462,19 +462,19 @@ public WeaponsMenuMarketHandle(Handle:menu_weapons_market, MenuAction:action, cl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resend menu
|
// Resend menu.
|
||||||
WeaponsMenuMarket(client);
|
WeaponsMenuMarket(client);
|
||||||
}
|
}
|
||||||
// Client closed the menu
|
// Client closed the menu.
|
||||||
if (action == MenuAction_Cancel)
|
if (action == MenuAction_Cancel)
|
||||||
{
|
{
|
||||||
// Client hit "Back" button
|
// Client hit "Back" button.
|
||||||
if (slot == MenuCancel_ExitBack)
|
if (slot == MenuCancel_ExitBack)
|
||||||
{
|
{
|
||||||
WeaponsMenuMain(client);
|
WeaponsMenuMain(client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Client hit "Exit" button
|
// Client hit "Exit" button.
|
||||||
else if (action == MenuAction_End)
|
else if (action == MenuAction_End)
|
||||||
{
|
{
|
||||||
CloseHandle(menu_weapons_market);
|
CloseHandle(menu_weapons_market);
|
||||||
|
@ -38,22 +38,22 @@ enum WpnRestrictQuery
|
|||||||
*/
|
*/
|
||||||
RestrictInit()
|
RestrictInit()
|
||||||
{
|
{
|
||||||
// Initialize weapon restrict array
|
// Initialize weapon restrict array.
|
||||||
gRestrictedWeapons = CreateArray(32, 0);
|
gRestrictedWeapons = CreateArray(32, 0);
|
||||||
|
|
||||||
// Hook buy command
|
// Hook buy command.
|
||||||
RegConsoleCmd("buy", RestrictBuyHook);
|
RegConsoleCmd("buy", RestrictBuyHook);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears weapon restrict data
|
* Clears weapon restrict data.
|
||||||
*/
|
*/
|
||||||
RestrictClearData()
|
RestrictClearData()
|
||||||
{
|
{
|
||||||
// Clear restricted weapons
|
// Clear restricted weapons.
|
||||||
RestrictWeaponUnrestrictAll();
|
RestrictWeaponUnrestrictAll();
|
||||||
|
|
||||||
// Load weapon group data
|
// Load weapon group data.
|
||||||
if (kvWeaponGroups != INVALID_HANDLE)
|
if (kvWeaponGroups != INVALID_HANDLE)
|
||||||
{
|
{
|
||||||
CloseHandle(kvWeaponGroups);
|
CloseHandle(kvWeaponGroups);
|
||||||
@ -67,13 +67,13 @@ RestrictClearData()
|
|||||||
*/
|
*/
|
||||||
RestrictOnMapStart()
|
RestrictOnMapStart()
|
||||||
{
|
{
|
||||||
// Restrict default restrictions (set in weapons.txt)
|
// Restrict default restrictions. (set in weapons.txt)
|
||||||
RestrictDefaultRestrictions();
|
RestrictDefaultRestrictions();
|
||||||
|
|
||||||
decl String:path[PLATFORM_MAX_PATH];
|
decl String:path[PLATFORM_MAX_PATH];
|
||||||
BuildPath(Path_SM, path, sizeof(path), "configs/zr/weapons/weapongroups.txt");
|
BuildPath(Path_SM, path, sizeof(path), "configs/zr/weapons/weapongroups.txt");
|
||||||
|
|
||||||
// If file isn't found, stop plugin
|
// If file isn't found, stop plugin.
|
||||||
if (!FileToKeyValues(kvWeaponGroups, path))
|
if (!FileToKeyValues(kvWeaponGroups, path))
|
||||||
{
|
{
|
||||||
if (LogFlagCheck(LOG_CORE_EVENTS, LOG_MODULE_WEAPONS))
|
if (LogFlagCheck(LOG_CORE_EVENTS, LOG_MODULE_WEAPONS))
|
||||||
@ -88,7 +88,7 @@ RestrictOnMapStart()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restrict default restrictions (set in weapons.txt)
|
* Restrict default restrictions. (set in weapons.txt)
|
||||||
*/
|
*/
|
||||||
RestrictDefaultRestrictions()
|
RestrictDefaultRestrictions()
|
||||||
{
|
{
|
||||||
@ -103,7 +103,7 @@ RestrictDefaultRestrictions()
|
|||||||
{
|
{
|
||||||
KvGetSectionName(kvWeapons, weapon, sizeof(weapon));
|
KvGetSectionName(kvWeapons, weapon, sizeof(weapon));
|
||||||
|
|
||||||
// If weapon is defaulted to restricted, then restrict weapon
|
// If weapon is defaulted to restricted, then restrict weapon.
|
||||||
decl String:restrict[8];
|
decl String:restrict[8];
|
||||||
KvGetString(kvWeapons, "restrict", restrict, sizeof(restrict), "no");
|
KvGetString(kvWeapons, "restrict", restrict, sizeof(restrict), "no");
|
||||||
|
|
||||||
@ -113,7 +113,7 @@ RestrictDefaultRestrictions()
|
|||||||
RestrictPrintRestrictOutput(0, output, display, true);
|
RestrictPrintRestrictOutput(0, output, display, true);
|
||||||
|
|
||||||
// Function calls above screwed with the keyvalue stack, so we have to set it back
|
// Function calls above screwed with the keyvalue stack, so we have to set it back
|
||||||
// to where it was before those calls
|
// to where it was before those calls.
|
||||||
KvRewind(kvWeapons);
|
KvRewind(kvWeapons);
|
||||||
KvJumpToKey(kvWeapons, weapon);
|
KvJumpToKey(kvWeapons, weapon);
|
||||||
}
|
}
|
||||||
@ -126,14 +126,16 @@ RestrictDefaultRestrictions()
|
|||||||
*/
|
*/
|
||||||
RestrictValidateWeaponGroups()
|
RestrictValidateWeaponGroups()
|
||||||
{
|
{
|
||||||
// If log flag check fails, don't log
|
// If log flag check fails, don't log.
|
||||||
if (!LogFlagCheck(LOG_CORE_EVENTS, LOG_MODULE_WEAPONS))
|
if (!LogFlagCheck(LOG_CORE_EVENTS, LOG_MODULE_WEAPONS))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset keygroup's traversal stack.
|
||||||
KvRewind(kvWeaponGroups);
|
KvRewind(kvWeaponGroups);
|
||||||
|
|
||||||
|
// Traverse into the keygroup. (weapon groups level)
|
||||||
if (KvGotoFirstSubKey(kvWeaponGroups))
|
if (KvGotoFirstSubKey(kvWeaponGroups))
|
||||||
{
|
{
|
||||||
decl String:weapongroup[WEAPONS_MAX_LENGTH];
|
decl String:weapongroup[WEAPONS_MAX_LENGTH];
|
||||||
@ -143,12 +145,14 @@ RestrictValidateWeaponGroups()
|
|||||||
{
|
{
|
||||||
KvGetSectionName(kvWeaponGroups, weapongroup, sizeof(weapongroup));
|
KvGetSectionName(kvWeaponGroups, weapongroup, sizeof(weapongroup));
|
||||||
|
|
||||||
|
// Traverse into the keygroup. (weapons level)
|
||||||
if (KvGotoFirstSubKey(kvWeaponGroups))
|
if (KvGotoFirstSubKey(kvWeaponGroups))
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
KvGetSectionName(kvWeaponGroups, groupweapon, sizeof(groupweapon));
|
KvGetSectionName(kvWeaponGroups, groupweapon, sizeof(groupweapon));
|
||||||
|
|
||||||
|
// If weapon is invalid, then log it.
|
||||||
if (!WeaponsIsValidWeapon(groupweapon))
|
if (!WeaponsIsValidWeapon(groupweapon))
|
||||||
{
|
{
|
||||||
ZR_LogMessageFormatted(-1, "Weapon Restrict", "Config Validation", "Invalid weapon \"%s\" in group \"%s\" configured in weapongroups.txt.", LOG_FORMAT_TYPE_ERROR, groupweapon, weapongroup);
|
ZR_LogMessageFormatted(-1, "Weapon Restrict", "Config Validation", "Invalid weapon \"%s\" in group \"%s\" configured in weapongroups.txt.", LOG_FORMAT_TYPE_ERROR, groupweapon, weapongroup);
|
||||||
@ -157,6 +161,7 @@ RestrictValidateWeaponGroups()
|
|||||||
|
|
||||||
KvGoBack(kvWeaponGroups);
|
KvGoBack(kvWeaponGroups);
|
||||||
}
|
}
|
||||||
|
// If it couldn't traverse to the weapons, then log no weapons within group.
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ZR_LogMessageFormatted(-1, "Weapon Restrict", "Config Validation", "No weapons listed in weapon group \"%s\" in weapongroups.txt.", LOG_FORMAT_TYPE_ERROR, weapongroup);
|
ZR_LogMessageFormatted(-1, "Weapon Restrict", "Config Validation", "No weapons listed in weapon group \"%s\" in weapongroups.txt.", LOG_FORMAT_TYPE_ERROR, weapongroup);
|
||||||
@ -174,7 +179,7 @@ RestrictWeaponUnrestrictAll()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook Weapon_CanUse function on a client.
|
* Client is joining the server.
|
||||||
*
|
*
|
||||||
* @param client The client index.
|
* @param client The client index.
|
||||||
*/
|
*/
|
||||||
@ -202,15 +207,15 @@ RestrictOnClientDisconnect(client)
|
|||||||
*/
|
*/
|
||||||
public Action:RestrictBuyHook(client, argc)
|
public Action:RestrictBuyHook(client, argc)
|
||||||
{
|
{
|
||||||
// If plugin is disabled then stop
|
// If plugin is disabled then stop.
|
||||||
new bool:enabled = GetConVarBool(gCvars[CVAR_ENABLE]);
|
new bool:enabled = GetConVarBool(gCvars[CVAR_ENABLE]);
|
||||||
if (!enabled)
|
if (!enabled)
|
||||||
{
|
{
|
||||||
// Allow command
|
// Allow command.
|
||||||
return Plugin_Continue;
|
return Plugin_Continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If player is a zombie then block command
|
// If player is a zombie then block command.
|
||||||
if (IsPlayerZombie(client))
|
if (IsPlayerZombie(client))
|
||||||
{
|
{
|
||||||
ZR_PrintToChat(client, "Zombie cant use weapon");
|
ZR_PrintToChat(client, "Zombie cant use weapon");
|
||||||
@ -224,16 +229,16 @@ public Action:RestrictBuyHook(client, argc)
|
|||||||
|
|
||||||
ReplaceString(weapon, sizeof(weapon), "weapon_", "");
|
ReplaceString(weapon, sizeof(weapon), "weapon_", "");
|
||||||
|
|
||||||
// Check if the weapon is restricted, if so then block command
|
// Check if the weapon is restricted, if so then block command.
|
||||||
if (RestrictIsWeaponRestricted(weapon))
|
if (RestrictIsWeaponRestricted(weapon))
|
||||||
{
|
{
|
||||||
ZR_PrintToChat(client, "Weapon is restricted", weapon);
|
ZR_PrintToChat(client, "Weapon is restricted", weapon);
|
||||||
|
|
||||||
// Block command
|
// Block command.
|
||||||
return Plugin_Handled;
|
return Plugin_Handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow command
|
// Allow command.
|
||||||
return Plugin_Continue;
|
return Plugin_Continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,18 +256,23 @@ public Action:RestrictBuyHook(client, argc)
|
|||||||
*/
|
*/
|
||||||
WpnRestrictQuery:RestrictRestrict(const String:weapon[], String:display[] = "")
|
WpnRestrictQuery:RestrictRestrict(const String:weapon[], String:display[] = "")
|
||||||
{
|
{
|
||||||
|
// Check if weapon is a custom group name.
|
||||||
if (RestrictIsWeaponGroup(weapon))
|
if (RestrictIsWeaponGroup(weapon))
|
||||||
{
|
{
|
||||||
|
// Return restrict failed if group is already restricted.
|
||||||
if (RestrictIsGroupRestricted(weapon))
|
if (RestrictIsGroupRestricted(weapon))
|
||||||
{
|
{
|
||||||
return Failed_Group;
|
return Failed_Group;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Jump to weapon group key.
|
||||||
KvRewind(kvWeaponGroups);
|
KvRewind(kvWeaponGroups);
|
||||||
KvJumpToKey(kvWeaponGroups, weapon);
|
KvJumpToKey(kvWeaponGroups, weapon);
|
||||||
|
|
||||||
|
// Get display name of the weapon group.
|
||||||
KvGetSectionName(kvWeaponGroups, display, WEAPONS_MAX_LENGTH);
|
KvGetSectionName(kvWeaponGroups, display, WEAPONS_MAX_LENGTH);
|
||||||
|
|
||||||
|
// Traverse into the group's weapons.
|
||||||
if (KvGotoFirstSubKey(kvWeaponGroups))
|
if (KvGotoFirstSubKey(kvWeaponGroups))
|
||||||
{
|
{
|
||||||
decl String:groupweapon[WEAPONS_MAX_LENGTH];
|
decl String:groupweapon[WEAPONS_MAX_LENGTH];
|
||||||
@ -271,12 +281,13 @@ WpnRestrictQuery:RestrictRestrict(const String:weapon[], String:display[] = "")
|
|||||||
{
|
{
|
||||||
KvGetSectionName(kvWeaponGroups, groupweapon, sizeof(groupweapon));
|
KvGetSectionName(kvWeaponGroups, groupweapon, sizeof(groupweapon));
|
||||||
|
|
||||||
// If weapon is invalid, then skip
|
// If weapon is invalid, then skip.
|
||||||
if (!WeaponsIsValidWeapon(groupweapon))
|
if (!WeaponsIsValidWeapon(groupweapon))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add to restricted weapon array if not already restricted.
|
||||||
if (!RestrictIsWeaponRestricted(groupweapon))
|
if (!RestrictIsWeaponRestricted(groupweapon))
|
||||||
{
|
{
|
||||||
PushArrayString(gRestrictedWeapons, groupweapon);
|
PushArrayString(gRestrictedWeapons, groupweapon);
|
||||||
@ -284,23 +295,29 @@ WpnRestrictQuery:RestrictRestrict(const String:weapon[], String:display[] = "")
|
|||||||
} while (KvGotoNextKey(kvWeaponGroups));
|
} while (KvGotoNextKey(kvWeaponGroups));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Successfully restricted a group
|
||||||
return Successful_Group;
|
return Successful_Group;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If weapon name is invalid then set display to invalid weapon name.
|
||||||
if (!WeaponsIsValidWeapon(weapon))
|
if (!WeaponsIsValidWeapon(weapon))
|
||||||
{
|
{
|
||||||
strcopy(display, WEAPONS_MAX_LENGTH, weapon);
|
strcopy(display, WEAPONS_MAX_LENGTH, weapon);
|
||||||
|
|
||||||
|
// Weapon name was invalid.
|
||||||
return Invalid;
|
return Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get display name of the weapon.
|
||||||
WeaponGetDisplayName(weapon, display);
|
WeaponGetDisplayName(weapon, display);
|
||||||
|
|
||||||
|
// Return restrict failed if weapon is already restricted.
|
||||||
if (RestrictIsWeaponRestricted(weapon))
|
if (RestrictIsWeaponRestricted(weapon))
|
||||||
{
|
{
|
||||||
return Failed_Weapon;
|
return Failed_Weapon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add to restricted weapon array.
|
||||||
PushArrayString(gRestrictedWeapons, display);
|
PushArrayString(gRestrictedWeapons, display);
|
||||||
|
|
||||||
return Successful_Weapon;
|
return Successful_Weapon;
|
||||||
@ -310,8 +327,8 @@ WpnRestrictQuery:RestrictRestrict(const String:weapon[], String:display[] = "")
|
|||||||
* Unrestricts a weapon.
|
* Unrestricts a weapon.
|
||||||
*
|
*
|
||||||
* @param weapon The weapon/group name.
|
* @param weapon The weapon/group name.
|
||||||
* @param display String set to the name set in weapons.txt
|
* @param display String set to the name set in weapons.txt.
|
||||||
* Set to the value of 'weapon' if invalid
|
* Set to the value of 'weapon' if invalid.
|
||||||
* @return Successful_Weapon: The call successfully restricted a weapon.
|
* @return Successful_Weapon: The call successfully restricted a weapon.
|
||||||
* Successful_Group: The call successfully restricted a weapon group.
|
* Successful_Group: The call successfully restricted a weapon group.
|
||||||
* Failed_Weapon: The call failed to restrict a weapon.
|
* Failed_Weapon: The call failed to restrict a weapon.
|
||||||
@ -320,18 +337,23 @@ WpnRestrictQuery:RestrictRestrict(const String:weapon[], String:display[] = "")
|
|||||||
*/
|
*/
|
||||||
WpnRestrictQuery:RestrictUnrestrict(const String:weapon[], String:display[] = "")
|
WpnRestrictQuery:RestrictUnrestrict(const String:weapon[], String:display[] = "")
|
||||||
{
|
{
|
||||||
|
// Check if weapon is a custom group name.
|
||||||
if (RestrictIsWeaponGroup(weapon))
|
if (RestrictIsWeaponGroup(weapon))
|
||||||
{
|
{
|
||||||
|
// Return restrict failed if group isn't restricted.
|
||||||
if (RestrictIsGroupUnrestricted(weapon))
|
if (RestrictIsGroupUnrestricted(weapon))
|
||||||
{
|
{
|
||||||
return Failed_Group;
|
return Failed_Group;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Jump to weapon group key.
|
||||||
KvRewind(kvWeaponGroups);
|
KvRewind(kvWeaponGroups);
|
||||||
KvJumpToKey(kvWeaponGroups, weapon);
|
KvJumpToKey(kvWeaponGroups, weapon);
|
||||||
|
|
||||||
|
// Get display name of the weapon group.
|
||||||
KvGetSectionName(kvWeaponGroups, display, WEAPONS_MAX_LENGTH);
|
KvGetSectionName(kvWeaponGroups, display, WEAPONS_MAX_LENGTH);
|
||||||
|
|
||||||
|
// Traverse into the group's weapons.
|
||||||
if (KvGotoFirstSubKey(kvWeaponGroups))
|
if (KvGotoFirstSubKey(kvWeaponGroups))
|
||||||
{
|
{
|
||||||
decl String:groupweapon[WEAPONS_MAX_LENGTH];
|
decl String:groupweapon[WEAPONS_MAX_LENGTH];
|
||||||
@ -346,8 +368,10 @@ WpnRestrictQuery:RestrictUnrestrict(const String:weapon[], String:display[] = ""
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove from restricted weapon array if currently restricted.
|
||||||
if (RestrictIsWeaponRestricted(groupweapon))
|
if (RestrictIsWeaponRestricted(groupweapon))
|
||||||
{
|
{
|
||||||
|
// Verify weapon is in the array.
|
||||||
new weaponindex = RestrictGetIndex(groupweapon);
|
new weaponindex = RestrictGetIndex(groupweapon);
|
||||||
if (weaponindex > -1)
|
if (weaponindex > -1)
|
||||||
{
|
{
|
||||||
@ -357,9 +381,11 @@ WpnRestrictQuery:RestrictUnrestrict(const String:weapon[], String:display[] = ""
|
|||||||
} while (KvGotoNextKey(kvWeaponGroups));
|
} while (KvGotoNextKey(kvWeaponGroups));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Successfully unrestricted a group
|
||||||
return Successful_Group;
|
return Successful_Group;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If weapon name is invalid then set display to invalid weapon name.
|
||||||
if (!WeaponsIsValidWeapon(weapon))
|
if (!WeaponsIsValidWeapon(weapon))
|
||||||
{
|
{
|
||||||
strcopy(display, WEAPONS_MAX_LENGTH, weapon);
|
strcopy(display, WEAPONS_MAX_LENGTH, weapon);
|
||||||
@ -367,16 +393,20 @@ WpnRestrictQuery:RestrictUnrestrict(const String:weapon[], String:display[] = ""
|
|||||||
return Invalid;
|
return Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get display name of the weapon.
|
||||||
WeaponGetDisplayName(weapon, display);
|
WeaponGetDisplayName(weapon, display);
|
||||||
|
|
||||||
|
// Return unrestrict failed if weapon isn't restricted.
|
||||||
if (!RestrictIsWeaponRestricted(weapon))
|
if (!RestrictIsWeaponRestricted(weapon))
|
||||||
{
|
{
|
||||||
return Failed_Weapon;
|
return Failed_Weapon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify weapon is in the array.
|
||||||
new weaponindex = RestrictGetIndex(display);
|
new weaponindex = RestrictGetIndex(display);
|
||||||
if (weaponindex > -1)
|
if (weaponindex > -1)
|
||||||
{
|
{
|
||||||
|
// Remove from restricted weapon array.
|
||||||
RemoveFromArray(gRestrictedWeapons, weaponindex);
|
RemoveFromArray(gRestrictedWeapons, weaponindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -394,6 +424,7 @@ RestrictPrintRestrictOutput(client, WpnRestrictQuery:output, const String:weapon
|
|||||||
{
|
{
|
||||||
switch(output)
|
switch(output)
|
||||||
{
|
{
|
||||||
|
// Weapon was successfully restricted.
|
||||||
case Successful_Weapon:
|
case Successful_Weapon:
|
||||||
{
|
{
|
||||||
ZR_PrintToChat(0, "Restrict weapon", weapon);
|
ZR_PrintToChat(0, "Restrict weapon", weapon);
|
||||||
@ -403,6 +434,7 @@ RestrictPrintRestrictOutput(client, WpnRestrictQuery:output, const String:weapon
|
|||||||
ZR_LogMessageFormatted(client, "Weapon Restrict", "Restrict", "\"%L\" restricted weapon: \"%s\".", LOG_FORMAT_TYPE_FULL, client, weapon);
|
ZR_LogMessageFormatted(client, "Weapon Restrict", "Restrict", "\"%L\" restricted weapon: \"%s\".", LOG_FORMAT_TYPE_FULL, client, weapon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Weapon group was successfully restricted.
|
||||||
case Successful_Group:
|
case Successful_Group:
|
||||||
{
|
{
|
||||||
decl String:weaponlist[128];
|
decl String:weaponlist[128];
|
||||||
@ -415,6 +447,7 @@ RestrictPrintRestrictOutput(client, WpnRestrictQuery:output, const String:weapon
|
|||||||
ZR_LogMessageFormatted(client, "Weapon Restrict", "Restrict", "\"%L\" restricted weapon group: \"%s\".", LOG_FORMAT_TYPE_FULL, client, weapon);
|
ZR_LogMessageFormatted(client, "Weapon Restrict", "Restrict", "\"%L\" restricted weapon group: \"%s\".", LOG_FORMAT_TYPE_FULL, client, weapon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Weapon was already restricted.
|
||||||
case Failed_Weapon:
|
case Failed_Weapon:
|
||||||
{
|
{
|
||||||
if (reply)
|
if (reply)
|
||||||
@ -426,6 +459,7 @@ RestrictPrintRestrictOutput(client, WpnRestrictQuery:output, const String:weapon
|
|||||||
ZR_PrintToChat(client, "Restrict weapon failed", weapon);
|
ZR_PrintToChat(client, "Restrict weapon failed", weapon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Weapon group was already restricted.
|
||||||
case Failed_Group:
|
case Failed_Group:
|
||||||
{
|
{
|
||||||
decl String:weaponlist[128];
|
decl String:weaponlist[128];
|
||||||
@ -440,6 +474,7 @@ RestrictPrintRestrictOutput(client, WpnRestrictQuery:output, const String:weapon
|
|||||||
ZR_PrintToChat(client, "Restrict custom weapon group failed", weapon, weaponlist);
|
ZR_PrintToChat(client, "Restrict custom weapon group failed", weapon, weaponlist);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Weapon name was invalid.
|
||||||
case Invalid:
|
case Invalid:
|
||||||
{
|
{
|
||||||
if (reply)
|
if (reply)
|
||||||
@ -465,6 +500,7 @@ RestrictPrintUnrestrictOutput(client, WpnRestrictQuery:output, const String:weap
|
|||||||
{
|
{
|
||||||
switch(output)
|
switch(output)
|
||||||
{
|
{
|
||||||
|
// Weapon was successfully unrestricted.
|
||||||
case Successful_Weapon:
|
case Successful_Weapon:
|
||||||
{
|
{
|
||||||
ZR_PrintToChat(0, "Unrestrict weapon", weapon);
|
ZR_PrintToChat(0, "Unrestrict weapon", weapon);
|
||||||
@ -474,6 +510,7 @@ RestrictPrintUnrestrictOutput(client, WpnRestrictQuery:output, const String:weap
|
|||||||
ZR_LogMessageFormatted(client, "Weapon Restrict", "Unrestrict", "\"%L\" unrestricted weapon: \"%s\".", LOG_FORMAT_TYPE_FULL, client, weapon);
|
ZR_LogMessageFormatted(client, "Weapon Restrict", "Unrestrict", "\"%L\" unrestricted weapon: \"%s\".", LOG_FORMAT_TYPE_FULL, client, weapon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Weapon group was successfully unrestricted.
|
||||||
case Successful_Group:
|
case Successful_Group:
|
||||||
{
|
{
|
||||||
decl String:weaponlist[128];
|
decl String:weaponlist[128];
|
||||||
@ -486,6 +523,7 @@ RestrictPrintUnrestrictOutput(client, WpnRestrictQuery:output, const String:weap
|
|||||||
ZR_LogMessageFormatted(client, "Weapon Restrict", "Unrestrict", "\"%L\" unrestricted weapon group: \"%s\".", LOG_FORMAT_TYPE_FULL, client, weapon);
|
ZR_LogMessageFormatted(client, "Weapon Restrict", "Unrestrict", "\"%L\" unrestricted weapon group: \"%s\".", LOG_FORMAT_TYPE_FULL, client, weapon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Weapon wasn't restricted.
|
||||||
case Failed_Weapon:
|
case Failed_Weapon:
|
||||||
{
|
{
|
||||||
if (reply)
|
if (reply)
|
||||||
@ -497,6 +535,7 @@ RestrictPrintUnrestrictOutput(client, WpnRestrictQuery:output, const String:weap
|
|||||||
ZR_PrintToChat(client, "Unrestrict weapon failed", weapon);
|
ZR_PrintToChat(client, "Unrestrict weapon failed", weapon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Weapon group wasn't restricted.
|
||||||
case Failed_Group:
|
case Failed_Group:
|
||||||
{
|
{
|
||||||
decl String:weaponlist[128];
|
decl String:weaponlist[128];
|
||||||
@ -511,6 +550,7 @@ RestrictPrintUnrestrictOutput(client, WpnRestrictQuery:output, const String:weap
|
|||||||
ZR_PrintToChat(client, "Unrestrict custom weapon group failed", weapon, weaponlist);
|
ZR_PrintToChat(client, "Unrestrict custom weapon group failed", weapon, weaponlist);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Weapon name was invalid.
|
||||||
case Invalid:
|
case Invalid:
|
||||||
{
|
{
|
||||||
if (reply)
|
if (reply)
|
||||||
@ -529,22 +569,28 @@ RestrictPrintUnrestrictOutput(client, WpnRestrictQuery:output, const String:weap
|
|||||||
* Checks if a weapon is restricted.
|
* Checks if a weapon is restricted.
|
||||||
*
|
*
|
||||||
* @param weapon The weapon name.
|
* @param weapon The weapon name.
|
||||||
|
* @return True if weapon is restricted, false if not.
|
||||||
*/
|
*/
|
||||||
bool:RestrictIsWeaponRestricted(const String:weapon[])
|
bool:RestrictIsWeaponRestricted(const String:weapon[])
|
||||||
{
|
{
|
||||||
decl String:restrictedweapon[WEAPONS_MAX_LENGTH];
|
decl String:restrictedweapon[WEAPONS_MAX_LENGTH];
|
||||||
|
|
||||||
new size = GetArraySize(gRestrictedWeapons);
|
new size = GetArraySize(gRestrictedWeapons);
|
||||||
|
|
||||||
|
// x = restricted weapon index.
|
||||||
for (new x = 0; x < size; x++)
|
for (new x = 0; x < size; x++)
|
||||||
{
|
{
|
||||||
GetArrayString(gRestrictedWeapons, x, restrictedweapon, sizeof(restrictedweapon));
|
GetArrayString(gRestrictedWeapons, x, restrictedweapon, sizeof(restrictedweapon));
|
||||||
|
|
||||||
|
// Check if weapon matches any weapon names in the restricted weapon array.
|
||||||
if (StrEqual(weapon, restrictedweapon, false))
|
if (StrEqual(weapon, restrictedweapon, false))
|
||||||
{
|
{
|
||||||
|
// Weapon is restricted.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Weapon is not restricted.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -555,11 +601,15 @@ bool:RestrictIsWeaponRestricted(const String:weapon[])
|
|||||||
*/
|
*/
|
||||||
bool:RestrictIsGroupRestricted(const String:weapongroup[])
|
bool:RestrictIsGroupRestricted(const String:weapongroup[])
|
||||||
{
|
{
|
||||||
|
// Reset keygroup's traversal stack.
|
||||||
KvRewind(kvWeaponGroups);
|
KvRewind(kvWeaponGroups);
|
||||||
|
|
||||||
|
// Traverse in to the group names.
|
||||||
if (KvJumpToKey(kvWeaponGroups, weapongroup))
|
if (KvJumpToKey(kvWeaponGroups, weapongroup))
|
||||||
{
|
{
|
||||||
decl String:groupweapon[WEAPONS_MAX_LENGTH];
|
decl String:groupweapon[WEAPONS_MAX_LENGTH];
|
||||||
|
|
||||||
|
// Traverse into the group's weapons.
|
||||||
if (KvGotoFirstSubKey(kvWeaponGroups))
|
if (KvGotoFirstSubKey(kvWeaponGroups))
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
@ -587,11 +637,15 @@ bool:RestrictIsGroupRestricted(const String:weapongroup[])
|
|||||||
*/
|
*/
|
||||||
bool:RestrictIsGroupUnrestricted(const String:weapongroup[])
|
bool:RestrictIsGroupUnrestricted(const String:weapongroup[])
|
||||||
{
|
{
|
||||||
|
// Reset keygroup's traversal stack.
|
||||||
KvRewind(kvWeaponGroups);
|
KvRewind(kvWeaponGroups);
|
||||||
|
|
||||||
|
// Traverse in to the group names.
|
||||||
if (KvJumpToKey(kvWeaponGroups, weapongroup))
|
if (KvJumpToKey(kvWeaponGroups, weapongroup))
|
||||||
{
|
{
|
||||||
decl String:groupweapon[WEAPONS_MAX_LENGTH];
|
decl String:groupweapon[WEAPONS_MAX_LENGTH];
|
||||||
|
|
||||||
|
// Traverse into the group's weapons.
|
||||||
if (KvGotoFirstSubKey(kvWeaponGroups))
|
if (KvGotoFirstSubKey(kvWeaponGroups))
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
@ -632,16 +686,21 @@ RestrictGetIndex(const String:weapon[])
|
|||||||
decl String:restrictedweapon[WEAPONS_MAX_LENGTH];
|
decl String:restrictedweapon[WEAPONS_MAX_LENGTH];
|
||||||
|
|
||||||
new size = GetArraySize(gRestrictedWeapons);
|
new size = GetArraySize(gRestrictedWeapons);
|
||||||
|
|
||||||
|
// x = restricted weapon index.
|
||||||
for (new x = 0; x < size; x++)
|
for (new x = 0; x < size; x++)
|
||||||
{
|
{
|
||||||
GetArrayString(gRestrictedWeapons, x, restrictedweapon, sizeof(restrictedweapon));
|
GetArrayString(gRestrictedWeapons, x, restrictedweapon, sizeof(restrictedweapon));
|
||||||
|
|
||||||
|
// Check if weapon matches weapon in restricted weapons array.
|
||||||
if (StrEqual(weapon, restrictedweapon, false))
|
if (StrEqual(weapon, restrictedweapon, false))
|
||||||
{
|
{
|
||||||
|
// Return restricted weapon's index.
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Weapon isn't restricted.
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,10 +712,10 @@ RestrictGetIndex(const String:weapon[])
|
|||||||
*/
|
*/
|
||||||
bool:RestrictIsWeaponGroup(const String:groupname[])
|
bool:RestrictIsWeaponGroup(const String:groupname[])
|
||||||
{
|
{
|
||||||
// Reset the traversal stack
|
// Reset keygroup's traversal stack.
|
||||||
KvRewind(kvWeaponGroups);
|
KvRewind(kvWeaponGroups);
|
||||||
|
|
||||||
// Returns true if groupname is listed in the custom groups file
|
// Returns true if groupname is listed in the custom groups file.
|
||||||
return KvJumpToKey(kvWeaponGroups, groupname);
|
return KvJumpToKey(kvWeaponGroups, groupname);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -710,7 +769,7 @@ RestrictCreateGroupWeaponsArray(&Handle:arrayGroupWeapons, const String:weapongr
|
|||||||
{
|
{
|
||||||
KvGetSectionName(kvWeaponGroups, groupweapon, maxlen);
|
KvGetSectionName(kvWeaponGroups, groupweapon, maxlen);
|
||||||
|
|
||||||
// If the weapon is invalid, then stop
|
// If the weapon is invalid, then stop.
|
||||||
if (!WeaponsIsValidWeapon(groupweapon))
|
if (!WeaponsIsValidWeapon(groupweapon))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@ -749,7 +808,7 @@ RestrictGetGroupWeapons(const String:groupname[], String:weaponlist[], maxlen, c
|
|||||||
{
|
{
|
||||||
KvGetSectionName(kvWeaponGroups, groupweapon, sizeof(groupweapon));
|
KvGetSectionName(kvWeaponGroups, groupweapon, sizeof(groupweapon));
|
||||||
|
|
||||||
// If weapon is invalid, then skip
|
// If weapon is invalid, then skip.
|
||||||
if (!WeaponsIsValidWeapon(groupweapon))
|
if (!WeaponsIsValidWeapon(groupweapon))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@ -775,7 +834,7 @@ RestrictGetGroupWeapons(const String:groupname[], String:weaponlist[], maxlen, c
|
|||||||
*/
|
*/
|
||||||
public RestrictCanUse(client, weapon, dummy1, dummy2, dummy3, dummy4)
|
public RestrictCanUse(client, weapon, dummy1, dummy2, dummy3, dummy4)
|
||||||
{
|
{
|
||||||
// If plugin is disabled then stop
|
// If plugin is disabled then stop.
|
||||||
new bool:enabled = GetConVarBool(gCvars[CVAR_ENABLE]);
|
new bool:enabled = GetConVarBool(gCvars[CVAR_ENABLE]);
|
||||||
if (!enabled)
|
if (!enabled)
|
||||||
{
|
{
|
||||||
@ -785,16 +844,16 @@ public RestrictCanUse(client, weapon, dummy1, dummy2, dummy3, dummy4)
|
|||||||
new String:weaponname[WEAPONS_MAX_LENGTH];
|
new String:weaponname[WEAPONS_MAX_LENGTH];
|
||||||
GetEdictClassname(weapon, weaponname, sizeof(weaponname));
|
GetEdictClassname(weapon, weaponname, sizeof(weaponname));
|
||||||
|
|
||||||
// Strip "weapon_" from entity name
|
// Strip "weapon_" from entity name.
|
||||||
ReplaceString(weaponname, sizeof(weaponname), "weapon_", "");
|
ReplaceString(weaponname, sizeof(weaponname), "weapon_", "");
|
||||||
|
|
||||||
// If the weapon is restricted then prevent pickup
|
// If the weapon is restricted then prevent pickup.
|
||||||
if (RestrictIsWeaponRestricted(weaponname))
|
if (RestrictIsWeaponRestricted(weaponname))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the player is a zombie and the weapon isn't a knife then prevent pickup
|
// If the player is a zombie and the weapon isn't a knife then prevent pickup.
|
||||||
if (IsPlayerZombie(client) && !StrEqual(weaponname, "knife"))
|
if (IsPlayerZombie(client) && !StrEqual(weaponname, "knife"))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -25,7 +25,7 @@ new Handle:kvWeapons = INVALID_HANDLE;
|
|||||||
#include "zr/weapons/menu_weapons"
|
#include "zr/weapons/menu_weapons"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Weapons module init function
|
* Weapons module init function.
|
||||||
*/
|
*/
|
||||||
WeaponsInit()
|
WeaponsInit()
|
||||||
{
|
{
|
||||||
@ -34,7 +34,7 @@ WeaponsInit()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears weapon data
|
* Clears weapon data.
|
||||||
*/
|
*/
|
||||||
WeaponsClearData()
|
WeaponsClearData()
|
||||||
{
|
{
|
||||||
@ -50,18 +50,18 @@ WeaponsClearData()
|
|||||||
/**
|
/**
|
||||||
* Loads weapon data from file.
|
* Loads weapon data from file.
|
||||||
*/
|
*/
|
||||||
WeaponsOnMapStart()
|
WeaponsLoad()
|
||||||
{
|
{
|
||||||
// Clear weapon data
|
// Clear weapon data.
|
||||||
WeaponsClearData();
|
WeaponsClearData();
|
||||||
|
|
||||||
// Clear weapon restrict data
|
// Clear weapon restrict data.
|
||||||
RestrictClearData();
|
RestrictClearData();
|
||||||
|
|
||||||
decl String:path[PLATFORM_MAX_PATH];
|
decl String:path[PLATFORM_MAX_PATH];
|
||||||
BuildPath(Path_SM, path, sizeof(path), "configs/zr/weapons/weapons.txt");
|
BuildPath(Path_SM, path, sizeof(path), "configs/zr/weapons/weapons.txt");
|
||||||
|
|
||||||
// If file isn't found, stop plugin
|
// If file isn't found, stop plugin.
|
||||||
if (!FileToKeyValues(kvWeapons, path))
|
if (!FileToKeyValues(kvWeapons, path))
|
||||||
{
|
{
|
||||||
if (LogFlagCheck(LOG_CORE_EVENTS, LOG_MODULE_WEAPONS))
|
if (LogFlagCheck(LOG_CORE_EVENTS, LOG_MODULE_WEAPONS))
|
||||||
@ -72,16 +72,19 @@ WeaponsOnMapStart()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate weapons config
|
// Validate weapons config.
|
||||||
WeaponsValidateWeaponsConfig();
|
WeaponsValidateConfig();
|
||||||
|
|
||||||
// Forward event to sub-module
|
// Forward event to sub-module.
|
||||||
RestrictOnMapStart();
|
RestrictOnMapStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
WeaponsValidateWeaponsConfig()
|
/**
|
||||||
|
* Validate weapon config file and settings.
|
||||||
|
*/
|
||||||
|
WeaponsValidateConfig()
|
||||||
{
|
{
|
||||||
// If log flag check fails, don't log
|
// If log flag check fails, don't log.
|
||||||
if (!LogFlagCheck(LOG_CORE_EVENTS, LOG_MODULE_WEAPONS))
|
if (!LogFlagCheck(LOG_CORE_EVENTS, LOG_MODULE_WEAPONS))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -94,15 +97,25 @@ WeaponsValidateWeaponsConfig()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client is joining the server.
|
||||||
|
*
|
||||||
|
* @param client The client index.
|
||||||
|
*/
|
||||||
WeaponsClientInit(client)
|
WeaponsClientInit(client)
|
||||||
{
|
{
|
||||||
// Forward event to sub-module
|
// Forward event to sub-module.
|
||||||
RestrictClientInit(client);
|
RestrictClientInit(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client is leaving the server.
|
||||||
|
*
|
||||||
|
* @param client The client index.
|
||||||
|
*/
|
||||||
WeaponsOnClientDisconnect(client)
|
WeaponsOnClientDisconnect(client)
|
||||||
{
|
{
|
||||||
// Forward event to sub-module
|
// Forward event to sub-module.
|
||||||
RestrictOnClientDisconnect(client);
|
RestrictOnClientDisconnect(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +141,7 @@ WeaponsCreateWeaponArray(&Handle:arrayWeapons, maxlen = WEAPONS_MAX_LENGTH)
|
|||||||
{
|
{
|
||||||
KvGetSectionName(kvWeapons, weapon, maxlen);
|
KvGetSectionName(kvWeapons, weapon, maxlen);
|
||||||
|
|
||||||
// Push weapon name into the array
|
// Push weapon name into the array.
|
||||||
PushArrayString(arrayWeapons, weapon);
|
PushArrayString(arrayWeapons, weapon);
|
||||||
|
|
||||||
// Increment count.
|
// Increment count.
|
||||||
@ -141,12 +154,13 @@ WeaponsCreateWeaponArray(&Handle:arrayWeapons, maxlen = WEAPONS_MAX_LENGTH)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a weapon is valid (aka listed in weapons.txt)
|
* Checks if a weapon is valid. (aka listed in weapons.txt)
|
||||||
* @param weapon The weapon name.
|
* @param weapon The weapon name.
|
||||||
* @return Returns true if valid, false it not.
|
* @return Returns true if valid, false it not.
|
||||||
*/
|
*/
|
||||||
bool:WeaponsIsValidWeapon(const String:weapon[])
|
bool:WeaponsIsValidWeapon(const String:weapon[])
|
||||||
{
|
{
|
||||||
|
// Reset keyvalue's traversal stack.
|
||||||
KvRewind(kvWeapons);
|
KvRewind(kvWeapons);
|
||||||
if (KvGotoFirstSubKey(kvWeapons))
|
if (KvGotoFirstSubKey(kvWeapons))
|
||||||
{
|
{
|
||||||
@ -156,6 +170,7 @@ bool:WeaponsIsValidWeapon(const String:weapon[])
|
|||||||
{
|
{
|
||||||
KvGetSectionName(kvWeapons, validweapon, sizeof(validweapon));
|
KvGetSectionName(kvWeapons, validweapon, sizeof(validweapon));
|
||||||
|
|
||||||
|
// If weaponname matches a valid weapon, then return true.
|
||||||
if (StrEqual(validweapon, weapon, false))
|
if (StrEqual(validweapon, weapon, false))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@ -164,16 +179,18 @@ bool:WeaponsIsValidWeapon(const String:weapon[])
|
|||||||
} while (KvGotoNextKey(kvWeapons));
|
} while (KvGotoNextKey(kvWeapons));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Weapon is invalid.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Looks up a weapon in weapons.txt and returns exact display name
|
* Looks up a weapon in weapons.txt and returns exact display name.
|
||||||
* @param weapon The weapon name.
|
* @param weapon The weapon name.
|
||||||
* @param display Returns with the display name, is not changed if weapon is invalid.
|
* @param display Returns with the display name, is not changed if weapon is invalid.
|
||||||
*/
|
*/
|
||||||
WeaponGetDisplayName(const String:weapon[], String:display[])
|
WeaponGetDisplayName(const String:weapon[], String:display[])
|
||||||
{
|
{
|
||||||
|
// Reset keyvalue's traversal stack.
|
||||||
KvRewind(kvWeapons);
|
KvRewind(kvWeapons);
|
||||||
if (KvGotoFirstSubKey(kvWeapons))
|
if (KvGotoFirstSubKey(kvWeapons))
|
||||||
{
|
{
|
||||||
@ -183,6 +200,7 @@ WeaponGetDisplayName(const String:weapon[], String:display[])
|
|||||||
{
|
{
|
||||||
KvGetSectionName(kvWeapons, validweapon, sizeof(validweapon));
|
KvGetSectionName(kvWeapons, validweapon, sizeof(validweapon));
|
||||||
|
|
||||||
|
// If weapon matches a valid weapon (case-insensitive), then return display name.
|
||||||
if (StrEqual(validweapon, weapon, false))
|
if (StrEqual(validweapon, weapon, false))
|
||||||
{
|
{
|
||||||
strcopy(display, WEAPONS_MAX_LENGTH, validweapon);
|
strcopy(display, WEAPONS_MAX_LENGTH, validweapon);
|
||||||
@ -225,7 +243,7 @@ bool:WeaponsIsWeaponMenu(const String:weapon[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns knockback multiplier of the weapon
|
* Returns knockback multiplier of the weapon.
|
||||||
* @param weapon The weapon name.
|
* @param weapon The weapon name.
|
||||||
* @return The float value of the knockback multiplier, 1.0 if not found.
|
* @return The float value of the knockback multiplier, 1.0 if not found.
|
||||||
*/
|
*/
|
||||||
|
@ -519,6 +519,7 @@ ZRLogFlagsMenu(client)
|
|||||||
decl String:z_log_module_teleport[64];
|
decl String:z_log_module_teleport[64];
|
||||||
decl String:z_log_module_classes[64];
|
decl String:z_log_module_classes[64];
|
||||||
decl String:z_log_module_weapons[64];
|
decl String:z_log_module_weapons[64];
|
||||||
|
decl String:z_log_module_hitgroups[64];
|
||||||
decl String:z_log_module_commands[64];
|
decl String:z_log_module_commands[64];
|
||||||
decl String:z_log_module_anticamp[64];
|
decl String:z_log_module_anticamp[64];
|
||||||
decl String:z_log_module_damagecontrol[64];
|
decl String:z_log_module_damagecontrol[64];
|
||||||
@ -541,6 +542,7 @@ ZRLogFlagsMenu(client)
|
|||||||
Format(z_log_module_teleport, sizeof(z_log_module_teleport), "Teleporter (%d)", LogHasFlag(LOG_MODULE_TELEPORT));
|
Format(z_log_module_teleport, sizeof(z_log_module_teleport), "Teleporter (%d)", LogHasFlag(LOG_MODULE_TELEPORT));
|
||||||
Format(z_log_module_classes, sizeof(z_log_module_classes), "Classes (%d)", LogHasFlag(LOG_MODULE_CLASSES));
|
Format(z_log_module_classes, sizeof(z_log_module_classes), "Classes (%d)", LogHasFlag(LOG_MODULE_CLASSES));
|
||||||
Format(z_log_module_weapons, sizeof(z_log_module_weapons), "Weapons (%d)", LogHasFlag(LOG_MODULE_WEAPONS));
|
Format(z_log_module_weapons, sizeof(z_log_module_weapons), "Weapons (%d)", LogHasFlag(LOG_MODULE_WEAPONS));
|
||||||
|
Format(z_log_module_hitgroups, sizeof(z_log_module_hitgroups), "Hitgroups (%d)", LogHasFlag(LOG_MODULE_HITGROUPS));
|
||||||
Format(z_log_module_commands, sizeof(z_log_module_commands), "Admin commands (%d)", LogHasFlag(LOG_MODULE_COMMANDS));
|
Format(z_log_module_commands, sizeof(z_log_module_commands), "Admin commands (%d)", LogHasFlag(LOG_MODULE_COMMANDS));
|
||||||
Format(z_log_module_anticamp, sizeof(z_log_module_anticamp), "Anticamp (%d)", LogHasFlag(LOG_MODULE_ANTICAMP));
|
Format(z_log_module_anticamp, sizeof(z_log_module_anticamp), "Anticamp (%d)", LogHasFlag(LOG_MODULE_ANTICAMP));
|
||||||
Format(z_log_module_damagecontrol, sizeof(z_log_module_damagecontrol), "Damage control (suicides) (%d)", LogHasFlag(LOG_MODULE_DAMAGECONTROL));
|
Format(z_log_module_damagecontrol, sizeof(z_log_module_damagecontrol), "Damage control (suicides) (%d)", LogHasFlag(LOG_MODULE_DAMAGECONTROL));
|
||||||
@ -665,20 +667,25 @@ public ZRLogFlagsMenuHandle(Handle:menu_log_flags , MenuAction:action, client, s
|
|||||||
}
|
}
|
||||||
case 17:
|
case 17:
|
||||||
{
|
{
|
||||||
ToggleLogFlag(LOG_MODULE_COMMANDS);
|
ToggleLogFlag(LOG_MODULE_HITGROUPS);
|
||||||
ZRLogFlagsMenu(client);
|
ZRLogFlagsMenu(client);
|
||||||
}
|
}
|
||||||
case 18:
|
case 18:
|
||||||
{
|
{
|
||||||
ToggleLogFlag(LOG_MODULE_ANTICAMP);
|
ToggleLogFlag(LOG_MODULE_COMMANDS);
|
||||||
ZRLogFlagsMenu(client);
|
ZRLogFlagsMenu(client);
|
||||||
}
|
}
|
||||||
case 19:
|
case 19:
|
||||||
{
|
{
|
||||||
ToggleLogFlag(LOG_MODULE_DAMAGECONTROL);
|
ToggleLogFlag(LOG_MODULE_ANTICAMP);
|
||||||
ZRLogFlagsMenu(client);
|
ZRLogFlagsMenu(client);
|
||||||
}
|
}
|
||||||
case 20:
|
case 20:
|
||||||
|
{
|
||||||
|
ToggleLogFlag(LOG_MODULE_DAMAGECONTROL);
|
||||||
|
ZRLogFlagsMenu(client);
|
||||||
|
}
|
||||||
|
case 21:
|
||||||
{
|
{
|
||||||
ToggleLogFlag(LOG_MODULE_OFFSETS);
|
ToggleLogFlag(LOG_MODULE_OFFSETS);
|
||||||
ZRLogFlagsMenu(client);
|
ZRLogFlagsMenu(client);
|
||||||
|
@ -194,14 +194,6 @@ Zombify_Mother(client)
|
|||||||
tHandles[client][TMOAN] = CreateTimer(interval, ZombieMoanTimer, client, TIMER_REPEAT);
|
tHandles[client][TMOAN] = CreateTimer(interval, ZombieMoanTimer, client, TIMER_REPEAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tHandles[client][TPROTECT] != INVALID_HANDLE)
|
|
||||||
{
|
|
||||||
pProtect[client] = false;
|
|
||||||
|
|
||||||
KillTimer(tHandles[client][TPROTECT]);
|
|
||||||
tHandles[client][TPROTECT] = INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tHandles[client][TZHP] != INVALID_HANDLE)
|
if (tHandles[client][TZHP] != INVALID_HANDLE)
|
||||||
{
|
{
|
||||||
KillTimer(tHandles[client][TZHP]);
|
KillTimer(tHandles[client][TZHP]);
|
||||||
@ -270,15 +262,6 @@ Zombify(client, attacker = -1, bool:motherinfect = false)
|
|||||||
tHandles[client][TMOAN] = CreateTimer(interval, ZombieMoanTimer, client, TIMER_REPEAT);
|
tHandles[client][TMOAN] = CreateTimer(interval, ZombieMoanTimer, client, TIMER_REPEAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kill spawn protection timer.
|
|
||||||
if (tHandles[client][TPROTECT] != INVALID_HANDLE)
|
|
||||||
{
|
|
||||||
pProtect[client] = false;
|
|
||||||
|
|
||||||
KillTimer(tHandles[client][TPROTECT]);
|
|
||||||
tHandles[client][TPROTECT] = INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Kill HP display timer.
|
// Kill HP display timer.
|
||||||
if (tHandles[client][TZHP] != INVALID_HANDLE)
|
if (tHandles[client][TZHP] != INVALID_HANDLE)
|
||||||
{
|
{
|
||||||
@ -635,36 +618,6 @@ public Action:ZHPTimer(Handle:timer, any:index)
|
|||||||
return Plugin_Continue;
|
return Plugin_Continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Action:ProtectTimer(Handle:timer, any:index)
|
|
||||||
{
|
|
||||||
if (!IsClientInGame(index))
|
|
||||||
{
|
|
||||||
tHandles[index][TPROTECT] = INVALID_HANDLE;
|
|
||||||
return Plugin_Stop;
|
|
||||||
}
|
|
||||||
|
|
||||||
pTimeLeft[index]--;
|
|
||||||
ZR_HudHint(index, "Spawn Protect", pTimeLeft[index]);
|
|
||||||
|
|
||||||
if (pTimeLeft[index] <= 0)
|
|
||||||
{
|
|
||||||
pProtect[index] = false;
|
|
||||||
|
|
||||||
if (IsPlayerHuman(index))
|
|
||||||
{
|
|
||||||
ZR_HudHint(index, "Spawn protection end");
|
|
||||||
SetPlayerAlpha(index, 255);
|
|
||||||
SetPlayerSpeed(index, 300.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
tHandles[index][TPROTECT] = INVALID_HANDLE;
|
|
||||||
|
|
||||||
return Plugin_Stop;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Plugin_Continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
RespawnPlayer(client)
|
RespawnPlayer(client)
|
||||||
{
|
{
|
||||||
if (!IsClientInGame(client))
|
if (!IsClientInGame(client))
|
||||||
|
@ -55,9 +55,10 @@ enum ZTeam
|
|||||||
#define LOG_MODULE_OVERLAYS 65536 /** overlays.inc */
|
#define LOG_MODULE_OVERLAYS 65536 /** overlays.inc */
|
||||||
#define LOG_MODULE_TELEPORT 131072 /** teleport.inc */
|
#define LOG_MODULE_TELEPORT 131072 /** teleport.inc */
|
||||||
#define LOG_MODULE_WEAPONS 262144 /** Weapons module - weapons/ *.inc */
|
#define LOG_MODULE_WEAPONS 262144 /** Weapons module - weapons/ *.inc */
|
||||||
#define LOG_MODULE_ANTICAMP 524288 /** anticamp.inc */
|
#define LOG_MODULE_HITGROUPS 524288 /** hitgroups.inc */
|
||||||
#define LOG_MODULE_DAMAGECONTROL 1048576 /** damagecontrol.inc */
|
#define LOG_MODULE_ANTICAMP 1048576 /** anticamp.inc */
|
||||||
#define LOG_MODULE_OFFSETS 2097152 /** offsets.inc */
|
#define LOG_MODULE_DAMAGECONTROL 2097152 /** damagecontrol.inc */
|
||||||
|
#define LOG_MODULE_OFFSETS 4194304 /** offsets.inc */
|
||||||
/*
|
/*
|
||||||
* @endsection
|
* @endsection
|
||||||
*/
|
*/
|
||||||
@ -76,8 +77,6 @@ new bool:dispHP[MAXPLAYERS + 1];
|
|||||||
new bool:pProtect[MAXPLAYERS + 1];
|
new bool:pProtect[MAXPLAYERS + 1];
|
||||||
new bool:gKilledByWorld[MAXPLAYERS + 1] = {false, ...};
|
new bool:gKilledByWorld[MAXPLAYERS + 1] = {false, ...};
|
||||||
|
|
||||||
new pTimeLeft[MAXPLAYERS + 1];
|
|
||||||
|
|
||||||
new Float:spawnLoc[MAXPLAYERS + 1][3];
|
new Float:spawnLoc[MAXPLAYERS + 1][3];
|
||||||
new Float:bufferLoc[MAXPLAYERS + 1][3];
|
new Float:bufferLoc[MAXPLAYERS + 1][3];
|
||||||
new bool:ztele_spawned[MAXPLAYERS + 1] = {false, ...};
|
new bool:ztele_spawned[MAXPLAYERS + 1] = {false, ...};
|
||||||
@ -96,15 +95,14 @@ new Handle:tInfect = INVALID_HANDLE;
|
|||||||
|
|
||||||
new Handle:pList = INVALID_HANDLE;
|
new Handle:pList = INVALID_HANDLE;
|
||||||
|
|
||||||
#define MAXTIMERS 7
|
#define MAXTIMERS 6
|
||||||
|
|
||||||
#define TMOAN 0
|
#define TMOAN 0
|
||||||
#define TREGEN 1
|
#define TREGEN 1
|
||||||
#define TTELE 2
|
#define TTELE 2
|
||||||
#define TZHP 3
|
#define TZHP 3
|
||||||
#define TPROTECT 4
|
#define TRESPAWN 4
|
||||||
#define TRESPAWN 5
|
#define TZVISION 5
|
||||||
#define TZVISION 6
|
|
||||||
|
|
||||||
new Handle:tHandles[MAXPLAYERS + 1][MAXTIMERS];
|
new Handle:tHandles[MAXPLAYERS + 1][MAXTIMERS];
|
||||||
|
|
||||||
@ -243,11 +241,9 @@ bool:IsClientPlayer(client)
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether a player is a generic admin or not.
|
* Returns whether a player is a generic admin or not.
|
||||||
@ -261,8 +257,6 @@ bool:IsClientAdmin(client)
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user