]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge remote-tracking branch 'origin/master' into samual/notification_rewrite
authorSamual Lenks <samual@xonotic.org>
Tue, 11 Dec 2012 21:53:06 +0000 (16:53 -0500)
committerSamual Lenks <samual@xonotic.org>
Tue, 11 Dec 2012 21:53:06 +0000 (16:53 -0500)
1  2 
defaultXonotic.cfg
qcsrc/client/Main.qc
qcsrc/client/View.qc
qcsrc/client/hud.qc
qcsrc/client/scoreboard.qc
qcsrc/common/constants.qh
qcsrc/server/cl_client.qc
qcsrc/server/cl_player.qc
qcsrc/server/defs.qh
qcsrc/server/g_damage.qc
qcsrc/server/g_world.qc

diff --combined defaultXonotic.cfg
index e20969c788b8a18f6a3903613aaa5e7013c10d41,9796e60027f44f1ca3308e856c002e03dc1f17a9..60582e21aae06bdfd25181e2d0205027cf65eeae
@@@ -813,7 -813,6 +813,7 @@@ set g_chat_flood_lmax_tell 2       "private c
  set g_chat_flood_burst_tell 2 "private chat: allow bursts of so many chat lines"
  set g_chat_flood_notify_flooder 1     "when 0, the flooder still can see his own message"
  set g_chat_teamcolors 0       "colorize nicknames in team color for chat"
 +set g_chat_tellprivacy 1 "when disabled, tell messages are also sent to the server console log... otherwise they're kept private between players."
  set g_nick_flood_timeout 120 "time after which nick flood protection resets (set to 0 to disable nick flood checking)"
  set g_nick_flood_penalty 0.5 "duration of the nick flood penalty"
  set g_nick_flood_penalty_yellow 3 "number of changes to allow before warning and movement blocking"
@@@ -964,6 -963,7 +964,7 @@@ seta scoreboard_offset_left 0.15 "how f
  seta scoreboard_offset_right 0.15 "how far (by percent) the scoreboard is offset from the right screen edge"
  seta scoreboard_offset_vertical 0.05 "how far (by percent) the scoreboard is offset from the top and bottom of the screen"
  seta scoreboard_bg_scale 0.25 "scale for the tiled scoreboard background"
+ seta scoreboard_respawntime_decimals 1 "decimal places to show for the respawntime countdown display on the scoreboard"
  
  seta accuracy_color_levels "0 20 100" "accuracy values at which a specified color (accuracy_color<X>) will be used. If your accuracy is between 2 of these values then a mix of the Xth and X+1th colors will be used. You can specify up to 10 values, in increasing order"
  seta accuracy_color0 "1 0 0"
diff --combined qcsrc/client/Main.qc
index 97048d8745d33fc48628c8993dfe49329e854ca3,835d2855ed78a866c8e0e15a806b63b6ff6b9766..3562435b93de46b5334d2eb287d2cd765e05a2c9
@@@ -149,14 -149,12 +149,14 @@@ void CSQC_Init(void
        teams = Sort_Spawn();
        players = Sort_Spawn();
  
 -      GetTeam(COLOR_SPECTATOR, true); // add specs first
 +      GetTeam(FL_SPECTATOR, true); // add specs first
  
        // needs to be done so early because of the constants they create
        CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
        CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
 -
 +      CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
 +      CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
 +      
        WaypointSprite_Load();
  
        // precaches
@@@ -261,16 -259,16 +261,16 @@@ float SetTeam(entity o, float Team
                switch(Team)
                {
                        case -1:
 -                      case COLOR_TEAM1:
 -                      case COLOR_TEAM2:
 -                      case COLOR_TEAM3:
 -                      case COLOR_TEAM4:
 +                      case FL_TEAM_1:
 +                      case FL_TEAM_2:
 +                      case FL_TEAM_3:
 +                      case FL_TEAM_4:
                                break;
                        default:
                                if(GetTeam(Team, false) == world)
                                {
                                        print(sprintf(_("trying to switch to unsupported team %d\n"), Team));
 -                                      Team = COLOR_SPECTATOR;
 +                                      Team = FL_SPECTATOR;
                                }
                                break;
                }
                                if(GetTeam(Team, false) == world)
                                {
                                        print(sprintf(_("trying to switch to unsupported team %d\n"), Team));
 -                                      Team = COLOR_SPECTATOR;
 +                                      Team = FL_SPECTATOR;
                                }
                                break;
                }
@@@ -385,9 -383,10 +385,10 @@@ float button_zoom
  // CSQC_InputEvent : Used to perform actions based on any key pressed, key released and mouse on the client.
  // Return value should be 1 if CSQC handled the input, otherwise return 0 to have the input passed to the engine.
  // All keys are in ascii.
- // bInputType = 0 is key pressed, 1 is key released, 2 is mouse input.
+ // bInputType = 0 is key pressed, 1 is key released, 2 and 3 are mouse input.
  // In the case of keyboard input, nPrimary is the ascii code, and nSecondary is 0.
  // In the case of mouse input, nPrimary is xdelta, nSecondary is ydelta.
+ // In the case of mouse input after a setcursormode(1) call, nPrimary is xpos, nSecondary is ypos.
  float CSQC_InputEvent(float bInputType, float nPrimary, float nSecondary)
  {
        float bSkipKey;
@@@ -1210,10 -1209,6 +1211,10 @@@ float CSQC_Parse_TempEntity(
                        cl_notice_read();
                        bHandled = true;
                        break;
 +              case TE_CSQC_NOTIFICATION:
 +                      Read_Notification();
 +                      bHandled = true;
 +                      break;
                default:
                        // No special logic for this temporary entity; return 0 so the engine can handle it
                        bHandled = false;
diff --combined qcsrc/client/View.qc
index 2380e941f66356f3c8526cd3a9c5fc530ed10b8c,e9c21f9dd229b4e77967617ae4af7e5a956eb5b8..086728bcbc3a9d440f664c55e22d5256b47ea2fa
@@@ -240,7 -240,7 +240,7 @@@ float EnemyHitCheck(
        if(teamplay)
                if(t == myteam)
                        return SHOTTYPE_HITTEAM;
 -      if(t == COLOR_SPECTATOR)
 +      if(t == FL_SPECTATOR)
                return SHOTTYPE_HITWORLD;
        return SHOTTYPE_HITENEMY;
  }
@@@ -473,9 -473,9 +473,9 @@@ void CSQC_UpdateView(float w, float h
                        eventchase_current_distance = 0; // start from 0 next time
                }
        }
-       
        // do lockview after event chase camera so that it still applies whenever necessary.
-       if(autocvar_cl_lockview || (autocvar__hud_configure && spectatee_status <= 0) || intermission > 1)
+       if(autocvar_cl_lockview || (!autocvar_hud_cursormode && (autocvar__hud_configure && spectatee_status <= 0 || intermission > 1)))
        {
                setproperty(VF_ORIGIN, freeze_org);
                setproperty(VF_ANGLES, freeze_ang);
diff --combined qcsrc/client/hud.qc
index e91e09e0785182b77d28ee532f78f25ba255879e,13f37b70eb9b594cc8c68dcfde1f42936385ea41..2289017ef4f403ad29c727c5cd5cc830c331d31a
@@@ -241,30 -241,6 +241,30 @@@ float race_CheckName(string net_name) 
        return 0;
  }
  
 +float GetPlayerColorForce(float i)
 +{
 +      if(!teamplay)
 +              return 0;
 +      else
 +              return stof(getplayerkeyvalue(i, "colors")) & 15;
 +}
 +
 +float GetPlayerColor(float i)
 +{
 +      if not(playerslots[i].gotscores) // unconnected
 +              return FL_SPECTATOR;
 +      else if(stof(getplayerkeyvalue(i, "frags")) == FRAGS_SPECTATOR)
 +              return FL_SPECTATOR;
 +      else
 +              return GetPlayerColorForce(i);
 +}
 +
 +string GetPlayerName(float i)
 +{
 +      return ColorTranslateRGB(getplayerkeyvalue(i, "name"));
 +}
 +
 +
  /*
  ==================
  HUD panels
@@@ -1622,10 -1598,31 +1622,10 @@@ string Weapon_KillMessage(float deathty
        return w_deathtypestring;
  }
  
 -#define KN_MAX_ENTRIES 10
 -float kn_index;
 -float killnotify_times[KN_MAX_ENTRIES];
 -float killnotify_deathtype[KN_MAX_ENTRIES];
 -float killnotify_actiontype[KN_MAX_ENTRIES]; // 0 = "Y [used by] X", 1 = "X [did action to] Y"
 -string killnotify_attackers[KN_MAX_ENTRIES];
 -string killnotify_victims[KN_MAX_ENTRIES];
 -void HUD_KillNotify_Push(string attacker, string victim, float actiontype, float wpn)
 -{
 -      --kn_index;
 -      if (kn_index == -1)
 -              kn_index = KN_MAX_ENTRIES-1;
 -      killnotify_times[kn_index] = time;
 -      killnotify_deathtype[kn_index] = wpn;
 -      killnotify_actiontype[kn_index] = actiontype;
 -      if(killnotify_attackers[kn_index])
 -              strunzone(killnotify_attackers[kn_index]);
 -      killnotify_attackers[kn_index] = strzone(attacker);
 -      if(killnotify_victims[kn_index])
 -              strunzone(killnotify_victims[kn_index]);
 -      killnotify_victims[kn_index] = strzone(victim);
 -}
  
  void HUD_KillNotify(string s1, string s2, string s3, float type, float msg) // s1 = attacker, s2 = victim
  {
 +      /*
        float w;
        float alsoprint, gentle;
        alsoprint = (autocvar_hud_panel_notify_print || !panel_enabled); // print message to console if: notify panel disabled, or cvar to do so enabled
                        if(alsoprint)
                                print(sprintf(_("%s^7 has dropped the ball!\n"), s1));
                }
 -      }
 +      }*/
  }
  
  void HUD_KillCenterprint(string s1, string s2, float type, float msg)
                                centerprint_hud(_("^1Don't go against team mates!"));
                        else
                                centerprint_hud(_("^1Don't shoot your team mates!"));
 -              } else if (type == DEATH_QUIET) {
 -                      // do nothing
                } else { // generic message
                        if(gentle)
                                centerprint_hud(_("^1You need to be more careful!"));
        }
  }
  
 -void HUD_Notify (void)
 +void HUD_Notify(void)
  {
        if(!autocvar__hud_configure)
        {
        float fadetime;
        fadetime = autocvar_hud_panel_notify_fadetime;
  
 -      string s;
 -
 -      vector pos_attacker, pos_victim;
 -      vector weap_pos;
 +      vector pos_attacker, pos_victim, pos_icon;
        float width_attacker;
 -      string attacker, victim;
 +      string attacker, victim, icon;
  
        float i, j, w, type, step, limit;
        if(autocvar_hud_panel_notify_flip) //order items from the top down
                                a = entries - 1 - i;
                        attacker = textShortenToWidth(sprintf(_("Player %d"), a+1), 0.48 * mySize_x - height, fontsize, stringwidth_colors);
                        victim = textShortenToWidth(sprintf(_("Player %d"), a+2), 0.48 * mySize_x - height, fontsize, stringwidth_colors);
 -                      s = strcat("weapon", get_weaponinfo(WEP_FIRST + mod(floor(a*2.4), WEP_LAST)).netname);
 +                      icon = strcat("weapon", get_weaponinfo(WEP_FIRST + mod(floor(a*2.4), WEP_LAST)).netname);
                        a = bound(0, (when - a) / 4, 1);
                        goto hud_config_notifyprint;
                }
 -
 -              if (j == KN_MAX_ENTRIES)
 -                      j = 0;
 -
 -              if(killnotify_times[j] + when > time)
 -                      a = 1;
 -              else if(fadetime)
 -              {
 -                      a = bound(0, (killnotify_times[j] + when + fadetime - time) / fadetime, 1);
 -                      if(!a)
 -                      {
 -                              break;
 -                      }
 -              }
                else
                {
 -                      break;
 -              }
 -
 -              s = "";
 -
 -              type = killnotify_deathtype[j];
 -              w = DEATH_WEAPONOF(type);
 +                      if (j == KN_MAX_ENTRIES)
 +                              j = 0;
  
 -              // TODO: maybe print in team colors?
 -              //
 -              // Y [used by] X
 -              if(killnotify_actiontype[j] == 0) 
 -              {
 -                      if(type == DEATH_GENERIC)
 -                      {
 -                              s = "notify_death";
 -                      }
 -                      else if(type == DEATH_NOAMMO)
 -                      {
 -                              s = "notify_outofammo";
 -                      }
 -                      else if(type == DEATH_KILL)
 -                      {
 -                              s = "notify_selfkill";
 -                      }
 -                      else if(type == DEATH_CAMP)
 -                      {
 -                              s = "notify_camping";
 -                      }
 -                      else if(type == KILL_TEAM_RED)
 -                      {
 -                              s = "notify_teamkill_red";
 -                      }
 -                      else if(type == KILL_TEAM_BLUE)
 -                      {
 -                              s = "notify_teamkill_blue";
 -                      }
 -                      else if(type == DEATH_DROWN)
 -                      {
 -                              s = "notify_water";
 -                      }
 -                      else if(type == DEATH_SLIME)
 -                      {
 -                              s = "notify_slime";
 -                      }
 -                      else if(type == DEATH_LAVA)
 -                      {
 -                              s = "notify_lava";
 -                      }
 -                      else if(type == DEATH_FALL)
 -                      {
 -                              s = "notify_fall";
 -                      }
 -                      else if(type == DEATH_SHOOTING_STAR)
 -                      {
 -                              s = "notify_shootingstar";
 -                      }
 -                      else if(type == DEATH_HURTTRIGGER || type == DEATH_CUSTOM)
 -                      {
 -                              s = "notify_death";
 -                      }
 -                      else if(type == INFO_GOTFLAG)
 -                      {
 -                              if(killnotify_victims[j] == "^1RED^7 flag")
 -                              {
 -                                      s = "notify_red_taken";
 -                              }
 -                              else
 -                              {
 -                                      s = "notify_blue_taken";
 -                              }
 -                      }
 -                      else if(type == INFO_RETURNFLAG)
 -                      {
 -                              if(killnotify_victims[j] == "^1RED^7 flag")
 -                              {
 -                                      s = "notify_red_returned";
 -                              }
 -                              else
 -                              {
 -                                      s = "notify_blue_returned";
 -                              }
 -                      }
 -                      else if(type == INFO_LOSTFLAG)
 -                      {
 -                              if(killnotify_victims[j] == "^1RED^7 flag")
 -                              {
 -                                      s = "notify_red_lost";
 -                              }
 -                              else
 -                              {
 -                                      s = "notify_blue_lost";
 -                              }
 -                      }
 -                      else if(type == INFO_CAPTUREFLAG)
 +                      if(killnotify_times[j] + when > time)
 +                              a = 1;
 +                      else if(fadetime)
                        {
 -                              if(killnotify_victims[j] == "^1RED^7 flag")
 -                              {
 -                                      s = "notify_red_captured";
 -                              }
 -                              else
 +                              a = bound(0, (killnotify_times[j] + when + fadetime - time) / fadetime, 1);
 +                              if(!a)
                                {
 -                                      s = "notify_blue_captured";
 +                                      break;
                                }
                        }
 -                      else if(type == KA_DROPBALL)
 -                      {
 -                              s = "notify_balldropped";
 -                      }
 -                      else if(type == KA_PICKUPBALL)
 +                      else
                        {
 -                              s = "notify_ballpickedup";
 +                              break;
                        }
                        
 -                      attacker = textShortenToWidth(killnotify_attackers[j], 0.48 * mySize_x - height, fontsize, stringwidth_colors);
 -                      pos_attacker = pos + eX * (0.52 * mySize_x + height) + eY * ((0.5 * fontsize_y + i * height) + (0.5 * (height - fontheight)));
 -                      weap_pos = pos + eX * 0.5 * mySize_x - eX * height + eY * i * height;
 -
 -                      if(s != "")
 -                      {
 -                              drawpic_aspect_skin(weap_pos, s, '2 1 0' * height, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
 -                              drawcolorcodedstring(pos_attacker, attacker, fontsize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
 -                      }
 +                      attacker = killnotify_attackers[j];
 +                      victim = killnotify_victims[j];
 +                      icon = killnotify_icon[j];
                }
 -              // X [did action to] Y
 -              else
 +
 +              //type = killnotify_deathtype[j];
 +              //w = DEATH_WEAPONOF(type);
 +
 +              if(icon != "")
                {
 -                      if(type & HITTYPE_SECONDARY && w == WEP_LASER)
 -                      {
 -                              s = "notify_melee_laser";
 -                      }
 -                      else if(type & HITTYPE_SECONDARY && w == WEP_SHOTGUN)
 -                      {
 -                              s = "notify_melee_shotgun";
 -                      }
 -                      else if(type & HITTYPE_HEADSHOT && (w == WEP_RIFLE || w == WEP_MINSTANEX)) // all headshot weapons go here
 -                      {
 -                              s = "notify_headshot";
 -                      }
 -                      else if(WEP_VALID(w))
 -                      {
 -                              self = get_weaponinfo(w);
 -                              s = strcat("weapon", self.netname);
 -                      }
 -                      else if(type == KILL_TEAM_RED)
 -                      {
 -                              s = "notify_teamkill_red";
 -                      }
 -                      else if(type == KILL_TEAM_BLUE)
 -                      {
 -                              s = "notify_teamkill_red";
 -                      }
 -                      else if(type == DEATH_TELEFRAG)
 -                      {
 -                              s = "notify_telefrag";
 -                      }
 -                      else if(type == DEATH_DROWN)
 -                      {
 -                              s = "notify_water";
 -                      }
 -                      else if(type == DEATH_SLIME)
 -                      {
 -                              s = "notify_slime";
 -                      }
 -                      else if(type == DEATH_LAVA)
 -                      {
 -                              s = "notify_lava";
 -                      }
 -                      else if(type == DEATH_FALL)
 -                      {
 -                              s = "notify_fall";
 -                      }
 -                      else if(type == DEATH_SHOOTING_STAR)
 -                      {
 -                              s = "notify_shootingstar";
 -                      }
 -                      else if(type == DEATH_HURTTRIGGER || type == DEATH_CUSTOM) // DEATH_CUSTOM is also void, right?
 -                      {
 -                              s = "notify_void";
 -                      }
 -                      else if(type == RACE_SERVER_RECORD)
 -                      {
 -                              s = "race_newrecordserver";
 -                      }
 -                      else if(type == RACE_NEW_RANK)
 -                      {
 -                              s = "race_newrankyellow";
 -                      }
 -                      else if(type == RACE_NEW_TIME)
 +                      if((attacker != "") && (victim == ""))
                        {
 -                              s = "race_newtime";
 +                              // Y [used by] X
 +                              attacker = textShortenToWidth(attacker, 0.73 * mySize_x - height, fontsize, stringwidth_colors);
 +                              pos_attacker = pos + eX * (0.27 * mySize_x + height) + eY * ((0.5 * fontsize_y + i * height) + (0.5 * (height - fontheight)));
 +                              pos_icon = pos + eX * 0.25 * mySize_x - eX * height + eY * i * height;
 +
 +                              drawpic_aspect_skin(pos_icon, icon, '2 1 0' * height, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
 +                              drawcolorcodedstring(pos_attacker, attacker, fontsize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
                        }
 -                      else if(type == RACE_FAIL)
 +                      else if((attacker != "") && (victim != ""))
                        {
 -                              s = "race_newfail";
 -                      }
 -
 -                      attacker = textShortenToWidth(killnotify_attackers[j], 0.48 * mySize_x - height, fontsize, stringwidth_colors);
 -                      victim = textShortenToWidth(killnotify_victims[j], 0.48 * mySize_x - height, fontsize, stringwidth_colors);
 +                              // X [did action to] Y
 +                              attacker = textShortenToWidth(attacker, 0.48 * mySize_x - height, fontsize, stringwidth_colors);
 +                              victim = textShortenToWidth(victim, 0.48 * mySize_x - height, fontsize, stringwidth_colors);
  :hud_config_notifyprint
 -                      width_attacker = stringwidth(attacker, TRUE, fontsize);
 -                      pos_attacker = pos + eX * (0.48 * mySize_x - height - width_attacker) + eY * ((0.5 * fontsize_y + i * height) + (0.5 * (height - fontheight)));
 -                      pos_victim = pos + eX * (0.52 * mySize_x + height) + eY * ((0.5 * fontsize_y + i * height) + (0.5 * (height - fontheight)));
 -                      weap_pos = pos + eX * 0.5 * mySize_x - eX * height + eY * i * height;
 +                              width_attacker = stringwidth(attacker, TRUE, fontsize);
 +                              pos_attacker = pos + eX * (0.48 * mySize_x - height - width_attacker) + eY * ((0.5 * fontsize_y + i * height) + (0.5 * (height - fontheight)));
 +                              pos_victim = pos + eX * (0.52 * mySize_x + height) + eY * ((0.5 * fontsize_y + i * height) + (0.5 * (height - fontheight)));
 +                              pos_icon = pos + eX * 0.5 * mySize_x - eX * height + eY * i * height;
  
 -                      if(s != "")
 -                      {
 -                              drawpic_aspect_skin(weap_pos, s, '2 1 0' * height, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
 +                              drawpic_aspect_skin(pos_icon, icon, '2 1 0' * height, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
                                drawcolorcodedstring(pos_attacker, attacker, fontsize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
                                drawcolorcodedstring(pos_victim, victim, fontsize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
                        }
@@@ -2473,8 -2647,8 +2473,8 @@@ void HUD_Radar(void
        for(tm = world; (tm = find(tm, classname, "entcs_receiver")); )
        {
                color2 = GetPlayerColor(tm.sv_entnum);
 -              //if(color == COLOR_SPECTATOR || color == color2)
 -                      draw_teamradar_player(tm.origin, tm.angles, GetTeamRGB(color2));
 +              //if(color == FL_SPECTATOR || color == color2)
 +                      draw_teamradar_player(tm.origin, tm.angles, Team_ColorRGB(color2));
        }
        draw_teamradar_player(view_origin, view_angles, '1 1 1');
  
@@@ -2515,7 -2689,7 +2515,7 @@@ void HUD_Score_Rankings(vector pos, vec
                        for(i=0; i<team_count; ++i) {
                                if (i == floor((entries - 2) / players_per_team) || (entries == 1 && i == 0))
                                        HUD_Panel_DrawHighlight(pos + eX * score_size * i, eX * score_size + eY * fontsize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 -                              drawstring_aspect(pos + eX * score_size * i, ftos(175 - 23*i), eX * score_size + eY * fontsize_y, GetTeamRGB(ColorByTeam(i)) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
 +                              drawstring_aspect(pos + eX * score_size * i, ftos(175 - 23*i), eX * score_size + eY * fontsize_y, Team_ColorRGB(ColorByTeam(i)) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
                        }
                        first_pl = 1;
                        pos_y += fontsize_y;
                        }
  
                        if (team_count)
 -                              score_color = GetTeamRGB(ColorByTeam(floor((i - first_pl) / players_per_team))) * 0.8;
 +                              score_color = Team_ColorRGB(ColorByTeam(floor((i - first_pl) / players_per_team))) * 0.8;
                        s = textShortenToWidth(s, name_size, fontsize, stringwidth_colors);
                        drawcolorcodedstring(pos + eX * (name_size - stringwidth(s, TRUE, fontsize)), s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
                        drawstring(pos + eX * (name_size + spacing_size), ftos(score), fontsize, score_color, panel_fg_alpha, DRAWFLAG_NORMAL);
                // show team scores in the first line
                float score_size = mySize_x / team_count;
                for(tm = teams.sort_next; tm; tm = tm.sort_next) {
 -                      if(tm.team == COLOR_SPECTATOR)
 +                      if(tm.team == FL_SPECTATOR)
                                continue;
                        if (tm.team == myteam)
                                drawfill(pos + eX * score_size * i, eX * score_size + eY * fontsize_y, '1 1 1', highlight_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
 -                      drawstring_aspect(pos + eX * score_size * i, ftos(tm.(teamscores[ts_primary])), eX * score_size + eY * fontsize_y, GetTeamRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
 +                      drawstring_aspect(pos + eX * score_size * i, ftos(tm.(teamscores[ts_primary])), eX * score_size + eY * fontsize_y, Team_ColorRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
                        ++i;
                }
                first_pl = 1;
        do
        for (pl = players.sort_next; pl && i<entries; pl = pl.sort_next)
        {
 -              if ((team_count && pl.team != tm.team) || pl.team == COLOR_SPECTATOR)
 +              if ((team_count && pl.team != tm.team) || pl.team == FL_SPECTATOR)
                        continue;
  
                if (i == entries-1 && !me_printed && pl != me)
                if (autocvar_hud_panel_score_rankings == 1 && spectatee_status != -1)
                {
                        for (pl = me.sort_next; pl; pl = pl.sort_next)
 -                              if (pl.team != COLOR_SPECTATOR)
 +                              if (pl.team != FL_SPECTATOR)
                                        break;
  
                        if (pl)
                        drawfill(pos, eX * mySize_x + eY * fontsize_y, rgb, highlight_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
                }
                if (team_count)
 -                      score_color = GetTeamRGB(pl.team) * 0.8;
 +                      score_color = Team_ColorRGB(pl.team) * 0.8;
                s = textShortenToWidth(GetPlayerName(pl.sv_entnum), name_size, fontsize, stringwidth_colors);
                drawcolorcodedstring(pos + eX * (name_size - stringwidth(s, TRUE, fontsize)), s, fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
                drawstring(pos + eX * (name_size + spacing_size), ftos(pl.(scores[ps_primary])), fontsize, score_color, panel_fg_alpha, DRAWFLAG_NORMAL);
                pos_y += fontsize_y;
                ++i;
        }
 -      while (i<entries && team_count && (tm = tm.sort_next) && (tm.team != COLOR_SPECTATOR || (tm = tm.sort_next)));
 +      while (i<entries && team_count && (tm = tm.sort_next) && (tm.team != FL_SPECTATOR || (tm = tm.sort_next)));
  }
  
  void HUD_Score(void)
                vector score_pos, score_size; //for scores other than myteam
                if (spectatee_status == -1 || autocvar_hud_panel_score_rankings)
                {
 -                      for(tm = teams.sort_next; tm, tm.team != COLOR_SPECTATOR; tm = tm.sort_next)
 +                      for(tm = teams.sort_next; tm, tm.team != FL_SPECTATOR; tm = tm.sort_next)
                                ++scores_count;
                        if (autocvar_hud_panel_score_rankings)
                        {
                max_fragcount = -99;
                draw_beginBoldFont();
                for(tm = teams.sort_next; tm; tm = tm.sort_next) {
 -                      if(tm.team == COLOR_SPECTATOR)
 +                      if(tm.team == FL_SPECTATOR)
                                continue;
                        score = tm.(teamscores[ts_primary]);
                        if(autocvar__hud_configure)
                                score_pos = pos + eX * column * (score_size_x + offset_x) + eY * row * (score_size_y + offset_y);
                                if (max_fragcount == score)
                                        HUD_Panel_DrawHighlight(score_pos, score_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 -                              drawstring_aspect(score_pos, ftos(score), score_size, GetTeamRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
 +                              drawstring_aspect(score_pos, ftos(score), score_size, Team_ColorRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
                                ++row;
                                if(row >= rows)
                                {
                        else if(tm.team == myteam) {
                                if (max_fragcount == score)
                                        HUD_Panel_DrawHighlight(pos, eX * 0.75 * mySize_x + eY * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 -                              drawstring_aspect(pos, ftos(score), eX * 0.75 * mySize_x + eY * mySize_y, GetTeamRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
 +                              drawstring_aspect(pos, ftos(score), eX * 0.75 * mySize_x + eY * mySize_y, Team_ColorRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
                        } else {
                                if (max_fragcount == score)
                                        HUD_Panel_DrawHighlight(pos + eX * 0.75 * mySize_x + eY * (1/3) * rows * mySize_y, score_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
 -                              drawstring_aspect(pos + eX * 0.75 * mySize_x + eY * (1/3) * rows * mySize_y, ftos(score), score_size, GetTeamRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
 +                              drawstring_aspect(pos + eX * 0.75 * mySize_x + eY * (1/3) * rows * mySize_y, ftos(score), score_size, Team_ColorRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
                                ++rows;
                        }
                }
@@@ -3206,7 -3380,7 +3206,7 @@@ void HUD_Mod_CTF(vector pos, vector myS
                case 2: red_icon = "flag_red_lost"; break;
                case 3: red_icon = "flag_red_carrying"; red_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break;
                default:
 -                      if((stat_items & IT_CTF_SHIELDED) && (myteam == COLOR_TEAM2))
 +                      if((stat_items & IT_CTF_SHIELDED) && (myteam == FL_TEAM_2))
                                red_icon = "flag_red_shielded";
                        else
                                red_icon = string_null;
                default:
                        if(redflag == 3)
                                red_icon_prevstatus = "flag_red_carrying"; // make it more visible
 -                      else if((stat_items & IT_CTF_SHIELDED) && (myteam == COLOR_TEAM2))
 +                      else if((stat_items & IT_CTF_SHIELDED) && (myteam == FL_TEAM_2))
                                red_icon_prevstatus = "flag_red_shielded";
                        else
                                red_icon_prevstatus = string_null;
                case 2: blue_icon = "flag_blue_lost"; break;
                case 3: blue_icon = "flag_blue_carrying"; blue_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break;
                default:
 -                      if((stat_items & IT_CTF_SHIELDED) && (myteam == COLOR_TEAM1))
 +                      if((stat_items & IT_CTF_SHIELDED) && (myteam == FL_TEAM_1))
                                blue_icon = "flag_blue_shielded";
                        else
                                blue_icon = string_null;
                default:
                        if(blueflag == 3)
                                blue_icon_prevstatus = "flag_blue_carrying"; // make it more visible
 -                      else if((stat_items & IT_CTF_SHIELDED) && (myteam == COLOR_TEAM1))
 +                      else if((stat_items & IT_CTF_SHIELDED) && (myteam == FL_TEAM_1))
                                blue_icon_prevstatus = "flag_blue_shielded";
                        else
                                blue_icon_prevstatus = string_null;
        }
  
        if(mySize_x > mySize_y) {
 -              if (myteam == COLOR_TEAM1) { // always draw own flag on left
 +              if (myteam == FL_TEAM_1) { // always draw own flag on left
                        redflag_pos = pos;
                        blueflag_pos = pos + eX * 0.5 * mySize_x;
                } else {
                }
                flag_size = eX * 0.5 * mySize_x + eY * mySize_y;
        } else {
 -              if (myteam == COLOR_TEAM1) { // always draw own flag on left
 +              if (myteam == FL_TEAM_1) { // always draw own flag on left
                        redflag_pos = pos;
                        blueflag_pos = pos + eY * 0.5 * mySize_y;
                } else {
@@@ -3378,16 -3552,16 +3378,16 @@@ void HUD_Mod_KH(vector pos, vector mySi
                {
                        switch(keyteam)
                        {
 -                              case COLOR_TEAM1:
 +                              case FL_TEAM_1:
                                        drawpic_aspect_skin(pa, "kh_redarrow", kh_asize, '1 1 1', aa, DRAWFLAG_NORMAL);  // show 30% theAlpha key
                                        break;
 -                              case COLOR_TEAM2:
 +                              case FL_TEAM_2:
                                        drawpic_aspect_skin(pa, "kh_bluearrow", kh_asize, '1 1 1', aa, DRAWFLAG_NORMAL);  // show 30% theAlpha key
                                        break;
 -                              case COLOR_TEAM3:
 +                              case FL_TEAM_3:
                                        drawpic_aspect_skin(pa, "kh_yellowarrow", kh_asize, '1 1 1', aa, DRAWFLAG_NORMAL);  // show 30% theAlpha key
                                        break;
 -                              case COLOR_TEAM4:
 +                              case FL_TEAM_4:
                                        drawpic_aspect_skin(pa, "kh_pinkarrow", kh_asize, '1 1 1', aa, DRAWFLAG_NORMAL);  // show 30% theAlpha key
                                        break;
                                default:
@@@ -3725,7 -3899,7 +3725,7 @@@ void HUD_Mod_Dom(vector myPos, vector m
        entity tm;
        float teams_count;
        for(tm = teams.sort_next; tm; tm = tm.sort_next)
 -              if(tm.team != COLOR_SPECTATOR)
 +              if(tm.team != FL_SPECTATOR)
                        ++teams_count;
  
        float layout = autocvar_hud_panel_modicons_dom_layout;
@@@ -4184,7 -4358,7 +4184,7 @@@ void HUD_InfoMessages(void
                        {
                                for(; tm.sort_next; tm = tm.sort_next)
                                {
 -                                      if(!tm.team_size || tm.team == COLOR_SPECTATOR)
 +                                      if(!tm.team_size || tm.team == FL_SPECTATOR)
                                                continue;
                                        if(!ts_min) ts_min = tm.team_size;
                                        else ts_min = min(ts_min, tm.team_size);
                                        s = strcat(blinkcolor, _("Teamnumbers are unbalanced!"));
                                        tm = GetTeam(myteam, false);
                                        if (tm)
 -                                      if (tm.team != COLOR_SPECTATOR)
 +                                      if (tm.team != FL_SPECTATOR)
                                        if (tm.team_size == ts_max)
                                                s = strcat(s, sprintf(_(" Press ^3%s%s to adjust"), getcommandkey("team menu", "menu_showteamselect"), blinkcolor));
                                        drawInfoMessage(s)
@@@ -5017,8 -5191,13 +5017,13 @@@ void HUD_Main (void
                        HUD_Panel_HlBorder(panel_bg_border + 1.5 * hlBorderSize, '0 0.5 1', 0.25 * (1 - autocvar__menu_alpha));
                }
                if (!hud_configure_prev)
+               {
+                       if(autocvar_hud_cursormode) { setcursormode(1); }
                        hudShiftState = 0;
+               }
        }
+       else if (hud_configure_prev && autocvar_hud_cursormode)
+               setcursormode(0);
  
        hud_configure_prev = autocvar__hud_configure;
  
index 324c83b423c093fe3e14dd73e0cb7d93ad4e0c3e,364f9e969e27aeee9a5ca91c3a3310f2b4ee3740..aa2d7259f7b0ea4d2b89d269c8598e24a14d1ee9
@@@ -136,16 -136,16 +136,16 @@@ float HUD_ComparePlayerScores(entity le
        vr = GetPlayerColor(right.sv_entnum);
  
        if(!left.gotscores)
 -              vl = COLOR_SPECTATOR;
 +              vl = FL_SPECTATOR;
        if(!right.gotscores)
 -              vr = COLOR_SPECTATOR;
 +              vr = FL_SPECTATOR;
  
        if(vl > vr)
                return true;
        if(vl < vr)
                return false;
  
 -      if(vl == COLOR_SPECTATOR)
 +      if(vl == FL_SPECTATOR)
        {
                // FIRST the one with scores (spectators), THEN the ones without (downloaders)
                // no other sorting
@@@ -201,9 -201,9 +201,9 @@@ float HUD_CompareTeamScores(entity left
  {
        float vl, vr;
  
 -      if(left.team == COLOR_SPECTATOR)
 +      if(left.team == FL_SPECTATOR)
                return 1;
 -      if(right.team == COLOR_SPECTATOR)
 +      if(right.team == FL_SPECTATOR)
                return 0;
  
        vl = left.teamscores[ts_primary];
@@@ -659,11 -659,11 +659,11 @@@ string HUD_FixScoreboardColumnWidth(flo
  void HUD_PrintScoreboardItem(vector pos, entity pl, float is_self, float pl_number)
  {
        vector tmp, rgb;
 -      rgb = GetTeamRGB(pl.team);
 +      rgb = Team_ColorRGB(pl.team);
        string str;
        float i, field;
        float is_spec;
 -      is_spec = (GetPlayerColor(pl.sv_entnum) == COLOR_SPECTATOR);
 +      is_spec = (GetPlayerColor(pl.sv_entnum) == FL_SPECTATOR);
  
        if((rgb == '1 1 1') && (!is_spec)) {
                rgb_x = autocvar_scoreboard_color_bg_r + 0.5;
@@@ -907,7 -907,7 +907,7 @@@ vector HUD_Scoreboard_MakeTable(vector 
        else
                for(pl = players.sort_next; pl; pl = pl.sort_next)
                {
 -                      if(pl.team == COLOR_SPECTATOR)
 +                      if(pl.team == FL_SPECTATOR)
                                continue;
                        HUD_PrintScoreboardItem(pos, pl, (pl.sv_entnum == player_localnum), i);
                        pos_y += 1.25 * hud_fontsize_y;
@@@ -1124,7 -1124,7 +1124,7 @@@ vector HUD_DrawScoreboardRankings(vecto
                return pos;
  
        float is_spec;
 -      is_spec = (GetPlayerColor(pl.sv_entnum) == COLOR_SPECTATOR);
 +      is_spec = (GetPlayerColor(pl.sv_entnum) == FL_SPECTATOR);
        vector hl_rgb;
        hl_rgb_x = autocvar_scoreboard_color_bg_r + 0.5;
        hl_rgb_y = autocvar_scoreboard_color_bg_g + 0.5;
@@@ -1241,11 -1241,11 +1241,11 @@@ void HUD_DrawScoreboard(
                team_score_baseoffset = eY * (2 * autocvar_scoreboard_border_thickness + hud_fontsize_y) - eX * (autocvar_scoreboard_border_thickness + hud_fontsize_x * 0.25);
                for(tm = teams.sort_next; tm; tm = tm.sort_next)
                {
 -                      if(tm.team == COLOR_SPECTATOR)
 +                      if(tm.team == FL_SPECTATOR)
                                continue;
  
                        draw_beginBoldFont();
 -                      rgb = GetTeamRGB(tm.team);
 +                      rgb = Team_ColorRGB(tm.team);
                        str = ftos(tm.(teamscores[ts_primary]));
                        drawstring(pos + team_score_baseoffset - eX * stringwidth(str, FALSE, hud_fontsize * 1.5), str, hud_fontsize * 1.5, rgb, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
  
  
                for(tm = teams.sort_next; tm; tm = tm.sort_next)
                {
 -                      if(tm.team == COLOR_SPECTATOR)
 +                      if(tm.team == FL_SPECTATOR)
                                continue;
  
                        pos = HUD_Scoreboard_MakeTable(pos, tm, rgb, bg_size);
        }
        else if(autocvar_scoreboard_accuracy && spectatee_status != -1 && !warmup_stage) {
                if(teamplay)
 -                      pos = HUD_DrawScoreboardAccuracyStats(pos, GetTeamRGB(myteam), bg_size);
 +                      pos = HUD_DrawScoreboardAccuracyStats(pos, Team_ColorRGB(myteam), bg_size);
                else
                        pos = HUD_DrawScoreboardAccuracyStats(pos, rgb, bg_size);
        }
  
                
        if(teamplay)
 -              pos = HUD_DrawMapStats(pos, GetTeamRGB(myteam), bg_size);
 +              pos = HUD_DrawMapStats(pos, Team_ColorRGB(myteam), bg_size);
        else
                pos = HUD_DrawMapStats(pos, rgb, bg_size);
  
        tmp = pos;
        for(pl = players.sort_next; pl; pl = pl.sort_next)
        {
 -              if(pl.team != COLOR_SPECTATOR)
 +              if(pl.team != FL_SPECTATOR)
                        continue;
                pos_y += 1.25 * hud_fontsize_y;
                HUD_PrintScoreboardItem(pos, pl, (pl.sv_entnum == player_localnum), specs);
                }
        }
  
        pos_y += 1.2 * hud_fontsize_y;
        drawcolorcodedstring(pos + '0.5 0 0' * (sbwidth - stringwidth(str, TRUE, hud_fontsize)), str, hud_fontsize, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
  
+       // print information about respawn status
+       float respawn_time = getstatf(STAT_RESPAWN_TIME);
+       if(respawn_time)
+       {
+               if(respawn_time < 0)
+               {
+                       // a negative number means we are awaiting respawn, time value is still the same
+                       respawn_time *= -1; // remove mark now that we checked it
+                       if(time >= respawn_time) // don't show a negative value while the server is respawning the player (lag)
+                               str = _("^1Respawning...");
+                       else
+                               str = sprintf(_("^1Respawning in ^3%s^1 seconds..."), ftos_decimals(respawn_time - time, autocvar_scoreboard_respawntime_decimals));
+               }
+               else if(time < respawn_time)
+                       str = sprintf(_("You are dead, wait ^3%s^7 seconds before respawning"), ftos_decimals(respawn_time - time, autocvar_scoreboard_respawntime_decimals));
+               else if(time >= respawn_time)
+                       str = sprintf(_("You are dead, press ^2%s^7 to respawn"), getcommandkey("jump", "+jump"));
+               pos_y += 1.2 * hud_fontsize_y;
+               drawcolorcodedstring(pos + '0.5 0 0' * (sbwidth - stringwidth(str, TRUE, hud_fontsize)), str, hud_fontsize, scoreboard_alpha_fg, DRAWFLAG_NORMAL);
+       }
        scoreboard_bottom = pos_y + 2 * hud_fontsize_y;
  }
index 05b1e9dcbea8f94adff16a4c6ee365ca0d5605dd,75f5a0bde762037387dbeb344989a47b1409bc01..dc128e62f448836c56c8184b7cd6884974c96fd8
@@@ -47,7 -47,6 +47,7 @@@ const float TE_CSQC_MINELAYER_MAXMINES 
  const float TE_CSQC_HAGAR_MAXROCKETS = 118;
  const float TE_CSQC_VEHICLESETUP = 119;
  const float TE_CSQC_SVNOTICE = 120;
 +const float TE_CSQC_NOTIFICATION = 121;
  
  const float RACE_NET_CHECKPOINT_HIT_QUALIFYING = 0; // byte checkpoint, short time, short recordtime, string recordholder
  const float RACE_NET_CHECKPOINT_CLEAR = 1;
@@@ -180,6 -179,8 +180,8 @@@ const float STAT_VEHICLESTAT_RELOAD2 = 
  const float STAT_SECRETS_TOTAL = 70;
  const float STAT_SECRETS_FOUND = 71;
  
+ const float STAT_RESPAWN_TIME = 72;
  // mod stats (1xx)
  const float STAT_REDALIVE = 100;
  const float STAT_BLUEALIVE = 101;
@@@ -363,6 -364,85 +365,6 @@@ float SPECIES_ROBOT_RUSTY  =  4
  float SPECIES_ROBOT_SHINY  =  5;
  float SPECIES_RESERVED     = 15;
  
 -// Deathtypes (weapon deathtypes are the IT_* constants below)
 -// NOTE: when adding death types, please add an explanation to Docs/spamlog.txt too.
 -float DEATH_SPECIAL_START = 10000;
 -float DEATH_FALL = 10000;
 -float DEATH_TELEFRAG = 10001;
 -float DEATH_DROWN = 10002;
 -float DEATH_HURTTRIGGER = 10003;
 -float DEATH_LAVA = 10004;
 -float DEATH_SLIME = 10005;
 -float DEATH_KILL = 10006;
 -float DEATH_NOAMMO = 10007;
 -float DEATH_SWAMP = 10008;
 -float DEATH_TEAMCHANGE = 10009;
 -float DEATH_AUTOTEAMCHANGE = 10010;
 -float DEATH_CAMP = 10011;
 -float DEATH_SHOOTING_STAR = 10012;
 -float DEATH_ROT = 10013;
 -float DEATH_MIRRORDAMAGE = 10014;
 -float DEATH_TOUCHEXPLODE = 10015;
 -float DEATH_CHEAT = 10016;
 -float DEATH_FIRE = 10017;
 -float DEATH_QUIET = 10021;
 -
 -float  DEATH_VHFIRST       = 10030;
 -float  DEATH_VHCRUSH       = 10030;
 -float  DEATH_SBMINIGUN     = 10031;
 -float  DEATH_SBROCKET      = 10032;
 -float  DEATH_SBBLOWUP      = 10033;
 -float  DEATH_WAKIGUN       = 10034;
 -float  DEATH_WAKIROCKET    = 10035;
 -float  DEATH_WAKIBLOWUP    = 10036;
 -float  DEATH_RAPTOR_CANNON = 10037;
 -float  DEATH_RAPTOR_BOMB   = 10038;
 -float  DEATH_RAPTOR_BOMB_SPLIT = 10039;
 -float  DEATH_RAPTOR_DEATH   = 10040;
 -float  DEATH_BUMB_GUN       = 10041;
 -float  DEATH_BUMB_RAY       = 10042;
 -float  DEATH_BUMB_RAY_HEAL  = 10043;
 -float  DEATH_BUMB_DEATH     = 10044;
 -float  DEATH_VHLAST         = 10044;
 -#define DEATH_ISVEHICLE(t)  ((t) >= DEATH_VHFIRST && (t) <= DEATH_VHLAST)
 -
 -float DEATH_GENERIC = 10050;
 -
 -float DEATH_WEAPON = 10100;
 -
 -float DEATH_CUSTOM = 10300;
 -
 -float DEATH_TURRET                  = 10500;
 -float DEATH_TURRET_EWHEEL           = 10501;
 -float DEATH_TURRET_FLAC             = 10502;
 -float DEATH_TURRET_MACHINEGUN       = 10503;
 -float DEATH_TURRET_WALKER_GUN       = 10504;
 -float DEATH_TURRET_WALKER_MEELE     = 10505;
 -float DEATH_TURRET_WALKER_ROCKET    = 10506;
 -float DEATH_TURRET_HELLION          = 10507;
 -float DEATH_TURRET_HK               = 10508;
 -float DEATH_TURRET_MLRS             = 10509;
 -float DEATH_TURRET_PLASMA           = 10510;
 -float DEATH_TURRET_PHASER           = 10511;
 -float DEATH_TURRET_TESLA            = 10512;
 -float DEATH_TURRET_LAST            = 10512;
 -
 -float DEATH_WEAPONMASK = 0xFF;
 -float DEATH_HITTYPEMASK = 0x1F00; // which is WAY below 10000 used for normal deaths
 -float HITTYPE_SECONDARY = 0x100;
 -float HITTYPE_SPLASH = 0x200; // automatically set by RadiusDamage
 -float HITTYPE_BOUNCE = 0x400;
 -float HITTYPE_HEADSHOT = 0x800; // automatically set by Damage (if headshotbonus is set)
 -float HITTYPE_RESERVED = 0x1000; // unused yet
 -
 -// macros to access these
 -#define DEATH_ISTURRET(t)            ((t) >= DEATH_TURRET && (t) <= DEATH_TURRET_LAST)
 -#define DEATH_ISSPECIAL(t)            ((t) >= DEATH_SPECIAL_START)
 -#define DEATH_WEAPONOFWEAPONDEATH(t)  ((t) & DEATH_WEAPONMASK)
 -#define DEATH_ISWEAPON(t,w)           (!DEATH_ISSPECIAL(t) && DEATH_WEAPONOFWEAPONDEATH(t) == (w))
 -#define DEATH_WEAPONOF(t)             (DEATH_ISSPECIAL(t) ? 0 : DEATH_WEAPONOFWEAPONDEATH(t))
 -#define WEP_VALID(w)                  ((w) >= WEP_FIRST && (w) <= WEP_LAST)
 -
  #define FRAGS_PLAYER 0
  #define FRAGS_SPECTATOR -666
  #define FRAGS_LMS_LOSER -616
@@@ -390,6 -470,49 +392,6 @@@ float CPID_MOTD = 9
  float CPID_KH_MSG = 10;
  float CPID_PREVENT_JOIN = 11;
  
 -// CSQC centerprint/notify message types
 -float MSG_SUICIDE = 0;
 -float MSG_KILL = 1;
 -float MSG_SPREE = 2;
 -float MSG_KILL_ACTION = 3;
 -float MSG_KILL_ACTION_SPREE = 4;
 -float MSG_INFO = 5;
 -float MSG_KA = 6;
 -float MSG_RACE = 10;
 -
 -float KILL_TEAM_RED = 12001;
 -float KILL_TEAM_BLUE = 12002;
 -float KILL_TEAM_SPREE = 12003;
 -float KILL_FIRST_BLOOD = 12004;
 -float KILL_FIRST_VICTIM = 12005;
 -float KILL_TYPEFRAG = 12006;
 -float KILL_TYPEFRAGGED = 12007;
 -float KILL_FRAG = 12008;
 -float KILL_FRAGGED = 12009;
 -float KILL_SPREE = 12010;
 -float KILL_END_SPREE = 12011;
 -float KILL_SPREE_3 = 12012;
 -float KILL_SPREE_5 = 12013;
 -float KILL_SPREE_10 = 12014;
 -float KILL_SPREE_15 = 12015;
 -float KILL_SPREE_20 = 12016;
 -float KILL_SPREE_25 = 12017;
 -float KILL_SPREE_30 = 12018;
 -
 -float INFO_GOTFLAG = 13001;
 -float INFO_PICKUPFLAG = 13002;
 -float INFO_LOSTFLAG = 13003;
 -float INFO_RETURNFLAG = 13004;
 -float INFO_CAPTUREFLAG = 13005;
 -
 -float KA_PICKUPBALL = 14001;
 -float KA_DROPBALL = 14002;
 -
 -float RACE_SERVER_RECORD = 15001;
 -float RACE_NEW_TIME = 15002;
 -float RACE_NEW_RANK = 15003;
 -float RACE_FAIL = 15004;
 -
  // weapon requests
  float WR_SETUP                = 1; // (SVQC) setup weapon data
  float WR_THINK                = 2; // (SVQC) logic to run every frame
index 006db3c36b6d5e73f3c7f9b6c5a35a45121281bc,101e35cae2718d4702f43301b7061a4dbd138ae8..9c902bb5a45ab50ded5240b884163b49df4ec952
@@@ -554,7 -554,7 +554,7 @@@ void FixPlayermodel(
                if(teamplay)
                {
                        string s;
 -                      s = Team_ColorNameLowerCase(self.team);
 +                      s = Team_ColorName_Lower(self.team);
                        if(s != "neutral")
                        {
                                defaultmodel = cvar_string(strcat("sv_defaultplayermodel_", s));
@@@ -1241,10 -1241,10 +1241,10 @@@ void ClientKill_TeamChange (float targe
                }
                else
                {
 -                      self.killindicator.colormod = TeamColor(targetteam);
 +                      self.killindicator.colormod = Team_ColorRGB(targetteam);
                        if(clienttype(self) == CLIENTTYPE_REAL)
                        if(self.killindicator.cnt > 0)
 -                              Send_CSQC_Centerprint_Generic(self, CPID_TEAMCHANGE, strcat("Changing to ", ColoredTeamName(targetteam), " in %d seconds"), 1, self.killindicator.cnt);
 +                              Send_CSQC_Centerprint_Generic(self, CPID_TEAMCHANGE, strcat("^7Changing to ", Team_ColoredFullName(targetteam), "^7 in %d seconds"), 1, self.killindicator.cnt);
                }
        }
  
@@@ -1286,7 -1286,7 +1286,7 @@@ void FixClientCvars(entity e
                stuffcmd(e, "cl_cmd settemp cl_movecliptokeyboard 2\n");
        if(autocvar_g_antilag == 3) // client side hitscan
                stuffcmd(e, "cl_cmd settemp cl_prydoncursor_notrace 0\n");
 -      if(sv_gentle)
 +      if(autocvar_sv_gentle)
                stuffcmd(e, "cl_cmd settemp cl_gentle 1\n");
        /*
         * we no longer need to stuff this. Remove this comment block if you feel
@@@ -1335,6 -1335,7 +1335,6 @@@ ClientConnec
  Called when a client connects to the server
  =============
  */
 -string ColoredTeamName(float t);
  void DecodeLevelParms (void);
  //void dom_player_join_team(entity pl);
  void set_dom_state(entity e);
@@@ -1362,16 -1363,6 +1362,16 @@@ void ClientConnect (void
        self.flags = FL_CLIENT;
        self.version_nagtime = time + 10 + random() * 10;
  
 +      if(self.netaddress == "local")
 +      {
 +              print("^3server is local!\n");
 +
 +              if(server_is_local)
 +                      print("Multiple local clients???");
 +              else
 +                      server_is_local = TRUE;
 +      }
 +
        if(player_count<0)
        {
                dprint("BUG player count is lower than zero, this cannot happen!\n");
                {
                        switch(autocvar_g_campaign_forceteam)
                        {
 -                              case 1: self.team_forced = COLOR_TEAM1; break;
 -                              case 2: self.team_forced = COLOR_TEAM2; break;
 -                              case 3: self.team_forced = COLOR_TEAM3; break;
 -                              case 4: self.team_forced = COLOR_TEAM4; break;
 +                              case 1: self.team_forced = FL_TEAM_1; break;
 +                              case 2: self.team_forced = FL_TEAM_2; break;
 +                              case 3: self.team_forced = FL_TEAM_3; break;
 +                              case 4: self.team_forced = FL_TEAM_4; break;
                                default: self.team_forced = 0;
                        }
                }
        }
        else if(PlayerInIDList(self, autocvar_g_forced_team_red))
 -              self.team_forced = COLOR_TEAM1;
 +              self.team_forced = FL_TEAM_1;
        else if(PlayerInIDList(self, autocvar_g_forced_team_blue))
 -              self.team_forced = COLOR_TEAM2;
 +              self.team_forced = FL_TEAM_2;
        else if(PlayerInIDList(self, autocvar_g_forced_team_yellow))
 -              self.team_forced = COLOR_TEAM3;
 +              self.team_forced = FL_TEAM_3;
        else if(PlayerInIDList(self, autocvar_g_forced_team_pink))
 -              self.team_forced = COLOR_TEAM4;
 +              self.team_forced = FL_TEAM_4;
        else if(autocvar_g_forced_team_otherwise == "red")
 -              self.team_forced = COLOR_TEAM1;
 +              self.team_forced = FL_TEAM_1;
        else if(autocvar_g_forced_team_otherwise == "blue")
 -              self.team_forced = COLOR_TEAM2;
 +              self.team_forced = FL_TEAM_2;
        else if(autocvar_g_forced_team_otherwise == "yellow")
 -              self.team_forced = COLOR_TEAM3;
 +              self.team_forced = FL_TEAM_3;
        else if(autocvar_g_forced_team_otherwise == "pink")
 -              self.team_forced = COLOR_TEAM4;
 +              self.team_forced = FL_TEAM_4;
        else if(autocvar_g_forced_team_otherwise == "spectate")
                self.team_forced = -1;
        else if(autocvar_g_forced_team_otherwise == "spectator")
        bprint("^4", self.netname, "^4 connected");
  
        if(self.classname != "observer" && (g_domination || g_ctf))
 -              bprint(" and joined the ", ColoredTeamName(self.team));
 +              bprint(" and joined the ", Team_ColoredFullName(self.team));
  
        bprint("\n");
  
@@@ -2176,6 -2167,7 +2176,7 @@@ void SpectateCopy(entity spectatee) 
        self.dmg_inflictor = spectatee.dmg_inflictor;
        self.v_angle = spectatee.v_angle;
        self.angles = spectatee.v_angle;
+       self.stat_respawn_time = spectatee.stat_respawn_time;
        if(!self.BUTTON_USE)
                self.fixangle = TRUE;
        setorigin(self, spectatee.origin);
@@@ -2567,6 -2559,11 +2568,11 @@@ void PlayerPreThink (void
        self.stat_allow_oldnexbeam = autocvar_g_allow_oldnexbeam;
        self.stat_leadlimit = autocvar_leadlimit;
  
+       if(g_arena || (g_ca && !allowed_to_spawn))
+               self.stat_respawn_time = 0;
+       else
+               self.stat_respawn_time = self.respawn_time;
        if(frametime)
        {
                // physics frames: update anticheat stuff
                                }
                                ShowRespawnCountdown();
                        }
+                       // if respawning, invert stat_respawn_time to indicate this, the client translates it
+                       if(self.deadflag == DEAD_RESPAWNING && self.stat_respawn_time > 0)
+                               self.stat_respawn_time *= -1;
                        return;
                }
                // FIXME from now on self.deadflag is always 0 (and self.health is never < 1)
index db82486b953a8cf6ab2c2c7e79b7cd0356726185,dcf1ab76842afdd5a8885d68d4aacc16811c4627..6f75c89eefe4307aa026dde4c6b8d379ef0fbf0c
@@@ -496,6 -496,30 +496,30 @@@ void PlayerDamage (entity inflictor, en
                take = damage;
        }
  
+       if(attacker == self)
+       {
+               // don't reset pushltime for self damage as it may be an attempt to
+               // escape a lava pit or similar
+               //self.pushltime = 0;
+               self.istypefrag = 0;
+       }
+       else if(attacker.classname == "player")
+       {
+               self.pusher = attacker;
+               self.pushltime = time + autocvar_g_maxpushtime;
+               self.istypefrag = self.BUTTON_CHAT;
+       }
+       else if(time < self.pushltime)
+       {
+               attacker = self.pusher;
+               self.pushltime = max(self.pushltime, time + 0.6);
+       }
+       else
+       {
+               self.pushltime = 0;
+               self.istypefrag = 0;
+       }
        frag_inflictor = inflictor;
        frag_attacker = attacker;
        frag_target = self;
                        {
                                self.pain_finished = time + 0.5;        //Supajoe
  
 -                              if(sv_gentle < 1) {
 +                              if(autocvar_sv_gentle < 1) {
                                        if(self.classname != "body") // pain anim is BORKED on our ZYMs, FIXME remove this once we have good models
                                        {
                                                if (!self.animstate_override)
        self.dmg_take = self.dmg_take + take;//max(take - 10, 0);
        self.dmg_inflictor = inflictor;
  
-       if(attacker == self)
-       {
-               // don't reset pushltime for self damage as it may be an attempt to
-               // escape a lava pit or similar
-               //self.pushltime = 0;
-               self.istypefrag = 0;
-       }
-       else if(attacker.classname == "player")
-       {
-               self.pusher = attacker;
-               self.pushltime = time + autocvar_g_maxpushtime;
-               self.istypefrag = self.BUTTON_CHAT;
-       }
-       else if(time < self.pushltime)
-       {
-               attacker = self.pusher;
-               self.pushltime = max(self.pushltime, time + 0.6);
-       }
-       else
-       {
-               self.pushltime = 0;
-               self.istypefrag = 0;
-       }
+       if(g_ca && self != attacker && attacker.classname == "player")
+               PlayerScore_Add(attacker, SP_SCORE, (damage - excess) * autocvar_g_ca_damage2score_multiplier);
  
        float abot, vbot, awep;
        abot = (clienttype(attacker) == CLIENTTYPE_BOT);
                if(valid_damage_for_weaponstats)
                        WeaponStats_LogKill(awep, abot, self.weapon, vbot);
  
 -              if(sv_gentle < 1) // TODO make a "gentle" version?
 +              if(autocvar_sv_gentle < 1) // TODO make a "gentle" version?
                if(sound_allowed(MSG_BROADCAST, attacker))
                {
                        if(deathtype == DEATH_DROWN)
                // set up to fade out later
                SUB_SetFade (self, time + 6 + random (), 1);
  
 -              if(sv_gentle > 0 || autocvar_ekg) {
 +              if(autocvar_sv_gentle > 0 || autocvar_ekg) {
                        // remove corpse
                        PlayerCorpseDamage (inflictor, attacker, autocvar_sv_gibhealth+1.0, deathtype, hitloc, force);
                }
@@@ -1023,18 -1026,17 +1026,18 @@@ float Say(entity source, float teamsay
                        if(sourcecmsgstr != "" && !privatesay)
                                centerprint(source, sourcecmsgstr);
                }
 -              else if(privatesay) // private message, between 2 people only, not sent to server console
 +              else if(privatesay) // private message, between 2 people only
                {
                        sprint(source, sourcemsgstr);
                        sprint(privatesay, msgstr);
 +                      if not(autocvar_g_chat_tellprivacy) { dedicated_print(msgstr); } // send to server console too if "tellprivacy" is disabled
                        if(cmsgstr != "")
                                centerprint(privatesay, cmsgstr);
                }
                else if(teamsay > 0) // team message, only sent to team mates
                {
                        sprint(source, sourcemsgstr);
 -                      //print(msgstr); // send to server console too
 +                      dedicated_print(msgstr); // send to server console too
                        if(sourcecmsgstr != "")
                                centerprint(source, sourcecmsgstr);
                        FOR_EACH_REALPLAYER(head) if(head.team == source.team)
                else if(teamsay < 0) // spectator message, only sent to spectators
                {
                        sprint(source, sourcemsgstr);
 -                      //print(msgstr); // send to server console too
 +                      dedicated_print(msgstr); // send to server console too
                        FOR_EACH_REALCLIENT(head) if(head.classname != "player")
                                if(head != source)
                                        sprint(head, msgstr);
                else if(sourcemsgstr != msgstr) // trimmed/server fixed message, sent to all players
                {
                        sprint(source, sourcemsgstr);
 -                      //print(msgstr); // send to server console too
 +                      dedicated_print(msgstr); // send to server console too
                        FOR_EACH_REALCLIENT(head)
                                if(head != source)
                                        sprint(head, msgstr);
@@@ -1238,7 -1240,7 +1241,7 @@@ void FakeGlobalSound(string sample, flo
                                break;
                        if(!sv_taunt)
                                break;
 -                      if(sv_gentle)
 +                      if(autocvar_sv_gentle)
                                break;
                        tauntrand = random();
                        msg_entity = self;
                                        setanim(self, self.anim_taunt, FALSE, TRUE, TRUE);
                        if(!sv_taunt)
                                break;
 -                      if(sv_gentle)
 +                      if(autocvar_sv_gentle)
                                break;
                        msg_entity = self;
                        if (msg_entity.cvar_cl_voice_directional >= 1)
@@@ -1335,7 -1337,7 +1338,7 @@@ void GlobalSound(string sample, float c
                                break;
                        if(!sv_taunt)
                                break;
 -                      if(sv_gentle)
 +                      if(autocvar_sv_gentle)
                                break;
                        tauntrand = random();
                        FOR_EACH_REALCLIENT(msg_entity)
                                        setanim(self, self.anim_taunt, FALSE, TRUE, TRUE);
                        if(!sv_taunt)
                                break;
 -                      if(sv_gentle)
 +                      if(autocvar_sv_gentle)
                                break;
                        FOR_EACH_REALCLIENT(msg_entity)
                        {
@@@ -1417,15 -1419,14 +1420,15 @@@ void MoveToTeam(entity client, float te
  
        TeamchangeFrags(client);  // move the players frags
        SetPlayerColors(client, team_colour - 1);  // set the players colour
 -      Damage(client, client, client, 100000, ((show_message & 2) ? DEATH_QUIET : DEATH_AUTOTEAMCHANGE), client.origin, '0 0 0');  // kill the player
 +      Damage(client, client, client, 100000, DEATH_AUTOTEAMCHANGE, client.origin, '0 0 0');  // kill the player
  
        lockteams = lockteams_backup;  // restore the team lock
  
        LogTeamchange(client.playerid, client.team, type);
  
 +      // TODO FIXME FIXNOTIF
        if not(show_message & 1) // admin message
 -              sprint(client, strcat("\{1}\{13}^3", admin_name(), "^7: You have been moved to the ", Team_ColorNameLowerCase(team_colour), " team\n"));  // send a chat message
 +              sprint(client, strcat("\{1}\{13}^3", admin_name(), "^7: You have been moved to the ", Team_ColorName_Lower(team_colour), " team\n"));  // send a chat message
  
 -      bprint(strcat(client.netname, " joined the ", ColoredTeamName(client.team), "\n"));
 +      bprint(strcat(client.netname, " joined the ", Team_ColoredFullName(client.team), "\n"));
  }
diff --combined qcsrc/server/defs.qh
index 6b3b734ed8580b3ab63d216399a997da850f076a,d7772e5090d0fda499eb14eee8f3544b298bf007..ad932130049c712f16c82643f5aae3bc218c5435
@@@ -39,6 -39,7 +39,6 @@@ float g_pickup_respawntimejitter_poweru
  float g_jetpack;
  
  float sv_clones;
 -float sv_gentle;
  float sv_foginterval;
  
  entity        activator;
@@@ -57,8 -58,6 +57,8 @@@ float team1_score, team2_score, team3_s
  
  float maxclients;
  
 +float server_is_local; // innocent until proven guilty by ClientConnect() in cl_client.qc
 +
  // Fields
  
  .void(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) event_damage;
@@@ -648,6 -647,8 +648,8 @@@ float serverflags
  .entity muzzle_flash;
  .float misc_bulletcounter;    // replaces uzi & hlac bullet counter.
  
+ .float stat_respawn_time; // shows respawn time, and is negative when awaiting respawn
  void PlayerUseKey();
  
  typedef vector(entity player, entity spot, vector current) spawn_evalfunc_t;
diff --combined qcsrc/server/g_damage.qc
index 72d66d60240d425b10b4c8f97498fd9d2542dba7,1e7d2815d501af4bc8bb9d1df2177e7b13bbbcdb..d2cc9f4643867fdea74e18075c2362476ca6dc4b
@@@ -297,7 -297,7 +297,7 @@@ void LogDeath(string mode, float deatht
        s = strcat(":kill:", mode);
        s = strcat(s, ":", ftos(killer.playerid));
        s = strcat(s, ":", ftos(killed.playerid));
 -      s = strcat(s, ":type=", ftos(deathtype));
 +      s = strcat(s, ":type=", Deathtype_Name(deathtype));
        s = strcat(s, ":items=");
        s = AppendItemcodes(s, killer);
        if(killed != killer)
        GameLogEcho(s);
  }
  
 -void Send_KillNotification (string s1, string s2, string s3, float msg, float type)
 +void Obituary_SpecialDeath(entity notif_target, float murder, float deathtype, string s1, string s2, float f1, float f2, float f3)
  {
 -      WriteByte(MSG_ALL, SVC_TEMPENTITY);
 -      WriteByte(MSG_ALL, TE_CSQC_KILLNOTIFY);
 -      WriteString(MSG_ALL, s1);
 -      WriteString(MSG_ALL, s2);
 -      WriteString(MSG_ALL, s3);
 -      WriteShort(MSG_ALL, msg);
 -      WriteByte(MSG_ALL, type);
 +      float handled, hits;
 +      if(DEATH_ISSPECIAL(deathtype))
 +      {
 +              #define DEATHTYPE(name,msg_death_by,msg_death,position) \
 +                      { if(deathtype == max(0, name)) \
 +                      { \
 +                              #if murder \
 +                                      if(max(0, msg_death_by)) { Send_Notification(notif_target, MSG_ONE, MSG_DEATH, msg_death_by, s1, s2, f1, f2, f3); ++handled; } \
 +                              #else \
 +                                      if(max(0, msg_death)) { Send_Notification(notif_target, MSG_ONE, MSG_DEATH, msg_death, s1, s2, f1, f2, f3); ++handled; } \
 +                              #endif \
 +                              ++hits; \
 +                      } }
 +
 +              DEATHTYPES
 +              #undef DEATHTYPE
 +              
 +              if not(hits)
 +              {
 +                      backtrace("Unhandled deathtype. Please notify Samual!\n");
 +                      //return;
 +              }
 +              if not(handled)
 +              {
 +                      print(sprintf("Obituary_SpecialDeath(): ^1Deathtype ^7(%s-%d)^1 has no notification!\n", Deathtype_Name(deathtype), deathtype));
 +                      return;
 +              }
 +      }
  }
  
 -// Function is used to send a generic centerprint whose content CSQC gets to decide (gentle version or not in the below cases)
 -void Send_CSQC_KillCenterprint(entity e, string s1, string s2, float msg, float type)
 +void Obituary_WeaponDeath(entity notif_target, float deathtype, string s1, string s2, float f1, float f2, float f3)
  {
 -      if (clienttype(e) == CLIENTTYPE_REAL)
 +      float handled, hits;
 +      if(DEATH_ISSPECIAL(deathtype))
        {
 -              msg_entity = e;
 -              WRITESPECTATABLE_MSG_ONE({
 -                      WriteByte(MSG_ONE, SVC_TEMPENTITY);
 -                      WriteByte(MSG_ONE, TE_CSQC_KILLCENTERPRINT);
 -                      WriteString(MSG_ONE, s1);
 -                      WriteString(MSG_ONE, s2);
 -                      WriteShort(MSG_ONE, msg);
 -                      WriteByte(MSG_ONE, type);
 -              });
 +              #define DEATHTYPE(name,msg_death_by,msg_death,position) \
 +                      { if(deathtype == max(0, name)) \
 +                      { \
 +                              ++hits; \
 +                      } }
 +
 +              DEATHTYPES
 +              #undef DEATHTYPE
 +              
 +              if not(hits)
 +              {
 +                      backtrace("Unhandled deathtype. Please notify Samual!\n");
 +                      //return;
 +              }
 +              if not(handled)
 +              {
 +                      print(sprintf("Obituary_SpecialDeath(): ^1Deathtype ^7(%s-%d)^1 has no notification!\n", Deathtype_Name(deathtype), deathtype));
 +                      return;
 +              }
        }
  }
  
 -void Obituary (entity attacker, entity inflictor, entity targ, float deathtype)
 +.float FRAG_VERBOSE;
 +
 +void Obituary(entity attacker, entity inflictor, entity targ, float deathtype)
  {
 +      // Sanity check
 +      if not(targ.classname == "player") { backtrace("Obituary called on non-player?!\n"); return; }
 +
 +      // Declarations
        string  s, a, msg;
        float w, type;
  
 -      if (targ.classname == "player")
 -      {
 -              s = targ.netname;
 -              a = attacker.netname;
 +      string s1, s2 = NO_STR_ARG;
 +      float f1, f2, f3 = NO_FL_ARG;
 +      float notif_firstblood;
 +
  
 -              if (targ == attacker) // suicides
 +      print(sprintf("Obituary(): Deathtype = %s (%d), Attacker = %s, Inflictor = %s, Target = %s...\n", Deathtype_Name(deathtype), deathtype, attacker.netname, inflictor.netname, targ.netname));
 +
 +
 +      // =======
 +      // SUICIDE
 +      // =======
 +      if(targ == attacker)
 +      {
 +              if(DEATH_ISSPECIAL(deathtype))
                {
 -                      if (deathtype == DEATH_TEAMCHANGE || deathtype == DEATH_AUTOTEAMCHANGE)
 -                              msg = ColoredTeamName(targ.team); // TODO: check if needed?
 +                      if(deathtype == DEATH_TEAMCHANGE || deathtype == DEATH_AUTOTEAMCHANGE)
 +                      {
 +                              s1 = targ.netname;
 +                              f1 = targ.team;
 +                      }
                        else
 -                              msg = "";
 -            if(!g_cts) // no "killed your own dumb self" message in CTS
 -                Send_CSQC_KillCenterprint(targ, msg, "", deathtype, MSG_SUICIDE);
 -
 -                      if(deathtype != DEATH_TEAMCHANGE && deathtype != DEATH_QUIET)
                        {
 +                              switch(deathtype)
 +                              {
 +                                      case DEATH_MIRRORDAMAGE:
 +                                      {
 +                                              s1 = targ.netname;
 +                                              f1 = targ.team;
 +                                              //f2 = targ.killcount;
 +                                              break;
 +                                      }
 +                                      
 +                                      default:
 +                                      {
 +                                              s1 = s2 = NO_STR_ARG;
 +                                              f1 = f2 = f3 = NO_FL_ARG;
 +                                              break;
 +                                      }
 +                              }
                                LogDeath("suicide", deathtype, targ, targ);
                                GiveFrags(attacker, targ, -1, deathtype);
                        }
 +                      Obituary_SpecialDeath(targ, FALSE, deathtype, s1, s2, f1, f2, NO_FL_ARG);
 +              }
 +              else if(DEATH_WEAPONOF(deathtype))
 +              {
 +                      print("death was a weapon!\n");
 +              }
 +              else
 +              {
 +                      backtrace("what the hell happened here?\n");
 +              }
 +      }
 +
  
 -                      if (targ.killcount > 2)
 -                              msg = ftos(targ.killcount);
 +      // ======
 +      // MURDER
 +      // ======
 +      else if(attacker.classname == "player")
 +      {
 +              if(!IsDifferentTeam(attacker, targ))
 +              {
 +                      if(DEATH_ISSPECIAL(deathtype))
 +                      {
 +                              backtrace("hmm death was special?\n");
 +                      }
 +                      else if(DEATH_WEAPONOF(deathtype))
 +                      {
 +                              print("death was a weapon!\n");
 +                      }
                        else
 -                              msg = "";
 -                      if(teamplay && deathtype == DEATH_MIRRORDAMAGE)
                        {
 -                              if(attacker.team == COLOR_TEAM1)
 -                                      deathtype = KILL_TEAM_RED;
 -                              else
 -                                      deathtype = KILL_TEAM_BLUE;
 +                              backtrace("what the hell happened here?\n");
                        }
 -
 -                      Send_KillNotification(s, msg, ftos(w), deathtype, MSG_SUICIDE);
 +                      
 +                      LogDeath("tk", deathtype, attacker, targ);
 +                      GiveFrags(attacker, targ, -1, deathtype);
                }
 -              else if (attacker.classname == "player")
 +              else
                {
 -                      if(!IsDifferentTeam(attacker, targ))
 -                      {
 -                              if(attacker.team == COLOR_TEAM1)
 -                                      type = KILL_TEAM_RED;
 -                              else
 -                                      type = KILL_TEAM_BLUE;
 -
 -                              GiveFrags(attacker, targ, -1, deathtype);
 +                      s1 = attacker.netname;
 +                      s2 = targ.netname;
  
 -                              Send_CSQC_KillCenterprint(attacker, s, "", type, MSG_KILL);
 +                      attacker.FRAG_VERBOSE = TRUE;
 +                      targ.FRAG_VERBOSE = TRUE;
  
 -                              if (targ.killcount > 2)
 -                                      msg = ftos(targ.killcount);
 -                              else
 -                                      msg = "";
 +                      LogDeath("frag", deathtype, attacker, targ);
 +                      GiveFrags(attacker, targ, 1, deathtype);
  
 -                              if (attacker.killcount > 2) {
 -                                      msg = ftos(attacker.killcount);
 -                                      type = KILL_TEAM_SPREE;
 +                      attacker.taunt_soundtime = time + 1;
 +                      attacker.killcount = attacker.killcount + 1;
 +                      if(targ.killcount > 2) { Send_KillNotification(s, ftos(targ.killcount), a, KILL_END_SPREE, MSG_SPREE); }
 +                      
 +                      #define ADD_ACHIEVEMENT_CASE(numa,numb) \
 +                              case numa: \
 +                              { \
 +                                      AnnounceTo(attacker, strcat(#numb, "kills")); \
 +                                      PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_##numa, 1); \
 +                                      break; \
                                }
 -                              Send_KillNotification(a, s, msg, type, MSG_KILL);
 -
 -                              attacker.killcount = 0;
 +                      switch(attacker.killcount)
 +                      {
 +                              ADD_ACHIEVEMENT_CASE(3, 03)
 +                              ADD_ACHIEVEMENT_CASE(5, 05)
 +                              ADD_ACHIEVEMENT_CASE(10, 10)
 +                              ADD_ACHIEVEMENT_CASE(15, 15)
 +                              ADD_ACHIEVEMENT_CASE(20, 20)
 +                              ADD_ACHIEVEMENT_CASE(25, 25)
 +                              ADD_ACHIEVEMENT_CASE(30, 30)
 +                              default: break;
 +                      }
 +                      #undef ADD_ACHIEVEMENT_CASE
  
 -                              LogDeath("tk", deathtype, attacker, targ);
 +                      if(!checkrules_firstblood)
 +                      {
 +                              checkrules_firstblood = TRUE;
 +                              notif_firstblood = TRUE; // modify the current messages so that they too show firstblood information
 +                              PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_FIRSTBLOOD, 1);
 +                              PlayerStats_Event(targ, PLAYERSTATS_ACHIEVEMENT_FIRSTVICTIM, 1);
                        }
 -                      else
 +
 +                      if(notif_firstblood) // first blood, no kill sprees yet
                        {
 -                              if (!checkrules_firstblood)
 +                              if(targ.istypefrag)
                                {
 -                                      checkrules_firstblood = TRUE;
 -                                      Send_KillNotification(a, "", "", KILL_FIRST_BLOOD, MSG_KILL);
 -                                      // TODO: make these print a newline if they dont
 -                                      Send_CSQC_KillCenterprint(attacker, "", "", KILL_FIRST_BLOOD, MSG_KILL);
 -                                      Send_CSQC_KillCenterprint(targ, "", "", KILL_FIRST_VICTIM, MSG_KILL);
 -                                      PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_FIRSTBLOOD, 1);
 -                                      PlayerStats_Event(targ, PLAYERSTATS_ACHIEVEMENT_FIRSTVICTIM, 1);
 +                                      Send_Notification(attacker, MSG_ONE, MSG_DEATH, (attacker.FRAG_VERBOSE ? DEATH_MURDER_TYPEFRAG_FIRST_VERBOSE : DEATH_MURDER_TYPEFRAG_FIRST),
 +                                              s2, NO_STR_ARG, (attacker.FRAG_VERBOSE ? ((clienttype(targ) == CLIENTTYPE_BOT) ? BOT_PING : targ.ping) : NO_FL_ARG), NO_FL_ARG, NO_FL_ARG);
 +                                              
 +                                      Send_Notification(targ, MSG_ONE, MSG_DEATH, (targ.FRAG_VERBOSE ? DEATH_MURDER_TYPEFRAGGED_FIRST_VERBOSE : DEATH_MURDER_TYPEFRAGGED_FIRST),
 +                                              s1, NO_STR_ARG, (targ.FRAG_VERBOSE ? attacker.health : NO_FL_ARG), (targ.FRAG_VERBOSE ? attacker.armorvalue : NO_FL_ARG), (targ.FRAG_VERBOSE ? ((clienttype(attacker) == CLIENTTYPE_BOT) ? BOT_PING : attacker.ping) : NO_FL_ARG));
                                }
 -
 -                              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 {
 -                                      Send_CSQC_KillCenterprint(attacker, s, Obituary_ExtraFragInfo(targ), KILL_FRAG, MSG_KILL);
 -                                      Send_CSQC_KillCenterprint(targ, a, Obituary_ExtraFragInfo(attacker), KILL_FRAGGED, MSG_KILL);
 -                              }
 -
 -                              attacker.taunt_soundtime = time + 1;
 -
 -                              if (deathtype == DEATH_HURTTRIGGER && inflictor.message2 != "")
 -                                      msg = inflictor.message2;
 -                              else if (deathtype == DEATH_CUSTOM)
 -                                      msg = deathmessage;
                                else
 -                                      msg = "";
 -
 -                              if(strstrofs(msg, "%", 0) < 0)
 -                                      msg = strcat("%s ", msg, " by %s");
 -
 -                              Send_KillNotification(a, s, msg, deathtype, MSG_KILL);
 -
 -                              GiveFrags(attacker, targ, 1, deathtype);
 -
 -                              if (targ.killcount > 2) {
 -                                      Send_KillNotification(s, ftos(targ.killcount), a, KILL_END_SPREE, MSG_SPREE);
 -                              }
 -
 -                              attacker.killcount = attacker.killcount + 1;
 -
 -                              if (attacker.killcount == 3)
                                {
 -                                      Send_KillNotification(a, "", "", KILL_SPREE_3, MSG_SPREE);
 -                                      AnnounceTo(attacker, "03kills");
 -                                      PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_3, 1);
 +                                      Send_Notification(attacker, MSG_ONE, MSG_DEATH, (attacker.FRAG_VERBOSE ? DEATH_MURDER_FRAG_FIRST_VERBOSE : DEATH_MURDER_FRAG_FIRST),
 +                                              s2, NO_STR_ARG, (attacker.FRAG_VERBOSE ? ((clienttype(targ) == CLIENTTYPE_BOT) ? BOT_PING : targ.ping) : NO_FL_ARG), NO_FL_ARG, NO_FL_ARG);
 +                                              
 +                                      Send_Notification(targ, MSG_ONE, MSG_DEATH, (targ.FRAG_VERBOSE ? DEATH_MURDER_FRAGGED_FIRST_VERBOSE : DEATH_MURDER_FRAGGED_FIRST),
 +                                              s1, NO_STR_ARG, (targ.FRAG_VERBOSE ? attacker.health : NO_FL_ARG), (targ.FRAG_VERBOSE ? attacker.armorvalue : NO_FL_ARG), (targ.FRAG_VERBOSE ? ((clienttype(attacker) == CLIENTTYPE_BOT) ? BOT_PING : attacker.ping) : NO_FL_ARG));
                                }
 -                              else if (attacker.killcount == 5)
 -                              {
 -                                      Send_KillNotification(a, "", "", KILL_SPREE_5, MSG_SPREE);
 -                                      AnnounceTo(attacker, "05kills");
 -                                      PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_5, 1);
 -                              }
 -                              else if (attacker.killcount == 10)
 -                              {
 -                                      Send_KillNotification(a, "", "", KILL_SPREE_10, MSG_SPREE);
 -                                      AnnounceTo(attacker, "10kills");
 -                                      PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_10, 1);
 -                              }
 -                              else if (attacker.killcount == 15)
 -                              {
 -                                      Send_KillNotification(a, "", "", KILL_SPREE_15, MSG_SPREE);
 -                                      AnnounceTo(attacker, "15kills");
 -                                      PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_15, 1);
 -                              }
 -                              else if (attacker.killcount == 20)
 -                              {
 -                                      Send_KillNotification(a, "", "", KILL_SPREE_20, MSG_SPREE);
 -                                      AnnounceTo(attacker, "20kills");
 -                                      PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_20, 1);
 -                              }
 -                              else if (attacker.killcount == 25)
 +                              //Send_Notification(world, MSG_INFO, INFO_DEATH_FRAG_FIRSTBLOOD, s1, s2, attacker.team, NO_FL_ARG, NO_FL_ARG);
 +                      }
 +                      else // normal frags, kill sprees listed
 +                      {
 +                              if(targ.istypefrag)
                                {
 -                                      Send_KillNotification(a, "", "", KILL_SPREE_25, MSG_SPREE);
 -                                      AnnounceTo(attacker, "25kills");
 -                                      PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_KILL_SPREE_25, 1);
 +                                      Send_Notification(attacker, MSG_ONE, MSG_DEATH, (attacker.FRAG_VERBOSE ? DEATH_MURDER_TYPEFRAG_VERBOSE : DEATH_MURDER_TYPEFRAG),
 +                                              s2, NO_STR_ARG, attacker.killcount, (attacker.FRAG_VERBOSE ? ((clienttype(targ) == CLIENTTYPE_BOT) ? BOT_PING : targ.ping) : NO_FL_ARG), NO_FL_ARG);
 +                                              
 +                                      Send_Notification(targ, MSG_ONE, MSG_DEATH, (targ.FRAG_VERBOSE ? DEATH_MURDER_TYPEFRAGGED_VERBOSE : DEATH_MURDER_TYPEFRAGGED),
 +                                              s1, NO_STR_ARG, (targ.FRAG_VERBOSE ? attacker.health : NO_FL_ARG), (targ.FRAG_VERBOSE ? attacker.armorvalue : NO_FL_ARG), (targ.FRAG_VERBOSE ? ((clienttype(attacker) == CLIENTTYPE_BOT) ? BOT_PING : attacker.ping) : NO_FL_ARG));
                                }
 -                              else if (attacker.killcount == 30)
 +                              else
                                {
 -                                      Send_KillNotification(a, "", "", KILL_SPREE_30, MSG_SPREE);
 -                                      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);
 +                                      Send_Notification(attacker, MSG_ONE, MSG_DEATH, (attacker.FRAG_VERBOSE ? DEATH_MURDER_FRAG_VERBOSE : DEATH_MURDER_FRAG),
 +                                              s2, NO_STR_ARG, attacker.killcount, (attacker.FRAG_VERBOSE ? ((clienttype(targ) == CLIENTTYPE_BOT) ? BOT_PING : targ.ping) : NO_FL_ARG), NO_FL_ARG);
 +                                              
 +                                      Send_Notification(targ, MSG_ONE, MSG_DEATH, (targ.FRAG_VERBOSE ? DEATH_MURDER_FRAGGED_VERBOSE : DEATH_MURDER_FRAGGED),
 +                                              s1, NO_STR_ARG, (targ.FRAG_VERBOSE ? attacker.health : NO_FL_ARG), (targ.FRAG_VERBOSE ? attacker.armorvalue : NO_FL_ARG), (targ.FRAG_VERBOSE ? ((clienttype(attacker) == CLIENTTYPE_BOT) ? BOT_PING : attacker.ping) : NO_FL_ARG));
                                }
 -                              LogDeath("frag", deathtype, attacker, targ);
 +                              //if(DEATH_WEAPONOF(deathtype)) { Send_Notification(world, MSG_WEAPON, 50, s1, s2, attacker.killcount, targ.killcount, Obituary_Score_Position); }
 +                              //else { Obituary_SpecialDeath(world, deathtype, s1, s2, attacker.killcount, targ.killcount, Obituary_Score_Position); }
                        }
                }
 -              else
 -              {
 -                      Send_CSQC_KillCenterprint(targ, "", "", deathtype, MSG_KILL_ACTION);
 -                      if (deathtype == DEATH_HURTTRIGGER && inflictor.message != "")
 -                              msg = inflictor.message;
 -                      else if (deathtype == DEATH_CUSTOM)
 -                              msg = deathmessage;
 -                      else
 -                              msg = "";
 -                      if(strstrofs(msg, "%", 0) < 0)
 -                              msg = strcat("%s ", msg);
 -
 -                      GiveFrags(targ, targ, -1, deathtype);
 -                      if(PlayerScore_Add(targ, SP_SCORE, 0) == -5) {
 -                              AnnounceTo(targ, "botlike");
 -                              PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_BOTLIKE, 1);
 -                      }
 -                      Send_KillNotification(s, msg, "", deathtype, MSG_KILL_ACTION);
 +      }
  
 -                      if (targ.killcount > 2)
 -                              Send_KillNotification(s, ftos(targ.killcount), "", 0, MSG_KILL_ACTION_SPREE);
 +      // =============
 +      // ACCIDENT/TRAP
 +      // =============
 +      else
 +      {
 +              if (deathtype == DEATH_HURTTRIGGER && inflictor.message != "")
 +                      msg = inflictor.message;
 +              else if (deathtype == DEATH_CUSTOM)
 +                      msg = deathmessage;
 +              else
 +                      msg = "";
 +                      
 +              if(strstrofs(msg, "%", 0) < 0) { msg = strcat("%s ", msg); }
  
 -                      LogDeath("accident", deathtype, targ, targ);
 +              LogDeath("accident", deathtype, targ, targ);
 +              GiveFrags(targ, targ, -1, deathtype);
 +              if(PlayerScore_Add(targ, SP_SCORE, 0) == -5) {
 +                      AnnounceTo(targ, "botlike");
 +                      PlayerStats_Event(attacker, PLAYERSTATS_ACHIEVEMENT_BOTLIKE, 1);
                }
 +              //Send_KillNotification(s, msg, "", deathtype, MSG_KILL_ACTION);
  
 -              targ.death_origin = targ.origin;
 -              if(targ != attacker)
 -                      targ.killer_origin = attacker.origin;
 +              //if (targ.killcount > 2)
 +              //      Send_KillNotification(s, ftos(targ.killcount), "", 0, MSG_KILL_ACTION_SPREE);
  
 -              // FIXME: this should go in PutClientInServer
 -              if (targ.killcount)
 -                      targ.killcount = 0;
 +              Obituary_SpecialDeath(targ, FALSE, deathtype, s1, s2, f1, f2, NO_FL_ARG);
        }
 +
 +      targ.death_origin = targ.origin;
 +      if(targ != attacker)
 +              targ.killer_origin = attacker.origin;
 +
 +      // FIXME: this should go in PutClientInServer
 +      if (targ.killcount)
 +              targ.killcount = 0;
  }
  
  // these are updated by each Damage call for use in button triggering and such
@@@ -622,7 -571,7 +622,7 @@@ void Damage (entity targ, entity inflic
                        }
        }
  
 -      if(deathtype == DEATH_KILL || deathtype == DEATH_TEAMCHANGE || deathtype == DEATH_AUTOTEAMCHANGE || deathtype == DEATH_QUIET)
 +      if(deathtype == DEATH_KILL || deathtype == DEATH_TEAMCHANGE || deathtype == DEATH_AUTOTEAMCHANGE)
        {
                // These are ALWAYS lethal
                // No damage modification here
                                                        if(deathtype & HITTYPE_HEADSHOT)
                                                                headshot = 1;
                                                }
-                                               if(g_ca)
-                                                       PlayerScore_Add(attacker, SP_SCORE, damage * autocvar_g_ca_damage2score_multiplier);
                                        }
                                }
                                else
diff --combined qcsrc/server/g_world.qc
index b5ae693cb867c9affaf896ecd7e6f95cd71f5eec,69bf57d51b4af98e37a6f79e55d45cdc4cffe841..dfef41e7bd1e79c71021336e3cd473bee3652a66
@@@ -553,8 -553,6 +553,8 @@@ void spawnfunc___init_dedicated_server(
        // needs to be done so early because of the constants they create
        CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
        CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
 +      CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
 +      CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
  
        MapInfo_Enumerate();
        MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
@@@ -601,8 -599,6 +601,8 @@@ void spawnfunc_worldspawn (void
        // needs to be done so early because of the constants they create
        CALL_ACCUMULATED_FUNCTION(RegisterWeapons);
        CALL_ACCUMULATED_FUNCTION(RegisterGametypes);
 +      CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
 +      CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
  
        ServerProgsDB = db_load(strcat("server.db", autocvar_sessionid));
  
        // secrets
        addstat(STAT_SECRETS_TOTAL, AS_FLOAT, stat_secrets_total);
        addstat(STAT_SECRETS_FOUND, AS_FLOAT, stat_secrets_found);
+       // misc
+       addstat(STAT_RESPAWN_TIME, AS_FLOAT, stat_respawn_time);
        
        next_pingtime = time + 5;
  
@@@ -1758,10 -1757,10 +1761,10 @@@ float WinningCondition_Onslaught(
        {
                if (head.health > 0)
                {
 -                      if (head.team == COLOR_TEAM1) t1 = 1;
 -                      if (head.team == COLOR_TEAM2) t2 = 1;
 -                      if (head.team == COLOR_TEAM3) t3 = 1;
 -                      if (head.team == COLOR_TEAM4) t4 = 1;
 +                      if (head.team == FL_TEAM_1) t1 = 1;
 +                      if (head.team == FL_TEAM_2) t2 = 1;
 +                      if (head.team == FL_TEAM_3) t3 = 1;
 +                      if (head.team == FL_TEAM_4) t4 = 1;
                }
                head = find(head, classname, "onslaught_generator");
        }
        {
                // game over, only one team remains (or none)
                ClearWinners();
 -              if (t1) SetWinners(team, COLOR_TEAM1);
 -              if (t2) SetWinners(team, COLOR_TEAM2);
 -              if (t3) SetWinners(team, COLOR_TEAM3);
 -              if (t4) SetWinners(team, COLOR_TEAM4);
 +              if (t1) SetWinners(team, FL_TEAM_1);
 +              if (t2) SetWinners(team, FL_TEAM_2);
 +              if (t3) SetWinners(team, FL_TEAM_3);
 +              if (t4) SetWinners(team, FL_TEAM_4);
                dprint("Have a winner, ending game.\n");
                return WINNING_YES;
        }
@@@ -1810,13 -1809,13 +1813,13 @@@ float WinningCondition_Assault(
  
        status = WINNING_NO;
        // as the timelimit has not yet passed just assume the defending team will win
 -      if(assault_attacker_team == COLOR_TEAM1)
 +      if(assault_attacker_team == FL_TEAM_1)
        {
 -              SetWinners(team, COLOR_TEAM2);
 +              SetWinners(team, FL_TEAM_2);
        }
        else
        {
 -              SetWinners(team, COLOR_TEAM1);
 +              SetWinners(team, FL_TEAM_1);
        }
  
        entity ent;
@@@ -1942,10 -1941,10 +1945,10 @@@ float WinningCondition_Scores(float lim
  
        if(teamplay)
        {
 -              team1_score = TeamScore_GetCompareValue(COLOR_TEAM1);
 -              team2_score = TeamScore_GetCompareValue(COLOR_TEAM2);
 -              team3_score = TeamScore_GetCompareValue(COLOR_TEAM3);
 -              team4_score = TeamScore_GetCompareValue(COLOR_TEAM4);
 +              team1_score = TeamScore_GetCompareValue(FL_TEAM_1);
 +              team2_score = TeamScore_GetCompareValue(FL_TEAM_2);
 +              team3_score = TeamScore_GetCompareValue(FL_TEAM_3);
 +              team4_score = TeamScore_GetCompareValue(FL_TEAM_4);
        }
  
        ClearWinners();
@@@ -2062,25 -2061,25 +2065,25 @@@ float WinningCondition_RanOutOfSpawns(
  
        FOR_EACH_PLAYER(head) if(head.deadflag == DEAD_NO)
        {
 -              if(head.team == COLOR_TEAM1)
 +              if(head.team == FL_TEAM_1)
                        team1_score = 1;
 -              else if(head.team == COLOR_TEAM2)
 +              else if(head.team == FL_TEAM_2)
                        team2_score = 1;
 -              else if(head.team == COLOR_TEAM3)
 +              else if(head.team == FL_TEAM_3)
                        team3_score = 1;
 -              else if(head.team == COLOR_TEAM4)
 +              else if(head.team == FL_TEAM_4)
                        team4_score = 1;
        }
  
        for(head = world; (head = find(head, classname, "info_player_deathmatch")) != world; )
        {
 -              if(head.team == COLOR_TEAM1)
 +              if(head.team == FL_TEAM_1)
                        team1_score = 1;
 -              else if(head.team == COLOR_TEAM2)
 +              else if(head.team == FL_TEAM_2)
                        team2_score = 1;
 -              else if(head.team == COLOR_TEAM3)
 +              else if(head.team == FL_TEAM_3)
                        team3_score = 1;
 -              else if(head.team == COLOR_TEAM4)
 +              else if(head.team == FL_TEAM_4)
                        team4_score = 1;
        }
  
        {
                float t, i;
                if(team1_score)
 -                      t = COLOR_TEAM1;
 +                      t = FL_TEAM_1;
                else if(team2_score)
 -                      t = COLOR_TEAM2;
 +                      t = FL_TEAM_2;
                else if(team3_score)
 -                      t = COLOR_TEAM3;
 +                      t = FL_TEAM_3;
                else // if(team4_score)
 -                      t = COLOR_TEAM4;
 +                      t = FL_TEAM_4;
                CheckAllowedTeams(world);
                for(i = 0; i < MAX_TEAMSCORE; ++i)
                {
 -                      if(t != COLOR_TEAM1) if(c1 >= 0) TeamScore_AddToTeam(COLOR_TEAM1, i, -1000);
 -                      if(t != COLOR_TEAM2) if(c2 >= 0) TeamScore_AddToTeam(COLOR_TEAM2, i, -1000);
 -                      if(t != COLOR_TEAM3) if(c3 >= 0) TeamScore_AddToTeam(COLOR_TEAM3, i, -1000);
 -                      if(t != COLOR_TEAM4) if(c4 >= 0) TeamScore_AddToTeam(COLOR_TEAM4, i, -1000);
 +                      if(t != FL_TEAM_1) if(c1 >= 0) TeamScore_AddToTeam(FL_TEAM_1, i, -1000);
 +                      if(t != FL_TEAM_2) if(c2 >= 0) TeamScore_AddToTeam(FL_TEAM_2, i, -1000);
 +                      if(t != FL_TEAM_3) if(c3 >= 0) TeamScore_AddToTeam(FL_TEAM_3, i, -1000);
 +                      if(t != FL_TEAM_4) if(c4 >= 0) TeamScore_AddToTeam(FL_TEAM_4, i, -1000);
                }
  
                AddWinners(team, t);