Merge remote-tracking branch 'origin/mrbougo/killspree_bugfix'
authorJakob MG <jakob_mg@hotmail.com>
Thu, 23 Aug 2012 18:17:15 +0000 (20:17 +0200)
committerJakob MG <jakob_mg@hotmail.com>
Thu, 23 Aug 2012 18:17:15 +0000 (20:17 +0200)
1  2 
qcsrc/server/g_damage.qc

diff --combined qcsrc/server/g_damage.qc
index d77d614759e00944a15474e8bd4097785f39bbf4,b037e08a2d6821efd5cf6a6b033612a4f688765d..7b02f4e5ecdc9a2fe0446c49782089aa4b89dd43
@@@ -55,7 -55,6 +55,7 @@@ float damage_headshotbonus; // bonus mu
  .float teamkill_soundtime;
  .entity teamkill_soundsource;
  .entity pusher;
 +.float istypefrag;
  .float taunt_soundtime;
  
  
@@@ -141,9 -140,7 +141,9 @@@ void GiveFrags (entity attacker, entit
                // after a frag, exchange the current weapon (or the culprit, if detectable) by a new random weapon
                float culprit;
                culprit = DEATH_WEAPONOF(deathtype);
 -              if(!culprit || !WEPSET_CONTAINS_EW(attacker, culprit))
 +              if(!culprit)
 +                      culprit = attacker.weapon;
 +              else if(!WEPSET_CONTAINS_EW(attacker, culprit))
                        culprit = attacker.weapon;
  
                if(g_weaponarena_random_with_laser && culprit == WEP_LASER)
  
  string Obituary_ExtraFragInfo(entity player) // Extra fragmessage information
  {
 -      string health_output;
 -      string ping_output;
 -      string handicap_output;
 -      string output;
 +      string health_output = string_null;
 +      string ping_output = string_null;
 +      string handicap_output = string_null;
 +      string output = string_null;
  
        if(autocvar_sv_fraginfo && ((autocvar_sv_fraginfo == 2) || inWarmupStage))
        {
@@@ -355,8 -352,6 +355,8 @@@ void Obituary (entity attacker, entity 
                {
                        if (deathtype == DEATH_TEAMCHANGE || deathtype == DEATH_AUTOTEAMCHANGE)
                                msg = ColoredTeamName(targ.team); // TODO: check if needed?
 +                      else
 +                              msg = "";
              if(!g_cts) // no "killed your own dumb self" message in CTS
                  Send_CSQC_KillCenterprint(targ, msg, "", deathtype, MSG_SUICIDE);
  
  
                        if (targ.killcount > 2)
                                msg = ftos(targ.killcount);
 +                      else
 +                              msg = "";
                        if(teamplay && deathtype == DEATH_MIRRORDAMAGE)
                        {
                                if(attacker.team == COLOR_TEAM1)
  
                                Send_CSQC_KillCenterprint(attacker, s, "", type, MSG_KILL);
  
 -                              if (targ.killcount > 2) {
 +                              if (targ.killcount > 2)
                                        msg = ftos(targ.killcount);
 -                              }
 +                              else
 +                                      msg = "";
  
                                if (attacker.killcount > 2) {
                                        msg = ftos(attacker.killcount);
                                        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 {
  
                                attacker.taunt_soundtime = time + 1;
  
 -                              // TODO: fix this?
 -                              if (deathtype == DEATH_CUSTOM)
 +                              if (deathtype == DEATH_HURTTRIGGER && inflictor.message2 != "")
 +                                      msg = inflictor.message2;
 +                              else if (deathtype == DEATH_CUSTOM)
                                        msg = deathmessage;
                                else
 -                                      msg = inflictor.message2;
 +                                      msg = "";
  
                                if(strstrofs(msg, "%", 0) < 0)
                                        msg = strcat("%s ", msg, " by %s");
  
                                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");
                                        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);
                        }
                }
                                msg = inflictor.message;
                        else if (deathtype == DEATH_CUSTOM)
                                msg = deathmessage;
 +                      else
 +                              msg = "";
                        if(strstrofs(msg, "%", 0) < 0)
                                msg = strcat("%s ", msg);
  
@@@ -648,7 -637,9 +648,7 @@@ void Damage (entity targ, entity inflic
  
                                                        if(autocvar_g_mirrordamage_virtual)
                                                        {
 -                                                              vector v;
 -                                                              v = healtharmor_applydamage(attacker.armorvalue, autocvar_g_balance_armor_blockpercent, mirrordamage);
 -                                                              v_z = 0; // fteqcc sucks
 +                                                              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;
  
                                                        if(autocvar_g_friendlyfire_virtual)
                                                        {
 -                                                              vector v;
 -                                                              v = healtharmor_applydamage(targ.armorvalue, autocvar_g_balance_armor_blockpercent, damage);
 -                                                              v_z = 0; // fteqcc sucks
 +                                                              vector v = healtharmor_applydamage(targ.armorvalue, autocvar_g_balance_armor_blockpercent, damage);
                                                                targ.dmg_take += v_x;
                                                                targ.dmg_save += v_y;
                                                                targ.dmg_inflictor = inflictor;
@@@ -1270,59 -1263,43 +1270,59 @@@ float Fire_AddDamage(entity e, entity o
  
                if(maxtime > mintime || maxdps > mindps)
                {
 +                      // Constraints:
 +                      
 +                      // damage we have right now
                        mindamage = mindps * mintime;
 -                      maxdamage = mindamage + d;
 -
 -                      // interval [mintime, maxtime] * [mindps, maxdps]
 -                      // intersected with
 -                      // [mindamage, maxdamage]
 -                      // maximum of this!
  
 -                      if(maxdamage >= maxtime * maxdps)
 -                      {
 -                              totaltime = maxtime;
 -                              totaldamage = maxtime * maxdps;
 -
 -                              // this branch increases totaldamage if either t > mintime, or dps > mindps
 -                      }
 -                      else
 -                      {
 -                              // maxdamage is inside the interval!
 -                              // first, try to use mindps; only if this fails, increase dps as needed
 -                              totaltime = min(maxdamage / mindps, maxtime); // maxdamage / mindps >= mindamage / mindps = mintime
 -                              totaldamage = maxdamage;
 -                              // can totaldamage / totaltime be >= maxdps?
 -                              // max(mindps, maxdamage / maxtime) >= maxdps?
 -                              // we know maxdamage < maxtime * maxdps
 -                              // so it cannot be
 -
 -                              // this branch ALWAYS increases totaldamage, but requires maxdamage < maxtime * maxdps
 -                      }
 +                      // damage we want to get
 +                      maxdamage = mindamage + d;
  
 -                      // total conditions for increasing:
 -                      //     maxtime > mintime OR maxdps > mindps OR maxtime * maxdps > maxdamage
 -                      // however:
 -                      //     if maxtime = mintime, maxdps = mindps
 -                      // then:
 -                      //     maxdamage = mindamage + d
 -                      //     mindamage = mindps * mintime = maxdps * maxtime < maxdamage!
 -                      // so the last condition is not needed
 +                      // 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 due to lemma
 +                      */
 +
 +                      // alternate:
 +                      // at most as long as maximum allowed
 +                      // 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;