Created
March 18, 2016 18:39
-
-
Save ensiform/27c30883c10656ea2721 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/code/game/wp_saber.cpp b/code/game/wp_saber.cpp | |
index e8c41a4..bea9238 100644 | |
--- a/code/game/wp_saber.cpp | |
+++ b/code/game/wp_saber.cpp | |
@@ -30,8 +30,29 @@ along with this program; if not, see <http://www.gnu.org/licenses/>. | |
#include "../qcommon/tri_coll_test.h" | |
#include "../cgame/cg_local.h" | |
+#include <vector> | |
+ | |
#define JK2_RAGDOLL_GRIPNOHEALTH | |
+struct SaberDamage | |
+{ | |
+ int victimEntityNum; | |
+ float totalDmg; | |
+ vec3_t dmgDir; | |
+ vec3_t dmgNormal; | |
+ vec3_t dmgBladeVec; | |
+ vec3_t dmgSpot; | |
+ float dmgFraction; | |
+ int hitLoc; | |
+ qboolean hitDismember; | |
+ int hitDismemberLoc; | |
+}; | |
+ | |
+using SaberDamageVector = std::vector<SaberDamage>; | |
+ | |
+SaberDamageVector saberDamage; | |
+ | |
+#if 0 | |
#define MAX_SABER_VICTIMS 16 | |
static int victimEntityNum[MAX_SABER_VICTIMS]; | |
static float totalDmg[MAX_SABER_VICTIMS]; | |
@@ -43,11 +64,12 @@ static float dmgFraction[MAX_SABER_VICTIMS]; | |
static int hitLoc[MAX_SABER_VICTIMS]; | |
static qboolean hitDismember[MAX_SABER_VICTIMS]; | |
static int hitDismemberLoc[MAX_SABER_VICTIMS]; | |
+#endif | |
static vec3_t saberHitLocation, saberHitNormal={0,0,1.0}; | |
static float saberHitFraction; | |
static float sabersCrossed; | |
static int saberHitEntity; | |
-static int numVictims = 0; | |
+//static int numVictims = 0; | |
extern cvar_t *g_sex; | |
extern cvar_t *g_timescale; | |
@@ -1277,18 +1299,21 @@ void WP_SaberClearDamageForEntNum( gentity_t *attacker, int entityNum, int saber | |
} | |
} | |
- for ( int i = 0; i < numVictims; i++ ) | |
+ if ( saberDamage.empty() ) | |
+ return; | |
+ | |
+ for ( auto &it : saberDamage ) | |
{ | |
- if ( victimEntityNum[i] == entityNum ) | |
+ if ( it.victimEntityNum == entityNum ) | |
{ | |
//hold on a sec, let's still do any accumulated knockback | |
if ( knockBackScale ) | |
{ | |
- gentity_t *victim = &g_entities[victimEntityNum[i]]; | |
+ gentity_t *victim = &g_entities[it.victimEntityNum]; | |
if ( victim && victim->client ) | |
{ | |
vec3_t center, dirToCenter; | |
- float knockDownThreshHold, knockback = knockBackScale * totalDmg[i] * 0.5f; | |
+ float knockDownThreshHold, knockback = knockBackScale * it.totalDmg * 0.5f; | |
VectorAdd( victim->absmin, victim->absmax, center ); | |
VectorScale( center, 0.5, center ); | |
@@ -1296,7 +1321,7 @@ void WP_SaberClearDamageForEntNum( gentity_t *attacker, int entityNum, int saber | |
VectorNormalize( dirToCenter ); | |
G_Throw( victim, dirToCenter, knockback ); | |
if ( victim->client->ps.groundEntityNum != ENTITYNUM_NONE | |
- && dirToCenter[2] <= 0 ) | |
+ && dirToCenter[2] <= 0 ) | |
{//hit downward on someone who is standing on firm ground, so more likely to knock them down | |
knockDownThreshHold = Q_irand( 25, 50 ); | |
} | |
@@ -1312,11 +1337,11 @@ void WP_SaberClearDamageForEntNum( gentity_t *attacker, int entityNum, int saber | |
} | |
} | |
//now clear everything | |
- totalDmg[i] = 0;//no damage | |
- hitLoc[i] = HL_NONE; | |
- hitDismemberLoc[i] = HL_NONE; | |
- hitDismember[i] = qfalse; | |
- victimEntityNum[i] = ENTITYNUM_NONE;//like we never hit him | |
+ it.totalDmg = 0;//no damage | |
+ it.hitLoc = HL_NONE; | |
+ it.hitDismemberLoc = HL_NONE; | |
+ it.hitDismember = qfalse; | |
+ it.victimEntityNum = ENTITYNUM_NONE;//like we never hit him | |
} | |
} | |
} | |
@@ -1332,22 +1357,20 @@ qboolean WP_SaberApplyDamage( gentity_t *ent, float baseDamage, int baseDFlags, | |
float maxDmg; | |
saberType_t saberType = ent->client->ps.saber[saberNum].type; | |
- if ( !numVictims ) | |
- { | |
+ if ( saberDamage.empty() ) | |
return qfalse; | |
- } | |
- for ( int i = 0; i < numVictims; i++ ) | |
+ | |
+ for ( auto &it : saberDamage ) | |
{ | |
- dFlags = baseDFlags|DAMAGE_DEATH_KNOCKBACK|DAMAGE_NO_HIT_LOC; | |
- if ( victimEntityNum[i] != ENTITYNUM_NONE && &g_entities[victimEntityNum[i]] != NULL ) | |
- { // Don't bother with this damage if the fraction is higher than the saber's fraction | |
- if ( dmgFraction[i] < saberHitFraction || brokenParry ) | |
+ dFlags = baseDFlags | DAMAGE_DEATH_KNOCKBACK | DAMAGE_NO_HIT_LOC; | |
+ if ( it.victimEntityNum != ENTITYNUM_NONE && &g_entities[it.victimEntityNum] != NULL ) | |
+ { | |
+ // Don't bother with this damage if the fraction is higher than the saber's fraction | |
+ if ( it.dmgFraction < saberHitFraction || brokenParry ) | |
{ | |
- victim = &g_entities[victimEntityNum[i]]; | |
+ victim = &g_entities[it.victimEntityNum]; | |
if ( !victim ) | |
- { | |
continue; | |
- } | |
if ( victim->e_DieFunc == dieF_maglock_die ) | |
{//*sigh*, special check for maglocks | |
@@ -1368,10 +1391,10 @@ qboolean WP_SaberApplyDamage( gentity_t *ent, float baseDamage, int baseDFlags, | |
continue; | |
} | |
} | |
- if ( totalDmg[i] > 0 ) | |
+ if ( it.totalDmg > 0 ) | |
{//actually want to do *some* damage here | |
if ( victim->client | |
- && victim->client->NPC_class==CLASS_WAMPA | |
+ && victim->client->NPC_class == CLASS_WAMPA | |
&& victim->activator == ent ) | |
{ | |
} | |
@@ -1382,63 +1405,63 @@ qboolean WP_SaberApplyDamage( gentity_t *ent, float baseDamage, int baseDFlags, | |
else | |
{ | |
if ( victim->client | |
- && (victim->s.weapon == WP_SABER || (victim->client->NPC_class==CLASS_REBORN) || (victim->client->NPC_class==CLASS_WAMPA)) | |
+ && (victim->s.weapon == WP_SABER || (victim->client->NPC_class == CLASS_REBORN) || (victim->client->NPC_class == CLASS_WAMPA)) | |
&& !g_saberRealisticCombat->integer ) | |
{//dmg vs other saber fighters is modded by hitloc and capped | |
- totalDmg[i] *= damageModifier[hitLoc[i]]; | |
- if ( hitLoc[i] == HL_NONE ) | |
+ it.totalDmg *= damageModifier[it.hitLoc]; | |
+ if ( it.hitLoc == HL_NONE ) | |
{ | |
- maxDmg = 33*baseDamage; | |
+ maxDmg = 33 * baseDamage; | |
} | |
else | |
{ | |
- maxDmg = 50*hitLocHealthPercentage[hitLoc[i]]*baseDamage;//*victim->client->ps.stats[STAT_MAX_HEALTH]*2.0f; | |
+ maxDmg = 50 * hitLocHealthPercentage[it.hitLoc] * baseDamage;//*victim->client->ps.stats[STAT_MAX_HEALTH]*2.0f; | |
} | |
- if ( maxDmg < totalDmg[i] ) | |
+ if ( maxDmg < it.totalDmg ) | |
{ | |
- totalDmg[i] = maxDmg; | |
+ it.totalDmg = maxDmg; | |
} | |
//dFlags |= DAMAGE_NO_HIT_LOC; | |
} | |
//clamp the dmg | |
if ( victim->s.weapon != WP_SABER ) | |
{//clamp the dmg between 25 and maxhealth | |
- /* | |
- if ( totalDmg[i] > victim->max_health ) | |
- { | |
- totalDmg[i] = victim->max_health; | |
- } | |
- else */if ( totalDmg[i] < 25 ) | |
- { | |
- totalDmg[i] = 25; | |
- } | |
- if ( totalDmg[i] > 100 )//+(50*g_spskill->integer) ) | |
- {//clamp using same adjustment as in NPC_Begin | |
- totalDmg[i] = 100;//+(50*g_spskill->integer); | |
- } | |
+ /* | |
+ if ( totalDmg[i] > victim->max_health ) | |
+ { | |
+ totalDmg[i] = victim->max_health; | |
+ } | |
+ else */if ( it.totalDmg < 25 ) | |
+ { | |
+ it.totalDmg = 25; | |
+ } | |
+ if ( it.totalDmg > 100 )//+(50*g_spskill->integer) ) | |
+ {//clamp using same adjustment as in NPC_Begin | |
+ it.totalDmg = 100;//+(50*g_spskill->integer); | |
+ } | |
} | |
else | |
{//clamp the dmg between 5 and 100 | |
- if ( !victim->s.number && totalDmg[i] > 50 ) | |
+ if ( !victim->s.number && it.totalDmg > 50 ) | |
{//never do more than half full health damage to player | |
- //prevents one-hit kills | |
- totalDmg[i] = 50; | |
+ //prevents one-hit kills | |
+ it.totalDmg = 50; | |
} | |
- else if ( totalDmg[i] > 100 ) | |
+ else if ( it.totalDmg > 100 ) | |
{ | |
- totalDmg[i] = 100; | |
+ it.totalDmg = 100; | |
} | |
else | |
{ | |
- if ( totalDmg[i] < 5 ) | |
+ if ( it.totalDmg < 5 ) | |
{ | |
- totalDmg[i] = 5; | |
+ it.totalDmg = 5; | |
} | |
} | |
} | |
} | |
- if ( totalDmg[i] > 0 ) | |
+ if ( it.totalDmg > 0 ) | |
{ | |
gentity_t *inflictor = ent; | |
didDamage = qtrue; | |
@@ -1450,7 +1473,7 @@ qboolean WP_SaberApplyDamage( gentity_t *ent, float baseDamage, int baseDFlags, | |
dFlags |= DAMAGE_NO_DAMAGE; | |
} | |
- if( victim->client ) | |
+ if ( victim->client ) | |
{ | |
if ( victim->client->ps.pm_time > 0 && victim->client->ps.pm_flags & PMF_TIME_KNOCKBACK && victim->client->ps.velocity[2] > 0 ) | |
{//already being knocked around | |
@@ -1469,12 +1492,12 @@ qboolean WP_SaberApplyDamage( gentity_t *ent, float baseDamage, int baseDFlags, | |
if ( debug_subdivision->integer || g_saberRealisticCombat->integer ) | |
{ | |
dFlags |= DAMAGE_DISMEMBER; | |
- if ( hitDismember[i] ) | |
+ if ( it.hitDismember ) | |
{ | |
victim->client->dismembered = false; | |
} | |
} | |
- else if ( hitDismember[i] ) | |
+ else if ( it.hitDismember ) | |
{ | |
dFlags |= DAMAGE_DISMEMBER; | |
} | |
@@ -1495,11 +1518,11 @@ qboolean WP_SaberApplyDamage( gentity_t *ent, float baseDamage, int baseDFlags, | |
{ | |
if ( victim->takedamage ) | |
{//some other breakable thing | |
- //create a flash here | |
+ //create a flash here | |
if ( !g_noClashFlare ) | |
{ | |
- g_saberFlashTime = level.time-50; | |
- VectorCopy( dmgSpot[i], g_saberFlashPos ); | |
+ g_saberFlashTime = level.time - 50; | |
+ VectorCopy( it.dmgSpot, g_saberFlashPos ); | |
} | |
} | |
} | |
@@ -1512,44 +1535,44 @@ qboolean WP_SaberApplyDamage( gentity_t *ent, float baseDamage, int baseDFlags, | |
&& victim->s.number >= MAX_CLIENTS ) | |
{ | |
if ( victim->client->NPC_class == CLASS_SHADOWTROOPER | |
- || ( victim->NPC && (victim->NPC->aiFlags&NPCAI_BOSS_CHARACTER) ) ) | |
+ || (victim->NPC && (victim->NPC->aiFlags&NPCAI_BOSS_CHARACTER)) ) | |
{//hit a boss character | |
- int maxDmg = ((3-g_spskill->integer)*5)+10; | |
- if ( totalDmg[i] > maxDmg ) | |
+ int maxDmg = ((3 - g_spskill->integer) * 5) + 10; | |
+ if ( it.totalDmg > maxDmg ) | |
{ | |
- totalDmg[i] = maxDmg; | |
+ it.totalDmg = maxDmg; | |
} | |
} | |
else if ( victim->client->ps.weapon == WP_SABER | |
|| victim->client->NPC_class == CLASS_REBORN | |
|| victim->client->NPC_class == CLASS_JEDI ) | |
{//hit a non-boss saber-user | |
- int maxDmg = ((3-g_spskill->integer)*15)+30; | |
- if ( totalDmg[i] > maxDmg ) | |
+ int maxDmg = ((3 - g_spskill->integer) * 15) + 30; | |
+ if ( it.totalDmg > maxDmg ) | |
{ | |
- totalDmg[i] = maxDmg; | |
+ it.totalDmg = maxDmg; | |
} | |
} | |
} | |
if ( victim->s.number < MAX_CLIENTS | |
&& ent->NPC ) | |
{ | |
- if ( (ent->NPC->aiFlags&NPCAI_BOSS_CHARACTER) | |
+ if ( (ent->NPC->aiFlags&NPCAI_BOSS_CHARACTER) | |
|| (ent->NPC->aiFlags&NPCAI_SUBBOSS_CHARACTER) | |
|| ent->client->NPC_class == CLASS_SHADOWTROOPER ) | |
{//player hit by a boss character | |
- int maxDmg = ((g_spskill->integer+1)*4)+3; | |
- if ( totalDmg[i] > maxDmg ) | |
+ int maxDmg = ((g_spskill->integer + 1) * 4) + 3; | |
+ if ( it.totalDmg > maxDmg ) | |
{ | |
- totalDmg[i] = maxDmg; | |
+ it.totalDmg = maxDmg; | |
} | |
} | |
else if ( g_spskill->integer < 3 ) //was < 2 | |
{//player hit by any enemy //on easy or medium? | |
- int maxDmg = ((g_spskill->integer+1)*10)+20; | |
- if ( totalDmg[i] > maxDmg ) | |
+ int maxDmg = ((g_spskill->integer + 1) * 10) + 20; | |
+ if ( it.totalDmg > maxDmg ) | |
{ | |
- totalDmg[i] = maxDmg; | |
+ it.totalDmg = maxDmg; | |
} | |
} | |
} | |
@@ -1566,7 +1589,7 @@ qboolean WP_SaberApplyDamage( gentity_t *ent, float baseDamage, int baseDFlags, | |
} | |
if ( ent->client && !ent->s.number ) | |
{ | |
- switch( hitLoc[i] ) | |
+ switch ( it.hitLoc ) | |
{ | |
case HL_FOOT_RT: | |
case HL_FOOT_LT: | |
@@ -1597,12 +1620,12 @@ qboolean WP_SaberApplyDamage( gentity_t *ent, float baseDamage, int baseDFlags, | |
if ( saberType == SABER_SITH_SWORD ) | |
{//do knockback | |
- dFlags &= ~(DAMAGE_NO_KNOCKBACK|DAMAGE_DEATH_KNOCKBACK); | |
+ dFlags &= ~(DAMAGE_NO_KNOCKBACK | DAMAGE_DEATH_KNOCKBACK); | |
} | |
if ( !WP_SaberBladeUseSecondBladeStyle( &ent->client->ps.saber[saberNum], bladeNum ) | |
&& ent->client->ps.saber[saberNum].knockbackScale > 0.0f ) | |
{ | |
- dFlags &= ~(DAMAGE_NO_KNOCKBACK|DAMAGE_DEATH_KNOCKBACK); | |
+ dFlags &= ~(DAMAGE_NO_KNOCKBACK | DAMAGE_DEATH_KNOCKBACK); | |
if ( saberNum < 1 ) | |
{ | |
dFlags |= DAMAGE_SABER_KNOCKBACK1; | |
@@ -1615,7 +1638,7 @@ qboolean WP_SaberApplyDamage( gentity_t *ent, float baseDamage, int baseDFlags, | |
else if ( WP_SaberBladeUseSecondBladeStyle( &ent->client->ps.saber[saberNum], bladeNum ) | |
&& ent->client->ps.saber[saberNum].knockbackScale2 > 0.0f ) | |
{ | |
- dFlags &= ~(DAMAGE_NO_KNOCKBACK|DAMAGE_DEATH_KNOCKBACK); | |
+ dFlags &= ~(DAMAGE_NO_KNOCKBACK | DAMAGE_DEATH_KNOCKBACK); | |
if ( saberNum < 1 ) | |
{ | |
dFlags |= DAMAGE_SABER_KNOCKBACK1_B2; | |
@@ -1633,40 +1656,40 @@ qboolean WP_SaberApplyDamage( gentity_t *ent, float baseDamage, int baseDFlags, | |
if ( !WP_SaberBladeUseSecondBladeStyle( &ent->client->ps.saber[saberNum], bladeNum ) | |
&& ent->client->ps.saber[saberNum].damageScale != 1.0f ) | |
{ | |
- damage = ceil(totalDmg[i]*ent->client->ps.saber[saberNum].damageScale); | |
+ damage = ceil( it.totalDmg * ent->client->ps.saber[saberNum].damageScale ); | |
} | |
else if ( WP_SaberBladeUseSecondBladeStyle( &ent->client->ps.saber[saberNum], bladeNum ) | |
&& ent->client->ps.saber[saberNum].damageScale2 != 1.0f ) | |
{ | |
- damage = ceil(totalDmg[i]*ent->client->ps.saber[saberNum].damageScale2); | |
+ damage = ceil( it.totalDmg * ent->client->ps.saber[saberNum].damageScale2 ); | |
} | |
else | |
{ | |
- damage = ceil(totalDmg[i]); | |
+ damage = ceil( it.totalDmg ); | |
} | |
- G_Damage( victim, inflictor, ent, dmgDir[i], dmgSpot[i], damage, dFlags, MOD_SABER, hitDismemberLoc[i] ); | |
+ G_Damage( victim, inflictor, ent, it.dmgDir, it.dmgSpot, damage, dFlags, MOD_SABER, it.hitDismemberLoc ); | |
if ( damage > 0 && cg.time ) | |
{ | |
float sizeTimeScale = 1.0f; | |
if ( (vicWasAlive | |
- && victim->health <= 0 ) | |
+ && victim->health <= 0) | |
|| (!vicWasDismembered | |
&& victim->client->dismembered | |
- && hitDismemberLoc[i] != HL_NONE | |
- && hitDismember[i]) ) | |
+ && it.hitDismemberLoc != HL_NONE | |
+ && it.hitDismember) ) | |
{ | |
sizeTimeScale = 3.0f; | |
} | |
//FIXME: if not hitting the first model on the enemy, don't do this! | |
CG_SaberDoWeaponHitMarks( ent->client, | |
- (ent->client->ps.saberInFlight?&g_entities[ent->client->ps.saberEntityNum]:NULL), | |
+ (ent->client->ps.saberInFlight ? &g_entities[ent->client->ps.saberEntityNum] : NULL), | |
victim, | |
saberNum, | |
bladeNum, | |
- dmgSpot[i], | |
- dmgDir[i], | |
- dmgBladeVec[i], | |
- dmgNormal[i], | |
+ it.dmgSpot, | |
+ it.dmgDir, | |
+ it.dmgBladeVec, | |
+ it.dmgNormal, | |
sizeTimeScale ); | |
} | |
#ifndef FINAL_BUILD | |
@@ -1685,11 +1708,11 @@ qboolean WP_SaberApplyDamage( gentity_t *ent, float baseDamage, int baseDFlags, | |
//do the effect | |
//vec3_t splashBackDir; | |
//VectorScale( dmgNormal[i], -1, splashBackDir ); | |
- //G_PlayEffect( G_EffectIndex( "blood_sparks" ), dmgSpot[i], splashBackDir ); | |
+ //G_PlayEffect( G_EffectIndex( "blood_sparks" ), it.dmgSpot, splashBackDir ); | |
if ( ent->s.number == 0 ) | |
{ | |
- AddSoundEvent( victim->owner, dmgSpot[i], 256, AEL_DISCOVERED ); | |
- AddSightEvent( victim->owner, dmgSpot[i], 512, AEL_DISCOVERED, 50 ); | |
+ AddSoundEvent( victim->owner, it.dmgSpot, 256, AEL_DISCOVERED ); | |
+ AddSightEvent( victim->owner, it.dmgSpot, 512, AEL_DISCOVERED, 50 ); | |
} | |
if ( ent->client ) | |
{ | |
@@ -1712,8 +1735,9 @@ qboolean WP_SaberApplyDamage( gentity_t *ent, float baseDamage, int baseDFlags, | |
void WP_SaberDamageAdd( float trDmg, int trVictimEntityNum, vec3_t trDmgDir, vec3_t trDmgBladeVec, vec3_t trDmgNormal, vec3_t trDmgSpot, float dmg, float fraction, int trHitLoc, qboolean trDismember, int trDismemberLoc ) | |
{ | |
- int curVictim = 0; | |
- int i; | |
+ //int curVictim = 0; | |
+ SaberDamage curVictim{}; | |
+ //int i; | |
if ( trVictimEntityNum < 0 || trVictimEntityNum >= ENTITYNUM_WORLD ) | |
{ | |
@@ -1726,6 +1750,17 @@ void WP_SaberDamageAdd( float trDmg, int trVictimEntityNum, vec3_t trDmgDir, vec | |
} | |
if ( trDmg ) | |
{//did some damage to something | |
+ for ( auto &it : saberDamage ) | |
+ { | |
+ if ( it.victimEntityNum == trVictimEntityNum ) | |
+ { | |
+ curVictim = it; | |
+ break; | |
+ } | |
+ } | |
+ | |
+ | |
+ | |
for ( i = 0; i < numVictims; i++ ) | |
{ | |
if ( victimEntityNum[i] == trVictimEntityNum ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment