diff --git a/cstrike/addons/sourcemod/configs/zr/downloads.txt b/cstrike/addons/sourcemod/configs/zr/downloads.txt index f11d6b8..f9cbaaa 100644 --- a/cstrike/addons/sourcemod/configs/zr/downloads.txt +++ b/cstrike/addons/sourcemod/configs/zr/downloads.txt @@ -10,6 +10,7 @@ // ---------------------------------------------------------------------------- // Defaults: // ---------------------------------------------------------------------------- + materials/models/player/zh/Zombie_Classic_sheet.vmt materials/models/player/zh/corpse1.vmt materials/models/player/zh/Charple1_sheet.vmt diff --git a/cstrike/addons/sourcemod/configs/zr/models.txt b/cstrike/addons/sourcemod/configs/zr/models.txt index 40b6402..461a903 100644 --- a/cstrike/addons/sourcemod/configs/zr/models.txt +++ b/cstrike/addons/sourcemod/configs/zr/models.txt @@ -6,12 +6,25 @@ // Check the weapon configuration section in the manual for detailed info. // // ============================================================================ +// Format: +// ---------------------------------------------------------------------------- +// the/path/to/the/model ;public/hidden/adminonly/etc +// * ;public - The model will be treated as a model that any client has access to. +// * ;hidden - The model can only be accessed through explicit use of a player class. +// E.g. If a class uses the "random" setting for model, then any non-public +// models will not be chosen. +// ============================================================================ // * Each uncommented line will be used as a model path for clients to download, // and classes to utilize. +// * If no ; is specified, the model will be assumed as public. // ---------------------------------------------------------------------------- // Defaults: // ---------------------------------------------------------------------------- -models/player/zh/zh_charple001 -models/player/zh/zh_zombie003 -models/player/zh/zh_corpse002 -models/player/ics/hellknight_red/t_guerilla + +models/player/zh/zh_charple001 ;public +models/player/zh/zh_zombie003 ;public +models/player/zh/zh_corpse002 ;public +models/player/ics/hellknight_red/t_guerilla ;public +// models/player/adminmodels/1337model ;adminonly // None of these models will be randomly chosen. +// models/player/donatormodels/donatormodel ;donator +// models/player/hiddenmodels/myhiddenmodel ;non-public \ No newline at end of file diff --git a/src/zr/config.inc b/src/zr/config.inc index ecca535..f906a8a 100644 --- a/src/zr/config.inc +++ b/src/zr/config.inc @@ -422,9 +422,10 @@ stock ConfigGetConfigAlias(ConfigFile:config, String:alias[], maxlen) * * @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. * @return True if file was loaded successfuly, false otherwise. */ -stock bool:ConfigLoadConfig(ConfigFile:config, &Handle:arrayConfig) +stock bool:ConfigLoadConfig(ConfigFile:config, &Handle:arrayConfig, blocksize = CONFIG_MAX_LENGTH) { // Get config's structure. new ConfigStructure:structure = ConfigGetConfigStructure(config); @@ -441,7 +442,7 @@ stock bool:ConfigLoadConfig(ConfigFile:config, &Handle:arrayConfig) if (arrayConfig == INVALID_HANDLE) { // Create array in handle. - arrayConfig = CreateArray(CONFIG_MAX_LENGTH); + arrayConfig = CreateArray(blocksize); } switch(structure) @@ -463,17 +464,8 @@ stock bool:ConfigLoadConfig(ConfigFile:config, &Handle:arrayConfig) decl String:line[PLATFORM_MAX_PATH]; - while(!IsEndOfFile(hFile)) + while(ReadFileLine(hFile, line, sizeof(line))) { - // Get current line text. - ReadFileLine(hFile, line, sizeof(line)); - - // If line contains a ";", then stop. - if (StrContains(line, ";") > -1) - { - continue; - } - // Cut out comments at the end of a line. if (StrContains(line, "//") > -1) { @@ -518,7 +510,7 @@ stock bool:ConfigLoadConfig(ConfigFile:config, &Handle:arrayConfig) do { // Create new array to store information for config entry. - new Handle:arrayConfigEntry = CreateArray(CONFIG_MAX_LENGTH); + new Handle:arrayConfigEntry = CreateArray(blocksize); // Push the key name into the config entry's array. decl String:keyname[CONFIG_MAX_LENGTH]; diff --git a/src/zr/downloads.inc b/src/zr/downloads.inc index cf3a1fa..91e80e4 100644 --- a/src/zr/downloads.inc +++ b/src/zr/downloads.inc @@ -53,7 +53,7 @@ DownloadsLoad() ConfigSetConfigPath(File_Downloads, pathdownloads); // Load config from file and create array structure. - new bool:success = ConfigLoadConfig(File_Downloads, arrayDownloads); + new bool:success = ConfigLoadConfig(File_Downloads, arrayDownloads, PLATFORM_MAX_PATH); // Unexpected error, stop plugin. if (!success) diff --git a/src/zr/models.inc b/src/zr/models.inc index 6289ab2..d0f2e46 100644 --- a/src/zr/models.inc +++ b/src/zr/models.inc @@ -63,7 +63,7 @@ ModelsLoad() ConfigSetConfigPath(File_Models, pathmodels); // Load config from file and create array structure. - new bool:success = ConfigLoadConfig(File_Models, arrayModels); + new bool:success = ConfigLoadConfig(File_Models, arrayModels, PLATFORM_MAX_PATH); // Unexpected error, stop plugin. if (!success) @@ -72,7 +72,8 @@ ModelsLoad() } new modelcount; - new modelvalidcount; + new modelpublicvalidcount; + new modelnonpublicvalidcount; new modelfilecount; decl String:modelbase[PLATFORM_MAX_PATH]; @@ -91,9 +92,9 @@ ModelsLoad() // x = model array index. for (new x = 0; x < models; x++) { - // Get base model path (rawline in models.txt) - GetArrayString(arrayModels, x, modelbase, sizeof(modelbase)); - + // Get base model path, excluding the public/non-public setting. + ModelReturnPath(x, modelbase, sizeof(modelbase)); + PrintToServer("PATH BASE [%s]", modelbase); // Explode path into pieces. (separated by "/") new strings = ExplodeString(modelbase, "/", baseexploded, MODELS_PATH_MAX_DEPTH, MODELS_PATH_DIR_MAX_LENGTH); @@ -147,10 +148,18 @@ ModelsLoad() modelfilecount++; } - // Increment modelvalidcount if model files are valid. + // Increment variable if model files are valid. if (modelfilecount) { - modelvalidcount++; + // Increment proper variable. + if (ModelIsPublic(x)) + { + modelpublicvalidcount++; + } + else + { + modelnonpublicvalidcount++; + } } else { @@ -169,12 +178,12 @@ ModelsLoad() } // Log model validation info. - LogEvent(false, LogType_Normal, LOG_CORE_EVENTS, LogModule_Models, "Config Validation", "Total: %d | Successful: %d | Unsuccessful: %d", modelcount, modelvalidcount, modelcount - modelvalidcount); + LogEvent(false, LogType_Normal, LOG_CORE_EVENTS, LogModule_Models, "Config Validation", "Total: %d | Successful Public: %d | Successful Non-Public: %d | Unsuccessful: %d", modelcount, modelpublicvalidcount, modelnonpublicvalidcount, modelcount - (modelpublicvalidcount + modelnonpublicvalidcount)); // If none of the model paths are valid, then log and fail. - if (!modelvalidcount) + if (!modelpublicvalidcount) { - LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Models, "Config Validation", "No usable model paths in %s", pathmodels); + LogEvent(false, LogType_Fatal, LOG_CORE_EVENTS, LogModule_Models, "Config Validation", "No usable (public) model paths in %s", pathmodels); } // Set config data. @@ -191,3 +200,118 @@ public ModelsOnConfigReload(ConfigFile:config) // Reload models config. ModelsLoad(); } + +/** + * Checks if a model is public. + * + * @param modelindex The array index of the model to check. + * @return True if public, false if not. + */ +stock bool:ModelIsPublic(modelindex) +{ + // Get the entire model string to parse for what we need. + decl String:modelsetting[PLATFORM_MAX_PATH + 16]; + GetArrayString(arrayModels, modelindex, modelsetting, sizeof(modelsetting)); + + // We define this to use as little memory as possible, because the value won't be used. + decl String:modelpath[1]; + decl String:strpublic[32]; + + if (StrContains(modelsetting, ";") > -1) + { + // Get string index of where the public setting starts. + new strindex = SplitString(modelsetting, ";", modelpath, sizeof(modelpath)); + + // Copy setting to new string + strcopy(strpublic, sizeof(strpublic), modelsetting[strindex]); + + // Trim the whitespace. + TrimString(strpublic); + + // If public, return true, non-public returns false. + return StrEqual(strpublic, "public", false); + } + + // If nothing is specified, assume public. + return true; +} + +/** + * Returns the path of a given model index. + * + * @param modelindex The array index of the model. + * @param modelpath The output string of the model path. + * @param maxlen The maximum length of the output string. + */ +stock ModelReturnPath(modelindex, String:modelpath[], maxlen) +{ + // Get the entire model string to parse for what we need. + decl String:modelsetting[PLATFORM_MAX_PATH + 16]; + GetArrayString(arrayModels, modelindex, modelsetting, sizeof(modelsetting)); + + // Copy to path before split just in case the string has no ";" + strcopy(modelpath, maxlen, modelsetting); + if (StrContains(modelsetting, ";") > -1) + { + SplitString(modelsetting, ";", modelpath, maxlen); + } + + // Trim whitespace. + TrimString(modelpath); +} + +/** + * Get a random model index in arrayModels, allows you to specify a filter. + * + * @param modelpath The output string of the model path. + * @param maxlen The maximum length of the output string. + * @param all True to choose any of the models in the file, false to use 'publicmodels' param. + * @param publicmodels True to find a random public model, false to find non-public. + */ +stock ModelsGetRandomModelIndex(String:modelpath[], maxlen, bool:all = true, bool:publicmodels = true) +{ + new modelindex = -1; + + // Return any random model. + if (all) + { + // Get random model index and return the string in it. + modelindex = GetRandomInt(0, GetArraySize(arrayModels) - 1); + } + else + { + new Handle:modelsarray = CreateArray(PLATFORM_MAX_PATH); + decl String:modelsetting[PLATFORM_MAX_PATH]; + + // x = Array index. + new size = GetArraySize(arrayModels); + for (new x = 0; x < size; x++) + { + if (publicmodels == ModelIsPublic(x)) + { + // Transfer model to temp array. + GetArrayString(arrayModels, x, modelsetting, sizeof(modelsetting)); + PushArrayString(modelsarray, modelsetting); + } + } + + // y = Array index. + size = GetArraySize(modelsarray); + + // If there are no models then copy a blank string to the output. + if (size == 0) + { + strcopy(modelpath, maxlen, ""); + return; + } + + // Get random model index from the temp list, and return the string in it. + modelindex = GetRandomInt(0, GetArraySize(modelsarray) - 1); + + // Destroy the handle. + CloseHandle(modelsarray); + } + + // Get the path to the selected model. + ModelReturnPath(modelindex, modelpath, maxlen); +} \ No newline at end of file diff --git a/src/zr/playerclasses/apply.inc b/src/zr/playerclasses/apply.inc index 2f75092..45fd0bd 100644 --- a/src/zr/playerclasses/apply.inc +++ b/src/zr/playerclasses/apply.inc @@ -93,8 +93,7 @@ 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)); + ModelsGetRandomModelIndex(modelpath, sizeof(modelpath), false, true); Format(modelpath, sizeof(modelpath), "%s.mdl", modelpath); } diff --git a/src/zr/playerclasses/playerclasses.inc b/src/zr/playerclasses/playerclasses.inc index cf3a6ff..92be853 100644 --- a/src/zr/playerclasses/playerclasses.inc +++ b/src/zr/playerclasses/playerclasses.inc @@ -488,7 +488,7 @@ ClassLoad(bool:keepMultipliers = false) ClassData[ClassCount][class_health] = KvGetNum(kvClassData, "health", ZR_CLASS_DEFAULT_HEALTH); ClassData[ClassCount][class_health_regen_interval] = KvGetFloat(kvClassData, "health_regen_interval", ZR_CLASS_DEFAULT_HEALTH_REGEN_INTERVAL); ClassData[ClassCount][class_health_regen_amount] = KvGetNum(kvClassData, "health_regen_amount", ZR_CLASS_DEFAULT_HEALTH_REGEN_AMOUNT); - ClassData[ClassCount][class_health_infect_gain] = KvGetNum(kvClassData, "health_infect_bonus", ZR_CLASS_DEFAULT_HEALTH_INFECT_GAIN); + ClassData[ClassCount][class_health_infect_gain] = KvGetNum(kvClassData, "health_infect_gain", ZR_CLASS_DEFAULT_HEALTH_INFECT_GAIN); ClassData[ClassCount][class_kill_bonus] = KvGetNum(kvClassData, "kill_bonus", ZR_CLASS_DEFAULT_KILL_BONUS); ClassData[ClassCount][class_speed] = KvGetFloat(kvClassData, "speed", ZR_CLASS_DEFAULT_SPEED);