remove trailing whitespaces from sourcecode
This commit is contained in:
parent
6f9558373d
commit
d88e748f0e
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -47,13 +47,13 @@ CommandsInit()
|
|||
VolOnCommandsCreate();
|
||||
ZombieSoundsOnCommandsCreate();
|
||||
ImmunityOnCommandsCreate();
|
||||
|
||||
|
||||
#if defined ADD_VERSION_INFO
|
||||
VersionOnCommandsCreate();
|
||||
#endif
|
||||
|
||||
|
||||
DebugOnCommandsCreate();
|
||||
|
||||
|
||||
// Forward event to modules. (hook commands)
|
||||
ClassOnCommandsHook();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
168
src/zr/cvars.inc
168
src/zr/cvars.inc
|
@ -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.");
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
/**
|
||||
* All external API natives are created here.
|
||||
*/
|
||||
*/
|
||||
CreateGlobals()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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,
|
||||
|
|
130
src/zr/log.inc
130
src/zr/log.inc
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}*/
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user