From 704448e416ff06afd946c46830d7d37dc46fa7b0 Mon Sep 17 00:00:00 2001 From: "Dr. Jaska" Date: Wed, 8 Nov 2023 01:17:09 +0000 Subject: [PATCH] Added an inactive gameplay cvar for using the own shot origin or centers of other players' bboxes for force direction calculations --- qcsrc/common/weapons/weapon/shockwave.qc | 43 +++++++++++++++++++-- qcsrc/server/damage.qc | 49 +++++++++++++++++++++++- qcsrc/server/damage.qh | 2 + xonotic-server.cfg | 3 ++ 4 files changed, 91 insertions(+), 6 deletions(-) diff --git a/qcsrc/common/weapons/weapon/shockwave.qc b/qcsrc/common/weapons/weapon/shockwave.qc index 6c2fd8c93..bd4e5975a 100644 --- a/qcsrc/common/weapons/weapon/shockwave.qc +++ b/qcsrc/common/weapons/weapon/shockwave.qc @@ -360,7 +360,21 @@ void W_Shockwave_Attack(Weapon thiswep, entity actor, .entity weaponentity) * 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); @@ -431,7 +445,18 @@ void W_Shockwave_Attack(Weapon thiswep, entity actor, .entity weaponentity) // 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 @@ -467,8 +492,18 @@ void W_Shockwave_Attack(Weapon thiswep, entity actor, .entity weaponentity) // 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 diff --git a/qcsrc/server/damage.qc b/qcsrc/server/damage.qc index 99c99153a..2e84cac3a 100644 --- a/qcsrc/server/damage.qc +++ b/qcsrc/server/damage.qc @@ -945,10 +945,55 @@ float RadiusDamageForSource (entity inflictor, vector inflictororigin, vector in 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; diff --git a/qcsrc/server/damage.qh b/qcsrc/server/damage.qh index a1dadc1a2..09b80eea1 100644 --- a/qcsrc/server/damage.qh +++ b/qcsrc/server/damage.qh @@ -125,6 +125,8 @@ void Unfreeze(entity targ, bool reset_health); // 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); diff --git a/xonotic-server.cfg b/xonotic-server.cfg index a64f8d896..a72143db3 100644 --- a/xonotic-server.cfg +++ b/xonotic-server.cfg @@ -240,8 +240,11 @@ set g_grab_range 200 "distance at which dragable objects can be grabbed" 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" -- 2.39.2