]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
solidpen improvements
authorMartin Taibr <taibr.martin@gmail.com>
Sun, 28 Oct 2018 21:37:02 +0000 (22:37 +0100)
committerMartin Taibr <taibr.martin@gmail.com>
Sun, 28 Oct 2018 21:37:02 +0000 (22:37 +0100)
qcsrc/server/autocvars.qh
qcsrc/server/defs.qh
qcsrc/server/weapons/tracing.qc
vehicles.cfg
xonotic-server.cfg

index b23f6f148175478fbdc9acb885cc71cb3179b045..620d32ccdf873064ef69aeeb13cad673d990a365 100644 (file)
@@ -91,7 +91,8 @@ float autocvar_g_balance_selfdamagepercent;
 float autocvar_g_ballistics_density_corpse;
 float autocvar_g_ballistics_density_player;
 float autocvar_g_ballistics_mindistance;
-bool autocvar_g_ballistics_penetrate_clips;
+bool autocvar_g_ballistics_penetrate_clips = true;
+float autocvar_g_ballistics_solidpenetration_exponent = 0.25;
 float autocvar_g_ban_default_bantime;
 float autocvar_g_ban_default_masksize;
 float autocvar_g_ban_sync_interval;
index 5b5d8a66b78a017e5f077e975592e94b0b65227d..862bdd69a7c07ba50ea289c9053bf924427357c3 100644 (file)
@@ -338,7 +338,7 @@ string deathmessage;
 .float cvar_cl_weaponimpulsemode;
 .int selectweapon; // last selected weapon of the player
 
-.float ballistics_density; // wall piercing factor, larger = bullet can pass through more
+.float ballistics_density;
 
 //const int FROZEN_NOT                         = 0;
 const int FROZEN_NORMAL                                = 1;
index 9e78aa3c360acdec20c36f831f13fc3182fde369..9fda61202cecaf34a8116dfec1c34e28e87e7815 100644 (file)
@@ -347,15 +347,14 @@ void fireBullet_trace_callback(vector start, vector hit, vector end)
 
 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;
        fireBullet_trace_callback_eff = tracer_effect;
 
-       float solid_penetration_left = 1;
+       float solid_penetration_fraction = 1;
+       float damage_fraction = 1;
        float total_damage = 0;
 
        float lag = ((IS_REAL_CLIENT(this)) ? ANTILAG_LATENCY(this) : 0);
@@ -376,7 +375,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);
@@ -414,7 +412,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).
                {
@@ -423,13 +421,13 @@ 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;
+                               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);
                        }
                }
@@ -451,9 +449,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;
@@ -465,10 +463,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))
@@ -478,7 +476,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)
index 1d2f153e7dbed57ae6940fb2f9f46f0e69944ee0..68018529d0f26f2aaccfeb90a0cd6128163856ed 100644 (file)
@@ -287,7 +287,7 @@ set g_vehicle_spiderbot_minigun_ammo_max 100
 set g_vehicle_spiderbot_minigun_ammo_regen 40
 set g_vehicle_spiderbot_minigun_ammo_regen_pause 1
 set g_vehicle_spiderbot_minigun_force 9
-set g_vehicle_spiderbot_minigun_solidpenetration 32
+set g_vehicle_spiderbot_minigun_solidpenetration 63
 
 set g_vehicle_spiderbot_rocket_damage 50
 set g_vehicle_spiderbot_rocket_force 150
index e25ae7faca9b4d78250766ef4020dbdd4439e4ba..9b845cd9ceee60ce695ec448d5d7414bb05bfbaf 100644 (file)
@@ -415,15 +415,11 @@ set g_ban_sync_trusted_servers_verify 0   "when set to 1, additional bans sent by
 
 set g_showweaponspawns 1 "1: display waypoints for weapon spawns found on the map when a weapon key is pressed and the weapon is not owned; 2: for dropped weapons too; 3: for all the weapons sharing the same impulse"
 
-// ballistics use physical units, but qu based
-//   Quake-Newton: 1 qN  = 1 qu * 1 g / 1 s^2
-//   Quake-Joule:  1 qJ  = 1 qN * 1 qu
-//   Quake-Pascal: 1 qPa = 1 qN / 1 qu^2
-
-set g_ballistics_mindistance 2 // enable ballistics starting from 2 qu
-set g_ballistics_density_player 0.50 // players are 2x as easy to pass as walls
-set g_ballistics_density_corpse 0.10 // corpses are 10x as easy to pass as walls
-set g_ballistics_penetrate_clips 0 "allow ballistics to pass through weapon clips"
+set g_ballistics_mindistance 2 "when shooting through walls thinner than this, treat them as this thick (useful because patches (curved surfaces) have no thickness)"
+set g_ballistics_density_player 0.50 "how hard players are to shoot through compared to walls"
+set g_ballistics_density_corpse 0.10 "how hard corpses are to shoot through compared to walls"
+set g_ballistics_penetrate_clips 1 "allow ballistics to pass through weapon clips"
+set g_ballistics_solidpenetration_exponent 0.25 "how fast damage falls off when bullets pass through walls - 1 means linear, lower values mean slower initial falloff but faster once there's little solidpenetration left (damage_fraction = solidpen_fraction^exp for solidpen_fraction between 0 and 1)"
 
 sv_status_show_qcstatus 1      "Xonotic uses this field instead of frags"
 set g_full_getstatus_responses 0       "this currently breaks qstat"