Implemented human classes and fixed class related bugs.

Moved class initial event forward into OnConfigsExecuted.
Changed class attributes in default configuration file, and made new example human classes: speedy and light.
Implemented feature for applying human and admin classes. Admin mode is still not implemented.
Extended model path class attribute to support "default" for using default CS models.
Fixed event forward order in OnPlayerSpawn event. The class module depends on infection module.
Fixed class menu crash when there are no admin classes. Admin class and mode options are removed from the menu if there are no classes.
Fixed class menu not closing when selecting 0 (exit) if auto-close CVAR is disabled.
New global variable to separate current admin class and the admin class to be used on next spawn: ClassPlayerNextAdminClass.
Moved hard coded valitation values into defines.
Removed log warning if there are no admin classes. They are optional.
Fixed jump boost adding to height and not multiplying (which were 0 on the player velocity).
This commit is contained in:
richard 2009-04-25 14:19:14 +02:00
parent b99d253477
commit 257659a683
12 changed files with 371 additions and 183 deletions

View File

@ -64,7 +64,7 @@
// Hud
"overlay_path" "overlays/zr/zvision"
"nvgs" "1"
"nvgs" "0"
"fov" "90"
// Effects
@ -75,16 +75,16 @@
"immunity_amount" "0.0"
"no_fall_damage" "1"
"health" "5000"
"health" "3000"
"health_regen_interval" "0.0"
"health_regen_amount" "0"
"health_infect_gain" "800"
"kill_bonus" "2"
"speed" "350"
"knockback" "2.5"
"jump_height" "10.0"
"jump_distance" "0.1"
"knockback" "3"
"jump_height" "40.0"
"jump_distance" "1.5"
}
"fast"
@ -105,7 +105,7 @@
// Hud
"overlay_path" "overlays/zr/zvision"
"nvgs" "1"
"nvgs" "0"
"fov" "90"
// Effects
@ -116,7 +116,7 @@
"immunity_amount" "0.0"
"no_fall_damage" "1"
"health" "3000"
"health" "2000"
"health_regen_interval" "0.0"
"health_regen_amount" "0"
"health_infect_gain" "500"
@ -124,8 +124,8 @@
"speed" "380"
"knockback" "3.5"
"jump_height" "13.0"
"jump_distance" "0.2"
"jump_height" "60.0"
"jump_distance" "2.0"
}
"mutated"
@ -146,7 +146,7 @@
// Hud
"overlay_path" "overlays/zr/zvision"
"nvgs" "1"
"nvgs" "0"
"fov" "90"
// Effects
@ -157,16 +157,16 @@
"immunity_amount" "0.0"
"no_fall_damage" "1"
"health" "7000"
"health" "5000"
"health_regen_interval" "0.0"
"health_regen_amount" "0"
"health_infect_gain" "1200"
"health_infect_gain" "1000"
"kill_bonus" "2"
"speed" "275"
"knockback" "3"
"jump_height" "15.0"
"jump_distance" "0.3"
"knockback" "3.5"
"jump_height" "40.0"
"jump_distance" "1.3"
}
"heavy"
@ -187,7 +187,7 @@
// Hud
"overlay_path" "overlays/zr/zvision"
"nvgs" "1"
"nvgs" "0"
"fov" "90"
// Effects
@ -198,16 +198,16 @@
"immunity_amount" "0.0"
"no_fall_damage" "1"
"health" "7000"
"health" "5000"
"health_regen_interval" "0.0"
"health_regen_amount" "0"
"health_infect_gain" "1200"
"health_infect_gain" "1000"
"kill_bonus" "2"
"speed" "290"
"knockback" "2"
"speed" "280"
"knockback" "2.0"
"jump_height" "0.0"
"jump_distance" "0.0"
"jump_distance" "0.8"
}
// ------------------------------------------
@ -216,25 +216,25 @@
//
// ------------------------------------------
"ct"
"human_normal"
{
// General
"enabled" "1"
"team" "1"
"team_default" "1"
"name" "Counter Terrorist"
"description" "Normal CT"
"name" "Normal Human"
"description" "Default Counter-Strike settings"
// Model
"model_path" "models/player/ct_gign.mdl"
"model_path" "default"
"alpha_spawn" "255"
"alpha_damaged" "255"
"alpha_damage" "0"
// Hud
"overlay_path" ""
"nvgs" "1"
"nvgs" "0"
"fov" "90"
// Effects
@ -254,6 +254,88 @@
"speed" "300"
"knockback" "0"
"jump_height" "0.0"
"jump_distance" "0.0"
"jump_distance" "1.0"
}
"human_speedy"
{
// General
"enabled" "1"
"team" "1"
"team_default" "0"
"name" "Speedy"
"description" "Fast human"
// Model
"model_path" "default"
"alpha_spawn" "255"
"alpha_damaged" "255"
"alpha_damage" "0"
// Hud
"overlay_path" ""
"nvgs" "0"
"fov" "90"
// Effects
"napalm_time" "0.0"
// Player behaviour
"immunity_mode" "0"
"immunity_amount" "0.0"
"no_fall_damage" "0"
"health" "100"
"health_regen_interval" "0.0"
"health_regen_amount" "0"
"health_infect_gain" "0"
"kill_bonus" "1"
"speed" "380"
"knockback" "0"
"jump_height" "0.0"
"jump_distance" "1.0"
}
"human_light"
{
// General
"enabled" "1"
"team" "1"
"team_default" "0"
"name" "Light"
"description" "Regular human with improved jump skills"
// Model
"model_path" "default"
"alpha_spawn" "255"
"alpha_damaged" "255"
"alpha_damage" "0"
// Hud
"overlay_path" ""
"nvgs" "0"
"fov" "90"
// Effects
"napalm_time" "0.0"
// Player behaviour
"immunity_mode" "0"
"immunity_amount" "0.0"
"no_fall_damage" "0"
"health" "100"
"health_regen_interval" "0.0"
"health_regen_amount" "0"
"health_infect_gain" "0"
"kill_bonus" "1"
"speed" "300"
"knockback" "0"
"jump_height" "64.0"
"jump_distance" "2.0"
}
}

View File

@ -172,7 +172,6 @@ public OnMapStart()
LoadDownloadData();
// Forward event to modules.
ClassLoad();
WeaponsLoad();
RoundEndOnMapStart();
InfectOnMapStart();
@ -212,6 +211,7 @@ public OnConfigsExecuted()
// Forward event to modules.
SEffectsLoad();
ClassLoad();
}
public OnClientPutInServer(client)

View File

@ -110,8 +110,8 @@ public Action:PlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast)
}
// Forward event to modules.
ClassOnClientSpawn(index);
InfectOnClientSpawn(index);
ClassOnClientSpawn(index); // Module event depends on infect module.
SEffectsOnClientSpawn(index);
AccountOnClientSpawn(index);
SpawnProtectOnClientSpawn(index);
@ -189,7 +189,7 @@ public Action:PlayerJump(Handle:event, const String:name[], bool:dontBroadcast)
new Float:distance = ClassGetJumpDistance(client);
new Float:height = ClassGetJumpHeight(client);
JumpBoost(client, distance, height);
}

View File

@ -75,7 +75,12 @@ bool:ClassApplyModel(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER)
Format(modelpath, sizeof(modelpath), "%s.mdl", modelpath);
}
// TODO: Add support for keeping the default cs model ("default").
// Check if the user specified no change.
else if (strcmp(modelpath, "default", false) == 0)
{
// Don't change the model.
return true;
}
SetEntityModel(client, modelpath);
return true;

View File

@ -9,11 +9,6 @@
* ============================================================================
*/
/**
* Default FOV attribute value.
*/
#define ATTRIBUTES_FOV_DEFAULT 90
/*
* ------------------------------------
*

View File

@ -37,49 +37,71 @@ ClassOnClientDisconnect(client)
ClassOnClientSpawn(client)
{
// Reset client's FOV.
SetPlayerFOV(client, ATTRIBUTES_FOV_DEFAULT);
if (!IsPlayerAlive(client))
{
// The client isn't alive.
return;
}
new bool:randomclass = GetConVarBool(g_hCvarsList[CVAR_CLASSES_RANDOM]);
new bool:showmenu = GetConVarBool(g_hCvarsList[CVAR_CLASSES_SPAWN]);
decl String:steamid[16];
decl String:classname[64];
if (showmenu && !randomclass)
// Assign random classes if enabled. Always do it for bots.
GetClientAuthString(client, steamid, sizeof(steamid));
if (randomclass || StrEqual(steamid, "BOT"))
{
ClassMenuMain(client);
// Get random classes for each type.
new randomzombie = ClassGetRandomClass(ZR_CLASS_TEAM_ZOMBIES);
new randomhuman = ClassGetRandomClass(ZR_CLASS_TEAM_HUMANS);
// Mark zombie class as selected.
ClassSelected[client][ZR_CLASS_TEAM_ZOMBIES] = randomzombie;
ClassGetName(randomzombie, classname, sizeof(classname), ZR_CLASS_TEAM_ZOMBIES);
ZR_PrintToChat(client, "Auto-assign", classname);
// Mark human class as selected.
ClassSelected[client][ZR_CLASS_TEAM_HUMANS] = randomhuman;
ClassGetName(randomhuman, classname, sizeof(classname), ZR_CLASS_TEAM_HUMANS);
ZR_PrintToChat(client, "Auto-assign", classname);
// Update player cache with the human class data, and apply it.
ClassReloadPlayerCache(client, randomhuman);
ClassApplyAttributes(client);
}
// Assign random classes if enabled.
GetClientAuthString(client, steamid, sizeof(steamid));
if (StrEqual(steamid, "BOT") || randomclass)
// Check if the player should spawn in admin mode.
if (ClassPlayerAdminMode[client])
{
// Get player's team
new teamid = GetClientTeam(client);
// Mark player as in admin mode.
ClassPlayerInAdminMode[client] = true;
// If the first zombie spawned, and the player is on the terrorist team, then
// find a random zombie class, otherwise find a human class.
if (g_bZombieSpawned && teamid == CS_TEAM_T)
{
new classindex = ClassGetRandomClass(ZR_CLASS_TEAM_ZOMBIES);
ClassSelected[client][ZR_CLASS_TEAM_ZOMBIES] = classindex;
ClassGetName(client, classname, sizeof(classname));
}
else
{
new classindex = ClassGetRandomClass(ZR_CLASS_TEAM_HUMANS);
ClassSelected[client][ZR_CLASS_TEAM_HUMANS] = classindex;
ClassGetName(client, classname, sizeof(classname));
}
// Update player cache with the admin class and apply attributes.
new adminindex = ClassPlayerNextAdminClass[client];
ClassReloadPlayerCache(client, adminindex);
ClassApplyAttributes(client);
}
else
{
// Not in admin mode, spawn as a zombie or human.
ZR_PrintToChat(client, "Auto-assign", classname);
// Mark player as not in admin mode.
ClassPlayerInAdminMode[client] = false;
// Apply class attributes for the currently active class.
ClassReloadPlayerCache(client, ClassGetActiveIndex(client));
ClassApplyAttributes(client);
}
}
ClassOnClientDeath(client)
{
// Reset certain attributes to not make spectating disorted.
ClassHealthRegenStop(client);
ClassOverlayStop(client);
SetPlayerFOV(client, 90);
NightVisionOn(client, false);
}
ClassOnClientInfected(client, bool:motherzombie = false)
@ -93,10 +115,6 @@ ClassOnClientInfected(client, bool:motherzombie = false)
ClassApplyAttributes(client, motherzombie);
}
ClassOnRoundStart()
{
}
/* ------------------------------------
*

View File

@ -68,8 +68,8 @@ ClassMenuMain(client)
Format(humanselect, sizeof(humanselect), "%t\n %s", "!zclass human", humanclass);
AddMenuItem(menu, "", humanselect, human_itemdraw);
// Only display admin class options for admins.
if (ZRIsClientAdmin(client))
// Only display admin class options for admins, and if admin classes exist.
if (ZRIsClientAdmin(client) && ClassCountTeam(ZR_CLASS_TEAM_ADMINS))
{
// List admin class options.
ClassGetName(ClassSelected[client][ZR_CLASS_TEAM_ADMINS], adminclass, sizeof(adminclass), ZR_CLASS_CACHE_MODIFIED);
@ -243,23 +243,35 @@ public ClassMenuSelectHandle(Handle:menu, MenuAction:action, client, slot)
// Solve teamid from the class index.
teamid = ClassGetTeamID(classindex, ZR_CLASS_CACHE_MODIFIED);
// Set the players active class to the specified class.
ClassSelected[client][teamid] = classindex;
// Check if the class is a admin class.
if (teamid == ZR_CLASS_TEAM_ADMINS)
{
// Set the admin class to be used on next admin spawn.
ClassPlayerNextAdminClass[client] = classindex;
}
else
{
// Set the players active class to the specified class.
ClassSelected[client][teamid] = classindex;
}
}
case MenuAction_Cancel:
{
if (slot == MenuCancel_ExitBack)
{
ClassMenuMain(client);
return;
}
}
case MenuAction_End:
{
CloseHandle(menu);
return;
}
}
// Redisplay the main class menu if autoclose is disabled.
// Redisplay the main class menu after a selection, if autoclose is
// disabled.
if (!autoclose)
{
ClassMenuMain(client);

View File

@ -17,23 +17,41 @@ new Handle:tOverlay[MAXPLAYERS + 1];
/**
* Specifies if a client have a overlay.
*/
new bClientHasOverlay[MAXPLAYERS + 1];
new bool:bClientHasOverlay[MAXPLAYERS + 1];
/**
* Tells wether the overlay is on or not.
*/
new bClientOverlayOn[MAXPLAYERS + 1];
new bool:bClientOverlayOn[MAXPLAYERS + 1];
/**
* Path to the currently active overlay.
*/
new String:ActiveOverlay[MAXPLAYERS + 1][PLATFORM_MAX_PATH];
bool:ClientHasOverlay(client)
/**
* Returns if the have a overlay path specified.
*
* @param client The client index.
* @return True if a overlay path is specified, false otherwise.
*/
bool:ClassClientHasOverlay(client)
{
return bClientHasOverlay[client];
}
/**
* Returns if the overlay is currently on or not.
*
* @param client The client index.
* @return True if on, false otherwise.
*/
bool:ClassOverlayIsOn(client)
{
return bClientOverlayOn[client];
}
ClassOverlayInitialize(client, const String:overlay[])
{
if (IsFakeClient(client))

View File

@ -87,27 +87,26 @@ bool:ClassValidateTeamDefaults(cachetype = ZR_CLASS_CACHE_ORIGINAL)
ClassValidateAttributes(classindex)
{
// TODO: Validate immunity mode and amount.
// TODO: Validate jump values.
new flags;
// Name.
if (strlen(ClassData[classindex][class_name]) == 0)
if (strlen(ClassData[classindex][class_name]) < ZR_CLASS_NAME_MIN)
{
flags += ZR_CLASS_ATTRIB_ERR_NAME;
flags += ZR_CLASS_FLAG_NAME;
}
// Description.
if (strlen(ClassData[classindex][class_description]) == 0)
if (strlen(ClassData[classindex][class_description]) < ZR_CLASS_DESCRIPTION_MIN)
{
flags += ZR_CLASS_ATTRIB_ERR_DESCRIPTION;
flags += ZR_CLASS_FLAG_DESCRIPTION;
}
// Model path.
decl String:model_path[256];
decl String:model_path[PLATFORM_MAX_PATH];
if (strcopy(model_path, sizeof(model_path), ClassData[classindex][class_model_path]) == 0)
{
flags += ZR_CLASS_ATTRIB_ERR_MODEL_PATH;
flags += ZR_CLASS_FLAG_MODEL_PATH;
}
else
{
@ -117,99 +116,120 @@ ClassValidateAttributes(classindex)
// Check if the file exists.
if (!FileExists(model_path))
{
flags += ZR_CLASS_ATTRIB_ERR_MODEL_PATH;
flags += ZR_CLASS_FLAG_MODEL_PATH;
}
}
}
// Alpha, initial.
new alpha_initial = ClassData[classindex][class_alpha_initial];
if (!(alpha_initial >= 0 && alpha_initial <= 255))
if (!(alpha_initial >= ZR_CLASS_ALPHA_INITIAL_MIN && alpha_initial <= ZR_CLASS_ALPHA_INITIAL_MAX))
{
flags += ZR_CLASS_ATTRIB_ERR_ALPHA_INITIAL;
flags += ZR_CLASS_FLAG_ALPHA_INITIAL;
}
// Alpha, damaged.
new alpha_damaged = ClassData[classindex][class_alpha_damaged];
if (!(alpha_damaged >= 0 && alpha_damaged <= 255))
if (!(alpha_damaged >= ZR_CLASS_ALPHA_DAMAGED_MIN && alpha_damaged <= ZR_CLASS_ALPHA_DAMAGED_MAX))
{
flags += ZR_CLASS_ATTRIB_ERR_ALPHA_DAMAGED;
flags += ZR_CLASS_FLAG_ALPHA_DAMAGED;
}
// Alpha, damage.
new alpha_damage = ClassData[classindex][class_alpha_damage];
if (!(alpha_damage >= 0 && alpha_damage <= 65536))
if (!(alpha_damage >= ZR_CLASS_ALPHA_DAMAGE_MIN && alpha_damage <= ZR_CLASS_ALPHA_DAMAGE_MAX))
{
flags += ZR_CLASS_ATTRIB_ERR_ALPHA_DAMAGE;
flags += ZR_CLASS_FLAG_ALPHA_DAMAGE;
}
// Overlay path.
decl String:overlay_path[256];
decl String:overlay[256];
decl String:overlay_path[PLATFORM_MAX_PATH];
decl String:overlay[PLATFORM_MAX_PATH];
if (strcopy(overlay_path, sizeof(overlay_path), ClassData[classindex][class_overlay_path]) > 0)
{
// Check if the file exists.
Format(overlay, sizeof(overlay), "materials/%s.vmt", overlay_path);
if (!FileExists(overlay))
{
flags += ZR_CLASS_ATTRIB_ERR_OVERLAY_PATH;
flags += ZR_CLASS_FLAG_OVERLAY_PATH;
}
}
// Field of view.
new fov = ClassData[classindex][class_fov];
if (!(fov > 15 && fov < 180))
if (!(fov >= ZR_CLASS_FOV_MIN && fov <= ZR_CLASS_FOV_MAX))
{
flags += ZR_CLASS_ATTRIB_ERR_FOV;
flags += ZR_CLASS_FLAG_FOV;
}
// Napalm time.
new Float:napalm_time = ClassData[classindex][class_napalm_time];
if (!(napalm_time >= 0.0 && napalm_time <= 900.0))
if (!(napalm_time >= ZR_CLASS_NAPALM_TIME_MIN && napalm_time <= ZR_CLASS_NAPALM_TIME_MAX))
{
flags += ZR_CLASS_ATTRIB_ERR_NAPALM_TIME;
flags += ZR_CLASS_FLAG_NAPALM_TIME;
}
// Health.
new health = ClassData[classindex][class_health];
if (!(health >= ZR_CLASS_HEALTH_MIN && health <= ZR_CLASS_HEALTH_MAX))
{
flags += ZR_CLASS_FLAG_HEALTH;
}
// Health regen interval.
new Float:regen_interval = ClassData[classindex][class_health_regen_interval];
if (!(regen_interval >= 0.0 && regen_interval <= 900.0))
if (!(regen_interval >= ZR_CLASS_HEALTH_REGEN_INTERVAL_MIN && regen_interval <= ZR_CLASS_HEALTH_REGEN_INTERVAL_MAX))
{
flags += ZR_CLASS_ATTRIB_ERR_HEALTH_REGEN_INTERVAL;
flags += ZR_CLASS_FLAG_HEALTH_REGEN_INTERVAL;
// Health regen amount. Only validating if interval is set.
new regen_amount = ClassData[classindex][class_health_regen_amount];
if (!(regen_amount > 0 && regen_amount <= 65536))
if (!(regen_amount >= ZR_CLASS_HEALTH_REGEN_AMOUNT_MIN && regen_amount <= ZR_CLASS_HEALTH_REGEN_AMOUNT_MAX))
{
flags += ZR_CLASS_ATTRIB_ERR_HEALTH_REGEN_AMOUNT;
flags += ZR_CLASS_FLAG_HEALTH_REGEN_AMOUNT;
}
}
// Health infect gain.
new infect_gain = ClassData[classindex][class_health_infect_gain];
if (!(infect_gain >= 0 && infect_gain <= 65536))
if (!(infect_gain >= ZR_CLASS_HEALTH_INFECT_GAIN_MIN && infect_gain <= ZR_CLASS_HEALTH_INFECT_GAIN_MAX))
{
flags += ZR_CLASS_ATTRIB_ERR_INFECT_GAIN;
flags += ZR_CLASS_FLAG_INFECT_GAIN;
}
// Kill bonus.
new kill_bonus = ClassData[classindex][class_kill_bonus];
if (!(kill_bonus >= 0 && kill_bonus <= 128))
if (!(kill_bonus >= ZR_CLASS_KILL_BONUS_MIN && kill_bonus <= ZR_CLASS_KILL_BONUS_MAX))
{
flags += ZR_CLASS_ATTRIB_ERR_KILL_BONUS;
flags += ZR_CLASS_FLAG_KILL_BONUS;
}
// Speed.
new Float:speed = ClassData[classindex][class_speed];
if (!(speed >= 0.0 && speed <= 1024.0))
if (!(speed >= ZR_CLASS_SPEED_MIN && speed <= ZR_CLASS_SPEED_MAX))
{
flags += ZR_CLASS_ATTRIB_ERR_SPEED;
flags += ZR_CLASS_FLAG_SPEED;
}
// Knockback.
new Float:knockback = ClassData[classindex][class_knockback];
if (!(knockback >= -10.0 && knockback <= 50.0))
if (!(knockback >= ZR_CLASS_KNOCKBACK_MIN && knockback <= ZR_CLASS_KNOCKBACK_MAX))
{
flags += ZR_CLASS_ATTRIB_ERR_KNOCKBACK;
flags += ZR_CLASS_FLAG_KNOCKBACK;
}
// Jump height.
new Float:jump_height = ClassData[classindex][class_jump_height];
if (!(jump_height >= ZR_CLASS_JUMP_HEIGHT_MIN && jump_height <= ZR_CLASS_JUMP_HEIGHT_MAX))
{
flags += ZR_CLASS_FLAG_JUMP_HEIGHT;
}
// Jump distance.
new Float:jump_distance = ClassData[classindex][class_jump_distance];
if (!(jump_distance >= ZR_CLASS_JUMP_DISTANCE_MIN && jump_distance <= ZR_CLASS_JUMP_DISTANCE_MAX))
{
flags += ZR_CLASS_FLAG_JUMP_DISTANCE;
}
return flags;
@ -325,24 +345,31 @@ ClassGetActiveIndex(client)
{
new teamid = GetClientTeam(client);
if (teamid == CS_TEAM_SPECTATOR || teamid == CS_TEAM_NONE)
if (!ZRIsClientOnTeam(client))
{
// No active team.
return -1;
}
if (IsPlayerHuman(client))
// Check if the player currently is in admin mode.
if (ClassPlayerInAdminMode[client])
{
teamid = ZR_CLASS_TEAM_HUMANS;
teamid = ZR_CLASS_TEAM_ADMINS;
}
else
{
teamid = ZR_CLASS_TEAM_ZOMBIES;
// Not in admin mode, check if player is human or zombie.
if (IsPlayerHuman(client))
{
teamid = ZR_CLASS_TEAM_HUMANS;
}
else
{
teamid = ZR_CLASS_TEAM_ZOMBIES;
}
}
// TODO: How to detect that virtual admin team?
// Return the active class for the current team.
// Return the active class for the active team.
return ClassSelected[client][teamid];
}

View File

@ -122,29 +122,68 @@
* @endsection
*/
/**
* @section Attribute limit values. Used when validating.
*/
#define ZR_CLASS_NAME_MIN 1
#define ZR_CLASS_DESCRIPTION_MIN 1
/** Model path is checked for existance. */
#define ZR_CLASS_ALPHA_INITIAL_MIN 0
#define ZR_CLASS_ALPHA_INITIAL_MAX 255
#define ZR_CLASS_ALPHA_DAMAGED_MIN 0
#define ZR_CLASS_ALPHA_DAMAGED_MAX 255
#define ZR_CLASS_ALPHA_DAMAGE_MIN 0
#define ZR_CLASS_ALPHA_DAMAGE_MAX 16384
/** Overlay path is optional, and file is checked for existance if specified. */
#define ZR_CLASS_FOV_MIN 15
#define ZR_CLASS_FOV_MAX 165
#define ZR_CLASS_NAPALM_TIME_MIN 0.0
#define ZR_CLASS_NAPALM_TIME_MAX 600.0
#define ZR_CLASS_HEALTH_MIN 1
#define ZR_CLASS_HEALTH_MAX 16384
#define ZR_CLASS_HEALTH_REGEN_INTERVAL_MIN 0.0
#define ZR_CLASS_HEALTH_REGEN_INTERVAL_MAX 900.0
#define ZR_CLASS_HEALTH_REGEN_AMOUNT_MIN 0.0
#define ZR_CLASS_HEALTH_REGEN_AMOUNT_MAX 16384
#define ZR_CLASS_HEALTH_INFECT_GAIN_MIN 0
#define ZR_CLASS_HEALTH_INFECT_GAIN_MAX 16384
#define ZR_CLASS_KILL_BONUS_MIN 0
#define ZR_CLASS_KILL_BONUS_MAX 16
#define ZR_CLASS_SPEED_MIN 10.0
#define ZR_CLASS_SPEED_MAX 2000.0
#define ZR_CLASS_KNOCKBACK_MIN -10.0
#define ZR_CLASS_KNOCKBACK_MAX 20.0
#define ZR_CLASS_JUMP_HEIGHT_MIN 0.0
#define ZR_CLASS_JUMP_HEIGHT_MAX 1024.0
#define ZR_CLASS_JUMP_DISTANCE_MIN 0.0
#define ZR_CLASS_JUMP_DISTANCE_MAX 1024.0
/**
* @endsection
*/
/**
* @section Error flags for invalid class attributes.
*/
#define ZR_CLASS_ATTRIB_ERR_OK 0
#define ZR_CLASS_ATTRIB_ERR_NAME 1
#define ZR_CLASS_ATTRIB_ERR_DESCRIPTION 2
#define ZR_CLASS_ATTRIB_ERR_MODEL_PATH 4
#define ZR_CLASS_ATTRIB_ERR_ALPHA_INITIAL 8
#define ZR_CLASS_ATTRIB_ERR_ALPHA_DAMAGED 16
#define ZR_CLASS_ATTRIB_ERR_ALPHA_DAMAGE 32
#define ZR_CLASS_ATTRIB_ERR_OVERLAY_PATH 64
#define ZR_CLASS_ATTRIB_ERR_FOV 128
#define ZR_CLASS_ATTRIB_ERR_NAPALM_TIME 256
#define ZR_CLASS_ATTRIB_ERR_IMMUNITY_MODE 512
#define ZR_CLASS_ATTRIB_ERR_IMMUNITY_AMOUNT 1024
#define ZR_CLASS_ATTRIB_ERR_HEALTH_REGEN_INTERVAL 2048
#define ZR_CLASS_ATTRIB_ERR_HEALTH_REGEN_AMOUNT 4096
#define ZR_CLASS_ATTRIB_ERR_INFECT_GAIN 8192
#define ZR_CLASS_ATTRIB_ERR_KILL_BONUS 16384
#define ZR_CLASS_ATTRIB_ERR_SPEED 32768
#define ZR_CLASS_ATTRIB_ERR_KNOCKBACK 65536
#define ZR_CLASS_ATTRIB_ERR_JUMP_HEIGHT 131072
#define ZR_CLASS_ATTRIB_ERR_JUMP_DISTANCE 262144
#define ZR_CLASS_FLAG_NAME (1<<0)
#define ZR_CLASS_FLAG_DESCRIPTION (1<<1)
#define ZR_CLASS_FLAG_MODEL_PATH (1<<2)
#define ZR_CLASS_FLAG_ALPHA_INITIAL (1<<3)
#define ZR_CLASS_FLAG_ALPHA_DAMAGED (1<<4)
#define ZR_CLASS_FLAG_ALPHA_DAMAGE (1<<5)
#define ZR_CLASS_FLAG_OVERLAY_PATH (1<<6)
#define ZR_CLASS_FLAG_FOV (1<<7)
#define ZR_CLASS_FLAG_NAPALM_TIME (1<<8)
#define ZR_CLASS_FLAG_IMMUNITY_MODE (1<<9)
#define ZR_CLASS_FLAG_IMMUNITY_AMOUNT (1<<10)
#define ZR_CLASS_FLAG_HEALTH (1<<11)
#define ZR_CLASS_FLAG_HEALTH_REGEN_INTERVAL (1<<12)
#define ZR_CLASS_FLAG_HEALTH_REGEN_AMOUNT (1<<13)
#define ZR_CLASS_FLAG_INFECT_GAIN (1<<14)
#define ZR_CLASS_FLAG_KILL_BONUS (1<<15)
#define ZR_CLASS_FLAG_SPEED (1<<16)
#define ZR_CLASS_FLAG_KNOCKBACK (1<<17)
#define ZR_CLASS_FLAG_JUMP_HEIGHT (1<<18)
#define ZR_CLASS_FLAG_JUMP_DISTANCE (1<<19)
/**
* @endsection
*/
@ -164,13 +203,13 @@ enum ClassAttributes
String:class_description[256],
/* Model */
String:class_model_path[256],
String:class_model_path[PLATFORM_MAX_PATH],
class_alpha_initial,
class_alpha_damaged,
class_alpha_damage,
/* Hud */
String:class_overlay_path[256],
String:class_overlay_path[PLATFORM_MAX_PATH],
bool:class_nvgs,
class_fov,
@ -235,6 +274,11 @@ new bool:ClassPlayerInAdminMode[MAXPLAYERS + 1];
*/
new bool:ClassPlayerAdminMode[MAXPLAYERS + 1];
/**
* Specifies the admin class to use on next admin mode spawn.
*/
new ClassPlayerNextAdminClass[MAXPLAYERS + 1];
#include "zr/playerclasses/filtertools"
#include "zr/playerclasses/attributes"
#include "zr/playerclasses/apply"
@ -258,7 +302,7 @@ ClassLoad()
}
kvClassData = CreateKeyValues("classes");
decl String:classfile[256];
decl String:classfile[PLATFORM_MAX_PATH];
GetConVarString(g_hCvarsList[CVAR_CLASSES_FILE], classfile, sizeof(classfile));
// Try to load the class configuration file.
@ -279,8 +323,8 @@ ClassLoad()
decl String:name[64];
decl String:description[256];
decl String:model_path[256];
decl String:overlay_path[256];
decl String:model_path[PLATFORM_MAX_PATH];
decl String:overlay_path[PLATFORM_MAX_PATH];
ClassCount = 0;
new ClassErrorFlags;
@ -313,7 +357,7 @@ ClassLoad()
/* Model */
KvGetString(kvClassData, "model_path", model_path, sizeof(model_path), ZR_CLASS_DEFAULT_MODEL_PATH);
strcopy(ClassData[ClassCount][class_model_path], 256, model_path);
strcopy(ClassData[ClassCount][class_model_path], PLATFORM_MAX_PATH, model_path);
ClassData[ClassCount][class_alpha_initial] = KvGetNum(kvClassData, "alpha_initial", ZR_CLASS_DEFAULT_ALPHA_INITIAL);
ClassData[ClassCount][class_alpha_damaged] = KvGetNum(kvClassData, "alpha_damaged", ZR_CLASS_DEFAULT_ALPHA_DAMAGED);
@ -322,7 +366,7 @@ ClassLoad()
/* Hud */
KvGetString(kvClassData, "overlay_path", overlay_path, sizeof(overlay_path), ZR_CLASS_DEFAULT_OVERLAY_PATH);
strcopy(ClassData[ClassCount][class_overlay_path], 256, overlay_path);
strcopy(ClassData[ClassCount][class_overlay_path], PLATFORM_MAX_PATH, overlay_path);
ClassData[ClassCount][class_nvgs] = bool:KvGetNum(kvClassData, "nvgs", ZR_CLASS_DEFAULT_NVGS);
ClassData[ClassCount][class_fov] = KvGetNum(kvClassData, "fov", ZR_CLASS_DEFAULT_FOV);
@ -388,18 +432,13 @@ ClassLoad()
*/
bool:ClassReloadDataCache()
{
/*
* TODO: This must be done in a safe way, because the plugin may read from
* the cache at any time. The plugin might read attributes at the
* same time when the cache is reloaded. There's a chance for
* corrupted attributes at that exact moment.
*/
// Check if there are no classes.
if (ClassCount == 0)
{
return false;
}
// Loop through all classes.
for (new classindex = 0; classindex < ClassCount; classindex++)
{
/* General */
@ -410,13 +449,13 @@ bool:ClassReloadDataCache()
strcopy(ClassDataCache[classindex][class_description], 256, ClassData[classindex][class_description]);
/* Model */
strcopy(ClassDataCache[classindex][class_model_path], 256, ClassData[classindex][class_model_path]);
strcopy(ClassDataCache[classindex][class_model_path], PLATFORM_MAX_PATH, ClassData[classindex][class_model_path]);
ClassDataCache[classindex][class_alpha_initial] = ClassData[classindex][class_alpha_initial];
ClassDataCache[classindex][class_alpha_damaged] = ClassData[classindex][class_alpha_damaged];
ClassDataCache[classindex][class_alpha_damage] = ClassData[classindex][class_alpha_damage];
/* Hud */
strcopy(ClassDataCache[classindex][class_overlay_path], 256, ClassData[classindex][class_overlay_path]);
strcopy(ClassDataCache[classindex][class_overlay_path], PLATFORM_MAX_PATH, ClassData[classindex][class_overlay_path]);
ClassDataCache[classindex][class_nvgs] = ClassData[classindex][class_nvgs];
ClassDataCache[classindex][class_fov] = ClassData[classindex][class_fov];
@ -473,13 +512,13 @@ bool:ClassReloadPlayerCache(client, classindex, cachetype = ZR_CLASS_CACHE_MODIF
strcopy(ClassPlayerCache[client][class_description], 256, ClassData[classindex][class_description]);
/* Model */
strcopy(ClassPlayerCache[client][class_model_path], 256, ClassData[classindex][class_model_path]);
strcopy(ClassPlayerCache[client][class_model_path], PLATFORM_MAX_PATH, ClassData[classindex][class_model_path]);
ClassPlayerCache[client][class_alpha_initial] = ClassData[classindex][class_alpha_initial];
ClassPlayerCache[client][class_alpha_damaged] = ClassData[classindex][class_alpha_damaged];
ClassPlayerCache[client][class_alpha_damage] = ClassData[classindex][class_alpha_damage];
/* Hud */
strcopy(ClassPlayerCache[client][class_overlay_path], 256, ClassData[classindex][class_overlay_path]);
strcopy(ClassPlayerCache[client][class_overlay_path], PLATFORM_MAX_PATH, ClassData[classindex][class_overlay_path]);
ClassPlayerCache[client][class_nvgs] = ClassData[classindex][class_nvgs];
ClassPlayerCache[client][class_fov] = ClassData[classindex][class_fov];
@ -510,13 +549,13 @@ bool:ClassReloadPlayerCache(client, classindex, cachetype = ZR_CLASS_CACHE_MODIF
strcopy(ClassPlayerCache[client][class_description], 256, ClassDataCache[classindex][class_description]);
/* Model */
strcopy(ClassPlayerCache[client][class_model_path], 256, ClassDataCache[classindex][class_model_path]);
strcopy(ClassPlayerCache[client][class_model_path], PLATFORM_MAX_PATH, ClassDataCache[classindex][class_model_path]);
ClassPlayerCache[client][class_alpha_initial] = ClassDataCache[classindex][class_alpha_initial];
ClassPlayerCache[client][class_alpha_damaged] = ClassDataCache[classindex][class_alpha_damaged];
ClassPlayerCache[client][class_alpha_damage] = ClassDataCache[classindex][class_alpha_damage];
/* Hud */
strcopy(ClassPlayerCache[client][class_overlay_path], 256, ClassDataCache[classindex][class_overlay_path]);
strcopy(ClassPlayerCache[client][class_overlay_path], PLATFORM_MAX_PATH, ClassDataCache[classindex][class_overlay_path]);
ClassPlayerCache[client][class_nvgs] = ClassDataCache[classindex][class_nvgs];
ClassPlayerCache[client][class_fov] = ClassDataCache[classindex][class_fov];
@ -567,7 +606,7 @@ ClassClientSetDefaultIndexes(client = -1)
// log a warning.
if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CLASSES))
{
LogMessageFormatted(-1, "Classes", "SetDefaultIndexes", "Warning: Failed to get default zombie class, falling back to default class. Check spelling in \"zr_classes_default_zombie\".", LOG_FORMAT_TYPE_ERROR);
LogMessageFormatted(-1, "Classes", "SetDefaultIndexes", "Warning: Failed to get default zombie class, falling back to default class in class config. Check spelling in \"zr_classes_default_zombie\".", LOG_FORMAT_TYPE_ERROR);
}
// Use default class.
@ -581,7 +620,7 @@ ClassClientSetDefaultIndexes(client = -1)
// log a warning.
if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CLASSES))
{
LogMessageFormatted(-1, "Classes", "SetDefaultIndexes", "Warning: Failed to get default human class, falling back to default class. Check spelling in \"zr_classes_default_human\".", LOG_FORMAT_TYPE_ERROR);
LogMessageFormatted(-1, "Classes", "SetDefaultIndexes", "Warning: Failed to get default human class, falling back to default class in class config. Check spelling in \"zr_classes_default_human\".", LOG_FORMAT_TYPE_ERROR);
}
// Use default class.
@ -591,28 +630,14 @@ ClassClientSetDefaultIndexes(client = -1)
// Validate admin class index.
if (!ClassValidateIndex(adminindex))
{
// Invalid class index. Fall back to default class in class config and
// log a warning.
if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CLASSES))
{
LogMessageFormatted(-1, "Classes", "SetDefaultIndexes", "Warning: Failed to get default admin class, falling back to default class. Check spelling in \"zr_classes_default_admin\".", LOG_FORMAT_TYPE_ERROR);
}
// Use default class.
// Invalid class index. Fall back to default class in class config if
// possible. A invalid class index (-1) can also be stored if there are
// no admin classes at all.
adminindex = ClassGetDefaultClass(ZR_CLASS_TEAM_ADMINS);
}
// Check if a client is specified.
if (client > 0)
{
ClassSelected[client][ZR_CLASS_TEAM_ZOMBIES] = zombieindex;
ClassSelected[client][ZR_CLASS_TEAM_HUMANS] = humanindex;
ClassSelected[client][ZR_CLASS_TEAM_ADMINS] = adminindex;
// Copy human class data to player cache.
ClassReloadPlayerCache(client, humanindex);
}
else
// Check if a client isn't specified.
if (client < 1)
{
// No client specified. Loop through all players.
for (new clientindex = 1; clientindex <= MAXPLAYERS; clientindex++)
@ -620,11 +645,22 @@ 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);
}
}
else
{
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);
}
}
/**

View File

@ -7,7 +7,7 @@
*/
#include "include/adminmenu.inc"
new curMenuClass[MAXPLAYERS + 1];
//new curMenuClass[MAXPLAYERS + 1];
bool:ZRAdminMenu(client)
{

View File

@ -27,19 +27,14 @@ public Action:Command_NightVision(client, argc)
return;
}
if (!IsPlayerZombie(client))
{
return;
}
bClientOverlayOn[client] = !bClientOverlayOn[client];
decl String:overlay[256];
decl String:overlay[PLATFORM_MAX_PATH];
ClassGetOverlayPath(client, overlay, sizeof(overlay));
if (strlen(overlay) > 0)
{
if (bClientOverlayOn[client])
if (ClassOverlayIsOn(client))
{
ClassOverlayInitialize(client, overlay);
}
@ -84,7 +79,7 @@ JumpBoost(client, Float:distance, Float:height)
vel[0] *= distance;
vel[1] *= distance;
vel[2] *= height;
vel[2] += height;
SetPlayerVelocity(client, vel, false);
}