diff options
Diffstat (limited to 'src/game')
-rw-r--r-- | src/game/bg_pmove.c | 3 | ||||
-rw-r--r-- | src/game/g_buildable.c | 130 | ||||
-rw-r--r-- | src/game/g_client.c | 2 | ||||
-rw-r--r-- | src/game/g_local.h | 3 | ||||
-rw-r--r-- | src/game/g_main.c | 32 | ||||
-rw-r--r-- | src/game/g_physics.c | 21 | ||||
-rw-r--r-- | src/game/tremulous.h | 41 |
7 files changed, 164 insertions, 68 deletions
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 |