From 48c58eb27b4717e0d8402e4132ffffce3e3a5b37 Mon Sep 17 00:00:00 2001 From: drjaska Date: Sun, 22 May 2022 21:58:42 +0300 Subject: [PATCH] weapon independency fixes Damage() function now checks that the target entity does not have a realowner which is another independent player before dealing damage and/or force to it fireball's primary BFG no longer tries to target independent players fireball's secondary "turrets" no longer try to target independent players they also ignore frozen players as suggested by terence electro's primary's explosion no longer explodes electro balls owned by other independent players electro's primary's midair combo no longer explodes electro balls owned by other independent players electro's comboexplosion no longer explodes electro balls owned by other independent players --- qcsrc/common/weapons/weapon/electro.qc | 14 +++++ qcsrc/common/weapons/weapon/fireball.qc | 73 +++++++++++++++++-------- qcsrc/server/damage.qc | 8 +++ 3 files changed, 73 insertions(+), 22 deletions(-) diff --git a/qcsrc/common/weapons/weapon/electro.qc b/qcsrc/common/weapons/weapon/electro.qc index d80703175..3a70920e0 100644 --- a/qcsrc/common/weapons/weapon/electro.qc +++ b/qcsrc/common/weapons/weapon/electro.qc @@ -10,6 +10,13 @@ void W_Electro_TriggerCombo(vector org, float rad, entity own) { if(e.classname == "electro_orb") { + // check if the ball we are exploding is not owned by an + // independent player which is not the player who shot the ball + if(IS_INDEPENDENT_PLAYER(e.realowner) && own != e.realowner) + { + e = e.chain; + continue; + } // do we allow thruwall triggering? if(WEP_CVAR(electro, combo_comboradius_thruwall)) { @@ -151,6 +158,13 @@ void W_Electro_Bolt_Think(entity this) { if(e.classname == "electro_orb") { + // check if the ball we are exploding is not owned by an + // independent player which is not the player who shot the ball + if(IS_INDEPENDENT_PLAYER(e.realowner) && this.realowner != e.realowner) + { + e = e.chain; + continue; + } bool explode; if (this.owner == e.owner) { diff --git a/qcsrc/common/weapons/weapon/fireball.qc b/qcsrc/common/weapons/weapon/fireball.qc index 3021843be..b4a3da78a 100644 --- a/qcsrc/common/weapons/weapon/fireball.qc +++ b/qcsrc/common/weapons/weapon/fireball.qc @@ -15,7 +15,20 @@ void W_Fireball_Explode(entity this, entity directhitentity) // 1. dist damage d = (GetResource(this.realowner, RES_HEALTH) + GetResource(this.realowner, RES_ARMOR)); - RadiusDamage(this, this.realowner, WEP_CVAR_PRI(fireball, damage), WEP_CVAR_PRI(fireball, edgedamage), WEP_CVAR_PRI(fireball, radius), NULL, NULL, WEP_CVAR_PRI(fireball, force), this.projectiledeathtype, this.weaponentity_fld, directhitentity); + + RadiusDamage( + this, + this.realowner, + WEP_CVAR_PRI(fireball, damage), + WEP_CVAR_PRI(fireball, edgedamage), + WEP_CVAR_PRI(fireball, radius), + NULL, + NULL, + WEP_CVAR_PRI(fireball, force), + this.projectiledeathtype, + this.weaponentity_fld, directhitentity + ); + if(GetResource(this.realowner, RES_HEALTH) + GetResource(this.realowner, RES_ARMOR) >= d) if(!this.cnt) { @@ -24,28 +37,42 @@ void W_Fireball_Explode(entity this, entity directhitentity) // 2. bfg effect // NOTE: this cannot be made warpzone aware by design. So, better intentionally ignore warpzones here. for(e = findradius(this.origin, WEP_CVAR_PRI(fireball, bfgradius)); e; e = e.chain) - if(e != this.realowner) if(e.takedamage == DAMAGE_AIM) if(!IS_PLAYER(e) || !this.realowner || DIFF_TEAM(e, this)) { - // can we see fireball? - traceline(e.origin + e.view_ofs, this.origin, MOVE_NORMAL, e); - if(/* trace_startsolid || */ trace_fraction != 1) // startsolid should be never happening anyway - continue; - // can we see player who shot fireball? - traceline(e.origin + e.view_ofs, this.realowner.origin + this.realowner.view_ofs, MOVE_NORMAL, e); - if(trace_ent != this.realowner) - if(/* trace_startsolid || */ trace_fraction != 1) - continue; - dist = vlen(this.origin - e.origin - e.view_ofs); - points = (1 - sqrt(dist / WEP_CVAR_PRI(fireball, bfgradius))); - if(points <= 0) - continue; - dir = normalize(e.origin + e.view_ofs - this.origin); - - if(accuracy_isgooddamage(this.realowner, e)) - accuracy_add(this.realowner, WEP_FIREBALL, 0, WEP_CVAR_PRI(fireball, bfgdamage) * points); - - Damage(e, this, this.realowner, WEP_CVAR_PRI(fireball, bfgdamage) * points, this.projectiledeathtype | HITTYPE_BOUNCE | HITTYPE_SPLASH, this.weaponentity_fld, e.origin + e.view_ofs, WEP_CVAR_PRI(fireball, bfgforce) * dir); - Send_Effect(EFFECT_FIREBALL_BFGDAMAGE, e.origin, -1 * dir, 1); + if(e != this.realowner && e.takedamage == DAMAGE_AIM && !IS_INDEPENDENT_PLAYER(e)) + if(!IS_PLAYER(e) || !this.realowner || DIFF_TEAM(e, this)) + { + + // can we see fireball? + traceline(e.origin + e.view_ofs, this.origin, MOVE_NORMAL, e); + if(/* trace_startsolid || */ trace_fraction != 1) // startsolid should be never happening anyway + continue; + // can we see player who shot fireball? + traceline(e.origin + e.view_ofs, this.realowner.origin + this.realowner.view_ofs, MOVE_NORMAL, e); + if(trace_ent != this.realowner) + if(/* trace_startsolid || */ trace_fraction != 1) + continue; + dist = vlen(this.origin - e.origin - e.view_ofs); + points = (1 - sqrt(dist / WEP_CVAR_PRI(fireball, bfgradius))); + if(points <= 0) + continue; + dir = normalize(e.origin + e.view_ofs - this.origin); + + if(accuracy_isgooddamage(this.realowner, e)) + accuracy_add(this.realowner, WEP_FIREBALL, 0, WEP_CVAR_PRI(fireball, bfgdamage) * points); + + Damage( + e, + this, + this.realowner, + WEP_CVAR_PRI(fireball, bfgdamage) * points, + this.projectiledeathtype | HITTYPE_BOUNCE | HITTYPE_SPLASH, + this.weaponentity_fld, + e.origin + e.view_ofs, + WEP_CVAR_PRI(fireball, bfgforce) * dir + ); + + Send_Effect(EFFECT_FIREBALL_BFGDAMAGE, e.origin, -1 * dir, 1); + } } } @@ -80,7 +107,9 @@ void W_Fireball_LaserPlay(entity this, float dt, float dist, float damage, float RandomSelection_Init(); for(e = WarpZone_FindRadius(this.origin, dist, true); e; e = e.chain) { + if(STAT(FROZEN, e)) continue; if(e == this.realowner) continue; + if(IS_INDEPENDENT_PLAYER(e)) continue; if(e.takedamage != DAMAGE_AIM) continue; if(IS_PLAYER(e) && this.realowner && SAME_TEAM(e, this)) continue; diff --git a/qcsrc/server/damage.qc b/qcsrc/server/damage.qc index d0b3a288f..db9ddd0d9 100644 --- a/qcsrc/server/damage.qc +++ b/qcsrc/server/damage.qc @@ -628,11 +628,19 @@ void Damage(entity targ, entity inflictor, entity attacker, float damage, int de if(deathtype != DEATH_TELEFRAG.m_id) if(IS_PLAYER(attacker)) { + // avoid dealing damage or force to other independent players if(IS_PLAYER(targ) && targ != attacker && (IS_INDEPENDENT_PLAYER(attacker) || IS_INDEPENDENT_PLAYER(targ))) { damage = 0; force = '0 0 0'; } + // avoid dealing damage or force to things owned by other independent players + if(targ.realowner) + if(IS_INDEPENDENT_PLAYER(targ.realowner) && attacker != targ.realowner) + { + damage = 0; + force = '0 0 0'; + } else if(!STAT(FROZEN, targ) && SAME_TEAM(attacker, targ)) { if(autocvar_teamplay_mode == 1) -- 2.39.2