From 0019a52ca895dcaf175bb11113c78a9de305902a Mon Sep 17 00:00:00 2001 From: richard Date: Wed, 22 Jul 2009 14:06:18 +0200 Subject: [PATCH 1/2] Fixed selected class not restored after being mother zombie. --- src/zr/antistick.inc | 36 +++++------ src/zr/playerclasses/classevents.inc | 13 +++- src/zr/playerclasses/playerclasses.inc | 84 +++++++++++++++++++++++++- 3 files changed, 111 insertions(+), 22 deletions(-) diff --git a/src/zr/antistick.inc b/src/zr/antistick.inc index 4b8a516..2427424 100644 --- a/src/zr/antistick.inc +++ b/src/zr/antistick.inc @@ -31,24 +31,24 @@ #define ANTISTICK_COLLISIONS_OFF 2 #define ANTISTICK_COLLISIONS_ON 5 -#define COLLISION_GROUP_NONE 0 /** Default; collides with static and dynamic objects. */ -#define COLLISION_GROUP_DEBRIS 1 /** Collides with nothing but world and static stuff. */ -#define COLLISION_GROUP_DEBRIS_TRIGGER 2 /** Same as debris, but hits triggers. */ -#define COLLISION_GROUP_INTERACTIVE_DEBRIS 3 /** Collides with everything except other interactive debris or debris. */ -#define COLLISION_GROUP_INTERACTIVE 4 /** Collides with everything except interactive debris or debris. */ -#define COLLISION_GROUP_PLAYER 5 /** This is the default behavior expected for most prop_physics. */ -#define COLLISION_GROUP_BREAKABLE_GLASS 6 /** Special group for glass debris. */ -#define COLLISION_GROUP_VEHICLE 7 /** Collision group for driveable vehicles. */ -#define COLLISION_GROUP_PLAYER_MOVEMENT 8 /** For HL2, same as Collision_Group_Player. */ -#define COLLISION_GROUP_NPC 9 /** Generic NPC group. */ -#define COLLISION_GROUP_IN_VEHICLE 10 /** For any entity inside a vehicle. */ -#define COLLISION_GROUP_WEAPON 11 /** For any weapons that need collision detection. */ -#define COLLISION_GROUP_VEHICLE_CLIP 12 /** Vehicle clip brush to restrict vehicle movement. */ -#define COLLISION_GROUP_PROJECTILE 13 /** Projectiles. */ -#define COLLISION_GROUP_DOOR_BLOCKER 14 /** Blocks entities not permitted to get near moving doors. */ -#define COLLISION_GROUP_PASSABLE_DOOR 15 /** Doors that the player shouldn't collide with. */ -#define COLLISION_GROUP_DISSOLVING 16 /** Things that are dissolving are in this group. */ -#define COLLISION_GROUP_PUSHAWAY 17 /** Nonsolid on client and server, pushaway in player code. */ +#define COLLISION_GROUP_NONE 0 /** Default; collides with static and dynamic objects. */ +#define COLLISION_GROUP_DEBRIS 1 /** Collides with nothing but world and static stuff. */ +#define COLLISION_GROUP_DEBRIS_TRIGGER 2 /** Same as debris, but hits triggers. */ +#define COLLISION_GROUP_INTERACTIVE_DEBRIS 3 /** Collides with everything except other interactive debris or debris. */ +#define COLLISION_GROUP_INTERACTIVE 4 /** Collides with everything except interactive debris or debris. */ +#define COLLISION_GROUP_PLAYER 5 /** This is the default behavior expected for most prop_physics. */ +#define COLLISION_GROUP_BREAKABLE_GLASS 6 /** Special group for glass debris. */ +#define COLLISION_GROUP_VEHICLE 7 /** Collision group for driveable vehicles. */ +#define COLLISION_GROUP_PLAYER_MOVEMENT 8 /** For HL2, same as Collision_Group_Player. */ +#define COLLISION_GROUP_NPC 9 /** Generic NPC group. */ +#define COLLISION_GROUP_IN_VEHICLE 10 /** For any entity inside a vehicle. */ +#define COLLISION_GROUP_WEAPON 11 /** For any weapons that need collision detection. */ +#define COLLISION_GROUP_VEHICLE_CLIP 12 /** Vehicle clip brush to restrict vehicle movement. */ +#define COLLISION_GROUP_PROJECTILE 13 /** Projectiles. */ +#define COLLISION_GROUP_DOOR_BLOCKER 14 /** Blocks entities not permitted to get near moving doors. */ +#define COLLISION_GROUP_PASSABLE_DOOR 15 /** Doors that the player shouldn't collide with. */ +#define COLLISION_GROUP_DISSOLVING 16 /** Things that are dissolving are in this group. */ +#define COLLISION_GROUP_PUSHAWAY 17 /** Nonsolid on client and server, pushaway in player code. */ #define COLLISION_GROUP_NPC_ACTOR 18 /** Used so NPCs in scripts ignore the player. */ /** * @endsection diff --git a/src/zr/playerclasses/classevents.inc b/src/zr/playerclasses/classevents.inc index 9dcbada..42cc7fd 100644 --- a/src/zr/playerclasses/classevents.inc +++ b/src/zr/playerclasses/classevents.inc @@ -60,6 +60,9 @@ ClassOnClientDisconnect(client) { // Disable class attributes with timers. ClassHealthRegenStop(client); + + // Reset previously selected class indexes. + ClassResetPreviousIndexes(client); } /** @@ -73,13 +76,13 @@ ClassOnClientSpawn(client) decl String:steamid[16]; decl String:classname[64]; - // Check if the player is alive. + // Check if the player is dead. if (!IsPlayerAlive(client)) { return; } - // Check if there are valid classes. Block this event if classes aren't + // Check if there are no valid classes. Block this event if classes aren't // done loading. if (!ClassValidated) { @@ -89,6 +92,9 @@ ClassOnClientSpawn(client) // Reset attributes by triggering death event. ClassOnClientDeath(client); + // Restore previously selected classes if available. + ClassRestoreIndexes(client); + // Cache original player model. GetClientModel(client, originalmodel, sizeof(originalmodel)); strcopy(ClassOriginalPlayerModel[client], PLATFORM_MAX_PATH, originalmodel); @@ -219,6 +225,9 @@ ClassOnClientInfected(client, bool:motherzombie = false) // class skills aren't improved. motherzombie = false; + // Save class index to be restored next time. + ClassPrevious[client][ZR_CLASS_TEAM_ZOMBIES] = classindex; + // Change class. classindex = motherindex; } diff --git a/src/zr/playerclasses/playerclasses.inc b/src/zr/playerclasses/playerclasses.inc index 92be853..bda832f 100644 --- a/src/zr/playerclasses/playerclasses.inc +++ b/src/zr/playerclasses/playerclasses.inc @@ -337,10 +337,21 @@ new ClassCount; new bool:ClassValidated; /** - * Stores what class that the player have selected, for each team. + * Stores what class the player has selected, for each team. */ new ClassSelected[MAXPLAYERS + 1][ZR_CLASS_TEAMCOUNT]; +/** + * Stores what class the player had selected last time, if available. Classes + * specified here will be restored on the player when he dies. In normal cases + * it should be -1 for all teams on all players. + * + * Usage example of this one is to restore the player's zombie class after + * being a mother zombie with a mother zombie class. But this feature can also + * be useful in the future. + */ +new ClassPrevious[MAXPLAYERS + 1][ZR_CLASS_TEAMCOUNT]; + /** * Cache for the currently selected team (admin menus). */ @@ -527,6 +538,9 @@ ClassLoad(bool:keepMultipliers = false) // Cache class data. ClassReloadDataCache(); + // Reset previously selected class indexes. + ClassResetPreviousIndexes(); + // Reset attribute multipliers, if not keeping. if (!keepMultipliers) { @@ -542,7 +556,6 @@ ClassLoad(bool:keepMultipliers = false) // Set config data. ConfigSetConfigLoaded(File_Classes, true); ConfigSetConfigReloadFunc(File_Classes, GetFunctionByName(GetMyHandle(), "ClassOnConfigReload")); - // ConfigSetConfigHandle(File_Classes, INVALID_HANDLE); ConfigSetConfigPath(File_Classes, pathclasses); // Remove key/value cache. @@ -774,6 +787,73 @@ ClassResetMultiplierCache() } } +/** + * Resets the previously selected class indexes on one or all clients. + * + * @param client Optional. Specify client to reset. Default is all. + */ +ClassResetPreviousIndexes(client = -1) +{ + new teamid; + + if (client > 0) + { + for (teamid = 0; teamid < ZR_CLASS_TEAMCOUNT; teamid++) + { + ClassPrevious[client][teamid] = -1; + } + } + else + { + for (client = 1; client <= MAXPLAYERS; client++) + { + for (teamid = 0; teamid < ZR_CLASS_TEAMCOUNT; teamid++) + { + ClassPrevious[client][teamid] = -1; + } + } + } +} + +/** + * Restores previously selected class indexes on a player, if available. + * Note: Does not apply attributes. The classes are only marked as selected. + * + * @param client The client index. + */ +ClassRestoreIndexes(client) +{ + new previouszombie = ClassPrevious[client][ZR_CLASS_TEAM_ZOMBIES]; + new previoushuman = ClassPrevious[client][ZR_CLASS_TEAM_HUMANS]; + new previousadmin = ClassPrevious[client][ZR_CLASS_TEAM_ADMINS]; + + // Validate zombie class index. + if (ClassValidateIndex(previouszombie)) + { + // Mark previous zombie class as selected. + ClassSelected[client][ZR_CLASS_TEAM_ZOMBIES] = previouszombie; + } + + // Validate human class index. + if (ClassValidateIndex(previoushuman)) + { + // Mark previous zombie class as selected. + ClassSelected[client][ZR_CLASS_TEAM_HUMANS] = previoushuman; + } + + // Validate admin class index. + if (ClassValidateIndex(previousadmin)) + { + // Mark previous zombie class as selected. + ClassSelected[client][ZR_CLASS_TEAM_ADMINS] = previousadmin; + } + + // Reset indexes. + ClassPrevious[client][ZR_CLASS_TEAM_ZOMBIES] = -1; + ClassPrevious[client][ZR_CLASS_TEAM_HUMANS] = -1; + ClassPrevious[client][ZR_CLASS_TEAM_ADMINS] = -1; +} + /** * Sets default class indexes for each team on all players, or a single player * if specified. From 6a6300e21bb270f12b94d5dc67ad4faba1b47c9e Mon Sep 17 00:00:00 2001 From: richard Date: Thu, 23 Jul 2009 23:26:14 +0200 Subject: [PATCH 2/2] Fixes in class system. See details. Fixed class menus not displaying correct class. Made ClassSelectedNext array for storing class indexes to be set on next spawn. Useful for other stuff too, like saving settings in cookies. Code cleanup in class spawn and class infect events. --- .../translations/zombiereloaded.phrases.txt | 74 ++++++++---- src/zr/playerclasses/classevents.inc | 107 ++++++++++-------- src/zr/playerclasses/classmenus.inc | 102 ++++++++++++++--- src/zr/playerclasses/filtertools.inc | 1 - src/zr/playerclasses/playerclasses.inc | 97 ++++++++-------- 5 files changed, 252 insertions(+), 129 deletions(-) diff --git a/cstrike/addons/sourcemod/translations/zombiereloaded.phrases.txt b/cstrike/addons/sourcemod/translations/zombiereloaded.phrases.txt index b748f6a..0313d53 100644 --- a/cstrike/addons/sourcemod/translations/zombiereloaded.phrases.txt +++ b/cstrike/addons/sourcemod/translations/zombiereloaded.phrases.txt @@ -230,39 +230,75 @@ "Classes menu zombie" { - "en" "Select Zombie Class" + "en" "Select Zombie Class:" + } + + "Classes menu zombie current" + { + "#format" "{1:s}" + "en" "Select Zombie Class\n {1}" + } + + "Classes menu zombie next" + { + "#format" "{1:s},{2:s}" + "en" "Select Zombie Class\n Active: {1}\n Next spawn: {2}" } "Classes menu human" { - "en" "Select Human Class" + "en" "Select Human Class:" + } + + "Classes menu human current" + { + "#format" "{1:s}" + "en" "Select Human Class\n {1}" + } + + "Classes menu human next" + { + "#format" "{1:s},{2:s}" + "en" "Select Human Class\n Active: {1}\n Next spawn: {2}" } "Classes menu admin" { - "en" "Select Admin Class" + "en" "Select Admin Mode Class:" + } + + "Classes menu admin current" + { + "#format" "{1:s}" + "en" "Select Admin Mode Class\n {1}" + } + + "Classes menu admin next" + { + "#format" "{1:s},{2:s}" + "en" "Select Admin Mode Class\n Active: {1}\n Next spawn: {2}" } "Classes menu admin mode toggle" { "en" "Toggle Admin Mode" } - + "Classes Menu Team Select Title" { "en" "Select Team:" } - + "Classes Menu Zombies" { "en" "Zombies" } - + "Classes Menu Humans" { "en" "Humans" } - + "Classes Menu Multiplier Select Title" { "en" "Select Multiplier:" @@ -272,49 +308,49 @@ { "en" "Adjust Value:" } - + // Attributes - + "Classes Attrib Napalm Time" { "en" "Napalm Time" } - + "Classes Attrib Health" { "en" "Health" } - + "Classes Attrib Regen Interval" { "en" "Health Regeneration Interval" } - + "Classes Attrib Regen Amount" { "en" "Health Regeneration Amount" } - + "Classes Attrib Infect Gain" { "en" "Infection Health Gain" } - + "Classes Attrib Speed" { "en" "Running Speed" } - + "Classes Attrib Knockback" { "en" "Knock back" } - + "Classes Attrib Jump Height" { "en" "Jump Height" } - + "Classes Attrib Jump Distance" { "en" "Jump Distance" @@ -1100,13 +1136,13 @@ { "en" "This area is restricted, please move along." } - + "Vol Slay" { "#format" "{1:s},{2:d}" "en" "Slayed player \"{1}\" for camping in a restricted area (ID: {2})." } - + "Vol Ignite" { "#format" "{1:s},{2:d}" diff --git a/src/zr/playerclasses/classevents.inc b/src/zr/playerclasses/classevents.inc index 42cc7fd..b217081 100644 --- a/src/zr/playerclasses/classevents.inc +++ b/src/zr/playerclasses/classevents.inc @@ -62,7 +62,7 @@ ClassOnClientDisconnect(client) ClassHealthRegenStop(client); // Reset previously selected class indexes. - ClassResetPreviousIndexes(client); + ClassResetNextIndexes(client); } /** @@ -76,7 +76,8 @@ ClassOnClientSpawn(client) decl String:steamid[16]; decl String:classname[64]; - // Check if the player is dead. + // Check if the player is dead. Spawning into the game is also a event in + // the connection process. if (!IsPlayerAlive(client)) { return; @@ -92,65 +93,59 @@ ClassOnClientSpawn(client) // Reset attributes by triggering death event. ClassOnClientDeath(client); - // Restore previously selected classes if available. - ClassRestoreIndexes(client); + // Restore class indexes to be selected on spawn, if available. + ClassRestoreNextIndexes(client); // Cache original player model. GetClientModel(client, originalmodel, sizeof(originalmodel)); strcopy(ClassOriginalPlayerModel[client], PLATFORM_MAX_PATH, originalmodel); - // Exclude special class flags like mother zombies and admin classes. - new denyflags = ZR_CLASS_SPECIALFLAGS; - - // Allow admin classes if admin. - denyflags -= ZRIsClientAdmin(client) ? ZR_CLASS_FLAG_ADMIN_ONLY : 0; - - // Get random class setting. - new bool:randomclass = GetConVarBool(g_hCvarsList[CVAR_CLASSES_RANDOM]); - - // Assign random classes if enabled. Always do it for bots. - GetClientAuthString(client, steamid, sizeof(steamid)); - if (randomclass || StrEqual(steamid, "BOT")) - { - // Get random classes for each type. - new randomzombie = ClassGetRandomClass(ZR_CLASS_TEAM_ZOMBIES, _, _, denyflags); - new randomhuman = ClassGetRandomClass(ZR_CLASS_TEAM_HUMANS, _, _, denyflags); - - // Save selected zombie class index. - ClassSelected[client][ZR_CLASS_TEAM_ZOMBIES] = randomzombie; - ClassGetName(randomzombie, classname, sizeof(classname), ZR_CLASS_TEAM_ZOMBIES); - TranslationPrintToChat(client, "Classes random assignment", classname); - - // Save selected human class index. - ClassSelected[client][ZR_CLASS_TEAM_HUMANS] = randomhuman; - ClassGetName(randomhuman, classname, sizeof(classname), ZR_CLASS_TEAM_HUMANS); - TranslationPrintToChat(client, "Classes random assignment", classname); - - // Update player cache with the human class data, and apply it. - ClassReloadPlayerCache(client, randomhuman); - ClassApplyAttributes(client); - } - // Check if the player should spawn in admin mode. - if (ClassPlayerAdminMode[client]) + if (ClassPlayerInAdminMode[client]) { // Mark player as in admin mode. ClassPlayerInAdminMode[client] = true; - // Update player cache with the admin class and apply attributes. - new adminindex = ClassPlayerNextAdminClass[client]; - ClassReloadPlayerCache(client, adminindex); - ClassApplyAttributes(client); + // TODO: This is the place to initialize admin mode stuff like no-block + // and other stuff. } else { // Mark player as not in admin mode. ClassPlayerInAdminMode[client] = false; - // Apply class attributes for the currently active class. - ClassReloadPlayerCache(client, ClassGetActiveIndex(client)); - ClassApplyAttributes(client); + // Get random class setting and steam id. + new bool:randomclass = GetConVarBool(g_hCvarsList[CVAR_CLASSES_RANDOM]); + GetClientAuthString(client, steamid, sizeof(steamid)); + + // Assign random classes if enabled. Always do it for bots. + if (randomclass || StrEqual(steamid, "BOT")) + { + // Exclude special class flags like mother zombies and admin classes. + new denyflags = ZR_CLASS_SPECIALFLAGS; + + // Allow admin classes if admin. + denyflags -= ZRIsClientAdmin(client) ? ZR_CLASS_FLAG_ADMIN_ONLY : 0; + + // Get random classes for each type. + new randomzombie = ClassGetRandomClass(ZR_CLASS_TEAM_ZOMBIES, _, _, denyflags); + new randomhuman = ClassGetRandomClass(ZR_CLASS_TEAM_HUMANS, _, _, denyflags); + + // Set selected zombie class index. + ClassSelected[client][ZR_CLASS_TEAM_ZOMBIES] = randomzombie; + ClassGetName(randomzombie, classname, sizeof(classname), ZR_CLASS_TEAM_ZOMBIES); + TranslationPrintToChat(client, "Classes random assignment", classname); + + // Set selected human class index. + ClassSelected[client][ZR_CLASS_TEAM_HUMANS] = randomhuman; + ClassGetName(randomhuman, classname, sizeof(classname), ZR_CLASS_TEAM_HUMANS); + TranslationPrintToChat(client, "Classes random assignment", classname); + } } + + // Apply class attributes for the active class. + ClassReloadPlayerCache(client, ClassGetActiveIndex(client)); + ClassApplyAttributes(client); } /** @@ -208,7 +203,10 @@ ClassOnClientInfected(client, bool:motherzombie = false) // Validate index. Do not change class if it's invalid. if (ClassValidateIndex(motherindex)) - { + { + // Save active class index to be restored next spawn. + ClassSelectedNext[client][ZR_CLASS_TEAM_ZOMBIES] = classindex; + // Change class. classindex = motherindex; } @@ -221,12 +219,12 @@ ClassOnClientInfected(client, bool:motherzombie = false) // Validate index. Do not change class if it's invalid. if (ClassValidateIndex(motherindex)) { - // This is a mother zombie class. Reset mother zombie setting so - // class skills aren't improved. + // This is a mother zombie class. Reset mother zombie setting + // so class skills aren't improved. motherzombie = false; - // Save class index to be restored next time. - ClassPrevious[client][ZR_CLASS_TEAM_ZOMBIES] = classindex; + // Save active class index to be restored next spawn. + ClassSelectedNext[client][ZR_CLASS_TEAM_ZOMBIES] = classindex; // Change class. classindex = motherindex; @@ -240,13 +238,22 @@ ClassOnClientInfected(client, bool:motherzombie = false) // Validate index. if (ClassValidateIndex(motherindex)) { + // Save active class index to be restored next spawn. + ClassSelectedNext[client][ZR_CLASS_TEAM_ZOMBIES] = classindex; + // Change class. classindex = motherindex; } } } - // Update the players cache with zombie attributes. + // Update the player's selected class index. + ClassSelected[client][ZR_CLASS_TEAM_ZOMBIES] = classindex; + + // Restore next indexes, if available. But don't restore the zombie index. + ClassRestoreNextIndexes(client, ZR_CLASS_TEAM_ZOMBIES); + + // Update the player's cache with zombie attributes. ClassReloadPlayerCache(client, classindex); // Apply the new attributes. diff --git a/src/zr/playerclasses/classmenus.inc b/src/zr/playerclasses/classmenus.inc index d2283e5..6df326f 100644 --- a/src/zr/playerclasses/classmenus.inc +++ b/src/zr/playerclasses/classmenus.inc @@ -45,9 +45,13 @@ ClassMenuMain(client) SetGlobalTransTarget(client); SetMenuTitle(menu, "%t\n", "Classes menu title"); - decl String:zombieclass[128]; - decl String:humanclass[128]; - decl String:adminclass[128]; + decl String:zombieclass[64]; + decl String:humanclass[64]; + decl String:adminclass[64]; + + decl String:nextzombiename[64]; + decl String:nexthumanname[64]; + decl String:nextadminname[64]; decl String:zombieselect[128]; decl String:humanselect[128]; @@ -62,7 +66,13 @@ ClassMenuMain(client) new humancount = ClassCountTeam(ZR_CLASS_TEAM_ZOMBIES); new admincount = ClassCountTeam(ZR_CLASS_TEAM_ZOMBIES); + // Get previously selected class indexes, if set. + new nextzombie = ClassSelectedNext[client][ZR_CLASS_TEAM_ZOMBIES]; + new nexthuman = ClassSelectedNext[client][ZR_CLASS_TEAM_HUMANS]; + new nextadmin = ClassSelectedNext[client][ZR_CLASS_TEAM_ADMINS]; + // Set draw style on class options depending on number of enabled classes. + // Disable class selection if there's only one class. new zombie_itemdraw = (zombiecount > 1) ? ITEMDRAW_DEFAULT : ITEMDRAW_DISABLED; new human_itemdraw = (humancount > 1) ? ITEMDRAW_DEFAULT : ITEMDRAW_DISABLED; new admin_itemdraw = (admincount > 1) ? ITEMDRAW_DEFAULT : ITEMDRAW_DISABLED; @@ -76,25 +86,78 @@ ClassMenuMain(client) } // List zombie class options. + // -------------------------- + + // Get current class name. ClassGetName(ClassSelected[client][ZR_CLASS_TEAM_ZOMBIES], zombieclass, sizeof(zombieclass), ZR_CLASS_CACHE_MODIFIED); - Format(zombieselect, sizeof(zombieselect), "%t\n %s", "Classes menu zombie", zombieclass); + + // Check if previous index is set. + if (ClassValidateIndex(nextzombie)) + { + // Get name of previous class index and format item text. + ClassGetName(nextzombie, nextzombiename, sizeof(nextzombiename), ZR_CLASS_CACHE_MODIFIED); + Format(zombieselect, sizeof(zombieselect), "%t", "Classes menu zombie next", zombieclass, nextzombiename); + } + else + { + // Use current class name and format item text. + Format(zombieselect, sizeof(zombieselect), "%t", "Classes menu zombie current", zombieclass); + } + + // Add item to list. AddMenuItem(menu, "", zombieselect, zombie_itemdraw); + // List human class options. + // ------------------------- + + // Get current class name. ClassGetName(ClassSelected[client][ZR_CLASS_TEAM_HUMANS], humanclass, sizeof(humanclass), ZR_CLASS_CACHE_MODIFIED); - Format(humanselect, sizeof(humanselect), "%t\n %s", "Classes menu human", humanclass); + + // Check if previous index is set. + if (ClassValidateIndex(nexthuman)) + { + // Get name of previous class index and format item text. + ClassGetName(nexthuman, nexthumanname, sizeof(nexthumanname), ZR_CLASS_CACHE_MODIFIED); + Format(humanselect, sizeof(humanselect), "%t", "Classes menu human next", humanclass, nexthumanname); + } + else + { + // Use current class name and format item text. + Format(humanselect, sizeof(humanselect), "%t", "Classes menu human current", humanclass); + } + + // Add item to list. AddMenuItem(menu, "", humanselect, human_itemdraw); + + // List admin class options, if they exist. + // ---------------------------------------- + // Only display admin class options for admins, and if admin classes exist. if (ZRIsClientAdmin(client) && ClassCountTeam(ZR_CLASS_TEAM_ADMINS)) { - // List admin class options. + // Get current class name. ClassGetName(ClassSelected[client][ZR_CLASS_TEAM_ADMINS], adminclass, sizeof(adminclass), ZR_CLASS_CACHE_MODIFIED); - Format(adminselect, sizeof(adminselect), "%t\n %s", "Classes menu admin", adminclass); + + // Check if previous index is set. + if (ClassValidateIndex(nextadmin)) + { + // Get name of previous class index and format item text. + ClassGetName(nextadmin, nextadminname, sizeof(nextadminname), ZR_CLASS_CACHE_MODIFIED); + Format(adminselect, sizeof(adminselect), "%t", "Classes menu admin next", adminclass, nextadminname); + } + else + { + // Use current class name and format item text. + Format(adminselect, sizeof(adminselect), "%t", "Classes menu admin current", adminclass); + } + + // Add item to list. AddMenuItem(menu, "", adminselect, admin_itemdraw); // Set admin mode status string. - if (ClassPlayerAdminMode[client]) + if (ClassPlayerInAdminMode[client]) { Format(adminmode, sizeof(adminmode), "%t", "On"); } @@ -247,6 +310,7 @@ public ClassMenuSelectHandle(Handle:menu, MenuAction:action, client, slot) new classindex; new teamid; new bool:autoclose = GetConVarBool(g_hCvarsList[CVAR_CLASSES_MENU_AUTOCLOSE]); + new bool:iszombie = InfectIsClientInfected(client); switch (action) { @@ -261,15 +325,27 @@ public ClassMenuSelectHandle(Handle:menu, MenuAction:action, client, slot) // Solve teamid from the class index. teamid = ClassGetTeamID(classindex, ZR_CLASS_CACHE_MODIFIED); - // Check if the class is a admin class. - if (teamid == ZR_CLASS_TEAM_ADMINS) + // Check if the player is alive. + if (IsPlayerAlive(client)) { - // Set the admin class to be used on next admin spawn. - ClassPlayerNextAdminClass[client] = classindex; + // 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 { - // Set the players active class to the specified class. + // Player isn't alive. The class can be directly changed. ClassSelected[client][teamid] = classindex; } } diff --git a/src/zr/playerclasses/filtertools.inc b/src/zr/playerclasses/filtertools.inc index 61aa25e..e74c0b6 100644 --- a/src/zr/playerclasses/filtertools.inc +++ b/src/zr/playerclasses/filtertools.inc @@ -295,7 +295,6 @@ stock bool:ClassValidateIndex(classindex) } } - /** * Compares the class team ID with a team ID. * diff --git a/src/zr/playerclasses/playerclasses.inc b/src/zr/playerclasses/playerclasses.inc index bda832f..a2d8c5c 100644 --- a/src/zr/playerclasses/playerclasses.inc +++ b/src/zr/playerclasses/playerclasses.inc @@ -342,15 +342,9 @@ new bool:ClassValidated; new ClassSelected[MAXPLAYERS + 1][ZR_CLASS_TEAMCOUNT]; /** - * Stores what class the player had selected last time, if available. Classes - * specified here will be restored on the player when he dies. In normal cases - * it should be -1 for all teams on all players. - * - * Usage example of this one is to restore the player's zombie class after - * being a mother zombie with a mother zombie class. But this feature can also - * be useful in the future. + * Stores what class to be restored on next spawn, if available. */ -new ClassPrevious[MAXPLAYERS + 1][ZR_CLASS_TEAMCOUNT]; +new ClassSelectedNext[MAXPLAYERS + 1][ZR_CLASS_TEAMCOUNT]; /** * Cache for the currently selected team (admin menus). @@ -367,15 +361,10 @@ new ClassMultipliers:ClassAdminAttributeSelected[MAXPLAYERS + 1]; */ new bool:ClassPlayerInAdminMode[MAXPLAYERS + 1]; -/** - * Specifies whether a player is set to be in admin mode next spawn. - */ -new bool:ClassPlayerAdminMode[MAXPLAYERS + 1]; - /** * Specifies the admin class to use on next admin mode spawn. */ -new ClassPlayerNextAdminClass[MAXPLAYERS + 1]; +//new ClassPlayerNextAdminClass[MAXPLAYERS + 1]; /** * Cache for storing original model path before applying custom models. Used @@ -538,8 +527,8 @@ ClassLoad(bool:keepMultipliers = false) // Cache class data. ClassReloadDataCache(); - // Reset previously selected class indexes. - ClassResetPreviousIndexes(); + // Reset selected class indexes for next spawn. + ClassResetNextIndexes(); // Reset attribute multipliers, if not keeping. if (!keepMultipliers) @@ -760,7 +749,7 @@ bool:ClassReloadPlayer(client) } // Refresh cache and re-apply attributes. - ClassOnClientDeath(client); // Dummy event to clean up stuff. + ClassOnClientDeath(client); // Dummy event to clean up and turn off stuff. ClassReloadPlayerCache(client, activeclass); ClassApplyAttributes(client); @@ -788,11 +777,11 @@ ClassResetMultiplierCache() } /** - * Resets the previously selected class indexes on one or all clients. + * Resets the selected class indexes for next span on one or all clients. * * @param client Optional. Specify client to reset. Default is all. */ -ClassResetPreviousIndexes(client = -1) +ClassResetNextIndexes(client = -1) { new teamid; @@ -800,7 +789,7 @@ ClassResetPreviousIndexes(client = -1) { for (teamid = 0; teamid < ZR_CLASS_TEAMCOUNT; teamid++) { - ClassPrevious[client][teamid] = -1; + ClassSelectedNext[client][teamid] = -1; } } else @@ -809,49 +798,67 @@ ClassResetPreviousIndexes(client = -1) { for (teamid = 0; teamid < ZR_CLASS_TEAMCOUNT; teamid++) { - ClassPrevious[client][teamid] = -1; + ClassSelectedNext[client][teamid] = -1; } } } } /** - * Restores previously selected class indexes on a player, if available. + * Restores next class indexes on a player, if available. * Note: Does not apply attributes. The classes are only marked as selected. * - * @param client The client index. + * @param client The client index. + * @param excludeTeam Do not restore the specified team. */ -ClassRestoreIndexes(client) +ClassRestoreNextIndexes(client, excludeTeam = -1) { - new previouszombie = ClassPrevious[client][ZR_CLASS_TEAM_ZOMBIES]; - new previoushuman = ClassPrevious[client][ZR_CLASS_TEAM_HUMANS]; - new previousadmin = ClassPrevious[client][ZR_CLASS_TEAM_ADMINS]; + // Get next class indexes. + new zombie = ClassSelectedNext[client][ZR_CLASS_TEAM_ZOMBIES]; + new human = ClassSelectedNext[client][ZR_CLASS_TEAM_HUMANS]; + new admin = ClassSelectedNext[client][ZR_CLASS_TEAM_ADMINS]; - // Validate zombie class index. - if (ClassValidateIndex(previouszombie)) + // Check if the zombie team should be excluded. + if (excludeTeam != ZR_CLASS_TEAM_ZOMBIES) { - // Mark previous zombie class as selected. - ClassSelected[client][ZR_CLASS_TEAM_ZOMBIES] = previouszombie; + // Validate zombie class index. + if (ClassValidateIndex(zombie)) + { + // Mark next zombie class as selected. + ClassSelected[client][ZR_CLASS_TEAM_ZOMBIES] = zombie; + } + + // Reset index. + ClassSelectedNext[client][ZR_CLASS_TEAM_ZOMBIES] = -1; } - // Validate human class index. - if (ClassValidateIndex(previoushuman)) + // Check if the human team should be excluded. + if (excludeTeam != ZR_CLASS_TEAM_HUMANS) { - // Mark previous zombie class as selected. - ClassSelected[client][ZR_CLASS_TEAM_HUMANS] = previoushuman; + // Validate human class index. + if (ClassValidateIndex(human)) + { + // Mark next zombie class as selected. + ClassSelected[client][ZR_CLASS_TEAM_HUMANS] = human; + } + + // Reset index. + ClassSelectedNext[client][ZR_CLASS_TEAM_HUMANS] = -1; } - // Validate admin class index. - if (ClassValidateIndex(previousadmin)) + // Check if the human team should be excluded. + if (excludeTeam != ZR_CLASS_TEAM_ADMINS) { - // Mark previous zombie class as selected. - ClassSelected[client][ZR_CLASS_TEAM_ADMINS] = previousadmin; + // Validate admin class index. + if (ClassValidateIndex(admin)) + { + // Mark next zombie class as selected. + ClassSelected[client][ZR_CLASS_TEAM_ADMINS] = admin; + } + + // Reset index. + ClassSelectedNext[client][ZR_CLASS_TEAM_ADMINS] = -1; } - - // Reset indexes. - ClassPrevious[client][ZR_CLASS_TEAM_ZOMBIES] = -1; - ClassPrevious[client][ZR_CLASS_TEAM_HUMANS] = -1; - ClassPrevious[client][ZR_CLASS_TEAM_ADMINS] = -1; } /** @@ -907,7 +914,6 @@ 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); @@ -918,7 +924,6 @@ ClassClientSetDefaultIndexes(client = -1) 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);