summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/game/bg_misc.c4
-rw-r--r--src/game/g_buildable.c116
-rw-r--r--src/game/g_cmds.c19
-rw-r--r--src/game/g_local.h6
-rw-r--r--src/game/g_utils.c5
-rw-r--r--src/game/g_weapon.c56
6 files changed, 89 insertions, 117 deletions
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 );
}