*
WEP_CVAR(shockwave, blast_jump_force_velocitybias)
);
- final_force = normalize((CENTER_OR_VIEWOFS(head) - attack_hitpos) + vel);
+
+ if (autocvar_g_player_damageplayercenter)
+ {
+ vector shot_origin = CENTER_OR_VIEWOFS(actor);
+ shot_origin.z += actor.(weaponentity).movedir.z;
+ //if (head == actor) // was checked for already, is true
+ final_force = normalize((shot_origin - attack_hitpos) + vel);
+ //else // use target's bbox centerpoint
+ //final_force = normalize(((head.origin + ((head.mins + head.maxs) * 0.5)) - attack_hitpos) + vel);
+ }
+ else
+ {
+ // if it's a player, use the view origin as reference
+ final_force = normalize((CENTER_OR_VIEWOFS(head) - attack_hitpos) + vel);
+ }
// now multiply the direction by force units
final_force *= (WEP_CVAR(shockwave, blast_jump_force) * multiplier);
// figure out the direction of force
final_force = (w_shotdir * WEP_CVAR(shockwave, blast_splash_force_forwardbias));
- final_force = normalize(CENTER_OR_VIEWOFS(head) - (attack_hitpos - final_force));
+ if (autocvar_g_player_damageplayercenter)
+ {
+ //if (head == actor) // was checked for already, is false
+ //final_force = normalize(CENTER_OR_VIEWOFS(actor) + '0 0 actor.(weaponentity).movedir.z' - (attack_hitpos - final_force));
+ //else // use target's bbox centerpoint
+ final_force = normalize((head.origin + ((head.mins + head.maxs) * 0.5)) - (attack_hitpos - final_force));
+ }
+ else
+ {
+ // if it's a player, use the view origin as reference
+ final_force = normalize(CENTER_OR_VIEWOFS(head) - (attack_hitpos - final_force));
+ }
//te_lightning2(NULL, attack_hitpos, (attack_hitpos + (final_force * 200)));
// now multiply the direction by force units
// BLAST CONE CALCULATION
// ========================
- // if it's a player, use the view origin as reference (stolen from RadiusDamage functions in damage.qc)
- center = CENTER_OR_VIEWOFS(head);
+ if (autocvar_g_player_damageplayercenter)
+ {
+ //if (head == actor) // was checked for already, is false
+ //center = CENTER_OR_VIEWOFS(actor) + '0 0 actor.(weaponentity).movedir.z';
+ //else // use target's bbox centerpoint
+ center = head.origin + ((head.mins + head.maxs) * 0.5);
+ }
+ else
+ {
+ // if it's a player, use the view origin as reference (stolen from RadiusDamage functions in damage.qc)
+ center = CENTER_OR_VIEWOFS(head);
+ }
// find the closest point on the enemy to the center of the attack
float h; // hypotenuse, which is the distance between attacker to head
float a;
float c;
vector hitloc;
- vector center;
// if it's a player, use the view origin as reference
- center = CENTER_OR_VIEWOFS(targ);
+ vector center = CENTER_OR_VIEWOFS(targ);
+
+ if (autocvar_g_player_damageplayercenter)
+ {
+ if (targ != attacker)
+ {
+ // always use target's bbox centerpoint
+ center = targ.origin + ((targ.mins + targ.maxs) * 0.5);
+ }
+ else // targ == attacker
+ {
+ #if 0
+ // code stolen from W_SetupShot_Dir_ProjectileSize_Range()
+ vector md = targ.(weaponentity).movedir;
+ vector vecs = ((md.x > 0) ? md : '0 0 0');
+ vector dv = v_right * -vecs.y + v_up * vecs.z;
+ vector mi = '0 0 0', ma = '0 0 0';
+
+ if(IS_CLIENT(targ)) // no antilag for non-clients!
+ {
+ if(CS(targ).antilag_debug)
+ tracebox_antilag(targ, center, mi, ma, center + dv, MOVE_NORMAL, targ, CS(targ).antilag_debug);
+ else
+ tracebox_antilag(targ, center, mi, ma, center + dv, MOVE_NORMAL, targ, ANTILAG_LATENCY(targ));
+ }
+ else
+ tracebox(center, mi, ma, center + dv, MOVE_NORMAL, targ);
+
+ center.z = trace_endpos.z;
+ #else
+ // very cheap way but it skips movedir.x > 0 checks and move into solid checks which is fine most of the time for now AFAIK
+ // this should only really be an issue with absurd g_shootfromfixedorigin custom values like "-1 0 9001"
+ center.z = center.z + targ.(weaponentity).movedir.z;
+ #endif
+ }
+ }
+
+ /* debug prints
+ print(sprintf("origin vec %v\n", targ.origin));
+ print(sprintf("movedir vec %v\n", targ.(weaponentity).movedir));
+ print(sprintf("old def vec %v\n", CENTER_OR_VIEWOFS(targ)));
+ print(sprintf("origin+vofs %v\n", targ.origin + targ.view_ofs));
+ print(sprintf("bbox center %v\n", (targ.origin + ((targ.mins + targ.maxs) * 0.5))));
+ print(sprintf("center vec %v\n", center));
+ print(sprintf("shotorg vec %v\n", w_shotorg));
+ print("\n");
+ */
force = normalize(center - inflictororigin_wz);
force = force * (finaldmg / max(coredamage, edgedamage)) * forceintensity;
// WEAPONTODO
#define DMG_NOWEP (weaponentities[0])
+int autocvar_g_player_damageplayercenter;
+
// NOTE: the .weaponentity parameter can be set to DMG_NOWEP if the attack wasn't caused by a weapon or player
void Damage (entity targ, entity inflictor, entity attacker, float damage, int deathtype, .entity weaponentity, vector hitloc, vector force);
set g_player_alpha 1 "default opacity of players"
set g_player_brightness 0 "set to 2 for brighter players"
+
set g_player_damageforcescale 2 "push multiplier of attacks against players"
+set g_player_damageplayercenter 0 "0: always calculate knockback force direction from player's eyes instead of bbox center. 1: use bbox center point for others, shot origin for attacker's self-damage"
+
set g_playerclip_collisions 1 "0 = disable collision testing against playerclips, might be useful on some defrag maps"
set g_botclip_collisions 1 "0 = disable collision testing against botclips, might be useful on some defrag maps"