Made config module, recoded models.inc and added validations, added a cvar to flag any sayhook as quiet to hide from chat, hooked mp_limitteams, fixed menu handle function, moved file paths into cvars and updated all modules but classes to use it

This commit is contained in:
Greyscale 2009-04-30 07:36:57 +02:00
parent 1a638cfbac
commit 8da309e4f4
15 changed files with 466 additions and 191 deletions

View File

@ -13,7 +13,7 @@
"EyeAngles"
{
"windows" "206"
"osx" "207"
"linux" "207"
}
}

View File

@ -24,6 +24,7 @@
#include "zr/zombiereloaded"
#include "zr/log"
#include "zr/cvars"
#include "zr/config"
#include "zr/translation"
#include "zr/tools"
#include "zr/models"
@ -166,9 +167,6 @@ public OnLibraryAdded(const String:name[])
*/
public OnMapStart()
{
LoadModelData();
LoadDownloadData();
// Forward event to modules.
RoundEndOnMapStart();
InfectOnMapStart();
@ -191,26 +189,9 @@ public OnMapEnd()
*/
public OnConfigsExecuted()
{
// TODO: move to config module when made.
decl String:mapconfig[PLATFORM_MAX_PATH];
GetCurrentMap(mapconfig, sizeof(mapconfig));
Format(mapconfig, sizeof(mapconfig), "sourcemod/zombiereloaded/%s.cfg", mapconfig);
decl String:path[PLATFORM_MAX_PATH];
Format(path, sizeof(path), "cfg/%s", mapconfig);
if (FileExists(path))
{
ServerCommand("exec %s", mapconfig);
if (LogCheckFlag(LOG_CORE_EVENTS))
{
LogMessageFormatted(-1, "", "", "Executed map config file: %s.", LOG_FORMAT_TYPE_SIMPLE, mapconfig);
}
}
// Forward event to modules.
ConfigLoad();
ModelsLoad();
WeaponsLoad();
HitgroupsLoad();
InfectLoad();

View File

@ -24,6 +24,12 @@
enum CvarsList
{
Handle:CVAR_ENABLE,
Handle:CVAR_CONFIG_PATH_MODELS,
Handle:CVAR_CONFIG_PATH_DOWNLOADS,
Handle:CVAR_CONFIG_PATH_PLAYERCLASSES,
Handle:CVAR_CONFIG_PATH_WEAPONS,
Handle:CVAR_CONFIG_PATH_WEAPONGROUPS,
Handle:CVAR_CONFIG_PATH_HITGROUPS,
Handle:CVAR_CLASSES_SPAWN,
Handle:CVAR_CLASSES_RANDOM,
Handle:CVAR_CLASSES_DEFAULT_ZOMBIE,
@ -40,6 +46,8 @@ enum CvarsList
Handle:CVAR_DAMAGE_SUICIDE_ZOMBIE,
Handle:CVAR_DAMAGE_SUICIDE_HUMAN,
Handle:CVAR_DAMAGE_SUICIDE_CMDS,
Handle:CVAR_SAYHOOKS_QUIET,
Handle:CVAR_SAYHOOKS_QUIET_FLAGS,
Handle:CVAR_ROUNDEND_OVERLAY,
Handle:CVAR_ROUNDEND_OVERLAY_ZOMBIE,
Handle:CVAR_ROUNDEND_OVERLAY_HUMAN,
@ -177,6 +185,17 @@ CvarsCreate()
// (None)
// ===========================
// Config (core)
// ===========================
g_hCvarsList[CVAR_CONFIG_PATH_MODELS] = CreateConVar("zr_config_path_models", "configs/zr/models.txt", "");
g_hCvarsList[CVAR_CONFIG_PATH_DOWNLOADS] = CreateConVar("zr_config_path_downloads", "configs/zr/downloads.txt");
g_hCvarsList[CVAR_CONFIG_PATH_PLAYERCLASSES] = CreateConVar("zr_config_path_playerclasses", "configs/zr/playerclasses.txt");
g_hCvarsList[CVAR_CONFIG_PATH_WEAPONS] = CreateConVar("zr_config_path_weapons", "configs/zr/weapons/weapons.txt");
g_hCvarsList[CVAR_CONFIG_PATH_WEAPONGROUPS] = CreateConVar("zr_config_path_weapongroups", "configs/zr/weapons/weapongroups.txt");
g_hCvarsList[CVAR_CONFIG_PATH_HITGROUPS] = CreateConVar("zr_config_path_hitgroups", "configs/zr/hitgroups.txt");
// ===========================
// Tools (core)
// ===========================
@ -290,6 +309,22 @@ CvarsCreate()
g_hCvarsList[CVAR_DAMAGE_SUICIDE_CMDS] = CreateConVar("zr_damage_suicide_cmds", "kill, spectate, jointeam", "");
// Old Desc: List of suicide commands to intercept. (Delimited by \", \"
// ===========================
// Say Hooks (core)
// ===========================
g_hCvarsList[CVAR_SAYHOOKS_QUIET] = CreateConVar("zr_sayhooks_quiet", "1", "");
g_hCvarsList[CVAR_SAYHOOKS_QUIET_FLAGS] = CreateConVar("zr_sayhooks_quiet_flags", "58", "");
// Flags (default: 2 + 8 + 16 + 32)
// 0 Allow all.
// 1 Quiet "!zmenu" say hook.
// 2 Quiet "!zadmin" say hook.
// 4 Quiet "!zclass" say hook.
// 8 Quiet "!zspawn" say hook.
// 16 Quiet "!ztele" say hook.
// 32 Quiet "!zhp" say hook.
// 64 Quiet "!zmarket" say hook.
// ===========================
// Account (module)
// ===========================
@ -465,7 +500,7 @@ CvarsHook(bool:unhook = false)
// Hook cvar to prevent it from changing.
HookConVarChange(g_hAutoTeamBalance, CvarsHookLocked);
//HookConVarChange(hLimitTeams, CvarsHookLocked);
HookConVarChange(g_hLimitTeams, CvarsHookLocked);
HookConVarChange(g_hRestartGame, CvarsHookRestartGame);
// Anticamp shtuff. (needs to be moved to anticamp if these hooks are necessary)
@ -486,6 +521,12 @@ public CvarsHookLocked(Handle:cvar, const String:oldvalue[], const String:newval
// If cvar is mp_autoteambalance, then continue.
if (cvar == g_hAutoTeamBalance)
{
// If plugin is reverting value, then stop.
if (StringToInt(newvalue) == CVARS_AUTOTEAMBALANCE_LOCKED)
{
return;
}
// Revert to locked value.
SetConVarInt(g_hAutoTeamBalance, CVARS_AUTOTEAMBALANCE_LOCKED);
@ -498,6 +539,12 @@ public CvarsHookLocked(Handle:cvar, const String:oldvalue[], const String:newval
// If cvar is mp_limitteams, then continue.
else if (cvar == g_hLimitTeams)
{
// If plugin is reverting value, then stop.
if (StringToInt(newvalue) == CVARS_LIMITTEAMS_LOCKED)
{
return;
}
// Revert to locked value.
SetConVarInt(g_hLimitTeams, CVARS_LIMITTEAMS_LOCKED);

View File

@ -174,6 +174,7 @@ public Action:EventPlayerSpawn(Handle:event, const String:name[], bool:dontBroad
// Forward event to modules.
InfectOnClientSpawn(index);
ClassOnClientSpawn(index); // Module event depends on infect module.
RestrictOnClientSpawn(index);
SEffectsOnClientSpawn(index);
AccountOnClientSpawn(index);
SpawnProtectOnClientSpawn(index);

View File

@ -17,10 +17,10 @@ new Handle:kvHitgroups = INVALID_HANDLE;
/**
* @section Player hitgroup values.
*/
#define HITGROUP_GENERIC 0
#define HITGROUP_HEAD 1
#define HITGROUP_CHEST 2
#define HITGROUP_STOMACH 3
#define HITGROUP_GENERIC 0
#define HITGROUP_HEAD 1
#define HITGROUP_CHEST 2
#define HITGROUP_STOMACH 3
#define HITGROUP_LEFTARM 4
#define HITGROUP_RIGHTARM 5
#define HITGROUP_LEFTLEG 6
@ -59,20 +59,25 @@ HitgroupsLoad()
return;
}
decl String:path[PLATFORM_MAX_PATH];
BuildPath(Path_SM, path, sizeof(path), "configs/zr/hitgroups.txt");
// Get hitgroups config path.
decl String:pathhitgroups[PLATFORM_MAX_PATH];
new bool:exists = ConfigGetFilePath(CVAR_CONFIG_PATH_HITGROUPS, pathhitgroups);
// If file isn't found, stop plugin.
if (!FileToKeyValues(kvHitgroups, path))
// If file doesn't exist, then log and stop.
if (!exists)
{
// Log failure.
if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_HITGROUPS))
{
LogMessageFormatted(-1, "Hitgroups", "Config Validation", "Missing file hitgroups.txt, disabling hitgroup-based modules.", LOG_FORMAT_TYPE_FULL);
LogMessageFormatted(-1, "Hitgroups", "Config Validation", "Missing hitgroups config file: %s", LOG_FORMAT_TYPE_ERROR, pathhitgroups);
}
return;
}
// Put file data into memory.
FileToKeyValues(kvHitgroups, pathhitgroups);
// Validate hitgroups config.
HitgroupsValidateConfig();
}

View File

@ -82,6 +82,7 @@ public MenuMainHandle(Handle:menu, MenuAction:action, client, slot)
// Copy return to resend variable.
resend = !ZRAdminMenu(client);
}
// Select zclass.
case 1:
{
// Send class menu
@ -90,26 +91,30 @@ public MenuMainHandle(Handle:menu, MenuAction:action, client, slot)
// Don't resend this menu.
resend = false;
}
// Select zspawn.
case 2:
{
// Copy return to resend variable.
resend = !ZMarketSend(client);
}
case 3:
{
// Send zspawn command from client.
ZSpawnClient(client);
}
case 4:
// Select ztele.
case 3:
{
// Copy return to resend variable.
resend = !ZTele(client);
}
case 5:
// Select zhp.
case 4:
{
// Toggle ZHP.
ZHPToggle(client);
}
// Select zmarket.
case 5:
{
// Copy return to resend variable.
resend = !ZMarketMenu(client);
}
}
// Resend is still true, then resend menu.

View File

@ -1,117 +1,250 @@
/**
* ====================
/*
* ============================================================================
*
* Zombie:Reloaded
* File: models.inc
* Author: Greyscale
* ====================
*
* File: models.inc
* Description: Model validation and API
*
* ============================================================================
*/
new String:modelSuffix[8][16] = {".dx80.vtx", ".dx90.vtx", ".mdl", ".phy", ".sw.vtx", ".vvd", ".xbox", ".xbox.vtx"};
/**
* Maximum folder depth a model file can be located.
*/
#define MODELS_PATH_MAX_DEPTH 8
new Handle:arrayModels = INVALID_HANDLE;
/**
* Maximum string length of a folder a model file is located under.
*/
#define MODELS_PATH_DIR_MAX_LENGTH 32
FileLinesToArray(Handle:array, const Handle:file)
/**
* Array that stores a list of validated models.
*/
new Handle:arrayModelsList = INVALID_HANDLE;
ModelsLoad()
{
ClearArray(array);
// Add models to downloads table and validate.
ModelsPrepModels();
decl String:line[128];
// Add download entries to downloads table and validate.
ModelsPrepDownloads();
}
/**
* Validate model paths and add to downloads table.
*/
ModelsPrepModels()
{
// Get models file path.
decl String:pathmodels[PLATFORM_MAX_PATH];
new bool:exists = ConfigGetFilePath(CVAR_CONFIG_PATH_MODELS, pathmodels);
while(!IsEndOfFile(file) && ReadFileLine(file, line, sizeof(line)))
// If file doesn't exist, then log and stop.
if (!exists)
{
if (StrContains(line, ";") == -1)
// Log failure and stop plugin.
if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CORE))
{
if (StrContains(line, "//") > -1)
LogMessageFormatted(-1, "Models", "Config Validation", "Missing models file: %s", LOG_FORMAT_TYPE_FATALERROR, pathmodels);
}
}
// If model array exists, then destroy it.
if (arrayModelsList != INVALID_HANDLE)
{
CloseHandle(arrayModelsList);
}
arrayModelsList = ConfigLinesToArray(pathmodels);
// If array couldn't be created, then fail.
if (arrayModelsList == INVALID_HANDLE)
{
LogMessageFormatted(-1, "Models", "Config Validation", "Error parsing %s", LOG_FORMAT_TYPE_FATALERROR, pathmodels);
}
new modelcount;
new modelvalidcount;
new modelfilecount;
decl String:modelbase[PLATFORM_MAX_PATH];
decl String:modelpath[PLATFORM_MAX_PATH];
decl String:modelname[MODELS_PATH_DIR_MAX_LENGTH];
decl String:modelfile[MODELS_PATH_DIR_MAX_LENGTH];
decl String:modeldiskname[MODELS_PATH_DIR_MAX_LENGTH];
decl String:modelfullpath[PLATFORM_MAX_PATH];
new String:baseexploded[MODELS_PATH_MAX_DEPTH][MODELS_PATH_DIR_MAX_LENGTH];
new FileType:type;
new models = modelcount = GetArraySize(arrayModelsList);
// x = model array index.
for (new x = 0; x < models; x++)
{
// Get base model path (rawline in models.txt)
GetArrayString(arrayModelsList, x, modelbase, sizeof(modelbase));
// Explode path into pieces. (separated by "/")
new strings = ExplodeString(modelbase, "/", baseexploded, MODELS_PATH_MAX_DEPTH, MODELS_PATH_DIR_MAX_LENGTH);
// Get model file name.
strcopy(modelname, sizeof(modelname), baseexploded[strings - 1]);
// Get the path to the file.
// Works by truncating original path by the length of the file name.
strcopy(modelpath, strlen(modelbase) - strlen(modelname), modelbase);
// Open dir containing model files.
new Handle:modeldir = OpenDirectory(modelpath);
// Reset model file count.
modelfilecount = 0;
while (ReadDirEntry(modeldir, modelfile, sizeof(modelfile), type))
{
// If entry isn't a file, then stop.
if (type != FileType_File)
{
SplitString(line, "//", line, sizeof(line));
continue;
}
TrimString(line);
if (!StrEqual(line, "", false))
// Find break point index in the string to get model name.
// Add one because it seems to break on the character before.
new breakpoint = FindCharInString(modelfile, '.') + 1;
strcopy(modeldiskname, breakpoint, modelfile);
// If this file doesn't match, then stop.
if (!StrEqual(modelname, modeldiskname, false))
{
PushArrayString(array, line);
continue;
}
// Format a full path string.
strcopy(modelfullpath, sizeof(modelfullpath), modelpath);
Format(modelfullpath, sizeof(modelfullpath), "%s/%s", modelfullpath, modelfile);
// Precache model file and add to downloads table.
PrecacheModel(modelfullpath);
AddFileToDownloadsTable(modelfullpath);
// Increment modelfilecount
modelfilecount++;
}
}
}
LoadModelData()
{
decl String:path[PLATFORM_MAX_PATH];
BuildPath(Path_SM, path, sizeof(path), "configs/zr/models.txt");
if (arrayModels != INVALID_HANDLE)
{
CloseHandle(arrayModels);
}
arrayModels = CreateArray(256, 0);
new Handle:fileModels = OpenFile(path, "r");
if (fileModels == INVALID_HANDLE)
{
SetFailState("\"%s\" missing from server", path);
}
FileLinesToArray(arrayModels, fileModels);
if (!GetArraySize(arrayModels))
{
SetFailState("No models listed in models.txt, please add some models then restart");
}
decl String:model[256];
decl String:modelpath[256];
new modelsize = GetArraySize(arrayModels);
for (new x = 0; x < modelsize; x++)
{
for (new y = 0; y < 8; y++)
// Increment modelvalidcount if model files are valid.
if (modelfilecount)
{
GetArrayString(arrayModels, x, model, sizeof(model));
Format(modelpath, sizeof(modelpath), "%s%s", model, modelSuffix[y]);
if (FileExists(modelpath))
{
PrecacheModel(modelpath);
AddFileToDownloadsTable(modelpath);
}
}
}
CloseHandle(fileModels);
}
LoadDownloadData()
{
decl String:path[PLATFORM_MAX_PATH];
BuildPath(Path_SM, path, sizeof(path), "configs/zr/downloads.txt");
new Handle:fileDownloads = OpenFile(path, "r");
if (fileDownloads == INVALID_HANDLE)
{
SetFailState("\"%s\" missing from server", path);
}
new Handle:arrayDownloads = CreateArray(256, 0);
FileLinesToArray(arrayDownloads, fileDownloads);
decl String:file[256];
new downloadsize = GetArraySize(arrayDownloads);
for (new x = 0; x < downloadsize; x++)
{
GetArrayString(arrayDownloads, x, file, sizeof(file));
if (FileExists(file))
{
AddFileToDownloadsTable(file);
modelvalidcount++;
}
else
{
ZR_LogMessage("File load failed", file);
// Remove client from array.
RemoveFromArray(arrayModelsList, x);
// Subtract one from count.
models--;
// Backtrack one index, because we deleted it out from under the loop.
x--;
// Log missing model files.
if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CORE))
{
LogMessageFormatted(-1, "Models", "Config Validation", "Missing model files on server (%s)", LOG_FORMAT_TYPE_ERROR, modelbase);
}
}
}
// Log model validation info.
LogMessageFormatted(-1, "Models", "Config Validation", "Total: %d | Successful: %d | Unsuccessful: %d", LOG_FORMAT_TYPE_FULL, modelcount, modelvalidcount, modelcount - modelvalidcount);
// If none of the model paths are valid, then log and fail.
if (!modelvalidcount)
{
if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CORE))
{
LogMessageFormatted(-1, "Models", "Config Validation", "No usable model paths in %s", LOG_FORMAT_TYPE_FATALERROR, pathmodels);
}
}
CloseHandle(fileDownloads);
CloseHandle(arrayDownloads);
}
/**
* Validate custom download paths and add to downloads table.
*/
ModelsPrepDownloads()
{
// Get downloads file path.
decl String:pathdownloads[PLATFORM_MAX_PATH];
new bool:exists = ConfigGetFilePath(CVAR_CONFIG_PATH_DOWNLOADS, pathdownloads);
// If file doesn't exist, then log.
if (!exists)
{
// Log error, then stop.
if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CORE))
{
LogMessageFormatted(-1, "Downloads", "Config Validation", "Missing downloads file: %s", LOG_FORMAT_TYPE_ERROR, pathdownloads);
}
return;
}
new Handle:arrayDownloadsList = ConfigLinesToArray(pathdownloads);
// If array couldn't be created, then fail.
if (arrayModelsList == INVALID_HANDLE)
{
if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CORE))
{
LogMessageFormatted(-1, "Downloads", "Config Validation", "Error parsing %s", LOG_FORMAT_TYPE_ERROR, pathdownloads);
}
}
new downloadcount;
new downloadvalidcount;
decl String:downloadpath[PLATFORM_MAX_PATH];
new downloads = downloadcount = GetArraySize(arrayDownloadsList);
// x = download array index.
for (new x = 0; x < downloads; x++)
{
// Get base model path (rawline in models.txt)
GetArrayString(arrayDownloadsList, x, downloadpath, sizeof(downloadpath));
// If file doesn't exist, then remove, log, and stop.
if (!FileExists(downloadpath))
{
// Remove client from array.
RemoveFromArray(arrayDownloadsList, x);
// Subtract one from count.
downloads--;
// Backtrack one index, because we deleted it out from under the loop.
x--;
if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CORE))
{
LogMessageFormatted(-1, "Downloads", "Config Validation", "Missing file (%s)", LOG_FORMAT_TYPE_ERROR, downloadpath);
}
continue;
}
// Increment downloadvalidcount
downloadvalidcount++;
// Precache model file and add to downloads table.
AddFileToDownloadsTable(downloadpath);
}
// Log model validation info.
LogMessageFormatted(-1, "Downloads", "Config Validation", "Total: %d | Successful: %d | Unsuccessful: %d", LOG_FORMAT_TYPE_FULL, downloadcount, downloadvalidcount, downloadcount - downloadvalidcount);
}

View File

@ -70,8 +70,8 @@ bool:ClassApplyModel(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER)
if (strcmp(modelpath, "random", false) == 0)
{
// TODO: Make a function that gets a random model from the specified team.
new randmodel = GetRandomInt(0, GetArraySize(arrayModels) - 1);
GetArrayString(arrayModels, randmodel, modelpath, sizeof(modelpath));
new randmodel = GetRandomInt(0, GetArraySize(arrayModelsList) - 1);
GetArrayString(arrayModelsList, randmodel, modelpath, sizeof(modelpath));
Format(modelpath, sizeof(modelpath), "%s.mdl", modelpath);
}

View File

@ -261,6 +261,9 @@ public ClassMenuSelectHandle(Handle:menu, MenuAction:action, client, slot)
{
ClassMenuMain(client);
}
// Stop so menu doesn't reopen.
return;
}
case MenuAction_End:
{

View File

@ -251,6 +251,12 @@ RoundEndOutcome:RoundEndReasonToOutcome(reason)
*/
public Action:RoundEndTimer(Handle:timer)
{
// 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);
}

View File

@ -28,6 +28,20 @@
* @endsection
*/
/**
* @section Say hook quiet flags.
*/
#define SAYHOOKS_KEYWORD_FLAG_ZMENU 1
#define SAYHOOKS_KEYWORD_FLAG_ZADMIN 2
#define SAYHOOKS_KEYWORD_FLAG_ZCLASS 4
#define SAYHOOKS_KEYWORD_FLAG_ZSPAWN 8
#define SAYHOOKS_KEYWORD_FLAG_ZTELE 16
#define SAYHOOKS_KEYWORD_FLAG_ZHP 32
#define SAYHOOKS_KEYWORD_FLAG_ZMARKET 64
/**
* @endsection
*/
/**
* Say hooks module init function.
*/
@ -55,50 +69,114 @@ public Action:SayHooksCmdSay(client, argc)
// Strip away the quotes.
ReplaceString(args, sizeof(args), "\"", "");
// If client triggered the zmenu keyword, then send menu.
if (StrEqual(args, SAYHOOKS_KEYWORD_ZMENU, false))
new chatflag = SayHooksChatToFlag(args);
// If chatflag is invalid, then continue.
if (!chatflag)
{
MenuMain(client);
return Plugin_Continue;
}
// If client triggered the zmenu keyword, then send menu.
else if (StrEqual(args, SAYHOOKS_KEYWORD_ZADMIN, false))
switch(chatflag)
{
ZRAdminMenu(client);
// Client triggered ZMenu flag.
case SAYHOOKS_KEYWORD_FLAG_ZMENU:
{
// Send main menu.
MenuMain(client);
}
// Client triggered ZAdmin flag.
case SAYHOOKS_KEYWORD_FLAG_ZADMIN:
{
ZRAdminMenu(client);
}
// Client triggered ZClass flag.
case SAYHOOKS_KEYWORD_FLAG_ZCLASS:
{
// Send class menu.
ClassMenuMain(client);
}
// Client triggered ZSpawn flag.
case SAYHOOKS_KEYWORD_FLAG_ZSPAWN:
{
// Spawns a late-joining client into the game.
ZSpawnClient(client);
}
// Client triggered ZTele flag.
case SAYHOOKS_KEYWORD_FLAG_ZTELE:
{
ZTele(client);
}
// Client triggered ZHP flag.
case SAYHOOKS_KEYWORD_FLAG_ZHP:
{
// Toggle ZHP.
ZHPToggle(client);
}
// Client triggered ZMarket flag.
case SAYHOOKS_KEYWORD_FLAG_ZMARKET:
{
// Send market menu.
ZMarketMenu(client);
}
}
// If client triggered the zmenu keyword, then send menu.
else if (StrEqual(args, SAYHOOKS_KEYWORD_ZCLASS, false))
// If quiet cvar is disabled, then continue.
new bool:quiet = GetConVarBool(g_hCvarsList[CVAR_SAYHOOKS_QUIET]);
if (!quiet)
{
ClassMenuMain(client);
return Plugin_Continue;
}
// If client triggered the zmenu keyword, then send menu.
else if (StrEqual(args, SAYHOOKS_KEYWORD_ZSPAWN, false))
// If word is flagged to be quieted, then stop.
new quietflags = GetConVarInt(g_hCvarsList[CVAR_SAYHOOKS_QUIET_FLAGS]);
if (quietflags & chatflag)
{
// Spawns a late-joining client into the game.
ZSpawnClient(client);
}
// If client triggered the zmenu keyword, then send menu.
else if (StrEqual(args, SAYHOOKS_KEYWORD_ZTELE, false))
{
ZTele(client);
}
// If client triggered the zmenu keyword, then send menu.
else if (StrEqual(args, SAYHOOKS_KEYWORD_ZHP, false))
{
// Toggle ZHP.
ZHPToggle(client);
}
// If client triggered the zmenu keyword, then send menu.
else if (StrEqual(args, SAYHOOKS_KEYWORD_ZMARKET, false))
{
// Send market menu.
ZMarketSend(client);
return Plugin_Handled;
}
return Plugin_Continue;
}
/**
* Convert chat text into a defined flag.
*
* @param chat The chat text to convert.
* @return Returns flag for word given, returns 0 if matches none.
*/
SayHooksChatToFlag(const String:chat[])
{
// Return flag for chatstring.
if (StrEqual(chat, SAYHOOKS_KEYWORD_ZMENU, false))
{
return SAYHOOKS_KEYWORD_FLAG_ZMENU;
}
else if (StrEqual(chat, SAYHOOKS_KEYWORD_ZADMIN, false))
{
return SAYHOOKS_KEYWORD_FLAG_ZADMIN;
}
else if (StrEqual(chat, SAYHOOKS_KEYWORD_ZCLASS, false))
{
return SAYHOOKS_KEYWORD_FLAG_ZCLASS;
}
else if (StrEqual(chat, SAYHOOKS_KEYWORD_ZSPAWN, false))
{
return SAYHOOKS_KEYWORD_FLAG_ZSPAWN;
}
else if (StrEqual(chat, SAYHOOKS_KEYWORD_ZTELE, false))
{
return SAYHOOKS_KEYWORD_FLAG_ZTELE;
}
else if (StrEqual(chat, SAYHOOKS_KEYWORD_ZHP, false))
{
return SAYHOOKS_KEYWORD_FLAG_ZHP;
}
else if (StrEqual(chat, SAYHOOKS_KEYWORD_ZMARKET, false))
{
return SAYHOOKS_KEYWORD_FLAG_ZMARKET;
}
// Return 0.
return 0;
}

View File

@ -19,7 +19,7 @@ new bool:g_bMarket;
*
* @param client The client index.
*/
bool:ZMarketSend(client)
bool:ZMarketMenu(client)
{
// If market is disabled, then stop.
if (!g_bMarket)
@ -151,5 +151,5 @@ public Market_PostOnWeaponSelected(client, &bool:allowed)
}
// Resend market menu.
ZMarketSend(client);
ZMarketMenu(client);
}

View File

@ -48,16 +48,7 @@ WeaponsMenuMain(client)
AddMenuItem(menu_weapons_main, "toggleweaponrestriction", toggleweaponrestriction);
AddMenuItem(menu_weapons_main, "togglewgrouprestriction", togglewgrouprestriction);
// Disable market option if market isn't installed.
if (g_bMarket)
{
AddMenuItem(menu_weapons_main, "zmarket", zmarket);
}
else
{
AddMenuItem(menu_weapons_main, "zmarket", zmarket, ITEMDRAW_DISABLED);
}
AddMenuItem(menu_weapons_main, "zmarket", zmarket, MenuGetItemDraw(g_bMarket));
// Create a "Back" button to the weapons main menu.
SetMenuExitBackButton(menu_weapons_main, true);

View File

@ -82,20 +82,26 @@ RestrictOnMapStart()
// Restrict default restrictions. (set in weapons.txt)
RestrictDefaultRestrictions();
decl String:path[PLATFORM_MAX_PATH];
BuildPath(Path_SM, path, sizeof(path), "configs/zr/weapons/weapongroups.txt");
// Get weapon groups config path.
decl String:pathweapongroups[PLATFORM_MAX_PATH];
new bool:exists = ConfigGetFilePath(CVAR_CONFIG_PATH_WEAPONGROUPS, pathweapongroups);
// If file isn't found, stop plugin.
if (!FileToKeyValues(kvWeaponGroups, path))
// If file doesn't exist, then log and stop.
if (!exists)
{
// Log failure.
if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_WEAPONS))
{
LogMessageFormatted(-1, "Weapons", "Config Validation", "Missing file weapongroups.txt.", LOG_FORMAT_TYPE_ERROR);
LogMessageFormatted(-1, "Weapons", "Config Validation", "Missing weapon groups config file: %s", LOG_FORMAT_TYPE_ERROR, pathweapongroups);
}
return;
}
// Put file data into memory.
FileToKeyValues(kvWeaponGroups, pathweapongroups);
// Validate weapon groups config.
RestrictValidateWeaponGroups();
}
@ -197,6 +203,7 @@ RestrictWeaponUnrestrictAll()
*/
RestrictClientInit(client)
{
// Hook "canuse" on client.
gCanUseHookID[client] = Hacks_Hook(client, HACKS_HTYPE_WEAPON_CANUSE, RestrictCanUse, false);
}
@ -207,9 +214,22 @@ RestrictClientInit(client)
*/
RestrictOnClientDisconnect(client)
{
// Unhook "canuse" on client.
Hacks_Unhook(gCanUseHookID[client]);
}
/**
* Client is spawning into the game.
*
* @param client The client index.
*/
RestrictOnClientSpawn(client)
{
// Re-hook "canuse" on client.
Hacks_Unhook(gCanUseHookID[client]);
gCanUseHookID[client] = Hacks_Hook(client, HACKS_HTYPE_WEAPON_CANUSE, RestrictCanUse, false);
}
/**
* Command callback function for the "buy" command
* Used to block use of this command under certain conditions.

View File

@ -82,20 +82,25 @@ WeaponsLoad()
return;
}
decl String:path[PLATFORM_MAX_PATH];
BuildPath(Path_SM, path, sizeof(path), "configs/zr/weapons/weapons.txt");
// Get weapons config path.
decl String:pathweapons[PLATFORM_MAX_PATH];
new bool:exists = ConfigGetFilePath(CVAR_CONFIG_PATH_WEAPONS, pathweapons);
// If file isn't found, stop plugin.
if (!FileToKeyValues(kvWeapons, path))
// If file doesn't exist, then log and stop.
if (!exists)
{
// Log failure.
if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_WEAPONS))
{
LogMessageFormatted(-1, "Weapons", "Config Validation", "Missing file weapons.txt.", LOG_FORMAT_TYPE_ERROR);
LogMessageFormatted(-1, "Weapons", "Config Validation", "Missing weapons config file: %s", LOG_FORMAT_TYPE_ERROR, pathweapons);
}
return;
}
// Put file data into memory.
FileToKeyValues(kvWeapons, pathweapons);
// Validate weapons config.
WeaponsValidateConfig();