diff options
author | Tim Angus <tim@ngus.net> | 2003-09-01 05:02:20 +0000 |
---|---|---|
committer | Tim Angus <tim@ngus.net> | 2003-09-01 05:02:20 +0000 |
commit | bfe055a63d4ce8577e6b86c2e9535993ae592c59 (patch) | |
tree | 0e4e516eccf6792e915f04bea5ccbfc8fe77841e /src | |
parent | 6a4b99df6b94a9bbf90a6f59c3583c76424b421f (diff) |
* Realistic falling damage
* Added fallDamage to class database
* Added DAMAGE_NO_LOCDAMAGE dflag to avoid calculating locational damage
Diffstat (limited to 'src')
-rw-r--r-- | src/game/bg_misc.c | 36 | ||||
-rw-r--r-- | src/game/bg_pmove.c | 6 | ||||
-rw-r--r-- | src/game/bg_public.h | 5 | ||||
-rw-r--r-- | src/game/g_active.c | 25 | ||||
-rw-r--r-- | src/game/g_combat.c | 57 | ||||
-rw-r--r-- | src/game/g_local.h | 1 | ||||
-rw-r--r-- | src/game/tremulous.h | 7 |
7 files changed, 101 insertions, 36 deletions
diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c index eeef5f36..7676c2cf 100644 --- a/src/game/bg_misc.c +++ b/src/game/bg_misc.c @@ -1235,6 +1235,7 @@ classAttributes_t bg_classList[ ] = { 15, 15, 4 }, //vec3_t deadmaxs; 0, 0, //int viewheight, crouchviewheight; ABUILDER_HEALTH, //int health; + 0.2f, //float fallDamage; ABUILDER_REGEN, //int regenRate; SCA_TAKESFALLDAMAGE|SCA_FOVWARPS| SCA_NOFOOTSTEPS, //int abilities; @@ -1267,6 +1268,7 @@ classAttributes_t bg_classList[ ] = { 20, 20, 4 }, //vec3_t deadmaxs; 0, 0, //int viewheight, crouchviewheight; ABUILDER_UPG_HEALTH, //int health; + 0.0f, //float fallDamage; ABUILDER_UPG_REGEN, //int regenRate; SCA_CANJUMP|SCA_FOVWARPS|SCA_WALLCLIMBER| SCA_NOFOOTSTEPS, //int abilities; @@ -1299,6 +1301,7 @@ classAttributes_t bg_classList[ ] = { 15, 15, 4 }, //vec3_t deadmaxs; 0, 0, //int viewheight, crouchviewheight; SOLDIER_HEALTH, //int health; + 0.0f, //float fallDamage; SOLDIER_REGEN, //int regenRate; SCA_WALLCLIMBER|SCA_CANJUMP|SCA_NOWEAPONDRIFT| SCA_FOVWARPS|SCA_ALIENSENSE|SCA_NOFOOTSTEPS, //int abilities; @@ -1331,6 +1334,7 @@ classAttributes_t bg_classList[ ] = { 18, 18, 4 }, //vec3_t deadmaxs; 9, 9, //int viewheight, crouchviewheight; HYDRA_HEALTH, //int health; + 0.0f, //float fallDamage; HYDRA_REGEN, //int regenRate; SCA_CANJUMP|SCA_NOWEAPONDRIFT| SCA_FOVWARPS|SCA_WALLCLIMBER|SCA_ALIENSENSE| @@ -1364,6 +1368,7 @@ classAttributes_t bg_classList[ ] = { 20, 20, 4 }, //vec3_t deadmaxs; 10, 10, //int viewheight, crouchviewheight; HYDRA_UPG_HEALTH, //int health; + 0.0f, //float fallDamage; HYDRA_UPG_REGEN, //int regenRate; SCA_CANJUMP|SCA_NOWEAPONDRIFT|SCA_FOVWARPS| SCA_WALLCLIMBER|SCA_ALIENSENSE| @@ -1397,6 +1402,7 @@ classAttributes_t bg_classList[ ] = { 32, 32, 4 }, //vec3_t deadmaxs; 24, 24, //int viewheight, crouchviewheight; DRAGOON_HEALTH, //int health; + 0.0f, //float fallDamage; DRAGOON_REGEN, //int regenRate; SCA_CANJUMP|SCA_NOWEAPONDRIFT| SCA_FOVWARPS|SCA_ALIENSENSE|SCA_NOFOOTSTEPS, //int abilities; @@ -1429,6 +1435,7 @@ classAttributes_t bg_classList[ ] = { 32, 32, 4 }, //vec3_t deadmaxs; 27, 27, //int viewheight, crouchviewheight; DRAGOON_UPG_HEALTH, //int health; + 0.0f, //float fallDamage; DRAGOON_UPG_REGEN, //int regenRate; SCA_CANJUMP|SCA_NOWEAPONDRIFT| SCA_FOVWARPS|SCA_ALIENSENSE|SCA_NOFOOTSTEPS, //int abilities; @@ -1461,6 +1468,7 @@ classAttributes_t bg_classList[ ] = { 22, 22, 4 }, //vec3_t deadmaxs; 30, 30, //int viewheight, crouchviewheight; CHIMERA_HEALTH, //int health; + 0.0f, //float fallDamage; CHIMERA_REGEN, //int regenRate; SCA_CANJUMP|SCA_NOWEAPONDRIFT| SCA_FOVWARPS|SCA_ALIENSENSE|SCA_NOFOOTSTEPS, //int abilities; @@ -1493,6 +1501,7 @@ classAttributes_t bg_classList[ ] = { 24, 24, 4 }, //vec3_t deadmaxs; 32, 32, //int viewheight, crouchviewheight; CHIMERA_UPG_HEALTH, //int health; + 0.0f, //float fallDamage; CHIMERA_UPG_REGEN, //int regenRate; SCA_CANJUMP|SCA_NOWEAPONDRIFT| SCA_FOVWARPS|SCA_ALIENSENSE|SCA_NOFOOTSTEPS, //int abilities; @@ -1525,6 +1534,7 @@ classAttributes_t bg_classList[ ] = { 15, 15, 4 }, //vec3_t deadmaxs; 50, 50, //int viewheight, crouchviewheight; BMOFO_HEALTH, //int health; + 0.0f, //float fallDamage; BMOFO_REGEN, //int regenRate; SCA_CANJUMP|SCA_NOWEAPONDRIFT| SCA_FOVWARPS|SCA_ALIENSENSE|SCA_NOFOOTSTEPS, //int abilities; @@ -1557,6 +1567,7 @@ classAttributes_t bg_classList[ ] = { 15, 15, 4 }, //vec3_t deadmaxs; 26, 12, //int viewheight, crouchviewheight; 100, //int health; + 1.0f, //float fallDamage; 0, //int regenRate; SCA_TAKESFALLDAMAGE|SCA_CANJUMP, //int abilities; WP_NONE, //special-cased in g_client.c //weapon_t startWeapon @@ -1582,7 +1593,7 @@ classAttributes_t bg_classList[ ] = "default", "bsuit", ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), { 0, 0, 0 }, { 0, 0, 0, }, - { 0, 0, 0, }, { 0, 0, 0, }, { 0, 0, 0, }, 0, 0, 0, 0, 0, WP_NONE, 0.0f, 0, + { 0, 0, 0, }, { 0, 0, 0, }, { 0, 0, 0, }, 0, 0, 0, 0.0f, 0, 0, WP_NONE, 0.0f, 0, 0.0f, 0, 1.0f, 1.0f, 1.0f, 1.0f, { PCL_NONE, PCL_NONE, PCL_NONE }, 0, 0 } }; @@ -1854,6 +1865,27 @@ int BG_FindHealthForClass( int pclass ) /* ============== +BG_FindFallDamageForClass +============== +*/ +float BG_FindFallDamageForClass( int pclass ) +{ + int i; + + for( i = 0; i < bg_numPclasses; i++ ) + { + if( bg_classList[ i ].classNum == pclass ) + { + return bg_classList[ i ].fallDamage; + } + } + + Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindFallDamageForClass\n" ); + return 100; +} + +/* +============== BG_FindRegenRateForClass ============== */ @@ -1995,7 +2027,7 @@ float BG_FindStopSpeedForClass( int pclass ) } } - Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindFrictionForClass\n" ); + Com_Printf( S_COLOR_YELLOW "WARNING: fallthrough in BG_FindStopSpeedForClass\n" ); return 100.0f; } diff --git a/src/game/bg_pmove.c b/src/game/bg_pmove.c index 9e0ad62c..df2f7c7e 100644 --- a/src/game/bg_pmove.c +++ b/src/game/bg_pmove.c @@ -1396,11 +1396,13 @@ static void PM_CrashLand( void ) // want to take damage or play a crunch sound if( !( pml.groundTrace.surfaceFlags & SURF_NODAMAGE ) ) { - if( delta > 60 ) + pm->ps->stats[ STAT_FALLDIST ] = delta; + + if( delta > AVG_FALL_DISTANCE ) { PM_AddEvent( EV_FALL_FAR ); } - else if( delta > 40 ) + else if( delta > MIN_FALL_DISTANCE ) { // this is a pain grunt, so don't play it if dead if( pm->ps->stats[STAT_HEALTH] > 0 ) diff --git a/src/game/bg_public.h b/src/game/bg_public.h index 29325ef1..02456057 100644 --- a/src/game/bg_public.h +++ b/src/game/bg_public.h @@ -206,7 +206,8 @@ typedef enum STAT_STATE, //TA: client states e.g. wall climbing STAT_MISC, //TA: for uh...misc stuff STAT_BUILDABLE, //TA: which ghost model to display for building - STAT_BOOSTTIME //TA: time left for boost (alien only) + STAT_BOOSTTIME, //TA: time left for boost (alien only) + STAT_FALLDIST //TA: the distance the player fell } statIndex_t; #define SCA_WALLCLIMBER 0x00000001 @@ -895,6 +896,7 @@ typedef struct int crouchViewheight; int health; + float fallDamage; int regenRate; int abilities; @@ -1091,6 +1093,7 @@ qboolean BG_FindStagesForClass( int pclass, stage_t stage ); void BG_FindBBoxForClass( int pclass, vec3_t mins, vec3_t maxs, vec3_t cmaxs, vec3_t dmins, vec3_t dmaxs ); void BG_FindViewheightForClass( int pclass, int *viewheight, int *cViewheight ); int BG_FindHealthForClass( int pclass ); +float BG_FindFallDamageForClass( int pclass ); int BG_FindRegenRateForClass( int pclass ); int BG_FindFovForClass( int pclass ); float BG_FindBobForClass( int pclass ); diff --git a/src/game/g_active.c b/src/game/g_active.c index 564e1f37..89a71b91 100644 --- a/src/game/g_active.c +++ b/src/game/g_active.c @@ -652,12 +652,15 @@ void ClientEvents( gentity_t *ent, int oldEventSequence ) gclient_t *client; int damage; vec3_t dir; - vec3_t origin, angles; + vec3_t point, mins; // qboolean fired; gitem_t *item; gentity_t *drop; + float fallDistance; + pClass_t class; client = ent->client; + class = client->ps.stats[ STAT_PCLASS ]; if( oldEventSequence < client->ps.eventSequence - MAX_PS_EVENTS ) oldEventSequence = client->ps.eventSequence - MAX_PS_EVENTS; @@ -673,14 +676,24 @@ void ClientEvents( gentity_t *ent, int oldEventSequence ) if( ent->s.eType != ET_PLAYER ) break; // not in the player model - if( event == EV_FALL_FAR ) - damage = 10; - else - damage = 5; + fallDistance = ( (float)client->ps.stats[ STAT_FALLDIST ] - MIN_FALL_DISTANCE ) / + ( MAX_FALL_DISTANCE - MIN_FALL_DISTANCE ); + + if( fallDistance < 0.0f ) + fallDistance = 0.0f; + else if( fallDistance > 1.0f ) + fallDistance = 1.0f; + damage = (int)( (float)BG_FindHealthForClass( class ) * + BG_FindFallDamageForClass( class ) * fallDistance ); + VectorSet( dir, 0, 0, 1 ); + BG_FindBBoxForClass( class, mins, NULL, NULL, NULL, NULL ); + mins[ 0 ] = mins[ 1 ] = 0.0f; + VectorAdd( client->ps.origin, mins, point ); + ent->pain_debounce_time = level.time + 200; // no normal pain sound - G_Damage( ent, NULL, NULL, NULL, NULL, damage, 0, MOD_FALLING ); + G_Damage( ent, NULL, NULL, dir, point, damage, DAMAGE_NO_LOCDAMAGE, MOD_FALLING ); break; case EV_FIRE_WEAPON: diff --git a/src/game/g_combat.c b/src/game/g_combat.c index f1e47877..e7024bfb 100644 --- a/src/game/g_combat.c +++ b/src/game/g_combat.c @@ -620,7 +620,7 @@ void G_ParseDmgScript( char *buf, int class ) G_CalcDamageModifier ============ */ -float G_CalcDamageModifier( vec3_t point, gentity_t *targ, gentity_t *attacker, int class ) +static float G_CalcDamageModifier( vec3_t point, gentity_t *targ, gentity_t *attacker, int class, int dflags ) { vec3_t bulletPath; vec3_t bulletAngle; @@ -628,7 +628,7 @@ float G_CalcDamageModifier( vec3_t point, gentity_t *targ, gentity_t *attacker, float clientHeight, hitRelative, hitRatio; int bulletRotation, clientRotation, hitRotation; - float modifier = 1.0; + float modifier = 1.0f; int i, j; clientHeight = targ->r.maxs[ 2 ] - targ->r.mins[ 2 ]; @@ -643,8 +643,11 @@ float G_CalcDamageModifier( vec3_t point, gentity_t *targ, gentity_t *attacker, hitRelative = DotProduct( normal, pMINUSfloor ) / VectorLength( normal ); - if( hitRelative < 0.0 ) hitRelative = 0.0; - if( hitRelative > clientHeight ) hitRelative = clientHeight; + if( hitRelative < 0.0f ) + hitRelative = 0.0f; + + if( hitRelative > clientHeight ) + hitRelative = clientHeight; hitRatio = hitRelative / clientHeight; @@ -658,29 +661,32 @@ float G_CalcDamageModifier( vec3_t point, gentity_t *targ, gentity_t *attacker, hitRotation = hitRotation % 360; // Keep it in the 0-359 range - for( i = 0; i < g_numDamageRegions[ class ]; i++ ) + if( !( dflags & DAMAGE_NO_LOCDAMAGE ) ) { - qboolean rotationBound; - - if( g_damageRegions[ class ][ i ].minAngle > - g_damageRegions[ class ][ i ].maxAngle ) + for( i = 0; i < g_numDamageRegions[ class ]; i++ ) { - rotationBound = ( hitRotation >= g_damageRegions[ class ][ i ].minAngle && - hitRotation <= 360 ) || ( hitRotation >= 0 && - hitRotation <= g_damageRegions[ class ][ i ].maxAngle ); - } - else - { - rotationBound = ( hitRotation >= g_damageRegions[ class ][ i ].minAngle && - hitRotation <= g_damageRegions[ class ][ i ].maxAngle ); + qboolean rotationBound; + + if( g_damageRegions[ class ][ i ].minAngle > + g_damageRegions[ class ][ i ].maxAngle ) + { + rotationBound = ( hitRotation >= g_damageRegions[ class ][ i ].minAngle && + hitRotation <= 360 ) || ( hitRotation >= 0 && + hitRotation <= g_damageRegions[ class ][ i ].maxAngle ); + } + else + { + rotationBound = ( hitRotation >= g_damageRegions[ class ][ i ].minAngle && + hitRotation <= g_damageRegions[ class ][ i ].maxAngle ); + } + + if( rotationBound && + hitRatio >= g_damageRegions[ class ][ i ].minHeight && + hitRatio <= g_damageRegions[ class ][ i ].maxHeight && + ( g_damageRegions[ class ][ i ].crouch == + ( targ->client->ps.pm_flags & PMF_DUCKED ) ) ) + modifier *= g_damageRegions[ class ][ i ].modifier; } - - if( rotationBound && - hitRatio >= g_damageRegions[ class ][ i ].minHeight && - hitRatio <= g_damageRegions[ class ][ i ].maxHeight && - ( g_damageRegions[ class ][ i ].crouch == - ( targ->client->ps.pm_flags & PMF_DUCKED ) ) ) - modifier *= g_damageRegions[ class ][ i ].modifier; } for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ ) @@ -977,7 +983,8 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, // set the last client who damaged the target targ->client->lasthurt_client = attacker->s.number; targ->client->lasthurt_mod = mod; - take = (int)( (float)take * G_CalcDamageModifier( point, targ, attacker, client->ps.stats[ STAT_PCLASS ] ) ); + take = (int)( (float)take * G_CalcDamageModifier( point, targ, attacker, + client->ps.stats[ STAT_PCLASS ], dflags ) ); //if boosted poison every attack if( attacker->client && attacker->client->ps.stats[ STAT_STATE ] & SS_BOOSTED ) diff --git a/src/game/g_local.h b/src/game/g_local.h index 9e2584b5..89e1cc17 100644 --- a/src/game/g_local.h +++ b/src/game/g_local.h @@ -631,6 +631,7 @@ void G_InitDamageLocations( void ); #define DAMAGE_NO_ARMOR 0x00000002 // armour does not protect from this damage #define DAMAGE_NO_KNOCKBACK 0x00000004 // do not affect velocity, just view angles #define DAMAGE_NO_PROTECTION 0x00000008 // armor, shields, invulnerability, and godmode have no effect +#define DAMAGE_NO_LOCDAMAGE 0x00000010 // so not apply locational damage // // g_missile.c diff --git a/src/game/tremulous.h b/src/game/tremulous.h index 6c356203..5977a7b6 100644 --- a/src/game/tremulous.h +++ b/src/game/tremulous.h @@ -484,3 +484,10 @@ #define STAMINA_SPRINT_TAKE 10 #define STAMINA_LARMOUR_TAKE 5 +/* + * Misc + */ + +#define MIN_FALL_DISTANCE 30.0f //the fall distance at which fall damage kicks in +#define MAX_FALL_DISTANCE 120.0f //the fall distance at which maximum damage is dealt +#define AVG_FALL_DISTANCE ((MIN_FALL_DISTANCE+MAX_FALL_DISTANCE)/2.0f) |