summaryrefslogtreecommitdiff
path: root/src/game
diff options
context:
space:
mode:
Diffstat (limited to 'src/game')
-rw-r--r--src/game/bg_pmove.c5
-rw-r--r--src/game/g_buildable.c126
-rw-r--r--src/game/g_cmds.c17
-rw-r--r--src/game/g_combat.c3
-rw-r--r--src/game/g_local.h2
-rw-r--r--src/game/g_missile.c2
-rw-r--r--src/game/g_utils.c10
-rw-r--r--src/game/g_weapon.c4
-rw-r--r--src/game/tremulous.h2
9 files changed, 71 insertions, 100 deletions
diff --git a/src/game/bg_pmove.c b/src/game/bg_pmove.c
index d2c8acc5..e041ba26 100644
--- a/src/game/bg_pmove.c
+++ b/src/game/bg_pmove.c
@@ -835,7 +835,7 @@ static qboolean PM_CheckDodge( void )
vec3_t right, forward, velocity = { 0.0f, 0.0f, 0.0f };
float jump;
int i;
-
+
if( pm->ps->stats[ STAT_PTEAM ] != PTE_HUMANS )
return qfalse;
@@ -848,8 +848,7 @@ static qboolean PM_CheckDodge( void )
}
// Reasons to stop a sprint
- if( pm->cmd.forwardmove <= 0 ||
- pm->cmd.upmove < 0 ||
+ if( pm->cmd.forwardmove <= 0 || pm->cmd.upmove < 0 ||
pm->ps->pm_type != PM_NORMAL )
pm->ps->stats[ STAT_STATE ] &= ~SS_SPEEDBOOST;
diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c
index 1ef65f43..96a8face 100644
--- a/src/game/g_buildable.c
+++ b/src/game/g_buildable.c
@@ -488,8 +488,7 @@ static void G_CreepSlow( gentity_t *self )
enemy = &g_entities[ entityList[ i ] ];
if( enemy->client && enemy->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS &&
- enemy->client->ps.groundEntityNum != ENTITYNUM_NONE &&
- G_Visible( self, enemy ) )
+ enemy->client->ps.groundEntityNum != ENTITYNUM_NONE )
{
enemy->client->ps.stats[ STAT_STATE ] |= SS_CREEPSLOWED;
enemy->client->lastCreepSlowTime = level.time;
@@ -1082,7 +1081,7 @@ void AAcidTube_Think( gentity_t *self )
{
enemy = &g_entities[ entityList[ i ] ];
- if( !G_Visible( self, enemy ) )
+ if( !G_Visible( self, enemy, CONTENTS_SOLID ) )
continue;
if( enemy->client && enemy->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS )
@@ -1109,8 +1108,44 @@ void AAcidTube_Think( gentity_t *self )
//==================================================================================
+/*
+================
+AHive_CheckTarget
+
+Returns true and fires the hive missile if the target is valid
+================
+*/
+static qboolean AHive_CheckTarget( gentity_t *self, gentity_t *enemy )
+{
+ trace_t trace;
+ vec3_t tip_origin, dirToTarget;
+
+ // Check if this is a valid target
+ if( enemy->health <= 0 || !enemy->client ||
+ enemy->client->ps.stats[ STAT_PTEAM ] != PTE_HUMANS )
+ return qfalse;
+
+ // Check if the tip of the hive can see the target
+ VectorMA( self->s.pos.trBase, self->r.maxs[ 2 ], self->s.origin2,
+ tip_origin );
+ trap_Trace( &trace, tip_origin, NULL, NULL, enemy->s.pos.trBase,
+ self->s.number, MASK_SHOT );
+ if( trace.fraction < 1.0f && trace.entityNum != enemy->s.number )
+ return qfalse;
+
+ self->active = qtrue;
+ self->target_ent = enemy;
+ self->timestamp = level.time + HIVE_REPEAT;
+ VectorSubtract( enemy->s.pos.trBase, self->s.pos.trBase, dirToTarget );
+ VectorNormalize( dirToTarget );
+ vectoangles( dirToTarget, self->turretAim );
+ // Fire at target
+ FireWeapon( self );
+ G_SetBuildableAnim( self, BANIM_ATTACK1, qfalse );
+ return qtrue;
+}
/*
================
@@ -1121,53 +1156,30 @@ Think function for Alien Hive
*/
void AHive_Think( gentity_t *self )
{
- int entityList[ MAX_GENTITIES ];
- vec3_t range = { HIVE_SENSE_RANGE, HIVE_SENSE_RANGE, HIVE_SENSE_RANGE };
- vec3_t mins, maxs;
- int i, num;
- gentity_t *enemy;
- vec3_t dirToTarget;
-
self->powered = G_IsOvermindBuilt( );
self->nextthink = level.time + BG_FindNextThinkForBuildable( self->s.modelindex );
- VectorAdd( self->s.origin, range, maxs );
- VectorSubtract( self->s.origin, range, mins );
-
AGeneric_CreepCheck( self );
+ // Hive missile hasn't returned in HIVE_REPEAT seconds, forget about it
if( self->timestamp < level.time )
- self->active = qfalse; //nothing has returned in HIVE_REPEAT seconds, forget about it
+ self->active = qfalse;
+ // Find a target to attack
if( self->spawned && !self->active && G_FindOvermind( self ) )
{
- //do some damage
+ int i, num, entityList[ MAX_GENTITIES ];
+ vec3_t mins, maxs,
+ range = { HIVE_SENSE_RANGE, HIVE_SENSE_RANGE, HIVE_SENSE_RANGE };
+
+ VectorAdd( self->s.origin, range, maxs );
+ VectorSubtract( self->s.origin, range, mins );
num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES );
+
for( i = 0; i < num; i++ )
{
- enemy = &g_entities[ entityList[ i ] ];
-
- if( enemy->health <= 0 )
- continue;
-
- if( !G_Visible( self, enemy ) )
- continue;
-
- if( enemy->client && enemy->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS )
- {
- self->active = qtrue;
- self->target_ent = enemy;
- self->timestamp = level.time + HIVE_REPEAT;
-
- VectorSubtract( enemy->s.pos.trBase, self->s.pos.trBase, dirToTarget );
- VectorNormalize( dirToTarget );
- vectoangles( dirToTarget, self->turretAim );
-
- //fire at target
- FireWeapon( self );
- G_SetBuildableAnim( self, BANIM_ATTACK1, qfalse );
+ if( AHive_CheckTarget( self, g_entities + entityList[ i ] ) )
return;
- }
}
}
}
@@ -1181,22 +1193,9 @@ pain function for Alien Hive
*/
void AHive_Pain( gentity_t *self, gentity_t *attacker, int damage )
{
- if( attacker && attacker->client && attacker->biteam == BIT_HUMANS &&
- self->spawned && !self->active && G_FindOvermind( self ) )
- {
- vec3_t dirToTarget;
+ if( !self->active )
+ AHive_CheckTarget( self, attacker );
- self->active = qtrue;
- self->target_ent = attacker;
- self->timestamp = level.time + HIVE_REPEAT;
-
- VectorSubtract( attacker->s.pos.trBase, self->s.pos.trBase, dirToTarget );
- VectorNormalize( dirToTarget );
- vectoangles( dirToTarget, self->turretAim );
-
- //fire at target
- FireWeapon( self );
- }
G_SetBuildableAnim( self, BANIM_PAIN1, qfalse );
}
@@ -2164,6 +2163,7 @@ void HMGTurret_Think( gentity_t *self )
if( !HMGTurret_CheckTarget( self, self->enemy, qtrue ) )
{
self->active = qfalse;
+ self->turretSpinupTime = -1;
HMGTurret_FindEnemy( self );
}
if( !self->enemy )
@@ -2173,33 +2173,17 @@ void HMGTurret_Think( gentity_t *self )
if( !HMGTurret_TrackEnemy( self ) )
{
self->active = qfalse;
+ self->turretSpinupTime = -1;
return;
}
// Update spin state
if( !self->active && self->count < level.time )
{
- int spinTime;
-
self->active = qtrue;
- spinTime = level.time - self->turretSpinupTime - MGTURRET_SPIN_DURATION;
- if( spinTime <= 0 )
- {
- // Still has residual spin
- self->turretSpinupTime = level.time;
- }
- else if( spinTime < MGTURRET_SPINDOWN_TIME )
- {
- // Hasn't completely spun-down
- self->turretSpinupTime = level.time + spinTime;
- }
- else
- {
- // Needs a full spin-up
- self->turretSpinupTime = level.time + MGTURRET_SPINUP_TIME;
- G_AddEvent( self, EV_MGTURRET_SPINUP, 0 );
- }
+ self->turretSpinupTime = level.time + MGTURRET_SPINUP_TIME;
+ G_AddEvent( self, EV_MGTURRET_SPINUP, 0 );
}
// Not firing or haven't spun up yet
diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c
index 56f8e8eb..0a0d7343 100644
--- a/src/game/g_cmds.c
+++ b/src/game/g_cmds.c
@@ -2291,21 +2291,7 @@ void Cmd_Sell_f( gentity_t *ent )
BG_RemoveUpgradeFromInventory( i, ent->client->ps.stats );
if( i == UP_BATTPACK )
- {
- int j;
-
- //remove energy
- for( j = WP_NONE; j < WP_NUM_WEAPONS; j++ )
- {
- if( BG_InventoryContainsWeapon( j, ent->client->ps.stats ) &&
- BG_FindUsesEnergyForWeapon( j ) &&
- !BG_FindInfinteAmmoForWeapon( j ) )
- {
- ent->client->ps.ammo = 0;
- ent->client->ps.clips = 0;
- }
- }
- }
+ G_GiveClientMaxAmmo( ent, qtrue );
//add to funds
G_AddCreditToClient( ent->client, (short)BG_FindPriceForUpgrade( i ), qfalse );
@@ -2526,6 +2512,7 @@ void G_FollowLockView( gentity_t *ent )
ent->client->ps.stats[ STAT_STATE ] &= ~SS_WALLCLIMBINGCEILING;
ent->client->ps.stats[ STAT_VIEWLOCK ] = 0;
ent->client->ps.eFlags &= ~EF_WALLCLIMB;
+ ent->client->ps.eFlags ^= EF_TELEPORT_BIT;
ent->client->ps.viewangles[ PITCH ] = 0.0f;
// Put the view at the team spectator lock position
diff --git a/src/game/g_combat.c b/src/game/g_combat.c
index 74b8b141..a347b921 100644
--- a/src/game/g_combat.c
+++ b/src/game/g_combat.c
@@ -1018,7 +1018,8 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
// base is under attack warning if DCC'd
if( targ->biteam == BIT_HUMANS && G_FindDCC( targ ) &&
- level.time > level.humanBaseAttackTimer )
+ level.time > level.humanBaseAttackTimer &&
+ mod != MOD_DECONSTRUCT && mod != MOD_SUICIDE )
{
level.humanBaseAttackTimer = level.time + DC_ATTACK_PERIOD;
G_BroadcastEvent( EV_DCC_ATTACK, 0 );
diff --git a/src/game/g_local.h b/src/game/g_local.h
index 0c2e6d7d..6071a26f 100644
--- a/src/game/g_local.h
+++ b/src/game/g_local.h
@@ -810,7 +810,7 @@ void G_TriggerMenu( int clientNum, dynMenu_t menu );
void G_TriggerMenu2( int clientNum, dynMenu_t menu, int arg );
void G_CloseMenus( int clientNum );
-qboolean G_Visible( gentity_t *ent1, gentity_t *ent2 );
+qboolean G_Visible( gentity_t *ent1, gentity_t *ent2, int contents );
gentity_t *G_ClosestEnt( vec3_t origin, gentity_t **entities, int numEntities );
//
diff --git a/src/game/g_missile.c b/src/game/g_missile.c
index 4d5a751a..9e9a76e5 100644
--- a/src/game/g_missile.c
+++ b/src/game/g_missile.c
@@ -633,7 +633,7 @@ gentity_t *fire_hive( gentity_t *self, vec3_t start, vec3_t dir )
bolt->nextthink = level.time + HIVE_DIR_CHANGE_PERIOD;
bolt->think = AHive_SearchAndDestroy;
bolt->s.eType = ET_MISSILE;
- bolt->s.eFlags |= EF_BOUNCE|EF_NO_BOUNCE_SOUND;
+ bolt->s.eFlags |= EF_BOUNCE | EF_NO_BOUNCE_SOUND;
bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN;
bolt->s.weapon = WP_HIVE;
bolt->s.generic1 = WPM_PRIMARY; //weaponMode
diff --git a/src/game/g_utils.c b/src/game/g_utils.c
index 926a7cd2..5280432b 100644
--- a/src/game/g_utils.c
+++ b/src/game/g_utils.c
@@ -775,16 +775,14 @@ G_Visible
Test for a LOS between two entities
===============
*/
-qboolean G_Visible( gentity_t *ent1, gentity_t *ent2 )
+qboolean G_Visible( gentity_t *ent1, gentity_t *ent2, int contents )
{
trace_t trace;
- trap_Trace( &trace, ent1->s.pos.trBase, NULL, NULL, ent2->s.pos.trBase, ent1->s.number, MASK_SHOT );
+ trap_Trace( &trace, ent1->s.pos.trBase, NULL, NULL, ent2->s.pos.trBase,
+ ent1->s.number, contents );
- if( trace.contents & CONTENTS_SOLID )
- return qfalse;
-
- return qtrue;
+ return trace.fraction >= 1.0f || trace.entityNum == ent2 - g_entities;
}
/*
diff --git a/src/game/g_weapon.c b/src/game/g_weapon.c
index f5a118fa..5230d982 100644
--- a/src/game/g_weapon.c
+++ b/src/game/g_weapon.c
@@ -1536,6 +1536,10 @@ void FireWeapon( gentity_t *ent )
{
AngleVectors( ent->turretAim, forward, right, up );
VectorCopy( ent->s.pos.trBase, muzzle );
+
+ // Hive muzzle point is on the tip
+ if( ent->s.eType == ET_BUILDABLE && ent->s.modelindex == BA_A_HIVE )
+ VectorMA( muzzle, ent->r.maxs[ 2 ], ent->s.origin2, muzzle );
}
// fire the specific weapon
diff --git a/src/game/tremulous.h b/src/game/tremulous.h
index 585abe5d..b0d3cb8e 100644
--- a/src/game/tremulous.h
+++ b/src/game/tremulous.h
@@ -565,8 +565,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define MGTURRET_SPREAD 200
#define MGTURRET_DMG HDM(8)
#define MGTURRET_SPINUP_TIME 750 // time between target sighted and fire
-#define MGTURRET_SPIN_DURATION 50 // time that the turret stays spun-up
-#define MGTURRET_SPINDOWN_TIME 50 // time to return to idle state after a spinup
#define MGTURRET_VALUE HBVM(MGTURRET_BP)
#define TESLAGEN_BP 10