2009-04-11 01:56:22 +02:00
|
|
|
/*
|
|
|
|
* ============================================================================
|
|
|
|
*
|
2009-07-05 08:49:23 +02:00
|
|
|
* Zombie:Reloaded
|
2009-04-11 01:56:22 +02:00
|
|
|
*
|
2009-06-12 05:51:26 +02:00
|
|
|
* File: classevents.inc
|
|
|
|
* Type: Core
|
|
|
|
* Description: Functions for handling class related events.
|
2009-04-11 01:56:22 +02:00
|
|
|
*
|
|
|
|
* ============================================================================
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* ------------------------------------
|
|
|
|
*
|
|
|
|
* GAME EVENTS
|
|
|
|
*
|
|
|
|
* ------------------------------------
|
|
|
|
*/
|
|
|
|
|
2009-06-21 21:24:24 +02:00
|
|
|
/**
|
|
|
|
* Create class-related cookies here.
|
|
|
|
*/
|
|
|
|
ClassOnCookiesCreate()
|
|
|
|
{
|
|
|
|
// Forward event to sub-modules.
|
|
|
|
ClassOverlayOnCookiesCreate();
|
2009-08-15 06:32:44 +02:00
|
|
|
|
2009-10-10 18:26:27 +02:00
|
|
|
// Create cookie handles only if they don't exist.
|
|
|
|
if (g_hClassCookieClassSelected[ZR_CLASS_TEAM_HUMANS] == INVALID_HANDLE)
|
2009-10-08 19:47:23 +02:00
|
|
|
{
|
2009-10-10 18:26:27 +02:00
|
|
|
g_hClassCookieClassSelected[ZR_CLASS_TEAM_HUMANS] = RegClientCookie("zr_humanclass", "The last human class selected.", CookieAccess_Protected);
|
2009-10-08 19:47:23 +02:00
|
|
|
}
|
2009-10-10 18:26:27 +02:00
|
|
|
if (g_hClassCookieClassSelected[ZR_CLASS_TEAM_ZOMBIES] == INVALID_HANDLE)
|
2009-10-08 19:47:23 +02:00
|
|
|
{
|
2009-10-10 18:26:27 +02:00
|
|
|
g_hClassCookieClassSelected[ZR_CLASS_TEAM_ZOMBIES] = RegClientCookie("zr_zombieclass", "The last zombie class selected.", CookieAccess_Protected);
|
2009-10-08 19:47:23 +02:00
|
|
|
}
|
2009-10-10 18:26:27 +02:00
|
|
|
if (g_hClassCookieClassSelected[ZR_CLASS_TEAM_ADMINS] == INVALID_HANDLE)
|
2009-10-08 19:47:23 +02:00
|
|
|
{
|
2009-10-10 18:26:27 +02:00
|
|
|
g_hClassCookieClassSelected[ZR_CLASS_TEAM_ADMINS] = RegClientCookie("zr_adminclass", "The last admin mode class selected.", CookieAccess_Protected);
|
2009-10-08 19:47:23 +02:00
|
|
|
}
|
2009-06-21 21:24:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Called when all modules are done loading.
|
|
|
|
*/
|
|
|
|
ClassOnModulesLoaded()
|
|
|
|
{
|
|
|
|
// Set default classes on all player slots.
|
|
|
|
ClassClientSetDefaultIndexes();
|
|
|
|
}
|
|
|
|
|
2009-11-11 22:50:19 +01:00
|
|
|
/**
|
|
|
|
* Called when map is loading, before configs are loaded. Used for
|
|
|
|
* initializing class module.
|
|
|
|
*/
|
|
|
|
ClassOnMapStart()
|
|
|
|
{
|
|
|
|
// Clear multipliers.
|
|
|
|
ClassResetMultiplierCache();
|
2009-12-03 01:22:20 +01:00
|
|
|
|
|
|
|
// Prepare hp regeneration module.
|
|
|
|
ClassHealthRegenInit();
|
2009-11-11 22:50:19 +01:00
|
|
|
}
|
|
|
|
|
2009-04-11 01:56:22 +02:00
|
|
|
/**
|
2009-06-18 03:33:09 +02:00
|
|
|
* Called when a client connects to the server (OnClientPutInServer).
|
2009-04-11 01:56:22 +02:00
|
|
|
*/
|
|
|
|
ClassClientInit(client)
|
|
|
|
{
|
2009-05-10 18:49:47 +02:00
|
|
|
// Check if there are valid classes and the client is valid.
|
2009-06-18 02:09:55 +02:00
|
|
|
// To prevent bots or SourceTV causing errors. If classes are invalid this
|
|
|
|
// event was executed before classes were loaded.
|
2009-05-10 18:49:47 +02:00
|
|
|
if (ClassValidated && ZRIsClientValid(client))
|
2009-04-11 01:56:22 +02:00
|
|
|
{
|
|
|
|
// Set default class indexes on the player.
|
|
|
|
ClassClientSetDefaultIndexes(client);
|
2009-10-10 17:37:30 +02:00
|
|
|
|
|
|
|
// Forward event to sub-modules.
|
|
|
|
ClassOverlayClientInit(client);
|
2009-04-11 01:56:22 +02:00
|
|
|
}
|
2009-11-20 18:20:45 +01:00
|
|
|
|
|
|
|
// Reset spawn flag.
|
|
|
|
ClassPlayerSpawned[client] = false;
|
2009-05-14 02:28:26 +02:00
|
|
|
}
|
|
|
|
|
2009-06-18 03:33:09 +02:00
|
|
|
/**
|
|
|
|
* Called a client disconnects.
|
|
|
|
*/
|
2009-04-11 01:56:22 +02:00
|
|
|
ClassOnClientDisconnect(client)
|
|
|
|
{
|
2009-05-10 18:49:47 +02:00
|
|
|
// Disable class attributes with timers.
|
|
|
|
ClassHealthRegenStop(client);
|
2009-07-22 14:06:18 +02:00
|
|
|
|
|
|
|
// Reset previously selected class indexes.
|
2009-07-23 23:26:14 +02:00
|
|
|
ClassResetNextIndexes(client);
|
2009-04-11 01:56:22 +02:00
|
|
|
}
|
|
|
|
|
2009-05-14 02:28:26 +02:00
|
|
|
/**
|
|
|
|
* Client is spawning into the game.
|
|
|
|
*
|
|
|
|
* @param client The client index.
|
|
|
|
*/
|
2009-04-11 01:56:22 +02:00
|
|
|
ClassOnClientSpawn(client)
|
|
|
|
{
|
2009-06-22 17:01:26 +02:00
|
|
|
decl String:originalmodel[PLATFORM_MAX_PATH];
|
|
|
|
decl String:steamid[16];
|
|
|
|
decl String:classname[64];
|
2009-08-14 22:10:52 +02:00
|
|
|
new filter[ClassFilter];
|
2009-06-22 17:01:26 +02:00
|
|
|
|
2009-07-23 23:26:14 +02:00
|
|
|
// Check if the player is dead. Spawning into the game is also a event in
|
|
|
|
// the connection process.
|
2009-04-29 02:50:25 +02:00
|
|
|
if (!IsPlayerAlive(client))
|
|
|
|
{
|
2009-05-10 18:49:47 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-07-22 14:06:18 +02:00
|
|
|
// Check if there are no valid classes. Block this event if classes aren't
|
2009-05-10 18:49:47 +02:00
|
|
|
// done loading.
|
|
|
|
if (!ClassValidated)
|
|
|
|
{
|
2009-04-29 02:50:25 +02:00
|
|
|
return;
|
|
|
|
}
|
2009-04-22 04:53:19 +02:00
|
|
|
|
2009-06-18 02:09:55 +02:00
|
|
|
// Reset attributes by triggering death event.
|
|
|
|
ClassOnClientDeath(client);
|
|
|
|
|
2009-07-23 23:26:14 +02:00
|
|
|
// Restore class indexes to be selected on spawn, if available.
|
|
|
|
ClassRestoreNextIndexes(client);
|
2009-07-22 14:06:18 +02:00
|
|
|
|
2009-06-22 17:01:26 +02:00
|
|
|
// Cache original player model.
|
|
|
|
GetClientModel(client, originalmodel, sizeof(originalmodel));
|
|
|
|
strcopy(ClassOriginalPlayerModel[client], PLATFORM_MAX_PATH, originalmodel);
|
|
|
|
|
2009-04-29 02:50:25 +02:00
|
|
|
// Check if the player should spawn in admin mode.
|
2009-07-23 23:26:14 +02:00
|
|
|
if (ClassPlayerInAdminMode[client])
|
2009-04-11 01:56:22 +02:00
|
|
|
{
|
2009-04-29 02:50:25 +02:00
|
|
|
// Mark player as in admin mode.
|
|
|
|
ClassPlayerInAdminMode[client] = true;
|
2009-04-14 23:16:31 +02:00
|
|
|
|
2009-07-23 23:26:14 +02:00
|
|
|
// TODO: This is the place to initialize admin mode stuff like no-block
|
|
|
|
// and other stuff.
|
2009-04-29 02:50:25 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Mark player as not in admin mode.
|
|
|
|
ClassPlayerInAdminMode[client] = false;
|
2009-04-11 01:56:22 +02:00
|
|
|
|
2009-07-23 23:26:14 +02:00
|
|
|
// 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"))
|
|
|
|
{
|
2009-08-14 22:10:52 +02:00
|
|
|
// Setup filtering
|
|
|
|
// ---------------
|
2009-07-23 23:26:14 +02:00
|
|
|
|
2009-08-14 22:10:52 +02:00
|
|
|
// Exclude special class flags like mother zombies and admin classes.
|
|
|
|
filter[ClassFilter_DenyFlags] = ZR_CLASS_SPECIALFLAGS;
|
|
|
|
|
2009-07-23 23:26:14 +02:00
|
|
|
// Allow admin classes if admin.
|
2009-08-14 22:10:52 +02:00
|
|
|
filter[ClassFilter_DenyFlags] -= ZRIsClientAdmin(client) ? ZR_CLASS_FLAG_ADMIN_ONLY : 0;
|
|
|
|
|
|
|
|
// Specify client for checking group permissions.
|
|
|
|
filter[ClassFilter_Client] = client;
|
|
|
|
|
|
|
|
// Get classes
|
|
|
|
// -----------
|
2009-07-23 23:26:14 +02:00
|
|
|
|
|
|
|
// Get random classes for each type.
|
2009-08-14 22:10:52 +02:00
|
|
|
new randomzombie = ClassGetRandomClass(ZR_CLASS_TEAM_ZOMBIES, filter);
|
|
|
|
new randomhuman = ClassGetRandomClass(ZR_CLASS_TEAM_HUMANS, filter);
|
2009-07-23 23:26:14 +02:00
|
|
|
|
|
|
|
// 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);
|
|
|
|
}
|
2009-08-10 19:01:43 +02:00
|
|
|
|
2009-11-20 18:20:45 +01:00
|
|
|
// Display class menu if either menu cvar is set.
|
|
|
|
new bool:menuspawn = GetConVarBool(g_hCvarsList[CVAR_CLASSES_MENU_SPAWN]);
|
|
|
|
new bool:menujoin = GetConVarBool(g_hCvarsList[CVAR_CLASSES_MENU_JOIN]);
|
|
|
|
if (menuspawn || (menujoin && !ClassPlayerSpawned[client]))
|
2009-08-10 19:01:43 +02:00
|
|
|
{
|
2009-11-20 18:20:45 +01:00
|
|
|
ClassPlayerSpawned[client] = true;
|
2009-08-10 19:01:43 +02:00
|
|
|
ClassMenuMain(client);
|
|
|
|
}
|
2009-04-11 01:56:22 +02:00
|
|
|
}
|
2009-07-23 23:26:14 +02:00
|
|
|
|
|
|
|
// Apply class attributes for the active class.
|
|
|
|
ClassReloadPlayerCache(client, ClassGetActiveIndex(client));
|
|
|
|
ClassApplyAttributes(client);
|
2009-08-10 19:01:43 +02:00
|
|
|
|
|
|
|
// 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;
|
|
|
|
}
|
2009-04-11 01:56:22 +02:00
|
|
|
}
|
|
|
|
|
2009-06-18 03:33:09 +02:00
|
|
|
/**
|
|
|
|
* Client died. Stops timers and reset certain attributes. Call this event to
|
|
|
|
* clean up class related stuff.
|
|
|
|
*
|
|
|
|
* @param client The client index.
|
|
|
|
*/
|
2009-04-11 01:56:22 +02:00
|
|
|
ClassOnClientDeath(client)
|
|
|
|
{
|
2009-05-10 18:49:47 +02:00
|
|
|
// Disable class attributes with timers.
|
2009-04-11 01:56:22 +02:00
|
|
|
ClassHealthRegenStop(client);
|
2009-05-14 02:28:26 +02:00
|
|
|
|
2009-04-29 02:50:25 +02:00
|
|
|
// Set client's FOV back to normal.
|
|
|
|
ToolsSetClientDefaultFOV(client, 90);
|
2009-05-21 07:13:51 +02:00
|
|
|
|
|
|
|
// Forward event to sub-modules.
|
|
|
|
ClassOverlayOnClientDeath(client);
|
2009-04-11 01:56:22 +02:00
|
|
|
}
|
|
|
|
|
2009-06-18 03:33:09 +02:00
|
|
|
/**
|
|
|
|
* Client got infected. Reloads class attributes.
|
|
|
|
*
|
|
|
|
* @param client The client index.
|
|
|
|
*/
|
2009-04-11 01:56:22 +02:00
|
|
|
ClassOnClientInfected(client, bool:motherzombie = false)
|
|
|
|
{
|
|
|
|
new classindex = ClassGetActiveIndex(client);
|
2009-06-22 01:09:51 +02:00
|
|
|
new isadmin;
|
|
|
|
new motherindex;
|
2009-08-14 22:10:52 +02:00
|
|
|
new filter[ClassFilter];
|
2009-06-22 01:09:51 +02:00
|
|
|
|
|
|
|
decl String:motherzombiesetting[64];
|
2009-04-11 01:56:22 +02:00
|
|
|
|
2009-05-10 18:49:47 +02:00
|
|
|
// Disable class attributes with timers.
|
|
|
|
ClassHealthRegenStop(client);
|
|
|
|
|
2009-08-10 19:01:43 +02:00
|
|
|
// Make sure the player is not allowed to instantly change class.
|
|
|
|
ClassAllowInstantChange[client] = false;
|
|
|
|
|
2009-06-22 01:09:51 +02:00
|
|
|
// Check if it's a mother zombie.
|
|
|
|
if (motherzombie)
|
|
|
|
{
|
2009-06-22 16:29:13 +02:00
|
|
|
// Set admin flag if client is admin, so it's removed in special class
|
|
|
|
// flags.
|
|
|
|
isadmin = ZRIsClientAdmin(client) ? ZR_CLASS_FLAG_ADMIN_ONLY : 0;
|
2009-06-22 01:09:51 +02:00
|
|
|
|
|
|
|
// 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))
|
|
|
|
{
|
2009-08-14 22:10:52 +02:00
|
|
|
// 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
|
|
|
|
// ---------
|
|
|
|
|
2009-06-22 01:09:51 +02:00
|
|
|
// Get random regular zombie class. Remove admin flag if admin.
|
2009-08-14 22:10:52 +02:00
|
|
|
motherindex = ClassGetRandomClass(ZR_CLASS_TEAM_ZOMBIES, filter);
|
2009-07-08 02:16:29 +02:00
|
|
|
|
|
|
|
// Validate index. Do not change class if it's invalid.
|
|
|
|
if (ClassValidateIndex(motherindex))
|
2009-07-23 23:26:14 +02:00
|
|
|
{
|
|
|
|
// Save active class index to be restored next spawn.
|
|
|
|
ClassSelectedNext[client][ZR_CLASS_TEAM_ZOMBIES] = classindex;
|
|
|
|
|
2009-07-08 02:16:29 +02:00
|
|
|
// Change class.
|
|
|
|
classindex = motherindex;
|
|
|
|
}
|
2009-06-22 01:09:51 +02:00
|
|
|
}
|
|
|
|
else if (StrEqual(motherzombiesetting, "motherzombies", false))
|
|
|
|
{
|
2009-08-14 22:10:52 +02:00
|
|
|
// 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
|
|
|
|
// ---------
|
|
|
|
|
2009-07-08 02:16:29 +02:00
|
|
|
// Get random mother zombie class. Include admin classes if admin.
|
2009-08-14 22:10:52 +02:00
|
|
|
motherindex = ClassGetRandomClass(ZR_CLASS_TEAM_ZOMBIES, filter);
|
2009-07-08 02:16:29 +02:00
|
|
|
|
|
|
|
// Validate index. Do not change class if it's invalid.
|
|
|
|
if (ClassValidateIndex(motherindex))
|
|
|
|
{
|
2009-07-23 23:26:14 +02:00
|
|
|
// This is a mother zombie class. Reset mother zombie setting
|
|
|
|
// so class skills aren't improved.
|
2009-07-08 02:16:29 +02:00
|
|
|
motherzombie = false;
|
|
|
|
|
2009-07-23 23:26:14 +02:00
|
|
|
// Save active class index to be restored next spawn.
|
|
|
|
ClassSelectedNext[client][ZR_CLASS_TEAM_ZOMBIES] = classindex;
|
2009-07-22 14:06:18 +02:00
|
|
|
|
2009-07-08 02:16:29 +02:00
|
|
|
// Change class.
|
|
|
|
classindex = motherindex;
|
|
|
|
}
|
2009-06-22 01:09:51 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Assume it's a class name. Get index for the specified class name.
|
|
|
|
motherindex = ClassGetIndex(motherzombiesetting);
|
|
|
|
|
|
|
|
// Validate index.
|
|
|
|
if (ClassValidateIndex(motherindex))
|
|
|
|
{
|
2009-07-23 23:26:14 +02:00
|
|
|
// Save active class index to be restored next spawn.
|
|
|
|
ClassSelectedNext[client][ZR_CLASS_TEAM_ZOMBIES] = classindex;
|
|
|
|
|
2009-06-22 01:09:51 +02:00
|
|
|
// Change class.
|
|
|
|
classindex = motherindex;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-07-23 23:26:14 +02:00
|
|
|
// 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.
|
2009-04-11 01:56:22 +02:00
|
|
|
ClassReloadPlayerCache(client, classindex);
|
|
|
|
|
|
|
|
// Apply the new attributes.
|
|
|
|
ClassApplyAttributes(client, motherzombie);
|
|
|
|
}
|
2009-08-10 19:01:43 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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;
|
|
|
|
}
|