summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Levin <risujin@fastmail.fm>2009-10-03 11:19:05 +0000
committerTim Angus <tim@ngus.net>2013-01-03 00:14:52 +0000
commit5e46c5258c1999af57f2589a6cead5682af6ca5d (patch)
tree7f1ded1b916f9a74212f5bb169a40508675dc654 /src
parent16289f1b853e5da3f944045e191d465857110fad (diff)
* Turrets are smarter and will fire if they can hit their target rather than when perfectly aligned
* Also added two turret params: spin duration and spin down time which give finer control over turret behavior (set their values to minimum) * Fixed some patch problems, spacing and duplicate code * Fixed Sprint/Dodge binding through menu * Tutorial text size shrunk * ALL clients lose their credits entirely when switching teams
Diffstat (limited to 'src')
-rw-r--r--src/game/g_buildable.c238
-rw-r--r--src/game/g_cmds.c11
-rw-r--r--src/game/tremulous.h7
-rw-r--r--src/ui/ui_shared.c4
4 files changed, 113 insertions, 147 deletions
diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c
index 2dc55253..3420b5b0 100644
--- a/src/game/g_buildable.c
+++ b/src/game/g_buildable.c
@@ -2081,6 +2081,38 @@ void HMedistat_Think( gentity_t *self )
/*
================
+HMGTurret_CheckTarget
+
+Used by HMGTurret_Think to check enemies for validity
+================
+*/
+qboolean HMGTurret_CheckTarget( gentity_t *self, gentity_t *target,
+ qboolean los_check )
+{
+ trace_t tr;
+ gentity_t *traceEnt;
+ vec3_t dir, end;
+
+ if( !target || target->health <= 0 || !target->client ||
+ target->client->pers.teamSelection != PTE_ALIENS ||
+ ( target->client->ps.stats[ STAT_STATE ] & SS_HOVELING ) )
+ return qfalse;
+
+ if( !los_check )
+ return qtrue;
+
+ // Accept target if we can line-trace to it
+ VectorSubtract( target->s.pos.trBase, self->s.pos.trBase, dir );
+ VectorNormalize( dir );
+ VectorMA( self->s.pos.trBase, MGTURRET_RANGE, dir, end );
+ trap_Trace( &tr, self->s.pos.trBase, NULL, NULL, end,
+ self->s.number, MASK_SHOT );
+ return tr.entityNum == target - g_entities;
+}
+
+
+/*
+================
HMGTurret_TrackEnemy
Used by HMGTurret_Think to track enemy location
@@ -2088,19 +2120,15 @@ Used by HMGTurret_Think to track enemy location
*/
qboolean HMGTurret_TrackEnemy( gentity_t *self )
{
- vec3_t dirToTarget, dttAdjusted, angleToTarget, angularDiff, xNormal;
+ trace_t tr;
+ vec3_t dirToTarget, dttAdjusted, angleToTarget, angularDiff, xNormal, end;
vec3_t refNormal = { 0.0f, 0.0f, 1.0f };
- float temp, rotAngle;
- float accuracyTolerance, angularSpeed;
+ float temp, rotAngle, angularSpeed;
- accuracyTolerance = MGTURRET_ACCURACYTOLERANCE;
- if( self->locked )
- angularSpeed = MGTURRET_ANGULARSPEED_LOCKED;
- else
- angularSpeed = MGTURRET_ANGULARSPEED;
+ angularSpeed = self->lev1Grabbed ? MGTURRET_ANGULARSPEED_GRAB :
+ MGTURRET_ANGULARSPEED;
VectorSubtract( self->enemy->s.pos.trBase, self->s.pos.trBase, dirToTarget );
-
VectorNormalize( dirToTarget );
CrossProduct( self->s.origin2, refNormal, xNormal );
@@ -2141,63 +2169,11 @@ qboolean HMGTurret_TrackEnemy( gentity_t *self )
RotatePointAroundVector( dirToTarget, xNormal, dttAdjusted, -rotAngle );
vectoangles( dirToTarget, self->turretAim );
- //if pointing at our target return true
- if( abs( angleToTarget[ YAW ] - self->s.angles2[ YAW ] ) <= accuracyTolerance &&
- abs( angleToTarget[ PITCH ] - self->s.angles2[ PITCH ] ) <= accuracyTolerance )
- return qtrue;
-
- return qfalse;
-}
-
-
-/*
-================
-HMGTurret_CheckTarget
-
-Used by HMGTurret_Think to check enemies for validity
-================
-*/
-qboolean HMGTurret_CheckTarget( gentity_t *self, gentity_t *target )
-{
- trace_t trace;
- gentity_t *traceEnt;
-
- if( !target )
- return qfalse;
-
- if( !target->client )
- return qfalse;
-
- if( target->client->ps.stats[ STAT_STATE ] & SS_HOVELING )
- return qfalse;
-
- if( target->health <= 0 )
- return qfalse;
-
- if( Distance( self->s.origin, target->s.pos.trBase ) > MGTURRET_RANGE )
- return qfalse;
-
- trap_Trace( &trace, self->s.pos.trBase, NULL, NULL, target->s.pos.trBase, self->s.number, MASK_SHOT );
-
- traceEnt = &g_entities[ trace.entityNum ];
-
- if( !traceEnt->client )
- return qfalse;
-
- if( traceEnt->client && traceEnt->client->ps.stats[ STAT_PTEAM ] != PTE_ALIENS )
- return qfalse;
-
- trap_Trace( &trace, self->s.pos.trBase, NULL, NULL, target->s.pos.trBase, self->s.number, MASK_SHOT );
-
- traceEnt = &g_entities[ trace.entityNum ];
-
- if( !traceEnt->client )
- return qfalse;
-
- if( traceEnt->client && traceEnt->client->ps.stats[ STAT_PTEAM ] != PTE_ALIENS )
- return qfalse;
-
- return qtrue;
+ //if pointing at a valid target (not necessarily the original) return true
+ VectorMA( self->s.pos.trBase, MGTURRET_RANGE, dirToTarget, end );
+ trap_Trace( &tr, self->s.pos.trBase, NULL, NULL, end,
+ self->s.number, MASK_SHOT );
+ return HMGTurret_CheckTarget( self, g_entities + tr.entityNum, qfalse );
}
@@ -2216,29 +2192,26 @@ void HMGTurret_FindEnemy( gentity_t *self )
int i, num;
gentity_t *target;
+ if( self->enemy )
+ self->enemy->targeted = NULL;
+
+ self->enemy = NULL;
+
+ // Look for targets in a box around the turret
VectorSet( range, MGTURRET_RANGE, MGTURRET_RANGE, MGTURRET_RANGE );
VectorAdd( self->s.origin, range, maxs );
VectorSubtract( self->s.origin, range, mins );
-
- //find aliens
num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES );
for( i = 0; i < num; i++ )
{
target = &g_entities[ entityList[ i ] ];
+ if( !HMGTurret_CheckTarget( self, target, qtrue ) )
+ continue;
- if( target->client && target->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS )
- {
- //if target is not valid keep searching
- if( !HMGTurret_CheckTarget( self, target ) )
- continue;
-
- //we found a target
- self->enemy = target;
- return;
- }
+ self->enemy = target;
+ self->enemy->targeted = self;
+ return;
}
- //couldn't find a target
- self->enemy = NULL;
}
@@ -2251,77 +2224,76 @@ Think function for MG turret
*/
void HMGTurret_Think( gentity_t *self )
{
- int firespeed = BG_FindFireSpeedForBuildable( self->s.modelindex );
-
- self->nextthink = level.time + BG_FindNextThinkForBuildable( self->s.modelindex );
+ self->nextthink = level.time +
+ BG_FindNextThinkForBuildable( self->s.modelindex );
- //used for client side muzzle flashes
+ // Turn off client side muzzle flashes
self->s.eFlags &= ~EF_FIRING;
- //if not powered don't do anything and check again for power next think
+ // If not powered or spawned don't do anything
if( !( self->powered = G_FindPower( self ) ) )
{
self->nextthink = level.time + POWER_REFRESH_TIME;
return;
}
-
- if( self->spawned )
+ if( !self->spawned )
+ return;
+
+ // If the current target is not valid find a new enemy
+ if( !HMGTurret_CheckTarget( self, self->enemy, qtrue ) )
{
- //if the current target is not valid find a new one
- if( !HMGTurret_CheckTarget( self, self->enemy ) )
- {
- self->locked = qfalse;
- if( self->enemy )
- self->enemy->targeted = NULL;
-
- HMGTurret_FindEnemy( self );
- }
+ self->active = qfalse;
+ HMGTurret_FindEnemy( self );
+ }
+ if( !self->enemy )
+ return;
- //if a new target cannot be found don't do anything
- if( !self->enemy )
- return;
+ // Track until we can hit the target
+ if( !HMGTurret_TrackEnemy( self ) )
+ {
+ self->active = qfalse;
+ return;
+ }
- self->enemy->targeted = self;
+ // Update spin state
+ if( !self->active && self->count < level.time )
+ {
+ int spinTime;
+
+ self->active = qtrue;
+ spinTime = level.time - self->turretSpinupTime - MGTURRET_SPIN_DURATION;
- if( self->active )
+ if( spinTime <= 0 )
{
- qboolean canFire = HMGTurret_TrackEnemy( self );
-
- if( self->turretSpinupTime < level.time )
- {
- if( canFire )
- {
- if( !self->locked )
- {
- self->active = qfalse;
- }
- else if( self->count < level.time )
- {
- //fire at target
- FireWeapon( self );
- self->s.eFlags |= EF_FIRING;
- G_AddEvent( self, EV_FIRE_WEAPON, 0 );
- G_SetBuildableAnim( self, BANIM_ATTACK1, qfalse );
- self->count = level.time + firespeed;
- }
- }
- else
- {
- self->locked = qfalse;
- }
- }
- return;
+ // Still has residual spin
+ self->turretSpinupTime = level.time;
}
-
- //if we are pointing at our target, start spinning up
- if( HMGTurret_TrackEnemy( self ) && self->count < level.time )
+ else if( spinTime < MGTURRET_SPINDOWN_TIME )
{
- self->active = qtrue;
- self->locked = qtrue;
+ // 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 );
+ G_AddEvent( self, EV_MGTURRET_SPINUP, 0 );
}
}
+
+ // Not firing or haven't spun up yet
+ if( !self->active || self->turretSpinupTime > level.time )
+ return;
+
+ // Fire repeat delay
+ if( self->count > level.time )
+ return;
+
+ FireWeapon( self );
+ self->s.eFlags |= EF_FIRING;
+ self->count = level.time + BG_FindFireSpeedForBuildable( self->s.modelindex );
+ G_AddEvent( self, EV_FIRE_WEAPON, 0 );
+ G_SetBuildableAnim( self, BANIM_ATTACK1, qfalse );
}
diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c
index 11dd7973..05925bd4 100644
--- a/src/game/g_cmds.c
+++ b/src/game/g_cmds.c
@@ -575,16 +575,9 @@ void G_ChangeTeam( gentity_t *ent, pTeam_t newTeam )
ClientSpawn( ent, NULL, NULL, NULL );
ent->client->pers.joinedATeam = qtrue;
ent->client->pers.teamChangeTime = level.time;
+ ent->client->pers.credit = 0;
+ ent->client->ps.persistant[ PERS_CREDIT ] = 0;
ClientUserinfoChanged( ent->client->ps.clientNum );
-
- // Convert between Alien and Human credits, specs use Alien credits
- if( oldTeam == PTE_HUMANS )
- ent->client->pers.credit = (int)( ent->client->pers.credit *
- ALIEN_MAX_CREDITS / HUMAN_MAX_CREDITS + 0.5f );
- if( newTeam == PTE_HUMANS )
- ent->client->pers.credit = (int)( ent->client->ps.persistant[ PERS_CREDIT ] *
- HUMAN_MAX_CREDITS / ALIEN_MAX_CREDITS + 0.5f );
- ent->client->ps.persistant[ PERS_CREDIT ] = ent->client->pers.credit;
}
/*
diff --git a/src/game/tremulous.h b/src/game/tremulous.h
index 582e0a70..97e32929 100644
--- a/src/game/tremulous.h
+++ b/src/game/tremulous.h
@@ -559,15 +559,16 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define MGTURRET_SPLASHDAMAGE 100
#define MGTURRET_SPLASHRADIUS 100
#define MGTURRET_ANGULARSPEED 12
-#define MGTURRET_ANGULARSPEED_LOCKED 8
-#define MGTURRET_ACCURACYTOLERANCE 0
+#define MGTURRET_ANGULARSPEED_GRAB 8
#define MGTURRET_VERTICALCAP 30 // +/- maximum pitch
-#define MGTURRET_REPEAT 100
+#define MGTURRET_REPEAT 150
#define MGTURRET_K_SCALE 1.0f
#define MGTURRET_RANGE 400.0f
#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 320
#define TESLAGEN_BP 10
diff --git a/src/ui/ui_shared.c b/src/ui/ui_shared.c
index f41b8bdc..f0dce0bc 100644
--- a/src/ui/ui_shared.c
+++ b/src/ui/ui_shared.c
@@ -4716,7 +4716,7 @@ void Item_Text_Wrapped_Paint( itemDef_t *item )
buff[ lineLength + 2 ] = '\0';
}
else
- {
+ {
strncpy( buff, p, lineLength );
buff[ lineLength ] = '\0';
}
@@ -4984,7 +4984,7 @@ static bind_t g_bindings[] =
{ "+scores", K_TAB, -1, -1, -1 },
{ "+button2", K_ENTER, -1, -1, -1 },
{ "+speed", K_SHIFT, -1, -1, -1 },
- { "boost", 'x', -1, -1, -1 }, // human sprinting
+ { "+button6", 'x', -1, -1, -1 }, // human sprinting
{ "+forward", K_UPARROW, -1, -1, -1 },
{ "+back", K_DOWNARROW, -1, -1, -1 },
{ "+moveleft", ',', -1, -1, -1 },