Created overlay module to unify class overlays and round end overlays, removed unused class overlay functions, fixed invalid hookid error, allow client to toggle class overlay if allowed in cvar and made toggle cmds configurable, cleaned up translations file.

This commit is contained in:
Greyscale 2009-05-14 02:28:26 +02:00
parent 8f9a66e366
commit e051b7bdaa
22 changed files with 743 additions and 508 deletions

View File

@ -4,34 +4,15 @@
// General // General
// =========================== // ===========================
"Round objective" "General round objective"
{ {
"en" "The game is @greenHumans vs. Zombies@default, the goal for zombies is to infect all humans by knifing them." "en" "The game is @greenHumans vs. Zombies@default, the goal for zombies is to infect all humans by knifing them."
"ru" "Битва @greenЛюдей против Зомби@default, цель для зомби - инфицировать всех людей." "ru" "Битва @greenЛюдей против Зомби@default, цель для зомби - инфицировать всех людей."
} }
"You are a zombie" "General zmenu reminder"
{ {
"en" "You have been infected! Now go pass it on to as many people as you can." "en" "For help on Zombie:Reloaded commands, type !zmenu in chat."
"ru" "Вы были инфицированы! Теперь вы охотитесь за людьми."
}
"Zombie replacement"
{
"en" "The last zombie has left the game, and has passed the infection on to you."
"ru" "Последний зомби покинул игру и передал свою инфекцию вам."
}
"Auto-assign"
{
"#format" "{1:s}"
"en" "You have randomly been assigned to the @green\"{1}\" @defaultclass."
"ru" "Вам был случайным образом установлен класс \"{1}\"."
}
"!zmenu reminder"
{
"en" "Type !zmenu in chat to view all ZR commands."
"ru" "Напишите !zmenu в чате для просмотра всех команд." "ru" "Напишите !zmenu в чате для просмотра всех команд."
} }
@ -94,38 +75,90 @@
// General // General
"!zclass admin mode enabled" "Classes admin mode enabled"
{ {
"en" "Admin mode is enabled!" "en" "Admin mode is enabled!"
} }
"Classes random assignment"
{
"#format" "{1:s}"
"en" "You have randomly been assigned to the @green\"{1}\" @defaultclass."
"ru" "Вам был случайным образом установлен класс \"{1}\"."
}
// Center Text/HUD
"Classes overlay toggle"
{
"#format" "{1:s}"
"en" "Class overlay toggle commands: {1}"
}
// Menu // Menu
"!zclass title" "Classes menu title"
{ {
"en" "Class Selection:" "en" "Class Selection:"
} }
"!zclass zombie" "Classes menu zombie"
{ {
"en" "Select Zombie Class" "en" "Select Zombie Class"
} }
"!zclass human" "Classes menu human"
{ {
"en" "Select Human Class" "en" "Select Human Class"
} }
"!zclass admin" "Classes menu admin"
{ {
"en" "Select Admin Class" "en" "Select Admin Class"
} }
"!zclass admin mode toggle" "Classes menu admin mode toggle"
{ {
"en" "Toggle Admin Mode" "en" "Toggle Admin Mode"
} }
// ===========================
// (core) Overlays
// ===========================
"Overlays not supported"
{
"#format" "{1:d},{2:d}"
"en" "Blocking Overlay - DX{1} Detected (DX{2} Required)"
"ru" "Оверлей Отключен - Обнаружен DX{1} (Необходим DX{2})"
}
// ===========================
// (core) Infect
// ===========================
// General
"Infect infected"
{
"en" "You have been infected! Go pass it on to as many other players as you can."
}
"Infect disconnect"
{
"en" "The last zombie has left the game, and has passed the infection on to you."
"ru" "Последний зомби покинул игру и передал свою инфекцию вам."
}
// ===========================
// (core) Damage
// ===========================
"Damage suicide intercept"
{
"en" "Suicide attempt intercepted."
}
// =========================== // ===========================
// Menu (core) // Menu (core)
// =========================== // ===========================
@ -168,15 +201,6 @@
"en" "ZMarket ({1}) - Need a weapon? Buy them here." "en" "ZMarket ({1}) - Need a weapon? Buy them here."
} }
// ===========================
// (core) Damage
// ===========================
"Damage suicide intercept"
{
"en" "Suicide attempt intercepted."
}
// =========================== // ===========================
// (core) Weapons // (core) Weapons
// =========================== // ===========================
@ -460,13 +484,6 @@
"en" "Player {1} has been slayed for camping in a restricted area. (ID: {2})" "en" "Player {1} has been slayed for camping in a restricted area. (ID: {2})"
} }
"DX90 not supported"
{
"#format" "{1:d},{2:d}"
"en" "Blocking Overlay - DX{1} Detected (DX{2} Required)"
"ru" "Оверлей Отключен - Обнаружен DX{1} (Необходим DX{2})"
}
// =========================== // ===========================
// ZAdmin Menu // ZAdmin Menu
// =========================== // ===========================
@ -617,26 +634,4 @@
{ {
"en" "Toggle Logging Flags:" "en" "Toggle Logging Flags:"
} }
// ===========================
// Server Messages
// ===========================
"ZR"
{
"en" "ZR"
"ru" "ZR"
}
"Plugin loading"
{
"en" "-----------| Zombie:Reloaded Loading |----------"
"ru" "-----------| Zombie:Reloaded Загружается |----------"
}
"Plugin loaded"
{
"en" "-----------| Zombie:Reloaded Loaded |----------"
"ru" "-----------| Zombie:Reloaded Загружен |----------"
}
} }

View File

@ -31,6 +31,7 @@
#include "zr/sayhooks" #include "zr/sayhooks"
#include "zr/tools" #include "zr/tools"
#include "zr/models" #include "zr/models"
#include "zr/overlays"
#include "zr/playerclasses/playerclasses" #include "zr/playerclasses/playerclasses"
#include "zr/weapons/weapons" #include "zr/weapons/weapons"
#include "zr/hitgroups" #include "zr/hitgroups"
@ -98,9 +99,6 @@ public OnPluginStart()
LoadTranslations("common.phrases.txt"); LoadTranslations("common.phrases.txt");
LoadTranslations("zombiereloaded.phrases.txt"); LoadTranslations("zombiereloaded.phrases.txt");
// Start loading ZR init functions.
ZR_PrintToServer("Plugin loading");
// Log // Log
LogInit(); LogInit();
@ -110,16 +108,12 @@ public OnPluginStart()
// Tools // Tools
ToolsInit(); ToolsInit();
// TODO: Be modulized/recoded. // Commands
CreateCommands(); CommandsInit();
HookCommands();
// Weapons // Weapons
WeaponsInit(); WeaponsInit();
// Damage
DamageInit();
// Say Hooks // Say Hooks
SayHooksInit(); SayHooksInit();
@ -131,9 +125,6 @@ public OnPluginStart()
// Create public cvar for tracking. // Create public cvar for tracking.
CreateConVar("gs_zombiereloaded_version", VERSION, "[ZR] Current version of this plugin", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_UNLOGGED|FCVAR_DONTRECORD|FCVAR_REPLICATED|FCVAR_NOTIFY); CreateConVar("gs_zombiereloaded_version", VERSION, "[ZR] Current version of this plugin", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_UNLOGGED|FCVAR_DONTRECORD|FCVAR_REPLICATED|FCVAR_NOTIFY);
// Finish loading ZR init functions.
ZR_PrintToServer("Plugin loaded");
} }
/** /**
@ -171,6 +162,7 @@ public OnMapStart()
{ {
// Forward event to modules. // Forward event to modules.
SerialOnMapStart(); SerialOnMapStart();
OverlaysOnMapStart();
RoundEndOnMapStart(); RoundEndOnMapStart();
InfectOnMapStart(); InfectOnMapStart();
SEffectsOnMapStart(); SEffectsOnMapStart();
@ -216,8 +208,8 @@ public OnClientPutInServer(client)
{ {
// Forward event to modules. // Forward event to modules.
ClassClientInit(client); ClassClientInit(client);
OverlaysClientInit(client);
WeaponsClientInit(client); WeaponsClientInit(client);
RoundEndClientInit(client);
InfectClientInit(client); InfectClientInit(client);
DamageClientInit(client); DamageClientInit(client);
SEffectsClientInit(client); SEffectsClientInit(client);

View File

@ -31,12 +31,12 @@
/** /**
* Handle to keep track of AntiStickTimer. * Handle to keep track of AntiStickTimer.
*/ */
new Handle:tAntiStick = INVALID_HANDLE; new Handle:tAntiStick = INVALID_HANDLE;
/** /**
* Map is starting. * Map is starting.
*/ */
AntiStickOnMapStart() AntiStickOnMapStart()
{ {
// Reset timer handle. // Reset timer handle.
@ -71,7 +71,7 @@ AntiStickOnRoundStart()
* @param client The client index. * @param client The client index.
* @return The client index of the other stuck player, -1 when * @return The client index of the other stuck player, -1 when
* player is not stuck. * player is not stuck.
*/ */
AntiStickIsStuck(client) AntiStickIsStuck(client)
{ {
new Float:clientloc[3]; new Float:clientloc[3];
@ -116,7 +116,7 @@ AntiStickIsStuck(client)
/** /**
* Timer callback, automatically unsticks players that are stuck together. * Timer callback, automatically unsticks players that are stuck together.
*/ */
public Action:AntiStickTimer(Handle:timer) public Action:AntiStickTimer(Handle:timer)
{ {
// x = client index // x = client index
@ -155,7 +155,7 @@ public Action:AntiStickTimer(Handle:timer)
* *
* @param timer The timer handle. * @param timer The timer handle.
* @param client The client index. * @param client The client index.
*/ */
public Action:AntiStickSolidify(Handle:timer, any:client) public Action:AntiStickSolidify(Handle:timer, any:client)
{ {
// Validate player is in-game, alive, and is being unstuck. // Validate player is in-game, alive, and is being unstuck.

View File

@ -1,19 +1,33 @@
/** /*
* ==================== * ============================================================================
*
* Zombie:Reloaded * Zombie:Reloaded
*
* File: commands.inc * File: commands.inc
* Author: Greyscale * Type: Core
* ==================== * Description: Console command creation and hooking.
*
* ============================================================================
*/ */
CreateCommands() /**
* Commands are created/hooked.
*/
CommandsInit()
{
// Forward event to modules. (create commands)
WeaponsOnCommandsCreate();
// Forward event to modules. (hook commands)
ClassOnCommandsHook();
DamageOnCommandsHook();
}
/*CreateCommands()
{ {
RegAdminCmd("zr_infect", Command_Infect, ADMFLAG_GENERIC, "Infects the specified player"); RegAdminCmd("zr_infect", Command_Infect, ADMFLAG_GENERIC, "Infects the specified player");
RegAdminCmd("zr_spawn", Command_Respawn, ADMFLAG_GENERIC, "Respawns the specified player following auto-respawning rules"); RegAdminCmd("zr_spawn", Command_Respawn, ADMFLAG_GENERIC, "Respawns the specified player following auto-respawning rules");
// Weapon restrict commands
RegAdminCmd("zr_restrict", Command_Restrict, ADMFLAG_GENERIC, "Restrict a specified weapon");
RegAdminCmd("zr_unrestrict", Command_Unrestrict, ADMFLAG_GENERIC, "Unrestrict a specified weapon");
//RegAdminCmd("zr_set_class_knockback", Command_SetClassKnockback, ADMFLAG_GENERIC, "Sets the knockback to the specified class. Usage: zr_set_class_knockback <class name> <value>"); //RegAdminCmd("zr_set_class_knockback", Command_SetClassKnockback, ADMFLAG_GENERIC, "Sets the knockback to the specified class. Usage: zr_set_class_knockback <class name> <value>");
//RegAdminCmd("zr_get_class_knockback", Command_GetClassKnockback, ADMFLAG_GENERIC, "Gets the knockback to the specified class. Usage: zr_get_class_knockback <class name>"); //RegAdminCmd("zr_get_class_knockback", Command_GetClassKnockback, ADMFLAG_GENERIC, "Gets the knockback to the specified class. Usage: zr_get_class_knockback <class name>");
@ -29,9 +43,10 @@ CreateCommands()
RegConsoleCmd("zr_class_dump", Command_ClassDump, "Dumps class data at a specified index in the specified cache. Usage: zr_class_dump <cachetype> <index|targetname>"); RegConsoleCmd("zr_class_dump", Command_ClassDump, "Dumps class data at a specified index in the specified cache. Usage: zr_class_dump <cachetype> <index|targetname>");
RegAdminCmd("zr_class_modify", Command_ClassModify, ADMFLAG_GENERIC, "Modify class data on one or more classes. Usage: zr_class_modify <classname|\"zombies\"|\"humans\"|\"admins\"> <attribute> <value> [is_multiplier]"); RegAdminCmd("zr_class_modify", Command_ClassModify, ADMFLAG_GENERIC, "Modify class data on one or more classes. Usage: zr_class_modify <classname|\"zombies\"|\"humans\"|\"admins\"> <attribute> <value> [is_multiplier]");
}
public Action:Command_Infect(client, argc) }*/
/*public Action:Command_Infect(client, argc)
{ {
new bool:enabled = GetConVarBool(g_hCvarsList[CVAR_ENABLE]); new bool:enabled = GetConVarBool(g_hCvarsList[CVAR_ENABLE]);
if (argc < 1 || !enabled) if (argc < 1 || !enabled)
@ -129,110 +144,9 @@ public Action:Command_Respawn(client, argc)
} }
return Plugin_Handled; return Plugin_Handled;
} }*/
/** /*public Action:Command_AdminMenu(client, argc)
* Command callback (zr_restrict)
* Restricts a weapon or group
*
* @param client The client index.
* @param argc Argument count.
*/
public Action:Command_Restrict(client, argc)
{
// Disabled.
// If plugin is disabled then stop
/**new bool:enabled = GetConVarBool(g_hCvarsList[CVAR_ENABLE]);
if (argc < 1 || !enabled)
{
return Plugin_Handled;
}*/
// If weapons module is disabled, then stop.
new bool:weapons = GetConVarBool(g_hCvarsList[CVAR_WEAPONS]);
if (!weapons)
{
// Tell client command is disabled.
ZR_ReplyToCommand(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)
{
// Tell client command is disabled.
ZR_ReplyToCommand(client, "Feature is disabled");
return Plugin_Handled;
}
// arg1 = weapon being restricted
decl String:arg1[32];
GetCmdArg(1, arg1, sizeof(arg1));
// Strip "weapon_" from entity name
ReplaceString(arg1, sizeof(arg1), "weapon_", "");
decl String:display[WEAPONS_MAX_LENGTH];
new WpnRestrictQuery:output = RestrictRestrict(arg1, display);
RestrictPrintRestrictOutput(client, output, display, true);
return Plugin_Handled;
}
/**
* Command callback (zr_unrestrict)
* Unrestricts a weapon or group
*
* @param client The client index.
* @param argc Argument count.
*/
public Action:Command_Unrestrict(client, argc)
{
// Disabled.
// If plugin is disabled then stop
/**new bool:enabled = GetConVarBool(g_hCvarsList[CVAR_ENABLE]);
if (argc < 1 || !enabled)
{
return Plugin_Handled;
}*/
// If weapons module is disabled, then stop.
new bool:weapons = GetConVarBool(g_hCvarsList[CVAR_WEAPONS]);
if (!weapons)
{
// Tell client command is disabled.
ZR_ReplyToCommand(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)
{
// Tell client command is disabled.
ZR_ReplyToCommand(client, "Feature is disabled");
return Plugin_Handled;
}
// arg1 = weapon being restricted
decl String:arg1[32];
GetCmdArg(1, arg1, sizeof(arg1));
// Strip "weapon_" from entity name
ReplaceString(arg1, sizeof(arg1), "weapon_", "");
decl String:display[WEAPONS_MAX_LENGTH];
new WpnRestrictQuery:output = RestrictUnrestrict(arg1, display);
RestrictPrintUnrestrictOutput(client, output, display, true);
return Plugin_Handled;
}
public Action:Command_AdminMenu(client, argc)
{ {
if (ZRIsClientValid(client)) if (ZRIsClientValid(client))
{ {
@ -308,4 +222,4 @@ public Action:Command_LogFlags(client, argc)
ReplyToCommand(client, message); ReplyToCommand(client, message);
return Plugin_Handled; return Plugin_Handled;
} }*/

View File

@ -36,6 +36,9 @@ enum CvarsList
Handle:CVAR_CLASSES_DEFAULT_ZOMBIE, Handle:CVAR_CLASSES_DEFAULT_ZOMBIE,
Handle:CVAR_CLASSES_DEFAULT_HUMAN, Handle:CVAR_CLASSES_DEFAULT_HUMAN,
Handle:CVAR_CLASSES_DEFAULT_ADMIN, Handle:CVAR_CLASSES_DEFAULT_ADMIN,
Handle:CVAR_CLASSES_OVERLAY_TOGGLE,
Handle:CVAR_CLASSES_OVERLAY_TOGGLECMDS,
Handle:CVAR_CLASSES_OVERLAY_DEFAULT,
Handle:CVAR_WEAPONS, Handle:CVAR_WEAPONS,
Handle:CVAR_WEAPONS_RESTRICT, Handle:CVAR_WEAPONS_RESTRICT,
Handle:CVAR_WEAPONS_ZMARKET_BUYZONE, Handle:CVAR_WEAPONS_ZMARKET_BUYZONE,
@ -49,6 +52,7 @@ enum CvarsList
Handle:CVAR_SAYHOOKS_QUIET, Handle:CVAR_SAYHOOKS_QUIET,
Handle:CVAR_SAYHOOKS_QUIET_FILTER, Handle:CVAR_SAYHOOKS_QUIET_FILTER,
Handle:CVAR_SAYHOOKS_QUIET_FLAGS, Handle:CVAR_SAYHOOKS_QUIET_FLAGS,
Handle:CVAR_OVERLAYS_UPDATE_TIME,
Handle:CVAR_ROUNDEND_OVERLAY, Handle:CVAR_ROUNDEND_OVERLAY,
Handle:CVAR_ROUNDEND_OVERLAY_ZOMBIE, Handle:CVAR_ROUNDEND_OVERLAY_ZOMBIE,
Handle:CVAR_ROUNDEND_OVERLAY_HUMAN, Handle:CVAR_ROUNDEND_OVERLAY_HUMAN,
@ -117,8 +121,6 @@ enum CvarsList
Handle:CVAR_ZHP_DEFAULT, Handle:CVAR_ZHP_DEFAULT,
// To be modulized/recoded. // To be modulized/recoded.
Handle:CVAR_OVERLAY_REDISPLAY,
Handle:CVAR_ZVISION_ALLOW_DISABLE,
Handle:CVAR_MENU_AUTOCLOSE, Handle:CVAR_MENU_AUTOCLOSE,
Handle:CVAR_ANTICAMP, Handle:CVAR_ANTICAMP,
Handle:CVAR_ANTICAMP_UPDATE_INTERVAL, Handle:CVAR_ANTICAMP_UPDATE_INTERVAL,
@ -224,6 +226,8 @@ CvarsCreate()
// Classes (core) // Classes (core)
// =========================== // ===========================
// General
g_hCvarsList[CVAR_CLASSES_SPAWN] = CreateConVar("zr_classes_spawn", "0", ""); g_hCvarsList[CVAR_CLASSES_SPAWN] = CreateConVar("zr_classes_spawn", "0", "");
// Old Desc: Classmenu is re-displayed every spawn (0: Disable) // Old Desc: Classmenu is re-displayed every spawn (0: Disable)
g_hCvarsList[CVAR_CLASSES_RANDOM] = CreateConVar("zr_classes_random", "0", ""); g_hCvarsList[CVAR_CLASSES_RANDOM] = CreateConVar("zr_classes_random", "0", "");
@ -235,6 +239,14 @@ CvarsCreate()
g_hCvarsList[CVAR_CLASSES_DEFAULT_ADMIN] = CreateConVar("zr_classes_default_admin", "random", ""); g_hCvarsList[CVAR_CLASSES_DEFAULT_ADMIN] = CreateConVar("zr_classes_default_admin", "random", "");
// Old Desc: Default admin-only class selected for admins when they connect. Use \"random\" to select a random class, or blank to use class config defaults. // Old Desc: Default admin-only class selected for admins when they connect. Use \"random\" to select a random class, or blank to use class config defaults.
// Overlays
g_hCvarsList[CVAR_CLASSES_OVERLAY_TOGGLE] = CreateConVar("zr_classes_overlay_toggle", "1", "");
// Desc: Allow clients to toggle class overlay, zr_classes_overlay_default will be applied on connect.
g_hCvarsList[CVAR_CLASSES_OVERLAY_TOGGLECMDS] = CreateConVar("zr_classes_overlay_togglecmds", "nightvision", "");
g_hCvarsList[CVAR_CLASSES_OVERLAY_DEFAULT] = CreateConVar("zr_classes_overlay_default", "0", "");
// Desc: Default toggle value of class overlay. [Ignored when zr_classes_overlay_toggle is disabled.]
// =========================== // ===========================
// Weapons (core) // Weapons (core)
// =========================== // ===========================
@ -262,17 +274,6 @@ CvarsCreate()
g_hCvarsList[CVAR_HITGROUPS] = CreateConVar("zr_hitgroups", "1", ""); g_hCvarsList[CVAR_HITGROUPS] = CreateConVar("zr_hitgroups", "1", "");
// Note make config file cvar. // Note make config file cvar.
// ===========================
// Round End (core)
// ===========================
g_hCvarsList[CVAR_ROUNDEND_OVERLAY] = CreateConVar("zr_roundend_overlay", "1", "");
// Old Desc: Shows an overlay to all clients when a team wins. (0: Disable)
g_hCvarsList[CVAR_ROUNDEND_OVERLAY_HUMAN] = CreateConVar("zr_roundend_overlays_human", "overlays/zr/humans_win");
// Old Desc: overlays/zr/humans_win", "Path to \"humans win\" overlay
g_hCvarsList[CVAR_ROUNDEND_OVERLAY_ZOMBIE] = CreateConVar("zr_roundend_overlays_zombie", "overlays/zr/zombies_win", "");
// Old Desc: Path to \"zombies win\" overlay
// =========================== // ===========================
// Infect (core) // Infect (core)
// =========================== // ===========================
@ -337,6 +338,23 @@ CvarsCreate()
// 32 Quiet "!zhp" say hook. // 32 Quiet "!zhp" say hook.
// 64 Quiet "!zmarket" say hook. // 64 Quiet "!zmarket" say hook.
// ===========================
// Overlays (core)
// ===========================
g_hCvarsList[CVAR_OVERLAYS_UPDATE_TIME] = CreateConVar("zr_overlays_update_time", "1.0", "");
// ===========================
// Round End (core)
// ===========================
g_hCvarsList[CVAR_ROUNDEND_OVERLAY] = CreateConVar("zr_roundend_overlay", "1", "");
// Old Desc: Shows an overlay to all clients when a team wins. (0: Disable)
g_hCvarsList[CVAR_ROUNDEND_OVERLAY_HUMAN] = CreateConVar("zr_roundend_overlays_human", "overlays/zr/humans_win");
// Old Desc: overlays/zr/humans_win", "Path to \"humans win\" overlay
g_hCvarsList[CVAR_ROUNDEND_OVERLAY_ZOMBIE] = CreateConVar("zr_roundend_overlays_zombie", "overlays/zr/zombies_win", "");
// Old Desc: Path to \"zombies win\" overlay
// =========================== // ===========================
// Account (module) // Account (module)
// =========================== // ===========================
@ -480,10 +498,6 @@ CvarsCreate()
// Old Desc: The default value of zombie health display to new clients (1: On, 0: Off) // Old Desc: The default value of zombie health display to new clients (1: On, 0: Off)
// TO BE MODULIZED/RECODED.
g_hCvarsList[CVAR_OVERLAY_REDISPLAY] = CreateConVar("zr_overlay_redisplay", "3", "");
// Old Desc: Frequency, in seconds, to display overlay on the client's screen (Never go below 0.1, 0.2 seems safe)
g_hCvarsList[CVAR_ZVISION_ALLOW_DISABLE] = CreateConVar("zr_zvision_allow_disable", "1", "");
// Old Desc: Allow users to disable ZVision with their nightvision key (0: Disable) // Old Desc: Allow users to disable ZVision with their nightvision key (0: Disable)
g_hCvarsList[CVAR_MENU_AUTOCLOSE] = CreateConVar("zr_menu_autoclose", "0", ""); g_hCvarsList[CVAR_MENU_AUTOCLOSE] = CreateConVar("zr_menu_autoclose", "0", "");
// Old Desc: Automatically close menus on selection. If disabled the menu will remain open. // Old Desc: Automatically close menus on selection. If disabled the menu will remain open.

View File

@ -24,23 +24,22 @@
*/ */
/** /**
* List of damage-related hooks. * Array to store TraceAttack HookIDs.
*/ */
enum DamageHooks new g_iDamageTraceAttackHookID[MAXPLAYERS + 1] = {-1, ...};
{
Hook_TraceAttack, /** TraceAttack HookID */
Hook_OnTakeDamage, /** OnTakeDamage HookID */
}
new g_iDamageHookID[MAXPLAYERS + 1][DamageHooks];
/** /**
* Damage module init function. * Array to store OnTakeDamage HookIDs.
*/ */
DamageInit() new g_iDamageOnTakeDamageHookID[MAXPLAYERS + 1] = {-1, ...};
/**
* Hook commands related to damage here.
*/
DamageOnCommandsHook()
{ {
// Create command callbacks (intercepts) for listed suicide commands. // Create command callbacks (intercepts) for listed suicide commands.
decl String:suicidecmds[64]; decl String:suicidecmds[DAMAGE_SUICIDE_MAX_CMDS * DAMAGE_SUICIDE_MAX_LENGTH];
GetConVarString(g_hCvarsList[CVAR_DAMAGE_SUICIDE_CMDS], suicidecmds, sizeof(suicidecmds)); GetConVarString(g_hCvarsList[CVAR_DAMAGE_SUICIDE_CMDS], suicidecmds, sizeof(suicidecmds));
// Create array to store cmds // Create array to store cmds
@ -66,8 +65,8 @@ DamageInit()
DamageClientInit(client) DamageClientInit(client)
{ {
// Hook damage callbacks. // Hook damage callbacks.
g_iDamageHookID[client][Hook_TraceAttack] = ZRTools_HookTraceAttack(client, DamageTraceAttack); g_iDamageTraceAttackHookID[client] = ZRTools_HookTraceAttack(client, DamageTraceAttack);
g_iDamageHookID[client][Hook_OnTakeDamage] = ZRTools_HookOnTakeDamage(client, DamageOnTakeDamage); g_iDamageOnTakeDamageHookID[client] = ZRTools_HookOnTakeDamage(client, DamageOnTakeDamage);
} }
/** /**
@ -77,9 +76,19 @@ DamageClientInit(client)
*/ */
DamageOnClientDisconnect(client) DamageOnClientDisconnect(client)
{ {
// Unhook damage callbacks. // Unhook damage callbacks, and reset variables.
ZRTools_UnhookTraceAttack(g_iDamageHookID[client][Hook_TraceAttack]);
ZRTools_UnhookOnTakeDamage(g_iDamageHookID[client][Hook_OnTakeDamage]); if (g_iDamageTraceAttackHookID[client] != -1)
{
ZRTools_UnhookTraceAttack(g_iDamageTraceAttackHookID[client]);
g_iDamageTraceAttackHookID[client] = -1;
}
if (g_iDamageOnTakeDamageHookID[client] != -1)
{
ZRTools_UnhookOnTakeDamage(g_iDamageOnTakeDamageHookID[client]);
g_iDamageOnTakeDamageHookID[client] = -1;
}
} }
/** /**

View File

@ -66,9 +66,10 @@ EventHook(bool:unhook = false)
*/ */
public Action:EventRoundStart(Handle:event, const String:name[], bool:dontBroadcast) public Action:EventRoundStart(Handle:event, const String:name[], bool:dontBroadcast)
{ {
ZR_PrintToChat(0, "Round objective"); ZR_PrintToChat(0, "General round objective");
// Forward event to sub-modules. // Forward event to sub-modules.
OverlaysOnRoundStart();
RoundEndOnRoundStart(); RoundEndOnRoundStart();
InfectOnRoundStart(); InfectOnRoundStart();
SEffectsOnRoundStart(); SEffectsOnRoundStart();
@ -182,7 +183,7 @@ public Action:EventPlayerSpawn(Handle:event, const String:name[], bool:dontBroad
ZTeleOnClientSpawn(index); ZTeleOnClientSpawn(index);
ZHPOnClientSpawn(index); ZHPOnClientSpawn(index);
ZR_PrintToChat(index, "!zmenu reminder"); ZR_PrintToChat(index, "General zmenu reminder");
} }
/** /**

View File

@ -180,7 +180,7 @@ InfectOnClientDisconnect(client)
InfectClient(randclient); InfectClient(randclient);
// Tell client they have been randomly been chosen to replace disconnecting zombie. // Tell client they have been randomly been chosen to replace disconnecting zombie.
ZR_PrintToChat(randclient, "Zombie replacement"); ZR_PrintToChat(randclient, "Infect disconnect");
// Destroy handle. // Destroy handle.
CloseHandle(arrayEligibleClients); CloseHandle(arrayEligibleClients);
@ -565,6 +565,12 @@ InfectClient(client, attacker = -1, bool:motherinfect = false)
// TODO: A solution to stop confusing bots? Respawn and teleport? // TODO: A solution to stop confusing bots? Respawn and teleport?
CS_SwitchTeam(client, CS_TEAM_T); CS_SwitchTeam(client, CS_TEAM_T);
// Format infection message.
SetGlobalTransTarget(client);
// Print message to client.
ZR_PrintToChat(client, "Infect infected");
// Forward event to modules. // Forward event to modules.
ClassOnClientInfected(client, motherinfect); ClassOnClientInfected(client, motherinfect);
RoundEndOnClientInfected(); RoundEndOnClientInfected();

View File

@ -156,7 +156,7 @@ LogMessageFormatted(client, const String:module[], const String:block[], const S
SetGlobalTransTarget(client); SetGlobalTransTarget(client);
// Print to client. // Print to client.
PrintToConsole(client, "%t %s", "ZR", logtext); PrintToConsole(client, "[ZR] %s", logtext);
} }
} }
@ -183,7 +183,7 @@ LogToAdmins(String:message[])
SetGlobalTransTarget(x); SetGlobalTransTarget(x);
// Format message to admin, then print. // Format message to admin, then print.
Format(buffer, sizeof(buffer), "%t %s", "ZR", message); Format(buffer, sizeof(buffer), "[ZR] %s", message);
PrintToChat(x, buffer); PrintToChat(x, buffer);
} }
} }

284
src/zr/overlays.inc Normal file
View File

@ -0,0 +1,284 @@
/*
* ============================================================================
*
* Zombie:Reloaded
*
* File: overlays.inc
* Type: Core
* Description: Overlay system, separating different types into "overlay channels."
*
* ============================================================================
*/
/**
* Minimum dx level required to see overlays.
*/
#define OVERLAYS_DXL_MIN 90
/**
* Maximum amount of overlay channels.
*/
#define OVERLAYS_CHANNEL_MAX 2
/**
* All possible overlay channels, in order of priority.
*/
enum OverlaysChannel
{
OVERLAYS_CHANNEL_NONE = -1, /** Client has no overlay */
OVERLAYS_CHANNEL_ROUNDEND = 0, /** Round win overlay */
OVERLAYS_CHANNEL_CLASSES = 1, /** Class overlay */
}
/**
* Global variable to store a convar query cookie
*/
new QueryCookie:mat_dxlevel;
/**
* The DirectX level of a client.
*/
new g_iOverlaysDXL[MAXPLAYERS + 1];
/**
* Array to track overlay channel state on each client.
*/
new bool:g_bOverlayChannel[MAXPLAYERS + 1][OverlaysChannel];
/**
* Array to store overlay path for each channel.
*/
new String:g_strOverlayPath[MAXPLAYERS + 1][OverlaysChannel][PLATFORM_MAX_PATH];
/**
* Create variable to store global timer handle.
*/
new Handle:tOverlays = INVALID_HANDLE;
/**
* Map is starting.
*/
OverlaysOnMapStart()
{
// Reset timer handle.
tOverlays = INVALID_HANDLE;
}
/**
* Client is joining the server.
*
* @param client The client index.
*/
OverlaysClientInit(client)
{
// x = channel index.
for (new x = 0; x < OVERLAYS_CHANNEL_MAX; x++)
{
// 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.
*/
OverlaysGetClientDXLevel(client)
{
// If client is fake (or bot), then stop.
if (IsFakeClient(client))
{
return;
}
// Query mat_dxlevel on client.
mat_dxlevel = QueryClientConVar(client, "mat_dxlevel", OverlaysQueryClientDXLevel);
}
/**
* Query callback function.
*
* @param cookie Unique cookie of the query.
* @param client The client index.
* @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.
if (cookie != mat_dxlevel)
{
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);
}
/**
* The round is starting.
*/
OverlaysOnRoundStart()
{
// If timer is running, kill it.
if (tOverlays != INVALID_HANDLE)
{
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.
*/
OverlaysClientUpdateOverlay(client, OverlaysChannel:channel = OVERLAYS_CHANNEL_NONE)
{
// Find highest priority, enabled, overlay channel of client.
if (channel == OVERLAYS_CHANNEL_NONE)
{
channel = OverlaysClientFindChannel(client);
}
// Stop here if client has no overlay channel enabled.
if (channel == OVERLAYS_CHANNEL_NONE)
{
// Clear any existing overlay from screen.
ClientCommand(client, "r_screenoverlay \"\"");
return;
}
// If dxLevel is 0, then query on client failed, so try again, then stop.
if (!g_iOverlaysDXL[client])
{
// Query dxlevel cvar, again.
OverlaysGetClientDXLevel(client);
return;
}
// If client doesn't meet DXLevel requirement, then tell client, then stop.
if (g_iOverlaysDXL[client] < OVERLAYS_DXL_MIN)
{
ZR_PrintCenterText(client, "Overlays not supported", g_iOverlaysDXL[client], OVERLAYS_DXL_MIN);
return;
}
// Display overlay to client.
ClientCommand(client, "r_screenoverlay %s", g_strOverlayPath[client][channel]);
}
OverlaysChannel:OverlaysClientFindChannel(client)
{
// x = channel index.
for (new x = 0; x < OVERLAYS_CHANNEL_MAX; x++)
{
// 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 toggle 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.
*/
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.
*/
bool:OverlaysClientGetChannelState(client, OverlaysChannel:channel)
{
// Return current value.
return g_bOverlayChannel[client][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.
*/
OverlaysClientSetChannelPath(client, OverlaysChannel:channel, const String:path[])
{
// Copy path to the overlay channel's path string.
strcopy(g_strOverlayPath[client][channel], PLATFORM_MAX_PATH, path);
}
/**
* Timer callback, updates overlay on each client.
*
* @param timer The timer handle.
*/
public Action:OverlaysTimer(Handle:timer)
{
// x = client index
for (new x = 1; x <= MaxClients; x++)
{
// If client isn't in game, then stop.
if (!IsClientInGame(x))
{
continue;
}
// Update client's overlay.
OverlaysClientUpdateOverlay(x);
}
}

View File

@ -136,21 +136,6 @@ bool:ClassApplyAlpha(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER)
*/ */
bool:ClassApplyOverlay(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER) bool:ClassApplyOverlay(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER)
{ {
// If dxLevel is 0, then query on client failed, so try again, then stop.
if (!dxLevel[client])
{
// Query dxlevel cvar.
RoundEndGetClientDXLevel(client);
return false;
}
// If client doesn't meet minimum requirement, then print unsupported text.
if (dxLevel[client] < GENERAL_DXLEVEL_MIN)
{
ZR_PrintCenterText(client, "DX90 not supported", dxLevel[client], GENERAL_DXLEVEL_MIN);
return false;
}
decl String:overlaypath[PLATFORM_MAX_PATH]; decl String:overlaypath[PLATFORM_MAX_PATH];
// Get the overlay path from the specified cache. // Get the overlay path from the specified cache.

View File

@ -29,6 +29,18 @@ ClassClientInit(client)
// Set default class indexes on the player. // Set default class indexes on the player.
ClassClientSetDefaultIndexes(client); ClassClientSetDefaultIndexes(client);
} }
// Forward event to sub-modules
ClassOverlayClientInit(client);
}
/**
* Hook commands related to classes here.
*/
ClassOnCommandsHook()
{
// Forward event to sub-modules.
ClassOverlayOnCommandsHook();
} }
/** /**
@ -44,9 +56,13 @@ ClassOnClientDisconnect(client)
{ {
// Disable class attributes with timers. // Disable class attributes with timers.
ClassHealthRegenStop(client); ClassHealthRegenStop(client);
ClassOverlayStop(client);
} }
/**
* Client is spawning into the game.
*
* @param client The client index.
*/
ClassOnClientSpawn(client) ClassOnClientSpawn(client)
{ {
// Check if the player is alive. // Check if the player is alive.
@ -78,12 +94,12 @@ ClassOnClientSpawn(client)
// Mark zombie class as selected. // Mark zombie class as selected.
ClassSelected[client][ZR_CLASS_TEAM_ZOMBIES] = randomzombie; ClassSelected[client][ZR_CLASS_TEAM_ZOMBIES] = randomzombie;
ClassGetName(randomzombie, classname, sizeof(classname), ZR_CLASS_TEAM_ZOMBIES); ClassGetName(randomzombie, classname, sizeof(classname), ZR_CLASS_TEAM_ZOMBIES);
ZR_PrintToChat(client, "Auto-assign", classname); ZR_PrintToChat(client, "Classes random assignment", classname);
// Mark human class as selected. // Mark human class as selected.
ClassSelected[client][ZR_CLASS_TEAM_HUMANS] = randomhuman; ClassSelected[client][ZR_CLASS_TEAM_HUMANS] = randomhuman;
ClassGetName(randomhuman, classname, sizeof(classname), ZR_CLASS_TEAM_HUMANS); ClassGetName(randomhuman, classname, sizeof(classname), ZR_CLASS_TEAM_HUMANS);
ZR_PrintToChat(client, "Auto-assign", classname); ZR_PrintToChat(client, "Classes random assignment", classname);
// Update player cache with the human class data, and apply it. // Update player cache with the human class data, and apply it.
ClassReloadPlayerCache(client, randomhuman); ClassReloadPlayerCache(client, randomhuman);
@ -111,13 +127,18 @@ ClassOnClientSpawn(client)
ClassReloadPlayerCache(client, ClassGetActiveIndex(client)); ClassReloadPlayerCache(client, ClassGetActiveIndex(client));
ClassApplyAttributes(client); ClassApplyAttributes(client);
} }
// Forward event to sub-modules.
ClassOverlayOnClientSpawn(client);
} }
ClassOnClientDeath(client) ClassOnClientDeath(client)
{ {
// Disable class attributes with timers. // Disable class attributes with timers.
ClassHealthRegenStop(client); ClassHealthRegenStop(client);
ClassOverlayStop(client);
// Disable overlay.
OverlaysClientSetChannelState(client, OVERLAYS_CHANNEL_CLASSES, true, false, false, true);
// Set client's FOV back to normal. // Set client's FOV back to normal.
ToolsSetClientDefaultFOV(client, 90); ToolsSetClientDefaultFOV(client, 90);
@ -129,11 +150,13 @@ ClassOnClientInfected(client, bool:motherzombie = false)
// Disable class attributes with timers. // Disable class attributes with timers.
ClassHealthRegenStop(client); ClassHealthRegenStop(client);
ClassOverlayStop(client);
// Update the players cache with zombie attributes. // Update the players cache with zombie attributes.
ClassReloadPlayerCache(client, classindex); ClassReloadPlayerCache(client, classindex);
// Apply the new attributes. // Apply the new attributes.
ClassApplyAttributes(client, motherzombie); ClassApplyAttributes(client, motherzombie);
// Forward event to sub-modules.
ClassOverlayOnClientInfected(client);
} }

View File

@ -27,7 +27,7 @@ ClassMenuMain(client)
new Handle:menu = CreateMenu(ClassMenuMainHandle); new Handle:menu = CreateMenu(ClassMenuMainHandle);
SetGlobalTransTarget(client); SetGlobalTransTarget(client);
SetMenuTitle(menu, "%t\n", "!zclass title"); SetMenuTitle(menu, "%t\n", "Classes menu title");
decl String:zombieclass[128]; decl String:zombieclass[128];
decl String:humanclass[128]; decl String:humanclass[128];
@ -55,18 +55,18 @@ ClassMenuMain(client)
if (ClassPlayerInAdminMode[client]) if (ClassPlayerInAdminMode[client])
{ {
// Notify the player. // Notify the player.
Format(inadminmnode, sizeof(inadminmnode), "%t\n", "!zclass admin mode enabled"); Format(inadminmnode, sizeof(inadminmnode), "%t\n", "Classes admin mode enabled");
AddMenuItem(menu, "", inadminmnode, ITEMDRAW_RAWLINE); AddMenuItem(menu, "", inadminmnode, ITEMDRAW_RAWLINE);
} }
// List zombie class options. // List zombie class options.
ClassGetName(ClassSelected[client][ZR_CLASS_TEAM_ZOMBIES], zombieclass, sizeof(zombieclass), ZR_CLASS_CACHE_MODIFIED); ClassGetName(ClassSelected[client][ZR_CLASS_TEAM_ZOMBIES], zombieclass, sizeof(zombieclass), ZR_CLASS_CACHE_MODIFIED);
Format(zombieselect, sizeof(zombieselect), "%t\n %s", "!zclass zombie", zombieclass); Format(zombieselect, sizeof(zombieselect), "%t\n %s", "Classes menu zombie", zombieclass);
AddMenuItem(menu, "", zombieselect, zombie_itemdraw); AddMenuItem(menu, "", zombieselect, zombie_itemdraw);
// List human class options. // List human class options.
ClassGetName(ClassSelected[client][ZR_CLASS_TEAM_HUMANS], humanclass, sizeof(humanclass), ZR_CLASS_CACHE_MODIFIED); ClassGetName(ClassSelected[client][ZR_CLASS_TEAM_HUMANS], humanclass, sizeof(humanclass), ZR_CLASS_CACHE_MODIFIED);
Format(humanselect, sizeof(humanselect), "%t\n %s", "!zclass human", humanclass); Format(humanselect, sizeof(humanselect), "%t\n %s", "Classes menu human", humanclass);
AddMenuItem(menu, "", humanselect, human_itemdraw); AddMenuItem(menu, "", humanselect, human_itemdraw);
// Only display admin class options for admins, and if admin classes exist. // Only display admin class options for admins, and if admin classes exist.
@ -74,7 +74,7 @@ ClassMenuMain(client)
{ {
// List admin class options. // List admin class options.
ClassGetName(ClassSelected[client][ZR_CLASS_TEAM_ADMINS], adminclass, sizeof(adminclass), ZR_CLASS_CACHE_MODIFIED); ClassGetName(ClassSelected[client][ZR_CLASS_TEAM_ADMINS], adminclass, sizeof(adminclass), ZR_CLASS_CACHE_MODIFIED);
Format(adminselect, sizeof(adminselect), "%t\n %s", "!zclass admin", adminclass); Format(adminselect, sizeof(adminselect), "%t\n %s", "Classes menu admin", adminclass);
AddMenuItem(menu, "", adminselect, admin_itemdraw); AddMenuItem(menu, "", adminselect, admin_itemdraw);
// Set admin mode status string. // Set admin mode status string.
@ -91,7 +91,7 @@ ClassMenuMain(client)
AddMenuItem(menu, "", " ", ITEMDRAW_RAWLINE); AddMenuItem(menu, "", " ", ITEMDRAW_RAWLINE);
// Show admin mode toggle option. // Show admin mode toggle option.
Format(toggleadminmode, sizeof(toggleadminmode), "%t\n %s", "!zclass admin mode toggle", adminmode); Format(toggleadminmode, sizeof(toggleadminmode), "%t\n %s", "Classes menu admin mode toggle", adminmode);
AddMenuItem(menu, "", toggleadminmode, admin_itemdraw); AddMenuItem(menu, "", toggleadminmode, admin_itemdraw);
} }
@ -174,15 +174,15 @@ ClassMenuSelect(client, teamid)
{ {
case ZR_CLASS_TEAM_ZOMBIES: case ZR_CLASS_TEAM_ZOMBIES:
{ {
Format(title, sizeof(title), "%t\n", "!zclass zombie"); Format(title, sizeof(title), "%t\n", "Classes menu zombie");
} }
case ZR_CLASS_TEAM_HUMANS: case ZR_CLASS_TEAM_HUMANS:
{ {
Format(title, sizeof(title), "%t\n", "!zclass human"); Format(title, sizeof(title), "%t\n", "Classes menu human");
} }
case ZR_CLASS_TEAM_ADMINS: case ZR_CLASS_TEAM_ADMINS:
{ {
Format(title, sizeof(title), "%t\n", "!zclass admin"); Format(title, sizeof(title), "%t\n", "Classes menu admin");
} }
} }
SetMenuTitle(menu, title); SetMenuTitle(menu, title);
@ -213,7 +213,8 @@ ClassMenuSelect(client, teamid)
{ {
// No classes found. Display message. The main class menu should // No classes found. Display message. The main class menu should
// prevent this from happening, but we print a message just in case. // prevent this from happening, but we print a message just in case.
Format(menuitem, sizeof(menuitem), "%t\n", "!zclass not found"); // THIS TRANSLATION PHRASES IS NOT IN FILE.
Format(menuitem, sizeof(menuitem), "%t\n", "Classes menu not found");
AddMenuItem(menu, classname, menuitem, ITEMDRAW_RAWLINE); AddMenuItem(menu, classname, menuitem, ITEMDRAW_RAWLINE);
} }

View File

@ -11,46 +11,100 @@
*/ */
/** /**
* Timer handles for redisplaying overlays on clients. * @section Suicide intercept defines.
*/
#define CLASSOVERLAY_TOGGLE_MAX_CMDS 5
#define CLASSOVERLAY_TOGGLE_MAX_LENGTH 16
/**
* @endsection
*/ */
new Handle:tOverlay[MAXPLAYERS + 1];
/** /**
* Specifies if a client have a overlay. * Array to store default class overlay enable flag.
*/ */
new bool:bClientHasOverlay[MAXPLAYERS + 1]; new bool:h_bClassOverlay[MAXPLAYERS + 1];
/** /**
* Tells whether the overlay is on or not. * Client is joining the server.
*/
new bool:bClientOverlayOn[MAXPLAYERS + 1];
/**
* Path to the currently active overlay.
*/
new String:ActiveOverlay[MAXPLAYERS + 1][PLATFORM_MAX_PATH];
/**
* Returns if the have a overlay path specified.
* *
* @param client The client index. * @param client The client index.
* @return True if a overlay path is specified, false otherwise.
*/ */
bool:ClassClientHasOverlay(client) ClassOverlayClientInit(client)
{ {
return bClientHasOverlay[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]);
// Apply default value if toggle is enabled, default to true if toggle is disabled.
h_bClassOverlay[client] = overlaytoggle ? overlaydefault : true;
} }
/** /**
* Returns if the overlay is currently on or not. * Hook commands related to overlay here.
*/
ClassOverlayOnCommandsHook()
{
// Create command callbacks (intercepts) for listed suicide commands.
decl String:togglecmds[CLASSOVERLAY_TOGGLE_MAX_CMDS * CLASSOVERLAY_TOGGLE_MAX_LENGTH];
GetConVarString(g_hCvarsList[CVAR_CLASSES_OVERLAY_TOGGLECMDS], togglecmds, sizeof(togglecmds));
// Create array to store cmds
new String:arrayCmds[CLASSOVERLAY_TOGGLE_MAX_CMDS][CLASSOVERLAY_TOGGLE_MAX_LENGTH];
// Explode string into array indexes.
new cmdcount = ExplodeString(togglecmds, ", ", arrayCmds, CLASSOVERLAY_TOGGLE_MAX_CMDS, CLASSOVERLAY_TOGGLE_MAX_LENGTH);
// x = array index.
// arrayCmds[x] = suicide command.
for (new x = 0; x <= cmdcount - 1; x++)
{
// Prepare intercept for this command.
RegConsoleCmd(arrayCmds[x], ClassOverlayEnableCommand);
}
}
/**
* Client is spawning into the game.
* *
* @param client The client index. * @param client The client index.
* @return True if on, false otherwise.
*/ */
bool:ClassOverlayIsOn(client) ClassOverlayOnClientSpawn(client)
{ {
return bClientOverlayOn[client]; // 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));
ZR_HudHint(client, "Classes overlay toggle", togglecmds);
}
}
/**
* Client has been infected.
*
* @param client The client index.
*/
ClassOverlayOnClientInfected(client)
{
// 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));
ZR_PrintCenterText(client, "Classes overlay toggle", togglecmds);
}
} }
ClassOverlayInitialize(client, const String:overlay[]) ClassOverlayInitialize(client, const String:overlay[])
@ -60,57 +114,34 @@ ClassOverlayInitialize(client, const String:overlay[])
return; return;
} }
if (strlen(overlay) == 0) // If overlay path is empty, then disable channel, then stop.
if (!overlay[0])
{ {
bClientHasOverlay[client] = false; OverlaysClientSetChannelState(client, OVERLAYS_CHANNEL_CLASSES, true, false, false, true);
return;
} }
else
{
bClientHasOverlay[client] = true;
strcopy(ActiveOverlay[client], PLATFORM_MAX_PATH, overlay);
ClassOverlayStart(client); // Display class overlays.
} OverlaysClientSetChannelPath(client, OVERLAYS_CHANNEL_CLASSES, overlay);
OverlaysClientSetChannelState(client, OVERLAYS_CHANNEL_CLASSES, true, false, h_bClassOverlay[client]);
} }
ClassOverlayStart(client) /**
* Command callback (See zr_classes_overlay_togglecmds)
* Toggles nightvision of a client.
*
* @param client The client index.
* @param argc Argument count.
*/
public Action:ClassOverlayEnableCommand(client, argc)
{ {
// Kill timer if it exist. // If overlay toggle is disabled, then stop.
if (tOverlay[client] != INVALID_HANDLE) new bool:overlaytoggle = GetConVarBool(g_hCvarsList[CVAR_CLASSES_OVERLAY_TOGGLE]);
if (!overlaytoggle)
{ {
KillTimer(tOverlay[client]); return;
tOverlay[client] = INVALID_HANDLE;
} }
ClientCommand(client, "r_screenoverlay \"%s\"", ActiveOverlay[client]); // Toggle current overlay channel, and retrieve new value.
bClientOverlayOn[client] = true; h_bClassOverlay[client] = OverlaysClientSetChannelState(client, OVERLAYS_CHANNEL_CLASSES, true, true);
new Float:redisplay = GetConVarFloat(g_hCvarsList[CVAR_OVERLAY_REDISPLAY]);
tOverlay[client] = CreateTimer(redisplay, ClassOverlayTimer, client, TIMER_REPEAT);
}
ClassOverlayStop(client)
{
// Kill timer if it exist.
if (tOverlay[client] != INVALID_HANDLE)
{
KillTimer(tOverlay[client]);
tOverlay[client] = INVALID_HANDLE;
}
// Disable client overlay.
ClientCommand(client, "r_screenoverlay \"\"");
bClientOverlayOn[client] = false;
}
public Action:ClassOverlayTimer(Handle:timer, any:client)
{
if (!IsClientInGame(client) || !InfectIsClientInfected(client))
{
tOverlay[client] = INVALID_HANDLE;
return Plugin_Stop;
}
ClientCommand(client, "r_screenoverlay \"%s\"", ActiveOverlay[client]);
return Plugin_Continue;
} }

View File

@ -476,6 +476,8 @@ ClassLoad()
} }
} }
/** /**
* Updates the class data cache. Original values are retrieved from ClassData. * Updates the class data cache. Original values are retrieved from ClassData.
* *

View File

@ -54,11 +54,6 @@ enum RoundEndOutcome
*/ */
new Handle:tRoundEnd = INVALID_HANDLE; new Handle:tRoundEnd = INVALID_HANDLE;
/**
* Global variable to store a convar query cookie
*/
new QueryCookie:mat_dxlevel;
/** /**
* Map is starting. * Map is starting.
*/ */
@ -68,17 +63,6 @@ RoundEndOnMapStart()
tRoundEnd = INVALID_HANDLE; tRoundEnd = INVALID_HANDLE;
} }
/**
* Client is joining the server.
*
* @param client The client index.
*/
RoundEndClientInit(client)
{
// Get client's DX level.
RoundEndGetClientDXLevel(client);
}
/** /**
* Client has been killed. * Client has been killed.
*/ */
@ -167,53 +151,6 @@ RoundEndOnRoundEnd(reason)
RoundEndBalanceTeams(); RoundEndBalanceTeams();
} }
/**
* Finds DX level of a client.
*
* @param client The client index.
*/
RoundEndGetClientDXLevel(client)
{
// If client is fake (or bot), then stop.
if (IsFakeClient(client))
{
return;
}
// Query mat_dxlevel on client.
mat_dxlevel = QueryClientConVar(client, "mat_dxlevel", RoundEndQueryClientDXLevel);
}
/**
* Query callback function.
*
* @param cookie Unique cookie of the query.
* @param client The client index.
* @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 RoundEndQueryClientDXLevel(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.
if (cookie != mat_dxlevel)
{
return;
}
// Reset dxLevel.
dxLevel[client] = 0;
// If result is any other than ConVarQuery_Okay, then stop.
if (result != ConVarQuery_Okay)
{
return;
}
// Copy cvar value to dxLevel array.
dxLevel[client] = StringToInt(cvarValue);
}
/** /**
* Convert a round_end reason, to a round winner, or draw. * Convert a round_end reason, to a round winner, or draw.
* *
@ -397,34 +334,6 @@ RoundEndBalanceTeams()
CloseHandle(arrayEligibleClients); CloseHandle(arrayEligibleClients);
} }
/**
* Displays overlay to client, or prints unsupported message on client's screen.
*
* @param client The client index.
* @param overlay The overlay path.
*/
RoundEndDisplayClientOverlay(client, const String:overlay[])
{
// If dxLevel is 0, then query on client failed, so try again, then stop.
if (!dxLevel[client])
{
// Query dxlevel cvar.
RoundEndGetClientDXLevel(client);
return;
}
// If dxLevel is above or equal to minimum requirement, then display overlay.
if (dxLevel[client] >= GENERAL_DXLEVEL_MIN)
{
ClientCommand(client, "r_screenoverlay \"%s\"", overlay);
}
// If client doesn't meet minimum requirement, then print unsupported text.
else
{
ZR_PrintCenterText(client, "DX90 not supported", dxLevel[client], GENERAL_DXLEVEL_MIN);
}
}
/** /**
* Displays overlays to clients, depending on the outcome. * Displays overlays to clients, depending on the outcome.
* *
@ -470,7 +379,14 @@ RoundEndOverlayStart(Float:time, RoundEndOutcome:outcome)
continue; continue;
} }
RoundEndDisplayClientOverlay(x, overlaypath); // 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);
} }
CreateTimer(time, RoundEndOverlayTimer, _, TIMER_FLAG_NO_MAPCHANGE); CreateTimer(time, RoundEndOverlayTimer, _, TIMER_FLAG_NO_MAPCHANGE);
@ -487,8 +403,14 @@ RoundEndOverlayStop()
continue; continue;
} }
// Removes overlay from client's screen. // If client is fake (or bot), then stop.
ClientCommand(x, "r_screenoverlay \"\""); if (IsFakeClient(x))
{
continue;
}
// Disable roundend overlay channel.
OverlaysClientSetChannelState(x, OVERLAYS_CHANNEL_ROUNDEND, true, false, false, true);
} }
} }

View File

@ -12,7 +12,7 @@
FormatTextString(String:text[], maxlen) FormatTextString(String:text[], maxlen)
{ {
Format(text, maxlen, "@green[%t] @default%s", "ZR", text); Format(text, maxlen, "@green[ZR] @default%s", text);
ReplaceString(text, maxlen, "@default","\x01"); ReplaceString(text, maxlen, "@default","\x01");
ReplaceString(text, maxlen, "@lgreen","\x03"); ReplaceString(text, maxlen, "@lgreen","\x03");
@ -92,7 +92,7 @@ stock ZR_PrintToServer(any:...)
decl String:buffer[192]; decl String:buffer[192];
VFormat(phrase, sizeof(phrase), "%t", 1); VFormat(phrase, sizeof(phrase), "%t", 1);
Format(buffer, sizeof(buffer), "[%t] %s", "ZR", phrase); Format(buffer, sizeof(buffer), "[ZR] %s", phrase);
PrintToServer(buffer); PrintToServer(buffer);
} }

View File

@ -24,7 +24,7 @@ new Handle:gRestrictedWeapons = INVALID_HANDLE;
/** /**
* Array that stores the "HookID" to be later unhooked on player disconnect. * Array that stores the "HookID" to be later unhooked on player disconnect.
*/ */
new gCanUseHookID[MAXPLAYERS + 1]; new g_iCanUseHookID[MAXPLAYERS + 1] = {-1, ...};
/** /**
* Query results returned when (un)restricting a weapon. * Query results returned when (un)restricting a weapon.
@ -52,6 +52,16 @@ RestrictInit()
RegConsoleCmd("rebuy", RestrictBuyCommand); RegConsoleCmd("rebuy", RestrictBuyCommand);
} }
/**
* Hook commands related to restrict here.
*/
RestrictOnCommandsCreate()
{
// Create admin commands.
RegAdminCmd("zr_restrict", RestrictRestrictCommand, ADMFLAG_GENERIC, "zr_restrict <weapon> - Restrict a weapon.");
RegAdminCmd("zr_unrestrict", RestrictUnrestrictCommand, ADMFLAG_GENERIC, "zr_unrestrict <weapon> - Unrestrict a weapon.");
}
/** /**
* Clears weapon restrict data. * Clears weapon restrict data.
*/ */
@ -209,7 +219,7 @@ RestrictWeaponUnrestrictAll()
RestrictClientInit(client) RestrictClientInit(client)
{ {
// Hook "Weapon_CanUse" on client. // Hook "Weapon_CanUse" on client.
gCanUseHookID[client] = ZRTools_HookWeapon_CanUse(client, RestrictCanUse); g_iCanUseHookID[client] = ZRTools_HookWeapon_CanUse(client, RestrictCanUse);
} }
/** /**
@ -219,8 +229,13 @@ RestrictClientInit(client)
*/ */
RestrictOnClientDisconnect(client) RestrictOnClientDisconnect(client)
{ {
// Unhook "Weapon_CanUse" on client. // Unhook "Weapon_CanUse" callback, and reset variable.
ZRTools_UnhookWeapon_CanUse(gCanUseHookID[client]);
if (g_iCanUseHookID[client] != -1)
{
ZRTools_UnhookWeapon_CanUse(g_iCanUseHookID[client]);
g_iCanUseHookID[client] = -1;
}
} }
/** /**
@ -231,8 +246,8 @@ RestrictOnClientDisconnect(client)
RestrictOnClientSpawn(client) RestrictOnClientSpawn(client)
{ {
// Re-hook "canuse" on client. // Re-hook "canuse" on client.
ZRTools_UnhookWeapon_CanUse(gCanUseHookID[client]); ZRTools_UnhookWeapon_CanUse(g_iCanUseHookID[client]);
gCanUseHookID[client] = ZRTools_HookWeapon_CanUse(client, RestrictCanUse); g_iCanUseHookID[client] = ZRTools_HookWeapon_CanUse(client, RestrictCanUse);
} }
/** /**
@ -903,3 +918,87 @@ public ZRTools_Action:RestrictCanUse(client, weapon)
// Allow pickup. // Allow pickup.
return ZRTools_Continue; return ZRTools_Continue;
} }
/**
* Command callback (zr_restrict)
* Restricts a weapon or group
*
* @param client The client index.
* @param argc Argument count.
*/
public Action:RestrictRestrictCommand(client, argc)
{
// If weapons module is disabled, then stop.
new bool:weapons = GetConVarBool(g_hCvarsList[CVAR_WEAPONS]);
if (!weapons)
{
// Tell client command is disabled.
ZR_ReplyToCommand(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)
{
// Tell client command is disabled.
ZR_ReplyToCommand(client, "Feature is disabled");
return Plugin_Handled;
}
// arg1 = weapon being restricted
decl String:arg1[32];
GetCmdArg(1, arg1, sizeof(arg1));
// Strip "weapon_" from entity name
ReplaceString(arg1, sizeof(arg1), "weapon_", "");
decl String:display[WEAPONS_MAX_LENGTH];
new WpnRestrictQuery:output = RestrictRestrict(arg1, display);
RestrictPrintRestrictOutput(client, output, display, true);
return Plugin_Handled;
}
/**
* Command callback (zr_unrestrict)
* Unrestricts a weapon or group
*
* @param client The client index.
* @param argc Argument count.
*/
public Action:RestrictUnrestrictCommand(client, argc)
{
// If weapons module is disabled, then stop.
new bool:weapons = GetConVarBool(g_hCvarsList[CVAR_WEAPONS]);
if (!weapons)
{
// Tell client command is disabled.
ZR_ReplyToCommand(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)
{
// Tell client command is disabled.
ZR_ReplyToCommand(client, "Feature is disabled");
return Plugin_Handled;
}
// arg1 = weapon being restricted
decl String:arg1[32];
GetCmdArg(1, arg1, sizeof(arg1));
// Strip "weapon_" from entity name
ReplaceString(arg1, sizeof(arg1), "weapon_", "");
decl String:display[WEAPONS_MAX_LENGTH];
new WpnRestrictQuery:output = RestrictUnrestrict(arg1, display);
RestrictPrintUnrestrictOutput(client, output, display, true);
return Plugin_Handled;
}

View File

@ -129,6 +129,12 @@ WeaponsValidateConfig()
} }
} }
WeaponsOnCommandsCreate()
{
// Forward event to sub-modules.
RestrictOnCommandsCreate();
}
/** /**
* Client is joining the server. * Client is joining the server.
* *

View File

@ -72,7 +72,7 @@ ZHPOnClientDeath(client)
} }
/** /**
* Player has been infected. * Client has been infected.
* *
* @param client The client index. * @param client The client index.
*/ */

View File

@ -1,42 +1,3 @@
/**
* ====================
* Zombie:Reloaded
* File: zombie.inc
* Author: Greyscale
* ====================
*/
HookCommands()
{
RegConsoleCmd("nightvision", Command_NightVision);
}
public Action:Command_NightVision(client, argc)
{
new bool:allow_disable = GetConVarBool(g_hCvarsList[CVAR_ZVISION_ALLOW_DISABLE]);
if (!allow_disable)
{
return;
}
bClientOverlayOn[client] = !bClientOverlayOn[client];
decl String:overlay[PLATFORM_MAX_PATH];
ClassGetOverlayPath(client, overlay, sizeof(overlay));
if (strlen(overlay) > 0)
{
if (bClientOverlayOn[client])
{
ClassOverlayInitialize(client, overlay);
}
else
{
ClassOverlayStop(client);
}
}
}
RemoveObjectives() RemoveObjectives()
{ {
decl String:classname[64]; decl String:classname[64];

View File

@ -10,11 +10,6 @@
* ============================================================================ * ============================================================================
*/ */
/**
* Minimum dx level required to see overlays.
*/
#define GENERAL_DXLEVEL_MIN 90
/** /**
* @section Conversion factors. * @section Conversion factors.
*/ */
@ -24,11 +19,6 @@
* @endsection * @endsection
*/ */
/**
* The DirectX level of a client.
*/
new dxLevel[MAXPLAYERS + 1];
/** /**
* Global variable set to true when the first zombie(s) is/are spawned. * Global variable set to true when the first zombie(s) is/are spawned.
*/ */