]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into LegendaryGuard/cyber
authorLegendaryGuard <rootuser999@gmail.com>
Wed, 5 Jan 2022 18:18:09 +0000 (19:18 +0100)
committerLegendaryGuard <rootuser999@gmail.com>
Wed, 5 Jan 2022 18:18:09 +0000 (19:18 +0100)
23 files changed:
1  2 
qcsrc/client/hud/panel/timer.qc
qcsrc/common/ent_cs.qc
qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc
qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qh
qcsrc/common/gamemodes/gamemode/freezetag/sv_freezetag.qc
qcsrc/common/replicate.qh
qcsrc/common/weapons/weapon/electro.qc
qcsrc/server/chat.qc
qcsrc/server/client.qc
qcsrc/server/command/cmd.qc
qcsrc/server/command/common.qc
qcsrc/server/command/sv_cmd.qc
qcsrc/server/command/vote.qc
qcsrc/server/command/vote.qh
qcsrc/server/items/items.qc
qcsrc/server/round_handler.qc
qcsrc/server/scores.qc
qcsrc/server/teamplay.qc
qcsrc/server/teamplay.qh
qcsrc/server/weapons/accuracy.qc
qcsrc/server/weapons/accuracy.qh
qcsrc/server/world.qc
qcsrc/server/world.qh

index a4877660235a9526094e9e8f3e320b6b9664c6b3,035d21b60d9c889e00209f19076631aafc5251e5..906e942ad2775912b47cd7cfb8a9cb47a563e465
@@@ -38,23 -36,14 +38,23 @@@ void HUD_Timer(
                mySize -= '2 2 0' * panel_bg_padding;
        }
  
 -      string timer;
 -      float timelimit, timeleft, minutesLeft;
 +      string timer_sub = "";
 +      float timelimit, timeleft, minutesLeft, overtimes, timeout_last;
  
        timelimit = STAT(TIMELIMIT);
 +      overtimes = STAT(OVERTIMESADDED);
 +      timeout_last = STAT(TIMEOUT_LAST);
  
-       timeleft = max(0, timelimit * 60 + STAT(GAMESTARTTIME) - time);
+       timeleft = bound(0, timelimit * 60 + STAT(GAMESTARTTIME) - time, timelimit * 60);
        timeleft = ceil(timeleft);
  
 +      // countdown sound
 +      if(autocvar_hud_panel_timer_count && timeleft > 0 && timeleft != last_timeleft && timeleft <= 10)
 +      {
 +              sound(NULL, CH_INFO, SND_ENDCOUNT, VOL_BASE, ATTN_NONE);
 +              last_timeleft = timeleft;
 +      }
 +
        minutesLeft = floor(timeleft / 60);
  
        float warmup_timeleft = 0;
Simple merge
index 446995d4f255c909bfad350ccae74b67bb7435d7,866a00419c36c0a2be08367f156c3b4c98d98cca..087d9b1bf45dd9c3259cedc74e0b14a7096b309f
@@@ -42,49 -40,8 +47,24 @@@ void CA_count_alive_players(
        });
  }
  
- int CA_GetWinnerTeam()
- {
-       int winner_team = 0;
-       if (Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(1)) >= 1)
-       {
-               winner_team = NUM_TEAM_1;
-       }
-       for (int i = 2; i <= NUM_TEAMS; ++i)
-       {
-               if (Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(i)) >= 1)
-               {
-                       if (winner_team != 0)
-                       {
-                               return 0;
-                       }
-                       winner_team = Team_IndexToTeam(i);
-               }
-       }
-       if (winner_team)
-       {
-               return winner_team;
-       }
-       return -1; // no player left
- }
  void nades_Clear(entity player);
  
 +entity ca_LastPlayer(float tm)
 +{
 +      entity last_pl = NULL;
 +      FOREACH_CLIENT(IS_PLAYER(it) && it.team == tm, {
 +              if (!IS_DEAD(it))
 +              {
 +                      if (!last_pl)
 +                              last_pl = it;
 +                      else
 +                              return NULL;
 +              }
 +      });
 +      return last_pl;
 +}
 +
 +
  float CA_CheckWinner()
  {
        if(round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0)
        }
  
        CA_count_alive_players();
-       if (Team_GetNumberOfAliveTeams() > 1)
-       {
+       int winner_team = Team_GetWinnerAliveTeam();
+       if (!winner_team)
                return 0;
-       }
--
-       int winner_team = CA_GetWinnerTeam();
++      
 +      bool perfect = false;
        if(winner_team > 0)
        {
 +              entity tm = Team_GetTeam(winner_team);
 +              entity last_pl = ca_LastPlayer(winner_team);
 +              
 +              if(last_pl && Team_GetNumberOfPlayers(tm) >= 3) {
 +                      Give_Medal(last_pl, DEFENSE);
 +              }
 +              
                Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, APP_TEAM_NUM(winner_team, CENTER_ROUND_TEAM_WIN));
                Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(winner_team, INFO_ROUND_TEAM_WIN));
 +              if(fragsleft > 1) Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, APP_TEAM_NUM(winner_team, ANNCE_ROUND_TEAM_WIN));
                TeamScore_AddToTeam(winner_team, ST_CA_ROUNDS, +1);
 +              
 +              if (Team_GetNumberOfPlayers(tm) >= 3 &&
 +                      Team_GetNumberOfAlivePlayers(tm) == Team_GetNumberOfPlayers(tm))
 +                              perfect = true;
        }
        else if(winner_team == -1)
        {
index 93e291b242c159e2d1fb980eebfe04f63f1a88c9,58fd90c897f15213ce6b686e9a5b402df00c19d6..fbf6cd451177608c22e9376b8aa69fec9903efbf
@@@ -140,23 -102,15 +120,21 @@@ bool freezetag_CheckWinner(
                return true;
        }
  
-       if (Team_GetNumberOfAliveTeams() > 1)
-       {
+       int winner_team = Team_GetWinnerAliveTeam();
+       if (!winner_team)
                return false;
-       }
  
-       int winner_team = freezetag_getWinnerTeam();
        if(winner_team > 0)
        {
 -              Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, APP_TEAM_NUM(winner_team, CENTER_ROUND_TEAM_WIN));
 -              Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(winner_team, INFO_ROUND_TEAM_WIN));
 +              entity last_pl = freezetag_LastPlayer(winner_team);
 +              if(last_pl) {
 +                      Give_Medal(last_pl, DEFENSE);
 +              }
 +      
 +              Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, APP_TEAM_NUM(winner_team, CENTER_ROUND_TEAM_SCORES));
 +              Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(winner_team, INFO_ROUND_TEAM_SCORES));
                TeamScore_AddToTeam(winner_team, ST_FT_ROUNDS, +1);
 +              if(fragsleft > 1) AnnounceScores(winner_team);
        }
        else if(winner_team == -1)
        {
Simple merge
index 82da61ff2d7a8a5d76fdad2346ba62d51ef0da3d,a73de2a1f6c58f2ed97e4303ae5179a7354b07db..33a2e406f286435fc6cf0997d50f713c36cbc5bd
@@@ -323,12 -315,10 +323,12 @@@ int Say(entity source, int teamsay, ent
                {
                        sprint(source, sourcemsgstr);
                        dedicated_print(msgstr); // send to server console too
-                       FOREACH_CLIENT(!(IS_PLAYER(it) || it.caplayer) && IS_REAL_CLIENT(it) && it != source && !MUTATOR_CALLHOOK(ChatMessageTo, it, source), {
+                       FOREACH_CLIENT(!(IS_PLAYER(it) || INGAME(it)) && IS_REAL_CLIENT(it) && it != source && !MUTATOR_CALLHOOK(ChatMessageTo, it, source), {
                                sprint(it, msgstr);
                        });
 -                      event_log_msg = sprintf(":chat_spec:%d:%s", source.playerid, strreplace("\n", " ", msgin));
 +                      
 +                      if(!play_chatsound(source, msgin))
 +                              event_log_msg = sprintf(":chat_spec:%d:%s", source.playerid, strreplace("\n", " ", msgin));
                }
                else
                {
Simple merge
index 961059738ebbb77c0df20769e5cc1c1dd91541cb,c9ceb31b6dc14cc09d4fe24c4d1a9446ec27cb97..17e237114b23c9451fa87371f01ea42843b9fc4d
@@@ -372,31 -372,17 +372,17 @@@ void ClientCommand_ready(entity caller
        {
                case CMD_REQUEST_COMMAND:
                {
 -                      if (IS_CLIENT(caller))
 +                      if (IS_CLIENT(caller) && caller.last_ready < time - 3) // anti-spam
                        {
-                               if (warmup_stage || autocvar_sv_ready_restart || g_race_qualifying == 2)
+                               if (warmup_stage || g_race_qualifying == 2)
                                {
-                                       if (!readyrestart_happened || autocvar_sv_ready_restart_repeatable)
+                                       if (time < game_starttime) // game is already restarting
+                                               return;
+                                       if (caller.ready)            // toggle
                                        {
-                                               if (time < game_starttime) // game is already restarting
-                                                       return;
-                                               if (caller.ready)            // toggle
-                                               {
-                                                       caller.ready = false;
-                                                       if(IS_PLAYER(caller) || caller.caplayer == 1)
-                                                               bprint("\{1}", playername(caller.netname, caller.team, false), "^2 is ^1NOT^2 ready\n");
-                                               }
-                                               else
-                                               {
-                                                       caller.ready = true;
-                                                       if(IS_PLAYER(caller) || caller.caplayer == 1)
-                                                               bprint("\{1}", playername(caller.netname, caller.team, false), "^2 is ready\n");
-                                               }
-                                               
-                                               caller.last_ready = time;
-                                               // cannot reset the game while a timeout is active!
-                                               if (!timeout_status) ReadyCount();
+                                               caller.ready = false;
+                                               if (IS_PLAYER(caller) || INGAME_JOINED(caller))
+                                                       bprint(playername(caller.netname, caller.team, false), "^2 is ^1NOT^2 ready\n");
                                        }
                                        else
                                        {
Simple merge
index 9b72f7a3fb81f6d660767656df6ffcf26db41800,ca6b268e23708a51b5fdb000e295fa4226512657..d2a143bada432a286b97186d0ac8143de647ceea
@@@ -1708,11 -1651,8 +1739,11 @@@ void GameCommand_(int request
  // ==================================
  
  // Do not hard code aliases for these, instead create them in commands.cfg... also: keep in alphabetical order, please ;)
 +SERVER_COMMAND(setflag, "Set client flag") { GameCommand_setflag(request, arguments); }
 +SERVER_COMMAND(teamname, "Set team name") { GameCommand_teamname(request, arguments); }
 +
  SERVER_COMMAND(adminmsg, "Send an admin message to a client directly") { GameCommand_adminmsg(request, arguments); }
- SERVER_COMMAND(allready, "Restart the server and reset the players") { GameCommand_allready(request); }
+ SERVER_COMMAND(allready, "Ends warmup and starts the match") { GameCommand_allready(request); }
  SERVER_COMMAND(allspec, "Force all players to spectate") { GameCommand_allspec(request, arguments); }
  SERVER_COMMAND(anticheat, "Create an anticheat report for a client") { GameCommand_anticheat(request, arguments); }
  SERVER_COMMAND(animbench, "Benchmark model animation (LAGS)") { GameCommand_animbench(request, arguments); }
index a179438ce20d77f590237145102bd9b67e1bfd5b,6b39ab7b6d90ffd4d4e8ea90a0dc5962d531af33..b5b97b00b03c1e5106d6d7be62ddc729e0d96780
@@@ -420,10 -414,8 +418,9 @@@ void reset_map(bool dorespawn, bool is_
  // Restarts the map after the countdown is over (and cvar sv_ready_restart_after_countdown is set)
  void ReadyRestart_think(entity this)
  {
-       restart_mapalreadyrestarted = true;
-       reset_map(true);
+       reset_map(true, false);
        Score_ClearAll();
 +      Inventory_ClearAll();
        delete(this);
  }
  
@@@ -449,22 -443,14 +448,17 @@@ void ReadyRestart_force(bool is_fake_ro
        FOREACH_CLIENT(IS_PLAYER(it), {
                it.alivetime = 0;
                CS(it).killcount = 0;
-               float val = PlayerStats_GameReport_Event_Player(it, PLAYERSTATS_ALIVETIME, 0);
-               PlayerStats_GameReport_Event_Player(it, PLAYERSTATS_ALIVETIME, -val);
        });
  
-       restart_mapalreadyrestarted = false; // reset this var, needed when cvar sv_ready_restart_repeatable is in use
-       // disable the warmup global for the server
-       if(warmup_stage)
+       // if we're ending the warmup stage call the corresponding hook
+       if(!is_fake_round_start && !warmup_stage)
                localcmd("\nsv_hook_warmupend\n");
-       warmup_stage = 0;                // once the game is restarted the game is in match stage
  
        // reset the .ready status of all players (also spectators)
 -      FOREACH_CLIENT(IS_REAL_CLIENT(it), { it.ready = false; });
 +      FOREACH_CLIENT(IS_REAL_CLIENT(it), {
 +              it.ready = false;
 +              Kill_Notification(NOTIF_ONE_ONLY, it, MSG_CENTER, CPID_MISSING_READY);
 +      });
        readycount = 0;
        Nagger_ReadyCounted();  // NOTE: this causes a resend of that entity, and will also turn off warmup state on the client
  
index 156021b8fb9fa87bd63afaa5ec44c64dbd80aab1,63c9e8e453765892bff4823cc41de0e7865e1453..355f241ef1b680f1d71138c0d93127e8b1a723eb
@@@ -70,10 -63,7 +70,8 @@@ void VoteCommand(int request, entity ca
  const float RESTART_COUNTDOWN = 10;
  entity nagger;
  float readycount;                  // amount of players who are ready
- float readyrestart_happened;       // keeps track of whether a restart has already happened
- float restart_mapalreadyrestarted; // bool, indicates whether reset_map() was already executed
  .float ready;                      // flag for if a player is ready
 +.float last_ready;                               // z411 time of the last readyup for anti-spam
  .int team_saved;                   // team number to restore upon map reset
  .void(entity this) reset;            // if set, an entity is reset using this
  .void(entity this) reset2;         // if set, an entity is reset using this (after calling ALL the reset functions for other entities)
Simple merge
Simple merge
Simple merge
index d27be8ad86b65a5d65ea3f0ff0ed6e1ba010be5c,0bc7e7cbb6707956066873d7ea95fdbfdabb7997..d21a33b0cbcfc7e3dae6141a518b6f946f574481
@@@ -103,16 -92,21 +103,31 @@@ void Team_SetNumberOfAlivePlayers(entit
        team_ent.m_num_players_alive = number;
  }
  
 +int Team_GetNumberOfPlayers(entity team_ent)
 +{
 +      return team_ent.m_num_players;
 +}
 +
 +void Team_SetNumberOfPlayers(entity team_ent, int number)
 +{
 +      team_ent.m_num_players = number;
 +}
 +
+ int Team_GetWinnerAliveTeam()
+ {
+       int winner = 0;
+       for (int i = 0; i < NUM_TEAMS; ++i)
+       {
+               if (g_team_entities[i].m_num_players_alive > 0)
+               {
+                       if (winner)
+                               return 0;
+                       winner = Team_IndexToTeam(i + 1);
+               }
+       }
+       return (winner ? winner : -1);
+ }
  int Team_GetNumberOfAliveTeams()
  {
        int result = 0;
index c8e6a5d18ae4b5de3cf95d9437c27234caac80d8,a94b247a8a64150d78ba6c1ca52200ff16b70350..8c67bb84fbf2cf05c9b19addc9e30b4290f46fb2
@@@ -51,8 -50,11 +51,12 @@@ int Team_GetNumberOfPlayers(entity team
  /// \param[in,out] team_ent Team entity.
  /// \param[in] number Number of players to set.
  void Team_SetNumberOfAlivePlayers(entity team_ent, int number);
 +void Team_SetNumberOfPlayers(entity team_ent, int number);
  
+ /// \brief Returns the winner team.
+ /// \return Winner team or 0 if 2 or more teams have alive players or -1 if no team has any alive players.
+ int Team_GetWinnerAliveTeam();
  /// \brief Returns the number of alive teams.
  /// \return Number of alive teams.
  int Team_GetNumberOfAliveTeams();
index 4482fc9fdbd2142cae8387a4df8c0286b37fa2ec,337ae54a98c86d4b889bb03da4b1cac0439116ee..8005506179bbae8ae813bfbe14fd819f5ed488e6
@@@ -71,9 -53,23 +71,24 @@@ void accuracy_init(entity e
  void accuracy_free(entity e)
  {
        delete(CS(e).accuracy);
 +      delete(e.roundaccuracy);
  }
  
+ void accuracy_reset(entity e)
+ {
+       entity a = CS(e).accuracy;
+       if (!a) return;
+       for (int i = 0; i < REGISTRY_MAX(Weapons); i++)
+       {
+               a.accuracy_frags[i] = 0;
+               a.accuracy_hit[i] = 0;
+               a.accuracy_fired[i] = 0;
+               a.accuracy_cnt_hit[i] = 0;
+               a.accuracy_cnt_fired[i] = 0;
+       }
+ }
  // force a resend of a player's accuracy stats
  void accuracy_resend(entity e)
  {
Simple merge
index 8a93d4169ba5461a77124b6986b792ce5edc37df,a438e633f61a71f7f47e89bd95bd6c93fe72f58b..65ee2b1a60c691623f2102f91e876f2db5c2b77e
@@@ -1448,52 -1405,10 +1456,52 @@@ void AddWinners(.float field, float val
  // clear the .winning flags
  void ClearWinners()
  {
-       FOREACH_CLIENT(IS_PLAYER(it), { it.winning = 0; });
+       FOREACH_CLIENT(IS_PLAYER(it) || INGAME(it), { it.winning = 0; });
  }
  
 -int fragsleft_last;
 +void AnnounceNewLeader()
 +{
 +      if(teamplay) {
 +              if (WinningConditionHelper_equality)
 +                      Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_TEAM_LEADS_TIED);
 +              else
 +                      FOREACH_CLIENT(IS_PLAYER(it), {
 +                              if(it.team == WinningConditionHelper_winnerteam)
 +                                      Send_Notification(NOTIF_ONE_ONLY, it, MSG_ANNCE, ANNCE_TEAM_LEADS_TEAM);
 +                              else
 +                                      Send_Notification(NOTIF_ONE_ONLY, it, MSG_ANNCE, ANNCE_TEAM_LEADS_ENEMY);
 +                      });
 +                      Send_Notification(NOTIF_ALL_SPEC, NULL, MSG_ANNCE, APP_TEAM_NUM(WinningConditionHelper_winnerteam, ANNCE_TEAM_LEADS));
 +      } else {
 +              if (WinningConditionHelper_equality)
 +              {
 +                      Send_Notification(NOTIF_ONE, WinningConditionHelper_equality_one, MSG_ANNCE, ANNCE_LEAD_TIED);
 +                      Send_Notification(NOTIF_ONE, WinningConditionHelper_equality_two, MSG_ANNCE, ANNCE_LEAD_TIED);
 +              }
 +              else
 +              {
 +                      Send_Notification(NOTIF_ONE, WinningConditionHelper_winner, MSG_ANNCE, ANNCE_LEAD_GAINED);
 +                      Send_Notification(NOTIF_ONE, WinningConditionHelper_second, MSG_ANNCE, ANNCE_LEAD_LOST);
 +              }
 +      }
 +}
 +
 +void AnnounceScores(float tm)
 +{
 +      WinningConditionHelper(NULL);
 +      if (Score_NewLeader()) {
 +              AnnounceNewLeader();
 +      } else {
 +              FOREACH_CLIENT(IS_PLAYER(it), {
 +                      if(it.team == tm)
 +                              Send_Notification(NOTIF_ONE_ONLY, it, MSG_ANNCE, ANNCE_TEAM_SCORES_TEAM);
 +                      else
 +                              Send_Notification(NOTIF_ONE_ONLY, it, MSG_ANNCE, ANNCE_TEAM_SCORES_ENEMY);
 +              });
 +              Send_Notification(NOTIF_ALL_SPEC, NULL, MSG_ANNCE, APP_TEAM_NUM(tm, ANNCE_TEAM_SCORES));
 +      }
 +}
 +
  float WinningCondition_Scores(float limit, float leadlimit)
  {
        // TODO make everything use THIS winning condition (except LMS)
Simple merge