summaryrefslogtreecommitdiff
path: root/src/game/g_combat.c
diff options
context:
space:
mode:
authorPaweł Redman <pawel@redman.xyz>2017-04-13 11:30:00 +0000
committer/dev/humancontroller <devhc@example.com>2017-04-15 12:06:43 +0200
commit5ad9e26c3be1f2ebc6cdb340b685aef30ae16db7 (patch)
tree5ee97c52196122bd8356ad8e09403332e7712fcd /src/game/g_combat.c
parent45973dc48641365b31475733bce7af9c3b8603a6 (diff)
import the cQVM game module
replacing the existing one
Diffstat (limited to 'src/game/g_combat.c')
-rw-r--r--src/game/g_combat.c238
1 files changed, 234 insertions, 4 deletions
diff --git a/src/game/g_combat.c b/src/game/g_combat.c
index 0cc079a..0d8d013 100644
--- a/src/game/g_combat.c
+++ b/src/game/g_combat.c
@@ -138,6 +138,7 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
float percentDamage = 0.0f;
gentity_t *player;
qboolean tk = qfalse;
+ int spreeRate = 0;
if( self->client->ps.pm_type == PM_DEAD )
@@ -163,6 +164,7 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
if( attacker != self && attacker->client->ps.stats[ STAT_PTEAM ] == self->client->ps.stats[ STAT_PTEAM ] )
{
attacker->client->pers.statscounters.teamkills++;
+ attacker->client->pers.karma -= 300;
if( attacker->client->pers.teamSelection == PTE_ALIENS )
{
level.alienStatsCounters.teamkills++;
@@ -205,6 +207,16 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ )
BG_DeactivateUpgrade( i, self->client->ps.stats );
+ // killing spree over
+ if( self->client->pers.statscounters.spreekills == -1 )
+ {
+ spreeRate = 2;
+ trap_SendServerCommand( -1,
+ va( "print \"%s^7's killing spree has come to an end\n\"",
+ self->client->pers.netname ) );
+ }
+ self->client->pers.statscounters.spreekills = 0;
+
if( meansOfDeath == MOD_SLAP )
{
trap_SendServerCommand( -1,
@@ -233,13 +245,14 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
va( "cp \"You killed ^1TEAMMATE^7 %s\"", self->client->pers.netname ) );
G_LogOnlyPrintf("%s^7 was killed by ^1TEAMMATE^7 %s^7 (Did %d damage to %d max)\n",
self->client->pers.netname, attacker->client->pers.netname, self->client->tkcredits[ attacker->s.number ], self->client->ps.stats[ STAT_MAX_HEALTH ] );
- G_TeamKill_Repent( attacker );
+ G_admin_tklog_log( attacker, self, meansOfDeath );
}
self->enemy = attacker;
self->client->ps.persistant[ PERS_KILLED ]++;
self->client->pers.statscounters.deaths++;
+ self->client->pers.karma -= 10;
if( self->client->pers.teamSelection == PTE_ALIENS )
{
level.alienStatsCounters.deaths++;
@@ -280,6 +293,7 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
attacker->client->lastKillTime = level.time;
attacker->client->pers.statscounters.kills++;
+ attacker->client->pers.karma += 50;
if( attacker->client->pers.teamSelection == PTE_ALIENS )
{
level.alienStatsCounters.kills++;
@@ -288,11 +302,26 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
{
level.humanStatsCounters.kills++;
}
+
+ if( g_killingSpree.integer > 2 )
+ {
+ if( attacker->client->pers.statscounters.spreekills >= 0 )
+ attacker->client->pers.statscounters.spreekills += 60;
+ if( attacker->client->pers.statscounters.spreekills > ( g_killingSpree.integer - 1 ) * 60 )
+ {
+ attacker->client->pers.statscounters.spreekills = -1;
+ attacker->client->pers.karma += 50;
+ trap_SendServerCommand( -1,
+ va( "print \"%s^3 is on a killing spree! killer gets a double reward bonus\n\"",
+ attacker->client->pers.netname ) );
+ }
+ }
}
if( attacker == self )
{
attacker->client->pers.statscounters.suicides++;
+ attacker->client->pers.karma -= 100;
if( attacker->client->pers.teamSelection == PTE_ALIENS )
{
level.alienStatsCounters.suicides++;
@@ -441,7 +470,16 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
if( g_alienStage.integer < 2 )
{
self->client->pers.statscounters.feeds++;
+ self->client->pers.karma -= 25;
level.humanStatsCounters.feeds++;
+
+ if( g_feedingSpree.integer &&
+ level.reactorPresent &&
+ !G_BuildableRange( self->client->ps.origin, 600, BA_H_REACTOR ) &&
+ !G_BuildableRange( self->client->ps.origin, 200, BA_H_SPAWN ) )
+ {
+ self->client->pers.statscounters.spreefeeds += SPREE_FEED_VALUE;
+ }
}
}
else if( self->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS )
@@ -450,7 +488,16 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
if( g_humanStage.integer < 2 )
{
self->client->pers.statscounters.feeds++;
+ self->client->pers.karma -= 25;
level.alienStatsCounters.feeds++;
+
+ if( g_feedingSpree.integer &&
+ level.overmindPresent &&
+ !G_BuildableRange( self->client->ps.origin, 600, BA_A_OVERMIND ) &&
+ !G_BuildableRange( self->client->ps.origin, 200, BA_A_SPAWN ) )
+ {
+ self->client->pers.statscounters.spreefeeds += SPREE_FEED_VALUE;
+ }
}
}
}
@@ -482,6 +529,9 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
level.humanStatsCounters.assists++;
}
+ if( spreeRate && player == attacker )
+ percentDamage *= (float)spreeRate;
+
//add credit
G_AddCreditToClient( player->client,
(int)( classValue * percentDamage ), qtrue );
@@ -516,6 +566,7 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
if( percentDamage > 0 && percentDamage < 1)
{
player->client->pers.statscounters.assists++;
+ player->client->pers.karma += 25;
level.alienStatsCounters.assists++;
}
@@ -524,7 +575,10 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
if( frags > 0 )
{
//add kills
- G_AddCreditToClient( player->client, frags, qtrue );
+ if( spreeRate && player == attacker )
+ G_AddCreditToClient( player->client, frags * spreeRate, qtrue );
+ else
+ G_AddCreditToClient( player->client, frags, qtrue );
//can't revist this account later
self->credits[ i ] = 0;
@@ -565,7 +619,10 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
player = g_entities + topClient;
//add kills
- G_AddCreditToClient( player->client, 1, qtrue );
+ if( spreeRate && player == attacker )
+ G_AddCreditToClient( player->client, spreeRate, qtrue );
+ else
+ G_AddCreditToClient( player->client, 1, qtrue );
//can't revist this account again
self->credits[ topClient ] = 0;
@@ -618,6 +675,38 @@ finish_dying: // from MOD_SLAP
// g_forcerespawn may force spawning at some later time
self->client->respawnTime = level.time + 1700;
+ if( g_feedingSpree.integer )
+ {
+ int maxfeed;
+
+ maxfeed = g_feedingSpree.integer * SPREE_FEED_VALUE;
+ if( self->client->pers.statscounters.spreefeeds > maxfeed )
+ {
+ self->client->respawnTime += SPREE_FEED_DELAY * (self->client->pers.statscounters.spreefeeds - maxfeed );
+ self->client->pers.karma -= 20;
+ trap_SendServerCommand( self->client->ps.clientNum,
+ va( "print \"You are on a feeding spree! respawn delayed %d seconds\n\"",
+ (self->client->respawnTime - level.time) / 1000 ) );
+ }
+ }
+
+ if( self->client->pers.bleeder )
+ {
+ int spreeLength;
+
+ spreeLength = self->client->pers.statscounters.spreebleeds / 10;
+ self->client->respawnTime += 9 * 1000;
+
+ trap_SendServerCommand( self->client->ps.clientNum,
+ va( "print \"^3Bleeding has made you an enemy of your own base for ^7%d:%02d\n^1Respawn delayed ^7%d^1 seconds\n",
+ spreeLength / 60, spreeLength % 60,
+ ( self->client->respawnTime - level.time) / 1000 ) );
+ trap_SendServerCommand( self->client->ps.clientNum,
+ va( "cp \"^3Bleeding made you an enemy of your own base!\n\n^7for %d:%02d\n\n^1Respawn delayed %d seconds\"",
+ spreeLength / 60, spreeLength % 60,
+ ( self->client->respawnTime - level.time) / 1000 ) );
+ }
+
// remove powerups
memset( self->client->ps.powerups, 0, sizeof( self->client->ps.powerups ) );
@@ -1013,6 +1102,7 @@ static float G_CalcDamageModifier( vec3_t point, gentity_t *targ, gentity_t *att
if( attacker && attacker->client && modifier == 2 )
{
attacker->client->pers.statscounters.headshots++;
+ attacker->client->pers.karma += 5;
level.alienStatsCounters.headshots++;
}
@@ -1149,7 +1239,7 @@ dflags these flags are used to control how T_Damage works
void G_SelectiveDamage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
vec3_t dir, vec3_t point, int damage, int dflags, int mod, int team )
{
- if( targ->client && ( team != targ->client->ps.stats[ STAT_PTEAM ] ) )
+ if( targ->client && ( team != targ->client->ps.stats[ STAT_PTEAM ] || targ->client->pers.bleeder ) )
G_Damage( targ, inflictor, attacker, dir, point, damage, dflags, mod );
}
@@ -1398,6 +1488,7 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
targ->client->lastPoisonTime = level.time;
targ->client->lastPoisonClient = attacker;
attacker->client->pers.statscounters.repairspoisons++;
+ attacker->client->pers.karma += 1;
level.alienStatsCounters.repairspoisons++;
}
}
@@ -1429,6 +1520,8 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
if( targ->biteam == attacker->client->pers.teamSelection || OnSameTeam( targ, attacker ) )
{
attacker->client->pers.statscounters.ffdmgdone += takeNoOverkill;
+ if( attacker != targ )
+ attacker->client->pers.karma -= take;
if( attacker->client->pers.teamSelection == PTE_ALIENS )
{
level.alienStatsCounters.ffdmgdone+=takeNoOverkill;
@@ -1437,10 +1530,88 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
{
level.humanStatsCounters.ffdmgdone+=takeNoOverkill;
}
+
+ // bleeding spree
+ if( g_bleedingSpree.integer > 1 && attacker != targ &&
+ mod != MOD_SUICIDE && mod != MOD_TELEFRAG )
+ {
+ attacker->client->pers.statscounters.spreebleeds += take;
+
+ if( g_bleedingSpreeKick.integer == 2 )
+ {
+ if( attacker->client->pers.statscounters.spreebleeds > g_bleedingSpree.integer * 100 )
+ {
+ char buf[ MAX_STRING_CHARS ];
+
+ G_admin_autorevert( attacker );
+
+ Com_sprintf( buf, sizeof( buf ),
+ "%s^7 moved from %s to spectators due to excessive team damage\n",
+ attacker->client->pers.netname,
+ ( attacker->client->pers.teamSelection == PTE_ALIENS ) ? "aliens" : "humans" );
+ trap_SendServerCommand( -1, va( "print \"%s\"", buf ) );
+ G_LogOnlyPrintf( "Teamkilling: %s", buf );
+
+ G_admin_tklog_log( attacker, NULL, mod );
+
+ trap_SendConsoleCommand( EXEC_APPEND, va( "!putteam %d s %s\n", attacker - g_entities, g_adminTempSpec.string ) );
+ attacker->client->pers.statscounters.spreebleeds = 0;
+ }
+ else if( attacker->client->pers.statscounters.spreebleeds > g_bleedingSpree.integer * 66 &&
+ attacker->client->pers.bleederLastWarn + 20 * 1000 < level.time )
+ {
+ attacker->client->pers.bleederLastWarn = level.time;
+ trap_SendServerCommand( attacker - g_entities,
+ "print \"^3Please do not damage your teammates or your base\n\"" );
+ trap_SendServerCommand( attacker - g_entities,
+ "cp \"^1Please do not damage your teammates or your base\"" );
+ }
+ }
+ else if( g_bleedingSpreeKick.integer && attacker->client->pers.bleeder &&
+ attacker->client->pers.statscounters.spreebleeds > g_bleedingSpree.integer * 100 + g_bleedingSpree.integer * 20 )
+ {
+ trap_SendConsoleCommand( EXEC_APPEND,
+ va("!kick %d auto-kick for team bleeding\n", ( attacker - g_entities )) );
+ attacker->client->pers.statscounters.spreebleeds = -9000;
+ }
+ else if( attacker->client->pers.statscounters.spreebleeds > g_bleedingSpree.integer * 100 &&
+ !attacker->client->pers.bleeder )
+ {
+ attacker->client->pers.bleeder = qtrue;
+ attacker->client->pers.karma -= 500;
+ level.bleeders++;
+ trap_SendServerCommand( -1,
+ va( "print \"%s^3 has become an enemy of their own base\n\"",
+ attacker->client->pers.netname ) );
+ trap_SendServerCommand( attacker - g_entities,
+ "cp \"^1Your team bleeding has irritated your base!\"" );
+
+ G_admin_tklog_log( attacker, NULL, mod );
+
+ if( g_bleedingSpreeKick.integer )
+ trap_SendServerCommand( attacker - g_entities,
+ "print \"^1Continued bleeding will result in kick\n\"" );
+ }
+ else if( attacker->client->pers.statscounters.spreebleeds > g_bleedingSpree.integer * 66 &&
+ !attacker->client->pers.bleeder &&
+ attacker->client->pers.bleederLastWarn + 20 * 1000 < level.time )
+ {
+ attacker->client->pers.bleederLastWarn = level.time;
+ trap_SendServerCommand( attacker - g_entities,
+ "print \"^3Your bleeding is close to aggravating your base!\n\"" );
+ trap_SendServerCommand( attacker - g_entities,
+ "cp \"^1Your bleeding is close to aggravating your base!\"" );
+
+ if( g_bleedingSpreeKick.integer )
+ trap_SendServerCommand( attacker - g_entities,
+ "print \"^1Continued bleeding will result in kick\n\"" );
+ }
+ }
}
else if( targ->s.eType == ET_BUILDABLE )
{
attacker->client->pers.statscounters.structdmgdone += takeNoOverkill;
+ attacker->client->pers.karma += ( take / 10 );
if( attacker->client->pers.teamSelection == PTE_ALIENS )
{
@@ -1454,6 +1625,7 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
if( targ->health > 0 && ( targ->health - take ) <=0 )
{
attacker->client->pers.statscounters.structskilled++;
+ attacker->client->pers.karma += 10;
if( attacker->client->pers.teamSelection == PTE_ALIENS )
{
level.alienStatsCounters.structskilled++;
@@ -1461,12 +1633,27 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
else if( attacker->client->pers.teamSelection == PTE_HUMANS )
{
level.humanStatsCounters.structskilled++;
+
+ if( attacker->client->pers.statscounters.spreefeeds )
+ {
+ attacker->client->pers.statscounters.spreefeeds -= take;
+ if( attacker->client->pers.statscounters.spreefeeds < 0 )
+ attacker->client->pers.statscounters.spreefeeds = 0;
+ }
+
+ if( attacker->client->pers.statscounters.spreebleeds > 10 )
+ {
+ attacker->client->pers.statscounters.spreebleeds -= take / 3;
+ if( attacker->client->pers.statscounters.spreebleeds < 10 )
+ attacker->client->pers.statscounters.spreebleeds = 10;
+ }
}
}
}
else if( targ->client )
{
attacker->client->pers.statscounters.dmgdone +=takeNoOverkill;
+ attacker->client->pers.karma += ( take / 10 );
attacker->client->pers.statscounters.hits++;
if( attacker->client->pers.teamSelection == PTE_ALIENS )
{
@@ -1476,9 +1663,52 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
{
level.humanStatsCounters.dmgdone+=takeNoOverkill;
}
+
+ if( attacker->client->pers.statscounters.spreefeeds )
+ {
+ attacker->client->pers.statscounters.spreefeeds -= take;
+ if( attacker->client->pers.statscounters.spreefeeds < 0 )
+ attacker->client->pers.statscounters.spreefeeds = 0;
+ }
+
+ if( attacker->client->pers.statscounters.spreebleeds > 10 )
+ {
+ attacker->client->pers.statscounters.spreebleeds -= take / 3;
+ if( attacker->client->pers.statscounters.spreebleeds < 10 )
+ attacker->client->pers.statscounters.spreebleeds = 10;
+ }
}
}
+ if( g_vampireDeath.integer && targ->client && attacker->client && targ != attacker )
+ {
+ if( OnSameTeam( targ, attacker ) )
+ {
+ if( mod == MOD_GRENADE )
+ return;
+
+ if( take > attacker->health )
+ take = attacker->health;
+
+ attacker->health -= take;
+ attacker->client->ps.stats[ STAT_HEALTH ] = attacker->health;
+ attacker->lastDamageTime = level.time;
+
+ if( attacker->health <= 0 )
+ {
+ if( attacker->health < -999 )
+ attacker->health = -999;
+ attacker->die( attacker, attacker, attacker, take, MOD_SUICIDE );
+ }
+
+ take = 0 - take;
+ }
+ else
+ {
+ attacker->health += takeNoOverkill;
+ attacker->client->ps.stats[ STAT_HEALTH ] = attacker->health;
+ }
+ }
//Do the damage
targ->health = targ->health - take;