diff options
Diffstat (limited to 'src/game')
-rw-r--r-- | src/game/bg_pmove.c | 5 | ||||
-rw-r--r-- | src/game/g_buildable.c | 126 | ||||
-rw-r--r-- | src/game/g_cmds.c | 17 | ||||
-rw-r--r-- | src/game/g_combat.c | 3 | ||||
-rw-r--r-- | src/game/g_local.h | 2 | ||||
-rw-r--r-- | src/game/g_missile.c | 2 | ||||
-rw-r--r-- | src/game/g_utils.c | 10 | ||||
-rw-r--r-- | src/game/g_weapon.c | 4 | ||||
-rw-r--r-- | src/game/tremulous.h | 2 |
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 |