remove trailing whitespaces from sourcecode

This commit is contained in:
BotoX 2016-02-06 00:47:47 +01:00
parent 6f9558373d
commit d88e748f0e
85 changed files with 3559 additions and 3559 deletions

View File

@ -6,7 +6,7 @@
* File: zombiereloaded.inc
* Type: Include
* Description: Main API include file.
* Notes: Include this file to include the whole ZR API.
* Notes: Include this file to include the whole ZR API.
*
* Copyright (C) 2009-2013 Greyscale, Richard Helgeby
*

View File

@ -29,7 +29,7 @@
* Returns true if the player is a zombie, false if not.
*
* @param client The client index.
*
*
* @return True if zombie, false if not.
* @error Invalid client index, not connected or not alive.
*/
@ -39,7 +39,7 @@ native bool:ZR_IsClientZombie(client);
* Returns true if the player is a human, false if not.
*
* @param client The client index.
*
*
* @return True if human, false if not.
* @error Invalid client index, not connected or not alive.
*/
@ -77,13 +77,13 @@ native ZR_HumanClient(client, bool:respawn = false, bool:protect = false);
/**
* Called when a player is about to become a zombie.
* Here you can modify any variable or block the infection entirely.
*
*
* @param client The client index.
* @param attacker The the infecter. (-1 if there is no infecter)
* @param motherInfect If the client is becoming a mother zombie.
* @param respawnOverride True if the respawn cvar is being overridden.
* @param respawn The value that respawn is being overridden with.
*
*
* @return Plugin_Handled to block infection. Anything else
* (like Plugin_Continue) to allow infection.
*/
@ -91,7 +91,7 @@ forward Action:ZR_OnClientInfect(&client, &attacker, &bool:motherInfect, &bool:r
/**
* Called after a player has become a zombie.
*
*
* @param client The client that was infected.
* @param attacker The the infecter. (-1 if there is no infecter)
* @param motherInfect If the client is a mother zombie.
@ -103,11 +103,11 @@ forward ZR_OnClientInfected(client, attacker, bool:motherInfect, bool:respawnOve
/**
* Called when a player is about to become a human. (Through an admin command).
* Here you can modify any variable or block the action entirely.
*
*
* @param client The client index.
* @param respawn True if the client was respawned, false if not.
* @param protect True if the client spawn protected, false if not.
*
*
* @return Plugin_Handled to block infection. Anything else
* (like Plugin_Continue) to allow acion.
*/
@ -115,7 +115,7 @@ forward Action:ZR_OnClientHuman(&client, &bool:respawn, &bool:protect);
/**
* Called after a player has become a human. (Through an admin command.)
*
*
* @param client The client index.
* @param respawn Whether the client was respawned.
* @param protect Whether the client has spawn protection.

View File

@ -38,7 +38,7 @@ enum ZR_RespawnCondition
/**
* Spawns a player into the round.
*
*
* @param client The client index.
* @param condition Optional. Set respawn condition, defaults to current
* ZR settings. See ZR_RespawnCondition for details.
@ -49,7 +49,7 @@ native ZR_RespawnClient(client, ZR_RespawnCondition:condition = ZR_Repsawn_Defau
/**
* Called right before ZR is about to respawn a player.
* Here you can modify any variable or stop the action entirely.
*
*
* @param client The client index.
* @param condition Respawn condition. See ZR_RespawnCondition for
* details.
@ -60,7 +60,7 @@ forward Action:ZR_OnClientRespawn(&client, &ZR_RespawnCondition:condition);
/**
* Called after ZR respawned a player.
*
*
* @param client The client index.
* @param condition Current condition of the respawned player. See
* ZR_RespawnCondition for details.
@ -69,10 +69,10 @@ forward ZR_OnClientRespawned(client, ZR_RespawnCondition:condition);
/**
* Set if a player died by a suicide or world damage.
* Note: This will change the respawn condition.
* Note: This value is reset to default by ZR when a zombie player dies.
*
*
* @param client The client index.
* @param suicide True to say the player suicided, false if killed by another
* player.
@ -85,9 +85,9 @@ native ZR_SetKilledByWorld(client, bool:suicide);
* Get whether the player died by a suicide or world damage.
*
* Note: This value is only valid after death event, and before respawn.
*
*
* @param client The client index.
*
*
* @return True if the player died by suicide, false if killed by
* another player.
* @error Invalid client index or not connected.

View File

@ -41,7 +41,7 @@ public Plugin:myinfo =
public OnPluginStart()
{
LoadTranslations("common.phrases");
RegConsoleCmd("zrtest_is_valid_class_index", IsValidClassCommand, "Returns whether the specified class index is valid or not. Usage: zrtest_is_valid_class_index <class index>");
RegConsoleCmd("zrtest_get_active_class", GetActiveClassCommand, "Gets the current class the specified player is using. Usage: zrtest_get_active_class <target>");
RegConsoleCmd("zrtest_select_class", SelectClassCommand, "Selects a class for a player. Usage: zrtest_select_class <target> <class index>");
@ -53,7 +53,7 @@ public Action:IsValidClassCommand(client, argc)
{
new classIndex = -1;
new String:valueString[64];
if (argc >= 1)
{
GetCmdArg(1, valueString, sizeof(valueString));
@ -66,7 +66,7 @@ public Action:IsValidClassCommand(client, argc)
}
ReplyToCommand(client, "Class %d is valid: %d", classIndex, ZR_IsValidClassIndex(classIndex));
return Plugin_Handled;
}
@ -74,7 +74,7 @@ public Action:GetActiveClassCommand(client, argc)
{
new target = -1;
new String:valueString[64];
if (argc >= 1)
{
GetCmdArg(1, valueString, sizeof(valueString));
@ -87,7 +87,7 @@ public Action:GetActiveClassCommand(client, argc)
}
ReplyToCommand(client, "Active class of client %d: %d", target, ZR_GetActiveClass(target));
return Plugin_Handled;
}
@ -97,22 +97,22 @@ public Action:SelectClassCommand(client, argc)
new classIndex = -1;
new bool:applyIfPossible = true;
new bool:saveIfEnabled = true;
new String:valueString[64];
if (argc >= 1)
{
GetCmdArg(1, valueString, sizeof(valueString));
target = FindTarget(client, valueString);
GetCmdArg(2, valueString, sizeof(valueString));
classIndex = StringToInt(valueString);
if (argc >= 4)
{
GetCmdArg(3, valueString, sizeof(valueString));
applyIfPossible = bool:StringToInt(valueString);
GetCmdArg(4, valueString, sizeof(valueString));
saveIfEnabled = bool:StringToInt(valueString);
}
@ -124,14 +124,14 @@ public Action:SelectClassCommand(client, argc)
}
ReplyToCommand(client, "Selected class %d for client %d. Result: %d", classIndex, target, ZR_SelectClientClass(target, classIndex, applyIfPossible, saveIfEnabled));
return Plugin_Handled;
}
public Action:GetClassCommand(client, argc)
{
new String:className[64];
if (argc >= 1)
{
GetCmdArg(1, className, sizeof(className));
@ -143,7 +143,7 @@ public Action:GetClassCommand(client, argc)
}
ReplyToCommand(client, "Class index of \"%s\": %d", className, ZR_GetClassByName(className));
return Plugin_Handled;
}
@ -152,12 +152,12 @@ public Action:GetNameCommand(client, argc)
new classIndex = -1;
new String:valueString[64];
new String:displayName[64];
if (argc >= 1)
{
GetCmdArg(1, valueString, sizeof(valueString));
classIndex = StringToInt(valueString);
if (!ZR_IsValidClassIndex(classIndex))
{
ReplyToCommand(client, "Invalid class index: %d", classIndex);
@ -169,9 +169,9 @@ public Action:GetNameCommand(client, argc)
ReplyToCommand(client, "Gets class display name. Usage: zrtest_get_class_display_name <class index>");
return Plugin_Handled;
}
ZR_GetClassDisplayName(classIndex, displayName, sizeof(displayName));
ReplyToCommand(client, "Display name of class %d: \"%s\"", classIndex, displayName);
return Plugin_Handled;
}

View File

@ -45,7 +45,7 @@ public OnPluginStart()
{
hBlockOnTakeDamage = CreateConVar("zrtest_blockontakedamage", "0", "Block OnTakeDamage.");
hBlockTraceAttack = CreateConVar("zrtest_blocktraceattack", "0", "Block TraceAttack.");
if (!HookEventEx("player_hurt", Event_PlayerHurt))
{
LogError("Failed to hook event player_hurt.");
@ -74,15 +74,15 @@ public Action:Event_PlayerHurt(Handle:event, const String:name[], bool:dontBroad
decl String:weapon[64];
weapon[0] = 0;
GetEventString(event, "weapon", weapon, sizeof(weapon));
decl String:msg[128];
msg[0] = 0;
Format(msg, sizeof(msg), "victim:%d | attacker:%d | hitgroup:%d | dmg:%d | dmg armor:%d | weapon:%s", victim, attacker, hitgroup, damage, damageArmor, weapon);
PrintToChat(victim, "Receive hurt event -- %s", msg);
PrintToConsole(victim, "Receive hurt event -- %s", msg);
if (attacker > 0 && attacker < MaxClients)
{
PrintToChat(attacker, "Send hurt event -- %s", msg);
@ -95,29 +95,29 @@ public Action:OnTakeDamage(victim, &attacker, &inflictor, &Float:damage, &damage
/*
Here we can control whether bullets or other damage that hits the
victim's body should be allowed.
If TraceAttack is blocked, bullets will go through the body and the
attacker can't deal any damage to the victim.
By blocking OnTakeDamage we can use this to allow players to actually
hit a player without giving damage to him. This can be used as a simple
trace, for example healing the victim instead of damaging him.
*/
decl String:msg[128];
msg[0] = 0;
Format(msg, sizeof(msg), "victim:%d | attacker:%d | inflictor:%d | dmg:%0.2f | dmg type:%d | weapon ent:%d | force:%0.2f | dmg pos:%0.2f", victim, attacker, inflictor, damage, damagetype, weapon, damageForce, damagePosition);
PrintToChat(victim, "Damage taken -- %s", msg);
PrintToConsole(victim, "Damage taken -- %s", msg);
if (attacker > 0 && attacker < MaxClients)
{
PrintToChat(attacker, "Damage given -- %s", msg);
PrintToConsole(attacker, "Damage given -- %s", msg);
}
if (GetConVarBool(hBlockOnTakeDamage))
{
return Plugin_Handled;
@ -133,26 +133,26 @@ public Action:TraceAttack(victim, &attacker, &inflictor, &Float:damage, &damaget
/*
Here we can control whether bullets or other damage is allowed to hit
the player's body.
If blocked, bullets will go through the body.
OnTakeDamage decides whether damage is actually allowed.
*/
decl String:msg[128];
msg[0] = 0;
Format(msg, sizeof(msg), "victim:%d | attacker:%d | inflictor:%d | dmg:%0.2f | dmg type:%d | ammo type:%d | hitbox:%d | hitgroup: %d", victim, attacker, inflictor, damage, damagetype, ammotype, hitbox, hitgroup);
PrintToChat(victim, "Receive attack -- %s", msg);
PrintToConsole(victim, "Receive attack -- %s", msg);
if (attacker > 0 && attacker < MaxClients)
{
PrintToChat(attacker, "Attacking -- %s", msg);
PrintToConsole(attacker, "Attacking -- %s", msg);
}
if (GetConVarBool(hBlockTraceAttack))
{
return Plugin_Handled;

View File

@ -44,13 +44,13 @@ new Handle:cvarBlockHuman;
public OnPluginStart()
{
LoadTranslations("common.phrases");
RegConsoleCmd("zrtest_iszombie", IsZombieCommand, "Returns whether a player is a zombie or not. Usage: zrtest_iszombie <target>");
RegConsoleCmd("zrtest_ishuman", IsHumanCommand, "Returns whether a player is a human or not. Usage: zrtest_ishuman <target>");
RegConsoleCmd("zrtest_infect", InfectClientCommand, "Infects a player. Usage: zrtest_infect <target>");
RegConsoleCmd("zrtest_human", HumanClientCommand, "Turns a player back into a human. Usage: zrtest_human <target>");
cvarBlockInfect = CreateConVar("zrtest_block_infect", "0", "Block infection.");
cvarBlockHuman = CreateConVar("zrtest_block_human", "0", "Block turning players back into humans.");
}
@ -59,7 +59,7 @@ public Action:IsZombieCommand(client, argc)
{
new target = -1;
new String:valueString[64];
if (argc >= 1)
{
GetCmdArg(1, valueString, sizeof(valueString));
@ -72,7 +72,7 @@ public Action:IsZombieCommand(client, argc)
}
ReplyToCommand(client, "Client %d is a zombie: %d", client, ZR_IsClientZombie(target));
return Plugin_Handled;
}
@ -80,7 +80,7 @@ public Action:IsHumanCommand(client, argc)
{
new target = -1;
new String:valueString[64];
if (argc >= 1)
{
GetCmdArg(1, valueString, sizeof(valueString));
@ -93,7 +93,7 @@ public Action:IsHumanCommand(client, argc)
}
ReplyToCommand(client, "Client %d is a human: %d", client, ZR_IsClientHuman(target));
return Plugin_Handled;
}
@ -101,13 +101,13 @@ public Action:InfectClientCommand(client, argc)
{
new target = -1;
new String:valueString[64];
if (argc >= 1)
{
GetCmdArg(1, valueString, sizeof(valueString));
target = FindTarget(client, valueString);
}
if (target < 0)
{
ReplyToCommand(client, "Infects a player. Usage: zrtest_infect <target>");
@ -115,7 +115,7 @@ public Action:InfectClientCommand(client, argc)
}
ZR_InfectClient(target);
return Plugin_Handled;
}
@ -123,13 +123,13 @@ public Action:HumanClientCommand(client, argc)
{
new target = -1;
new String:valueString[64];
if (argc >= 1)
{
GetCmdArg(1, valueString, sizeof(valueString));
target = FindTarget(client, valueString);
}
if (target < 0)
{
ReplyToCommand(client, "Turns a player back into a human. Usage: zrtest_human <target>");
@ -137,7 +137,7 @@ public Action:HumanClientCommand(client, argc)
}
ZR_HumanClient(target);
return Plugin_Handled;
}
@ -148,7 +148,7 @@ public Action:ZR_OnClientInfect(&client, &attacker, &bool:motherInfect, &bool:re
PrintToChatAll("Infection blocked on client %d.", client);
return Plugin_Handled;
}
PrintToChatAll("Client %d is about to be infected. Attacker: %d, Mother zombie: %d, Respawn override: %d, Respawn: %d.", client, attacker, motherInfect, respawnOverride, respawn);
return Plugin_Continue;
}
@ -165,7 +165,7 @@ public Action:ZR_OnClientHuman(&client, &bool:respawn, &bool:protect)
PrintToChatAll("Turning human blocked on client %d.", client);
return Plugin_Handled;
}
PrintToChatAll("Client %d is about to become a human. Respawn: %d, Spawn protect: %d", client, respawn, protect);
return Plugin_Continue;
}

View File

@ -46,19 +46,19 @@ new bool:VelocityMonitor[MAXPLAYERS];
public OnPluginStart()
{
hKnockBackMultiplier = CreateConVar("zrtest_knockback", "4.0", "Knock back multiplier.");
if (!HookEventEx("player_hurt", Event_PlayerHurt))
{
LogError("Failed to hook event player_hurt.");
}
// If offset "m_vecVelocity[0]" can't be found, then stop the plugin.
g_iToolsVelocity = FindSendPropInfo("CBasePlayer", "m_vecVelocity[0]");
if (g_iToolsVelocity == -1)
{
LogError("Offset \"CBasePlayer::m_vecVelocity[0]\" was not found.");
}
RegConsoleCmd("zrtest_push_player", Command_PushPlayer, "Push a player. Usage: zrtest_push_player <x> <y> <z> [0|1 - base velocity]");
RegConsoleCmd("zrtest_parent", Command_Parent, "Prints your parent entity.");
RegConsoleCmd("zrtest_friction", Command_Friction, "Prints your floor friction multiplier.");
@ -72,25 +72,25 @@ public Action:Command_PushPlayer(client, argc)
ReplyToCommand(client, "Push a player. Usage: zrtest_push_player <x> <y> <z> [0|1 - base velocity]");
return Plugin_Handled;
}
new Float:velocity[3];
new String:buffer[32];
new bool:baseVelocity = false;
for (new i = 0; i < 3; i++)
{
GetCmdArg(i + 1, buffer, sizeof(buffer));
velocity[i] = StringToFloat(buffer);
}
if (argc > 3)
{
GetCmdArg(4, buffer, sizeof(buffer));
baseVelocity = bool:StringToInt(buffer);
}
PrintToChatAll("Applying velocity on client %d (base: %d): %0.2f | %0.2f | %0.2f", client, baseVelocity, velocity[0], velocity[1], velocity[2]);
if (baseVelocity)
{
SetBaseVelocity(client, velocity);
@ -100,7 +100,7 @@ public Action:Command_PushPlayer(client, argc)
TeleportEntity(client, NULL_VECTOR, NULL_VECTOR, velocity);
//SetVelocity(client, velocity);
}
return Plugin_Handled;
}
@ -108,7 +108,7 @@ public Action:Command_Parent(client, argc)
{
new parent = GetParent(client);
ReplyToCommand(client, "Parent index: %d", parent);
return Plugin_Handled;
}
@ -116,7 +116,7 @@ public Action:Command_Friction(client, argc)
{
new Float:friction = GetFriction(client);
ReplyToCommand(client, "Friction: %0.2f", friction);
return Plugin_Handled;
}
@ -124,7 +124,7 @@ public Action:Command_MaxSpeed(client, argc)
{
new Float:maxSpeed = GetMaxSpeed(client);
ReplyToCommand(client, "Max speed: %0.2f", maxSpeed);
return Plugin_Handled;
}
@ -157,7 +157,7 @@ public Action:Event_PlayerHurt(Handle:event, const String:name[], bool:dontBroad
/*public Action:OnTakeDamage(victim, &attacker, &inflictor, &Float:damage, &damagetype, &weapon, Float:damageForce[3], Float:damagePosition[3])
{
KnockbackOnClientHurt(victim, attacker, Float:damage);
// Allow damage.
return Plugin_Continue;
}
@ -192,7 +192,7 @@ public PostThink(client)
/*{
PrintVelocity(client, "PostThink");
}*/
SetMaxSpeed(client, 1000.0);
}
@ -217,7 +217,7 @@ stock PrintVelocity(client, const String:prefix[])
* @param client The client index. (zombie)
* @param attacker The attacker index. (human)
* @param weapon The weapon used.
* @param hitgroup Hitgroup attacker has damaged.
* @param hitgroup Hitgroup attacker has damaged.
* @param dmg_health Damage done.
*/
KnockbackOnClientHurt(client, attacker, Float:dmg_health)
@ -227,29 +227,29 @@ KnockbackOnClientHurt(client, attacker, Float:dmg_health)
{
return;
}
// Get zombie knockback value.
new Float:knockback = GetConVarFloat(hKnockBackMultiplier);
new Float:clientloc[3];
new Float:attackerloc[3];
GetClientAbsOrigin(client, clientloc);
// Get attackers eye position.
GetClientEyePosition(attacker, attackerloc);
// Get attackers eye angles.
new Float:attackerang[3];
GetClientEyeAngles(attacker, attackerang);
// Calculate knockback end-vector.
TR_TraceRayFilter(attackerloc, attackerang, MASK_ALL, RayType_Infinite, KnockbackTRFilter);
TR_GetEndPosition(clientloc);
// Apply damage knockback multiplier.
knockback *= dmg_health;
// Apply knockback.
PrintToChat(attacker, "Applying knock back: %0.2f", knockback);
VelocityMonitor[client] = true;
@ -258,34 +258,34 @@ KnockbackOnClientHurt(client, attacker, Float:dmg_health)
/**
* Sets velocity on a player.
*
*
* @param client The client index.
* @param startpoint The starting coordinate to push from.
* @param endpoint The ending coordinate to push towards.
* @param magnitude Magnitude of the push.
*/
*/
KnockbackSetVelocity(client, const Float:startpoint[3], const Float:endpoint[3], Float:magnitude)
{
// Create vector from the given starting and ending points.
new Float:vector[3];
MakeVectorFromPoints(startpoint, endpoint, vector);
// Normalize the vector (equal magnitude at varying distances).
NormalizeVector(vector, vector);
// Changes by zephyrus:
//new flags = GetEntityFlags(client);
//if(flags & FL_ONGROUND)
// vector[2]=0.5;
// Apply the magnitude by scaling the vector (multiplying each of its components).
ScaleVector(vector, magnitude);
// Changes by zephyrus:
//if(flags & FL_ONGROUND)
// if(vector[2]>350.0)
// vector[2]=350.0;
new flags = GetEntityFlags(client);
if (flags & FL_ONGROUND)
{
@ -294,7 +294,7 @@ KnockbackSetVelocity(client, const Float:startpoint[3], const Float:endpoint[3],
vector[2] = 251.0;
}
}
// ADD the given vector to the client's current velocity.
PrintToChatAll("Applying velocity on client %d: %0.2f | %0.2f | %0.2f", client, vector[0], vector[1], vector[2]);
ToolsClientVelocity(client, vector);
@ -318,37 +318,37 @@ stock ToolsClientVelocity(client, Float:vecVelocity[3], bool:apply = true, bool:
{
vecVelocity[x] = GetEntDataFloat(client, g_iToolsVelocity + (x*4));
}
// Stop here.
return;
}
// If stack is true, then add client's velocity.
if (stack)
{
// Get client's velocity.
new Float:vecClientVelocity[3];
// x = vector component.
for (new x = 0; x < 3; x++)
{
vecClientVelocity[x] = GetEntDataFloat(client, g_iToolsVelocity + (x*4));
}
AddVectors(vecClientVelocity, vecVelocity, vecVelocity);
}
// Apply velocity on client.
TeleportEntity(client, NULL_VECTOR, NULL_VECTOR, vecVelocity);
}
/**
* Trace Ray forward, used as a filter to continue tracing if told so. (See sdktools_trace.inc)
*
*
* @param entity The entity index.
* @param contentsMask The contents mask.
* @return True to allow hit, false to continue tracing.
*/
* @return True to allow hit, false to continue tracing.
*/
public bool:KnockbackTRFilter(entity, contentsMask)
{
// If entity is a player, continue tracing.
@ -356,7 +356,7 @@ public bool:KnockbackTRFilter(entity, contentsMask)
{
return false;
}
// Allow hit.
return true;
}

View File

@ -44,10 +44,10 @@ new Handle:cvarAllSuicide;
public OnPluginStart()
{
LoadTranslations("common.phrases");
RegConsoleCmd("zrtest_killed_by_world", KilledByWorldCommand, "Gets or sets the killed by world value. Usage: zrtest_killed_by_world <target> [1|0]");
RegConsoleCmd("zrtest_respawn", RespawnClientCommand, "Respawn a player. Usage: zrtest_respawn <target>");
cvarBlockRespawn = CreateConVar("zrtest_block_respawn", "0", "Block respawning.");
cvarAllSuicide = CreateConVar("zrtest_all_suicide", "0", "Treat all deaths as suicide.");
}
@ -56,19 +56,19 @@ public Action:KilledByWorldCommand(client, argc)
{
new target = -1;
new String:valueString[64];
if (argc >= 1)
{
GetCmdArg(1, valueString, sizeof(valueString));
target = FindTarget(client, valueString);
}
if (target <= 0)
{
ReplyToCommand(client, "Gets or sets the killed by world value. Usage: zrtest_killed_by_world <target> [value]");
return Plugin_Handled;
}
if (argc > 1)
{
// Set value.
@ -80,7 +80,7 @@ public Action:KilledByWorldCommand(client, argc)
// Print value.
ReplyToCommand(client, "Killed by world: %d", ZR_GetKilledByWorld(target));
}
return Plugin_Handled;
}
@ -88,13 +88,13 @@ public Action:RespawnClientCommand(client, argc)
{
new target = -1;
new String:valueString[64];
if (argc >= 1)
{
GetCmdArg(1, valueString, sizeof(valueString));
target = FindTarget(client, valueString);
}
if (target < 0)
{
ReplyToCommand(client, "Respawn a player. Usage: zrtest_respawn <target>");
@ -102,7 +102,7 @@ public Action:RespawnClientCommand(client, argc)
}
ZR_RespawnClient(target, ZR_Repsawn_Default);
return Plugin_Handled;
}
@ -113,16 +113,16 @@ public Action:ZR_OnClientRespawn(&client, &ZR_RespawnCondition:condition)
PrintToChatAll("Respawn blocked on client %d.", client);
return Plugin_Handled;
}
PrintToChatAll("Client %d is about to respawn. Condition: %d", client, condition);
if (GetConVarBool(cvarAllSuicide))
{
// Set client suicide.
ZR_SetKilledByWorld(client, true);
PrintToChatAll("Client %d is marked as suicide victim.");
}
return Plugin_Continue;
}

View File

@ -44,19 +44,19 @@ new m_hMyWeapons;
public OnPluginStart()
{
LoadTranslations("common.phrases");
m_hActiveWeapon = FindSendPropInfo("CBasePlayer", "m_hActiveWeapon");
if (m_hActiveWeapon == -1)
{
LogError("Can't find CBasePlayer::m_hActiveWeapon");
}
m_hMyWeapons = FindSendPropOffs("CBasePlayer", "m_hMyWeapons");
if (m_hMyWeapons == -1)
{
LogError("Can't find CBasePlayer::m_hMyWeapons");
}
RegConsoleCmd("zrtest_weaponslots", Command_ListWeaponSlots, "Lists weapon slots. Usage: zrtest_weaponslots [target]");
RegConsoleCmd("zrtest_weaponlist", Command_ListWeapons, "Lists all weapons. Usage: zrtest_weaponlist [target]");
RegConsoleCmd("zrtest_knife", Command_Knife, "Gives a knife. Usage: zrtest_knife [target]");
@ -67,19 +67,19 @@ public Action:Command_ListWeaponSlots(client, argc)
{
new target = -1;
new String:valueString[64];
if (argc >= 1)
{
GetCmdArg(1, valueString, sizeof(valueString));
target = FindTarget(client, valueString);
}
if (target <= 0)
{
ReplyToCommand(client, "Lists weapon slots. Usage: zrtest_weaponlist [target]");
return Plugin_Handled;
}
if (argc >= 1)
{
ListWeaponSlots(target, client);
@ -88,7 +88,7 @@ public Action:Command_ListWeaponSlots(client, argc)
{
ListWeaponSlots(client, client);
}
return Plugin_Handled;
}
@ -96,19 +96,19 @@ public Action:Command_ListWeapons(client, argc)
{
new target = -1;
new String:valueString[64];
if (argc >= 1)
{
GetCmdArg(1, valueString, sizeof(valueString));
target = FindTarget(client, valueString);
}
if (target <= 0)
{
ReplyToCommand(client, "Lists all weapon. Usage: zrtest_weaponlist [target]");
return Plugin_Handled;
}
if (argc >= 1)
{
ListWeapons(target, client);
@ -117,7 +117,7 @@ public Action:Command_ListWeapons(client, argc)
{
ListWeapons(client, client);
}
return Plugin_Handled;
}
@ -125,19 +125,19 @@ public Action:Command_Knife(client, argc)
{
new target = -1;
new String:valueString[64];
if (argc >= 1)
{
GetCmdArg(1, valueString, sizeof(valueString));
target = FindTarget(client, valueString);
}
if (target <= 0)
{
ReplyToCommand(client, "Gives a knife. Usage: zrtest_knife [target]");
return Plugin_Handled;
}
if (argc >= 1)
{
GiveKnife(target);
@ -146,7 +146,7 @@ public Action:Command_Knife(client, argc)
{
GiveKnife(client);
}
return Plugin_Handled;
}
@ -154,19 +154,19 @@ public Action:Command_RemoveWeapons(client, argc)
{
new target = -1;
new String:valueString[64];
if (argc >= 1)
{
GetCmdArg(1, valueString, sizeof(valueString));
target = FindTarget(client, valueString);
}
if (target <= 0)
{
ReplyToCommand(client, "Removes all weapons. Usage: zrtest_removeweapons [target]");
return Plugin_Handled;
}
if (argc >= 1)
{
RemoveAllClientWeapons(target, client);
@ -175,7 +175,7 @@ public Action:Command_RemoveWeapons(client, argc)
{
RemoveAllClientWeapons(client, client);
}
return Plugin_Handled;
}
@ -189,21 +189,21 @@ public Action:Command_RemoveWeapons(client, argc)
ListWeaponSlots(client, observer, count = 10)
{
ReplyToCommand(observer, "Slot:\tEntity:\tClassname:");
// Loop through slots.
for (new slot = 0; slot < count; slot++)
{
new weapon = GetPlayerWeaponSlot(client, slot);
if (weapon < 0)
{
ReplyToCommand(observer, "%d\t(empty/invalid)", slot);
continue;
}
new String:classname[64];
GetEntityClassname(weapon, classname, sizeof(classname));
ReplyToCommand(observer, "%d\t%d\t%s", slot, weapon, classname);
}
}
@ -217,28 +217,28 @@ ListWeaponSlots(client, observer, count = 10)
ListWeapons(client, observer)
{
ReplyToCommand(observer, "Offset:\tEntity:\tClassname:");
// Loop through entries in m_hMyWeapons.
for(new offset = 0; offset < 128; offset += 4) // +4 to skip to next entry in array.
{
new weapon = GetEntDataEnt2(client, m_hMyWeapons + offset);
if (weapon < 0)
{
ReplyToCommand(observer, "%d\t(empty/invalid)", offset);
continue;
}
new String:classname[64];
GetEntityClassname(weapon, classname, sizeof(classname));
ReplyToCommand(observer, "%d\t%d\t%s", offset, weapon, classname);
}
}
/**
* Remove all weapons.
*
*
* @param client Source client.
* @param observer Client that will receive output.
* @param count Optional. Number of slots to list.
@ -249,16 +249,16 @@ RemoveAllClientWeapons(client, observer, count = 5)
for (new slot = 0; slot < count; slot++)
{
new weapon = GetPlayerWeaponSlot(client, slot);
// Remove all weapons in this slot.
while (weapon > 0)
{
// Remove weapon entity.
RemovePlayerItem(client, weapon);
AcceptEntityInput(weapon, "Kill");
ReplyToCommand(observer, "Removed weapon in slot %d.", slot);
// Get next weapon in this slot, if any.
weapon = GetPlayerWeaponSlot(client, slot);
}

View File

@ -36,13 +36,13 @@
#if defined USE_SDKHOOKS
#include <sdkhooks>
#define ACTION_CONTINUE Plugin_Continue
#define ACTION_CHANGED Plugin_Changed
#define ACTION_HANDLED Plugin_Handled
#else
#include <zrtools>
#define ACTION_CONTINUE ZRTools_Continue
#define ACTION_CHANGED ZRTools_Changed
#define ACTION_HANDLED ZRTools_Handled
@ -132,7 +132,7 @@ public Plugin:myinfo =
/**
* Called before plugin is loaded.
*
*
* @param myself The plugin handle.
* @param late True if the plugin was loaded after map change, false on map start.
* @param error Error message if load failed.
@ -144,7 +144,7 @@ public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
{
// Load API.
APIInit();
// Let plugin load.
return APLRes_Success;
}
@ -155,7 +155,7 @@ public APLRes:AskPluginLoad2(Handle:myself, bool:late, String:error[], err_max)
public OnPluginStart()
{
UpdateGameFolder();
// Forward event to modules.
LogInit(); // Doesn't depend on CVARs.
TranslationInit();
@ -247,7 +247,7 @@ public OnConfigsExecuted()
ClassOnConfigsExecuted();
ClassLoad();
VolLoad();
// Forward event to modules. (OnModulesLoaded)
ConfigOnModulesLoaded();
ClassOnModulesLoaded();
@ -264,7 +264,7 @@ public OnClientConnected(client)
/**
* Client is joining the server.
*
*
* @param client The client index.
*/
public OnClientPutInServer(client)
@ -286,7 +286,7 @@ public OnClientPutInServer(client)
/**
* Called once a client's saved cookies have been loaded from the database.
*
*
* @param client Client index.
*/
public OnClientCookiesCached(client)
@ -296,7 +296,7 @@ public OnClientCookiesCached(client)
{
return;
}
// Forward "OnCookiesCached" event to modules.
ClassOnCookiesCached(client);
WeaponsOnCookiesCached(client);
@ -304,10 +304,10 @@ public OnClientCookiesCached(client)
}
/**
* Called once a client is authorized and fully in-game, and
* after all post-connection authorizations have been performed.
* Called once a client is authorized and fully in-game, and
* after all post-connection authorizations have been performed.
*
* This callback is gauranteed to occur on all clients, and always
* This callback is gauranteed to occur on all clients, and always
* after each OnClientPutInServer() call.
*
* @param client Client index.
@ -321,7 +321,7 @@ public OnClientPostAdminCheck(client)
/**
* Client is leaving the server.
*
*
* @param client The client index.
*/
public OnClientDisconnect(client)

View File

@ -50,7 +50,7 @@ AccountOnOffsetsFound()
/**
* Client is spawning into the game.
*
*
* @param client The client index.
*/
AccountOnClientSpawn(client)
@ -61,10 +61,10 @@ AccountOnClientSpawn(client)
{
return;
}
// Get cash value.
new cash = GetConVarInt(g_hCvarsList[CVAR_ACCOUNT_CASHFILL_VALUE]);
// Set client's account.
AccountSetClientCash(client, cash);
}
@ -81,26 +81,26 @@ AccountOnClientHurt(client, attacker, dmg_health)
{
return;
}
// If cashdmg cvar is disabled, then stop.
new bool:accountcashdmg = GetConVarBool(g_hCvarsList[CVAR_ACCOUNT_CASHDMG]);
if (!accountcashdmg)
{
return;
}
// If attacker is hurting themself, then stop.
if (client == attacker)
{
return;
}
// If attacker isn't a human, then stop.
if (!InfectIsClientHuman(attacker))
{
return;
}
// Get current cash, add the damage done to it, then set new value.
new cash = AccountGetClientCash(attacker);
AccountSetClientCash(attacker, cash + dmg_health);
@ -108,7 +108,7 @@ AccountOnClientHurt(client, attacker, dmg_health)
/**
* Get's a client's account value (cash)
*
*
* @param client The client index.
* @return The client's current account value.
*/
@ -120,7 +120,7 @@ stock AccountGetClientCash(client)
/**
* Set's a client's account value (cash)
*
*
* @param client The client index.
* @param value The value to set to.
*/
@ -131,7 +131,7 @@ stock AccountSetClientCash(client, value)
{
value = 0;
}
// Set client's cash.
SetEntData(client, g_iToolsAccount, value, 4);
}

View File

@ -4,7 +4,7 @@
* Zombie:Reloaded
*
* File: admintools.inc
* Type: Core
* Type: Core
* Description: Functions for checking extended admin privileges.
*
* Copyright (C) 2009-2013 Greyscale, Richard Helgeby
@ -61,13 +61,13 @@ stock bool:ZRIsClientPrivileged(client, OperationTypes:operationType = Operation
// Console always has full access no matter what.
return true;
}
// Validate client index.
if (!ZRIsClientValid(client))
{
return false;
}
// Check if group authentication is used.
new bool:groupauth = GetConVarBool(g_hCvarsList[CVAR_PERMISSIONS_USE_GROUPS]);
if (groupauth)
@ -77,13 +77,13 @@ stock bool:ZRIsClientPrivileged(client, OperationTypes:operationType = Operation
* GROUP BASED AUTHENTICATION *
* *
**********************************/
// Check if client is full admin.
if (ZRIsClientInGroup(client, ZR_GROUP_ADMINS))
{
return true;
}
// Check operation type.
switch (operationType)
{
@ -96,7 +96,7 @@ stock bool:ZRIsClientPrivileged(client, OperationTypes:operationType = Operation
return ZRIsClientInGroup(client, ZR_GROUP_CONFIGURATORS);
}
}
// Invalid operation type.
return false;
}
@ -107,9 +107,9 @@ stock bool:ZRIsClientPrivileged(client, OperationTypes:operationType = Operation
* FLAG BASED AUTHENTICATION *
* *
*********************************/
new AdminFlag:flag;
// Check operation type.
switch (operationType)
{
@ -127,7 +127,7 @@ stock bool:ZRIsClientPrivileged(client, OperationTypes:operationType = Operation
return false;
}
}
return GetAdminFlag(GetUserAdmin(client), flag);
}
}
@ -142,17 +142,17 @@ stock bool:ZRIsClientPrivileged(client, OperationTypes:operationType = Operation
stock bool:ZRIsClientInGroup(client, const String:groupName[])
{
new AdminId:id = GetUserAdmin(client);
// Validate id.
if (id == INVALID_ADMIN_ID)
{
return false;
}
// Get number of groups.
new groupnum = GetAdminGroupCount(id);
decl String:groupname[64];
// Validate number of groups.
if (groupnum > 0)
{
@ -161,7 +161,7 @@ stock bool:ZRIsClientInGroup(client, const String:groupName[])
{
// Get group name.
GetAdminGroup(id, group, groupname, sizeof(groupname));
// Compare names.
if (StrEqual(groupName, groupname, false))
{
@ -169,7 +169,7 @@ stock bool:ZRIsClientInGroup(client, const String:groupName[])
}
}
}
// No groups or no match.
return false;
}

View File

@ -66,7 +66,7 @@ new g_iStartTouchHookID[MAXPLAYERS + 1] = {-1, ...};
/**
* List of components that make up the model's rectangular boundaries.
*
*
* F = Front
* B = Back
* L = Left
@ -95,7 +95,7 @@ AntiStickOnCommandsCreate()
/**
* Client is joining the server.
*
*
* @param client The client index.
*/
AntiStickClientInit(client)
@ -103,7 +103,7 @@ AntiStickClientInit(client)
// Hook "StartTouch" and "EndTouch" on client.
#if defined USE_SDKHOOKS
SDKHook(client, SDKHook_StartTouch, AntiStickStartTouch);
// Set dummy value so it think it's hooked.
g_iStartTouchHookID[client] = 1;
#else
@ -113,7 +113,7 @@ AntiStickClientInit(client)
/**
* Unhook StartTouch and EndTouch function on a client.
*
*
* @param client The client index.
*/
AntiStickOnClientDisconnect(client)
@ -126,14 +126,14 @@ AntiStickOnClientDisconnect(client)
#else
ZRTools_UnhookStartTouch(g_iStartTouchHookID[client]);
#endif
g_iStartTouchHookID[client] = -1;
}
}
/**
* Callback function for StartTouch.
*
*
* @param client The client index.
* @param entity The entity index of the entity being touched.
*/
@ -149,41 +149,41 @@ public ZRTools_Action:AntiStickStartTouch(client, entity)
{
return;
}
// If client isn't in-game, then stop.
if (!IsClientInGame(client))
{
return;
}
// If client is touching themselves, then leave them alone :P
if (client == entity)
{
return;
}
// If touched entity isn't a valid client, then stop.
if (!ZRIsClientValid(entity))
{
return;
}
// If the clients aren't colliding, then stop.
if (!AntiStickIsModelBoxColliding(client, entity))
{
return;
}
// From this point we know that client and entity is more or less within eachother.
LogEvent(false, LogType_Normal, LOG_DEBUG, LogModule_AntiStick, "Collision", "Player \"%N\" and \"%N\" are intersecting. Removing collisions.", client, entity);
// Get current collision groups of client and entity.
new clientcollisiongroup = AntiStickGetCollisionGroup(client);
// Note: If zombies get stuck on infection or stuck in a teleport, they'll
// get the COLLISION_GROUP_PUSHAWAY collision group, so check this
// one too.
// If the client is in any other collision group than "off", than we must set them to off, to unstick.
if (clientcollisiongroup != ANTISTICK_COLLISIONS_OFF)
{
@ -195,7 +195,7 @@ public ZRTools_Action:AntiStickStartTouch(client, entity)
/**
* Callback for solidify timer.
*
*
* @param client The client index.
*/
public Action:AntiStickSolidifyTimer(Handle:timer, any:client)
@ -205,19 +205,19 @@ public Action:AntiStickSolidifyTimer(Handle:timer, any:client)
{
return Plugin_Stop;
}
// If the client is dead, then stop.
if (!IsPlayerAlive(client))
{
return Plugin_Stop;
}
// If the client's collisions are already on, then stop.
if (AntiStickGetCollisionGroup(client) == ANTISTICK_COLLISIONS_ON)
{
return Plugin_Stop;
}
// Loop through all clients and check if client is stuck in them.
for (new x = 1; x <= MaxClients; x++)
{
@ -226,38 +226,38 @@ public Action:AntiStickSolidifyTimer(Handle:timer, any:client)
{
continue;
}
// If the client is dead, then skip it.
if (!IsPlayerAlive(x))
{
continue;
}
// Don't compare the same clients.
if (client == x)
{
continue;
}
// If the client is colliding with a client, then allow timer to continue.
if (AntiStickIsModelBoxColliding(client, x))
{
return Plugin_Continue;
}
}
// Change collisions back to normal.
AntiStickSetCollisionGroup(client, ANTISTICK_COLLISIONS_ON);
// Debug message. May be useful when calibrating antistick.
LogEvent(false, LogType_Normal, LOG_DEBUG, LogModule_AntiStick, "Collision", "Player \"%N\" is no longer intersecting anyone. Applying normal collisions.", client);
return Plugin_Stop;
}
/**
* Build the model box by finding all vertices.
*
*
* @param client The client index.
* @param boundaries Array with 'AntiStickBoxBounds' for indexes to return bounds into.
* @param width The width of the model box.
@ -269,38 +269,38 @@ stock AntiStickBuildModelBox(client, Float:boundaries[AntiStickBoxBound][3], Flo
new Float:cornerang[3];
new Float:sideloc[3];
new Float:finalloc[4][3];
// Get needed vector info.
GetClientAbsOrigin(client, clientloc);
// Set the pitch to 0.
twistang[1] = 90.0;
cornerang[1] = 0.0;
for (new x = 0; x < 4; x++)
{
// Jump to point on player's left side.
AntiStickJumpToPoint(clientloc, twistang, width / 2, sideloc);
// From this point, jump to the corner, which would be half the width from the middle of a side.
AntiStickJumpToPoint(sideloc, cornerang, width / 2, finalloc[x]);
// Twist 90 degrees to find next side/corner.
twistang[1] += 90.0;
cornerang[1] += 90.0;
// Fix angles.
if (twistang[1] > 180.0)
{
twistang[1] -= 360.0;
}
if (cornerang[1] > 180.0)
{
cornerang[1] -= 360.0;
}
}
// Copy all horizontal model box data to array.
boundaries[BoxBound_FUR][0] = finalloc[3][0];
boundaries[BoxBound_FUR][1] = finalloc[3][1];
@ -318,11 +318,11 @@ stock AntiStickBuildModelBox(client, Float:boundaries[AntiStickBoxBound][3], Flo
boundaries[BoxBound_BDR][1] = finalloc[2][1];
boundaries[BoxBound_BDL][0] = finalloc[1][0];
boundaries[BoxBound_BDL][1] = finalloc[1][1];
// Set Z bounds.
new Float:eyeloc[3];
GetClientEyePosition(client, eyeloc);
boundaries[BoxBound_FUR][2] = eyeloc[2];
boundaries[BoxBound_FUL][2] = eyeloc[2];
boundaries[BoxBound_FDR][2] = clientloc[2] + 15.0;
@ -335,7 +335,7 @@ stock AntiStickBuildModelBox(client, Float:boundaries[AntiStickBoxBound][3], Flo
/**
* Jumps from a point to another based off angle and distance.
*
*
* @param vec Point to jump from.
* @param ang Angle to base jump off of.
* @param distance Distance to jump
@ -344,23 +344,23 @@ stock AntiStickBuildModelBox(client, Float:boundaries[AntiStickBoxBound][3], Flo
stock AntiStickJumpToPoint(const Float:vec[3], const Float:ang[3], Float:distance, Float:result[3])
{
new Float:viewvec[3];
// Turn client angle, into a vector.
GetAngleVectors(ang, viewvec, NULL_VECTOR, NULL_VECTOR);
// Normalize vector.
NormalizeVector(viewvec, viewvec);
// Scale to the given distance.
ScaleVector(viewvec, distance);
// Add the vectors together.
AddVectors(vec, viewvec, result);
}
/**
* Get the max/min value of a 3D box on any axis.
*
*
* @param axis The axis to check.
* @param boundaries The boundaries to check.
* @param min Return the min value instead.
@ -369,7 +369,7 @@ stock Float:AntiStickGetBoxMaxBoundary(axis, Float:boundaries[AntiStickBoxBound]
{
// Create 'outlier' with initial value of first boundary.
new Float:outlier = boundaries[0][axis];
// x = Boundary index. (Start at 1 because we initialized 'outlier' with the 0 index's value)
new size = sizeof(boundaries);
for (new x = 1; x < size; x++)
@ -383,7 +383,7 @@ stock Float:AntiStickGetBoxMaxBoundary(axis, Float:boundaries[AntiStickBoxBound]
outlier = boundaries[x][axis];
}
}
// Return value.
return outlier;
}
@ -399,44 +399,44 @@ stock bool:AntiStickIsModelBoxColliding(client1, client2)
{
new Float:client1modelbox[AntiStickBoxBound][3];
new Float:client2modelbox[AntiStickBoxBound][3];
// Build model boxes for each client.
AntiStickBuildModelBox(client1, client1modelbox, ANTISTICK_DEFAULT_HULL_WIDTH);
AntiStickBuildModelBox(client2, client2modelbox, ANTISTICK_DEFAULT_HULL_WIDTH);
// Compare x values.
new Float:max1x = AntiStickGetBoxMaxBoundary(0, client1modelbox);
new Float:max2x = AntiStickGetBoxMaxBoundary(0, client2modelbox);
new Float:min1x = AntiStickGetBoxMaxBoundary(0, client1modelbox, true);
new Float:min2x = AntiStickGetBoxMaxBoundary(0, client2modelbox, true);
if (max1x < min2x || min1x > max2x)
{
return false;
}
// Compare y values.
new Float:max1y = AntiStickGetBoxMaxBoundary(1, client1modelbox);
new Float:max2y = AntiStickGetBoxMaxBoundary(1, client2modelbox);
new Float:min1y = AntiStickGetBoxMaxBoundary(1, client1modelbox, true);
new Float:min2y = AntiStickGetBoxMaxBoundary(1, client2modelbox, true);
if (max1y < min2y || min1y > max2y)
{
return false;
}
// Compare z values.
new Float:max1z = AntiStickGetBoxMaxBoundary(2, client1modelbox);
new Float:max2z = AntiStickGetBoxMaxBoundary(2, client2modelbox);
new Float:min1z = AntiStickGetBoxMaxBoundary(2, client1modelbox, true);
new Float:min2z = AntiStickGetBoxMaxBoundary(2, client2modelbox, true);
if (max1z < min2z || min1z > max2z)
{
return false;
}
// They are intersecting.
return true;
}
@ -552,7 +552,7 @@ AntiStickCollisionGroupToString(collisiongroup, String:buffer[], maxlen)
return strcopy(buffer, maxlen, "COLLISION_GROUP_NPC_ACTOR");
}
}
// No match. Write a blank string.
return strcopy(buffer, maxlen, "");
}
@ -560,7 +560,7 @@ AntiStickCollisionGroupToString(collisiongroup, String:buffer[], maxlen)
/**
* Command callback (zr_antistick_dump_group)
* Dumps collision group data.
*
*
* @param client The client index.
* @param argc Argument count.
*/
@ -570,14 +570,14 @@ public Action:AntiStickDumpGroupCommand(client, argc)
new target;
decl String:groupname[64];
decl String:arg[96];
// Write header.
ReplyToCommand(client, "Player: Collision group:\n--------------------------------------------------------------------------------");
if (argc < 1)
{
// Dump collision groups on all players.
// Loop through all alive players.
for (target = 1; target <= MaxClients; target++)
{
@ -586,11 +586,11 @@ public Action:AntiStickDumpGroupCommand(client, argc)
{
continue;
}
// Get collision group name.
collisiongroup = AntiStickGetCollisionGroup(target);
AntiStickCollisionGroupToString(collisiongroup, groupname, sizeof(groupname));
// List player name and collision group.
ReplyToCommand(client, "%-35N %s", target, groupname);
}
@ -600,18 +600,18 @@ public Action:AntiStickDumpGroupCommand(client, argc)
// Get the target.
GetCmdArg(1, arg, sizeof(arg));
target = FindTarget(client, arg);
// Validate target.
if (ZRIsClientValid(target))
{
// Get collision group name.
collisiongroup = AntiStickGetCollisionGroup(target);
AntiStickCollisionGroupToString(collisiongroup, groupname, sizeof(groupname));
// List player name and collision group.
ReplyToCommand(client, "%-35N %s", target, groupname);
}
}
return Plugin_Handled;
}

View File

@ -27,18 +27,18 @@
/**
* Application Programming Interface (API)
*
*
* To allow other plugins or extensions to interact directly with Zombie:Reloaded we need to implement
* an API. SourceMod allows us to do this by creating global "natives" or "forwards."
*
*
* Natives are basically functions that can be called from any plugin that includes its definition.
* Forwards are functions that are called on a given event. (Such as OnClientPutInServer)
* ZR's API files are located in sourcemod/scripting/include/zr/category.zr.inc. We chose to create multiple
* files simply for organization. Including zr.inc will automatically include the rest of the files as well.
*
*
* To better understand how natives and forwards are created, go here:
* http://wiki.alliedmods.net/Creating_Natives_(SourceMod_Scripting)
* http://wiki.alliedmods.net/Function_Calling_API_(SourceMod_Scripting)
* http://wiki.alliedmods.net/Function_Calling_API_(SourceMod_Scripting)
*/
#include "zr/api/infect.api"
@ -58,10 +58,10 @@ APIInit()
/**
* Validates a client index and when it fails, an error is thrown.
*
*
* @param client The client index to validate.
* @param alive Set to true to validate that the client is alive, false to ignore.
*
*
* @error Throws an error when the client isn't valid.
*/
stock APIValidateClientIndex(client, EligibleCondition:alive = Condition_Either)
@ -72,14 +72,14 @@ stock APIValidateClientIndex(client, EligibleCondition:alive = Condition_Either)
ThrowNativeError(SP_ERROR_NATIVE, "Invalid client index. (%d)", client);
return;
}
// Verify that the client is connected.
if (!IsClientConnected(client))
{
ThrowNativeError(SP_ERROR_NATIVE, "Client %d is not connected.", client);
return;
}
// Check if the player must be dead or alive.
new bool:bAlive = bool:alive;
if (alive != Condition_Either)

View File

@ -31,7 +31,7 @@
APIClassInit()
{
// Class module natives/forwards (class.zr.inc)
// Natives
CreateNative("ZR_IsValidClassIndex", APIIsValidClassIndex);
CreateNative("ZR_GetActiveClass", APIGetActiveClass);
@ -50,7 +50,7 @@ APIClassInit()
public APIIsValidClassIndex(Handle:plugin, numParams)
{
new classIndex = GetNativeCell(1);
return ClassValidateIndex(classIndex);
}
@ -62,10 +62,10 @@ public APIIsValidClassIndex(Handle:plugin, numParams)
public APIGetActiveClass(Handle:plugin, numParams)
{
new client = GetNativeCell(1);
// Validate the client index. Player must be alive.
APIValidateClientIndex(client, Condition_True);
return ClassGetActiveIndex(client);
}
@ -77,10 +77,10 @@ public APIGetActiveClass(Handle:plugin, numParams)
public APIGetHumanClass(Handle:plugin, numParams)
{
new client = GetNativeCell(1);
// Validate the client index. Player must be alive.
APIValidateClientIndex(client, Condition_True);
return ClassSelected[client][ZR_CLASS_TEAM_HUMANS];
}
@ -92,10 +92,10 @@ public APIGetHumanClass(Handle:plugin, numParams)
public APIGetZombieClass(Handle:plugin, numParams)
{
new client = GetNativeCell(1);
// Validate the client index. Player must be alive.
APIValidateClientIndex(client, Condition_True);
return ClassSelected[client][ZR_CLASS_TEAM_ZOMBIES];
}
@ -110,17 +110,17 @@ public APISelectClientClass(Handle:plugin, numParams)
new classIndex = GetNativeCell(2);
new bool:applyIfPossible = bool:GetNativeCell(3);
new bool:saveIfEnabled = bool:GetNativeCell(4);
// Validate the client index.
APIValidateClientIndex(client, Condition_Either);
// Validate class index.
if (!ClassValidateIndex(classIndex))
{
ThrowNativeError(SP_ERROR_NATIVE, "Invalid class index. (%d)", classIndex);
return -1;
}
return _:ClassSelectClientClass(client, classIndex, applyIfPossible, saveIfEnabled);
}
@ -133,21 +133,21 @@ public APIGetClassByName(Handle:plugin, numParams)
{
decl String:className[64];
className[0] = 0;
// Get class name.
if (GetNativeString(1, className, sizeof(className)) != SP_ERROR_NONE)
{
ThrowNativeError(SP_ERROR_NATIVE, "Unexpected error when reading className parameter. Possibly corrupt or missing data.");
return -1;
}
new cacheType = GetNativeCell(2);
if (cacheType == ZR_CLASS_CACHE_PLAYER)
{
ThrowNativeError(SP_ERROR_NATIVE, "Invalid cache type. Player cache is not allowed in this function.");
return -1;
}
return ClassGetIndex(className, cacheType);
}
@ -161,13 +161,13 @@ public APIGetClassDisplayName(Handle:plugin, numParams)
new index = GetNativeCell(1);
new maxlen = GetNativeCell(3);
new cacheType = GetNativeCell(4);
if (maxlen <= 0)
{
// No buffer size.
return 0;
}
// Validate index.
if (cacheType == ZR_CLASS_CACHE_PLAYER)
{
@ -183,17 +183,17 @@ public APIGetClassDisplayName(Handle:plugin, numParams)
return 0;
}
}
decl String:displayName[maxlen];
new bytes = ClassGetName(index, displayName, maxlen, cacheType);
if (bytes <= 0)
{
// The class doesn't have a name for some reason. Make sure the buffer is empty.
displayName[0] = 0;
}
SetNativeString(2, displayName, maxlen);
return bytes;
}

View File

@ -42,13 +42,13 @@ new Handle:g_hAPIFwdOnClientHumanPost = INVALID_HANDLE;
APIInfectInit()
{
// Infect module natives/forwards (infect.zr.inc)
// Natives
CreateNative("ZR_IsClientZombie", APIIsClientZombie);
CreateNative("ZR_IsClientHuman", APIIsClientHuman);
CreateNative("ZR_InfectClient", APIInfectClient);
CreateNative("ZR_HumanClient", APIHumanClient);
// Forwards
g_hAPIFwdOnClientInfect = CreateGlobalForward("ZR_OnClientInfect", ET_Hook, Param_CellByRef, Param_CellByRef, Param_CellByRef, Param_CellByRef, Param_CellByRef);
g_hAPIFwdOnClientInfected = CreateGlobalForward("ZR_OnClientInfected", ET_Ignore, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell);
@ -63,33 +63,33 @@ APIInfectInit()
public APIIsClientZombie(Handle:plugin, numParams)
{
new client = GetNativeCell(1);
// Validate the client index.
APIValidateClientIndex(client, Condition_True);
return InfectIsClientInfected(client);
}
/**
* Native call function (ZR_IsClientHuman)
* Returns true if the client is a human, false if not.
*
*
* bool:InfectIsClientHuman(client)
*/
public APIIsClientHuman(Handle:plugin, numParams)
{
new client = GetNativeCell(1);
// Validate the client index.
APIValidateClientIndex(client, Condition_True);
return InfectIsClientHuman(client);
}
/**
* Native call function (ZR_InfectClient)
* Infects a client.
*
*
* native ZR_InfectClient(client, attacker = -1, bool:motherInfect = false, bool:respawnOverride = false, bool:respawn = false);
*/
public APIInfectClient(Handle:plugin, numParams)
@ -99,17 +99,17 @@ public APIInfectClient(Handle:plugin, numParams)
new bool:motherInfect = bool:GetNativeCell(3);
new bool:respawnOverride = bool:GetNativeCell(4);
new bool:respawn = bool:GetNativeCell(5);
// Validate the client index.
APIValidateClientIndex(client, Condition_True);
InfectHumanToZombie(client, attacker, motherInfect, respawnOverride, respawn);
}
/**
* Native call function (ZR_HumanClient)
* Turns a zombie back into a human.
*
*
* native ZR_HumanClient(client, bool:respawn = false, bool:protect = false);
*/
public APIHumanClient(Handle:plugin, numParams)
@ -117,36 +117,36 @@ public APIHumanClient(Handle:plugin, numParams)
new client = GetNativeCell(1);
new bool:respawn = bool:GetNativeCell(2);
new bool:protect = bool:GetNativeCell(2);
// Validate the client index.
APIValidateClientIndex(client, Condition_True);
InfectZombieToHuman(client, respawn, protect);
}
/**
* Called when a client is about to become a zombie.
*
*
* @param client The client to infect.
* @param attacker The attacker who did the infect.
* @param motherinfect Indicates a mother zombie infect.
* @param respawnoverride Set to true to override respawn cvar.
* @param respawn Value to override with.
*
*
* InfectHumanToZombie(client, attacker = -1, bool:motherinfect = false, bool:respawnoverride = false, bool:respawn = false)
*/
Action:APIOnClientInfect(&client, &attacker, &bool:motherinfect, &bool:respawnoverride, &bool:respawn)
{
// Start forward call.
Call_StartForward(g_hAPIFwdOnClientInfect);
// Push the parameters.
Call_PushCellRef(client);
Call_PushCellRef(attacker);
Call_PushCellRef(motherinfect);
Call_PushCellRef(respawnoverride);
Call_PushCellRef(respawn);
// Get what they returned.
new Action:result;
Call_Finish(result);
@ -155,50 +155,50 @@ Action:APIOnClientInfect(&client, &attacker, &bool:motherinfect, &bool:respawnov
/**
* Called after a client has become a zombie.
*
*
* @param client The client to infect.
* @param attacker The attacker who did the infect.
* @param motherinfect Indicates a mother zombie infect.
* @param respawnoverride Set to true to override respawn cvar.
* @param respawn Value to override with.
*
*
* InfectHumanToZombie(client, attacker = -1, bool:motherinfect = false, bool:respawnoverride = false, bool:respawn = false)
*/
APIOnClientInfected(client, attacker, bool:motherinfect, bool:respawnoverride, bool:respawn)
{
// Start forward call.
Call_StartForward(g_hAPIFwdOnClientInfected);
// Push the parameters.
Call_PushCell(client);
Call_PushCell(attacker);
Call_PushCell(motherinfect);
Call_PushCell(respawnoverride);
Call_PushCell(respawn);
// Finish the call.
Call_Finish();
}
/**
* Called when a client is about to become a human. (Through either zr_human or admin menu)
*
*
* @param client The client index.
* @param respawn True if the client was respawned, false if not.
* @param protect True if the client spawn protected, false if not.
*
*
* InfectZombieToHuman(client, bool:respawn = false, bool:protect = false)
*/
Action:APIOnClientHuman(&client, &bool:respawn, &bool:protect)
{
// Start forward call.
Call_StartForward(g_hAPIFwdOnClientHuman);
// Push the parameters.
Call_PushCellRef(client);
Call_PushCellRef(respawn);
Call_PushCellRef(protect);
// Get what they returned.
new Action:result;
Call_Finish(result);
@ -207,23 +207,23 @@ Action:APIOnClientHuman(&client, &bool:respawn, &bool:protect)
/**
* Called after a client has become a human. (Through either zr_human or admin menu)
*
*
* @param client The client index.
* @param respawn True if the client was respawned, false if not.
* @param protect True if the client spawn protected, false if not.
*
*
* InfectZombieToHuman(client, bool:respawn = false, bool:protect = false)
*/
APIOnClientHumanPost(client, bool:respawn, bool:protect)
{
// Start forward call.
Call_StartForward(g_hAPIFwdOnClientHumanPost);
// Push the parameters.
Call_PushCell(client);
Call_PushCell(respawn);
Call_PushCell(protect);
// Finish the call.
Call_Finish();
}

View File

@ -40,12 +40,12 @@ new Handle:g_hAPIFwdOnClientRespawned = INVALID_HANDLE;
APIRespawnInit()
{
// Respawn module natives/forwards (respawn.zr.inc)
// Natives
CreateNative("ZR_RespawnClient", APIRespawnClient);
CreateNative("ZR_SetKilledByWorld", APISetKilledByWorld);
CreateNative("ZR_GetKilledByWorld", APIGetKilledByWorld);
// Forwards
g_hAPIFwdOnClientRespawn = CreateGlobalForward("ZR_OnClientRespawn", ET_Hook, Param_CellByRef, Param_CellByRef);
g_hAPIFwdOnClientRespawned = CreateGlobalForward("ZR_OnClientRespawned", ET_Ignore, Param_Cell, Param_Cell);
@ -54,29 +54,29 @@ APIRespawnInit()
/**
* Native call function (ZR_RespawnClient)
* Spawns a player into the round following rules set by cvars.
*
*
* RespawnSpawnClient(client, bool:zombie = false, bool:zombie_if_suicide = false)
*/
public APIRespawnClient(Handle:plugin, numParams)
{
new client = GetNativeCell(1);
// Validate index and that player isn't alive.
APIValidateClientIndex(client, Condition_False);
// Restore respawn condition.
new RespawnCondition:condition = RespawnCondition:GetNativeCell(2);
new bool:zombie;
new bool:zombieIfSuicide;
RespawnRestoreCondition(condition, zombie, zombieIfSuicide);
// Respawn the client.
RespawnSpawnClient(client, zombie, zombieIfSuicide);
}
/**
* Called right before ZR is about to respawn a player.
*
*
* @param client The client index.
* @param condition Respawn condition. See RespawnCondition for
* details.
@ -85,11 +85,11 @@ Action:APIOnClientRespawn(&client, &RespawnCondition:condition)
{
// Start forward call.
Call_StartForward(g_hAPIFwdOnClientRespawn);
// Push the parameters.
Call_PushCellRef(client);
Call_PushCellRef(condition);
// Get what they returned.
new Action:result;
Call_Finish(result);
@ -98,7 +98,7 @@ Action:APIOnClientRespawn(&client, &RespawnCondition:condition)
/**
* Called after a player was respawned.
*
*
* @param client The client index.
* @param condition Current condition of the respawned player. See
* RespawnCondition for details.
@ -107,11 +107,11 @@ Action:APIOnClientRespawned(client, RespawnCondition:condition)
{
// Start forward call.
Call_StartForward(g_hAPIFwdOnClientRespawned);
// Push the parameters.
Call_PushCell(client);
Call_PushCell(condition);
// Finish the call.
Call_Finish();
}
@ -123,12 +123,12 @@ Action:APIOnClientRespawned(client, RespawnCondition:condition)
public APISetKilledByWorld(Handle:plugin, numParams)
{
new client = GetNativeCell(1);
// Validate the client index.
APIValidateClientIndex(client, Condition_Either);
new bool:suicide = bool:GetNativeCell(2);
// Override the old value.
bKilledByWorld[client] = suicide;
}
@ -140,10 +140,10 @@ public APISetKilledByWorld(Handle:plugin, numParams)
public APIGetKilledByWorld(Handle:plugin, numParams)
{
new client = GetNativeCell(1);
// Validate the client index.
APIValidateClientIndex(client, Condition_Either);
// Return the value.
return _:bKilledByWorld[client];
}

View File

@ -47,13 +47,13 @@ CommandsInit()
VolOnCommandsCreate();
ZombieSoundsOnCommandsCreate();
ImmunityOnCommandsCreate();
#if defined ADD_VERSION_INFO
VersionOnCommandsCreate();
#endif
DebugOnCommandsCreate();
// Forward event to modules. (hook commands)
ClassOnCommandsHook();
}

View File

@ -27,88 +27,88 @@
/*
Using config API:
-Before any of these helper functions can be used on a config file you must
"register" the module handling the data.
Example:
ConfigRegisterConfig(File_Example, Structure_List, "example");
* The first parameter of this call is the config file we want to register.
this needs to be listed in the "ConfigFile" enum in config.inc.
* The second parameter is the structure of the config file we are loading.
The supported structures are listed in the "ConfigStructure" enum in config.inc
* The last parameter is the file's alias. Or what we use to refer to the
config file from a non-developer's point of view. For example zr_config_reload
requires the file alias to identify the config file the user wants to reload.
-Next we need to define the config file's path. To do this we first need to
retrieve the path file from cvar.
Example:
new bool:exists = ConfigGetCvarFilePath(CVAR_CONFIG_PATH_EXAMPLE, pathexample);
* The first parameter is the cvar handle we are looking into.
* The second parameter is the string to store the path in.
* The return value is true if the file exists on the server, false if not.
If the file doesn't exist, handle it. (Print log, stop plugin, etc)
If the file doesn't exist, handle it. (Print log, stop plugin, etc)
Then store it in the config file data.
Example:
ConfigSetConfigPath(File_Example, pathexample);
* The first parameter is the config file we want to set path to.
* The second parameter is the path we want to set to the config file.
-Next we load config file and prepare its nested array structure.
Example:
new bool:success = ConfigLoadConfig(File_Example, arrayExample);
* The first parameter is the config file we want to load.
* The second parameter is the array handle we want to prepare data structure in.
* The return value is true if the file was successfully loaded, false if the
config file couldn't be loaded. (Invalid data, missing quotes, brackets, etc)
-Next validate the config so far, stopping if no data was found or if ConfigLoadConfig
returned false.
-Then cache the config file data into the arrays (only for Keyvalue structures)
by iterating through the data and pushing the values into the array.
-Validate the values of the data.
-Lastly we need to set specific info to the module now that it has successfully
loaded.
Example:
ConfigSetConfigLoaded(File_Example, true);
ConfigSetConfigReloadFunc(File_Example, GetFunctionByName(GetMyHandle(), "ExampleOnConfigReload"));
ConfigSetConfigHandle(File_Example, arrayExample);
These functions will modify the config file data for other things to use.
(such as zr_config_reload)
* The first function call will set the loaded state of the config file to
true, failing to do this will cause the config module to think your
config file isn't loaded, therefore causing some undesired erroring.
* The second function sets the reload function of the config file. This
function will be called upon its config file being reloaded.
* The third function stores the array handle for use by other parts of the
module.
*/
@ -202,24 +202,24 @@ ConfigOnCommandsCreate()
ConfigLoad()
{
decl String:mapconfig[PLATFORM_MAX_PATH];
// Get map name and format into config path.
GetCurrentMap(mapconfig, sizeof(mapconfig));
Format(mapconfig, sizeof(mapconfig), "sourcemod/zombiereloaded/%s.cfg", mapconfig);
// Prepend cfg to path.
decl String:path[PLATFORM_MAX_PATH];
Format(path, sizeof(path), "cfg/%s", mapconfig);
// File doesn't exist, then stop.
if (!FileExists(path))
{
return;
}
// Execute config file.
ServerCommand("exec %s", mapconfig);
// Log action.
LogEvent(false, LogType_Normal, LOG_CORE_EVENTS, LogModule_Config, "Map Configs", "Executed map config file: %s", path);
}
@ -235,18 +235,18 @@ ConfigOnModulesLoaded()
decl String:mapname[256];
decl String:mapconfig[PLATFORM_MAX_PATH];
decl String:path[PLATFORM_MAX_PATH];
// Get map name and format into config path.
GetCurrentMap(mapname, sizeof(mapname));
Format(mapconfig, sizeof(mapconfig), "sourcemod/zombiereloaded/%s.post.cfg", mapname);
// Prepend cfg to path.
Format(path, sizeof(path), "cfg/%s", mapconfig);
// Workaround for bug 3083 in SourceMod compiler. Having FileExist directly
// in the if in this function makes it crash. Storing the result in a
// boolean first works.
// Check if the file exist.
new bool:cfgexists = FileExists(path);
if (!cfgexists)
@ -254,7 +254,7 @@ ConfigOnModulesLoaded()
// File doesn't exist, then stop.
return;
}
// Check if ConfigList is available.
if (g_ConfigListAvailable)
{
@ -262,10 +262,10 @@ ConfigOnModulesLoaded()
// may not exist, but that's ok.
ServerCommand("cfglist_exec_list zr_post_exec");
}
// Execute config file.
ServerCommand("exec %s", mapconfig);
// Log action.
LogEvent(false, LogType_Normal, LOG_CORE_EVENTS, LogModule_Config, "Post Map Configs", "Executed post map config file: %s", path);
}
@ -322,7 +322,7 @@ stock ConfigRegisterConfig(ConfigFile:file, ConfigStructure:structure, const Str
/**
* Set the loaded state of a config file entry.
*
*
* @param config Config file to set load state of.
* @param loaded True to set as loaded, false to set as unloaded.
*/
@ -334,7 +334,7 @@ stock ConfigSetConfigLoaded(ConfigFile:config, bool:loaded)
/**
* Set the structure type of a config file entry.
*
*
* @param config Config file to set structure type of.
* @param structure Structure to set as.
*/
@ -346,7 +346,7 @@ stock ConfigSetConfigStructure(ConfigFile:config, ConfigStructure:structure)
/**
* Set the reload function of a config file entry.
*
*
* @param config Config file to set reload function of.
* @param reloadfunc Reload function.
*/
@ -358,7 +358,7 @@ stock ConfigSetConfigReloadFunc(ConfigFile:config, Function:reloadfunc)
/**
* Set the file handle of a config file entry.
*
*
* @param config Config file to set handle of.
* @param loaded Config file handle.
*/
@ -370,7 +370,7 @@ stock ConfigSetConfigHandle(ConfigFile:config, Handle:file)
/**
* Set the config file path of a config file entry.
*
*
* @param config Config file to set file path of.
* @param loaded File path.
*/
@ -382,7 +382,7 @@ stock ConfigSetConfigPath(ConfigFile:config, const String:path[])
/**
* Set the alias of a config file entry.
*
*
* @param config Config file to set alias of.
* @param loaded Alias of the config file entry.
*/
@ -394,7 +394,7 @@ stock ConfigSetConfigAlias(ConfigFile:config, const String:alias[])
/**
* Returns if a config was successfully loaded.
*
*
* @param config Config file to check load status of.
* @return True if config is loaded, false otherwise.
*/
@ -406,7 +406,7 @@ stock bool:ConfigIsConfigLoaded(ConfigFile:config)
/**
* Returns config's structure type.
*
*
* @param config Config file to get structure type of.
* @return Config structure type.
*/
@ -418,7 +418,7 @@ stock ConfigStructure:ConfigGetConfigStructure(ConfigFile:config)
/**
* Returns config's reload function.
*
*
* @param config Config file to get reload function of.
* @return Config reload function.
*/
@ -430,7 +430,7 @@ stock Function:ConfigGetConfigReloadFunc(ConfigFile:config)
/**
* Returns config's file handle.
*
*
* @param config Config file to get file handle of.
* @return Config file handle.
*/
@ -442,7 +442,7 @@ stock Handle:ConfigGetConfigHandle(ConfigFile:config)
/**
* Returns the path for a given config file entry.
*
*
* @param config Config file to get path of. (see ConfigFile enum)
*/
stock ConfigGetConfigPath(ConfigFile:config, String:path[], maxlen)
@ -453,7 +453,7 @@ stock ConfigGetConfigPath(ConfigFile:config, String:path[], maxlen)
/**
* Returns the alias for a given config file entry.
*
*
* @param config Config file to get alias of. (see ConfigFile enum)
*/
stock ConfigGetConfigAlias(ConfigFile:config, String:alias[], maxlen)
@ -464,32 +464,32 @@ stock ConfigGetConfigAlias(ConfigFile:config, String:alias[], maxlen)
/**
* Loads a config file and sets up a nested array type data storage.
*
*
* @param config The config file to load.
* @param arrayConfig Handle of the main array containing file data.
* @param blocksize The max length of the contained strings.
* @param blocksize The max length of the contained strings.
* @return True if file was loaded successfuly, false otherwise.
*/
stock bool:ConfigLoadConfig(ConfigFile:config, &Handle:arrayConfig, blocksize = CONFIG_MAX_LENGTH)
{
// Get config's structure.
new ConfigStructure:structure = ConfigGetConfigStructure(config);
// Get config's alias
decl String:configalias[CONFIG_MAX_LENGTH];
ConfigGetConfigAlias(config, configalias, sizeof(configalias));
// Get config's file path.
decl String:configpath[PLATFORM_MAX_PATH];
ConfigGetConfigPath(config, configpath, sizeof(configpath));
// If array hasn't been created, then create.
if (arrayConfig == INVALID_HANDLE)
{
// Create array in handle.
arrayConfig = CreateArray(blocksize);
}
switch(structure)
{
case Structure_List:
@ -497,18 +497,18 @@ stock bool:ConfigLoadConfig(ConfigFile:config, &Handle:arrayConfig, blocksize =
// Open file.
new Handle:hFile;
new success = ConfigOpenConfigFile(config, hFile);
// If config file failed to open, then stop.
if (!success)
{
return false;
}
// Clear out array.
ClearArray(arrayConfig);
decl String:line[PLATFORM_MAX_PATH];
while(ReadFileLine(hFile, line, sizeof(line)))
{
// Cut out comments at the end of a line.
@ -516,23 +516,23 @@ stock bool:ConfigLoadConfig(ConfigFile:config, &Handle:arrayConfig, blocksize =
{
SplitString(line, "//", line, sizeof(line));
}
// Trim off whitespace.
TrimString(line);
// If line is empty, then stop.
if (!line[0])
{
continue;
}
// Push line into array.
PushArrayString(arrayConfig, line);
}
// We're done this file, so now we can destory it from memory.
// We're done this file, so now we can destory it from memory.
CloseHandle(hFile);
return true;
}
case Structure_Keyvalue:
@ -540,47 +540,47 @@ stock bool:ConfigLoadConfig(ConfigFile:config, &Handle:arrayConfig, blocksize =
// Open file.
new Handle:hKeyvalue;
new success = ConfigOpenConfigFile(config, hKeyvalue);
// If config file failed to open, then stop.
if (!success)
{
return false;
}
// Destroy all old data.
ConfigClearKvArray(arrayConfig);
if (KvGotoFirstSubKey(hKeyvalue))
{
do
{
// Create new array to store information for config entry.
new Handle:arrayConfigEntry = CreateArray(blocksize);
// Push the key name into the config entry's array.
decl String:keyname[CONFIG_MAX_LENGTH];
KvGetSectionName(hKeyvalue, keyname, sizeof(keyname));
PushArrayString(arrayConfigEntry, keyname); // Index: 0
// Store this handle in the main array.
PushArrayCell(arrayConfig, arrayConfigEntry);
} while(KvGotoNextKey(hKeyvalue));
}
// We're done this file for now, so now we can destory it from memory.
// We're done this file for now, so now we can destory it from memory.
CloseHandle(hKeyvalue);
return true;
}
}
return false;
}
/**
* Reload a config file.
*
*
* @param config The config file entry to reload.
* @return True if the config is loaded, false if not.
*/
@ -592,33 +592,33 @@ stock bool:ConfigReloadConfig(ConfigFile:config)
{
return false;
}
// Call reload function
new Function:reloadfunc = ConfigGetConfigReloadFunc(config);
// This should never be true unless someone has tampered with the code.
if (reloadfunc == INVALID_FUNCTION)
{
// Get config alias.
decl String:configalias[CONFIG_MAX_LENGTH];
ConfigGetConfigAlias(config, configalias, sizeof(configalias));
// Print reload failure to logs.
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Config, "Reload Function", "Invalid reload function for config: \"%s\"", configalias);
return true;
}
// Call reload function.
Call_StartFunction(GetMyHandle(), reloadfunc);
Call_Finish();
return true;
}
/**
* Opens a config file with appropriate method.
*
*
* @param config The config file.
* @param structure The structure of the config file.
* @param hConfig The handle of the opened file.
@ -627,28 +627,28 @@ stock bool:ConfigOpenConfigFile(ConfigFile:config, &Handle:hConfig)
{
// Get config's structure
new ConfigStructure:structure = ConfigGetConfigStructure(config);
// Get config's file path.
decl String:configpath[PLATFORM_MAX_PATH];
ConfigGetConfigPath(config, configpath, sizeof(configpath));
// Get config's alias
decl String:configalias[CONFIG_MAX_LENGTH];
ConfigGetConfigAlias(config, configalias, sizeof(configalias));
switch(structure)
{
case Structure_List:
{
// Open file.
hConfig = OpenFile(configpath, "r");
// If file couldn't be opened, then stop.
if (hConfig == INVALID_HANDLE)
{
return false;
}
return true;
}
case Structure_Keyvalue:
@ -657,7 +657,7 @@ stock bool:ConfigOpenConfigFile(ConfigFile:config, &Handle:hConfig)
return FileToKeyValues(hConfig, configpath);
}
}
return false;
}
@ -665,7 +665,7 @@ stock bool:ConfigOpenConfigFile(ConfigFile:config, &Handle:hConfig)
* Creates, deletes, sets, or gets any key/setting of any ZR config keyvalue file in memory.
* Only use when interacting with a command or manipulating single keys/values,
* using this function everywhere would be EXTREMELY inefficient.
*
*
* @param config Config file to modify.
* @param action Action to perform on keyvalue tree. (see enum ConfigKeyvalueAction)
* @param keys Array containing keys to traverse into.
@ -673,32 +673,32 @@ stock bool:ConfigOpenConfigFile(ConfigFile:config, &Handle:hConfig)
* @param setting (Optional) The name of the setting to modify.
* @param value (Optional) The new value to set.
* @param maxlen (Optional) The maxlength of the retrieved value.
* @return True if the change was made successfully, false otherwise.
* @return True if the change was made successfully, false otherwise.
*/
stock bool:ConfigKeyvalueTreeSetting(ConfigFile:config, ConfigKvAction:action = KvAction_Create, const String:keys[][], keysMax, const String:setting[] = "", String:value[] = "", maxlen = 0)
{
// Get config file's structure.
new ConfigStructure:structure = ConfigGetConfigStructure(config);
// If the config is any other structure beside keyvalue, then stop.
if (structure != Structure_Keyvalue)
{
return false;
}
// Retrieve handle of the keyvalue tree.
new Handle:hConfig;
new bool:success = ConfigOpenConfigFile(config, hConfig);
// If the file couldn't be opened, then stop.
if (!success)
{
return false;
}
// Rewind keyvalue tree.
KvRewind(hConfig);
// x = keys index.
// Traverse into the keygroup, stop if it fails.
for (new x = 0; x < keysMax; x++)
@ -708,10 +708,10 @@ stock bool:ConfigKeyvalueTreeSetting(ConfigFile:config, ConfigKvAction:action =
{
break;
}
// Try to jump to next level in the transversal stack, create key if specified.
new bool:exists = KvJumpToKey(hConfig, keys[x], (action == KvAction_Create));
// If exists is false, then stop.
if (!exists)
{
@ -719,7 +719,7 @@ stock bool:ConfigKeyvalueTreeSetting(ConfigFile:config, ConfigKvAction:action =
return false;
}
}
switch(action)
{
case KvAction_Create:
@ -729,7 +729,7 @@ stock bool:ConfigKeyvalueTreeSetting(ConfigFile:config, ConfigKvAction:action =
// We created the key already, so return true.
return true;
}
// Set new value.
KvSetString(hConfig, setting, value);
}
@ -749,14 +749,14 @@ stock bool:ConfigKeyvalueTreeSetting(ConfigFile:config, ConfigKvAction:action =
KvGetString(hConfig, setting, value, maxlen);
}
}
// We successfully set or got the value.
return true;
}
/**
* Destroy all array handles within an array, and clear main array.
*
*
* @param arrayKv The array converted from a keyvalue structure.
*/
ConfigClearKvArray(Handle:arrayKv)
@ -769,14 +769,14 @@ ConfigClearKvArray(Handle:arrayKv)
new Handle:arrayKvKey = GetArrayCell(arrayKv, x);
CloseHandle(arrayKvKey);
}
// Now that all data within has been destroyed, we can clear the main array.
ClearArray(arrayKv);
}
/**
* Load config file.
*
*
* @param file The cvar define of the path to the file.
* @return True if the file exists, false if not.
*/
@ -785,39 +785,39 @@ stock bool:ConfigGetCvarFilePath(CvarsList:cvar, String:path[])
// Get cvar's path.
decl String:filepath[PLATFORM_MAX_PATH];
GetConVarString(Handle:g_hCvarsList[cvar], filepath, sizeof(filepath));
// Build full path in return string.
BuildPath(Path_SM, path, PLATFORM_MAX_PATH, filepath);
return FileExists(path);
}
/**
* Finds a config file entry, (see ConfigFile enum) for a given alias.
*
*
* @param alias The alias to find config file entry of.
* @return Config file entry, ConfigInvalid is returned if alias was not found.
*/
stock ConfigFile:ConfigAliasToConfigFile(const String:alias[])
{
decl String:checkalias[CONFIG_MAX_LENGTH];
// x = config file entry index.
for (new x = 0; x < sizeof(g_ConfigData); x++)
{
// Get config alias.
ConfigGetConfigAlias(ConfigFile:x, checkalias, sizeof(checkalias));
// If alias doesn't match, then stop.
if (!StrEqual(alias, checkalias, false))
{
continue;
}
// Return config file entry.
return ConfigFile:x;
}
// Invalid config file.
return File_Invalid;
}
@ -825,7 +825,7 @@ stock ConfigFile:ConfigAliasToConfigFile(const String:alias[])
/**
* Command callback (zr_config_reload)
* Reloads a config file and forwards event to modules.
*
*
* @param client The client index.
* @param argc Argument count.
*/
@ -837,7 +837,7 @@ public Action:ConfigReloadCommand(client, argc)
TranslationReplyToCommand(client, "No access to command");
return Plugin_Handled;
}
// If not enough arguments given, then stop.
if (argc < 1)
{
@ -846,17 +846,17 @@ public Action:ConfigReloadCommand(client, argc)
TranslationPrintToConsole(client, "Config command reload syntax aliases", CONFIG_FILE_ALIAS_MODELS, CONFIG_FILE_ALIAS_DOWNLOADS, CONFIG_FILE_ALIAS_CLASSES, CONFIG_FILE_ALIAS_WEAPONS, CONFIG_FILE_ALIAS_HITGROUPS);
return Plugin_Handled;
}
decl String:filealias[CONFIG_MAX_LENGTH];
decl String:path[PLATFORM_MAX_PATH];
decl String:logmessage[LOG_MAX_LENGTH_FILE];
new args = GetCmdArgs();
for (new x = 1; x <= args; x++)
{
// Get alias to restrict.
GetCmdArg(x, filealias, sizeof(filealias));
// If alias is invalid, then stop.
new ConfigFile:config = ConfigAliasToConfigFile(filealias);
if (config == File_Invalid)
@ -864,36 +864,36 @@ public Action:ConfigReloadCommand(client, argc)
TranslationReplyToCommand(client, "Config command reload invalid", filealias);
return Plugin_Handled;
}
// Reload config file.
new bool:loaded = ConfigReloadConfig(config);
// Get config file path.
ConfigGetConfigPath(config, path, sizeof(path));
// Format log message
Format(logmessage, sizeof(logmessage), "Admin \"%L\" reloaded config file \"%s\". (zr_config_reload)", client, path);
// If file isn't loaded then tell client, then stop.
if (!loaded)
{
TranslationReplyToCommand(client, "Config command reload not loaded", filealias);
// Format a failed attempt string to the end of the log message.
Format(logmessage, sizeof(logmessage), "%s -- attempt failed, config file not loaded", logmessage);
}
// Log action to game events.
LogEvent(false, LogType_Normal, LOG_GAME_EVENTS, LogModule_Config, "Reload Config", logmessage);
}
return Plugin_Handled;
}
/**
* Command callback (zr_config_reloadall)
* Reloads all config files and forwards event to all modules.
*
*
* @param client The client index.
* @param argc Argument count.
*/
@ -905,21 +905,21 @@ public Action:ConfigReloadAllCommand(client, argc)
TranslationReplyToCommand(client, "No access to command");
return Plugin_Handled;
}
// Begin statistics.
TranslationReplyToCommand(client, "Config command reload all stats begin");
decl String:configalias[CONFIG_MAX_LENGTH];
// x = config file entry index.
for (new x = 0; x < sizeof(g_ConfigData); x++)
{
// Reload config file.
new bool:successful = ConfigReloadConfig(ConfigFile:x);
// Get config's alias.
ConfigGetConfigAlias(ConfigFile:x, configalias, sizeof(configalias));
if (successful)
{
TranslationReplyToCommand(client, "Config command reload all stats successful", configalias);
@ -929,16 +929,16 @@ public Action:ConfigReloadAllCommand(client, argc)
TranslationReplyToCommand(client, "Config command reload all stats failed", configalias);
}
}
// Log action to game events.
LogEvent(false, LogType_Normal, LOG_GAME_EVENTS, LogModule_Config, "Reload All Config", "Admin \"%L\" reloaded all config files.", client);
return Plugin_Handled;
}
/**
* Converts string of "yes/on" or "no/off" to a boolean value. Always uses english as yes/no/on/off language.
*
*
* @param option "yes/on" or "no/off" string to be converted.
* @return True if string is "yes", false otherwise.
*/
@ -949,14 +949,14 @@ stock bool:ConfigSettingToBool(const String:option[])
{
return true;
}
// Option isn't yes.
return false;
}
/**
* Converts boolean value to "yes" or "no".
*
*
* @param bOption True/false value to be converted to "yes/on"/"no/off", respectively.
* @param option Destination string buffer to store "yes/on" or "no/off" in.
* @param maxlen Length of destination string buffer.
@ -967,13 +967,13 @@ stock ConfigBoolToSetting(bool:bOption, String:option[], maxlen, bool:yesno = tr
{
decl String:t_yes[16], String:t_on[32];
decl String:t_no[16], String:t_off[32];
SetGlobalTransTarget(target);
// Get the yes/no translations for the target.
Format(t_yes, sizeof(t_yes), "%t", "Yes"); Format(t_on, sizeof(t_on), "%t", "On");
Format(t_no, sizeof(t_no), "%t", "No"); Format(t_off, sizeof(t_off), "%t", "Off");
// If option is true, then copy "yes" to return string.
if (bOption)
{
@ -988,7 +988,7 @@ stock ConfigBoolToSetting(bool:bOption, String:option[], maxlen, bool:yesno = tr
/**
* Returns a "yes/no" string from config as a bool.
*
*
* @param kv The keyvalue handle.
* @param key The keyname the value is under.
* @param defaultvalue (Optional) Value to return if setting is missing.
@ -997,6 +997,6 @@ stock bool:ConfigKvGetStringBool(Handle:kv, const String:key[], const String:def
{
decl String:value[CONFIG_MAX_LENGTH];
KvGetString(kv, key, value, sizeof(value), defaultvalue);
return ConfigSettingToBool(value);
}

View File

@ -27,7 +27,7 @@
/**
* Cookies module init function.
*/
*/
CookiesInit()
{
// Forward "OnCookiesCreate" event to modules.
@ -38,7 +38,7 @@ CookiesInit()
/**
* Accepts a bools for setting client cookies.
*
*
* @param client The client index.
* @param cookie The handle to the cookie.
* @param cookievalue The bool value to set cookie as.
@ -48,14 +48,14 @@ CookiesSetClientCookieBool(client, Handle:cookie, bool:cookievalue)
// Convert bool to string.
decl String:strCookievalue[8];
ZRBoolToString(cookievalue, strCookievalue, sizeof(strCookievalue));
// Set the converted string to the cookie.
SetClientCookie(client, cookie, strCookievalue);
}
/**
* Returns a cookie value as a bool.
*
*
* @param client The client index.
* @param cookie The handle to the cookie.
*/
@ -64,7 +64,7 @@ bool:CookiesGetClientCookieBool(client, Handle:cookie)
// Get cookie string.
decl String:cookievalue[8];
GetClientCookie(client, cookie, cookievalue, sizeof(cookievalue));
// Return string casted into an int, then to bool.
return bool:StringToInt(cookievalue);
}
@ -81,7 +81,7 @@ CookiesSetInt(client, Handle:cookie, value)
// Convert value to string.
decl String:strValue[16];
IntToString(value, strValue, sizeof(strValue));
// Set string value.
SetClientCookie(client, cookie, strValue);
}
@ -97,6 +97,6 @@ CookiesGetInt(client, Handle:cookie)
decl String:strValue[16];
strValue[0] = 0;
GetClientCookie(client, cookie, strValue, sizeof(strValue));
return StringToInt(strValue);
}

View File

@ -201,22 +201,22 @@ CvarsInit()
g_hAutoTeamBalance = FindConVar("mp_autoteambalance");
g_hLimitTeams = FindConVar("mp_limitteams");
g_hRestartGame = FindConVar("mp_restartgame");
// Create zombiereloaded cvars.
CvarsCreate();
// Hook cvars.
CvarsHook();
// Create public cvar for tracking.
decl String:description[64];
Format(description, sizeof(description), "%s Current version of this plugin", TRANSLATION_PHRASE_PREFIX);
CreateConVar("gs_zombiereloaded_version", VERSION, description, FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_UNLOGGED|FCVAR_DONTRECORD|FCVAR_REPLICATED|FCVAR_NOTIFY);
#if defined ADD_VERSION_INFO
CreateConVar("zombiereloaded_revision", ZR_VER_REVISION, "Revision number for this plugin in source code repository.", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_UNLOGGED|FCVAR_DONTRECORD|FCVAR_REPLICATED|FCVAR_NOTIFY);
#endif
// Forward event to modules.
VEffectsOnCvarInit();
}
@ -236,8 +236,8 @@ CvarsCreate()
g_hCvarsList[CVAR_LOG_ERROR_OVERRIDE] = CreateConVar("zr_log_error_override", "1", "Always log error messages no matter what logging flags or modules filters that are enabled.");
g_hCvarsList[CVAR_LOG_PRINT_ADMINS] = CreateConVar("zr_log_print_admins", "0", "Print log events to admin chat in addition to the log file.");
g_hCvarsList[CVAR_LOG_PRINT_CHAT] = CreateConVar("zr_log_print_chat", "0", "Print log events to public chat in addition to the log file.");
// ===========================
// Config (core)
// ===========================
@ -246,18 +246,18 @@ CvarsCreate()
g_hCvarsList[CVAR_CONFIG_PATH_CLASSES] = CreateConVar("zr_config_path_playerclasses", "configs/zr/playerclasses.txt", "Path, relative to root sourcemod directory, to playerclasses config file.");
g_hCvarsList[CVAR_CONFIG_PATH_WEAPONS] = CreateConVar("zr_config_path_weapons", "configs/zr/weapons.txt", "Path, relative to root sourcemod directory, to weapons config file.");
g_hCvarsList[CVAR_CONFIG_PATH_HITGROUPS] = CreateConVar("zr_config_path_hitgroups", "configs/zr/hitgroups.txt", "Path, relative to root sourcemod directory, to hitgroups config file.");
// ===========================
// Permission Settings
// ===========================
g_hCvarsList[CVAR_PERMISSIONS_USE_GROUPS] = CreateConVar("zr_permissions_use_groups", "0", "Use group authentication instead of flags to access admin features. Generic admin flag is still required on some features.");
// ===========================
// Classes (core)
// ===========================
// General
g_hCvarsList[CVAR_CLASSES_MENU_SPAWN] = CreateConVar("zr_classes_menu_spawn", "0", "Re-display class selection menu every spawn.");
g_hCvarsList[CVAR_CLASSES_MENU_JOIN] = CreateConVar("zr_classes_menu_join", "0", "Display class selection menu when a player spawn for the first time.");
@ -274,44 +274,44 @@ CvarsCreate()
g_hCvarsList[CVAR_CLASSES_ADMIN_SELECT] = CreateConVar("zr_classes_admin_select", "1", "Allow admins to select admin mode classes. (Not to be confused by admin-only classes!)");
g_hCvarsList[CVAR_CLASSES_SPEED_METHOD] = CreateConVar("zr_classes_speed_method", "prop", "Speed method to use when applying player speed. Do not touch this if you don't know what you're doing! [\"lmv\" = Lagged movement value | \"prop\" = Player speed property");
g_hCvarsList[CVAR_CLASSES_CSGO_KNOCKBACK_BOOST] = CreateConVar("zr_classes_csgo_knockback_boost", "1", "CS: GO only: Applies an upwards boost if necessary as a workaround for low knock back when standing on the ground. Side effects: Weaker and flying zombies (compensate with lower knock back).");
// Menu
g_hCvarsList[CVAR_CLASSES_MENU_AUTOCLOSE] = CreateConVar("zr_classes_menu_autoclose", "1", "Automatically close class selection menu after selecting a class.");
// Overlays
g_hCvarsList[CVAR_CLASSES_OVERLAY_TOGGLE] = CreateConVar("zr_classes_overlay_toggle", "1", "Allow players to toggle class overlay.");
g_hCvarsList[CVAR_CLASSES_OVERLAY_TOGGLECMDS] = CreateConVar("zr_classes_overlay_togglecmds", "nightvision", "List of commands to hook that players can use to toggle class overlay. [Dependency: zr_classes_overlay_toggle | Delimiter: \",\"]");
g_hCvarsList[CVAR_CLASSES_OVERLAY_DEFAULT] = CreateConVar("zr_classes_overlay_default", "1", "Default class overlay toggle state set on connecting player.");
// ===========================
// Weapons (core)
// ===========================
// General
g_hCvarsList[CVAR_WEAPONS] = CreateConVar("zr_weapons", "1", "Enable weapons module, disabling this will disable any weapons-related features. (weapon restrictions, weapon knockback multipliers, etc)");
// Restrict
g_hCvarsList[CVAR_WEAPONS_RESTRICT] = CreateConVar("zr_weapons_restrict", "1", "Enable weapon restriction module, disabling this will disable weapon restriction commands.");
g_hCvarsList[CVAR_WEAPONS_RESTRICT_ENDEQUIP] = CreateConVar("zr_weapons_restrict_endequip", "1", "Restricts zombies from picking up weapons after the round has ended but before the next round has begun.");
// ZMarket
g_hCvarsList[CVAR_WEAPONS_ZMARKET] = CreateConVar("zr_weapons_zmarket", "1", "Allow player to buy from a list of weapons in the weapons config.");
g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE] = CreateConVar("zr_weapons_zmarket_buyzone", "1", "Requires player to be inside a buyzone to use ZMarket. [Dependency: zr_weapons_zmarket]");
g_hCvarsList[CVAR_WEAPONS_ZMARKET_REBUY] = CreateConVar("zr_weapons_zmarket_rebuy", "1", "Allow players to rebuy their previous weapons. [Dependency: zr_weapons_zmarket]");
g_hCvarsList[CVAR_WEAPONS_ZMARKET_REBUY_AUTO] = CreateConVar("zr_weapons_zmarket_rebuy_auto", "1", "Allow players to automatically rebuy their previous weapons. [Dependency: zr_weapons_zmarket&zr_weapons_zmarket_rebuy]");
// ===========================
// Hitgroups (core)
// ===========================
g_hCvarsList[CVAR_HITGROUPS] = CreateConVar("zr_hitgroups", "1", "Enable hitgroups module, disabling this will disable hitgroup-related features. (hitgroup knockback multipliers, hitgroup damage control)");
// ===========================
// Infect (core)
// ===========================
// General
g_hCvarsList[CVAR_INFECT_MZOMBIE_MODE] = CreateConVar("zr_infect_mzombie_mode", "dynamic", "Mother zombie infection mode. ['dynamic' = every n-th zombie (ratio) | 'absolute' = n zombies (ratio) | 'range' = min/max]");
g_hCvarsList[CVAR_INFECT_MZOMBIE_RATIO] = CreateConVar("zr_infect_mzombie_ratio", "7", "Dynamic mode: Infection ratio. Every n-th player is infected. | Absolute mode: Number of zombies to infect (positive ratio), or number of humans to keep (negative ratio).");
@ -323,7 +323,7 @@ CvarsCreate()
g_hCvarsList[CVAR_INFECT_SPAWNTIME_MAX] = CreateConVar("zr_infect_spawntime_max", "50.0", "Maximum time from the start of the round until picking the mother zombie(s).");
g_hCvarsList[CVAR_INFECT_CONSECUTIVE_BLOCK] = CreateConVar("zr_infect_consecutive_block", "1", "Prevent a player from being chosen as mother zombie two rounds in a row.");
g_hCvarsList[CVAR_INFECT_WEAPONS_DROP] = CreateConVar("zr_infect_weapons_drop", "1", "Force player to drop all weapons on infect, disabling this will strip weapons instead.");
// Effects
g_hCvarsList[CVAR_INFECT_EXPLOSION] = CreateConVar("zr_infect_explosion", "1", "Disabling this will disable the fireball, smoke cloud, and sparks in a more efficient way.");
g_hCvarsList[CVAR_INFECT_FIREBALL] = CreateConVar("zr_infect_fireball", "1", "Spawn a fireball effect around player on infection. [Dependency: zr_infect_explosion]");
@ -334,35 +334,35 @@ CvarsCreate()
g_hCvarsList[CVAR_INFECT_SHAKE] = CreateConVar("zr_infect_shake", "1", "Shake player's view on infect.");
g_hCvarsList[CVAR_INFECT_SHAKE_AMP] = CreateConVar("zr_infect_shake_amp", "15.0", "Amplitude of shaking effect. [Dependency: zr_infect_shake]");
g_hCvarsList[CVAR_INFECT_SHAKE_FREQUENCY] = CreateConVar("zr_infect_shake_frequency", "1.0", "Frequency of shaking effect. [Dependency: zr_infect_shake]");
g_hCvarsList[CVAR_INFECT_SHAKE_DURATION] = CreateConVar("zr_infect_shake_duration", "5.0", "Duration of shaking effect. [Dependency: zr_infect_shake]");
g_hCvarsList[CVAR_INFECT_SHAKE_DURATION] = CreateConVar("zr_infect_shake_duration", "5.0", "Duration of shaking effect. [Dependency: zr_infect_shake]");
// ===========================
// Damage (core)
// ===========================
// Hitgroup Damage
g_hCvarsList[CVAR_DAMAGE_HITGROUPS] = CreateConVar("zr_damage_hitgroups", "1", "Read hitgroup damage control from hitgroup config file, disabling this allows all zombie hitgroups to be shot.");
// Block Damage Types
g_hCvarsList[CVAR_DAMAGE_BLOCK_FF] = CreateConVar("zr_damage_block_ff", "1", "Block friendly fire.");
g_hCvarsList[CVAR_DAMAGE_BLOCK_BLAST] = CreateConVar("zr_damage_block_blast", "1", "Block blast damage inflicted on self or teammates.");
// Suicide Intercept
g_hCvarsList[CVAR_DAMAGE_SUICIDE_ZOMBIE] = CreateConVar("zr_damage_suicide_zombie", "0", "Intercept suicide commands attempted by zombies.");
g_hCvarsList[CVAR_DAMAGE_SUICIDE_MZOMBIE] = CreateConVar("zr_damage_suicide_mzombie", "1", "Intercept suicide commands attempted by mother zombies.");
g_hCvarsList[CVAR_DAMAGE_SUICIDE_HUMAN] = CreateConVar("zr_damage_suicide_human", "0", "Intercept suicide commands attempted by humans.");
g_hCvarsList[CVAR_DAMAGE_SUICIDE_CMDS] = CreateConVar("zr_damage_suicide_cmds", "kill, spectate, jointeam, joinclass, explode", "List of client commands to intercept as suicide attempts. [Delimiter: \", \"]");
g_hCvarsList[CVAR_SUICIDE_AFTER_INFECT] = CreateConVar("zr_damage_suicide_after_infect", "1", "Intercept suicide commands only after the first zombie has spawned.");
// ===========================
// Overlays (core)
// ===========================
g_hCvarsList[CVAR_OVERLAYS_UPDATE_TIME] = CreateConVar("zr_overlays_update_time", "1.0", "How often to update overlays on players. [0.0 = Disabled]");
g_hCvarsList[CVAR_OVERLAYS_MIN_DXLEVEL] = CreateConVar("zr_overlays_min_dxlevel", "80", "Minimum DirectX level allowed for overlays (mat_dxlevel).");
// ===========================
// Round End (core)
// ===========================
@ -370,31 +370,31 @@ CvarsCreate()
g_hCvarsList[CVAR_ROUNDEND_OVERLAY_HUMAN] = CreateConVar("zr_roundend_overlays_human", "overlays/zr/humans_win", "Overlay, relative to \"materials\" folder, to display when humans win the round. [Dependency: zr_roundend_overlay]");
g_hCvarsList[CVAR_ROUNDEND_OVERLAY_ZOMBIE] = CreateConVar("zr_roundend_overlays_zombie", "overlays/zr/zombies_win", "Overlay, relative to \"materials\" folder, to display when zombies win the round. [Dependency: zr_roundend_overlay]");
g_hCvarsList[CVAR_ROUNDEND_BALANCE_TEAMS] = CreateConVar("zr_roundend_balance_teams", "1", "Balances the team every time the round ends. Disable this if you use something else to balance teams.");
// ===========================
// Account (module)
// ===========================
g_hCvarsList[CVAR_ACCOUNT_CASHFILL] = CreateConVar("zr_account_cashfill", "1", "Reset player's cash each spawn.");
g_hCvarsList[CVAR_ACCOUNT_CASHFILL_VALUE] = CreateConVar("zr_account_cashfill_value", "12000", "Amount of cash to set player's account to. [Dependency: zr_account_cashfill]");
g_hCvarsList[CVAR_ACCOUNT_CASHDMG] = CreateConVar("zr_account_cashdmg", "0", "Attacker receives amount of cash equivalent to the damage that was inflicted.");
// ===========================
// Visual Effects (module)
// ===========================
// Lightstyle
g_hCvarsList[CVAR_VEFFECTS_LIGHTSTYLE] = CreateConVar("zr_veffects_lightstyle", "0", "Change lightstyle (brightness) of the map.");
g_hCvarsList[CVAR_VEFFECTS_LIGHTSTYLE_VALUE] = CreateConVar("zr_veffects_lightstyle_value", "b", "Lightstyle value. ['a' = Darkest | 'z' = Brightest | Dependency: zr_veffects_lightstyle]");
// Sky
g_hCvarsList[CVAR_VEFFECTS_SKY] = CreateConVar("zr_veffects_sky", "0", "Change map skybox.");
g_hCvarsList[CVAR_VEFFECTS_SKY_PATH] = CreateConVar("zr_veffects_sky_path", "sky_borealis01up.vmt", "Skybox file, relative to \"materials/skybox\" folder, to change map skybox to. This file is automatically downloaded to clients. [Dependency: zr_veffects_sky]");
// Sun
g_hCvarsList[CVAR_VEFFECTS_SUN_DISABLE] = CreateConVar("zr_veffects_sun_disable", "0", "Disable sun rendering on map.");
// Fog
g_hCvarsList[CVAR_VEFFECTS_FOG] = CreateConVar("zr_veffects_fog", "0", "(UNSUPPORTED) Enable fog rendering on the map.");
g_hCvarsList[CVAR_VEFFECTS_FOG_OVERRIDE] = CreateConVar("zr_veffects_fog_override", "0", "(UNSUPPORTED) If fog exists already on the map, then replace with new modified fog. [Dependency: zr_veffects_fog]");
@ -404,41 +404,41 @@ CvarsCreate()
g_hCvarsList[CVAR_VEFFECTS_FOG_STARTDIST] = CreateConVar("zr_veffects_fog_startdist", "0", "(UNSUPPORTED) Distance from player to start rendering foremost fog. [Dependency: zr_veffects_fog]");
g_hCvarsList[CVAR_VEFFECTS_FOG_ENDDIST] = CreateConVar("zr_veffects_fog_enddist", "400", "(UNSUPPORTED) Distance from player to stop rendering fog. [Dependency: zr_veffects_fog]");
g_hCvarsList[CVAR_VEFFECTS_FOG_FARZ] = CreateConVar("zr_veffects_fog_farz", "2000", "(UNSUPPORTED) Vertical clipping plane.");
// Ragdoll
g_hCvarsList[CVAR_VEFFECTS_RAGDOLL_REMOVE] = CreateConVar("zr_veffects_ragdoll_remove", "1", "Remove players' ragdolls from the game after a delay.");
g_hCvarsList[CVAR_VEFFECTS_RAGDOLL_DISSOLVE] = CreateConVar("zr_veffects_ragdoll_dissolve", "-1", "The ragdoll removal effect. ['-2' = Effectless removal | '-1' = Random effect | '0' = Energy dissolve | '1' = Heavy electrical dissolve | '2' = Light electrical dissolve | '3' = Core dissolve | Dependency: zr_veffects_ragdoll_remove]");
g_hCvarsList[CVAR_VEFFECTS_RAGDOLL_DELAY] = CreateConVar("zr_veffects_ragdoll_delay", "0.5", "Time to wait before removing the ragdoll. [Dependency: zr_veffects_ragdoll_remove]");
// ===========================
// Sound Effects (module)
// ===========================
// Voice
g_hCvarsList[CVAR_VOICE] = CreateConVar("zr_voice", "0", "(Incomplete) Modify sv_alltalk to obey zombie/human teams instead of t/ct.");
g_hCvarsList[CVAR_VOICE_ZOMBIES_MUTE] = CreateConVar("zr_voice_zombies_mute", "0", "(Incomplete) Only allow humans to communicate, block verbal zombie communication.");
// Zombie Sounds
g_hCvarsList[CVAR_SEFFECTS_MOAN] = CreateConVar("zr_seffects_moan", "30.0", "Time between emission of a moan sound from a zombie.");
g_hCvarsList[CVAR_SEFFECTS_GROAN] = CreateConVar("zr_seffects_groan", "5", "The probability that a groan sound will be emitted from a zombie when shot. ['100' = 1% chance | '50' = 2% chance | '1' = 100% chance]");
g_hCvarsList[CVAR_SEFFECTS_DEATH] = CreateConVar("zr_seffects_death", "1", "Emit a death sound when a zombie dies.");
g_hCvarsList[CVAR_SEFFECTS_COMMAND_LIMIT] = CreateConVar("zr_seffects_command_limit", "4", "Number of sound commands allowed within the time span, or total limit if time span is disabled. ['0' = Disable sound command limit]");
g_hCvarsList[CVAR_SEFFECTS_COMMAND_TIMESPAN] = CreateConVar("zr_seffects_command_timespan", "10", "Time span for sound command limiter (in seconds). ['0' = Disable time span check | positive number = Time span]");
// Ambient Sounds
g_hCvarsList[CVAR_AMBIENTSOUNDS] = CreateConVar("zr_ambientsounds", "1", "Play an ambient sound to all players during gameplay.");
g_hCvarsList[CVAR_AMBIENTSOUNDS_FILE] = CreateConVar("zr_ambientsounds_file", "ambient/zr/zr_ambience.mp3", "Sound file, relative to \"sound\" folder, to play as ambience. This file is automatically downloaded to clients. [Dependency: zr_ambientsounds]");
g_hCvarsList[CVAR_AMBIENTSOUNDS_LENGTH] = CreateConVar("zr_ambientsounds_length", "60.0", "Length of the ambient sound. [Dependency: zr_ambientsounds]");
g_hCvarsList[CVAR_AMBIENTSOUNDS_VOLUME] = CreateConVar("zr_ambientsounds_volume", "0.8", "Volume of the ambient sound. [1.0 = Max volume | 0.0001 = Not audible | Dependency: zr_ambientsounds]");
// ===========================
// Anti-Stick (module)
// ===========================
g_hCvarsList[CVAR_ANTISTICK] = CreateConVar("zr_antistick", "1", "Automatically unstick players when stuck within each others' collision hull.");
// ===========================
// Spawn Protect (module)
// ===========================
@ -446,8 +446,8 @@ CvarsCreate()
g_hCvarsList[CVAR_SPAWNPROTECT_TIME] = CreateConVar("zr_spawnprotect_time", "10", "Amount of time to protect player. [Dependency: zr_spawnprotect]");
g_hCvarsList[CVAR_SPAWNPROTECT_SPEED] = CreateConVar("zr_spawnprotect_speed", "250.0", "Speed of the player during protection. See the manual for more information. [Dependency: zr_spawnprotect]");
g_hCvarsList[CVAR_SPAWNPROTECT_ALPHA] = CreateConVar("zr_spawnprotect_alpha", "0", "Alpha of the player during protection. ['255' = Fully visible | '0' = Completely invisible | Dependency: zr_spawnprotect]");
// ===========================
// Respawn (module)
// ===========================
@ -455,60 +455,60 @@ CvarsCreate()
g_hCvarsList[CVAR_RESPAWN_DELAY] = CreateConVar("zr_respawn_delay", "1", "Time after death to delay player respawn. [Dependency: zr_respawn]");
g_hCvarsList[CVAR_RESPAWN_TEAM_ZOMBIE] = CreateConVar("zr_respawn_team_zombie", "1", "Respawn player as a zombie. [Dependency: zr_respawn]");
g_hCvarsList[CVAR_RESPAWN_TEAM_ZOMBIE_WORLD] = CreateConVar("zr_respawn_team_zombie_world", "1", "Respawn player as a zombie if player was a zombie and killed by world damage. [Override: zr_respawn_team_zombie]");
// ===========================
// Napalm (module)
// ===========================
g_hCvarsList[CVAR_NAPALM_IGNITE] = CreateConVar("zr_napalm_ignite", "1", "Ignite grenade in mid-air after player throws it. [Dependency: Human Attribute 'has_napalm']");
g_hCvarsList[CVAR_NAPALM_TIME_RESET] = CreateConVar("zr_napalm_time_reset", "1", "The burn-time is reset when being naded multiple times. [0: Original burn-time is used.]");
g_hCvarsList[CVAR_NAPALM_DOUSE] = CreateConVar("zr_napalm_douse", "0", "Minimum water-saturation before flame is extinguished. ['0' = Disabled | '1' = Feet | '2' = Waist | '3' = Full submersion]");
// ===========================
// Jump Boost (module)
// ===========================
g_hCvarsList[CVAR_JUMPBOOST_BHOP_PROTECT] = CreateConVar("zr_jumpboost_bhop_protect", "1", "Prevent players from using forward jump boost multipliers to bunny hop.");
g_hCvarsList[CVAR_JUMPBOOST_BHOP_MAX] = CreateConVar("zr_jumpboost_bhop_max", "300", "The maximum horizontal velocity a player can achieve before bunnyhop protection kicks in. [Dependency: zr_jumpboost_bhop_protect]");
// ===========================
// Volumetric Features (module)
// ===========================
g_hCvarsList[CVAR_VOL] = CreateConVar("zr_vol", "1", "Enables volumetric features.");
g_hCvarsList[CVAR_VOL_UPDATE_INTERVAL] = CreateConVar("zr_vol_update_interval", "0.5", "How often to update player positions and trigger events, in seconds.");
g_hCvarsList[CVAR_VOL_TRIGGER_INTERVAL] = CreateConVar("zr_vol_trigger_interval", "0.5", "How often to check for delayed events, in seconds. Use lower values for more precise delays.");
// ===========================
// ZSpawn (module)
// ===========================
g_hCvarsList[CVAR_ZSPAWN] = CreateConVar("zr_zspawn", "1", "Allow players to spawn into the game late.");
g_hCvarsList[CVAR_ZSPAWN_TEAM_OVERRIDE] = CreateConVar("zr_zspawn_team_override", "1", "Override spawn team when spawning by means of ZSpawn.");
g_hCvarsList[CVAR_ZSPAWN_TEAM_ZOMBIE] = CreateConVar("zr_zspawn_team_zombie", "0", "Spawn player on zombie team when spawning by means of ZSpawn. [Dependency: zr_zspawn_team_override | Override: zr_respawn_team_zombie]");
g_hCvarsList[CVAR_ZSPAWN_BLOCK_REJOIN] = CreateConVar("zr_zspawn_block_rejoin", "1", "Block players disconnecting and rejoing the game using zspawn.");
g_hCvarsList[CVAR_ZSPAWN_TIMELIMIT] = CreateConVar("zr_zspawn_timelimit", "1", "Put a time limit on the use of ZSpawn.");
g_hCvarsList[CVAR_ZSPAWN_TIMELIMIT_TIME] = CreateConVar("zr_zspawn_timelimit_time", "120.0", "Time from the start of the round to allow ZSpawn. [Dependency: zr_zspawn_timelimit]");
g_hCvarsList[CVAR_ZSPAWN_TIMELIMIT_ZOMBIE] = CreateConVar("zr_zspawn_timelimit_zombie", "1", "Spawn player on the zombie team AFTER the timelimit is up. ['-1' = Block ZSpawn | '0' = Spawn as human | '1' = Spawn as zombie | Dependency: zr_zspawn_timelimit]");
// ===========================
// ZHP (module)
// ===========================
g_hCvarsList[CVAR_ZHP] = CreateConVar("zr_zhp", "1", "Allow player to toggle real HP display as a zombie.");
g_hCvarsList[CVAR_ZHP_DEFAULT] = CreateConVar("zr_zhp_default", "1", "Default ZHP toggle state set on connecting player. [Dependency: zr_zhp]");
ZTele_OnCvarsCreate();
// Auto-generate config file if it doesn't exist, then execute.
AutoExecConfig(true, "zombiereloaded", "sourcemod/zombiereloaded");
}
/**
* Hook cvar changes.
*
*
* @param unhook If true, cvars will be unhooked, false to hook cvars.
*/
CvarsHook(bool:unhook = false)
@ -520,29 +520,29 @@ CvarsHook(bool:unhook = false)
UnhookConVarChange(g_hAutoTeamBalance, CvarsHookLocked);
UnhookConVarChange(g_hLimitTeams, CvarsHookLocked);
UnhookConVarChange(g_hRestartGame, CvarsHookRestartGame);
UnhookConVarChange(g_hCvarsList[CVAR_VOL], VolEnabledChanged);
// Stop after unhooking cvars.
return;
}
// Set locked cvars to their locked value.
SetConVarInt(g_hAutoTeamBalance, CVARS_AUTOTEAMBALANCE_LOCKED);
SetConVarInt(g_hLimitTeams, CVARS_LIMITTEAMS_LOCKED);
// Hook cvar to prevent it from changing.
HookConVarChange(g_hAutoTeamBalance, CvarsHookLocked);
HookConVarChange(g_hLimitTeams, CvarsHookLocked);
HookConVarChange(g_hRestartGame, CvarsHookRestartGame);
HookConVarChange(g_hCvarsList[CVAR_VOL], VolEnabledChanged);
}
/**
* Cvar hook callback (mp_autoteambalance, mp_limitteams)
* Prevents changes to cvar.
*
*
* @param convar The cvar handle.
* @param oldvalue The value before the attempted change.
* @param newvalue The new value.
@ -557,10 +557,10 @@ public CvarsHookLocked(Handle:cvar, const String:oldvalue[], const String:newval
{
return;
}
// Revert to locked value.
SetConVarInt(g_hAutoTeamBalance, CVARS_AUTOTEAMBALANCE_LOCKED);
// If log flag check fails, then don't log.
LogEvent(false, LogType_Normal, LOG_CORE_EVENTS, LogModule_Cvars, "Cvar Locked", "Cvar \"mp_autoteambalance\" was reverted back to %d.", CVARS_AUTOTEAMBALANCE_LOCKED);
}
@ -572,10 +572,10 @@ public CvarsHookLocked(Handle:cvar, const String:oldvalue[], const String:newval
{
return;
}
// Revert to locked value.
SetConVarInt(g_hLimitTeams, CVARS_LIMITTEAMS_LOCKED);
// If log flag check fails, then don't log.
LogEvent(false, LogType_Normal, LOG_CORE_EVENTS, LogModule_Cvars, "Cvar Locked", "Cvar \"mp_limitteams\" was reverted back to %d.", CVARS_LIMITTEAMS_LOCKED);
}
@ -584,7 +584,7 @@ public CvarsHookLocked(Handle:cvar, const String:oldvalue[], const String:newval
/**
* Cvar hook callback (mp_restartgame)
* Stops restart and just ends the round.
*
*
* @param convar The cvar handle.
* @param oldvalue The value before the attempted change.
* @param newvalue The new value.
@ -593,17 +593,17 @@ public CvarsHookRestartGame(Handle:cvar, const String:oldvalue[], const String:n
{
// Prevent round restart.
SetConVarInt(cvar, 0);
// If value was invalid or 0, then stop.
new Float:delay = StringToFloat(newvalue);
if (delay <= 0)
{
return;
}
// Terminate the round with restart time as delay.
RoundEndTerminateRound(delay);
// If log flag check fails, then don't log.
LogEvent(false, LogType_Normal, LOG_CORE_EVENTS, LogModule_Cvars, "Restart Game", "\"mp_restartgame\" was caught and blocked, commencing round.");
}

View File

@ -74,36 +74,36 @@ DamageLoad()
{
return;
}
// Create command callbacks (intercepts) for listed suicide commands.
decl String:suicidecmds[DAMAGE_SUICIDE_MAX_CMDS * DAMAGE_SUICIDE_MAX_LENGTH];
GetConVarString(g_hCvarsList[CVAR_DAMAGE_SUICIDE_CMDS], suicidecmds, sizeof(suicidecmds));
// Create array to store cmds
new String:arrayCmds[DAMAGE_SUICIDE_MAX_CMDS][DAMAGE_SUICIDE_MAX_LENGTH];
// Explode string into array indexes.
new cmdcount = ExplodeString(suicidecmds, ",", arrayCmds, sizeof(arrayCmds), sizeof(arrayCmds[]));
// x = Array index.
// arrayCmds[x] = suicide command.
for (new x = 0; x <= cmdcount - 1; x++)
{
// Trim whitespace.
TrimString(arrayCmds[x]);
// Prepare intercept for this command.
RegConsoleCmd(arrayCmds[x], DamageSuicideIntercept);
}
// Important: If ZR can be unloaded some day, make sure to remove the listeners and set this to false.
g_bSuicideCmdsHooked = true;
}
/**
* Client is joining the server.
*
* @param client The client index.
*
* @param client The client index.
*/
DamageClientInit(client)
{
@ -111,7 +111,7 @@ DamageClientInit(client)
#if defined USE_SDKHOOKS
SDKHook(client, SDKHook_TraceAttack, DamageTraceAttack);
SDKHook(client, SDKHook_OnTakeDamage, DamageOnTakeDamage);
// Set dummy values so it think it's hooked.
g_iDamageTraceAttackHookID[client] = 1;
g_iDamageOnTakeDamageHookID[client] = 1;
@ -123,13 +123,13 @@ DamageClientInit(client)
/**
* Client is leaving the server.
*
*
* @param client The client index.
*/
DamageOnClientDisconnect(client)
{
// Unhook damage callbacks, and reset variables.
if (g_iDamageTraceAttackHookID[client] != -1)
{
#if defined USE_SDKHOOKS
@ -137,10 +137,10 @@ DamageOnClientDisconnect(client)
#else
ZRTools_UnhookTraceAttack(g_iDamageTraceAttackHookID[client]);
#endif
g_iDamageTraceAttackHookID[client] = -1;
}
if (g_iDamageOnTakeDamageHookID[client] != -1)
{
#if defined USE_SDKHOOKS
@ -148,14 +148,14 @@ DamageOnClientDisconnect(client)
#else
ZRTools_UnhookOnTakeDamage(g_iDamageOnTakeDamageHookID[client]);
#endif
g_iDamageOnTakeDamageHookID[client] = -1;
}
}
/**
* A client was infected.
*
*
* @param client The client index.
* @param motherinfect True if the zombie is mother, false if not.
*/
@ -168,13 +168,13 @@ DamageOnClientInfected(client, bool:motherinfect)
/**
* Hook: TraceAttack
* Called right before the bullet enters a client.
*
*
* @param client The client index.
* @param inflictor The entity index of the inflictor.
* @param attacker The client index of the attacker.
* @param damage The amount of damage inflicted.
* @param hitbox The hitbox index.
* @param hitgroup The hitgroup index.
* @param hitgroup The hitgroup index.
* @return Return ZRTools_Handled to stop bullet from hitting client.
* ZRTools_Continue to allow bullet to hit client.
*/
@ -189,17 +189,17 @@ public ZRTools_Action:DamageTraceAttack(client, inflictor, attacker, Float:damag
{
return ACTION_CONTINUE;
}
// If client is attacking himself, then stop.
if(attacker == client)
{
return ACTION_CONTINUE;
}
// Get zombie flag for each client.
new bool:clientzombie = InfectIsClientInfected(client);
new bool:attackerzombie = InfectIsClientInfected(attacker);
// If the flags are the same on both clients, then stop.
if (clientzombie == attackerzombie)
{
@ -209,27 +209,27 @@ public ZRTools_Action:DamageTraceAttack(client, inflictor, attacker, Float:damag
{
return ACTION_CONTINUE;
}
// Stop bullet from hurting client.
return ACTION_HANDLED;
}
// Here we know that attacker and client are different teams.
// Check if immunity module requires damage to be blocked.
if (ImmunityOnClientTraceAttack(client, attacker, damage, hitgroup, damagetype))
{
// Block damage.
return ACTION_HANDLED;
}
// If client is a human, then allow damage.
if (InfectIsClientHuman(client))
{
// Allow damage.
return ACTION_CONTINUE;
}
// If damage hitgroups cvar is disabled, then allow damage.
// TODO: There are two cvars: zr_hitgroups and zr_damage_hitgroups. Maybe
// just use zr_hitgroups?
@ -239,24 +239,24 @@ public ZRTools_Action:DamageTraceAttack(client, inflictor, attacker, Float:damag
// Allow damage.
return ACTION_CONTINUE;
}
// If damage is disabled for this hitgroup, then stop.
new index = HitgroupToIndex(hitgroup);
// If index can't be found, then allow damage.
if (index == -1)
{
// Allow damage.
return ACTION_CONTINUE;
}
new bool:candamage = HitgroupsCanDamage(index);
if (!candamage)
{
// Stop bullet from hurting client.
return ACTION_HANDLED;
}
// Allow damage.
return ACTION_CONTINUE;
}
@ -264,13 +264,13 @@ public ZRTools_Action:DamageTraceAttack(client, inflictor, attacker, Float:damag
/**
* Hook: OnTakeDamage
* Called right before damage is done.
*
*
* @param client The client index.
* @param inflictor The entity index of the inflictor.
* @param attacker The client index of the attacker.
* @param damage The amount of damage inflicted.
* @param damagetype The type of damage inflicted.
* @param ammotype The ammo type of the attacker's weapon.
* @param ammotype The ammo type of the attacker's weapon.
* @return Return ZRTools_Handled to stop the damage to client.
* ZRTools_Continue to allow damage to client.
*/
@ -283,18 +283,18 @@ public ZRTools_Action:DamageOnTakeDamage(client, inflictor, attacker, Float:dama
// Get classname of the inflictor.
decl String:classname[64];
GetEdictClassname(inflictor, classname, sizeof(classname));
// If entity is a trigger, then allow damage. (Map is damaging client)
if (StrContains(classname, "trigger") > -1)
{
return ACTION_CONTINUE;
}
new action;
// Forward this hook to another module an return (or not) what it wants.
action = NapalmOnTakeDamage(client, damagetype);
// If the napalm module wants to return here, then return the int casted into the action type.
if (action > -1)
{
@ -304,7 +304,7 @@ public ZRTools_Action:DamageOnTakeDamage(client, inflictor, attacker, Float:dama
return ZRTools_Action:action;
#endif
}
// Client was shot or knifed.
if (damagetype & DMG_CSS_BULLET)
{
@ -313,25 +313,25 @@ public ZRTools_Action:DamageOnTakeDamage(client, inflictor, attacker, Float:dama
{
return ACTION_CONTINUE;
}
// Get zombie flag for each client.
new bool:clientzombie = InfectIsClientInfected(client);
new bool:attackerzombie = InfectIsClientInfected(attacker);
// If client and attacker are on the same team, then let CS:S handle the rest.
if (clientzombie == attackerzombie)
{
return ACTION_CONTINUE;
}
// We know that clientzombie is the opposite of attacker zombie.
// If the client is a zombie, then allow damage.
if (clientzombie)
{
return ACTION_CONTINUE;
}
// Check if immunity module blocked or modified the damage.
new Action:immunityAction = ImmunityOnClientDamage(client, attacker, damage);
if (immunityAction != Plugin_Continue)
@ -339,14 +339,14 @@ public ZRTools_Action:DamageOnTakeDamage(client, inflictor, attacker, Float:dama
// Damage was blocked or modified.
return immunityAction;
}
// Client is about to be infected, re-add HP so they aren't killed by
// knife. But only do this when immunity mode is disabled.
if (ClassGetImmunityMode(client) == Immunity_None)
{
new health = GetClientHealth(client);
SetEntityHealth(client, health + RoundToNearest(damage));
// Allow damage.
return ACTION_CONTINUE;
}
@ -360,19 +360,19 @@ public ZRTools_Action:DamageOnTakeDamage(client, inflictor, attacker, Float:dama
{
return ACTION_CONTINUE;
}
// If attacker isn't valid, then allow damage.
if (!ZRIsClientValid(attacker))
{
return ACTION_CONTINUE;
}
// If client is a zombie, then allow damage.
if (InfectIsClientInfected(client))
{
return ACTION_CONTINUE;
}
// Stop damage.
return ACTION_HANDLED;
}
@ -385,11 +385,11 @@ public ZRTools_Action:DamageOnTakeDamage(client, inflictor, attacker, Float:dama
{
return ACTION_CONTINUE;
}
// Stop damage.
return ACTION_HANDLED;
}
// Allow damage.
return ACTION_CONTINUE;
}
@ -397,10 +397,10 @@ public ZRTools_Action:DamageOnTakeDamage(client, inflictor, attacker, Float:dama
/**
* Command callback (kill, spectate, jointeam, joinclass)
* Block command if plugin thinks they are trying to commit suicide.
*
*
* @param client The client index.
* @param argc The number of arguments in command string.
*/
*/
public Action:DamageSuicideIntercept(client, argc)
{
// Get suicide interception settings.
@ -408,10 +408,10 @@ public Action:DamageSuicideIntercept(client, argc)
new bool:suicideZombie = GetConVarBool(g_hCvarsList[CVAR_DAMAGE_SUICIDE_ZOMBIE]);
new bool:suicideZombieMother = GetConVarBool(g_hCvarsList[CVAR_DAMAGE_SUICIDE_MZOMBIE]);
new bool:suicideHuman = GetConVarBool(g_hCvarsList[CVAR_DAMAGE_SUICIDE_HUMAN]);
// Check various criterias that will _allow_ the command. If no criterias
// match, block it.
// Check general criterias.
if ((suicideAfterInfect && !InfectHasZombieSpawned()) || // Check if it should block suicides before mother zombie.
!ZRIsClientValid(client) || // Validate client (to stop console).
@ -420,7 +420,7 @@ public Action:DamageSuicideIntercept(client, argc)
// Allow command.
return Plugin_Continue;
}
// Check zombie criterias.
if (InfectIsClientInfected(client))
{
@ -431,7 +431,7 @@ public Action:DamageSuicideIntercept(client, argc)
return Plugin_Continue;
}
}
// Check human criterias.
// Allow suicide if player is a human and humans can suicide.
if (InfectIsClientHuman(client) && !suicideHuman)
@ -439,11 +439,11 @@ public Action:DamageSuicideIntercept(client, argc)
// Allow command.
return Plugin_Continue;
}
// Tell client their command has been intercepted, and log.
TranslationPrintToChat(client, "Damage suicide intercept");
LogEvent(false, LogType_Normal, LOG_GAME_EVENTS, LogModule_Damage, "Suicide Intercept", "\"%L\" attempted suicide.", client);
// Block command.
return Plugin_Handled;
}

View File

@ -4,7 +4,7 @@
* Zombie:Reloaded
*
* File: debugtools.inc
* Type: Core
* Type: Core
* Description: Place to put custom functions and test stuff.
*
* Copyright (C) 2009-2013 Greyscale, Richard Helgeby
@ -42,29 +42,29 @@ public Action:Command_GetParameterCount(client, argc)
ReplyToCommand(client, "No parameter string passed. Usage: zr_getparametercount <paramstring>");
return Plugin_Handled;
}
decl String:argbuffer[256];
decl String:paramstring[256];
paramstring[0] = 0;
// Join the last parameters in a string.
for (new arg = 1; arg <= argc; arg++)
{
GetCmdArg(arg, argbuffer, sizeof(argbuffer));
StrCat(paramstring, sizeof(paramstring), argbuffer);
// Add space, except on the last parameter.
if (arg < argc)
{
StrCat(paramstring, sizeof(paramstring), " ");
}
}
ReplyToCommand(client, "Parameter string: \"%s\"", paramstring);
new paramcount = GetParameterCount(paramstring);
ReplyToCommand(client, "Parameter count: %d", paramcount);
return Plugin_Handled;
}
@ -75,35 +75,35 @@ public Action:Command_GetParameterValue(client, argc)
ReplyToCommand(client, "Missing parameters. Usage: zr_getparametervalue <paramname> <paramstring>");
return Plugin_Handled;
}
decl String:paramname[256];
decl String:paramstring[256];
decl String:valuebuffer[64];
decl String:argbuffer[256];
paramstring[0] = 0;
valuebuffer[0] = 0;
GetCmdArg(1, paramname, sizeof(paramname));
// Join the last parameters in a string.
for (new arg = 2; arg <= argc; arg++)
{
GetCmdArg(arg, argbuffer, sizeof(argbuffer));
StrCat(paramstring, sizeof(paramstring), argbuffer);
// Add space, except on the last parameter.
if (arg < argc)
{
StrCat(paramstring, sizeof(paramstring), " ");
}
}
new retval = GetParameterValue(valuebuffer, sizeof(valuebuffer), paramstring, paramname);
ReplyToCommand(client, "Return value: %d\nParameter string: \"%s\"\nParameter value: \"%s\"", retval, paramstring, valuebuffer);
return Plugin_Handled;
}
*/

View File

@ -37,69 +37,69 @@ DownloadsLoad()
{
// Register config file.
ConfigRegisterConfig(File_Downloads, Structure_List, CONFIG_FILE_ALIAS_DOWNLOADS);
// Get downloads file path.
decl String:pathdownloads[PLATFORM_MAX_PATH];
new bool:exists = ConfigGetCvarFilePath(CVAR_CONFIG_PATH_DOWNLOADS, pathdownloads);
// If file doesn't exist, then log and stop.
if (!exists)
{
// Log failure and stop plugin.
LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Downloads, "Config Validation", "Missing downloads file: \"%s\"", pathdownloads);
}
// Set the path to the config file.
ConfigSetConfigPath(File_Downloads, pathdownloads);
// Load config from file and create array structure.
new bool:success = ConfigLoadConfig(File_Downloads, arrayDownloads, PLATFORM_MAX_PATH);
// Unexpected error, stop plugin.
if (!success)
{
LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Downloads, "Config Validation", "Unexpected error encountered loading: %s", pathdownloads);
}
new downloadcount;
new downloadvalidcount;
decl String:downloadpath[PLATFORM_MAX_PATH];
new downloads = downloadcount = GetArraySize(arrayDownloads);
// x = download array index.
for (new x = 0; x < downloads; x++)
{
// Get download path
GetArrayString(arrayDownloads, x, downloadpath, sizeof(downloadpath));
// If file doesn't exist, then remove, log, and stop.
if (!FileExists(downloadpath, true))
{
// Remove client from array.
RemoveFromArray(arrayDownloads, x);
// Subtract one from count.
downloads--;
// Backtrack one index, because we deleted it out from under the loop.
x--;
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Downloads, "Config Validation", "Missing file \"%s\"", downloadpath);
continue;
}
// Increment downloadvalidcount
downloadvalidcount++;
// Precache model file and add to downloads table.
AddFileToDownloadsTable(downloadpath);
}
// Log model validation info.
LogEvent(false, LogType_Normal, LOG_CORE_EVENTS, LogModule_Downloads, "Config Validation", "Total: %d | Successful: %d | Unsuccessful: %d", downloadcount, downloadvalidcount, downloadcount - downloadvalidcount);
// Set config data.
ConfigSetConfigLoaded(File_Downloads, true);
ConfigSetConfigReloadFunc(File_Downloads, GetFunctionByName(GetMyHandle(), "DownloadsOnConfigReload"));
@ -108,7 +108,7 @@ DownloadsLoad()
/**
* Called when configs are being reloaded.
*
*
* @param config The config being reloaded. (only if 'all' is false)
*/
public DownloadsOnConfigReload(ConfigFile:config)

View File

@ -36,9 +36,9 @@ EventInit()
/**
* Hook events used by plugin.
*
*
* @param unhook If true, then unhook all events, if false, then hook.
*/
*/
EventHook(bool:unhook = false)
{
// If unhook is true, then continue.
@ -54,11 +54,11 @@ EventHook(bool:unhook = false)
UnhookEvent("player_death", EventPlayerDeath);
UnhookEvent("player_jump", EventPlayerJump);
UnhookEvent("weapon_fire", EventWeaponFire);
// Stop after unhooking events.
return;
}
// Hook all events used by plugin.
HookEvent("round_start", EventRoundStart);
HookEvent("round_freeze_end", EventRoundFreezeEnd);
@ -74,7 +74,7 @@ EventHook(bool:unhook = false)
/**
* Event callback (round_start)
* The round is starting.
*
*
* @param event The event handle.
* @param name Name of the event.
* @dontBroadcast If true, event is broadcasted to all clients, false if not.
@ -89,7 +89,7 @@ public Action:EventRoundStart(Handle:event, const String:name[], bool:dontBroadc
SEffectsOnRoundStart();
ZSpawnOnRoundStart();
VolOnRoundStart();
// Fire post round_start event.
//CreateTimer(0.0, EventRoundStartPost);
}
@ -97,7 +97,7 @@ public Action:EventRoundStart(Handle:event, const String:name[], bool:dontBroadc
/**
* Event callback (round_start)
* The round is starting. *Post
*
*
* @param event The event handle.
* @param name Name of the event.
* @dontBroadcast If true, event is broadcasted to all clients, false if not.
@ -110,7 +110,7 @@ public Action:EventRoundStart(Handle:event, const String:name[], bool:dontBroadc
/**
* Event callback (round_freeze_end)
* The freeze time is ending.
*
*
* @param event The event handle.
* @param name Name of the event.
* @dontBroadcast If true, event is broadcasted to all clients, false if not.
@ -126,7 +126,7 @@ public Action:EventRoundFreezeEnd(Handle:event, const String:name[], bool:dontBr
/**
* Event callback (round_end)
* The round is ending.
*
*
* @param event The event handle.
* @param name Name of the event.
* @dontBroadcast If true, event is broadcasted to all clients, false if not.
@ -135,7 +135,7 @@ public Action:EventRoundEnd(Handle:event, const String:name[], bool:dontBroadcas
{
// Get all required event info.
new reason = GetEventInt(event, "reason");
// Forward event to modules.
WeaponsOnRoundEnd();
RoundEndOnRoundEnd(reason);
@ -150,7 +150,7 @@ public Action:EventRoundEnd(Handle:event, const String:name[], bool:dontBroadcas
/**
* Event callback (player_team)
* Client is joining a team.
*
*
* @param event The event handle.
* @param name Name of the event.
* @dontBroadcast If true, event is broadcasted to all clients, false if not.
@ -160,18 +160,18 @@ public Action:EventPlayerTeam(Handle:event, const String:name[], bool:dontBroadc
// Get all required event info.
new index = GetClientOfUserId(GetEventInt(event, "userid"));
new team = GetEventInt(event, "team");
// Forward event to modules.
InfectOnClientTeam(index, team);
ImmunityOnClientTeam(index);
return Plugin_Handled;
}
/**
* Event callback (player_spawn)
* Client is spawning into the game.
*
*
* @param event The event handle.
* @param name Name of the event.
* @dontBroadcast If true, event is broadcasted to all clients, false if not.
@ -180,7 +180,7 @@ public Action:EventPlayerSpawn(Handle:event, const String:name[], bool:dontBroad
{
// Get all required event info.
new index = GetClientOfUserId(GetEventInt(event, "userid"));
// Forward event to modules.
InfectOnClientSpawn(index); // Some modules depend on this to finish first.
AccountOnClientSpawn(index); // Some modules depend on this to finish first.
@ -193,7 +193,7 @@ public Action:EventPlayerSpawn(Handle:event, const String:name[], bool:dontBroad
ZHPOnClientSpawn(index);
VolOnPlayerSpawn(index);
ImmunityClientSpawn(index);
// Fire post player_spawn event.
CreateTimer(0.1, EventPlayerSpawnPost, index);
}
@ -201,7 +201,7 @@ public Action:EventPlayerSpawn(Handle:event, const String:name[], bool:dontBroad
/**
* Event callback (player_spawn)
* Client is spawning into the game. *Post
*
*
* @param event The event handle.
* @param name Name of the event.
* @dontBroadcast If true, event is broadcasted to all clients, false if not.
@ -213,7 +213,7 @@ public Action:EventPlayerSpawnPost(Handle:timer, any:client)
{
return;
}
// Forward event to modules.
WeaponsOnClientSpawnPost(client);
SEffectsOnClientSpawnPost(client);
@ -224,7 +224,7 @@ public Action:EventPlayerSpawnPost(Handle:timer, any:client)
/**
* Event callback (player_hurt)
* Client is being hurt.
*
*
* @param event The event handle.
* @param name Name of the event.
* @dontBroadcast If true, event is broadcasted to all clients, false if not.
@ -236,10 +236,10 @@ public Action:EventPlayerHurt(Handle:event, const String:name[], bool:dontBroadc
new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
new hitgroup = GetEventInt(event, "hitgroup");
new dmg_health = GetEventInt(event, "dmg_health");
decl String:weapon[WEAPONS_MAX_LENGTH];
GetEventString(event, "weapon", weapon, sizeof(weapon));
// Forward event to modules.
ClassAlphaUpdate(index);
InfectOnClientHurt(index, attacker, weapon);
@ -253,7 +253,7 @@ public Action:EventPlayerHurt(Handle:event, const String:name[], bool:dontBroadc
/**
* Event callback (player_death)
* Client has been killed.
*
*
* @param event The event handle.
* @param name Name of the event.
* @dontBroadcast If true, event is broadcasted to all clients, false if not.
@ -263,17 +263,17 @@ public Action:EventPlayerDeath(Handle:event, const String:name[], bool:dontBroad
// Get the weapon name.
decl String:weapon[WEAPONS_MAX_LENGTH];
GetEventString(event, "weapon", weapon, sizeof(weapon));
// If client is being infected, then stop.
if (StrEqual(weapon, "zombie_claws_of_death", false))
{
return;
}
// Get all required event info.
new index = GetClientOfUserId(GetEventInt(event, "userid"));
new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
// Validate client.
if (!ZRIsClientValid(index))
{
@ -281,7 +281,7 @@ public Action:EventPlayerDeath(Handle:event, const String:name[], bool:dontBroad
// other mods might sent this event with bad data.
return;
}
// Forward event to modules.
ClassOnClientDeath(index);
InfectOnClientDeath(index, attacker);
@ -301,7 +301,7 @@ public Action:EventPlayerDeath(Handle:event, const String:name[], bool:dontBroad
/**
* Event callback (player_jump)
* Client is jumping.
*
*
* @param event The event handle.
* @param name Name of the event.
* @dontBroadcast If true, event is broadcasted to all clients, false if not.
@ -310,7 +310,7 @@ public Action:EventPlayerJump(Handle:event, const String:name[], bool:dontBroadc
{
// Get all required event info.
new index = GetClientOfUserId(GetEventInt(event, "userid"));
// Fire post player_jump event.
CreateTimer(0.0, EventPlayerJumpPost, index);
}
@ -318,7 +318,7 @@ public Action:EventPlayerJump(Handle:event, const String:name[], bool:dontBroadc
/**
* Event callback (player_jump)
* Client is jumping. *Post
*
*
* @param event The event handle.
* @param name Name of the event.
* @dontBroadcast If true, event is broadcasted to all clients, false if not.
@ -330,7 +330,7 @@ public Action:EventPlayerJumpPost(Handle:timer, any:client)
{
return;
}
// Forward event to modules.
JumpBoostOnClientJumpPost(client);
}
@ -338,7 +338,7 @@ public Action:EventPlayerJumpPost(Handle:timer, any:client)
/**
* Event callback (weapon_fire)
* Weapon has been fired.
*
*
* @param event The event handle.
* @param name Name of the event.
* @dontBroadcast If true, event is broadcasted to all clients, false if not.
@ -349,7 +349,7 @@ public Action:EventWeaponFire(Handle:event, const String:name[], bool:dontBroadc
new index = GetClientOfUserId(GetEventInt(event, "userid"));
decl String:weapon[32];
GetEventString(event, "weapon", weapon, sizeof(weapon));
// Forward event to modules.
NapalmOnWeaponFire(index, weapon);
}

View File

@ -27,7 +27,7 @@
/**
* All external API natives are created here.
*/
*/
CreateGlobals()
{
}

View File

@ -72,59 +72,59 @@ HitgroupsOnCommandsCreate()
RegConsoleCmd("zr_hitgroup_enable_all", HitgroupsEnableAllCommand, "Enables all zombie hitgroups to be damaged. Usage: zr_hitgroup_enable_all");
RegConsoleCmd("zr_hitgroup_headshots_only", HitgroupsHeadshotsOnlyCommand, "Disables all zombie hitgroups but the head. Usage: zr_hitgroup_headshots_only");
}
/**
* Loads hitgroup data from file.
*/
*/
HitgroupsLoad()
{
// Register config file.
ConfigRegisterConfig(File_Hitgroups, Structure_Keyvalue, CONFIG_FILE_ALIAS_HITGROUPS);
// If module is disabled, then stop.
new bool:hitgroups = GetConVarBool(g_hCvarsList[CVAR_HITGROUPS]);
if (!hitgroups)
{
return;
}
// Get hitgroups config path.
decl String:pathhitgroups[PLATFORM_MAX_PATH];
new bool:exists = ConfigGetCvarFilePath(CVAR_CONFIG_PATH_HITGROUPS, pathhitgroups);
// If file doesn't exist, then log and stop.
if (!exists)
{
// Log failure.
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Hitgroups, "Config Validation", "Missing hitgroups config file: %s", pathhitgroups);
return;
}
// Set the path to the config file.
ConfigSetConfigPath(File_Hitgroups, pathhitgroups);
// Load config from file and create array structure.
new bool:success = ConfigLoadConfig(File_Hitgroups, arrayHitgroups);
// Unexpected error, stop plugin.
if (!success)
{
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Hitgroups, "Config Validation", "Unexpected error encountered loading: %s", pathhitgroups);
return;
}
// Validate hitgroups config.
new size = GetArraySize(arrayHitgroups);
if (!size)
{
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Hitgroups, "Config Validation", "No usable data found in hitgroups config file: %s", pathhitgroups);
}
// Now copy data to array structure.
HitgroupsCacheData();
// Set config data.
ConfigSetConfigLoaded(File_Hitgroups, true);
ConfigSetConfigReloadFunc(File_Hitgroups, GetFunctionByName(GetMyHandle(), "HitgroupsOnConfigReload"));
@ -140,54 +140,54 @@ HitgroupsCacheData()
// Get config's file path.
decl String:pathhitgroups[PLATFORM_MAX_PATH];
ConfigGetConfigPath(File_Hitgroups, pathhitgroups, sizeof(pathhitgroups));
new Handle:kvHitgroups;
new bool:success = ConfigOpenConfigFile(File_Hitgroups, kvHitgroups);
if (!success)
{
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Hitgroups, "Config Validation", "Unexpected error caching data from hitgroups config file: %s", pathhitgroups);
}
decl String:hitgroupname[HITGROUPS_MAX_LENGTH];
// x = array index
new size = GetArraySize(arrayHitgroups);
for (new x = 0; x < size; x++)
{
HitgroupsGetName(x, hitgroupname, sizeof(hitgroupname));
KvRewind(kvHitgroups);
if (!KvJumpToKey(kvHitgroups, hitgroupname))
{
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Hitgroups, "Config Validation", "Couldn't cache hitgroup data for: %s (check hitgroup config)", hitgroupname);
continue;
}
// General
new index = KvGetNum(kvHitgroups, "index", -1);
// Damage
new bool:damage = ConfigKvGetStringBool(kvHitgroups, "damage", "yes");
// Knockback (module)
new Float:knockback = KvGetFloat(kvHitgroups, "knockback", 1.0);
new Handle:arrayHitgroup = GetArrayCell(arrayHitgroups, x);
// Push data into array.
PushArrayCell(arrayHitgroup, index); // Index: 1
PushArrayCell(arrayHitgroup, damage); // Index: 2
PushArrayCell(arrayHitgroup, knockback); // Index: 3
}
// We're done with this file now, so we can close it.
CloseHandle(kvHitgroups);
}
/**
* Called when configs are being reloaded.
*
*
* @param config The config being reloaded. (only if 'all' is false)
*/
public HitgroupsOnConfigReload(ConfigFile:config)
@ -198,22 +198,22 @@ public HitgroupsOnConfigReload(ConfigFile:config)
/**
* Find the index at which the hitgroup's name is at.
*
*
* @param hitgroup The higroup name.
* @param maxlen (Only if 'overwritename' is true) The max length of the hitgroup name.
* @param maxlen (Only if 'overwritename' is true) The max length of the hitgroup name.
* @param overwritename (Optional) If true, the hitgroup given will be overwritten with the name from the config.
* @return The array index containing the given hitgroup name.
*/
stock HitgroupsNameToIndex(String:hitgroup[], maxlen = 0, bool:overwritename = false)
{
decl String:hitgroupname[HITGROUPS_MAX_LENGTH];
// x = Array index.
new size = GetArraySize(arrayHitgroups);
for (new x = 0; x < size; x++)
{
HitgroupsGetName(x, hitgroupname, sizeof(hitgroupname));
// If names match, then return index.
if (StrEqual(hitgroup, hitgroupname, false))
{
@ -223,19 +223,19 @@ stock HitgroupsNameToIndex(String:hitgroup[], maxlen = 0, bool:overwritename = f
// Copy config name to return string.
strcopy(hitgroup, maxlen, hitgroupname);
}
// Return this index.
return x;
}
}
// Name doesn't exist.
return -1;
}
/**
* Find the array index at which the hitgroup index is at.
*
*
* @param hitgroup The hitgroup index to search for.
* @return The array index that contains the given hitgroup index.
*/
@ -247,14 +247,14 @@ stock HitgroupToIndex(hitgroup)
{
// Get hitgroup index at this array index.
new index = HitgroupsGetIndex(x);
// If hitgroup indexes match, then return array index.
if (hitgroup == index)
{
return x;
}
}
// Hitgroup index doesn't exist.
return -1;
}
@ -269,14 +269,14 @@ stock HitgroupsGetName(index, String:hitgroup[], maxlen)
{
// Get array handle of hitgroup at given index.
new Handle:arrayHitgroup = GetArrayCell(arrayHitgroups, index);
// Get hitgroup name.
GetArrayString(arrayHitgroup, _:HITGROUPS_DATA_NAME, hitgroup, maxlen);
}
/**
* Retrieve hitgroup index. (static)
*
*
* @param index The array index.
* @return The hitgroup index.
*/
@ -284,14 +284,14 @@ stock HitgroupsGetIndex(index)
{
// Get array handle of hitgroup at given index.
new Handle:arrayHitgroup = GetArrayCell(arrayHitgroups, index);
// Return hitgroup index of the hitgroup.
return GetArrayCell(arrayHitgroup, _:HITGROUPS_DATA_INDEX);
}
/**
* Set hitgroup damage value. (dynamic)
*
*
* @param index The array index.
* @param candamage True to allow damage to hitgroup, false to block damage.
*/
@ -299,14 +299,14 @@ stock HitgroupsSetDamage(index, bool:candamage)
{
// Get array handle of hitgroup at given index.
new Handle:arrayHitgroup = GetArrayCell(arrayHitgroups, index);
// Return true if hitgroup can be damaged, false if not.
SetArrayCell(arrayHitgroup, _:HITGROUPS_DATA_DAMAGE, candamage);
}
/**
* Retrieve hitgroup damage value. (dynamic)
*
*
* @param index The array index.
* @return True if hitgroup can be damaged, false if not.
*/
@ -314,14 +314,14 @@ stock bool:HitgroupsCanDamage(index)
{
// Get array handle of hitgroup at given index.
new Handle:arrayHitgroup = GetArrayCell(arrayHitgroups, index);
// Return true if hitgroup can be damaged, false if not.
return bool:GetArrayCell(arrayHitgroup, _:HITGROUPS_DATA_DAMAGE);
}
/**
* Set hitgroup knockback value. (dynamic)
*
*
* @param index The array index.
* @param knockback The knockback multiplier for the hitgroup.
*/
@ -329,14 +329,14 @@ stock HitgroupsSetKnockback(index, Float:knockback)
{
// Get array handle of hitgroup at given index.
new Handle:arrayHitgroup = GetArrayCell(arrayHitgroups, index);
// Return the knockback multiplier for the hitgroup.
SetArrayCell(arrayHitgroup, _:HITGROUPS_DATA_KNOCKBACK, knockback);
}
/**
* Retrieve hitgroup knockback value. (dynamic)
*
*
* @param index The array index.
* @return The knockback multiplier of the hitgroup.
*/
@ -344,14 +344,14 @@ stock Float:HitgroupsGetKnockback(index)
{
// Get array handle of hitgroup at given index.
new Handle:arrayHitgroup = GetArrayCell(arrayHitgroups, index);
// Return the knockback multiplier for the hitgroup.
return Float:GetArrayCell(arrayHitgroup, _:HITGROUPS_DATA_KNOCKBACK);
}
/**
* Sends list of hitgroups to client.
*
*
* @param client The client index.
* @return True if sent successfully, false if not.
*/
@ -363,31 +363,31 @@ bool:HitgroupsMenuHitgroups(client)
{
return false;
}
// Create menu handle.
new Handle:menu_hitgroups = CreateMenu(HitgroupsMenuHitgroupsHandle);
// Set client as translation target.
SetGlobalTransTarget(client);
decl String:title[MENU_LINE_HUGE_LENGTH];
decl String:enableall[MENU_LINE_REG_LENGTH];
decl String:headshotsonly[MENU_LINE_REG_LENGTH];
// Format menu options.
Format(title, sizeof(title), "%t\n ", "Hitgroups menu hitgroups title");
Format(enableall, sizeof(enableall), "%t", "Hitgroups menu hitgroups enable all");
Format(headshotsonly, sizeof(headshotsonly), "%t\n ", "Hitgroups menu hitgroups headshots only");
// Add options to menu.
SetMenuTitle(menu_hitgroups, title);
AddMenuItem(menu_hitgroups, "Enable All", enableall);
AddMenuItem(menu_hitgroups, "Headshots Only", headshotsonly);
decl String:hitgroupoption[MENU_LINE_REG_LENGTH];
decl String:hitgroupcandamage[MENU_LINE_SMALL_LENGTH];
decl String:hitgroupid[4];
// x = Hitgroup index.
new size = GetArraySize(arrayHitgroups);
for (new x = 0; x < size; x++)
@ -395,23 +395,23 @@ bool:HitgroupsMenuHitgroups(client)
// Get hitgroup name.
HitgroupsGetName(x, hitgroupoption, sizeof(hitgroupoption));
IntToString(x, hitgroupid, sizeof(hitgroupid));
// Convert bool to "On/Off"
ConfigBoolToSetting(HitgroupsCanDamage(x), hitgroupcandamage, sizeof(hitgroupcandamage), false, client);
// Format "on/off" to the option.
Format(hitgroupoption, sizeof(hitgroupoption), "%s: %s", hitgroupoption, hitgroupcandamage);
// Add option to menu.
AddMenuItem(menu_hitgroups, hitgroupid, hitgroupoption);
}
// Create a "Back" button to the main admin menu.
SetMenuExitBackButton(menu_hitgroups, true);
// Send menu.
DisplayMenu(menu_hitgroups, client, MENU_TIME_FOREVER);
return true;
}
@ -421,7 +421,7 @@ bool:HitgroupsMenuHitgroups(client)
* @param action The action done on the menu (see menus.inc, enum MenuAction).
* @param client The client index.
* @param slot The slot index selected (starting from 0).
*/
*/
public HitgroupsMenuHitgroupsHandle(Handle:menu_hitgroups, MenuAction:action, client, slot)
{
// Client selected an option.
@ -439,7 +439,7 @@ public HitgroupsMenuHitgroupsHandle(Handle:menu_hitgroups, MenuAction:action, cl
// Enable hitgroup.
HitgroupsSetDamage(x, true);
}
// Tell the server that all hitgroups have been enabled.
TranslationPrintToChatAll(true, false, "Hitgroups command enable all successful");
}
@ -454,14 +454,14 @@ public HitgroupsMenuHitgroupsHandle(Handle:menu_hitgroups, MenuAction:action, cl
{
// Enable hitgroup.
HitgroupsSetDamage(x, true);
continue;
}
// Disable hitgroup.
HitgroupsSetDamage(x, false);
}
// Tell the server that headshots only been enabled.
TranslationPrintToChatAll(true, false, "Hitgroups command headshots only successful");
}
@ -471,13 +471,13 @@ public HitgroupsMenuHitgroupsHandle(Handle:menu_hitgroups, MenuAction:action, cl
decl String:hitgroupid[4];
GetMenuItem(menu_hitgroups, slot, hitgroupid, sizeof(hitgroupid));
new hitgroup = StringToInt(hitgroupid);
// Toggle value.
new bool:hitgroupcandamage = HitgroupsCanDamage(hitgroup);
HitgroupsSetDamage(hitgroup, !hitgroupcandamage);
}
}
// Re-send menu.
HitgroupsMenuHitgroups(client);
}
@ -501,7 +501,7 @@ public HitgroupsMenuHitgroupsHandle(Handle:menu_hitgroups, MenuAction:action, cl
/**
* Command callback (zr_hitgroup)
* Toggles or sets if a zombie's hitgroup can be damaged.
*
*
* @param client The client index.
* @param argc Argument count.
*/
@ -513,7 +513,7 @@ public Action:HitgroupsCommand(client, argc)
TranslationReplyToCommand(client, "No access to command");
return Plugin_Handled;
}
// If module is disabled, then stop.
new bool:hitgroups = GetConVarBool(g_hCvarsList[CVAR_HITGROUPS]);
if (!hitgroups)
@ -521,17 +521,17 @@ public Action:HitgroupsCommand(client, argc)
TranslationReplyToCommand(client, "Feature is disabled");
return Plugin_Handled;
}
// If not enough arguments given, then stop.
if (argc < 1)
{
TranslationReplyToCommand(client, "Hitgroups command syntax");
TranslationReplyToCommand(client, "Hitgroups command related commands");
TranslationPrintToConsole(client, "Hitgroups command syntax names");
// Print all the hitgroup names in the client's console.
decl String:hitgroupname[HITGROUPS_MAX_LENGTH];
// x = Hitgroup index.
new size = GetArraySize(arrayHitgroups);
for (new x = 0; x < size; x++)
@ -540,14 +540,14 @@ public Action:HitgroupsCommand(client, argc)
HitgroupsGetName(x, hitgroupname, sizeof(hitgroupname));
PrintToConsole(client, "* %s", hitgroupname);
}
return Plugin_Handled;
}
// Get hitgroup alias given.
decl String:target[HITGROUPS_MAX_LENGTH];
GetCmdArg(1, target, sizeof(target));
// If the hitgroup is invalid, then stop and tell client.
new hitgroup = HitgroupsNameToIndex(target, sizeof(target), true);
if (hitgroup == -1)
@ -555,9 +555,9 @@ public Action:HitgroupsCommand(client, argc)
TranslationReplyToCommand(client, "Hitgroups command invalid hitgroup", target);
return Plugin_Handled;
}
new bool:hitgroupdamage;
// Check if value was given
decl String:value[4];
GetCmdArg(2, value, sizeof(value));
@ -571,10 +571,10 @@ public Action:HitgroupsCommand(client, argc)
// Cast the given value to a bool.
hitgroupdamage = bool:StringToInt(value);
}
// Set new value in the hitgroup data cache.
HitgroupsSetDamage(hitgroup, hitgroupdamage);
// Tell client the new value of the hitgroup.
if (hitgroupdamage)
{
@ -584,17 +584,17 @@ public Action:HitgroupsCommand(client, argc)
{
TranslationReplyToCommand(client, "Hitgroups command successful off", target);
}
// Log action to game events.
LogEvent(false, LogType_Normal, LOG_GAME_EVENTS, LogModule_Hitgroups, "Headshots Toggle", "Admin \"%L\" toggled hitgroup \"%s\" to \"%d\". (zr_hitgroup)", client, target, hitgroupdamage);
return Plugin_Handled;
}
/**
* Command callback (zr_hitgroup_enable_all)
* Enables all zombie hitgroups to be damaged.
*
*
* @param client The client index.
* @param argc Argument count.
*/
@ -606,7 +606,7 @@ public Action:HitgroupsEnableAllCommand(client, argc)
TranslationReplyToCommand(client, "No access to command");
return Plugin_Handled;
}
// If module is disabled, then stop.
new bool:hitgroups = GetConVarBool(g_hCvarsList[CVAR_HITGROUPS]);
if (!hitgroups)
@ -614,7 +614,7 @@ public Action:HitgroupsEnableAllCommand(client, argc)
TranslationReplyToCommand(client, "Feature is disabled");
return Plugin_Handled;
}
// x = Hitgroup index.
new size = GetArraySize(arrayHitgroups);
for (new x = 0; x < size; x++)
@ -622,20 +622,20 @@ public Action:HitgroupsEnableAllCommand(client, argc)
// Set that hitgroup index to true for damage.
HitgroupsSetDamage(x, true);
}
// Tell the server that all hitgroups have been enabled.
TranslationPrintToChatAll(true, false, "Hitgroups command enable all successful");
// Log action to game events.
LogEvent(false, LogType_Normal, LOG_GAME_EVENTS, LogModule_Hitgroups, "Enable All", "Admin \"%L\" enabled all zombie hitgroups. (zr_hitgroup_enable_all)", client);
return Plugin_Handled;
}
/**
* Command callback (zr_hitgroup_enable_all)
* Disables all zombie hitgroups but the head.
*
*
* @param client The client index.
* @param argc Argument count.
*/
@ -647,7 +647,7 @@ public Action:HitgroupsHeadshotsOnlyCommand(client, argc)
TranslationReplyToCommand(client, "No access to command");
return Plugin_Handled;
}
// If module is disabled, then stop.
new bool:hitgroups = GetConVarBool(g_hCvarsList[CVAR_HITGROUPS]);
if (!hitgroups)
@ -655,7 +655,7 @@ public Action:HitgroupsHeadshotsOnlyCommand(client, argc)
TranslationReplyToCommand(client, "Feature is disabled");
return Plugin_Handled;
}
// x = Hitgroup index.
new size = GetArraySize(arrayHitgroups);
for (new x = 0; x < size; x++)
@ -666,16 +666,16 @@ public Action:HitgroupsHeadshotsOnlyCommand(client, argc)
HitgroupsSetDamage(x, true);
continue;
}
// Set that hitgroup index to true for damage.
HitgroupsSetDamage(x, false);
}
// Tell the server that headshots only been enabled.
TranslationPrintToChatAll(true, false, "Hitgroups command headshots only successful");
// Log action to game events.
LogEvent(false, LogType_Normal, LOG_GAME_EVENTS, LogModule_Hitgroups, "Headshots Only", "Admin \"%L\" enabled headshots only. (zr_hitgroup_headshots_only)", client);
return Plugin_Handled;
}

View File

@ -72,7 +72,7 @@ ImmunityOnCommandsCreate()
/*____________________________________________________________________________*/
/**
/**
* Client executed the deploy shield command.
*
* @param client Client index.
@ -86,10 +86,10 @@ public Action:Command_DeployShield(client, argc)
TranslationPrintToServer("Must be player");
return Plugin_Handled;
}
// Attempt to deploy shield.
ImmunityDeployShield(client);
return Plugin_Handled;
}
@ -109,7 +109,7 @@ bool:ImmunityOnClientInfect(client, attacker)
{
// Get immunity mode from client class.
new ImmunityMode:mode = ClassGetImmunityMode(client);
// Check mode.
switch(mode)
{
@ -141,7 +141,7 @@ bool:ImmunityOnClientInfect(client, attacker)
return ImmunityShieldModeHandler(client);
}
}
// Current mode doesn't apply to infection.
return false;
}
@ -169,10 +169,10 @@ bool:ImmunityOnClientTraceAttack(client, attacker, Float:damage, hitgroup, damag
// Allow damage.
return false;
}
// Get immunity mode from client class.
new ImmunityMode:mode = ClassGetImmunityMode(client);
// Check mode.
switch(mode)
{
@ -189,7 +189,7 @@ bool:ImmunityOnClientTraceAttack(client, attacker, Float:damage, hitgroup, damag
// Allow damage.
return false;
}
// Check if damage give HP below the infection threshold.
if (ImmunityBelowInfectThreshold(client, damage))
{
@ -208,7 +208,7 @@ bool:ImmunityOnClientTraceAttack(client, attacker, Float:damage, hitgroup, damag
// Allow damage.
return false;
}
// Get attacker weapon.
decl String:weapon[32];
weapon[0] = 0;
@ -223,10 +223,10 @@ bool:ImmunityOnClientTraceAttack(client, attacker, Float:damage, hitgroup, damag
{
GetClientWeapon(attacker, weapon, sizeof(weapon));
}
// Since damage is blocked, trigger knock back hurt event manually.
KnockbackOnClientHurt(client, attacker, weapon, hitgroup, RoundToNearest(damage));
// Block damage from attacker.
return true;
}
@ -238,7 +238,7 @@ bool:ImmunityOnClientTraceAttack(client, attacker, Float:damage, hitgroup, damag
// Allow damage.
return false;
}
// Check if shield is active.
if (PlayerImmunityTimer[client] != INVALID_HANDLE)
{
@ -248,7 +248,7 @@ bool:ImmunityOnClientTraceAttack(client, attacker, Float:damage, hitgroup, damag
}
}
}
// Allow damage.
return false;
}
@ -276,17 +276,17 @@ Action:ImmunityOnClientDamage(client, attacker, &Float:damage)
// Allow damage.
return Plugin_Continue;
}
// Check if spawn protection is on.
if (bInfectImmune[client][INFECT_TYPE_NORMAL])
{
// Block damage.
return Plugin_Handled;
}
// Get immunity mode from client class.
new ImmunityMode:mode = ClassGetImmunityMode(client);
switch(mode)
{
case Immunity_Kill:
@ -298,15 +298,15 @@ Action:ImmunityOnClientDamage(client, attacker, &Float:damage)
// Don't modify damage.
return Plugin_Continue;
}
// A zombie is attacking a human in kill immunity mode. Increase
// damage so human will be instantly killed. (Using a high damage
// value in case the human class has a lot of HP.)
damage = 60000.0;
// Update score and health gain.
InfectUpdateScore(attacker, client);
// Damage was changed.
return Plugin_Changed;
}
@ -319,7 +319,7 @@ Action:ImmunityOnClientDamage(client, attacker, &Float:damage)
// Fake hurt event because it's not triggered when the damage
// was removed (because no one is actually hurt).
InfectOnClientHurt(client, attacker, "knife");
// Block damage to prevent player from dying.
return Plugin_Handled;
}
@ -331,12 +331,12 @@ Action:ImmunityOnClientDamage(client, attacker, &Float:damage)
// still be triggered so that subsequent attacks are registered,
// without dealing any damage.
InfectOnClientHurt(client, attacker, "knife");
// Block damage to prevent player from dying.
return Plugin_Handled;
}
}
// Allow damage.
return Plugin_Continue;
}
@ -360,7 +360,7 @@ bool:ImmunityInfectModeHandler(client)
// Note: ImmunityOnClientDamage and ImmunityOnClientTraceAttack hook into
// the damage module to prevent humans with low HP from dying when
// they're not supposed to.
new threshold = ClassGetImmunityAmount(client);
// Check if infection is disabled.
if (threshold == 0)
@ -368,13 +368,13 @@ bool:ImmunityInfectModeHandler(client)
// Infection is handled here: blocked.
return true;
}
if (PlayerImmunityThresholdPassed[client])
{
// Client HP below threshold, allow instant infection.
return false;
}
return true;
}
@ -395,7 +395,7 @@ bool:ImmunityDelayModeHandler(client, attacker)
{
// Additional attacks while a delayed infection is in progress will
// speedup the infection.
// Get reduction amount for subsequent zombie attack.
new reduction = ClassGetImmunityCooldown(client);
if (reduction > 0)
@ -403,26 +403,26 @@ bool:ImmunityDelayModeHandler(client, attacker)
// Reduce duration. Add one because the timer handler itself reduce
// duration by one.
PlayerImmunityDuration[client] -= reduction + 1;
// Note: This feature can be used to trigger an instant infection
// when a human receive a second attack, by setting the
// reduction value high enough.
// Trigger timer event to reduce delay and infect faster.
ImmunityDelayTimerHandler(PlayerImmunityTimer[client], client);
}
// Block infection.
return true;
}
// Start a delayed infection. Initialize duration and attacker.
PlayerImmunityDuration[client] = ClassGetImmunityAmount(client);
PlayerImmunityAttacker[client] = attacker;
// Create repated 1-second timer for handling the countdown.
PlayerImmunityTimer[client] = CreateTimer(1.0, ImmunityDelayTimerHandler, client, TIMER_FLAG_NO_MAPCHANGE | TIMER_REPEAT);
// Block infection.
return true;
}
@ -442,26 +442,26 @@ public Action:ImmunityDelayTimerHandler(Handle:timer, any:client)
ImmunityAbortHandler(client);
return Plugin_Stop;
}
// Reduce duration.
PlayerImmunityDuration[client] -= 1;
// Check if time is up.
if (PlayerImmunityDuration[client] <= 0)
{
// Get attacker before cleaning up.
new attacker = PlayerImmunityAttacker[client];
// Time is up. Reset data.
PlayerImmunityDuration[client] = 0;
ImmunityAbortHandler(client);
// Infect client. Give credit to the stored attacker.
InfectHumanToZombie(client, attacker);
return Plugin_Stop;
}
return Plugin_Continue;
}
@ -486,7 +486,7 @@ bool:ImmunityShieldModeHandler(client)
// Block infection.
return true;
}
// Shield is not active, allow infection.
return false;
}
@ -506,12 +506,12 @@ ImmunityDeployShield(client)
// Not available.
return;
}
// Deploy the shield.
PlayerImmunityDuration[client] = ClassGetImmunityAmount(client);
PlayerImmunityLastUse[client] = GetTime();
PlayerImmunityTimer[client] = CreateTimer(1.0, ImmunityShieldTimerHandler, client, TIMER_FLAG_NO_MAPCHANGE | TIMER_REPEAT);
// Trigger initial countdown.
ImmunityShieldTimerHandler(PlayerImmunityTimer[client], client);
}
@ -530,13 +530,13 @@ public Action:ImmunityShieldTimerHandler(Handle:timer, any:client)
ImmunityAbortHandler(client);
return Plugin_Stop;
}
// Reduce duration.
PlayerImmunityDuration[client] -= 1;
// Print remaining shield time.
TranslationPrintCenterText(client, "Immunity Shield Time Left", PlayerImmunityDuration[client]);
// Check if time is up.
if (PlayerImmunityDuration[client] <= 0)
{
@ -544,7 +544,7 @@ public Action:ImmunityShieldTimerHandler(Handle:timer, any:client)
ImmunityAbortHandler(client, false);
return Plugin_Stop;
}
return Plugin_Continue;
}
@ -560,12 +560,12 @@ ImmunityAbortHandler(client, bool:resetLastUse = true)
{
// Stop timer, if running.
ZREndTimer(PlayerImmunityTimer[client]);
// Reset data.
PlayerImmunityDuration[client] = -1;
PlayerImmunityAttacker[client] = 0;
PlayerImmunityThresholdPassed[client] = false;
if (resetLastUse)
{
PlayerImmunityLastUse[client] = 0;
@ -608,7 +608,7 @@ bool:ImmunityOnClientKnockBack(client)
// Client is human, allow knock back.
return false;
}
// Block knock back if shield is deployed.
if (PlayerImmunityTimer[client] != INVALID_HANDLE)
{
@ -616,7 +616,7 @@ bool:ImmunityOnClientKnockBack(client)
return true;
}
}
// Allow knock back.
return false;
}
@ -681,7 +681,7 @@ ImmunityClientSpawn(client)
ImmunityOnClientDisconnect(client)
{
ImmunityAbortHandler(client);
// Loop through attacker cache and remove client (set to 0).
for (new victim = 0; victim < sizeof(PlayerImmunityAttacker); victim++)
{
@ -744,14 +744,14 @@ bool:ImmunityBelowInfectThreshold(client, Float:damage)
new threshold = ClassGetImmunityAmount(client);
new clientHP = GetClientHealth(client);
new dmg = RoundToNearest(damage);
// Check if the damage go below the HP threshold. Client can only go below
// threshold when threshold is enabled (above zero).
if (clientHP - dmg <= threshold && threshold > 0)
{
return true;
}
return false;
}
@ -770,7 +770,7 @@ ImmunityMode:ImmunityStringToMode(const String:mode[])
{
return Immunity_Invalid;
}
if (StrEqual(mode, "none", false))
{
return Immunity_None;
@ -799,7 +799,7 @@ ImmunityMode:ImmunityStringToMode(const String:mode[])
{
return Immunity_Shield;
}
return Immunity_Invalid;
}
@ -820,7 +820,7 @@ ImmunityModeToString(ImmunityMode:mode, String:buffer[], maxlen)
{
return 0;
}
switch (mode)
{
case Immunity_None:
@ -852,7 +852,7 @@ ImmunityModeToString(ImmunityMode:mode, String:buffer[], maxlen)
return strcopy(buffer, maxlen, "shield");
}
}
return 0;
}
@ -896,7 +896,7 @@ bool:ImmunityIsValidAmount(ImmunityMode:mode, amount)
{
return false;
}
// There's no upper limit. If the value is too high it will
// overflow and become negative.
}
@ -925,7 +925,7 @@ bool:ImmunityIsValidAmount(ImmunityMode:mode, amount)
return false;
}
}
// Passed.
return true;
}
@ -979,7 +979,7 @@ bool:ImmunityIsValidCooldown(ImmunityMode:mode, cooldown)
{
return false;
}
// No upper limit. It may be intentional to use a high value so that
// the section attack will remove all delay and infect instantly.
}
@ -989,7 +989,7 @@ bool:ImmunityIsValidCooldown(ImmunityMode:mode, cooldown)
{
return false;
}
// No upper limit. It may be intentional to use a high value so that
// the shield can only be used once per life.
}
@ -999,7 +999,7 @@ bool:ImmunityIsValidCooldown(ImmunityMode:mode, cooldown)
return false;
}
}
// Passed.
return true;
}
@ -1028,7 +1028,7 @@ bool:ImmunityCanDeployShield(client, bool:printResponse = true)
}
return false;
}
// Check if cooldown is still in progress.
new cooldown = ClassGetImmunityCooldown(client);
new timeLeft = PlayerImmunityLastUse[client] + cooldown - GetTime();
@ -1040,18 +1040,18 @@ bool:ImmunityCanDeployShield(client, bool:printResponse = true)
}
return false;
}
// Check if a shield is already deployed.
if (PlayerImmunityTimer[client] != INVALID_HANDLE)
{
return false;
}
// Humans cannot deploy shield before first zombie.
if (!InfectHasZombieSpawned())
{
return false;
}
return true;
}

File diff suppressed because it is too large Load Diff

View File

@ -27,7 +27,7 @@
/**
* Client is jumping.
*
*
* @param client The client index.
*/
JumpBoostOnClientJumpPost(client)
@ -35,18 +35,18 @@ JumpBoostOnClientJumpPost(client)
// Get class jump multipliers.
new Float:distancemultiplier = ClassGetJumpDistance(client);
new Float:heightmultiplier = ClassGetJumpHeight(client);
// If both are set to 1.0, then stop here to save some work.
if (distancemultiplier == 1.0 && heightmultiplier == 1.0)
{
return;
}
new Float:vecVelocity[3];
// Get client's current velocity.
ToolsClientVelocity(client, vecVelocity, false);
// Only apply horizontal multiplier if it's not a bhop.
if (!JumpBoostIsBHop(vecVelocity))
{
@ -54,10 +54,10 @@ JumpBoostOnClientJumpPost(client)
vecVelocity[0] *= distancemultiplier;
vecVelocity[1] *= distancemultiplier;
}
// Apply height multiplier to jump vector.
vecVelocity[2] *= heightmultiplier;
// Set new velocity.
ToolsClientVelocity(client, vecVelocity, true, false);
}
@ -65,7 +65,7 @@ JumpBoostOnClientJumpPost(client)
/**
* This function detects excessive bunnyhopping.
* Note: This ONLY catches bunnyhopping that is worse than CS:S already allows.
*
*
* @param vecVelocity The velocity of the client jumping.
* @return True if the client is bunnyhopping, false if not.
*/
@ -77,10 +77,10 @@ stock bool:JumpBoostIsBHop(const Float:vecVelocity[])
{
return false;
}
// Calculate the magnitude of jump on the xy plane.
new Float:magnitude = SquareRoot(Pow(vecVelocity[0], 2.0) + Pow(vecVelocity[1], 2.0));
// Return true if the magnitude exceeds the max.
new Float:bunnyhopmax = GetConVarFloat(g_hCvarsList[CVAR_JUMPBOOST_BHOP_MAX]);
return (magnitude > bunnyhopmax);

View File

@ -36,7 +36,7 @@
* @param client The client index. (zombie)
* @param attacker The attacker index. (human)
* @param weapon The weapon used.
* @param hitgroup Hitgroup attacker has damaged.
* @param hitgroup Hitgroup attacker has damaged.
* @param dmg_health Damage done.
*/
KnockbackOnClientHurt(client, attacker, const String:weapon[], hitgroup, dmg_health)
@ -46,33 +46,33 @@ KnockbackOnClientHurt(client, attacker, const String:weapon[], hitgroup, dmg_hea
{
return;
}
// Client is a human, then stop.
if (InfectIsClientHuman(client))
{
return;
}
// If attacker is a zombie, then stop.
if (InfectIsClientInfected(attacker))
{
return;
}
// Block knock back if an immunity mode is handling this.
if (ImmunityOnClientKnockBack(client))
{
return;
}
// Get zombie knockback value.
new Float:knockback = ClassGetKnockback(client);
new Float:clientloc[3];
new Float:attackerloc[3];
GetClientAbsOrigin(client, clientloc);
// Check if a grenade was thrown.
if (StrEqual(weapon, "hegrenade"))
{
@ -87,16 +87,16 @@ KnockbackOnClientHurt(client, attacker, const String:weapon[], hitgroup, dmg_hea
{
// Get attackers eye position.
GetClientEyePosition(attacker, attackerloc);
// Get attackers eye angles.
new Float:attackerang[3];
GetClientEyeAngles(attacker, attackerang);
// Calculate knockback end-vector.
TR_TraceRayFilter(attackerloc, attackerang, MASK_ALL, RayType_Infinite, KnockbackTRFilter);
TR_GetEndPosition(clientloc);
}
new bool:weapons = GetConVarBool(g_hCvarsList[CVAR_WEAPONS]);
if (weapons)
{
@ -107,7 +107,7 @@ KnockbackOnClientHurt(client, attacker, const String:weapon[], hitgroup, dmg_hea
knockback *= WeaponsGetKnockback(weaponindex);
}
}
new bool:hitgroups = GetConVarBool(g_hCvarsList[CVAR_HITGROUPS]);
if (hitgroups)
{
@ -118,41 +118,41 @@ KnockbackOnClientHurt(client, attacker, const String:weapon[], hitgroup, dmg_hea
knockback *= HitgroupsGetKnockback(hitgroupindex);
}
}
// Apply damage knockback multiplier.
knockback *= float(dmg_health);
// Apply knockback.
KnockbackSetVelocity(client, attackerloc, clientloc, knockback);
}
/**
* Sets velocity on a player.
*
*
* @param client The client index.
* @param startpoint The starting coordinate to push from.
* @param endpoint The ending coordinate to push towards.
* @param magnitude Magnitude of the push.
*/
*/
KnockbackSetVelocity(client, const Float:startpoint[3], const Float:endpoint[3], Float:magnitude)
{
// Create vector from the given starting and ending points.
new Float:vector[3];
MakeVectorFromPoints(startpoint, endpoint, vector);
// Normalize the vector (equal magnitude at varying distances).
NormalizeVector(vector, vector);
// Apply the magnitude by scaling the vector (multiplying each of its components).
ScaleVector(vector, magnitude);
// CS: GO workaround. Apply knock back boost if enabled.
if (g_Game == Game_CSGO && GetConVarBool(g_hCvarsList[CVAR_CLASSES_CSGO_KNOCKBACK_BOOST]))
{
new flags = GetEntityFlags(client);
new Float:velocity[3];
ToolsGetClientVelocity(client, velocity);
// Remove boost if current velocity is too high.
if (velocity[2] > CSGO_KNOCKBACK_BOOST_MAX)
{
@ -165,18 +165,18 @@ KnockbackSetVelocity(client, const Float:startpoint[3], const Float:endpoint[3],
vector[2] = CSGO_KNOCKBACK_BOOST;
}
}
// ADD the given vector to the client's current velocity.
ToolsClientVelocity(client, vector);
}
/**
* Trace Ray forward, used as a filter to continue tracing if told so. (See sdktools_trace.inc)
*
*
* @param entity The entity index.
* @param contentsMask The contents mask.
* @return True to allow hit, false to continue tracing.
*/
* @return True to allow hit, false to continue tracing.
*/
public bool:KnockbackTRFilter(entity, contentsMask)
{
// If entity is a player, continue tracing.
@ -184,21 +184,21 @@ public bool:KnockbackTRFilter(entity, contentsMask)
{
return false;
}
// Allow hit.
return true;
}
/**
* Find the location of an exploding grenade (currently inflicting damage in player_hurt).
*
*
* @param heLoc The location of the exploding grenade.
* @return The entity index of the grenade.
*/
* @return The entity index of the grenade.
*/
KnockbackFindExplodingGrenade(Float:heLoc[3])
{
decl String:classname[64];
// Find max entities and loop through all of them.
new maxentities = GetMaxEntities();
for (new x = MaxClients; x <= maxentities; x++)
@ -208,26 +208,26 @@ KnockbackFindExplodingGrenade(Float:heLoc[3])
{
continue;
}
// If entity isn't a grenade, then stop.
GetEdictClassname(x, classname, sizeof(classname));
if (!StrEqual(classname, "hegrenade_projectile", false))
{
continue;
}
// If m_takedamage is set to 0, we found our grenade.
new takedamage = GetEntProp(x, Prop_Data, "m_takedamage");
if (takedamage == 0)
{
// Return its location.
GetEntPropVector(x, Prop_Send, "m_vecOrigin", heLoc);
// Return its entity index.
return x;
}
}
// Didn't find the grenade.
return -1;
}

View File

@ -59,7 +59,7 @@ enum LogTypes
/**
* List of modules that write log events. Add new modules if needed (in
* alphabetical order).
*
*
* Update following when adding modules:
* - Admin log flag menu
* - LogGetModuleNameString
@ -68,7 +68,7 @@ enum LogTypes
enum LogModules
{
bool:LogModule_Invalid = 0, /** Used as return value when an error occoured.*/
bool:LogModule_Account,
bool:LogModule_AntiStick,
bool:LogModule_Config,

View File

@ -36,7 +36,7 @@ LogInit()
{
CloseHandle(hLogModuleFilter);
}
// Initialize module filter array.
hLogModuleFilter = CreateArray(32);
}
@ -132,7 +132,7 @@ LogGetModuleNameString(String:buffer[], maxlen, LogModules:module, bool:shortNam
return shortName ? strcopy(buffer, maxlen, "ztele") : strcopy(buffer, maxlen, "ZTele");
}
}
// Module mismatch.
return 0;
}
@ -222,7 +222,7 @@ LogModules:LogGetModule(const String:moduleName[])
{
return LogModule_ZTele;
}
// No match.
return LogModule_Invalid;
}
@ -250,7 +250,7 @@ bool:LogCheckFlag(eventType)
* Check if the specified module is enabled in the log module filter cache.
*
* @param module Module to check.
* @return True if enabled, false otherwise.
* @return True if enabled, false otherwise.
*/
bool:LogCheckModuleFilter(LogModules:module)
{
@ -290,19 +290,19 @@ LogEvent(bool:isConsole = false, LogTypes:logType = LogType_Normal, eventType =
{
return;
}
// Check if console is ignored.
if (isConsole && GetConVarBool(g_hCvarsList[CVAR_LOG_IGNORE_CONSOLE]))
{
return;
}
// Check event type (log flag).
if (!LogCheckFlag(eventType))
{
return;
}
// Check if module filtering is enabled.
if (GetConVarBool(g_hCvarsList[CVAR_LOG_MODULE_FILTER]))
{
@ -313,18 +313,18 @@ LogEvent(bool:isConsole = false, LogTypes:logType = LogType_Normal, eventType =
}
}
}
// Format extra parameters into the log buffer.
decl String:logbuffer[LOG_MAX_LENGTH_FILE];
VFormat(logbuffer, sizeof(logbuffer), text, 7);
// Get human readable module name.
new String:modulename[64];
LogGetModuleNameString(modulename, sizeof(modulename), module);
// Format
// Format
Format(logbuffer, sizeof(logbuffer), "[%s] [%s] %s", modulename, description, logbuffer);
// Format other parameters onto the log text.
switch (logType)
{
@ -344,16 +344,16 @@ LogEvent(bool:isConsole = false, LogTypes:logType = LogType_Normal, eventType =
SetFailState(logbuffer);
}
}
// Note: The phrase "Literal text" is a blank phrase to pass any string we want into it.
// Check if printing log events to admins is enabled.
if (GetConVarBool(g_hCvarsList[CVAR_LOG_PRINT_ADMINS]))
{
// Print text to admins.
TranslationPrintToChatAll(false, true, "Literal text", logbuffer);
}
// Check if printing log events to public chat is enabled.
if (GetConVarBool(g_hCvarsList[CVAR_LOG_PRINT_CHAT]))
{
@ -372,16 +372,16 @@ LogEvent(bool:isConsole = false, LogTypes:logType = LogType_Normal, eventType =
bool:LogModuleFilterAdd(LogModules:module)
{
decl String:modulename[64];
// Check if empty.
if (strlen(modulename) == 0)
{
return false;
}
// Convert module name.
LogGetModuleNameString(modulename, sizeof(modulename), module, true);
// Check if the module isn't already is listed.
if (FindStringInArray(hLogModuleFilter, modulename) < 0)
{
@ -389,7 +389,7 @@ bool:LogModuleFilterAdd(LogModules:module)
PushArrayString(hLogModuleFilter, modulename);
return true;
}
return false;
}
@ -404,19 +404,19 @@ bool:LogModuleFilterRemove(LogModules:module)
{
decl String:modulename[64];
new moduleindex;
// Check if empty.
if (strlen(modulename) == 0)
{
return false;
}
// Convert module name.
LogGetModuleNameString(modulename, sizeof(modulename), module, true);
// Get the module index.
moduleindex = FindStringInArray(hLogModuleFilter, modulename);
// Check if successful.
if (moduleindex >= 0)
{
@ -424,7 +424,7 @@ bool:LogModuleFilterRemove(LogModules:module)
RemoveFromArray(hLogModuleFilter, moduleindex);
return true;
}
return false;
}
@ -437,24 +437,24 @@ LogModuleFilterCacheUpdate()
new LogModules:moduletype;
new modulecount;
new filtersize;
// Clear all entries in module cache.
modulecount = sizeof(LogModuleFilterCache);
for (new module = 1; module < modulecount; module++)
{
LogModuleFilterCache[LogModules:module] = false;
}
// Loop through the module array.
filtersize = GetArraySize(hLogModuleFilter);
for (new index = 0; index < filtersize; index++)
{
// Get the module name.
GetArrayString(hLogModuleFilter, index, modulename, sizeof(modulename));
// Convert to type.
moduletype = LogGetModule(modulename);
// Validate type.
if (moduletype != LogModule_Invalid)
{
@ -486,62 +486,62 @@ public Action:Command_LogList(client, argc)
decl String:linebuffer[96];
decl String:modulename[64];
decl String:modulenameshort[64];
new modulecount;
// Strings to store translated phrases. Because formatting width settings
// doesn't work with "%t", but "%s".
decl String:phrasegenericflag[32];
decl String:phrasevalue[32];
decl String:phrasemodule[32];
decl String:phraseshortname[32];
// Quick initialize string buffer.
buffer[0] = 0;
// Set language.
SetGlobalTransTarget(client);
// Get phrases.
Format(phrasegenericflag, sizeof(phrasegenericflag), "%t", "Log Generic Flag");
Format(phrasevalue, sizeof(phrasevalue), "%t", "Log Value");
Format(phrasemodule, sizeof(phrasemodule), "%t", "Log Module");
Format(phraseshortname, sizeof(phraseshortname), "%t", "Log Module Short Name");
// Log flags:
Format(linebuffer, sizeof(linebuffer), "%-19s %-7s %t\n", phrasegenericflag, phrasevalue, "Log Status");
StrCat(buffer, sizeof(buffer), linebuffer);
StrCat(buffer, sizeof(buffer), "--------------------------------------------------------------------------------\n");
Format(linebuffer, sizeof(linebuffer), "LOG_CORE_EVENTS 1 %t\n", LogCheckFlag(LOG_CORE_EVENTS) ? "On" : "Off");
StrCat(buffer, sizeof(buffer), linebuffer);
Format(linebuffer, sizeof(linebuffer), "LOG_GAME_EVENTS 2 %t\n", LogCheckFlag(LOG_GAME_EVENTS) ? "On" : "Off");
StrCat(buffer, sizeof(buffer), linebuffer);
Format(linebuffer, sizeof(linebuffer), "LOG_PLAYER_COMMANDS 4 %t\n", LogCheckFlag(LOG_PLAYER_COMMANDS) ? "On" : "Off");
StrCat(buffer, sizeof(buffer), linebuffer);
Format(linebuffer, sizeof(linebuffer), "LOG_DEBUG 8 %t\n", LogCheckFlag(LOG_DEBUG) ? "On" : "Off");
StrCat(buffer, sizeof(buffer), linebuffer);
Format(linebuffer, sizeof(linebuffer), "LOG_DEBUG_DETAIL 16 %t\n", LogCheckFlag(LOG_DEBUG_DETAIL) ? "On" : "Off");
StrCat(buffer, sizeof(buffer), linebuffer);
ReplyToCommand(client, buffer);
buffer[0] = 0;
// Module filtering status:
Format(linebuffer, sizeof(linebuffer), "%t %t\n\n", "Log Module Filtering", GetConVarBool(g_hCvarsList[CVAR_LOG_MODULE_FILTER]) ? "On" : "Off");
StrCat(buffer, sizeof(buffer), linebuffer);
Format(linebuffer, sizeof(linebuffer), "%-23s %-19s %t\n", phrasemodule, phraseshortname, "Log Status");
StrCat(buffer, sizeof(buffer), linebuffer);
StrCat(buffer, sizeof(buffer), "--------------------------------------------------------------------------------");
ReplyToCommand(client, buffer);
buffer[0] = 0;
// Module status:
modulecount = sizeof(LogModuleFilterCache);
for (new module = 1; module < modulecount; module++)
@ -551,7 +551,7 @@ public Action:Command_LogList(client, argc)
Format(linebuffer, sizeof(linebuffer), "%-23s %-19s %t", modulename, modulenameshort, LogModuleFilterCache[LogModules:module] ? "On" : "Off");
ReplyToCommand(client, linebuffer);
}
return Plugin_Handled;
}
@ -566,16 +566,16 @@ public Action:Command_LogAddModule(client, argc)
decl String:buffer[256];
decl String:argument[32];
buffer[0] = 0;
// Check if privileged.
if (!ZRIsClientPrivileged(client, OperationType_Configuration))
{
TranslationReplyToCommand(client, "No access to command");
return Plugin_Handled;
}
new LogModules:logmodule;
// Check if no arguments.
if (argc < 1)
{
@ -584,32 +584,32 @@ public Action:Command_LogAddModule(client, argc)
StrCat(buffer, sizeof(buffer), "See zr_log_list to list available module names (short names).");
ReplyToCommand(client, buffer);
}
// Loop through each argument.
for (new arg = 1; arg <= argc; arg++)
{
// Get argument string.
GetCmdArg(arg, argument, sizeof(argument));
// Convert to module type.
logmodule = LogGetModule(argument);
// Check if invalid.
if (logmodule == LogModule_Invalid)
{
ReplyToCommand(client, "Invalid module name: \"%s\"", argument);
// Skip to next argument.
continue;
}
LogModuleFilterAdd(logmodule);
ReplyToCommand(client, "Added \"%s\" to module filter.", argument);
}
// Update cache.
LogModuleFilterCacheUpdate();
return Plugin_Handled;
}
@ -624,16 +624,16 @@ public Action:Command_LogRemoveModule(client, argc)
decl String:buffer[256];
decl String:argument[32];
buffer[0] = 0;
// Check if privileged.
if (!ZRIsClientPrivileged(client, OperationType_Configuration))
{
TranslationReplyToCommand(client, "No access to command");
return Plugin_Handled;
}
new LogModules:logmodule;
// Check if no arguments.
if (argc < 1)
{
@ -642,31 +642,31 @@ public Action:Command_LogRemoveModule(client, argc)
StrCat(buffer, sizeof(buffer), "See zr_log_list to list available module names (short names).");
ReplyToCommand(client, buffer);
}
// Loop through each argument.
for (new arg = 1; arg <= argc; arg++)
{
// Get argument string.
GetCmdArg(arg, argument, sizeof(argument));
// Convert to module type.
logmodule = LogGetModule(argument);
// Check if invalid.
if (logmodule == LogModule_Invalid)
{
ReplyToCommand(client, "Invalid module name: \"%s\"", argument);
// Skip to next argument.
continue;
}
LogModuleFilterRemove(logmodule);
ReplyToCommand(client, "Removed \"%s\" from module filter.", argument);
}
// Update cache.
LogModuleFilterCacheUpdate();
return Plugin_Handled;
}

View File

@ -50,7 +50,7 @@ MenuOnCommandsCreate()
/**
* Command callback (zmenu)
* Opens ZR's main menu.
*
*
* @param client The client index.
* @param argc Argument count.
*/
@ -62,26 +62,26 @@ public Action:ZMenuCommand(client, argc)
TranslationPrintToServer("Must be player");
return Plugin_Handled;
}
// Send main menu.
ZMenuMain(client);
// This stops the "Unknown command" message in client's console.
return Plugin_Handled;
}
/**
* Show main menu to client.
*
*
* @param client The client index.
*/
ZMenuMain(client)
{
// Create menu handle.
new Handle:menu_main = CreateMenu(ZMenuMainHandle);
SetGlobalTransTarget(client);
// Initialize menu lines.
decl String:title[MENU_LINE_TITLE_LENGTH];
decl String:zadmin[MENU_LINE_HUGE_LENGTH];
@ -91,7 +91,7 @@ ZMenuMain(client)
decl String:ztele[MENU_LINE_HUGE_LENGTH];
decl String:zhp[MENU_LINE_HUGE_LENGTH];
decl String:zmarket[MENU_LINE_HUGE_LENGTH];
// Translate each line into client's language.
Format(title, sizeof(title), "%t\n ", "Menu main title", SAYHOOKS_CHAT_PUBLIC_DEFAULT, SAYHOOKS_CHAT_SILENT_DEFAULT);
Format(zadmin, sizeof(zadmin), "%t", "Menu main zadmin");
@ -101,25 +101,25 @@ ZMenuMain(client)
Format(ztele, sizeof(ztele), "%t", "Menu main ztele");
Format(zhp, sizeof(zhp), "%t", "Menu main zhp");
Format(zmarket, sizeof(zmarket), "%t", "Menu main zmarket");
// Add items to menu.
SetMenuTitle(menu_main, title);
// Disable option if client isn't an admin.
new bool:admin = ZRIsClientAdmin(client);
AddMenuItem(menu_main, "zadmin", zadmin, MenuGetItemDraw(admin));
// Decide whether the client can use zclass.
new zclassdraw = ClassAllowSelection(client) ? ITEMDRAW_DEFAULT : ITEMDRAW_DISABLED;
AddMenuItem(menu_main, "zclass", zclass, zclassdraw);
AddMenuItem(menu_main, "zcookies", zcookies);
AddMenuItem(menu_main, "zspawn", zspawn);
AddMenuItem(menu_main, "ztele", ztele);
AddMenuItem(menu_main, "zhp", zhp);
AddMenuItem(menu_main, "zmarket", zmarket);
// Display menu to client.
DisplayMenu(menu_main, client, MENU_TIME_FOREVER);
}
@ -127,7 +127,7 @@ ZMenuMain(client)
/**
* Menu callback (main)
* Redirects client to selected option's handle code.
*
*
* @param menu The menu handle.
* @param action Action client is doing in menu.
* @param client The client index.
@ -140,7 +140,7 @@ public ZMenuMainHandle(Handle:menu, MenuAction:action, client, slot)
{
// Create variable to possible resend menu later.
new bool:resend = true;
switch(slot)
{
// Selected ZAdmin.
@ -154,7 +154,7 @@ public ZMenuMainHandle(Handle:menu, MenuAction:action, client, slot)
{
// Send ZClass menu
ClassMenuMain(client);
// Don't resend this menu.
resend = false;
}
@ -163,7 +163,7 @@ public ZMenuMainHandle(Handle:menu, MenuAction:action, client, slot)
{
// Send ZCookies menu
ZCookiesMenuMain(client);
// Don't resend this menu.
resend = false;
}
@ -192,7 +192,7 @@ public ZMenuMainHandle(Handle:menu, MenuAction:action, client, slot)
resend = !ZMarketMenuMain(client);
}
}
// Resend is still true, then resend menu.
if (resend)
{
@ -208,34 +208,34 @@ public ZMenuMainHandle(Handle:menu, MenuAction:action, client, slot)
/**
* Shows a list of all clients to a client, different handlers can be used for this, as well as title.
*
*
* @param client The client index.
* @param handler The menu handler.
* @param team If true, only clients on a team will be displayed.
* @param alive If true, only clients that are alive will be displayed.
* @param dead If true, only clients that are dead will be displayed.
* @param any Title is a translations phrase.
* @param dead If true, only clients that are dead will be displayed.
* @param any Title is a translations phrase.
*/
stock MenuClientList(client, MenuHandler:handler, bool:team = false, bool:alive = false, bool:dead = false, any:...)
{
// Create menu handle.
new Handle:menu_clients = CreateMenu(handler);
// Set client as translation target.
SetGlobalTransTarget(client);
// Translate phrase.
decl String:translation[MENU_LINE_TITLE_LENGTH];
VFormat(translation, sizeof(translation), "%t", 6);
// Set menu title to the translated phrase.
SetMenuTitle(menu_clients, translation);
decl String:clientoption[MENU_LINE_REG_LENGTH];
decl String:clientuserid[8];
new count = 0;
// x = Client index.
for (new x = 1; x <= MaxClients; x++)
{
@ -244,61 +244,61 @@ stock MenuClientList(client, MenuHandler:handler, bool:team = false, bool:alive
{
continue;
}
// If client isn't on a team, then stop.
if (team && !ZRIsClientOnTeam(x))
{
continue;
}
// If client is dead, then stop.
if (alive && !IsPlayerAlive(x))
{
continue;
}
// If client is alive, then stop.
if (dead && IsPlayerAlive(x))
{
continue;
}
// Get client info.
GetClientName(x, clientoption, sizeof(clientoption));
IntToString(GetClientUserId(x), clientuserid, sizeof(clientuserid));
// Add option to menu.
AddMenuItem(menu_clients, clientuserid, clientoption);
// Increment count.
count++;
}
// If there are no clients, add an "(Empty)" line.
if (count == 0)
{
// Set translation language again, because SetMenuTitle above reset
// this for some reason.
SetGlobalTransTarget(client);
decl String:empty[64];
Format(empty, sizeof(empty), "%t", "Menu empty");
AddMenuItem(menu_clients, "empty", empty, ITEMDRAW_DISABLED);
}
// Create a "Back" button to the main admin menu.
SetMenuExitBackButton(menu_clients, true);
// Send menu.
DisplayMenu(menu_clients, client, MENU_TIME_FOREVER);
}
/**
* Gets the client index of the selected client in the menu.
*
*
* @param menu The menu handle.
* @param slot The menu slot that was selected.
* @param slot The menu slot that was selected.
* @return The client index, 0 if the selected client is no longer in the server.
*/
stock MenuGetClientIndex(Handle:menu, slot)
@ -306,14 +306,14 @@ stock MenuGetClientIndex(Handle:menu, slot)
// Get menu slot's information.
decl String:clientuserid[8];
GetMenuItem(menu, slot, clientuserid, sizeof(clientuserid));
// Return the targetted client through their userid which was set into the menu slot's info param.
return GetClientOfUserId(StringToInt(clientuserid));
}
/**
* Return itemdraw flag for SM menus.
*
*
* @param condition If this is true, item will be drawn normally.
*/
stock MenuGetItemDraw(bool:condition)

View File

@ -46,52 +46,52 @@ new ModelCount;
ModelsLoad()
{
new Handle:kvModels = INVALID_HANDLE;
// Register config file.
ConfigRegisterConfig(File_Models, Structure_List, CONFIG_FILE_ALIAS_MODELS);
// Get models file path.
decl String:modelPath[PLATFORM_MAX_PATH];
new bool:exists = ConfigGetCvarFilePath(CVAR_CONFIG_PATH_MODELS, modelPath);
// If file doesn't exist, then log and stop.
if (!exists)
{
// Log failure and stop plugin.
LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Models, "Config Validation", "Missing model list: \"%s\"", modelPath);
}
// Set the path to the config file.
ConfigSetConfigPath(File_Models, modelPath);
// Prepare key/value structure.
kvModels = CreateKeyValues(CONFIG_FILE_ALIAS_MODELS);
// Log what models file that is loaded.
LogEvent(false, LogType_Normal, LOG_CORE_EVENTS, LogModule_Models, "Config Validation", "Loading models from file \"%s\".", modelPath);
// Load model data file.
FileToKeyValues(kvModels, modelPath);
// Try to find the first model.
KvRewind(kvModels);
if (!KvGotoFirstSubKey(kvModels))
{
LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Models, "Config Validation", "Can't find any models in \"%s\"", modelPath);
}
decl String:buffer[256];
decl String:name[64];
decl String:path[PLATFORM_MAX_PATH];
decl String:team[64];
decl String:access[64];
decl String:group[64];
ModelCount = 0;
new failedCount;
new publicCount;
new downloadCount;
// Loop through all models and store attributes in ModelData array.
do
{
@ -99,28 +99,28 @@ ModelsLoad()
{
// Maximum number of models reached. Log a warning and exit the loop.
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Models, "Config Validation", "Warning: Maximum number of models reached (%d). Skipping other models.", MODELS_MAX + 1);
break;
}
KvGetString(kvModels, "name", name, sizeof(name));
strcopy(ModelData[ModelCount][Model_Name], 64, name);
KvGetString(kvModels, "path", path, sizeof(path));
strcopy(ModelData[ModelCount][Model_Path], 64, path);
KvGetString(kvModels, "team", team, sizeof(team));
ModelData[ModelCount][Model_Team] = ModelsStringToTeam(team);
KvGetString(kvModels, "access", access, sizeof(access));
ModelData[ModelCount][Model_Access] = ModelsStringToAccess(access);
KvGetString(kvModels, "group", group, sizeof(group));
strcopy(ModelData[ModelCount][Model_Group], 64, group);
// Validate model attributes.
// Build path and check if model file exist.
strcopy(buffer, sizeof(buffer), path);
StrCat(buffer, sizeof(buffer), name);
@ -131,7 +131,7 @@ ModelsLoad()
failedCount++;
continue;
}
// Validate team.
if (ModelData[ModelCount][Model_Team] == ModelTeam_Invalid)
{
@ -139,7 +139,7 @@ ModelsLoad()
failedCount++;
continue;
}
// Validate access.
if (ModelData[ModelCount][Model_Access] == ModelAccess_Invalid)
{
@ -155,7 +155,7 @@ ModelsLoad()
publicCount++;
}
}
// Validate group.
if (ModelData[ModelCount][Model_Access] == ModelAccess_Group &&
FindAdmGroup(group) == INVALID_GROUP_ID)
@ -164,24 +164,24 @@ ModelsLoad()
failedCount++;
continue;
}
// Open directory with model files.
new Handle:dir = OpenDirectory(path);
// Check if failed.
if (dir == INVALID_HANDLE)
{
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Models, "Config Validation", "Error opening directory: %s", dir);
continue;
}
// Reset file counter for the current model.
downloadCount = 0;
new FileType:type;
decl String:file[64];
decl String:fileShort[64];
// Search for model files with the specified name and add them to
// downloads table.
while (ReadDirEntry(dir, file, sizeof(file), type))
@ -191,28 +191,28 @@ ModelsLoad()
{
continue;
}
// Find break point index in the string to get model name.
// Add one to make space for null terminator.
new breakpoint = FindCharInString(file, '.') + 1;
strcopy(fileShort, breakpoint, file);
// If this file doesn't match model name, then skip it.
if (!StrEqual(name, fileShort, false))
{
continue;
}
// Format a full path string.
strcopy(buffer, sizeof(buffer), path);
Format(buffer, sizeof(buffer), "%s%s", buffer, file);
AddFileToDownloadsTable(buffer);
downloadCount++;
}
CloseHandle(dir);
// Check if no model files were found.
if (!downloadCount)
{
@ -223,21 +223,21 @@ ModelsLoad()
ModelCount++;
}
} while (KvGotoNextKey(kvModels));
CloseHandle(kvModels);
// Check if there are no public models.
if (!publicCount)
{
LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Models, "Config Validation", "Missing public model in \"%s\". There must be at least one public model.", modelPath);
}
// Precache models.
ModelsPrecache();
// Log model validation info.
LogEvent(false, LogType_Normal, LOG_CORE_EVENTS, LogModule_Models, "Config Validation", "Successful: %d | Unsuccessful: %d", ModelCount, failedCount);
// Set config data.
ConfigSetConfigLoaded(File_Models, true);
ConfigSetConfigReloadFunc(File_Models, GetFunctionByName(GetMyHandle(), "ModelsOnConfigReload"));
@ -274,7 +274,7 @@ ModelsPrecache()
* permissions in "group" or "admins" access mode.
* Use negative index to disable permission check
* (default).
* @param teamFilter Optional. Team filtering settings. Use
* @param teamFilter Optional. Team filtering settings. Use
* ModelTeam_Invalid to disable filter. Default is
* ModelTeam_Zombies.
* @param accessRequireFlags Optional. One or more required access flags.
@ -285,7 +285,7 @@ ModelsGetRandomModel(client = -1, ModelTeam:teamFilter = ModelTeam_Zombies, acce
{
decl modelIndexes[MODELS_MAX];
new listCount;
// Loop through all models.
for (new index = 0; index < ModelCount; index++)
{
@ -295,18 +295,18 @@ ModelsGetRandomModel(client = -1, ModelTeam:teamFilter = ModelTeam_Zombies, acce
{
continue;
}
// Cache current model access flag.
new ModelAccess:access = ModelsGetAccess(index);
new accessFlag = ModelsGetAccessFlag(access);
// Check access filtering. Skip if no match.
if (accessRequireFlags > 0 &&
!(accessRequireFlags & accessFlag))
{
continue;
}
// Do client group authentication if client is specified.
if (client > 0)
{
@ -315,7 +315,7 @@ ModelsGetRandomModel(client = -1, ModelTeam:teamFilter = ModelTeam_Zombies, acce
{
decl String:group[64];
ModelsGetGroup(index, group, sizeof(group));
if (!ZRIsClientInGroup(client, group))
{
// Client not authorized to use this model.
@ -334,12 +334,12 @@ ModelsGetRandomModel(client = -1, ModelTeam:teamFilter = ModelTeam_Zombies, acce
}
}
}
// Model passed filter tests. Add to list.
modelIndexes[listCount] = index;
listCount++;
}
// Check if any models passed the filter.
if (listCount)
{
@ -363,7 +363,7 @@ ModelsGetRandomModel(client = -1, ModelTeam:teamFilter = ModelTeam_Zombies, acce
bool:ModelsIsValidIndex(index, bool:rangeOnly = false)
{
new bool:rangeValid = (index >= 0 && index < MODELS_MAX);
if (rangeOnly)
{
// Only check if the index is valid.
@ -391,7 +391,7 @@ ModelsGetName(index, String:buffer[], maxlen)
{
return -1;
}
return strcopy(buffer, maxlen, ModelData[index][Model_Name]);
}
@ -410,7 +410,7 @@ ModelsGetPath(index, String:buffer[], maxlen)
{
return -1;
}
return strcopy(buffer, maxlen, ModelData[index][Model_Path]);
}
@ -427,7 +427,7 @@ ModelTeam:ModelsGetTeam(index)
{
return ModelTeam_Invalid;
}
return ModelData[index][Model_Team];
}
@ -445,7 +445,7 @@ ModelAccess:ModelsGetAccess(index)
{
return ModelAccess_Invalid;
}
return ModelData[index][Model_Access];
}
@ -480,7 +480,7 @@ ModelsGetAccessFlag(ModelAccess:access)
return MODEL_ACCESS_GROUP;
}
}
// Invalid access flag.
return 0;
}
@ -500,7 +500,7 @@ ModelsGetGroup(index, String:buffer[], maxlen)
{
return -1;
}
return strcopy(buffer, maxlen, ModelData[index][Model_Group]);
}
@ -516,12 +516,12 @@ ModelsGetFullPath(index, String:buffer[], maxlen)
{
decl String:path[PLATFORM_MAX_PATH];
decl String:name[64];
ModelsGetPath(index, path, sizeof(path));
ModelsGetName(index, name, sizeof(name));
buffer[0] = 0;
StrCat(buffer, maxlen, path);
StrCat(buffer, maxlen, name);
StrCat(buffer, maxlen, ".mdl");
@ -543,7 +543,7 @@ ModelTeam:ModelsStringToTeam(const String:team[])
{
return ModelTeam_Humans;
}
return ModelTeam_Invalid;
}
@ -566,7 +566,7 @@ ModelTeam:ModelsTeamIdToTeam(teamid)
return ModelTeam_Humans;
}
}
return ModelTeam_Invalid;
}
@ -598,6 +598,6 @@ ModelAccess:ModelsStringToAccess(const String:access[])
{
return ModelAccess_Group;
}
return ModelAccess_Invalid;
}

View File

@ -4,7 +4,7 @@
* Zombie:Reloaded
*
* File: napalm.inc
* Type: Module
* Type: Module
* Description: Grenades burn zombies when damaged by them.
*
* Copyright (C) 2009-2013 Greyscale, Richard Helgeby
@ -27,7 +27,7 @@
/**
* The fuse length of an hegrenade.
*/
*/
#define GRENADE_FUSE_TIME 3.0
/**
@ -62,7 +62,7 @@ NapalmOnOffsetsFound()
/**
* Hook: OnTakeDamage
* Forwarded from the damage module to check if we should extinguish any flames.
*
*
* @param client The client index.
* @param damagetype The type of damage inflicted.
* @return Return ZRTools_Handled to stop the damage to client.
@ -76,16 +76,16 @@ NapalmOnTakeDamage(client, damagetype)
{
// Only take action if it isn't disabled, or the option is valid.
new douse = GetConVarInt(g_hCvarsList[CVAR_NAPALM_DOUSE]);
if (douse > NAPALM_WLEVEL_DRY && douse <= NAPALM_WLEVEL_FULL)
{
// If the client water-level is equal or higher than the given, then we want to extinguish the flame.
if (NapalmGetClientWaterLevel(client) >= douse)
{
// Put the fire out.
//ExtinguishEntity(client); <-- Don't use this. Takes off the FL_ONFIRE flag, but flame doesn't get extinguished.
// This works.
new fire = GetEntPropEnt(client, Prop_Data, "m_hEffectEntity");
if (IsValidEntity(fire))
@ -103,22 +103,22 @@ NapalmOnTakeDamage(client, damagetype)
LogEvent(false, LogType_Normal, LOG_GAME_EVENTS, LogModule_Napalm, "Napalm Douse", "Found unexpected entity in prop \"m_flLifetime\": \"%s\"", classname);
}
}
return _:ACTION_CONTINUE;
}
}
}
// Let the damage module continue as usual.
return -1;
}
/**
* Client has been hurt.
*
*
* @param client The client index.
* @param attacker The attacker index.
* @param weapon The weapon name.
* @param weapon The weapon name.
*/
NapalmOnClientHurt(client, attacker, const String:weapon[])
{
@ -127,37 +127,37 @@ NapalmOnClientHurt(client, attacker, const String:weapon[])
{
return;
}
// If player isn't a zombie, then stop.
if (!InfectIsClientInfected(client))
{
return;
}
// If napalm time is invalid or 0, then stop.
new Float:napalm_time = ClassGetNapalmTime(client);
if (napalm_time <= 0.0)
{
return;
}
// If the attacker can't throw napalm grenades, then stop.
if (!ClassGetHasNapalm(attacker))
{
return;
}
// If weapon is a grenade, then ignite player.
if (StrEqual(weapon, "hegrenade", false))
{
new bool:reset = GetConVarBool(g_hCvarsList[CVAR_NAPALM_TIME_RESET]);
new flags = GetEntityFlags(client);
if (reset || !(flags & FL_ONFIRE))
{
// This stops the fire before re-ignition.
ExtinguishEntity(client);
// Ignite client.
IgniteEntity(client, napalm_time);
}
@ -166,7 +166,7 @@ NapalmOnClientHurt(client, attacker, const String:weapon[])
/**
* Client has been killed.
*
*
* @param client The client index.
*/
NapalmOnClientDeath(client)
@ -189,35 +189,35 @@ NapalmOnWeaponFire(client, const String:weapon[])
{
return;
}
// If human class can't throw napalm grenades, then stop.
if (!ClassGetHasNapalm(client))
{
return;
}
// If weapon isn't a grenade, then stop.
if (!StrEqual(weapon, "hegrenade", false))
{
return;
}
// Wait .1 seconds.
CreateTimer(0.1, NapalmIgniteGrenade);
}
/**
* Timer callback, ignite's all hegrenade projectiles.
*
*
* @param timer The timer handle.
*/
*/
public Action:NapalmIgniteGrenade(Handle:timer)
{
decl String:classname[64];
// Get max entities.
new maxentities = GetMaxEntities();
// x = entity index.
for (new x = 0; x <= maxentities; x++)
{
@ -226,7 +226,7 @@ public Action:NapalmIgniteGrenade(Handle:timer)
{
continue;
}
GetEdictClassname(x, classname, sizeof(classname));
if(StrEqual(classname, "hegrenade_projectile"))
{
@ -237,9 +237,9 @@ public Action:NapalmIgniteGrenade(Handle:timer)
/**
* Checks the current water-level on a client.
*
*
* @param client The client index.
* @return A NAPALM_WLEVEL_ define.
* @return A NAPALM_WLEVEL_ define.
*/
stock NapalmGetClientWaterLevel(client)
{

View File

@ -42,7 +42,7 @@ enum OverlaysChannel
/**
* Global variable to store a convar query cookie
*/
*/
new QueryCookie:mat_dxlevel;
/**
@ -76,8 +76,8 @@ OverlaysOnMapStart()
/**
* Client is joining the server.
*
* @param client The client index.
*
* @param client The client index.
*/
OverlaysClientInit(client)
{
@ -87,15 +87,15 @@ OverlaysClientInit(client)
// Disable all channels, and reset.
OverlaysClientSetChannelState(client, OverlaysChannel:x, false, false, false, true);
}
// Get client's DX level.
OverlaysGetClientDXLevel(client);
}
/**
* Finds DX level of a client.
*
* @param client The client index.
*
* @param client The client index.
*/
OverlaysGetClientDXLevel(client)
{
@ -104,7 +104,7 @@ OverlaysGetClientDXLevel(client)
{
return;
}
// Query mat_dxlevel on client.
mat_dxlevel = QueryClientConVar(client, "mat_dxlevel", OverlaysQueryClientDXLevel);
}
@ -117,7 +117,7 @@ OverlaysGetClientDXLevel(client)
* @param result The result of the query (see console.inc enum ConVarQueryResult)
* @param cvarName Name of the cvar.
* @param cvarValue Value of the cvar.
*/
*/
public OverlaysQueryClientDXLevel(QueryCookie:cookie, client, ConVarQueryResult:result, const String:cvarName[], const String:cvarValue[])
{
// If query cookie does not match cookie given by mat_dxlevel query, then stop, this isn't our query.
@ -125,16 +125,16 @@ public OverlaysQueryClientDXLevel(QueryCookie:cookie, client, ConVarQueryResult:
{
return;
}
// Reset dxLevel.
g_iOverlaysDXL[client] = 0;
// If result is any other than ConVarQuery_Okay, then stop.
if (result != ConVarQuery_Okay)
{
{
return;
}
// Copy cvar value to dxLevel array.
g_iOverlaysDXL[client] = StringToInt(cvarValue);
}
@ -149,21 +149,21 @@ OverlaysOnRoundStart()
{
KillTimer(tOverlays);
}
// If antistick is disabled, then stop.
new Float:overlaysupdate = GetConVarFloat(g_hCvarsList[CVAR_OVERLAYS_UPDATE_TIME]);
if (overlaysupdate <= 0.0)
{
return;
}
// Start repeating timer.
tOverlays = CreateTimer(overlaysupdate, OverlaysTimer, _, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
}
/**
* Update overlay on a client. (Displays highest priority overlays first, if enabled.)
*
*
* @param client The client index.
* @param channel (Optional) The channel overlay to update.
*/
@ -174,7 +174,7 @@ OverlaysClientUpdateOverlay(client, OverlaysChannel:channel = OVERLAYS_CHANNEL_N
{
channel = OverlaysClientFindChannel(client);
}
// Stop here if client has no overlay channel enabled.
if (channel == OVERLAYS_CHANNEL_NONE)
{
@ -182,13 +182,13 @@ OverlaysClientUpdateOverlay(client, OverlaysChannel:channel = OVERLAYS_CHANNEL_N
ClientCommand(client, "r_screenoverlay \"\"");
return;
}
// If channel we are updating is disabled, then stop.
if (!g_bOverlayChannel[client][channel])
{
return;
}
// If dxLevel is 0, then query on client failed, so try again, then stop.
if (!g_iOverlaysDXL[client])
{
@ -196,7 +196,7 @@ OverlaysClientUpdateOverlay(client, OverlaysChannel:channel = OVERLAYS_CHANNEL_N
OverlaysGetClientDXLevel(client);
return;
}
// If client doesn't meet DXLevel requirement, then tell client and stop.
new minDxLevel = GetConVarInt(g_hCvarsList[CVAR_OVERLAYS_MIN_DXLEVEL]);
if (g_iOverlaysDXL[client] < minDxLevel)
@ -204,7 +204,7 @@ OverlaysClientUpdateOverlay(client, OverlaysChannel:channel = OVERLAYS_CHANNEL_N
TranslationPrintCenterText(client, "Overlays not supported", g_iOverlaysDXL[client], minDxLevel);
return;
}
// Display overlay to client.
ClientCommand(client, "r_screenoverlay \"%s\"", g_strOverlayPath[client][channel]);
}
@ -216,51 +216,51 @@ OverlaysChannel:OverlaysClientFindChannel(client)
{
// Convert to OverlaysChannel datatype.
new OverlaysChannel:channel = OverlaysChannel:x;
if (OverlaysClientGetChannelState(client, channel))
{
// Return channel.
return channel;
}
}
return OVERLAYS_CHANNEL_NONE;
}
/**
* Toggle or set new value to a channel state of a client.
*
*
* @param client The client index.
* @param channel The channel to change state of.
* @param update (Optional) Update the overlay when this function is called.
* @param update (Optional) Update the overlay when this function is called.
* @param toggle (Optional) Set to true to toggle state, false to use value param.
* @param value (Optional) New value of the state, only used if toggle is false.
* @param reset (Optional) Resets the channel path.
* @return The overlay's new state.
* @return The overlay's new state.
*/
bool:OverlaysClientSetChannelState(client, OverlaysChannel:channel, bool:update = false, bool:toggle = true, bool:value = false, bool:reset = false)
{
// Toggle or set new state to channel of a client.
g_bOverlayChannel[client][channel] = toggle ? !g_bOverlayChannel[client][channel] : value;
if (update)
{
// Update client overlay.
OverlaysClientUpdateOverlay(client);
}
if (reset)
{
OverlaysClientSetChannelPath(client, channel, "");
}
// Return new value.
return g_bOverlayChannel[client][channel];
}
/**
* Get current value of a channel state of a client.
*
*
* @param client The client index.
* @param channel The channel to get state of.
*/
@ -272,7 +272,7 @@ bool:OverlaysClientGetChannelState(client, OverlaysChannel:channel)
/**
* Set overlay path for a channel.
*
*
* @param client The client index.
* @param channel The channel to set path on.
* @param path Path to overlay.
@ -285,7 +285,7 @@ OverlaysClientSetChannelPath(client, OverlaysChannel:channel, const String:path[
/**
* Timer callback, updates overlay on each client.
*
*
* @param timer The timer handle.
*/
public Action:OverlaysTimer(Handle:timer)
@ -298,13 +298,13 @@ public Action:OverlaysTimer(Handle:timer)
{
continue;
}
// If no overlay is on the client's screen, then stop.
if (OverlaysClientFindChannel(x) == OVERLAYS_CHANNEL_NONE)
{
continue;
}
// Update client's overlay.
OverlaysClientUpdateOverlay(x);
}

View File

@ -4,7 +4,7 @@
* Zombie:Reloaded
*
* File: paramparser.inc
* Type: Core
* Type: Core
* Description: Provides functions for parsing single line strings with
* flags, and parameters in key=value format.
*
@ -104,10 +104,10 @@ stock ParamParseString(buffer[][ParamParseResult], maxlen, String:paramString[],
/*
* VALIDATION OF INPUT AND BUFFERS
*/
// Trim raw string.
TrimString(paramString);
// Check if raw string is empty.
if (strlen(paramString) == 0)
{
@ -115,7 +115,7 @@ stock ParamParseString(buffer[][ParamParseResult], maxlen, String:paramString[],
errPos = 0;
return 0;
}
// Validate specified length of destination buffer.
if (maxlen == 0)
{
@ -123,27 +123,27 @@ stock ParamParseString(buffer[][ParamParseResult], maxlen, String:paramString[],
errPos = 0;
return 0;
}
/*
* PARSE LOOP
*/
// Get raw string length.
new rawlen = sizeof(paramString);
// Initialize. Expect the start to be a key or a flag.
new ParamModes:mode = ParamMode_TypeCheck;
// Counter for number of parameters parsed.
new paramcount;
// Buffers for temp values.
new startpos;
new endpos;
new bool:quoteon;
decl String:value[PARAM_VALUE_MAXLEN];
// Loop through all characters in the string. Exclude null terminator.
for (new strpos = 0; strpos < rawlen - 1; strpos++)
{
@ -155,12 +155,12 @@ stock ParamParseString(buffer[][ParamParseResult], maxlen, String:paramString[],
errPos = strpos;
break;
}
/*
* MODE CHECK
*/
// Check mode for deciding what to do.
switch (mode)
{
@ -168,13 +168,13 @@ stock ParamParseString(buffer[][ParamParseResult], maxlen, String:paramString[],
{
// Find start position of first non white space character.
startpos = ParamFindStartPos(paramString, strpos);
// Check if it's a flag type.
if (paramString[startpos] == '-')
{
// It's a flag, change mode.
mode = ParamMode_Flag;
// Update current position.
strpos = startpos;
}
@ -182,7 +182,7 @@ stock ParamParseString(buffer[][ParamParseResult], maxlen, String:paramString[],
{
// Expect a key name.
mode = ParamMode_Key;
// Update current position. Substract by one to include
// the current character in next mode.
strpos = startpos - 1;
@ -192,19 +192,19 @@ stock ParamParseString(buffer[][ParamParseResult], maxlen, String:paramString[],
{
// Find stop position (last non white space character).
endpos = ParamFindEndPos(paramString, strpos);
// Extract key name.
StrExtract(value, sizeof(value), paramString, strpos, endpos);
// Copy flag to destination buffer.
strcopy(buffer[paramcount][Param_Name], PARAM_NAME_MAXLEN, value);
// Set flag type.
buffer[paramcount][Param_IsFlag] = true;
// Increment parameter counter.
paramcount++;
// Set next parse mode.
mode = ParamMode_TypeCheck;
}
@ -212,19 +212,19 @@ stock ParamParseString(buffer[][ParamParseResult], maxlen, String:paramString[],
{
// Find stop position.
endpos = ParamFindEndPos(paramString, strpos);
// Extract key name.
StrExtract(value, sizeof(value), paramString, strpos, endpos);
// Copy key name to destination buffer.
strcopy(buffer[paramcount][Param_Name], PARAM_NAME_MAXLEN, value);
// Make sure flag type is not set.
buffer[paramcount][Param_IsFlag] = false;
// Note: Do not increment parameter counter until the
// entire key/value pair is parsed.
// Set next parse mode. Expect a equation sign.
mode = ParamMode_Equal;
}
@ -232,7 +232,7 @@ stock ParamParseString(buffer[][ParamParseResult], maxlen, String:paramString[],
{
// Find start position of first non white space character.
startpos = ParamFindStartPos(paramString, strpos);
// Validate position.
if (startpos >= 0)
{
@ -241,7 +241,7 @@ stock ParamParseString(buffer[][ParamParseResult], maxlen, String:paramString[],
{
// Change mode to expect a value at next position.
mode = ParamMode_Value;
// Update current position.
strpos = startpos;
}
@ -265,13 +265,13 @@ stock ParamParseString(buffer[][ParamParseResult], maxlen, String:paramString[],
{
// Find start position of first non white space character.
startpos = ParamFindStartPos(paramString, strpos);
// Validate start position.
if (startpos >= 0)
{
// Reset quote and escape settings.
quoteon = false;
// Loop through all characters starting from the current
// position. Exclude null terminator.
for (strpos = startpos; strpos < rawlen - 1; strpos++)
@ -284,7 +284,7 @@ stock ParamParseString(buffer[][ParamParseResult], maxlen, String:paramString[],
{
quoteon = !quoteon;
}
// Check quote state.
if (quoteon)
{
@ -297,18 +297,18 @@ stock ParamParseString(buffer[][ParamParseResult], maxlen, String:paramString[],
endpos = strpos - 1;
}
}
// Check if it's a white space character or end of the string.
else if (!quoteon && (IsCharSpace(paramString[strpos]) || strpos == rawlen - 1))
{
// End of value reached. Save positions.
endpos = strpos - 1;
// Exit loop.
break;
}
}
// Check if quote still haven't ended.
if (quoteon)
{
@ -317,22 +317,22 @@ stock ParamParseString(buffer[][ParamParseResult], maxlen, String:paramString[],
errPos = strpos;
break;
}
// Extract value string.
StrExtract(value, sizeof(value), paramString, startpos, endpos);
// Unescape string (converting "\n" to newline, etc.).
StrUnescape(value);
// Copy value string to destination buffer.
strcopy(buffer[paramcount][Param_Value], PARAM_VALUE_MAXLEN, value);
// Make sure flag type is not set.
buffer[paramcount][Param_IsFlag] = false;
// Increment parameter counter.
paramcount++;
// Set next parse mode. Expect a key or a flag.
mode = ParamMode_TypeCheck;
}
@ -346,7 +346,7 @@ stock ParamParseString(buffer[][ParamParseResult], maxlen, String:paramString[],
}
}
}
// Return number of parameters parsed.
return paramcount;
}
@ -372,7 +372,7 @@ stock ParamFindKey(const params[][ParamParseResult], maxlen, const String:key[],
// It's a flag type, skip index.
continue;
}
// Match key name.
if (StrEqual(params[index][Param_Name], key, caseSensitive))
{
@ -380,7 +380,7 @@ stock ParamFindKey(const params[][ParamParseResult], maxlen, const String:key[],
return index;
}
}
return -1;
}
@ -405,7 +405,7 @@ stock bool:ParamHasFlag(const params[][ParamParseResult], maxlen, const String:f
// It's a key type, skip index.
continue;
}
// Match flag name.
if (StrEqual(params[index][Param_Name], flag, caseSensitive))
{
@ -413,7 +413,7 @@ stock bool:ParamHasFlag(const params[][ParamParseResult], maxlen, const String:f
return true;
}
}
return false;
}
@ -436,13 +436,13 @@ stock bool:ParamHasFlag(const params[][ParamParseResult], maxlen, const String:f
stock ParamFindEndPos(const String:paramString[], startPos = 0)
{
new rawlen = sizeof(paramString);
// Validate string length.
if (rawlen == 0)
{
return -1;
}
// Loop through all characters from the specified start position.
for (new strpos = startPos; strpos < rawlen; strpos++)
{
@ -453,7 +453,7 @@ stock ParamFindEndPos(const String:paramString[], startPos = 0)
return strpos - 1;
}
}
// It should never reach this place. Added to satisfy compiler.
return -1;
}
@ -469,13 +469,13 @@ stock ParamFindEndPos(const String:paramString[], startPos = 0)
stock ParamFindStartPos(const String:paramString[], startPos = 0)
{
new rawlen = sizeof(paramString);
// Validate string length.
if (rawlen == 0)
{
return -1;
}
// Loop through all characters from the specified start position.
for (new strpos = startPos; strpos < rawlen; strpos++)
{
@ -485,7 +485,7 @@ stock ParamFindStartPos(const String:paramString[], startPos = 0)
return strpos;
}
}
// No character found.
return -1;
}
@ -503,16 +503,16 @@ stock ParamFindStartPos(const String:paramString[], startPos = 0)
stock StrExtract(String:buffer[], maxlen, const String:source[], startpos, endpos)
{
new len;
// Calculate string length. Also add space for null terminator.
len = endpos - startpos + 1;
// Validate length.
if (len < 0)
{
return 0;
}
// Extract string and store it in the buffer.
return strcopy(buffer, len, source[startpos]);
}
@ -525,7 +525,7 @@ stock StrExtract(String:buffer[], maxlen, const String:source[], startpos, endpo
stock StrUnescape(String:str[])
{
new len = sizeof(str);
ReplaceString(str, len, "\\n", "\n");
ReplaceString(str, len, "\\r", "\r");
ReplaceString(str, len, "\\t", "\t");

View File

@ -4,7 +4,7 @@
* Zombie:Reloaded
*
* File: paramtools.inc
* Type: Core
* Type: Core
* Description: Provides functions for parsing strings with parameters in
* key=value format.
*
@ -38,28 +38,28 @@ stock GetParameterCount(const String:rawString[])
new paramCount;
new searchPos;
new splitPos;
// Check if the raw string is empty.
if (lenRawString == 0)
{
return 0;
}
// Count number of "=".
for (splitPos = 0; splitPos < lenRawString; splitPos++)
{
// Find next "=".
searchPos = StrContains(rawString[splitPos], "=", false);
// Note: searchPos is an offset from rawString[splitPos]. If searchPos
// is 0, then the real position is splitPos.
// Check if "=" was found.
if (searchPos >= 0)
{
// Parameter found.
paramCount++;
// Update split position.
splitPos += searchPos;
}
@ -69,7 +69,7 @@ stock GetParameterCount(const String:rawString[])
break;
}
}
return paramCount;
}
@ -97,39 +97,39 @@ stock GetParameterValue(String:buffer[], maxlen, const String:rawString[], const
new valueLen;
new nextPos;
new splitPos;
// Get the position of parameter.
paramPos = StrContains(rawString, parameter, false);
splitPos = paramPos;
// Check if found.
if (paramPos >= 0)
{
// Get parameter length.
paramLen = strlen(parameter);
// Get the position of the next parameter by finding the next space.
nextPos = StrContains(rawString[splitPos], " ");
// Check if the next parameter was found.
if (nextPos >= 0)
{
// Calculate value starting position.
valuePos = paramPos + paramLen + 1;
// Calculate value length. Note: Adding 1 for space to the null
// terminator.
valueLen = nextPos + splitPos - valuePos + 1;
// Check if value length is longer than buffer size.
if (valueLen > maxlen)
{
valueLen = maxlen;
}
// Copy value to buffer.
return strcopy(buffer, valueLen, rawString[valuePos]);
}
else
{
@ -159,13 +159,13 @@ stock GetParameterName(String:buffer[], maxlen, const String:rawString[], parame
new valuePos;
new nextValuePos;
new splitPos;
// Check if the raw string is empty.
if (strlen(rawString) == 0)
{
return -1;
}
if (parameterIndex > 0)
{
// Get the value starting position for the previous index.
@ -174,18 +174,18 @@ stock GetParameterName(String:buffer[], maxlen, const String:rawString[], parame
valuePos = StrContains(rawString[splitPos], "=");
splitPos += valuePos;
}
// Find the next space from splitPos where the specified parameter
// starts.
paramPos = StrContains(rawString[splitPos], " ") + splitPos + 1;
// Update split position.
splitPos += paramPos;
// Find the next value position from splitPos to get the end position
// of the parameter name.
nextValuePos = StrContains(rawString[splitPos], "=") + splitPos;
// Check if a value is specified.
if (nextValuePos > 0)
{
@ -202,7 +202,7 @@ stock GetParameterName(String:buffer[], maxlen, const String:rawString[], parame
{
// It's the first parameter. Read the string until '=' is found.
valuePos = StrContains(rawString, "=");
// Check if a value is specified.
if (valuePos > 0)
{

View File

@ -43,19 +43,19 @@ new Float:g_flClassApplySpeed[MAXPLAYERS + 1];
bool:ClassApplyAttributes(client, bool:improved = false)
{
new classindex = ClassGetActiveIndex(client);
// Validate class index.
if (!ClassValidateIndex(classindex))
{
return false;
}
// Override improved settings if it's a mother zombie class.
if (ClassHasFlags(classindex, ZR_CLASS_FLAG_MOTHER_ZOMBIE))
{
improved = false;
}
ClassApplyModel(client, classindex);
ClassApplyAlpha(client, classindex);
ClassApplyOverlay(client, classindex);
@ -64,7 +64,7 @@ bool:ClassApplyAttributes(client, bool:improved = false)
ClassApplyHealth(client, classindex, improved);
ClassApplyHealthRegen(client, classindex);
ClassApplySpeed(client, classindex);
return true;
}
@ -89,7 +89,7 @@ bool:ClassApplyModel(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER)
new access;
new model;
new skinIndex = 0;
// Get correct index according to cache type.
if (cachetype == ZR_CLASS_CACHE_PLAYER)
{
@ -99,26 +99,26 @@ bool:ClassApplyModel(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER)
{
index = classindex;
}
// Get the model path from the specified cache.
ClassGetModelPath(index, modelpath, sizeof(modelpath), cachetype);
// Get model skin index.
skinIndex = ClassGetModelSkinIndex(index, cachetype);
// Get model team setting from the specified cache.
team = ModelsTeamIdToTeam(ClassGetTeamID(index, cachetype));
// Check if the user specified a pre-defined model setting. If so, setup
// model filter settings.
if (StrEqual(modelpath, "random", false))
{
// Set access filter flags.
access = MODEL_ACCESS_PUBLIC | MODEL_ACCESS_ADMINS;
// Specify client for including admin models if client is admin.
index = client;
isAttributePreset = true;
}
else if (StrEqual(modelpath, "random_public", false))
@ -149,7 +149,7 @@ bool:ClassApplyModel(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER)
{
// Get current model.
GetClientModel(client, modelpath, sizeof(modelpath));
// Restore original model if not already set.
if (!StrEqual(ClassOriginalPlayerModel[client], modelpath))
{
@ -166,13 +166,13 @@ bool:ClassApplyModel(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER)
// Do nothing.
return true;
}
// Check if model setting is a attribute preset.
if (isAttributePreset)
{
// Get model based on filter settings set up earlier.
model = ModelsGetRandomModel(index, team, access);
// Check if found.
if (model >= 0)
{
@ -187,10 +187,10 @@ bool:ClassApplyModel(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER)
ModelsGetFullPath(model, modelpath, sizeof(modelpath));
}
}
SetEntityModel(client, modelpath);
SetEntProp(client, Prop_Send, "m_nSkin", skinIndex);
return true;
}
@ -209,7 +209,7 @@ bool:ClassApplyModel(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER)
bool:ClassApplyAlpha(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER)
{
new alpha;
// Get the alpha value from the specified cache.
if (cachetype == ZR_CLASS_CACHE_PLAYER)
{
@ -219,12 +219,12 @@ bool:ClassApplyAlpha(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER)
{
alpha = ClassGetAlphaInitial(classindex, cachetype);
}
if (alpha < 0)
{
return false;
}
ToolsSetClientAlpha(client, alpha);
return true;
}
@ -244,7 +244,7 @@ bool:ClassApplyAlpha(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER)
bool:ClassApplyOverlay(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER)
{
decl String:overlaypath[PLATFORM_MAX_PATH];
// Get the overlay path from the specified cache.
if (cachetype == ZR_CLASS_CACHE_PLAYER)
{
@ -254,7 +254,7 @@ bool:ClassApplyOverlay(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER)
{
ClassGetOverlayPath(classindex, overlaypath, sizeof(overlaypath), cachetype);
}
ClassOverlayInitialize(client, overlaypath);
return true;
}
@ -274,7 +274,7 @@ bool:ClassApplyOverlay(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER)
bool:ClassApplyNightVision(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER)
{
new bool:nvgs;
// Get the night vision setting from the specified cache.
if (cachetype == ZR_CLASS_CACHE_PLAYER)
{
@ -284,10 +284,10 @@ bool:ClassApplyNightVision(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER
{
nvgs = ClassGetNvgs(classindex, cachetype);
}
ToolsSetClientNightVision(client, nvgs);
ToolsSetClientNightVision(client, nvgs, false);
return true;
}
@ -306,7 +306,7 @@ bool:ClassApplyNightVision(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER
bool:ClassApplyFOV(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER)
{
new fov;
// Get the field of view setting from the specified cache.
if (cachetype == ZR_CLASS_CACHE_PLAYER)
{
@ -316,7 +316,7 @@ bool:ClassApplyFOV(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER)
{
fov = ClassGetFOV(classindex, cachetype);
}
ToolsSetClientDefaultFOV(client, fov);
return true;
}
@ -337,7 +337,7 @@ bool:ClassApplyFOV(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER)
bool:ClassApplyHealth(client, classindex, bool:boost = false, cachetype = ZR_CLASS_CACHE_PLAYER)
{
new health;
// Get the health points from the specified cache.
if (cachetype == ZR_CLASS_CACHE_PLAYER)
{
@ -347,12 +347,12 @@ bool:ClassApplyHealth(client, classindex, bool:boost = false, cachetype = ZR_CLA
{
health = ClassGetHealth(classindex, cachetype);
}
if (boost)
{
health *= 2;
}
SetEntityHealth(client, health);
return true;
}
@ -375,7 +375,7 @@ bool:ClassApplyHealthRegen(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER
new Float:interval;
new amount;
new max;
// Get the health regeneration info from the specified cache.
if (cachetype == ZR_CLASS_CACHE_PLAYER)
{
@ -389,7 +389,7 @@ bool:ClassApplyHealthRegen(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER
amount = ClassGetHealthRegenAmount(classindex, cachetype);
max = ClassGetHealth(classindex, cachetype);
}
if (interval > 0)
{
ClassHealthRegenInitClient(client, interval, amount, max);
@ -418,7 +418,7 @@ bool:ClassApplyHealthRegen(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER
bool:ClassApplySpeed(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER)
{
new Float:speed;
// Get the health points from the specified cache.
if (cachetype == ZR_CLASS_CACHE_PLAYER)
{
@ -428,7 +428,7 @@ bool:ClassApplySpeed(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER)
{
speed = ClassGetSpeed(classindex, cachetype);
}
ClassApplySpeedEx(client, speed);
return true;
}
@ -458,7 +458,7 @@ ClassApplySpeedEx(client, Float:speed)
/**
* Called before the client can "think"
* Here we can change the client's speed through m_flMaxSpeed.
*
*
* @param client The client index.
*/
public ClassPreThinkPost(client)
@ -470,7 +470,7 @@ public ClassPreThinkPost(client)
{
return;
}
// Note: Default is around 200.0 - 250.0
new Float:newspeed = GetEntPropFloat(client, Prop_Data, "m_flMaxspeed") + g_flClassApplySpeed[client];
SetEntPropFloat(client, Prop_Data, "m_flMaxspeed", newspeed);
@ -487,21 +487,21 @@ Class_OnPlayerRunCmd(client, Float:vel[3])
{
if (!IsPlayerAlive(client))
return;
// Only modify speed if the prop method is used.
if (ClassSpeedMethod == ClassSpeed_Prop)
{
// x-axis speed.
if (vel[0] < 0.0)
vel[0] = -5000.0;
else if (vel[0] > 0.0)
vel[0] = 5000.0;
// y-axis speed.
if (vel[1] < 0.0)
vel[1] = -5000.0;
else if (vel[1] > 0.0)
vel[1] = 5000.0;
}

View File

@ -32,7 +32,7 @@
*
* ------------------------------------
*/
/**
* Checks if the specified class is enabled.
*
@ -230,7 +230,7 @@ stock ClassGetGroup(index, String:buffer[], maxlen, cachetype = ZR_CLASS_CACHE_P
return strcopy(buffer, maxlen, ClassPlayerCache[index][Class_Group]);
}
}
return -1;
}
@ -265,7 +265,7 @@ stock ClassGetSM_Flags(index, String:buffer[], maxlen, cachetype = ZR_CLASS_CACH
return strcopy(buffer, maxlen, ClassPlayerCache[index][Class_SM_Flags]);
}
}
return -1;
}
@ -300,7 +300,7 @@ stock ClassGetName(index, String:buffer[], maxlen, cachetype = ZR_CLASS_CACHE_PL
return strcopy(buffer, maxlen, ClassPlayerCache[index][Class_Name]);
}
}
return -1;
}
@ -553,7 +553,7 @@ stock ClassGetOverlayPath(index, String:buffer[], maxlen, cachetype = ZR_CLASS_C
return strcopy(buffer, maxlen, ClassPlayerCache[index][Class_OverlayPath]);
}
}
return -1;
return -1;
}
/**
@ -1037,16 +1037,16 @@ stock Float:ClassGetSpeed(index, cachetype = ZR_CLASS_CACHE_PLAYER)
{
new Float:speed = ClassPlayerCache[index][Class_Speed];
new Float:multiplier = ClassGetAttributeMultiplier(index, ClassM_Speed);
// Apply multiplier.
if (ClassSpeedMethod == ClassSpeed_Prop)
{
// Prop speed is an offset. Convert to absolute value.
speed += 250;
// Apply multiplier.
speed *= multiplier;
// Convert back to speed offset.
speed -= 250;
}
@ -1296,7 +1296,7 @@ stock ClassAttributeNameToFlag(const String:attributename[])
{
return ZR_CLASS_JUMP_DISTANCE;
}
// Invalid attribute name.
return -1;
}
@ -1347,7 +1347,7 @@ stock ClassMultipliers:ClassAttributeNameToMultiplier(const String:attributename
{
return ClassM_JumpDistance;
}
// Invalid attribute name or not a multiplier.
return ClassM_Invalid;
}
@ -1371,7 +1371,7 @@ stock ClassDataTypes:ClassGetAttributeType(attributeflag)
{
return ClassDataType_Boolean;
}
// Integer.
case ZR_CLASS_FLAGS,
ZR_CLASS_MODEL_SKIN_INDEX,
@ -1388,7 +1388,7 @@ stock ClassDataTypes:ClassGetAttributeType(attributeflag)
{
return ClassDataType_Integer;
}
// Float.
case ZR_CLASS_NAPALM_TIME,
ZR_CLASS_HEALTH_REGEN_INTERVAL,
@ -1399,7 +1399,7 @@ stock ClassDataTypes:ClassGetAttributeType(attributeflag)
{
return ClassDataType_Float;
}
// String.
case ZR_CLASS_GROUP,
ZR_CLASS_NAME,
@ -1411,7 +1411,7 @@ stock ClassDataTypes:ClassGetAttributeType(attributeflag)
return ClassDataType_String;
}
}
// Invalid flag or multiple flags combined.
return ClassDataType_InvalidType;
}

View File

@ -4,7 +4,7 @@
* Zombie:Reloaded
*
* File: classcommands.inc
* Type: Core
* Type: Core
* Description: Console commands for working with classes.
*
* Copyright (C) 2009-2013 Greyscale, Richard Helgeby
@ -29,7 +29,7 @@ ClassOnCommandsCreate()
{
// Register ZClass command.
RegConsoleCmd(SAYHOOKS_KEYWORD_ZCLASS, ZClassCommand, "Opens class selection menu.");
// Create base class commands.
RegConsoleCmd("zr_class_dump", ClassDumpCommand, "Dumps class data at a specified index in the specified cache. Usage: zr_class_dump <cachetype> <index|targetname>");
RegConsoleCmd("zr_class_dump_multipliers", ClassDumpMultipliersCommand, "Dumps class attribute multipliers for the specified team. Usage: zr_class_dump_multipliers <\"zombies\"|\"humans\">");
@ -50,7 +50,7 @@ ClassOnCommandsHook()
/**
* Command callback (zclass)
* Opens class selection menu.
*
*
* @param client The client index.
* @param argc Argument count.
*/
@ -62,10 +62,10 @@ public Action:ZClassCommand(client, argc)
TranslationPrintToChat(client, "Must be player");
return Plugin_Handled;
}
// Send class menu.
ClassMenuMain(client);
// This stops the "Unknown command" message in client's console.
return Plugin_Handled;
}
@ -73,7 +73,7 @@ public Action:ZClassCommand(client, argc)
/**
* Command callback. (zr_class_dump)
* Dumps class data at a specified index in the specified cache.
*
*
* @param client The client index.
* @param argc Argument count.
*/
@ -81,14 +81,14 @@ public Action:ClassDumpCommand(client, argc)
{
decl String:syntax[320];
syntax[0] = 0;
// Check if privileged.
if (!ZRIsClientPrivileged(client, OperationType_Generic))
{
TranslationReplyToCommand(client, "No access to command");
return Plugin_Handled;
}
if (argc < 2)
{
// Write syntax info.
@ -98,23 +98,23 @@ public Action:ClassDumpCommand(client, argc)
StrCat(syntax, sizeof(syntax), "modified - Newest class data\n");
StrCat(syntax, sizeof(syntax), "player - Players class data\n");
ReplyToCommand(client, syntax);
return Plugin_Handled;
}
new cachetype = -1;
new index = -1;
decl String:type[64];
decl String:target[64];
decl String:buffer[2048];
// Quick initialize buffer.
buffer[0] = 0;
// Get cache type.
GetCmdArg(1, type, sizeof(type));
// Set cache type depending on parameter setting.
if (StrEqual(type, "original", false))
{
@ -127,11 +127,11 @@ public Action:ClassDumpCommand(client, argc)
else if (StrEqual(type, "player", false))
{
cachetype = ZR_CLASS_CACHE_PLAYER;
// Get client index.
GetCmdArg(2, target, sizeof(target));
index = FindTarget(client, target, _, false);
// Check if failed.
if (index < 0)
{
@ -139,32 +139,32 @@ public Action:ClassDumpCommand(client, argc)
return Plugin_Handled;
}
}
// Check if cachetype is valid.
if (cachetype < 0)
{
ReplyToCommand(client, "Invalid cache type.");
return Plugin_Handled;
}
// Validate class index.
if (cachetype != ZR_CLASS_CACHE_PLAYER)
{
// Get class index.
GetCmdArg(2, target, sizeof(target));
index = StringToInt(target);
if (!ClassValidateIndex(index))
{
ReplyToCommand(client, "Invalid class index.");
return Plugin_Handled;
}
}
// Dump the specified cache.
ReplyToCommand(client, "DUMPING CACHE: \"%s\" (%d classes total)\n========================================\n", type, ClassCount);
ClassDumpData(index, cachetype, buffer, sizeof(buffer));
// Print all data to client.
decl String:partbuffer[1024];
new pos;
@ -176,14 +176,14 @@ public Action:ClassDumpCommand(client, argc)
ReplyToCommand(client, partbuffer);
pos += cellswritten;
}
return Plugin_Handled;
}
/**
* Command callback. (zr_class_dump_multipliers)
* Dumps class attribute multipliers for the specified team.
*
*
* @param client The client index.
* @param argc Argument count.
*/
@ -193,23 +193,23 @@ public Action:ClassDumpMultipliersCommand(client, argc)
decl String:linebuffer[128];
decl String:arg[16];
buffer[0] = 0;
// Check if privileged.
if (!ZRIsClientPrivileged(client, OperationType_Generic))
{
TranslationReplyToCommand(client, "No access to command");
return Plugin_Handled;
}
if (argc < 1)
{
// Write syntax info.
ReplyToCommand(client, "Dumps class attribute multipliers for the specified team. Usage: zr_class_dump_multipliers <\"zombies\"|\"humans\">");
return Plugin_Handled;
}
new teamid = -1;
// Get team id.
GetCmdArg(1, arg, sizeof(arg));
if (StrEqual(arg, "zombies", false))
@ -220,12 +220,12 @@ public Action:ClassDumpMultipliersCommand(client, argc)
{
teamid = ZR_CLASS_TEAM_HUMANS;
}
if (teamid >= 0)
{
Format(linebuffer, sizeof(linebuffer), "Dumping multipliers for team: %s\n----------------------------------------\n", arg);
StrCat(buffer, sizeof(buffer), linebuffer);
Format(linebuffer, sizeof(linebuffer), "Napalm time: %f\n", ClassMultiplierCache[teamid][ClassM_NapalmTime]);
StrCat(buffer, sizeof(buffer), linebuffer);
Format(linebuffer, sizeof(linebuffer), "Health: %f\n", ClassMultiplierCache[teamid][ClassM_Health]);
@ -244,7 +244,7 @@ public Action:ClassDumpMultipliersCommand(client, argc)
StrCat(buffer, sizeof(buffer), linebuffer);
Format(linebuffer, sizeof(linebuffer), "Jump distance: %f", ClassMultiplierCache[teamid][ClassM_JumpDistance]);
StrCat(buffer, sizeof(buffer), linebuffer);
ReplyToCommand(client, buffer);
return Plugin_Handled;
}
@ -275,14 +275,14 @@ public Action:ClassModifyCommand(client, argc)
{
decl String:syntax[1024];
syntax[0] = 0;
// Check if privileged.
if (!ZRIsClientPrivileged(client, OperationType_Configuration))
{
TranslationReplyToCommand(client, "No access to command");
return Plugin_Handled;
}
if (argc < 3)
{
// Write syntax info.
@ -293,30 +293,30 @@ public Action:ClassModifyCommand(client, argc)
StrCat(syntax, sizeof(syntax), "is_multiplier: Optional. specifies wether the original value should be multiplied by the specified value. Not all attributes support multipliers. Defaults to false.\n\n");
StrCat(syntax, sizeof(syntax), "Note: Original values are retrieved from the original class cache, not the modified class cache.");
ReplyToCommand(client, syntax);
return Plugin_Handled;
}
decl String:classname[64];
decl String:attributename[128];
decl String:value[256];
decl String:ismultiplier[4];
new attributeflag;
new ClassDataTypes:attributetype;
new bool:isgroup;
new bool:hasmultiplier;
new Handle:classlist;
new classindex;
new bool:listresult;
classlist = CreateArray();
// Get command arguments.
GetCmdArg(1, classname, sizeof(classname));
GetCmdArg(2, attributename, sizeof(attributename));
GetCmdArg(3, value, sizeof(value));
// Get last command argument if specified.
if (argc == 4)
{
@ -326,20 +326,20 @@ public Action:ClassModifyCommand(client, argc)
hasmultiplier = true;
}
}
// Get attribute flag.
attributeflag = ClassAttributeNameToFlag(attributename);
// Validate attribute flag.
if (attributeflag < 0)
{
ReplyToCommand(client, "Invalid class attribute specified.");
return Plugin_Handled;
}
// Get attribute data type.
attributetype = ClassGetAttributeType(attributeflag);
// Check if classname is a group. Add classes to the class list
// and use the specified team filter.
if (StrEqual(classname, "all", false))
@ -362,7 +362,7 @@ public Action:ClassModifyCommand(client, argc)
listresult = ClassAddToArray(classlist, ZR_CLASS_TEAM_ADMINS);
isgroup = true;
}
// Check if classname is a group.
if (isgroup)
{
@ -372,14 +372,14 @@ public Action:ClassModifyCommand(client, argc)
ReplyToCommand(client, "Failed to get classes in the specified team: \"%s\".", classname);
return Plugin_Handled;
}
// Loop through all classes in the list.
new listsize = GetArraySize(classlist);
for (new i = 0; i < listsize; i++)
{
classindex = GetArrayCell(classlist, i);
switch (attributetype)
{
case ClassDataType_Boolean:
@ -427,14 +427,14 @@ public Action:ClassModifyCommand(client, argc)
{
// It's a single class.
classindex = ClassGetIndex(classname);
// Validate classindex.
if (!ClassValidateIndex(classindex))
{
ReplyToCommand(client, "Invalid class name specified.");
return Plugin_Handled;
}
switch (attributetype)
{
case ClassDataType_Boolean:
@ -477,7 +477,7 @@ public Action:ClassModifyCommand(client, argc)
}
}
}
return Plugin_Handled;
}
@ -501,14 +501,14 @@ public Action:ClassSetMultiplierCommand(client, argc)
{
decl String:syntax[320];
syntax[0] = 0;
// Check if privileged.
if (!ZRIsClientPrivileged(client, OperationType_Configuration))
{
TranslationReplyToCommand(client, "No access to command");
return Plugin_Handled;
}
if (argc < 3)
{
// Write syntax info.
@ -518,20 +518,20 @@ public Action:ClassSetMultiplierCommand(client, argc)
ReplyToCommand(client, syntax);
return Plugin_Handled;
}
decl String:teamname[16];
decl String:attributename[32];
decl String:multiplier[32];
new teamid = -1;
new ClassMultipliers:attribute;
new Float:value;
// Get arguments.
GetCmdArg(1, teamname, sizeof(teamname));
GetCmdArg(2, attributename, sizeof(attributename));
GetCmdArg(3, multiplier, sizeof(multiplier));
// Get team id.
if (StrEqual(teamname, "zombies", false))
{
@ -541,37 +541,37 @@ public Action:ClassSetMultiplierCommand(client, argc)
{
teamid = ZR_CLASS_TEAM_HUMANS;
}
// Validate team id.
if (teamid < 0)
{
ReplyToCommand(client, "Invalid team name: %s", teamname);
return Plugin_Handled;
}
// Get attribute type.
attribute = ClassAttributeNameToMultiplier(attributename);
// Validate type.
if (attribute == ClassM_Invalid)
{
ReplyToCommand(client, "Attribute is invalid or not a multiplier: %s", attributename);
return Plugin_Handled;
}
// Get value.
value = StringToFloat(multiplier);
// Set multiplier.
ClassMultiplierCache[teamid][attribute] = value;
return Plugin_Handled;
}
/**
* Command callback. (zr_class_reload)
* Dumps class data at a specified index in the specified cache.
*
*
* @param client The client index.
* @param argc Argument count.
*/
@ -582,25 +582,25 @@ public Action:ClassReloadCommand(client, argc)
new targetlist[MAXPLAYERS + 1];
new targetcount;
new bool:tn_is_ml;
// Check if privileged.
if (!ZRIsClientPrivileged(client, OperationType_Generic))
{
TranslationReplyToCommand(client, "No access to command");
return Plugin_Handled;
}
if (argc < 1)
{
// Write syntax info.
ReplyToCommand(client, "Refreshes the player cache and reloads class attributes on one or more players. Usage: zr_class_reload <target>");
return Plugin_Handled;
}
// Get the target string.
GetCmdArg(1, arg, sizeof(arg));
// Get target clients.
if ((targetcount = ProcessTargetString(arg, client, targetlist, sizeof(targetlist), 0, targetname, sizeof(targetname), tn_is_ml)) <= 0)
{
@ -608,13 +608,13 @@ public Action:ClassReloadCommand(client, argc)
ReplyToTargetError(client, targetcount);
return Plugin_Handled;
}
// Loop through each target.
for (new target = 0; target < targetcount; target++)
{
ClassReloadPlayer(targetlist[target]);
}
// Check phrase format.
if (tn_is_ml)
{
@ -624,7 +624,7 @@ public Action:ClassReloadCommand(client, argc)
{
ReplyToCommand(client, "Refreshed cache to %s.", targetname);
}
return Plugin_Handled;
}
@ -643,7 +643,7 @@ stock bool:ClassModifyBoolean(classindex, attributeflag, bool:value)
{
return false;
}
switch (attributeflag)
{
case ZR_CLASS_ENABLED:
@ -667,7 +667,7 @@ stock bool:ClassModifyBoolean(classindex, attributeflag, bool:value)
return true;
}
}
// Invalid flag or multiple flags combined.
return false;
}
@ -691,10 +691,10 @@ stock ClassModifyInteger(classindex, attributeflag, value, Float:multiplier = 0.
{
return false;
}
// Check if multiplier is specified.
new bool:ismultiplier = (multiplier != 0.0) ? true : false;
switch (attributeflag)
{
case ZR_CLASS_FLAGS:
@ -794,7 +794,7 @@ stock ClassModifyInteger(classindex, attributeflag, value, Float:multiplier = 0.
return true;
}
}
// Invalid flag or multiple flags combined.
return false;
}
@ -817,7 +817,7 @@ stock ClassModifyFloat(classindex, attributeflag, Float:value, bool:ismultiplier
{
return false;
}
switch (attributeflag)
{
case ZR_CLASS_NAPALM_TIME:
@ -875,7 +875,7 @@ stock ClassModifyFloat(classindex, attributeflag, Float:value, bool:ismultiplier
return true;
}
}
// Invalid flag or multiple flags combined.
return false;
}
@ -895,7 +895,7 @@ stock ClassModifyString(classindex, attributeflag, const String:value[])
{
return false;
}
switch (attributeflag)
{
case ZR_CLASS_GROUP:
@ -932,7 +932,7 @@ stock ClassModifyString(classindex, attributeflag, const String:value[])
{
// Convert to mode.
new ImmunityMode:mode = ImmunityStringToMode(value);
// Validate.
if (mode != Immunity_Invalid)
{
@ -945,7 +945,7 @@ stock ClassModifyString(classindex, attributeflag, const String:value[])
}
}
}
// Invalid flag or multiple flags combined.
return false;
}

View File

@ -44,7 +44,7 @@ ClassOnCookiesCreate()
{
// Forward event to sub-modules.
ClassOverlayOnCookiesCreate();
// Create cookie handles only if they don't exist.
if (g_hClassCookieClassSelected[ZR_CLASS_TEAM_HUMANS] == INVALID_HANDLE)
{
@ -77,7 +77,7 @@ ClassOnMapStart()
{
// Clear multipliers.
ClassResetMultiplierCache();
// Prepare hp regeneration module.
ClassHealthRegenInit();
}
@ -88,7 +88,7 @@ ClassOnMapStart()
ClassOnConfigsExecuted()
{
new ClassSpeedMethods:speedMethod = ClassGetSpeedMethod();
if (speedMethod != ClassSpeed_Invalid)
{
// Set speed method.
@ -109,7 +109,7 @@ ClassOnClientConnected(client)
{
// Unhook "PreThinkPost" on the client.
SDKUnhook(client, SDKHook_PreThinkPost, ClassPreThinkPost);
// Initialize the admin checked variable.
g_bAdminChecked[client] = false;
}
@ -121,16 +121,16 @@ ClassClientInit(client)
{
// Hook "PreThinkPost" on the client.
SDKHook(client, SDKHook_PreThinkPost, ClassPreThinkPost);
// Reset spawn flag.
ClassPlayerSpawned[client] = false;
}
/**
* Called once a client is authorized and fully in-game, and
* after all post-connection authorizations have been performed.
* Called once a client is authorized and fully in-game, and
* after all post-connection authorizations have been performed.
*
* This callback is gauranteed to occur on all clients, and always
* This callback is gauranteed to occur on all clients, and always
* after each OnClientPutInServer() call.
*
* @param client Client index.
@ -140,11 +140,11 @@ ClassOnClientPostAdminCheck(client)
{
// Client has been checked.
g_bAdminChecked[client] = true;
// Below this depends on client cookies.
if (!AreClientCookiesCached(client))
return;
// Check if classes are loaded successfully and the client is valid.
if (ClassValidated)
{
@ -155,7 +155,7 @@ ClassOnClientPostAdminCheck(client)
/**
* Called once a client's saved cookies have been loaded from the database.
*
*
* @param client Client index.
*/
ClassOnCookiesCached(client)
@ -166,11 +166,11 @@ ClassOnCookiesCached(client)
// Forward event to sub-modules.
ClassOverlayOnCookiesCached(client);
}
// Below this depends on client authorization.
if (!g_bAdminChecked[client])
return;
// Check if classes are loaded successfully and the client is valid.
if (ClassValidated)
{
@ -186,14 +186,14 @@ ClassOnClientDisconnect(client)
{
// Disable class attributes with timers.
ClassHealthRegenStop(client);
// Reset previously selected class indexes.
ClassResetNextIndexes(client);
}
/**
* Client is spawning into the game.
*
*
* @param client The client index.
*/
ClassOnClientSpawn(client)
@ -201,37 +201,37 @@ ClassOnClientSpawn(client)
decl String:originalmodel[PLATFORM_MAX_PATH];
decl String:classname[64];
new filter[ClassFilter];
// Check if the player is dead. Spawning into the game is also a event in
// the connection process.
if (!IsPlayerAlive(client))
{
return;
}
// Check if there are no valid classes. Block this event if classes aren't
// done loading.
if (!ClassValidated)
{
return;
}
// Reset attributes by triggering death event.
ClassOnClientDeath(client);
// Restore class indexes to be selected on spawn, if available.
ClassRestoreNextIndexes(client);
// Cache original player model.
GetClientModel(client, originalmodel, sizeof(originalmodel));
strcopy(ClassOriginalPlayerModel[client], PLATFORM_MAX_PATH, originalmodel);
// Check if the player should spawn in admin mode.
if (ClassPlayerInAdminMode[client])
{
// Mark player as in admin mode.
ClassPlayerInAdminMode[client] = true;
// TODO: This is the place to initialize admin mode stuff like no-block
// and other stuff.
}
@ -239,43 +239,43 @@ ClassOnClientSpawn(client)
{
// Mark player as not in admin mode.
ClassPlayerInAdminMode[client] = false;
// Get random class setting.
new bool:randomclass = GetConVarBool(g_hCvarsList[CVAR_CLASSES_RANDOM]);
// Assign random classes if enabled. Always do it for bots.
if (randomclass || IsFakeClient(client))
{
// Setup filtering
// ---------------
// Exclude special class flags like mother zombies and admin classes.
filter[ClassFilter_DenyFlags] = ZR_CLASS_SPECIALFLAGS;
// Allow admin classes if admin.
filter[ClassFilter_DenyFlags] -= ZRIsClientAdmin(client) ? ZR_CLASS_FLAG_ADMIN_ONLY : 0;
// Specify client for checking group permissions.
filter[ClassFilter_Client] = client;
// Get classes
// -----------
// Get random classes for each type.
new randomzombie = ClassGetRandomClass(ZR_CLASS_TEAM_ZOMBIES, filter);
new randomhuman = ClassGetRandomClass(ZR_CLASS_TEAM_HUMANS, filter);
// Set selected zombie class index.
ClassSelected[client][ZR_CLASS_TEAM_ZOMBIES] = randomzombie;
ClassGetName(randomzombie, classname, sizeof(classname), ZR_CLASS_TEAM_ZOMBIES);
TranslationPrintToChat(client, "Classes random assignment", classname);
// Set selected human class index.
ClassSelected[client][ZR_CLASS_TEAM_HUMANS] = randomhuman;
ClassGetName(randomhuman, classname, sizeof(classname), ZR_CLASS_TEAM_HUMANS);
TranslationPrintToChat(client, "Classes random assignment", classname);
}
// Display class menu if either menu cvar is set.
new bool:menuspawn = GetConVarBool(g_hCvarsList[CVAR_CLASSES_MENU_SPAWN]);
new bool:menujoin = GetConVarBool(g_hCvarsList[CVAR_CLASSES_MENU_JOIN]);
@ -285,19 +285,19 @@ ClassOnClientSpawn(client)
ClassMenuMain(client);
}
}
// Load class attributes for the active class.
ClassReloadPlayerCache(client, ClassGetActiveIndex(client));
// Note: Class attributes are applied in ClassOnClientSpawnPost.
// Check if instant class change cvar is set.
new Float:instantspawn = GetConVarFloat(g_hCvarsList[CVAR_CLASSES_CHANGE_TIMELIMIT]);
if (instantspawn > 0)
{
// Allow instant class change.
ClassAllowInstantChange[client] = true;
// Create timer to disable instant change.
CreateTimer(instantspawn, Event_ClassDisableInstantSpawn, client, TIMER_FLAG_NO_MAPCHANGE);
}
@ -310,7 +310,7 @@ ClassOnClientSpawn(client)
/**
* Client have just spawned (delayed event).
*
*
* @param client The client index.
*/
ClassOnClientSpawnPost(client)
@ -321,31 +321,31 @@ ClassOnClientSpawnPost(client)
{
return;
}
ClassApplyAttributes(client);
}
/**
* Client died. Stops timers and reset certain attributes. Call this event to
* clean up class related stuff.
*
*
* @param client The client index.
*/
ClassOnClientDeath(client)
{
// Disable class attributes with timers.
ClassHealthRegenStop(client);
// Set client's FOV back to normal.
ToolsSetClientDefaultFOV(client, 90);
// Forward event to sub-modules.
ClassOverlayOnClientDeath(client);
}
/**
* Client got infected. Reloads class attributes.
*
*
* @param client The client index.
*/
ClassOnClientInfected(client, bool:motherzombie = false)
@ -354,25 +354,25 @@ ClassOnClientInfected(client, bool:motherzombie = false)
new isadmin;
new motherindex;
new filter[ClassFilter];
decl String:motherzombiesetting[64];
// Disable class attributes with timers.
ClassHealthRegenStop(client);
// Make sure the player is not allowed to instantly change class.
ClassAllowInstantChange[client] = false;
// Check if it's a mother zombie.
if (motherzombie)
{
// Set admin flag if client is admin, so it's removed in special class
// flags.
isadmin = ZRIsClientAdmin(client) ? ZR_CLASS_FLAG_ADMIN_ONLY : 0;
// Get default mother zombie setting.
GetConVarString(g_hCvarsList[CVAR_CLASSES_DEFAULT_M_ZOMB], motherzombiesetting, sizeof(motherzombiesetting));
if (StrEqual(motherzombiesetting, "disabled", false))
{
// Do nothing. Keep current class.
@ -381,28 +381,28 @@ ClassOnClientInfected(client, bool:motherzombie = false)
{
// Setup filtering
// ---------------
// Exclude special class flags.
filter[ClassFilter_DenyFlags] = ZR_CLASS_SPECIALFLAGS;
// Allow admin classes if admin.
filter[ClassFilter_DenyFlags] -= isadmin;
// Specify client for checking group permissions.
filter[ClassFilter_Client] = client;
// Get class
// ---------
// Get random regular zombie class. Remove admin flag if admin.
motherindex = ClassGetRandomClass(ZR_CLASS_TEAM_ZOMBIES, filter);
// Validate index. Do not change class if it's invalid.
if (ClassValidateIndex(motherindex))
{
// Save active class index to be restored next spawn.
ClassSelectedNext[client][ZR_CLASS_TEAM_ZOMBIES] = classindex;
// Change class.
classindex = motherindex;
}
@ -411,35 +411,35 @@ ClassOnClientInfected(client, bool:motherzombie = false)
{
// Setup filtering
// ---------------
// Exclude special class flags except mother zombies.
filter[ClassFilter_DenyFlags] = ZR_CLASS_SPECIALFLAGS - ZR_CLASS_FLAG_MOTHER_ZOMBIE;
// Require mother zombie class flag.
filter[ClassFilter_RequireFlags] = ZR_CLASS_FLAG_MOTHER_ZOMBIE;
// Allow admin classes if admin.
filter[ClassFilter_DenyFlags] -= isadmin;
// Specify client for checking group permissions.
filter[ClassFilter_Client] = client;
// Get class
// ---------
// Get random mother zombie class. Include admin classes if admin.
motherindex = ClassGetRandomClass(ZR_CLASS_TEAM_ZOMBIES, filter);
// Validate index. Do not change class if it's invalid.
if (ClassValidateIndex(motherindex))
{
// This is a mother zombie class. Reset mother zombie setting
// so class skills aren't improved.
motherzombie = false;
// Save active class index to be restored next spawn.
ClassSelectedNext[client][ZR_CLASS_TEAM_ZOMBIES] = classindex;
// Change class.
classindex = motherindex;
}
@ -448,28 +448,28 @@ ClassOnClientInfected(client, bool:motherzombie = false)
{
// Assume it's a class name. Get index for the specified class name.
motherindex = ClassGetIndex(motherzombiesetting);
// Validate index.
if (ClassValidateIndex(motherindex))
{
// Save active class index to be restored next spawn.
ClassSelectedNext[client][ZR_CLASS_TEAM_ZOMBIES] = classindex;
// Change class.
classindex = motherindex;
}
}
}
// Update the player's selected class index.
ClassSelected[client][ZR_CLASS_TEAM_ZOMBIES] = classindex;
// Restore next indexes, if available. But don't restore the zombie index.
ClassRestoreNextIndexes(client, ZR_CLASS_TEAM_ZOMBIES);
// Update the player's cache with zombie attributes.
ClassReloadPlayerCache(client, classindex);
// Apply the new attributes.
ClassApplyAttributes(client, motherzombie);
}

View File

@ -41,60 +41,60 @@
ClassMenuMain(client)
{
new Handle:menu = CreateMenu(ClassMenuMainHandle);
SetGlobalTransTarget(client);
decl String:title[MENU_LINE_TITLE_LENGTH];
decl String:zombieclass[MENU_LINE_REG_LENGTH];
decl String:humanclass[MENU_LINE_REG_LENGTH];
decl String:adminclass[MENU_LINE_REG_LENGTH];
decl String:nextzombiename[MENU_LINE_REG_LENGTH];
decl String:nexthumanname[MENU_LINE_REG_LENGTH];
decl String:nextadminname[MENU_LINE_REG_LENGTH];
decl String:zombieselect[MENU_LINE_BIG_LENGTH];
decl String:humanselect[MENU_LINE_BIG_LENGTH];
decl String:adminselect[MENU_LINE_BIG_LENGTH];
decl String:inadminmnode[MENU_LINE_BIG_LENGTH];
decl String:adminmode[MENU_LINE_BIG_LENGTH];
decl String:toggleadminmode[MENU_LINE_BIG_LENGTH];
// Setup filtering.
// ----------------
new filter[ClassFilter];
// Hide mother zombie classes.
filter[ClassFilter_DenyFlags] = ZR_CLASS_FLAG_MOTHER_ZOMBIE;
// Hide admin-only classes if not admin.
filter[ClassFilter_DenyFlags] += !ZRIsClientAdmin(client) ? ZR_CLASS_FLAG_ADMIN_ONLY : 0;
// Specify client for checking class group permissions.
filter[ClassFilter_Client] = client;
// Setup item draw style.
// ----------------------
// Get number of enabled classes per team.
new zombiecount = ClassCountTeam(ZR_CLASS_TEAM_ZOMBIES, filter);
new humancount = ClassCountTeam(ZR_CLASS_TEAM_HUMANS, filter);
new admincount = ClassCountTeam(ZR_CLASS_TEAM_ADMINS, filter);
// Get next class indexes, if set.
new nextzombie = ClassSelectedNext[client][ZR_CLASS_TEAM_ZOMBIES];
new nexthuman = ClassSelectedNext[client][ZR_CLASS_TEAM_HUMANS];
new nextadmin = ClassSelectedNext[client][ZR_CLASS_TEAM_ADMINS];
// Set draw style on class options depending on number of enabled classes
// and selection permissions. Disable class selection if there's only one
// class.
new zombie_itemdraw = (zombiecount > 1 && ClassAllowSelection(client, ZR_CLASS_TEAM_ZOMBIES, filter)) ? ITEMDRAW_DEFAULT : ITEMDRAW_DISABLED;
new human_itemdraw = (humancount > 1 && ClassAllowSelection(client, ZR_CLASS_TEAM_HUMANS, filter)) ? ITEMDRAW_DEFAULT : ITEMDRAW_DISABLED;
new admin_itemdraw = (admincount > 1 && ClassAllowSelection(client, ZR_CLASS_TEAM_ADMINS, filter)) ? ITEMDRAW_DEFAULT : ITEMDRAW_DISABLED;
// Check if the player is in admin mode.
if (ClassPlayerInAdminMode[client])
{
@ -102,19 +102,19 @@ ClassMenuMain(client)
Format(inadminmnode, sizeof(inadminmnode), "%t\n", "Classes admin mode enabled");
AddMenuItem(menu, "", inadminmnode, ITEMDRAW_RAWLINE);
}
// List zombie class options.
// --------------------------
// Get current class name.
ClassGetName(ClassSelected[client][ZR_CLASS_TEAM_ZOMBIES], zombieclass, sizeof(zombieclass), ZR_CLASS_CACHE_MODIFIED);
// Check if next index is set.
if (ClassValidateIndex(nextzombie))
{
// Get name of previous class index and format item text.
ClassGetName(nextzombie, nextzombiename, sizeof(nextzombiename), ZR_CLASS_CACHE_MODIFIED);
Format(zombieselect, sizeof(zombieselect), "%t\n %t\n %t", "Classes menu select zombie", "Classes menu active", zombieclass, "Classes menu next", nextzombiename);
}
else
@ -122,23 +122,23 @@ ClassMenuMain(client)
// Use current class name and format item text.
Format(zombieselect, sizeof(zombieselect), "%t\n %s", "Classes menu select zombie", zombieclass);
}
// Add item to list.
AddMenuItem(menu, "", zombieselect, zombie_itemdraw);
// List human class options.
// -------------------------
// Get current class name.
ClassGetName(ClassSelected[client][ZR_CLASS_TEAM_HUMANS], humanclass, sizeof(humanclass), ZR_CLASS_CACHE_MODIFIED);
// Check if next index is set.
if (ClassValidateIndex(nexthuman))
{
// Get name of previous class index and format item text.
ClassGetName(nexthuman, nexthumanname, sizeof(nexthumanname), ZR_CLASS_CACHE_MODIFIED);
Format(humanselect, sizeof(humanselect), "%t\n %t\n %t", "Classes menu select human", "Classes menu active", humanclass, "Classes menu next", nexthumanname);
}
else
@ -146,20 +146,20 @@ ClassMenuMain(client)
// Use current class name and format item text.
Format(humanselect, sizeof(humanselect), "%t\n %s", "Classes menu select human", humanclass);
}
// Add item to list.
AddMenuItem(menu, "", humanselect, human_itemdraw);
// List admin class options, if they exist.
// ----------------------------------------
// Only display admin class options for admins, and if admin classes exist.
if (ZRIsClientAdmin(client) && ClassCountTeam(ZR_CLASS_TEAM_ADMINS))
{
// Get current class name.
ClassGetName(ClassSelected[client][ZR_CLASS_TEAM_ADMINS], adminclass, sizeof(adminclass), ZR_CLASS_CACHE_MODIFIED);
// Check if next index is set.
if (ClassValidateIndex(nextadmin))
{
@ -172,10 +172,10 @@ ClassMenuMain(client)
// Use current class name and format item text.
Format(adminselect, sizeof(adminselect), "%t\n %s", "Classes menu select admin", adminclass);
}
// Add item to list.
AddMenuItem(menu, "", adminselect, admin_itemdraw);
// Set admin mode status string.
if (ClassPlayerInAdminMode[client])
{
@ -185,18 +185,18 @@ ClassMenuMain(client)
{
Format(adminmode, sizeof(adminmode), "%t", "Off");
}
// Spacer. ITEMDRAW_SPACER not used because it use a slot.
AddMenuItem(menu, "", " ", ITEMDRAW_RAWLINE);
// Show admin mode toggle option.
Format(toggleadminmode, sizeof(toggleadminmode), "%t\n %s", "Classes menu admin mode toggle", adminmode);
AddMenuItem(menu, "", toggleadminmode, admin_itemdraw);
}
Format(title, sizeof(title), "%t\n", "Classes menu title");
SetMenuTitle(menu, title);
SetMenuExitBackButton(menu, true);
DisplayMenu(menu, client, MENU_TIME_FOREVER);
}
@ -263,14 +263,14 @@ ClassMenuSelect(client, teamid)
new Handle:menu = CreateMenu(ClassMenuSelectHandle);
new arraycount;
new classindex;
decl String:title[MENU_LINE_TITLE_LENGTH];
decl String:classname[MENU_LINE_REG_LENGTH];
decl String:description[MENU_LINE_BIG_LENGTH];
decl String:menuitem[MENU_LINE_HUGE_LENGTH];
SetGlobalTransTarget(client);
// Set correct menu title depending on team ID.
switch (teamid)
{
@ -288,32 +288,32 @@ ClassMenuSelect(client, teamid)
}
}
SetMenuTitle(menu, title);
// Create buffer array.
new Handle:classarray = CreateArray();
// Set up filtering
// ----------------
new filter[ClassFilter];
// Hide mother zombie classes.
filter[ClassFilter_DenyFlags] = ZR_CLASS_FLAG_MOTHER_ZOMBIE;
// Hide admin-only classes if not admin.
filter[ClassFilter_DenyFlags] += !ZRIsClientAdmin(client) ? ZR_CLASS_FLAG_ADMIN_ONLY : 0;
// Specify client for checking class group permissions.
filter[ClassFilter_Client] = client;
// Get classes
// -----------
// Copy all class indexes into the array, with the specified filter settings.
if (ClassAddToArray(classarray, teamid, filter))
{
// Get number of classes.
arraycount = GetArraySize(classarray);
// Loop through each class.
for (new i = 0; i < arraycount; i++)
{
@ -321,16 +321,16 @@ ClassMenuSelect(client, teamid)
classindex = GetArrayCell(classarray, i);
ClassGetName(classindex, classname, sizeof(classname), ZR_CLASS_CACHE_MODIFIED);
ClassGetDescription(classindex, description, sizeof(description), ZR_CLASS_CACHE_MODIFIED);
// Add menu item. Using extra spaces for indention on the second line.
Format(menuitem, sizeof(menuitem), "%s\n %s", classname, description);
AddMenuItem(menu, classname, menuitem);
}
}
// Destroy array.
CloseHandle(classarray);
SetMenuExitBackButton(menu, true);
DisplayMenu(menu, client, MENU_TIME_FOREVER);
}
@ -343,17 +343,17 @@ public ClassMenuSelectHandle(Handle:menu, MenuAction:action, client, slot)
decl String:className[MENU_LINE_REG_LENGTH];
new classIndex;
new bool:autoclose = GetConVarBool(g_hCvarsList[CVAR_CLASSES_MENU_AUTOCLOSE]);
switch (action)
{
case MenuAction_Select:
{
// Get class name from the information string.
GetMenuItem(menu, slot, className, sizeof(className));
// Solve class index from the name.
classIndex = ClassGetIndex(className);
// Select (and eventually apply) class.
ClassSelectClientClass(client, classIndex);
}
@ -363,19 +363,19 @@ public ClassMenuSelectHandle(Handle:menu, MenuAction:action, client, slot)
{
ClassMenuMain(client);
}
// Stop so menu doesn't reopen.
return;
}
case MenuAction_End:
{
CloseHandle(menu);
// Stop so menu doesn't reopen.
return;
}
}
// Redisplay the main class menu if autoclose is disabled.
if (!autoclose)
{
@ -397,36 +397,36 @@ public ClassMenuSelectHandle(Handle:menu, MenuAction:action, client, slot)
* @return True if displayed, false otherwise.
*/
bool:ClassTeamSelect(client)
{
{
// Validate permissions.
if (!ZRIsClientPrivileged(client, OperationType_Configuration))
{
return false;
}
// Create menu.
new Handle:menu = CreateMenu(ClassTeamSelectHandle);
decl String:title[MENU_LINE_TITLE_LENGTH];
decl String:zombies[MENU_LINE_SMALL_LENGTH];
decl String:humans[MENU_LINE_SMALL_LENGTH];
// Set translation language.
SetGlobalTransTarget(client);
// Translate phrases.
Format(title, sizeof(title), "%t", "Classes Menu Team Select Title");
Format(zombies, sizeof(zombies), "%t", "Classes Menu Zombies");
Format(humans, sizeof(humans), "%t", "Classes Menu Humans");
SetMenuTitle(menu, title);
AddMenuItem(menu, "zombies", zombies);
AddMenuItem(menu, "humans", humans);
SetMenuExitBackButton(menu, true);
DisplayMenu(menu, client, MENU_TIME_FOREVER);
return true;
}
@ -450,7 +450,7 @@ public ClassTeamSelectHandle(Handle:menu, MenuAction:action, client, slot)
ClassAdminTeamSelected[client] = ZR_CLASS_TEAM_HUMANS;
}
}
// Display multiplier menu.
ClassMultiplierSelectMenu(client);
}
@ -484,10 +484,10 @@ ClassMultiplierSelectMenu(client)
{
// Create menu.
new Handle:menu = CreateMenu(ClassMultiplierSelectHandle);
new teamid = ClassAdminTeamSelected[client];
new bool:zombiesselected = bool:(teamid == ZR_CLASS_TEAM_ZOMBIES);
decl String:title[MENU_LINE_TITLE_LENGTH];
decl String:napalmtime[MENU_LINE_REG_LENGTH];
decl String:health[MENU_LINE_REG_LENGTH];
@ -498,7 +498,7 @@ ClassMultiplierSelectMenu(client)
decl String:knockback[MENU_LINE_REG_LENGTH];
decl String:jumpheight[MENU_LINE_REG_LENGTH];
decl String:jumpdistance[MENU_LINE_REG_LENGTH];
new Float:currentnapalmtime;
new Float:currenthealth;
new Float:currentregeninterval;
@ -508,7 +508,7 @@ ClassMultiplierSelectMenu(client)
new Float:currentknockback;
new Float:currentjumpheight;
new Float:currentjumpdistance;
// Get current multipliers.
currentnapalmtime = Float:ClassMultiplierCache[teamid][ClassM_NapalmTime];
currenthealth = Float:ClassMultiplierCache[teamid][ClassM_Health];
@ -519,9 +519,9 @@ ClassMultiplierSelectMenu(client)
currentknockback = Float:ClassMultiplierCache[teamid][ClassM_Knockback];
currentjumpheight = Float:ClassMultiplierCache[teamid][ClassM_JumpHeight];
currentjumpdistance = Float:ClassMultiplierCache[teamid][ClassM_JumpDistance];
SetGlobalTransTarget(client);
// Translate phrases.
Format(title, sizeof(title), "%t\n", "Classes Menu Multiplier Select Title");
Format(health, sizeof(health), "%t\n %.2f", "Classes Attrib Health", currenthealth);
@ -530,7 +530,7 @@ ClassMultiplierSelectMenu(client)
Format(speed, sizeof(speed), "%t\n %.2f", "Classes Attrib Speed", currentspeed);
Format(jumpheight, sizeof(jumpheight), "%t\n %.2f", "Classes Attrib Jump Height", currentjumpheight);
Format(jumpdistance, sizeof(jumpdistance), "%t\n %.2f", "Classes Attrib Jump Distance", currentjumpdistance);
// Only translate zombie phrases if zombie team is selected.
if (zombiesselected)
{
@ -538,9 +538,9 @@ ClassMultiplierSelectMenu(client)
Format(infectgain, sizeof(infectgain), "%t\n %.2f", "Classes Attrib Infect Gain", currentinfectgain);
Format(knockback, sizeof(knockback), "%t\n %.2f", "Classes Attrib Knockback", currentknockback);
}
SetMenuTitle(menu, title);
// Add items. Don't add zombie attributes if human team is selected.
if (zombiesselected) AddMenuItem(menu, "napalmtime", napalmtime);
AddMenuItem(menu, "health", health);
@ -551,7 +551,7 @@ ClassMultiplierSelectMenu(client)
if (zombiesselected) AddMenuItem(menu, "knockback", knockback);
AddMenuItem(menu, "jumpheight", jumpheight);
AddMenuItem(menu, "jumpdistance", jumpdistance);
SetMenuExitBackButton(menu, true);
DisplayMenu(menu, client, MENU_TIME_FOREVER);
}
@ -563,17 +563,17 @@ public ClassMultiplierSelectHandle(Handle:menu, MenuAction:action, client, slot)
{
decl String:attributename[48];
new ClassMultipliers:attribute;
switch (action)
{
case MenuAction_Select:
{
// Get attribute name.
GetMenuItem(menu, slot, attributename, sizeof(attributename));
// Initialize in case of errors.
attribute = ClassM_Knockback;
// Convert type.
if (StrEqual(attributename, "napalmtime", false))
{
@ -611,7 +611,7 @@ public ClassMultiplierSelectHandle(Handle:menu, MenuAction:action, client, slot)
{
attribute = ClassM_JumpDistance;
}
// Display multiplier menu for the selected attribute.
ClassMultiplierMenu(client, attribute);
}
@ -643,20 +643,20 @@ ClassMultiplierMenu(client, ClassMultipliers:attribute)
{
// Cache selected attribute.
ClassAdminAttributeSelected[client] = attribute;
new Handle:menu = CreateMenu(ClassMultiplierHandle);
decl String:title[MENU_LINE_TITLE_LENGTH];
decl String:attributename[MENU_LINE_REG_LENGTH];
decl String:linebuffer[MENU_LINE_REG_LENGTH];
// Get attribute string.
ClassMultiplierToString(client, attribute, attributename, sizeof(attributename));
SetGlobalTransTarget(client);
Format(title, sizeof(title), "%t %s\n%t %.2f\n", "Classes Menu Adjust Value", attributename, "Current Value", Float:ClassMultiplierCache[ClassAdminTeamSelected[client]][attribute]);
SetMenuTitle(menu, title);
SetGlobalTransTarget(client);
Format(linebuffer, sizeof(linebuffer), "%t", "Increase by", "0.5");
AddMenuItem(menu, "increasehalf", linebuffer);
@ -666,7 +666,7 @@ ClassMultiplierMenu(client, ClassMultipliers:attribute)
AddMenuItem(menu, "decreasedeci", linebuffer);
Format(linebuffer, sizeof(linebuffer), "%t", "Decrease by", "0.5");
AddMenuItem(menu, "decreasehalf", linebuffer);
SetMenuExitBackButton(menu, true);
DisplayMenu(menu, client, MENU_TIME_FOREVER);
}
@ -674,7 +674,7 @@ ClassMultiplierMenu(client, ClassMultipliers:attribute)
public ClassMultiplierHandle(Handle:menu, MenuAction:action, client, slot)
{
new Float:value;
switch (action)
{
case MenuAction_Select:
@ -698,10 +698,10 @@ public ClassMultiplierHandle(Handle:menu, MenuAction:action, client, slot)
value = -0.5;
}
}
// Update multiplier.
ClassAddToMultiplier(ClassAdminTeamSelected[client], ClassAdminAttributeSelected[client], value);
// Re-display menu.
ClassMultiplierMenu(client, ClassAdminAttributeSelected[client]);
}

View File

@ -33,7 +33,7 @@ ClassAlphaUpdate(client)
new current_health = GetClientHealth(client);
new max_health = ClassGetHealth(client);
new max_damage = ClassGetAlphaDamage(client);
// Calculate if enough damage is done to change alpha.
if ((max_health - current_health) > max_damage)
{

View File

@ -4,7 +4,7 @@
* Zombie:Reloaded
*
* File: clientoverlays.inc
* Type: Core
* Type: Core
* Description: Handles overlays on clients, as a part of class attributes.
*
* Copyright (C) 2009-2013 Greyscale, Richard Helgeby
@ -51,13 +51,13 @@ ClassOverlayOnCommandsHook()
{
decl String:togglecmds[CLASSOVERLAY_TOGGLE_MAX_CMDS * CLASSOVERLAY_TOGGLE_MAX_LENGTH];
GetConVarString(g_hCvarsList[CVAR_CLASSES_OVERLAY_TOGGLECMDS], togglecmds, sizeof(togglecmds));
// Array to store commands.
new String:arrayCmds[CLASSOVERLAY_TOGGLE_MAX_CMDS][CLASSOVERLAY_TOGGLE_MAX_LENGTH];
// Put the commands into an array.
new cmdcount = ExplodeString(togglecmds, ",", arrayCmds, sizeof(arrayCmds), sizeof(arrayCmds[]));
// Register all overlay commands.
for (new i = 0; i < cmdcount; i++)
{
@ -80,7 +80,7 @@ ClassOverlayOnCookiesCreate()
/**
* Called once a client's saved cookies have been loaded from the database.
*
*
* @param client Client index.
*/
ClassOverlayOnCookiesCached(client)
@ -88,11 +88,11 @@ ClassOverlayOnCookiesCached(client)
// Get overlay toggle cvar values.
new bool:overlaytoggle = GetConVarBool(g_hCvarsList[CVAR_CLASSES_OVERLAY_TOGGLE]);
new bool:overlaydefault = GetConVarBool(g_hCvarsList[CVAR_CLASSES_OVERLAY_DEFAULT]);
// Get ZHP enabled cookie value.
decl String:overlayenabled[8];
GetClientCookie(client, g_hOverlayEnabledCookie, overlayenabled, sizeof(overlayenabled));
// If the cookie is empty, then set the default value.
if (!overlayenabled[0])
{
@ -104,7 +104,7 @@ ClassOverlayOnCookiesCached(client)
/**
* Client has been killed.
*
*
* @param client The client index.
*/
ClassOverlayOnClientDeath(client)
@ -119,28 +119,28 @@ ClassOverlayInitialize(client, const String:overlay[])
{
return;
}
// If overlay path is empty, then disable channel, then stop.
if (!overlay[0])
{
OverlaysClientSetChannelState(client, OVERLAYS_CHANNEL_CLASSES, true, false, false, true);
return;
}
// If overlay toggle is enabled and class has an overlay, then send center text.
new bool:overlaytoggle = GetConVarBool(g_hCvarsList[CVAR_CLASSES_OVERLAY_TOGGLE]);
decl String:overlaypath[PLATFORM_MAX_PATH];
ClassGetOverlayPath(client, overlaypath, sizeof(overlaypath));
if (overlaytoggle && overlaypath[0])
{
decl String:togglecmds[CLASSOVERLAY_TOGGLE_MAX_CMDS * CLASSOVERLAY_TOGGLE_MAX_LENGTH];
GetConVarString(g_hCvarsList[CVAR_CLASSES_OVERLAY_TOGGLECMDS], togglecmds, sizeof(togglecmds));
TranslationPrintHintText(client, "Classes overlay toggle", togglecmds);
}
// Display class overlays.
OverlaysClientSetChannelPath(client, OVERLAYS_CHANNEL_CLASSES, overlay);
OverlaysClientSetChannelState(client, OVERLAYS_CHANNEL_CLASSES, true, false, CookiesGetClientCookieBool(client, g_hOverlayEnabledCookie));
@ -149,7 +149,7 @@ ClassOverlayInitialize(client, const String:overlay[])
/**
* Command callback. (See zr_classes_overlay_togglecmds)
* Toggles nightvision of a client.
*
*
* @param client The client index.
* @param argc Argument count.
*/
@ -160,14 +160,14 @@ public Action:ClassOverlayEnableCommand(client, argc)
{
return;
}
// If overlay toggle is disabled, then stop.
new bool:overlaytoggle = GetConVarBool(g_hCvarsList[CVAR_CLASSES_OVERLAY_TOGGLE]);
if (!overlaytoggle)
{
return;
}
// Toggle current overlay channel, retrieve new value, and update cookie.
new bool:overlayenabled = OverlaysClientSetChannelState(client, OVERLAYS_CHANNEL_CLASSES, true, true);
CookiesSetClientCookieBool(client, g_hOverlayEnabledCookie, overlayenabled);

View File

@ -4,7 +4,7 @@
* Zombie:Reloaded
*
* File: filtertools.inc
* Type: Core
* Type: Core
* Description: Class system tools; validating, getting indexes or lists
*
* Copyright (C) 2009-2013 Greyscale, Richard Helgeby
@ -39,23 +39,23 @@ stock bool:ClassValidateTeamRequirements(cachetype = ZR_CLASS_CACHE_ORIGINAL)
{
new zombieindex;
new humanindex;
// Check if there are no classes.
if (ClassCount == 0)
{
return false;
}
// Test if a zombie and human class was found.
zombieindex = ClassGetFirstClass(ZR_CLASS_TEAM_ZOMBIES, _, cachetype);
humanindex = ClassGetFirstClass(ZR_CLASS_TEAM_HUMANS, _, cachetype);
// Validate indexes.
if (ClassValidateIndex(zombieindex) && ClassValidateIndex(humanindex))
{
return true;
}
return false;
}
@ -71,17 +71,17 @@ stock bool:ClassValidateTeamDefaults(cachetype = ZR_CLASS_CACHE_ORIGINAL)
{
new zombieindex;
new humanindex;
// Check if there are no classes.
if (ClassCount == 0)
{
return false;
}
// Test if a default zombie and human class was found.
zombieindex = ClassGetDefaultClass(ZR_CLASS_TEAM_ZOMBIES, _, cachetype);
humanindex = ClassGetDefaultClass(ZR_CLASS_TEAM_HUMANS, _, cachetype);
// Validate indexes.
if (ClassValidateIndex(zombieindex) && ClassValidateIndex(humanindex))
{
@ -104,7 +104,7 @@ stock bool:ClassValidateTeamDefaults(cachetype = ZR_CLASS_CACHE_ORIGINAL)
stock ClassValidateAttributes(classindex, bool:logErrors = false)
{
new flags;
// Team.
new team = ClassData[classindex][Class_Team];
if (team < ZR_CLASS_TEAM_MIN || team > ZR_CLASS_TEAM_MAX)
@ -115,7 +115,7 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false)
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Invalid team at index %d: %d", classindex, team);
}
}
// Class flags.
new class_flags = ClassData[classindex][Class_Flags];
if (class_flags < ZR_CLASS_FLAGS_MIN || class_flags > ZR_CLASS_FLAGS_MAX)
@ -126,7 +126,7 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false)
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Invalid flags at index %d: %d", classindex, class_flags);
}
}
// Group.
decl String:group[64];
group[0] = 0;
@ -142,7 +142,7 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false)
}
}
}
// Name.
decl String:name[64];
name[0] = 0;
@ -169,7 +169,7 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false)
}
}
}
// Description.
if (strlen(ClassData[classindex][Class_Description]) < ZR_CLASS_DESCRIPTION_MIN)
{
@ -179,7 +179,7 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false)
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Missing description at index %d.", classindex);
}
}
// Model path.
decl String:model_path[PLATFORM_MAX_PATH];
if (strcopy(model_path, sizeof(model_path), ClassData[classindex][Class_ModelPath]) == 0)
@ -212,7 +212,7 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false)
}
}
}
// Model skin index.
new model_skin_index = ClassData[classindex][Class_ModelSkinIndex];
if (model_skin_index < ZR_CLASS_MODEL_SKIN_INDEX_MIN)
@ -223,7 +223,7 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false)
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Invalid model_skin_index at index %d: %d", classindex, model_skin_index);
}
}
// Alpha, initial.
new alpha_initial = ClassData[classindex][Class_AlphaInitial];
if (!(alpha_initial >= ZR_CLASS_ALPHA_INITIAL_MIN && alpha_initial <= ZR_CLASS_ALPHA_INITIAL_MAX))
@ -234,7 +234,7 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false)
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Invalid alpha_inital at index %d: %d", classindex, alpha_initial);
}
}
// Alpha, damaged.
new alpha_damaged = ClassData[classindex][Class_AlphaDamaged];
if (!(alpha_damaged >= ZR_CLASS_ALPHA_DAMAGED_MIN && alpha_damaged <= ZR_CLASS_ALPHA_DAMAGED_MAX))
@ -245,7 +245,7 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false)
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Invalid alpha_damaged at index %d: %d", classindex, alpha_damaged);
}
}
// Alpha, damage.
new alpha_damage = ClassData[classindex][Class_AlphaDamage];
if (!(alpha_damage >= ZR_CLASS_ALPHA_DAMAGE_MIN && alpha_damage <= ZR_CLASS_ALPHA_DAMAGE_MAX))
@ -256,7 +256,7 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false)
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Invalid alpha_damage at index %d: %d", classindex, alpha_damage);
}
}
// Overlay path.
decl String:overlay_path[PLATFORM_MAX_PATH];
decl String:overlay[PLATFORM_MAX_PATH];
@ -273,7 +273,7 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false)
}
}
}
// Field of view.
new fov = ClassData[classindex][Class_Fov];
if (!(fov >= ZR_CLASS_FOV_MIN && fov <= ZR_CLASS_FOV_MAX))
@ -284,7 +284,7 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false)
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Invalid fov at index %d: %d", classindex, fov);
}
}
// Napalm time.
new Float:napalm_time = ClassData[classindex][Class_NapalmTime];
if (!(napalm_time >= ZR_CLASS_NAPALM_TIME_MIN && napalm_time <= ZR_CLASS_NAPALM_TIME_MAX))
@ -295,7 +295,7 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false)
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Invalid napalm_time at index %d: %0.2f", classindex, napalm_time);
}
}
// Immunity mode.
new ImmunityMode:immunityMode = ClassData[classindex][Class_ImmunityMode];
if (immunityMode == Immunity_Invalid)
@ -306,7 +306,7 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false)
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Invalid immunity_mode at index %d.", classindex);
}
}
// Immunity amount.
new immunityAmount = ClassData[classindex][Class_ImmunityAmount];
if (!ImmunityIsValidAmount(immunityMode, immunityAmount))
@ -317,7 +317,7 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false)
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Invalid immunity_amount at index %d.", classindex);
}
}
// Immunity cooldown.
new immunityCooldown = ClassData[classindex][Class_ImmunityCooldown];
if (!ImmunityIsValidCooldown(immunityMode, immunityCooldown))
@ -328,7 +328,7 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false)
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Invalid immunity_cooldown at index %d.", classindex);
}
}
// Health.
new health = ClassData[classindex][Class_Health];
if (!(health >= ZR_CLASS_HEALTH_MIN && health <= ZR_CLASS_HEALTH_MAX))
@ -339,7 +339,7 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false)
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Invalid health at index %d: %d", classindex, health);
}
}
// Health regen interval.
new Float:regen_interval = ClassData[classindex][Class_HealthRegenInterval];
if (!(regen_interval >= ZR_CLASS_REGEN_INTERVAL_MIN && regen_interval <= ZR_CLASS_REGEN_INTERVAL_MAX))
@ -350,7 +350,7 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false)
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Invalid health_regen_interval at index %d: %0.2f", classindex, regen_interval);
}
}
// Health regen amount.
new regen_amount = ClassData[classindex][Class_HealthRegenAmount];
if (!(regen_amount >= ZR_CLASS_REGEN_AMOUNT_MIN && regen_amount <= ZR_CLASS_REGEN_AMOUNT_MAX))
@ -361,7 +361,7 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false)
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Invalid health_regen_amount at index %d: %d", classindex, regen_amount);
}
}
// Health infect gain.
new infect_gain = ClassData[classindex][Class_HealthInfectGain];
if (!(infect_gain >= ZR_CLASS_HEALTH_INFECT_GAIN_MIN && infect_gain <= ZR_CLASS_HEALTH_INFECT_GAIN_MAX))
@ -372,7 +372,7 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false)
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Invalid health_infect_gain at index %d: %d", classindex, infect_gain);
}
}
// Kill bonus.
new kill_bonus = ClassData[classindex][Class_KillBonus];
if (!(kill_bonus >= ZR_CLASS_KILL_BONUS_MIN && kill_bonus <= ZR_CLASS_KILL_BONUS_MAX))
@ -383,7 +383,7 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false)
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Invalid kill_bonus at index %d: %d", classindex, kill_bonus);
}
}
// Speed.
new Float:speed = ClassData[classindex][Class_Speed];
new Float:min;
@ -409,7 +409,7 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false)
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Invalid speed at index %d: %0.2f", classindex, speed);
}
}
// Knockback.
new Float:knockback = ClassData[classindex][Class_KnockBack];
if (!(knockback >= ZR_CLASS_KNOCKBACK_MIN && knockback <= ZR_CLASS_KNOCKBACK_MAX))
@ -420,7 +420,7 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false)
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Invalid knockback at index %d: %0.2f", classindex, knockback);
}
}
// Jump height.
new Float:jump_height = ClassData[classindex][Class_JumpHeight];
if (!(jump_height >= ZR_CLASS_JUMP_HEIGHT_MIN && jump_height <= ZR_CLASS_JUMP_HEIGHT_MAX))
@ -431,7 +431,7 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false)
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Invalid jump_height at index %d: %0.2f", classindex, jump_height);
}
}
// Jump distance.
new Float:jump_distance = ClassData[classindex][Class_JumpDistance];
if (!(jump_distance >= ZR_CLASS_JUMP_DISTANCE_MIN && jump_distance <= ZR_CLASS_JUMP_DISTANCE_MAX))
@ -442,7 +442,7 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false)
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Invalid jump_distance at index %d: %0.2f", classindex, jump_distance);
}
}
return flags;
}
@ -456,14 +456,14 @@ stock ClassValidateAttributes(classindex, bool:logErrors = false)
stock ClassValidateEditableAttributes(attributes[ClassEditableAttributes])
{
new flags;
// Model skin index.
new model_skin_index = attributes[ClassEdit_ModelSkinIndex];
if (model_skin_index < ZR_CLASS_MODEL_SKIN_INDEX_MIN)
{
flags += ZR_CLASS_MODEL_SKIN_INDEX;
}
// Alpha initial.
new alphaInitial = attributes[ClassEdit_AlphaInitial];
if (alphaInitial >= 0)
@ -473,7 +473,7 @@ stock ClassValidateEditableAttributes(attributes[ClassEditableAttributes])
flags += ZR_CLASS_ALPHA_INITIAL;
}
}
// Alpha damaged.
new alphaDamaged = attributes[ClassEdit_AlphaDamaged];
if (alphaDamaged >= 0)
@ -483,7 +483,7 @@ stock ClassValidateEditableAttributes(attributes[ClassEditableAttributes])
flags += ZR_CLASS_ALPHA_DAMAGED;
}
}
// Alpha damage.
new alphaDamage = attributes[ClassEdit_AlphaDamage];
if (alphaDamage >= 0)
@ -493,7 +493,7 @@ stock ClassValidateEditableAttributes(attributes[ClassEditableAttributes])
flags += ZR_CLASS_ALPHA_DAMAGE;
}
}
// Overlay.
if (!StrEqual(attributes[ClassEdit_OverlayPath], "nochange", false))
{
@ -509,7 +509,7 @@ stock ClassValidateEditableAttributes(attributes[ClassEditableAttributes])
}
}
}
// Fov.
new fov = attributes[ClassEdit_Fov];
if (fov >= 0)
@ -519,7 +519,7 @@ stock ClassValidateEditableAttributes(attributes[ClassEditableAttributes])
flags += ZR_CLASS_FOV;
}
}
// Napalm time.
new Float:napalmTime = attributes[ClassEdit_NapalmTime];
if (napalmTime >= 0.0)
@ -529,17 +529,17 @@ stock ClassValidateEditableAttributes(attributes[ClassEditableAttributes])
flags += ZR_CLASS_NAPALM_TIME;
}
}
// Immunity mode.
new ImmunityMode:immunityMode = attributes[ClassEdit_ImmunityMode];
if (immunityMode == Immunity_Invalid)
{
flags += ZR_CLASS_IMMUNITY_MODE;
}
// Immunity amount.
// TODO: Validate amount value. This depends on the immunity mode.
// Health regen interval.
new Float:healthRegenInterval = attributes[ClassEdit_RegenInterval];
if (healthRegenInterval >= 0.0)
@ -549,7 +549,7 @@ stock ClassValidateEditableAttributes(attributes[ClassEditableAttributes])
flags += ZR_CLASS_REGEN_INTERVAL;
}
}
// Health regen amount.
new healthRegenAmount = attributes[ClassEdit_RegenAmount];
if (healthRegenAmount >= 0)
@ -559,7 +559,7 @@ stock ClassValidateEditableAttributes(attributes[ClassEditableAttributes])
flags += ZR_CLASS_REGEN_AMOUNT;
}
}
// Infect gain.
new infectGain = attributes[ClassEdit_InfectGain];
if (infectGain >= 0)
@ -569,7 +569,7 @@ stock ClassValidateEditableAttributes(attributes[ClassEditableAttributes])
flags += ZR_CLASS_HEALTH_INFECT_GAIN;
}
}
// Kill bonus.
new killBonus = attributes[ClassEdit_KillBonus];
if (killBonus >= 0)
@ -579,7 +579,7 @@ stock ClassValidateEditableAttributes(attributes[ClassEditableAttributes])
flags += ZR_CLASS_KILL_BONUS;
}
}
// Speed.
new Float:speed = attributes[ClassEdit_Speed];
if (speed >= 0)
@ -604,7 +604,7 @@ stock ClassValidateEditableAttributes(attributes[ClassEditableAttributes])
flags += ZR_CLASS_SPEED;
}
}
// Knock back.
new Float:knockBack = attributes[ClassEdit_KnockBack];
if (knockBack > ZR_CLASS_KNOCKBACK_IGNORE)
@ -614,7 +614,7 @@ stock ClassValidateEditableAttributes(attributes[ClassEditableAttributes])
flags += ZR_CLASS_KNOCKBACK;
}
}
// Jump heigt.
new Float:jumpHeight = attributes[ClassEdit_JumpHeight];
if (jumpHeight >= 0.0)
@ -624,7 +624,7 @@ stock ClassValidateEditableAttributes(attributes[ClassEditableAttributes])
flags += ZR_CLASS_JUMP_HEIGHT;
}
}
// Jump distance.
new Float:jumpDistance = attributes[ClassEdit_JumpDistance];
if (jumpDistance >= 0.0)
@ -634,7 +634,7 @@ stock ClassValidateEditableAttributes(attributes[ClassEditableAttributes])
flags += ZR_CLASS_JUMP_DISTANCE;
}
}
return flags;
}
@ -719,7 +719,7 @@ stock ClassGetIndex(const String:name[], cachetype = ZR_CLASS_CACHE_MODIFIED)
{
return -1;
}
// Loop through all classes.
for (new classindex = 0; classindex < ClassCount; classindex++)
{
@ -730,7 +730,7 @@ stock ClassGetIndex(const String:name[], cachetype = ZR_CLASS_CACHE_MODIFIED)
return classindex;
}
}
// The class index wasn't found.
return -1;
}
@ -745,13 +745,13 @@ stock ClassGetIndex(const String:name[], cachetype = ZR_CLASS_CACHE_MODIFIED)
stock ClassGetActiveIndex(client)
{
new teamid;
if (!ZRIsClientOnTeam(client))
{
// No active team.
return -1;
}
// Check if the player currently is in admin mode.
if (ClassPlayerInAdminMode[client])
{
@ -769,7 +769,7 @@ stock ClassGetActiveIndex(client)
teamid = ZR_CLASS_TEAM_ZOMBIES;
}
}
// Return the active class for the active team.
return ClassSelected[client][teamid];
}
@ -785,7 +785,7 @@ stock ClassGetActiveIndex(client)
stock Float:ClassGetAttributeMultiplier(client, ClassMultipliers:attribute)
{
new teamid;
// Check if player is not in admin mode.
if (!ClassPlayerInAdminMode[client])
{
@ -798,7 +798,7 @@ stock Float:ClassGetAttributeMultiplier(client, ClassMultipliers:attribute)
{
teamid = ZR_CLASS_TEAM_ZOMBIES;
}
// Get multiplier for the specified team and attribute.
return Float:ClassMultiplierCache[teamid][attribute];
}
@ -811,7 +811,7 @@ stock Float:ClassGetAttributeMultiplier(client, ClassMultipliers:attribute)
/**
* Check if a class pass the specified filter.
*
*
* @param index Index of the class in a class cache or a client index,
* depending on the cache type specified.
* @param filter Structure with filter settings.
@ -830,23 +830,23 @@ stock bool:ClassFilterMatch(index, filter[ClassFilter], cachetype = ZR_CLASS_CAC
{
return false;
}
// Check if class flags pass the flag filter.
if (!ClassFlagFilterMatch(index, filter[ClassFilter_RequireFlags], filter[ClassFilter_DenyFlags], cachetype))
{
return false;
}
// Get class group name.
decl String:groupname[64];
groupname[0] = 0;
ClassGetGroup(index, groupname, sizeof(groupname), cachetype);
// Get class sm_flags.
decl String:sm_flags[64];
sm_flags[0] = 0;
ClassGetSM_Flags(index, sm_flags, sizeof(sm_flags), cachetype);
// Check if a client is specified in the filter.
new client = filter[ClassFilter_Client];
if (ZRIsClientValid(client))
@ -874,7 +874,7 @@ stock bool:ClassFilterMatch(index, filter[ClassFilter], cachetype = ZR_CLASS_CAC
return false;
}
}
// Check if classes with groups are set to be excluded.
if (client < 0)
{
@ -890,14 +890,14 @@ stock bool:ClassFilterMatch(index, filter[ClassFilter], cachetype = ZR_CLASS_CAC
return false;
}
}
// The class passed the filter.
return true;
}
/**
* Check if a class pass the specified flag filters.
*
*
* @param index Index of the class in a class cache or a client index,
* depending on the cache type specified.
* @param require Class flags to require. 0 for no filter.
@ -915,37 +915,37 @@ stock bool:ClassFlagFilterMatch(index, require, deny, cachetype)
new flags;
new bool:requirepassed = false;
new bool:denypassed = false;
// Do quick check for optimization reasons: Check if no flags are specified.
if (require == 0 && deny == 0)
{
return true;
}
// Cache flags.
flags = ClassGetFlags(index, cachetype);
// Match require filter.
if (require == 0 || flags & require)
{
// All required flags are set.
requirepassed = true;
}
// Match deny filter.
if (deny == 0 || !(flags & deny))
{
// No denied flags are set.
denypassed = true;
}
// Check if required and denied flags passed the filter.
if (requirepassed && denypassed)
{
// The class pass the filter.
return true;
}
// The class didn't pass the filter.
return false;
}
@ -964,20 +964,20 @@ bool:ClassAllowSelection(client, team = -1, filter[ClassFilter] = ClassNoFilter)
new bool:zombie = GetConVarBool(g_hCvarsList[CVAR_CLASSES_ZOMBIE_SELECT]);
new bool:human = GetConVarBool(g_hCvarsList[CVAR_CLASSES_HUMAN_SELECT]);
new bool:admin = GetConVarBool(g_hCvarsList[CVAR_CLASSES_ADMIN_SELECT]);
// Since admin mode classes are optional they must be counted to verify
// that they exist.
new bool:adminexist;
// Check if player is admin.
new bool:isadmin = ZRIsClientAdmin(client);
// Only count admin mode classes if client is admin.
if (isadmin)
{
adminexist = ClassCountTeam(ZR_CLASS_TEAM_ADMINS, filter) > 0;
}
// Check if a team id is specified.
if (team >= 0)
{
@ -998,7 +998,7 @@ bool:ClassAllowSelection(client, team = -1, filter[ClassFilter] = ClassNoFilter)
return admin && isadmin && adminexist;
}
}
// Team ID didn't match.
return false;
}
@ -1012,7 +1012,7 @@ bool:ClassAllowSelection(client, team = -1, filter[ClassFilter] = ClassNoFilter)
/**
* Gets all class indexes or from a specified team, and adds them to the
* specified array.
*
*
* @param array The destination array to add class indexes.
* @param teamfilter Optional. The team ID to filter. A negative value
* for no filter (default).
@ -1032,17 +1032,17 @@ stock bool:ClassAddToArray(Handle:array, teamfilter = -1, filter[ClassFilter] =
{
return false;
}
// Check if there are no classes.
if (ClassCount == 0)
{
return false;
}
// Store a local boolean that says if the user specified a team filter or not.
new bool:hasteamfilter = bool:(teamfilter >= 0);
new classesadded;
// Loop through all classes.
for (new classindex = 0; classindex < ClassCount; classindex++)
{
@ -1052,7 +1052,7 @@ stock bool:ClassAddToArray(Handle:array, teamfilter = -1, filter[ClassFilter] =
// The class is didn't pass the filter, skip class.
continue;
}
// Check team filtering.
if (hasteamfilter)
{
@ -1071,7 +1071,7 @@ stock bool:ClassAddToArray(Handle:array, teamfilter = -1, filter[ClassFilter] =
classesadded++;
}
}
if (classesadded)
{
return true;
@ -1103,11 +1103,11 @@ stock ClassCountTeam(teamfilter = -1, filter[ClassFilter] = ClassNoFilter, cache
{
return 0;
}
// Store a local boolean that says if the user specified a team filter or not.
new bool:hasteamfilter = bool:(teamfilter >= 0);
new count;
// Loop through all classes.
for (new classindex = 0; classindex < ClassCount; classindex++)
{
@ -1117,7 +1117,7 @@ stock ClassCountTeam(teamfilter = -1, filter[ClassFilter] = ClassNoFilter, cache
// The class is didn't pass the filter, skip class.
continue;
}
// Check team filtering.
if (hasteamfilter)
{
@ -1134,7 +1134,7 @@ stock ClassCountTeam(teamfilter = -1, filter[ClassFilter] = ClassNoFilter, cache
count++;
}
}
// Return number of classes found.
return count;
}
@ -1158,16 +1158,16 @@ stock ClassGetRandomClass(teamfilter = -1, filter[ClassFilter] = ClassNoSpecialC
new arraycount;
new randnum;
new buffer;
classarray = CreateArray();
// Try to get a class list.
if (ClassAddToArray(classarray, teamfilter, filter, cachetype))
{
// Get a random index from the new class array.
arraycount = GetArraySize(classarray);
randnum = GetRandomInt(0, arraycount - 1);
// Return the value at the random index.
buffer = GetArrayCell(classarray, randnum);
CloseHandle(classarray);
@ -1203,9 +1203,9 @@ stock ClassGetFirstClass(teamfilter = -1, filter[ClassFilter] = ClassNoSpecialCl
{
return false;
}
new bool:hasteamfilter = bool:(teamfilter >= 0);
// Loop through all classes.
for (new classindex = 0; classindex < ClassCount; classindex++)
{
@ -1215,7 +1215,7 @@ stock ClassGetFirstClass(teamfilter = -1, filter[ClassFilter] = ClassNoSpecialCl
// The class is didn't pass the filter, skip class.
continue;
}
if (hasteamfilter)
{
if (teamfilter == ClassGetTeamID(classindex, cachetype))
@ -1230,7 +1230,7 @@ stock ClassGetFirstClass(teamfilter = -1, filter[ClassFilter] = ClassNoSpecialCl
return classindex;
}
}
return -1;
}
@ -1253,9 +1253,9 @@ stock ClassGetDefaultClass(teamid, filter[ClassFilter] = ClassNoSpecialClasses,
new Handle:classarray;
new arraycount;
new classindex;
classarray = CreateArray();
// Get all classes from the specified team.
if (!ClassAddToArray(classarray, teamid, filter, cachetype))
{
@ -1263,14 +1263,14 @@ stock ClassGetDefaultClass(teamid, filter[ClassFilter] = ClassNoSpecialClasses,
CloseHandle(classarray);
return -1;
}
// Loop through all classes and return the first class marked as team default.
arraycount = GetArraySize(classarray);
for (new i = 0; i < arraycount; i++)
{
// Get class index from the array.
classindex = GetArrayCell(classarray, i);
// Check if the current class is marked as team default.
if (ClassGetTeamDefault(classindex, cachetype))
{
@ -1279,7 +1279,7 @@ stock ClassGetDefaultClass(teamid, filter[ClassFilter] = ClassNoSpecialClasses,
return classindex;
}
}
CloseHandle(classarray);
return -1;
}
@ -1303,7 +1303,7 @@ stock ClassGetDefaultSpawnClass(teamid, filter[ClassFilter] = ClassNoSpecialClas
{
decl String:classname[64];
new classindex;
// Get the default class name from the correct CVAR depending on teamid.
switch (teamid)
{
@ -1325,7 +1325,7 @@ stock ClassGetDefaultSpawnClass(teamid, filter[ClassFilter] = ClassNoSpecialClas
return -1;
}
}
// Check if the class name isn't empty.
if (strlen(classname) > 0)
{
@ -1335,7 +1335,7 @@ stock ClassGetDefaultSpawnClass(teamid, filter[ClassFilter] = ClassNoSpecialClas
// Get a list of all classes with the specified team ID. Deny
// classes with special flags.
classindex = ClassGetRandomClass(teamid, filter, cachetype);
// Validate the result, in case there were errors.
if (ClassValidateIndex(classindex))
{
@ -1352,10 +1352,10 @@ stock ClassGetDefaultSpawnClass(teamid, filter[ClassFilter] = ClassNoSpecialClas
else
{
// The user set a spesific class.
// Try to get the class index with the specified class name.
classindex = ClassGetIndex(classname, cachetype);
// Validate the class index and check if the team IDs match.
if (ClassValidateIndex(classindex) && (teamid == ClassGetTeamID(classindex, cachetype)))
{
@ -1367,9 +1367,9 @@ stock ClassGetDefaultSpawnClass(teamid, filter[ClassFilter] = ClassNoSpecialClas
// Because it's user input, we'll fall back to the first class
// in the specified team, and log a warning.
classindex = ClassGetFirstClass(teamid, filter, cachetype);
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Default Spawn Class", "Warning: Failed to set \"%s\" as default spawn class for team %d. The class doesn't exist or the team IDs doesn't match. Falling back to the first class in the team.", classname, teamid);
// Validate the new index.
if (ClassValidateIndex(classindex))
{

View File

@ -4,7 +4,7 @@
* Zombie:Reloaded
*
* File: healthregen.inc
* Type: Core
* Type: Core
* Description: Functions for managing health regeneration on a client.
*
* Copyright (C) 2009-2013 Greyscale, Richard Helgeby
@ -66,7 +66,7 @@ ClassHealthRegenStart(client, Float:interval)
{
// Stop timer if it already exist.
ClassHealthRegenStop(client);
// Create new timer.
tHealthRegen[client] = CreateTimer(interval, ClassHealthRegenTimer, client, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
}
@ -97,16 +97,16 @@ public Action:ClassHealthRegenTimer(Handle:timer, any:client)
tHealthRegen[client] = INVALID_HANDLE;
return Plugin_Stop;
}
new health = GetClientHealth(client);
new health = GetClientHealth(client);
health += ClientHealthRegenAmount[client];
// Check if the health points is below the limit.
if (health < ClientHealthRegenMax[client])
{
// Increase health.
SetEntityHealth(client, health);
}
return Plugin_Continue;
}

View File

@ -4,7 +4,7 @@
* Zombie:Reloaded
*
* File: playerclasses.inc
* Type: Core
* Type: Core
* Description: Provides functions for managing classes.
*
* Copyright (C) 2009-2013 Greyscale, Richard Helgeby
@ -32,11 +32,11 @@
below) they turn into zombies.
- Fully imune to all damage. Can't take or give damage. Sould only be used
on admin mode classes.
TODO: Make class attributes for for changing model render mode and colors.
TODO: Make class attributes for fancy effects, like a glow (if possible).
TODO: Make immunity settings suitable for both teams, or certain zombie-
only/human-only settings.
*/
@ -249,38 +249,38 @@ enum ClassAttributes
Class_Flags,
String:Class_Group[64],
String:Class_SM_Flags[64],
String:Class_Name[64],
String:Class_Description[256],
/* Model */
String:Class_ModelPath[PLATFORM_MAX_PATH],
Class_ModelSkinIndex,
Class_AlphaInitial,
Class_AlphaDamaged,
Class_AlphaDamage,
/* Hud */
String:Class_OverlayPath[PLATFORM_MAX_PATH],
bool:Class_Nvgs,
Class_Fov,
/* Effects */
bool:Class_HasNapalm,
Float:Class_NapalmTime,
/* Player behaviour */
ImmunityMode:Class_ImmunityMode,
Class_ImmunityAmount,
Class_ImmunityCooldown,
bool:Class_NoFallDamage,
Class_Health,
Float:Class_HealthRegenInterval,
Class_HealthRegenAmount,
Class_HealthInfectGain,
Class_KillBonus,
Float:Class_Speed,
Float:Class_KnockBack,
Float:Class_JumpHeight,
@ -304,27 +304,27 @@ enum ClassEditableAttributes
ClassEdit_AlphaInitial,
ClassEdit_AlphaDamaged,
ClassEdit_AlphaDamage,
/* Hud */
String:ClassEdit_OverlayPath[PLATFORM_MAX_PATH],
ClassEdit_Nvgs,
ClassEdit_Fov,
/* Effects */
ClassEdit_HasNapalm,
Float:ClassEdit_NapalmTime,
/* Player behavior */
ImmunityMode:ClassEdit_ImmunityMode,
ClassEdit_ImmunityAmount,
ClassEdit_ImmunityCooldown,
ClassEdit_NoFallDamage,
Float:ClassEdit_RegenInterval,
ClassEdit_RegenAmount,
ClassEdit_InfectGain,
ClassEdit_KillBonus,
Float:ClassEdit_Speed,
Float:ClassEdit_KnockBack,
Float:ClassEdit_JumpHeight,
@ -525,41 +525,41 @@ ClassLoad()
{
// Register config file.
ConfigRegisterConfig(File_Classes, Structure_Keyvalue, CONFIG_FILE_ALIAS_CLASSES);
new Handle:kvClassData;
// Make sure kvClassData is ready to use.
kvClassData = CreateKeyValues(CONFIG_FILE_ALIAS_CLASSES);
// Get weapons config path.
decl String:pathclasses[PLATFORM_MAX_PATH];
new bool:exists = ConfigGetCvarFilePath(CVAR_CONFIG_PATH_CLASSES, pathclasses);
// If file doesn't exist, then log and stop.
if (!exists)
{
LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Missing playerclasses config file \"%s\"", pathclasses);
// Remove key/value cache.
CloseHandle(kvClassData);
kvClassData = INVALID_HANDLE;
return;
}
// Log what class file that is loaded.
LogEvent(false, LogType_Normal, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Loading classes from file \"%s\".", pathclasses);
// Put file data into memory.
FileToKeyValues(kvClassData, pathclasses);
// Try to find the first class.
KvRewind(kvClassData);
if (!KvGotoFirstSubKey(kvClassData))
{
LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Can't find any classes in \"%s\"", pathclasses);
}
new String:name[64];
new String:group[64];
new String:sm_flags[64];
@ -567,11 +567,11 @@ ClassLoad()
new String:model_path[PLATFORM_MAX_PATH];
new String:immunity_mode[32];
new String:overlay_path[PLATFORM_MAX_PATH];
ClassCount = 0;
new failedcount;
new ClassErrorFlags;
// Loop through all classes and store attributes in the ClassData array.
do
{
@ -579,70 +579,70 @@ ClassLoad()
{
// Maximum classes reached. Write a warning and exit the loop.
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Maximum classes reached (%d). Skipping other classes.", ZR_CLASS_MAX + 1);
break;
}
/* General */
ClassData[ClassCount][Class_Enabled] = ConfigKvGetStringBool(kvClassData, "enabled", ZR_CLASS_DEFAULT_ENABLED);
ClassData[ClassCount][Class_Team] = KvGetNum(kvClassData, "team", ZR_CLASS_DEFAULT_TEAM);
ClassData[ClassCount][Class_TeamDefault] = ConfigKvGetStringBool(kvClassData, "team_default", ZR_CLASS_DEFAULT_TEAM_DEFAULT);
ClassData[ClassCount][Class_Flags] = KvGetNum(kvClassData, "flags", ZR_CLASS_DEFAULT_FLAGS);
KvGetString(kvClassData, "group", group, sizeof(group), ZR_CLASS_DEFAULT_GROUP);
strcopy(ClassData[ClassCount][Class_Group], 64, group);
KvGetString(kvClassData, "sm_flags", sm_flags, sizeof(sm_flags), ZR_CLASS_DEFAULT_SM_FLAGS);
strcopy(ClassData[ClassCount][Class_SM_Flags], 64, sm_flags);
KvGetString(kvClassData, "name", name, sizeof(name), ZR_CLASS_DEFAULT_NAME);
strcopy(ClassData[ClassCount][Class_Name], 64, name);
KvGetString(kvClassData, "description", description, sizeof(description), ZR_CLASS_DEFAULT_DESCRIPTION);
strcopy(ClassData[ClassCount][Class_Description], 256, description);
/* Model */
KvGetString(kvClassData, "model_path", model_path, sizeof(model_path), ZR_CLASS_DEFAULT_MODEL_PATH);
strcopy(ClassData[ClassCount][Class_ModelPath], PLATFORM_MAX_PATH, model_path);
ClassData[ClassCount][Class_ModelSkinIndex] = KvGetNum(kvClassData, "model_skin_index", ZR_CLASS_DEFAULT_MODEL_SKIN_INDEX);
ClassData[ClassCount][Class_AlphaInitial] = KvGetNum(kvClassData, "alpha_initial", ZR_CLASS_DEFAULT_ALPHA_INITIAL);
ClassData[ClassCount][Class_AlphaDamaged] = KvGetNum(kvClassData, "alpha_damaged", ZR_CLASS_DEFAULT_ALPHA_DAMAGED);
ClassData[ClassCount][Class_AlphaDamage] = KvGetNum(kvClassData, "alpha_damage", ZR_CLASS_DEFAULT_ALPHA_DAMAGE);
/* Hud */
KvGetString(kvClassData, "overlay_path", overlay_path, sizeof(overlay_path), ZR_CLASS_DEFAULT_OVERLAY_PATH);
strcopy(ClassData[ClassCount][Class_OverlayPath], PLATFORM_MAX_PATH, overlay_path);
ClassData[ClassCount][Class_Nvgs] = ConfigKvGetStringBool(kvClassData, "nvgs", ZR_CLASS_DEFAULT_NVGS);
ClassData[ClassCount][Class_Fov] = KvGetNum(kvClassData, "fov", ZR_CLASS_DEFAULT_FOV);
/* Effects */
ClassData[ClassCount][Class_HasNapalm] = ConfigKvGetStringBool(kvClassData, "has_napalm", ZR_CLASS_DEFAULT_HAS_NAPALM);
ClassData[ClassCount][Class_NapalmTime] = KvGetFloat(kvClassData, "napalm_time", ZR_CLASS_DEFAULT_NAPALM_TIME);
/* Player behaviour */
KvGetString(kvClassData, "immunity_mode", immunity_mode, sizeof(immunity_mode), ZR_CLASS_DEFAULT_IMMUNITY_MODE);
ClassData[ClassCount][Class_ImmunityMode] = ImmunityStringToMode(immunity_mode);
ClassData[ClassCount][Class_ImmunityAmount] = KvGetNum(kvClassData, "immunity_amount", ZR_CLASS_DEFAULT_IMMUNITY_AMOUNT);
ClassData[ClassCount][Class_ImmunityCooldown] = KvGetNum(kvClassData, "immunity_cooldown", ZR_CLASS_DEFAULT_IMMUNITY_COOLDOWN);
ClassData[ClassCount][Class_NoFallDamage] = ConfigKvGetStringBool(kvClassData, "no_fall_damage", ZR_CLASS_DEFAULT_NO_FALL_DAMAGE);
ClassData[ClassCount][Class_Health] = KvGetNum(kvClassData, "health", ZR_CLASS_DEFAULT_HEALTH);
ClassData[ClassCount][Class_HealthRegenInterval] = KvGetFloat(kvClassData, "health_regen_interval", ZR_CLASS_DEFAULT_HEALTH_REGEN_INTERVAL);
ClassData[ClassCount][Class_HealthRegenAmount] = KvGetNum(kvClassData, "health_regen_amount", ZR_CLASS_DEFAULT_HEALTH_REGEN_AMOUNT);
ClassData[ClassCount][Class_HealthInfectGain] = KvGetNum(kvClassData, "health_infect_gain", ZR_CLASS_DEFAULT_HEALTH_INFECT_GAIN);
ClassData[ClassCount][Class_KillBonus] = KvGetNum(kvClassData, "kill_bonus", ZR_CLASS_DEFAULT_KILL_BONUS);
ClassData[ClassCount][Class_Speed] = KvGetFloat(kvClassData, "speed", ZR_CLASS_DEFAULT_SPEED);
ClassData[ClassCount][Class_KnockBack] = KvGetFloat(kvClassData, "knockback", ZR_CLASS_DEFAULT_KNOCKBACK);
ClassData[ClassCount][Class_JumpHeight] = KvGetFloat(kvClassData, "jump_height", ZR_CLASS_DEFAULT_JUMP_HEIGHT);
ClassData[ClassCount][Class_JumpDistance] = KvGetFloat(kvClassData, "jump_distance", ZR_CLASS_DEFAULT_JUMP_DISTANCE);
// Validate class attributes if class is enabled.
if (ClassData[ClassCount][Class_Enabled])
{
@ -653,44 +653,44 @@ ClassLoad()
// and log an error message.
ClassData[ClassCount][Class_Enabled] = false;
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Warning: Invalid class at index %d, disabled class. Class error flags: %d.", ClassCount, ClassErrorFlags);
failedcount++;
}
}
// Update the counter.
ClassCount++;
} while (KvGotoNextKey(kvClassData));
// Validate team requirements.
if (!ClassValidateTeamRequirements())
{
LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "The class configuration doesn't match the team requirements.");
}
// Validate team default requirements.
if (!ClassValidateTeamDefaults())
{
LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Couldn't find a default class for one or more teams. At least one class per team must be marked as default.");
}
// Cache class data.
ClassReloadDataCache();
// Reset selected class indexes for next spawn.
ClassResetNextIndexes();
// Mark classes as valid.
ClassValidated = true;
// Log summary.
LogEvent(false, LogType_Normal, LOG_CORE_EVENTS, LogModule_Playerclasses, "Config Validation", "Total: %d | Successful: %d | Unsuccessful: %d", ClassCount, ClassCount - failedcount, failedcount);
// Set config data.
ConfigSetConfigLoaded(File_Classes, true);
ConfigSetConfigReloadFunc(File_Classes, GetFunctionByName(GetMyHandle(), "ClassOnConfigReload"));
ConfigSetConfigPath(File_Classes, pathclasses);
// Remove key/value cache.
CloseHandle(kvClassData);
kvClassData = INVALID_HANDLE;
@ -698,7 +698,7 @@ ClassLoad()
/**
* Called when configs are being reloaded.
*
*
* @param config The config being reloaded. (only if 'all' is false)
*/
public ClassOnConfigReload(ConfigFile:config)
@ -707,7 +707,7 @@ public ClassOnConfigReload(ConfigFile:config)
ClassLoad();
}
/**
/**
* Gets the speed method.
*
* @return Speed method, or ClassSpeed_Invalid on error.
@ -716,9 +716,9 @@ ClassSpeedMethods:ClassGetSpeedMethod()
{
decl String:speedMethod[16];
speedMethod[0] = 0;
GetConVarString(g_hCvarsList[CVAR_CLASSES_SPEED_METHOD], speedMethod, sizeof(speedMethod));
if (StrEqual(speedMethod, "lmv", false))
{
return ClassSpeed_LMV;
@ -727,7 +727,7 @@ ClassSpeedMethods:ClassGetSpeedMethod()
{
return ClassSpeed_Prop;
}
return ClassSpeed_Invalid;
}
@ -743,7 +743,7 @@ bool:ClassReloadDataCache()
{
return false;
}
// Loop through all classes.
for (new classindex = 0; classindex < ClassCount; classindex++)
{
@ -756,23 +756,23 @@ bool:ClassReloadDataCache()
strcopy(ClassDataCache[classindex][Class_SM_Flags], 64, ClassData[classindex][Class_SM_Flags]);
strcopy(ClassDataCache[classindex][Class_Name], 64, ClassData[classindex][Class_Name]);
strcopy(ClassDataCache[classindex][Class_Description], 256, ClassData[classindex][Class_Description]);
/* Model */
strcopy(ClassDataCache[classindex][Class_ModelPath], PLATFORM_MAX_PATH, ClassData[classindex][Class_ModelPath]);
ClassDataCache[classindex][Class_ModelSkinIndex] = ClassData[classindex][Class_ModelSkinIndex];
ClassDataCache[classindex][Class_AlphaInitial] = ClassData[classindex][Class_AlphaInitial];
ClassDataCache[classindex][Class_AlphaDamaged] = ClassData[classindex][Class_AlphaDamaged];
ClassDataCache[classindex][Class_AlphaDamage] = ClassData[classindex][Class_AlphaDamage];
/* Hud */
strcopy(ClassDataCache[classindex][Class_OverlayPath], PLATFORM_MAX_PATH, ClassData[classindex][Class_OverlayPath]);
ClassDataCache[classindex][Class_Nvgs] = ClassData[classindex][Class_Nvgs];
ClassDataCache[classindex][Class_Fov] = ClassData[classindex][Class_Fov];
/* Effects */
ClassDataCache[classindex][Class_HasNapalm] = ClassData[classindex][Class_HasNapalm];
ClassDataCache[classindex][Class_NapalmTime] = ClassData[classindex][Class_NapalmTime];
/* Player behavior */
ClassDataCache[classindex][Class_ImmunityMode] = ClassData[classindex][Class_ImmunityMode];
ClassDataCache[classindex][Class_ImmunityAmount] = ClassData[classindex][Class_ImmunityAmount];
@ -788,7 +788,7 @@ bool:ClassReloadDataCache()
ClassDataCache[classindex][Class_JumpHeight] = ClassData[classindex][Class_JumpHeight];
ClassDataCache[classindex][Class_JumpDistance] = ClassData[classindex][Class_JumpDistance];
}
return true;
}
@ -810,7 +810,7 @@ bool:ClassReloadPlayerCache(client, classindex, cachetype = ZR_CLASS_CACHE_MODIF
{
return false;
}
switch (cachetype)
{
case ZR_CLASS_CACHE_ORIGINAL:
@ -824,23 +824,23 @@ bool:ClassReloadPlayerCache(client, classindex, cachetype = ZR_CLASS_CACHE_MODIF
strcopy(ClassPlayerCache[client][Class_SM_Flags], 64, ClassData[classindex][Class_SM_Flags]);
strcopy(ClassPlayerCache[client][Class_Name], 64, ClassData[classindex][Class_Name]);
strcopy(ClassPlayerCache[client][Class_Description], 256, ClassData[classindex][Class_Description]);
/* Model */
strcopy(ClassPlayerCache[client][Class_ModelPath], PLATFORM_MAX_PATH, ClassData[classindex][Class_ModelPath]);
ClassPlayerCache[client][Class_ModelSkinIndex] = ClassData[classindex][Class_ModelSkinIndex];
ClassPlayerCache[client][Class_AlphaInitial] = ClassData[classindex][Class_AlphaInitial];
ClassPlayerCache[client][Class_AlphaDamaged] = ClassData[classindex][Class_AlphaDamaged];
ClassPlayerCache[client][Class_AlphaDamage] = ClassData[classindex][Class_AlphaDamage];
/* Hud */
strcopy(ClassPlayerCache[client][Class_OverlayPath], PLATFORM_MAX_PATH, ClassData[classindex][Class_OverlayPath]);
ClassPlayerCache[client][Class_Nvgs] = ClassData[classindex][Class_Nvgs];
ClassPlayerCache[client][Class_Fov] = ClassData[classindex][Class_Fov];
/* Effects */
ClassPlayerCache[client][Class_HasNapalm] = ClassData[classindex][Class_HasNapalm];
ClassPlayerCache[client][Class_NapalmTime] = ClassData[classindex][Class_NapalmTime];
/* Player behavior */
ClassPlayerCache[client][Class_ImmunityMode] = ClassData[classindex][Class_ImmunityMode];
ClassPlayerCache[client][Class_ImmunityAmount] = ClassData[classindex][Class_ImmunityAmount];
@ -867,23 +867,23 @@ bool:ClassReloadPlayerCache(client, classindex, cachetype = ZR_CLASS_CACHE_MODIF
strcopy(ClassPlayerCache[client][Class_SM_Flags], 64, ClassDataCache[classindex][Class_SM_Flags]);
strcopy(ClassPlayerCache[client][Class_Name], 64, ClassDataCache[classindex][Class_Name]);
strcopy(ClassPlayerCache[client][Class_Description], 256, ClassDataCache[classindex][Class_Description]);
/* Model */
strcopy(ClassPlayerCache[client][Class_ModelPath], PLATFORM_MAX_PATH, ClassDataCache[classindex][Class_ModelPath]);
ClassPlayerCache[client][Class_ModelSkinIndex] = ClassDataCache[classindex][Class_ModelSkinIndex];
ClassPlayerCache[client][Class_AlphaInitial] = ClassDataCache[classindex][Class_AlphaInitial];
ClassPlayerCache[client][Class_AlphaDamaged] = ClassDataCache[classindex][Class_AlphaDamaged];
ClassPlayerCache[client][Class_AlphaDamage] = ClassDataCache[classindex][Class_AlphaDamage];
/* Hud */
strcopy(ClassPlayerCache[client][Class_OverlayPath], PLATFORM_MAX_PATH, ClassDataCache[classindex][Class_OverlayPath]);
ClassPlayerCache[client][Class_Nvgs] = ClassDataCache[classindex][Class_Nvgs];
ClassPlayerCache[client][Class_Fov] = ClassDataCache[classindex][Class_Fov];
/* Effects */
ClassPlayerCache[client][Class_HasNapalm] = ClassDataCache[classindex][Class_HasNapalm];
ClassPlayerCache[client][Class_NapalmTime] = ClassDataCache[classindex][Class_NapalmTime];
/* Player behavior */
ClassPlayerCache[client][Class_ImmunityMode] = ClassDataCache[classindex][Class_ImmunityMode];
ClassPlayerCache[client][Class_ImmunityAmount] = ClassDataCache[classindex][Class_ImmunityAmount];
@ -905,7 +905,7 @@ bool:ClassReloadPlayerCache(client, classindex, cachetype = ZR_CLASS_CACHE_MODIF
return false;
}
}
return true;
}
@ -918,21 +918,21 @@ bool:ClassReloadPlayerCache(client, classindex, cachetype = ZR_CLASS_CACHE_MODIF
bool:ClassReloadPlayer(client)
{
new activeclass;
// Get active class index.
activeclass = ClassGetActiveIndex(client);
// Validate index.
if (activeclass < 0)
{
return false;
}
// Refresh cache and re-apply attributes.
ClassOnClientDeath(client); // Dummy event to clean up and turn off stuff.
ClassReloadPlayerCache(client, activeclass);
ClassApplyAttributes(client);
return true;
}
@ -964,7 +964,7 @@ ClassResetMultiplierCache()
ClassResetNextIndexes(client = -1)
{
new teamid;
if (client > 0)
{
for (teamid = 0; teamid < ZR_CLASS_TEAMCOUNT; teamid++)
@ -997,7 +997,7 @@ ClassRestoreNextIndexes(client, excludeTeam = -1)
new zombie = ClassSelectedNext[client][ZR_CLASS_TEAM_ZOMBIES];
new human = ClassSelectedNext[client][ZR_CLASS_TEAM_HUMANS];
new admin = ClassSelectedNext[client][ZR_CLASS_TEAM_ADMINS];
// Check if the zombie team should be excluded.
if (excludeTeam != ZR_CLASS_TEAM_ZOMBIES)
{
@ -1007,11 +1007,11 @@ ClassRestoreNextIndexes(client, excludeTeam = -1)
// Mark next zombie class as selected.
ClassSelected[client][ZR_CLASS_TEAM_ZOMBIES] = zombie;
}
// Reset index.
ClassSelectedNext[client][ZR_CLASS_TEAM_ZOMBIES] = -1;
}
// Check if the human team should be excluded.
if (excludeTeam != ZR_CLASS_TEAM_HUMANS)
{
@ -1021,11 +1021,11 @@ ClassRestoreNextIndexes(client, excludeTeam = -1)
// Mark next zombie class as selected.
ClassSelected[client][ZR_CLASS_TEAM_HUMANS] = human;
}
// Reset index.
ClassSelectedNext[client][ZR_CLASS_TEAM_HUMANS] = -1;
}
// Check if the human team should be excluded.
if (excludeTeam != ZR_CLASS_TEAM_ADMINS)
{
@ -1035,7 +1035,7 @@ ClassRestoreNextIndexes(client, excludeTeam = -1)
// Mark next zombie class as selected.
ClassSelected[client][ZR_CLASS_TEAM_ADMINS] = admin;
}
// Reset index.
ClassSelectedNext[client][ZR_CLASS_TEAM_ADMINS] = -1;
}
@ -1052,37 +1052,37 @@ ClassClientSetDefaultIndexes(client = -1)
new bool:clientvalid = ZRIsClientValid(client);
new filter[ClassFilter];
new bool:saveclasses = GetConVarBool(g_hCvarsList[CVAR_CLASSES_SAVE]);
new zombieindex;
new humanindex;
new adminindex;
new bool:haszombie;
new bool:hashuman;
new bool:hasadmin;
/*
* SETUP CLASS FILTER
*/
// Do not require any class flags to be set.
filter[ClassFilter_RequireFlags] = 0;
// Set filter to hide mother zombie classes.
filter[ClassFilter_DenyFlags] = ZR_CLASS_FLAG_MOTHER_ZOMBIE;
// Set filter to also hide admin-only classes if not admin.
filter[ClassFilter_DenyFlags] += !ZRIsClientAdmin(client) ? ZR_CLASS_FLAG_ADMIN_ONLY : 0;
// Specify client so it can check group permissions.
filter[ClassFilter_Client] = client;
/*
* GET CLASS INDEXES
*/
// Check if a client is specified.
if (clientvalid)
{
@ -1101,11 +1101,11 @@ ClassClientSetDefaultIndexes(client = -1)
humanindex = 0;
adminindex = 0;
}
// Note: When class indexes are set on cookies, they're incremented by
// one so zero means no class set and will result in a invalid
// class index when restored.
// Check if class indexes are set and that the client pass the filter.
// Also check that the saved class' team id match with the loaded class.
// If not, fall back to default class indexes. Otherwise substract
@ -1121,7 +1121,7 @@ ClassClientSetDefaultIndexes(client = -1)
zombieindex--;
haszombie = true;
}
if (humanindex <= 0 ||
!ClassTeamCompare(humanindex - 1, ZR_CLASS_TEAM_HUMANS) ||
!ClassFilterMatch(humanindex - 1, filter))
@ -1133,7 +1133,7 @@ ClassClientSetDefaultIndexes(client = -1)
humanindex--;
hashuman = true;
}
if (adminindex <= 0 ||
!ClassTeamCompare(adminindex - 1, ZR_CLASS_TEAM_ADMINS) ||
!ClassFilterMatch(adminindex - 1, filter))
@ -1150,14 +1150,14 @@ ClassClientSetDefaultIndexes(client = -1)
{
// Set filter to exclude classes that require groups.
filter[ClassFilter_Client] = -1;
// Get default class indexes.
zombieindex = ClassGetDefaultSpawnClass(ZR_CLASS_TEAM_ZOMBIES, filter);
humanindex = ClassGetDefaultSpawnClass(ZR_CLASS_TEAM_HUMANS, filter);
adminindex = ClassGetDefaultSpawnClass(ZR_CLASS_TEAM_ADMINS, filter);
}
/*
* VALIDATE INDEXES
*/
@ -1166,21 +1166,21 @@ ClassClientSetDefaultIndexes(client = -1)
// Invalid class index. Fall back to default class in class config and
// log a warning.
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Set Default Indexes", "Warning: Failed to get the specified zombie class, falling back to default class in class config. Check spelling in \"zr_classes_default_zombie\".");
// Use default class.
zombieindex = ClassGetDefaultClass(ZR_CLASS_TEAM_ZOMBIES, filter);
}
if (!ClassValidateIndex(humanindex))
{
// Invalid class index. Fall back to default class in class config and
// log a warning.
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Playerclasses, "Set Default Indexes", "Warning: Failed to get the specified human class, falling back to default class in class config. Check spelling in \"zr_classes_default_human\".");
// Use default class.
humanindex = ClassGetDefaultClass(ZR_CLASS_TEAM_HUMANS, filter);
}
if (!ClassValidateIndex(adminindex))
{
// Invalid class index. Fall back to default class in class config if
@ -1188,12 +1188,12 @@ ClassClientSetDefaultIndexes(client = -1)
// no admin classes at all.
adminindex = ClassGetDefaultClass(ZR_CLASS_TEAM_ADMINS, filter);
}
/*
* MARK INDEXES AS SELECTED, UPDATE CACHE AND COOKIES
*/
// Check if a client is specified.
if (clientvalid)
{
@ -1201,10 +1201,10 @@ ClassClientSetDefaultIndexes(client = -1)
ClassSelected[client][ZR_CLASS_TEAM_ZOMBIES] = zombieindex;
ClassSelected[client][ZR_CLASS_TEAM_HUMANS] = humanindex;
ClassSelected[client][ZR_CLASS_TEAM_ADMINS] = adminindex;
// Copy human class data to player cache.
ClassReloadPlayerCache(client, humanindex);
// Save indexes in cookies if enabled, and not already saved.
if (saveclasses)
{
@ -1231,7 +1231,7 @@ ClassClientSetDefaultIndexes(client = -1)
ClassSelected[clientindex][ZR_CLASS_TEAM_ZOMBIES] = zombieindex;
ClassSelected[clientindex][ZR_CLASS_TEAM_HUMANS] = humanindex;
ClassSelected[clientindex][ZR_CLASS_TEAM_ADMINS] = adminindex;
// Copy human class data to player cache.
ClassReloadPlayerCache(client, humanindex);
}
@ -1261,7 +1261,7 @@ ClassSelectResult:ClassSelectClientClass(client, classIndex, bool:applyIfPossibl
new bool:iszombie = InfectIsClientInfected(client);
new teamid = ClassGetTeamID(classIndex, ZR_CLASS_CACHE_MODIFIED);
new ClassSelectResult:selectResult = ClassSelected_NoChange;
// Allow instant class change if enabled and both class and player is human.
if (applyIfPossible &&
ClassAllowInstantChange[client] &&
@ -1269,11 +1269,11 @@ ClassSelectResult:ClassSelectClientClass(client, classIndex, bool:applyIfPossibl
{
// Update selected class index.
ClassSelected[client][teamid] = classIndex;
// Update cache and apply attributes.
ClassReloadPlayerCache(client, classIndex);
ClassApplyAttributes(client);
selectResult = ClassSelected_Instant;
}
else
@ -1307,14 +1307,14 @@ ClassSelectResult:ClassSelectClientClass(client, classIndex, bool:applyIfPossibl
selectResult = ClassSelected_NextSpawn;
}
}
// Save selected class index in cookie if enabled.
// Note: Saved indexes are increased by one.
if (saveIfEnabled && GetConVarBool(g_hCvarsList[CVAR_CLASSES_SAVE]))
{
CookiesSetInt(client, g_hClassCookieClassSelected[teamid], classIndex + 1);
}
return selectResult;
}
@ -1337,123 +1337,123 @@ ClassDumpData(index, cachetype, String:buffer[], maxlen)
new cellcount;
decl String:attribute[320];
decl String:format_buffer[256];
if (maxlen == 0)
{
return 0;
}
Format(format_buffer, sizeof(format_buffer), "Class data at index %d:\n", index);
cellcount += StrCat(buffer, maxlen, format_buffer);
cellcount += StrCat(buffer, maxlen, "-------------------------------------------------------------------------------\n");
Format(attribute, sizeof(attribute), "enabled: \"%d\"\n", ClassIsEnabled(index, cachetype));
cellcount += StrCat(buffer, maxlen, attribute);
Format(attribute, sizeof(attribute), "team: \"%d\"\n", ClassGetTeamID(index, cachetype));
cellcount += StrCat(buffer, maxlen, attribute);
Format(attribute, sizeof(attribute), "team_default: \"%d\"\n", ClassGetTeamDefault(index, cachetype));
cellcount += StrCat(buffer, maxlen, attribute);
Format(attribute, sizeof(attribute), "flags: \"%d\"\n", ClassGetFlags(index, cachetype));
cellcount += StrCat(buffer, maxlen, attribute);
ClassGetGroup(index, format_buffer, sizeof(format_buffer), cachetype);
Format(attribute, sizeof(attribute), "group: \"%s\"\n", format_buffer);
cellcount += StrCat(buffer, maxlen, attribute);
ClassGetSM_Flags(index, format_buffer, sizeof(format_buffer), cachetype);
Format(attribute, sizeof(attribute), "sm_flags: \"%s\"\n", format_buffer);
cellcount += StrCat(buffer, maxlen, attribute);
ClassGetName(index, format_buffer, sizeof(format_buffer), cachetype);
Format(attribute, sizeof(attribute), "name: \"%s\"\n", format_buffer);
cellcount += StrCat(buffer, maxlen, attribute);
ClassGetDescription(index, format_buffer, sizeof(format_buffer), cachetype);
Format(attribute, sizeof(attribute), "description: \"%s\"\n", format_buffer);
cellcount += StrCat(buffer, maxlen, attribute);
ClassGetModelPath(index, format_buffer, sizeof(format_buffer), cachetype);
Format(attribute, sizeof(attribute), "model_path: \"%s\"\n", format_buffer);
cellcount += StrCat(buffer, maxlen, attribute);
Format(attribute, sizeof(attribute), "model_skin_index: \"%d\"\n", ClassGetModelSkinIndex(index, cachetype));
cellcount += StrCat(buffer, maxlen, attribute);
Format(attribute, sizeof(attribute), "alpha_initial: \"%d\"\n", ClassGetAlphaInitial(index, cachetype));
cellcount += StrCat(buffer, maxlen, attribute);
Format(attribute, sizeof(attribute), "alpha_damaged: \"%d\"\n", ClassGetAlphaDamaged(index, cachetype));
cellcount += StrCat(buffer, maxlen, attribute);
Format(attribute, sizeof(attribute), "alpha_damage: \"%d\"\n", ClassGetAlphaDamage(index, cachetype));
cellcount += StrCat(buffer, maxlen, attribute);
ClassGetOverlayPath(index, format_buffer, sizeof(format_buffer), cachetype);
Format(attribute, sizeof(attribute), "overlay_path: \"%s\"\n", format_buffer);
cellcount += StrCat(buffer, maxlen, attribute);
Format(attribute, sizeof(attribute), "nvgs: \"%d\"\n", ClassGetNvgs(index, cachetype));
cellcount += StrCat(buffer, maxlen, attribute);
Format(attribute, sizeof(attribute), "fov: \"%d\"\n", ClassGetFOV(index, cachetype));
cellcount += StrCat(buffer, maxlen, attribute);
Format(attribute, sizeof(attribute), "has_napalm: \"%d\"\n", ClassGetHasNapalm(index, cachetype));
cellcount += StrCat(buffer, maxlen, attribute);
Format(attribute, sizeof(attribute), "napalm_time: \"%f\"\n", ClassGetNapalmTime(index, cachetype));
cellcount += StrCat(buffer, maxlen, attribute);
ImmunityModeToString(ClassGetImmunityMode(index, cachetype), format_buffer, sizeof(format_buffer));
Format(attribute, sizeof(attribute), "immunity_mode: \"%s\"\n", format_buffer);
cellcount += StrCat(buffer, maxlen, attribute);
Format(attribute, sizeof(attribute), "immunity_amount: \"%d\"\n", ClassGetImmunityAmount(index, cachetype));
cellcount += StrCat(buffer, maxlen, attribute);
Format(attribute, sizeof(attribute), "immunity_cooldown: \"%d\"\n", ClassGetImmunityCooldown(index, cachetype));
cellcount += StrCat(buffer, maxlen, attribute);
Format(attribute, sizeof(attribute), "no_fall_damage: \"%d\"\n", ClassGetNoFallDamage(index, cachetype));
cellcount += StrCat(buffer, maxlen, attribute);
Format(attribute, sizeof(attribute), "health: \"%d\"\n", ClassGetHealth(index, cachetype));
cellcount += StrCat(buffer, maxlen, attribute);
Format(attribute, sizeof(attribute), "health_regen_interval: \"%f\"\n", ClassGetHealthRegenInterval(index, cachetype));
cellcount += StrCat(buffer, maxlen, attribute);
Format(attribute, sizeof(attribute), "health_regen_amount: \"%d\"\n", ClassGetHealthRegenAmount(index, cachetype));
cellcount += StrCat(buffer, maxlen, attribute);
Format(attribute, sizeof(attribute), "health_infect_gain: \"%d\"\n", ClassGetHealthInfectGain(index, cachetype));
cellcount += StrCat(buffer, maxlen, attribute);
Format(attribute, sizeof(attribute), "kill_bonus: \"%d\"\n", ClassGetKillBonus(index, cachetype));
cellcount += StrCat(buffer, maxlen, attribute);
Format(attribute, sizeof(attribute), "speed: \"%f\"\n", ClassGetSpeed(index, cachetype));
cellcount += StrCat(buffer, maxlen, attribute);
Format(attribute, sizeof(attribute), "knockback: \"%f\"\n", ClassGetKnockback(index, cachetype));
cellcount += StrCat(buffer, maxlen, attribute);
Format(attribute, sizeof(attribute), "jump_height: \"%f\"\n", ClassGetJumpHeight(index, cachetype));
cellcount += StrCat(buffer, maxlen, attribute);
Format(attribute, sizeof(attribute), "jump_distance: \"%f\"\n", ClassGetJumpDistance(index, cachetype));
cellcount += StrCat(buffer, maxlen, attribute);
return cellcount;
}
/**
* Converts a multiplier attribute to a human readable string.
*
* @param client The client index to translate correct language.
* @param client The client index to translate correct language.
* @param attribute Attribute to convert.
* @param buffer Destination string buffer.
* @param maxlen Size of buffer.
@ -1462,7 +1462,7 @@ ClassDumpData(index, cachetype, String:buffer[], maxlen)
ClassMultiplierToString(client, ClassMultipliers:attribute, String:buffer[], maxlen)
{
decl String:phrase[48];
SetGlobalTransTarget(client);
switch (attribute)
{
@ -1512,6 +1512,6 @@ ClassMultiplierToString(client, ClassMultipliers:attribute, String:buffer[], max
return strcopy(buffer, maxlen, phrase);
}
}
return 0;
}

View File

@ -4,7 +4,7 @@
* Zombie:Reloaded
*
* File: respawn.inc
* Type: Module
* Type: Module
* Description: Players come back to life
*
* Copyright (C) 2009-2013 Greyscale, Richard Helgeby
@ -43,24 +43,24 @@ new Handle:tRespawn[MAXPLAYERS + 1];
/**
* Array for flagging zombies who were killed by world.
*/
*/
new bool:bKilledByWorld[MAXPLAYERS + 1];
/**
* Client is joining the server.
*/
*/
RespawnClientInit(client)
{
// Reset timer handle.
tRespawn[client] = INVALID_HANDLE;
// Init bKilledByWorld for client.
bKilledByWorld[client] = false;
}
/**
* Client is spawning into the game.
*
*
* @param client The client index.
*/
RespawnOnClientSpawn(client)
@ -70,14 +70,14 @@ RespawnOnClientSpawn(client)
{
KillTimer(tRespawn[client]);
}
// Reset timer handle.
tRespawn[client] = INVALID_HANDLE;
}
/**
* Client has been killed.
*
*
* @param client The client index.
*/
RespawnOnClientDeath(client, attacker, const String:weapon[])
@ -88,26 +88,26 @@ RespawnOnClientDeath(client, attacker, const String:weapon[])
// Set bKilledByWorld to true if attacker is not a valid client.
bKilledByWorld[client] = !ZRIsClientValid(attacker);
}
// If timer is running, kill it.
if (tRespawn[client] != INVALID_HANDLE)
{
KillTimer(tRespawn[client]);
}
// If player was infected, then stop.
if (StrEqual(weapon, "zombie_claws_of_death", false))
{
return;
}
// If respawn is disabled, stop here.
new bool:respawn = GetConVarBool(g_hCvarsList[CVAR_RESPAWN]);
if (!respawn)
{
return;
}
// Start respawn timer.
new Float:delay = GetConVarFloat(g_hCvarsList[CVAR_RESPAWN_DELAY]);
tRespawn[client] = CreateTimer(delay, RespawnTimer, client, TIMER_FLAG_NO_MAPCHANGE);
@ -126,16 +126,16 @@ RespawnOnRoundEnd()
{
continue;
}
// If timer isn't currently running, then stop.
if (tRespawn[x] == INVALID_HANDLE)
{
continue;
}
// Stop timer.
KillTimer(tRespawn[x]);
// Reset timer handle.
tRespawn[x] = INVALID_HANDLE;
}
@ -143,7 +143,7 @@ RespawnOnRoundEnd()
/**
* Spawns a player into the round.
*
*
* @param client The client index.
* @param zombie Respawn as zombie.
* @param zombieIfSuicide Respawn as zombie if killed by world damage.
@ -157,32 +157,32 @@ bool:RespawnSpawnClient(client, bool:zombie = false, bool:zombieIfSuicide = fals
{
return false;
}
// Get respawn condition.
new RespawnCondition:condition = RespawnToContition(zombie, zombieIfSuicide);
// Trigger API forward.
new Action:result = APIOnClientRespawn(client, condition);
// Check if respawn should be stopped.
if (result == Plugin_Handled)
{
return false;
}
// Restore respawn condition.
RespawnRestoreCondition(condition, zombie, zombieIfSuicide);
new bool:ragdollremove = GetConVarBool(g_hCvarsList[CVAR_VEFFECTS_RAGDOLL_REMOVE]);
if (!ragdollremove)
{
// Detatch ragdoll so it's not removed on respawn.
RagdollResetClientRagdoll(client);
}
// Spawn player.
CS_RespawnPlayer(client);
// Check if first zombie has spawned.
if (InfectHasZombieSpawned())
{
@ -198,51 +198,51 @@ bool:RespawnSpawnClient(client, bool:zombie = false, bool:zombieIfSuicide = fals
bKilledByWorld[client] = false;
}
}
// Forward event to modules.
APIOnClientRespawned(client, condition);
return true;
}
/**
* Timer callback, respawns a player.
*
*
* @param timer The timer handle.
* @param client The client index.
*/
*/
public Action:RespawnTimer(Handle:timer, any:client)
{
// Reset timer handle.
tRespawn[client] = INVALID_HANDLE;
// If client isn't in-game, then stop.
if (!IsClientInGame(client))
{
return;
}
// If player already is alive, then stop.
if (IsPlayerAlive(client))
{
return;
}
// Get client team.
new team = GetClientTeam(client);
// If player isn't on a team, then stop.
if (team != CS_TEAM_T && team != CS_TEAM_CT)
{
return;
}
// Get whether player should respawn as zombie.
new bool:zombie = GetConVarBool(g_hCvarsList[CVAR_RESPAWN_TEAM_ZOMBIE]);
// Get whether zombies died by suicide should respawn as zombies.
new bool:zombieIfSuicide = GetConVarBool(g_hCvarsList[CVAR_RESPAWN_TEAM_ZOMBIE_WORLD]);
// Spawn player.
RespawnSpawnClient(client, zombie, zombieIfSuicide);
}
@ -260,7 +260,7 @@ RespawnCondition:RespawnToContition(bool:zombie, bool:zombieIfSuicide)
{
return Respawn_ZombieIfSuicide;
}
return Respawn_Human;
}

View File

@ -52,7 +52,7 @@
* Delay between round ending and new round starting. (Normal)
*/
#define ROUNDEND_DELAY 5.0
/**
* Possible round end outcomes.
*/
@ -71,7 +71,7 @@ new Handle:tRoundEnd = INVALID_HANDLE;
/**
* Map is starting.
*/
*/
RoundEndOnMapStart()
{
// Reset timer handle.
@ -111,13 +111,13 @@ RoundEndOnRoundStart()
{
// Stop all overlays.
RoundEndOverlayStop();
// If round end timer is running, then kill it.
if (tRoundEnd != INVALID_HANDLE)
{
// Kill timer.
KillTimer(tRoundEnd);
// Reset timer handle.
tRoundEnd = INVALID_HANDLE;
}
@ -131,10 +131,10 @@ RoundEndOnRoundFreezeEnd()
// Calculate round length, in seconds.
// Get mp_roundtime. (in minutes)
new Float:roundtime = GetConVarFloat(FindConVar("mp_roundtime"));
// Convert to seconds.
roundtime *= 60.0;
// Subtract one second if running CS: GO to prevent round draw when round
// ends. For some reason the timing doesn't match the actual round end.
// Thanks to Jargon.
@ -142,14 +142,14 @@ RoundEndOnRoundFreezeEnd()
{
roundtime--;
}
// Start timer.
tRoundEnd = CreateTimer(roundtime, RoundEndTimer, _, TIMER_FLAG_NO_MAPCHANGE);
}
/**
* The round is ending.
*
*
* @param reason Reason the round has ended.
*/
RoundEndOnRoundEnd(reason)
@ -159,17 +159,17 @@ RoundEndOnRoundEnd(reason)
{
// Kill timer.
KillTimer(tRoundEnd);
// Reset timer handle.
tRoundEnd = INVALID_HANDLE;
}
// Tell plugin no zombies have been spawned.
g_bZombieSpawned = false;
// Get outcome of the round.
new RoundEndOutcome:outcome = RoundEndReasonToOutcome(reason);
// Update team scores.
new teamscore;
switch(outcome)
@ -189,10 +189,10 @@ RoundEndOnRoundEnd(reason)
SetTeamScore(CS_TEAM_CT, ++teamscore);
}
}
// Display the overlay to all clients.
RoundEndOverlayStart(outcome);
// Balance teams if enabled.
if (GetConVarBool(g_hCvarsList[CVAR_ROUNDEND_BALANCE_TEAMS]))
{
@ -202,10 +202,10 @@ RoundEndOnRoundEnd(reason)
/**
* Convert a round_end reason, to a round winner, or draw.
*
*
* @param reason The round_end reason.
* @return The winner of the round. (see enum RoundEndOutcome)
*/
*/
RoundEndOutcome:RoundEndReasonToOutcome(reason)
{
switch(reason)
@ -226,7 +226,7 @@ RoundEndOutcome:RoundEndReasonToOutcome(reason)
return Draw;
}
}
// Return draw to satisfy compiler. (code will never reach this point.)
return Draw;
}
@ -240,20 +240,20 @@ public Action:RoundEndTimer(Handle:timer)
{
// Set the global timer handle variable to INVALID_HANDLE.
tRoundEnd = INVALID_HANDLE;
// If there aren't clients on both teams, then stop.
if (!ZRTeamHasClients())
{
return;
}
// Terminate the round with humans as the winner.
RoundEndTerminateRound(ROUNDEND_DELAY, HumansWin);
}
/**
* Checks if the round is over.
*
*
* @param outcome Set to the outcome of the round, if round is over.
* @return True if the round is over, false otherwise.
*/
@ -265,30 +265,30 @@ bool:RoundEndGetRoundStatus(&RoundEndOutcome:outcome)
// Round isn't over.
return false;
}
// Initialize count variables
new zombiecount;
new humancount;
// Count valid clients. (true to only allow living clients)
ZRCountValidClients(zombiecount, humancount, true);
// If there are no clients on either teams, then stop.
if (!zombiecount && !humancount)
{
// Round isn't active.
return false;
}
// If there are clients on both teams, then stop.
if (zombiecount && humancount)
{
// Round isn't over.
return false;
}
// We know here, that either zombiecount or humancount is 0. (not both)
// If there are zombies, then zombies won the round.
if (zombiecount)
{
@ -299,15 +299,15 @@ bool:RoundEndGetRoundStatus(&RoundEndOutcome:outcome)
{
outcome = HumansWin;
}
// Round is over.
return true;
}
/**
* Ends the round with the given outcome and delay.
*
* @param delay Delay before new round starts.
*
* @param delay Delay before new round starts.
* @param outcome The outcome of the round.
*/
RoundEndTerminateRound(Float:delay, RoundEndOutcome:outcome = Restart)
@ -345,51 +345,51 @@ RoundEndBalanceTeams()
// Create eligible player list.
new Handle:arrayEligibleClients = INVALID_HANDLE;
new eligibleclients = ZRCreateEligibleClientList(arrayEligibleClients, true);
// If there are no eligible client's then stop.
if (!eligibleclients)
{
// Destroy handle.
CloseHandle(arrayEligibleClients);
return;
}
new client;
// Move all clients to T
// x = Array index.
// client = client index.
for (new x = 0; x < eligibleclients; x++)
{
// Get client stored in array index.
client = GetArrayCell(arrayEligibleClients, x);
// Switch client to T
CS_SwitchTeam(client, CS_TEAM_T);
}
// Move every other client back to CT
// x = array index
// client = client index.
for (new x = 0; x < eligibleclients; x += 2)
{
// Get client stored in array index.
client = GetArrayCell(arrayEligibleClients, x);
// Switch client to CT
CS_SwitchTeam(client, CS_TEAM_CT);
}
// Destroy handle.
CloseHandle(arrayEligibleClients);
}
/**
* Displays overlays to clients, depending on the outcome.
*
*
* @param time Time to display overlays.
* @param outcome The outcome of the round.
*/
@ -401,9 +401,9 @@ RoundEndOverlayStart(RoundEndOutcome:outcome)
{
return;
}
decl String:overlaypath[PLATFORM_MAX_PATH];
switch(outcome)
{
// Show "zombies win" overlay.
@ -422,7 +422,7 @@ RoundEndOverlayStart(RoundEndOutcome:outcome)
strcopy(overlaypath, sizeof(overlaypath), "");
}
}
// x = client index.
for (new x = 1; x <= MaxClients; x++)
{
@ -431,13 +431,13 @@ RoundEndOverlayStart(RoundEndOutcome:outcome)
{
continue;
}
// If client is fake (or bot), then stop.
if (IsFakeClient(x))
{
continue;
}
OverlaysClientSetChannelPath(x, OVERLAYS_CHANNEL_ROUNDEND, overlaypath);
OverlaysClientSetChannelState(x, OVERLAYS_CHANNEL_ROUNDEND, true, false, true);
}
@ -453,13 +453,13 @@ RoundEndOverlayStop()
{
continue;
}
// If client is fake (or bot), then stop.
if (IsFakeClient(x))
{
continue;
}
// Disable roundend overlay channel.
OverlaysClientSetChannelState(x, OVERLAYS_CHANNEL_ROUNDEND, true, false, false, true);
}

View File

@ -32,7 +32,7 @@
/**
* Client is spawning into the game.
*
*
* @param client The client index.
*/
RoundStartOnClientSpawn(client)
@ -42,7 +42,7 @@ RoundStartOnClientSpawn(client)
{
return;
}
// Print to client, how to access ZMenu.
TranslationPrintToChat(client, "General zmenu reminder", SAYHOOKS_CHAT_PUBLIC_DEFAULT, SAYHOOKS_KEYWORD_ZMENU);
}
@ -54,7 +54,7 @@ RoundStartOnRoundStart()
{
// Print round objective to all clients.
TranslationPrintToChatAll(true, false, "General round objective");
// Kill all objective entities.
RoundStartKillObjectives();
}
@ -65,10 +65,10 @@ RoundStartOnRoundStart()
stock RoundStartKillObjectives()
{
decl String:classname[64];
// Get max entity count.
new maxentities = GetMaxEntities();
// x = entity index.
for (new x = 0; x <= maxentities; x++)
{
@ -77,10 +77,10 @@ stock RoundStartKillObjectives()
{
continue;
}
// Get valid edict's classname.
GetEdictClassname(x, classname, sizeof(classname));
// Check if it matches any objective entities, then stop if it doesn't.
if(StrContains(ROUNDSTART_OBJECTIVE_ENTITIES, classname) > -1)
{

View File

@ -32,23 +32,23 @@
* String: "Bacon, Egg, Egg, Milk, Butter"
* Shopping List: "Bacon, Eggx2, Milk, Butter"
* Function parameters will include options to change the "," to any character. As well as the "x2" format.
*
*
* More complex examples:
* String: "Red - Green - Blue-Red- Green -Green - Yellow -Grey" Note: Horribly formatted, but we can handle it.
* Shopping List: "Red(2)\nGreen(3)\nBlue\nYellow\nGrey" Note: We can change what to separate each item with, as well as how to display the quantity.
*
*
* List Options:
*
*
* Construct: Take a string and dump out a list. Simple.
* Remove: Removes an item from the list. Must remove from the end to preserve list order.
*
*
* Scenario:
* String: "Apple, Orange, Mango, Orange"
* Shopping List: "Apple, Orange x2, Mango"
* Remove: "Orange"
* Remove first orange: "Apple, Mango, Orange" Different order.
* Remove last orange: "Apple, Orange, Mango" Yay.
*
*
*/
/**
@ -64,7 +64,7 @@
* Takes a given string and outputs a re-formatted shopping list styled list. See description above.
* Note: This is for display purposes only, meaning there will be no API made to format the output of this function.
* If you plan on the list being dynamic, store the raw string and use the API to edit those.
*
*
* @param list Raw string to be formatted.
* @param shoppinglist Outputted shopping list.
* @param slist_maxlen The maximum length of the shopping list.
@ -77,57 +77,57 @@ stock ShoppingListConstruct(const String:list[], String:shoppinglist[], slist_ma
// Put each item in a list.
new String:items[SHOPPINGLIST_MAXITEMS][SHOPPINGLIST_MAXLEN];
ExplodeString(list, in_token, items, SHOPPINGLIST_MAXITEMS, SHOPPINGLIST_MAXLEN);
// Put each item in a trie where we count each item.
new Handle:trieItems = CreateTrie();
new item_count;
new validstrings;
// x = Array index.
for (new x = 0; x < SHOPPINGLIST_MAXITEMS; x++)
{
// Trim off any whitespace.
TrimString(items[x]);
// If there are no more items left, exit the loop.
if (!items[x][0])
break;
// Reset item_count to 0, retrieve value, if it already exists, and set value + 1.
item_count = 0;
GetTrieValue(trieItems, items[x], item_count);
SetTrieValue(trieItems, items[x], ++item_count);
validstrings++;
}
// Initialize 'shoppinglist'.
strcopy(shoppinglist, slist_maxlen, "");
decl String:item_formatted[SHOPPINGLIST_MAXLEN];
decl String:strQuantity[8];
// x = Array index.
for (new x = 0; x < validstrings; x++)
{
// Get quantity count, in string and int.
GetTrieValue(trieItems, items[x], item_count);
// If the item_count is 0, this item is already in the shopping list.
if (item_count == 0)
continue;
IntToString(item_count, strQuantity, sizeof(strQuantity));
strcopy(item_formatted, sizeof(item_formatted), items[x]);
// Format the quantity on if there was more than 1.
if (item_count > 1)
{
Format(item_formatted, sizeof(item_formatted), "%s%s", item_formatted, quantityformat);
ReplaceString(item_formatted, sizeof(item_formatted), "##", strQuantity);
}
// Format the item onto the list.
if (!shoppinglist[0])
{
@ -137,10 +137,10 @@ stock ShoppingListConstruct(const String:list[], String:shoppinglist[], slist_ma
{
Format(shoppinglist, slist_maxlen, "%s%s%s", shoppinglist, out_token, item_formatted);
}
SetTrieValue(trieItems, items[x], 0);
}
// Destroy the trie handle.
CloseHandle(trieItems);
}
@ -149,69 +149,69 @@ stock ShoppingListConstruct(const String:list[], String:shoppinglist[], slist_ma
* Add an item to the list.
* Notes:
* For max number of items, and the max length of each item, see SHOPPINGLIST_* defines at the top.
*
*
* @param list The list to remove item from.
* @param maxlen The maximum length of the finished list.
* @param item The item to remove from the list.
* @param token The token to remove with the item.
* @return True if the item was found and removed, false if not found.
* @param token The token to remove with the item.
* @return True if the item was found and removed, false if not found.
*/
public bool:ShoppingListRemove(String:list[], maxlen, const String:item[], const String:token[])
{
// Explode the items into an array.
new String:items[SHOPPINGLIST_MAXITEMS][SHOPPINGLIST_MAXLEN];
ExplodeString(list, token, items, SHOPPINGLIST_MAXITEMS, SHOPPINGLIST_MAXLEN);
new validstrings;
// x = Array index.
for (new x = SHOPPINGLIST_MAXITEMS - 1; x >= 0; x--)
{
// Trim off any whitespace.
TrimString(items[x]);
if (StrEqual(item, items[x], false))
{
// Nullify the matching string.
items[x][0] = 0;
// Re-copy each index after the matching string to overwrite it.
// Re-copy each index after the matching string to overwrite it.
for (new y = x; y < SHOPPINGLIST_MAXITEMS - 1; y++)
items[y] = items[y + 1];
// Implode the array of strings back together into a full string.
ImplodeStrings(items, validstrings + x, token, list, maxlen);
return true;
}
// If this is a valid string, count it.
if (items[x][0])
validstrings++;
}
return false;
}
/**
*
*
*
* BROKEN STUFF
* Attempted versions of the above code.
* The working version is mostly (99%) Frus's code.
*
*
*
*/
/**
* Add an item to the list.
*
*
* @param list The list to remove item from.
* @param maxlen The maximum length of the finished list.
* @param item The item to remove from the list.
* @param token The token to remove with the item.
* @return True if the item was found and removed, false if not found.
* @param token The token to remove with the item.
* @return True if the item was found and removed, false if not found.
*/
/*stock bool:ShoppingListRemove(String:list[], maxlen, const String:item[], const String:token[])
{
@ -221,46 +221,46 @@ public bool:ShoppingListRemove(String:list[], maxlen, const String:item[], const
while (itemindex == itemindex2)
{
itemindex2 = pos = StrContains(list[pos], item, false);
if (itemindex2 != -1)
{
itemindex = itemindex2;
pos += 1;
PrintToServer("%d %d %d %s", itemindex, itemindex2, pos, list[pos]);
}
else
break;
}
if (itemindex == -1)
return false;
PrintToServer("position %d", itemindex);
return true;
}*/
/**
* Add an item to the list.
*
*
* @param list The list to remove item from.
* @param maxlen The maximum length of the finished list.
* @param maxitems The maximum number of shopping items.
* @param maxitemlen The maximum length of EACH item in the string.
* @param item The item to remove from the list.
* @param token The token to remove with the item.
* @return True if the item was found and removed, false if not found.
* @param token The token to remove with the item.
* @return True if the item was found and removed, false if not found.
*/
/*stock bool:ShoppingListRemove(String:list[], maxlen, maxitems, maxitemlen, const String:item[], const String:token[])
{
// Default initialized value = false.
new bool:success;
// Put each item in a list.
new String:items[maxitems][maxitemlen];
ExplodeString(list, token, items, maxitems, maxitemlen);
// x = List index.
for (new x = maxitems - 1; x >= 0; x--)
{
@ -272,24 +272,24 @@ public bool:ShoppingListRemove(String:list[], maxlen, const String:item[], const
break;
}
}
new String:items_after[maxitems][maxitemlen];
new count;
// x = List index.
for (new x = 0; x < maxitems; x++)
{
PrintToServer("%d \"%s\"", x, items[x]);
if (!items[x][0])
continue;
// Move valid item to new array, and increment count after.
strcopy(items_after[count++], maxitemlen, items[x]);
}
// Join the valid strings back together.
ImplodeStrings(items_after, count, token, list, maxlen);
return success;
}*/

View File

@ -4,7 +4,7 @@
* Zombie:Reloaded
*
* File: ambientsounds.inc
* Type: Core
* Type: Core
* Description: Plays ambient sounds to clients.
*
* Copyright (C) 2009-2013 Greyscale, Richard Helgeby
@ -27,7 +27,7 @@
/**
* Global variable that tells if ambient sound cvar data was loaded successfully.
*/
*/
new bool:g_bAmbientSounds;
/**
@ -38,7 +38,7 @@ new Handle:tAmbientSounds = INVALID_HANDLE;
/**
* Array for flagging client to play sound.
*/
new bool:bAmbientSoundsIsPlaying[MAXPLAYERS + 1];
new bool:bAmbientSoundsIsPlaying[MAXPLAYERS + 1];
/**
* Load ambient sound data.
@ -51,7 +51,7 @@ AmbientSoundsLoad()
/**
* Client is joining the server.
*
*
* @param client The client index.
*/
AmbientSoundsClientInit(client)
@ -72,12 +72,12 @@ bool:AmbientSoundsValidateConfig()
g_bAmbientSounds = false;
return false;
}
// Get ambient sound file.
decl String:sound[SOUND_MAX_PATH];
GetConVarString(g_hCvarsList[CVAR_AMBIENTSOUNDS_FILE], sound, sizeof(sound));
Format(sound, sizeof(sound), "sound/%s", sound);
// If file doesn't exist, then log error and stop.
if (!FileExists(sound, true))
{
@ -85,30 +85,30 @@ bool:AmbientSoundsValidateConfig()
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_SEffects, "Config Validation", "Invalid sound file specified in \"zr_ambientsounds_file\": %s", sound);
return false;
}
// If volume is muted or invalid, then log error and stop.
new Float:ambientvolume = GetConVarFloat(g_hCvarsList[CVAR_AMBIENTSOUNDS_VOLUME]);
if (ambientvolume <= 0.0)
{
// Log invalid ambient sound volume error.
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_SEffects, "Config Validation", "Ambient sound volume specified in \"zr_ambientsounds_volume\" is either muted or invalid.");
return false;
}
// If length is invalid, then log error and stop.
new Float:ambientlength = GetConVarFloat(g_hCvarsList[CVAR_AMBIENTSOUNDS_LENGTH]);
if (ambientlength <= 0.0)
{
// Log invalid ambient sound length error.
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_SEffects, "Config Validation", "Ambient sound length specified in \"zr_ambientsounds_length\" is invalid.");
return false;
}
// Add sound file to downloads table.
AddFileToDownloadsTable(sound);
g_bAmbientSounds = true;
return true;
}
@ -145,7 +145,7 @@ AmbientSoundsOnRoundEnd()
/**
* Client is spawning into the game.
*
*
* @param client The client index.
*/
AmbientSoundsOnClientSpawnPost(client)
@ -155,23 +155,23 @@ AmbientSoundsOnClientSpawnPost(client)
{
return;
}
// If flag is enabled, then stop.
if (bAmbientSoundsIsPlaying[client])
{
return;
}
// Get ambient sound file.
decl String:sound[SOUND_MAX_PATH];
GetConVarString(g_hCvarsList[CVAR_AMBIENTSOUNDS_FILE], sound, sizeof(sound));
// Get ambient sound volume.
new Float:ambientvolume = GetConVarFloat(g_hCvarsList[CVAR_AMBIENTSOUNDS_VOLUME]);
// Emit ambient sound.
SEffectsEmitAmbientSound(sound, ambientvolume, client);
// Flag client that sound is playing.
bAmbientSoundsIsPlaying[client] = true;
}
@ -187,24 +187,24 @@ AmbientSoundsRestart()
KillTimer(tAmbientSounds);
tAmbientSounds = INVALID_HANDLE;
}
// If ambience is disabled, then stop.
if (!g_bAmbientSounds)
{
return;
}
// Get ambient sound length.
new Float:ambientlength = GetConVarFloat(g_hCvarsList[CVAR_AMBIENTSOUNDS_LENGTH]);
// Start ambient sounds timer.
tAmbientSounds = CreateTimer(ambientlength, AmbientSoundsTimer, _, TIMER_FLAG_NO_MAPCHANGE);
}
/**
* Timer callback, Replays ambient sound on all clients.
*
* @param timer The timer handle.
*
* @param timer The timer handle.
*/
public Action:AmbientSoundsTimer(Handle:timer)
{
@ -213,23 +213,23 @@ public Action:AmbientSoundsTimer(Handle:timer)
{
return;
}
// Get ambient sound file.
decl String:sound[SOUND_MAX_PATH];
GetConVarString(g_hCvarsList[CVAR_AMBIENTSOUNDS_FILE], sound, sizeof(sound));
// Get ambient sound volume.
new Float:ambientvolume = GetConVarFloat(g_hCvarsList[CVAR_AMBIENTSOUNDS_VOLUME]);
// Stop sound before playing again.
SEffectsStopAmbientSound(sound);
// Emit ambient sound.
SEffectsEmitAmbientSound(sound, ambientvolume);
// Get ambient sound length.
new Float:ambientlength = GetConVarFloat(g_hCvarsList[CVAR_AMBIENTSOUNDS_LENGTH]);
// Start new timer with sound length as delay.
tAmbientSounds = CreateTimer(ambientlength, AmbientSoundsTimer, _, TIMER_FLAG_NO_MAPCHANGE);
}

View File

@ -4,7 +4,7 @@
* Zombie:Reloaded
*
* File: soundeffects.inc
* Type: Core
* Type: Core
* Description: Basic sound-management API.
*
* Copyright (C) 2009-2013 Greyscale, Richard Helgeby
@ -50,7 +50,7 @@ SEffectsLoad()
/**
* Map is starting.
*/
*/
SEffectsOnMapStart()
{
// Forward event to sub-modules.
@ -59,7 +59,7 @@ SEffectsOnMapStart()
/**
* Client is joining the server.
*
*
* @param client The client index.
*/
SEffectsClientInit(client)
@ -92,7 +92,7 @@ SEffectsOnRoundEnd()
/**
* Client is spawning into the game.
*
*
* @param client The client index.
*/
SEffectsOnClientSpawn(client)
@ -104,7 +104,7 @@ SEffectsOnClientSpawn(client)
/**
* Client is spawning into the game. *Post
*
*
* @param client The client index.
*/
SEffectsOnClientSpawnPost(client)
@ -115,7 +115,7 @@ SEffectsOnClientSpawnPost(client)
/**
* Client has been killed.
*
*
* @param client The client index.
*/
SEffectsOnClientDeath(client)
@ -126,7 +126,7 @@ SEffectsOnClientDeath(client)
/**
* Client has been hurt.
*
*
* @param client The client index.
*/
SEffectsOnClientHurt(client)
@ -137,7 +137,7 @@ SEffectsOnClientHurt(client)
/**
* Client has been infected.
*
*
* @param client The client index.
*/
SEffectsOnClientInfected(client)
@ -149,7 +149,7 @@ SEffectsOnClientInfected(client)
/**
* Client has been turned back human.
*
*
* @param client The client index.
*/
SEffectsOnClientHuman(client)
@ -160,7 +160,7 @@ SEffectsOnClientHuman(client)
/**
* Emits an ambient sound
*
*
* @param sound The path to the sound file (relative to sounds/)
* @param soundvolume The volume of the sound (0.0 - 1.0)
* @param client (Optional) Client index to play sound to.
@ -169,12 +169,12 @@ SEffectsEmitAmbientSound(const String:sound[], Float:ambientvolume = 1.0, client
{
// Precache sound before playing.
PrecacheSound(sound);
if (ZRIsClientValid(client))
{
// Emit ambient sound.
EmitSoundToClient(client, sound, SOUND_FROM_PLAYER, SOUND_AMBIENT_CHANNEL, _, _, ambientvolume);
// Flag client that sound is playing.
bAmbientSoundsIsPlaying[client] = true;
}
@ -187,7 +187,7 @@ SEffectsEmitAmbientSound(const String:sound[], Float:ambientvolume = 1.0, client
{
continue;
}
// Emit ambient sound.
EmitSoundToClient(x, sound, SOUND_FROM_PLAYER, SNDCHAN_AUTO, _, _, ambientvolume);
}
@ -196,8 +196,8 @@ SEffectsEmitAmbientSound(const String:sound[], Float:ambientvolume = 1.0, client
/**
* Stop an ambient sound
*
* @param sound The path to the sound file (relative to sounds/)
*
* @param sound The path to the sound file (relative to sounds/)
*/
SEffectsStopAmbientSound(const String:sound[])
{
@ -209,7 +209,7 @@ SEffectsStopAmbientSound(const String:sound[])
{
continue;
}
// Stop ambient sound.
StopSound(x, SOUND_AMBIENT_CHANNEL, sound);
}
@ -217,13 +217,13 @@ SEffectsStopAmbientSound(const String:sound[])
/**
* Replay an ambient sound
*
*
* @param sound The path to the sound file (relative to sounds/)
*/
*/
/**
* Emits a sound from a client.
*
*
* @param client The client index.
* @param sound The sound file relative to the sound/ directory.
* @param level The attenuation of the sound.
@ -232,7 +232,7 @@ SEffectsEmitSoundFromClient(client, const String:sound[], level = SNDLEVEL_NORMA
{
// Precache sound before playing.
PrecacheSound(sound);
// Emit sound from client.
EmitSoundToAll(sound, client, _, level);
}

View File

@ -36,13 +36,13 @@ new bool:g_bVoice;
VoiceOnRoundStart()
{
new bool:voice = GetConVarBool(g_hCvarsList[CVAR_VOICE]);
// If the cvar has changed, then reset the voice permissions.
if (g_bVoice != voice)
{
VoiceReset();
}
// Update g_bVoice with new value.
g_bVoice = voice;
}
@ -57,14 +57,14 @@ VoiceOnRoundEnd()
{
return;
}
// Allow everyone to listen/speak with each other.
VoiceAllTalk();
}
/**
* Client is spawning into the game.
*
*
* @param client The client index.
*/
VoiceOnClientSpawn(client)
@ -75,7 +75,7 @@ VoiceOnClientSpawn(client)
/**
* Client has been infected.
*
*
* @param client The client index.
*/
VoiceOnClientInfected(client)
@ -86,7 +86,7 @@ VoiceOnClientInfected(client)
/**
* Client has been turned back human.
*
*
* @param client The client index.
*/
VoiceOnClientHuman(client)
@ -110,9 +110,9 @@ stock bool:VoiceSetClientListening(iReceiver, iSender, bool:bListen)
{
return false;
}
new ListenOverride:override = bListen ? Listen_Yes : Listen_No;
return SetListenOverride(iReceiver, iSender, override);
}
@ -130,7 +130,7 @@ stock VoiceAllTalk()
{
continue;
}
for (new y = 1; y <= MaxClients; y++)
{
// If sender isn't in-game, then stop.
@ -138,13 +138,13 @@ stock VoiceAllTalk()
{
continue;
}
// No need to alter listening/speaking flags between one client.
if (x == y)
{
continue;
}
// Receiver (x) can now hear the sender (y), only if sender isn't muted.
VoiceSetClientListening(x, y, true);
}
@ -153,7 +153,7 @@ stock VoiceAllTalk()
/**
* Set which team the client is allowed to listen/speak with.
*
*
* @param client The client index.
* @param zombie True to permit verbal communication to zombies only, false for humans only.
*/
@ -167,16 +167,16 @@ stock VoiceSetClientTeam(client, bool:zombie)
{
continue;
}
// No need to alter listening/speaking flags between one client.
if (client == x)
{
continue;
}
// Client can only listen/speak if the sender is on their team.
new bool:canlisten = (zombie == InfectIsClientInfected(x));
// (Dis)allow clients to listen/speak with each other, don't touch if the sender is muted.
VoiceSetClientListening(client, x, canlisten);
VoiceSetClientListening(x, client, canlisten);
@ -185,7 +185,7 @@ stock VoiceSetClientTeam(client, bool:zombie)
/**
* Update a client's listening/speaking status.
*
*
* @param client The client index.
*/
stock VoiceUpdateClient(client)
@ -195,14 +195,14 @@ stock VoiceUpdateClient(client)
{
return;
}
// Set the client's listening/speaking status to their current team.
VoiceSetClientTeam(client, InfectIsClientInfected(client));
}
/**
* This function returns if the client is muted.
*
*
* @param client The client index.
* @return True if the client is muted, false if not.
*/
@ -219,10 +219,10 @@ stock VoiceReset()
{
// Is alltalk enabled?
new bool:alltalk = GetConVarBool(FindConVar("sv_alltalk"));
// Determine new voice flags based off of alltalk.
new voiceflags = alltalk ? VOICE_SPEAKALL | VOICE_LISTENALL : VOICE_TEAM | VOICE_LISTENTEAM;
// x = Client index.
for (new x = 1; x <= MaxClients; x++)
{
@ -231,7 +231,7 @@ stock VoiceReset()
{
continue;
}
// Apply new voice flags.
SetClientListeningFlags(x, voiceflags);
}

View File

@ -4,7 +4,7 @@
* Zombie:Reloaded
*
* File: zombiesounds.inc
* Type: Core
* Type: Core
* Description: Zombie sound effects.
*
* Copyright (C) 2009-2013 Greyscale, Richard Helgeby
@ -64,7 +64,7 @@ enum ZombieSounds
Groan, /** When zombie is hurt */
Death, /** When a zombie is killed */
}
/**
* Array for storing zombie moaning timer handles per client.
*/
@ -82,14 +82,14 @@ new Handle:g_hSEffectsCommandTimer[MAXPLAYERS + 1];
/**
* Client is joining the server.
*
*
* @param client The client index.
*/
ZombieSoundsClientInit(client)
{
// Reset timer handle.
tSEffectsMoan[client] = INVALID_HANDLE;
// Reset command counter and make sure there's no timer running.
g_SEffectsCommandCount[client] = 0;
ZREndTimer(g_hSEffectsCommandTimer[client]);
@ -97,7 +97,7 @@ ZombieSoundsClientInit(client)
/**
* Client is spawning into the game.
*
*
* @param client The client index.
*/
ZombieSoundsOnClientSpawn(client)
@ -107,10 +107,10 @@ ZombieSoundsOnClientSpawn(client)
{
KillTimer(tSEffectsMoan[client]);
}
// Reset timer handle.
tSEffectsMoan[client] = INVALID_HANDLE;
// Reset command counter and kill timer.
g_SEffectsCommandCount[client] = 0;
ZREndTimer(g_hSEffectsCommandTimer[client]);
@ -118,7 +118,7 @@ ZombieSoundsOnClientSpawn(client)
/**
* Client has been killed.
*
*
* @param client The client index.
*/
ZombieSoundsOnClientDeath(client)
@ -128,37 +128,37 @@ ZombieSoundsOnClientDeath(client)
{
KillTimer(tSEffectsMoan[client]);
}
// Reset timer handle.
tSEffectsMoan[client] = INVALID_HANDLE;
// Reset command counter and kill timer.
g_SEffectsCommandCount[client] = 0;
ZREndTimer(g_hSEffectsCommandTimer[client]);
// If player isn't a zombie, then stop.
if (!InfectIsClientInfected(client))
{
return;
}
// If death sound cvar is disabled, then stop.
new bool:death = GetConVarBool(g_hCvarsList[CVAR_SEFFECTS_DEATH]);
if (!death)
{
return;
}
// Get random death sound.
decl String:sound[SOUND_MAX_PATH];
ZombieSoundsGetRandomSound(sound, Death);
SEffectsEmitSoundFromClient(client, sound);
}
/**
* Client has been hurt.
*
*
* @param client The client index.
*/
ZombieSoundsOnClientHurt(client)
@ -168,28 +168,28 @@ ZombieSoundsOnClientHurt(client)
{
return;
}
// Get groan factor, if 0, then stop.
new groan = GetConVarInt(g_hCvarsList[CVAR_SEFFECTS_GROAN]);
if (!groan)
{
return;
}
// 1 in 'groan' chance of groaning.
if (GetRandomInt(1, groan) == 1)
{
// Get random groan sound.
decl String:sound[SOUND_MAX_PATH];
ZombieSoundsGetRandomSound(sound, Groan);
SEffectsEmitSoundFromClient(client, sound);
}
}
/**
* Client has been infected.
*
*
* @param client The client index.
*/
ZombieSoundsOnClientInfected(client)
@ -200,13 +200,13 @@ ZombieSoundsOnClientInfected(client)
{
return;
}
// If timer is currently running, kill it.
if (tSEffectsMoan[client] != INVALID_HANDLE)
{
KillTimer(tSEffectsMoan[client]);
}
// Start repeating timer.
tSEffectsMoan[client] = CreateTimer(interval, ZombieSoundsMoanTimer, client, TIMER_FLAG_NO_MAPCHANGE|TIMER_REPEAT);
}
@ -236,14 +236,14 @@ ZombieSoundsOnCommandsCreate()
*
* @param sound The randomly picked sound.
* @param soundtype The type of sound to get. (See enum ZombieSounds)
* @return True if sound was successfully picked, false otherwise.
*/
* @return True if sound was successfully picked, false otherwise.
*/
bool:ZombieSoundsGetRandomSound(String:sound[], ZombieSounds:soundtype)
{
new soundmin;
new soundmax;
decl String:soundpath[SOUND_MAX_PATH];
switch(soundtype)
{
// Find moan sound.
@ -252,7 +252,7 @@ bool:ZombieSoundsGetRandomSound(String:sound[], ZombieSounds:soundtype)
// Copy min and max
soundmin = SOUND_MOAN_MIN;
soundmax = SOUND_MOAN_MAX;
// Copy path
strcopy(soundpath, sizeof(soundpath), SOUND_MOAN_PATH);
}
@ -262,7 +262,7 @@ bool:ZombieSoundsGetRandomSound(String:sound[], ZombieSounds:soundtype)
// Copy min and max
soundmin = SOUND_GROAN_MIN;
soundmax = SOUND_GROAN_MAX;
// Copy path
strcopy(soundpath, sizeof(soundpath), SOUND_GROAN_PATH);
}
@ -272,7 +272,7 @@ bool:ZombieSoundsGetRandomSound(String:sound[], ZombieSounds:soundtype)
// Copy min and max
soundmin = SOUND_DEATH_MIN;
soundmax = SOUND_DEATH_MAX;
// Copy path
strcopy(soundpath, sizeof(soundpath), SOUND_DEATH_PATH);
}
@ -283,20 +283,20 @@ bool:ZombieSoundsGetRandomSound(String:sound[], ZombieSounds:soundtype)
return false;
}
}
// Pick a random integer between min and max sound file index.
new randsound = GetRandomInt(soundmin, soundmax);
// Format random index into sound path.
Format(sound, SOUND_MAX_PATH, soundpath, randsound);
// Found sound.
return true;
}
/**
* Timer callback, repeats a moaning sound on zombies.
*
*
* @param timer The timer handle.
* @param client The client index.
*/
@ -307,14 +307,14 @@ public Action:ZombieSoundsMoanTimer(Handle:timer, any:client)
{
// Reset timer handle.
tSEffectsMoan[client] = INVALID_HANDLE;
// Stop timer.
return Plugin_Stop;
}
// Emit moan sound.
ZombieSoundsMoan(client);
// Allow timer to continue.
return Plugin_Continue;
}
@ -329,7 +329,7 @@ ZombieSoundsMoan(client)
// Get random moan sound.
decl String:sound[SOUND_MAX_PATH];
ZombieSoundsGetRandomSound(sound, Moan);
// Emit sound from client.
SEffectsEmitSoundFromClient(client, sound, SNDLEVEL_SCREAMING);
}
@ -343,7 +343,7 @@ ZombieSoundsScream(client)
{
decl String:sound[PLATFORM_MAX_PATH];
GetConVarString(g_hCvarsList[CVAR_INFECT_SOUND], sound, sizeof(sound));
// If cvar contains path, then continue.
if (sound[0])
{
@ -363,7 +363,7 @@ ZombieSoundsCmdTimerCheck(client)
if (g_hSEffectsCommandTimer[client] == INVALID_HANDLE)
{
new Float:timespan = GetConVarFloat(g_hCvarsList[CVAR_SEFFECTS_COMMAND_TIMESPAN]);
// Only create timer if time span is enabled.
if (timespan > 0.0)
{
@ -403,13 +403,13 @@ ZombieSoundsResetCmdTimers()
bool:ZombieSoundsCommandAllowed(client)
{
new limit = GetConVarInt(g_hCvarsList[CVAR_SEFFECTS_COMMAND_LIMIT]);
if (limit <= 0 ||
g_SEffectsCommandCount[client] < limit)
{
return true;
}
return false;
}
@ -427,7 +427,7 @@ public Action:ZombieSoundsScreamCommand(client, argc)
g_SEffectsCommandCount[client]++;
ZombieSoundsCmdTimerCheck(client);
}
return Plugin_Handled;
}
@ -445,7 +445,7 @@ public Action:ZombieSoundsMoanCommand(client, argc)
g_SEffectsCommandCount[client]++;
ZombieSoundsCmdTimerCheck(client);
}
return Plugin_Handled;
}

View File

@ -34,10 +34,10 @@ new Handle:tSpawnProtect[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)
@ -48,9 +48,9 @@ SpawnProtectClientInit(client)
/**
* Client is spawning into the game. *Post
*
*
* @param client The client index.
*/
*/
SpawnProtectOnClientSpawnPost(client)
{
// If client is dead, then they are joining the server, not spawning.
@ -58,33 +58,33 @@ SpawnProtectOnClientSpawnPost(client)
{
return;
}
// If timer is currently running, kill it.
if (tSpawnProtect[client] != INVALID_HANDLE)
{
KillTimer(tSpawnProtect[client]);
}
// Reset timer handle.
tSpawnProtect[client] = INVALID_HANDLE;
// If protect cvar is disabled, then stop.
new bool:protect = GetConVarBool(g_hCvarsList[CVAR_SPAWNPROTECT]);
if (!protect)
{
return;
}
// Disable spawn protection on client.
bInfectImmune[client][INFECT_TYPE_NORMAL] = false;
// Start spawn protection.
SpawnProtectStart(client);
}
/**
* Client has been killed.
*
*
* @param client The client index.
*/
SpawnProtectOnClientDeath(client)
@ -94,14 +94,14 @@ SpawnProtectOnClientDeath(client)
{
KillTimer(tSpawnProtect[client]);
}
// Reset timer handle.
tSpawnProtect[client] = INVALID_HANDLE;
}
/**
* Start spawn protection on a client.
*
*
* @param client The client index.
*/
SpawnProtectStart(client)
@ -111,23 +111,23 @@ SpawnProtectStart(client)
{
return;
}
// If zombie hasn't spawned, then stop.
if (!InfectHasZombieSpawned())
{
return;
}
// If client is a zombie, then stop.
if (InfectIsClientInfected(client))
{
return;
}
// Get spawn protect attribute cvars.
new Float:speed = GetConVarFloat(g_hCvarsList[CVAR_SPAWNPROTECT_SPEED]);
new alpha = GetConVarInt(g_hCvarsList[CVAR_SPAWNPROTECT_ALPHA]);
// Validate attributes
new Float:min;
new Float:max;
@ -156,34 +156,34 @@ SpawnProtectStart(client)
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModules:LogModule_Config, "Config validation", "Out of range value in cvar zr_spawnprotect_alpha (%d). Aborting spawn protection.", alpha);
return;
}
// Set spawn protect flag on client.
bInfectImmune[client][INFECT_TYPE_NORMAL] = true;
// Set spawn protect attributes.
ClassApplySpeedEx(client, speed);
ToolsSetClientAlpha(client, alpha);
// Set time left to zr_protect_time's value.
new protect_time = GetConVarInt(g_hCvarsList[CVAR_SPAWNPROTECT_TIME]);
pSpawnProtectTime[client] = protect_time;
// Tell client they are being protected.
TranslationPrintToChat(client, "Spawn protection begin", protect_time);
// Send time left in a hud message.
TranslationPrintHintText(client, "Spawn Protect", pSpawnProtectTime[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.
@ -193,7 +193,7 @@ public Action:SpawnProtectTimer(Handle:timer, any:client)
tSpawnProtect[client] = INVALID_HANDLE;
return Plugin_Stop;
}
// If client has become a zombie, then stop timer.
if (!InfectIsClientHuman(client))
{
@ -201,33 +201,33 @@ public Action:SpawnProtectTimer(Handle:timer, any:client)
tSpawnProtect[client] = INVALID_HANDLE;
return Plugin_Stop;
}
// Decrement time left.
pSpawnProtectTime[client]--;
// Print time left to client.
TranslationPrintHintText(client, "Spawn Protect", pSpawnProtectTime[client]);
// Time has expired.
if (pSpawnProtectTime[client] <= 0)
{
// Remove protect flag.
bInfectImmune[client][INFECT_TYPE_NORMAL] = false;
// Tell client spawn protection is over.
TranslationPrintHintText(client, "Spawn protection end");
// Fix attributes.
ToolsSetClientAlpha(client, ClassGetAlphaInitial(client));
ClassApplySpeedEx(client, ClassGetSpeed(client));
// Clear timer handle.
tSpawnProtect[client] = INVALID_HANDLE;
// Stop timer.
return Plugin_Stop;
}
// Allow timer to continue repeating.
return Plugin_Continue;
}

View File

@ -32,7 +32,7 @@
/**
* Creates a steamid cache.
*
*
* @return Handle to SteamID cache.
*/
stock Handle:SteamidCacheCreate()
@ -43,7 +43,7 @@ stock Handle:SteamidCacheCreate()
/**
* Add client serial number to the SteamID cache.
*
*
* @param steamidcache The SteamID cache to add client to.
* @param client The client index.
* @return True if the client was added successfully, false if the client already exists.
@ -55,21 +55,21 @@ stock bool:SteamidCacheAddClient(Handle:steamidcache, client)
{
return false;
}
// Get client's SteamID.
new String:steamid[STEAMIDCACHE_MAX_LENGTH];
GetClientAuthId(client, AuthId_SteamID64, steamid, sizeof(steamid), true);
// Push SteamID into the SteamID cache.
PushArrayString(steamidcache, steamid);
// Client added successfully.
return true;
}
/**
* Check if a client is in the SteamID cache.
*
*
* @param steamidcache The SteamID cache to check in.
* @param client The client index.
* @return True if the client exists, false otherwise.
@ -79,14 +79,14 @@ stock bool:SteamidCacheClientExists(Handle:steamidcache, client)
// Get client's SteamID.
decl String:steamid[STEAMIDCACHE_MAX_LENGTH];
GetClientAuthId(client, AuthId_SteamID64, steamid, sizeof(steamid), true);
// Return true if client was found, false otherwise.
return (FindStringInArray(steamidcache, steamid) != -1);
}
/**
* Reset SteamID cache.
*
*
* @param steamidcache The SteamID cache to reset.
*/
stock SteamidCacheReset(Handle:steamidcache)

View File

@ -61,35 +61,35 @@ ToolsFindOffsets()
{
LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Tools, "Offsets", "Offset \"CBasePlayer::m_vecVelocity[0]\" was not found.");
}
// If offset "m_flLaggedMovementValue" can't be found, then stop the plugin.
g_iToolsLMV = FindSendPropInfo("CCSPlayer", "m_flLaggedMovementValue");
if (g_iToolsLMV == -1)
{
LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Tools, "Offsets", "Offset \"CCSPlayer::m_flLaggedMovementValue\" was not found.");
}
// If offset "m_bHasNightVision" can't be found, then stop the plugin.
g_iToolsHasNightVision = FindSendPropInfo("CCSPlayer", "m_bHasNightVision");
if (g_iToolsHasNightVision == -1)
{
LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Tools, "Offsets", "Offset \"CCSPlayer::m_bHasNightVision\" was not found.");
}
// If offset "m_bNightVisionOn" can't be found, then stop the plugin.
g_iToolsNightVisionOn = FindSendPropInfo("CCSPlayer", "m_bNightVisionOn");
if (g_iToolsNightVisionOn == -1)
{
LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Tools, "Offsets", "Offset \"CCSPlayer::m_bNightVisionOn\" was not found.");
}
// If offset "m_iFOV" can't be found, then stop the plugin.
g_iToolsFOV = FindSendPropInfo("CBasePlayer", "m_iFOV");
if (g_iToolsFOV == -1)
{
LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Tools, "Offsets", "Offset \"CBasePlayer::m_iFOV\" was not found.");
}
// Forward event to modules.
WeaponsOnOffsetsFound();
AccountOnOffsetsFound();

View File

@ -43,26 +43,26 @@ stock ToolsClientVelocity(client, Float:vecVelocity[3], bool:apply = true, bool:
{
vecVelocity[x] = GetEntDataFloat(client, g_iToolsVelocity + (x*4));
}
// Stop here.
return;
}
// If stack is true, then add client's velocity.
if (stack)
{
// Get client's velocity.
new Float:vecClientVelocity[3];
// x = vector component.
for (new x = 0; x < 3; x++)
{
vecClientVelocity[x] = GetEntDataFloat(client, g_iToolsVelocity + (x*4));
}
AddVectors(vecClientVelocity, vecVelocity, vecVelocity);
}
// Apply velocity on client.
TeleportEntity(client, NULL_VECTOR, NULL_VECTOR, vecVelocity);
}
@ -107,7 +107,7 @@ stock bool:ToolsGetClientNightVision(client, bool:ownership = true)
{
return bool:GetEntData(client, g_iToolsHasNightVision, 1);
}
return bool:GetEntData(client, g_iToolsNightVisionOn, 1);
}
@ -124,11 +124,11 @@ stock ToolsSetClientNightVision(client, bool:enable, bool:ownership = true)
if (ownership)
{
SetEntData(client, g_iToolsHasNightVision, enable, 1, true);
// Stop here.
return;
}
SetEntData(client, g_iToolsNightVisionOn, enable, 1, true);
}
@ -144,10 +144,10 @@ stock ToolsSetClientDefaultFOV(client, FOV)
/**
* Get or set a client's score or deaths.
*
*
* @param client The client index.
* @param score True to look at score, false to look at deaths.
* @param apply True to set scores or death, false to get.
* @param score True to look at score, false to look at deaths.
* @param apply True to set scores or death, false to get.
* @param value The value of the client's score or deaths.
* @return The score or death count of the client, -1 if setting.
*/
@ -166,7 +166,7 @@ stock ToolsClientScore(client, bool:score = true, bool:apply = true, value = 0)
return GetEntProp(client, Prop_Data, "m_iDeaths");
}
}
// If score is true, then set client's score.
if (score)
{
@ -177,14 +177,14 @@ stock ToolsClientScore(client, bool:score = true, bool:apply = true, value = 0)
{
SetEntProp(client, Prop_Data, "m_iDeaths", value);
}
// We set the client's score or deaths.
return -1;
}
/**
* Set a client's alpha value.
*
*
* @param client The client index.
* @param alpha The alpha value to set client's alpha to. (0-255)
* @param weapons Apply alpha to all client's weapons.
@ -193,10 +193,10 @@ stock ToolsSetClientAlpha(client, alpha)
{
// Turn rendermode on, on the client.
SetEntityRenderMode(client, RENDER_TRANSALPHA);
// Set alpha value on the client.
SetEntityRenderColor(client, _, _, _, alpha);
// Forward event to modules.
WeaponAlphaOnClientAlphaChanged(client, alpha);
}
@ -211,22 +211,22 @@ stock ToolsGetEntityAlpha(entity)
{
static bool:gotconfig = false;
static String:prop[32];
if (!gotconfig)
{
new Handle:gc = LoadGameConfigFile("core.games");
new bool:exists = GameConfGetKeyValue(gc, "m_clrRender", prop, sizeof(prop));
CloseHandle(gc);
if (!exists)
{
strcopy(prop, sizeof(prop), "m_clrRender");
}
gotconfig = true;
}
new offset = GetEntSendPropOffs(entity, prop);
return GetEntData(entity, offset + 3, 1);
}

View File

@ -62,24 +62,24 @@ TranslationInit()
/**
* Translate a phrase in zombiereloaded.phrases.txt
*
*
* @param client The client index
* @param translation The translated text.
* @param maxlen Maximum length of the translated string.
* @param ... Translation formatting parameters.
* @param ... Translation formatting parameters.
*/
stock TranslationTranslatePhrase(client, String:translation[], maxlen, any:...)
{
// Set translation target to given target.
SetGlobalTransTarget(client);
// Dump translation into return string.
VFormat(translation, maxlen, "%t", 3);
}
/**
* Format the string to the plugin's style.
*
*
* @param text Text to format.
* @param maxlen Maximum length of the formatted text.
*/
@ -89,44 +89,44 @@ stock TranslationPluginFormatString(String:text[], maxlen, bool:color = true)
{
// Format prefix onto the string.
Format(text, maxlen, "@green%s @default%s", TRANSLATION_PHRASE_PREFIX, text);
// Replace color tokens with CS:S color chars.
ReplaceString(text, maxlen, "@default", TRANSLATION_TEXT_COLOR_DEFAULT);
ReplaceString(text, maxlen, "@lgreen", TRANSLATION_TEXT_COLOR_LGREEN);
ReplaceString(text, maxlen, "@green", TRANSLATION_TEXT_COLOR_GREEN);
return;
}
// Format prefix onto the string.
Format(text, maxlen, "%s %s", TRANSLATION_PHRASE_PREFIX, text);
}
/**
* Print chat text to client. (with style)
*
*
* @param client The client index.
* @param ... Translation formatting parameters.
* @param ... Translation formatting parameters.
*/
stock TranslationPrintToChat(client, any:...)
{
// Set translation target
SetGlobalTransTarget(client);
// Translate phrase.
decl String:translation[TRANSLATION_MAX_LENGTH_CHAT];
VFormat(translation, sizeof(translation), "%t", 2);
// Format string to create plugin style.
TranslationPluginFormatString(translation, sizeof(translation));
// Print translated phrase to client.
PrintToChat(client, translation);
}
/**
* Format the string to the plugin's style.
*
*
* @param server True to also print text to server console, false just to clients.
* @param admin True to only print text to admins, false to print to everyone.
* @param ... Translation formatting parameters.
@ -134,22 +134,22 @@ stock TranslationPrintToChat(client, any:...)
stock TranslationPrintToChatAll(bool:server, bool:admin, any:...)
{
decl String:translation[TRANSLATION_MAX_LENGTH_CHAT];
if (server)
{
// Set translation target
SetGlobalTransTarget(LANG_SERVER);
// Translate phrase.
VFormat(translation, sizeof(translation), "%t", 3);
// Format string to create plugin style.
TranslationPluginFormatString(translation, sizeof(translation), false);
// Print phrase to server.
PrintToServer(translation);
}
// x = client index.
for (new x = 1; x <= MaxClients; x++)
{
@ -158,22 +158,22 @@ stock TranslationPrintToChatAll(bool:server, bool:admin, any:...)
{
continue;
}
// If client isn't an admin, and we're only printing to admins, then stop.
if (admin && !ZRIsClientAdmin(x))
{
continue;
}
// Set translation target to client.
SetGlobalTransTarget(x);
// Translate phrase.
VFormat(translation, sizeof(translation), "%t", 3);
// Format string to create plugin style.
TranslationPluginFormatString(translation, sizeof(translation));
// Print translated phrase to client.
PrintToChat(x, translation);
}
@ -181,51 +181,51 @@ stock TranslationPrintToChatAll(bool:server, bool:admin, any:...)
/**
* Print console text to client. (with style)
*
*
* @param client The client index.
* @param ... Translation formatting parameters.
* @param ... Translation formatting parameters.
*/
stock TranslationPrintToConsole(client, any:...)
{
// Set translation target
SetGlobalTransTarget(client);
// Translate phrase.
decl String:translation[TRANSLATION_MAX_LENGTH_CONSOLE];
VFormat(translation, sizeof(translation), "%t", 2);
// Format string to create plugin style.
TranslationPluginFormatString(translation, sizeof(translation), false);
// Print translated phrase to client.
PrintToConsole(client, translation);
}
/**
* Format the string to the plugin's style.
*
*
* @param server True to also print text to server console, false just to clients.
* @param ... Translation formatting parameters.
*/
stock TranslationPrintToConsoleAll(bool:server, bool:admin, any:...)
{
decl String:translation[TRANSLATION_MAX_LENGTH_CONSOLE];
if (server)
{
// Set translation target
SetGlobalTransTarget(LANG_SERVER);
// Translate phrase.
VFormat(translation, sizeof(translation), "%t", 3);
// Format string to create plugin style.
TranslationPluginFormatString(translation, sizeof(translation), false);
// Print phrase to server.
PrintToServer(translation);
}
// x = client index.
for (new x = 1; x <= MaxClients; x++)
{
@ -234,22 +234,22 @@ stock TranslationPrintToConsoleAll(bool:server, bool:admin, any:...)
{
continue;
}
// If client isn't an admin, and we're only printing to admins, then stop.
if (admin && !ZRIsClientAdmin(x))
{
continue;
}
// Set translation target
SetGlobalTransTarget(LANG_SERVER);
// Translate phrase.
VFormat(translation, sizeof(translation), "%t", 3);
// Format string to create plugin style.
TranslationPluginFormatString(translation, sizeof(translation), false);
// Print translated phrase to client.
PrintToConsole(x, translation);
}
@ -257,28 +257,28 @@ stock TranslationPrintToConsoleAll(bool:server, bool:admin, any:...)
/**
* Print center text to client. (with style)
*
*
* @param client The client index.
* @param ... Translation formatting parameters.
* @param ... Translation formatting parameters.
*/
stock TranslationPrintCenterText(client, any:...)
{
// Set translation target
SetGlobalTransTarget(client);
// Translate phrase.
decl String:translation[TRANSLATION_MAX_LENGTH_CHAT];
VFormat(translation, sizeof(translation), "%t", 2);
// Print translated phrase to client.
PrintCenterText(client, translation);
}
/**
* Print center text to all clients. (with style)
*
*
* @param client The client index.
* @param ... Translation formatting parameters.
* @param ... Translation formatting parameters.
*/
stock TranslationPrintCenterTextAll(bool:admin, any:...)
{
@ -289,26 +289,26 @@ stock TranslationPrintCenterTextAll(bool:admin, any:...)
{
continue;
}
// Skip clients who haven't selected a team yet (team menu open).
if (GetClientTeam(client) == CS_TEAM_NONE)
{
continue;
}
// Skip non-admins if only printing to admins.
if (admin && !ZRIsClientAdmin(client))
{
continue;
}
// Set translation target
SetGlobalTransTarget(client);
// Translate phrase.
decl String:translation[TRANSLATION_MAX_LENGTH_CHAT];
VFormat(translation, sizeof(translation), "%t", 2);
// Print translated phrase to client.
PrintCenterText(client, translation);
}
@ -316,22 +316,22 @@ stock TranslationPrintCenterTextAll(bool:admin, any:...)
/**
* Print HUD text to client. (with style)
*
*
* @param client The client index.
* @param ... Translation formatting parameters.
* @param ... Translation formatting parameters.
*/
stock TranslationPrintHintText(client, any:...)
{
// Set translation target
SetGlobalTransTarget(client);
// Translate phrase.
decl String:translation[TRANSLATION_MAX_LENGTH_CHAT];
VFormat(translation, sizeof(translation), "%t", 2);
// Print translated phrase to client.
PrintHintText(client, translation);
// Stop hint text sound in CS:S.
if (g_Game == Game_CSS)
{
@ -341,40 +341,40 @@ stock TranslationPrintHintText(client, any:...)
/**
* Print text to server. (with style)
*
* @param ... Translation formatting parameters.
*
* @param ... Translation formatting parameters.
*/
stock TranslationPrintToServer(any:...)
{
// Set translation target
SetGlobalTransTarget(LANG_SERVER);
// Translate phrase.
decl String:translation[TRANSLATION_MAX_LENGTH_CONSOLE];
VFormat(translation, sizeof(translation), "%t", 1);
// Format string to create plugin style.
TranslationPluginFormatString(translation, sizeof(translation), false);
// Print translated phrase to client.
PrintToServer(translation);
}
/**
* Print chat text to client. (with style)
*
*
* @param client The client index.
* @param ... Translation formatting parameters.
* @param ... Translation formatting parameters.
*/
stock TranslationReplyToCommand(client, any:...)
{
// Set translation target
SetGlobalTransTarget(client);
// Translate phrase.
decl String:translation[TRANSLATION_MAX_LENGTH_CONSOLE];
VFormat(translation, sizeof(translation), "%t", 2);
if (ZRIsClientValid(client))
{
// Format string to create plugin style. (color)
@ -385,7 +385,7 @@ stock TranslationReplyToCommand(client, any:...)
// Format string to create plugin style. (no color)
TranslationPluginFormatString(translation, sizeof(translation), false);
}
// Print translated phrase to server or client's chat/console.
ReplyToCommand(client, translation);
}

View File

@ -35,30 +35,30 @@ public Action:Command_Version(client, argc)
decl String:linebuffer[128];
buffer[0] = 0;
linebuffer[0] = 0;
#define FORMATSTRING "%24s: %s\n"
Format(linebuffer, sizeof(linebuffer), "%s\n", ZR_VER_PRODUCT_NAME);
StrCat(buffer, sizeof(buffer), linebuffer);
Format(linebuffer, sizeof(linebuffer), "%s\n\n", ZR_VER_COPYRIGHT);
StrCat(buffer, sizeof(buffer), linebuffer);
Format(linebuffer, sizeof(linebuffer), FORMATSTRING, "Version", ZR_VER_VERSION);
StrCat(buffer, sizeof(buffer), linebuffer);
Format(linebuffer, sizeof(linebuffer), FORMATSTRING, "Compile date", ZR_VER_DATE);
StrCat(buffer, sizeof(buffer), linebuffer);
Format(linebuffer, sizeof(linebuffer), FORMATSTRING, "License", ZR_VER_LICENSE);
StrCat(buffer, sizeof(buffer), linebuffer);
Format(linebuffer, sizeof(linebuffer), FORMATSTRING, "Build", ZR_VER_REVISION);
StrCat(buffer, sizeof(buffer), linebuffer);
Format(linebuffer, sizeof(linebuffer), FORMATSTRING, "Development branch", ZR_VER_BRANCH);
StrCat(buffer, sizeof(buffer), linebuffer);
ReplyToCommand(client, buffer);
return Plugin_Handled;
}

View File

@ -58,7 +58,7 @@ RagdollOnOffsetsFound()
/**
* Client has been killed.
*
*
* @param client The client index.
*/
RagdollOnClientDeath(client)
@ -69,79 +69,79 @@ RagdollOnClientDeath(client)
{
return;
}
new ragdoll = RagdollGetClientRagdoll(client);
// If the ragdoll is invalid, then stop.
if (ragdoll == -1)
{
return;
}
// Get the delay.
new Float:dissolvedelay = GetConVarFloat(g_hCvarsList[CVAR_VEFFECTS_RAGDOLL_DELAY]);
// If the delay is 0 or less, then remove right now.
if (dissolvedelay <= 0)
{
RagdollTimer(INVALID_HANDLE, ragdoll);
return;
}
// Create a timer to remove/dissolve ragdoll.
CreateTimer(dissolvedelay, RagdollTimer, ragdoll, TIMER_FLAG_NO_MAPCHANGE);
}
/**
* Removed a ragdoll from the game following plugin settings.
*
*
* @param ragdoll The ragdoll index.
*/
RagdollRemove(ragdoll)
{
// Get the dissolve type.
new dissolve = GetConVarInt(g_hCvarsList[CVAR_VEFFECTS_RAGDOLL_DISSOLVE]);
if (dissolve == VEFFECTS_RAGDOLL_DISSOLVE_EFFECTLESS)
{
// Remove entity from world.
AcceptEntityInput(ragdoll, "Kill");
return;
}
// If random, set value to any between "energy" effect and "core" effect.
if (dissolve == VEFFECTS_RAGDOLL_DISSOLVE_RANDOM)
{
dissolve = GetRandomInt(VEFFECTS_RAGDOLL_DISSOLVE_ENERGY, VEFFECTS_RAGDOLL_DISSOLVE_CORE);
}
// Prep the ragdoll for dissolving.
decl String:targetname[64];
Format(targetname, sizeof(targetname), "zr_dissolve_%d", ragdoll);
DispatchKeyValue(ragdoll, "targetname", targetname);
// Prep the dissolve entity.
new dissolver = CreateEntityByName("env_entity_dissolver");
// Set the target to the ragdoll.
DispatchKeyValue(dissolver, "target", targetname);
// Set the dissolve type.
decl String:dissolvetype[16];
Format(dissolvetype, sizeof(dissolvetype), "%d", dissolve);
DispatchKeyValue(dissolver, "dissolvetype", dissolvetype);
// Tell the entity to dissolve the ragdoll.
AcceptEntityInput(dissolver, "Dissolve");
// Remove the dissolver.
AcceptEntityInput(dissolver, "Kill");
}
/**
* Timer callback. Removed a client's ragdoll.
*
* @param timer The timer handle.
*
* @param timer The timer handle.
* @param ragdoll The ragdoll index.
*/
public Action:RagdollTimer(Handle:timer, any:ragdoll)
@ -152,13 +152,13 @@ public Action:RagdollTimer(Handle:timer, any:ragdoll)
{
return;
}
// If the ragdoll is already gone, then stop.
if (!IsValidEdict(ragdoll))
{
return;
}
// Make sure this edict is still a ragdoll and not become a new valid entity.
decl String:classname[64];
GetEdictClassname(ragdoll, classname, sizeof(classname));
@ -166,7 +166,7 @@ public Action:RagdollTimer(Handle:timer, any:ragdoll)
{
return;
}
// Remove the ragdoll.
RagdollRemove(ragdoll);
}

View File

@ -46,30 +46,30 @@ VAmbienceLoad()
{
// Apply all visual effects now.
VAmbienceApplyAll();
// If sky is disabled, then stop.
new bool:sky = GetConVarBool(g_hCvarsList[CVAR_VEFFECTS_SKY]);
if (!sky)
{
return;
}
decl String:downloadpath[PLATFORM_MAX_PATH];
decl String:skypath[PLATFORM_MAX_PATH];
// Get sky path.
GetConVarString(g_hCvarsList[CVAR_VEFFECTS_SKY_PATH], skypath, sizeof(skypath));
// Prepend materials/skybox to the path.
Format(downloadpath, sizeof(downloadpath), "materials/skybox/%s", skypath);
// Add skybox file to downloads table.
AddFileToDownloadsTable(downloadpath);
}
/**
* Hook zr_veffects_* cvar changes.
*
*
* @param unhook If true, cvars will be unhooked, false to hook cvars.
*/
VAmbienceCvarsHook(bool:unhook = false)
@ -80,14 +80,14 @@ VAmbienceCvarsHook(bool:unhook = false)
// Unhook lightstyle cvars.
UnhookConVarChange(g_hCvarsList[CVAR_VEFFECTS_LIGHTSTYLE], VAmbienceCvarsHookLightStyle);
UnhookConVarChange(g_hCvarsList[CVAR_VEFFECTS_LIGHTSTYLE_VALUE], VAmbienceCvarsHookLightStyle);
// Unhook sky cvars.
UnhookConVarChange(g_hCvarsList[CVAR_VEFFECTS_SKY], VAmbienceCvarsHookSky);
UnhookConVarChange(g_hCvarsList[CVAR_VEFFECTS_SKY_PATH], VAmbienceCvarsHookSky);
// Unhook sun cvars.
UnhookConVarChange(g_hCvarsList[CVAR_VEFFECTS_SUN_DISABLE], VAmbienceCvarsHookSunDisable);
// Unhook fog cvars.
UnhookConVarChange(g_hCvarsList[CVAR_VEFFECTS_FOG], VAmbienceCvarsHookFog);
UnhookConVarChange(g_hCvarsList[CVAR_VEFFECTS_FOG_OVERRIDE], VAmbienceCvarsHookFog);
@ -97,22 +97,22 @@ VAmbienceCvarsHook(bool:unhook = false)
UnhookConVarChange(g_hCvarsList[CVAR_VEFFECTS_FOG_STARTDIST], VAmbienceCvarsHookFog);
UnhookConVarChange(g_hCvarsList[CVAR_VEFFECTS_FOG_ENDDIST], VAmbienceCvarsHookFog);
UnhookConVarChange(g_hCvarsList[CVAR_VEFFECTS_FOG_FARZ], VAmbienceCvarsHookFog);
// Stop after unhooking cvars.
return;
}
// Hook lightstyle cvars.
HookConVarChange(g_hCvarsList[CVAR_VEFFECTS_LIGHTSTYLE], VAmbienceCvarsHookLightStyle);
HookConVarChange(g_hCvarsList[CVAR_VEFFECTS_LIGHTSTYLE_VALUE], VAmbienceCvarsHookLightStyle);
// Hook sky cvars.
HookConVarChange(g_hCvarsList[CVAR_VEFFECTS_SKY], VAmbienceCvarsHookSky);
HookConVarChange(g_hCvarsList[CVAR_VEFFECTS_SKY_PATH], VAmbienceCvarsHookSky);
// Hook sun cvars.
HookConVarChange(g_hCvarsList[CVAR_VEFFECTS_SUN_DISABLE], VAmbienceCvarsHookSunDisable);
// Hook fog cvars.
HookConVarChange(g_hCvarsList[CVAR_VEFFECTS_FOG], VAmbienceCvarsHookFog);
HookConVarChange(g_hCvarsList[CVAR_VEFFECTS_FOG_OVERRIDE], VAmbienceCvarsHookFog);
@ -127,7 +127,7 @@ VAmbienceCvarsHook(bool:unhook = false)
/**
* Cvar hook callback (zr_veffects_lightstyle, zr_veffects_lightstyle_value)
* Updated server to cvar values.
*
*
* @param convar The cvar handle.
* @param oldvalue The value before change.
* @param newvalue The new value.
@ -136,7 +136,7 @@ public VAmbienceCvarsHookLightStyle(Handle:cvar, const String:oldvalue[], const
{
// If lightstyle is disabled, then disable.
new bool:lightstyle = GetConVarBool(g_hCvarsList[CVAR_VEFFECTS_LIGHTSTYLE]);
// Apply light style.
VAmbienceApplyLightStyle(!lightstyle);
}
@ -144,7 +144,7 @@ public VAmbienceCvarsHookLightStyle(Handle:cvar, const String:oldvalue[], const
/**
* Cvar hook callback (zr_veffects_sky, zr_veffects_sky_path)
* Updated server to cvar values.
*
*
* @param convar The cvar handle.
* @param oldvalue The value before change.
* @param newvalue The new value.
@ -153,7 +153,7 @@ public VAmbienceCvarsHookSky(Handle:cvar, const String:oldvalue[], const String:
{
// If sky is disabled, then disable.
new bool:sky = GetConVarBool(g_hCvarsList[CVAR_VEFFECTS_SKY]);
// Apply new sky.
VAmbienceApplySky(!sky);
}
@ -161,7 +161,7 @@ public VAmbienceCvarsHookSky(Handle:cvar, const String:oldvalue[], const String:
/**
* Cvar hook callback (zr_veffects_sun_disable)
* Updated server to cvar values.
*
*
* @param convar The cvar handle.
* @param oldvalue The value before change.
* @param newvalue The new value.
@ -170,7 +170,7 @@ public VAmbienceCvarsHookSunDisable(Handle:cvar, const String:oldvalue[], const
{
// If fog is disabled, then disable.
new bool:sun = GetConVarBool(g_hCvarsList[CVAR_VEFFECTS_SUN_DISABLE]);
// Apply fog.
VAmbienceApplySunDisable(!sun);
}
@ -178,7 +178,7 @@ public VAmbienceCvarsHookSunDisable(Handle:cvar, const String:oldvalue[], const
/**
* Cvar hook callback (zr_veffects_fog_*)
* Updated server to cvar values.
*
*
* @param convar The cvar handle.
* @param oldvalue The value before change.
* @param newvalue The new value.
@ -187,7 +187,7 @@ public VAmbienceCvarsHookFog(Handle:cvar, const String:oldvalue[], const String:
{
// If fog is disabled, then disable.
new bool:fogoverride = GetConVarBool(g_hCvarsList[CVAR_VEFFECTS_FOG_OVERRIDE]);
// Apply fog.
VAmbienceApplyFog(fogoverride);
}
@ -199,19 +199,19 @@ VAmbienceApplyAll()
{
// If lightstyle is disabled, then disable.
new bool:lightstyle = GetConVarBool(g_hCvarsList[CVAR_VEFFECTS_LIGHTSTYLE]);
// Apply light style.
VAmbienceApplyLightStyle(!lightstyle);
// If sky is disabled, then disable.
new bool:sky = GetConVarBool(g_hCvarsList[CVAR_VEFFECTS_SKY]);
// Apply new sky.
VAmbienceApplySky(!sky);
// If fog is disabled, then disable.
new bool:fogoverride = GetConVarBool(g_hCvarsList[CVAR_VEFFECTS_FOG_OVERRIDE]);
// Apply fog.
VAmbienceApplyFog(fogoverride);
}
@ -223,14 +223,14 @@ VAmbienceApplyLightStyle(bool:disable = false)
{
// Set light style.
SetLightStyle(0, "n");
return;
}
// Get light value.
decl String:lightstylevalue[4];
GetConVarString(g_hCvarsList[CVAR_VEFFECTS_LIGHTSTYLE_VALUE], lightstylevalue, sizeof(lightstylevalue));
// Set light style.
SetLightStyle(0, lightstylevalue);
}
@ -243,13 +243,13 @@ VAmbienceApplySky(bool:disable = false)
{
return;
}
// Store map's default sky before applying new one.
if (!g_VAmbienceDefaultSky[0])
{
GetConVarString(hSkyname, g_VAmbienceDefaultSky, sizeof(g_VAmbienceDefaultSky));
}
// If default, then set to default sky.
if (disable)
{
@ -258,14 +258,14 @@ VAmbienceApplySky(bool:disable = false)
// Set default sky on all clients.
SetConVarString(hSkyname, g_VAmbienceDefaultSky, true);
}
return;
}
// Get sky path.
decl String:skypath[PLATFORM_MAX_PATH];
GetConVarString(g_hCvarsList[CVAR_VEFFECTS_SKY_PATH], skypath, sizeof(skypath));
// Set new sky on all clients.
SetConVarString(hSkyname, skypath, true);
}
@ -274,22 +274,22 @@ VAmbienceApplySunDisable(bool:disable = false)
{
// Find sun entity.
new sun = FindEntityByClassname(-1, "env_sun");
// If sun is invalid, then stop.
if (sun == -1)
{
return;
}
// If default, then re-enable sun rendering.
if (disable)
{
// Turn on sun rendering.
AcceptEntityInput(sun, "TurnOn");
return;
}
// Turn off sun rendering.
AcceptEntityInput(sun, "TurnOff");
}
@ -298,15 +298,15 @@ VAmbienceApplyFog(bool:override = false)
{
// If fog is disabled, then stop.
new bool:fog = GetConVarBool(g_hCvarsList[CVAR_VEFFECTS_FOG]);
if (!fog)
{
return;
}
// Find current fog index
new fogindex = FindEntityByClassname(-1, "env_fog_controller");
// If override is enabled, then continue.
if (override)
{
@ -318,7 +318,7 @@ VAmbienceApplyFog(bool:override = false)
fogindex = -1;
}
}
// If there is no fog on the map, create new fog.
if (fogindex == -1)
{
@ -326,29 +326,29 @@ VAmbienceApplyFog(bool:override = false)
fogindex = CreateEntityByName("env_fog_controller");
DispatchSpawn(fogindex);
}
decl String:fogcolor[16];
// Set primary fog color.
GetConVarString(g_hCvarsList[CVAR_VEFFECTS_FOG_PCOLOR], fogcolor, sizeof(fogcolor));
VAmbienceSetFogColor(fogindex, fogcolor, true);
// Set secondary fog color.
GetConVarString(g_hCvarsList[CVAR_VEFFECTS_FOG_SCOLOR], fogcolor, sizeof(fogcolor));
VAmbienceSetFogColor(fogindex, fogcolor, false);
// Set fog's density.
new Float:fogdensity = GetConVarFloat(g_hCvarsList[CVAR_VEFFECTS_FOG_DENSITY]);
VAmbienceSetFogDensity(fogindex, fogdensity);
// Set fog's start distance.
new fogstart = GetConVarInt(g_hCvarsList[CVAR_VEFFECTS_FOG_STARTDIST]);
VAmbienceSetFogStartDist(fogindex, fogstart);
// Set fog's end distance.
new fogend = GetConVarInt(g_hCvarsList[CVAR_VEFFECTS_FOG_ENDDIST]);
VAmbienceSetFogEndDist(fogindex, fogend);
// Set fog's far z distance.
new fogfarz = GetConVarInt(g_hCvarsList[CVAR_VEFFECTS_FOG_FARZ]);
VAmbienceSetFogFarZ(fogindex, fogfarz);
@ -356,9 +356,9 @@ VAmbienceApplyFog(bool:override = false)
/**
* Set fog's primary or secondary color.
*
*
* @param fogindex Edict index of the fog to modify.
* @param color The rgb color of the fog.
* @param color The rgb color of the fog.
* @param primary (Optional) True to set primary, false otherwise.
*/
VAmbienceSetFogColor(fogindex, const String:color[], bool:primary = true)
@ -381,9 +381,9 @@ VAmbienceSetFogColor(fogindex, const String:color[], bool:primary = true)
/**
* Set fog's density.
*
*
* @param fogindex Edict index of the fog to modify.
* @param density The density of the fog.
* @param density The density of the fog.
*/
VAmbienceSetFogDensity(fogindex, Float:density)
{
@ -393,9 +393,9 @@ VAmbienceSetFogDensity(fogindex, Float:density)
/**
* Set fog's start distance.
*
*
* @param fogindex Edict index of the fog to modify.
* @param startdist The start distance of the fog.
* @param startdist The start distance of the fog.
*/
VAmbienceSetFogStartDist(fogindex, startdist)
{
@ -406,9 +406,9 @@ VAmbienceSetFogStartDist(fogindex, startdist)
/**
* Set fog's end distance.
*
*
* @param fogindex Edict index of the fog to modify.
* @param enddist The end distance of the fog.
* @param enddist The end distance of the fog.
*/
VAmbienceSetFogEndDist(fogindex, enddist)
{
@ -419,9 +419,9 @@ VAmbienceSetFogEndDist(fogindex, enddist)
/**
* Set fog's far z distance.
*
*
* @param fogindex Edict index of the fog to modify.
* @param farz The far z distance of the fog.
* @param farz The far z distance of the fog.
*/
VAmbienceSetFogFarZ(fogindex, farz)
{

View File

@ -66,7 +66,7 @@ VEffectsOnOffsetsFound()
/**
* Client has been killed.
*
*
* @param client The client index.
*/
VEffectsOnClientDeath(client)
@ -77,7 +77,7 @@ VEffectsOnClientDeath(client)
/**
* Create an energy splash effect.
*
*
* @param client The client index.
* @param origin The origin of the effect.
* @param direction The direction of the effect.
@ -90,7 +90,7 @@ VEffectsCreateEnergySplash(const Float:origin[3], const Float:direction[3], bool
/**
* Create an explosion effect with strict flags.
*
*
* @param origin The (x, y, z) coordinate of the explosion.
* @param flags The flags to set on the explosion.
*/
@ -98,40 +98,40 @@ VEffectsCreateExplosion(const Float:origin[3], flags)
{
// Create an explosion entity.
new explosion = CreateEntityByName("env_explosion");
// If explosion entity isn't valid, then stop.
if (explosion == -1)
{
return;
}
// Get and modify flags on explosion.
new spawnflags = GetEntProp(explosion, Prop_Data, "m_spawnflags");
spawnflags = spawnflags | EXP_NODAMAGE | EXP_NODECAL | flags;
// Set modified flags on entity.
SetEntProp(explosion, Prop_Data, "m_spawnflags", spawnflags);
// Spawn the entity into the world.
DispatchSpawn(explosion);
// Set the origin of the explosion.
DispatchKeyValueVector(explosion, "origin", origin);
// Set fireball material.
PrecacheModel("materials/sprites/xfireball3.vmt");
DispatchKeyValue(explosion, "fireballsprite", "materials/sprites/xfireball3.vmt");
// Tell the entity to explode.
AcceptEntityInput(explosion, "Explode");
// Remove entity from world.
AcceptEntityInput(explosion, "Kill");
}
/**
* Shake a client's screen with specific parameters.
*
*
* @param client The client index.
* @param amplitude The amplitude (intensity) of the shaking.
* @param frequency The frequency (speed) of the shaking.
@ -140,13 +140,13 @@ VEffectsCreateExplosion(const Float:origin[3], flags)
VEffectsShakeClientScreen(client, Float:amplitude, Float:frequency, Float:duration)
{
new Handle:hShake = StartMessageOne("Shake", client);
// Validate.
if (hShake == INVALID_HANDLE)
{
return;
}
// Future code using protocol buffers (not tested). Enabling this will bump
// SourceMod version requirement to a snapshot, we don't want to do that
// until that branch is declared stable.
@ -164,13 +164,13 @@ VEffectsShakeClientScreen(client, Float:amplitude, Float:frequency, Float:durati
BfWriteFloat(hShake, frequency);
BfWriteFloat(hShake, duration);
}*/
// Write shake information to message handle.
BfWriteByte(hShake, 0);
BfWriteFloat(hShake, amplitude);
BfWriteFloat(hShake, frequency);
BfWriteFloat(hShake, duration);
// End usermsg and send to client.
EndMessage();
}

View File

@ -56,12 +56,12 @@ enum VolTypeAnticamp
bool:Anticamp_InUse, /** Specifies if the data index is used or not. */
Float:Anticamp_Interval, /** How often to trigger an action. */
Handle:Anticamp_Timer, /** Action timer handle. */
VolAnticampAction:Anticamp_Action, /** What to do with players in anti-camp volumes */
Float:Anticamp_Amount, /** Amount depending on action type. Usually time in seconds or damage amount. */
VolAnticampeWarningType:Anticamp_Warning, /** How to warn the player. */
String:Anticamp_Message[256] /** Override warning message. Max 256 characters. */
String:Anticamp_Message[256] /** Override warning message. Max 256 characters. */
}
/**
@ -72,28 +72,28 @@ new AnticampData[ZR_VOLUMES_MAX][VolTypeAnticamp];
/**
* Event callback. Enables a anticamp volume.
*
* @param volumeIndex The volume index.
* @param volumeIndex The volume index.
*/
VolAnticampEnable(volumeIndex)
{
new Float:interval;
new Handle:timer;
// Validate index.
if (!VolIsValidIndex(volumeIndex))
{
return;
}
// Get data index.
new dataindex = Volumes[volumeIndex][Vol_DataIndex];
// Validate data index.
if (!VolAnticampValidateIndex(dataindex))
{
return;
}
// Check if in use.
if (AnticampData[dataindex][Anticamp_InUse])
{
@ -104,10 +104,10 @@ VolAnticampEnable(volumeIndex)
KillTimer(timer);
AnticampData[dataindex][Anticamp_Timer] = INVALID_HANDLE;
}
// Get interval.
interval = AnticampData[dataindex][Anticamp_Interval];
// Validate interval.
if (interval > 0.0)
{
@ -130,7 +130,7 @@ stock VolAnticampEnableAll()
{
new Float:interval;
new dataindex;
// Loop through all volumes.
for (new volumeindex = 0; volumeindex < ZR_VOLUMES_MAX; volumeindex++)
{
@ -140,13 +140,13 @@ stock VolAnticampEnableAll()
// Volume not in use, skip it.
continue;
}
// Check if it's a anticamp volume.
if (VolIsType(volumeindex, VolFeature_Anticamp))
{
// Get data index.
dataindex = Volumes[volumeindex][Vol_DataIndex];
// Kill timer if it exist.
timer = AnticampData[dataindex][Anticamp_Timer];
if (timer != INVALID_HANDLE)
@ -154,10 +154,10 @@ stock VolAnticampEnableAll()
KillTimer(timer);
AnticampData[dataindex][Anticamp_Timer] = INVALID_HANDLE;
}
// Get interval.
interval = AnticampData[dataindex][Anticamp_Interval];
// Validate interval.
if (interval > 0.0)
{
@ -178,22 +178,22 @@ stock VolAnticampEnableAll()
VolAnticampDisable(volumeIndex)
{
new Handle:timerbuffer;
// Validate index.
if (!VolIsValidIndex(volumeIndex))
{
return;
}
// Get data index.
new dataindex = Volumes[volumeIndex][Vol_DataIndex];
// Validate data index.
if (!VolAnticampValidateIndex(dataindex))
{
return;
}
// Check if in use.
if (AnticampData[dataindex][Anticamp_InUse])
{
@ -204,10 +204,10 @@ VolAnticampDisable(volumeIndex)
KillTimer(timerbuffer);
AnticampData[dataindex][Anticamp_Timer] = INVALID_HANDLE;
}
LogEvent(_, LogType_Normal, LOG_DEBUG, LogModule_Volfeatures, "Vol state", "Disabled anticamp volume %d.", volumeIndex);
}
}
/**
@ -216,7 +216,7 @@ VolAnticampDisable(volumeIndex)
stock VolAnticampDisableAll()
{
new Handle:timerbuffer;
// Loop through all volumes.
for (new dataindex = 0; dataindex < ZR_VOLUMES_MAX; dataindex++)
{
@ -242,17 +242,17 @@ stock VolAnticampDisableAll()
VolAnticampReset(dataIndex)
{
AnticampData[dataIndex][Anticamp_InUse] = false;
AnticampData[dataIndex][Anticamp_Interval] = 1.0;
if (AnticampData[dataIndex][Anticamp_Timer] != INVALID_HANDLE)
{
KillTimer(AnticampData[dataIndex][Anticamp_Timer]);
AnticampData[dataIndex][Anticamp_Timer] = INVALID_HANDLE;
}
AnticampData[dataIndex][Anticamp_Action] = Anticamp_Damage;
AnticampData[dataIndex][Anticamp_Amount] = 5.0;
AnticampData[dataIndex][Anticamp_Warning] = Anticamp_Chat;
Format(String:AnticampData[dataIndex][Anticamp_Message], 256, "");
}
@ -278,7 +278,7 @@ VolAnticampInit()
VolAnticampOnPlayerLeave(client, volumeIndex)
{
new dataindex = Volumes[volumeIndex][Vol_DataIndex];
switch (AnticampData[dataindex][Anticamp_Action])
{
case Anticamp_Drug:
@ -305,19 +305,19 @@ public Action:Event_VolAnticampTrigger(Handle:timer, any:volumeIndex)
{
continue;
}
// Check if the volume is unused.
if (!VolInUse(volumeIndex))
{
continue;
}
// Check if the volume is disabled.
if (!VolIsEnabled(volumeIndex))
{
continue;
}
// Check if it's a anticamp volume.
if (VolIsType(volumeIndex, VolFeature_Anticamp))
{
@ -341,17 +341,17 @@ public Action:Event_VolAnticampTrigger(Handle:timer, any:volumeIndex)
VolAnticampApplyAction(client, dataIndex, volumeIndex)
{
new Float:amount = AnticampData[dataIndex][Anticamp_Amount];
// Set client language.
SetGlobalTransTarget(client);
// Get player name.
decl String:name[64];
GetClientName(client, name, sizeof(name));
// Send warning message.
VolAnticampWarnPlayer(client, dataIndex);
switch (AnticampData[dataIndex][Anticamp_Action])
{
case Anticamp_NoAction:
@ -363,7 +363,7 @@ VolAnticampApplyAction(client, dataIndex, volumeIndex)
// Give damage to player. Kill if zero HP or below.
new damage = RoundToNearest(amount);
new health = GetClientHealth(client) - damage;
if (health > 0)
{
SetEntityHealth(client, health);
@ -372,7 +372,7 @@ VolAnticampApplyAction(client, dataIndex, volumeIndex)
{
// Health is zero or below. Kill player.
ForcePlayerSuicide(client);
// Log event.
LogEvent(false, LogType_Normal, LOG_GAME_EVENTS, LogModule_Volfeatures, "Anti-camp", "%t", "Vol Slay", name, volumeIndex);
}
@ -381,7 +381,7 @@ VolAnticampApplyAction(client, dataIndex, volumeIndex)
{
// Instantly kill the player.
ForcePlayerSuicide(client);
// Log event.
LogEvent(false, LogType_Normal, LOG_GAME_EVENTS, LogModule_Volfeatures, "Anti-camp", "%t", "Vol Slay", name, volumeIndex);
}
@ -396,10 +396,10 @@ VolAnticampApplyAction(client, dataIndex, volumeIndex)
{
// Extinguish player first.
ExtinguishEntity(client);
// Ignite player for "amount" seconds.
IgniteEntity(client, amount);
// Log event.
LogEvent(false, LogType_Normal, LOG_GAME_EVENTS, LogModule_Volfeatures, "Anti-camp", "%t", "Vol Ignite", name, volumeIndex);
}
@ -417,10 +417,10 @@ VolAnticampWarnPlayer(client, dataIndex)
{
decl String:buffer[256];
new bool:custommessage = (strlen(AnticampData[dataIndex][Anticamp_Message]) > 0) ? true : false;
// Set language.
SetGlobalTransTarget(client);
// Format message.
if (custommessage)
{
@ -432,7 +432,7 @@ VolAnticampWarnPlayer(client, dataIndex)
// Use default anticamp message in translations file.
Format(buffer, sizeof(buffer), "%t", "Vol Anticamp Message");
}
switch (AnticampData[dataIndex][Anticamp_Warning])
{
case Anticamp_NoWarning:
@ -454,17 +454,17 @@ VolAnticampWarnPlayer(client, dataIndex)
{
// Display the message in a menu panel.
new Handle:panel = CreatePanel();
SetPanelTitle(panel, "Zombie:Reloaded");
DrawPanelItem(panel, "", ITEMDRAW_SPACER);
DrawPanelItem(panel, buffer);
DrawPanelItem(panel, "", ITEMDRAW_SPACER);
SetPanelCurrentKey(panel, 10);
Format(buffer, sizeof(buffer), "%t", "Exit");
DrawPanelItem(panel, buffer, ITEMDRAW_CONTROL);
SendPanelToClient(panel, client, Handler_AnitcampDummy, 10);
CloseHandle(panel);
}
@ -495,12 +495,12 @@ VolAnticampGetFreeIndex()
{
// Mark as in use.
AnticampData[dataindex][Anticamp_InUse] = true;
// Return the new index.
return dataindex;
}
}
// No free index found.
return -1;
}
@ -537,37 +537,37 @@ VolAnticampDumpData(dataIndex, String:buffer[], maxlen)
decl String:valuebuffer[256];
new anticampcache[VolTypeAnticamp];
new cellswritten;
// Validate index.
if (!VolAnticampValidateIndex(dataIndex))
{
return 0;
}
// Initialize and clear buffer.
buffer[0] = 0;
// Cache data.
anticampcache = AnticampData[dataIndex];
Format(linebuffer, sizeof(linebuffer), "Interval: %.2f\n", anticampcache[Anticamp_Interval]);
cellswritten += StrCat(buffer, maxlen, linebuffer);
VolAnticampActionToString(anticampcache[Anticamp_Action], valuebuffer, sizeof(valuebuffer));
Format(linebuffer, sizeof(linebuffer), "Action: %s\n", valuebuffer);
cellswritten += StrCat(buffer, maxlen, linebuffer);
Format(linebuffer, sizeof(linebuffer), "Action amount: %.2f\n", anticampcache[Anticamp_Amount]);
cellswritten += StrCat(buffer, maxlen, linebuffer);
VolAnticampWarningToString(anticampcache[Anticamp_Warning], valuebuffer, sizeof(valuebuffer));
Format(linebuffer, sizeof(linebuffer), "Warning type: %s\n", valuebuffer);
cellswritten += StrCat(buffer, maxlen, linebuffer);
strcopy(valuebuffer, sizeof(valuebuffer), anticampcache[Anticamp_Message]);
Format(linebuffer, sizeof(linebuffer), "Warning message: \"%s\"\n", valuebuffer);
cellswritten += StrCat(buffer, maxlen, linebuffer);
return cellswritten;
}
@ -613,7 +613,7 @@ VolAnticampActionToString(VolAnticampAction:actionType, String:buffer[], maxlen,
return shortName ? strcopy(buffer, maxlen, "ignite") : strcopy(buffer, maxlen, "Ignite player");
}
}
return 0;
}
@ -630,7 +630,7 @@ stock VolAnticampAction:VolAnticampStringToAction(const String:action[])
{
return Anticamp_NoAction;
}
if (StrEqual(action, "none", false))
{
return Anticamp_NoWarning;
@ -651,7 +651,7 @@ stock VolAnticampAction:VolAnticampStringToAction(const String:action[])
{
return Anticamp_Ignite;
}
// No match.
return Anticamp_NoAction;
}
@ -687,7 +687,7 @@ VolAnticampWarningToString(VolAnticampeWarningType:warningType, String:buffer[],
return shortName ? strcopy(buffer, maxlen, "menu") : strcopy(buffer, maxlen, "Message in menu panel");
}
}
return 0;
}
@ -704,7 +704,7 @@ stock VolAnticampeWarningType:VolAnticampStringToWarning(const String:warning[])
{
return Anticamp_NoWarning;
}
if (StrEqual(warning, "none", false))
{
return Anticamp_NoWarning;
@ -721,7 +721,7 @@ stock VolAnticampeWarningType:VolAnticampStringToWarning(const String:warning[])
{
return Anticamp_Menu;
}
// No match.
return Anticamp_NoWarning;
}
@ -748,7 +748,7 @@ bool:VolAnticampSetAttribute(dataIndex, const String:attribName[], const String:
{
return false;
}
// Check attribute names.
if (StrEqual(attribName, "interval", false))
{
@ -783,7 +783,7 @@ bool:VolAnticampSetAttribute(dataIndex, const String:attribName[], const String:
// Unsupported because of technical limits in command parser. Spaces
// and quoted strings aren't supported yet.
}
return false;
}
@ -792,22 +792,22 @@ bool:VolAnticampSetAttribute(dataIndex, const String:attribName[], const String:
*
* @param dataIndex Local data index.
* @param interval Interval to set. A floating point number formatted as a
* string.
* string.
* @return True if successfully set, false otherwise.
*/
bool:VolAnticampSetIntervalString(dataIndex, const String:interval[])
{
new Float:anticampinterval;
// Check if string value is empty.
if (strlen(interval) == 0)
{
return false;
}
// Convert value.
anticampinterval = StringToFloat(interval);
// Apply value.
AnticampData[dataIndex][Anticamp_Interval] = anticampinterval;
return true;
@ -827,7 +827,7 @@ bool:VolAnticampSetActionString(dataIndex, const String:action[])
{
return false;
}
// Check effect string values and apply them to the volume.
if (StrEqual(action, "none", false))
{
@ -854,7 +854,7 @@ bool:VolAnticampSetActionString(dataIndex, const String:action[])
AnticampData[dataIndex][Anticamp_Action] = Anticamp_Ignite;
return true;
}
// The string value didn't match any valid action types.
return false;
}
@ -864,22 +864,22 @@ bool:VolAnticampSetActionString(dataIndex, const String:action[])
*
* @param dataIndex Local data index.
* @param amount Amount to set. A floating point number formatted as a
* string.
* string.
* @return True if successfully set, false otherwise.
*/
bool:VolAnticampSetAmountString(dataIndex, const String:amount[])
{
new Float:actionamount;
// Check if string value is empty.
if (strlen(amount) == 0)
{
return false;
}
// Convert value.
actionamount = StringToFloat(amount);
// Apply value.
AnticampData[dataIndex][Anticamp_Amount] = actionamount;
return true;
@ -894,13 +894,13 @@ bool:VolAnticampSetAmountString(dataIndex, const String:amount[])
*/
bool:VolAnticampSetWarningString(dataIndex, const String:warning[])
{
// Check if string value is empty.
if (strlen(warning) == 0)
{
return false;
}
// Check effect string values and apply them to the volume.
if (StrEqual(warning, "none", false))
{
@ -922,7 +922,7 @@ bool:VolAnticampSetWarningString(dataIndex, const String:warning[])
AnticampData[dataIndex][Anticamp_Warning] = Anticamp_Menu;
return true;
}
// The string value didn't match any valid action types.
return false;
}

View File

@ -35,23 +35,23 @@ new VolEmptyAttributes[ClassEditableAttributes] = {
-1, /** AlphaInitial */
-1, /** AlphaDamaged */
-1, /** AlphaDamage */
"nochange", /** OverlayPath */
-1, /** Nvgs */
-1, /** Fov */
-1, /** HasNapalm */
-1.0, /** NapalmTime */
Immunity_Invalid, /** ImmunityMode */
-1, /** ImmunityAmount */
-1, /** ImmunityCooldown */
-1, /** NoFallDamage */
-1.0, /** RegenInterval */
-1, /** RegenAmount */
-1, /** InfectGain */
-1, /** KillBonus */
-1.0, /** Speed */
ZR_CLASS_KNOCKBACK_IGNORE, /** KnockBack */
-1.0, /** JumpHeight */
@ -73,7 +73,7 @@ enum VolClassEditMode
enum VolTypeClassEdit
{
bool:VolClassEdit_InUse,
VolClassEditMode:VolClassEdit_Mode,
String:VolClassEdit_ClassName[VOL_CLASSNAME_SIZE],
VolClassEdit_ClassData[ClassEditableAttributes]
@ -115,12 +115,12 @@ VolClassEditGetFreeIndex()
{
// Mark as in use.
VolClassEditData[dataindex][VolClassEdit_InUse] = true;
// Unused index found.
return dataindex;
}
}
// Unused index not found.
return -1;
}
@ -129,7 +129,7 @@ VolClassEditReset(dataIndex)
{
VolClassEditData[dataIndex][VolClassEdit_InUse] = false;
VolClassEditData[dataIndex][VolClassEdit_Mode] = ClassEditMode_Attributes;
strcopy(VolClassEditData[dataIndex][VolClassEdit_ClassName], 64, "");
VolClassEditData[dataIndex][VolClassEdit_ClassData] = VolEmptyAttributes;
}
@ -160,7 +160,7 @@ VolClassEditSetAttribute(dataIndex, const String:attribName[], const String:attr
{
return false;
}
/* Class Editor Attributes */
if (StrEqual(attribName, "mode", false))
{
@ -176,7 +176,7 @@ VolClassEditSetAttribute(dataIndex, const String:attribName[], const String:attr
return true;
}
}
/* Model */
else if (StrEqual(attribName, "alpha_initial", false))
{
@ -199,7 +199,7 @@ VolClassEditSetAttribute(dataIndex, const String:attribName[], const String:attr
return true;
}
}
/* Hud */
else if (StrEqual(attribName, "overlay_path", false))
{
@ -222,7 +222,7 @@ VolClassEditSetAttribute(dataIndex, const String:attribName[], const String:attr
return true;
}
}
/* Effects */
else if (StrEqual(attribName, "has_napalm", false))
{
@ -238,7 +238,7 @@ VolClassEditSetAttribute(dataIndex, const String:attribName[], const String:attr
return true;
}
}
/* Player behavior */
else if (StrEqual(attribName, "immunity_mode", false))
{
@ -324,7 +324,7 @@ VolClassEditSetAttribute(dataIndex, const String:attribName[], const String:attr
return true;
}
}
// Invalid attribute name or empty value.
return false;
}
@ -340,28 +340,28 @@ VolClassEditSetAttribute(dataIndex, const String:attribName[], const String:attr
VolClassEditDumpData(dataIndex, String:buffer[], maxlen)
{
#define CLASSEDIT_DUMP_FORMAT "%-19s %s\n"
decl String:linebuffer[128];
decl String:valuebuffer[256];
new cache[VolTypeClassEdit];
new cellswritten;
// Validate index.
if (!VolIsValidIndex(dataIndex))
{
return 0;
}
// Initialize and clear buffer.
buffer[0] = 0;
// Cache data.
cache = VolClassEditData[dataIndex];
VolClassEditModeToString(cache[VolClassEdit_Mode], valuebuffer, sizeof(valuebuffer));
Format(linebuffer, sizeof(linebuffer), CLASSEDIT_DUMP_FORMAT, "Mode:", valuebuffer);
cellswritten += StrCat(buffer, maxlen, linebuffer);
switch (cache[VolClassEdit_Mode])
{
case ClassEditMode_Name:
@ -374,85 +374,85 @@ VolClassEditDumpData(dataIndex, String:buffer[], maxlen)
VolClassEditIntToString(dataIndex, ClassEdit_AlphaInitial, valuebuffer, sizeof(valuebuffer));
Format(linebuffer, sizeof(linebuffer), CLASSEDIT_DUMP_FORMAT, "Alpha initial:", valuebuffer);
cellswritten += StrCat(buffer, maxlen, linebuffer);
VolClassEditIntToString(dataIndex, ClassEdit_AlphaDamaged, valuebuffer, sizeof(valuebuffer));
Format(linebuffer, sizeof(linebuffer), CLASSEDIT_DUMP_FORMAT, "Alpha damaged:", valuebuffer);
cellswritten += StrCat(buffer, maxlen, linebuffer);
VolClassEditIntToString(dataIndex, ClassEdit_AlphaDamage, valuebuffer, sizeof(valuebuffer));
Format(linebuffer, sizeof(linebuffer), CLASSEDIT_DUMP_FORMAT, "Alpha damage:", valuebuffer);
cellswritten += StrCat(buffer, maxlen, linebuffer);
VolClassEditStringToHumanStr(dataIndex, ClassEdit_OverlayPath, valuebuffer, sizeof(valuebuffer));
Format(linebuffer, sizeof(linebuffer), CLASSEDIT_DUMP_FORMAT, "Overlay path:", valuebuffer);
cellswritten += StrCat(buffer, maxlen, linebuffer);
VolClassEditIntToString(dataIndex, ClassEdit_Nvgs, valuebuffer, sizeof(valuebuffer));
Format(linebuffer, sizeof(linebuffer), CLASSEDIT_DUMP_FORMAT, "NVGs:", valuebuffer);
cellswritten += StrCat(buffer, maxlen, linebuffer);
VolClassEditIntToString(dataIndex, ClassEdit_Fov, valuebuffer, sizeof(valuebuffer));
Format(linebuffer, sizeof(linebuffer), CLASSEDIT_DUMP_FORMAT, "FOV:", valuebuffer);
cellswritten += StrCat(buffer, maxlen, linebuffer);
VolClassEditIntToString(dataIndex, ClassEdit_HasNapalm, valuebuffer, sizeof(valuebuffer));
Format(linebuffer, sizeof(linebuffer), CLASSEDIT_DUMP_FORMAT, "Has napalm:", valuebuffer);
cellswritten += StrCat(buffer, maxlen, linebuffer);
VolClassEditFloatToString(dataIndex, ClassEdit_NapalmTime, valuebuffer, sizeof(valuebuffer));
Format(linebuffer, sizeof(linebuffer), CLASSEDIT_DUMP_FORMAT, "Napalm time:", valuebuffer);
cellswritten += StrCat(buffer, maxlen, linebuffer);
ImmunityModeToString(VolClassEditData[dataIndex][ClassEdit_ImmunityMode], valuebuffer, sizeof(valuebuffer));
Format(linebuffer, sizeof(linebuffer), CLASSEDIT_DUMP_FORMAT, "Immunity mode:", valuebuffer);
cellswritten += StrCat(buffer, maxlen, linebuffer);
VolClassEditIntToString(dataIndex, ClassEdit_ImmunityAmount, valuebuffer, sizeof(valuebuffer));
Format(linebuffer, sizeof(linebuffer), CLASSEDIT_DUMP_FORMAT, "Immunity amount:", valuebuffer);
cellswritten += StrCat(buffer, maxlen, linebuffer);
VolClassEditIntToString(dataIndex, ClassEdit_ImmunityCooldown, valuebuffer, sizeof(valuebuffer));
Format(linebuffer, sizeof(linebuffer), CLASSEDIT_DUMP_FORMAT, "Immunity cooldown:", valuebuffer);
cellswritten += StrCat(buffer, maxlen, linebuffer);
VolClassEditIntToString(dataIndex, ClassEdit_NoFallDamage, valuebuffer, sizeof(valuebuffer));
Format(linebuffer, sizeof(linebuffer), CLASSEDIT_DUMP_FORMAT, "No fall damage:", valuebuffer);
cellswritten += StrCat(buffer, maxlen, linebuffer);
VolClassEditFloatToString(dataIndex, ClassEdit_RegenInterval, valuebuffer, sizeof(valuebuffer));
Format(linebuffer, sizeof(linebuffer), CLASSEDIT_DUMP_FORMAT, "Regen interval:", valuebuffer);
cellswritten += StrCat(buffer, maxlen, linebuffer);
VolClassEditIntToString(dataIndex, ClassEdit_RegenAmount, valuebuffer, sizeof(valuebuffer));
Format(linebuffer, sizeof(linebuffer), CLASSEDIT_DUMP_FORMAT, "Regen amount:", valuebuffer);
cellswritten += StrCat(buffer, maxlen, linebuffer);
VolClassEditIntToString(dataIndex, ClassEdit_InfectGain, valuebuffer, sizeof(valuebuffer));
Format(linebuffer, sizeof(linebuffer), CLASSEDIT_DUMP_FORMAT, "Infect gain:", valuebuffer);
cellswritten += StrCat(buffer, maxlen, linebuffer);
VolClassEditIntToString(dataIndex, ClassEdit_KillBonus, valuebuffer, sizeof(valuebuffer));
Format(linebuffer, sizeof(linebuffer), CLASSEDIT_DUMP_FORMAT, "Kill bonus:", valuebuffer);
cellswritten += StrCat(buffer, maxlen, linebuffer);
VolClassEditFloatToString(dataIndex, ClassEdit_Speed, valuebuffer, sizeof(valuebuffer));
Format(linebuffer, sizeof(linebuffer), CLASSEDIT_DUMP_FORMAT, "Speed:", valuebuffer);
cellswritten += StrCat(buffer, maxlen, linebuffer);
VolClassEditFloatToString(dataIndex, ClassEdit_KnockBack, valuebuffer, sizeof(valuebuffer), ZR_CLASS_KNOCKBACK_IGNORE);
Format(linebuffer, sizeof(linebuffer), CLASSEDIT_DUMP_FORMAT, "Knock back:", valuebuffer);
cellswritten += StrCat(buffer, maxlen, linebuffer);
VolClassEditFloatToString(dataIndex, ClassEdit_JumpHeight, valuebuffer, sizeof(valuebuffer));
Format(linebuffer, sizeof(linebuffer), CLASSEDIT_DUMP_FORMAT, "Jump height:", valuebuffer);
cellswritten += StrCat(buffer, maxlen, linebuffer);
VolClassEditFloatToString(dataIndex, ClassEdit_JumpDistance, valuebuffer, sizeof(valuebuffer));
Format(linebuffer, sizeof(linebuffer), CLASSEDIT_DUMP_FORMAT, "Jump distance:", valuebuffer);
cellswritten += StrCat(buffer, maxlen, linebuffer);
}
}
return cellswritten;
}
@ -477,10 +477,10 @@ VolClassEditApply(client, dataIndex)
{
// Cache volume attributes.
new classindex = ClassGetIndex(VolClassEditData[dataIndex][VolClassEdit_ClassName]);
// Save player's selected class.
VolClassEditSelectedClass[client] = ClassGetActiveIndex(client);
// Update cache with new attributes.
ClassReloadPlayerCache(client, classindex);
}
@ -491,9 +491,9 @@ VolClassEditApply(client, dataIndex)
VolClassEditUpdateAttributes(client, VolClassEditData[dataIndex][VolClassEdit_ClassData]);
}
}
LogEvent(_, LogType_Normal, LOG_DEBUG, LogModule_Volfeatures, "ClassEdit", "Applied class data on client %d.", client);
// Apply the updated attributes.
ClassApplyAttributes(client);
}
@ -506,7 +506,7 @@ VolClassEditApply(client, dataIndex)
VolClassEditRestore(client, dataIndex)
{
new classindex = ClassGetActiveIndex(client);
switch (VolClassEditData[dataIndex][VolClassEdit_Mode])
{
case ClassEditMode_Name:
@ -521,7 +521,7 @@ VolClassEditRestore(client, dataIndex)
VolClassEditRestoreAttributes(client, classindex, VolClassEditData[dataIndex][VolClassEdit_ClassData]);
}
}
// Apply the restored attributes.
if (ClassApplyAttributes(client))
{
@ -609,13 +609,13 @@ VolClassEditModeToString(VolClassEditMode:mode, String:buffer[], maxlen)
return strcopy(buffer, maxlen, "Attributes");
}
}
return 0;
}
/**
* Gets a integer attribute and converts it to a human readable string.
*
*
* Note: attribute is assumed to be a integer (cell) and is not type cheked!
*
* @param dataIndex Local data index.
@ -627,9 +627,9 @@ VolClassEditIntToString(dataIndex, ClassEditableAttributes:attribute, String:buf
{
new intVal;
new String:strVal[8];
intVal = VolClassEditData[dataIndex][VolClassEdit_ClassData][attribute];
// Check if the attribute is marked as ignored.
if (intVal == -1)
{
@ -656,9 +656,9 @@ VolClassEditFloatToString(dataIndex, ClassEditableAttributes:attribute, String:b
{
new Float:floatVal;
new String:strVal[8];
floatVal = Float:VolClassEditData[dataIndex][VolClassEdit_ClassData][attribute];
// Check if the attribute is marked as ignored.
if (floatVal == minval)
{
@ -685,7 +685,7 @@ VolClassEditStringToHumanStr(dataIndex, ClassEditableAttributes:attribute, Strin
{
decl String:strVal[PLATFORM_MAX_PATH];
strcopy(strVal, sizeof(strVal), String:VolClassEditData[dataIndex][VolClassEdit_ClassData][attribute]);
// Check if the attribute is marked as ignored.
if (StrEqual(strVal, "nochange", false))
{
@ -711,7 +711,7 @@ bool:VolClassEditSetMode(dataIndex, const String:value[])
{
return false;
}
if (StrEqual(value, "name", false))
{
VolClassEditData[dataIndex][VolClassEdit_Mode] = ClassEditMode_Name;
@ -722,7 +722,7 @@ bool:VolClassEditSetMode(dataIndex, const String:value[])
VolClassEditData[dataIndex][VolClassEdit_Mode] = ClassEditMode_Attributes;
return true;
}
// No match.
return false;
}
@ -741,11 +741,11 @@ bool:VolClassEditSetName(dataIndex, const String:value[])
{
return false;
}
strcopy(VolClassEditData[dataIndex][VolClassEdit_ClassName], VOL_CLASSNAME_SIZE, value);
// TODO: Validate name.
return true;
}
@ -765,7 +765,7 @@ bool:VolClassEditSetAlphaInitial(dataIndex, const String:value[])
{
return false;
}
VolClassEditData[dataIndex][VolClassEdit_ClassData][ClassEdit_AlphaInitial] = StringToInt(value);
return true;
}
@ -786,7 +786,7 @@ bool:VolClassEditSetAlphaDamaged(dataIndex, const String:value[])
{
return false;
}
VolClassEditData[dataIndex][VolClassEdit_ClassData][ClassEdit_AlphaDamaged] = StringToInt(value);
return true;
}
@ -807,7 +807,7 @@ bool:VolClassEditSetAlphaDamage(dataIndex, const String:value[])
{
return false;
}
VolClassEditData[dataIndex][VolClassEdit_ClassData][ClassEdit_AlphaDamage] = StringToInt(value);
return true;
}
@ -828,7 +828,7 @@ bool:VolClassEditSetOverlayPath(dataIndex, const String:value[])
{
return false;
}
strcopy(VolClassEditData[dataIndex][VolClassEdit_ClassData][ClassEdit_OverlayPath], PLATFORM_MAX_PATH, value);
return true;
}
@ -849,7 +849,7 @@ bool:VolClassEditSetNvgs(dataIndex, const String:value[])
{
return false;
}
VolClassEditData[dataIndex][VolClassEdit_ClassData][ClassEdit_Nvgs] = StringToInt(value);
return true;
}
@ -870,7 +870,7 @@ bool:VolClassEditSetFov(dataIndex, const String:value[])
{
return false;
}
VolClassEditData[dataIndex][VolClassEdit_ClassData][ClassEdit_Fov] = StringToInt(value);
return true;
}
@ -891,7 +891,7 @@ bool:VolClassEditSetHasNapalm(dataIndex, const String:value[])
{
return false;
}
VolClassEditData[dataIndex][VolClassEdit_ClassData][ClassEdit_HasNapalm] = StringToInt(value);
return true;
}
@ -912,7 +912,7 @@ bool:VolClassEditSetNapalmTime(dataIndex, const String:value[])
{
return false;
}
VolClassEditData[dataIndex][VolClassEdit_ClassData][ClassEdit_NapalmTime] = StringToFloat(value);
return true;
}
@ -933,7 +933,7 @@ bool:VolClassEditSetImmunityMode(dataIndex, const String:value[])
{
return false;
}
new ImmunityMode:mode = ImmunityStringToMode(value);
VolClassEditData[dataIndex][VolClassEdit_ClassData][ClassEdit_ImmunityMode] = mode;
return true;
@ -955,7 +955,7 @@ bool:VolClassEditSetImmunityAmount(dataIndex, const String:value[])
{
return false;
}
VolClassEditData[dataIndex][VolClassEdit_ClassData][ClassEdit_ImmunityAmount] = StringToInt(value);
return true;
}
@ -976,7 +976,7 @@ bool:VolClassEditSetImmunityCooldown(dataIndex, const String:value[])
{
return false;
}
VolClassEditData[dataIndex][VolClassEdit_ClassData][ClassEdit_ImmunityCooldown] = StringToInt(value);
return true;
}
@ -997,7 +997,7 @@ bool:VolClassEditSetNoFallDamage(dataIndex, const String:value[])
{
return false;
}
VolClassEditData[dataIndex][VolClassEdit_ClassData][ClassEdit_NoFallDamage] = StringToInt(value);
return true;
}
@ -1018,7 +1018,7 @@ bool:VolClassEditSetRegenInterval(dataIndex, const String:value[])
{
return false;
}
VolClassEditData[dataIndex][VolClassEdit_ClassData][ClassEdit_RegenInterval] = StringToFloat(value);
return true;
}
@ -1039,7 +1039,7 @@ bool:VolClassEditSetRegenAmount(dataIndex, const String:value[])
{
return false;
}
VolClassEditData[dataIndex][VolClassEdit_ClassData][ClassEdit_RegenAmount] = StringToInt(value);
return true;
}
@ -1060,7 +1060,7 @@ bool:VolClassEditSetInfectGain(dataIndex, const String:value[])
{
return false;
}
VolClassEditData[dataIndex][VolClassEdit_ClassData][ClassEdit_InfectGain] = StringToInt(value);
return true;
}
@ -1081,7 +1081,7 @@ bool:VolClassEditSetKillBonus(dataIndex, const String:value[])
{
return false;
}
VolClassEditData[dataIndex][VolClassEdit_ClassData][ClassEdit_KillBonus] = StringToInt(value);
return true;
}
@ -1102,7 +1102,7 @@ bool:VolClassEditSetSpeed(dataIndex, const String:value[])
{
return false;
}
VolClassEditData[dataIndex][VolClassEdit_ClassData][ClassEdit_Speed] = StringToFloat(value);
return true;
}
@ -1123,7 +1123,7 @@ bool:VolClassEditSetKnockBack(dataIndex, const String:value[])
{
return false;
}
VolClassEditData[dataIndex][VolClassEdit_ClassData][ClassEdit_KnockBack] = StringToFloat(value);
return true;
}
@ -1144,7 +1144,7 @@ bool:VolClassEditSetJumpHeight(dataIndex, const String:value[])
{
return false;
}
VolClassEditData[dataIndex][VolClassEdit_ClassData][ClassEdit_JumpHeight] = StringToFloat(value);
return true;
}
@ -1165,7 +1165,7 @@ bool:VolClassEditSetJumpDistance(dataIndex, const String:value[])
{
return false;
}
VolClassEditData[dataIndex][VolClassEdit_ClassData][ClassEdit_JumpDistance] = StringToFloat(value);
return true;
}
@ -1183,133 +1183,133 @@ bool:VolClassEditSetJumpDistance(dataIndex, const String:value[])
VolClassEditUpdateAttributes(client, const attributes[])
{
new numChanges;
// Alpha initial.
if (attributes[ClassEdit_AlphaInitial] > -1)
{
ClassPlayerCache[client][Class_AlphaInitial] = attributes[ClassEdit_AlphaInitial];
numChanges++;
}
// Alpha damaged.
if (attributes[ClassEdit_AlphaDamaged] > -1)
{
ClassPlayerCache[client][Class_AlphaDamaged] = attributes[ClassEdit_AlphaDamaged];
numChanges++;
}
// Alpha damage.
if (attributes[ClassEdit_AlphaDamage] > -1)
{
ClassPlayerCache[client][Class_AlphaDamage] = attributes[ClassEdit_AlphaDamage];
numChanges++;
}
// Overlay path.
if (!StrEqual(attributes[ClassEdit_OverlayPath], "nochange"))
{
strcopy(ClassPlayerCache[client][Class_OverlayPath], PLATFORM_MAX_PATH, attributes[ClassEdit_OverlayPath]);
numChanges++;
}
// Nvgs.
if (attributes[ClassEdit_Nvgs] > -1)
{
ClassPlayerCache[client][Class_Nvgs] = bool:attributes[ClassEdit_Nvgs];
numChanges++;
}
// Napalm time.
if (attributes[ClassEdit_NapalmTime] > -1.0)
{
ClassPlayerCache[client][Class_NapalmTime] = attributes[ClassEdit_NapalmTime];
numChanges++;
}
// Immunity mode.
if (attributes[ClassEdit_ImmunityMode] != Immunity_Invalid)
{
ClassPlayerCache[client][Class_ImmunityMode] = attributes[ClassEdit_ImmunityMode];
numChanges++;
}
// Immunity amount.
if (attributes[ClassEdit_ImmunityAmount] > -1)
{
ClassPlayerCache[client][Class_ImmunityAmount] = attributes[ClassEdit_ImmunityAmount];
numChanges++;
}
// Immunity cooldown.
if (attributes[ClassEdit_ImmunityCooldown] > -1)
{
ClassPlayerCache[client][Class_ImmunityCooldown] = attributes[ClassEdit_ImmunityCooldown];
numChanges++;
}
// No fall damage.
if (attributes[ClassEdit_NoFallDamage] > -1)
{
ClassPlayerCache[client][Class_NoFallDamage] = bool:attributes[ClassEdit_NoFallDamage];
numChanges++;
}
// Health regen interval.
if (attributes[ClassEdit_RegenInterval] > -1.0)
{
ClassPlayerCache[client][Class_HealthRegenInterval] = attributes[ClassEdit_RegenInterval];
numChanges++;
}
// Health regen amount.
if (attributes[ClassEdit_RegenAmount] > -1)
{
ClassPlayerCache[client][Class_HealthRegenAmount] = attributes[ClassEdit_RegenAmount];
numChanges++;
}
// Infect gain.
if (attributes[ClassEdit_InfectGain] > -1)
{
ClassPlayerCache[client][Class_HealthInfectGain] = attributes[ClassEdit_InfectGain];
numChanges++;
}
// Kill bonus.
if (attributes[ClassEdit_KillBonus] > -1)
{
ClassPlayerCache[client][Class_KillBonus] = attributes[ClassEdit_KillBonus];
numChanges++;
}
// Speed.
if (attributes[ClassEdit_Speed] > -1.0)
{
ClassPlayerCache[client][Class_Speed] = attributes[ClassEdit_Speed];
numChanges++;
}
// Knock back.
if (attributes[ClassEdit_KnockBack] > ZR_CLASS_KNOCKBACK_IGNORE)
{
ClassPlayerCache[client][Class_KnockBack] = attributes[ClassEdit_KnockBack];
numChanges++;
}
// Jump height.
if (attributes[ClassEdit_JumpHeight] > -1.0)
{
ClassPlayerCache[client][Class_JumpHeight] = attributes[ClassEdit_JumpHeight];
numChanges++;
}
// Jump distance.
if (attributes[ClassEdit_JumpDistance] > -1.0)
{
ClassPlayerCache[client][Class_JumpDistance] = attributes[ClassEdit_JumpDistance];
numChanges++;
}
LogEvent(_, LogType_Normal, LOG_DEBUG, LogModule_Volfeatures, "ClassEdit", "Applied %d attribute(s).", numChanges);
return numChanges;
}
@ -1326,28 +1326,28 @@ VolClassEditUpdateAttributes(client, const attributes[])
VolClassEditRestoreAttributes(client, classindex, const attributes[])
{
new numChanges;
// Alpha initial.
if (attributes[ClassEdit_AlphaInitial] > -1)
{
ClassPlayerCache[client][Class_AlphaInitial] = ClassGetAlphaInitial(classindex, ZR_CLASS_CACHE_MODIFIED);
numChanges++;
}
// Alpha damaged.
if (attributes[ClassEdit_AlphaDamaged] > -1)
{
ClassPlayerCache[client][Class_AlphaDamaged] = ClassGetAlphaDamaged(classindex, ZR_CLASS_CACHE_MODIFIED);
numChanges++;
}
// Alpha damage.
if (attributes[ClassEdit_AlphaDamage] > -1)
{
ClassPlayerCache[client][Class_AlphaDamage] = ClassGetAlphaDamage(classindex, ZR_CLASS_CACHE_MODIFIED);
numChanges++;
}
// Overlay path.
if (!StrEqual(attributes[ClassEdit_OverlayPath], "nochange"))
{
@ -1356,98 +1356,98 @@ VolClassEditRestoreAttributes(client, classindex, const attributes[])
strcopy(ClassPlayerCache[client][Class_OverlayPath], PLATFORM_MAX_PATH, path);
numChanges++;
}
// Nvgs.
if (attributes[ClassEdit_Nvgs] > -1)
{
ClassPlayerCache[client][Class_Nvgs] = ClassGetNvgs(classindex, ZR_CLASS_CACHE_MODIFIED);
numChanges++;
}
// Napalm time.
if (attributes[ClassEdit_NapalmTime] > -1.0)
{
ClassPlayerCache[client][Class_NapalmTime] = ClassGetNapalmTime(classindex, ZR_CLASS_CACHE_MODIFIED);
numChanges++;
}
// Immunity mode.
if (attributes[ClassEdit_ImmunityMode] != Immunity_Invalid)
{
ClassPlayerCache[client][Class_ImmunityMode] = ClassGetImmunityMode(classindex, ZR_CLASS_CACHE_MODIFIED);
numChanges++;
}
// Immunity amount.
if (attributes[ClassEdit_ImmunityAmount] > -1.0)
{
ClassPlayerCache[client][Class_ImmunityAmount] = ClassGetImmunityAmount(classindex, ZR_CLASS_CACHE_MODIFIED);
numChanges++;
}
// No fall damage.
if (attributes[ClassEdit_NoFallDamage] > -1)
{
ClassPlayerCache[client][Class_NoFallDamage] = ClassGetNoFallDamage(classindex, ZR_CLASS_CACHE_MODIFIED);
numChanges++;
}
// Health regen interval.
if (attributes[ClassEdit_RegenInterval] > -1.0)
{
ClassPlayerCache[client][Class_HealthRegenInterval] = ClassGetHealthRegenInterval(classindex, ZR_CLASS_CACHE_MODIFIED);
numChanges++;
}
// Health regen amount.
if (attributes[ClassEdit_RegenAmount] > -1)
{
ClassPlayerCache[client][Class_HealthRegenAmount] = ClassGetHealthRegenAmount(classindex, ZR_CLASS_CACHE_MODIFIED);
numChanges++;
}
// Infect gain.
if (attributes[ClassEdit_InfectGain] > -1)
{
ClassPlayerCache[client][Class_HealthInfectGain] = ClassGetHealthInfectGain(classindex, ZR_CLASS_CACHE_MODIFIED);
numChanges++;
}
// Kill bonus.
if (attributes[ClassEdit_KillBonus] > -1)
{
ClassPlayerCache[client][Class_KillBonus] = ClassGetKillBonus(classindex, ZR_CLASS_CACHE_MODIFIED);
numChanges++;
}
// Speed.
if (attributes[ClassEdit_Speed] > -1.0)
{
ClassPlayerCache[client][Class_Speed] = ClassGetSpeed(classindex, ZR_CLASS_CACHE_MODIFIED);
numChanges++;
}
// Knock back.
if (attributes[ClassEdit_KnockBack] > ZR_CLASS_KNOCKBACK_IGNORE)
{
ClassPlayerCache[client][Class_KnockBack] = ClassGetKnockback(classindex, ZR_CLASS_CACHE_MODIFIED);
numChanges++;
}
// Jump height.
if (attributes[ClassEdit_JumpHeight] > -1.0)
{
ClassPlayerCache[client][Class_JumpHeight] = ClassGetJumpHeight(classindex, ZR_CLASS_CACHE_MODIFIED);
numChanges++;
}
// Jump distance.
if (attributes[ClassEdit_JumpDistance] > -1.0)
{
ClassPlayerCache[client][Class_JumpDistance] = ClassGetJumpDistance(classindex, ZR_CLASS_CACHE_MODIFIED);
numChanges++;
}
LogEvent(_, LogType_Normal, LOG_DEBUG, LogModule_Volfeatures, "ClassEdit", "Applied %d attribute(s).", numChanges);
return numChanges;
}

View File

@ -68,7 +68,7 @@ public Action:VolAddVolumeCommand(client, argc)
{
decl String:buffer[640];
buffer[0] = 0;
// Check if privileged.
if (!ZRIsClientPrivileged(client, OperationType_Configuration))
{
@ -92,11 +92,11 @@ public Action:VolAddVolumeCommand(client, argc)
StrCat(buffer, sizeof(buffer), " effect=none|wireframe|smoke\n");
StrCat(buffer, sizeof(buffer), " effect_color=0,0,0\n");
StrCat(buffer, sizeof(buffer), " enabled=1");
ReplyToCommand(client, buffer);
return Plugin_Handled;
}
new Float:x1;
new Float:y1;
new Float:z1;
@ -110,41 +110,41 @@ public Action:VolAddVolumeCommand(client, argc)
new volindex;
new dataindex;
new paramcount;
decl String:params[512];
decl String:argbuffer[256];
params[0] = 0;
// Get a free volume index.
volindex = VolGetFreeVolume();
// Validate index.
if (!VolIsValidIndex(volindex))
{
ReplyToCommand(client, "Cannot add volume. Maximum number of volumes reached.");
return Plugin_Handled;
}
}
// Get positions.
GetCmdArg(1, argbuffer, sizeof(argbuffer));
x1 = StringToFloat(argbuffer);
GetCmdArg(2, argbuffer, sizeof(argbuffer));
y1 = StringToFloat(argbuffer);
GetCmdArg(3, argbuffer, sizeof(argbuffer));
z1 = StringToFloat(argbuffer);
GetCmdArg(4, argbuffer, sizeof(argbuffer));
x2 = StringToFloat(argbuffer);
GetCmdArg(5, argbuffer, sizeof(argbuffer));
y2 = StringToFloat(argbuffer);
GetCmdArg(6, argbuffer, sizeof(argbuffer));
z2 = StringToFloat(argbuffer);
// Check if both locations are equal.
if (FloatCompare(x1, x2) == 0)
{
@ -157,7 +157,7 @@ public Action:VolAddVolumeCommand(client, argc)
}
}
}
// Sort out max and min values so 1-values are smaller.
if (FloatCompare(x1, x2) == 1)
{
@ -180,7 +180,7 @@ public Action:VolAddVolumeCommand(client, argc)
z1 = z2;
z2 = floatbuffer;
}
// Copy coordinates to location vectors.
min[0] = x1;
min[1] = y1;
@ -188,31 +188,31 @@ public Action:VolAddVolumeCommand(client, argc)
max[0] = x2;
max[1] = y2;
max[2] = z2;
// Get volume type.
GetCmdArg(7, argbuffer, sizeof(argbuffer));
voltype = VolGetTypeFromString(argbuffer);
// Validate volume type.
if (voltype == VolFeature_Invalid)
{
ReplyToCommand(client, "Cannot add volume. Invalid volume type: %s", argbuffer);
return Plugin_Handled;
}
// Get free data index for the specified type.
dataindex = VolGetFreeDataIndex(voltype);
// Validate data index.
if (dataindex < 0)
{
ReplyToCommand(client, "Cannot add volume. Out of free data indexes for type \"%s\"", argbuffer);
return Plugin_Handled;
}
// Add volume.
volindex = VolAdd(volindex, min, max, voltype, dataindex);
// Get additional parameters if they exist.
if (argc >= 8)
{
@ -221,14 +221,14 @@ public Action:VolAddVolumeCommand(client, argc)
{
GetCmdArg(arg, argbuffer, sizeof(argbuffer));
StrCat(params, sizeof(params), argbuffer);
// Add space, except on the last parameter.
if (arg < argc)
{
StrCat(params, sizeof(params), " ");
}
}
// Set attributes.
paramcount = VolSetAttributes(volindex, params);
}
@ -237,7 +237,7 @@ public Action:VolAddVolumeCommand(client, argc)
// No attributes set.
paramcount = 0;
}
if (paramcount < 1)
{
Format(buffer, sizeof(buffer), "No additional attributes set.");
@ -246,10 +246,10 @@ public Action:VolAddVolumeCommand(client, argc)
{
Format(buffer, sizeof(buffer), "Additional attributes set: %d", paramcount);
}
// Send enable event to volume.
VolOnEnabled(volindex);
ReplyToCommand(client, "Added volume at index %d. %s", volindex, buffer);
return Plugin_Handled;
}
@ -261,42 +261,42 @@ public Action:VolRemoveVolumeCommand(client, argc)
{
decl String:arg[16];
new volindex;
// Check if privileged.
if (!ZRIsClientPrivileged(client, OperationType_Configuration))
{
TranslationReplyToCommand(client, "No access to command");
return Plugin_Handled;
}
if (argc < 1)
{
// Write syntax info.
ReplyToCommand(client, "Removes an existing volume in the map. Usage: zr_vol_remove <volume index>");
return Plugin_Handled;
}
// Get volume index.
GetCmdArg(1, arg, sizeof(arg));
volindex = StringToInt(arg);
// Validate index.
if (!VolIsValidIndex(volindex))
{
ReplyToCommand(client, "Invalid volume index.");
return Plugin_Handled;
}
// Check if volume exist.
if (!Volumes[volindex][Vol_InUse])
{
ReplyToCommand(client, "Volume %d doesn't exist.", volindex);
return Plugin_Handled;
}
// Remove volume.
VolRemove(volindex);
ReplyToCommand(client, "Successfully disabled and removed volume %d.", volindex);
return Plugin_Handled;
}
@ -310,14 +310,14 @@ public Action:VolListCommand(client, argc)
decl String:linebuffer[128];
decl String:valuebuffer[32];
decl String:arg[16];
buffer[0] = 0;
linebuffer[0] = 0;
new volindex;
new volcount;
new volcache[VolumeAttributes];
if (argc < 1)
{
// No volume specified. Display syntax and list volumes.
@ -325,7 +325,7 @@ public Action:VolListCommand(client, argc)
StrCat(buffer, sizeof(buffer), "ID: Type: Min loc: Max loc:\n");
StrCat(buffer, sizeof(buffer), "--------------------------------------------------------------------------------");
ReplyToCommand(client, buffer);
// Loop through all indexes.
for (volindex = 0; volindex < ZR_VOLUMES_MAX; volindex++)
{
@ -334,7 +334,7 @@ public Action:VolListCommand(client, argc)
{
// Cache volume data.
volcache = Volumes[volindex];
// Add to list.
VolTypeToString(volcache[Vol_Type], valuebuffer, sizeof(valuebuffer), true);
Format(linebuffer, sizeof(linebuffer), "%-4d %-15s %-8.2f %-8.2f %-8.2f %-8.2f %-8.2f %-8.2f",
@ -346,12 +346,12 @@ public Action:VolListCommand(client, argc)
volcache[Vol_xMax],
volcache[Vol_yMax],
volcache[Vol_zMax]);
ReplyToCommand(client, linebuffer);
volcount++;
}
}
Format(linebuffer, sizeof(linebuffer), "\nTotal volumes: %d", volcount);
ReplyToCommand(client, linebuffer);
return Plugin_Handled;
@ -359,73 +359,73 @@ public Action:VolListCommand(client, argc)
else
{
// Dump data for the specified volume.
// Get volume index.
GetCmdArg(1, arg, sizeof(arg));
volindex = StringToInt(arg);
// Validate index.
if (!VolIsValidIndex(volindex))
{
ReplyToCommand(client, "The specified volume index is invalid: %d", volindex);
return Plugin_Handled;
}
// Check if unused.
if (!VolInUse(volindex))
{
ReplyToCommand(client, "The specified volume doesn't exist: %d.", volindex);
return Plugin_Handled;
}
// Cache volume data.
volcache = Volumes[volindex];
// Dump generic volume data.
Format(linebuffer, sizeof(linebuffer), "Volume data at index %d:\n", volindex);
StrCat(buffer, sizeof(buffer), linebuffer);
StrCat(buffer, sizeof(buffer), "--------------------------------------------------------------------------------");
ReplyToCommand(client, buffer);
// Clear buffer.
buffer[0] = 0;
Format(linebuffer, sizeof(linebuffer), "ID: %d\n", volindex);
StrCat(buffer, sizeof(buffer), linebuffer);
Format(linebuffer, sizeof(linebuffer), "Enabled: %d\n", volcache[Vol_Enabled]);
StrCat(buffer, sizeof(buffer), linebuffer);
VolTypeToString(volcache[Vol_Type], valuebuffer, sizeof(valuebuffer));
Format(linebuffer, sizeof(linebuffer), "Type: %s\n", valuebuffer);
StrCat(buffer, sizeof(buffer), linebuffer);
Format(linebuffer, sizeof(linebuffer), "Min loc: %-8.2f %-8.2f %-8.2f\n", volcache[Vol_xMin], volcache[Vol_yMin], volcache[Vol_zMin]);
StrCat(buffer, sizeof(buffer), linebuffer);
Format(linebuffer, sizeof(linebuffer), "Max loc: %-8.2f %-8.2f %-8.2f\n", volcache[Vol_xMax], volcache[Vol_yMax], volcache[Vol_zMax]);
StrCat(buffer, sizeof(buffer), linebuffer);
VolEffectToString(volcache[Vol_Effect], valuebuffer, sizeof(valuebuffer));
Format(linebuffer, sizeof(linebuffer), "Effect: %s\n", valuebuffer);
StrCat(buffer, sizeof(buffer), linebuffer);
Format(linebuffer, sizeof(linebuffer), "Effect color: %d, %d, %d\n", volcache[Vol_EffectColor][0], volcache[Vol_EffectColor][1], volcache[Vol_EffectColor][2]);
StrCat(buffer, sizeof(buffer), linebuffer);
VolTeamToString(volcache[Vol_TeamFilter], valuebuffer, sizeof(valuebuffer));
Format(linebuffer, sizeof(linebuffer), "Team filter: %s\n", valuebuffer);
StrCat(buffer, sizeof(buffer), linebuffer);
Format(linebuffer, sizeof(linebuffer), "Trigger delay: %.2f", volcache[Vol_TriggerDelay]);
StrCat(buffer, sizeof(buffer), linebuffer);
// Print generic attributes.
ReplyToCommand(client, buffer);
// Clear buffer.
buffer[0] = 0;
// Get type spesific attributes.
switch (volcache[Vol_Type])
{
@ -438,13 +438,13 @@ public Action:VolListCommand(client, argc)
VolClassEditDumpData(volcache[Vol_DataIndex], buffer, sizeof(buffer));
}
}
// Print type spesific attributes if any.
if (strlen(buffer) > 0)
{
ReplyToCommand(client, buffer);
}
return Plugin_Handled;
}
}
@ -453,41 +453,41 @@ public Action:VolDumpStatesCommand(client, argc)
{
decl String:target[64];
new targetclient;
// Check if privileged.
if (!ZRIsClientPrivileged(client, OperationType_Generic))
{
TranslationReplyToCommand(client, "No access to command");
return Plugin_Handled;
}
if (argc < 1)
{
ReplyToCommand(client, "Dumps volume states for the specified player. Usage: zr_vol_dumpstates <index|targetname>");
return Plugin_Handled;
}
// Get target.
GetCmdArg(1, target, sizeof(target));
targetclient = FindTarget(client, target);
// Validate target.
if (targetclient <= 0)
{
// Note: FindTarget automatically print error messages.
return Plugin_Handled;
}
// Print header.
ReplyToCommand(client, "Volume ID: Player in volume:\n----------------------------------------");
// Get player states.
new bool:statebuffer[ZR_VOLUMES_MAX];
VolGetPlayerStates(targetclient, statebuffer, sizeof(statebuffer));
// Set language.
SetGlobalTransTarget(client);
// Loop through each volume.
for (new volumeindex = 0; volumeindex < ZR_VOLUMES_MAX; volumeindex++)
{
@ -498,7 +498,7 @@ public Action:VolDumpStatesCommand(client, argc)
ReplyToCommand(client, "%-11d %t", volumeindex, statebuffer[volumeindex] ? "Yes" : "No");
}
}
return Plugin_Handled;
}
@ -522,30 +522,30 @@ VolAdd(volumeIndex = -1, Float:locMin[3], Float:locMax[3], VolumeFeatureTypes:vo
// Get a free volume index.
volumeIndex = VolGetFreeVolume();
}
// Validate index.
if (VolIsValidIndex(volumeIndex))
{
// Mark volume as enabled and in use.
Volumes[volumeIndex][Vol_Enabled] = true;
Volumes[volumeIndex][Vol_InUse] = true;
// Set location data.
Volumes[volumeIndex][Vol_xMin] = locMin[0];
Volumes[volumeIndex][Vol_yMin] = locMin[1];
Volumes[volumeIndex][Vol_zMin] = locMin[2];
Volumes[volumeIndex][Vol_xMax] = locMax[0];
Volumes[volumeIndex][Vol_yMax] = locMax[1];
Volumes[volumeIndex][Vol_zMax] = locMax[2];
// Set type.
Volumes[volumeIndex][Vol_Type] = volumeType;
Volumes[volumeIndex][Vol_DataIndex] = dataIndex;
// Update number of volumes.
VolumeCount++;
// Return the new index.
return volumeIndex;
}
@ -569,7 +569,7 @@ bool:VolRemove(volumeIndex)
{
// Trigger event to clean up data and stop timers.
VolOnDisabled(volumeIndex);
// Clear feature data.
switch (Volumes[volumeIndex][Vol_Type])
{
@ -578,10 +578,10 @@ bool:VolRemove(volumeIndex)
VolAnticampReset(Volumes[volumeIndex][Vol_DataIndex]);
}
}
// Clear volume data.
VolClear(volumeIndex);
return true;
}
else
@ -600,20 +600,20 @@ VolClear(volumeIndex)
{
Volumes[volumeIndex][Vol_Enabled] = false;
Volumes[volumeIndex][Vol_InUse] = false;
Volumes[volumeIndex][Vol_xMin] = 0.0;
Volumes[volumeIndex][Vol_yMin] = 0.0;
Volumes[volumeIndex][Vol_zMin] = 0.0;
Volumes[volumeIndex][Vol_xMax] = 0.0;
Volumes[volumeIndex][Vol_yMax] = 0.0;
Volumes[volumeIndex][Vol_zMax] = 0.0;
Volumes[volumeIndex][Vol_Effect] = VolEffect_None;
Volumes[volumeIndex][Vol_EffectColor][0] = 0;
Volumes[volumeIndex][Vol_EffectColor][1] = 0;
Volumes[volumeIndex][Vol_EffectColor][2] = 0;
new dataindex = Volumes[volumeIndex][Vol_DataIndex];
if (dataindex >= 0)
{
@ -629,10 +629,10 @@ VolClear(volumeIndex)
}
}
}
Volumes[volumeIndex][Vol_Type] = VolFeature_Invalid;
Volumes[volumeIndex][Vol_DataIndex] = -1;
Volumes[volumeIndex][Vol_TeamFilter] = VolTeam_All;
Volumes[volumeIndex][Vol_TriggerDelay] = 0.0;
}
@ -664,39 +664,39 @@ VolSetAttributes(volumeIndex, const String:attributes[])
new dataindex;
decl String:attribName[64];
decl String:attribValue[256];
// Validate volume index.
if (!VolIsValidIndex(volumeIndex))
{
return -1;
}
// Count attributes.
attribCount = GetParameterCount(attributes);
// Check if empty.
if (!attribCount)
{
return -1;
}
// Get volumetric feature type.
voltype = Volumes[volumeIndex][Vol_Type];
// Get feature data index.
dataindex = Volumes[volumeIndex][Vol_DataIndex];
// Loop through all attributes.
for (new attrib = 0; attrib < attribCount; attrib++)
{
// Get attribute name.
GetParameterName(attribName, sizeof(attribName), attributes, attrib);
// Get attribute value.
GetParameterValue(attribValue, sizeof(attribValue), attributes, attribName);
LogEvent(_, LogType_Normal, LOG_DEBUG, LogModule_Volfeatures, "Set attribute", "Got parameter: \"%s\" = \"%s\"", attribName, attribValue);
// Check generic attributes.
if (StrEqual(attribName, "teamfilter", false))
{
@ -738,7 +738,7 @@ VolSetAttributes(volumeIndex, const String:attributes[])
successfulCount++;
}
}
// Pass attribute onto the volumetric feature attribute handler.
else
{
@ -761,7 +761,7 @@ VolSetAttributes(volumeIndex, const String:attributes[])
}
}
}
// Return number of successfully attributes set.
return successfulCount;
}

View File

@ -39,9 +39,9 @@ VolOnPlayerEnter(client, volumeIndex)
// Volumetric features disabled.
return;
}
LogEvent(_, LogType_Normal, LOG_DEBUG, LogModule_Volfeatures, "Event", "Player %N entered volume %d.", client, volumeIndex);
// Forward event to features.
new VolumeFeatureTypes:voltype = Volumes[volumeIndex][Vol_Type];
switch (voltype)
@ -67,9 +67,9 @@ VolOnPlayerLeave(client, volumeIndex)
// Volumetric features disabled.
return;
}
LogEvent(_, LogType_Normal, LOG_DEBUG, LogModule_Volfeatures, "Event", "Player %N left volume %d.", client, volumeIndex);
// Forward event to features.
new VolumeFeatureTypes:voltype = Volumes[volumeIndex][Vol_Type];
switch (voltype)
@ -98,7 +98,7 @@ VolOnPlayerSpawn(client)
// Volumetric features disabled.
return;
}
// Cache player location.
VolUpdatePlayerLocation(client);
}
@ -118,13 +118,13 @@ VolOnPlayerDeath(client)
{
continue;
}
// Check if volume is disabled.
if (!Volumes[volindex][Vol_Enabled])
{
continue;
}
// Check if player is inside the volume.
if (VolPlayerInVolume[client][volindex])
{
@ -144,7 +144,7 @@ VolOnPlayerDisconnect(client)
{
// Disable trigger delay counters.
VolResetCountDown(client);
// Trigger death event to clean up.
VolOnPlayerDeath(client);
}
@ -160,10 +160,10 @@ VolOnRoundStart()
// Volumetric features disabled.
return;
}
// Start main timer.
VolStartUpdateTimer();
// Start volumes.
VolEnableVolumes();
}
@ -175,7 +175,7 @@ VolOnRoundEnd()
{
// Stop main timer.
VolStopUpdateTimer();
// Stop volumes.
VolDisableVolumes();
}
@ -201,9 +201,9 @@ VolOnDisabled(volumeIndex)
// Volumetric features disabled.
return;
}
new VolumeFeatureTypes:voltype = Volumes[volumeIndex][Vol_Type];
// Forward stop event to features.
switch (voltype)
{
@ -230,9 +230,9 @@ VolOnEnabled(volumeIndex)
// Volumetric features disabled.
return;
}
new VolumeFeatureTypes:voltype = Volumes[volumeIndex][Vol_Type];
// Forward enable event to features.
switch (voltype)
{

View File

@ -38,25 +38,25 @@ enum VolumeAttributes
/* General */
bool:Vol_Enabled, /** Volume state. */
bool:Vol_InUse, /** Marks if the volume is used. */
/* Location */
Float:Vol_xMin, /** Minimum x position. */
Float:Vol_xMax, /** Maximum x position. */
Float:Vol_yMin, /** Minimum y position. */
Float:Vol_yMax, /** Maximum y position. */
Float:Vol_zMin, /** Minimum z position. */
Float:Vol_zMax, /** Maximum z position. */
/* Style */
VolumeEffects:Vol_Effect, /** Visual effect to apply on the volume. */
Vol_EffectColor[3], /** Render color of the effect. RGB colors. */
/* Data */
VolumeFeatureTypes:Vol_Type, /** The volumetric feature type. */
Vol_DataIndex, /** Index in remote feature array. */
/* Behaviour */
VolumeTeamFilters:Vol_TeamFilter, /** Team filtering. Trigger by certain teams, or all. */
Float:Vol_TriggerDelay, /** Trigger delay. How many seconds players have to stay to trigger volume events. */
@ -169,11 +169,11 @@ VolInit()
{
// Clear all volumes.
VolClearAll();
// Initialize sub features.
VolAnticampInit();
VolClassEditInit();
}
}
/**
* Initialize volumetric feature settings.
@ -192,7 +192,7 @@ VolDisable()
VolEnabled = false;
VolStopUpdateTimer();
VolDisableVolumes();
LogEvent(_, LogType_Normal, LOG_DEBUG, LogModule_Volfeatures, "Disabled", "Volfeatures disabled.");
}
@ -204,7 +204,7 @@ VolEnable()
VolEnabled = true;
VolStartUpdateTimer();
VolEnableVolumes();
LogEvent(_, LogType_Normal, LOG_DEBUG, LogModule_Volfeatures, "Enabled", "Volfeatures enabled.");
}
@ -220,7 +220,7 @@ VolDisableVolumes()
{
// Mark as disabled.
Volumes[volindex][Vol_Enabled] = false;
// Trigger player left volume event if inside a volume.
for (new client = 1; client <= MaxClients; client++)
{
@ -229,7 +229,7 @@ VolDisableVolumes()
{
continue;
}
// Check if player is inside the volume.
if (VolPlayerInVolume[client][volindex])
{
@ -238,7 +238,7 @@ VolDisableVolumes()
VolOnPlayerLeave(client, volindex);
}
}
// Trigger disabled event.
VolOnDisabled(volindex);
}
@ -274,22 +274,22 @@ bool:VolStartUpdateTimer()
// Volumetric features disabled.
return false;
}
// Stop timer if it exist.
VolStopUpdateTimer();
// Get update interval.
new Float:interval = GetConVarFloat(g_hCvarsList[CVAR_VOL_UPDATE_INTERVAL]);
// Validate interval.
if (interval > 0.0)
{
// Create a new timer.
hVolUpdateTimer = CreateTimer(interval, Event_VolUpdateTimer, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
// Also start the trigger delay timer.
VolStartTriggerTimer();
// Volumetric features started.
return true;
}
@ -312,10 +312,10 @@ VolStopUpdateTimer()
KillTimer(hVolUpdateTimer);
hVolUpdateTimer = INVALID_HANDLE;
}
// Also stop trigger delay timer.
VolStopTriggerTimer();
// Reset all trigger delay counters.
VolResetCountDown();
}
@ -329,16 +329,16 @@ bool:VolStartTriggerTimer()
{
// Make sure existing timer is killed.
VolStopTriggerTimer();
// Get trigger interval and cache it.
VolTriggerInterval = GetConVarFloat(g_hCvarsList[CVAR_VOL_TRIGGER_INTERVAL]);
// Validate interval.
if (VolTriggerInterval > 0.0)
{
// Start the timer.
hVolTriggerTimer = CreateTimer(VolTriggerInterval, Event_VolTriggerTimer, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
// Trigger timer started.
return true;
}
@ -418,7 +418,7 @@ VolUpdatePlayerLocation(client = -1)
{
continue;
}
// Save location in array.
GetClientAbsOrigin(client, VolPlayerLoc[client]);
}
@ -433,12 +433,12 @@ VolUpdatePlayerChanges()
{
new bool:volumeStates[ZR_VOLUMES_MAX];
new bool:volumeNewStates[ZR_VOLUMES_MAX];
new bool:newState;
new bool:oldState;
new Float:trigger_delay;
// Loop through all players.
for (new client = 1; client <= MaxClients; client++)
{
@ -448,16 +448,16 @@ VolUpdatePlayerChanges()
// Skip client.
continue;
}
// Get the current volume states based on player location cache.
VolGetPlayerStates(client, volumeStates, sizeof(volumeStates));
// Update player location cache.
GetClientAbsOrigin(client, VolPlayerLoc[client]);
// Get new volume states.
VolGetPlayerStates(client, volumeNewStates, sizeof(volumeNewStates));
// Loop through each volume and compare states.
for (new volumeIndex = 0; volumeIndex < ZR_VOLUMES_MAX; volumeIndex++)
{
@ -467,30 +467,30 @@ VolUpdatePlayerChanges()
// Skip volume.
continue;
}
// Check team filtering on the volume.
if (!VolTeamFilterMatch(client, volumeIndex))
{
// Team filter mismatch.
continue;
}
newState = volumeNewStates[volumeIndex];
oldState = volumeStates[volumeIndex];
// Check for no change.
if (newState == oldState)
{
// No change. Skip to next volume.
continue;
}
// Check if client entered the volume.
if (newState && !oldState)
{
// Get trigger delay value.
trigger_delay = Volumes[volumeIndex][Vol_TriggerDelay];
// Check if the volume has a trigger delay.
if (trigger_delay > 0.0)
{
@ -501,18 +501,18 @@ VolUpdatePlayerChanges()
{
// Update cache.
VolPlayerInVolume[client][volumeIndex] = true;
// No trigger delay, trigger event instantly.
VolOnPlayerEnter(client, volumeIndex);
}
}
// Check if client left the volume.
else if (!newState && oldState)
{
// Make sure count down value is reset.
VolPlayerCountDown[client][volumeIndex] = -1.0;
// Only trigger left volume event if player already is in the
// volume, so volumes with trigger delay won't get a left event
// before the enter event.
@ -520,7 +520,7 @@ VolUpdatePlayerChanges()
{
// Update cache.
VolPlayerInVolume[client][volumeIndex] = false;
// Trigger event.
VolOnPlayerLeave(client, volumeIndex);
}
@ -543,7 +543,7 @@ public Action:Event_VolUpdateTimer(Handle:timer)
public Action:Event_VolTriggerTimer(Handle:timer)
{
new Float:countDown;
// Loop through all players.
for (new client = 1; client <= MaxClients; client++)
{
@ -556,29 +556,29 @@ public Action:Event_VolTriggerTimer(Handle:timer)
// Not in use or enabled, skip volume.
continue;
}
// Get count down value.
countDown = VolPlayerCountDown[client][volumeIndex];
// Check if volume trigger delay is enabled.
if (countDown > 0.0)
{
// Substract by trigger interval.
countDown -= VolTriggerInterval;
// Check if time is up.
if (countDown <= 0.0)
{
// Update cache.
VolPlayerInVolume[client][volumeIndex] = true;
// Trigger volume enter event.
VolOnPlayerEnter(client, volumeIndex);
// Reset count down value.
VolPlayerCountDown[client][volumeIndex] = -1.0;
}
// Update count down value and continue.
VolPlayerCountDown[client][volumeIndex] = countDown;
}
@ -592,7 +592,7 @@ public Action:Event_VolTriggerTimer(Handle:timer)
public VolEnabledChanged(Handle:cvar, const String:oldvalue[], const String:newvalue[])
{
new bool:isEnabled = bool:StringToInt(newvalue);
if (isEnabled)
{
// Volumetric features is enabled.

View File

@ -4,7 +4,7 @@
* Zombie:Reloaded
*
* File: volgenericattributes.inc
* Type: Module
* Type: Module
* Description: Functions for getting or setting general volume attributes.
*
* Copyright (C) 2009-2013 Greyscale, Richard Helgeby
@ -36,13 +36,13 @@
stock bool:VolSetTeamString(volumeIndex, const String:team[])
{
new VolumeTeamFilters:teamfilter;
// Check if string value is empty.
if (strlen(team) == 0)
{
return false;
}
// Convert value.
if (StrEqual(team, "all", false))
{
@ -56,11 +56,11 @@ stock bool:VolSetTeamString(volumeIndex, const String:team[])
{
teamfilter = VolTeam_Zombies;
}
// Apply value.
Volumes[volumeIndex][Vol_TeamFilter] = teamfilter;
return true;
}
/**
@ -101,7 +101,7 @@ stock VolTeamToString(VolumeTeamFilters:team, String:buffer[], maxlen, bool:shor
return shortName ? strcopy(buffer, maxlen, "zombies") : strcopy(buffer, maxlen, "Zombies");
}
}
return 0;
}
@ -110,22 +110,22 @@ stock VolTeamToString(VolumeTeamFilters:team, String:buffer[], maxlen, bool:shor
*
* @param volumeIndex The volume index to apply to.
* @param delay The delay to apply. A floating point number formatted
* as a string.
* as a string.
* @return True if successfully set, false otherwise.
*/
stock bool:VolSetDelayString(volumeIndex, const String:delay[])
{
new Float:triggerdelay;
// Check if string value is empty.
if (strlen(delay) == 0)
{
return false;
}
// Convert value.
triggerdelay = StringToFloat(delay);
// Apply value.
Volumes[volumeIndex][Vol_TriggerDelay] = triggerdelay;
return true;
@ -157,7 +157,7 @@ stock bool:VolSetEffectString(volumeIndex, const String:effect[])
{
return false;
}
// Check effect string values and apply them to the volume.
if (StrEqual(effect, "none", false))
{
@ -174,7 +174,7 @@ stock bool:VolSetEffectString(volumeIndex, const String:effect[])
Volumes[volumeIndex][Vol_Effect] = VolEffect_Smoke;
return true;
}
// The string value didn't match any valid effects.
return false;
}
@ -217,7 +217,7 @@ stock VolEffectToString(VolumeEffects:effect, String:buffer[], maxlen, bool:shor
return shortName ? strcopy(buffer, maxlen, "smoke") : strcopy(buffer, maxlen, "Smoke");
}
}
return 0;
}
@ -233,21 +233,21 @@ stock bool:VolSetEffectColorString(volumeIndex, const String:effect_color[])
{
new String:colors[3][3];
new red, green, blue;
// Check if string value is empty.
if (strlen(effect_color) == 0)
{
return false;
}
// Split values into a string array.
ExplodeString(effect_color, ",", colors, 3, 3);
// Convert values.
red = StringToInt(colors[0]);
green = StringToInt(colors[1]);
blue = StringToInt(colors[2]);
// Apply values.
Volumes[volumeIndex][Vol_EffectColor][0] = red;
Volumes[volumeIndex][Vol_EffectColor][1] = green;
@ -285,9 +285,9 @@ stock bool:VolSetEnabledString(volumeIndex, const String:enabled[])
{
return false;
}
new bool:val = bool:StringToInt(enabled);
// Check yes or no values first.
if (StrEqual(enabled, "yes", false))
{
@ -297,7 +297,7 @@ stock bool:VolSetEnabledString(volumeIndex, const String:enabled[])
{
val = false;
}
// Check if the new value is different from the current.
if (Volumes[volumeIndex][Vol_Enabled] != val)
{
@ -311,7 +311,7 @@ stock bool:VolSetEnabledString(volumeIndex, const String:enabled[])
VolOnDisabled(volumeIndex);
}
}
// Apply converted value.
Volumes[volumeIndex][Vol_Enabled] = val;
return true;

View File

@ -40,7 +40,7 @@ bool:IsPointInLocation(Float:point[3], Float:min[3], Float:max[3])
new Float:posX = point[0];
new Float:posY = point[1];
new Float:posZ = point[2];
// Check if within x boundaries.
if ((posX >= min[0]) && (posX <= max[0]))
{
@ -55,7 +55,7 @@ bool:IsPointInLocation(Float:point[3], Float:min[3], Float:max[3])
}
}
}
// The point is outside the location boundaries.
return false;
}
@ -121,7 +121,7 @@ VolGetFreeVolume()
return volumeIndex;
}
}
// No free volumes found.
return -1;
}
@ -145,7 +145,7 @@ VolGetFreeDataIndex(VolumeFeatureTypes:volumeType)
return VolClassEditGetFreeIndex();
}
}
// No match.
return -1;
}
@ -161,10 +161,10 @@ VolGetFreeDataIndex(VolumeFeatureTypes:volumeType)
bool:VolTeamFilterMatch(client, volumeIndex)
{
new VolumeTeamFilters:filter;
// Chache filter value.
filter = Volumes[volumeIndex][Vol_TeamFilter];
switch (filter)
{
case VolTeam_All:
@ -183,7 +183,7 @@ bool:VolTeamFilterMatch(client, volumeIndex)
return InfectIsClientInfected(client);
}
}
// Invalid filter value.
return false;
}
@ -213,10 +213,10 @@ VolGetPlayerStates(client, bool:buffer[], maxlen)
{
new volumeBuffer[VolumeAttributes];
new volCount;
new Float:volMinBuffer[3];
new Float:volMaxBuffer[3];
// Loop through all available volumes.
for (new volumeIndex = 0; volumeIndex < ZR_VOLUMES_MAX && volumeIndex < maxlen; volumeIndex++)
{
@ -224,17 +224,17 @@ VolGetPlayerStates(client, bool:buffer[], maxlen)
{
// Chache volume to avoid re-indexing.
volumeBuffer = Volumes[volumeIndex];
// Get min positions.
volMinBuffer[0] = volumeBuffer[Vol_xMin];
volMinBuffer[1] = volumeBuffer[Vol_yMin];
volMinBuffer[2] = volumeBuffer[Vol_zMin];
// Get max positions.
volMaxBuffer[0] = volumeBuffer[Vol_xMax];
volMaxBuffer[1] = volumeBuffer[Vol_yMax];
volMaxBuffer[2] = volumeBuffer[Vol_zMax];
// Check the cached player location.
if (IsPointInLocation(VolPlayerLoc[client], volMinBuffer, volMaxBuffer))
{
@ -249,7 +249,7 @@ VolGetPlayerStates(client, bool:buffer[], maxlen)
}
}
}
return volCount;
}
@ -266,7 +266,7 @@ VolumeFeatureTypes:VolGetTypeFromString(const String:volType[])
{
return VolFeature_Invalid;
}
// Match types.
if (StrEqual(volType, "anticamp", false))
{
@ -276,7 +276,7 @@ VolumeFeatureTypes:VolGetTypeFromString(const String:volType[])
{
return VolFeature_ClassEdit;
}
// No match.
return VolFeature_Invalid;
}
@ -308,6 +308,6 @@ VolTypeToString(VolumeFeatureTypes:volType, String:buffer[], maxlen, bool:shortN
return shortName ? strcopy(buffer, maxlen, "classedit") : strcopy(buffer, maxlen, "Class Editor");
}
}
return 0;
}

View File

@ -32,7 +32,7 @@ new g_iWeaponsCurType[MAXPLAYERS + 1];
/**
* Sends main weapon menu to client.
*
*
* @param client The client index.
*/
bool:WeaponsMenuMain(client)
@ -43,42 +43,42 @@ bool:WeaponsMenuMain(client)
{
return false;
}
// Create menu handle.
new Handle:menu_weapons_main = CreateMenu(WeaponsMenuMainHandle);
SetGlobalTransTarget(client);
decl String:title[MENU_LINE_TITLE_LENGTH];
decl String:restrict[MENU_LINE_SMALL_LENGTH];
decl String:zmarket[MENU_LINE_SMALL_LENGTH];
Format(title, sizeof(title), "%t\n ", "Weapons menu restrict main title");
Format(restrict, sizeof(restrict), "%t", "Weapons menu restrict main restrict");
Format(zmarket, sizeof(zmarket), "%t", "Weapons menu restrict main market");
// Draw items, make unselectable if module is disabled.
SetMenuTitle(menu_weapons_main, title);
AddMenuItem(menu_weapons_main, "restrict", restrict, MenuGetItemDraw(GetConVarBool(g_hCvarsList[CVAR_WEAPONS_RESTRICT])));
AddMenuItem(menu_weapons_main, "zmarket", zmarket, MenuGetItemDraw(GetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET])));
// Create a "Back" button to the weapons main menu.
SetMenuExitBackButton(menu_weapons_main, true);
// Send menu.
DisplayMenu(menu_weapons_main, client, MENU_TIME_FOREVER);
return true;
}
/**
* Called when client selects option in the weapons main menu, and handles it.
*
*
* @param menu_weapons_main Handle of the menu being used.
* @param action The action done on the menu (see menus.inc, enum MenuAction).
* @param client The client index.
* @param slot The slot index selected (starting from 0).
*/
*/
public WeaponsMenuMainHandle(Handle:menu_weapons_main, MenuAction:action, client, slot)
{
// Client selected an option.
@ -117,58 +117,58 @@ public WeaponsMenuMainHandle(Handle:menu_weapons_main, MenuAction:action, client
/**
* Sends weapon type list to client.
*
*
* @param client The client index.
*/
WeaponsMenuTypes(client)
{
// Create menu handle.
new Handle:menu_weapons_types = CreateMenu(WeaponsMenuTypesHandle);
SetGlobalTransTarget(client);
decl String:title[MENU_LINE_TITLE_LENGTH];
Format(title, sizeof(title), "%t\n ", "Weapons menu restrict types title");
SetMenuTitle(menu_weapons_types, title);
decl String:typename[WEAPONS_MAX_LENGTH];
// x = Array index.
new size = GetArraySize(arrayWeaponTypes);
for (new x = 0; x < size; x++)
{
// Get name of type.
RestrictWeaponTypeGetName(x, typename, sizeof(typename));
// Add item to menu.
AddMenuItem(menu_weapons_types, typename, typename);
}
// If there are no weapons, add an "(Empty)" line.
if (size == 0)
{
SetGlobalTransTarget(client);
decl String:empty[MENU_LINE_SMALL_LENGTH];
Format(empty, sizeof(empty), "%t", "Menu empty");
AddMenuItem(menu_weapons_types, "empty", empty, ITEMDRAW_DISABLED);
}
// Set exit back button.
SetMenuExitBackButton(menu_weapons_types, true);
DisplayMenu(menu_weapons_types, client, MENU_TIME_FOREVER);
}
/**
* Called when client selects option in the weapons list menu, and handles it.
*
*
* @param menu_weapons_types Handle of the menu being used.
* @param action The action done on the menu (see menus.inc, enum MenuAction).
* @param client The client index.
* @param slot The slot index selected (starting from 0).
*/
*/
public WeaponsMenuTypesHandle(Handle:menu_weapons_types, MenuAction:action, client, slot)
{
// Client selected an option.
@ -176,7 +176,7 @@ public WeaponsMenuTypesHandle(Handle:menu_weapons_types, MenuAction:action, clie
{
// Menu slot index is = weapon type index.
g_iWeaponsCurType[client] = slot;
// Send weapons of the selected type in a menu to client.
WeaponsMenuTypeWeapons(client);
}
@ -198,77 +198,77 @@ public WeaponsMenuTypesHandle(Handle:menu_weapons_types, MenuAction:action, clie
/**
* Sends a list of weapons of a certain type in a menu to the client.
*
*
* @param client The client index.
*/
WeaponsMenuTypeWeapons(client)
{
// Create menu handle.
new Handle:menu_weapons_typeweapons = CreateMenu(WeaponsMenuTypeWeaponsHandle);
decl String:typename[WEAPONS_MAX_LENGTH];
RestrictWeaponTypeGetName(g_iWeaponsCurType[client], typename, sizeof(typename));
// Set translation language.
SetGlobalTransTarget(client);
decl String:title[MENU_LINE_TITLE_LENGTH];
decl String:restrictall[MENU_LINE_REG_LENGTH];
decl String:unrestrictall[MENU_LINE_REG_LENGTH];
Format(title, sizeof(title), "%t\n ", "Weapons menu restrict types weapon type title", typename);
Format(restrictall, sizeof(restrictall), "%t", "Weapons menu restrict types restrict all", typename);
Format(unrestrictall, sizeof(unrestrictall), "%t\n ", "Weapons menu restrict types unrestrict all", typename);
// Draw items as selectable only if not all weapons within the type are restricted or unrestricted.
SetMenuTitle(menu_weapons_typeweapons, title);
AddMenuItem(menu_weapons_typeweapons, "restrictall", restrictall, MenuGetItemDraw(!RestrictIsTypeUniform(true, g_iWeaponsCurType[client])));
AddMenuItem(menu_weapons_typeweapons, "unrestrictall", unrestrictall, MenuGetItemDraw(!RestrictIsTypeUniform(false, g_iWeaponsCurType[client])));
decl String:typeweapon[MENU_LINE_SMALL_LENGTH];
decl String:display[MENU_LINE_SMALL_LENGTH + 2]; // +2 to allow room for the [ ] if its restricted.
// Get an array populated with all weapons of the given type.
new Handle:arrayTypeWeapons;
new count = RestrictGetTypeWeapons(g_iWeaponsCurType[client], arrayTypeWeapons);
// x = Array index.
for (new x = 0; x < count; x++)
{
// Get weapon index to check restricted status of.
new weaponindex = GetArrayCell(arrayTypeWeapons, x);
// Get name of weapon.
WeaponsGetName(weaponindex, typeweapon, sizeof(typeweapon));
strcopy(display, sizeof(display), typeweapon);
if (RestrictIsWeaponRestricted(weaponindex))
{
Format(display, sizeof(display), "[%s]", typeweapon);
}
// Disable option if it isn't toggleable.
AddMenuItem(menu_weapons_typeweapons, typeweapon, display, MenuGetItemDraw(WeaponsGetToggleable(weaponindex)));
}
// Destroy the array handle.
CloseHandle(arrayTypeWeapons);
// Set menu back button.
SetMenuExitBackButton(menu_weapons_typeweapons, true);
// Display menu to client.
DisplayMenu(menu_weapons_typeweapons, client, MENU_TIME_FOREVER);
}
/**
* Called when client selects option in the weapon group menu, and handles it.
*
*
* @param menu_weapons_typeweapons Handle of the menu being used.
* @param action The action done on the menu (see menus.inc, enum MenuAction).
* @param client The client index.
* @param slot The slot index selected (starting from 0).
*/
*/
public WeaponsMenuTypeWeaponsHandle(Handle:menu_weapons_typeweapons, MenuAction:action, client, slot)
{
// Client selected an option.
@ -277,14 +277,14 @@ public WeaponsMenuTypeWeaponsHandle(Handle:menu_weapons_typeweapons, MenuAction:
// Get name of current weapon type.
decl String:typename[WEAPONS_MAX_LENGTH];
RestrictWeaponTypeGetName(g_iWeaponsCurType[client], typename, sizeof(typename));
new RestrictQuery:query;
new bool:single;
new bool:restrict;
decl String:returntarget[WEAPONS_MAX_LENGTH];
switch(slot)
{
{
case 0:
{
// Restrict all weapons of this type.
@ -302,17 +302,17 @@ public WeaponsMenuTypeWeaponsHandle(Handle:menu_weapons_typeweapons, MenuAction:
// Get weappon name.
decl String:typeweapon[MENU_LINE_REG_LENGTH];
GetMenuItem(menu_weapons_typeweapons, slot, typeweapon, sizeof(typeweapon));
// Get weapon index.
new weaponindex = WeaponsNameToIndex(typeweapon);
// If weapon index is -1, then something went very wrong.
if (weaponindex == -1)
{
CloseHandle(menu_weapons_typeweapons);
return;
}
// If weapon isn't restricted, then restrict it.
if (!RestrictIsWeaponRestricted(weaponindex))
{
@ -328,10 +328,10 @@ public WeaponsMenuTypeWeaponsHandle(Handle:menu_weapons_typeweapons, MenuAction:
}
}
}
// Print query response.
RestrictPrintQueryResponse(client, query, single, restrict, returntarget);
// Resend menu.
WeaponsMenuTypeWeapons(client);
}
@ -353,45 +353,45 @@ public WeaponsMenuTypeWeaponsHandle(Handle:menu_weapons_typeweapons, MenuAction:
/**
* Sends ZMarket options menu to client.
*
*
* @param client The client index.
*/
WeaponsMenuZMarket(client)
{
// Create menu handle.
new Handle:menu_weapons_market = CreateMenu(WeaponsMenuZMarketHandle);
// Get "yes" or "no" settings from respective cvar.
decl String:buyzonesetting[MENU_LINE_SMALL_LENGTH];
ConfigBoolToSetting(GetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE]), buyzonesetting, sizeof(buyzonesetting), true, client);
SetGlobalTransTarget(client);
decl String:title[MENU_LINE_TITLE_LENGTH];
decl String:buyzone[MENU_LINE_REG_LENGTH];
// Add options to menu.
Format(title, sizeof(title), "%t\n ", "Weapons menu restrict zmarket title");
Format(buyzone, sizeof(buyzone), "%t", "Weapons menu restrict zmarket buyzone", buyzonesetting);
SetMenuTitle(menu_weapons_market, title);
AddMenuItem(menu_weapons_market, "buyzone", buyzone);
// Create a "Back" button to the weapons main menu.
SetMenuExitBackButton(menu_weapons_market, true);
// Send menu
DisplayMenu(menu_weapons_market, client, MENU_TIME_FOREVER);
}
/**
* Called when client selects option in the weapons main menu, and handles it.
*
*
* @param menu_weapons_market Handle of the menu being used.
* @param action The action done on the menu (see menus.inc, enum MenuAction).
* @param client The client index.
* @param slot The slot index selected (starting from 0).
*/
*/
public WeaponsMenuZMarketHandle(Handle:menu_weapons_market, MenuAction:action, client, slot)
{
// Client selected an option.
@ -407,7 +407,7 @@ public WeaponsMenuZMarketHandle(Handle:menu_weapons_market, MenuAction:action, c
SetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE], !zmarketbuyzone);
}
}
// Resend menu.
WeaponsMenuZMarket(client);
}

View File

@ -77,7 +77,7 @@ RestrictInit()
/**
* Auto-create a list of types loaded by weapons module.
*/
*/
RestrictLoad()
{
// If array exists, then destroy it.
@ -85,31 +85,31 @@ RestrictLoad()
{
CloseHandle(arrayWeaponTypes);
}
// Initialize array.
arrayWeaponTypes = CreateArray(WEAPONS_MAX_LENGTH);
decl String:weapontype[WEAPONS_MAX_LENGTH];
new String:weapontypes[WEAPONS_RESTRICT_MAX_TYPES][WEAPONS_MAX_LENGTH];
// x = Array index.
new size = GetArraySize(arrayWeapons);
for (new x = 0; x < size; x++)
{
WeaponsGetType(x, weapontype, sizeof(weapontype));
ExplodeString(weapontype, ",", weapontypes, sizeof(weapontypes), sizeof(weapontypes[]));
for (new y = 0; y < WEAPONS_RESTRICT_MAX_TYPES; y++)
{
// Cut off whitespace.
TrimString(weapontypes[y]);
// If we've reached the end of the weapon's types, then stop.
if (!weapontypes[y][0])
{
break;
}
// If the weapon type isn't in the main array, then push it in.
if (FindStringInArray(arrayWeaponTypes, weapontypes[y]) == -1)
{
@ -132,7 +132,7 @@ RestrictOnCommandsCreate()
/**
* Client is joining the server.
*
*
* @param client The client index.
*/
RestrictClientInit(client)
@ -140,20 +140,20 @@ RestrictClientInit(client)
// Hook "Weapon_CanUse" on client.
#if defined USE_SDKHOOKS
SDKHook(client, SDKHook_WeaponCanUse, RestrictCanUse);
// Set dummy value so it think it's hooked.
g_iCanUseHookID[client] = 1;
#else
g_iCanUseHookID[client] = ZRTools_HookWeapon_CanUse(client, RestrictCanUse);
#endif
// Reset block weapons flag.
g_bRestrictBlockWeapon[client] = false;
}
/**
* Unhook Weapon_CanUse function on a client.
*
*
* @param client The client index.
*/
RestrictOnClientDisconnect(client)
@ -166,14 +166,14 @@ RestrictOnClientDisconnect(client)
#else
ZRTools_UnhookWeapon_CanUse(g_iCanUseHookID[client]);
#endif
g_iCanUseHookID[client] = -1;
}
}
/**
* Client is spawning into the game.
*
*
* @param client The client index.
*/
RestrictOnClientSpawn(client)
@ -187,14 +187,14 @@ RestrictOnClientSpawn(client)
ZRTools_UnhookWeapon_CanUse(g_iCanUseHookID[client]);
g_iCanUseHookID[client] = ZRTools_HookWeapon_CanUse(client, RestrictCanUse);
#endif
// H4x. Unfortunately I can't disable this flag early enough for CS:S to give start USP/Glock.
// So I have to give BOOTLEG weapons. (Sorry Valve)
if (g_bRestrictBlockWeapon[client])
{
// Reset block weapons flag.
g_bRestrictBlockWeapon[client] = false;
if (ZRIsClientOnTeam(client, CS_TEAM_T))
{
GivePlayerItem(client, WEAPONS_SPAWN_T_WEAPON);
@ -216,7 +216,7 @@ RestrictOnRoundEnd()
{
return;
}
// x = Client index.
for (new x = 1; x <= MaxClients; x++)
{
@ -225,13 +225,13 @@ RestrictOnRoundEnd()
{
continue;
}
// If client is a human, then stop.
if (InfectIsClientHuman(x))
{
continue;
}
// Enable block weapon flag.
g_bRestrictBlockWeapon[x] = true;
}
@ -240,7 +240,7 @@ RestrictOnRoundEnd()
/**
* Command callback function for the "buy" command
* Used to block use of this command under certain conditions.
*
*
* @param client The client index.
* @param argc Argument count.
*/
@ -251,52 +251,52 @@ public Action:RestrictBuyCommand(client, argc)
{
return Plugin_Continue;
}
// If the client isn't in a buyzone, then stop.
if (!WeaponsIsClientInBuyZone(client))
{
return Plugin_Continue;
}
// If player is a zombie, then block command.
if (InfectIsClientInfected(client))
{
TranslationPrintToChat(client, "Zombie cant use weapon");
// Block command
return Plugin_Handled;
}
decl String:weapon[WEAPONS_MAX_LENGTH];
GetCmdArg(1, weapon, sizeof(weapon));
// If the weapon is restricted, then prevent pickup.
decl String:weaponname[WEAPONS_MAX_LENGTH];
new weaponindex = WeaponsEntityToDisplay(weapon, weaponname, sizeof(weaponname), true);
// If weapon isn't configged, then allow pickup.
if (weaponindex == -1)
{
// Allow command.
return Plugin_Continue;
}
// If weapon is restricted, then stop.
if (RestrictIsWeaponRestricted(weaponindex))
{
TranslationPrintToChat(client, "Weapon is restricted", weaponname);
// Block command.
return Plugin_Handled;
}
// Allow command.
return Plugin_Continue;
}
/**
* Restricts (or unrestricts) a given weapon or weapon type.
*
*
* @param restrict True to restrict, false to unrestrict.
* @param target Weapon or weapon type to restrict/unrestrict.
* @param single True if a single weapon is being restricted, false if weapon type.
@ -308,41 +308,41 @@ RestrictQuery:RestrictWeapon(bool:restrict, const String:target[], &bool:single
{
// Copy 'target' to 'returntarget' to be possibly changed later.
strcopy(returntarget, maxlen, target);
// Find index of the given weapon type.
new typeindex = RestrictTypeToIndex(returntarget);
// Single weapon.
if (typeindex == -1)
{
single = true;
new weaponindex = WeaponsNameToIndex(returntarget);
// If weapon index is invalid, then return invalid.
if (weaponindex == -1)
{
return Query_Invalid;
}
// Return proper weapon name.
WeaponsGetName(weaponindex, returntarget, maxlen);
// If weapon is untoggleable, then return locked.
if (!WeaponsGetToggleable(weaponindex))
{
return Query_Locked;
}
// If weapon restriction is redundant then return stopped.
if (RestrictIsWeaponRestricted(weaponindex) == restrict)
{
return Query_Stopped;
}
// Set weapon's restricted state.
RestrictSetWeaponRestricted(weaponindex, false, restrict);
// Successfully restricted weapon.
return Query_Successful;
}
@ -350,35 +350,35 @@ RestrictQuery:RestrictWeapon(bool:restrict, const String:target[], &bool:single
else
{
single = false;
// Get all weapons in the given type.
new Handle:arrayTypeWeapons;
new count = RestrictGetTypeWeapons(typeindex, arrayTypeWeapons);
// Return proper weapon name.
RestrictWeaponTypeGetName(typeindex, returntarget, maxlen);
// If weapon restriction is redundant then return stopped.
if (RestrictIsTypeUniform(restrict, typeindex))
{
return Query_Stopped;
}
for (new x = 0; x < count; x++)
{
// Get weapon index.
new weaponindex = GetArrayCell(arrayTypeWeapons, x);
// If weapon is untoggleable, then stop.
if (!WeaponsGetToggleable(weaponindex))
{
continue;
}
// Set weapon's restricted state.
RestrictSetWeaponRestricted(weaponindex, false, restrict);
}
// Successfully restricted weapon type.
return Query_Successful;
}
@ -464,20 +464,20 @@ RestrictPrintQueryResponse(client, RestrictQuery:query, bool:single, bool:restri
stock RestrictTypeToIndex(const String:type[])
{
decl String:typename[WEAPONS_MAX_LENGTH];
// x = Array index.
new size = GetArraySize(arrayWeaponTypes);
for (new x = 0; x < size; x++)
{
RestrictWeaponTypeGetName(x, typename, sizeof(typename));
// If types match, then return index.
if (StrEqual(type, typename, false))
{
return x;
}
}
// Type doesn't exist.
return -1;
}
@ -496,7 +496,7 @@ stock RestrictWeaponTypeGetName(index, String:weapontype[], maxlen)
/**
* Returns an array containing all weapon indexes matching the given type.
*
*
* @param index The weapon type index.
* @param arrayTypeWeapons A handle to store array containing matching weapons.
* Don't forget to close this!
@ -505,33 +505,33 @@ stock RestrictGetTypeWeapons(index, &Handle:arrayTypeWeapons)
{
// Create array to hold weapons of the given type.
arrayTypeWeapons = CreateArray();
// Get name of the weapon type at given index.
decl String:typename[WEAPONS_MAX_LENGTH];
RestrictWeaponTypeGetName(index, typename, sizeof(typename));
new count;
decl String:weapontype[WEAPONS_MAX_LENGTH];
new String:weapontypes[WEAPONS_RESTRICT_MAX_TYPES][WEAPONS_MAX_LENGTH];
// x = Array index.
new size = GetArraySize(arrayWeapons);
for (new x = 0; x < size; x++)
{
WeaponsGetType(x, weapontype, sizeof(weapontype));
ExplodeString(weapontype, ",", weapontypes, sizeof(weapontypes), sizeof(weapontypes[]));
for (new y = 0; y < WEAPONS_RESTRICT_MAX_TYPES; y++)
{
// Cut off whitespace.
TrimString(weapontypes[y]);
// If we've reached the end of the weapon's types, then stop.
if (!weapontypes[y][0])
{
break;
}
// If types match, then add weapon to array.
if (StrEqual(typename, weapontypes[y], false))
{
@ -540,14 +540,14 @@ stock RestrictGetTypeWeapons(index, &Handle:arrayTypeWeapons)
}
}
}
// Return number of weapons of the given type.
return count;
}
/**
* Gets the restricted status on a weapon.
*
*
* @param index The weapon index.
* @param toggle If true, the value is toggled, otherwise 'restrict' param is used.
* @param restrict (Only if 'toggle' is 'false') Restricted status of the weapon.
@ -556,7 +556,7 @@ stock RestrictSetWeaponRestricted(index, bool:toggle, bool:restrict = false)
{
// Get array handle of weapon at given index.
new Handle:arrayWeapon = GetArrayCell(arrayWeapons, index);
// Set restricted status.
new bool:value = toggle ? !RestrictIsWeaponRestricted(index) : restrict;
SetArrayCell(arrayWeapon, _:WEAPONS_DATA_RESTRICTED, value);
@ -564,7 +564,7 @@ stock RestrictSetWeaponRestricted(index, bool:toggle, bool:restrict = false)
/**
* Gets the restricted status on a weapon.
*
*
* @param index The weapon index.
* @return True if weapon is restricted, false if not.
*/
@ -572,14 +572,14 @@ stock bool:RestrictIsWeaponRestricted(index)
{
// Get array handle of weapon at given index.
new Handle:arrayWeapon = GetArrayCell(arrayWeapons, index);
// Return restricted status.
return bool:GetArrayCell(arrayWeapon, _:WEAPONS_DATA_RESTRICTED);
}
/**
* Used to check if all weapons of a type are restricted.
*
*
* @param restricted True to check if all weapons of given type are restricted.
* @param index The weapon type index.
* @return True if all weapons of the given type are restricted or not, false if not.
@ -588,20 +588,20 @@ stock bool:RestrictIsTypeUniform(bool:restricted, index)
{
new Handle:arrayTypeWeapons;
new count = RestrictGetTypeWeapons(index, arrayTypeWeapons);
// x = array index
for (new x = 0; x < count; x++)
{
// Get weapon index to check restricted status of.
new weaponindex = GetArrayCell(arrayTypeWeapons, x);
// If weapon is toggleable and it's not uniform with the given status, then return false.
if (WeaponsGetToggleable(weaponindex) && RestrictIsWeaponRestricted(weaponindex) != restricted)
{
return false;
}
}
// All weapons are restricted, so return true.
return true;
}
@ -621,59 +621,59 @@ public ZRTools_Action:RestrictCanUse(client, weapon)
{
new String:weaponentity[WEAPONS_MAX_LENGTH];
GetEdictClassname(weapon, weaponentity, sizeof(weaponentity));
// If weapon is a knife, then allow pickup.
if (StrEqual(weaponentity, "weapon_knife"))
{
return ACTION_CONTINUE;
}
// If the player is a zombie, then prevent pickup.
if (InfectIsClientInfected(client))
{
return ACTION_HANDLED;
}
// If client is flagged for not picking up weapons, then stop.
if (g_bRestrictBlockWeapon[client])
{
return ACTION_HANDLED;
}
// If weapons module is disabled, then stop.
new bool:weapons = GetConVarBool(g_hCvarsList[CVAR_WEAPONS]);
if (!weapons)
{
return ACTION_CONTINUE;
}
// If restrict module is disabled, then stop.
new bool:restrict = GetConVarBool(g_hCvarsList[CVAR_WEAPONS_RESTRICT]);
if (!restrict)
{
return ACTION_CONTINUE;
}
// If the weapon is restricted, then prevent pickup.
decl String:weaponname[WEAPONS_MAX_LENGTH];
new weaponindex = WeaponsEntityToDisplay(weaponentity, weaponname, sizeof(weaponname));
// If weapon isn't configged, then allow pickup.
if (weaponindex == -1)
{
// Allow pickup.
return ACTION_CONTINUE;
}
// If weapon is restricted, then stop.
if (RestrictIsWeaponRestricted(weaponindex))
{
return ACTION_HANDLED;
}
// Forward event to weapons module.
WeaponsOnItemPickup(client, weapon);
// Allow pickup.
return ACTION_CONTINUE;
}
@ -685,7 +685,7 @@ public ZRTools_Action:RestrictCanUse(client, weapon)
/**
* Command callback (zr_restrict)
* Restricts a weapon or group
*
*
* @param client The client index.
* @param argc Argument count.
*/
@ -697,7 +697,7 @@ public Action:RestrictCommand(client, argc)
TranslationReplyToCommand(client, "No access to command");
return Plugin_Handled;
}
// If weapons module is disabled, then stop.
new bool:weapons = GetConVarBool(g_hCvarsList[CVAR_WEAPONS]);
if (!weapons)
@ -706,7 +706,7 @@ public Action:RestrictCommand(client, argc)
TranslationReplyToCommand(client, "Feature is disabled");
return Plugin_Handled;
}
// If restrict module is disabled, then stop.
new bool:restrict = GetConVarBool(g_hCvarsList[CVAR_WEAPONS_RESTRICT]);
if (!restrict)
@ -715,38 +715,38 @@ public Action:RestrictCommand(client, argc)
TranslationReplyToCommand(client, "Feature is disabled");
return Plugin_Handled;
}
// If not enough arguments given, then stop.
if (argc < 1)
{
TranslationReplyToCommand(client, "Weapons command restrict syntax");
return Plugin_Handled;
}
decl String:target[WEAPONS_MAX_LENGTH];
new args = GetCmdArgs();
for (new x = 1; x <= args; x++)
{
// Get target to restrict.
GetCmdArg(x, target, sizeof(target));
// Query restrict on this target, and get a result back.
new bool:single;
decl String:returntarget[WEAPONS_MAX_LENGTH];
new RestrictQuery:query = RestrictWeapon(true, target, single, returntarget, sizeof(returntarget));
// Print response to client(s).
RestrictPrintQueryResponse(client, query, single, true, returntarget);
}
return Plugin_Handled;
}
/**
* Command callback (zr_unrestrict)
* Unrestricts a weapon or group
*
*
* @param client The client index.
* @param argc Argument count.
*/
@ -758,7 +758,7 @@ public Action:UnrestrictCommand(client, argc)
TranslationReplyToCommand(client, "No access to command");
return Plugin_Handled;
}
// If weapons module is disabled, then stop.
new bool:weapons = GetConVarBool(g_hCvarsList[CVAR_WEAPONS]);
if (!weapons)
@ -767,7 +767,7 @@ public Action:UnrestrictCommand(client, argc)
TranslationReplyToCommand(client, "Feature is disabled");
return Plugin_Handled;
}
// If restrict module is disabled, then stop.
new bool:restrict = GetConVarBool(g_hCvarsList[CVAR_WEAPONS_RESTRICT]);
if (!restrict)
@ -776,31 +776,31 @@ public Action:UnrestrictCommand(client, argc)
TranslationReplyToCommand(client, "Feature is disabled");
return Plugin_Handled;
}
// If not enough arguments given, then stop.
if (argc < 1)
{
TranslationReplyToCommand(client, "Weapons command unrestrict syntax");
return Plugin_Handled;
}
// arg1 = weapon being restricted
decl String:target[WEAPONS_MAX_LENGTH];
new args = GetCmdArgs();
for (new x = 1; x <= args; x++)
{
// Get target to restrict.
GetCmdArg(x, target, sizeof(target));
// Query unrestrict on this target, and get a result back.
new bool:single;
decl String:returntarget[WEAPONS_MAX_LENGTH];
new RestrictQuery:query = RestrictWeapon(false, target, single, returntarget, sizeof(returntarget));
// Print response to client(s).
RestrictPrintQueryResponse(client, query, single, false, returntarget);
}
return Plugin_Handled;
}

View File

@ -4,7 +4,7 @@
* Zombie:Reloaded
*
* File: weaponalpha.inc
* Type: Core
* Type: Core
* Description: Weapon alpha functions, and alpha updating on drop/pickup.
*
* Copyright (C) 2009-2013 Greyscale, Richard Helgeby
@ -37,7 +37,7 @@ new g_iWeaponDropHookID[MAXPLAYERS + 1] = {-1, ...};
/**
* Client is joining the server.
*
*
* @param client The client index.
*/
WeaponAlphaClientInit(client)
@ -46,7 +46,7 @@ WeaponAlphaClientInit(client)
// Hook "Weapon_Drop" on client.
#if defined USE_SDKHOOKS
SDKHook(client, SDKHook_WeaponDrop, WeaponAlphaDrop);
// Set dummy value so it think it's hooked.
g_iWeaponDropHookID[client] = 1;
#else
@ -56,7 +56,7 @@ WeaponAlphaClientInit(client)
/**
* Client is leaving the server.
*
*
* @param client The client index.
*/
WeaponAlphaOnClientDisconnect(client)
@ -70,16 +70,16 @@ WeaponAlphaOnClientDisconnect(client)
#else
ZRTools_UnhookWeapon_Drop(g_iWeaponDropHookID[client]);
#endif
g_iWeaponDropHookID[client] = -1;
}
}
/**
* Client has just picked up a weapon.
*
*
* @param client The client index.
* @param weapon The weapon index.
* @param weapon The weapon index.
*/
WeaponAlphaOnItemPickupPost(client, weapon)
{
@ -93,10 +93,10 @@ WeaponAlphaOnItemPickupPost(client, weapon)
// (entity 666/info_particle_system)
return;
}
// Get client's current alpha.
new alpha = ToolsGetEntityAlpha(client);
// Set new alpha on weapons.
WeaponAlphaApplyWeaponAlpha(weapon, alpha);
}
@ -104,7 +104,7 @@ WeaponAlphaOnItemPickupPost(client, weapon)
/**
* Callback function for Weapon_Drop.
* Called when a client drops their weapon.
*
*
* @param client The client index.
* @param weapon The weapon index.
*/
@ -120,14 +120,14 @@ public ZRTools_Action:WeaponAlphaDrop(client, weapon)
{
return;
}
// Set new alpha on weapons.
WeaponAlphaApplyWeaponAlpha(weapon, WEAPONALPHA_DEFAULT_VALUE);
}
/**
* A client's alpha has been changed by the plugin.
*
*
* @param client The client index.
*/
WeaponAlphaOnClientAlphaChanged(client, alpha)
@ -139,7 +139,7 @@ WeaponAlphaOnClientAlphaChanged(client, alpha)
/**
* Set's the alpha on a client's weapons.
*
*
* @param entity If client index is given, alpha will be set on all their weapons.
* If a non-client index is given, alpha will be set on given entity.
* @param alpha The alpha to set the weapons to.
@ -151,18 +151,18 @@ WeaponAlphaApplyWeaponAlpha(entity, alpha)
{
// Turn rendermode on, on the weapon.
SetEntityRenderMode(entity, RENDER_TRANSALPHA);
// Set alpha value on the weapon.
SetEntityRenderColor(entity, _, _, _, alpha);
// Entity alpha has been set, so stop.
return;
}
// Get client's list of weapons.
new weapons[WeaponsSlot];
WeaponsGetClientWeapons(entity, weapons);
// Loop through array slots and set alpha.
// x = weapon slot.
for (new x = 0; x < WEAPONS_SLOTS_MAX; x++)
@ -172,10 +172,10 @@ WeaponAlphaApplyWeaponAlpha(entity, alpha)
{
continue;
}
// Turn rendermode on, on the weapon.
SetEntityRenderMode(weapons[x], RENDER_TRANSALPHA);
// Set alpha value on the weapon.
SetEntityRenderColor(weapons[x], _, _, _, alpha);
}

View File

@ -4,7 +4,7 @@
* Zombie:Reloaded
*
* File: weaponammo.inc
* Type: Core
* Type: Core
* Description: API for all weaponammo-related functions.
*
* Copyright (C) 2009-2013 Greyscale, Richard Helgeby
@ -90,14 +90,14 @@ WeaponAmmoOnOffsetsFound()
{
LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Weapons, "Offsets", "Offset \"CBaseCombatWeapon::m_iClip1\" was not found.");
}
// If offset "m_iClip2" can't be found, then stop the plugin.
g_iToolsClip2 = FindSendPropInfo("CBaseCombatWeapon", "m_iClip2");
if (g_iToolsClip2 == -1)
{
LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Weapons, "Offsets", "Offset \"CBaseCombatWeapon::m_iClip2\" was not found.");
}
// If offset "m_iAmmo" can't be found, then stop the plugin.
g_iToolsAmmo = FindSendPropInfo("CBasePlayer", "m_iAmmo");
if (g_iToolsAmmo == -1)
@ -108,7 +108,7 @@ WeaponAmmoOnOffsetsFound()
/**
* Set clip/reserve ammo on a weapon.
*
*
* @param weapon The weapon index.
* @param clip True sets clip ammo, false sets reserve.
* @param value The amount of ammo to set to.
@ -118,23 +118,23 @@ stock WeaponAmmoSetAmmo(weapon, bool:clip, value, bool:add = false)
{
// Set variable to offset we are changing.
new ammooffset = clip ? g_iToolsClip1 : g_iToolsClip2;
// Initialize variable (value is 0)
new ammovalue;
// If we are adding, then update variable with current ammo value.
if (add)
{
ammovalue = WeaponAmmoGetAmmo(weapon, clip);
}
// Return ammo offset value.
SetEntData(weapon, ammooffset, ammovalue + value, _, true);
}
/**
* Get clip/reserve ammo on a weapon.
*
*
* @param weapon The weapon index.
* @param clip True gets clip ammo, false gets reserve.
*/
@ -142,36 +142,36 @@ stock WeaponAmmoGetAmmo(weapon, bool:clip)
{
// Set variable to offset we are changing.
new ammooffset = clip ? g_iToolsClip1 : g_iToolsClip2;
// Return ammo offset value.
return GetEntData(weapon, ammooffset);
}
/**
* Set the count of any grenade-type a client has.
*
*
* @param client The client index.
* @param slot The type of
* @param value The amount of ammo to set to.
* @param add (Optional) If true, the value is added to the grenades' current ammo count.
* @param add (Optional) If true, the value is added to the grenades' current ammo count.
*/
stock WeaponAmmoSetGrenadeCount(client, WeaponAmmoGrenadeType:type, value, bool:add)
{
// Initialize variable (value is 0)
new ammovalue;
// If we are adding, then update variable with current ammo value.
if (add)
{
ammovalue = WeaponAmmoGetGrenadeCount(client, type);
}
SetEntData(client, g_iToolsAmmo + (_:type * 4), ammovalue + value, _, true);
}
/**
* Get the count of any grenade-type a client has.
*
*
* @param client The client index.
* @param slot The type of
*/
@ -182,7 +182,7 @@ stock WeaponAmmoGetGrenadeCount(client, WeaponAmmoGrenadeType:type)
/**
* Takes a weapon entity and returns an entry in enum WeaponAmmoGrenadeType.
*
*
* @param weaponentity The weapon entity to find entry for.
* @return An entry in WeaponAmmoGrenadeType.
*/
@ -200,15 +200,15 @@ stock WeaponAmmoGrenadeType:WeaponAmmoEntityToGrenadeType(const String:weaponent
{
return GrenadeType_Smokegrenade;
}
return GrenadeType_Invalid;
}
/**
* Returns the max amount of this type of grenades the client is allowed to carry.
*
*
* @param weaponentity The weapon entity to get the limit for.
* @return The grenade limit, -1 if an unhandled grenade entity was given.
* @return The grenade limit, -1 if an unhandled grenade entity was given.
*/
stock WeaponAmmoGetGrenadeLimit(WeaponAmmoGrenadeType:grenadetype)
{
@ -218,7 +218,7 @@ stock WeaponAmmoGrenadeType:WeaponAmmoEntityToGrenadeType(const String:weaponent
{
// Attempt to find a cvar provided by an outside plugin.
new Handle:gplimit = FindConVar(GRENADE_PACK_CVAR_LIMIT);
// If Grenade Pack is loaded and the cvar was found, then get the value of the outside cvar, if not return CS:S default.
return (g_bGrenadePack && gplimit != INVALID_HANDLE) ? GetConVarInt(gplimit) : WEAPONAMMO_HEGRENADE_LIMIT;
}
@ -231,7 +231,7 @@ stock WeaponAmmoGrenadeType:WeaponAmmoEntityToGrenadeType(const String:weaponent
return WEAPONAMMO_SMOKEGRENADE_LIMIT;
}
}
return -1;
}
@ -243,25 +243,25 @@ stock bool:ZMarketIsGPLoaded()
new Handle:hPlugins = GetPluginIterator();
new Handle:hPlugin;
decl String:strPlugin[PLATFORM_MAX_PATH];
while (MorePlugins(hPlugins))
{
// Read the next plugin.
hPlugin = ReadPlugin(hPlugins);
GetPluginFilename(hPlugin, strPlugin, sizeof(strPlugin));
if (!StrEqual(strPlugin, GRENADE_PACK_FILENAME, false))
{
continue;
}
// Plugin was found, now return true only if it is running.
return (GetPluginStatus(hPlugin) == Plugin_Running);
}
// Done iterating, close handle.
CloseHandle(hPlugins);
// Plugin wasn't found.
return false;
}

View File

@ -4,7 +4,7 @@
* Zombie:Reloaded
*
* File: weapons.inc
* Type: Core
* Type: Core
* Description: API for all weapon-related functions.
*
* Copyright (C) 2009-2013 Greyscale, Richard Helgeby
@ -126,14 +126,14 @@ WeaponsOnOffsetsFound()
{
LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Weapons, "Offsets", "Offset \"CBasePlayer::m_hActiveWeapon\" was not found.");
}
// If offset "m_bInBuyZone" can't be found, then stop the plugin.
g_iToolsInBuyZone = FindSendPropInfo("CCSPlayer", "m_bInBuyZone");
if (g_iToolsInBuyZone == -1)
{
LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Weapons, "Offsets", "Offset \"CCSPlayer::m_bInBuyZone\" was not found.");
}
// Forward event to sub-modules
WeaponAmmoOnOffsetsFound();
}
@ -164,54 +164,54 @@ WeaponsLoad()
{
// Register config file.
ConfigRegisterConfig(File_Weapons, Structure_Keyvalue, CONFIG_FILE_ALIAS_WEAPONS);
// If module is disabled, then stop.
new bool:weapons = GetConVarBool(g_hCvarsList[CVAR_WEAPONS]);
if (!weapons)
{
return;
}
// Get weapons config path.
decl String:pathweapons[PLATFORM_MAX_PATH];
new bool:exists = ConfigGetCvarFilePath(CVAR_CONFIG_PATH_WEAPONS, pathweapons);
// If file doesn't exist, then log and stop.
if (!exists)
{
// Log failure.
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Weapons, "Config Validation", "Missing weapons config file: %s", pathweapons);
return;
}
// Set the path to the config file.
ConfigSetConfigPath(File_Weapons, pathweapons);
// Load config from file and create array structure.
new bool:success = ConfigLoadConfig(File_Weapons, arrayWeapons);
// Unexpected error, stop plugin.
if (!success)
{
LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Weapons, "Config Validation", "Unexpected error encountered loading: %s", pathweapons);
}
// Validate weapons config.
new size = GetArraySize(arrayWeapons);
if (!size)
{
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Weapons, "Config Validation", "No usable data found in weapons config file: %s", pathweapons);
}
// Now copy data to array structure.
WeaponsCacheData();
// Set config data.
ConfigSetConfigLoaded(File_Weapons, true);
ConfigSetConfigReloadFunc(File_Weapons, GetFunctionByName(GetMyHandle(), "WeaponsOnConfigReload"));
ConfigSetConfigHandle(File_Weapons, arrayWeapons);
// Forward event to sub-modules
RestrictLoad();
}
@ -225,17 +225,17 @@ WeaponsCacheData()
// Get config's file path.
decl String:pathweapons[PLATFORM_MAX_PATH];
ConfigGetConfigPath(File_Weapons, pathweapons, sizeof(pathweapons));
new Handle:kvWeapons;
new bool:success = ConfigOpenConfigFile(File_Weapons, kvWeapons);
if (!success)
{
LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Weapons, "Config Validation", "Unexpected error caching data from weapons config file: %s", pathweapons);
}
decl String:weaponname[WEAPONS_MAX_LENGTH];
// x = array index
new size = GetArraySize(arrayWeapons);
for (new x = 0; x < size; x++)
@ -247,35 +247,35 @@ WeaponsCacheData()
LogEvent(false, LogType_Error, LOG_CORE_EVENTS, LogModule_Weapons, "Config Validation", "Couldn't cache weapon data for: %s (check weapons config)", weaponname);
continue;
}
// Get config data.
decl String:weaponentity[CONFIG_MAX_LENGTH];
decl String:weapontype[CONFIG_MAX_LENGTH];
decl String:ammotype[CONFIG_MAX_LENGTH];
// General
KvGetString(kvWeapons, "weaponentity", weaponentity, sizeof(weaponentity));
KvGetString(kvWeapons, "weapontype", weapontype, sizeof(weapontype));
new WeaponsSlot:weaponslot = WeaponsSlot:KvGetNum(kvWeapons, "weaponslot", -1);
// Restrict (core)
new bool:restrictdefault = ConfigKvGetStringBool(kvWeapons, "restrictdefault", "no");
new bool:toggleable = ConfigKvGetStringBool(kvWeapons, "toggleable", "yes");
// Weapon Ammo (core)
KvGetString(kvWeapons, "ammotype", ammotype, sizeof(ammotype));
new ammoprice = KvGetNum(kvWeapons, "ammoprice", -1);
// Knockback (module)
new Float:knockback = KvGetFloat(kvWeapons, "knockback", 1.0);
// ZMarket (module)
new zmarketprice = KvGetNum(kvWeapons, "zmarketprice", -1);
new zmarketpurchasemax = KvGetNum(kvWeapons, "zmarketpurchasemax", 0);
new Handle:arrayWeapon = GetArrayCell(arrayWeapons, x);
// Push data into array.
PushArrayString(arrayWeapon, weaponentity); // Index: 1
PushArrayString(arrayWeapon, weapontype); // Index: 2
@ -287,11 +287,11 @@ WeaponsCacheData()
PushArrayCell(arrayWeapon, knockback); // Index: 8
PushArrayCell(arrayWeapon, zmarketprice); // Index: 9
PushArrayCell(arrayWeapon, zmarketpurchasemax); // Index: 10
// Initialize other stored weapon info here.
PushArrayCell(arrayWeapon, restrictdefault); // Index: 11
}
// We're done with this file now, so we can close it.
CloseHandle(kvWeapons);
}
@ -304,11 +304,11 @@ public WeaponsOnConfigReload()
// Reload weapons config.
WeaponsLoad();
}
/**
* Client is joining the server.
*
* @param client The client index.
*
* @param client The client index.
*/
WeaponsClientInit(client)
{
@ -320,7 +320,7 @@ WeaponsClientInit(client)
/**
* Called once a client's saved cookies have been loaded from the database.
*
*
* @param client Client index.
*/
WeaponsOnCookiesCached(client)
@ -331,7 +331,7 @@ WeaponsOnCookiesCached(client)
/**
* Client is leaving the server.
*
*
* @param client The client index.
*/
WeaponsOnClientDisconnect(client)
@ -344,7 +344,7 @@ WeaponsOnClientDisconnect(client)
/**
* Client is spawning into the game.
*
*
* @param client The client index.
*/
WeaponsOnClientSpawn(client)
@ -355,14 +355,14 @@ WeaponsOnClientSpawn(client)
/**
* Client is spawning into the game. *Post
*
*
* @param client The client index.
*/
WeaponsOnClientSpawnPost(client)
{
// Refresh all weapons on clients to cleanup any rendering errors.
WeaponsRefreshAllClientWeapons(client);
// Forward event to sub-modules.
ZMarketOnClientSpawnPost(client);
}
@ -378,28 +378,28 @@ WeaponsOnRoundEnd()
/**
* Called when a client picks up an item.
*
*
* @param client The client index.
* @param weapon The weapon index.
*/
WeaponsOnItemPickup(client, weapon)
{
// Forward event to sub-modules.
// Fire post OnItemPickup event.
// Fill datapack with event information.
new Handle:eventinfo = CreateDataPack();
WritePackCell(eventinfo, client);
WritePackCell(eventinfo, weapon);
// Create post delay timer.
CreateTimer(0.0, WeaponsOnItemPickupPost, eventinfo, TIMER_DATA_HNDL_CLOSE);
}
/**
* Called when a client picks up an item. *Post
*
*
* @param client The client index.
* @param weapon The weapon index.
*/
@ -409,19 +409,19 @@ public Action:WeaponsOnItemPickupPost(Handle:timer, Handle:eventinfo)
ResetPack(eventinfo);
new client = ReadPackCell(eventinfo);
new weapon = ReadPackCell(eventinfo);
// If client isn't in the game anymore, then stop.
if (!IsClientInGame(client))
{
return;
}
// If the weapon entity isn't valid anymore, then stop.
if (!IsValidEdict(weapon))
{
return;
}
// Forward event to sub-modules.
WeaponAlphaOnItemPickupPost(client, weapon);
}
@ -432,53 +432,53 @@ public Action:WeaponsOnItemPickupPost(Handle:timer, Handle:eventinfo)
/**
* Clear cache for a given weapon.
*
*
* @param index The weapon index.
*/
stock WeaponsClearCache(index)
{
// Get array handle of weapon at given index.
new Handle:hWeapon = GetArrayCell(arrayWeapons, index);
// Clear array.
ClearArray(hWeapon);
}
/**
* Find the index at which the weapon's name is at.
*
*
* @param weapon The weapon name.
* @return The array index containing the given weapon name.
*/
stock WeaponsNameToIndex(const String:weapon[])
{
decl String:weaponname[WEAPONS_MAX_LENGTH];
// x = Array index.
new size = GetArraySize(arrayWeapons);
for (new x = 0; x < size; x++)
{
WeaponsGetName(x, weaponname, sizeof(weaponname));
// If names match, then return index.
if (StrEqual(weapon, weaponname, false))
{
return x;
}
}
// Name doesn't exist.
return -1;
}
/**
* Takes a weapon's entity name and returns the display name in weapons config file.
*
*
* @param entityname The entity to find the display of.
* @param display Buffer to store display name in.
* @param displaymaxlen The max length of the display name.
* @param noprefix If this is true, the entity name will be compared without the weapon_/item_ prefix.
* @return The index of the weapon found.
* @return The index of the weapon found.
*/
stock WeaponsEntityToDisplay(const String:entityname[], String:display[], displaymaxlen, noprefix = false)
{
@ -487,38 +487,38 @@ stock WeaponsEntityToDisplay(const String:entityname[], String:display[], displa
{
return -1;
}
decl String:weaponentity[WEAPONS_MAX_LENGTH];
// Initialize string to null.
strcopy(display, sizeof(displaymaxlen), "");
// x = Array index.
new size = GetArraySize(arrayWeapons);
for (new x = 0; x < size; x++)
{
// If entity names don't match, then stop.
WeaponsGetEntity(x, weaponentity, sizeof(weaponentity));
// If noprefix is true, then strip the weapon_/item_ prefix.
if (noprefix)
{
ReplaceString(weaponentity, sizeof(weaponentity), "weapon_", "");
ReplaceString(weaponentity, sizeof(weaponentity), "item_", "");
}
if (!StrEqual(entityname, weaponentity, false))
{
continue;
}
// The entity names match, so return display.
WeaponsGetName(x, display, displaymaxlen);
// Return the weapon index.
return x;
}
// Nothing was found.
return -1;
}
@ -543,7 +543,7 @@ stock WeaponsGetName(index, String:weapon[], maxlen)
{
// Get array handle of weapon at given index.
new Handle:arrayWeapon = GetArrayCell(arrayWeapons, index);
// Get weapon name.
GetArrayString(arrayWeapon, _:WEAPONS_DATA_NAME, weapon, maxlen);
}
@ -558,7 +558,7 @@ stock WeaponsGetEntity(index, String:type[], maxlen)
{
// Get array handle of weapon at given index.
new Handle:arrayWeapon = GetArrayCell(arrayWeapons, index);
// Get weapon type.
GetArrayString(arrayWeapon, _:WEAPONS_DATA_ENTITY, type, maxlen);
}
@ -573,7 +573,7 @@ stock WeaponsGetType(index, String:type[], maxlen)
{
// Get array handle of weapon at given index.
new Handle:arrayWeapon = GetArrayCell(arrayWeapons, index);
// Get weapon type.
GetArrayString(arrayWeapon, _:WEAPONS_DATA_TYPE, type, maxlen);
}
@ -587,7 +587,7 @@ stock WeaponsSlot:WeaponsGetSlot(index)
{
// Get array handle of weapon at given index.
new Handle:arrayWeapon = GetArrayCell(arrayWeapons, index);
// Return default restriction status.
return WeaponsSlot:GetArrayCell(arrayWeapon, _:WEAPONS_DATA_SLOT);
}
@ -601,7 +601,7 @@ stock bool:WeaponsGetRestrictDefault(index)
{
// Get array handle of weapon at given index.
new Handle:arrayWeapon = GetArrayCell(arrayWeapons, index);
// Return default restriction status.
return bool:GetArrayCell(arrayWeapon, _:WEAPONS_DATA_RESTRICTDEFAULT);
}
@ -615,7 +615,7 @@ stock bool:WeaponsGetToggleable(index)
{
// Get array handle of weapon at given index.
new Handle:arrayWeapon = GetArrayCell(arrayWeapons, index);
// Return if weapon is toggleable.
return bool:GetArrayCell(arrayWeapon, _:WEAPONS_DATA_TOGGLEABLE);
}
@ -630,7 +630,7 @@ stock WeaponsGetAmmoType(index, String:ammotype[], maxlen)
{
// Get array handle of weapon at given index.
new Handle:arrayWeapon = GetArrayCell(arrayWeapons, index);
// Get ammo type of the weapon.
GetArrayString(arrayWeapon, _:WEAPONS_DATA_AMMOTYPE, ammotype, maxlen);
}
@ -644,7 +644,7 @@ stock WeaponsGetAmmoPrice(index)
{
// Get array handle of weapon at given index.
new Handle:arrayWeapon = GetArrayCell(arrayWeapons, index);
// Return ammo price of the weapon.
return GetArrayCell(arrayWeapon, _:WEAPONS_DATA_AMMOPRICE);
}
@ -658,7 +658,7 @@ stock Float:WeaponsGetKnockback(index)
{
// Get array handle of weapon at given index.
new Handle:arrayWeapon = GetArrayCell(arrayWeapons, index);
// Return knockback multiplier of the weapon.
return Float:GetArrayCell(arrayWeapon, _:WEAPONS_DATA_KNOCKBACK);
}
@ -672,7 +672,7 @@ stock WeaponsGetZMarketPrice(index)
{
// Get array handle of weapon at given index.
new Handle:arrayWeapon = GetArrayCell(arrayWeapons, index);
// Return the ZMarket price of the weapon.
return GetArrayCell(arrayWeapon, _:WEAPONS_DATA_ZMARKETPRICE);
}
@ -686,7 +686,7 @@ stock WeaponsGetZMarketPurchaseMax(index)
{
// Get array handle of weapon at given index.
new Handle:arrayWeapon = GetArrayCell(arrayWeapons, index);
// Return the ZMarket price of the weapon.
return GetArrayCell(arrayWeapon, _:WEAPONS_DATA_ZMARKETPURCHASEMAX);
}
@ -697,7 +697,7 @@ stock WeaponsGetZMarketPurchaseMax(index)
/**
* Checks if a client has a specific weapon.
*
*
* @param client The client index.
* @param weapon The weapon classname.
*/
@ -706,9 +706,9 @@ stock bool:WeaponsClientHasWeapon(client, const String:weapon[])
// Get all of client's current weapons.
new weapons[WeaponsSlot];
WeaponsGetClientWeapons(client, weapons);
decl String:classname[64];
// x = slot index
for (new x = 0; x < WEAPONS_SLOTS_MAX; x++)
{
@ -717,7 +717,7 @@ stock bool:WeaponsClientHasWeapon(client, const String:weapon[])
{
continue;
}
// If the weapon's classname matches, then return true.
GetEdictClassname(weapons[x], classname, sizeof(classname));
if (StrEqual(weapon, classname, false))
@ -725,16 +725,16 @@ stock bool:WeaponsClientHasWeapon(client, const String:weapon[])
return true;
}
}
return false;
}
/**
* Return an array that contains all client's weapon indexes.
*
*
* @param client The client index.
* @param weapons The weapon index array.
* -1 if no weapon in slot.
* -1 if no weapon in slot.
*/
stock WeaponsGetClientWeapons(client, weapons[WeaponsSlot])
{
@ -747,10 +747,10 @@ stock WeaponsGetClientWeapons(client, weapons[WeaponsSlot])
/**
* Returns weapon index of the client's deployed weapon.
*
*
* @param client The client index.
* @return The weapon index of the deployed weapon.
* -1 if no weapon is deployed.
* -1 if no weapon is deployed.
*/
stock WeaponsGetDeployedWeaponIndex(client)
{
@ -769,16 +769,16 @@ stock WeaponsSlot:WeaponsGetDeployedWeaponSlot(client)
// Get all client's weapon indexes.
new weapons[WeaponsSlot];
WeaponsGetClientWeapons(client, weapons);
// Get client's deployed weapon.
new deployedweapon = WeaponsGetDeployedWeaponIndex(client);
// If client has no deployed weapon, then stop.
if (deployedweapon == -1)
{
return Type_Invalid;
}
// x = weapon slot.
for (new x = 0; x < WEAPONS_SLOTS_MAX; x++)
{
@ -787,13 +787,13 @@ stock WeaponsSlot:WeaponsGetDeployedWeaponSlot(client)
return WeaponsSlot:x;
}
}
return Type_Invalid;
}
/**
* Forces player to drop weapon index. (Simplified wrapper)
*
*
* @param client The client index.
* @param weapon The weapon index to force client to drop.
*/
@ -805,9 +805,9 @@ stock WeaponsForceClientDrop(client, weapon)
/**
* Used to explicitly remove projectile weapons from a client.
*
*
* @param client The client index.
* @param weaponsdrop True to force drop on all weapons, false to strip.
* @param weaponsdrop True to force drop on all weapons, false to strip.
*/
stock WeaponsRemoveClientGrenades(client, bool:weaponsdrop)
{
@ -826,7 +826,7 @@ stock WeaponsRemoveClientGrenades(client, bool:weaponsdrop)
RemovePlayerItem(client, grenade);
AcceptEntityInput(grenade, "Kill");
}
// Find next grenade.
grenade = GetPlayerWeaponSlot(client, _:Slot_Projectile);
}
@ -834,24 +834,24 @@ stock WeaponsRemoveClientGrenades(client, bool:weaponsdrop)
/**
* Refresh a weapon by taking it and giving it back.
*
*
* @param client The client index.
* @param slot The weapon slot to refresh. (see enum WeaponsSlot)
*/
stock WeaponsRefreshClientWeapon(client, WeaponsSlot:slot)
{
new weaponindex = GetPlayerWeaponSlot(client, _:slot);
// If weapon is invalid, then stop.
if (weaponindex == -1)
{
return;
}
// Get the classname of the weapon to re-give.
decl String:entityname[WEAPONS_MAX_LENGTH];
GetEdictClassname(weaponindex, entityname, sizeof(entityname));
// Refresh weapon.
RemovePlayerItem(client, weaponindex);
AcceptEntityInput(weaponindex, "Kill");
@ -860,7 +860,7 @@ stock WeaponsRefreshClientWeapon(client, WeaponsSlot:slot)
/**
* Remove all weapons, except knife, on a client, with options.
*
*
* @param client The client index.
* @param weaponsdrop True to force drop on all weapons, false to strip.
*/
@ -869,7 +869,7 @@ stock WeaponsRemoveAllClientWeapons(client, bool:weaponsdrop)
// Get a list of all client's weapon indexes.
new weapons[WeaponsSlot];
WeaponsGetClientWeapons(client, weapons);
// Loop through array slots and force drop.
// x = weapon slot.
for (new x = 0; x < WEAPONS_SLOTS_MAX; x++)
@ -879,7 +879,7 @@ stock WeaponsRemoveAllClientWeapons(client, bool:weaponsdrop)
{
continue;
}
// If this is the knife slot, then strip it and stop.
if (WeaponsSlot:x == Slot_Melee)
{
@ -888,7 +888,7 @@ stock WeaponsRemoveAllClientWeapons(client, bool:weaponsdrop)
AcceptEntityInput(weapons[x], "Kill");
continue;
}
if (weaponsdrop)
{
// Force client to drop weapon.
@ -901,17 +901,17 @@ stock WeaponsRemoveAllClientWeapons(client, bool:weaponsdrop)
AcceptEntityInput(weapons[x], "Kill");
}
}
// Remove left-over projectiles.
WeaponsRemoveClientGrenades(client, weaponsdrop);
// Give zombie a new knife. (If you leave the old one there will be glitches with the knife positioning)
GivePlayerItem(client, "weapon_knife");
}
/**
* Refresh a weapon by taking it and giving it back.
*
*
* @param client The client index.
*/
stock WeaponsRefreshAllClientWeapons(client)
@ -919,7 +919,7 @@ stock WeaponsRefreshAllClientWeapons(client)
// Get a list of all client's weapon indexes.
new weapons[WeaponsSlot];
WeaponsGetClientWeapons(client, weapons);
// Loop through array slots and force drop.
// x = weapon slot.
for (new x = 0; x < WEAPONS_SLOTS_MAX; x++)
@ -929,14 +929,14 @@ stock WeaponsRefreshAllClientWeapons(client)
{
continue;
}
WeaponsRefreshClientWeapon(client, WeaponsSlot:x);
}
}
/**
* Checks if a client is in a buyzone.
*
*
* @param client The client index.
*/
stock bool:WeaponsIsClientInBuyZone(client)

File diff suppressed because it is too large Load Diff

View File

@ -37,7 +37,7 @@ ZAdminOnCommandsCreate()
/**
* Command callback (zadmin)
* Opens ZR admin menu.
*
*
* @param client The client index.
* @param argc Argument count.
*/
@ -49,17 +49,17 @@ public Action:ZAdminCommand(client, argc)
TranslationPrintToServer("Must be player");
return Plugin_Handled;
}
// Send admin menu.
ZAdminMenu(client);
// This stops the "Unknown command" message in client's console.
return Plugin_Handled;
}
/**
* Main admin menu.
*
*
* @param client The client index.
*/
bool:ZAdminMenu(client)
@ -70,16 +70,16 @@ bool:ZAdminMenu(client)
TranslationPrintToChat(client, "Must be admin");
return false;
}
// Boolean that tell if client is allowed to do configuration.
new bool:configallowed = ZRIsClientPrivileged(client, OperationType_Configuration);
// Create menu handle.
new Handle:menu_zadmin = CreateMenu(ZAdminMenuHandle);
// Set translation target as the client.
SetGlobalTransTarget(client);
decl String:title[MENU_LINE_TITLE_LENGTH];
decl String:classmultipliers[MENU_LINE_REG_LENGTH];
decl String:weapons[MENU_LINE_REG_LENGTH];
@ -87,7 +87,7 @@ bool:ZAdminMenu(client)
decl String:infect[MENU_LINE_REG_LENGTH];
decl String:zspawn[MENU_LINE_REG_LENGTH];
decl String:ztele[MENU_LINE_REG_LENGTH];
Format(title, sizeof(title), "%t\n ", "ZAdmin main title");
Format(classmultipliers, sizeof(classmultipliers), "%t", "ZAdmin main class multipliers");
Format(weapons, sizeof(weapons), "%t", "ZAdmin main weapons");
@ -95,12 +95,12 @@ bool:ZAdminMenu(client)
Format(infect, sizeof(infect), "%t", "ZAdmin main zombie");
Format(zspawn, sizeof(zspawn), "%t", "ZAdmin main force zspawn");
Format(ztele, sizeof(ztele), "%t", "ZAdmin main force ztele");
// Get conditions for options.
new configdraw = MenuGetItemDraw(configallowed);
new moderatordraw = MenuGetItemDraw(ZRIsClientPrivileged(client, OperationType_Generic));
new hitgroupdraw = MenuGetItemDraw(GetConVarBool(g_hCvarsList[CVAR_HITGROUPS]) && configallowed);
// Add items to menu.
SetMenuTitle(menu_zadmin, title);
AddMenuItem(menu_zadmin, "classmultipliers", classmultipliers, configdraw);
@ -109,20 +109,20 @@ bool:ZAdminMenu(client)
AddMenuItem(menu_zadmin, "infect", infect, moderatordraw);
AddMenuItem(menu_zadmin, "zspawn", zspawn, moderatordraw);
AddMenuItem(menu_zadmin, "ztele", ztele, moderatordraw);
// Set "Back" button.
SetMenuExitBackButton(menu_zadmin, true);
// Send menu to client.
DisplayMenu(menu_zadmin, client, MENU_TIME_FOREVER);
return true;
}
/**
* Menu callback (zadmin)
* Handles options selected in the admin menu.
*
*
* @param menu The menu handle.
* @param action Action client is doing in menu.
* @param client The client index.
@ -134,7 +134,7 @@ public ZAdminMenuHandle(Handle:menu_zadmin, MenuAction:action, client, slot)
{
// Create variable to possible resend menu later.
new bool:resend = true;
switch(slot)
{
// Class multipliers.
@ -157,7 +157,7 @@ public ZAdminMenuHandle(Handle:menu_zadmin, MenuAction:action, client, slot)
{
// We're not resending this menu.
resend = false;
// Send list of clients to infect.
InfectMenuClients(client);
}
@ -166,7 +166,7 @@ public ZAdminMenuHandle(Handle:menu_zadmin, MenuAction:action, client, slot)
{
// We're not resending this menu.
resend = false;
// Send list of clients to infect.
MenuClientList(client, ZSpawnForceHandle, true, false, true, "ZSpawn clients title");
}
@ -175,19 +175,19 @@ public ZAdminMenuHandle(Handle:menu_zadmin, MenuAction:action, client, slot)
{
// We're not resending this menu.
resend = false;
// Send list of clients to infect.
MenuClientList(client, ZTele_ForceHandle, true, true, false, "ZTele clients title");
}
}
// Re-send menu if selection failed.
if (resend)
{
ZAdminMenu(client);
}
}
if (action == MenuAction_Cancel)
{
if (slot == MenuCancel_ExitBack)

View File

@ -36,56 +36,56 @@ ZCookiesOnCommandsCreate()
/**
* Show ZCookies menu to client.
*
*
* @param client The client index.
*/
ZCookiesMenuMain(client)
{
// Create menu handle.
new Handle:zcookies_menu_main = CreateMenu(ZCookiesMenuMainHandle);
// Make client global translations target.
SetGlobalTransTarget(client);
decl String:autorebuyenabled[MENU_LINE_SMALL_LENGTH];
decl String:zhpenabled[MENU_LINE_SMALL_LENGTH];
decl String:overlayenabled[MENU_LINE_SMALL_LENGTH];
// Get the current toggle state of the cookies.
ConfigBoolToSetting(CookiesGetClientCookieBool(client, g_hZMarketAutoRebuyCookie), autorebuyenabled, sizeof(autorebuyenabled), false, client);
ConfigBoolToSetting(CookiesGetClientCookieBool(client, g_hZHPEnabledCookie), zhpenabled, sizeof(zhpenabled), false, client);
ConfigBoolToSetting(CookiesGetClientCookieBool(client, g_hOverlayEnabledCookie), overlayenabled, sizeof(overlayenabled), false, client);
decl String:title[MENU_LINE_TITLE_LENGTH];
decl String:autorebuy[MENU_LINE_REG_LENGTH];
decl String:zhp[MENU_LINE_REG_LENGTH];
decl String:overlay[MENU_LINE_REG_LENGTH];
decl String:zmarket[MENU_LINE_REG_LENGTH];
// Translate each line into client's language.
Format(title, sizeof(title), "%t\n ", "ZCookies Menu main title");
Format(autorebuy, sizeof(autorebuy), "%t", "ZCookies menu main auto-rebuy", autorebuyenabled);
Format(zhp, sizeof(zhp), "%t", "ZCookies menu main zhp", zhpenabled);
Format(overlay, sizeof(overlay), "%t", "ZCookies menu main overlay", overlayenabled);
Format(zmarket, sizeof(zmarket), "%t", "ZCookies zmarket loadout");
// Get conditional values for each option.
new bool:weapons = GetConVarBool(g_hCvarsList[CVAR_WEAPONS]); // For auto-rebuy.
new bool:zmarketrebuyauto = GetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_REBUY_AUTO]); // For auto-rebuy.
new bool:zhpcvar = GetConVarBool(g_hCvarsList[CVAR_ZHP]); // For ZHP.
new bool:overlaytoggle = GetConVarBool(g_hCvarsList[CVAR_CLASSES_OVERLAY_TOGGLE]); // For class overlay.
new bool:zmarketenabled = GetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET]); // For ZMarket loadout.
// Add items to menu.
SetMenuTitle(zcookies_menu_main, title);
AddMenuItem(zcookies_menu_main, "autorebuy", autorebuy, MenuGetItemDraw(weapons && zmarketrebuyauto));
AddMenuItem(zcookies_menu_main, "zhp", zhp, MenuGetItemDraw(zhpcvar));
AddMenuItem(zcookies_menu_main, "overlay", overlay, MenuGetItemDraw(overlaytoggle));
AddMenuItem(zcookies_menu_main, "zmarket", zmarket, MenuGetItemDraw(zmarketenabled));
// Create a "Back" button to the main menu.
SetMenuExitBackButton(zcookies_menu_main, true);
// Display menu to client.
DisplayMenu(zcookies_menu_main, client, MENU_TIME_FOREVER);
}
@ -93,7 +93,7 @@ ZCookiesMenuMain(client)
/**
* Menu callback (main)
* Toggles client cookies.
*
*
* @param menu The menu handle.
* @param action Action client is doing in menu.
* @param client The client index.
@ -105,7 +105,7 @@ public ZCookiesMenuMainHandle(Handle:menu, MenuAction:action, client, slot)
if (action == MenuAction_Select)
{
new bool:resend = true;
switch(slot)
{
// Toggled auto-rebuy
@ -136,12 +136,12 @@ public ZCookiesMenuMainHandle(Handle:menu, MenuAction:action, client, slot)
{
// Show a client their current loadout.
ZMarketMenuLoadout(client);
// Don't resend ZCookies.
resend = false;
}
}
if (resend)
{
// Re-send menu.
@ -168,7 +168,7 @@ public ZCookiesMenuMainHandle(Handle:menu, MenuAction:action, client, slot)
/**
* Command callback (zcookies)
* Toggle all ZR cookies here.
*
*
* @param client The client index.
* @param argc Argument count.
*/
@ -180,10 +180,10 @@ public Action:ZCookiesCommand(client, argc)
TranslationPrintToServer("Must be player");
return Plugin_Handled;
}
// Send ZCookies menu.
ZCookiesMenuMain(client);
// This stops the "Unknown command" message in client's console.
return Plugin_Handled;
}

View File

@ -63,7 +63,7 @@ ZHPOnCookiesCreate()
/**
* Client is joining the server.
*
*
* @param client The client index.
*/
ZHPClientInit(client)
@ -74,18 +74,18 @@ ZHPClientInit(client)
/**
* Called once a client's saved cookies have been loaded from the database.
*
*
* @param client Client index.
*/
ZHPOnCookiesCached(client)
{
// Get default client setting from cvar.
new bool:zhp = GetConVarBool(g_hCvarsList[CVAR_ZHP_DEFAULT]);
// Get ZHP enabled cookie value.
decl String:zhpenabled[8];
GetClientCookie(client, g_hZHPEnabledCookie, zhpenabled, sizeof(zhpenabled));
// If the cookie is empty, then set the default value.
if (!zhpenabled[0])
{
@ -96,7 +96,7 @@ ZHPOnCookiesCached(client)
/**
* Client is spawning into the game.
*
*
* @param client The client index.
*/
ZHPOnClientSpawn(client)
@ -106,14 +106,14 @@ ZHPOnClientSpawn(client)
{
KillTimer(tZHP[client]);
}
// Reset timer handle.
tZHP[client] = INVALID_HANDLE;
}
/**
* Client has been killed.
*
*
* @param client The client index.
*/
ZHPOnClientDeath(client)
@ -123,14 +123,14 @@ ZHPOnClientDeath(client)
{
KillTimer(tZHP[client]);
}
// Reset timer handle.
tZHP[client] = INVALID_HANDLE;
}
/**
* Client has been infected.
*
*
* @param client The client index.
*/
ZHPOnClientInfected(client)
@ -141,23 +141,23 @@ ZHPOnClientInfected(client)
{
return;
}
// Update HP display.
ZHPUpdateHUD(client);
// If timer is currently running, kill it.
if (tZHP[client] != INVALID_HANDLE)
{
KillTimer(tZHP[client]);
}
// Start repeating timer to update display.
tZHP[client] = CreateTimer(5.0, ZHPTimer, client, TIMER_FLAG_NO_MAPCHANGE|TIMER_REPEAT);
}
/**
* Client has been hurt.
*
*
* @param client The client index.
*/
ZHPOnClientHurt(client)
@ -168,7 +168,7 @@ ZHPOnClientHurt(client)
/**
* Zombie has gained health for infecting a player.
*
*
* @param client The client index.
*/
ZHPOnHealthInfectGain(client)
@ -179,7 +179,7 @@ ZHPOnHealthInfectGain(client)
/**
* Toggle ZHP on a client.
*
*
* @param client The client index.
*/
bool:ZHPToggle(client)
@ -190,17 +190,17 @@ bool:ZHPToggle(client)
{
// Tell client feature is disabled.
TranslationPrintToChat(client, "Feature is disabled");
// Stop.
return false;
}
// Get the cookie value.
new bool:zhpstate = CookiesGetClientCookieBool(client, g_hZHPEnabledCookie);
// Toggle the value.
CookiesSetClientCookieBool(client, g_hZHPEnabledCookie, !zhpstate);
// If ZHP was enabled, then tell client it has been disabled.
if (zhpstate)
{
@ -210,19 +210,19 @@ bool:ZHPToggle(client)
else
{
TranslationPrintToChat(client, "ZHP enable");
// Update HP display.
ZHPUpdateHUD(client);
}
return true;
}
/**
* Update HP display for a player.
*
*
* @param client The client index.
*/
*/
ZHPUpdateHUD(client)
{
// If ZHP is disabled, then stop.
@ -231,23 +231,23 @@ ZHPUpdateHUD(client)
{
return;
}
// Get ZHP enabled cookie as a bool.
new bool:zhpstate = CookiesGetClientCookieBool(client, g_hZHPEnabledCookie);
// If player is a zombie, or has ZHP disabled, then stop.
if (!InfectIsClientInfected(client) || !zhpstate)
{
return;
}
// Get health, and if below 0 then set back to 0. (for display purposes)
new health = GetClientHealth(client);
if (health < 0)
{
health = 0;
}
// Display HP
TranslationPrintHintText(client, "Display HP", health);
}
@ -255,7 +255,7 @@ ZHPUpdateHUD(client)
/**
* Command callback (zhp)
* Shows real HP as zombie.
*
*
* @param client The client index.
* @param argc Argument count.
*/
@ -267,18 +267,18 @@ public Action:ZHPCommand(client, argc)
TranslationPrintToServer("Must be player");
return Plugin_Handled;
}
// Toggle ZHP setting.
ZHPToggle(client);
// This stops the "Unknown command" message in client's console.
return Plugin_Handled;
}
/**
* Timer callback. Repetitively calls ZHPUpdateHUD() until stopped.
*
* @param timer The timer handle.
*
* @param timer The timer handle.
* @param client The client index.
*/
public Action:ZHPTimer(Handle:timer, any:client)
@ -288,10 +288,10 @@ public Action:ZHPTimer(Handle:timer, any:client)
{
return Plugin_Stop;
}
// Update HP display.
ZHPUpdateHUD(client);
// Allow timer to continue.
return Plugin_Continue;
}

View File

@ -4,7 +4,7 @@
* Zombie:Reloaded
*
* File: zombiereloaded.inc
* Type: Core
* Type: Core
* Description: General plugin functions and defines.
*
* Copyright (C) 2009-2013 Greyscale, Richard Helgeby
@ -77,7 +77,7 @@ UpdateGameFolder()
{
new String:gameFolder[PLATFORM_MAX_PATH];
GetGameFolderName(gameFolder, sizeof(gameFolder));
if (StrEqual(gameFolder, "cstrike", false))
{
g_Game = Game_CSS;
@ -90,14 +90,14 @@ UpdateGameFolder()
PrintToServer("Game detected: csgo");
return;
}
LogError("Warning: Zombie:Reloaded doesn't support this game: %s", gameFolder);
g_Game = Game_Unknown;
}
/**
* Function to convert numbers to defined units.
*
*
* @param number The number to convert.
* @param conversion The conversion factor to multiply by. (See defines above)
* @return The converted number.
@ -109,19 +109,19 @@ Float:ZRConvertUnitsFloat(Float:number, Float:conversion)
/**
* Create an array populated with eligible clients to be zombie.
*
*
* @param arrayEligibleClients The handle of the array, don't forget to call CloseHandle
* on it when finished!
* @param team Client is only eligible if on a team.
* @param alive Client is only eligible if alive.
* @param human Client is only eligible if human.
* @param immunity True to ignore clients immune from mother infect, false to count them.
*/
*/
stock ZRCreateEligibleClientList(&Handle:arrayEligibleClients, bool:team = false, bool:alive = false, bool:human = false)
{
// Create array.
arrayEligibleClients = CreateArray();
// Populate list with eligible clients.
// x = client index.
for (new x = 1; x <= MaxClients; x++)
@ -131,35 +131,35 @@ stock ZRCreateEligibleClientList(&Handle:arrayEligibleClients, bool:team = false
{
continue;
}
// If client isn't on a team, then stop.
if (team && !ZRIsClientOnTeam(x))
{
continue;
}
// If client is dead, then stop.
if (alive && !IsPlayerAlive(x))
{
continue;
}
// If client is already zombie (via admin), then stop.
if (human && !InfectIsClientHuman(x))
{
continue;
}
// Add eligible client to array.
PushArrayCell(arrayEligibleClients, x);
}
return GetArraySize(arrayEligibleClients);
}
/**
* Checks if a timer is currently running.
*
*
* @param timer The timer handle.
*/
stock bool:ZRIsTimerRunning(Handle:timer)
@ -171,11 +171,11 @@ stock bool:ZRIsTimerRunning(Handle:timer)
/**
* Wrapper functions for KilLTimer.
* Ends a timer if running, and resets its timer handle variable.
*
*
* @param timer The timer handle.
* @param kill True to kill the timer and reset the variable, false to only reset the variable.
* Using false is useful when calling from the timer callback, because the timer is already killed.
*
*
* @return True if the handle wasn't INVALID_HANDLE, false if the handle wasn't valid.
*/
stock bool:ZREndTimer(&Handle:timer, bool:kill = true)
@ -188,26 +188,26 @@ stock bool:ZREndTimer(&Handle:timer, bool:kill = true)
{
KillTimer(timer);
}
// Reset variable.
timer = INVALID_HANDLE;
return true;
}
// Reset variable.
timer = INVALID_HANDLE;
return false;
}
/**
* Check if a client index is a valid player.
*
*
* @param client The client index.
* @param console True to include console (index 0), false if not.
* @return True if client is valid, false otherwise.
*/
* @return True if client is valid, false otherwise.
*/
stock bool:ZRIsClientValid(client, bool:console = false)
{
// If index is greater than max number of clients, then return false.
@ -215,18 +215,18 @@ stock bool:ZRIsClientValid(client, bool:console = false)
{
return false;
}
// If console is true, return if client is >= 0, if not, then return client > 0.
return console ? (client >= 0) : (client > 0);
}
/**
* Check if a given index is console.
*
*
* @param client The client index.
* @param console True to include console (index 0), false if not.
* @return True if client is valid, false otherwise.
*/
* @return True if client is valid, false otherwise.
*/
stock bool:ZRIsConsole(index)
{
// Return true if index is equal to console's index.
@ -235,7 +235,7 @@ stock bool:ZRIsConsole(index)
/**
* Count clients on each team.
*
*
* @param zombies This is set to the number of clients that are zombies.
* @param humans This is set to the number of clients that are humans.
* @param alive If true it will only count live players, false will count alive and dead.
@ -248,7 +248,7 @@ stock bool:ZRCountValidClients(&zombiecount = 0, &humancount = 0, bool:alive = t
{
return false;
}
// x = client index.
for (new x = 1; x <= MaxClients; x++)
{
@ -257,19 +257,19 @@ stock bool:ZRCountValidClients(&zombiecount = 0, &humancount = 0, bool:alive = t
{
continue;
}
// If client isn't on a team, then stop.
if (!ZRIsClientOnTeam(x))
{
continue;
}
// If player must be alive, and player is dead, then stop.
if (alive && !IsPlayerAlive(x))
{
continue;
}
// If player is a zombie, then increment zombie variable.
if (InfectIsClientInfected(x))
{
@ -281,17 +281,17 @@ stock bool:ZRCountValidClients(&zombiecount = 0, &humancount = 0, bool:alive = t
humancount++;
}
}
return true;
}
/**
* Check if a client index is on a team.
*
*
* @param client The client index.
* @param team Team to check if player is on, -1 to check both.
* @return True if client is on a team, false otherwise.
*/
* @param team Team to check if player is on, -1 to check both.
* @return True if client is on a team, false otherwise.
*/
stock bool:ZRIsClientOnTeam(client, team = -1)
{
// If index is invalid, then stop.
@ -299,21 +299,21 @@ stock bool:ZRIsClientOnTeam(client, team = -1)
{
return false;
}
// Get client team.
new clientteam = GetClientTeam(client);
if (team == -1)
{
return (clientteam == CS_TEAM_T || clientteam == CS_TEAM_CT);
}
return (clientteam == team);
}
/**
* Check if there are clients on a team.
*
*
* @param team (Optional) Team to check if there are clients on.
*/
stock bool:ZRTeamHasClients(team = -1)
@ -324,7 +324,7 @@ stock bool:ZRTeamHasClients(team = -1)
// Return true if both teams have at least 1 client.
return (GetTeamClientCount(CS_TEAM_T) && GetTeamClientCount(CS_TEAM_CT));
}
// Return true if given team has at least 1 client.
return bool:GetTeamClientCount(team);
}
@ -343,19 +343,19 @@ stock bool:ZRIsClientAdmin(client, AdminFlag:flag = Admin_Generic)
{
return false;
}
// If client doesn't have the specified flag, then stop.
if (!GetAdminFlag(GetUserAdmin(client), flag))
{
return false;
}
// Client is an admin.
return true;
}
/**
* Replies to a client with a given message describing a targetting
* Replies to a client with a given message describing a targetting
* failure reason. (formatted for ZR)
*
* Note: The translation phrases are found in common.phrases.txt.
@ -420,7 +420,7 @@ stock ZRPrintToConsoleLong(client, const String:text[], splitsize = 1022)
{
return;
}
decl String:partbuffer[splitsize];
new pos;
new cellswritten = 1; // Initialize for the loop.
@ -435,7 +435,7 @@ stock ZRPrintToConsoleLong(client, const String:text[], splitsize = 1022)
/**
* Converts a boolean value into a string.
*
*
* @param value The value to convert to string.
* @param output The converted string.
* @param maxlen The maximum length of the string.
@ -456,12 +456,12 @@ ZRBoolToString(bool:value, String:output[], maxlen)
/**
* (from SMLIB 0.10.2)
*
*
* Returns a random, uniform Integer number in the specified (inclusive) range.
* This is safe to use multiple times in a function.
* The seed is set automatically for each plugin.
* Rewritten by MatthiasVance, thanks.
*
*
* @param min Min value used as lower border
* @param max Max value used as upper border
* @return Random Integer number between min and max
@ -470,7 +470,7 @@ ZRBoolToString(bool:value, String:output[], maxlen)
stock Math_GetRandomInt(min, max)
{
new random = GetURandomInt();
if (random == 0) {
random++;
}
@ -481,7 +481,7 @@ stock Math_GetRandomInt(min, max)
/**
* (from SMLIB)
* Gets the parent entity of an entity.
*
*
* @param entity Entity Index.
* @return Entity Index of the parent.
*/
@ -500,7 +500,7 @@ stock Entity_GetParent(entity)
stock bool:Entity_HasChildren(entity)
{
new maxEntities = GetMaxEntities();
// Loop through all entity indexes, after players.
for (new loopEntity = MAXPLAYERS + 1; loopEntity < maxEntities; loopEntity++)
{
@ -508,13 +508,13 @@ stock bool:Entity_HasChildren(entity)
{
continue;
}
new parentEntity = Entity_GetParent(loopEntity);
if (parentEntity == entity)
{
return true;
}
}
return false;
}

View File

@ -42,7 +42,7 @@ ZSpawnOnCommandsCreate()
{
// Register ZSpawn command.
RegConsoleCmd(SAYHOOKS_KEYWORD_ZSPAWN, ZSpawnCommand, "Spawn into the game after joining late.");
// Register admin command to force ZSpawn.
RegConsoleCmd("zr_zspawn_force", ZSpawnForceCommand, "Force ZSpawn on a client. Usage: zr_zspawn_force <client> ['0' = Spawn as human | '1' = Spawn as zombie]");
}
@ -54,20 +54,20 @@ ZSpawnOnMapStart()
{
// Reset timer handle.
tZSpawn = INVALID_HANDLE;
// If SteamID cache hasn't been created yet, then create.
if (g_hZSpawnSteamIDCache == INVALID_HANDLE)
{
g_hZSpawnSteamIDCache = SteamidCacheCreate();
}
// Reset the SteamID cache.
SteamidCacheReset(g_hZSpawnSteamIDCache);
}
/**
* Client is leaving the server.
*
*
* @param client The client index.
*/
ZSpawnOnClientDisconnect(client)
@ -77,20 +77,20 @@ ZSpawnOnClientDisconnect(client)
{
return;
}
// Check if client is a bot.
if (IsFakeClient(client))
{
return;
}
// Add client to the SteamID cache.
SteamidCacheAddClient(g_hZSpawnSteamIDCache, client);
}
/**
* Client has been killed.
*
*
* @param client The client index.
*/
ZSpawnOnClientDeath(client)
@ -106,13 +106,13 @@ ZSpawnOnRoundStart()
{
// Reset the SteamID cache.
SteamidCacheReset(g_hZSpawnSteamIDCache);
// If zspawn timer is running, then kill it.
if (tZSpawn != INVALID_HANDLE)
{
// Kill timer.
KillTimer(tZSpawn);
// Reset timer handle.
tZSpawn = INVALID_HANDLE;
}
@ -129,24 +129,24 @@ ZSpawnOnRoundFreezeEnd()
// Kill timer.
KillTimer(tZSpawn);
}
// If zspawn is disabled, then stop.
new bool:zspawn = GetConVarBool(g_hCvarsList[CVAR_ZSPAWN]);
if (!zspawn)
{
return;
}
// If timelimit is disabled, then stop.
new bool:zspawntimelimit = GetConVarBool(g_hCvarsList[CVAR_ZSPAWN_TIMELIMIT]);
if (!zspawntimelimit)
{
return;
}
// Get timelimit
new Float:zspawntime = GetConVarFloat(g_hCvarsList[CVAR_ZSPAWN_TIMELIMIT_TIME]);
// Start timer.
tZSpawn = CreateTimer(zspawntime, ZSpawnTimer, _, TIMER_FLAG_NO_MAPCHANGE);
}
@ -161,7 +161,7 @@ ZSpawnOnRoundEnd()
{
// Kill timer.
KillTimer(tZSpawn);
// Reset timer handle.
tZSpawn = INVALID_HANDLE;
}
@ -169,7 +169,7 @@ ZSpawnOnRoundEnd()
/**
* Spawns a late-joining client into the game.
*
*
* @param client The client index.
* @param force (Optional) True to force spawning of the client, false to follow rules.
* @param zombie (Optional) If you are forcing spawn, you must override the team here.
@ -184,7 +184,7 @@ bool:ZSpawnClient(client, bool:force = false, bool:zombie = false)
TranslationPrintToChat(client, "Feature is disabled");
return false;
}
// If client isn't on a team, then stop.
if (!ZRIsClientOnTeam(client))
{
@ -193,10 +193,10 @@ bool:ZSpawnClient(client, bool:force = false, bool:zombie = false)
// Tell client the command may only be used when on a team.
TranslationPrintToChat(client, "Must be on team");
}
return false;
}
// If client is alive, then stop.
if (IsPlayerAlive(client))
{
@ -205,10 +205,10 @@ bool:ZSpawnClient(client, bool:force = false, bool:zombie = false)
// Tell client the command may only be used when dead.
TranslationPrintToChat(client, "Must be dead");
}
return false;
}
// Block if client has already played during this round.
new blockrejoin = GetConVarBool(g_hCvarsList[CVAR_ZSPAWN_BLOCK_REJOIN]);
if (!force && SteamidCacheClientExists(g_hZSpawnSteamIDCache, client) && blockrejoin)
@ -217,15 +217,15 @@ bool:ZSpawnClient(client, bool:force = false, bool:zombie = false)
TranslationPrintToChat(client, "ZSpawn double spawn");
return false;
}
new bool:teamzombie;
if (!force)
{
// Check if zspawn override is enabled, and if so get overidden value.
new bool:teamoverride = GetConVarBool(g_hCvarsList[CVAR_ZSPAWN_TEAM_OVERRIDE]);
teamzombie = teamoverride ? GetConVarBool(g_hCvarsList[CVAR_ZSPAWN_TEAM_ZOMBIE]) : GetConVarBool(g_hCvarsList[CVAR_RESPAWN_TEAM_ZOMBIE]);
// Block is the time limit is up.
new bool:zspawntimelimit = GetConVarBool(g_hCvarsList[CVAR_ZSPAWN_TIMELIMIT]);
if (zspawntimelimit)
@ -239,7 +239,7 @@ bool:ZSpawnClient(client, bool:force = false, bool:zombie = false)
{
// Get timelimit
new Float:zspawntime = GetConVarFloat(g_hCvarsList[CVAR_ZSPAWN_TIMELIMIT_TIME]);
// Tell client the timelimit for this command has expired.
TranslationPrintToChat(client, "ZSpawn timelimit", RoundToNearest(zspawntime));
return false;
@ -261,7 +261,7 @@ bool:ZSpawnClient(client, bool:force = false, bool:zombie = false)
// Use the override team in the function if were forcing the spawn.
teamzombie = zombie;
}
// Tell respawn module to respawn client.
return RespawnSpawnClient(client, teamzombie, false);
}
@ -269,7 +269,7 @@ bool:ZSpawnClient(client, bool:force = false, bool:zombie = false)
/**
* Menu callback (zspawn_force)
* Forces ZSpawn on a client.
*
*
* @param menu The menu handle.
* @param action Action client is doing in menu.
* @param client The client index.
@ -282,23 +282,23 @@ public ZSpawnForceHandle(Handle:menu_zspawn_force, MenuAction:action, client, sl
{
// Get the client index of the selected client.
new target = MenuGetClientIndex(menu_zspawn_force, slot);
// If the target is 0, then the client left before being selected from the menu.
if (target == 0)
{
// Re-send the menu.
MenuClientList(client, ZSpawnForceHandle, true, true, false, "ZSpawn clients title");
return;
}
// Get the target's name for future use.
decl String:targetname[MAX_NAME_LENGTH];
GetClientName(target, targetname, sizeof(targetname));
// Force ZSpawn on the target.
new bool:success = ZSpawnClient(target, true);
// Tell admin the outcome of the action.
if (success)
{
@ -309,7 +309,7 @@ public ZSpawnForceHandle(Handle:menu_zspawn_force, MenuAction:action, client, sl
{
TranslationReplyToCommand(client, "ZSpawn command force unsuccessful", targetname);
}
// Re-send the menu.
MenuClientList(client, ZSpawnForceHandle, true, false, true, "ZSpawn clients title");
}
@ -333,7 +333,7 @@ public ZSpawnForceHandle(Handle:menu_zspawn_force, MenuAction:action, client, sl
/**
* Command callback (zspawn)
* Spawn into the game after joining late.
*
*
* @param client The client index.
* @param argc Argument count.
*/
@ -345,10 +345,10 @@ public Action:ZSpawnCommand(client, argc)
TranslationPrintToServer("Must be player");
return Plugin_Handled;
}
// Spawn client.
ZSpawnClient(client);
// This stops the "Unknown command" message in client's console.
return Plugin_Handled;
}
@ -356,7 +356,7 @@ public Action:ZSpawnCommand(client, argc)
/**
* Command callback (zr_zspawn_force)
* Force ZSpawn on a client.
*
*
* @param client The client index.
* @param argc Argument count.
*/
@ -368,45 +368,45 @@ public Action:ZSpawnForceCommand(client, argc)
TranslationReplyToCommand(client, "No access to command");
return Plugin_Handled;
}
// If not enough arguments given, then stop.
if (argc < 1)
{
TranslationReplyToCommand(client, "ZSpawn command force syntax");
return Plugin_Handled;
}
decl String:target[MAX_NAME_LENGTH], String:targetname[MAX_NAME_LENGTH];
new targets[MAXPLAYERS], bool:tn_is_ml, result;
// Get targetname.
GetCmdArg(1, target, sizeof(target));
// Find a target.
result = ProcessTargetString(target, client, targets, sizeof(targets), COMMAND_FILTER_DEAD, targetname, sizeof(targetname), tn_is_ml);
// Check if there was a problem finding a client.
if (result <= 0)
{
ZRReplyToTargetError(client, result);
return Plugin_Handled;
}
// Get item to give to client.
decl String:strZombie[4];
GetCmdArg(2, strZombie, sizeof(strZombie));
// Copy value of second (optional) parameter to 'zombie'.
// It will be false if the parameter wasn't specified.
new bool:zombie = bool:StringToInt(strZombie);
// x = Client index.
for (new x = 0; x < result; x++)
{
// Give client the item.
new bool:success = ZSpawnClient(targets[x], true, zombie);
LogAction(client, targets[x], "\"%L\" forced a ZSpawn on \"%L\"%s", client, targets[x], zombie ? " and made them zombie" : "");
// Tell admin the outcome of the command if only 1 client was targetted.
if (result == 1)
{
@ -420,16 +420,16 @@ public Action:ZSpawnForceCommand(client, argc)
}
}
}
// Log action to game events.
//LogEvent(false, LogType_Normal, LOG_GAME_EVENTS, LogModule_ZSpawn, "Force ZSpawn", "Admin \"%L\" forced player(s) to spawn. (zr_zspawn_force)", client);
return Plugin_Handled;
}
/**
* Timer callback, resets handle.
*
*
* @param timer The timer handle.
*/
public Action:ZSpawnTimer(Handle:timer)

View File

@ -61,14 +61,14 @@ void ZTele_OnCommandsCreate()
{
// Register ZTele command.
RegConsoleCmd(SAYHOOKS_KEYWORD_ZTELE, ZTele_Command, "Teleport back to spawn if you are stuck.");
// Register admin command to force ZTele.
RegConsoleCmd("zr_ztele_force", ZTele_ForceCommand, "Force ZTele on a client. Usage: zr_ztele_force <client>");
}
/**
* Client is joining the server.
*
*
* @param client The client index.
*/
void ZTele_OnClientPutInServer(int client)
@ -78,23 +78,23 @@ void ZTele_OnClientPutInServer(int client)
/**
* Client is spawning into the game.
*
*
* @param client The client index.
*/
void ZTele_OnClientSpawn(int client)
{
// Reset tele count.
g_iZTeleCount[client] = 0;
// Get spawn location.
GetClientAbsOrigin(client, g_vecZTeleSpawn[client]);
ZTele_StopTimer(client);
}
/**
* Client has been killed.
*
*
* @param client The client index.
*/
void ZTele_OnClientDeath(int client)
@ -109,7 +109,7 @@ void ZTele_OnClientDisconnect(int client)
/**
* Player has been infected.
*
*
* @param client The client index.
*/
void ZTele_OnClientInfected(int client)
@ -119,11 +119,11 @@ void ZTele_OnClientInfected(int client)
/**
* Teleports a client back to spawn if conditions are met.
*
*
* @param client The client index.
* @param force (Optional) True to force teleporting of the client, false to follow rules.
* @param zombie (Optional) True to teleport instantly, false to use delay.
* @return True if teleport was successful, false otherwise.
* @return True if teleport was successful, false otherwise.
*/
bool ZTeleClient(int client, bool force = false)
{
@ -132,7 +132,7 @@ bool ZTeleClient(int client, bool force = false)
{
return false;
}
// If teleport is already in progress, then stop.
if (ZTele_ClientInProgress(client))
{
@ -140,26 +140,26 @@ bool ZTeleClient(int client, bool force = false)
{
TranslationPrintToChat(client, "ZTele in progress");
}
return false;
}
if (force)
{
// Forcing teleport.
ZTele_TeleportClient(client);
// Skip everything else.
return true;
}
if (ZTele_MustBeHuman(client))
{
// Tell client they must be human to use this feature.
TranslationPrintToChat(client, "Must be human");
return false;
}
bool infected = InfectIsClientInfected(client);
if (!infected && !ZTele_CanHumanTeleport())
{
@ -175,17 +175,17 @@ bool ZTeleClient(int client, bool force = false)
TranslationPrintToChat(client, "ZTele max", maxTeleports);
return false;
}
// Get current location.
GetClientAbsOrigin(client, g_vecZTeleOrigin[client]);
// Set timeleft array to value of respective cvar.
g_iZTeleTimeLeft[client] = ZTele_GetClientDelay(client);
if (g_iZTeleTimeLeft[client] > 0)
{
// Tell client how much time is left until teleport.
TranslationPrintCenterText(client, "ZTele countdown", g_iZTeleTimeLeft[client]);
// Start timer.
tZTele[client] = CreateTimer(1.0, ZTele_Timer, client, TIMER_FLAG_NO_MAPCHANGE|TIMER_REPEAT);
}
@ -193,22 +193,22 @@ bool ZTeleClient(int client, bool force = false)
{
// Teleport client to spawn.
ZTele_TeleportClient(client);
// Increment teleport count.
g_iZTeleCount[client]++;
// If we're forcing the ZTele, then don't increment the count or print how many teleports they have used.
// Tell client they've been teleported.
int maxTeleports = ZTele_GetClientLimit(client);
TranslationPrintCenterText(client, "ZTele countdown end", g_iZTeleCount[client], maxTeleports);
}
return true;
}
/**
* Teleport client to their spawn location.
*
*
* @param client The client index.
*/
// TODO: This function is called externally, move to interface.
@ -221,7 +221,7 @@ void ZTele_TeleportClient(int client)
/**
* Menu callback (ztele_force)
* Forces ZTele on a client.
*
*
* @param menu The menu handle.
* @param action Action client is doing in menu.
* @param client The client index.
@ -235,23 +235,23 @@ public int ZTele_ForceHandle(Handle menu_ztele_force, MenuAction action, int cli
{
// Get the client index of the selected client.
int target = MenuGetClientIndex(menu_ztele_force, slot);
// If the target is 0, then the client left before being selected from the menu.
if (target == 0)
{
// Re-send the menu.
MenuClientList(client, ZTele_ForceHandle, true, true, false, "ZTele clients title");
return;
}
// Get the target's name for future use.
char targetname[MAX_NAME_LENGTH];
GetClientName(target, targetname, sizeof(targetname));
// Force ZSpawn on the target.
bool success = ZTeleClient(target, true);
// Tell admin the outcome of the action.
if (success)
{
@ -261,7 +261,7 @@ public int ZTele_ForceHandle(Handle menu_ztele_force, MenuAction action, int cli
{
TranslationReplyToCommand(client, "ZTele command force unsuccessful", targetname);
}
// Re-send the menu.
MenuClientList(client, ZTele_ForceHandle, true, true, false, "ZTele clients title");
}
@ -285,7 +285,7 @@ public int ZTele_ForceHandle(Handle menu_ztele_force, MenuAction action, int cli
/**
* Command callback (zr_ztele_force)
* Force ZSpawn on a client.
*
*
* @param client The client index.
* @param argc Argument count.
*/
@ -297,39 +297,39 @@ public Action ZTele_ForceCommand(int client, int argc)
TranslationReplyToCommand(client, "No access to command");
return Plugin_Handled;
}
// If not enough arguments given, then stop.
if (argc < 1)
{
TranslationReplyToCommand(client, "ZTele command force syntax");
return Plugin_Handled;
}
char target[MAX_NAME_LENGTH];
char targetname[MAX_NAME_LENGTH];
int targets[MAXPLAYERS];
bool tn_is_ml;
int result;
// Get targetname.
GetCmdArg(1, target, sizeof(target));
// Find a target.
result = ProcessTargetString(target, client, targets, sizeof(targets), COMMAND_FILTER_ALIVE, targetname, sizeof(targetname), tn_is_ml);
// Check if there was a problem finding a client.
if (result <= 0)
{
ZRReplyToTargetError(client, result);
return Plugin_Handled;
}
// x = Client index.
for (int x = 0; x < result; x++)
{
// Give client the item.
bool success = ZTeleClient(targets[x], true);
// Tell admin the outcome of the command if only 1 client was targetted.
if (result == 1)
{
@ -342,18 +342,18 @@ public Action ZTele_ForceCommand(int client, int argc)
TranslationReplyToCommand(client, "ZTele command force unsuccessful", targetname);
}
}
// Log action to game events.
LogEvent(false, LogType_Normal, LOG_GAME_EVENTS, LogModule_ZTele, "Force ZTele", "\"%L\" teleported \"%L\" to spawn.", client, targets[x]);
}
return Plugin_Handled;
}
/**
* Command callback (ztele)
* Teleport back to spawn if you are stuck.
*
*
* @param client The client index.
* @param argc Argument count.
*/
@ -365,17 +365,17 @@ public Action ZTele_Command(int client, int argc)
TranslationPrintToServer("Must be player");
return Plugin_Handled;
}
// Start teleportation process.
ZTeleClient(client);
// This stops the "Unknown command" message in client's console.
return Plugin_Handled;
}
/**
* Timer callback, counts down teleport to the client.
*
*
* @param timer The timer handle.
* @param client The client index.
*/
@ -387,47 +387,47 @@ public Action ZTele_Timer(Handle timer, int client)
tZTele[client] = null;
return Plugin_Stop;
}
if (ZTele_PlayerWalkedTooFar(client))
{
// Abort teleport.
int maxDistanceInFeet = RoundToNearest(ZTele_GetAutoCancelDistance());
TranslationPrintCenterText(client, "ZTele autocancel centertext");
TranslationPrintToChat(client, "ZTele autocancel text", maxDistanceInFeet);
tZTele[client] = null;
return Plugin_Stop;
}
// Decrement time left.
g_iZTeleTimeLeft[client]--;
// Tell client how much time is left until teleport.
TranslationPrintCenterText(client, "ZTele countdown", g_iZTeleTimeLeft[client]);
// Time has expired.
if (g_iZTeleTimeLeft[client] <= 0)
{
// Teleport client.
TeleportEntity(client, g_vecZTeleSpawn[client], NULL_VECTOR, NULL_VECTOR);
// Increment teleport count.
g_iZTeleCount[client]++;
// Get max teleports per round.
int ztelemax = InfectIsClientInfected(client) ? ZTele_GetZombieLimit() : ZTele_GetHumanLimit();
// Tell client spawn protection is over.
TranslationPrintCenterText(client, "ZTele countdown end", g_iZTeleCount[client], ztelemax);
// Clear timer handle.
tZTele[client] = null;
// Stop timer.
return Plugin_Stop;
}
// Allow timer to continue repeating.
return Plugin_Continue;
}
@ -450,7 +450,7 @@ bool ZTele_MustBeHuman(int client)
{
bool infected = InfectIsClientInfected(client);
bool ztelezombie = ZTele_ZombieCanTeleport();
return (infected && !ztelezombie);
}
@ -489,14 +489,14 @@ bool ZTele_PlayerWalkedTooFar(int client)
{
return false;
}
float clientPosition[3];
GetClientAbsOrigin(client, clientPosition);
float clientDistance = GetVectorDistance(clientPosition, g_vecZTeleOrigin[client]);
float maxDistanceInFeet = ZTele_GetAutoCancelDistance();
float maxDistance = ZRConvertUnitsFloat(maxDistanceInFeet, CONVERSION_FEET_TO_UNITS);
return clientDistance > maxDistance;
}