X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fserver%2Fweapons%2Ftracing.qc;h=b37e1578e2878ed0011c4fe22d59cf42eee168ad;hp=1f7f5946757dac215ca0621bb682cb0f97aeca51;hb=edf6dc79ea73da8ee78f426ba13675ef482d17f1;hpb=931d24d4337e58557fa82a68aa8a740e523c2f22 diff --git a/qcsrc/server/weapons/tracing.qc b/qcsrc/server/weapons/tracing.qc index 1f7f59467..b37e1578e 100644 --- a/qcsrc/server/weapons/tracing.qc +++ b/qcsrc/server/weapons/tracing.qc @@ -10,6 +10,7 @@ #include "../antilag.qh" #include +#include #include #include @@ -56,7 +57,7 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, .entity weaponentity, vect accuracy_add(ent, ent.(weaponentity).m_weapon.m_id, maxdamage, 0); if(IS_PLAYER(ent)) - W_HitPlotAnalysis(ent, v_forward, v_right, v_up); + W_HitPlotAnalysis(ent, weaponentity, v_forward, v_right, v_up); vector md = ent.(weaponentity).movedir; if(md.x > 0) @@ -198,33 +199,21 @@ void W_SetupProjVelocity_Explicit(entity proj, vector dir, vector upDir, float p void FireRailgunBullet (entity this, .entity weaponentity, vector start, vector end, float bdamage, float bforce, float mindist, float maxdist, float halflifedist, float forcehalflifedist, int deathtype) { - vector hitloc, force, endpoint, dir; - entity ent, endent; - float endq3surfaceflags; - float totaldmg; - entity o; + entity pseudoprojectile = NULL; - float length; - vector beampos; - string snd; - entity pseudoprojectile; - float f, ffs; - - pseudoprojectile = NULL; - - dir = normalize(end - start); - length = vlen(end - start); - force = dir * bforce; + vector dir = normalize(end - start); + float length = vlen(end - start); + vector force = dir * bforce; // go a little bit into the wall because we need to hit this wall later end = end + dir; - totaldmg = 0; + float totaldmg = 0; // trace multiple times until we hit a wall, each obstacle will be made // non-solid so we can hit the next, while doing this we spawn effects and // note down which entities were hit so we can damage them later - o = this; + entity o = this; while (1) { if(CS(this).antilag_debug) @@ -259,18 +248,15 @@ void FireRailgunBullet (entity this, .entity weaponentity, vector start, vector trace_ent.solid = SOLID_NOT; } - endpoint = trace_endpos; - endent = trace_ent; - endq3surfaceflags = trace_dphitq3surfaceflags; + vector endpoint = trace_endpos; + entity endent = trace_ent; + float endq3surfaceflags = trace_dphitq3surfaceflags; // find all the entities the railgun hit and restore their solid state - ent = findfloat(NULL, railgunhit, true); - while (ent) + FOREACH_ENTITY_FLOAT(railgunhit, true, { - // restore their solid type - ent.solid = ent.railgunhitsolidbackup; - ent = findfloat(ent, railgunhit, true); - } + it.solid = it.railgunhitsolidbackup; + }); // spawn a temporary explosion entity for RadiusDamage calls //explosion = spawn(); @@ -284,17 +270,15 @@ void FireRailgunBullet (entity this, .entity weaponentity, vector start, vector { msg_entity = it; // nearest point on the beam - beampos = start + dir * bound(0, (msg_entity.origin - start) * dir, length); + vector beampos = start + dir * bound(0, (msg_entity.origin - start) * dir, length); - f = bound(0, 1 - vlen(beampos - msg_entity.origin) / 512, 1); + float f = bound(0, 1 - vlen(beampos - msg_entity.origin) / 512, 1); if(f <= 0) continue; - snd = SND(NEXWHOOSH_RANDOM()); - if(!pseudoprojectile) pseudoprojectile = spawn(); // we need this so the sound uses the "entchannel4" volume - soundtoat(MSG_ONE, pseudoprojectile, beampos, CH_SHOTS, snd, VOL_BASE * f, ATTEN_NONE); + soundtoat(MSG_ONE, pseudoprojectile, beampos, CH_SHOTS, SND(NEXWHOOSH_RANDOM()), VOL_BASE * f, ATTEN_NONE); } )); @@ -303,34 +287,30 @@ void FireRailgunBullet (entity this, .entity weaponentity, vector start, vector } // find all the entities the railgun hit and hurt them - ent = findfloat(NULL, railgunhit, true); - while (ent) + FOREACH_ENTITY_FLOAT(railgunhit, true, { // get the details we need to call the damage function - hitloc = ent.railgunhitloc; + vector hitloc = it.railgunhitloc; - f = ExponentialFalloff(mindist, maxdist, halflifedist, ent.railgundistance); - ffs = ExponentialFalloff(mindist, maxdist, forcehalflifedist, ent.railgundistance); + float foff = ExponentialFalloff(mindist, maxdist, halflifedist, it.railgundistance); + float ffs = ExponentialFalloff(mindist, maxdist, forcehalflifedist, it.railgundistance); - if(accuracy_isgooddamage(this, ent)) - totaldmg += bdamage * f; + if(accuracy_isgooddamage(this, it)) + totaldmg += bdamage * foff; // apply the damage - if (ent.takedamage) - Damage (ent, this, this, bdamage * f, deathtype, hitloc, ent.railgunforce * ffs); + if (it.takedamage) + Damage (it, this, this, bdamage * foff, deathtype, hitloc, it.railgunforce * ffs); // create a small explosion to throw gibs around (if applicable) //setorigin(explosion, hitloc); //RadiusDamage (explosion, this, 10, 0, 50, NULL, NULL, 300, deathtype); - ent.railgunhitloc = '0 0 0'; - ent.railgunhitsolidbackup = SOLID_NOT; - ent.railgunhit = false; - ent.railgundistance = 0; - - // advance to the next entity - ent = findfloat(ent, railgunhit, true); - } + it.railgunhitloc = '0 0 0'; + it.railgunhitsolidbackup = SOLID_NOT; + it.railgunhit = false; + it.railgundistance = 0; + }); // calculate hits and fired shots for hitscan accuracy_add(this, this.(weaponentity).m_weapon.m_id, 0, min(bdamage, totaldmg)); @@ -353,7 +333,7 @@ void fireBullet(entity this, .entity weaponentity, vector start, vector dir, flo vector end; dir = normalize(dir + randomvec() * spread); - end = start + dir * MAX_SHOT_DISTANCE; + end = start + dir * max_shot_distance; fireBullet_last_hit = NULL; float solid_penetration_left = 1; @@ -398,6 +378,10 @@ void fireBullet(entity this, .entity weaponentity, vector start, vector dir, flo start = trace_endpos; entity hit = trace_ent; + // traced up to max_shot_distance and didn't hit anything at all + if (trace_fraction == 1.0) + break; + // When hitting sky, stop. if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY) break; @@ -431,7 +415,7 @@ void fireBullet(entity this, .entity weaponentity, vector start, vector dir, flo { fireBullet_last_hit = hit; yoda = 0; - MUTATOR_CALLHOOK(FireBullet_Hit, this, hit, start, end, damage); + MUTATOR_CALLHOOK(FireBullet_Hit, this, hit, start, end, damage, this.(weaponentity)); damage = M_ARGV(4, float); float g = accuracy_isgooddamage(this, hit); Damage(hit, this, this, damage * solid_penetration_left, dtype, start, force * dir * solid_penetration_left);