X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fserver%2Fweapons%2Ftracing.qc;h=fdee0d6fe93acf9496f4a20532d314cead002fe9;hp=ddf1ff26248066b0fa719c18ab543802fc866d4b;hb=546842f7e5a63b11a9b862dbf1709318bb97689b;hpb=e51ce3d45d2852ca793118fc73da9c25f789101f diff --git a/qcsrc/server/weapons/tracing.qc b/qcsrc/server/weapons/tracing.qc index ddf1ff2624..fdee0d6fe9 100644 --- a/qcsrc/server/weapons/tracing.qc +++ b/qcsrc/server/weapons/tracing.qc @@ -32,7 +32,16 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, .entity weaponentity, vect if(!IS_CLIENT(ent)) antilag = false; // no antilag for non-clients! if (IS_PLAYER(ent) && (wep.spawnflags & WEP_FLAG_PENETRATEWALLS)) + { + // This is the reason rifle, MG, OKMG and other fireBullet weapons don't hit the crosshair when shooting at walls. + // This is intentional, otherwise if you stand too close to a (glass) wall and attempt to shoot an enemy through it, + // trueaim will cause the shot to hit the wall exactly but then miss the enemy (unless shooting from eye/center). + // TODO for fireBullet, find how far the shot will penetrate and aim at that + // for fireRailgunbullet, find the farthest target and aim at that + // this will avoid issues when another player is passing in front of you when you shoot + // (currently such a shot will hit him but then miss the original target) ent.dphitcontentsmask = DPCONTENTS_BODY | DPCONTENTS_CORPSE; + } else ent.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE; if(antilag) @@ -57,7 +66,7 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, .entity weaponentity, vect // track max damage if (IS_PLAYER(ent) && accuracy_canbegooddamage(ent)) - accuracy_add(ent, wep.m_id, maxdamage, 0); + accuracy_add(ent, wep, maxdamage, 0); if(IS_PLAYER(ent)) W_HitPlotAnalysis(ent, wep, v_forward, v_right, v_up); @@ -65,6 +74,8 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, .entity weaponentity, vect vector md = ent.(weaponentity).movedir; vector vecs = ((md.x > 0) ? md : '0 0 0'); + // TODO this is broken - see 637056bea7bf7f5c9c0fc6113e94731a2767476 for an attempted fix + // which fixes issue #1957 but causes #2129 vector dv = v_right * -vecs.y + v_up * vecs.z; w_shotorg = ent.origin + ent.view_ofs + dv; @@ -138,7 +149,7 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, .entity weaponentity, vect ent.punchangle_x = recoil * -1; if (snd != SND_Null) { - sound (ent, chan, snd, (W_DualWielding(ent) ? VOL_BASE * 0.7 : VOL_BASE), ATTN_NORM); + sound(ent, chan, snd, (W_DualWielding(ent) ? VOL_BASE * 0.7 : VOL_BASE), ATTN_NORM); W_PlayStrengthSound(ent); } @@ -266,7 +277,7 @@ void FireRailgunBullet (entity this, .entity weaponentity, vector start, vector //explosion = spawn(); // Find all non-hit players the beam passed close by - if(deathtype == WEP_VAPORIZER.m_id || deathtype == WEP_VORTEX.m_id) + if(deathtype == WEP_VAPORIZER.m_id || deathtype == WEP_VORTEX.m_id) // WEAPONTODO { FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != this, { if(!it.railgunhit) @@ -321,7 +332,8 @@ void FireRailgunBullet (entity this, .entity weaponentity, vector start, vector IL_CLEAR(g_railgunhit); // calculate hits and fired shots for hitscan - accuracy_add(this, this.(weaponentity).m_weapon.m_id, 0, min(bdamage, totaldmg)); + if(this.(weaponentity)) + accuracy_add(this, this.(weaponentity).m_weapon, 0, min(bdamage, totaldmg)); trace_endpos = endpoint; trace_ent = endent; @@ -336,23 +348,17 @@ void fireBullet_trace_callback(vector start, vector hit, vector end) fireBullet_last_hit = NULL; } -void fireBullet(entity this, .entity weaponentity, vector start, vector dir, float spread, float max_solid_penetration, float damage, float force, float dtype, int tracereffects) +void fireBullet(entity this, .entity weaponentity, vector start, vector dir, float spread, float max_solid_penetration, float damage, float force, float dtype, entity tracer_effect) { - vector end; - dir = normalize(dir + randomvec() * spread); - end = start + dir * max_shot_distance; + vector end = start + dir * max_shot_distance; fireBullet_last_hit = NULL; - float solid_penetration_left = 1; - float total_damage = 0; + fireBullet_trace_callback_eff = tracer_effect; - if(tracereffects & EF_RED) - fireBullet_trace_callback_eff = EFFECT_RIFLE; - else if(tracereffects & EF_BLUE) - fireBullet_trace_callback_eff = EFFECT_RIFLE_WEAK; - else - fireBullet_trace_callback_eff = EFFECT_BULLET; + float solid_penetration_fraction = 1; + float damage_fraction = 1; + float total_damage = 0; float lag = ((IS_REAL_CLIENT(this)) ? ANTILAG_LATENCY(this) : 0); if(lag < 0.001) @@ -372,7 +378,6 @@ void fireBullet(entity this, .entity weaponentity, vector start, vector dir, flo for (;;) { - // TODO also show effect while tracing WarpZone_TraceBox_ThroughZone(start, '0 0 0', '0 0 0', end, false, WarpZone_trace_forent, NULL, fireBullet_trace_callback); dir = WarpZone_TransformVelocity(WarpZone_trace_transform, dir); end = WarpZone_TransformOrigin(WarpZone_trace_transform, end); @@ -410,7 +415,7 @@ void fireBullet(entity this, .entity weaponentity, vector start, vector dir, flo is_weapclip = true; if(!hit || hit.solid == SOLID_BSP || hit.solid == SOLID_SLIDEBOX) - Damage_DamageInfo(start, damage * solid_penetration_left, 0, 0, max(1, force) * dir * solid_penetration_left, dtype, hit.species, this); + Damage_DamageInfo(start, damage * damage_fraction, 0, 0, max(1, force) * dir * damage_fraction, dtype, hit.species, this); if (hit && hit != WarpZone_trace_forent && hit != fireBullet_last_hit) // Avoid self-damage (except after going through a warp); avoid hitting the same entity twice (engine bug). { @@ -419,14 +424,14 @@ void fireBullet(entity this, .entity weaponentity, vector start, vector dir, flo MUTATOR_CALLHOOK(FireBullet_Hit, this, hit, start, end, damage, this.(weaponentity)); damage = M_ARGV(4, float); bool gooddamage = accuracy_isgooddamage(this, hit); - Damage(hit, this, this, damage * solid_penetration_left, dtype, weaponentity, start, force * dir * solid_penetration_left); + Damage(hit, this, this, damage * damage_fraction, dtype, weaponentity, start, force * dir * damage_fraction); // calculate hits for ballistic weapons if(gooddamage) { // do not exceed 100% - float added_damage = min(damage - total_damage, damage * solid_penetration_left); - total_damage += damage * solid_penetration_left; - accuracy_add(this, this.(weaponentity).m_weapon.m_id, 0, added_damage); + float added_damage = min(damage - total_damage, damage * damage_fraction); + total_damage += damage * damage_fraction; + accuracy_add(this, this.(weaponentity).m_weapon, 0, added_damage); } } @@ -447,9 +452,9 @@ void fireBullet(entity this, .entity weaponentity, vector start, vector dir, flo else if(hitstore.ballistics_density < 0) maxdist = vlen(hit.maxs - hit.mins) + 1; // -1: infinite travel distance else if(hitstore.ballistics_density == 0) - maxdist = max_solid_penetration * solid_penetration_left; + maxdist = max_solid_penetration * solid_penetration_fraction; else - maxdist = max_solid_penetration * solid_penetration_left * hitstore.ballistics_density; + maxdist = max_solid_penetration * solid_penetration_fraction / hitstore.ballistics_density; if(maxdist <= autocvar_g_ballistics_mindistance) break; @@ -461,10 +466,10 @@ void fireBullet(entity this, .entity weaponentity, vector start, vector dir, flo break; float dist_taken = max(autocvar_g_ballistics_mindistance, vlen(trace_endpos - start)); - // fraction_used_of_what_is_left = dist_taken / maxdist - // solid_penetration_left = solid_penetration_left - solid_penetration_left * fraction_used_of_what_is_left - solid_penetration_left *= 1 - dist_taken / maxdist; - solid_penetration_left = max(solid_penetration_left, 0); + float fraction_used_of_what_is_left = dist_taken / maxdist; + solid_penetration_fraction -= solid_penetration_fraction * fraction_used_of_what_is_left; + solid_penetration_fraction = max(solid_penetration_fraction, 0); + damage_fraction = pow(solid_penetration_fraction, autocvar_g_ballistics_solidpenetration_exponent); // Only show effect when going through a player (invisible otherwise) if (hit && (hit.solid != SOLID_BSP)) @@ -474,7 +479,7 @@ void fireBullet(entity this, .entity weaponentity, vector start, vector dir, flo start = trace_endpos; if(hit.solid == SOLID_BSP) - Damage_DamageInfo(start, 0, 0, 0, max(1, force) * normalize(dir) * -solid_penetration_left, dtype, 0, this); + Damage_DamageInfo(start, 0, 0, 0, max(1, force) * normalize(dir) * -damage_fraction, dtype, 0, this); } if(lag)