diff options
Diffstat (limited to 'src/game/g_main.c')
-rw-r--r-- | src/game/g_main.c | 708 |
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( ); |