diff options
-rw-r--r-- | src/game/bg_pmove.c | 5 | ||||
-rw-r--r-- | src/game/g_active.c | 8 | ||||
-rw-r--r-- | src/game/g_cmds.c | 59 | ||||
-rw-r--r-- | src/game/g_combat.c | 207 | ||||
-rw-r--r-- | src/game/g_local.h | 11 | ||||
-rw-r--r-- | src/game/tremulous.h | 4 |
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 |