diff --git a/cstrike/cfg/sourcemod/zombiereloaded/zombiereloaded.cfg b/cstrike/cfg/sourcemod/zombiereloaded/zombiereloaded.cfg index c36b0bf..f7e103f 100644 --- a/cstrike/cfg/sourcemod/zombiereloaded/zombiereloaded.cfg +++ b/cstrike/cfg/sourcemod/zombiereloaded/zombiereloaded.cfg @@ -143,10 +143,14 @@ zr_config_path_hitgroups "configs/zr/hitgroups.txt" // Default: "0" zr_classes_spawn "0" -// Player is assigned a random class every spawn. [Override: zr_classes_spawn & zr_classes_default_*] +// Player is assigned a random class every spawn. [Override: zr_classes_default_*] // Default: "0" zr_classes_random "0" +// Time limit to change class with instant change after spawning. Time is in seconds. Use 0 or negative to disable. +// Default: "20" +zr_classes_change_timelimit "20" + // Admin class assigned to admins on connect. ["random" = Random admin class | "" = Class config default] // Default: "random" zr_classes_default_admin "random" diff --git a/src/zr/cvars.inc b/src/zr/cvars.inc index 6925732..c3f012c 100644 --- a/src/zr/cvars.inc +++ b/src/zr/cvars.inc @@ -54,6 +54,7 @@ enum CvarsList Handle:CVAR_CONFIG_PATH_HITGROUPS, Handle:CVAR_CLASSES_SPAWN, Handle:CVAR_CLASSES_RANDOM, + Handle:CVAR_CLASSES_CHANGE_TIMELIMIT, Handle:CVAR_CLASSES_DEFAULT_ZOMBIE, Handle:CVAR_CLASSES_DEFAULT_M_ZOMB, Handle:CVAR_CLASSES_DEFAULT_HUMAN, @@ -240,7 +241,8 @@ CvarsCreate() // General g_hCvarsList[CVAR_CLASSES_SPAWN] = CreateConVar("zr_classes_spawn", "0", "Re-display class selection menu every spawn."); - g_hCvarsList[CVAR_CLASSES_RANDOM] = CreateConVar("zr_classes_random", "0", "Player is assigned a random class every spawn. [Override: zr_classes_spawn and zr_classes_default_*]"); + g_hCvarsList[CVAR_CLASSES_RANDOM] = CreateConVar("zr_classes_random", "0", "Player is assigned a random class every spawn. [Override: zr_classes_default_*]"); + g_hCvarsList[CVAR_CLASSES_CHANGE_TIMELIMIT] = CreateConVar("zr_classes_change_timelimit", "20", "Time limit to change class with instant change after spawning. Time is in seconds. Use 0 or negative to disable."); g_hCvarsList[CVAR_CLASSES_DEFAULT_ZOMBIE] = CreateConVar("zr_classes_default_zombie", "random", "Zombie class assigned to players on connect. [\"random\" = Random zombie class | \"\" = Class config default]"); g_hCvarsList[CVAR_CLASSES_DEFAULT_M_ZOMB] = CreateConVar("zr_classes_default_mother_zombie", "motherzombies","Zombie class assigned to mother zombies. [\"motherzombies\" = Random mother zombie class | \"random\" = Random regular zombie class | \"disabled\" = Don't change class on mother zombies]"); g_hCvarsList[CVAR_CLASSES_DEFAULT_HUMAN] = CreateConVar("zr_classes_default_human", "random", "Human class assigned to players on connect. [\"random\" = Random human class | \"\" = Class config default]"); diff --git a/src/zr/playerclasses/classevents.inc b/src/zr/playerclasses/classevents.inc index b217081..3ae4ebc 100644 --- a/src/zr/playerclasses/classevents.inc +++ b/src/zr/playerclasses/classevents.inc @@ -141,11 +141,34 @@ ClassOnClientSpawn(client) ClassGetName(randomhuman, classname, sizeof(classname), ZR_CLASS_TEAM_HUMANS); TranslationPrintToChat(client, "Classes random assignment", classname); } + + // Display class menu if enabled. + new bool:classmenu = GetConVarBool(g_hCvarsList[CVAR_CLASSES_SPAWN]); + if (classmenu) + { + ClassMenuMain(client); + } } // Apply class attributes for the active class. ClassReloadPlayerCache(client, ClassGetActiveIndex(client)); ClassApplyAttributes(client); + + // Check if instant class change cvar is set. + new Float:instantspawn = GetConVarFloat(g_hCvarsList[CVAR_CLASSES_CHANGE_TIMELIMIT]); + if (instantspawn > 0) + { + // Allow instant class change. + ClassAllowInstantChange[client] = true; + + // Create timer to disable instant change. + CreateTimer(instantspawn, Event_ClassDisableInstantSpawn, client, TIMER_FLAG_NO_MAPCHANGE); + } + else + { + // Make sure instant change is not allowed. + ClassAllowInstantChange[client] = false; + } } /** @@ -182,6 +205,9 @@ ClassOnClientInfected(client, bool:motherzombie = false) // Disable class attributes with timers. ClassHealthRegenStop(client); + // Make sure the player is not allowed to instantly change class. + ClassAllowInstantChange[client] = false; + // Check if it's a mother zombie. if (motherzombie) { @@ -259,3 +285,12 @@ ClassOnClientInfected(client, bool:motherzombie = false) // Apply the new attributes. ClassApplyAttributes(client, motherzombie); } + +/** + * Timer callback for disabling instant class change setting on a client. + */ +public Action:Event_ClassDisableInstantSpawn(Handle:timer, any:client) +{ + // Disable instant class change. + ClassAllowInstantChange[client] = false; +} diff --git a/src/zr/playerclasses/classmenus.inc b/src/zr/playerclasses/classmenus.inc index e3f6bc2..88602bb 100644 --- a/src/zr/playerclasses/classmenus.inc +++ b/src/zr/playerclasses/classmenus.inc @@ -332,28 +332,41 @@ public ClassMenuSelectHandle(Handle:menu, MenuAction:action, client, slot) // Solve teamid from the class index. teamid = ClassGetTeamID(classindex, ZR_CLASS_CACHE_MODIFIED); - // Check if the player is alive. - if (IsPlayerAlive(client)) + // Allow instant class change if enabled and both class and player is human. + if (ClassAllowInstantChange[client] && !iszombie && teamid == ZR_CLASS_TEAM_HUMANS) { - // Set next spawn index if the player is changing the class on - // his active team. - if ((iszombie && teamid == ZR_CLASS_TEAM_ZOMBIES) || - (!iszombie && teamid == ZR_CLASS_TEAM_HUMANS) || - (ClassPlayerInAdminMode[client] && teamid == ZR_CLASS_TEAM_ADMINS)) - { - // Set class to be used on next spawn. - ClassSelectedNext[client][teamid] = classindex; - } - else - { - // Directly change the selected class index. - ClassSelected[client][teamid] = classindex; - } + // Directly change the selected class index. + ClassSelected[client][teamid] = classindex; + + // Update cache and apply attributes. + ClassReloadPlayerCache(client, classindex); + ClassApplyAttributes(client); } else { - // Player isn't alive. The class can be directly changed. - ClassSelected[client][teamid] = classindex; + // Check if the player is alive. + if (IsPlayerAlive(client)) + { + // Set next spawn index if the player is changing the class on + // his active team. + if ((iszombie && teamid == ZR_CLASS_TEAM_ZOMBIES) || + (!iszombie && teamid == ZR_CLASS_TEAM_HUMANS) || + (ClassPlayerInAdminMode[client] && teamid == ZR_CLASS_TEAM_ADMINS)) + { + // Set class to be used on next spawn. + ClassSelectedNext[client][teamid] = classindex; + } + else + { + // Directly change the selected class index. + ClassSelected[client][teamid] = classindex; + } + } + else + { + // Player isn't alive. The class can be directly changed. + ClassSelected[client][teamid] = classindex; + } } } case MenuAction_Cancel: diff --git a/src/zr/playerclasses/playerclasses.inc b/src/zr/playerclasses/playerclasses.inc index 0de2ee4..05ddf75 100644 --- a/src/zr/playerclasses/playerclasses.inc +++ b/src/zr/playerclasses/playerclasses.inc @@ -362,9 +362,13 @@ new ClassMultipliers:ClassAdminAttributeSelected[MAXPLAYERS + 1]; new bool:ClassPlayerInAdminMode[MAXPLAYERS + 1]; /** - * Specifies the admin class to use on next admin mode spawn. + * Specifies whether a player is allowed to change class with instant effect. + * This is only used on human classes, and in combination with the + * zr_classes_change_timelimit time limit, but could be used other places too. + * The class menu will automatically check this setting and apply attributes if + * set to true. */ -//new ClassPlayerNextAdminClass[MAXPLAYERS + 1]; +new bool:ClassAllowInstantChange[MAXPLAYERS + 1]; /** * Cache for storing original model path before applying custom models. Used