summaryrefslogtreecommitdiff
path: root/src/game/g_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/g_main.c')
-rw-r--r--src/game/g_main.c708
1 files changed, 599 insertions, 109 deletions
diff --git a/src/game/g_main.c b/src/game/g_main.c
index b946238..732fecd 100644
--- a/src/game/g_main.c
+++ b/src/game/g_main.c
@@ -23,8 +23,14 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "g_local.h"
-#define QVM_NAME "Slackers QVM" " (Lakitu7 5.5)"
-#define QVM_VERSIONNUM "1.1+"
+#define QVM_NAME "cQVM"
+#define MAJ_VERSION "5.5"
+
+#ifdef SVN_ID
+ #define QVM_VERSIONNUM MAJ_VERSION " svn" SVN_ID
+#else
+ #define QVM_VERSIONNUM MAJ_VERSION
+#endif
level_locals_t level;
@@ -47,6 +53,9 @@ vmCvar_t g_timelimit;
vmCvar_t g_suddenDeathTime;
vmCvar_t g_suddenDeath;
vmCvar_t g_suddenDeathMode;
+vmCvar_t g_vampireDeathTime;
+vmCvar_t g_vampireDeath;
+vmCvar_t g_vampireDeathInfo;
vmCvar_t g_capturelimit;
vmCvar_t g_friendlyFire;
vmCvar_t g_friendlyFireAliens;
@@ -65,6 +74,7 @@ vmCvar_t g_cheats;
vmCvar_t g_knockback;
vmCvar_t g_quadfactor;
vmCvar_t g_inactivity;
+vmCvar_t g_inactivityMode;
vmCvar_t g_debugMove;
vmCvar_t g_debugDamage;
vmCvar_t g_debugAlloc;
@@ -85,6 +95,7 @@ vmCvar_t g_podiumDrop;
vmCvar_t g_allowVote;
vmCvar_t g_requireVoteReasons;
vmCvar_t g_voteLimit;
+vmCvar_t g_pollVotes;
vmCvar_t g_suddenDeathVotePercent;
vmCvar_t g_suddenDeathVoteDelay;
vmCvar_t g_extendVotesPercent;
@@ -101,14 +112,13 @@ vmCvar_t g_customVote7;
vmCvar_t g_customVote8;
vmCvar_t g_customVotePercent;
vmCvar_t g_mapVotesPercent;
-vmCvar_t g_extendVotesPercent;
-vmCvar_t g_extendVotesTime;
-vmCvar_t g_extendVotesCount;
vmCvar_t g_mapRotationVote;
vmCvar_t g_readyPercent;
vmCvar_t g_designateVotes;
vmCvar_t g_teamAutoJoin;
vmCvar_t g_teamForceBalance;
+vmCvar_t g_popularMaps;
+vmCvar_t g_popularMapsVotePercent;
vmCvar_t g_banIPs;
vmCvar_t g_filterBan;
vmCvar_t g_smoothClients;
@@ -122,6 +132,8 @@ vmCvar_t g_minNameChangePeriod;
vmCvar_t g_maxNameChanges;
vmCvar_t g_newbieNumbering;
vmCvar_t g_newbieNamePrefix;
+vmCvar_t g_newbieNoBuild;
+vmCvar_t g_newbieNoBuildMessage;
vmCvar_t g_humanBuildPoints;
vmCvar_t g_alienBuildPoints;
@@ -142,6 +154,9 @@ vmCvar_t g_unlagged;
vmCvar_t g_disabledEquipment;
vmCvar_t g_disabledClasses;
vmCvar_t g_disabledBuildables;
+vmCvar_t g_buildPointsRecoverRate;
+vmCvar_t g_dynamicBuildPoints;
+vmCvar_t g_instantBuild;
vmCvar_t g_markDeconstruct;
vmCvar_t g_markDeconstructMode;
@@ -151,16 +166,17 @@ vmCvar_t g_debugMapRotation;
vmCvar_t g_currentMapRotation;
vmCvar_t g_currentMap;
vmCvar_t g_nextMap;
+vmCvar_t g_idleMapSwitch;
vmCvar_t g_initialMapRotation;
vmCvar_t g_shove;
vmCvar_t g_mapConfigs;
vmCvar_t g_chatTeamPrefix;
+vmCvar_t g_sayAreaRange;
vmCvar_t g_actionPrefix;
vmCvar_t g_floodMaxDemerits;
vmCvar_t g_floodMinTime;
-vmCvar_t g_spamTime;
vmCvar_t g_layouts;
vmCvar_t g_layoutAuto;
@@ -172,31 +188,42 @@ vmCvar_t g_adminSayFilter;
vmCvar_t g_adminNameProtect;
vmCvar_t g_adminTempMute;
vmCvar_t g_adminTempBan;
+vmCvar_t g_adminBanRepeatKicks;
vmCvar_t g_adminMaxBan;
vmCvar_t g_adminTempSpec;
vmCvar_t g_adminMapLog;
+vmCvar_t g_adminRegisterLevel;
+vmCvar_t g_adminRegisterAdminPass;
+vmCvar_t g_adminRegisterAdminLevel;
vmCvar_t g_minLevelToJoinTeam;
-vmCvar_t g_minDeconLevel;
-vmCvar_t g_minDeconAffectsMark;
vmCvar_t g_forceAutoSelect;
vmCvar_t g_privateMessages;
-vmCvar_t g_fullIgnore;
vmCvar_t g_decolourLogfiles;
vmCvar_t g_minLevelToSpecMM1;
vmCvar_t g_publicSayadmins;
vmCvar_t g_myStats;
-vmCvar_t g_AllStats;
-vmCvar_t g_AllStatsTime;
vmCvar_t g_teamStatus;
vmCvar_t g_antiSpawnBlock;
+
+vmCvar_t g_killingSpree;
+vmCvar_t g_feedingSpree;
+vmCvar_t g_bleedingSpree;
+vmCvar_t g_bleedingSpreeKick;
+vmCvar_t g_autoRevert;
+
vmCvar_t g_banNotice;
+vmCvar_t g_karma;
+vmCvar_t g_chat;
+vmCvar_t g_adminExpireTime;
vmCvar_t g_devmapKillerHP;
vmCvar_t g_killerHP;
vmCvar_t g_buildLogMaxLength;
+vmCvar_t g_maxGhosts;
+
vmCvar_t g_tag;
vmCvar_t g_dretchPunt;
@@ -213,27 +240,38 @@ vmCvar_t g_slapDamage;
vmCvar_t g_voteMinTime;
vmCvar_t g_mapvoteMaxTime;
vmCvar_t g_votableMaps;
+vmCvar_t g_defeatVoteMinTime;
+
+vmCvar_t g_practiceText;
+vmCvar_t g_practiceCount;
+vmCvar_t g_freeCredits;
vmCvar_t g_msg;
vmCvar_t g_msgTime;
vmCvar_t g_welcomeMsg;
vmCvar_t g_welcomeMsgTime;
+vmCvar_t g_turretAim;
+
+vmCvar_t g_modBuildableHealth;
+vmCvar_t g_modBuildableSpeed;
+vmCvar_t g_modBuildableCount;
+vmCvar_t g_modHumanStamina;
+vmCvar_t g_modHumanHealth;
+vmCvar_t g_modAlienHealth;
+vmCvar_t g_modAlienRegenRange;
+vmCvar_t g_modHumanRate;
+vmCvar_t g_modAlienRate;
+vmCvar_t g_modWeaponAmmo;
+vmCvar_t g_modWeaponReload;
+vmCvar_t g_modTurretAngle;
+vmCvar_t g_modStage3Strength;
+vmCvar_t g_modMainStrength;
vmCvar_t mod_jetpackFuel;
vmCvar_t mod_jetpackConsume;
vmCvar_t mod_jetpackRegen;
-vmCvar_t g_adminExpireTime;
-
-vmCvar_t g_autoGhost;
-
-vmCvar_t g_teamKillThreshold;
-
-vmCvar_t g_aimbotAdvertBan;
-vmCvar_t g_aimbotAdvertBanTime;
-vmCvar_t g_aimbotAdvertBanReason;
-
static cvarTable_t gameCvarTable[ ] =
{
// don't override the cheat state set by the system
@@ -260,6 +298,10 @@ static cvarTable_t gameCvarTable[ ] =
{ &g_suddenDeathMode, "g_suddenDeathMode", "0", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_NORESTART, 0, qtrue },
{ &g_suddenDeath, "g_suddenDeath", "0", CVAR_SERVERINFO | CVAR_NORESTART, 0, qtrue },
+ { &g_vampireDeathTime, "g_vampireDeathTime", "0", CVAR_ARCHIVE | CVAR_NORESTART, 0, qtrue },
+ { &g_vampireDeath, "g_vampireDeath", "0", CVAR_NORESTART, 0, qtrue },
+ { &g_vampireDeathInfo, "g_vampireDeathInfo", "( !info vampire )", CVAR_ARCHIVE, 0, qtrue },
+
{ &g_synchronousClients, "g_synchronousClients", "0", CVAR_SYSTEMINFO, 0, qfalse },
{ &g_friendlyFire, "g_friendlyFire", "0", CVAR_ARCHIVE | CVAR_SERVERINFO, 0, qtrue },
@@ -272,11 +314,14 @@ static cvarTable_t gameCvarTable[ ] =
{ &g_devmapNoStructDmg, "g_devmapNoStructDmg", "0", CVAR_ARCHIVE, 0, qtrue },
{ &g_slapKnockback, "g_slapKnockback", "200", CVAR_ARCHIVE, 0, qfalse},
- { &g_slapDamage, "g_slapDamage", "0", CVAR_ARCHIVE, 0, qfalse},
+ { &g_slapDamage, "g_slapDamage", "5", CVAR_ARCHIVE, 0, qfalse},
{ &g_teamAutoJoin, "g_teamAutoJoin", "0", CVAR_ARCHIVE },
{ &g_teamForceBalance, "g_teamForceBalance", "1", CVAR_ARCHIVE },
+ { &g_popularMaps, "g_popularMaps", "arachnid2 atcs karith nexus6 niveus transit tremor", CVAR_ARCHIVE },
+ { &g_popularMapsVotePercent, "g_popularMapsVotePercent", "0", CVAR_ARCHIVE },
+
{ &g_warmup, "g_warmup", "10", CVAR_ARCHIVE, 0, qtrue },
{ &g_warmupMode, "g_warmupMode", "1", CVAR_ARCHIVE, 0, qtrue },
{ &g_doWarmup, "g_doWarmup", "1", CVAR_ARCHIVE, 0, qtrue },
@@ -289,8 +334,6 @@ static cvarTable_t gameCvarTable[ ] =
{ &g_filterBan, "g_filterBan", "1", CVAR_ARCHIVE, 0, qfalse },
{ &g_needpass, "g_needpass", "0", CVAR_SERVERINFO | CVAR_ROM, 0, qfalse },
-
- { &g_autoGhost, "g_autoGhost", "1", CVAR_SERVERINFO, 0, qfalse },
{ &g_dedicated, "dedicated", "0", 0, 0, qfalse },
@@ -301,6 +344,7 @@ static cvarTable_t gameCvarTable[ ] =
{ &g_weaponRespawn, "g_weaponrespawn", "5", 0, 0, qtrue },
{ &g_weaponTeamRespawn, "g_weaponTeamRespawn", "30", 0, 0, qtrue },
{ &g_inactivity, "g_inactivity", "0", 0, 0, qtrue },
+ { &g_inactivityMode, "g_inactivityMode", "0", 0, 0, qfalse },
{ &g_debugMove, "g_debugMove", "0", 0, 0, qfalse },
{ &g_debugDamage, "g_debugDamage", "0", 0, 0, qfalse },
{ &g_debugAlloc, "g_debugAlloc", "0", 0, 0, qfalse },
@@ -312,12 +356,19 @@ static cvarTable_t gameCvarTable[ ] =
{ &g_allowVote, "g_allowVote", "1", CVAR_ARCHIVE, 0, qfalse },
{ &g_requireVoteReasons, "g_requireVoteReasons", "0", CVAR_ARCHIVE, 0, qfalse },
+ { &g_pollVotes, "g_pollVotes", "1", CVAR_ARCHIVE, 0, qfalse },
{ &g_voteLimit, "g_voteLimit", "5", CVAR_ARCHIVE, 0, qfalse },
{ &g_voteMinTime, "g_voteMinTime", "120", CVAR_ARCHIVE, 0, qfalse },
{ &g_mapvoteMaxTime, "g_mapvoteMaxTime", "240", CVAR_ARCHIVE, 0, qfalse },
{ &g_votableMaps, "g_votableMaps", "", CVAR_ARCHIVE, 0, qtrue },
+ { &g_defeatVoteMinTime, "g_defeatVoteMinTime", "60", CVAR_ARCHIVE, 0, qfalse },
{ &g_suddenDeathVotePercent, "g_suddenDeathVotePercent", "74", CVAR_ARCHIVE, 0, qfalse },
{ &g_suddenDeathVoteDelay, "g_suddenDeathVoteDelay", "180", CVAR_ARCHIVE, 0, qfalse },
+ { &g_extendVotesPercent, "g_extendVotesPercent", "74", CVAR_ARCHIVE, 0, qfalse },
+ { &g_extendVotesTime, "g_extendVotesTime", "10", CVAR_ARCHIVE, 0, qfalse },
+ { &g_extendVotesCount, "g_extendVotesCount", "2", CVAR_ARCHIVE, 0, qfalse },
+ { &g_kickVotesPercent, "g_kickVotesPercent", "50", CVAR_ARCHIVE, 0, qtrue },
+
{ &g_customVote1, "g_customVote1", "", CVAR_ARCHIVE, 0, qfalse },
{ &g_customVote2, "g_customVote2", "", CVAR_ARCHIVE, 0, qfalse },
{ &g_customVote3, "g_customVote3", "", CVAR_ARCHIVE, 0, qfalse },
@@ -327,13 +378,15 @@ static cvarTable_t gameCvarTable[ ] =
{ &g_customVote7, "g_customVote7", "", CVAR_ARCHIVE, 0, qfalse },
{ &g_customVote8, "g_customVote8", "", CVAR_ARCHIVE, 0, qfalse },
{ &g_customVotePercent, "g_customVotePercent", "50", CVAR_ARCHIVE, 0, qfalse },
+
{ &g_mapVotesPercent, "g_mapVotesPercent", "50", CVAR_ARCHIVE, 0, qfalse },
- { &g_extendVotesPercent, "g_extendVotesPercent", "74", CVAR_ARCHIVE, 0, qfalse },
- { &g_extendVotesTime, "g_extendVotesTime", "10", CVAR_ARCHIVE, 0, qfalse },
- { &g_extendVotesCount, "g_extendVotesCount", "2", CVAR_ARCHIVE, 0, qfalse },
{ &g_mapRotationVote, "g_mapRotationVote", "15", CVAR_ARCHIVE, 0, qfalse },
{ &g_readyPercent, "g_readyPercent", "0", CVAR_ARCHIVE, 0, qfalse },
{ &g_designateVotes, "g_designateVotes", "0", CVAR_ARCHIVE, 0, qfalse },
+
+ { &g_practiceText, "g_practiceText", "", 0, 0, qfalse},
+ { &g_practiceCount, "g_practiceCount", "0", 0, 0, qfalse},
+ { &g_freeCredits, "g_freeCredits", "0", CVAR_ARCHIVE, 0, qtrue },
{ &g_listEntity, "g_listEntity", "0", 0, 0, qfalse },
{ &g_minCommandPeriod, "g_minCommandPeriod", "500", 0, 0, qfalse},
@@ -341,6 +394,9 @@ static cvarTable_t gameCvarTable[ ] =
{ &g_maxNameChanges, "g_maxNameChanges", "5", 0, 0, qfalse},
{ &g_newbieNumbering, "g_newbieNumbering", "0", CVAR_ARCHIVE, 0, qfalse},
{ &g_newbieNamePrefix, "g_newbieNamePrefix", "Newbie#", CVAR_ARCHIVE, 0, qfalse},
+ { &g_newbieNoBuild, "g_newbieNoBuild", "0", CVAR_ARCHIVE, 0, qfalse},
+ { &g_newbieNoBuildMessage, "g_newbieNoBuildMessage",
+ "Set a name by pressing Escape and choosing Options", CVAR_ARCHIVE, 0, qfalse},
{ &g_smoothClients, "g_smoothClients", "1", 0, 0, qfalse},
{ &g_clientUpgradeNotice, "g_clientUpgradeNotice", "1", 0, 0, qfalse},
@@ -362,17 +418,20 @@ static cvarTable_t gameCvarTable[ ] =
{ &g_teamImbalanceWarnings, "g_teamImbalanceWarnings", "30", CVAR_ARCHIVE, 0, qfalse },
- { &g_unlagged, "g_unlagged", "1", CVAR_SERVERINFO | CVAR_ARCHIVE, 0, qtrue },
+ { &g_unlagged, "g_unlagged", "1", CVAR_SERVERINFO | CVAR_ARCHIVE, 0, qfalse },
{ &g_disabledEquipment, "g_disabledEquipment", "", CVAR_ROM, 0, qfalse },
{ &g_disabledClasses, "g_disabledClasses", "", CVAR_ROM, 0, qfalse },
{ &g_disabledBuildables, "g_disabledBuildables", "", CVAR_ROM, 0, qfalse },
+ { &g_buildPointsRecoverRate, "g_buildPointsRecoverRate", "0", CVAR_ARCHIVE, 0, qfalse },
+ { &g_dynamicBuildPoints, "g_dynamicBuildPoints", "0", CVAR_ARCHIVE, 0, qfalse },
+ { &g_instantBuild, "g_instantBuild", "0", CVAR_ARCHIVE, 0, qfalse },
{ &g_chatTeamPrefix, "g_chatTeamPrefix", "1", CVAR_ARCHIVE },
+ { &g_sayAreaRange, "g_sayAreaRange", "1000", CVAR_ARCHIVE, 0, qtrue },
{ &g_actionPrefix, "g_actionPrefix", "* ", CVAR_ARCHIVE, 0, qfalse },
{ &g_floodMaxDemerits, "g_floodMaxDemerits", "5000", CVAR_ARCHIVE, 0, qfalse },
{ &g_floodMinTime, "g_floodMinTime", "2000", CVAR_ARCHIVE, 0, qfalse },
- { &g_spamTime, "g_spamTime", "2", CVAR_ARCHIVE, 0, qfalse },
{ &g_markDeconstruct, "g_markDeconstruct", "0", CVAR_ARCHIVE, 0, qtrue },
{ &g_markDeconstructMode, "g_markDeconstructMode", "0", CVAR_ARCHIVE, 0, qfalse },
@@ -382,6 +441,7 @@ static cvarTable_t gameCvarTable[ ] =
{ &g_currentMapRotation, "g_currentMapRotation", "-1", 0, 0, qfalse }, // -1 = NOT_ROTATING
{ &g_currentMap, "g_currentMap", "0", 0, 0, qfalse },
{ &g_nextMap, "g_nextMap", "", 0 , 0, qtrue },
+ { &g_idleMapSwitch, "g_idleMapSwitch", "0", CVAR_ARCHIVE, 0, qfalse },
{ &g_initialMapRotation, "g_initialMapRotation", "", CVAR_ARCHIVE, 0, qfalse },
{ &g_shove, "g_shove", "15", CVAR_ARCHIVE, 0, qfalse },
{ &g_mapConfigs, "g_mapConfigs", "", CVAR_ARCHIVE, 0, qfalse },
@@ -397,53 +457,74 @@ static cvarTable_t gameCvarTable[ ] =
{ &g_adminNameProtect, "g_adminNameProtect", "1", CVAR_ARCHIVE, 0, qfalse },
{ &g_adminTempMute, "g_adminTempMute", "5m", CVAR_ARCHIVE, 0, qfalse },
{ &g_adminTempBan, "g_adminTempBan", "2m", CVAR_ARCHIVE, 0, qfalse },
+ { &g_adminBanRepeatKicks, "g_adminBanRepeatKicks", "0", CVAR_ARCHIVE, 0, qfalse },
{ &g_adminMaxBan, "g_adminMaxBan", "2w", CVAR_ARCHIVE, 0, qfalse },
{ &g_adminTempSpec, "g_adminTempSpec", "2m", CVAR_ARCHIVE, 0, qfalse },
{ &g_adminMapLog, "g_adminMapLog", "", CVAR_ROM, 0, qfalse },
+ { &g_adminRegisterLevel, "g_adminRegisterLevel", "1", CVAR_ARCHIVE, 0, qfalse },
+ { &g_adminRegisterAdminPass, "g_adminRegisterAdminPass", "", CVAR_ARCHIVE, 0, qfalse },
+ { &g_adminRegisterAdminLevel, "g_adminRegisterAdminLevel", "0", CVAR_ARCHIVE, 0, qfalse },
{ &g_minLevelToJoinTeam, "g_minLevelToJoinTeam", "0", CVAR_ARCHIVE, 0, qfalse },
- { &g_minDeconLevel, "g_minDeconLevel", "0", CVAR_ARCHIVE, 0, qfalse},
- { &g_minDeconAffectsMark, "g_minDeconAffectsMark", "0", CVAR_ARCHIVE, 0, qfalse},
{ &g_forceAutoSelect, "g_forceAutoSelect", "0", CVAR_ARCHIVE, 0, qtrue },
- { &g_adminExpireTime, "g_adminExpireTime", "0", CVAR_ARCHIVE, 0, qfalse },
+
+ { &g_maxGhosts, "g_maxGhosts", "0", CVAR_ARCHIVE, 0, qfalse },
{ &g_privateMessages, "g_privateMessages", "1", CVAR_ARCHIVE, 0, qfalse },
- { &g_fullIgnore, "g_fullIgnore", "1", CVAR_ARCHIVE, 0, qtrue },
{ &g_decolourLogfiles, "g_decolourLogfiles", "0", CVAR_ARCHIVE, 0, qfalse },
{ &g_buildLogMaxLength, "g_buildLogMaxLength", "50", CVAR_ARCHIVE, 0, qfalse },
{ &g_myStats, "g_myStats", "1", CVAR_ARCHIVE, 0, qtrue },
- { &g_AllStats, "g_AllStats", "0", CVAR_ARCHIVE, 0, qtrue },
- { &g_AllStatsTime, "g_AllStatsTime", "60", CVAR_ARCHIVE, 0, qfalse },
- { &g_teamStatus, "g_teamStatus", "0", CVAR_ARCHIVE, 0, qtrue },
+ { &g_teamStatus, "g_teamStatus", "0", CVAR_ARCHIVE, 0, qfalse },
{ &g_publicSayadmins, "g_publicSayadmins", "1", CVAR_ARCHIVE, 0, qfalse },
{ &g_minLevelToSpecMM1, "g_minLevelToSpecMM1", "0", CVAR_ARCHIVE, 0, qfalse },
{ &g_antiSpawnBlock, "g_antiSpawnBlock", "0", CVAR_ARCHIVE, 0, qfalse },
+ { &g_karma, "g_karma", "0", CVAR_ARCHIVE, 0, qfalse },
+ { &g_chat, "g_chat", "chat.dat", CVAR_ARCHIVE, 0, qfalse },
+ { &g_adminExpireTime, "g_adminExpireTime", "0", CVAR_ARCHIVE, 0, qfalse },
{ &g_devmapKillerHP, "g_devmapKillerHP", "0", CVAR_ARCHIVE, 0, qtrue },
- { &g_killerHP, "g_killerHP", "0", CVAR_ARCHIVE, 0, qtrue },
+ { &g_killerHP, "g_killerHP", "0", CVAR_ARCHIVE, 0, qfalse },
{ &g_tag, "g_tag", "main", CVAR_INIT, 0, qfalse },
{ &g_dretchPunt, "g_dretchPunt", "1", CVAR_ARCHIVE, 0, qfalse },
+
+ { &g_killingSpree, "g_killingSpree", "0", CVAR_ARCHIVE, 0, qfalse },
+ { &g_feedingSpree, "g_feedingSpree", "0", CVAR_ARCHIVE, 0, qfalse },
+ { &g_bleedingSpree, "g_bleedingSpree", "0", CVAR_ARCHIVE, 0, qfalse },
+ { &g_bleedingSpreeKick, "g_bleedingSpreeKick", "0", CVAR_ARCHIVE, 0, qfalse },
+ { &g_autoRevert, "g_autoRevert", "0", CVAR_ARCHIVE, 0, qfalse },
{ &g_msg, "g_msg", "", CVAR_ARCHIVE, 0, qfalse },
{ &g_msgTime, "g_msgTime", "0", CVAR_ARCHIVE, 0, qfalse },
{ &g_welcomeMsg, "g_welcomeMsg", "", CVAR_ARCHIVE, 0, qfalse },
{ &g_welcomeMsgTime, "g_welcomeMsgTime", "0", CVAR_ARCHIVE, 0, qfalse },
+
+ { &g_turretAim, "g_turretAim", "0", CVAR_ARCHIVE, 0, qfalse },
+
+ { &g_modBuildableHealth, "g_modBuildableHealth", "0", CVAR_ARCHIVE, 0, qfalse },
+ { &g_modBuildableSpeed, "g_modBuildableSpeed", "0", CVAR_ARCHIVE, 0, qfalse },
+ { &g_modBuildableCount, "g_modBuildableCount", "0", CVAR_ARCHIVE, 0, qfalse },
+ { &g_modHumanStamina, "g_modHumanStamina", "0", CVAR_ARCHIVE, 0, qfalse },
+ { &g_modHumanHealth, "g_modHumanHealth", "0", CVAR_ARCHIVE, 0, qfalse },
+ { &g_modAlienHealth, "g_modAlienHealth", "0", CVAR_ARCHIVE, 0, qfalse },
+ { &g_modAlienRegenRange, "g_modAlienRegenRange", "0", CVAR_ARCHIVE, 0, qfalse },
+ { &g_modHumanRate, "g_modHumanRate", "0", CVAR_ARCHIVE, 0, qfalse },
+ { &g_modAlienRate, "g_modAlienRate", "0", CVAR_ARCHIVE, 0, qfalse },
+ { &g_modWeaponAmmo, "g_modWeaponAmmo", "0", CVAR_ARCHIVE, 0, qfalse },
+ { &g_modWeaponReload, "g_modWeaponReload", "0", CVAR_ARCHIVE, 0, qfalse },
+ { &g_modTurretAngle, "g_modTurretAngle", "0", CVAR_ARCHIVE, 0, qfalse },
+ { &g_modStage3Strength, "g_modStage3Strength", "0", CVAR_ARCHIVE, 0, qfalse },
+ { &g_modMainStrength, "g_modMainStrength", "0", CVAR_ARCHIVE, 0, qfalse },
{ &g_rankings, "g_rankings", "0", 0, 0, qfalse },
{ &g_allowShare, "g_allowShare", "0", CVAR_ARCHIVE | CVAR_SERVERINFO, 0, qfalse},
{ &g_creditOverflow, "g_creditOverflow", "0", CVAR_ARCHIVE | CVAR_SERVERINFO, 0, qfalse},
{ &g_banNotice, "g_banNotice", "", CVAR_ARCHIVE, 0, qfalse },
- { &mod_jetpackFuel, "mod_jetpackFuel", "0", CVAR_ARCHIVE, 0, qtrue },
+ { &mod_jetpackFuel, "mod_jetpackFuel", "0", CVAR_ARCHIVE, 0, qfalse },
{ &mod_jetpackConsume, "mod_jetpackConsume", "2", CVAR_ARCHIVE, 0, qfalse },
- { &mod_jetpackRegen, "mod_jetpackRegen", "3", CVAR_ARCHIVE, 0, qfalse },
-
- { &g_teamKillThreshold, "g_teamKillThreshold", "0", CVAR_ARCHIVE, 0, qfalse },
+ { &mod_jetpackRegen, "mod_jetpackRegen", "3", CVAR_ARCHIVE, 0, qfalse }
- { &g_aimbotAdvertBan, "g_aimbotAdvertBan", "0", CVAR_ARCHIVE, 0, qfalse },
- { &g_aimbotAdvertBanTime, "g_aimbotAdvertBanTime", "0", CVAR_ARCHIVE, 0, qfalse },
- { &g_aimbotAdvertBanReason, "g_aimbotAdvertBanReason", "AUTOBAN: AIMBOT", CVAR_ARCHIVE, 0, qfalse }
};
static int gameCvarTableSize = sizeof( gameCvarTable ) / sizeof( gameCvarTable[ 0 ] );
@@ -676,6 +757,23 @@ void G_UpdateCvars( void )
G_RemapTeamShaders( );
}
+static void G_InitModCvars( void )
+{
+ BG_MOD_set( MOD_BG_BUILDABLE_HEALTH, g_modBuildableHealth.integer );
+ BG_MOD_set( MOD_BG_BUILDABLE_SPEED, g_modBuildableSpeed.integer );
+ BG_MOD_set( MOD_BG_HUMAN_STAMINA, g_modHumanStamina.integer );
+ BG_MOD_set( MOD_BG_HUMAN_HEALTH, g_modHumanHealth.integer );
+ BG_MOD_set( MOD_BG_ALIEN_HEALTH, g_modAlienHealth.integer );
+ BG_MOD_set( MOD_BG_HUMAN_RATE, g_modHumanRate.integer );
+ BG_MOD_set( MOD_BG_ALIEN_RATE, g_modAlienRate.integer );
+ BG_MOD_set( MOD_BG_WEAPON_AMMO, g_modWeaponAmmo.integer );
+ BG_MOD_set( MOD_BG_WEAPON_RELOAD, g_modWeaponReload.integer );
+ BG_MOD_set( MOD_BG_TURRET_ANGLE, g_modTurretAngle.integer );
+ BG_MOD_set( MOD_BG_STAGE3_STRENGTH, g_modStage3Strength.integer );
+
+ BG_MOD_update( );
+}
+
/*
=================
G_MapConfigs
@@ -813,13 +911,29 @@ void G_InitGame( int levelTime, int randomSeed, int restart )
// load up a custom building layout if there is one
G_LayoutLoad( );
-
- // load any nobuild markers that have been saved
- G_NobuildLoad( );
+
+ // load up nobuild zones
+ nobuild_init( );
// the map might disable some things
BG_InitAllowedGameElements( );
+ // practice counter
+ if( g_practiceCount.integer > 0 )
+ {
+ trap_Cvar_Set( "g_practiceCount", va( "%d", g_practiceCount.integer - 1 ) );
+ }
+
+ // free credits expiration
+ if( g_freeCredits.integer > 1 )
+ {
+ trap_Cvar_Set( "g_freeCredits",
+ va( "%d", ( g_freeCredits.integer > 2 ) ? g_freeCredits.integer - 1 : 0 ) );
+ }
+
+ // syncronize mod cvars
+ G_InitModCvars( );
+
// general initialization
G_FindTeams( );
@@ -841,6 +955,7 @@ void G_InitGame( int levelTime, int randomSeed, int restart )
trap_Cvar_Set( "g_humanKills", 0 );
trap_Cvar_Set( "g_suddenDeath", 0 );
level.suddenDeathBeginTime = g_suddenDeathTime.integer * 60000;
+ trap_Cvar_Set( "g_vampireDeath", 0 );
G_Printf( "-----------------------------------\n" );
@@ -891,6 +1006,8 @@ void G_ShutdownGame( int restart )
G_Printf( "==== ShutdownGame ====\n" );
+ G_admin_chat_writeconfig();
+
if( level.logFile )
{
G_LogPrintf( "ShutdownGame:\n" );
@@ -898,15 +1015,13 @@ void G_ShutdownGame( int restart )
trap_FS_FCloseFile( level.logFile );
}
- // write admin.dat for !seen data
- admin_writeconfig();
-
// write all the client session data so we can get it back
G_WriteSessionData( );
G_admin_cleanup( );
G_admin_namelog_cleanup( );
G_admin_adminlog_cleanup( );
+ G_admin_tklog_cleanup( );
level.restarted = qfalse;
level.surrenderTeam = PTE_NONE;
@@ -1281,6 +1396,15 @@ int G_TimeTilSuddenDeath( void )
return ( ( level.suddenDeathBeginTime ) - ( level.time - level.startTime ) );
}
+int G_TimeTilVampireDeath( void )
+{
+ if( !g_vampireDeathTime.integer )
+ return 3600000; // Always some time away
+
+ return ( g_vampireDeathTime.integer * 60000 ) -
+ ( level.time - level.startTime );
+}
+
#define PLAYER_COUNT_MOD 5.0f
@@ -1366,6 +1490,43 @@ void G_CalculateBuildPoints( void )
}
}
+ //vampire death
+ if( !g_vampireDeath.integer && level.vampireDeath )
+ {
+ level.vampireDeath = 0;
+ level.vampireDeathWarning = 0;
+ }
+ if( !level.vampireDeath )
+ {
+ if( g_vampireDeath.integer || G_TimeTilVampireDeath( ) <= 0 ) //Conditions to enter VD
+ {
+ if( level.vampireDeathWarning < TW_PASSED )
+ {
+ trap_SendServerCommand( -1, "cp \"^1Vampire Sudden Death!\"" );
+ level.vampireDeath = 1;
+ level.vampireDeathBeginTime = level.time;
+ level.vampireDeathWarning = TW_PASSED;
+ g_vampireDeath.integer = 1;
+ }
+ }
+ else if( G_TimeTilVampireDeath( ) <= 60000 && level.vampireDeathWarning < TW_IMMINENT )
+ {
+ trap_SendServerCommand( -1,
+ va( "cp \"^1Vampire\n^7Sudden Death in 60 seconds!%s%s\"",
+ ( g_vampireDeathInfo.string[ 0 ] ) ? "\n\n" : "",
+ g_vampireDeathInfo.string ) );
+ level.vampireDeathWarning = TW_IMMINENT;
+ }
+ else if( G_TimeTilVampireDeath( ) <= 300000 && level.vampireDeathWarning < TW_SOON )
+ {
+ trap_SendServerCommand( -1,
+ va ("cp \"^1Vampire\n^7Sudden Death in 5 minutes!%s%s\"",
+ ( g_vampireDeathInfo.string[ 0 ] ) ? "\n\n" : "",
+ g_vampireDeathInfo.string ) );
+ level.vampireDeathWarning = TW_SOON;
+ }
+ }
+
//set BP at each cycle
if( g_suddenDeath.integer )
{
@@ -1378,8 +1539,34 @@ void G_CalculateBuildPoints( void )
localATP = g_alienBuildPoints.integer;
}
- level.humanBuildPoints = level.humanBuildPointsPowered = localHTP;
- level.alienBuildPoints = localATP;
+ // Build Point Recovery
+ // each gained stage adds 50% delay
+ if( g_buildPointsRecoverRate.integer )
+ {
+ while( level.humanRecoverBuildPoints > 0 &&
+ level.humanRecoverTime < level.time )
+ {
+ level.humanRecoverBuildPoints--;
+ level.humanRecoverTime +=
+ ( 60000 + g_humanStage.integer * 30000 ) / g_buildPointsRecoverRate.integer;
+ }
+ while( level.alienRecoverBuildPoints > 0 &&
+ level.alienRecoverTime < level.time )
+ {
+ level.alienRecoverBuildPoints--;
+ level.alienRecoverTime +=
+ ( 60000 + g_alienStage.integer * 30000 ) / g_buildPointsRecoverRate.integer;
+ }
+ }
+ else
+ {
+ // recover may have been turned off, reset
+ level.humanRecoverBuildPoints = 0;
+ level.alienRecoverBuildPoints = 0;
+ }
+
+ level.humanBuildPoints = level.humanBuildPointsPowered = localHTP - level.humanRecoverBuildPoints;
+ level.alienBuildPoints = localATP - level.alienRecoverBuildPoints;
level.reactorPresent = qfalse;
level.overmindPresent = qfalse;
@@ -1392,6 +1579,9 @@ void G_CalculateBuildPoints( void )
if( ent->s.eType != ET_BUILDABLE )
continue;
+ if( ent->s.eFlags & EF_DEAD )
+ continue;
+
buildable = ent->s.modelindex;
if( buildable != BA_NONE )
@@ -1612,6 +1802,7 @@ void CalculateRanks( void )
level.numHumanClients = 0;
level.numLiveAlienClients = 0;
level.numLiveHumanClients = 0;
+ level.bleeders = 0;
for( i = 0; i < level.maxclients; i++ )
{
@@ -1644,6 +1835,9 @@ void CalculateRanks( void )
if( level.clients[ i ].sess.sessionTeam != TEAM_SPECTATOR )
level.numLiveHumanClients++;
}
+
+ if( level.clients[ i ].pers.bleeder )
+ level.bleeders++;
}
}
}
@@ -1940,7 +2134,7 @@ void QDECL G_AdminsPrintf( const char *fmt, ... )
for( j = 0; j < level.maxclients; j++ )
{
tempent = &g_entities[ j ];
- if( G_admin_permission( tempent, ADMF_ADMINCHAT ) &&
+ if( G_admin_permission( tempent, ADMF_ADMINCHAT) &&
!tempent->client->pers.ignoreAdminWarnings )
{
trap_SendServerCommand(tempent-g_entities,va( "print \"^6[Admins]^7 %s\"", string) );
@@ -1950,37 +2144,7 @@ void QDECL G_AdminsPrintf( const char *fmt, ... )
G_LogPrintf("%s",string);
}
-/*
-=================
-G_WarningsPrintf
-
-Print to everyone with a certain flag, and the logfile with a time stamp if it is open, and to the console
-(just a copy of the G_AdminsPrintf with flag suport)
-=================
-*/
-void QDECL G_WarningsPrintf( char *flag, const char *fmt, ... )
-{
- va_list argptr;
- char string[ 1024 ];
- gentity_t *tempent;
- int j;
-
- va_start( argptr, fmt );
- vsprintf( string, fmt,argptr );
- va_end( argptr );
- for( j = 0; j < level.maxclients; j++ )
- {
- tempent = &g_entities[ j ];
- if( G_admin_permission( tempent, flag ) )
- {
- trap_SendServerCommand(tempent-g_entities,va( "print \"^6[Warnings]^7 %s\"", string) );
- }
- }
-
- G_LogPrintf("%s",string);
-
-}
/*
=================
G_LogPrintf
@@ -2148,7 +2312,7 @@ void G_SendGameStat( pTeam_t team )
int ping;
cl = &level.clients[ level.sortedClients[ i ] ];
-
+
// Ignore invisible players
if ( cl->sess.invisible == qtrue )
continue;
@@ -2474,6 +2638,8 @@ void CheckVote( void )
{
int votePassThreshold=level.votePassThreshold;
int voteYesPercent;
+ int minVotes = 0;
+ qboolean pass = qfalse;
if( level.voteExecuteTime && level.voteExecuteTime < level.time )
{
@@ -2487,7 +2653,10 @@ void CheckVote( void )
{
G_admin_maplog_result( "m" );
}
-
+ else if( !Q_stricmpn( level.voteString, "!restart", 8 ) )
+ {
+ G_admin_maplog_result( "l" );
+ }
if( !Q_stricmp( level.voteString, "suddendeath" ) )
{
@@ -2512,6 +2681,13 @@ void CheckVote( void )
if( !level.voteTime )
return;
+ if( !Q_stricmpn( level.voteString, "ban", 3 ) )
+ {
+ minVotes = 3;
+ if( level.numConnectedClients < minVotes )
+ minVotes = level.numConnectedClients;
+ }
+
if( level.voteYes + level.voteNo > 0 )
voteYesPercent = (int)( 100 * ( level.voteYes ) / ( level.voteYes + level.voteNo ) );
else
@@ -2520,20 +2696,22 @@ void CheckVote( void )
if( ( level.time - level.voteTime >= VOTE_TIME ) ||
( level.voteYes + level.voteNo == level.numConnectedClients ) )
{
- if( voteYesPercent> votePassThreshold || level.voteNo == 0 )
+ if( level.voteYes + level.voteNo < minVotes )
+ {
+ // not enough voters
+ trap_SendServerCommand( -1, va( "print \"This vote type requires at least %d voters\n\"", minVotes ) );
+ pass = qfalse;
+ }
+ else if( voteYesPercent > votePassThreshold )
{
// execute the command, then remove the vote
- trap_SendServerCommand( -1, va("print \"Vote passed (%d - %d)\n\"",
- level.voteYes, level.voteNo ) );
- G_LogPrintf( "Vote: Vote passed (%d-%d)\n", level.voteYes, level.voteNo );
level.voteExecuteTime = level.time + 3000;
+ pass = qtrue;
}
else
{
// same behavior as a timeout
- trap_SendServerCommand( -1, va("print \"Vote failed (%d - %d)\n\"",
- level.voteYes, level.voteNo ) );
- G_LogPrintf( "Vote: Vote failed (%d - %d)\n", level.voteYes, level.voteNo );
+ pass = qfalse;
}
}
else
@@ -2542,18 +2720,14 @@ void CheckVote( void )
( (double) votePassThreshold/100.0 ) ) )
{
// execute the command, then remove the vote
- trap_SendServerCommand( -1, va("print \"Vote passed (%d - %d)\n\"",
- level.voteYes, level.voteNo ) );
- G_LogPrintf( "Vote: Vote passed (%d - %d)\n", level.voteYes, level.voteNo );
level.voteExecuteTime = level.time + 3000;
+ pass = qtrue;
}
else if( level.voteNo > (int)( (double) level.numConnectedClients *
( (double) ( 100.0-votePassThreshold )/ 100.0 ) ) )
{
// same behavior as a timeout
- trap_SendServerCommand( -1, va("print \"Vote failed (%d - %d)\n\"",
- level.voteYes, level.voteNo ) );
- G_LogPrintf("Vote failed\n");
+ pass = qfalse;
}
else
{
@@ -2562,6 +2736,22 @@ void CheckVote( void )
}
}
+ trap_SendServerCommand( -1,
+ va( "print \"Vote %s^7 (^2Y:%d^7-^1N:%d^7, %d percent) (%s)\n\"",
+ ( pass ) ? "^2passed" : "^1failed",
+ level.voteYes, level.voteNo, voteYesPercent,
+ level.voteDisplayString ) );
+
+ G_LogPrintf( "Vote: Vote %s (%d - %d)\n",
+ ( pass ) ? "passed" : "failed",
+ level.voteYes, level.voteNo );
+
+ G_admin_adminlog_log( NULL, "vote",
+ va( "%s^7 (^2Y:%d^7-^1N:%d^7, %d percent)",
+ ( pass ) ? "^2passed" : "^1failed",
+ level.voteYes, level.voteNo, voteYesPercent ),
+ 0, pass );
+
level.voteTime = 0;
trap_SetConfigstring( CS_VOTE_TIME, "" );
trap_SetConfigstring( CS_VOTE_STRING, "" );
@@ -2576,6 +2766,9 @@ CheckTeamVote
void CheckTeamVote( int team )
{
int cs_offset;
+ int votePassThreshold;
+ int voteYesPercent = 0;
+ qboolean pass = qfalse;
if ( team == PTE_HUMANS )
cs_offset = 0;
@@ -2584,38 +2777,44 @@ void CheckTeamVote( int team )
else
return;
+ votePassThreshold = level.teamVotePassThreshold[ cs_offset ];
+
if( !level.teamVoteTime[ cs_offset ] )
return;
+ if( ( level.teamVoteYes[ cs_offset ] + level.teamVoteNo[ cs_offset ] ) )
+ {
+ voteYesPercent = (100 * level.teamVoteYes[ cs_offset ]) /
+ (level.teamVoteYes[ cs_offset ] + level.teamVoteNo[ cs_offset ]);
+ }
+
if( level.time - level.teamVoteTime[ cs_offset ] >= VOTE_TIME )
{
- if( level.teamVoteYes[ cs_offset ] > level.teamVoteNo[ cs_offset ] && level.teamVoteYes[ cs_offset ] >= 2 )
+ if( voteYesPercent > votePassThreshold && level.teamVoteYes[ cs_offset ] >= 2 )
{
// execute the command, then remove the vote
- trap_SendServerCommand( -1, va("print \"Team vote passed (%d - %d)\n\"", level.teamVoteYes[ cs_offset ], level.teamVoteNo[ cs_offset ] ) );
trap_SendConsoleCommand( EXEC_APPEND, va( "%s\n", level.teamVoteString[ cs_offset ] ) );
+ pass = qtrue;
}
else
{
- trap_SendServerCommand( -1, va("print \"Team vote failed (%d - %d)\n\"", level.teamVoteYes[ cs_offset ], level.teamVoteNo[ cs_offset ] ) );
- G_LogPrintf( "Teamvote: Team vote failed (%d - %d)\n", level.teamVoteYes[ cs_offset ], level.teamVoteNo[ cs_offset ] );
+ pass = qfalse;
}
}
else
{
- if( level.teamVoteYes[ cs_offset ] > level.numteamVotingClients[ cs_offset ] / 2 )
+ if( level.teamVoteYes[ cs_offset ] > (int)((double)level.numteamVotingClients[ cs_offset ] *
+ (double)votePassThreshold/100.0) )
{
// execute the command, then remove the vote
- trap_SendServerCommand( -1, va("print \"Team vote passed (%d - %d)\n\"", level.teamVoteYes[ cs_offset ], level.teamVoteNo[ cs_offset ] ) );
- G_LogPrintf( "Teamvote: Team vote passed (%d - %d)\n", level.teamVoteYes[ cs_offset ], level.teamVoteNo[ cs_offset ] );
- //
trap_SendConsoleCommand( EXEC_APPEND, va( "%s\n", level.teamVoteString[ cs_offset ] ) );
+ pass = qtrue;
}
- else if( level.teamVoteNo[ cs_offset ] >= level.numteamVotingClients[ cs_offset ] / 2 )
+ else if( level.teamVoteNo[ cs_offset ] > (int)((double)level.numteamVotingClients[ cs_offset ] *
+ ((double)(100.0-votePassThreshold)/100.0)) )
{
// same behavior as a timeout
- trap_SendServerCommand( -1, va("print \"Team vote failed (%d - %d)\n\"", level.teamVoteYes[ cs_offset ], level.teamVoteNo[ cs_offset ] ) );
- G_LogPrintf( "Teamvote: Team vote failed (%d - %d)\n", level.teamVoteYes[ cs_offset ], level.teamVoteNo[ cs_offset ] );
+ pass = qfalse;
}
else
{
@@ -2624,11 +2823,70 @@ void CheckTeamVote( int team )
}
}
+ trap_SendServerCommand( -1,
+ va( "print \"Team vote %s^7 (^2Y:%d^7-^1N:%d^7, %d percent)\n\"",
+ ( pass ) ? "^2passed" : "^1failed",
+ level.teamVoteYes[ cs_offset ], level.teamVoteNo[ cs_offset ], voteYesPercent ) );
+
+ G_LogPrintf( "Teamvote: Team vote %s (%d - %d)\n",
+ ( pass ) ? "passed" : "failed",
+ level.teamVoteYes[ cs_offset ], level.teamVoteNo[ cs_offset ] );
+
+ G_admin_adminlog_log( NULL, "teamvote",
+ va( "%s^7 (^2Y:%d^7-^1N:%d^7, %d percent)",
+ ( pass ) ? "^2passed" : "^1failed",
+ level.teamVoteYes[ cs_offset ], level.teamVoteNo[ cs_offset ], voteYesPercent ),
+ 0, pass );
+
level.teamVoteTime[ cs_offset ] = 0;
trap_SetConfigstring( CS_TEAMVOTE_TIME + cs_offset, "" );
trap_SetConfigstring( CS_TEAMVOTE_STRING + cs_offset, "" );
}
+
+/*
+==================
+CheckIdleMap
+==================
+*/
+void CheckIdleMap( void )
+{
+ static int nextCheck = 0;
+ static int idleCount = 0;
+ static qboolean triggered = qfalse;
+
+ if( !g_idleMapSwitch.integer )
+ return;
+
+ if( triggered ||
+ nextCheck > level.time )
+ return;
+
+ nextCheck = level.time + 60000;
+ if( !level.numPlayingClients )
+ idleCount++;
+ else
+ idleCount = 0;
+
+ if( idleCount > g_idleMapSwitch.integer &&
+ !G_CurrentMapIsRotation() )
+ {
+ int newTL;
+
+ triggered = qtrue;
+
+ newTL = ( level.time - level.startTime ) / 60000;
+ newTL += 5;
+ if( !g_timelimit.integer || g_timelimit.integer > newTL )
+ {
+ trap_Cvar_Set( "timelimit", va( "%d", newTL ) );
+ trap_SendServerCommand( -1, va( "print \"Timelimit reduced due to idle server\n\"" ) );
+ G_LogPrintf( "Server is idle, timelimit reduced to %d\n", newTL );
+ }
+ }
+}
+
+
/*
==================
CheckMsgTimer
@@ -2723,6 +2981,60 @@ void CheckCountdown( void )
/*
==================
+G_CalculateDynamicBuildPoints
+==================
+*/
+static void G_CalculateDynamicBuildPoints( void )
+{
+ static int LastTime = 0;
+ int count = 0;
+ gentity_t *ent;
+ int bps;
+ int i;
+
+ if( !g_dynamicBuildPoints.integer )
+ return;
+
+ if( level.time - LastTime < 10000 )
+ return;
+
+ if( level.time - level.startTime < 30000 ||
+ !level.defaultAlienBuildPoints )
+ {
+ // remember default build points, after some time for exec commands
+ if( level.time - level.startTime > 1000 &&
+ level.defaultAlienBuildPoints == 0 )
+ {
+ level.defaultAlienBuildPoints = g_alienBuildPoints.integer;
+ level.defaultHumanBuildPoints = g_humanBuildPoints.integer;
+ }
+ return;
+ }
+
+ LastTime = level.time;
+
+ for( i = 0; i < level.maxclients; i++ )
+ {
+ ent = &g_entities[ i ];
+ if( ent && ent->client &&
+ ent->client->pers.connected == CON_CONNECTED &&
+ (ent->client->pers.teamSelection == PTE_ALIENS || ent->client->pers.teamSelection == PTE_HUMANS) )
+ {
+ count++;
+ }
+ }
+
+ bps = level.defaultAlienBuildPoints + count * g_dynamicBuildPoints.integer;
+ if( g_alienBuildPoints.integer < bps )
+ trap_Cvar_Set( "g_alienBuildPoints", va( "%d", bps ) );
+
+ bps = level.defaultHumanBuildPoints + count * g_dynamicBuildPoints.integer;
+ if( g_humanBuildPoints.integer < bps )
+ trap_Cvar_Set( "g_humanBuildPoints", va( "%d", bps ) );
+}
+
+/*
+==================
CheckCvars
==================
*/
@@ -2773,6 +3085,179 @@ void CheckCvars( void )
}
/*
+==================
+G_CheckVampireDeathBuildables
+==================
+*/
+static int G_VampireDeathKillBuildable( buildable_t buildable, int count )
+{
+ int i;
+ gentity_t *ent;
+ int n = 0;
+
+ for ( i = 1, ent = g_entities + i; i < level.num_entities; i++, ent++ )
+ {
+ if( ent->s.eType != ET_BUILDABLE )
+ continue;
+
+ if( ent->s.modelindex == buildable && ent->health > 0 )
+ {
+ G_Damage( ent, NULL, NULL, NULL, NULL, 10000, 0, MOD_SUICIDE );
+ n++;
+
+ if( count && n >= count )
+ return n;
+ }
+ }
+
+ return n;
+}
+
+static void G_CheckVampireDeathBuildables( void )
+{
+ static int LastAmmoTime = 0;
+ static int LastSuckTime = 0;
+ static int LastDestructTime = 0;
+ int i;
+ gentity_t *ent;
+ qboolean done = qtrue;
+
+ if( !level.vampireDeath )
+ return;
+
+ if( level.intermissionQueued ||
+ level.intermissiontime )
+ return;
+
+ // humans get more ammo every 20 seconds
+ if( level.time - LastAmmoTime >= 20000 )
+ {
+ LastAmmoTime = level.time;
+
+ for( i = 0; i < level.maxclients; i++ )
+ {
+ ent = g_entities + i;
+ if( !ent->inuse || ent->health <= 0 ||
+ ent->client->pers.connected != CON_CONNECTED)
+ continue;
+
+ if( ent->client->pers.teamSelection == PTE_HUMANS )
+ {
+ int ammo, clips, maxClips, maxAmmo;
+
+ BG_FindAmmoForWeapon( ent->client->ps.weapon, &maxAmmo, &maxClips );
+ BG_UnpackAmmoArray( ent->client->ps.weapon, ent->client->ps.ammo,
+ ent->client->ps.powerups, &ammo, &clips );
+
+ if( maxClips )
+ {
+ if( clips < maxClips )
+ clips++;
+ }
+ else
+ {
+ ammo += maxAmmo / 5;
+ if( ammo > maxAmmo )
+ ammo = maxAmmo;
+ }
+
+ BG_PackAmmoArray( ent->client->ps.weapon, ent->client->ps.ammo,
+ ent->client->ps.powerups, ammo, clips );
+ }
+ }
+ }
+
+ // health countdown
+ if( level.time - LastSuckTime >= 3000 )
+ {
+ int value;
+ int hp_rate;
+ int damage;
+
+ LastSuckTime = level.time;
+
+ // increase health removal each minute after 1
+ hp_rate = 1 + ( level.time - level.vampireDeathBeginTime ) / 60000;
+ if( hp_rate < 1 ) hp_rate = 1;
+ if( hp_rate > 10) hp_rate = 10;
+
+ for( i = 0; i < level.maxclients; i++ )
+ {
+ ent = g_entities + i;
+ if( !ent->inuse ||
+ ent->health <= 0 ||
+ !ent->client ||
+ ent->client->pers.connected != CON_CONNECTED ||
+ ent->client->sess.sessionTeam == TEAM_SPECTATOR ||
+ ( ent->client->pers.teamSelection != PTE_ALIENS && ent->client->pers.teamSelection != PTE_HUMANS ) )
+ continue;
+
+ value = BG_FindHealthForClass( ent->client->pers.classSelection );
+ if( value < 1 )
+ value = 1;
+ // death from full HP in 60s with damage every 3s, 1000 / 60 * 3 = 50
+ ent->client->pers.vampireSuckFraction += value * 50 * hp_rate;
+
+ damage = ent->client->pers.vampireSuckFraction / 1000;
+ ent->client->pers.vampireSuckFraction -= damage * 1000;
+
+ if ( ent->health > damage )
+ ent->health -= damage;
+ else
+ G_Damage( ent, NULL, NULL, NULL, NULL, damage,
+ DAMAGE_NO_ARMOR|DAMAGE_NO_KNOCKBACK|DAMAGE_NO_PROTECTION|DAMAGE_NO_LOCDAMAGE, MOD_SUICIDE );
+ }
+ }
+
+ // base self destruct
+ if( level.vampireDeath == 2 )
+ return;
+
+ if( level.time - LastDestructTime < 1000 )
+ return;
+
+ LastDestructTime = level.time;
+
+ if( level.numLiveAlienClients == 0 &&
+ level.numLiveHumanClients == 0 )
+ {
+ level.lastWin = PTE_NONE;
+ trap_SendServerCommand( -1, "print \"Timelimit hit\n\"" );
+ trap_SetConfigstring( CS_WINNER, "Stalemate" );
+ LogExit( "Timelimit hit." );
+ G_admin_maplog_result( "t" );
+ }
+
+ if( G_VampireDeathKillBuildable( BA_A_ACIDTUBE, 1 ) ||
+ G_VampireDeathKillBuildable( BA_A_HIVE, 1 ) ||
+ G_VampireDeathKillBuildable( BA_A_TRAPPER, 1 ) ||
+ G_VampireDeathKillBuildable( BA_A_BARRICADE, 1 ) ||
+ G_VampireDeathKillBuildable( BA_A_BOOSTER, 1 ) ||
+ G_VampireDeathKillBuildable( BA_A_SPAWN, 1 ) ||
+ G_VampireDeathKillBuildable( BA_A_OVERMIND, 1 ) )
+ {
+ done = qfalse;
+ }
+
+ if( G_VampireDeathKillBuildable( BA_H_MGTURRET, 1 ) ||
+ G_VampireDeathKillBuildable( BA_H_TESLAGEN, 1 ) ||
+ G_VampireDeathKillBuildable( BA_H_DCC, 1 ) ||
+ G_VampireDeathKillBuildable( BA_H_REPEATER, 1 ) ||
+ G_VampireDeathKillBuildable( BA_H_MEDISTAT, 1 ) ||
+ G_VampireDeathKillBuildable( BA_H_ARMOURY, 1 ) ||
+ G_VampireDeathKillBuildable( BA_H_SPAWN, 1 ) ||
+ G_VampireDeathKillBuildable( BA_H_REACTOR, 1 ) )
+ {
+ done = qfalse;
+ }
+
+ if( done )
+ {
+ level.vampireDeath = 2;
+ }
+}
+
+/*
=============
G_RunThink
@@ -2960,6 +3445,8 @@ void G_RunFrame( int levelTime )
ClientEndFrame( ent );
}
+ G_CheckVampireDeathBuildables();
+
// save position information for all active clients
G_UnlaggedStore( );
@@ -2974,8 +3461,11 @@ void G_RunFrame( int levelTime )
G_CalculateAvgPlayers( );
G_UpdateZaps( msec );
+ G_CalculateDynamicBuildPoints( );
+
// see if it is time to end the level
CheckExitRules( );
+ CheckIdleMap( );
// update to team status?
CheckTeamStatus( );