This commit is contained in:
test 2009-04-29 02:34:49 +02:00
commit 5556218f7e
8 changed files with 303 additions and 140 deletions

View File

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

@ -170,7 +170,6 @@ public OnMapStart()
LoadDownloadData(); LoadDownloadData();
// Forward event to modules. // Forward event to modules.
ClassLoad();
RoundEndOnMapStart(); RoundEndOnMapStart();
InfectOnMapStart(); InfectOnMapStart();
SEffectsOnMapStart(); SEffectsOnMapStart();
@ -217,6 +216,7 @@ public OnConfigsExecuted()
InfectLoad(); InfectLoad();
VEffectsLoad(); VEffectsLoad();
SEffectsLoad(); SEffectsLoad();
ClassLoad();
} }
/** /**

View File

@ -75,7 +75,12 @@ bool:ClassApplyModel(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER)
Format(modelpath, sizeof(modelpath), "%s.mdl", modelpath); 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); SetEntityModel(client, modelpath);
return true; return true;

View File

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

View File

@ -17,23 +17,41 @@ new Handle:tOverlay[MAXPLAYERS + 1];
/** /**
* Specifies if a client have a overlay. * Specifies if a client have a overlay.
*/ */
new bClientHasOverlay[MAXPLAYERS + 1]; new bool:bClientHasOverlay[MAXPLAYERS + 1];
/** /**
* Tells wether the overlay is on or not. * Tells whether the overlay is on or not.
*/ */
new bClientOverlayOn[MAXPLAYERS + 1]; new bool:bClientOverlayOn[MAXPLAYERS + 1];
/** /**
* Path to the currently active overlay. * Path to the currently active overlay.
*/ */
new String:ActiveOverlay[MAXPLAYERS + 1][PLATFORM_MAX_PATH]; 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]; 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[]) ClassOverlayInitialize(client, const String:overlay[])
{ {
if (IsFakeClient(client)) if (IsFakeClient(client))

View File

@ -87,27 +87,26 @@ bool:ClassValidateTeamDefaults(cachetype = ZR_CLASS_CACHE_ORIGINAL)
ClassValidateAttributes(classindex) ClassValidateAttributes(classindex)
{ {
// TODO: Validate immunity mode and amount. // TODO: Validate immunity mode and amount.
// TODO: Validate jump values.
new flags; new flags;
// Name. // 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. // 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. // 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) 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 else
{ {
@ -117,99 +116,120 @@ ClassValidateAttributes(classindex)
// Check if the file exists. // Check if the file exists.
if (!FileExists(model_path)) if (!FileExists(model_path))
{ {
flags += ZR_CLASS_ATTRIB_ERR_MODEL_PATH; flags += ZR_CLASS_FLAG_MODEL_PATH;
} }
} }
} }
// Alpha, initial. // Alpha, initial.
new alpha_initial = ClassData[classindex][class_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. // Alpha, damaged.
new alpha_damaged = ClassData[classindex][class_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. // Alpha, damage.
new alpha_damage = ClassData[classindex][class_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. // Overlay path.
decl String:overlay_path[256]; decl String:overlay_path[PLATFORM_MAX_PATH];
decl String:overlay[256]; decl String:overlay[PLATFORM_MAX_PATH];
if (strcopy(overlay_path, sizeof(overlay_path), ClassData[classindex][class_overlay_path]) > 0) if (strcopy(overlay_path, sizeof(overlay_path), ClassData[classindex][class_overlay_path]) > 0)
{ {
// Check if the file exists. // Check if the file exists.
Format(overlay, sizeof(overlay), "materials/%s.vmt", overlay_path); Format(overlay, sizeof(overlay), "materials/%s.vmt", overlay_path);
if (!FileExists(overlay)) if (!FileExists(overlay))
{ {
flags += ZR_CLASS_ATTRIB_ERR_OVERLAY_PATH; flags += ZR_CLASS_FLAG_OVERLAY_PATH;
} }
} }
// Field of view. // Field of view.
new fov = ClassData[classindex][class_fov]; 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. // Napalm time.
new Float:napalm_time = ClassData[classindex][class_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. // Health regen interval.
new Float:regen_interval = ClassData[classindex][class_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. // Health regen amount. Only validating if interval is set.
new regen_amount = ClassData[classindex][class_health_regen_amount]; 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. // Health infect gain.
new infect_gain = ClassData[classindex][class_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. // Kill bonus.
new kill_bonus = ClassData[classindex][class_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. // Speed.
new Float:speed = ClassData[classindex][class_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. // Knockback.
new Float:knockback = ClassData[classindex][class_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; return flags;
@ -325,24 +345,31 @@ ClassGetActiveIndex(client)
{ {
new teamid = GetClientTeam(client); new teamid = GetClientTeam(client);
if (teamid == CS_TEAM_SPECTATOR || teamid == CS_TEAM_NONE) if (!ZRIsClientOnTeam(client))
{ {
// No active team. // No active team.
return -1; return -1;
} }
if (InfectIsClientHuman(client)) // Check if the player currently is in admin mode.
if (ClassPlayerInAdminMode[client])
{ {
teamid = ZR_CLASS_TEAM_HUMANS; teamid = ZR_CLASS_TEAM_ADMINS;
} }
else else
{ {
teamid = ZR_CLASS_TEAM_ZOMBIES; // Not in admin mode, check if player is human or zombie.
if (InfectIsClientHuman(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 active team.
// Return the active class for the current team.
return ClassSelected[client][teamid]; return ClassSelected[client][teamid];
} }

View File

@ -122,29 +122,68 @@
* @endsection * @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. * @section Error flags for invalid class attributes.
*/ */
#define ZR_CLASS_ATTRIB_ERR_OK 0 #define ZR_CLASS_FLAG_NAME (1<<0)
#define ZR_CLASS_ATTRIB_ERR_NAME 1 #define ZR_CLASS_FLAG_DESCRIPTION (1<<1)
#define ZR_CLASS_ATTRIB_ERR_DESCRIPTION 2 #define ZR_CLASS_FLAG_MODEL_PATH (1<<2)
#define ZR_CLASS_ATTRIB_ERR_MODEL_PATH 4 #define ZR_CLASS_FLAG_ALPHA_INITIAL (1<<3)
#define ZR_CLASS_ATTRIB_ERR_ALPHA_INITIAL 8 #define ZR_CLASS_FLAG_ALPHA_DAMAGED (1<<4)
#define ZR_CLASS_ATTRIB_ERR_ALPHA_DAMAGED 16 #define ZR_CLASS_FLAG_ALPHA_DAMAGE (1<<5)
#define ZR_CLASS_ATTRIB_ERR_ALPHA_DAMAGE 32 #define ZR_CLASS_FLAG_OVERLAY_PATH (1<<6)
#define ZR_CLASS_ATTRIB_ERR_OVERLAY_PATH 64 #define ZR_CLASS_FLAG_FOV (1<<7)
#define ZR_CLASS_ATTRIB_ERR_FOV 128 #define ZR_CLASS_FLAG_NAPALM_TIME (1<<8)
#define ZR_CLASS_ATTRIB_ERR_NAPALM_TIME 256 #define ZR_CLASS_FLAG_IMMUNITY_MODE (1<<9)
#define ZR_CLASS_ATTRIB_ERR_IMMUNITY_MODE 512 #define ZR_CLASS_FLAG_IMMUNITY_AMOUNT (1<<10)
#define ZR_CLASS_ATTRIB_ERR_IMMUNITY_AMOUNT 1024 #define ZR_CLASS_FLAG_HEALTH (1<<11)
#define ZR_CLASS_ATTRIB_ERR_HEALTH_REGEN_INTERVAL 2048 #define ZR_CLASS_FLAG_HEALTH_REGEN_INTERVAL (1<<12)
#define ZR_CLASS_ATTRIB_ERR_HEALTH_REGEN_AMOUNT 4096 #define ZR_CLASS_FLAG_HEALTH_REGEN_AMOUNT (1<<13)
#define ZR_CLASS_ATTRIB_ERR_INFECT_GAIN 8192 #define ZR_CLASS_FLAG_INFECT_GAIN (1<<14)
#define ZR_CLASS_ATTRIB_ERR_KILL_BONUS 16384 #define ZR_CLASS_FLAG_KILL_BONUS (1<<15)
#define ZR_CLASS_ATTRIB_ERR_SPEED 32768 #define ZR_CLASS_FLAG_SPEED (1<<16)
#define ZR_CLASS_ATTRIB_ERR_KNOCKBACK 65536 #define ZR_CLASS_FLAG_KNOCKBACK (1<<17)
#define ZR_CLASS_ATTRIB_ERR_JUMP_HEIGHT 131072 #define ZR_CLASS_FLAG_JUMP_HEIGHT (1<<18)
#define ZR_CLASS_ATTRIB_ERR_JUMP_DISTANCE 262144 #define ZR_CLASS_FLAG_JUMP_DISTANCE (1<<19)
/** /**
* @endsection * @endsection
*/ */
@ -164,13 +203,13 @@ enum ClassAttributes
String:class_description[256], String:class_description[256],
/* Model */ /* Model */
String:class_model_path[256], String:class_model_path[PLATFORM_MAX_PATH],
class_alpha_initial, class_alpha_initial,
class_alpha_damaged, class_alpha_damaged,
class_alpha_damage, class_alpha_damage,
/* Hud */ /* Hud */
String:class_overlay_path[256], String:class_overlay_path[PLATFORM_MAX_PATH],
bool:class_nvgs, bool:class_nvgs,
class_fov, class_fov,
@ -235,6 +274,11 @@ new bool:ClassPlayerInAdminMode[MAXPLAYERS + 1];
*/ */
new bool:ClassPlayerAdminMode[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/filtertools"
#include "zr/playerclasses/attributes" #include "zr/playerclasses/attributes"
#include "zr/playerclasses/apply" #include "zr/playerclasses/apply"
@ -258,7 +302,7 @@ ClassLoad()
} }
kvClassData = CreateKeyValues("classes"); kvClassData = CreateKeyValues("classes");
decl String:classfile[256]; decl String:classfile[PLATFORM_MAX_PATH];
GetConVarString(g_hCvarsList[CVAR_CLASSES_FILE], classfile, sizeof(classfile)); GetConVarString(g_hCvarsList[CVAR_CLASSES_FILE], classfile, sizeof(classfile));
// Try to load the class configuration file. // Try to load the class configuration file.
@ -279,8 +323,8 @@ ClassLoad()
decl String:name[64]; decl String:name[64];
decl String:description[256]; decl String:description[256];
decl String:model_path[256]; decl String:model_path[PLATFORM_MAX_PATH];
decl String:overlay_path[256]; decl String:overlay_path[PLATFORM_MAX_PATH];
ClassCount = 0; ClassCount = 0;
new ClassErrorFlags; new ClassErrorFlags;
@ -313,7 +357,7 @@ ClassLoad()
/* Model */ /* Model */
KvGetString(kvClassData, "model_path", model_path, sizeof(model_path), ZR_CLASS_DEFAULT_MODEL_PATH); 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_initial] = KvGetNum(kvClassData, "alpha_initial", ZR_CLASS_DEFAULT_ALPHA_INITIAL);
ClassData[ClassCount][class_alpha_damaged] = KvGetNum(kvClassData, "alpha_damaged", ZR_CLASS_DEFAULT_ALPHA_DAMAGED); ClassData[ClassCount][class_alpha_damaged] = KvGetNum(kvClassData, "alpha_damaged", ZR_CLASS_DEFAULT_ALPHA_DAMAGED);
@ -322,7 +366,7 @@ ClassLoad()
/* Hud */ /* Hud */
KvGetString(kvClassData, "overlay_path", overlay_path, sizeof(overlay_path), ZR_CLASS_DEFAULT_OVERLAY_PATH); 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_nvgs] = bool:KvGetNum(kvClassData, "nvgs", ZR_CLASS_DEFAULT_NVGS);
ClassData[ClassCount][class_fov] = KvGetNum(kvClassData, "fov", ZR_CLASS_DEFAULT_FOV); ClassData[ClassCount][class_fov] = KvGetNum(kvClassData, "fov", ZR_CLASS_DEFAULT_FOV);
@ -388,18 +432,13 @@ ClassLoad()
*/ */
bool:ClassReloadDataCache() bool:ClassReloadDataCache()
{ {
/* // Check if there are no classes.
* 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.
*/
if (ClassCount == 0) if (ClassCount == 0)
{ {
return false; return false;
} }
// Loop through all classes.
for (new classindex = 0; classindex < ClassCount; classindex++) for (new classindex = 0; classindex < ClassCount; classindex++)
{ {
/* General */ /* General */
@ -410,13 +449,13 @@ bool:ClassReloadDataCache()
strcopy(ClassDataCache[classindex][class_description], 256, ClassData[classindex][class_description]); strcopy(ClassDataCache[classindex][class_description], 256, ClassData[classindex][class_description]);
/* Model */ /* 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_initial] = ClassData[classindex][class_alpha_initial];
ClassDataCache[classindex][class_alpha_damaged] = ClassData[classindex][class_alpha_damaged]; ClassDataCache[classindex][class_alpha_damaged] = ClassData[classindex][class_alpha_damaged];
ClassDataCache[classindex][class_alpha_damage] = ClassData[classindex][class_alpha_damage]; ClassDataCache[classindex][class_alpha_damage] = ClassData[classindex][class_alpha_damage];
/* Hud */ /* 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_nvgs] = ClassData[classindex][class_nvgs];
ClassDataCache[classindex][class_fov] = ClassData[classindex][class_fov]; 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]); strcopy(ClassPlayerCache[client][class_description], 256, ClassData[classindex][class_description]);
/* Model */ /* 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_initial] = ClassData[classindex][class_alpha_initial];
ClassPlayerCache[client][class_alpha_damaged] = ClassData[classindex][class_alpha_damaged]; ClassPlayerCache[client][class_alpha_damaged] = ClassData[classindex][class_alpha_damaged];
ClassPlayerCache[client][class_alpha_damage] = ClassData[classindex][class_alpha_damage]; ClassPlayerCache[client][class_alpha_damage] = ClassData[classindex][class_alpha_damage];
/* Hud */ /* 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_nvgs] = ClassData[classindex][class_nvgs];
ClassPlayerCache[client][class_fov] = ClassData[classindex][class_fov]; 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]); strcopy(ClassPlayerCache[client][class_description], 256, ClassDataCache[classindex][class_description]);
/* Model */ /* 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_initial] = ClassDataCache[classindex][class_alpha_initial];
ClassPlayerCache[client][class_alpha_damaged] = ClassDataCache[classindex][class_alpha_damaged]; ClassPlayerCache[client][class_alpha_damaged] = ClassDataCache[classindex][class_alpha_damaged];
ClassPlayerCache[client][class_alpha_damage] = ClassDataCache[classindex][class_alpha_damage]; ClassPlayerCache[client][class_alpha_damage] = ClassDataCache[classindex][class_alpha_damage];
/* Hud */ /* 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_nvgs] = ClassDataCache[classindex][class_nvgs];
ClassPlayerCache[client][class_fov] = ClassDataCache[classindex][class_fov]; ClassPlayerCache[client][class_fov] = ClassDataCache[classindex][class_fov];
@ -567,7 +606,7 @@ ClassClientSetDefaultIndexes(client = -1)
// log a warning. // log a warning.
if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CLASSES)) 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. // Use default class.
@ -581,7 +620,7 @@ ClassClientSetDefaultIndexes(client = -1)
// log a warning. // log a warning.
if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CLASSES)) 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. // Use default class.
@ -591,28 +630,14 @@ ClassClientSetDefaultIndexes(client = -1)
// Validate admin class index. // Validate admin class index.
if (!ClassValidateIndex(adminindex)) if (!ClassValidateIndex(adminindex))
{ {
// Invalid class index. Fall back to default class in class config and // Invalid class index. Fall back to default class in class config if
// log a warning. // possible. A invalid class index (-1) can also be stored if there are
if (LogCheckFlag(LOG_CORE_EVENTS, LOG_MODULE_CLASSES)) // no admin classes at all.
{
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.
adminindex = ClassGetDefaultClass(ZR_CLASS_TEAM_ADMINS); adminindex = ClassGetDefaultClass(ZR_CLASS_TEAM_ADMINS);
} }
// Check if a client is specified. // Check if a client isn't specified.
if (client > 0) if (client < 1)
{
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
{ {
// No client specified. Loop through all players. // No client specified. Loop through all players.
for (new clientindex = 1; clientindex <= MAXPLAYERS; clientindex++) 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_ZOMBIES] = zombieindex;
ClassSelected[clientindex][ZR_CLASS_TEAM_HUMANS] = humanindex; ClassSelected[clientindex][ZR_CLASS_TEAM_HUMANS] = humanindex;
ClassSelected[clientindex][ZR_CLASS_TEAM_ADMINS] = adminindex; ClassSelected[clientindex][ZR_CLASS_TEAM_ADMINS] = adminindex;
ClassPlayerNextAdminClass[clientindex] = adminindex;
// Copy human class data to player cache. // Copy human class data to player cache.
ClassReloadPlayerCache(client, humanindex); 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" #include "include/adminmenu.inc"
new curMenuClass[MAXPLAYERS + 1]; //new curMenuClass[MAXPLAYERS + 1];
bool:ZRAdminMenu(client) bool:ZRAdminMenu(client)
{ {