diff --git a/Gamemodes/BedWars.cs b/Gamemodes/BedWars.cs
index 2f2a9d548..cb456ed7c 100644
--- a/Gamemodes/BedWars.cs
+++ b/Gamemodes/BedWars.cs
@@ -290,7 +290,7 @@ public static class BedWars
{
WinnerData = (team.GetColor(), team.GetName() + Translator.GetString("Win"));
CustomWinnerHolder.WinnerIds = Data.Where(x => x.Value.Team == team).Select(x => x.Key).ToHashSet();
- Logger.Info($"Winners: {team.GetName()} - {string.Join(", ", CustomWinnerHolder.WinnerIds.Select(id => Main.AllPlayerNames.GetValueOrDefault(id, string.Empty)))}", "BedWars");
+ Logger.Info($"Winners: {team.GetName()} - {CustomWinnerHolder.WinnerIds.Join(", ", id => Main.AllPlayerNames.GetValueOrDefault(id, string.Empty))}", "BedWars");
SendRPC();
return true;
}
diff --git a/Gamemodes/CustomHnS.cs b/Gamemodes/CustomHnS.cs
index fdd987217..486cdc4d1 100644
--- a/Gamemodes/CustomHnS.cs
+++ b/Gamemodes/CustomHnS.cs
@@ -346,34 +346,72 @@ internal static class CustomHnS
return targetRole.Interface.Team == Team.Impostor && (targetRole.Role != CustomRoles.Agent || seerRole.Interface.Team == Team.Impostor);
}
+ private static readonly StringBuilder TaskBarText = new();
+
public static string GetTaskBarText()
{
- string text = Main.PlayerStates.IntersectBy(PlayerRoles.Keys, x => x.Key).Aggregate("", (current, state) => $"{current}{GetStateText(state)}\n");
- return $"{text}\r\n\r\n<#00ffa5>{Translator.GetString("HNS.TaskCount")} {GameData.Instance.CompletedTasks}/{GameData.Instance.TotalTasks}";
+ bool seeRoles = PlayersSeeRoles.GetBool();
+ bool agentEnabled = CustomRoles.Agent.IsEnable();
+ string deadText = Translator.GetString("Dead");
- static string GetStateText(KeyValuePair state)
+ TaskBarText.Clear();
+ TaskBarText.Append("");
+
+ foreach ((byte id, PlayerState state) in Main.PlayerStates)
{
- string name = Main.AllPlayerNames.GetValueOrDefault(state.Key, $"ID {state.Key}");
- name = Utils.ColorString(Main.PlayerColors.GetValueOrDefault(state.Key, Color.white), name);
- bool isSeeker = PlayerRoles[state.Key].Interface.Team == Team.Impostor;
- bool alive = !state.Value.IsDead;
+ if (!PlayerRoles.TryGetValue(id, out var playerRole)) continue;
- TaskState taskState = state.Value.TaskState;
- var stateText = string.Empty;
+ string name = Main.AllPlayerNames.TryGetValue(id, out string playerName) ? playerName : $"ID {id}";
+ name = Utils.ColorString(Main.PlayerColors.GetValueOrDefault(id, Color.white), name);
+ TaskBarText.Append(name);
- if (PlayersSeeRoles.GetBool())
- stateText = $" ({GetRole().ToColoredString()}){GetTaskCount()}";
- else if (isSeeker) stateText = $" ({CustomRoles.Seeker.ToColoredString()})";
+ if (seeRoles)
+ {
+ CustomRoles role = state.MainRole == CustomRoles.Agent ? CustomRoles.Hider : state.MainRole;
- if (!alive) stateText += $" {Translator.GetString("Dead")}";
+ TaskBarText.Append(' ');
+ TaskBarText.Append('(');
+ TaskBarText.Append(role.ToColoredString());
+ TaskBarText.Append(')');
- stateText = $"{name}{stateText}";
- return stateText;
+ TaskState taskState = state.TaskState;
- CustomRoles GetRole() => state.Value.MainRole == CustomRoles.Agent ? CustomRoles.Hider : state.Value.MainRole;
+ if (state.MainRole != CustomRoles.GM && !agentEnabled && taskState.HasTasks)
+ {
+ TaskBarText.Append(' ');
+ TaskBarText.Append('(');
+ TaskBarText.Append(taskState.CompletedTasksCount);
+ TaskBarText.Append('/');
+ TaskBarText.Append(taskState.AllTasksCount);
+ TaskBarText.Append(')');
+ }
+ }
+ else if (playerRole.Interface.Team == Team.Impostor)
+ {
+ TaskBarText.Append(' ');
+ TaskBarText.Append('(');
+ TaskBarText.Append(CustomRoles.Seeker.ToColoredString());
+ TaskBarText.Append(')');
+ }
- string GetTaskCount() => state.Value.MainRole == CustomRoles.GM || CustomRoles.Agent.IsEnable() || !taskState.HasTasks ? string.Empty : $" ({taskState.CompletedTasksCount}/{taskState.AllTasksCount})";
+ if (state.IsDead)
+ {
+ TaskBarText.Append(" ");
+ TaskBarText.Append(deadText);
+ TaskBarText.Append("");
+ }
+
+ TaskBarText.Append('\n');
}
+
+ TaskBarText.Append("\r\n\r\n<#00ffa5>");
+ TaskBarText.Append(Translator.GetString("HNS.TaskCount"));
+ TaskBarText.Append(" ");
+ TaskBarText.Append(GameData.Instance.CompletedTasks);
+ TaskBarText.Append('/');
+ TaskBarText.Append(GameData.Instance.TotalTasks);
+
+ return TaskBarText.ToString();
}
private static readonly StringBuilder Suffix = new();
@@ -401,7 +439,7 @@ internal static class CustomHnS
if (PlayersSeeRoles.GetBool() && !CustomRoles.Agent.IsEnable() && IntroCutsceneDestroyPatch.IntroDestroyTS + 15 > Utils.TimeStamp)
{
Suffix.AppendLine();
- Suffix.AppendFormat(Translator.GetString("HNSSeekers"), string.Join(", ", PlayerRoles.Where(x => x.Value.Interface.Team == Team.Impostor).Select(x => x.Key.ColoredPlayerName())));
+ Suffix.AppendFormat(Translator.GetString("HNSSeekers"), PlayerRoles.Where(x => x.Value.Interface.Team == Team.Impostor).Join(", ", x => x.Key.ColoredPlayerName()));
}
}
}
diff --git a/Gamemodes/Deathrace.cs b/Gamemodes/Deathrace.cs
index 9d2cf096a..d847c19e1 100644
--- a/Gamemodes/Deathrace.cs
+++ b/Gamemodes/Deathrace.cs
@@ -250,7 +250,7 @@ public static class Deathrace
var track = Track.ToList();
if (!Clockwise) track.Reverse();
- players.NotifyPlayers("<#ffffff>" + string.Format(Translator.GetString("Deathrace.Tutorial.Track"), string.Join(" » ", track.ConvertAll(x => Translator.GetString(x.ToString())))), 100f);
+ players.NotifyPlayers("<#ffffff>" + string.Format(Translator.GetString("Deathrace.Tutorial.Track"), track.Join(" » ", x => Translator.GetString(x.ToString()))), 100f);
yield return new WaitForSecondsRealtime(Track.Count);
NameNotifyManager.Reset();
@@ -394,7 +394,7 @@ public static class Deathrace
public static string GetTaskBarText()
{
- return string.Join('\n', Data.Select(x => $"{x.Key.ColoredPlayerName()}: {string.Format(Translator.GetString("Deathrace.Lap"), x.Value.Lap + 1, LapsToWin)}"));
+ return Data.Join('\n', x => $"{x.Key.ColoredPlayerName()}: {string.Format(Translator.GetString("Deathrace.Lap"), x.Value.Lap + 1, LapsToWin)}");
}
public static void OnCheckMurder(PlayerControl killer, PlayerControl target)
diff --git a/Gamemodes/KingOfTheZones.cs b/Gamemodes/KingOfTheZones.cs
index 0863bc862..e96132d22 100644
--- a/Gamemodes/KingOfTheZones.cs
+++ b/Gamemodes/KingOfTheZones.cs
@@ -579,10 +579,10 @@ public static class KingOfTheZones
SystemTypes zone = !room ? SystemTypes.Hallway : room.RoomId;
if (justStarted) Suffix.Append(GetString(Zones.Count == 1 ? "KOTZ.SuffixHelp.Zones.Single" : "KOTZ.SuffixHelp.Zones.Plural"));
- Suffix.AppendLine(string.Join(" | ", Zones.Select(x => Utils.ColorString(ZoneDomination[x].GetColor(), (zone == x ? "" : string.Empty) + GetString($"{x}") + (zone == x ? "" : string.Empty) + (ZoneMoveSchedules.TryGetValue(x, out long moveTS) ? $" {(ZoneDowntimeExpire.TryGetValue(x, out long downtimeEndTS) ? Utils.ColorString(Color.gray, $"{downtimeEndTS - now}") : $"<#ffff44>{moveTS - now}")}" : string.Empty)))));
+ Suffix.AppendLine(Zones.Join(" | ", x => Utils.ColorString(ZoneDomination[x].GetColor(), (zone == x ? "" : string.Empty) + GetString($"{x}") + (zone == x ? "" : string.Empty) + (ZoneMoveSchedules.TryGetValue(x, out long moveTS) ? $" {(ZoneDowntimeExpire.TryGetValue(x, out long downtimeEndTS) ? Utils.ColorString(Color.gray, $"{downtimeEndTS - now}") : $"<#ffff44>{moveTS - now}")}" : string.Empty))));
if (justStarted) Suffix.Append(GetString("KOTZ.SuffixHelp.Points"));
- Suffix.AppendLine(string.Join(" | ", Points.IntersectBy(PlayerTeams.Values, x => x.Key).Select(x => Utils.ColorString(x.Key.GetColor(), $"{x.Value}"))));
+ Suffix.AppendLine(Points.IntersectBy(PlayerTeams.Values, x => x.Key).Join(" | ", x => Utils.ColorString(x.Key.GetColor(), $"{x.Value}")));
int highestPoints = Points.Values.Max();
bool tie = Points.Values.Count(x => x == highestPoints) > 1;
@@ -590,7 +590,7 @@ public static class KingOfTheZones
if (tie && end)
{
- string tieTeams = string.Join(' ', Points.Where(x => x.Value == highestPoints).Select(x => Utils.ColorString(x.Key.GetColor(), "\u25a0")));
+ string tieTeams = Points.Where(x => x.Value == highestPoints).Join(' ', x => Utils.ColorString(x.Key.GetColor(), "\u25a0"));
Suffix.Append("").AppendFormat(GetString("KOTZ.Suffix.Tie"), tieTeams).AppendLine("");
}
else
@@ -966,7 +966,7 @@ public static class KingOfTheZones
}
}
- Logger.Info($"Zone domination: {string.Join(", ", ZoneDomination.Select(x => $"{x.Key} = {x.Value}"))}", "KOTZ");
+ Logger.Info($"Zone domination: {ZoneDomination.Join(", ", x => $"{x.Key} = {x.Value}")}", "KOTZ");
}
catch (Exception e) { Utils.ThrowException(e); }
diff --git a/Gamemodes/Mingle.cs b/Gamemodes/Mingle.cs
index ced6c47f2..e4cef2545 100644
--- a/Gamemodes/Mingle.cs
+++ b/Gamemodes/Mingle.cs
@@ -130,7 +130,7 @@ public static class Mingle
return true;
case var p when p <= MaxWinningPlayers:
CustomWinnerHolder.WinnerIds = aapc.Select(x => x.PlayerId).ToHashSet();
- Logger.Info($"Winners: {string.Join(", ", aapc.Select(x => x.GetRealName().RemoveHtmlTags()))}", "Mingle");
+ Logger.Info($"Winners: {aapc.Join(", ", x => x.GetRealName().RemoveHtmlTags())}", "Mingle");
Main.DoBlockNameChange = true;
return true;
default:
diff --git a/Gamemodes/NaturalDisasters.cs b/Gamemodes/NaturalDisasters.cs
index 7820bf7d8..49ecd1a81 100644
--- a/Gamemodes/NaturalDisasters.cs
+++ b/Gamemodes/NaturalDisasters.cs
@@ -393,7 +393,7 @@ public static class NaturalDisasters
if (DeathMessageQueue.Count > 0 && DeathMessageQueue.FindFirst(x => x.recordTimeStamp + 3 <= now, out var expired))
{
- var names = string.Join(", ", DeathMessageQueue.Where(x => x.deathReason == expired.deathReason).Select(x => x.id.ColoredPlayerName()));
+ var names = DeathMessageQueue.Where(x => x.deathReason == expired.deathReason).Join(", ", x => x.id.ColoredPlayerName());
string msgOthers = string.Format(Translator.GetString($"ND_DRLaughMessageOthers-{IRandom.Instance.Next(4)}.{expired.deathReason}"), names);
Main.EnumerateAlivePlayerControls().NotifyPlayers($"<#ff0000>[╳] {Utils.ColorString(DeathReasonColor(expired.deathReason), msgOthers)}");
DeathMessageQueue.RemoveAll(x => x.deathReason == expired.deathReason);
diff --git a/Gamemodes/Quiz.cs b/Gamemodes/Quiz.cs
index 1210d414f..a7f744bcd 100644
--- a/Gamemodes/Quiz.cs
+++ b/Gamemodes/Quiz.cs
@@ -149,7 +149,7 @@ public static class Quiz
public static string GetStatistics(byte id)
{
if (!NumCorrectAnswers.TryGetValue(id, out var data)) return string.Empty;
- string str = string.Join(" | ", data.Select(x => $"{x.Key.ToString()[0]}-{x.Value.Sum()}"));
+ string str = data.Join(" | ", x => $"{x.Key.ToString()[0]}-{x.Value.Sum()}");
return GetString("Quiz.EndResults.CorrectAnswerNum") + str;
}
@@ -235,7 +235,7 @@ public static class Quiz
if (!AllowKills) return string.Empty;
requiredCorrect = Settings[CurrentDifficulty].CorrectRequirement.GetInt();
- gotCorrect = NumCorrectAnswers[seer.PlayerId][CurrentDifficulty][Round];
+ gotCorrect = NumCorrectAnswers[seer.PlayerId][CurrentDifficulty][Round - 1];
failed = gotCorrect < requiredCorrect;
var ffaTimeLeft = FFAEndTS - Utils.TimeStamp;
@@ -276,7 +276,7 @@ public static class Quiz
var aapc = Main.AllAlivePlayerControlsToList;
bool showTutorial = !SubmergedCompatibility.IsSubmerged() && aapc.ExceptBy(HasPlayedFriendCodes, x => x.FriendCode).Count() > aapc.Count / 2;
- var usedRooms = string.Join('\n', UsedRooms[Main.CurrentMap].Select(x => $"{x.Key}: {GetString(x.Value.ToString())}"));
+ var usedRooms = UsedRooms[Main.CurrentMap].Join('\n', x => $"{x.Key}: {GetString(x.Value.ToString())}");
aapc.NotifyPlayers(string.Format(GetString("Quiz.Tutorial.Basics"), usedRooms), 11f);
yield return new WaitForSecondsRealtime(showTutorial ? 9f : 5f);
if (GameStates.IsMeeting || ExileController.Instance || !GameStates.InGame || GameStates.IsLobby) yield break;
@@ -454,8 +454,8 @@ public static class Quiz
if (DyingPlayers.Count == 0) NumAllCorrectAnswers++;
bool everyoneWasWrong = DyingPlayers.Count == aapcCount;
if (!everyoneWasWrong) NumCorrectAnswers.IntersectBy(aapc.Select(x => x.PlayerId), x => x.Key).DoIf(x => !DyingPlayers.Contains(x.Key), x => x.Value[CurrentDifficulty][Round]++);
- Logger.Info($"{(everyoneWasWrong ? "Everyone" : "Players who")} got the question wrong: {string.Join(", ", DyingPlayers.Select(x => Main.AllPlayerNames.GetValueOrDefault(x, $"Someone (ID {x})")))}", "Quiz");
- Logger.Info($"Number of correct answers for everyone currently: {string.Join(", ", NumCorrectAnswers.Select(x => $"{Main.AllPlayerNames.GetValueOrDefault(x.Key, string.Empty)}: {x.Value[CurrentDifficulty][Round]}"))}", "Quiz");
+ Logger.Info($"{(everyoneWasWrong ? "Everyone" : "Players who")} got the question wrong: {DyingPlayers.Join(", ", x => Main.AllPlayerNames.GetValueOrDefault(x, $"Someone (ID {x})"))}", "Quiz");
+ Logger.Info($"Number of correct answers for everyone currently: {NumCorrectAnswers.Join(", ", x => $"{Main.AllPlayerNames.GetValueOrDefault(x.Key, string.Empty)}: {x.Value[CurrentDifficulty][Round]}")}", "Quiz");
if (everyoneWasWrong) QuestionsAsked--;
Utils.NotifyRoles();
@@ -475,7 +475,7 @@ public static class Quiz
var correctRequirement = settings.CorrectRequirement.GetInt();
List dyingPlayers = NumCorrectAnswers.Where(x => x.Value[CurrentDifficulty][Round] < correctRequirement).Select(x => x.Key).Where(x => Main.PlayerStates.TryGetValue(x, out var s) && !s.IsDead).ToList();
- Logger.Info($"Round {Round + 1} of {CurrentDifficulty} difficulty ended. Dying players: {dyingPlayers.Count} | {string.Join(", ", dyingPlayers.Select(x => Main.AllPlayerNames[x]))}", "Quiz");
+ Logger.Info($"Round {Round + 1} of {CurrentDifficulty} difficulty ended. Dying players: {dyingPlayers.Count} | {dyingPlayers.Join(", ", x => Main.AllPlayerNames[x])}", "Quiz");
Round++;
QuestionsAsked = 0;
@@ -559,7 +559,7 @@ public static class Quiz
{
try
{
- var correctAnswers = string.Join('\n', NumCorrectAnswers.Select(x => $"{x.Key.ColoredPlayerName()}: {string.Join(' ', x.Value.Select(k => $"{k.Key.ToString()[0]}-{k.Value.Sum()}"))}"));
+ var correctAnswers = NumCorrectAnswers.Join('\n', x => $"{x.Key.ColoredPlayerName()}: {x.Value.Join(' ', k => $"{k.Key.ToString()[0]}-{k.Value.Sum()}")}");
return string.Format(GetString("Quiz.TaskBarText"), CurrentDifficulty, Round + 1, QuestionsAsked + 1, correctAnswers);
}
catch { return string.Empty; }
diff --git a/Gamemodes/RoomRush.cs b/Gamemodes/RoomRush.cs
index 55ebec004..8e020dcd7 100644
--- a/Gamemodes/RoomRush.cs
+++ b/Gamemodes/RoomRush.cs
@@ -899,7 +899,7 @@ public static class RoomRush
if (WinByPointsInsteadOfDeaths.GetBool())
{
- Logger.Info($"Points: {string.Join(", ", Points.Select(x => $"{Main.AllPlayerNames[x.Key]}: {x.Value}"))}", "RoomRush");
+ Logger.Info($"Points: {Points.Join(", ", x => $"{Main.AllPlayerNames[x.Key]}: {x.Value}")}", "RoomRush");
if (Utils.DoRPC)
{
diff --git a/Gamemodes/Snowdown.cs b/Gamemodes/Snowdown.cs
index 5f407bca4..9e591537b 100644
--- a/Gamemodes/Snowdown.cs
+++ b/Gamemodes/Snowdown.cs
@@ -198,7 +198,7 @@ public static class Snowdown
{
int max = Data.Values.Max(x => x.Points);
CustomWinnerHolder.WinnerIds = Data.Where(x => x.Value.Points == max && x.Key.GetPlayer()).Select(x => x.Key).ToHashSet();
- Logger.Info($"Winners: {string.Join(", ", CustomWinnerHolder.WinnerIds.Select(x => Main.AllPlayerNames.GetValueOrDefault(x, "[Unknown player]")))}", "Snowdown");
+ Logger.Info($"Winners: {CustomWinnerHolder.WinnerIds.Join(", ", x => Main.AllPlayerNames.GetValueOrDefault(x, "[Unknown player]"))}", "Snowdown");
Main.DoBlockNameChange = true;
return true;
}
diff --git a/Gamemodes/Speedrun.cs b/Gamemodes/Speedrun.cs
index ea1a5ff70..ba7254dbd 100644
--- a/Gamemodes/Speedrun.cs
+++ b/Gamemodes/Speedrun.cs
@@ -87,14 +87,15 @@ public static class Speedrun
public static string GetTaskBarText()
{
- return string.Join('\n', Main.PlayerStates
- .Join(Main.EnumerateAlivePlayerControls(), x => x.Key, x => x.PlayerId, (kvp, _) => (
- Name: kvp.Key.ColoredPlayerName(),
- CompletedTasks: kvp.Value.TaskState.CompletedTasksCount,
- AllTasks: kvp.Value.TaskState.AllTasksCount,
- Time: AmongUsClient.Instance.AmHost ? $" ({Timers.GetValueOrDefault(kvp.Key)}s)" : string.Empty))
+ return Main.PlayerStates
+ .Where(x => !x.Value.IsDead)
+ .Select(x => (
+ Name: x.Key.ColoredPlayerName(),
+ CompletedTasks: x.Value.TaskState.CompletedTasksCount,
+ AllTasks: x.Value.TaskState.AllTasksCount,
+ Time: AmongUsClient.Instance.AmHost ? $" ({Timers.GetValueOrDefault(x.Key)}s)" : string.Empty))
.OrderByDescending(x => x.CompletedTasks)
- .Select(x => x.CompletedTasks < x.AllTasks ? $"{x.Name}: {x.CompletedTasks}/{x.AllTasks}{x.Time}" : $"{x.Name}: {Translator.GetString("Speedrun_KillingPlayer")}{x.Time}"));
+ .Join('\n', x => x.CompletedTasks < x.AllTasks ? $"{x.Name}: {x.CompletedTasks}/{x.AllTasks}{x.Time}" : $"{x.Name}: {Translator.GetString("Speedrun_KillingPlayer")}{x.Time}");
}
public static string GetSuffixText(PlayerControl pc)
diff --git a/Gamemodes/StopAndGo.cs b/Gamemodes/StopAndGo.cs
index ea3592fe5..91bea33ae 100644
--- a/Gamemodes/StopAndGo.cs
+++ b/Gamemodes/StopAndGo.cs
@@ -183,7 +183,7 @@ internal static class StopAndGo
private static IntegerValueRule CounterValueRule => new(1, 100, 1);
private static IntegerValueRule ExtraTimeValue => new(0, 50, 1);
private static int DefaultMinValue => 5;
- private static int DefaultMaxValue => 30;
+ private static int DefaultMaxValue => 20;
public static string GetHudText()
{
diff --git a/Gamemodes/TheMindGame.cs b/Gamemodes/TheMindGame.cs
index 03d3b91e0..358038b21 100644
--- a/Gamemodes/TheMindGame.cs
+++ b/Gamemodes/TheMindGame.cs
@@ -219,7 +219,7 @@ public static class TheMindGame
sb.Append('\n');
sb.Append('\n');
sb.Append("");
- sb.Append(string.Join('\n', AllItem.Select(x => $"{Translator.GetString($"TMG.Item.{x}")} (ID {ItemIds[seer.PlayerId][x]}) ({string.Format(Translator.GetString("TMG.Suffix.ItemCost"), ItemCosts[x])}) - {Translator.GetString($"TMG.ItemDescription.{x}")}")));
+ sb.Append(AllItem.Join('\n', x => $"{Translator.GetString($"TMG.Item.{x}")} (ID {ItemIds[seer.PlayerId][x]}) ({string.Format(Translator.GetString("TMG.Suffix.ItemCost"), ItemCosts[x])}) - {Translator.GetString($"TMG.ItemDescription.{x}")}"));
sb.Append('\n');
sb.Append('\n');
sb.Append(Translator.GetString("TMG.Suffix.BuyItemHint"));
@@ -236,7 +236,7 @@ public static class TheMindGame
sb.Append('\n');
sb.Append(Translator.GetString("TMG.Suffix.YourItems"));
sb.Append('\n');
- sb.Append(string.Join(", ", items.GroupBy(x => x).Select(x => $"{x.Count()}x {Translator.GetString($"TMG.Item.{x.Key}")} (ID {ItemIds[seer.PlayerId][x.Key]})")));
+ sb.Append(items.GroupBy(x => x).Join(", ", x => $"{x.Count()}x {Translator.GetString($"TMG.Item.{x.Key}")} (ID {ItemIds[seer.PlayerId][x.Key]})"));
sb.Append('\n');
sb.Append('\n');
sb.Append(Translator.GetString("TMG.Suffix.UseItemHint"));
@@ -439,7 +439,7 @@ public static class TheMindGame
List auctionWinners = Pick.Where(x => x.Value == highestBid).Select(x => x.Key).ToList();
auctionWinners.ForEach(x => SuperPoints[x] += AuctionValue);
- yield return NotifyEveryone("TMG.Notify.AuctionEnd", 4, highestBid, string.Join(" & ", auctionWinners.ConvertAll(x => x.ColoredPlayerName())), AuctionValue);
+ yield return NotifyEveryone("TMG.Notify.AuctionEnd", 4, highestBid, auctionWinners.Join(" & ", x => x.ColoredPlayerName()), AuctionValue);
if (Stop) yield break;
}
@@ -633,7 +633,7 @@ public static class TheMindGame
Dictionary round4Points = ranking.ToDictionary(x => x, x => (ranking.Count - ranking.IndexOf(x)) * 10);
round4Points.Do(x => Points[x.Key] += x.Value);
- join = string.Join('\n', round4Points.Select(x => $"{x.Key.ColoredPlayerName()}: +{x.Value}"));
+ join = round4Points.Join('\n', x => $"{x.Key.ColoredPlayerName()}: +{x.Value}");
yield return NotifyEveryone("TMG.Notify.Round4PointGain", 5, join);
if (Stop) yield break;
diff --git a/Modules/CustomRoleSelector.cs b/Modules/CustomRoleSelector.cs
index 5a03b3e77..242c2c7d1 100644
--- a/Modules/CustomRoleSelector.cs
+++ b/Modules/CustomRoleSelector.cs
@@ -205,12 +205,12 @@ internal static class CustomRoleSelector
Logger.Info($"Number of Coven members: {covenLimits.MinSetting.GetInt()} - {covenLimits.MaxSetting.GetInt()} => {numCovens}", "FactionLimits");
Logger.Msg("=====================================================", "AllActiveRoles");
- Logger.Info(string.Join(", ", roles[RoleAssignType.Impostor].Select(x => $"{x.Role}: {x.SpawnChance}% - {x.MaxCount}")), "ImpRoles");
- Logger.Info(string.Join(", ", roles[RoleAssignType.NeutralKilling].Select(x => $"{x.Role}: {x.SpawnChance}% - {x.MaxCount}")), "NKRoles");
- Logger.Info(string.Join(", ", roles[RoleAssignType.NonKillingNeutral].Select(x => $"{x.Role}: {x.SpawnChance}% - {x.MaxCount}")), "NNKRoles");
- Logger.Info(string.Join(", ", roles[RoleAssignType.Crewmate].Select(x => $"{x.Role}: {x.SpawnChance}% - {x.MaxCount}")), "CrewRoles");
- Logger.Info(string.Join(", ", roles[RoleAssignType.Madmate].Select(x => $"{x.Role}: {x.SpawnChance}% - {x.MaxCount}")), "MadmateRoles");
- Logger.Info(string.Join(", ", roles[RoleAssignType.Coven].Select(x => $"{x.Role}: {x.SpawnChance}% - {x.MaxCount}")), "CovenRoles");
+ Logger.Info(roles[RoleAssignType.Impostor].Join(", ", x => $"{x.Role}: {x.SpawnChance}% - {x.MaxCount}"), "ImpRoles");
+ Logger.Info(roles[RoleAssignType.NeutralKilling].Join(", ", x => $"{x.Role}: {x.SpawnChance}% - {x.MaxCount}"), "NKRoles");
+ Logger.Info(roles[RoleAssignType.NonKillingNeutral].Join(", ", x => $"{x.Role}: {x.SpawnChance}% - {x.MaxCount}"), "NNKRoles");
+ Logger.Info(roles[RoleAssignType.Crewmate].Join(", ", x => $"{x.Role}: {x.SpawnChance}% - {x.MaxCount}"), "CrewRoles");
+ Logger.Info(roles[RoleAssignType.Madmate].Join(", ", x => $"{x.Role}: {x.SpawnChance}% - {x.MaxCount}"), "MadmateRoles");
+ Logger.Info(roles[RoleAssignType.Coven].Join(", ", x => $"{x.Role}: {x.SpawnChance}% - {x.MaxCount}"), "CovenRoles");
Logger.Msg("=====================================================", "AllActiveRoles");
Dictionary subCategoryLimits;
@@ -232,7 +232,7 @@ internal static class CustomRoleSelector
}
catch (Exception e) { Utils.ThrowException(e); }
- if (subCategoryLimits.Count > 0) Logger.Info($"Sub-Category Limits: {string.Join(", ", subCategoryLimits.Select(x => $"{x.Key}: {x.Value}"))}", "SubCategoryLimits");
+ if (subCategoryLimits.Count > 0) Logger.Info($"Sub-Category Limits: {subCategoryLimits.Join(", ", x => $"{x.Key}: {x.Value}")}", "SubCategoryLimits");
int nkLimit = subCategoryLimits[RoleOptionType.Neutral_Killing];
int nnkLimit;
@@ -254,12 +254,12 @@ internal static class CustomRoleSelector
roles.Keys.Do(type => ApplySubCategoryLimits(type, subCategoryLimits));
Logger.Msg("===================================================", "PreSelectedRoles");
- Logger.Info(string.Join(", ", roles[RoleAssignType.Impostor].Select(x => x.Role.ToString())), "PreSelectedImpostorRoles");
- Logger.Info(string.Join(", ", roles[RoleAssignType.NeutralKilling].Select(x => x.Role.ToString())), "PreSelectedNKRoles");
- Logger.Info(string.Join(", ", roles[RoleAssignType.NonKillingNeutral].Select(x => x.Role.ToString())), "PreSelectedNNKRoles");
- Logger.Info(string.Join(", ", roles[RoleAssignType.Crewmate].Select(x => x.Role.ToString())), "PreSelectedCrewRoles");
- Logger.Info(string.Join(", ", roles[RoleAssignType.Madmate].Select(x => x.Role.ToString())), "PreSelectedMadmateRoles");
- Logger.Info(string.Join(", ", roles[RoleAssignType.Coven].Select(x => x.Role.ToString())), "PreSelectedCovenRoles");
+ Logger.Info(roles[RoleAssignType.Impostor].Join(", ", x => x.Role.ToString()), "PreSelectedImpostorRoles");
+ Logger.Info(roles[RoleAssignType.NeutralKilling].Join(", ", x => x.Role.ToString()), "PreSelectedNKRoles");
+ Logger.Info(roles[RoleAssignType.NonKillingNeutral].Join(", ", x => x.Role.ToString()), "PreSelectedNNKRoles");
+ Logger.Info(roles[RoleAssignType.Crewmate].Join(", ", x => x.Role.ToString()), "PreSelectedCrewRoles");
+ Logger.Info(roles[RoleAssignType.Madmate].Join(", ", x => x.Role.ToString()), "PreSelectedMadmateRoles");
+ Logger.Info(roles[RoleAssignType.Coven].Join(", ", x => x.Role.ToString()), "PreSelectedCovenRoles");
Logger.Msg("===================================================", "PreSelectedRoles");
try
@@ -284,12 +284,12 @@ internal static class CustomRoleSelector
catch (Exception e) { Utils.ThrowException(e); }
Logger.Msg("======================================================", "SelectedRoles");
- Logger.Info(string.Join(", ", roles[RoleAssignType.Impostor].Select(x => x.Role.ToString())), "SelectedImpostorRoles");
- Logger.Info(string.Join(", ", roles[RoleAssignType.NeutralKilling].Select(x => x.Role.ToString())), "SelectedNKRoles");
- Logger.Info(string.Join(", ", roles[RoleAssignType.NonKillingNeutral].Select(x => x.Role.ToString())), "SelectedNNKRoles");
- Logger.Info(string.Join(", ", roles[RoleAssignType.Crewmate].Select(x => x.Role.ToString())), "SelectedCrewRoles");
- Logger.Info(string.Join(", ", roles[RoleAssignType.Madmate].Select(x => x.Role.ToString())), "SelectedMadmateRoles");
- Logger.Info(string.Join(", ", roles[RoleAssignType.Coven].Select(x => x.Role.ToString())), "SelectedCovenRoles");
+ Logger.Info(roles[RoleAssignType.Impostor].Join(", ", x => x.Role.ToString()), "SelectedImpostorRoles");
+ Logger.Info(roles[RoleAssignType.NeutralKilling].Join(", ", x => x.Role.ToString()), "SelectedNKRoles");
+ Logger.Info(roles[RoleAssignType.NonKillingNeutral].Join(", ", x => x.Role.ToString()), "SelectedNNKRoles");
+ Logger.Info(roles[RoleAssignType.Crewmate].Join(", ", x => x.Role.ToString()), "SelectedCrewRoles");
+ Logger.Info(roles[RoleAssignType.Madmate].Join(", ", x => x.Role.ToString()), "SelectedMadmateRoles");
+ Logger.Info(roles[RoleAssignType.Coven].Join(", ", x => x.Role.ToString()), "SelectedCovenRoles");
Logger.Msg("======================================================", "SelectedRoles");
List allPlayers = Main.EnumerateAlivePlayerControls().ToList();
@@ -391,7 +391,7 @@ internal static class CustomRoleSelector
if (rd.Next(0, 100) < Bomber.NukerChance.GetInt() && finalRolesList.Remove(CustomRoles.Bomber)) finalRolesList.Add(CustomRoles.Nuker);
RoleResult.AddRange(allPlayers.Shuffle().Zip(finalRolesList.Shuffle()).ToDictionary(x => x.First.PlayerId, x => x.Second), false);
- Logger.Info(string.Join(", ", RoleResult.Values.Select(x => x.ToString())), "RoleResults");
+ Logger.Info(RoleResult.Values.Join(", ", x => x.ToString()), "RoleResults");
if (RoleResult.Count < allPlayers.Count) Logger.Error("Role assignment error: There are players who have not been assigned a role", "CustomRoleSelector");
diff --git a/Modules/Extensions/CollectionExtensions.cs b/Modules/Extensions/CollectionExtensions.cs
index 6e437bd01..f92a9a37e 100644
--- a/Modules/Extensions/CollectionExtensions.cs
+++ b/Modules/Extensions/CollectionExtensions.cs
@@ -346,6 +346,51 @@ public static class CollectionExtensions
return list;
}
+
+ public string Join(string separator, Func selector)
+ {
+ separator ??= string.Empty;
+ selector ??= x => x.ToString();
+
+ using IEnumerator enumerator = collection.GetEnumerator();
+
+ if (!enumerator.MoveNext())
+ return string.Empty;
+
+ StringBuilder sb = new();
+
+ sb.Append(selector(enumerator.Current));
+
+ while (enumerator.MoveNext())
+ {
+ sb.Append(separator);
+ sb.Append(selector(enumerator.Current));
+ }
+
+ return sb.ToString();
+ }
+
+ public string Join(char separator, Func selector)
+ {
+ selector ??= x => x.ToString();
+
+ using IEnumerator enumerator = collection.GetEnumerator();
+
+ if (!enumerator.MoveNext())
+ return string.Empty;
+
+ StringBuilder sb = new();
+
+ sb.Append(selector(enumerator.Current));
+
+ while (enumerator.MoveNext())
+ {
+ sb.Append(separator);
+ sb.Append(selector(enumerator.Current));
+ }
+
+ return sb.ToString();
+ }
}
/// The collection
@@ -388,6 +433,49 @@ public static class CollectionExtensions
if (collection.Count == 0) return default(T);
return collection[IRandom.Instance.Next(collection.Count)];
}
+
+ public string Join(string separator, Func selector)
+ {
+ separator ??= string.Empty;
+ selector ??= x => x.ToString();
+
+ int count = collection.Count;
+
+ if (count == 0)
+ return string.Empty;
+
+ StringBuilder sb = new();
+ sb.Append(selector(collection[0]));
+
+ for (int i = 1; i < count; i++)
+ {
+ sb.Append(separator);
+ sb.Append(selector(collection[i]));
+ }
+
+ return sb.ToString();
+ }
+
+ public string Join(char separator, Func selector)
+ {
+ selector ??= x => x.ToString();
+
+ int count = collection.Count;
+
+ if (count == 0)
+ return string.Empty;
+
+ StringBuilder sb = new();
+ sb.Append(selector(collection[0]));
+
+ for (int i = 1; i < count; i++)
+ {
+ sb.Append(separator);
+ sb.Append(selector(collection[i]));
+ }
+
+ return sb.ToString();
+ }
}
///
diff --git a/Modules/OptionHolder.cs b/Modules/OptionHolder.cs
index 150d0507e..cbb0db9ec 100644
--- a/Modules/OptionHolder.cs
+++ b/Modules/OptionHolder.cs
@@ -1151,7 +1151,7 @@ public static class Options
if (values.Count == 0) continue;
- string possibleValues = string.Join("
", values.Select(x => $"`{x}`"));
+ string possibleValues = values.Join("
", x => $"`{x}`");
string defaultValue = option switch
{
@@ -3373,7 +3373,7 @@ public static class Options
OptionItem.SyncAllOptions();
if (CurrentGameMode == CustomGameMode.Standard)
- Logger.SendInGame(string.Format(Translator.GetString("AutoFactionMinMaxSettings.Applied"), playerCount, usedPlayerCount, string.Join(", ", new[] { Team.Impostor, Team.Coven, Team.Neutral }.Select(x => $"{Utils.ColorString(x.GetColor(), Translator.GetString($"ShortTeamName.{x}").ToUpper())}: <#ffffff>{usedValues.TeamSettings[x].MinSetting.GetInt()}-{usedValues.TeamSettings[x].MaxSetting.GetInt()}")), usedValues.MinNNKs.GetInt(), usedValues.MaxNNKs.GetInt()));
+ Logger.SendInGame(string.Format(Translator.GetString("AutoFactionMinMaxSettings.Applied"), playerCount, usedPlayerCount, new[] { Team.Impostor, Team.Coven, Team.Neutral }.Join(", ", x => $"{Utils.ColorString(x.GetColor(), Translator.GetString($"ShortTeamName.{x}").ToUpper())}: <#ffffff>{usedValues.TeamSettings[x].MinSetting.GetInt()}-{usedValues.TeamSettings[x].MaxSetting.GetInt()}"), usedValues.MinNNKs.GetInt(), usedValues.MaxNNKs.GetInt()));
LastUsedPlayerCount = usedPlayerCount;
}
diff --git a/Modules/PrivateTagManager.cs b/Modules/PrivateTagManager.cs
index e402375d2..b779e84b4 100644
--- a/Modules/PrivateTagManager.cs
+++ b/Modules/PrivateTagManager.cs
@@ -25,7 +25,7 @@ public static class PrivateTagManager
private static void SaveTagsToFile()
{
- try { File.WriteAllText(TagFile, string.Join("\n", Tags.Select(x => $"{x.Key}={x.Value}"))); }
+ try { File.WriteAllText(TagFile, Tags.Join("\n", x => $"{x.Key}={x.Value}")); }
catch (Exception e) { Utils.ThrowException(e); }
}
diff --git a/Modules/TemplateManager.cs b/Modules/TemplateManager.cs
index eec28ee6d..4b12720d1 100644
--- a/Modules/TemplateManager.cs
+++ b/Modules/TemplateManager.cs
@@ -53,8 +53,8 @@ public static class TemplateManager
["PlayerName"] = () => DataManager.Player.Customization.Name,
["HostName"] = () => Main.AllPlayerNames.GetValueOrDefault(PlayerControl.LocalPlayer.PlayerId, PlayerControl.LocalPlayer.GetRealName()),
["Players"] = () => string.Join(", ", Main.AllPlayerNames.Values),
- ["AlivePlayers"] = () => string.Join(", ", Main.EnumerateAlivePlayerControls().Select(x => x.GetRealName())),
- ["DeadPlayers"] = () => string.Join(", ", Main.EnumeratePlayerControls().Where(x => !x.IsAlive()).Select(x => x.GetRealName())),
+ ["AlivePlayers"] = () => Main.EnumerateAlivePlayerControls().Join(", ", x => x.GetRealName()),
+ ["DeadPlayers"] = () => Main.EnumeratePlayerControls().Where(x => !x.IsAlive()).Join(", ", x => x.GetRealName()),
["PlayerCount"] = () => (GameData.Instance ? GameData.Instance.PlayerCount : 0).ToString(),
["AlivePlayerCount"] = () => Main.EnumerateAlivePlayerControls().Count().ToString(),
["DeadPlayerCount"] = () => Main.EnumeratePlayerControls().Count(x => !x.IsAlive()).ToString(),
@@ -507,14 +507,13 @@ public static class TemplateManager
string msg = (roleBlocked, rankBlocked) switch
{
- (true, _) => string.Format(GetString("Message.TemplateRoleRequired"), string.Join('/', roleBlockSource.AllowedRoles
- .Select(r =>
+ (true, _) => string.Format(GetString("Message.TemplateRoleRequired"), roleBlockSource.AllowedRoles.Join('/', r =>
{
string name = r.TrimStart('!');
return Enum.TryParse(name, ignoreCase: true, out CustomRoles role)
? GetString(role.ToString())
: name;
- }))),
+ })),
(_, true) => string.Format(GetString("Message.TemplateRankRequired"), string.Join('/', rankBlockSource.AllowedRanks)),
_ => string.Format(GetString(playerId == 0xff ? "Message.TemplateNotFoundHost" : "Message.TemplateNotFoundClient"), str, string.Join(", ", tags))
};
diff --git a/Modules/Translator.cs b/Modules/Translator.cs
index d4d34f1b3..80aae099a 100644
--- a/Modules/Translator.cs
+++ b/Modules/Translator.cs
@@ -328,7 +328,7 @@ public static class Translator
private static void CreateTemplateFile()
{
- File.WriteAllText($"{Main.DataPath}/{LanguageFolderName}/template.dat", string.Join('\n', TranslateMaps.Keys.Select(x => $"{x}:")));
+ File.WriteAllText($"{Main.DataPath}/{LanguageFolderName}/template.dat", TranslateMaps.Keys.Join('\n', x => $"{x}:"));
}
public static void ExportCustomTranslation()
diff --git a/Modules/Utils.cs b/Modules/Utils.cs
index b2eca7453..a43bd910b 100644
--- a/Modules/Utils.cs
+++ b/Modules/Utils.cs
@@ -2831,8 +2831,8 @@ public static class Utils
if (Options.CurrentGameMode != CustomGameMode.Standard) return;
- string seers = SeerList.Count == apc.Count ? "Everyone" : string.Join(", ", SeerList.Select(x => x.GetRealName()));
- string targets = TargetList.Count == apc.Count ? "Everyone" : string.Join(", ", TargetList.Select(x => x.GetRealName()));
+ string seers = SeerList.Count == apc.Count ? "Everyone" : SeerList.Join(", ", x => x.GetRealName());
+ string targets = TargetList.Count == apc.Count ? "Everyone" : TargetList.Join(", ", x => x.GetRealName());
if (seers.Length == 0) seers = "\u2205";
if (targets.Length == 0) targets = "\u2205";
diff --git a/Patches/ChatCommandPatch.cs b/Patches/ChatCommandPatch.cs
index 9f4a77c2a..6ca86a0ab 100644
--- a/Patches/ChatCommandPatch.cs
+++ b/Patches/ChatCommandPatch.cs
@@ -575,13 +575,13 @@ internal static class ChatCommands
{
if (args.Length < 2)
{
- Utils.SendMessage("" + string.Join('\n', Main.CachedAllPlayerControls().Select(x =>
+ Utils.SendMessage("" + Main.CachedAllPlayerControls().Join('\n', x =>
{
ClientData client = x.GetClient();
string name = Main.AllPlayerNames.GetValueOrDefault(x.PlayerId, string.Empty);
string id = string.IsNullOrEmpty(name) ? $"ID {x.PlayerId}" : $" (ID {x.PlayerId})";
return $"{name}{id} - {x.FriendCode} | {client?.GetHashedPuid()} | {client?.PlatformData.Platform}";
- })) + "", player.PlayerId);
+ }) + "", player.PlayerId);
}
else if (byte.TryParse(args[1], out byte playerId))
{
@@ -1019,7 +1019,7 @@ internal static class ChatCommands
{
if ((!player.IsHost() && !IsPlayerAdmin(player.FriendCode)) || args.Length < 3 || !GetRoleByName(args[1], out CustomRoles role1) || !GetRoleByName(args[2], out CustomRoles role2))
{
- Utils.SendMessage(string.Join('\n', Main.XORRoles.ConvertAll(x => $"{x.Item1.ToColoredString()} ⊕ {x.Item2.ToColoredString()}")), player.PlayerId, GetString("XORListTitle"));
+ Utils.SendMessage(Main.XORRoles.Join('\n', x => $"{x.Item1.ToColoredString()} ⊕ {x.Item2.ToColoredString()}"), player.PlayerId, GetString("XORListTitle"));
return;
}
@@ -1110,7 +1110,7 @@ internal static class ChatCommands
{
GMPollGameModes = Main.CustomGameModeValues[..^1].Where(x => Options.GMPollGameModesSettings[x].GetBool()).ToList();
if (GMPollGameModes.Contains(CustomGameMode.HideAndSeek)) GMPollGameModes.Add((CustomGameMode)100);
- string gmNames = string.Join(' ', GMPollGameModes.Select(x => GetString((int)x == 100 ? "HNS.ShiftAndSeek" : x.ToString()).Replace(' ', '_')));
+ string gmNames = GMPollGameModes.Join(' ', x => GetString((int)x == 100 ? "HNS.ShiftAndSeek" : x.ToString().Replace(' ', '_')));
var msg = $"/poll {GetString("GameModePoll.Question").TrimEnd('?')}? {gmNames}";
PollCommand(player, msg, msg.Split(' '));
}
@@ -1118,7 +1118,7 @@ internal static class ChatCommands
public static void MapPollCommand(PlayerControl player, string text, string[] args)
{
MPollMaps = Main.MapNamesValues.Where(x => Options.MPollMapsSettings[x].GetBool()).ToList();
- string mNames = string.Join(' ', MPollMaps.Select(x => GetString(x.ToString()).Replace(' ', '_')));
+ string mNames = MPollMaps.Join(' ', x => GetString(x.ToString().Replace(' ', '_')));
var msg = $"/poll {GetString("MapPoll.Question").TrimEnd('?')}? {mNames}";
PollCommand(player, msg, msg.Split(' '));
}
@@ -1126,10 +1126,7 @@ internal static class ChatCommands
public static void PresetPollCommand(PlayerControl player, string text, string[] args)
{
var presetConfigs = new[] { Main.Preset1, Main.Preset2, Main.Preset3, Main.Preset4, Main.Preset5, Main.Preset6, Main.Preset7, Main.Preset8, Main.Preset9, Main.Preset10, Main.Preset11, Main.Preset12, Main.Preset13, Main.Preset14, Main.Preset15, Main.Preset16, Main.Preset17, Main.Preset18, Main.Preset19, Main.Preset20 };
-
- string presetNames = string.Join(' ', presetConfigs.Select((cfg, i) =>
- (cfg.Value == (string)cfg.DefaultValue ? GetString($"Preset_{i + 1}") : cfg.Value)
- .Replace(' ', '_')));
+ string presetNames = string.Join(' ', presetConfigs.Select((cfg, i) => (cfg.Value == (string)cfg.DefaultValue ? GetString($"Preset_{i + 1}") : cfg.Value).Replace(' ', '_')));
var msg = $"/poll {GetString("PresetPoll.Question").TrimEnd('?')}? {presetNames}";
PollCommand(player, msg, msg.Split(' '));
@@ -1523,9 +1520,9 @@ internal static class ChatCommands
if (notReadyPlayers.Length == 0)
Utils.SendMessage("\n", player.PlayerId, GetString("EveryoneReadyTitle"));
else
- Utils.SendMessage(string.Join(", ", notReadyPlayers.Select(x => x.ColoredPlayerName())), player.PlayerId, string.Format(GetString("PlayersNotReadyTitle"), notReadyPlayers.Length));
+ Utils.SendMessage(notReadyPlayers.Join(", ", x => x.ColoredPlayerName()), player.PlayerId, string.Format(GetString("PlayersNotReadyTitle"), notReadyPlayers.Length));
- if (Spectators.Count > 0) Utils.SendMessage(string.Join(", ", Spectators.Select(x => x.ColoredPlayerName())), player.PlayerId, string.Format(GetString("SpectatorsList"), Spectators.Count));
+ if (Spectators.Count > 0) Utils.SendMessage(Spectators.Join(", ", x => x.ColoredPlayerName()), player.PlayerId, string.Format(GetString("SpectatorsList"), Spectators.Count));
}
}
@@ -1942,7 +1939,7 @@ internal static class ChatCommands
string result = winners.Length == 1
? string.Format(GetString("Poll.Winner"), winners[0].Key, PollAnswers[winners[0].Key], winners[0].Value) +
PollVotes.Where(x => x.Value > 0 && x.Key != winners[0].Key).Aggregate("", (s, t) => s + $"{t.Key} - {t.Value} {PollAnswers[t.Key]}\n")
- : string.Format(GetString("Poll.Tie"), string.Join(" & ", winners.Select(x => $"{x.Key}{PollAnswers[x.Key]}")), maxVotes);
+ : string.Format(GetString("Poll.Tie"), winners.Join(" & ", x => $"{x.Key}{PollAnswers[x.Key]}"), maxVotes);
Utils.SendMessage(result, title: Utils.ColorString(new(0, 255, 165, 255), GetString("PollResultTitle")));
diff --git a/Patches/GameOptionsMenuPatch.cs b/Patches/GameOptionsMenuPatch.cs
index 1b7faf34b..8c13e5fdf 100644
--- a/Patches/GameOptionsMenuPatch.cs
+++ b/Patches/GameOptionsMenuPatch.cs
@@ -971,7 +971,7 @@ public static class StringOptionPatch
_ => []
};
- return $" {string.Join('/', teams.Select(GetColoredShortTeamName))}";
+ return $" {teams.Join('/', GetColoredShortTeamName)}";
string GetColoredShortTeamName(Team t) => Utils.ColorString(t.GetColor(), Translator.GetString($"ShortTeamName.{t}").ToUpper());
}
diff --git a/Patches/GameStartManagerPatch.cs b/Patches/GameStartManagerPatch.cs
index 640544f0a..4d2a8e195 100644
--- a/Patches/GameStartManagerPatch.cs
+++ b/Patches/GameStartManagerPatch.cs
@@ -238,7 +238,7 @@ public static class GameStartManagerPatch
Logger.SendInGame(GetString("Error.InvalidColorPreventStart"), Color.yellow);
string msg = GetString("Error.InvalidColor");
- msg += "\n" + string.Join(",", invalidColor.Select(p => $"{p.GetRealName()}"));
+ msg += "\n" + invalidColor.Join(",", p => $"{p.GetRealName()}");
Utils.SendMessage(msg, importance: MessageImportance.Low);
}
@@ -576,7 +576,7 @@ public static class GameStartRandomMap
{
Logger.SendInGame(GetString("Error.InvalidColorPreventStart"), Color.yellow);
string msg = GetString("Error.InvalidColor");
- msg += "\n" + string.Join(",", invalidColor.Select(p => $"{p.GetRealName()}"));
+ msg += "\n" + invalidColor.Join(",", p => $"{p.GetRealName()}");
Utils.SendMessage(msg, importance: MessageImportance.Low);
return false;
}
diff --git a/Patches/HudPatch.cs b/Patches/HudPatch.cs
index 66b61b29a..698fb4012 100644
--- a/Patches/HudPatch.cs
+++ b/Patches/HudPatch.cs
@@ -1390,7 +1390,7 @@ internal static class TaskPanelBehaviourPatch
{
FinalTextBuilder.Append("\r\n\r\n")
.Append("")
- .Append(string.Join('\n', Main.EnumeratePlayerControls().Select(pc => new { pc, alive = pc.IsAlive() }).OrderByDescending(x => x.alive).Select(x => $"{(!x.alive ? "<#777777>" : "")}{HotPotato.GetIndicator(x.pc.PlayerId)}{(x.alive ? x.pc.PlayerId.ColoredPlayerName() : Main.AllPlayerNames.GetValueOrDefault(x.pc.PlayerId, $"ID {x.pc.PlayerId}"))}{(!x.alive ? $" <#ff0000>{GetString("Dead")}" : "")}")))
+ .Append(Main.CachedAllPlayerControls().Select(pc => new { pc, alive = pc.IsAlive() }).OrderByDescending(x => x.alive).Join('\n', x => $"{(!x.alive ? "<#777777>" : "")}{HotPotato.GetIndicator(x.pc.PlayerId)}{(x.alive ? x.pc.PlayerId.ColoredPlayerName() : Main.AllPlayerNames.GetValueOrDefault(x.pc.PlayerId, $"ID {x.pc.PlayerId}"))}{(!x.alive ? $" <#ff0000>{GetString("Dead")}" : "")}"))
.Append("");
break;
}
diff --git a/Patches/OutroPatch.cs b/Patches/OutroPatch.cs
index 0a157643b..23908ccfc 100644
--- a/Patches/OutroPatch.cs
+++ b/Patches/OutroPatch.cs
@@ -81,7 +81,7 @@ internal static class EndGamePatch
{
if (state.RoleHistory.Count > 0)
{
- string join = string.Join(" > ", state.RoleHistory.ConvertAll(x => x.ToColoredString()));
+ string join = state.RoleHistory.Join(" > ", x => x.ToColoredString());
sb.AppendLine($"{id.ColoredPlayerName()}: {join} > {state.MainRole.ToColoredString()}");
}
}
diff --git a/Patches/TextBoxPatch.cs b/Patches/TextBoxPatch.cs
index f94510d75..82b85b5fa 100644
--- a/Patches/TextBoxPatch.cs
+++ b/Patches/TextBoxPatch.cs
@@ -236,7 +236,7 @@ public static class TextBoxPatch
if (additionalInfo.Length == 0 && argName.Replace('[', '{').Replace(']', '}') is "{id}" or "{id1}" or "{id2}")
{
Dictionary allIds = Main.EnumeratePlayerControls().ToDictionary(x => x.PlayerId, x => x.PlayerId.ColoredPlayerName());
- additionalInfo = $"{Translator.GetString("PlayerIdList").TrimEnd(' ')}\n{string.Join('\n', allIds.Select(x => $"{x.Key} \uffeb {x.Value}"))}";
+ additionalInfo = $"{Translator.GetString("PlayerIdList").TrimEnd(' ')}\n{allIds.Join('\n', x => $"{x.Key} \uffeb {x.Value}")}";
// OptionShower.CurrentPage = 0;
}
@@ -278,7 +278,7 @@ public static class TextBoxPatch
: argName switch
{
"{id}" or "{id1}" or "{id2}" => $" ({byte.Parse(arg).ColoredPlayerName()})",
- "{ids}" => $" ({string.Join(", ", arg.Split(',').Select(x => byte.Parse(x).ColoredPlayerName()))})",
+ "{ids}" => $" ({arg.Split(',').Join(", ", x => byte.Parse(x).ColoredPlayerName())})",
"{role}" or "{addon}" or "[role]" when ChatCommands.GetRoleByName(arg, out CustomRoles role) => $" ({role.ToColoredString()})",
"{color}" when ColorUtility.TryParseHtmlString($"#{arg}", out Color color) => $" ({Utils.ColorString(color, "COLOR")})",
_ => string.Empty
diff --git a/Roles/Standard/Coven/Wyrd.cs b/Roles/Standard/Coven/Wyrd.cs
index 15b076c2b..9e618a8ab 100644
--- a/Roles/Standard/Coven/Wyrd.cs
+++ b/Roles/Standard/Coven/Wyrd.cs
@@ -211,7 +211,7 @@ public class Wyrd : CovenBase
if (!seerIsWyrd)
{
- var join = string.Join(", ", AllAction.Where(x => ActionSuicideSettings[x]).Select(x => Translator.GetString($"Wyrd.Suffix.SuicideWarningOnAction.{x}")));
+ var join = AllAction.Where(x => ActionSuicideSettings[x]).Join(", ", x => Translator.GetString($"Wyrd.Suffix.SuicideWarningOnAction.{x}"));
Suffix.AppendFormat(Translator.GetString("Wyrd.Suffix.SuicideWarnings"), join);
}
}
diff --git a/Roles/Standard/Crewmate/Chaos/Tornado.cs b/Roles/Standard/Crewmate/Chaos/Tornado.cs
index 06ad2bfc9..472ac5726 100644
--- a/Roles/Standard/Crewmate/Chaos/Tornado.cs
+++ b/Roles/Standard/Crewmate/Chaos/Tornado.cs
@@ -173,7 +173,7 @@ internal class Tornado : RoleBase
{
if (seer.PlayerId != target.PlayerId || !IsEnable || (seer.IsModdedClient() && !hud) || seer.PlayerId != TornadoPC.PlayerId || Tornados == null) return string.Empty;
- return string.Join(hud ? "\n" : ", ", Tornados.Select(x => $"Tornado {GetFormattedRoomName(x.Key.RoomName)} {GetFormattedVectorText(x.Key.Location)} ({(int)(TornadoDuration.GetInt() - (TimeStamp - x.Value) + 1)}s)"));
+ return Tornados.Join(hud ? "\n" : ", ", x => $"Tornado {GetFormattedRoomName(x.Key.RoomName)} {GetFormattedVectorText(x.Key.Location)} ({(int)(TornadoDuration.GetInt() - (TimeStamp - x.Value) + 1)}s)");
}
public override void ManipulateGameEndCheckCrew(PlayerState playerState, out bool keepGameGoing, out int countsAs)
diff --git a/Roles/Standard/Crewmate/Investigate/Captain.cs b/Roles/Standard/Crewmate/Investigate/Captain.cs
index a3b7c99b7..830addd2f 100644
--- a/Roles/Standard/Crewmate/Investigate/Captain.cs
+++ b/Roles/Standard/Crewmate/Investigate/Captain.cs
@@ -72,7 +72,7 @@ public class Captain : RoleBase
LateTask.New(() =>
{
- string msg = string.Format(Translator.GetString("Captain.TargetInfo"), TargetId.ColoredPlayerName(), string.Join(" ➡ ", TargetRooms.ConvertAll(x => Translator.GetString(x.ToString()))));
+ string msg = string.Format(Translator.GetString("Captain.TargetInfo"), TargetId.ColoredPlayerName(), TargetRooms.Join(" ➡ ", x => Translator.GetString(x.ToString())));
Utils.SendMessage(msg, CaptainId, CustomRoles.Captain.ToColoredString(), importance: MessageImportance.High);
TargetRooms = [];
}, 10f, "Captain Message");
diff --git a/Roles/Standard/Crewmate/Investigate/Catcher.cs b/Roles/Standard/Crewmate/Investigate/Catcher.cs
index 85f7bd98c..0ccf2481b 100644
--- a/Roles/Standard/Crewmate/Investigate/Catcher.cs
+++ b/Roles/Standard/Crewmate/Investigate/Catcher.cs
@@ -149,7 +149,7 @@ public class Catcher : RoleBase
{
if (CaughtRoles.Count >= MinPlayersTrappedToShowInfo.GetInt())
{
- string roles = string.Join(", ", CaughtRoles.Values.Select(x => x.ToColoredString()));
+ string roles = CaughtRoles.Values.Join(", ", x => x.ToColoredString());
Utils.SendMessage("\n", CatcherId, Translator.GetString("Catcher.CaughtRoles") + roles, importance: MessageImportance.High);
}
else
diff --git a/Roles/Standard/Crewmate/Investigate/Druid.cs b/Roles/Standard/Crewmate/Investigate/Druid.cs
index d1b95a1cf..4a929228e 100644
--- a/Roles/Standard/Crewmate/Investigate/Druid.cs
+++ b/Roles/Standard/Crewmate/Investigate/Druid.cs
@@ -189,7 +189,7 @@ public class Druid : RoleBase
Suffix.Clear().Append("\n");
Suffix.AppendLine($"<#00ffa5>{Triggers.Count} trigger{(Triggers.Count == 1 ? string.Empty : 's')} active")
- .Append(string.Join(", ", Triggers.Select(trigger => $"Trigger {GetFormattedRoomName(trigger.Value)} {GetFormattedVectorText(trigger.Key)}")))
+ .Append(Triggers.Join(", ", trigger => $"Trigger {GetFormattedRoomName(trigger.Value)} {GetFormattedVectorText(trigger.Key)}"))
.Append("");
return Suffix.ToString();
@@ -202,7 +202,7 @@ public class Druid : RoleBase
HudText.Clear();
HudText.AppendLine($"<#00ffa5>{Triggers.Count} trigger{(Triggers.Count == 1 ? string.Empty : 's')} active");
- HudText.Append(string.Join('\n', Triggers.Select(trigger => $"Trigger {GetFormattedRoomName(trigger.Value)} {GetFormattedVectorText(trigger.Key)}")));
+ HudText.Append(Triggers.Join('\n', trigger => $"Trigger {GetFormattedRoomName(trigger.Value)} {GetFormattedVectorText(trigger.Key)}"));
return HudText.ToString();
}
diff --git a/Roles/Standard/Crewmate/Investigate/Forensic.cs b/Roles/Standard/Crewmate/Investigate/Forensic.cs
index c952a0f35..8d02540e6 100644
--- a/Roles/Standard/Crewmate/Investigate/Forensic.cs
+++ b/Roles/Standard/Crewmate/Investigate/Forensic.cs
@@ -63,7 +63,7 @@ internal class Forensic : RoleBase
msg += ";" + string.Format(Translator.GetString("ForensicNoticeDeathReason"), Translator.GetString($"DeathReason.{Main.PlayerStates[tpc.PlayerId].deathReason}"));
if (ForensicCanknowAddons.GetBool())
- msg += ";" + string.Format(Translator.GetString("ForensicNoticeAddons"), string.Join(", ", tpc.GetCustomSubRoles().Select(x => x.ToColoredString())));
+ msg += ";" + string.Format(Translator.GetString("ForensicNoticeAddons"), tpc.GetCustomSubRoles().Join(", ", x => x.ToColoredString()));
DateTime deathTimeStamp = Main.PlayerStates[tpc.PlayerId].RealKiller.TimeStamp;
DateTime now = DateTime.Now;
@@ -75,10 +75,8 @@ internal class Forensic : RoleBase
if (ForensicCanknowColorType.GetBool() && realKiller != null && timeSpanSeconds >= ForensicCanknowColorTypeMinBodyAge.GetInt())
{
var darker = new List { 0, 1, 2, 6, 8, 9, 12, 15 };
- bool isDarker = darker.Contains(realKiller.CurrentOutfit.ColorId);
- Func selector = x => Utils.ColorString(Palette.PlayerColors[x], Palette.GetColorName(x));
- var colors = isDarker ? string.Join('/', darker.Select(selector)) : string.Join('/', Enumerable.Range(0, 18).Except(darker).Select(selector));
- var str = Translator.GetString(isDarker ? "WhispererInfo.ColorDark" : "WhispererInfo.ColorLight");
+ var colors = (darker.Contains(realKiller.CurrentOutfit.ColorId) ? darker : Enumerable.Range(0, 18).Except(darker)).Join('/', x => Utils.ColorString(Palette.PlayerColors[x], Palette.GetColorName(x)));
+ var str = Translator.GetString(darker.Contains(realKiller.CurrentOutfit.ColorId) ? "WhispererInfo.ColorDark" : "WhispererInfo.ColorLight");
msg += ";" + string.Format(Translator.GetString("ForensicNoticeColorType"), str, colors);
}
diff --git a/Roles/Standard/Crewmate/Investigate/FortuneTeller.cs b/Roles/Standard/Crewmate/Investigate/FortuneTeller.cs
index bce1dcdf5..4954958ce 100644
--- a/Roles/Standard/Crewmate/Investigate/FortuneTeller.cs
+++ b/Roles/Standard/Crewmate/Investigate/FortuneTeller.cs
@@ -89,7 +89,7 @@ public class FortuneTeller : RoleBase
roleList.Do(x => x.RoleList.Insert(IRandom.Instance.Next(x.RoleList.Count), x.Player.GetCustomRole()));
AllPlayerRoleList = roleList.ToDictionary(x => x.Player.PlayerId, x => x.RoleList);
- Logger.Info(string.Join(" ---- ", AllPlayerRoleList.Select(x => $"ID {x.Key} ({x.Key.GetPlayer().GetNameWithRole()}): {string.Join(", ", x.Value)}")), "FortuneTeller Roles");
+ Logger.Info(AllPlayerRoleList.Join(" ---- ", x => $"ID {x.Key} ({x.Key.GetPlayer().GetNameWithRole()}): {string.Join(", ", x.Value)}"), "FortuneTeller Roles");
}, 8f, log: false);
}
@@ -122,7 +122,7 @@ public class FortuneTeller : RoleBase
msg = string.Format(GetString("FortuneTellerCheck.TaskDone"), target.GetRealName(), target.GetCustomRole().ToColoredString());
else
{
- string roles = string.Join(", ", AllPlayerRoleList[target.PlayerId].Select(x => x.ToColoredString()));
+ string roles = AllPlayerRoleList[target.PlayerId].Join(", ", x => x.ToColoredString());
msg = string.Format(GetString("FortuneTellerCheckResult"), target.GetRealName(), roles);
}
diff --git a/Roles/Standard/Crewmate/Investigate/Inquisitor.cs b/Roles/Standard/Crewmate/Investigate/Inquisitor.cs
index c0b7b8f9d..1cc787772 100644
--- a/Roles/Standard/Crewmate/Investigate/Inquisitor.cs
+++ b/Roles/Standard/Crewmate/Investigate/Inquisitor.cs
@@ -55,9 +55,9 @@ public class Inquisitor : RoleBase
if (knownRoles.Count <= 1)
result = Translator.GetString("InquisitorNoInfo");
else if (KnowExactRolesAfterTasksFinished.GetBool() && voter.GetTaskState().IsTaskFinished)
- result = string.Join('\n', knownRoles.ConvertAll(x => $"{x.Id.ColoredPlayerName()}: {x.Role.ToColoredString()}"));
+ result = knownRoles.Join('\n', x => $"{x.Id.ColoredPlayerName()}: {x.Role.ToColoredString()}");
else
- result = string.Join(", ", knownRoles.ConvertAll(x => x.Id.ColoredPlayerName()));
+ result = knownRoles.Join(", ", x => x.Id.ColoredPlayerName());
Utils.SendMessage("\n", voter.PlayerId, string.Format(Translator.GetString("InquisitorVoteResult"), target.PlayerId.ColoredPlayerName(), result), importance: MessageImportance.High);
diff --git a/Roles/Standard/Crewmate/Investigate/Whisperer.cs b/Roles/Standard/Crewmate/Investigate/Whisperer.cs
index 6bdfd7827..c74f3a0d3 100644
--- a/Roles/Standard/Crewmate/Investigate/Whisperer.cs
+++ b/Roles/Standard/Crewmate/Investigate/Whisperer.cs
@@ -144,9 +144,9 @@ public class Whisperer : RoleBase
{
0 => string.Format(Translator.GetString("WhispererInfo.Color"), GetColorInfo(GameData.Instance.GetPlayerById(ID).DefaultOutfit.ColorId, out string colors), colors),
1 => string.Format(Translator.GetString("WhispererInfo.Time"), (int)Math.Round((LastMeetingStart - TimeStamp).TotalSeconds)),
- 2 => string.Format(Translator.GetString("WhispererInfo.Role"), state.MainRole.ToColoredString() + (state.SubRoles.Count == 0 ? string.Empty : string.Join(' ', state.SubRoles.ConvertAll(x => x.ToColoredString())))),
- 3 => string.Format(Translator.GetString("WhispererInfo.KillerRole"), killerState.MainRole.ToColoredString() + (killerState.SubRoles.Count == 0 ? string.Empty : string.Join(' ', killerState.SubRoles.ConvertAll(x => x.ToColoredString())))),
- 4 => string.Format(Translator.GetString(deathInfo.SameRoomPlayers.Length == 0 ? "WhispererInfo.AloneInRoomAtDeath" : "WhispererInfo.PlayersInSameRoomAtDeath"), string.Join(", ", deathInfo.SameRoomPlayers.Select(x => x.ColoredPlayerName()))),
+ 2 => string.Format(Translator.GetString("WhispererInfo.Role"), state.MainRole.ToColoredString() + (state.SubRoles.Count == 0 ? string.Empty : state.SubRoles.Join(' ', x => x.ToColoredString()))),
+ 3 => string.Format(Translator.GetString("WhispererInfo.KillerRole"), killerState.MainRole.ToColoredString() + (killerState.SubRoles.Count == 0 ? string.Empty : killerState.SubRoles.Join(' ', x => x.ToColoredString()))),
+ 4 => string.Format(Translator.GetString(deathInfo.SameRoomPlayers.Length == 0 ? "WhispererInfo.AloneInRoomAtDeath" : "WhispererInfo.PlayersInSameRoomAtDeath"), deathInfo.SameRoomPlayers.Join(", ", x => x.ColoredPlayerName())),
5 => string.Format(Translator.GetString(deathInfo.ActiveSabotage.HasValue ? "WhispererInfo.NoSabotageAtDeath" : "WhispererInfo.SabotageAtDeath"), Translator.GetString(deathInfo.ActiveSabotage.HasValue ? deathInfo.ActiveSabotage.ToString() : "None")),
6 => string.Format(Translator.GetString("WhispererInfo.DeathReason"), Translator.GetString($"DeathReason.{state.deathReason}")),
_ => string.Empty
@@ -190,8 +190,7 @@ public class Whisperer : RoleBase
{
var darker = new List { 0, 1, 2, 6, 8, 9, 12, 15 };
bool isDarker = darker.Contains(colorId);
- Func selector = x => Utils.ColorString(Palette.PlayerColors[x], Palette.GetColorName(x));
- colors = isDarker ? string.Join('/', darker.Select(selector)) : string.Join('/', Enumerable.Range(0, 18).Except(darker).Select(selector));
+ colors = (isDarker ? darker : Enumerable.Range(0, 18).Except(darker)).Join('/', x => Utils.ColorString(Palette.PlayerColors[x], Palette.GetColorName(x)));
return isDarker ? Translator.GetString("WhispererInfo.ColorDark") : Translator.GetString("WhispererInfo.ColorLight");
}
diff --git a/Roles/Standard/Crewmate/Power/Adventurer.cs b/Roles/Standard/Crewmate/Power/Adventurer.cs
index 671e43fe4..5c3a97de8 100644
--- a/Roles/Standard/Crewmate/Power/Adventurer.cs
+++ b/Roles/Standard/Crewmate/Power/Adventurer.cs
@@ -460,9 +460,9 @@ internal class Adventurer : RoleBase
? string.Format(
Translator.GetString("AdventurerIngredientsDisplay"),
Translator.GetString($"AdventurerGun.{SelectedWeaponToCraft}"),
- string.Join(' ', Ingredients[SelectedWeaponToCraft]
- .Select(x => $"{Utils.ColorString(ResourceDisplayData[x.Resource].Color, $"{ResourceDisplayData[x.Resource].Icon}")}" +
- $"{Utils.ColorString(x.Count > ResourceCounts[x.Resource] ? Color.red : Color.white, $"{x.Count}")}")))
+ Ingredients[SelectedWeaponToCraft].Join(' ', x =>
+ $"{Utils.ColorString(ResourceDisplayData[x.Resource].Color, $"{ResourceDisplayData[x.Resource].Icon}")}" +
+ $"{Utils.ColorString(x.Count > ResourceCounts[x.Resource] ? Color.red : Color.white, $"{x.Count}")}"))
: Translator.GetString("AdventurerVentToEnterCrafting");
finalText += "";
diff --git a/Roles/Standard/Crewmate/Support/Aid.cs b/Roles/Standard/Crewmate/Support/Aid.cs
index ee027aaad..b9b96f6dd 100644
--- a/Roles/Standard/Crewmate/Support/Aid.cs
+++ b/Roles/Standard/Crewmate/Support/Aid.cs
@@ -128,6 +128,6 @@ public class Aid : RoleBase
return string.Format(Translator.GetString("AidCounterSelf"), timeLeft);
}
- return seer.PlayerId == AidId ? string.Join("\n", ShieldedPlayers.Select(x => string.Format(Translator.GetString("AidCounterTarget"), x.Key.ColoredPlayerName(), (int)Math.Ceiling(x.Value.Remaining.TotalSeconds)))) : string.Empty;
+ return seer.PlayerId == AidId ? ShieldedPlayers.Join("\n", x => string.Format(Translator.GetString("AidCounterTarget"), x.Key.ColoredPlayerName(), (int)Math.Ceiling(x.Value.Remaining.TotalSeconds))) : string.Empty;
}
}
\ No newline at end of file
diff --git a/Roles/Standard/Crewmate/Support/Chef.cs b/Roles/Standard/Crewmate/Support/Chef.cs
index de4b95999..75d24907b 100644
--- a/Roles/Standard/Crewmate/Support/Chef.cs
+++ b/Roles/Standard/Crewmate/Support/Chef.cs
@@ -252,7 +252,7 @@ public class Chef : RoleBase
if (meeting) return string.Empty;
long now = Utils.TimeStamp;
- if (ActiveEvents.TryGetValue(target.PlayerId, out List events) && (seer.PlayerId == target.PlayerId || seer.PlayerId == ChefId)) return $"{string.Join('\n', events.Select(e => string.Format(Translator.GetString("ChefBoostSuffix"), GetEventString(e), e.Duration - (now - e.StartTimeStamp))))}";
+ if (ActiveEvents.TryGetValue(target.PlayerId, out List events) && (seer.PlayerId == target.PlayerId || seer.PlayerId == ChefId)) return $"{events.Join('\n', e => string.Format(Translator.GetString("ChefBoostSuffix"), GetEventString(e), e.Duration - (now - e.StartTimeStamp)))}";
if (RottenFood.TryGetValue(seer.PlayerId, out long ts) && seer.PlayerId == target.PlayerId) return string.Format(Translator.GetString("ChefRottenSuffix"), RottenTime.GetInt() - (now - ts));
diff --git a/Roles/Standard/Crewmate/Support/Doorjammer.cs b/Roles/Standard/Crewmate/Support/Doorjammer.cs
index 0faf6c400..09d945633 100644
--- a/Roles/Standard/Crewmate/Support/Doorjammer.cs
+++ b/Roles/Standard/Crewmate/Support/Doorjammer.cs
@@ -87,7 +87,7 @@ public class Doorjammer : RoleBase
public override string GetSuffix(PlayerControl seer, PlayerControl target, bool hud = false, bool meeting = false)
{
if (seer.PlayerId != DoorjammerId || seer.PlayerId != target.PlayerId || (seer.IsModdedClient() && !hud) || meeting) return string.Empty;
- string join = string.Join(", ", JammedRooms.ConvertAll(x => Translator.GetString(x.ToString())));
+ string join = JammedRooms.Join(", ", x => Translator.GetString(x.ToString()));
return string.Format(Translator.GetString("Doorjammer.Suffix"), JammedRooms.Count, MaxRoomsJammedAtOnce.GetInt(), string.IsNullOrWhiteSpace(join) ? string.Empty : $"\n{join}");
}
}
\ No newline at end of file
diff --git a/Roles/Standard/Crewmate/Support/Wizard.cs b/Roles/Standard/Crewmate/Support/Wizard.cs
index f7c1fd117..34c914309 100644
--- a/Roles/Standard/Crewmate/Support/Wizard.cs
+++ b/Roles/Standard/Crewmate/Support/Wizard.cs
@@ -288,7 +288,7 @@ public class Wizard : RoleBase
{
if (seer.PlayerId != WizardId || meeting) return string.Empty;
- if (PlayerBuffs.TryGetValue(target.PlayerId, out Dictionary buffs)) return string.Join('\n', buffs.Select(x => $"{Translator.GetString($"Wizard.Buff.{x.Key}")}: {Math.Round(x.Value, 1):N1}{GetBuffFormat(x.Key)}"));
+ if (PlayerBuffs.TryGetValue(target.PlayerId, out Dictionary buffs)) return buffs.Join('\n', x => $"{Translator.GetString($"Wizard.Buff.{x.Key}")}: {Math.Round(x.Value, 1):N1}{GetBuffFormat(x.Key)}");
if (seer.PlayerId != target.PlayerId || (seer.IsModdedClient() && !hud)) return string.Empty;
diff --git a/Roles/Standard/Impostor/Killing/Abyssbringer.cs b/Roles/Standard/Impostor/Killing/Abyssbringer.cs
index 8477340fc..9555cefe0 100644
--- a/Roles/Standard/Impostor/Killing/Abyssbringer.cs
+++ b/Roles/Standard/Impostor/Killing/Abyssbringer.cs
@@ -234,7 +234,7 @@ public class Abyssbringer : RoleBase
{
if (seer.PlayerId != target.PlayerId || seer.PlayerId != AbyssbringerId || meeting || (seer.IsModdedClient() && !hud) || BlackHoles.Count == 0) return string.Empty;
- return string.Format(Translator.GetString("Abyssbringer.Suffix"), BlackHoles.Count, string.Join('\n', BlackHoles.Select(x => GetBlackHoleFormatText(x.RoomName, x.PlayersConsumed))));
+ return string.Format(Translator.GetString("Abyssbringer.Suffix"), BlackHoles.Count, BlackHoles.Join('\n', x => GetBlackHoleFormatText(x.RoomName, x.PlayersConsumed)));
string GetBlackHoleFormatText(string roomName, int playersConsumed)
{
diff --git a/Roles/Standard/Impostor/Killing/Kamikaze.cs b/Roles/Standard/Impostor/Killing/Kamikaze.cs
index 193963520..cf4bbc910 100644
--- a/Roles/Standard/Impostor/Killing/Kamikaze.cs
+++ b/Roles/Standard/Impostor/Killing/Kamikaze.cs
@@ -114,7 +114,7 @@ internal class Kamikaze : RoleBase
}
}
- Logger.Info($"Murder {kamikazePc.GetRealName()}'s targets: {string.Join(", ", kk.MarkedPlayers.Select(x => GetPlayerById(x).GetNameWithRole()))}", "Kamikaze");
+ Logger.Info($"Murder {kamikazePc.GetRealName()}'s targets: {kk.MarkedPlayers.Join(", ", x => GetPlayerById(x).GetNameWithRole())}", "Kamikaze");
kk.MarkedPlayers.Clear();
}
}
diff --git a/Roles/Standard/Impostor/Killing/Wasp.cs b/Roles/Standard/Impostor/Killing/Wasp.cs
index 3aa7e1212..464d45af7 100644
--- a/Roles/Standard/Impostor/Killing/Wasp.cs
+++ b/Roles/Standard/Impostor/Killing/Wasp.cs
@@ -120,7 +120,7 @@ public class Wasp : RoleBase
{
LateTask.New(() =>
{
- string stung = string.Join(", ", MeetingKills.Select(x => x.ColoredPlayerName()));
+ string stung = MeetingKills.Join(", ", x => x.ColoredPlayerName());
string role = CustomRoles.Wasp.ToColoredString();
string text = string.Format(Translator.GetString("WaspStungPlayersMessage"), stung, role);
Utils.SendMessage(text, title: Translator.GetString("MessageTitle.Attention"), importance: MessageImportance.High);
diff --git a/Roles/Standard/Impostor/Killing/Witch.cs b/Roles/Standard/Impostor/Killing/Witch.cs
index 69e858433..cdda8d3d7 100644
--- a/Roles/Standard/Impostor/Killing/Witch.cs
+++ b/Roles/Standard/Impostor/Killing/Witch.cs
@@ -220,7 +220,7 @@ public class Witch : RoleBase
{
LateTask.New(() =>
{
- string cursed = string.Join(", ", spelledPlayers.Select(x => x.ColoredPlayerName()));
+ string cursed = spelledPlayers.Join(", ", x => x.ColoredPlayerName());
string role = IsHM ? CustomRoles.HexMaster.ToColoredString() : CustomRoles.Witch.ToColoredString();
string text = string.Format(GetString("WitchCursedPlayersMessage"), cursed, role);
Utils.SendMessage(text, title: GetString("MessageTitle.Attention"), importance: MessageImportance.High);
diff --git a/Roles/Standard/Impostor/Miscellaneous/Frightener.cs b/Roles/Standard/Impostor/Miscellaneous/Frightener.cs
index 6f848350c..cd945b3f6 100644
--- a/Roles/Standard/Impostor/Miscellaneous/Frightener.cs
+++ b/Roles/Standard/Impostor/Miscellaneous/Frightener.cs
@@ -95,6 +95,6 @@ public class Frightener : RoleBase
public override string GetSuffix(PlayerControl seer, PlayerControl target, bool hud = false, bool meeting = false)
{
if (seer.PlayerId != FrightenerId || seer.PlayerId != target.PlayerId || (seer.IsModdedClient() && !hud) || meeting || AlarmedPlayers.Count == 0) return string.Empty;
- return string.Format(Translator.GetString("Frightener.Suffix"), string.Join(", ", AlarmedPlayers.Select(x => x.ColoredPlayerName())));
+ return string.Format(Translator.GetString("Frightener.Suffix"), AlarmedPlayers.Join(", ", x => x.ColoredPlayerName()));
}
}
\ No newline at end of file
diff --git a/Roles/Standard/Neutral/Evil/Gaslighter.cs b/Roles/Standard/Neutral/Evil/Gaslighter.cs
index 0087778cb..411cb8ff3 100644
--- a/Roles/Standard/Neutral/Evil/Gaslighter.cs
+++ b/Roles/Standard/Neutral/Evil/Gaslighter.cs
@@ -187,7 +187,7 @@ public class Gaslighter : RoleBase
{
LateTask.New(() =>
{
- string cursed = string.Join(", ", spelledPlayers.Select(x => x.ColoredPlayerName()));
+ string cursed = spelledPlayers.Join(", ", x => x.ColoredPlayerName());
string role = IRandom.Instance.Next(2) == 0 ? CustomRoles.HexMaster.ToColoredString() : CustomRoles.Witch.ToColoredString();
string text = string.Format(Translator.GetString("WitchCursedPlayersMessage"), cursed, role);
Utils.SendMessage(text, title: Translator.GetString("MessageTitle.Attention"), importance: MessageImportance.High);
diff --git a/Roles/Standard/Neutral/Killing/Bargainer.cs b/Roles/Standard/Neutral/Killing/Bargainer.cs
index 4e8e458e4..7049d0bb0 100644
--- a/Roles/Standard/Neutral/Killing/Bargainer.cs
+++ b/Roles/Standard/Neutral/Killing/Bargainer.cs
@@ -486,14 +486,14 @@ internal class Bargainer : RoleBase
if (seer.IsModdedClient()) result += "";
- result += string.Join(' ', bg.ActiveItems.Select(x =>
+ result += bg.ActiveItems.Join(' ', x =>
{
long timeLeft = x.Duration - (Utils.TimeStamp - x.ActivateTimeStamp) + 1;
string icon = Icons[x.Item];
if (x.Item == Item.LensOfTruth && x.Target != byte.MaxValue) icon = Utils.ColorString(Main.PlayerColors[x.Target], icon);
return seer.IsModdedClient() && timeLeft < 10 ? $"{icon} ({timeLeft}s)" : icon;
- }));
+ });
if (seer.IsModdedClient()) result += "";
diff --git a/Roles/Standard/Neutral/Killing/Chemist.cs b/Roles/Standard/Neutral/Killing/Chemist.cs
index f666d6c38..733611bb5 100644
--- a/Roles/Standard/Neutral/Killing/Chemist.cs
+++ b/Roles/Standard/Neutral/Killing/Chemist.cs
@@ -689,9 +689,9 @@ internal class Chemist : RoleBase
(List<(int Count, Item Item)> ingredients, List<(int Count, Item Item)> results) = Processes[CurrentFactory][SelectedProcess];
Func<(int Count, Item Item), string> selector = x => $"{x.Count} {Utils.ColorString(GetItemColor(x.Item), $"{GetChemicalForm(x.Item)}")}";
- Suffix.Append(string.Join(", ", ingredients.Select(selector)));
+ Suffix.Append(ingredients.Join(", ", selector));
Suffix.Append(" → ");
- Suffix.Append(string.Join(", ", results.Select(selector)));
+ Suffix.Append(results.Join(", ", selector));
}
if ((AcidPlayersDieOptions)AcidPlayersDie.GetValue() == AcidPlayersDieOptions.AfterTime)
diff --git a/Roles/Standard/Neutral/Killing/Evolver.cs b/Roles/Standard/Neutral/Killing/Evolver.cs
index b27294259..cc3f62f63 100644
--- a/Roles/Standard/Neutral/Killing/Evolver.cs
+++ b/Roles/Standard/Neutral/Killing/Evolver.cs
@@ -264,7 +264,7 @@ public class Evolver : RoleBase
{
if (seer.PlayerId != target.PlayerId || seer.PlayerId != EvolverPC.PlayerId || (seer.IsModdedClient() && !hud) || meeting || ChooseTimer == 0 || Upgrades.Count == 0 || SelectedUpgradeIndex == -1) return string.Empty;
- return string.Format(Translator.GetString("EvolverSuffix"), ChooseTimer, Translator.GetString($"EvolverUpgrade.{Upgrades[SelectedUpgradeIndex]}"), string.Join(", ", Upgrades.ConvertAll(x => Translator.GetString($"EvolverUpgrade.{x}"))));
+ return string.Format(Translator.GetString("EvolverSuffix"), ChooseTimer, Translator.GetString($"EvolverUpgrade.{Upgrades[SelectedUpgradeIndex]}"), Upgrades.Join(", ", x => Translator.GetString($"EvolverUpgrade.{x}")));
}
public override void GetProgressText(byte playerId, bool comms, StringBuilder resultText)
diff --git a/Roles/Standard/Neutral/Killing/Spider.cs b/Roles/Standard/Neutral/Killing/Spider.cs
index 8ab453e24..c21367b1d 100644
--- a/Roles/Standard/Neutral/Killing/Spider.cs
+++ b/Roles/Standard/Neutral/Killing/Spider.cs
@@ -231,6 +231,6 @@ public class Spider : RoleBase
public override string GetSuffix(PlayerControl seer, PlayerControl target, bool hud = false, bool meeting = false)
{
if (seer.PlayerId != SpiderId || seer.PlayerId != target.PlayerId || (seer.IsModdedClient() && !hud) || meeting) return string.Empty;
- return string.Join('\n', Webs.Where(x => x.Value.Count > 0).Select(x => $"{LocateArrow.GetArrow(seer, x.Key)} {x.Value.Count} ({Math.Max(0, x.Value.Values.Min() - Utils.TimeStamp)}s)"));
+ return Webs.Where(x => x.Value.Count > 0).Join('\n', x => $"{LocateArrow.GetArrow(seer, x.Key)} {x.Value.Count} ({Math.Max(0, x.Value.Values.Min() - Utils.TimeStamp)}s)");
}
}