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.
This commit is contained in:
richard 2009-07-23 23:26:14 +02:00
parent 9077a6ba69
commit 6a6300e21b
5 changed files with 252 additions and 129 deletions

View File

@ -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}"

View File

@ -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.

View File

@ -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;
}
}

View File

@ -295,7 +295,6 @@ stock bool:ClassValidateIndex(classindex)
}
}
/**
* Compares the class team ID with a team ID.
*

View File

@ -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);