diff --git a/cstrike/addons/sourcemod/configs/zr/playerclasses.txt b/cstrike/addons/sourcemod/configs/zr/playerclasses.txt index 0f38713..6d50103 100644 --- a/cstrike/addons/sourcemod/configs/zr/playerclasses.txt +++ b/cstrike/addons/sourcemod/configs/zr/playerclasses.txt @@ -64,7 +64,7 @@ // Hud "overlay_path" "overlays/zr/zvision" - "nvgs" "1" + "nvgs" "0" "fov" "90" // Effects @@ -75,16 +75,16 @@ "immunity_amount" "0.0" "no_fall_damage" "1" - "health" "5000" + "health" "3000" "health_regen_interval" "0.0" "health_regen_amount" "0" "health_infect_gain" "800" "kill_bonus" "2" "speed" "350" - "knockback" "2.5" - "jump_height" "10.0" - "jump_distance" "0.1" + "knockback" "3" + "jump_height" "40.0" + "jump_distance" "1.5" } "fast" @@ -105,7 +105,7 @@ // Hud "overlay_path" "overlays/zr/zvision" - "nvgs" "1" + "nvgs" "0" "fov" "90" // Effects @@ -116,7 +116,7 @@ "immunity_amount" "0.0" "no_fall_damage" "1" - "health" "3000" + "health" "2000" "health_regen_interval" "0.0" "health_regen_amount" "0" "health_infect_gain" "500" @@ -124,8 +124,8 @@ "speed" "380" "knockback" "3.5" - "jump_height" "13.0" - "jump_distance" "0.2" + "jump_height" "60.0" + "jump_distance" "2.0" } "mutated" @@ -146,7 +146,7 @@ // Hud "overlay_path" "overlays/zr/zvision" - "nvgs" "1" + "nvgs" "0" "fov" "90" // Effects @@ -157,16 +157,16 @@ "immunity_amount" "0.0" "no_fall_damage" "1" - "health" "7000" + "health" "5000" "health_regen_interval" "0.0" "health_regen_amount" "0" - "health_infect_gain" "1200" + "health_infect_gain" "1000" "kill_bonus" "2" "speed" "275" - "knockback" "3" - "jump_height" "15.0" - "jump_distance" "0.3" + "knockback" "3.5" + "jump_height" "40.0" + "jump_distance" "1.3" } "heavy" @@ -187,7 +187,7 @@ // Hud "overlay_path" "overlays/zr/zvision" - "nvgs" "1" + "nvgs" "0" "fov" "90" // Effects @@ -198,16 +198,16 @@ "immunity_amount" "0.0" "no_fall_damage" "1" - "health" "7000" + "health" "5000" "health_regen_interval" "0.0" "health_regen_amount" "0" - "health_infect_gain" "1200" + "health_infect_gain" "1000" "kill_bonus" "2" - "speed" "290" - "knockback" "2" + "speed" "280" + "knockback" "2.0" "jump_height" "0.0" - "jump_distance" "0.0" + "jump_distance" "0.8" } // ------------------------------------------ @@ -216,25 +216,25 @@ // // ------------------------------------------ - "ct" + "human_normal" { // General "enabled" "1" "team" "1" "team_default" "1" - "name" "Counter Terrorist" - "description" "Normal CT" + "name" "Normal Human" + "description" "Default Counter-Strike settings" // Model - "model_path" "models/player/ct_gign.mdl" + "model_path" "default" "alpha_spawn" "255" "alpha_damaged" "255" "alpha_damage" "0" // Hud "overlay_path" "" - "nvgs" "1" + "nvgs" "0" "fov" "90" // Effects @@ -254,6 +254,88 @@ "speed" "300" "knockback" "0" "jump_height" "0.0" - "jump_distance" "0.0" + "jump_distance" "1.0" + } + + "human_speedy" + { + // General + "enabled" "1" + "team" "1" + "team_default" "0" + + "name" "Speedy" + "description" "Fast human" + + // Model + "model_path" "default" + "alpha_spawn" "255" + "alpha_damaged" "255" + "alpha_damage" "0" + + // Hud + "overlay_path" "" + "nvgs" "0" + "fov" "90" + + // Effects + "napalm_time" "0.0" + + // Player behaviour + "immunity_mode" "0" + "immunity_amount" "0.0" + "no_fall_damage" "0" + + "health" "100" + "health_regen_interval" "0.0" + "health_regen_amount" "0" + "health_infect_gain" "0" + "kill_bonus" "1" + + "speed" "380" + "knockback" "0" + "jump_height" "0.0" + "jump_distance" "1.0" + } + + "human_light" + { + // General + "enabled" "1" + "team" "1" + "team_default" "0" + + "name" "Light" + "description" "Regular human with improved jump skills" + + // Model + "model_path" "default" + "alpha_spawn" "255" + "alpha_damaged" "255" + "alpha_damage" "0" + + // Hud + "overlay_path" "" + "nvgs" "0" + "fov" "90" + + // Effects + "napalm_time" "0.0" + + // Player behaviour + "immunity_mode" "0" + "immunity_amount" "0.0" + "no_fall_damage" "0" + + "health" "100" + "health_regen_interval" "0.0" + "health_regen_amount" "0" + "health_infect_gain" "0" + "kill_bonus" "1" + + "speed" "300" + "knockback" "0" + "jump_height" "64.0" + "jump_distance" "2.0" } } diff --git a/src/zombiereloaded.sp b/src/zombiereloaded.sp index 94300fb..96eff6c 100644 --- a/src/zombiereloaded.sp +++ b/src/zombiereloaded.sp @@ -172,7 +172,6 @@ public OnMapStart() LoadDownloadData(); // Forward event to modules. - ClassLoad(); WeaponsLoad(); RoundEndOnMapStart(); InfectOnMapStart(); @@ -212,6 +211,7 @@ public OnConfigsExecuted() // Forward event to modules. SEffectsLoad(); + ClassLoad(); } public OnClientPutInServer(client) diff --git a/src/zr/event.inc b/src/zr/event.inc index 6d1647f..77ed8af 100644 --- a/src/zr/event.inc +++ b/src/zr/event.inc @@ -110,8 +110,8 @@ public Action:PlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast) } // Forward event to modules. - ClassOnClientSpawn(index); InfectOnClientSpawn(index); + ClassOnClientSpawn(index); // Module event depends on infect module. SEffectsOnClientSpawn(index); AccountOnClientSpawn(index); SpawnProtectOnClientSpawn(index); @@ -189,7 +189,7 @@ public Action:PlayerJump(Handle:event, const String:name[], bool:dontBroadcast) new Float:distance = ClassGetJumpDistance(client); new Float:height = ClassGetJumpHeight(client); - + JumpBoost(client, distance, height); } diff --git a/src/zr/playerclasses/apply.inc b/src/zr/playerclasses/apply.inc index c096b4d..9d97887 100644 --- a/src/zr/playerclasses/apply.inc +++ b/src/zr/playerclasses/apply.inc @@ -75,7 +75,12 @@ bool:ClassApplyModel(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER) Format(modelpath, sizeof(modelpath), "%s.mdl", modelpath); } - // TODO: Add support for keeping the default cs model ("default"). + // Check if the user specified no change. + else if (strcmp(modelpath, "default", false) == 0) + { + // Don't change the model. + return true; + } SetEntityModel(client, modelpath); return true; diff --git a/src/zr/playerclasses/attributes.inc b/src/zr/playerclasses/attributes.inc index b9fc84f..f0d7fe4 100644 --- a/src/zr/playerclasses/attributes.inc +++ b/src/zr/playerclasses/attributes.inc @@ -9,11 +9,6 @@ * ============================================================================ */ -/** - * Default FOV attribute value. - */ -#define ATTRIBUTES_FOV_DEFAULT 90 - /* * ------------------------------------ * diff --git a/src/zr/playerclasses/classevents.inc b/src/zr/playerclasses/classevents.inc index 27e50e5..bde28a5 100644 --- a/src/zr/playerclasses/classevents.inc +++ b/src/zr/playerclasses/classevents.inc @@ -37,49 +37,71 @@ ClassOnClientDisconnect(client) ClassOnClientSpawn(client) { - // Reset client's FOV. - SetPlayerFOV(client, ATTRIBUTES_FOV_DEFAULT); + if (!IsPlayerAlive(client)) + { + // The client isn't alive. + return; + } new bool:randomclass = GetConVarBool(g_hCvarsList[CVAR_CLASSES_RANDOM]); - new bool:showmenu = GetConVarBool(g_hCvarsList[CVAR_CLASSES_SPAWN]); decl String:steamid[16]; decl String:classname[64]; - if (showmenu && !randomclass) + // Assign random classes if enabled. Always do it for bots. + GetClientAuthString(client, steamid, sizeof(steamid)); + if (randomclass || StrEqual(steamid, "BOT")) { - ClassMenuMain(client); + // Get random classes for each type. + new randomzombie = ClassGetRandomClass(ZR_CLASS_TEAM_ZOMBIES); + new randomhuman = ClassGetRandomClass(ZR_CLASS_TEAM_HUMANS); + + // Mark zombie class as selected. + ClassSelected[client][ZR_CLASS_TEAM_ZOMBIES] = randomzombie; + ClassGetName(randomzombie, classname, sizeof(classname), ZR_CLASS_TEAM_ZOMBIES); + ZR_PrintToChat(client, "Auto-assign", classname); + + // Mark human class as selected. + ClassSelected[client][ZR_CLASS_TEAM_HUMANS] = randomhuman; + ClassGetName(randomhuman, classname, sizeof(classname), ZR_CLASS_TEAM_HUMANS); + ZR_PrintToChat(client, "Auto-assign", classname); + + // Update player cache with the human class data, and apply it. + ClassReloadPlayerCache(client, randomhuman); + ClassApplyAttributes(client); } - // Assign random classes if enabled. - GetClientAuthString(client, steamid, sizeof(steamid)); - if (StrEqual(steamid, "BOT") || randomclass) + // Check if the player should spawn in admin mode. + if (ClassPlayerAdminMode[client]) { - // Get player's team - new teamid = GetClientTeam(client); + // Mark player as in admin mode. + ClassPlayerInAdminMode[client] = true; - // If the first zombie spawned, and the player is on the terrorist team, then - // find a random zombie class, otherwise find a human class. - if (g_bZombieSpawned && teamid == CS_TEAM_T) - { - new classindex = ClassGetRandomClass(ZR_CLASS_TEAM_ZOMBIES); - ClassSelected[client][ZR_CLASS_TEAM_ZOMBIES] = classindex; - ClassGetName(client, classname, sizeof(classname)); - } - else - { - new classindex = ClassGetRandomClass(ZR_CLASS_TEAM_HUMANS); - ClassSelected[client][ZR_CLASS_TEAM_HUMANS] = classindex; - ClassGetName(client, classname, sizeof(classname)); - } + // Update player cache with the admin class and apply attributes. + new adminindex = ClassPlayerNextAdminClass[client]; + ClassReloadPlayerCache(client, adminindex); + ClassApplyAttributes(client); + } + else + { + // Not in admin mode, spawn as a zombie or human. - ZR_PrintToChat(client, "Auto-assign", classname); + // Mark player as not in admin mode. + ClassPlayerInAdminMode[client] = false; + + // Apply class attributes for the currently active class. + ClassReloadPlayerCache(client, ClassGetActiveIndex(client)); + ClassApplyAttributes(client); } } ClassOnClientDeath(client) { + // Reset certain attributes to not make spectating disorted. ClassHealthRegenStop(client); ClassOverlayStop(client); + + SetPlayerFOV(client, 90); + NightVisionOn(client, false); } ClassOnClientInfected(client, bool:motherzombie = false) @@ -93,10 +115,6 @@ ClassOnClientInfected(client, bool:motherzombie = false) ClassApplyAttributes(client, motherzombie); } -ClassOnRoundStart() -{ -} - /* ------------------------------------ * diff --git a/src/zr/playerclasses/classmenus.inc b/src/zr/playerclasses/classmenus.inc index 810b741..46efbf1 100644 --- a/src/zr/playerclasses/classmenus.inc +++ b/src/zr/playerclasses/classmenus.inc @@ -68,8 +68,8 @@ ClassMenuMain(client) Format(humanselect, sizeof(humanselect), "%t\n %s", "!zclass human", humanclass); AddMenuItem(menu, "", humanselect, human_itemdraw); - // Only display admin class options for admins. - if (ZRIsClientAdmin(client)) + // Only display admin class options for admins, and if admin classes exist. + if (ZRIsClientAdmin(client) && ClassCountTeam(ZR_CLASS_TEAM_ADMINS)) { // List admin class options. ClassGetName(ClassSelected[client][ZR_CLASS_TEAM_ADMINS], adminclass, sizeof(adminclass), ZR_CLASS_CACHE_MODIFIED); @@ -243,23 +243,35 @@ public ClassMenuSelectHandle(Handle:menu, MenuAction:action, client, slot) // Solve teamid from the class index. teamid = ClassGetTeamID(classindex, ZR_CLASS_CACHE_MODIFIED); - // Set the players active class to the specified class. - ClassSelected[client][teamid] = classindex; + // Check if the class is a admin class. + if (teamid == ZR_CLASS_TEAM_ADMINS) + { + // Set the admin class to be used on next admin spawn. + ClassPlayerNextAdminClass[client] = classindex; + } + else + { + // Set the players active class to the specified class. + ClassSelected[client][teamid] = classindex; + } } case MenuAction_Cancel: { if (slot == MenuCancel_ExitBack) { ClassMenuMain(client); + return; } } case MenuAction_End: { CloseHandle(menu); + return; } } - // Redisplay the main class menu if autoclose is disabled. + // Redisplay the main class menu after a selection, if autoclose is + // disabled. if (!autoclose) { ClassMenuMain(client); diff --git a/src/zr/playerclasses/clientoverlays.inc b/src/zr/playerclasses/clientoverlays.inc index c02cf9c..07fdae6 100644 --- a/src/zr/playerclasses/clientoverlays.inc +++ b/src/zr/playerclasses/clientoverlays.inc @@ -17,23 +17,41 @@ new Handle:tOverlay[MAXPLAYERS + 1]; /** * Specifies if a client have a overlay. */ -new bClientHasOverlay[MAXPLAYERS + 1]; +new bool:bClientHasOverlay[MAXPLAYERS + 1]; /** * Tells wether the overlay is on or not. */ -new bClientOverlayOn[MAXPLAYERS + 1]; +new bool:bClientOverlayOn[MAXPLAYERS + 1]; /** * Path to the currently active overlay. */ new String:ActiveOverlay[MAXPLAYERS + 1][PLATFORM_MAX_PATH]; -bool:ClientHasOverlay(client) + +/** + * Returns if the have a overlay path specified. + * + * @param client The client index. + * @return True if a overlay path is specified, false otherwise. + */ +bool:ClassClientHasOverlay(client) { return bClientHasOverlay[client]; } +/** + * Returns if the overlay is currently on or not. + * + * @param client The client index. + * @return True if on, false otherwise. + */ +bool:ClassOverlayIsOn(client) +{ + return bClientOverlayOn[client]; +} + ClassOverlayInitialize(client, const String:overlay[]) { if (IsFakeClient(client)) diff --git a/src/zr/playerclasses/filtertools.inc b/src/zr/playerclasses/filtertools.inc index 30f29c6..bab3dbc 100644 --- a/src/zr/playerclasses/filtertools.inc +++ b/src/zr/playerclasses/filtertools.inc @@ -87,27 +87,26 @@ bool:ClassValidateTeamDefaults(cachetype = ZR_CLASS_CACHE_ORIGINAL) ClassValidateAttributes(classindex) { // TODO: Validate immunity mode and amount. - // TODO: Validate jump values. new flags; // Name. - if (strlen(ClassData[classindex][class_name]) == 0) + if (strlen(ClassData[classindex][class_name]) < ZR_CLASS_NAME_MIN) { - flags += ZR_CLASS_ATTRIB_ERR_NAME; + flags += ZR_CLASS_FLAG_NAME; } // Description. - if (strlen(ClassData[classindex][class_description]) == 0) + if (strlen(ClassData[classindex][class_description]) < ZR_CLASS_DESCRIPTION_MIN) { - flags += ZR_CLASS_ATTRIB_ERR_DESCRIPTION; + flags += ZR_CLASS_FLAG_DESCRIPTION; } // Model path. - decl String:model_path[256]; + decl String:model_path[PLATFORM_MAX_PATH]; if (strcopy(model_path, sizeof(model_path), ClassData[classindex][class_model_path]) == 0) { - flags += ZR_CLASS_ATTRIB_ERR_MODEL_PATH; + flags += ZR_CLASS_FLAG_MODEL_PATH; } else { @@ -117,99 +116,120 @@ ClassValidateAttributes(classindex) // Check if the file exists. if (!FileExists(model_path)) { - flags += ZR_CLASS_ATTRIB_ERR_MODEL_PATH; + flags += ZR_CLASS_FLAG_MODEL_PATH; } } } // Alpha, initial. new alpha_initial = ClassData[classindex][class_alpha_initial]; - if (!(alpha_initial >= 0 && alpha_initial <= 255)) + if (!(alpha_initial >= ZR_CLASS_ALPHA_INITIAL_MIN && alpha_initial <= ZR_CLASS_ALPHA_INITIAL_MAX)) { - flags += ZR_CLASS_ATTRIB_ERR_ALPHA_INITIAL; + flags += ZR_CLASS_FLAG_ALPHA_INITIAL; } // Alpha, damaged. new alpha_damaged = ClassData[classindex][class_alpha_damaged]; - if (!(alpha_damaged >= 0 && alpha_damaged <= 255)) + if (!(alpha_damaged >= ZR_CLASS_ALPHA_DAMAGED_MIN && alpha_damaged <= ZR_CLASS_ALPHA_DAMAGED_MAX)) { - flags += ZR_CLASS_ATTRIB_ERR_ALPHA_DAMAGED; + flags += ZR_CLASS_FLAG_ALPHA_DAMAGED; } // Alpha, damage. new alpha_damage = ClassData[classindex][class_alpha_damage]; - if (!(alpha_damage >= 0 && alpha_damage <= 65536)) + if (!(alpha_damage >= ZR_CLASS_ALPHA_DAMAGE_MIN && alpha_damage <= ZR_CLASS_ALPHA_DAMAGE_MAX)) { - flags += ZR_CLASS_ATTRIB_ERR_ALPHA_DAMAGE; + flags += ZR_CLASS_FLAG_ALPHA_DAMAGE; } // Overlay path. - decl String:overlay_path[256]; - decl String:overlay[256]; + decl String:overlay_path[PLATFORM_MAX_PATH]; + decl String:overlay[PLATFORM_MAX_PATH]; if (strcopy(overlay_path, sizeof(overlay_path), ClassData[classindex][class_overlay_path]) > 0) { // Check if the file exists. Format(overlay, sizeof(overlay), "materials/%s.vmt", overlay_path); if (!FileExists(overlay)) { - flags += ZR_CLASS_ATTRIB_ERR_OVERLAY_PATH; + flags += ZR_CLASS_FLAG_OVERLAY_PATH; } } // Field of view. new fov = ClassData[classindex][class_fov]; - if (!(fov > 15 && fov < 180)) + if (!(fov >= ZR_CLASS_FOV_MIN && fov <= ZR_CLASS_FOV_MAX)) { - flags += ZR_CLASS_ATTRIB_ERR_FOV; + flags += ZR_CLASS_FLAG_FOV; } // Napalm time. new Float:napalm_time = ClassData[classindex][class_napalm_time]; - if (!(napalm_time >= 0.0 && napalm_time <= 900.0)) + if (!(napalm_time >= ZR_CLASS_NAPALM_TIME_MIN && napalm_time <= ZR_CLASS_NAPALM_TIME_MAX)) { - flags += ZR_CLASS_ATTRIB_ERR_NAPALM_TIME; + flags += ZR_CLASS_FLAG_NAPALM_TIME; + } + + // Health. + new health = ClassData[classindex][class_health]; + if (!(health >= ZR_CLASS_HEALTH_MIN && health <= ZR_CLASS_HEALTH_MAX)) + { + flags += ZR_CLASS_FLAG_HEALTH; } // Health regen interval. new Float:regen_interval = ClassData[classindex][class_health_regen_interval]; - if (!(regen_interval >= 0.0 && regen_interval <= 900.0)) + if (!(regen_interval >= ZR_CLASS_HEALTH_REGEN_INTERVAL_MIN && regen_interval <= ZR_CLASS_HEALTH_REGEN_INTERVAL_MAX)) { - flags += ZR_CLASS_ATTRIB_ERR_HEALTH_REGEN_INTERVAL; + flags += ZR_CLASS_FLAG_HEALTH_REGEN_INTERVAL; // Health regen amount. Only validating if interval is set. new regen_amount = ClassData[classindex][class_health_regen_amount]; - if (!(regen_amount > 0 && regen_amount <= 65536)) + if (!(regen_amount >= ZR_CLASS_HEALTH_REGEN_AMOUNT_MIN && regen_amount <= ZR_CLASS_HEALTH_REGEN_AMOUNT_MAX)) { - flags += ZR_CLASS_ATTRIB_ERR_HEALTH_REGEN_AMOUNT; + flags += ZR_CLASS_FLAG_HEALTH_REGEN_AMOUNT; } } // Health infect gain. new infect_gain = ClassData[classindex][class_health_infect_gain]; - if (!(infect_gain >= 0 && infect_gain <= 65536)) + if (!(infect_gain >= ZR_CLASS_HEALTH_INFECT_GAIN_MIN && infect_gain <= ZR_CLASS_HEALTH_INFECT_GAIN_MAX)) { - flags += ZR_CLASS_ATTRIB_ERR_INFECT_GAIN; + flags += ZR_CLASS_FLAG_INFECT_GAIN; } // Kill bonus. new kill_bonus = ClassData[classindex][class_kill_bonus]; - if (!(kill_bonus >= 0 && kill_bonus <= 128)) + if (!(kill_bonus >= ZR_CLASS_KILL_BONUS_MIN && kill_bonus <= ZR_CLASS_KILL_BONUS_MAX)) { - flags += ZR_CLASS_ATTRIB_ERR_KILL_BONUS; + flags += ZR_CLASS_FLAG_KILL_BONUS; } // Speed. new Float:speed = ClassData[classindex][class_speed]; - if (!(speed >= 0.0 && speed <= 1024.0)) + if (!(speed >= ZR_CLASS_SPEED_MIN && speed <= ZR_CLASS_SPEED_MAX)) { - flags += ZR_CLASS_ATTRIB_ERR_SPEED; + flags += ZR_CLASS_FLAG_SPEED; } // Knockback. new Float:knockback = ClassData[classindex][class_knockback]; - if (!(knockback >= -10.0 && knockback <= 50.0)) + if (!(knockback >= ZR_CLASS_KNOCKBACK_MIN && knockback <= ZR_CLASS_KNOCKBACK_MAX)) { - flags += ZR_CLASS_ATTRIB_ERR_KNOCKBACK; + flags += ZR_CLASS_FLAG_KNOCKBACK; + } + + // Jump height. + new Float:jump_height = ClassData[classindex][class_jump_height]; + if (!(jump_height >= ZR_CLASS_JUMP_HEIGHT_MIN && jump_height <= ZR_CLASS_JUMP_HEIGHT_MAX)) + { + flags += ZR_CLASS_FLAG_JUMP_HEIGHT; + } + + // Jump distance. + new Float:jump_distance = ClassData[classindex][class_jump_distance]; + if (!(jump_distance >= ZR_CLASS_JUMP_DISTANCE_MIN && jump_distance <= ZR_CLASS_JUMP_DISTANCE_MAX)) + { + flags += ZR_CLASS_FLAG_JUMP_DISTANCE; } return flags; @@ -325,24 +345,31 @@ ClassGetActiveIndex(client) { new teamid = GetClientTeam(client); - if (teamid == CS_TEAM_SPECTATOR || teamid == CS_TEAM_NONE) + if (!ZRIsClientOnTeam(client)) { // No active team. return -1; } - if (IsPlayerHuman(client)) + // Check if the player currently is in admin mode. + if (ClassPlayerInAdminMode[client]) { - teamid = ZR_CLASS_TEAM_HUMANS; + teamid = ZR_CLASS_TEAM_ADMINS; } else { - teamid = ZR_CLASS_TEAM_ZOMBIES; + // Not in admin mode, check if player is human or zombie. + if (IsPlayerHuman(client)) + { + teamid = ZR_CLASS_TEAM_HUMANS; + } + else + { + teamid = ZR_CLASS_TEAM_ZOMBIES; + } } - // TODO: How to detect that virtual admin team? - - // Return the active class for the current team. + // Return the active class for the active team. return ClassSelected[client][teamid]; } diff --git a/src/zr/playerclasses/playerclasses.inc b/src/zr/playerclasses/playerclasses.inc index 6b4d4d2..e158af7 100644 --- a/src/zr/playerclasses/playerclasses.inc +++ b/src/zr/playerclasses/playerclasses.inc @@ -122,29 +122,68 @@ * @endsection */ +/** + * @section Attribute limit values. Used when validating. + */ +#define ZR_CLASS_NAME_MIN 1 +#define ZR_CLASS_DESCRIPTION_MIN 1 +/** Model path is checked for existance. */ +#define ZR_CLASS_ALPHA_INITIAL_MIN 0 +#define ZR_CLASS_ALPHA_INITIAL_MAX 255 +#define ZR_CLASS_ALPHA_DAMAGED_MIN 0 +#define ZR_CLASS_ALPHA_DAMAGED_MAX 255 +#define ZR_CLASS_ALPHA_DAMAGE_MIN 0 +#define ZR_CLASS_ALPHA_DAMAGE_MAX 16384 +/** Overlay path is optional, and file is checked for existance if specified. */ +#define ZR_CLASS_FOV_MIN 15 +#define ZR_CLASS_FOV_MAX 165 +#define ZR_CLASS_NAPALM_TIME_MIN 0.0 +#define ZR_CLASS_NAPALM_TIME_MAX 600.0 +#define ZR_CLASS_HEALTH_MIN 1 +#define ZR_CLASS_HEALTH_MAX 16384 +#define ZR_CLASS_HEALTH_REGEN_INTERVAL_MIN 0.0 +#define ZR_CLASS_HEALTH_REGEN_INTERVAL_MAX 900.0 +#define ZR_CLASS_HEALTH_REGEN_AMOUNT_MIN 0.0 +#define ZR_CLASS_HEALTH_REGEN_AMOUNT_MAX 16384 +#define ZR_CLASS_HEALTH_INFECT_GAIN_MIN 0 +#define ZR_CLASS_HEALTH_INFECT_GAIN_MAX 16384 +#define ZR_CLASS_KILL_BONUS_MIN 0 +#define ZR_CLASS_KILL_BONUS_MAX 16 +#define ZR_CLASS_SPEED_MIN 10.0 +#define ZR_CLASS_SPEED_MAX 2000.0 +#define ZR_CLASS_KNOCKBACK_MIN -10.0 +#define ZR_CLASS_KNOCKBACK_MAX 20.0 +#define ZR_CLASS_JUMP_HEIGHT_MIN 0.0 +#define ZR_CLASS_JUMP_HEIGHT_MAX 1024.0 +#define ZR_CLASS_JUMP_DISTANCE_MIN 0.0 +#define ZR_CLASS_JUMP_DISTANCE_MAX 1024.0 +/** + * @endsection + */ + /** * @section Error flags for invalid class attributes. */ -#define ZR_CLASS_ATTRIB_ERR_OK 0 -#define ZR_CLASS_ATTRIB_ERR_NAME 1 -#define ZR_CLASS_ATTRIB_ERR_DESCRIPTION 2 -#define ZR_CLASS_ATTRIB_ERR_MODEL_PATH 4 -#define ZR_CLASS_ATTRIB_ERR_ALPHA_INITIAL 8 -#define ZR_CLASS_ATTRIB_ERR_ALPHA_DAMAGED 16 -#define ZR_CLASS_ATTRIB_ERR_ALPHA_DAMAGE 32 -#define ZR_CLASS_ATTRIB_ERR_OVERLAY_PATH 64 -#define ZR_CLASS_ATTRIB_ERR_FOV 128 -#define ZR_CLASS_ATTRIB_ERR_NAPALM_TIME 256 -#define ZR_CLASS_ATTRIB_ERR_IMMUNITY_MODE 512 -#define ZR_CLASS_ATTRIB_ERR_IMMUNITY_AMOUNT 1024 -#define ZR_CLASS_ATTRIB_ERR_HEALTH_REGEN_INTERVAL 2048 -#define ZR_CLASS_ATTRIB_ERR_HEALTH_REGEN_AMOUNT 4096 -#define ZR_CLASS_ATTRIB_ERR_INFECT_GAIN 8192 -#define ZR_CLASS_ATTRIB_ERR_KILL_BONUS 16384 -#define ZR_CLASS_ATTRIB_ERR_SPEED 32768 -#define ZR_CLASS_ATTRIB_ERR_KNOCKBACK 65536 -#define ZR_CLASS_ATTRIB_ERR_JUMP_HEIGHT 131072 -#define ZR_CLASS_ATTRIB_ERR_JUMP_DISTANCE 262144 +#define ZR_CLASS_FLAG_NAME (1<<0) +#define ZR_CLASS_FLAG_DESCRIPTION (1<<1) +#define ZR_CLASS_FLAG_MODEL_PATH (1<<2) +#define ZR_CLASS_FLAG_ALPHA_INITIAL (1<<3) +#define ZR_CLASS_FLAG_ALPHA_DAMAGED (1<<4) +#define ZR_CLASS_FLAG_ALPHA_DAMAGE (1<<5) +#define ZR_CLASS_FLAG_OVERLAY_PATH (1<<6) +#define ZR_CLASS_FLAG_FOV (1<<7) +#define ZR_CLASS_FLAG_NAPALM_TIME (1<<8) +#define ZR_CLASS_FLAG_IMMUNITY_MODE (1<<9) +#define ZR_CLASS_FLAG_IMMUNITY_AMOUNT (1<<10) +#define ZR_CLASS_FLAG_HEALTH (1<<11) +#define ZR_CLASS_FLAG_HEALTH_REGEN_INTERVAL (1<<12) +#define ZR_CLASS_FLAG_HEALTH_REGEN_AMOUNT (1<<13) +#define ZR_CLASS_FLAG_INFECT_GAIN (1<<14) +#define ZR_CLASS_FLAG_KILL_BONUS (1<<15) +#define ZR_CLASS_FLAG_SPEED (1<<16) +#define ZR_CLASS_FLAG_KNOCKBACK (1<<17) +#define ZR_CLASS_FLAG_JUMP_HEIGHT (1<<18) +#define ZR_CLASS_FLAG_JUMP_DISTANCE (1<<19) /** * @endsection */ @@ -164,13 +203,13 @@ enum ClassAttributes String:class_description[256], /* Model */ - String:class_model_path[256], + String:class_model_path[PLATFORM_MAX_PATH], class_alpha_initial, class_alpha_damaged, class_alpha_damage, /* Hud */ - String:class_overlay_path[256], + String:class_overlay_path[PLATFORM_MAX_PATH], bool:class_nvgs, class_fov, @@ -235,6 +274,11 @@ new bool:ClassPlayerInAdminMode[MAXPLAYERS + 1]; */ new bool:ClassPlayerAdminMode[MAXPLAYERS + 1]; +/** + * Specifies the admin class to use on next admin mode spawn. + */ +new ClassPlayerNextAdminClass[MAXPLAYERS + 1]; + #include "zr/playerclasses/filtertools" #include "zr/playerclasses/attributes" #include "zr/playerclasses/apply" @@ -258,7 +302,7 @@ ClassLoad() } kvClassData = CreateKeyValues("classes"); - decl String:classfile[256]; + decl String:classfile[PLATFORM_MAX_PATH]; GetConVarString(g_hCvarsList[CVAR_CLASSES_FILE], classfile, sizeof(classfile)); // Try to load the class configuration file. @@ -279,8 +323,8 @@ ClassLoad() decl String:name[64]; decl String:description[256]; - decl String:model_path[256]; - decl String:overlay_path[256]; + decl String:model_path[PLATFORM_MAX_PATH]; + decl String:overlay_path[PLATFORM_MAX_PATH]; ClassCount = 0; new ClassErrorFlags; @@ -313,7 +357,7 @@ ClassLoad() /* Model */ KvGetString(kvClassData, "model_path", model_path, sizeof(model_path), ZR_CLASS_DEFAULT_MODEL_PATH); - strcopy(ClassData[ClassCount][class_model_path], 256, model_path); + strcopy(ClassData[ClassCount][class_model_path], PLATFORM_MAX_PATH, model_path); ClassData[ClassCount][class_alpha_initial] = KvGetNum(kvClassData, "alpha_initial", ZR_CLASS_DEFAULT_ALPHA_INITIAL); ClassData[ClassCount][class_alpha_damaged] = KvGetNum(kvClassData, "alpha_damaged", ZR_CLASS_DEFAULT_ALPHA_DAMAGED); @@ -322,7 +366,7 @@ ClassLoad() /* Hud */ KvGetString(kvClassData, "overlay_path", overlay_path, sizeof(overlay_path), ZR_CLASS_DEFAULT_OVERLAY_PATH); - strcopy(ClassData[ClassCount][class_overlay_path], 256, overlay_path); + strcopy(ClassData[ClassCount][class_overlay_path], PLATFORM_MAX_PATH, overlay_path); ClassData[ClassCount][class_nvgs] = bool:KvGetNum(kvClassData, "nvgs", ZR_CLASS_DEFAULT_NVGS); ClassData[ClassCount][class_fov] = KvGetNum(kvClassData, "fov", ZR_CLASS_DEFAULT_FOV); @@ -388,18 +432,13 @@ ClassLoad() */ bool:ClassReloadDataCache() { - /* - * TODO: This must be done in a safe way, because the plugin may read from - * the cache at any time. The plugin might read attributes at the - * same time when the cache is reloaded. There's a chance for - * corrupted attributes at that exact moment. - */ - + // Check if there are no classes. if (ClassCount == 0) { return false; } + // Loop through all classes. for (new classindex = 0; classindex < ClassCount; classindex++) { /* General */ @@ -410,13 +449,13 @@ bool:ClassReloadDataCache() strcopy(ClassDataCache[classindex][class_description], 256, ClassData[classindex][class_description]); /* Model */ - strcopy(ClassDataCache[classindex][class_model_path], 256, ClassData[classindex][class_model_path]); + strcopy(ClassDataCache[classindex][class_model_path], PLATFORM_MAX_PATH, ClassData[classindex][class_model_path]); ClassDataCache[classindex][class_alpha_initial] = ClassData[classindex][class_alpha_initial]; ClassDataCache[classindex][class_alpha_damaged] = ClassData[classindex][class_alpha_damaged]; ClassDataCache[classindex][class_alpha_damage] = ClassData[classindex][class_alpha_damage]; /* Hud */ - strcopy(ClassDataCache[classindex][class_overlay_path], 256, ClassData[classindex][class_overlay_path]); + strcopy(ClassDataCache[classindex][class_overlay_path], PLATFORM_MAX_PATH, ClassData[classindex][class_overlay_path]); ClassDataCache[classindex][class_nvgs] = ClassData[classindex][class_nvgs]; ClassDataCache[classindex][class_fov] = ClassData[classindex][class_fov]; @@ -473,13 +512,13 @@ bool:ClassReloadPlayerCache(client, classindex, cachetype = ZR_CLASS_CACHE_MODIF strcopy(ClassPlayerCache[client][class_description], 256, ClassData[classindex][class_description]); /* Model */ - strcopy(ClassPlayerCache[client][class_model_path], 256, ClassData[classindex][class_model_path]); + strcopy(ClassPlayerCache[client][class_model_path], PLATFORM_MAX_PATH, ClassData[classindex][class_model_path]); ClassPlayerCache[client][class_alpha_initial] = ClassData[classindex][class_alpha_initial]; ClassPlayerCache[client][class_alpha_damaged] = ClassData[classindex][class_alpha_damaged]; ClassPlayerCache[client][class_alpha_damage] = ClassData[classindex][class_alpha_damage]; /* Hud */ - strcopy(ClassPlayerCache[client][class_overlay_path], 256, ClassData[classindex][class_overlay_path]); + strcopy(ClassPlayerCache[client][class_overlay_path], PLATFORM_MAX_PATH, ClassData[classindex][class_overlay_path]); ClassPlayerCache[client][class_nvgs] = ClassData[classindex][class_nvgs]; ClassPlayerCache[client][class_fov] = ClassData[classindex][class_fov]; @@ -510,13 +549,13 @@ bool:ClassReloadPlayerCache(client, classindex, cachetype = ZR_CLASS_CACHE_MODIF strcopy(ClassPlayerCache[client][class_description], 256, ClassDataCache[classindex][class_description]); /* Model */ - strcopy(ClassPlayerCache[client][class_model_path], 256, ClassDataCache[classindex][class_model_path]); + strcopy(ClassPlayerCache[client][class_model_path], PLATFORM_MAX_PATH, ClassDataCache[classindex][class_model_path]); ClassPlayerCache[client][class_alpha_initial] = ClassDataCache[classindex][class_alpha_initial]; ClassPlayerCache[client][class_alpha_damaged] = ClassDataCache[classindex][class_alpha_damaged]; ClassPlayerCache[client][class_alpha_damage] = ClassDataCache[classindex][class_alpha_damage]; /* Hud */ - strcopy(ClassPlayerCache[client][class_overlay_path], 256, ClassDataCache[classindex][class_overlay_path]); + strcopy(ClassPlayerCache[client][class_overlay_path], PLATFORM_MAX_PATH, ClassDataCache[classindex][class_overlay_path]); ClassPlayerCache[client][class_nvgs] = ClassDataCache[classindex][class_nvgs]; ClassPlayerCache[client][class_fov] = ClassDataCache[classindex][class_fov]; @@ -567,7 +606,7 @@ ClassClientSetDefaultIndexes(client = -1) // log a warning. if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CLASSES)) { - LogMessageFormatted(-1, "Classes", "SetDefaultIndexes", "Warning: Failed to get default zombie class, falling back to default class. Check spelling in \"zr_classes_default_zombie\".", LOG_FORMAT_TYPE_ERROR); + LogMessageFormatted(-1, "Classes", "SetDefaultIndexes", "Warning: Failed to get default zombie class, falling back to default class in class config. Check spelling in \"zr_classes_default_zombie\".", LOG_FORMAT_TYPE_ERROR); } // Use default class. @@ -581,7 +620,7 @@ ClassClientSetDefaultIndexes(client = -1) // log a warning. if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CLASSES)) { - LogMessageFormatted(-1, "Classes", "SetDefaultIndexes", "Warning: Failed to get default human class, falling back to default class. Check spelling in \"zr_classes_default_human\".", LOG_FORMAT_TYPE_ERROR); + LogMessageFormatted(-1, "Classes", "SetDefaultIndexes", "Warning: Failed to get default human class, falling back to default class in class config. Check spelling in \"zr_classes_default_human\".", LOG_FORMAT_TYPE_ERROR); } // Use default class. @@ -591,28 +630,14 @@ ClassClientSetDefaultIndexes(client = -1) // Validate admin class index. if (!ClassValidateIndex(adminindex)) { - // Invalid class index. Fall back to default class in class config and - // log a warning. - if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CLASSES)) - { - LogMessageFormatted(-1, "Classes", "SetDefaultIndexes", "Warning: Failed to get default admin class, falling back to default class. Check spelling in \"zr_classes_default_admin\".", LOG_FORMAT_TYPE_ERROR); - } - - // Use default class. + // Invalid class index. Fall back to default class in class config if + // possible. A invalid class index (-1) can also be stored if there are + // no admin classes at all. adminindex = ClassGetDefaultClass(ZR_CLASS_TEAM_ADMINS); } - // Check if a client is specified. - if (client > 0) - { - ClassSelected[client][ZR_CLASS_TEAM_ZOMBIES] = zombieindex; - ClassSelected[client][ZR_CLASS_TEAM_HUMANS] = humanindex; - ClassSelected[client][ZR_CLASS_TEAM_ADMINS] = adminindex; - - // Copy human class data to player cache. - ClassReloadPlayerCache(client, humanindex); - } - else + // Check if a client isn't specified. + if (client < 1) { // No client specified. Loop through all players. for (new clientindex = 1; clientindex <= MAXPLAYERS; clientindex++) @@ -620,11 +645,22 @@ ClassClientSetDefaultIndexes(client = -1) ClassSelected[clientindex][ZR_CLASS_TEAM_ZOMBIES] = zombieindex; ClassSelected[clientindex][ZR_CLASS_TEAM_HUMANS] = humanindex; ClassSelected[clientindex][ZR_CLASS_TEAM_ADMINS] = adminindex; + ClassPlayerNextAdminClass[clientindex] = adminindex; // Copy human class data to player cache. ClassReloadPlayerCache(client, humanindex); } } + else + { + ClassSelected[client][ZR_CLASS_TEAM_ZOMBIES] = zombieindex; + ClassSelected[client][ZR_CLASS_TEAM_HUMANS] = humanindex; + ClassSelected[client][ZR_CLASS_TEAM_ADMINS] = adminindex; + ClassPlayerNextAdminClass[client] = adminindex; + + // Copy human class data to player cache. + ClassReloadPlayerCache(client, humanindex); + } } /** diff --git a/src/zr/zadmin.inc b/src/zr/zadmin.inc index 8e9396e..01bd30b 100644 --- a/src/zr/zadmin.inc +++ b/src/zr/zadmin.inc @@ -7,7 +7,7 @@ */ #include "include/adminmenu.inc" -new curMenuClass[MAXPLAYERS + 1]; +//new curMenuClass[MAXPLAYERS + 1]; bool:ZRAdminMenu(client) { diff --git a/src/zr/zombie.inc b/src/zr/zombie.inc index ec892db..e40870c 100644 --- a/src/zr/zombie.inc +++ b/src/zr/zombie.inc @@ -27,19 +27,14 @@ public Action:Command_NightVision(client, argc) return; } - if (!IsPlayerZombie(client)) - { - return; - } - bClientOverlayOn[client] = !bClientOverlayOn[client]; - decl String:overlay[256]; + decl String:overlay[PLATFORM_MAX_PATH]; ClassGetOverlayPath(client, overlay, sizeof(overlay)); if (strlen(overlay) > 0) { - if (bClientOverlayOn[client]) + if (ClassOverlayIsOn(client)) { ClassOverlayInitialize(client, overlay); } @@ -84,7 +79,7 @@ JumpBoost(client, Float:distance, Float:height) vel[0] *= distance; vel[1] *= distance; - vel[2] *= height; + vel[2] += height; SetPlayerVelocity(client, vel, false); }