summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Angus <tim@ngus.net>2004-02-07 19:33:00 +0000
committerTim Angus <tim@ngus.net>2004-02-07 19:33:00 +0000
commit062269e2abb237a37d9a33a6de46974a599408b4 (patch)
tree134243f756ad60f2ca8dcf6c898411946ef1f9a3
parentb3b15cc492b10515706085ae5199713535c1624b (diff)
* Fixed a wall walking bug (DEAR GOD WHEN WILL IT END)
* Shadow is now rendered on walls as well as the ground * Buildables are now vulnerable in the prebuild stage * Alien buildables take longer to build * A bunch of other stuff
-rw-r--r--Makefile2
-rw-r--r--src/cgame/cg_buildable.c4
-rw-r--r--src/cgame/cg_main.c3
-rw-r--r--src/cgame/cg_players.c51
-rw-r--r--src/cgame/cg_weapons.c10
-rw-r--r--src/game/bg_pmove.c3
-rw-r--r--src/game/g_buildable.c130
-rw-r--r--src/game/g_client.c2
-rw-r--r--src/game/g_local.h3
-rw-r--r--src/game/g_main.c32
-rw-r--r--src/game/g_physics.c21
-rw-r--r--src/game/tremulous.h41
12 files changed, 214 insertions, 88 deletions
diff --git a/Makefile b/Makefile
index 184a27f9..97d17db2 100644
--- a/Makefile
+++ b/Makefile
@@ -138,7 +138,7 @@ LIBEXT=a
SHLIBEXT=so
SHLIBCFLAGS=-fPIC
-SHLIBLDFLAGS=-shared
+SHLIBLDFLAGS=-fPIC -shared
ARFLAGS=ar rv
RANLIB=ranlib
diff --git a/src/cgame/cg_buildable.c b/src/cgame/cg_buildable.c
index 29b89ec4..0cf39a86 100644
--- a/src/cgame/cg_buildable.c
+++ b/src/cgame/cg_buildable.c
@@ -201,7 +201,6 @@ void CG_HumanBuildableExplosion( vec3_t origin, vec3_t dir )
}
-#define CREEP_SCALEDOWN_TIME 3000
#define CREEP_SIZE 64.0f
/*
@@ -793,6 +792,9 @@ static void CG_BuildableParticleEffects( centity_t *cent )
int health = es->generic1 & ~( B_POWERED_TOGGLEBIT | B_DCCED_TOGGLEBIT | B_SPAWNED_TOGGLEBIT );
float healthFrac = (float)health / B_HEALTH_SCALE;
+ if( !( es->generic1 & B_SPAWNED_TOGGLEBIT ) )
+ return;
+
if( team == BIT_HUMANS )
{
if( healthFrac < 0.33f && !CG_IsParticleSystemValid( &cent->buildablePS ) )
diff --git a/src/cgame/cg_main.c b/src/cgame/cg_main.c
index 1312cc23..bda93826 100644
--- a/src/cgame/cg_main.c
+++ b/src/cgame/cg_main.c
@@ -1446,7 +1446,8 @@ static const char *CG_FeederItemText( float feederID, int index, int column, qha
switch( column )
{
case 0:
- if( atoi( CG_ConfigString( CS_CLIENTS_READY ) ) & ( 1 << sp->client ) )
+ if( ( atoi( CG_ConfigString( CS_CLIENTS_READY ) ) & ( 1 << sp->client ) ) &&
+ cg.intermissionStarted )
return "Ready";
break;
diff --git a/src/cgame/cg_players.c b/src/cgame/cg_players.c
index ce288e52..65a34d2e 100644
--- a/src/cgame/cg_players.c
+++ b/src/cgame/cg_players.c
@@ -1342,7 +1342,7 @@ static void CG_PlayerWWSmoothing( centity_t *cent, vec3_t in[ 3 ], vec3_t out[ 3
if( VectorCompare( ceilingNormal, cent->pe.lastNormal ) &&
VectorCompare( refNormal, surfNormal ) )
{
- VectorCopy( in, rotAxis );
+ VectorCopy( in[ 1 ], rotAxis );
rotAngle = 180.0f;
}
else
@@ -1714,10 +1714,24 @@ Returns the Z component of the surface being shadowed
#define SHADOW_DISTANCE 128
static qboolean CG_PlayerShadow( centity_t *cent, float *shadowPlane, pClass_t class )
{
- vec3_t end, mins = { -15, -15, 0 }, maxs = { 15, 15, 2 };
- trace_t trace;
- float alpha;
+ vec3_t end, mins, maxs;
+ trace_t trace;
+ float alpha;
+ entityState_t *es = &cent->currentState;
+ vec3_t surfNormal = { 0.0f, 0.0f, 1.0f };
+ BG_FindBBoxForClass( class, mins, maxs, NULL, NULL, NULL );
+ mins[ 2 ] = 0.0f;
+ maxs[ 2 ] = 2.0f;
+
+ if( es->eFlags & EF_WALLCLIMB )
+ {
+ if( es->eFlags & EF_WALLCLIMBCEILING )
+ VectorSet( surfNormal, 0.0f, 0.0f, -1.0f );
+ else
+ VectorCopy( es->angles2, surfNormal );
+ }
+
*shadowPlane = 0;
if( cg_shadows.integer == 0 )
@@ -1725,7 +1739,7 @@ static qboolean CG_PlayerShadow( centity_t *cent, float *shadowPlane, pClass_t c
// send a trace down from the player to the ground
VectorCopy( cent->lerpOrigin, end );
- end[ 2 ] -= SHADOW_DISTANCE;
+ VectorMA( cent->lerpOrigin, -SHADOW_DISTANCE, surfNormal, end );
trap_CM_BoxTrace( &trace, cent->lerpOrigin, end, mins, maxs, 0, MASK_PLAYERSOLID );
@@ -1733,7 +1747,14 @@ static qboolean CG_PlayerShadow( centity_t *cent, float *shadowPlane, pClass_t c
if( trace.fraction == 1.0 || trace.startsolid || trace.allsolid )
return qfalse;
- *shadowPlane = trace.endpos[ 2 ] + 1;
+ //TA: FIXME: stencil shadows will be broken for walls.
+ // Unfortunately there isn't much that can be
+ // done since Q3 references only the Z coord
+ // of the shadowPlane
+ if( surfNormal[ 2 ] < 0.0f )
+ *shadowPlane = trace.endpos[ 2 ] - 1.0f;
+ else
+ *shadowPlane = trace.endpos[ 2 ] + 1.0f;
if( cg_shadows.integer != 1 ) // no mark for stencil or projection shadows
return qtrue;
@@ -1744,8 +1765,8 @@ static qboolean CG_PlayerShadow( centity_t *cent, float *shadowPlane, pClass_t c
// add the mark as a temporary, so it goes directly to the renderer
// without taking a spot in the cg_marks array
CG_ImpactMark( cgs.media.shadowMarkShader, trace.endpos, trace.plane.normal,
- cent->pe.legs.yawAngle, alpha,alpha,alpha,1, qfalse,
- 24 * BG_FindShadowScaleForClass( class ), qtrue );
+ cent->pe.legs.yawAngle, alpha, alpha, alpha, 1, qfalse,
+ 24.0f * BG_FindShadowScaleForClass( class ), qtrue );
return qtrue;
}
@@ -1964,7 +1985,7 @@ int CG_AmbientLight( vec3_t point )
return (int)((float)( result[ 0 ] + result[ 1 ] + result[ 2 ] ) / 3.0f );
}
-#define TRACE_DEPTH 128.0f
+#define TRACE_DEPTH 32.0f
/*
===============
@@ -1982,7 +2003,7 @@ void CG_Player( centity_t *cent )
refEntity_t head;
int clientNum;
int renderfx;
- qboolean shadow;
+ qboolean shadow = qfalse;
float shadowPlane;
entityState_t *es = &cent->currentState;
pClass_t class = ( es->powerups >> 8 ) & 0xFF;
@@ -2068,6 +2089,8 @@ void CG_Player( centity_t *cent )
CG_PlayerSprites( cent );
// add the shadow
+ if( ( es->number == cg.snap->ps.clientNum && cg.renderingThirdPerson ) ||
+ es->number != cg.snap->ps.clientNum )
shadow = CG_PlayerShadow( cent, &shadowPlane, class );
// add a water splash if partially in and out of water
@@ -2119,7 +2142,11 @@ void CG_Player( centity_t *cent )
VectorMA( legs.origin, -TRACE_DEPTH, surfNormal, end );
VectorMA( legs.origin, 1.0f, surfNormal, start );
CG_CapTrace( &tr, start, mins, maxs, end, es->number, MASK_PLAYERSOLID );
- VectorMA( legs.origin, tr.fraction * -TRACE_DEPTH, surfNormal, legs.origin );
+
+ //if the trace misses completely then just use legs.origin
+ //apparently capsule traces are "smaller" than box traces
+ if( tr.fraction != 1.0f )
+ VectorMA( legs.origin, tr.fraction * -TRACE_DEPTH, surfNormal, legs.origin );
VectorCopy( legs.origin, legs.lightingOrigin );
VectorCopy( legs.origin, legs.oldorigin ); // don't positionally lerp at all
@@ -2229,7 +2256,7 @@ void CG_Corpse( centity_t *cent )
entityState_t *es = &cent->currentState;
int corpseNum;
int renderfx;
- qboolean shadow;
+ qboolean shadow = qfalse;
float shadowPlane;
vec3_t origin, liveZ, deadZ;
float scale;
diff --git a/src/cgame/cg_weapons.c b/src/cgame/cg_weapons.c
index 3b24ee11..1f06c35a 100644
--- a/src/cgame/cg_weapons.c
+++ b/src/cgame/cg_weapons.c
@@ -1475,12 +1475,12 @@ static qboolean CG_WeaponSelectable( int i )
BG_unpackAmmoArray( i, cg.snap->ps.ammo, cg.snap->ps.powerups, &ammo, &clips, &maxclips );
- if ( !ammo && !clips && !BG_FindInfinteAmmoForWeapon( i ) ) {
- return qfalse;
- }
- if ( !BG_gotWeapon( i, cg.snap->ps.stats ) ) {
+ //TA: this is a pain in the ass
+/* if( !ammo && !clips && !BG_FindInfinteAmmoForWeapon( i ) )
+ return qfalse;*/
+
+ if( !BG_gotWeapon( i, cg.snap->ps.stats ) )
return qfalse;
- }
return qtrue;
}
diff --git a/src/game/bg_pmove.c b/src/game/bg_pmove.c
index 26a95255..77692398 100644
--- a/src/game/bg_pmove.c
+++ b/src/game/bg_pmove.c
@@ -1926,7 +1926,7 @@ static void PM_GroundClimbTrace( void )
vectoangles( trace.plane.normal, toAngles );
vectoangles( pm->ps->grapplePoint, surfAngles );
- pm->ps->delta_angles[ 1 ] -= ANGLE2SHORT( ( ( surfAngles[ 1 ] - toAngles[ 1 ] ) * 2 ) - 180 );
+ pm->ps->delta_angles[ 1 ] -= ANGLE2SHORT( ( ( surfAngles[ 1 ] - toAngles[ 1 ] ) * 2 ) - 180.0f );
}
}
@@ -1949,7 +1949,6 @@ static void PM_GroundClimbTrace( void )
else if( trace.allsolid )
{
// do something corrective if the trace starts in a solid...
- //TA: fuck knows what this does with all my new stuff :(
if( !PM_CorrectAllSolid( &trace ) )
return;
}
diff --git a/src/game/g_buildable.c b/src/game/g_buildable.c
index a525ae9c..7035ec18 100644
--- a/src/game/g_buildable.c
+++ b/src/game/g_buildable.c
@@ -268,6 +268,62 @@ static qboolean isDCC( )
/*
================
+findOvermind
+
+Attempt to find an overmind for self
+================
+*/
+static qboolean findOvermind( gentity_t *self )
+{
+ int i;
+ gentity_t *ent;
+ gentity_t *closestOvermind;
+ int distance = 0;
+ int minDistance = 10000;
+ vec3_t temp_v;
+ qboolean foundOvermind = qfalse;
+
+ if( self->biteam != BIT_ALIENS )
+ return qfalse;
+
+ //if this already has dcc then stop now
+ if( self->overmindNode )
+ return qtrue;
+
+ //reset parent
+ self->overmindNode = NULL;
+
+ //iterate through entities
+ for( i = 1, ent = g_entities + i; i < level.num_entities; i++, ent++ )
+ {
+ if( !ent->classname || ent->s.eType != ET_BUILDABLE )
+ continue;
+
+ //if entity is a dcc calculate the distance to it
+ if( ent->s.modelindex == BA_A_OVERMIND && ent->spawned )
+ {
+ VectorSubtract( self->s.origin, ent->s.origin, temp_v );
+ distance = VectorLength( temp_v );
+ if( distance < minDistance && ent->powered )
+ {
+ closestOvermind = ent;
+ minDistance = distance;
+ foundOvermind = qtrue;
+ }
+ }
+ }
+
+ //if there were no power items nearby give up
+ if( !foundOvermind )
+ return qfalse;
+
+ self->overmindNode = closestOvermind;
+
+ return qtrue;
+}
+
+/*
+================
findCreep
attempt to find creep for self, return qtrue if successful
@@ -413,7 +469,14 @@ void A_CreepRecede( gentity_t *self )
{
self->s.eFlags |= EF_DEAD;
G_AddEvent( self, EV_BUILD_DESTROY, 0 );
- self->s.time = -level.time;
+
+ if( self->spawned )
+ self->s.time = -level.time;
+ else
+ self->s.time = -( level.time -
+ (int)( (float)CREEP_SCALEDOWN_TIME *
+ ( 1.0f - ( (float)( level.time - self->buildTime ) /
+ (float)BG_FindBuildTimeForBuildable( self->s.modelindex ) ) ) ) );
}
//creep is still receeding
@@ -448,7 +511,14 @@ void ASpawn_Melt( gentity_t *self )
{
self->s.eFlags |= EF_DEAD;
G_AddEvent( self, EV_BUILD_DESTROY, 0 );
- self->s.time = -level.time;
+
+ if( self->spawned )
+ self->s.time = -level.time;
+ else
+ self->s.time = -( level.time -
+ (int)( (float)CREEP_SCALEDOWN_TIME *
+ ( 1.0f - ( (float)( level.time - self->buildTime ) /
+ (float)BG_FindBuildTimeForBuildable( self->s.modelindex ) ) ) ) );
}
//not dead yet
@@ -500,7 +570,12 @@ void ASpawn_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
self->die = nullDieFunction;
self->think = ASpawn_Blast;
- self->nextthink = level.time + 5000; //wait .5 seconds before damaging others
+
+ if( self->spawned )
+ self->nextthink = level.time + 5000;
+ else
+ self->nextthink = level.time; //blast immediately
+
self->s.eFlags &= ~EF_FIRING; //prevent any firing effects
if( attacker && attacker->client && attacker->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS )
@@ -523,7 +598,7 @@ void ASpawn_Think( gentity_t *self )
{
gentity_t *ent;
- if( self->spawned )
+ if( self->spawned )
{
//only suicide if at rest
if( self->s.groundEntityNum )
@@ -706,7 +781,11 @@ void ABarricade_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker,
self->die = nullDieFunction;
self->think = ABarricade_Blast;
self->s.eFlags &= ~EF_FIRING; //prevent any firing effects
- self->nextthink = level.time + 5000;
+
+ if( self->spawned )
+ self->nextthink = level.time + 5000;
+ else
+ self->nextthink = level.time; //blast immediately
}
/*
@@ -800,7 +879,7 @@ void AAcidTube_Think( gentity_t *self )
return;
}
- if( self->spawned )
+ if( self->spawned && findOvermind( self ) )
{
//do some damage
num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES );
@@ -866,7 +945,7 @@ void AHive_Think( gentity_t *self )
if( self->timestamp < level.time )
self->active = qfalse; //nothing has returned in HIVE_REPEAT seconds, forget about it
- if( self->spawned && !self->active )
+ if( self->spawned && !self->active && findOvermind( self ) )
{
//do some damage
num = trap_EntitiesInBox( mins, maxs, entityList, MAX_GENTITIES );
@@ -999,7 +1078,7 @@ void AHovel_Use( gentity_t *self, gentity_t *other, gentity_t *activator )
{
vec3_t hovelOrigin, hovelAngles, inverseNormal;
- if( self->spawned )
+ if( self->spawned && findOvermind( self ) )
{
if( self->active )
{
@@ -1142,6 +1221,9 @@ void ABooster_Touch( gentity_t *self, gentity_t *other, trace_t *trace )
if( !self->spawned )
return;
+
+ if( !findOvermind( self ) )
+ return;
if( !client )
return;
@@ -1307,7 +1389,7 @@ void ATrapper_Think( gentity_t *self )
return;
}
- if( self->spawned )
+ if( self->spawned && findOvermind( self ) )
{
//if the current target is not valid find a new one
if( !ADef_CheckTarget( self, self->enemy, range ) )
@@ -1932,9 +2014,13 @@ void HSpawn_Die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
self->die = nullDieFunction;
self->think = HSpawn_Blast;
- self->nextthink = level.time + HUMAN_DETONATION_DELAY;
self->powered = qfalse; //free up power
self->s.eFlags &= ~EF_FIRING; //prevent any firing effects
+
+ if( self->spawned )
+ self->nextthink = level.time + HUMAN_DETONATION_DELAY;
+ else
+ self->nextthink = level.time; //blast immediately
if( attacker && attacker->client && attacker->client->ps.stats[ STAT_PTEAM ] == PTE_ALIENS )
{
@@ -1999,17 +2085,15 @@ void G_BuildableThink( gentity_t *ent, int msec )
{
int bHealth = BG_FindHealthForBuildable( ent->s.modelindex );
int bRegen = BG_FindRegenRateForBuildable( ent->s.modelindex );
+ int bTime = BG_FindBuildTimeForBuildable( ent->s.modelindex );
//pack health, power and dcc
//toggle spawned flag for buildables
if( !ent->spawned )
{
- if( ent->buildTime + BG_FindBuildTimeForBuildable( ent->s.modelindex ) < level.time )
- {
- ent->takedamage = qtrue;
+ if( ent->buildTime + bTime < level.time )
ent->spawned = qtrue;
- }
}
ent->s.generic1 = (int)( ( (float)ent->health / (float)bHealth ) * B_HEALTH_SCALE );
@@ -2032,14 +2116,13 @@ void G_BuildableThink( gentity_t *ent, int msec )
{
ent->time1000 -= 1000;
- //regenerate health
- if( ent->health > 0 && ent->health < bHealth && bRegen )
- {
+ if( !ent->spawned )
+ ent->health += (int)( ceil( (float)bHealth / (float)( bTime * 0.001 ) ) );
+ else if( ent->health > 0 && ent->health < bHealth && bRegen )
ent->health += bRegen;
-
- if( ent->health > bHealth )
- ent->health = bHealth;
- }
+
+ if( ent->health > bHealth )
+ ent->health = bHealth;
}
//fall back on normal physics routines
@@ -2306,7 +2389,7 @@ gentity_t *G_buildItem( gentity_t *builder, buildable_t buildable, vec3_t origin
built->biteam = built->s.modelindex2 = BG_FindTeamForBuildable( buildable );
BG_FindBBoxForBuildable( buildable, built->r.mins, built->r.maxs );
- built->health = BG_FindHealthForBuildable( buildable );
+ built->health = 1;
built->splashDamage = BG_FindSplashDamageForBuildable( buildable );
built->splashRadius = BG_FindSplashRadiusForBuildable( buildable );
@@ -2314,7 +2397,7 @@ gentity_t *G_buildItem( gentity_t *builder, buildable_t buildable, vec3_t origin
built->nextthink = BG_FindNextThinkForBuildable( buildable );
- built->takedamage = qfalse;
+ built->takedamage = qtrue;
built->spawned = qfalse;
built->buildTime = built->s.time = level.time;
@@ -2595,6 +2678,7 @@ void 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;
// drop to floor
diff --git a/src/game/g_client.c b/src/game/g_client.c
index da1fb811..dc1d37bf 100644
--- a/src/game/g_client.c
+++ b/src/game/g_client.c
@@ -1381,7 +1381,6 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles
VectorNormalize( dir );
VectorScale( dir, UP_VEL, client->ps.velocity );
-
}
G_AddPredictableEvent( ent, EV_PLAYER_RESPAWN, 0 );
@@ -1402,7 +1401,6 @@ void ClientSpawn( gentity_t *ent, gentity_t *spawn, vec3_t origin, vec3_t angles
// force the base weapon up
client->ps.weapon = WP_NONE;
client->ps.weaponstate = WEAPON_READY;
-
}
// don't allow full run speed for a bit
diff --git a/src/game/g_local.h b/src/game/g_local.h
index 2cdddf2e..9f267c51 100644
--- a/src/game/g_local.h
+++ b/src/game/g_local.h
@@ -189,6 +189,7 @@ struct gentity_s
qboolean powered; //TA: for human buildables
int builtBy; //TA: clientNum of person that built this
gentity_t *dccNode; //TA: controlling dcc
+ gentity_t *overmindNode;//TA: controlling overmind
qboolean dcced; //TA: controlled by a dcc or not?
qboolean spawned; //TA: whether or not this buildable has finished spawning
int buildTime; //TA: when this buildable was built
@@ -196,6 +197,8 @@ struct gentity_s
int overmindAttackTimer;
int overmindDyingTimer;
int overmindSpawnsTimer;
+ int nextPhysicsTime; //TA: buildables don't need to check what they're sitting on
+ // every single frame.. so only do it periodically
int credits[ MAX_CLIENTS ]; //TA: human credits for each client
qboolean creditsHash[ MAX_CLIENTS ]; //TA: track who has claimed credit
diff --git a/src/game/g_main.c b/src/game/g_main.c
index 0ad46bb9..8656f0f5 100644
--- a/src/game/g_main.c
+++ b/src/game/g_main.c
@@ -680,7 +680,7 @@ void countSpawns( void )
level.numAlienSpawns = 0;
level.numHumanSpawns = 0;
- for ( i = 1, ent = g_entities + i ; i < level.num_entities ; i++, ent++ )
+ for( i = 1, ent = g_entities + i ; i < level.num_entities ; i++, ent++ )
{
if( !ent->inuse )
continue;
@@ -703,34 +703,38 @@ Recalculate the quantity of building points available to the teams
*/
void calculateBuildPoints( void )
{
- int i;
- int bclass;
- gentity_t *ent;
- int localHTP = g_humanBuildPoints.integer,
- localATP = g_alienBuildPoints.integer;
+ int i;
+ int bclass;
+ buildable_t buildable;
+ gentity_t *ent;
+ int localHTP = g_humanBuildPoints.integer,
+ localATP = g_alienBuildPoints.integer;
level.humanBuildPoints = level.humanBuildPointsPowered = localHTP;
level.alienBuildPoints = localATP;
- for ( i = 1, ent = g_entities + i ; i < level.num_entities ; i++, ent++ )
+ for( i = 1, ent = g_entities + i ; i < level.num_entities ; i++, ent++ )
{
- if (!ent->inuse)
+ if( !ent->inuse )
+ continue;
+
+ if( ent->s.eType != ET_BUILDABLE )
continue;
- bclass = BG_FindBuildNumForEntityName( ent->classname );
+ buildable = ent->s.modelindex;
- if( bclass != BA_NONE )
+ if( buildable != BA_NONE )
{
- if( BG_FindTeamForBuildable( bclass ) == BIT_HUMANS )
+ if( BG_FindTeamForBuildable( buildable ) == BIT_HUMANS )
{
- level.humanBuildPoints -= BG_FindBuildPointsForBuildable( bclass );
+ level.humanBuildPoints -= BG_FindBuildPointsForBuildable( buildable );
if( ent->powered )
- level.humanBuildPointsPowered -= BG_FindBuildPointsForBuildable( bclass );
+ level.humanBuildPointsPowered -= BG_FindBuildPointsForBuildable( buildable );
}
else
{
- level.alienBuildPoints -= BG_FindBuildPointsForBuildable( bclass );
+ level.alienBuildPoints -= BG_FindBuildPointsForBuildable( buildable );
}
}
}
diff --git a/src/game/g_physics.c b/src/game/g_physics.c
index a1183ad4..856fcadb 100644
--- a/src/game/g_physics.c
+++ b/src/game/g_physics.c
@@ -68,6 +68,7 @@ static void G_Bounce( gentity_t *ent, trace_t *trace )
ent->s.pos.trTime = level.time;
}
+#define PHYSICS_TIME 200
/*
================
@@ -111,14 +112,20 @@ void G_Physics( gentity_t *ent, int msec )
// check think function
G_RunThink( ent );
- VectorCopy( ent->r.currentOrigin, origin );
+ //check floor infrequently
+ if( ent->nextPhysicsTime < level.time )
+ {
+ VectorCopy( ent->r.currentOrigin, origin );
+
+ VectorMA( origin, -2.0f, ent->s.origin2, origin );
- VectorMA( origin, -2.0f, ent->s.origin2, origin );
+ trap_Trace( &tr, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, origin, ent->s.number, mask );
+
+ if( tr.fraction == 1.0f )
+ ent->s.groundEntityNum = -1;
- trap_Trace( &tr, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, origin, ent->s.number, mask );
-
- if( tr.fraction == 1.0 )
- ent->s.groundEntityNum = -1;
+ ent->nextPhysicsTime = level.time + PHYSICS_TIME;
+ }
return;
}
@@ -138,7 +145,7 @@ void G_Physics( gentity_t *ent, int msec )
// check think function
G_RunThink( ent );
- if( tr.fraction == 1 )
+ if( tr.fraction == 1.0f )
return;
// if it is in a nodrop volume, remove it
diff --git a/src/game/tremulous.h b/src/game/tremulous.h
index a8960a0e..ccca7044 100644
--- a/src/game/tremulous.h
+++ b/src/game/tremulous.h
@@ -38,7 +38,7 @@
#define ABUILDER_BLOB_TIME 5000
#define SOLDIER_BITE_DMG ADM(60)
-#define SOLDIER_BITE_RANGE 80.0f
+#define SOLDIER_BITE_RANGE 64.0f
#define SOLDIER_BITE_REPEAT 500
#define HYDRA_CLAW_DMG ADM(40)
@@ -189,37 +189,38 @@
#define CREEP_TIMEOUT 1000
#define CREEP_MODIFIER 0.5f
#define CREEP_ARMOUR_MODIFIER 0.75f
+#define CREEP_SCALEDOWN_TIME 3000
#define ASPAWN_BP 100
-#define ASPAWN_BT 10000
+#define ASPAWN_BT 15000
#define ASPAWN_HEALTH ABHM(500)
-#define ASPAWN_REGEN 10
+#define ASPAWN_REGEN 8
#define ASPAWN_SPLASHDAMAGE 50
#define ASPAWN_SPLASHRADIUS 50
#define ASPAWN_CREEPSIZE 120
#define ASPAWN_VALUE 150
#define BARRICADE_BP 80
-#define BARRICADE_BT 10000
+#define BARRICADE_BT 20000
#define BARRICADE_HEALTH ABHM(350)
-#define BARRICADE_REGEN 15
+#define BARRICADE_REGEN 12
#define BARRICADE_SPLASHDAMAGE 50
#define BARRICADE_SPLASHRADIUS 50
#define BARRICADE_CREEPSIZE 120
#define BOOSTER_BP 120
-#define BOOSTER_BT 10000
+#define BOOSTER_BT 15000
#define BOOSTER_HEALTH ABHM(300)
-#define BOOSTER_REGEN 10
+#define BOOSTER_REGEN 8
#define BOOSTER_SPLASHDAMAGE 50
#define BOOSTER_SPLASHRADIUS 50
#define BOOSTER_CREEPSIZE 120
#define BOOSTER_INTERVAL 30000 //time in msec between uses (per player)
#define ACIDTUBE_BP 50
-#define ACIDTUBE_BT 10000
+#define ACIDTUBE_BT 15000
#define ACIDTUBE_HEALTH ABHM(200)
-#define ACIDTUBE_REGEN 10
+#define ACIDTUBE_REGEN 8
#define ACIDTUBE_SPLASHDAMAGE 40
#define ACIDTUBE_SPLASHRADIUS 300
#define ACIDTUBE_CREEPSIZE 120
@@ -227,9 +228,9 @@
#define ACIDTUBE_REPEAT 3000
#define HIVE_BP 50
-#define HIVE_BT 10000
+#define HIVE_BT 20000
#define HIVE_HEALTH ABHM(200)
-#define HIVE_REGEN 10
+#define HIVE_REGEN 8
#define HIVE_SPLASHDAMAGE 30
#define HIVE_SPLASHRADIUS 200
#define HIVE_CREEPSIZE 120
@@ -240,9 +241,9 @@
#define HIVE_DIR_CHANGE_PERIOD 500
#define TRAPPER_BP 150
-#define TRAPPER_BT 5000
+#define TRAPPER_BT 12000
#define TRAPPER_HEALTH ABHM(80)
-#define TRAPPER_REGEN 8
+#define TRAPPER_REGEN 6
#define TRAPPER_SPLASHDAMAGE 15
#define TRAPPER_SPLASHRADIUS 100
#define TRAPPER_CREEPSIZE 30
@@ -252,9 +253,9 @@
#define LOCKBLOB_DOT 0.85f // max angle = acos( LOCKBLOB_DOT )
#define OVERMIND_BP 0
-#define OVERMIND_BT 20000
+#define OVERMIND_BT 30000
#define OVERMIND_HEALTH ABHM(1000)
-#define OVERMIND_REGEN 15
+#define OVERMIND_REGEN 10
#define OVERMIND_SPLASHDAMAGE 100
#define OVERMIND_SPLASHRADIUS 300
#define OVERMIND_CREEPSIZE 120
@@ -263,7 +264,7 @@
#define OVERMIND_VALUE 300
#define HOVEL_BP 80
-#define HOVEL_BT 10000
+#define HOVEL_BT 15000
#define HOVEL_HEALTH ABHM(750)
#define HOVEL_REGEN 20
#define HOVEL_SPLASHDAMAGE 20
@@ -372,8 +373,8 @@
#define LCANNON_REPEAT 500
#define LCANNON_CHARGEREPEAT 1000
#define LCANNON_RELOAD 2000
-#define LCANNON_DAMAGE HDM(400)
-#define LCANNON_RADIUS 200
+#define LCANNON_DAMAGE HDM(300)
+#define LCANNON_RADIUS 150
#define LCANNON_SECONDARY_DAMAGE HDM(30)
#define LCANNON_SECONDARY_RADIUS 75
#define LCANNON_SPEED 250
@@ -457,7 +458,7 @@
#define MGTURRET_BP 80
#define MGTURRET_BT 10000
-#define MGTURRET_HEALTH HBHM(250)
+#define MGTURRET_HEALTH HBHM(500)
#define MGTURRET_SPLASHDAMAGE 50
#define MGTURRET_SPLASHRADIUS 100
#define MGTURRET_ANGULARSPEED 5 //degrees/think ~= 200deg/sec
@@ -466,7 +467,7 @@
#define MGTURRET_REPEAT 100
#define MGTURRET_RANGE 250
#define MGTURRET_SPREAD 200
-#define MGTURRET_DMG HDM(5)
+#define MGTURRET_DMG HDM(6)
#define MGTURRET_DCC_ANGULARSPEED 7
#define MGTURRET_DCC_ACCURACYTOLERANCE MGTURRET_DCC_ANGULARSPEED / 1.5f