From d15e0a4ba2f859a52d2fc5a5baec60e9cce4e8b0 Mon Sep 17 00:00:00 2001 From: Gurge44 Date: Mon, 9 Mar 2026 15:19:15 +0100 Subject: [PATCH] optimize KOTZ code --- Gamemodes/KingOfTheZones.cs | 71 ++++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 13 deletions(-) diff --git a/Gamemodes/KingOfTheZones.cs b/Gamemodes/KingOfTheZones.cs index dafce0950..4f6b7043b 100644 --- a/Gamemodes/KingOfTheZones.cs +++ b/Gamemodes/KingOfTheZones.cs @@ -694,6 +694,7 @@ public static class KingOfTheZones public static class FixedUpdatePatch { private static long LastUpdate; + private static readonly int TeamsEnumSize = Enum.GetNames(typeof(KOTZTeam)).Length; public static void Postfix() { @@ -719,7 +720,7 @@ public static class KingOfTheZones if (ZoneMoveSchedules.Count == 0) { - for (var index = 0; index < Zones.Count; index++) + for (int index = 0; index < Zones.Count; index++) { SystemTypes zone = Zones[index]; int timeFromNow = atOnce ? moveTime : (int)Math.Ceiling(timePart * (index + 1)); @@ -839,22 +840,66 @@ public static class KingOfTheZones try { - Dictionary> roomPlayersAndTeams = Zones.ToDictionary(x => x, x => Main.EnumerateAlivePlayerControls().ExceptBy(RespawnTimes.Keys, k => k.PlayerId).Where(k => k.IsInRoom(x)).GroupBy(k => PlayerTeams[k.PlayerId]).Select(k => (Team: k.Key, Length: k.Count())).OrderByDescending(k => k.Length).ToList()); + Dictionary zoneTeamCounts = new(Zones.Count); + + foreach (SystemTypes zone in Zones) + zoneTeamCounts[zone] = new int[TeamsEnumSize]; - foreach ((SystemTypes zone, List<(KOTZTeam Team, int Length)> teamPlayers) in roomPlayersAndTeams) + foreach (PlayerControl player in Main.EnumerateAlivePlayerControls()) { - ZoneDomination[zone] = ZoneDowntimeExpire.ContainsKey(zone) - ? KOTZTeam.None - : teamPlayers.Count switch - { - 0 => KOTZTeam.None, - 1 => teamPlayers[0].Team, - _ when teamPlayers[0].Length == teamPlayers[1].Length => KOTZTeam.None, - _ => teamPlayers[0].Team - }; + if (RespawnTimes.ContainsKey(player.PlayerId)) + continue; + + int team = (int)PlayerTeams[player.PlayerId]; + + foreach (SystemTypes zone in Zones) + { + if (player.IsInRoom(zone)) + zoneTeamCounts[zone][team]++; + } } - ZoneDomination.Values.DoIf(x => x != KOTZTeam.None, x => Points[x]++); + foreach (SystemTypes zone in Zones) + { + if (ZoneDowntimeExpire.ContainsKey(zone)) + { + ZoneDomination[zone] = KOTZTeam.None; + continue; + } + + int[] counts = zoneTeamCounts[zone]; + + int maxTeam = -1; + int max = 0; + int second = 0; + + for (int i = 0; i < counts.Length; i++) + { + int c = counts[i]; + + if (c > max) + { + second = max; + max = c; + maxTeam = i; + } + else if (c > second) + { + second = c; + } + } + + ZoneDomination[zone] = + max == 0 || max == second + ? KOTZTeam.None + : (KOTZTeam)maxTeam; + } + + foreach (KOTZTeam team in ZoneDomination.Values) + { + if (team != KOTZTeam.None) + Points[team]++; + } Logger.Info($"Zone domination: {string.Join(", ", ZoneDomination.Select(x => $"{x.Key} = {x.Value}"))}", "KOTZ"); }