From 1342d53528fb2a68d7dfe920c53834ce73cd9f4e Mon Sep 17 00:00:00 2001 From: Tim Angus Date: Wed, 10 Oct 2001 17:54:36 +0000 Subject: Buildable BBOX handling. Creep tests no longer happen at build time. --- src/game/bg_misc.c | 4 +- src/game/g_buildable.c | 116 +++++++++++++++++-------------------------------- src/game/g_cmds.c | 19 ++++---- src/game/g_local.h | 6 ++- src/game/g_utils.c | 5 ++- src/game/g_weapon.c | 56 ++++++++++++------------ 6 files changed, 89 insertions(+), 117 deletions(-) (limited to 'src') diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c index 3c7a2fc7..9d0d288b 100644 --- a/src/game/bg_misc.c +++ b/src/game/bg_misc.c @@ -983,7 +983,7 @@ TA: human defense item { "team_human_def3", "sound/items/holdable.wav", - { "models/buildables/plasmaturret/pturret_base.md3", "models/weapons2/railgun/railgun.md3", 0, 0 }, + { "models/buildables/plasmaturret/pturret_base.md3", 0, 0, 0 }, "icons/teleporter", //icon "Human Defense3", //pickup 0, @@ -1529,7 +1529,7 @@ buildableAttributes_t bg_buildableList[ ] = 150, //int nextthink; 4000, //int turretFireSpeed; 1500, //int turretRange; - WP_RAILGUN, //weapon_t turretProjType; + WP_LIGHTNING, //weapon_t turretProjType; 0.707f, //float minNormal; qfalse, //qboolean invertNormal; qfalse, //qboolean creepTest; diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c index f59e8d9c..7ee5e570 100644 --- a/src/game/g_buildable.c +++ b/src/game/g_buildable.c @@ -187,6 +187,10 @@ qboolean findCreep( gentity_t *self ) int distance = 0; int minDistance = 10000; vec3_t temp_v; + + //don't check for creep if flying through the air + if( self->s.groundEntityNum == -1 ) + return qtrue; //if self does not have a parentNode or it's parentNode is invalid find a new one if( ( self->parentNode == NULL ) || !self->parentNode->inuse ) @@ -198,6 +202,7 @@ qboolean findCreep( gentity_t *self ) if( ent->s.clientNum == BA_D_SPAWN || ent->s.clientNum == BA_D_HIVEMIND ) { + /*VectorSubtract( self->s.origin, ent->s.origin, temp_v );*/ VectorSubtract( self->s.origin, ent->s.origin, temp_v ); distance = VectorLength( temp_v ); if( distance < minDistance ) @@ -1196,65 +1201,25 @@ qboolean hdef2_trackenemy( gentity_t *self ) return qfalse; } -#define HDEF3_ANGULARSPEED 2 //degrees/think ~= 200deg/sec -#define HDEF3_ACCURACYTOLERANCE HDEF3_ANGULARSPEED / 2 //angular difference for turret to fire -#define HDEF3_VERTICALCAP 15 //+/- maximum pitch - /* ================ -hdef3_trackenemy +hdef3_fireonemeny -Used by HDef1_Think to track enemy location +Used by HDef_Think to fire at enemy ================ */ -qboolean hdef3_trackenemy( gentity_t *self ) +void hdef3_fireonenemy( gentity_t *self, int firespeed ) { - vec3_t dirToTarget, angleToTarget, angularDiff; - float temp; - + vec3_t dirToTarget; + VectorSubtract( self->enemy->s.pos.trBase, self->s.pos.trBase, dirToTarget ); - VectorNormalize( dirToTarget ); - - vectoangles( dirToTarget, angleToTarget ); - - angularDiff[ PITCH ] = AngleSubtract( self->s.angles2[ PITCH ], angleToTarget[ PITCH ] ); - angularDiff[ YAW ] = AngleSubtract( self->s.angles2[ YAW ], angleToTarget[ YAW ] ); - - //if not pointing at our target then move accordingly - if( angularDiff[ PITCH ] < -HDEF3_ACCURACYTOLERANCE ) - self->s.angles2[ PITCH ] += HDEF3_ANGULARSPEED; - else if( angularDiff[ PITCH ] > HDEF3_ACCURACYTOLERANCE ) - self->s.angles2[ PITCH ] -= HDEF3_ANGULARSPEED; - else - self->s.angles2[ PITCH ] = angleToTarget[ PITCH ]; - - //disallow vertical movement past a certain limit - temp = fabs( self->s.angles2[ PITCH ] ); - if( temp > 180 ) - temp -= 360; - - if( temp < -HDEF3_VERTICALCAP ) - self->s.angles2[ PITCH ] = (-360)+HDEF3_VERTICALCAP; - else if( temp > HDEF3_VERTICALCAP ) - self->s.angles2[ PITCH ] = -HDEF3_VERTICALCAP; - - //if not pointing at our target then move accordingly - if( angularDiff[ YAW ] < -HDEF3_ACCURACYTOLERANCE ) - self->s.angles2[ YAW ] += HDEF3_ANGULARSPEED; - else if( angularDiff[ YAW ] > HDEF3_ACCURACYTOLERANCE ) - self->s.angles2[ YAW ] -= HDEF3_ANGULARSPEED; - else - self->s.angles2[ YAW ] = angleToTarget[ YAW ]; - - trap_LinkEntity( self ); + vectoangles( dirToTarget, self->s.angles2 ); - //if pointing at our target return true - if( abs( angleToTarget[ YAW ] - self->s.angles2[ YAW ] ) <= HDEF3_ACCURACYTOLERANCE && - abs( angleToTarget[ PITCH ] - self->s.angles2[ PITCH ] ) <= HDEF3_ACCURACYTOLERANCE ) - return qtrue; - - return qfalse; + //fire at target + FireWeapon( self ); + G_setBuildableAnim( self, BANIM_ATTACK1, qfalse ); + self->count = level.time + firespeed; } /* @@ -1399,8 +1364,8 @@ void HDef_Think( gentity_t *self ) break; case BA_H_DEF3: - if( hdef3_trackenemy( self ) && ( self->count < level.time ) ) - hdef_fireonenemy( self, firespeed ); + if( self->count < level.time ) + hdef3_fireonenemy( self, firespeed ); break; default: @@ -1524,14 +1489,14 @@ G_itemFits Checks to see if an item fits in a specific area ================ */ -itemBuildError_t G_itemFits( gentity_t *ent, buildable_t buildable, int distance ) +itemBuildError_t G_itemFits( gentity_t *ent, buildable_t buildable, int distance, vec3_t origin ) { vec3_t forward; vec3_t angles; - vec3_t player_origin, entity_origin; + vec3_t player_origin, entity_origin, target_origin; vec3_t mins, maxs; vec3_t temp_v; - trace_t tr1, tr2; + trace_t tr1, tr2, tr3; int i; itemBuildError_t reason = IBE_NONE; gentity_t *tempent, *closestPower; @@ -1545,21 +1510,30 @@ itemBuildError_t G_itemFits( gentity_t *ent, buildable_t buildable, int distance VectorCopy( ent->s.pos.trBase, player_origin ); VectorMA( player_origin, distance, forward, entity_origin ); + VectorCopy( entity_origin, target_origin ); + entity_origin[ 2 ] += 32; + target_origin[ 2 ] -= 4096; + BG_FindBBoxForBuildable( buildable, mins, maxs ); - trap_Trace( &tr1, entity_origin, mins, maxs, entity_origin, ent->s.number, MASK_PLAYERSOLID ); - trap_Trace( &tr2, player_origin, NULL, NULL, entity_origin, ent->s.number, MASK_PLAYERSOLID ); + trap_Trace( &tr1, entity_origin, mins, maxs, target_origin, ent->s.number, MASK_PLAYERSOLID ); + VectorCopy( tr1.endpos, entity_origin ); + entity_origin[ 2 ] += 0.1f; + + trap_Trace( &tr2, entity_origin, mins, maxs, entity_origin, ent->s.number, MASK_PLAYERSOLID ); + trap_Trace( &tr3, player_origin, NULL, NULL, entity_origin, ent->s.number, MASK_PLAYERSOLID ); + + VectorCopy( entity_origin, origin ); //this item does not fit here - if( tr1.fraction < 1.0 || tr2.fraction < 1.0 ) + if( tr2.fraction < 1.0 || tr3.fraction < 1.0 ) return IBE_NOROOM; //NO other reason is allowed to override this if( ent->client->ps.stats[ STAT_PTEAM ] == PTE_DROIDS ) { //droid criteria //check there is creep near by for building on - - if( BG_FindCreepTestForBuildable( buildable ) ) +/* if( BG_FindCreepTestForBuildable( buildable ) ) { for ( i = 1, tempent = g_entities + i; i < level.num_entities; i++, tempent++ ) { @@ -1576,7 +1550,7 @@ itemBuildError_t G_itemFits( gentity_t *ent, buildable_t buildable, int distance if( i >= level.num_entities ) reason = IBE_NOCREEP; - } + }*/ //look for a hivemind for ( i = 1, tempent = g_entities + i; i < level.num_entities; i++, tempent++ ) @@ -1708,20 +1682,10 @@ G_buildItem Spawns a buildable ================ */ -gentity_t *G_buildItem( gentity_t *ent, buildable_t buildable, int distance, float speed ) +gentity_t *G_buildItem( gentity_t *builder, buildable_t buildable, vec3_t origin, vec3_t angles, float speed ) { - vec3_t forward; - vec3_t angles; - vec3_t origin; gentity_t *built; - VectorCopy( ent->s.apos.trBase, angles ); - angles[PITCH] = 0; // always forward - - AngleVectors( angles, forward, NULL, NULL ); - VectorCopy( ent->s.pos.trBase, origin ); - VectorMA( origin, distance, forward, origin ); - //spawn the buildable built = G_Spawn(); @@ -1847,19 +1811,21 @@ gentity_t *G_buildItem( gentity_t *ent, buildable_t buildable, int distance, flo built->enemy = NULL; built->s.weapon = BG_FindProjTypeForBuildable( buildable ); - if( ent->client ) - built->builtBy = ent->client->ps.clientNum; + if( builder->client ) + built->builtBy = builder->client->ps.clientNum; else built->builtBy = -1; G_SetOrigin( built, origin ); VectorCopy( angles, built->s.angles ); + built->s.angles[ PITCH ] = 0.0f; built->s.angles2[ YAW ] = angles[ YAW ]; VectorCopy( origin, built->s.origin ); built->s.pos.trType = BG_FindTrajectoryForBuildable( buildable ); built->physicsBounce = BG_FindBounceForBuildable( buildable ); + built->s.groundEntityNum = -1; built->s.pos.trTime = level.time; - AngleVectors( ent->s.apos.trBase, built->s.pos.trDelta, NULL, NULL ); + AngleVectors( angles, built->s.pos.trDelta, NULL, NULL ); VectorScale( built->s.pos.trDelta, speed, built->s.pos.trDelta ); VectorSet( built->s.origin2, 0.0f, 0.0f, 1.0f ); diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c index f77fd7e1..539bb722 100644 --- a/src/game/g_cmds.c +++ b/src/game/g_cmds.c @@ -2025,7 +2025,7 @@ void Cmd_Deposit_f( gentity_t *ent ) if( amount <= ent->client->ps.stats[ STAT_CREDIT ] ) { ent->client->ps.stats[ STAT_CREDIT ] -= amount; - bankEntity->credits[ ent->client->ps.clientNum ] += amount; + level.bankCredits[ ent->client->ps.clientNum ] += amount; } else G_AddPredictableEvent( ent, EV_MENU, MN_H_NOFUNDS ); @@ -2066,7 +2066,7 @@ void Cmd_Withdraw_f( gentity_t *ent ) } if( !Q_stricmp( s, "all" ) ) - amount = bankEntity->credits[ ent->client->ps.clientNum ]; + amount = level.bankCredits[ ent->client->ps.clientNum ]; else amount = atoi( s ); @@ -2077,10 +2077,10 @@ void Cmd_Withdraw_f( gentity_t *ent ) return; } - if( amount <= bankEntity->credits[ ent->client->ps.clientNum ] ) + if( amount <= level.bankCredits[ ent->client->ps.clientNum ] ) { ent->client->ps.stats[ STAT_CREDIT ] += amount; - bankEntity->credits[ ent->client->ps.clientNum ] -= amount; + level.bankCredits[ ent->client->ps.clientNum ] -= amount; } else G_AddPredictableEvent( ent, EV_MENU, MN_H_NOFUNDS ); @@ -2099,6 +2099,7 @@ void Cmd_Build_f( gentity_t *ent ) buildable_t buildable; weapon_t weapon; float dist, speed, maxspeed; + vec3_t origin; trap_Argv( 1, s, sizeof( s ) ); trap_Argv( 2, s1, sizeof( s1 ) ); @@ -2115,10 +2116,10 @@ void Cmd_Build_f( gentity_t *ent ) { dist = BG_FindBuildDistForClass( ent->client->ps.stats[ STAT_PCLASS ] ); - switch( G_itemFits( ent, buildable, dist ) ) + switch( G_itemFits( ent, buildable, dist, origin ) ) { case IBE_NONE: - G_buildItem( ent, buildable, dist, speed ); + G_buildItem( ent, buildable, origin, ent->s.apos.trBase, speed ); break; case IBE_NOCREEP: @@ -2158,17 +2159,17 @@ void Cmd_Build_f( gentity_t *ent ) case IBE_SPWNWARN: G_AddPredictableEvent( ent, EV_MENU, MN_D_SPWNWARN ); - G_buildItem( ent, buildable, dist, speed ); + G_buildItem( ent, buildable, origin, ent->s.apos.trBase, speed ); break; case IBE_RPLWARN: G_AddPredictableEvent( ent, EV_MENU, MN_H_RPLWARN ); - G_buildItem( ent, buildable, dist, speed ); + G_buildItem( ent, buildable, origin, ent->s.apos.trBase, speed ); break; case IBE_RPTWARN: G_AddPredictableEvent( ent, EV_MENU, MN_H_RPTWARN ); - G_buildItem( ent, buildable, dist, speed ); + G_buildItem( ent, buildable, origin, ent->s.apos.trBase, speed ); break; } } diff --git a/src/game/g_local.h b/src/game/g_local.h index cf5bb8f4..2522a176 100644 --- a/src/game/g_local.h +++ b/src/game/g_local.h @@ -478,6 +478,8 @@ typedef struct { int droidBuildPoints; int humanBuildPoints; int humanBuildPointsPowered; + + int bankCredits[ MAX_CLIENTS ]; //global credits storage } level_locals_t; // @@ -549,8 +551,8 @@ typedef enum IBE_MAXERRORS } itemBuildError_t; -itemBuildError_t G_itemFits( gentity_t *ent, buildable_t buildable, int distance ); -gentity_t *G_buildItem( gentity_t *ent, buildable_t buildable, int distance, float speed ); +itemBuildError_t G_itemFits( gentity_t *ent, buildable_t buildable, int distance, vec3_t origin ); +gentity_t *G_buildItem( gentity_t *builder, buildable_t buildable, vec3_t origin, vec3_t angles, float speed ); void G_setBuildableAnim( gentity_t *ent, buildableAnimNumber_t anim, qboolean force ); void G_setIdleBuildableAnim( gentity_t *ent, buildableAnimNumber_t anim ); diff --git a/src/game/g_utils.c b/src/game/g_utils.c index 8105af8b..8c013a1a 100644 --- a/src/game/g_utils.c +++ b/src/game/g_utils.c @@ -632,7 +632,8 @@ G_SetOrigin Sets the pos trajectory for a fixed position ================ */ -void G_SetOrigin( gentity_t *ent, vec3_t origin ) { +void G_SetOrigin( gentity_t *ent, vec3_t origin ) +{ VectorCopy( origin, ent->s.pos.trBase ); ent->s.pos.trType = TR_STATIONARY; ent->s.pos.trTime = 0; @@ -640,7 +641,7 @@ void G_SetOrigin( gentity_t *ent, vec3_t origin ) { VectorClear( ent->s.pos.trDelta ); VectorCopy( origin, ent->r.currentOrigin ); - VectorCopy( origin, ent->s.origin ); //TA: it shit breaks - blame this line + VectorCopy( origin, ent->s.origin ); //TA: if shit breaks - blame this line } //TA: from quakestyle.telefragged.com diff --git a/src/game/g_weapon.c b/src/game/g_weapon.c index be708264..6bfdcc30 100644 --- a/src/game/g_weapon.c +++ b/src/game/g_weapon.c @@ -572,7 +572,8 @@ LIGHTNING GUN */ -void Weapon_LightningFire( gentity_t *ent ) { +void Weapon_LightningFire( gentity_t *ent ) +{ trace_t tr; vec3_t end; gentity_t *traceEnt, *tent; @@ -580,38 +581,39 @@ void Weapon_LightningFire( gentity_t *ent ) { damage = 8; - passent = ent->s.number; - for (i = 0; i < 10; i++) { - VectorMA( muzzle, LIGHTNING_RANGE, forward, end ); + VectorMA( muzzle, LIGHTNING_RANGE, forward, end ); - trap_Trace( &tr, muzzle, NULL, NULL, end, passent, MASK_SHOT ); + trap_Trace( &tr, muzzle, NULL, NULL, end, ent->s.number, MASK_SHOT ); - if ( tr.entityNum == ENTITYNUM_NONE ) { - return; - } + if( tr.entityNum == ENTITYNUM_NONE ) + return; - traceEnt = &g_entities[ tr.entityNum ]; + traceEnt = &g_entities[ tr.entityNum ]; - if ( traceEnt->takedamage) { - G_Damage( traceEnt, ent, ent, forward, tr.endpos, - damage, 0, MOD_LIGHTNING); - } + if( traceEnt->takedamage) + { + G_Damage( traceEnt, ent, ent, forward, tr.endpos, + damage, 0, MOD_LIGHTNING); + } - if ( traceEnt->takedamage && traceEnt->client ) { - tent = G_TempEntity( tr.endpos, EV_MISSILE_HIT ); - tent->s.otherEntityNum = traceEnt->s.number; - tent->s.eventParm = DirToByte( tr.plane.normal ); - tent->s.weapon = ent->s.weapon; - if( LogAccuracyHit( traceEnt, ent ) ) { - ent->client->accuracy_hits++; - } - } else if ( !( tr.surfaceFlags & SURF_NOIMPACT ) ) { - tent = G_TempEntity( tr.endpos, EV_MISSILE_MISS ); - tent->s.eventParm = DirToByte( tr.plane.normal ); - } + // snap the endpos to integers to save net bandwidth, but nudged towards the line + SnapVectorTowards( tr.endpos, muzzle ); - break; - } + // send railgun beam effect + tent = G_TempEntity( tr.endpos, EV_RAILTRAIL ); + + // set player number for custom colors on the railtrail + tent->s.clientNum = ent->s.clientNum; + + VectorCopy( muzzle, tent->s.origin2 ); + // move origin a bit to come closer to the drawn gun muzzle + VectorMA( tent->s.origin2, 16, up, tent->s.origin2 ); + + // no explosion at end if SURF_NOIMPACT, but still make the trail + if( tr.surfaceFlags & SURF_NOIMPACT ) + tent->s.eventParm = 255; // don't make the explosion at the end + else + tent->s.eventParm = DirToByte( tr.plane.normal ); } -- cgit