/* * ============================================================================ * * Zombie:Reloaded * * File: classevents.inc * Type: Core * Description: Functions for handling class related events. * * ============================================================================ */ /* ------------------------------------ * * GAME EVENTS * * ------------------------------------ */ /** * Create class-related cookies here. */ ClassOnCookiesCreate() { // Forward event to sub-modules. ClassOverlayOnCookiesCreate(); // Create cookie handles only if they don't exist. if (g_hClassCookieClassSelected[ZR_CLASS_TEAM_HUMANS] == INVALID_HANDLE) { g_hClassCookieClassSelected[ZR_CLASS_TEAM_HUMANS] = RegClientCookie("zr_humanclass", "The last human class selected.", CookieAccess_Protected); } if (g_hClassCookieClassSelected[ZR_CLASS_TEAM_ZOMBIES] == INVALID_HANDLE) { g_hClassCookieClassSelected[ZR_CLASS_TEAM_ZOMBIES] = RegClientCookie("zr_zombieclass", "The last zombie class selected.", CookieAccess_Protected); } if (g_hClassCookieClassSelected[ZR_CLASS_TEAM_ADMINS] == INVALID_HANDLE) { g_hClassCookieClassSelected[ZR_CLASS_TEAM_ADMINS] = RegClientCookie("zr_adminclass", "The last admin mode class selected.", CookieAccess_Protected); } } /** * Called when all modules are done loading. */ ClassOnModulesLoaded() { // Set default classes on all player slots. ClassClientSetDefaultIndexes(); } /** * Called when map is loading, before configs are loaded. Used for * initializing class module. */ ClassOnMapStart() { // Clear multipliers. ClassResetMultiplierCache(); } /** * Called when a client connects to the server (OnClientPutInServer). */ ClassClientInit(client) { // Check if there are valid classes and the client is valid. // To prevent bots or SourceTV causing errors. If classes are invalid this // event was executed before classes were loaded. if (ClassValidated && ZRIsClientValid(client)) { // Set default class indexes on the player. ClassClientSetDefaultIndexes(client); // Forward event to sub-modules. ClassOverlayClientInit(client); } } /** * Called a client disconnects. */ ClassOnClientDisconnect(client) { // Disable class attributes with timers. ClassHealthRegenStop(client); // Reset previously selected class indexes. ClassResetNextIndexes(client); } /** * Client is spawning into the game. * * @param client The client index. */ ClassOnClientSpawn(client) { decl String:originalmodel[PLATFORM_MAX_PATH]; decl String:steamid[16]; decl String:classname[64]; new filter[ClassFilter]; // Check if the player is dead. Spawning into the game is also a event in // the connection process. if (!IsPlayerAlive(client)) { return; } // Check if there are no valid classes. Block this event if classes aren't // done loading. if (!ClassValidated) { return; } // Reset attributes by triggering death event. ClassOnClientDeath(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); // Check if the player should spawn in admin mode. if (ClassPlayerInAdminMode[client]) { // Mark player as in admin mode. ClassPlayerInAdminMode[client] = true; // 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; // 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")) { // Setup filtering // --------------- // Exclude special class flags like mother zombies and admin classes. filter[ClassFilter_DenyFlags] = ZR_CLASS_SPECIALFLAGS; // Allow admin classes if admin. filter[ClassFilter_DenyFlags] -= ZRIsClientAdmin(client) ? ZR_CLASS_FLAG_ADMIN_ONLY : 0; // Specify client for checking group permissions. filter[ClassFilter_Client] = client; // Get classes // ----------- // Get random classes for each type. new randomzombie = ClassGetRandomClass(ZR_CLASS_TEAM_ZOMBIES, filter); new randomhuman = ClassGetRandomClass(ZR_CLASS_TEAM_HUMANS, filter); // 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); } // 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; } } /** * Client died. Stops timers and reset certain attributes. Call this event to * clean up class related stuff. * * @param client The client index. */ ClassOnClientDeath(client) { // Disable class attributes with timers. ClassHealthRegenStop(client); // Set client's FOV back to normal. ToolsSetClientDefaultFOV(client, 90); // Forward event to sub-modules. ClassOverlayOnClientDeath(client); } /** * Client got infected. Reloads class attributes. * * @param client The client index. */ ClassOnClientInfected(client, bool:motherzombie = false) { new classindex = ClassGetActiveIndex(client); new isadmin; new motherindex; new filter[ClassFilter]; decl String:motherzombiesetting[64]; // 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) { // Set admin flag if client is admin, so it's removed in special class // flags. isadmin = ZRIsClientAdmin(client) ? ZR_CLASS_FLAG_ADMIN_ONLY : 0; // Get default mother zombie setting. GetConVarString(g_hCvarsList[CVAR_CLASSES_DEFAULT_M_ZOMB], motherzombiesetting, sizeof(motherzombiesetting)); if (StrEqual(motherzombiesetting, "disabled", false)) { // Do nothing. Keep current class. } else if (StrEqual(motherzombiesetting, "random", false)) { // Setup filtering // --------------- // Exclude special class flags. filter[ClassFilter_DenyFlags] = ZR_CLASS_SPECIALFLAGS; // Allow admin classes if admin. filter[ClassFilter_DenyFlags] -= isadmin; // Specify client for checking group permissions. filter[ClassFilter_Client] = client; // Get class // --------- // Get random regular zombie class. Remove admin flag if admin. motherindex = ClassGetRandomClass(ZR_CLASS_TEAM_ZOMBIES, filter); // 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; } } else if (StrEqual(motherzombiesetting, "motherzombies", false)) { // Setup filtering // --------------- // Exclude special class flags except mother zombies. filter[ClassFilter_DenyFlags] = ZR_CLASS_SPECIALFLAGS - ZR_CLASS_FLAG_MOTHER_ZOMBIE; // Require mother zombie class flag. filter[ClassFilter_RequireFlags] = ZR_CLASS_FLAG_MOTHER_ZOMBIE; // Allow admin classes if admin. filter[ClassFilter_DenyFlags] -= isadmin; // Specify client for checking group permissions. filter[ClassFilter_Client] = client; // Get class // --------- // Get random mother zombie class. Include admin classes if admin. motherindex = ClassGetRandomClass(ZR_CLASS_TEAM_ZOMBIES, filter); // 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. motherzombie = false; // Save active class index to be restored next spawn. ClassSelectedNext[client][ZR_CLASS_TEAM_ZOMBIES] = classindex; // Change class. classindex = motherindex; } } else { // Assume it's a class name. Get index for the specified class name. motherindex = ClassGetIndex(motherzombiesetting); // 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 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. 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; }