summaryrefslogtreecommitdiff
path: root/src/game
diff options
context:
space:
mode:
authorMichael Levin <risujin@fastmail.fm>2009-10-03 11:14:25 +0000
committerTim Angus <tim@ngus.net>2013-01-03 00:14:47 +0000
commitc31fde4d9a30526bf6fb93d9bc00852e284bff5b (patch)
tree8e0d213a1a50a8768df96e198b90834fdcfdd9ac /src/game
parent64e9a5cc363ca9ff3c60edfbadfb417c0960c0d4 (diff)
* Dodge no longer drains stamina while flying with a jetpack
* Stamina will replenish when moving whith jetpack on * Damage region calculation code rewrite to be correct and compact * Added damage test function (cheats only), \damage [damage] * Norfenstein's balance tweaks: Dretch HP 25 -> 20, Basilisk grab time reduced
Diffstat (limited to 'src/game')
-rw-r--r--src/game/bg_pmove.c5
-rw-r--r--src/game/g_active.c8
-rw-r--r--src/game/g_cmds.c59
-rw-r--r--src/game/g_combat.c207
-rw-r--r--src/game/g_local.h11
-rw-r--r--src/game/tremulous.h4
6 files changed, 179 insertions, 115 deletions
diff --git a/src/game/bg_pmove.c b/src/game/bg_pmove.c
index e7915b96..1547ec1d 100644
--- a/src/game/bg_pmove.c
+++ b/src/game/bg_pmove.c
@@ -821,7 +821,7 @@ static qboolean PM_CheckWaterJump( void )
==================
PM_CheckDodge
-Starts a human dodge or sprint
+Checks the dodge key and starts a human dodge or sprint
==================
*/
static qboolean PM_CheckDodge( void )
@@ -1306,7 +1306,7 @@ static void PM_WalkMove( void )
return;
}
- if( PM_CheckJump( ) || PM_CheckPounce( ) || PM_CheckDodge( ) )
+ if( PM_CheckJump( ) || PM_CheckPounce( ) )
{
// jumped away
if( pm->waterlevel > 1 )
@@ -3532,6 +3532,7 @@ void PmoveSingle( pmove_t *pmove )
PM_DeadMove( );
PM_DropTimers( );
+ PM_CheckDodge( );
if( pm->ps->pm_type == PM_JETPACK )
PM_JetPackMove( );
diff --git a/src/game/g_active.c b/src/game/g_active.c
index a55e9e3b..242cdc67 100644
--- a/src/game/g_active.c
+++ b/src/game/g_active.c
@@ -573,13 +573,15 @@ void ClientTimerActions( gentity_t *ent, int msec )
client->time100 -= 100;
// Restore or subtract stamina
- if( client->ps.stats[ STAT_STATE ] & SS_SPEEDBOOST )
+ if( stopped || client->ps.pm_type == PM_JETPACK )
+ client->ps.stats[ STAT_STAMINA ] += STAMINA_STOP_RESTORE;
+ else if( client->ps.stats[ STAT_STATE ] & SS_SPEEDBOOST )
client->ps.stats[ STAT_STAMINA ] -= STAMINA_SPRINT_TAKE;
else if( walking || crouched )
client->ps.stats[ STAT_STAMINA ] += STAMINA_WALK_RESTORE;
- else if( stopped )
- client->ps.stats[ STAT_STAMINA ] += STAMINA_STOP_RESTORE;
+
+ // Check stamina limits
if( client->ps.stats[ STAT_STAMINA ] > MAX_STAMINA )
client->ps.stats[ STAT_STAMINA ] = MAX_STAMINA;
else if( client->ps.stats[ STAT_STAMINA ] < -MAX_STAMINA )
diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c
index 0878957d..e0e77cc1 100644
--- a/src/game/g_cmds.c
+++ b/src/game/g_cmds.c
@@ -2824,6 +2824,54 @@ static void Cmd_Ignore_f( gentity_t *ent )
}
}
+/*
+=================
+Cmd_Test_f
+=================
+*/
+static void Cmd_Test_f( gentity_t *ent )
+{
+}
+
+/*
+=================
+Cmd_Damage_f
+
+Deals damage to you (for testing), arguments: [damage] [dx] [dy] [dz]
+The dx/dy arguments describe the damage point's offset from the entity origin
+=================
+*/
+void Cmd_Damage_f( gentity_t *ent )
+{
+ vec3_t point;
+ char arg[ 16 ];
+ float dx = 0.f, dy = 0.f, dz = 100.f;
+ int damage = 100, angle = 180;
+ qboolean nonloc = qtrue;
+
+ if( trap_Argc() > 1 )
+ {
+ trap_Argv( 1, arg, sizeof( arg ) );
+ damage = atoi( arg );
+ }
+ if( trap_Argc() > 4 )
+ {
+ trap_Argv( 2, arg, sizeof( arg ) );
+ dx = atof( arg );
+ trap_Argv( 3, arg, sizeof( arg ) );
+ dy = atof( arg );
+ trap_Argv( 4, arg, sizeof( arg ) );
+ dz = atof( arg );
+ nonloc = qfalse;
+ }
+ VectorCopy( ent->s.origin, point );
+ point[ 0 ] += dx;
+ point[ 1 ] += dy;
+ point[ 2 ] += dz;
+ G_Damage( ent, NULL, NULL, NULL, point, damage,
+ ( nonloc ? DAMAGE_NO_LOCDAMAGE : 0 ), MOD_TARGET_LASER );
+}
+
commands_t cmds[ ] = {
// normal commands
{ "team", 0, Cmd_Team_f },
@@ -2851,8 +2899,8 @@ commands_t cmds[ ] = {
{ "levelshot", CMD_CHEAT, Cmd_LevelShot_f },
{ "setviewpos", CMD_CHEAT, Cmd_SetViewpos_f },
{ "destroy", CMD_CHEAT|CMD_TEAM|CMD_LIVING, Cmd_Destroy_f },
-
- { "kill", CMD_TEAM|CMD_LIVING, Cmd_Kill_f },
+ { "test", CMD_CHEAT, Cmd_Test_f },
+ { "damage", CMD_CHEAT|CMD_LIVING, Cmd_Damage_f },
// game commands
{ "ptrcverify", 0, Cmd_PTRCVerify_f },
@@ -2865,6 +2913,7 @@ commands_t cmds[ ] = {
{ "where", CMD_TEAM, Cmd_Where_f },
{ "teamvote", CMD_TEAM, Cmd_TeamVote_f },
{ "class", CMD_TEAM, Cmd_Class_f },
+ { "kill", CMD_TEAM|CMD_LIVING, Cmd_Kill_f },
{ "build", CMD_TEAM|CMD_LIVING, Cmd_Build_f },
{ "deconstruct", CMD_TEAM|CMD_LIVING, Cmd_Destroy_f },
@@ -2875,8 +2924,6 @@ commands_t cmds[ ] = {
{ "itemdeact", CMD_HUMAN|CMD_LIVING, Cmd_DeActivateItem_f },
{ "itemtoggle", CMD_HUMAN|CMD_LIVING, Cmd_ToggleItem_f },
{ "reload", CMD_HUMAN|CMD_LIVING, Cmd_Reload_f },
-
- { "test", 0, Cmd_Test_f }
};
static int numCmds = sizeof( cmds ) / sizeof( cmds[ 0 ] );
@@ -3215,7 +3262,3 @@ void G_PrivateMessage( gentity_t *ent )
}
}
-void Cmd_Test_f( gentity_t *ent )
-{
- G_Printf("%d\n", ent->client->pers.score);
-}
diff --git a/src/game/g_combat.c b/src/game/g_combat.c
index cf068fc0..7a339f56 100644
--- a/src/game/g_combat.c
+++ b/src/game/g_combat.c
@@ -26,7 +26,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
damageRegion_t g_damageRegions[ PCL_NUM_CLASSES ][ MAX_LOCDAMAGE_REGIONS ];
int g_numDamageRegions[ PCL_NUM_CLASSES ];
-armourRegion_t g_armourRegions[ UP_NUM_UPGRADES ][ MAX_ARMOUR_REGIONS ];
+damageRegion_t g_armourRegions[ UP_NUM_UPGRADES ][ MAX_ARMOUR_REGIONS ];
int g_numArmourRegions[ UP_NUM_UPGRADES ];
/*
@@ -664,6 +664,99 @@ void G_ParseDmgScript( char *buf, int class )
}
}
+/*
+============
+GetNonLocDamageModifier
+
+Returns the non-locational damage modifier for a set of regions. The method
+to calculate the damage in effect stretches every region across the entire
+body, diluting the modifier, and then returns the modifier as if the damage
+had hit through all the regions in turn.
+============
+*/
+static float GetNonLocDamageModifier( gentity_t *targ,
+ damageRegion_t *regions, int len )
+{
+ float modifier = 1.;
+ int i;
+
+ for( i = 0; i < len; i++ )
+ {
+ float angleSpan, heightSpan;
+
+ if( regions[ i ].crouch != ( targ->client->ps.pm_flags & PMF_DUCKED ) )
+ continue;
+
+ // Angle portion covered
+ if( regions[ i ].minAngle < regions[ i ].maxAngle )
+ angleSpan = regions[ i ].maxAngle - regions[ i ].minAngle;
+ else
+ angleSpan = 360 - regions[ i ].minAngle + regions[ i ].maxAngle;
+
+ if( angleSpan < 0.f )
+ angleSpan = 0.f;
+
+ if( angleSpan > 360.f )
+ angleSpan = 360.f;
+
+ angleSpan /= 360.f;
+
+ // Height portion covered
+ heightSpan = regions[ i ].maxHeight - regions[ i ].minHeight;
+
+ if( heightSpan < 0.f )
+ heightSpan = -heightSpan;
+
+ if( heightSpan > 1.f )
+ heightSpan = 1.f;
+
+ modifier += ( regions[ i ].modifier - modifier ) * angleSpan * heightSpan;
+ }
+
+ if( g_debugDamage.integer )
+ G_Printf( "GetNonLocDamageModifier(): %f\n", modifier );
+
+ return modifier;
+}
+
+/*
+============
+GetDamageRegionModifier
+
+Returns the damage region given an angle and a height proportion
+============
+*/
+static float GetDamageRegionModifier( gentity_t *targ, damageRegion_t *regions,
+ int len, float angle, float height )
+{
+ float modifier = 1.f;
+ int i;
+
+ for( i = 0; i < len; i++ )
+ {
+ // Angle must be within range
+ if( ( regions[ i ].minAngle <= regions[ i ].maxAngle &&
+ ( angle < regions[ i ].minAngle || angle > regions[ i ].maxAngle ) ||
+ ( regions[ i ].minAngle > regions[ i ].maxAngle &&
+ angle > regions[ i ].maxAngle && angle < regions[ i ].minAngle ) ) )
+ continue;
+
+ // Height must be within range
+ if( height < regions[ i ].minHeight || height > regions[ i ].maxHeight )
+ continue;
+
+ // Crouch state must match
+ if( regions[ i ].crouch != ( targ->client->ps.pm_flags & PMF_DUCKED ) )
+ continue;
+
+ modifier *= regions[ i ].modifier;
+ }
+
+ if( g_debugDamage.integer )
+ G_Printf( "GetDamageRegionModifier(): %f\n", modifier );
+
+ return modifier;
+}
/*
============
@@ -672,132 +765,67 @@ G_CalcDamageModifier
*/
static float G_CalcDamageModifier( vec3_t point, gentity_t *targ, gentity_t *attacker, int class, int dflags )
{
- vec3_t targOrigin;
- vec3_t bulletPath;
- vec3_t bulletAngle;
- vec3_t pMINUSfloor, floor, normal;
-
- float clientHeight, hitRelative, hitRatio;
- int bulletRotation, clientRotation, hitRotation;
- float modifier = 1.0f;
- int i, j;
+ vec3_t targOrigin, bulletPath, bulletAngle, pMINUSfloor, floor, normal;
+ float clientHeight, hitRelative, hitRatio, modifier;
+ int hitRotation, i, j;
if( point == NULL )
return 1.0f;
+ // Get the point location relative to the floor under the target
if( g_unlagged.integer && targ->client && targ->client->unlaggedCalc.used )
VectorCopy( targ->client->unlaggedCalc.origin, targOrigin );
else
VectorCopy( targ->r.currentOrigin, targOrigin );
-
- clientHeight = targ->r.maxs[ 2 ] - targ->r.mins[ 2 ];
-
BG_GetClientNormal( &targ->client->ps, normal );
-
VectorMA( targOrigin, targ->r.mins[ 2 ], normal, floor );
VectorSubtract( point, floor, pMINUSfloor );
+ // Get the proportion of the target height where the hit landed
+ clientHeight = targ->r.maxs[ 2 ] - targ->r.mins[ 2 ];
hitRelative = DotProduct( normal, pMINUSfloor ) / VectorLength( normal );
-
if( hitRelative < 0.0f )
hitRelative = 0.0f;
-
if( hitRelative > clientHeight )
hitRelative = clientHeight;
-
hitRatio = hitRelative / clientHeight;
+ // Get the yaw of the attack relative to the target's view yaw
VectorSubtract( targOrigin, point, bulletPath );
vectoangles( bulletPath, bulletAngle );
+ hitRotation = targ->client->ps.viewangles[ YAW ] - bulletAngle[ YAW ];
+ if( hitRotation < 0.f )
+ hitRotation += 360.f;
- clientRotation = targ->client->ps.viewangles[ YAW ];
- bulletRotation = bulletAngle[ YAW ];
-
- hitRotation = abs( clientRotation - bulletRotation );
-
- hitRotation = hitRotation % 360; // Keep it in the 0-359 range
-
+ // Get modifiers from the target's armour and damage regions
if( dflags & DAMAGE_NO_LOCDAMAGE )
{
+ modifier = GetNonLocDamageModifier( targ, g_damageRegions[ class ],
+ g_numDamageRegions[ class ] );
for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ )
{
- float totalModifier = 0.0f;
- float averageModifier = 1.0f;
-
- //average all of this upgrade's armour regions together
if( BG_InventoryContainsUpgrade( i, targ->client->ps.stats ) )
{
- for( j = 0; j < g_numArmourRegions[ i ]; j++ )
- totalModifier += g_armourRegions[ i ][ j ].modifier;
-
- if( g_numArmourRegions[ i ] )
- averageModifier = totalModifier / g_numArmourRegions[ i ];
- else
- averageModifier = 1.0f;
+ modifier *= GetNonLocDamageModifier( targ, g_armourRegions[ i ],
+ g_numArmourRegions[ i ] );
}
-
- modifier *= averageModifier;
}
}
else
{
- for( i = 0; i < g_numDamageRegions[ class ]; i++ )
- {
- 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;
- }
-
+ modifier = GetDamageRegionModifier( targ, g_damageRegions[ class ],
+ g_numDamageRegions[ class ],
+ hitRotation, hitRatio );
for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ )
{
if( BG_InventoryContainsUpgrade( i, targ->client->ps.stats ) )
{
- for( j = 0; j < g_numArmourRegions[ i ]; j++ )
- {
- qboolean rotationBound;
-
- if( g_armourRegions[ i ][ j ].minAngle >
- g_armourRegions[ i ][ j ].maxAngle )
- {
- rotationBound = ( hitRotation >= g_armourRegions[ i ][ j ].minAngle &&
- hitRotation <= 360 ) || ( hitRotation >= 0 &&
- hitRotation <= g_armourRegions[ i ][ j ].maxAngle );
- }
- else
- {
- rotationBound = ( hitRotation >= g_armourRegions[ i ][ j ].minAngle &&
- hitRotation <= g_armourRegions[ i ][ j ].maxAngle );
- }
-
- if( rotationBound &&
- hitRatio >= g_armourRegions[ i ][ j ].minHeight &&
- hitRatio <= g_armourRegions[ i ][ j ].maxHeight &&
- ( g_armourRegions[ i ][ j ].crouch ==
- ( targ->client->ps.pm_flags & PMF_DUCKED ) ) )
- modifier *= g_armourRegions[ i ][ j ].modifier;
- }
+ modifier *= GetDamageRegionModifier( targ, g_armourRegions[ i ],
+ g_numArmourRegions[ i ],
+ hitRotation, hitRatio );
}
}
}
-
return modifier;
}
@@ -1111,8 +1139,9 @@ 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 ], dflags ) );
+ take = (int)( take * G_CalcDamageModifier( point, targ, attacker,
+ client->ps.stats[ STAT_PCLASS ],
+ dflags ) + 0.5f );
//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 14673f2f..3fb2dcb9 100644
--- a/src/game/g_local.h
+++ b/src/game/g_local.h
@@ -513,17 +513,6 @@ typedef struct damageRegion_s
#define MAX_ARMOUR_TEXT 8192
#define MAX_ARMOUR_REGIONS 16
-// store locational armour regions
-typedef struct armourRegion_s
-{
- float minHeight, maxHeight;
- int minAngle, maxAngle;
-
- float modifier;
-
- qboolean crouch;
-} armourRegion_t;
-
//status of the warning of certain events
typedef enum
{
diff --git a/src/game/tremulous.h b/src/game/tremulous.h
index 47dbb438..311db017 100644
--- a/src/game/tremulous.h
+++ b/src/game/tremulous.h
@@ -63,8 +63,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define LEVEL1_CLAW_K_SCALE 1.0f
#define LEVEL1_CLAW_U_K_SCALE 1.0f
#define LEVEL1_GRAB_RANGE 96.0f
-#define LEVEL1_GRAB_TIME 400
-#define LEVEL1_GRAB_U_TIME 600
+#define LEVEL1_GRAB_TIME 300
+#define LEVEL1_GRAB_U_TIME 500
#define LEVEL1_PCLOUD_DMG ADM(4)
#define LEVEL1_PCLOUD_RANGE 150.0f
#define LEVEL1_PCLOUD_REPEAT 2500