summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTim Angus <tim@ngus.net>2003-09-01 05:02:20 +0000
committerTim Angus <tim@ngus.net>2003-09-01 05:02:20 +0000
commitbfe055a63d4ce8577e6b86c2e9535993ae592c59 (patch)
tree0e4e516eccf6792e915f04bea5ccbfc8fe77841e /src
parent6a4b99df6b94a9bbf90a6f59c3583c76424b421f (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.c36
-rw-r--r--src/game/bg_pmove.c6
-rw-r--r--src/game/bg_public.h5
-rw-r--r--src/game/g_active.c25
-rw-r--r--src/game/g_combat.c57
-rw-r--r--src/game/g_local.h1
-rw-r--r--src/game/tremulous.h7
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)