Put infection handling in its own core module, added infect sound to downloads table, updated cvars, made an account module (handles cash), zombies now drop weapons on infect (all of them), removed RemoveAllItems, weapon api can handle it and its unneeded now.

This commit is contained in:
Greyscale 2009-04-22 04:53:19 +02:00
parent 557b6d883c
commit b99d253477
19 changed files with 971 additions and 701 deletions

View File

@ -9,11 +9,6 @@
"Offsets"
{
"RemoveAllItems"
{
"windows" "283"
"linux" "284"
}
"EyePosition"
{

View File

@ -41,18 +41,24 @@
// Class System (core)
#include "zr/playerclasses/playerclasses"
// Weapons (core)
#include "zr/weapons/weapons"
// Round End (core)
#include "zr/roundend"
// Infect (core)
#include "zr/infect"
// Damage (core)
#include "zr/damage"
// Weapons (core)
#include "zr/weapons/weapons"
// Hitgroups (core)
#include "zr/hitgroups"
// Account (module)
#include "zr/account"
// Sound Effects (module)
#include "zr/soundeffects/soundeffects"
@ -162,15 +168,14 @@ public OnLibraryAdded(const String:name[])
public OnMapStart()
{
MapChangeCleanup();
LoadModelData();
LoadDownloadData();
// Forward event to modules.
ClassLoad();
RoundEndOnMapStart();
WeaponsLoad();
RoundEndOnMapStart();
InfectOnMapStart();
HitgroupsLoad();
SEffectsOnMapStart();
AntiStickOnMapStart();
@ -211,14 +216,13 @@ public OnConfigsExecuted()
public OnClientPutInServer(client)
{
bMotherInfectImmune[client] = false;
// Forward event to modules.
ClassClientInit(client);
WeaponsClientInit(client);
RoundEndClientInit(client);
InfectClientInit(client);
DamageClientInit(client);
SEffectsClientInit(client);
WeaponsClientInit(client);
SpawnProtectClientInit(client);
RespawnClientInit(client);
ZHPClientInit(client);
@ -226,44 +230,10 @@ public OnClientPutInServer(client)
public OnClientDisconnect(client)
{
PlayerLeft(client);
// Forward event to modules.
ClassOnClientDisconnect(client);
DamageOnClientDisconnect(client);
WeaponsOnClientDisconnect(client);
InfectOnClientDisconnect(client);
DamageOnClientDisconnect(client);
ZTeleResetClient(client);
}
MapChangeCleanup()
{
tInfect = INVALID_HANDLE;
}
/*ZREnd()
{
TerminateRound(3.0, Game_Commencing);
CvarsHook();
CvarsUnhook();
// TODO: Disable all modules! Teleport, ambience, overlays, antistick, etc.
new maxplayers = GetMaxClients();
for (new x = 1; x <= maxplayers; x++)
{
if (!IsClientInGame(x))
{
continue;
}
for (new y = 0; y < MAXTIMERS; y++)
{
if (tHandles[x][y] != INVALID_HANDLE)
{
KillTimer(tHandles[x][y]);
tHandles[x][y] = INVALID_HANDLE;
}
}
}
}*/
}

59
src/zr/account.inc Normal file
View File

@ -0,0 +1,59 @@
/*
* ============================================================================
*
* Zombie:Reloaded
*
* File: account.inc
* Description: (Module) Handles client's accounts. (cash)
*
* ============================================================================
*/
/**
* Maximum limit for cash in CS:S.
*/
#define ACCOUNT_CASH_MAX 16000
/**
* Client is spawning into the game.
*
* @param client The client index.
*/
AccountOnClientSpawn(client)
{
// If cashfill cvar is disabled, then stop.
new bool:accountcashfill = GetConVarBool(g_hCvarsList[CVAR_ACCOUNT_CASHFILL]);
if (!accountcashfill)
{
return;
}
// Get cash value.
new cash = GetConVarInt(g_hCvarsList[CVAR_ACCOUNT_CASHFILL_VALUE]);
// Set client's account.
AccountSetClientCash(client, cash);
}
/**
* Set's a client's account value (cash)
*
* @param client The client index.
* @param value The value to set to.
*/
AccountSetClientCash(client, value)
{
// If value if below 0, then set to 0.
if (value < 0)
{
value = 0;
}
// If value is above max, then set to max.
else if (value > ACCOUNT_CASH_MAX)
{
value = ACCOUNT_CASH_MAX;
}
// Set client's cash.
SetEntData(client, offsAccount, value, 4);
}

View File

@ -29,9 +29,26 @@ enum CvarsList
Handle:CVAR_DAMAGE_SUICIDE_ZOMBIE,
Handle:CVAR_DAMAGE_SUICIDE_HUMAN,
Handle:CVAR_DAMAGE_SUICIDE_CMDS,
Handle:CVAR_INFECT_SPAWNTIME_MIN,
Handle:CVAR_INFECT_SPAWNTIME_MAX,
Handle:CVAR_INFECT_CONSECUTIVE_BLOCK,
Handle:CVAR_INFECT_MZOMBIE_RATIO,
Handle:CVAR_INFECT_MZOMBIE_RESPAWN,
Handle:CVAR_INFECT_SOUND,
Handle:CVAR_INFECT_ESPLASH,
Handle:CVAR_INFECT_FIREBALL,
Handle:CVAR_INFECT_SMOKE,
Handle:CVAR_INFECT_SPARKS,
Handle:CVAR_INFECT_SHAKE,
Handle:CVAR_INFECT_SHAKE_AMP,
Handle:CVAR_INFECT_SHAKE_FREQUENCY,
Handle:CVAR_INFECT_SHAKE_DURATION,
Handle:CVAR_WEAPONS,
Handle:CVAR_WEAPONS_RESTRICT,
Handle:CVAR_WEAPONS_ZMARKET_BUYZONE,
Handle:CVAR_HITGROUPS,
Handle:CVAR_ACCOUNT_CASHFILL,
Handle:CVAR_ACCOUNT_CASHFILL_VALUE,
Handle:CVAR_SOUNDEFFECTS_MOAN,
Handle:CVAR_SOUNDEFFECTS_GROAN,
Handle:CVAR_SOUNDEFFECTS_DEATH,
@ -57,13 +74,6 @@ enum CvarsList
Handle:CVAR_DARK,
Handle:CVAR_DARK_LEVEL,
Handle:CVAR_DARK_SKY,
Handle:CVAR_MOTHER_ZOMBIE_RATIO,
Handle:CVAR_MOTHER_ZOMBIE_RESPAWN,
Handle:CVAR_SUICIDE_WORLD_DAMAGE,
Handle:CVAR_SPAWN_MIN,
Handle:CVAR_SPAWN_MAX,
Handle:CVAR_INFECT_CONSECUTIVE_BLOCK,
Handle:CVAR_ZMARKET_BUYZONE,
Handle:CVAR_ZSPAWN,
Handle:CVAR_ZTELE,
Handle:CVAR_ZTELE_STARTUP_DELAY,
@ -73,17 +83,6 @@ enum CvarsList
Handle:CVAR_ZTELE_ZOMBIE_DELAY,
Handle:CVAR_ZTELE_ZOMBIE_LIMIT,
Handle:CVAR_ZTELE_RESET_BUFFERS,
Handle:CVAR_CASHFILL,
Handle:CVAR_CASHAMOUNT,
Handle:CVAR_INFECT_FIREBALL,
Handle:CVAR_INFECT_SMOKE,
Handle:CVAR_INFECT_SPARKS,
Handle:CVAR_INFECT_SOUND,
Handle:CVAR_INFECT_ESPLASH,
Handle:CVAR_INFECT_SHAKE,
Handle:CVAR_INFECT_SHAKE_AMP,
Handle:CVAR_INFECT_SHAKE_FREQUENCY,
Handle:CVAR_INFECT_SHAKE_DURATION,
Handle:CVAR_ANTICAMP,
Handle:CVAR_ANTICAMP_UPDATE_INTERVAL,
}
@ -184,6 +183,28 @@ CvarsInit()
g_hCvarsList[CVAR_DAMAGE_SUICIDE_CMDS] = CreateConVar("zr_damage_suicide_cmds", "kill, spectate, jointeam", "");
// Old Desc: List of suicide commands to intercept. (Delimited by \", \"
// ===========================
// Infect (core)
// ===========================
g_hCvarsList[CVAR_INFECT_MZOMBIE_RATIO] = CreateConVar("zr_infect_motherzombie_ratio", "5", "");
g_hCvarsList[CVAR_INFECT_MZOMBIE_RESPAWN] = CreateConVar("zr_infect_motherzombie_respawn", "0", "");
g_hCvarsList[CVAR_INFECT_SPAWNTIME_MIN] = CreateConVar("zr_infect_spawntime_min", "30.0", "");
g_hCvarsList[CVAR_INFECT_SPAWNTIME_MAX] = CreateConVar("zr_infect_spawntime_max", "50.0", "");
g_hCvarsList[CVAR_INFECT_CONSECUTIVE_BLOCK] = CreateConVar("zr_infect_consecutive_block", "1", "");
// Effects
g_hCvarsList[CVAR_INFECT_FIREBALL] = CreateConVar("zr_infect_fireball", "1", "");
g_hCvarsList[CVAR_INFECT_SMOKE] = CreateConVar("zr_infect_smoke", "1", "");
g_hCvarsList[CVAR_INFECT_SPARKS] = CreateConVar("zr_infect_sparks", "1", "");
g_hCvarsList[CVAR_INFECT_SOUND] = CreateConVar("zr_infect_sound", "npc/fast_zombie/fz_scream1.wav", "");
g_hCvarsList[CVAR_INFECT_ESPLASH] = CreateConVar("zr_infect_esplash", "1", "");
g_hCvarsList[CVAR_INFECT_SHAKE] = CreateConVar("zr_infect_shake", "1", "");
g_hCvarsList[CVAR_INFECT_SHAKE_AMP] = CreateConVar("zr_infect_shake_amp", "15.0", "");
g_hCvarsList[CVAR_INFECT_SHAKE_FREQUENCY] = CreateConVar("zr_infect_shake_frequency", "1.0", "");
g_hCvarsList[CVAR_INFECT_SHAKE_DURATION] = CreateConVar("zr_infect_shake_duration", "5.0", "");
// ===========================
// Weapons (core)
// ===========================
@ -199,6 +220,11 @@ CvarsInit()
g_hCvarsList[CVAR_WEAPONS_RESTRICT] = CreateConVar("zr_weapons_restrict", "1", "");
// Note make config file cvar.
// Market Handler
g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE] = CreateConVar("zr_weapons_zmarket_buyzone", "1", "");
// Old Desc: Must be in buyzone to access !zmarket, if Market is installed (0: Can be used anywhere)
// ===========================
// Hitgroups (core)
// ===========================
@ -206,6 +232,15 @@ CvarsInit()
g_hCvarsList[CVAR_HITGROUPS] = CreateConVar("zr_hitgroups", "1", "");
// Note make config file cvar.
// ===========================
// Account (module)
// ===========================
g_hCvarsList[CVAR_ACCOUNT_CASHFILL] = CreateConVar("zr_account_cashfill", "1", "");
// Old Desc: Enable the mod to set the players cash to zr_cashamount (0: Disabled)
g_hCvarsList[CVAR_ACCOUNT_CASHFILL_VALUE] = CreateConVar("zr_account_cashfill_value", "12000", "");
// Old Desc: How much money players will have when they spawn when zr_cashfill is 1
// ===========================
// Sound Effects (module)
// ===========================
@ -294,18 +329,6 @@ CvarsInit()
// Old Desc: The darkness of the map, a being the darkest, z being extremely bright when zr_dark is 1 (n: Default)
g_hCvarsList[CVAR_DARK_SKY] = CreateConVar("zr_dark_sky", "sky_borealis01", "");
// Old Desc: The sky the map will have when zr_dark is 1
g_hCvarsList[CVAR_MOTHER_ZOMBIE_RATIO] = CreateConVar("zr_mother_zombie_ratio", "5", "");
// Old Desc: For every 'x' number of humans, there will be 1 zombie (0: Always only 1 mother zombie)
g_hCvarsList[CVAR_MOTHER_ZOMBIE_RESPAWN] = CreateConVar("zr_mother_zombie_respawn", "0", "");
// Old Desc: First zombie(s) will be teleported back to spawn when infected (0: Disable)
g_hCvarsList[CVAR_SPAWN_MIN] = CreateConVar("zr_spawn_min", "30", "");
// Old Desc: Minimum time a player is picked to be zombie after the round starts, in seconds
g_hCvarsList[CVAR_SPAWN_MAX] = CreateConVar("zr_spawn_max", "50", "");
// Old Desc: Maximum time a player is picked to be zombie after the round starts, in seconds
g_hCvarsList[CVAR_INFECT_CONSECUTIVE_BLOCK] = CreateConVar("zr_infect_consecutive_block", "1", "");
// Old Desc: Allow player to be randomly chosen twice in a row to be a mother zombie (0: Disable)
g_hCvarsList[CVAR_ZMARKET_BUYZONE] = CreateConVar("zr_zmarket_buyzone", "1", "");
// Old Desc: Must be in buyzone to access !zmarket, if Market is installed (0: Can be used anywhere)
g_hCvarsList[CVAR_ZSPAWN] = CreateConVar("zr_zspawn", "1", "");
// Old Desc: Allow players to spawn if they just joined the game (0: Disable)
g_hCvarsList[CVAR_ZTELE] = CreateConVar("zr_tele", "1", "");
@ -324,28 +347,6 @@ CvarsInit()
// Old Desc: Maximum number of teleports zombies can do. (0: Zombies can't use the teleporter. -1: Unlimited)
g_hCvarsList[CVAR_ZTELE_RESET_BUFFERS] = CreateConVar("zr_tele_reset_buffers", "1", "");
// Old Desc: Reset custom saved teleport locations on each round start. (0: Disable)
g_hCvarsList[CVAR_CASHFILL] = CreateConVar("zr_cashfill", "1", "");
// Old Desc: Enable the mod to set the players cash to zr_cashamount (0: Disabled)
g_hCvarsList[CVAR_CASHAMOUNT] = CreateConVar("zr_cashamount", "12000", "");
// Old Desc: How much money players will have when they spawn when zr_cashfill is 1
g_hCvarsList[CVAR_INFECT_FIREBALL] = CreateConVar("zr_infect_fireball", "1", "");
// Old Desc: A fireball is created when a player is infected (0: Disable)
g_hCvarsList[CVAR_INFECT_SMOKE] = CreateConVar("zr_infect_smoke", "1", "");
// Old Desc: A puff of smoke is created when a player is infected (0: Disable)
g_hCvarsList[CVAR_INFECT_SPARKS] = CreateConVar("zr_infect_sparks", "1", "");
// Old Desc: Sparks are emitted when a player is infected (0: Disable)
g_hCvarsList[CVAR_INFECT_SOUND] = CreateConVar("zr_infect_sound", "");
// Old Desc: npc/fast_zombie/fz_scream1.wav", "Sound played from from player on infection (Leave blank to disable)
g_hCvarsList[CVAR_INFECT_ESPLASH] = CreateConVar("zr_infect_esplash", "1", "");
// Old Desc: An energy splash is emitted when player is infected (0: Disable)
g_hCvarsList[CVAR_INFECT_SHAKE] = CreateConVar("zr_infect_shake", "1", "");
// Old Desc: Player's screen is shaken on infection (0: Disable)
g_hCvarsList[CVAR_INFECT_SHAKE_AMP] = CreateConVar("zr_infect_shake_amp", "15.0", "");
// Old Desc: Amplitude of the shake, when zr_infect_shake is 1
g_hCvarsList[CVAR_INFECT_SHAKE_FREQUENCY] = CreateConVar("zr_infect_shake_frequency", "1.0", "");
// Old Desc: Frequency of the shake, when zr_infect_shake is 1
g_hCvarsList[CVAR_INFECT_SHAKE_DURATION] = CreateConVar("zr_infect_shake_duration", "5.0", "");
// Old Desc: Duration of the shake, when zr_infect_shake is 1
g_hCvarsList[CVAR_ANTICAMP] = CreateConVar("zr_anticamp", "1", "");
// Old Desc: Enables or disables hurt volumes for preventing unfair camping. (0: Disable)
g_hCvarsList[CVAR_ANTICAMP_UPDATE_INTERVAL] = CreateConVar("zr_anticamp_update_interval", "1", "");

View File

@ -69,7 +69,7 @@ DamageInit()
* Client is joining the server.
*
* @param client The client index.
*/
*/
DamageClientInit(client)
{
// Hook damage callbacks.

View File

@ -36,28 +36,11 @@ public Action:RoundStart(Handle:event, const String:name[], bool:dontBroadcast)
{
ChangeLightStyle();
if (tInfect != INVALID_HANDLE)
{
KillTimer(tInfect);
tInfect = INVALID_HANDLE;
}
g_bZombieSpawned = false;
for (new x = 1; x<= MaxClients; x++)
{
if (!IsClientInGame(x))
{
continue;
}
bZombie[x] = false;
}
ZR_PrintToChat(0, "Round objective");
// Forward event to sub-modules.
RoundEndOnRoundStart();
InfectOnRoundStart();
SEffectsOnRoundStart();
AntiStickOnRoundStart();
}
@ -66,68 +49,41 @@ public Action:RoundFreezeEnd(Handle:event, const String:name[], bool:dontBroadca
{
RemoveObjectives();
if (tInfect != INVALID_HANDLE)
{
KillTimer(tInfect);
}
new Float:min = GetConVarFloat(g_hCvarsList[CVAR_SPAWN_MIN]);
new Float:max = GetConVarFloat(g_hCvarsList[CVAR_SPAWN_MAX]);
new Float:randlen = GetRandomFloat(min, max);
tInfect = CreateTimer(randlen, MotherZombie, _, TIMER_FLAG_NO_MAPCHANGE);
// Forward events to modules.
RoundEndOnRoundFreezeEnd();
InfectOnRoundFreezeEnd();
ZTeleEnable();
}
public Action:RoundEnd(Handle:event, const String:name[], bool:dontBroadcast)
{
// Get all required event info.
new reason = GetEventInt(event, "reason");
if (tInfect != INVALID_HANDLE)
{
KillTimer(tInfect);
tInfect = INVALID_HANDLE;
}
g_bZombieSpawned = false;
for (new x = 1; x<= MaxClients; x++)
{
if (!IsClientInGame(x))
{
continue;
}
bZombie[x] = false;
}
// Forward event to modules.
RoundEndOnRoundEnd(reason);
InfectOnRoundEnd();
ZTeleReset();
}
public Action:PlayerTeam(Handle:event, const String:name[], bool:dontBroadcast)
{
// Get all required event info.
new index = GetClientOfUserId(GetEventInt(event, "userid"));
new team = GetEventInt(event, "team");
if (team == CS_TEAM_SPECTATOR)
{
bZombie[index] = false;
}
// Forward event to modules.
InfectOnClientTeam(index, team);
return Plugin_Handled;
}
public Action:PlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast)
{
// Get all required event info.
new index = GetClientOfUserId(GetEventInt(event, "userid"));
bZombie[index] = false;
// Reset FOV and overlay.
SetPlayerFOV(index, 90);
ClientCommand(index, "r_screenoverlay \"\"");
@ -135,13 +91,6 @@ public Action:PlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast)
// Check if client is on a team.
if (ZRIsClientOnTeam(index))
{
new bool:cashfill = GetConVarBool(g_hCvarsList[CVAR_CASHFILL]);
if (cashfill)
{
new cash = GetConVarInt(g_hCvarsList[CVAR_CASHAMOUNT]);
SetPlayerMoney(index, cash);
}
// Remove night vision.
NightVisionOn(index, false);
NightVision(index, false);
@ -162,7 +111,9 @@ public Action:PlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast)
// Forward event to modules.
ClassOnClientSpawn(index);
InfectOnClientSpawn(index);
SEffectsOnClientSpawn(index);
AccountOnClientSpawn(index);
SpawnProtectOnClientSpawn(index);
RespawnOnClientSpawn(index);
ZHPOnClientSpawn(index);
@ -173,32 +124,18 @@ public Action:PlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast)
public Action:PlayerHurt(Handle:event, const String:name[], bool:dontBroadcast)
{
// Get all required event info.
new index = GetClientOfUserId(GetEventInt(event, "userid"));
new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
new hitgroup = GetEventInt(event, "hitgroup");
new dmg_health = GetEventInt(event, "dmg_health");
decl String:weapon[32];
GetEventString(event, "weapon", weapon, sizeof(weapon));
// Check if the attacker is a player.
if (ZRIsValidClient(attacker))
{
// Check if a zombie attacks a human.
if (IsPlayerHuman(index) && IsPlayerZombie(attacker))
{
// Check if spawn protection is disabled and the weapon is a knife.
if (!pSpawnProtect[index] && StrEqual(weapon, "knife"))
{
InfectPlayer(index, attacker);
}
}
}
// Forward event to modules.
ClassAlphaUpdate(index);
InfectOnClientHurt(index, attacker, weapon);
SEffectsOnClientHurt(index);
KnockbackOnClientHurt(index, attacker, weapon, hitgroup, dmg_health);
NapalmOnClientHurt(index, weapon);
@ -207,72 +144,49 @@ public Action:PlayerHurt(Handle:event, const String:name[], bool:dontBroadcast)
public Action:PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
new index = GetClientOfUserId(GetEventInt(event, "userid"));
new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
// Extinguish fire.
ExtinguishEntity(index);
// Get the weapon name.
decl String:weapon[32];
GetEventString(event, "weapon", weapon, sizeof(weapon));
// Check if the player was infected.
// If client is being infected, then stop.
if (StrEqual(weapon, "zombie_claws_of_death", false))
{
// Add a death count to the players score.
if (ZRIsValidClient(index))
{
AddPlayerDeath(index, 1);
}
// Give a point to the attacker.
if (ZRIsValidClient(attacker))
{
AddPlayerScore(attacker, 1);
new healthgain = ClassGetHealthInfectGain(attacker);
new health = GetClientHealth(attacker);
SetEntityHealth(attacker, health + healthgain);
// Forward event to modules.
ZHPOnHealthInfectGain(attacker);
}
}
else
{
// Reset field of view.
SetPlayerFOV(index, DEFAULT_FOV);
if (IsPlayerZombie(index))
{
// Give kill bonus.
if (ZRIsValidClient(attacker))
{
new bonus = ClassGetKillBonus(attacker);
AddPlayerScore(attacker, bonus);
}
}
// Forward event to modules.
ClassOnClientDeath(index);
SEffectsOnClientDeath(index);
SpawnProtectOnClientDeath(index);
RespawnOnClientDeath(index, attacker, weapon);
ZHPOnClientDeath(index);
return;
}
new RoundEndOutcome:outcome;
if (RoundEndGetRoundStatus(outcome))
// Get all required event info.
new index = GetClientOfUserId(GetEventInt(event, "userid"));
new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));
// Extinguish any flames to stop burning sounds.
ExtinguishEntity(index);
// If the attacker is valid, then continue.
if (ZRIsValidClient(attacker))
{
RoundEndTerminateRound(outcome);
// If the client is a zombie, then continue.
if (IsPlayerZombie(index))
{
// Add kill bonus to attacker's score.
new bonus = ClassGetKillBonus(attacker);
AddPlayerScore(attacker, bonus);
}
}
// Forward event to modules.
ClassOnClientDeath(index);
RoundEndOnClientDeath();
SEffectsOnClientDeath(index);
SpawnProtectOnClientDeath(index);
RespawnOnClientDeath(index, attacker, weapon);
ZHPOnClientDeath(index);
}
public Action:PlayerJump(Handle:event, const String:name[], bool:dontBroadcast)
{
new client = GetClientOfUserId(GetEventInt(event, "userid"));
// Get all required event info.
new client = GetClientOfUserId(GetEventInt(event, "userid"));
new Float:distance = ClassGetJumpDistance(client);
new Float:height = ClassGetJumpHeight(client);
@ -281,6 +195,7 @@ public Action:PlayerJump(Handle:event, const String:name[], bool:dontBroadcast)
public Action:WeaponFire(Handle:event, const String:name[], bool:dontBroadcast)
{
// Get all required event info.
decl String:weapon[32];
GetEventString(event, "weapon", weapon, sizeof(weapon));

665
src/zr/infect.inc Normal file
View File

@ -0,0 +1,665 @@
/*
* ============================================================================
*
* Zombie:Reloaded
*
* File: infect.inc
* Description: Client infection functions.
*
* ============================================================================
*/
/**
* @section Explosion flags.
*/
#define EXP_NODAMAGE 1
#define EXP_REPEATABLE 2
#define EXP_NOFIREBALL 4
#define EXP_NOSMOKE 8
#define EXP_NODECAL 16
#define EXP_NOSPARKS 32
#define EXP_NOSOUND 64
#define EXP_RANDOMORIENTATION 128
#define EXP_NOFIREBALLSMOKE 256
#define EXP_NOPARTICLES 512
#define EXP_NODLIGHTS 1024
#define EXP_NOCLAMPMIN 2048
#define EXP_NOCLAMPMAX 4096
/**
* @endsection
*/
/**
* Global variable to store infect timer handle.
*/
new Handle:tInfect = INVALID_HANDLE;
/**
* Array for flagging client as zombie.
*/
new bool:bZombie[MAXPLAYERS + 1];
/**
* @section bInfectImmune indexes
*/
#define INFECT_TYPE_MOTHER 0
#define INFECT_TYPE_NORMAL 1
/**
* @endsection
*/
/**
* Array for flagging client to be protected. (See defines above)
*/
new bool:bInfectImmune[MAXPLAYERS + 1][2];
/**
* Map is starting.
*/
InfectOnMapStart()
{
// Reset timer handle.
tInfect = INVALID_HANDLE;
// Get infection sound.
decl String:sound[PLATFORM_MAX_PATH];
GetConVarString(g_hCvarsList[CVAR_INFECT_SOUND], sound, sizeof(sound));
// If infect sound cvar is empty, then stop.
if (!sound[0])
{
return;
}
// Prepend sound/ to the path.
Format(sound, sizeof(sound), "sound/%s", sound);
// Add sound file to downloads table.
AddFileToDownloadsTable(sound);
}
/**
* Client is joining the server.
*
* @param client The client index.
*/
InfectClientInit(client)
{
// Reset infect immunity flags.
bInfectImmune[client][INFECT_TYPE_MOTHER] = false;
bInfectImmune[client][INFECT_TYPE_NORMAL] = false;
}
/**
* Client is leaving the server.
*
* @param client The client index.
*/
InfectOnClientDisconnect(client)
{
// If zombie hasn't spawned, then stop.
if (!g_bZombieSpawned)
{
return;
}
// If client is dead, then stop.
if (!IsPlayerAlive(client))
{
return;
}
// Initialize count variables
new zombiecount;
new humancount;
// Count valid clients.
ZRCountValidClients(zombiecount, humancount);
// If client is a human.
if (IsPlayerHuman(client))
{
// If there are other humans (ignoring this human), then stop.
if (humancount > 1)
{
return;
}
// If there are no more clients in the server, then stop.
if (!ZRTeamHasClients(CS_TEAM_T))
{
return;
}
// Manually terminate round.
RoundEndTerminateRound(ZombiesWin);
return;
}
// We know here that player is a zombie.
// If there is 1 or less humans, then stop.
if (humancount <= 1)
{
return;
}
// If there are other zombies (ignoring this zombie), then stop.
if (zombiecount - 1)
{
return;
}
// Create eligible player list.
new Handle:arrayEligibleClients = INVALID_HANDLE;
// Create eligible client list, with no mother infect immunities
new eligibleclients = ZRCreateEligibleClientList(arrayEligibleClients, true, true, true);
// If there are no eligible client's then stop.
if (!eligibleclients)
{
return;
}
// Get a random valid array index.
new randindex = GetRandomInt(0, eligibleclients - 1);
// Get the client stored in the random array index.
new randclient = GetArrayCell(arrayEligibleClients, randindex);
// Infect player.
InfectPlayer(randclient);
// Tell client they have been randomly been chosen to replace disconnecting zombie.
ZR_PrintToChat(randclient, "Zombie replacement");
// Destroy handle.
CloseHandle(arrayEligibleClients);
}
/**
* Client is joining a team.
*
* @param client The client index.
* @param team The team index.
*/
InfectOnClientTeam(client, team)
{
// If client isn't joining spec, then stop.
if (team != CS_TEAM_SPECTATOR)
{
return;
}
// Disable zombie flag on client.
bZombie[client] = false;
}
/**
* Client is spawning into the game.
*
* @param client The client index.
*/
InfectOnClientSpawn(client)
{
// Disable zombie flag on client.
bZombie[client] = false;
}
/** Client has been hurt.
*
* @param client The client index.
* @param attacker The attacker index.
* @param weapon The weapon used.
*/
InfectOnClientHurt(client, attacker, const String:weapon[])
{
// If attacker isn't valid, then stop.
if (!ZRIsValidClient(attacker))
{
return;
}
// If client isn't a human, then stop.
if (!IsPlayerHuman(client))
{
return;
}
// Attacker isn't a zombie, then stop.
if (!IsPlayerZombie(attacker))
{
return;
}
// If client has infect immunity, then stop.
if (bInfectImmune[client][INFECT_TYPE_NORMAL])
{
return;
}
// If weapon isn't a knife, then stop.
if (!StrEqual(weapon, "knife"))
{
return;
}
// Infect client.
InfectPlayer(client, attacker);
}
/**
* The round is starting.
*/
InfectOnRoundStart()
{
// If infect timer is running, then kill it.
if (tInfect != INVALID_HANDLE)
{
// Kill timer.
KillTimer(tInfect);
// Reset timer handle.
tInfect = INVALID_HANDLE;
}
// x = client index.
for (new x = 1; x <= MaxClients; x++)
{
// If client isn't in-game, then stop.
if (!IsClientInGame(x))
{
continue;
}
// Disable zombie flag on client.
bZombie[x] = false;
}
}
/**
* The freeze time is ending.
*/
InfectOnRoundFreezeEnd()
{
// If infect timer is running, then kill it.
if (tInfect != INVALID_HANDLE)
{
// Kill timer.
KillTimer(tInfect);
}
// Get min and max times.
new Float:infectspawntimemin = GetConVarFloat(g_hCvarsList[CVAR_INFECT_SPAWNTIME_MIN]);
new Float:infectspawntimemax = GetConVarFloat(g_hCvarsList[CVAR_INFECT_SPAWNTIME_MAX]);
// Pick random time between min and max.
new Float:randomtime = GetRandomFloat(infectspawntimemin, infectspawntimemax);
tInfect = CreateTimer(randomtime, InfectMotherZombie, _, TIMER_FLAG_NO_MAPCHANGE);
}
/**
* The round is ending.
*/
InfectOnRoundEnd()
{
// If infect timer is running, then kill it.
if (tInfect != INVALID_HANDLE)
{
// Kill timer.
KillTimer(tInfect);
// Reset timer handle.
tInfect = INVALID_HANDLE;
}
// x = client index.
for (new x = 1; x <= MaxClients; x++)
{
// If client isn't in-game, then stop.
if (!IsClientInGame(x))
{
continue;
}
// Disable zombie flag on client.
bZombie[x] = false;
}
}
/**
* Timer callback, chooses mother zombies.
*
* @param timer The timer handle.
*/
public Action:InfectMotherZombie(Handle:timer)
{
// Reset timer handle.
tInfect = INVALID_HANDLE;
// Create eligible player list.
new Handle:arrayEligibleClients = INVALID_HANDLE;
new eligibleclients = ZRCreateEligibleClientList(arrayEligibleClients, true, true, true);
// If there are no eligible client's then stop.
if (!eligibleclients)
{
return;
}
// Variable to store client stored in random array index.
new client;
// Prune list of immune clients.
// x = array index.
// client = client index.
for (new x = 0; x < eligibleclients; x++)
{
// Get client stored in array index.
client = GetArrayCell(arrayEligibleClients, x);
// If client is immune from being a mother zombie, then stop.
if (bInfectImmune[client][INFECT_TYPE_MOTHER])
{
// Take away immunity.
bInfectImmune[client][INFECT_TYPE_MOTHER] = false;
// Remove client from array.
RemoveFromArray(arrayEligibleClients, x);
// Subtract one from count.
eligibleclients--;
// If there are no eligible client's then stop.
if (!eligibleclients)
{
return;
}
// Backtrack one index, because we deleted it out from under the loop.
x--;
}
}
// Move all clients to CT
for (new x = 1; x <= MaxClients; x++)
{
// If client isn't in-game, then stop.
if (!IsClientInGame(x))
{
continue;
}
// If client is dead, then stop.
if (!IsPlayerAlive(x))
{
continue;
}
// Switch client to CT team.
CS_SwitchTeam(x, CS_TEAM_CT);
}
// Variable to store randomly chosen array index.
new randindex;
// Ratio of mother zombies to humans.
new ratio = GetConVarInt(g_hCvarsList[CVAR_INFECT_MZOMBIE_RATIO]);
// If ratio is 0 or lower, then pick 1 zombie.
if (ratio <= 0)
{
// Get a random valid array index.
randindex = GetRandomInt(0, eligibleclients - 1);
// Get the client stored in the random array index.
client = GetArrayCell(arrayEligibleClients, randindex);
// Infect player.
InfectPlayer(client, _, true);
}
else
{
// Initialize count variables
new zombiecount;
new humancount;
// Count valid human clients
ZRCountValidClients(zombiecount, humancount, _, true);
// Calculate mother zombie count.
new mothercount = RoundToCeil(float(humancount) / ratio);
// x = current mother zombie count.
for (new x = 0; x < mothercount; x++)
{
// Recount eligible clients.
eligibleclients = GetArraySize(arrayEligibleClients);
// If there are no more eligible clients, then break loop.
if (!eligibleclients)
{
break;
}
// Get a random valid array index.
randindex = GetRandomInt(0, eligibleclients - 1);
// Get the client stored in the random array index.
client = GetArrayCell(arrayEligibleClients, randindex);
// Infect player.
InfectPlayer(client, _, true);
// Remove player from eligible zombie list.
RemoveFromArray(arrayEligibleClients, randindex);
}
}
// Mother zombies have been infected.
g_bZombieSpawned = true;
// Destroy handle.
CloseHandle(arrayEligibleClients);
}
/**
* Infects a player. Execute events, sets attributes and flags that indicate
* that the player is a zombie.
*
* @param client The player to infect.
* @param attacker (Optional) The attacker who did the infect.
* @param motherinfect (Optional) Indicates a mother zombie infect.
*/
InfectPlayer(client, attacker = -1, bool:motherinfect = false)
{
// Mark player as zombie.
bZombie[client] = true;
// Get a list of all client's weapon indexes.
new weapons[WeaponsType];
WeaponsGetClientWeapons(client, weapons);
// Loop through array slots and force drop.
// x = weapon slot.
for (new x = 0; x < WEAPONS_SLOTS_MAX; x++)
{
// If this is the knife slot, then stop.
if (WeaponsType:x == Type_Melee)
{
continue;
}
// If weapon is invalid, then stop.
if (weapons[x] == -1)
{
continue;
}
// Force client to drop weapon.
WeaponForceClientDrop(client, weapons[x]);
}
// If client has no knife, give them one.
if (weapons[Type_Melee] == -1)
{
GivePlayerItem(client, "weapon_knife");
}
// Check if consecutive infection protection is enabled.
new bool:infectconsecutiveblock = GetConVarBool(g_hCvarsList[CVAR_INFECT_CONSECUTIVE_BLOCK]);
// Flag player to be immune from being mother zombie twice, if consecutive infect protection is enabled.
bInfectImmune[client][INFECT_TYPE_MOTHER] = infectconsecutiveblock ? motherinfect : false;
// Apply effects.
InfectEffects(client);
// Add a death to the zombie's score.
AddPlayerDeath(client, 1);
// Fire death event and set weapon info if the attacker is specified.
if (ZRIsValidClient(attacker))
{
// Create and send custom player_death event.
new Handle:event = CreateEvent("player_death");
if (event != INVALID_HANDLE)
{
SetEventInt(event, "userid", GetClientUserId(client));
SetEventInt(event, "attacker", GetClientUserId(attacker));
SetEventString(event, "weapon", "zombie_claws_of_death");
FireEvent(event, false);
}
// Give client's infector a point.
AddPlayerScore(attacker, 1);
// Apply infect HP gain.
new healthgain = ClassGetHealthInfectGain(attacker);
new health = GetClientHealth(attacker);
// Set attacker's new health.
SetEntityHealth(attacker, health + healthgain);
// Forward event to modules.
ZHPOnHealthInfectGain(attacker);
}
// Switch the player to terrorists.
// TODO: A solution to stop confusing bots? Respawn and teleport?
CS_SwitchTeam(client, CS_TEAM_T);
// Forward event to modules.
ClassOnClientInfected(client, motherinfect);
SEffectsOnClientInfected(client);
ZHPOnClientInfected(client);
TeleportOnClientInfected(client);
// Terminate the round if the last player was infected.
new RoundEndOutcome:outcome;
if (RoundEndGetRoundStatus(outcome))
{
RoundEndTerminateRound(outcome);
}
}
/**
* Creates effects on a newly infected client.
*
* @param client The client index.
*/
InfectEffects(client)
{
// Create location and direction arrays.
new Float:clientloc[3];
new Float:direction[3] = {0.0, 0.0, 0.0};
// Get client's position.
GetClientAbsOrigin(client, clientloc);
clientloc[2] += 30;
// Get infection sound.
decl String:sound[PLATFORM_MAX_PATH];
GetConVarString(g_hCvarsList[CVAR_INFECT_SOUND], sound, sizeof(sound));
if (sound[0])
{
SEffectsEmitSoundFromClient(client, sound, SNDLEVEL_SCREAMING);
}
// Create an energy splash effect.
new bool:esplash = GetConVarBool(g_hCvarsList[CVAR_INFECT_ESPLASH]);
if (esplash)
{
TE_SetupEnergySplash(clientloc, direction, true);
TE_SendToAll();
}
// Create an explosion entity.
new explosion = CreateEntityByName("env_explosion");
// If explosion entity is valid, then continue.
if (explosion != -1)
{
// Get and set flags on explosion.
new flags = GetEntProp(explosion, Prop_Data, "m_spawnflags");
flags = flags | EXP_NODAMAGE | EXP_NODECAL;
// Set "nofireball" flag if fireball is disabled.
new bool:fireball = GetConVarBool(g_hCvarsList[CVAR_INFECT_FIREBALL]);
if (!fireball)
{
flags = flags | EXP_NOFIREBALL;
}
// Set "nosmoke" flag if smoke is disabled.
new bool:smoke = GetConVarBool(g_hCvarsList[CVAR_INFECT_SMOKE]);
if (!smoke)
{
flags = flags | EXP_NOSMOKE;
}
// Set "nosparks" flag if sparks are disabled.
new bool:sparks = GetConVarBool(g_hCvarsList[CVAR_INFECT_SPARKS]);
if (!sparks)
{
flags = flags | EXP_NOSPARKS;
}
// Set new flags on entity.
SetEntProp(explosion, Prop_Data, "m_spawnflags", flags);
// Spawn the entity into the world.
DispatchSpawn(explosion);
// Precache fireball model.
PrecacheModel("materials/sprites/xfireball3.vmt");
// Set origin and explosion key values on entity.
DispatchKeyValueVector(explosion, "origin", clientloc);
DispatchKeyValue(explosion, "fireballsprite", "materials/sprites/xfireball3.vmt");
// Tell the entity to explode.
AcceptEntityInput(explosion, "Explode");
}
// If shake effect is enabled, then continue.
new bool:shake = GetConVarBool(g_hCvarsList[CVAR_INFECT_SHAKE]);
if (shake)
{
// If shake usermsg isn't invalid, then continue.
new Handle:hShake = StartMessageOne("Shake", client);
if (hShake != INVALID_HANDLE)
{
// Write shake information to usermsg handle.
BfWriteByte(hShake, 0);
BfWriteFloat(hShake, GetConVarFloat(g_hCvarsList[CVAR_INFECT_SHAKE_AMP]));
BfWriteFloat(hShake, GetConVarFloat(g_hCvarsList[CVAR_INFECT_SHAKE_FREQUENCY]));
BfWriteFloat(hShake, GetConVarFloat(g_hCvarsList[CVAR_INFECT_SHAKE_DURATION]));
// End usermsg and sent to client.
EndMessage();
}
}
}

View File

@ -6,14 +6,14 @@
* ====================
*/
/** Player hurt event.
/** Client has been hurt.
*
* @param client The victim index. (zombie)
* @param client The client index. (zombie)
* @param attacker The attacker index. (human)
* @param weapon The weapon used.
* @param hitgroup Hitgroup attacker has damaged.
* @param dmg_health Damage done.
*/
*/
KnockbackOnClientHurt(client, attacker, const String:weapon[], hitgroup, dmg_health)
{
// If attacker is invalid, then stop.

View File

@ -13,7 +13,7 @@ new offsSpeed;
new offsNVG;
new offsNVGOn;
new offsCollision;
new offsMoney;
new offsAccount;
new offsFOV;
new offsBuyZone;
new offsColor;
@ -21,7 +21,6 @@ new offsRender;
new offsActiveWeapon;
new Handle:g_hGameConf = INVALID_HANDLE;
new Handle:g_hRemoveAllItems = INVALID_HANDLE;
new Handle:g_hEyePosition = INVALID_HANDLE;
new Handle:g_hEyeAngles = INVALID_HANDLE;
new Handle:g_hTerminateRound = INVALID_HANDLE;
@ -71,8 +70,8 @@ FindOffsets()
SetFailState("Couldn't find \"m_CollisionGroup\"!");
}
offsMoney = FindSendPropInfo("CCSPlayer", "m_iAccount");
if (offsMoney == -1)
offsAccount = FindSendPropInfo("CCSPlayer", "m_iAccount");
if (offsAccount == -1)
{
SetFailState("Couldn't find \"m_iAccount\"!");
}
@ -113,16 +112,6 @@ SetupGameData()
// Load game config file.
g_hGameConf = LoadGameConfigFile("plugin.zombiereloaded");
//
StartPrepSDKCall(SDKCall_Player);
PrepSDKCall_SetFromConf(g_hGameConf, SDKConf_Virtual, "RemoveAllItems");
g_hRemoveAllItems = EndPrepSDKCall();
if(g_hRemoveAllItems == INVALID_HANDLE)
{
SetFailState("Couldn't find offset \"RemoveAllItems\"!");
}
StartPrepSDKCall(SDKCall_Player);
PrepSDKCall_SetFromConf(g_hGameConf, SDKConf_Virtual, "EyePosition");
PrepSDKCall_SetReturnInfo(SDKType_QAngle, SDKPass_ByValue);
@ -230,11 +219,6 @@ bool:CanCollide(client)
return true;
}
SetPlayerMoney(client, amount)
{
SetEntData(client, offsMoney, amount, 4, true);
}
SetPlayerFOV(client, fov)
{
@ -258,11 +242,6 @@ AddPlayerDeath(client, amount)
SetEntProp(client, Prop_Data, "m_iDeaths", deaths + amount);
}
RemoveAllPlayersWeapons(client)
{
SDKCall(g_hRemoveAllItems, client);
}
GetPlayerEyePosition(client, Float:vec[3])
{
SDKCall(g_hEyePosition, client, vec);
@ -278,11 +257,6 @@ TerminateRound(Float:delay, reason)
SDKCall(g_hTerminateRound, delay, reason);
}
CSDropWeapon(client, weapon)
{
SDKCall(g_hCSWeaponDrop, client, weapon, true, false);
}
SetPlayerAlpha(client, alpha)
{
SetEntData(client, offsRender, 3, 1, true);

View File

@ -139,9 +139,9 @@ bool:ClassApplyOverlay(client, classindex, cachetype = ZR_CLASS_CACHE_PLAYER)
}
// If client doesn't meet minimum requirement, then print unsupported text.
if (dxLevel[client] < GENERAL_MIN_DXLEVEL)
if (dxLevel[client] < GENERAL_DXLEVEL_MIN)
{
ZR_PrintCenterText(client, "DX90 not supported", dxLevel[client], GENERAL_MIN_DXLEVEL);
ZR_PrintCenterText(client, "DX90 not supported", dxLevel[client], GENERAL_DXLEVEL_MIN);
return false;
}

View File

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

View File

@ -37,6 +37,9 @@ ClassOnClientDisconnect(client)
ClassOnClientSpawn(client)
{
// Reset client's FOV.
SetPlayerFOV(client, ATTRIBUTES_FOV_DEFAULT);
new bool:randomclass = GetConVarBool(g_hCvarsList[CVAR_CLASSES_RANDOM]);
new bool:showmenu = GetConVarBool(g_hCvarsList[CVAR_CLASSES_SPAWN]);
decl String:steamid[16];
@ -92,7 +95,6 @@ ClassOnClientInfected(client, bool:motherzombie = false)
ClassOnRoundStart()
{
}

View File

@ -82,6 +82,21 @@ RoundEndClientInit(client)
RoundEndGetClientDXLevel(client);
}
/**
* Client has been killed.
*
* @param client The client index.
*/
RoundEndOnClientDeath()
{
// Terminate the round if the last player was infected.
new RoundEndOutcome:outcome;
if (RoundEndGetRoundStatus(outcome))
{
RoundEndTerminateRound(outcome);
}
}
/**
* The round is starting.
*/
@ -97,6 +112,9 @@ RoundEndOnRoundStart()
tRoundEnd = INVALID_HANDLE;
}
// Tell plugin no zombies have been spawned.
g_bZombieSpawned = false;
// Balance teams, and respawn all players.
RoundEndBalanceTeams(true);
}
@ -134,6 +152,9 @@ RoundEndOnRoundEnd(reason)
tRoundEnd = INVALID_HANDLE;
}
// Tell plugin no zombies have been spawned.
g_bZombieSpawned = false;
// Get outcome of the round.
new RoundEndOutcome:outcome = RoundEndReasonToOutcome(reason);
@ -319,7 +340,7 @@ RoundEndBalanceTeams(bool:spawn = false)
{
// Create eligible player list.
new Handle:arrayEligibleClients = INVALID_HANDLE;
new eligibleclients = CreateEligibleClientList(arrayEligibleClients, true);
new eligibleclients = ZRCreateEligibleClientList(arrayEligibleClients, true);
// If there are no eligible client's then stop.
if (!eligibleclients)
@ -399,14 +420,14 @@ RoundEndDisplayClientOverlay(client, const String:overlay[])
}
// If dxLevel is above or equal to minimum requirement, then display overlay.
if (dxLevel[client] >= GENERAL_MIN_DXLEVEL)
if (dxLevel[client] >= GENERAL_DXLEVEL_MIN)
{
ClientCommand(client, "r_screenoverlay \"%s\"", overlay);
}
// If client doesn't meet minimum requirement, then print unsupported text.
else
{
ZR_PrintCenterText(client, "DX90 not supported", dxLevel[client], GENERAL_MIN_DXLEVEL);
ZR_PrintCenterText(client, "DX90 not supported", dxLevel[client], GENERAL_DXLEVEL_MIN);
}
}

View File

@ -14,11 +14,6 @@
*/
new Handle:tSpawnProtect[MAXPLAYERS + 1];
/**
* Array for flagging client to be protected.
*/
new bool:pSpawnProtect[MAXPLAYERS + 1];
/**
* Array for storing time left for spawn protection per client.
*/
@ -43,7 +38,7 @@ SpawnProtectClientInit(client)
SpawnProtectOnClientSpawn(client)
{
// Disable spawn protection on client.
pSpawnProtect[client] = false;
bInfectImmune[client][INFECT_TYPE_NORMAL] = false;
// If timer is currently running, kill it.
if (tSpawnProtect[client] != INVALID_HANDLE)
@ -80,7 +75,7 @@ SpawnProtectOnClientSpawn(client)
if (!respawn_zombie && !RespawnKilledByWorld(client))
{
// Set spawn protect flag on client.
pSpawnProtect[client] = true;
bInfectImmune[client][INFECT_TYPE_NORMAL] = true;
// Set improved attributes
// (Move to cvar?)
@ -149,7 +144,7 @@ public Action:SpawnProtectTimer(Handle:timer, any:client)
if (pSpawnProtectTime[client] <= 0)
{
// Remove protect flag.
pSpawnProtect[client] = false;
bInfectImmune[client][INFECT_TYPE_NORMAL] = false;
// Tell client spawn protection is over.
ZR_HudHint(client, "Spawn protection end");

View File

@ -1,11 +1,19 @@
/**
* ====================
/*
* ============================================================================
*
* Zombie:Reloaded
* File: markethandler.inc
* Author: Greyscale
* ====================
*
* File: markethandler.inc
* Description: Handles market (optional plugin) API, natives, and forwards.
*
* ============================================================================
*/
/**
* Global variable set to true if market plugin is installed
*/
new bool:g_bMarket;
/**
* Sends market menu to client.
*
@ -30,7 +38,7 @@ bool:ZMarketSend(client)
}
// Check buyzone cvar to see if client has to be in a buyzone to use.
new bool:buyzone = GetConVarBool(g_hCvarsList[CVAR_ZMARKET_BUYZONE]);
new bool:buyzone = GetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE]);
if (!IsClientInBuyZone(client) && buyzone)
{
// Tell client they must be in a buyzone.
@ -106,7 +114,7 @@ public bool:Market_OnWeaponSelected(client, String:weaponid[])
}
// Check if buyzone cvar is enabled, and if the client is in a buyzone.
new bool:buyzone = GetConVarBool(g_hCvarsList[CVAR_ZMARKET_BUYZONE]);
new bool:buyzone = GetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE]);
if (!IsClientInBuyZone(client) && buyzone)
{
ZR_PrintCenterText(client, "Market out of buyzone");

View File

@ -422,7 +422,7 @@ WeaponsMenuMarket(client)
decl String:togglebuyzone[64];
decl String:curSetting[8];
ZRBoolToConfigSetting(GetConVarBool(g_hCvarsList[CVAR_ZMARKET_BUYZONE]), curSetting, sizeof(curSetting));
ZRBoolToConfigSetting(GetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE]), curSetting, sizeof(curSetting));
Format(togglebuyzone, sizeof(togglebuyzone), "%t", "Weapons menu market toggle buyzone", curSetting);
@ -451,13 +451,13 @@ public WeaponsMenuMarketHandle(Handle:menu_weapons_market, MenuAction:action, cl
{
case 0:
{
if (GetConVarBool(g_hCvarsList[CVAR_ZMARKET_BUYZONE]))
if (GetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE]))
{
SetConVarBool(g_hCvarsList[CVAR_ZMARKET_BUYZONE], false);
SetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE], false);
}
else
{
SetConVarBool(g_hCvarsList[CVAR_ZMARKET_BUYZONE], true);
SetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE], true);
}
}
}

View File

@ -297,7 +297,7 @@ Float:WeaponGetWeaponKnockback(const String:weapon[])
/**
* General weapon API.
*/
/**
* Return an array that contains all client's weapon indexes.
*
@ -358,4 +358,16 @@ WeaponsType:WeaponsGetDeployedWeaponSlot(client)
}
return Type_Invalid;
}
/**
* Forces player to drop weapon index.
*
* @param client The client index.
* @param weapon The weapon index to force client to drop.
*/
WeaponForceClientDrop(client, weapon)
{
// Force client to drop weapon.
SDKCall(g_hCSWeaponDrop, client, weapon, true, false);
}

View File

@ -5,20 +5,6 @@
* Author: Greyscale
* ====================
*/
#define EXP_NODAMAGE 1
#define EXP_REPEATABLE 2
#define EXP_NOFIREBALL 4
#define EXP_NOSMOKE 8
#define EXP_NODECAL 16
#define EXP_NOSPARKS 32
#define EXP_NOSOUND 64
#define EXP_RANDOMORIENTATION 128
#define EXP_NOFIREBALLSMOKE 256
#define EXP_NOPARTICLES 512
#define EXP_NODLIGHTS 1024
#define EXP_NOCLAMPMIN 2048
#define EXP_NOCLAMPMAX 4096
new String:skyname[32];
@ -90,291 +76,6 @@ ChangeLightStyle()
}
}
/**
* Create an array populated with eligible clients to be zombie.
*
* @param arrayEligibleClients The handle of the array, don't forget to call CloseHandle
* on it when finished!
* @param immunity True to ignore clients immune from mother infect, false to count them.
*/
CreateEligibleClientList(&Handle:arrayEligibleClients, bool:team = false, bool:alive = false, bool:human = false, bool:immunity = false)
{
// Create array.
arrayEligibleClients = CreateArray();
// Populate list with eligible clients.
// x = client index.
for (new x = 1; x <= MaxClients; x++)
{
// If client isn't in-game, then stop.
if (!IsClientInGame(x))
{
continue;
}
// If client isn't on a team, then stop.
if (team && !ZRIsClientOnTeam(x))
{
continue;
}
// If client is dead, then stop.
if (alive && !IsPlayerAlive(x))
{
continue;
}
// If client is already zombie (via admin), then stop.
if (human && !IsPlayerHuman(x))
{
continue;
}
// If client is immune from being a mother zombie, then stop.
if (immunity && bMotherInfectImmune[x])
{
// Take away immunity.
bMotherInfectImmune[x] = false;
continue;
}
// Add eligible client to array.
PushArrayCell(arrayEligibleClients, x);
}
return GetArraySize(arrayEligibleClients);
}
/**
* Timer callback, chooses mother zombies.
*
* @param timer The timer handle.
*/
public Action:MotherZombie(Handle:timer)
{
// Reset timer handle.
tInfect = INVALID_HANDLE;
// Create eligible player list.
new Handle:arrayEligibleClients = INVALID_HANDLE;
new eligibleclients = CreateEligibleClientList(arrayEligibleClients, true, true, true, true);
// If there are no eligible client's then stop.
if (!eligibleclients)
{
return;
}
// Move all clients to CT
for (new x = 1; x <= MaxClients; x++)
{
// If client isn't in-game, then stop.
if (!IsClientInGame(x))
{
continue;
}
// If client is dead, then stop.
if (!IsPlayerAlive(x))
{
continue;
}
// Switch client to CT team.
CS_SwitchTeam(x, CS_TEAM_CT);
}
// Variable to store randomly chosen array index.
new randindex;
// Variable to store client stored in random array index.
new client;
// Ratio of mother zombies to humans.
new ratio = GetConVarInt(g_hCvarsList[CVAR_MOTHER_ZOMBIE_RATIO]);
// If ratio is 0 or lower, then pick 1 zombie.
if (ratio <= 0)
{
// Get a random valid array index.
randindex = GetRandomInt(0, eligibleclients - 1);
// Get the client stored in the random array index.
client = GetArrayCell(arrayEligibleClients, randindex);
// Infect player.
InfectPlayer(client, _, true);
}
else
{
// Calculate mother zombie sound.
new mothercount = RoundToCeil(float(eligibleclients) / ratio);
// x = current mother zombie count.
for (new x = 0; x < mothercount; x++)
{
// Recount eligible clients.
eligibleclients = GetArraySize(arrayEligibleClients);
// If there are no more eligible clients, then break loop.
if (!eligibleclients)
{
break;
}
// Get a random valid array index.
randindex = GetRandomInt(0, eligibleclients - 1);
// Get the client stored in the random array index.
client = GetArrayCell(arrayEligibleClients, randindex);
// Infect player.
InfectPlayer(client, _, true);
// Remove player from eligible zombie list.
RemoveFromArray(arrayEligibleClients, randindex);
}
}
// Mother zombies have been infected.
g_bZombieSpawned = true;
// Destroy handle.
CloseHandle(arrayEligibleClients);
}
/**
* Zombifies a player. Execute events, sets attributes and flags that indicate
* that the player is a zombie.
*
* @param client The player to infect.
* @param attacker Optional. The attacker who did the infect.
* @param motherinfect Optional. Indicates a mother zombie infect.
*/
InfectPlayer(client, attacker = -1, bool:motherinfect = false)
{
// Mark player as zombie.
bZombie[client] = true;
// Remove all weapons and give a knife.
RemoveAllPlayersWeapons(client);
GivePlayerItem(client, "weapon_knife");
// Check if consecutive infection protection is enabled.
new bool:infectconsecutiveblock = GetConVarBool(g_hCvarsList[CVAR_INFECT_CONSECUTIVE_BLOCK]);
// Flag player to be immune from being mother zombie twice, if consecutive infect protection is enabled.
bMotherInfectImmune[client] = infectconsecutiveblock ? motherinfect : false;
// Forward event to modules.
ClassOnClientInfected(client, motherinfect);
SEffectsOnClientInfected(client);
ZHPOnClientInfected(client);
TeleportOnClientInfected(client);
// Apply effects.
InfectionEffects(client);
// Fire death event and set weapon info if the attacker is specified.
if (ZRIsValidClient(attacker))
{
new Handle:event = CreateEvent("player_death");
if (event != INVALID_HANDLE)
{
SetEventInt(event, "userid", GetClientUserId(client));
SetEventInt(event, "attacker", GetClientUserId(attacker));
SetEventString(event, "weapon", "zombie_claws_of_death");
FireEvent(event, false);
}
}
// Switch the player to terrorists.
// TODO: A solution to stop confusing bots? Respawn and teleport?
CS_SwitchTeam(client, CS_TEAM_T);
// Terminate the round if the last player was infected.
new RoundEndOutcome:outcome;
if (RoundEndGetRoundStatus(outcome))
{
RoundEndTerminateRound(outcome);
}
}
InfectionEffects(client)
{
new Float:clientloc[3];
new Float:direction[3] = {0.0, 0.0, 0.0};
GetClientAbsOrigin(client, clientloc);
clientloc[2] += 30;
decl String:sound[128];
GetConVarString(g_hCvarsList[CVAR_INFECT_SOUND], sound, sizeof(sound));
if (sound[0])
{
SEffectsEmitSoundFromClient(client, sound, SNDLEVEL_SCREAMING);
}
new bool:esplash = GetConVarBool(g_hCvarsList[CVAR_INFECT_ESPLASH]);
if (esplash)
{
TE_SetupEnergySplash(clientloc, direction, true);
TE_SendToAll();
}
new explosion = CreateEntityByName("env_explosion");
if (explosion != -1)
{
new flags = GetEntProp(explosion, Prop_Data, "m_spawnflags");
flags = flags | EXP_NODAMAGE | EXP_NODECAL;
new bool:fireball = GetConVarBool(g_hCvarsList[CVAR_INFECT_FIREBALL]);
if (!fireball)
{
flags = flags | EXP_NOFIREBALL;
}
new bool:smoke = GetConVarBool(g_hCvarsList[CVAR_INFECT_SMOKE]);
if (!smoke)
{
flags = flags | EXP_NOSMOKE;
}
new bool:sparks = GetConVarBool(g_hCvarsList[CVAR_INFECT_SPARKS]);
if (!sparks)
{
flags = flags | EXP_NOSPARKS;
}
SetEntProp(explosion, Prop_Data, "m_spawnflags", flags);
DispatchSpawn(explosion);
PrecacheModel("materials/sprites/xfireball3.vmt");
DispatchKeyValueVector(explosion, "origin", clientloc);
DispatchKeyValue(explosion, "fireballsprite", "materials/sprites/xfireball3.vmt");
AcceptEntityInput(explosion, "Explode");
}
new bool:shake = GetConVarBool(g_hCvarsList[CVAR_INFECT_SHAKE]);
if (shake)
{
new Handle:hShake = StartMessageOne("Shake", client);
if (hShake != INVALID_HANDLE)
{
BfWriteByte(hShake, 0);
BfWriteFloat(hShake, GetConVarFloat(g_hCvarsList[CVAR_INFECT_SHAKE_AMP]));
BfWriteFloat(hShake, GetConVarFloat(g_hCvarsList[CVAR_INFECT_SHAKE_FREQUENCY]));
BfWriteFloat(hShake, GetConVarFloat(g_hCvarsList[CVAR_INFECT_SHAKE_DURATION]));
EndMessage();
}
}
}
JumpBoost(client, Float:distance, Float:height)
{
new Float:vel[3];
@ -388,86 +89,6 @@ JumpBoost(client, Float:distance, Float:height)
SetPlayerVelocity(client, vel, false);
}
/**
* Finds a new zombie if the last one disconnects.
*
* @param client The client index.
*/
PlayerLeft(client)
{
// If zombie hasn't spawned, then stop.
if (!g_bZombieSpawned)
{
return;
}
// If client is dead, then stop.
if (!IsPlayerAlive(client))
{
return;
}
// Get zombie flag on client.
new zombieclient = IsPlayerZombie(client);
// Initialize count variables
new zombiecount;
new humancount;
// Count valid clients.
ZRCountValidClients(zombiecount, humancount);
// If client is a human, and is the last one, then terminate round.
if (IsPlayerHuman(client) && humancount <= 1)
{
// If there are no more clients in the server, then stop.
if (!ZRTeamHasClients(CS_TEAM_T))
{
return;
}
// Manually terminate round.
RoundEndTerminateRound(ZombiesWin);
return;
}
// We know here that player is a zombie.
// If there are other zombies (ignoring this zombie), then stop.
if (zombiecount - 1)
{
return;
}
// Create eligible player list.
new Handle:arrayEligibleClients = INVALID_HANDLE;
// Create eligible client list, with no mother infect immunities
new eligibleclients = CreateEligibleClientList(arrayEligibleClients, true, true, true);
// If there are no eligible client's then stop.
if (!eligibleclients)
{
return;
}
// Get a random valid array index.
new randindex = GetRandomInt(0, eligibleclients - 1);
// Get the client stored in the random array index.
new randclient = GetArrayCell(arrayEligibleClients, randindex);
// Infect player.
InfectPlayer(randclient);
// Tell client they have been randomly been chosen to replace disconnecting zombie.
ZR_PrintToChat(randclient, "Zombie replacement");
// Destroy handle.
CloseHandle(arrayEligibleClients);
}
RemoveObjectives()
{
decl String:classname[64];

View File

@ -1,22 +1,18 @@
/**
* ====================
/*
* ============================================================================
*
* Zombie:Reloaded
* File: zombiereloaded.inc
* Author: Greyscale
* ====================
*
* File: zombiereloaded.inc
* Description: General plugin functions and defines.
*
* ============================================================================
*/
#define DEFAULT_FOV 90
/**
* Minimum dx level required to see overlays.
*/
#define GENERAL_MIN_DXLEVEL 90
/**
* Global variable set to true if market plugin is installed
*/
new bool:g_bMarket;
#define GENERAL_DXLEVEL_MIN 90
/**
* The DirectX level of a client.
@ -28,22 +24,6 @@ new dxLevel[MAXPLAYERS + 1];
*/
new bool:g_bZombieSpawned;
/**
* Array for flagging client as zombie.
*/
new bool:bZombie[MAXPLAYERS + 1];
/**
* Array for flagging player has immune to mother infect.
*/
new bool:bMotherInfectImmune[MAXPLAYERS + 1];
/**
* Global variable to store the infect timer handle.
*/
new Handle:tInfect = INVALID_HANDLE;
/**
* Converts string of "yes" or "no" to a boolean value.
*
@ -83,6 +63,53 @@ ZRBoolToConfigSetting(bool:bOption, String:option[], maxlen)
}
}
/**
* Create an array populated with eligible clients to be zombie.
*
* @param arrayEligibleClients The handle of the array, don't forget to call CloseHandle
* on it when finished!
* @param immunity True to ignore clients immune from mother infect, false to count them.
*/
ZRCreateEligibleClientList(&Handle:arrayEligibleClients, bool:team = false, bool:alive = false, bool:human = false)
{
// Create array.
arrayEligibleClients = CreateArray();
// Populate list with eligible clients.
// x = client index.
for (new x = 1; x <= MaxClients; x++)
{
// If client isn't in-game, then stop.
if (!IsClientInGame(x))
{
continue;
}
// If client isn't on a team, then stop.
if (team && !ZRIsClientOnTeam(x))
{
continue;
}
// If client is dead, then stop.
if (alive && !IsPlayerAlive(x))
{
continue;
}
// If client is already zombie (via admin), then stop.
if (human && !IsPlayerHuman(x))
{
continue;
}
// Add eligible client to array.
PushArrayCell(arrayEligibleClients, x);
}
return GetArraySize(arrayEligibleClients);
}
/**
* Check if a client index is a valid player.
*
@ -110,10 +137,10 @@ bool:ZRIsValidClient(client, bool:console = false)
* @param alive If true it will only count live players, false will count alive and dead.
* @return True if successful (zombie has spawned), false otherwise.
*/
bool:ZRCountValidClients(&zombiecount = 0, &humancount = 0, bool:alive = true)
bool:ZRCountValidClients(&zombiecount = 0, &humancount = 0, bool:alive = true, bool:ignorezombiespawned = false)
{
// If zombie hasn't spawned, then stop.
if (!g_bZombieSpawned)
// If zombie hasn't spawned and were not only counting humans, then stop.
if (!g_bZombieSpawned && !ignorezombiespawned)
{
return false;
}
@ -195,7 +222,7 @@ bool:ZRTeamHasClients(team = -1)
}
// Return true if given team has at least 1 client.
return (GetTeamClientCount(team));
return bool:GetTeamClientCount(team);
}
/**