]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/g_damage.qc
Merge remote-tracking branch 'origin/mrbougo/killspree_bugfix'
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / g_damage.qc
index 2df1e9d20cdaf374b39e3b6c95d20d37e00e7abc..7b02f4e5ecdc9a2fe0446c49782089aa4b89dd43 100644 (file)
@@ -55,6 +55,7 @@ float damage_headshotbonus; // bonus multiplier for head shots, set to 0 after u
 .float teamkill_soundtime;
 .entity teamkill_soundsource;
 .entity pusher;
+.float istypefrag;
 .float taunt_soundtime;
 
 
@@ -420,7 +421,7 @@ void Obituary (entity attacker, entity inflictor, entity targ, float deathtype)
                                        PlayerStats_Event(targ, PLAYERSTATS_ACHIEVEMENT_FIRSTVICTIM, 1);
                                }
 
-                               if(targ.BUTTON_CHAT) {
+                               if(targ.istypefrag) {
                                        Send_CSQC_KillCenterprint(attacker, s, Obituary_ExtraFragInfo(targ), KILL_TYPEFRAG, MSG_KILL);
                                        Send_CSQC_KillCenterprint(targ, a, Obituary_ExtraFragInfo(attacker), KILL_TYPEFRAGGED, MSG_KILL);
                                } else {
@@ -457,10 +458,7 @@ void Obituary (entity attacker, entity inflictor, entity targ, float deathtype)
 
                                attacker.killcount = attacker.killcount + 1;
 
-                               if (attacker.killcount > 2) {
-                                       Send_KillNotification(a, ftos(attacker.killcount), "", KILL_SPREE, MSG_SPREE);
-                               }
-                               else if (attacker.killcount == 3)
+                               if (attacker.killcount == 3)
                                {
                                        Send_KillNotification(a, "", "", KILL_SPREE_3, MSG_SPREE);
                                        AnnounceTo(attacker, "03kills");
@@ -502,6 +500,9 @@ void Obituary (entity attacker, entity inflictor, entity targ, float deathtype)
                                        AnnounceTo(attacker, "30kills");
                                        PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_30, 1);
                                }
+                               else if (attacker.killcount > 2) {
+                                       Send_KillNotification(a, ftos(attacker.killcount), "", KILL_SPREE, MSG_SPREE);
+                               }
                                LogDeath("frag", deathtype, attacker, targ);
                        }
                }
@@ -647,7 +648,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float
 
                                                        if(autocvar_g_mirrordamage_virtual)
                                                        {
-                                                               vector v = healtharmor_applydamage(attacker.armorvalue, autocvar_g_balance_armor_blockpercent, mirrordamage);
+                                                               vector v  = healtharmor_applydamage(attacker.armorvalue, autocvar_g_balance_armor_blockpercent, mirrordamage);
                                                                attacker.dmg_take += v_x;
                                                                attacker.dmg_save += v_y;
                                                                attacker.dmg_inflictor = inflictor;
@@ -1280,87 +1281,48 @@ float Fire_AddDamage(entity e, entity o, float d, float t, float dt)
                        // but we can't exceed maxtime * maxdps!
                        totaldamage = min(maxdamage, maxtime * maxdps);
 
+                       // LEMMA:
+                       // Look at:
+                       // totaldamage = min(mindamage + d, maxtime * maxdps)
+                       // We see:
+                       // totaldamage <= maxtime * maxdps
+                       // ==> totaldamage / maxdps <= maxtime.
+                       // We also see:
+                       // totaldamage / mindps = min(mindamage / mindps + d, maxtime * maxdps / mindps)
+                       //                     >= min(mintime, maxtime)
+                       // ==> totaldamage / maxdps >= mintime.
+
                        /*
                        // how long do we damage then?
                        // at least as long as before
                        // but, never exceed maxdps
-                       totaltime = max(mintime, totaldamage / maxdps); // always <= maxtime
+                       totaltime = max(mintime, totaldamage / maxdps); // always <= maxtime due to lemma
                        */
 
                        // alternate:
                        // at most as long as maximum allowed
-                       // but, try mindps
-                       totaltime = min(maxtime, totaldamage / mindps); // always >= mintime
-
-                       /*
-                       BOTH SAEM (but lower one is numerically more stable as maxtime has potentially less ops behind)
-                       because:
-                       maxtime = max(mintime, t)
-                       maxdps = max(mindps, d/t)
-                       mindamage = mindps * mintime
-                       maxdamage = mindps * mintime + d
-                       totaldamage = min(mindps * mintime + d, max(mintime, t) * max(mindps, d/t))
-                       totaltime1 = max(mintime, min(mindps * mintime + d, max(mintime, t) * max(mindps, d/t)) / max(mindps, d/t))
-                       totaltime2 = min(max(mintime, t), min(mindps * mintime + d, max(mintime, t) * max(mindps, d/t)) / mindps)
-                               
-                       1. max(mintime, t) == t
-                       totaltime1 = max(mintime, min(mindps * mintime + d, t * max(mindps, d/t)) / max(mindps, d/t))
-                       totaltime2 = min(t, min(mindps * mintime + d, t * max(mindps, d/t)) / mindps)
-
-                       1.1. max(mindps, d/t) == mindps
-                       <=> mindps >= d/t
-                       totaltime1 = max(mintime, min(mindps * mintime + d, t * mindps) / mindps)
-                       totaltime2 = min(t, min(mindps * mintime + d, t * mindps) / mindps)
-
-                       totaltime1 = max(mintime, min(mintime + d / mindps, t))
-                       totaltime2 = min(t, min(mintime + d / mindps, t))
-
-                       totaltime1 = max(mintime, min(mintime + d / mindps, t))
-                       totaltime2 = min(t, mintime + d / mindps)
-
-                       totaltime1 = min(max(mintime, mintime + d / mindps), max(mintime, t))
-                       totaltime2 = min(t, mintime + d / mindps)
-
-                       totaltime1 = min(mintime + d / mindps, t)
-                       totaltime2 = min(t, mintime + d / mindps)
-
-                       YES     
-
-                       1.2. max(mindps, d/t) == d/t
-                       totaltime1 = max(mintime, min(mindps * mintime + d, t * d/t) / d/t)
-                       totaltime2 = min(t, min(mindps * mintime + d, t * d/t) / mindps)
-
-                       totaltime1 = max(mintime, min(mindps * mintime / (d/t) + t, t))
-                       totaltime2 = min(t, min(mintime + d / mindps, d / mindps))
-
-                       totaltime1 = max(mintime, t) == t
-                       totaltime2 = min(t, d / mindps) == t
-
-                       YES
-
-                       2. max(mintime, t) == mintime
-                       totaltime1 = max(mintime, min(mindps * mintime + d, mintime * max(mindps, d/t)) / max(mindps, d/t))
-                       totaltime2 = min(mintime, min(mindps * mintime + d, mintime * max(mindps, d/t)) / mindps)
-
-                       2.1. max(mindps, d/t) == mindps
-                       totaltime1 = max(mintime, min(mindps * mintime + d, mintime * mindps) / mindps)
-                       totaltime2 = min(mintime, min(mindps * mintime + d, mintime * mindps) / mindps)
-
-                       totaltime1 = max(mintime, min(mintime + d / mindps, mintime)) = mintime
-                       totaltime2 = min(mintime, min(mintime + d / mindps, mintime)) = mintime
-
-                       YES
-
-                       2.2. max(mindps, d/t) == d/t
-                       totaltime1 = max(mintime, min(mindps * mintime + d, mintime * d/t) / d/t)
-                       totaltime2 = min(mintime, min(mindps * mintime + d, mintime * d/t) / mindps)
-
-                       totaltime1 = max(mintime, min(mindps * mintime / (d/t) + d / (d/t), mintime)) == mintime
-                       totaltime2 = min(mintime, min(mintime + d / mindps, mintime * d/t / mindps))
-                       //                    bigger!               bigger!
-
-                       YES
-                       */
+                       // but, never below mindps
+                       totaltime = min(maxtime, totaldamage / mindps); // always >= mintime due to lemma
+
+                       // assuming t > mintime, dps > mindps:
+                       // we get d = t * dps = maxtime * maxdps
+                       // totaldamage = min(maxdamage, maxtime * maxdps) = min(... + d, maxtime * maxdps) = maxtime * maxdps
+                       // totaldamage / maxdps = maxtime
+                       // totaldamage / mindps > totaldamage / maxdps = maxtime
+                       // FROM THIS:
+                       // a) totaltime = max(mintime, maxtime) = maxtime
+                       // b) totaltime = min(maxtime, totaldamage / maxdps) = maxtime
+
+                       // assuming t <= mintime:
+                       // we get maxtime = mintime
+                       // a) totaltime = max(mintime, ...) >= mintime, also totaltime <= maxtime by the lemma, therefore totaltime = mintime = maxtime
+                       // b) totaltime = min(maxtime, ...) <= maxtime, also totaltime >= mintime by the lemma, therefore totaltime = mintime = maxtime
+
+                       // assuming dps <= mindps:
+                       // we get mindps = maxdps.
+                       // With this, the lemma says that mintime <= totaldamage / mindps = totaldamage / maxdps <= maxtime.
+                       // a) totaltime = max(mintime, totaldamage / maxdps) = totaldamage / maxdps
+                       // b) totaltime = min(maxtime, totaldamage / mindps) = totaldamage / maxdps
 
                        e.fire_damagepersec = totaldamage / totaltime;
                        e.fire_endtime = time + totaltime;