From ca3ade0361afe2b5d87c7a46543e6937b04b89bf Mon Sep 17 00:00:00 2001 From: Michael Levin Date: Sat, 3 Oct 2009 11:30:33 +0000 Subject: * Buildable health accuracy increased to 8 bits, flags moved to eFlags (EF_B_*) * Fixed Tesla Generator not firing over turrets or missing small aliens entirely -- it now shoots from the top of its bounding box to the top of its target's bounding box * Dying, evolving, or changing teams properly resets the weapon Flame thrower changes: * Reverted flame thrower missile radius to 15 * Muzzle is offset for flame thrower to shoot from the hand --- src/game/bg_public.h | 9 ++---- src/game/g_buildable.c | 83 ++++++++++++++++++++++-------------------------- src/game/g_client.c | 6 ++-- src/game/g_weapon.c | 86 +++++++++++++++++++++++--------------------------- src/game/tremulous.h | 2 +- 5 files changed, 85 insertions(+), 101 deletions(-) (limited to 'src/game') diff --git a/src/game/bg_public.h b/src/game/bg_public.h index 30afb07f..67899978 100644 --- a/src/game/bg_public.h +++ b/src/game/bg_public.h @@ -285,6 +285,9 @@ typedef enum #define EF_BOUNCE 0x00000008 // for missiles #define EF_BOUNCE_HALF 0x00000010 // for missiles #define EF_NO_BOUNCE_SOUND 0x00000020 // for missiles +#define EF_B_SPAWNED 0x00000008 // buildable has spawned +#define EF_B_POWERED 0x00000010 // buildable is powered +#define EF_B_MARKED 0x00000020 // buildable is marked for deconstruction #define EF_WALLCLIMB 0x00000040 // wall walking #define EF_WALLCLIMBCEILING 0x00000080 // wall walking ceiling hack #define EF_NODRAW 0x00000100 // may have an event, but no model (unspawned items) @@ -441,12 +444,6 @@ typedef enum #define B_HEALTH_BITS 12 #define B_HEALTH_MASK ((1<persistant[PERS_PLAYEREVENTS]) #define PLAYEREVENT_DENIEDREWARD 0x0001 #define PLAYEREVENT_GAUNTLETREWARD 0x0002 diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c index e44623ee..fc119ad9 100644 --- a/src/game/g_buildable.c +++ b/src/game/g_buildable.c @@ -2182,13 +2182,6 @@ Think function for Tesla Generator */ void HTeslaGen_Think( gentity_t *self ) { - int entityList[ MAX_GENTITIES ]; - vec3_t range; - vec3_t mins, maxs; - vec3_t dir; - int i, num; - gentity_t *enemy; - self->nextthink = level.time + BG_FindNextThinkForBuildable( self->s.modelindex ); //if not powered don't do anything and check again for power next think @@ -2201,31 +2194,28 @@ void HTeslaGen_Think( gentity_t *self ) if( self->spawned && self->count < level.time ) { - //used to mark client side effects + vec3_t range, mins, maxs, dir; + int entityList[ MAX_GENTITIES ], i, num; + + // Communicates firing state to client self->s.eFlags &= ~EF_FIRING; VectorSet( range, TESLAGEN_RANGE, TESLAGEN_RANGE, TESLAGEN_RANGE ); VectorAdd( self->s.origin, range, maxs ); VectorSubtract( self->s.origin, range, mins ); - //find aliens + // Attack nearby Aliens num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES ); for( i = 0; i < num; i++ ) { - enemy = &g_entities[ entityList[ i ] ]; - - if( enemy->client && enemy->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS && - enemy->health > 0 && - Distance( enemy->s.pos.trBase, self->s.pos.trBase ) <= TESLAGEN_RANGE ) - { - VectorSubtract( enemy->s.pos.trBase, self->s.pos.trBase, dir ); - VectorNormalize( dir ); - vectoangles( dir, self->turretAim ); - - //fire at target + self->enemy = &g_entities[ entityList[ i ] ]; + if( self->enemy->client && self->enemy->health > 0 && + self->enemy->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS && + Distance( self->enemy->s.pos.trBase, + self->s.pos.trBase ) <= TESLAGEN_RANGE ) FireWeapon( self ); - } } + self->enemy = NULL; if( self->s.eFlags & EF_FIRING ) { @@ -2473,28 +2463,8 @@ void G_BuildableThink( gentity_t *ent, int msec ) ent->spawned = qtrue; } - // pack health, power and dcc - ent->dcc = ( ent->biteam != BIT_HUMANS ) ? 0 : G_FindDCC( ent ); - ent->s.generic1 = (int)( ( ent->health + bHealth / B_HEALTH_MASK - 1 ) * - B_HEALTH_MASK / bHealth ); - - if( ent->s.generic1 < 0 ) - ent->s.generic1 = 0; - - if( ent->powered ) - ent->s.generic1 |= B_POWERED_TOGGLEBIT; - - if( ent->dcc ) - ent->s.generic1 |= B_DCCED_TOGGLEBIT; - - if( ent->spawned ) - ent->s.generic1 |= B_SPAWNED_TOGGLEBIT; - - if( ent->deconstruct ) - ent->s.generic1 |= B_MARKED_TOGGLEBIT; - + // Timer actions ent->time1000 += msec; - if( ent->time1000 >= 1000 ) { ent->time1000 -= 1000; @@ -2528,6 +2498,27 @@ void G_BuildableThink( gentity_t *ent, int msec ) if( ent->clientSpawnTime < 0 ) ent->clientSpawnTime = 0; + // Pack health + ent->dcc = ( ent->biteam != BIT_HUMANS ) ? 0 : G_FindDCC( ent ); + if( ent->health > 0 ) + { + ent->s.generic1 = (int)( ( ent->health + bHealth / B_HEALTH_MASK - 1 ) * + B_HEALTH_MASK / bHealth ); + } + else + ent->s.generic1 = 0; + + // Set flags + ent->s.eFlags &= ~( EF_B_POWERED | EF_B_SPAWNED | EF_B_MARKED ); + if( ent->powered ) + ent->s.eFlags |= EF_B_POWERED; + + if( ent->spawned ) + ent->s.eFlags |= EF_B_SPAWNED; + + if( ent->deconstruct ) + ent->s.eFlags |= EF_B_MARKED; + //check if this buildable is touching any triggers G_BuildableTouchTriggers( ent ); @@ -3338,12 +3329,12 @@ static gentity_t *G_Build( gentity_t *builder, buildable_t buildable, vec3_t ori if( BG_FindTeamForBuildable( built->s.modelindex ) == PTE_ALIENS ) { built->powered = qtrue; - built->s.generic1 |= B_POWERED_TOGGLEBIT; + built->s.eFlags |= EF_B_POWERED; } else if( ( built->powered = G_FindPower( built ) ) ) - built->s.generic1 |= B_POWERED_TOGGLEBIT; + built->s.eFlags |= EF_B_POWERED; - built->s.generic1 &= ~B_SPAWNED_TOGGLEBIT; + built->s.eFlags &= ~EF_B_SPAWNED; VectorCopy( normal, built->s.origin2 ); @@ -3461,7 +3452,7 @@ static void G_FinishSpawningBuildable( gentity_t *ent ) built->takedamage = qtrue; built->spawned = qtrue; //map entities are already spawned built->health = BG_FindHealthForBuildable( buildable ); - built->s.generic1 |= B_SPAWNED_TOGGLEBIT; + built->s.eFlags |= EF_B_SPAWNED; // drop towards normal surface VectorScale( built->s.origin2, -4096.0f, dest ); diff --git a/src/game/g_client.c b/src/game/g_client.c index 621a0261..f9742109 100644 --- a/src/game/g_client.c +++ b/src/game/g_client.c @@ -1500,6 +1500,9 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles client->ps.ammo = maxAmmo; client->ps.clips = maxClips; + // We just spawned, not changing weapons + client->ps.persistant[ PERS_NEWWEAPON ] = 0; + ent->client->ps.stats[ STAT_PCLASS ] = ent->client->pers.classSelection; ent->client->ps.stats[ STAT_PTEAM ] = ent->client->pers.teamSelection; @@ -1571,9 +1574,8 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles trap_GetUsercmd( client - level.clients, &ent->client->pers.cmd ); G_SetClientViewAngle( ent, spawn_angles ); - if( !( client->sess.sessionTeam == TEAM_SPECTATOR ) ) + if( client->sess.sessionTeam != TEAM_SPECTATOR ) { - /*G_KillBox( ent );*/ //blame this if a newly spawned client gets stuck in another trap_LinkEntity( ent ); // force the base weapon up diff --git a/src/game/g_weapon.c b/src/game/g_weapon.c index 759a1a04..24317bd2 100644 --- a/src/game/g_weapon.c +++ b/src/game/g_weapon.c @@ -593,11 +593,12 @@ HIVE void hiveFire( gentity_t *ent ) { - gentity_t *m; - - m = fire_hive( ent, muzzle, forward ); + vec3_t origin; -// VectorAdd( m->s.pos.trDelta, ent->client->ps.velocity, m->s.pos.trDelta ); // "real" physics + // Fire from the hive tip, not the center + VectorMA( muzzle, ent->r.maxs[ 2 ], ent->s.origin2, origin ); + + fire_hive( ent, origin, forward ); } /* @@ -644,9 +645,15 @@ FLAME THROWER void flamerFire( gentity_t *ent ) { - gentity_t *m; + vec3_t origin; + + // Correct muzzle so that the missile does not start in the ceiling + VectorMA( muzzle, -7.0f, up, origin ); - m = fire_flamer( ent, muzzle, forward ); + // Correct muzzle so that the missile fires from the player's hand + VectorMA( origin, 4.5f, right, origin ); + + fire_flamer( ent, origin, forward ); } /* @@ -792,49 +799,44 @@ TESLA GENERATOR */ -void teslaFire( gentity_t *ent ) +void teslaFire( gentity_t *self ) { - trace_t tr; - vec3_t end; - gentity_t *traceEnt, *tent; - - VectorMA( muzzle, TESLAGEN_RANGE, forward, end ); - - trap_Trace( &tr, muzzle, NULL, NULL, end, ent->s.number, MASK_SHOT ); - - if( tr.entityNum == ENTITYNUM_NONE ) + trace_t tr; + vec3_t origin, target; + gentity_t *tent; + + if( !self->enemy ) return; - traceEnt = &g_entities[ tr.entityNum ]; + // Move the muzzle from the entity origin up a bit to fire over turrets + VectorMA( muzzle, self->r.maxs[ 2 ], self->s.origin2, origin ); - if( !traceEnt->client ) - return; + // Don't aim for the center, aim at the top of the bounding box + VectorCopy( self->enemy->s.origin, target ); + target[ 2 ] += self->enemy->r.maxs[ 2 ]; - if( traceEnt->client && traceEnt->client->ps.stats[ STAT_PTEAM ] != PTE_ALIENS ) + // Trace to the target entity + trap_Trace( &tr, origin, NULL, NULL, target, self->s.number, MASK_SHOT ); + if( tr.entityNum != self->enemy->s.number ) return; - //so the client side knows - ent->s.eFlags |= EF_FIRING; + // Client side firing effect + self->s.eFlags |= EF_FIRING; - if( traceEnt->takedamage ) + // Deal damage + if( self->enemy->takedamage ) { - G_Damage( traceEnt, ent, ent, forward, tr.endpos, - TESLAGEN_DMG, 0, MOD_TESLAGEN ); + vec3_t dir; + + VectorSubtract( target, origin, dir ); + G_Damage( self->enemy, self, self, dir, tr.endpos, + TESLAGEN_DMG, 0, MOD_TESLAGEN ); } - // snap the endpos to integers to save net bandwidth, but nudged towards the line - SnapVectorTowards( tr.endpos, muzzle ); - - // send railgun beam effect + // Send tesla zap trail tent = G_TempEntity( tr.endpos, EV_TESLATRAIL ); - - VectorCopy( muzzle, tent->s.origin2 ); - - tent->s.generic1 = ent->s.number; //src - tent->s.clientNum = traceEnt->s.number; //dest - - // move origin a bit to come closer to the drawn gun muzzle - VectorMA( tent->s.origin2, 28, up, tent->s.origin2 ); + tent->s.generic1 = self->s.number; // src + tent->s.clientNum = self->enemy->s.number; // dest } @@ -1532,20 +1534,12 @@ void FireWeapon( gentity_t *ent ) { // set aiming directions AngleVectors( ent->client->ps.viewangles, forward, right, up ); - CalcMuzzlePoint( ent, forward, right, up, muzzle ); + CalcMuzzlePoint( ent, forward, right, up, muzzle ); } else { 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 ); - - // Tesla generator muzzle point is offset too - if( ent->s.eType == ET_BUILDABLE && ent->s.modelindex == BA_H_TESLAGEN ) - VectorMA( muzzle, 28.0f, ent->s.origin2, muzzle ); } // fire the specific weapon diff --git a/src/game/tremulous.h b/src/game/tremulous.h index ce9136f0..3517a268 100644 --- a/src/game/tremulous.h +++ b/src/game/tremulous.h @@ -448,7 +448,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #define FLAMER_K_SCALE 1.0f #define FLAMER_DMG HDM(20) #define FLAMER_RADIUS 50 // splash radius -#define FLAMER_SIZE 8 // missile bounding box +#define FLAMER_SIZE 15 // missile bounding box #define FLAMER_LIFETIME 700.0f #define FLAMER_SPEED 300.0f #define FLAMER_LAG 0.65f // the amount of player velocity that is added to the fireball -- cgit