fixes & improvements

This commit is contained in:
Gurge44 committed 2025-07-03 14:03:35 +02:00
1 parent d5440356ad
commit 1982b79509
16 files changed
+447 -347

No files matched your search

+78 -58
View File
@@ -13,10 +13,10 @@ public static class BedWars
private static int SpeedPotionDuration = 30;
private static int InvisPotionDuration = 20;
private static int ReviveTime = 15;
private static int IronGenerationInterval = 2;
private static int GoldGenerationInterval = 5;
private static int EmeraldGenerationInterval = 10;
private static int DiamondGenerationInterval = 10;
private static int IronGenerationInterval = 3;
private static int GoldGenerationInterval = 10;
private static int EmeraldGenerationInterval = 20;
private static int DiamondGenerationInterval = 25;
private static int GracePeriod = 90;
private static int HealWaitAfterDamage = 5;
private static int MaxHealth = 20;
@@ -64,7 +64,7 @@ public static class BedWars
private static OptionItem IronSwordDamageMultiplierOption;
private static OptionItem DiamondSwordDamageMultiplierOption;
public static (Color Color, string Team) WinnerData = (Color.white, "No one wins");
public static (Color Color, string Team) Winner = (Color.white, "No one wins");
public static void SetupCustomOption()
{
@@ -89,22 +89,22 @@ public static class BedWars
.SetColor(color)
.SetGameMode(gameMode);
IronGenerationIntervalOption = new IntegerOptionItem(id++, "BedWars.IronGenerationIntervalOption", new(1, 60, 1), 2, tab)
IronGenerationIntervalOption = new IntegerOptionItem(id++, "BedWars.IronGenerationIntervalOption", new(1, 60, 1), 3, tab)
.SetValueFormat(OptionFormat.Seconds)
.SetColor(color)
.SetGameMode(gameMode);
GoldGenerationIntervalOption = new IntegerOptionItem(id++, "BedWars.GoldGenerationIntervalOption", new(1, 60, 1), 5, tab)
GoldGenerationIntervalOption = new IntegerOptionItem(id++, "BedWars.GoldGenerationIntervalOption", new(1, 60, 1), 10, tab)
.SetValueFormat(OptionFormat.Seconds)
.SetColor(color)
.SetGameMode(gameMode);
EmeraldGenerationIntervalOption = new IntegerOptionItem(id++, "BedWars.EmeraldGenerationIntervalOption", new(1, 60, 1), 10, tab)
EmeraldGenerationIntervalOption = new IntegerOptionItem(id++, "BedWars.EmeraldGenerationIntervalOption", new(1, 60, 1), 20, tab)
.SetValueFormat(OptionFormat.Seconds)
.SetColor(color)
.SetGameMode(gameMode);
DiamondGenerationIntervalOption = new IntegerOptionItem(id++, "BedWars.DiamondGenerationIntervalOption", new(1, 60, 1), 10, tab)
DiamondGenerationIntervalOption = new IntegerOptionItem(id++, "BedWars.DiamondGenerationIntervalOption", new(1, 60, 1), 25, tab)
.SetValueFormat(OptionFormat.Seconds)
.SetColor(color)
.SetGameMode(gameMode);
@@ -257,12 +257,13 @@ public static class BedWars
{
reason = GameOverReason.ImpostorsByKill;
if (GracePeriodEnd > Utils.TimeStamp || WinnerData.Team != "No one wins") return false;
if (!Main.IntroDestroyed || IsGracePeriod || GameStates.IsEnded) return false;
if (Enum.GetValues<BedWarsTeam>().FindFirst(x => Main.AllAlivePlayerControls.Select(p => p.PlayerId).Concat(Reviving).All(p => !Data.TryGetValue(p, out PlayerData data) || data.Team == x), out BedWarsTeam team))
{
WinnerData = (team.GetColor(), team.GetName() + Translator.GetString("Win"));
Winner = (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");
return true;
}
@@ -271,7 +272,7 @@ public static class BedWars
public static void OnCheckMurder(PlayerControl killer, PlayerControl target)
{
if (GracePeriodEnd > Utils.TimeStamp || !Data.TryGetValue(killer.PlayerId, out PlayerData killerData) || !Data.TryGetValue(target.PlayerId, out PlayerData targetData) || killerData.Team == targetData.Team) return;
if (IsGracePeriod || !Data.TryGetValue(killer.PlayerId, out PlayerData killerData) || !Data.TryGetValue(target.PlayerId, out PlayerData targetData) || killerData.Team == targetData.Team) return;
if (AllNetObjects.Values.Any(x => x.Bed.Breaking.Contains(killer.PlayerId)))
{
@@ -302,6 +303,8 @@ public static class BedWars
public static void Initialize()
{
GracePeriodEnd = Utils.TimeStamp + 60;
Data = [];
InShop = [];
Suffix = [];
@@ -311,11 +314,9 @@ public static class BedWars
Trapped = [];
Reviving = [];
WinnerData = (Color.white, "No one wins");
Winner = (Color.white, "No one wins");
FixedUpdatePatch.LastUpdate = [];
GracePeriodEnd = Utils.TimeStamp + 30;
SpeedPotionDuration = SpeedPotionDurationOption.GetInt();
InvisPotionDuration = InvisPotionDurationOption.GetInt();
ReviveTime = ReviveTimeOption.GetInt();
@@ -348,7 +349,9 @@ public static class BedWars
{
if (Options.CurrentGameMode != CustomGameMode.BedWars) yield break;
yield return new WaitForSeconds(3f);
Winner = (Color.white, "No one wins");
yield return new WaitForSecondsRealtime(3f);
if (GameStates.IsEnded || !GameStates.InGame || GameStates.IsLobby)
{
@@ -392,6 +395,8 @@ public static class BedWars
pc.TP(data.Base.SpawnPosition);
pc.RpcResetAbilityCooldown();
playerTeams.DoIf(x => x.Key != PlayerControl.LocalPlayer.PlayerId && x.Value == team, x => x.Key.GetPlayer()?.RpcSetRoleDesync(RoleTypes.Impostor, pc.OwnerId));
Data[pc.PlayerId] = data;
yield return new WaitForSeconds(0.2f);
@@ -469,6 +474,13 @@ public static class BedWars
private static long GracePeriodEnd;
public static bool IsGracePeriod => GracePeriodEnd > Utils.TimeStamp;
public static bool IsNotInLocalPlayersTeam(PlayerControl pc)
{
return !Data.TryGetValue(pc.PlayerId, out PlayerData data) || !Data.TryGetValue(PlayerControl.LocalPlayer.PlayerId, out PlayerData lpData) || data.Team != lpData.Team;
}
//[HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.FixedUpdate))]
public static class FixedUpdatePatch
{
@@ -476,10 +488,12 @@ public static class BedWars
public static void Postfix(PlayerControl __instance)
{
if (!AmongUsClient.Instance.AmHost || !GameStates.IsInTask || ExileController.Instance || Options.CurrentGameMode != CustomGameMode.BedWars || !Main.IntroDestroyed || __instance == null || __instance.PlayerId >= 254 || WinnerData.Team != "No one wins" || Utils.GameStartTimeStamp + 15 > Utils.TimeStamp || !Data.TryGetValue(__instance.PlayerId, out PlayerData data)) return;
if (!AmongUsClient.Instance.AmHost || !GameStates.IsInTask || ExileController.Instance || Options.CurrentGameMode != CustomGameMode.BedWars || !Main.IntroDestroyed || GameStates.IsEnded || __instance == null || __instance.PlayerId >= 254 || Utils.GameStartTimeStamp + 20 > Utils.TimeStamp) return;
if (__instance.IsHost()) ItemGenerators.ForEach(x => x.Update());
if (!Data.TryGetValue(__instance.PlayerId, out PlayerData data)) return;
long now = Utils.TimeStamp;
if (!LastUpdate.TryGetValue(__instance.PlayerId, out long lastUpdate) || lastUpdate != now)
@@ -615,7 +629,7 @@ public static class BedWars
public void Damage(PlayerControl pc, float damage, PlayerControl killer = null)
{
if (Health <= 0 || GracePeriodEnd > Utils.TimeStamp) return;
if (Health <= 0 || IsGracePeriod) return;
damage /= Armor switch
{
@@ -687,7 +701,7 @@ public static class BedWars
if (NameNotifyManager.GetNameNotify(pc, out string notify) && notify.Length > 0)
sb.AppendLine(notify);
sb.AppendLine(GracePeriodEnd > Utils.TimeStamp ? Translator.GetString("Bedwars.GracePeriod") : GetHealthInfo());
sb.AppendLine(IsGracePeriod ? Translator.GetString("Bedwars.GracePeriod") : GetHealthInfo());
if (InShop.TryGetValue(pc.PlayerId, out Shop shop))
{
@@ -696,7 +710,7 @@ public static class BedWars
}
int lines = sb.ToString().Count(x => x == '\n');
sb.Insert(0, Utils.ColorString(Color.clear, ".") + new string('\n', Math.Max(0, 15 - lines)));
sb.Insert(0, Utils.ColorString(Color.clear, ".") + new string('\n', Math.Max(0, 14 - lines)));
sb.Append(new string('\n', Math.Max(0, 5 - lines)));
sb.AppendLine(GetArmorInfo());
@@ -715,11 +729,13 @@ public static class BedWars
if (GracePeriodEnd <= Utils.TimeStamp)
{
sb.AppendLine(GetHealthInfo());
sb.AppendLine(GetArmorInfo());
sb.Append(GetHealthInfo());
sb.Append(' ');
sb.Append(' ');
sb.Append(GetArmorInfo());
if (Inventory.Items.ContainsKey(Item.TNT) && ItemDisplayData.TryGetValue(Item.TNT, out ItemDisplay display))
sb.Append(Utils.ColorString(display.Color, $"{display.Icon} {display.Name.Invoke()} {display.Icon}"));
sb.Append(Utils.ColorString(display.Color, $" {display.Icon} {display.Name.Invoke()} {display.Icon}"));
}
return $"<#ffffff>{sb.ToString().Trim()}</color>";
@@ -727,12 +743,12 @@ public static class BedWars
private string GetArmorInfo()
{
return $"{Translator.GetString("BedWars.Suffix.Armor")} {(Armor.HasValue && ItemDisplayData.TryGetValue(Armor.Value, out ItemDisplay display) ? Utils.ColorString(display.Color, display.Icon.ToString()) : Translator.GetString("None"))}";
return $"<size=80%>{Translator.GetString("BedWars.Suffix.Armor")} {(Armor.HasValue && ItemDisplayData.TryGetValue(Armor.Value, out ItemDisplay display) ? Utils.ColorString(display.Color, display.Icon.ToString()) : Translator.GetString("None"))}</size>";
}
private string GetHealthInfo()
{
return Utils.ColorString(GetHealthColor(), $"{Math.Round(Health, 1)}/{MaxHealth} ♥");
return Utils.ColorString(GetHealthColor(), $"{Math.Round(Health, 1)} ♥");
}
private Color GetHealthColor()
@@ -775,21 +791,21 @@ public static class BedWars
[MapNames.Polus] = new()
{
[BedWarsTeam.Blue] = new(new(3.32f, -21.65f), SystemTypes.LifeSupp, new(0.96f, -23.57f), new(3.57f, -24.45f), new(0.89f, -16.03f)),
[BedWarsTeam.Yellow] = new(new(20.88f, -21.28f), SystemTypes.Admin, new(22.75f, -20.75f), new(24.43f, -22.28f), new(24.87f, -20.71f)),
[BedWarsTeam.Yellow] = new(new(21.21f, -23f), SystemTypes.Admin, new(21.78f, -25.26f), new(20.74f, -21.53f), new(24.94f, -20.67f)),
[BedWarsTeam.Red] = new(new(31.43f, -7.53f), SystemTypes.Laboratory, new(33.54f, -5.84f), new(35.93f, -6.05f), new(40.41f, -6.73f)),
[BedWarsTeam.Green] = new(new(16.72f, -3.16f), SystemTypes.Dropship, new(14.94f, -0.9f), new(14.94f, -2.67f), new(16.69f, -0.6f))
},
[MapNames.Airship] = new()
{
[BedWarsTeam.Blue] = new(new(-17.47f, -1.09f), SystemTypes.Cockpit, new(-19.86f, 0.78f), new(-22.49f, 0.13f), new(-22.1f, -1.15f)),
[BedWarsTeam.Yellow] = new(new(6.04f, -10.45f), SystemTypes.Security, new(8.59f, -10.62f), new(8.4f, -12.47f), new(10.29f, -16.15f)),
[BedWarsTeam.Blue] = new(new(-17.47f, -1.09f), SystemTypes.Cockpit, new(-19.86f, 0.78f), new(-22.49f, -0.1f), new(-22.1f, -1.15f)),
[BedWarsTeam.Yellow] = new(new(6.04f, -10.45f), SystemTypes.Security, new(8.59f, -10.85f), new(8.4f, -12.47f), new(10.29f, -16.15f)),
[BedWarsTeam.Red] = new(new(33.7f, -0.88f), SystemTypes.CargoBay, new(38.41f, 1.29f), new(38.41f, -0.69f), new(37.37f, -3.46f)),
[BedWarsTeam.Green] = new(new(4.54f, 15.61f), SystemTypes.MeetingRoom, new(10.8f, 9.11f), new(12.66f, 6.29f), new(16.11f, 15.26f))
[BedWarsTeam.Green] = new(new(4.54f, 15.61f), SystemTypes.MeetingRoom, new(12f, 9.11f), new(12.66f, 6.29f), new(16.11f, 15.26f))
},
[MapNames.Fungle] = new()
{
[BedWarsTeam.Blue] = new(new(15.18f, -11.91f), SystemTypes.Jungle, new(11.07f, -14f), new(11.07f, -16.18f), new(15.15f, -16.06f)),
[BedWarsTeam.Yellow] = new(new(19.26f, 11.07f), SystemTypes.Comms, new(20.19f, 13.63f), new(22.89f, 13.32f), new(24.24f, 14.41f)),
[BedWarsTeam.Yellow] = new(new(19.83f, 11.07f), SystemTypes.Comms, new(20.19f, 13.63f), new(22.89f, 13.32f), new(24.24f, 14.41f)),
[BedWarsTeam.Red] = new(new(-7.39f, 8.81f), SystemTypes.Dropship, new(-9.86f, 13.43f), new(-7.42f, 12.96f), new(-11.21f, 12.5f)),
[BedWarsTeam.Green] = new(new(-15.55f, -7.04f), SystemTypes.Kitchen, new(-17.22f, -9.32f), new(-13.78f, -9.32f), new(-22.83f, -7.19f))
}
@@ -813,22 +829,22 @@ public static class BedWars
},
[MapNames.Polus] = new()
{
[Item.Iron] = [new(1.44f, -19.91f), new(21.67f, -24.86f), new(29.83f, -7.25f), new(18.54f, -1.68f)],
[Item.Gold] = [new(1.44f, -20.33f), new(21.67f, -25.26f), new(29.83f, -7.77f), new(18.54f, -2.2f)],
[Item.Iron] = [new(1.44f, -19.91f), new(20.09f, -25.15f), new(29.83f, -7.25f), new(18.54f, -1.68f)],
[Item.Gold] = [new(1.44f, -20.33f), new(20.09f, -24.74f), new(29.83f, -7.77f), new(18.54f, -2.2f)],
[Item.Emerald] = [new(11.73f, -15.87f), new(20.64f, -12.2f)],
[Item.Diamond] = [new(35.54f, -21.57f), new(23.91f, -6.82f), new(7.27f, -12.07f), new(12.67f, -23.38f)]
},
[MapNames.Airship] = new()
{
[Item.Iron] = [new(-21.58f, -3.44f), new(5.61f, -14.36f), new(28.95f, -1.25f), new(10.72f, 14.23f)],
[Item.Gold] = [new(-21.06f, -3.44f), new(6.13f, -14.36f), new(28.95f, -1.77f), new(11.34f, 14.23f)],
[Item.Gold] = [new(-21f, -3.44f), new(6.23f, -14.36f), new(28.95f, -1.77f), new(11.34f, 14.23f)],
[Item.Emerald] = [new(19.04f, 0.07f)],
[Item.Diamond] = [new(-13.6f, -14.38f), new(19.37f, -3.95f), new(19.86f, 11.76f), new(-0.8f, -2.55f)]
},
[MapNames.Fungle] = new()
{
[Item.Iron] = [new(17.63f, -12.48f), new(25.22f, 11.33f), new(-8.63f, 10.33f), new(-13.67f, -7.08f)],
[Item.Gold] = [new(18.05f, -12.48f), new(24.6f, 11.33f), new(-8.63f, 9.81f), new(-13.67f, -7.6f)],
[Item.Gold] = [new(18.19f, -12.48f), new(24.6f, 11.33f), new(-8.63f, 9.81f), new(-13.67f, -7.6f)],
[Item.Emerald] = [new(9.37f, 0.99f), new(-3.15f, -10.55f), new(2f, -1.57f)],
[Item.Diamond] = [new(22.28f, 3.18f), new(2.86f, 1.28f), new(-17.61f, 2.65f), new(-4.56f, -14.77f)]
}
@@ -852,7 +868,7 @@ public static class BedWars
{
return team switch
{
BedWarsTeam.Blue => Color.blue,
BedWarsTeam.Blue => Color.cyan,
BedWarsTeam.Yellow => Color.yellow,
BedWarsTeam.Green => Color.green,
BedWarsTeam.Red => Color.red,
@@ -1024,7 +1040,6 @@ public static class BedWars
itemsInCategory.Add($"{display.Name.Invoke()} {Utils.ColorString(display.Color, display.Icon.ToString())}");
}
Logger.Warn("we got here 0", "debug");
return string.Format(Translator.GetString("Bedwars.Shop.ItemShopSuffix.CategorySelection"), Translator.GetString($"BedWars.ItemCategory.{itemCategory}"), string.Join(' ', itemsInCategory));
}
else
@@ -1040,7 +1055,6 @@ public static class BedWars
if (!ItemCost.TryGetValue(selectedItem, out (Item Resource, int Count) cost) || !ItemDisplayData.TryGetValue(cost.Resource, out ItemDisplay costDisplay)) return string.Empty;
var costString = $"{cost.Count} {Utils.ColorString(costDisplay.Color, costDisplay.Icon.ToString())}";
Logger.Warn("we got here 1", "debug");
return string.Format(Translator.GetString("Bedwars.Shop.ItemShopSuffix.ItemSelection"), itemName, itemIcon, itemDescription, costString);
}
}
@@ -1091,7 +1105,6 @@ public static class BedWars
? "\n" + Translator.GetString("BedWars.Upgrade.AlreadyBought")
: string.Empty;
Logger.Warn("we got here 2", "debug");
return string.Format(Translator.GetString("Bedwars.Shop.UpgradeShopSuffix"), Translator.GetString($"BedWars.Upgrade.{selectedUpgrade}"), Translator.GetString($"BedWars.UpgradeDescription.{selectedUpgrade}"), alreadyBought, costString);
}
}
@@ -1144,9 +1157,9 @@ public static class BedWars
private abstract class ItemGenerator
{
public abstract BedWarsItemGenerator NetObject { get; set; }
public abstract int GenerationInterval { get; set; }
public abstract Item GeneratedItem { get; set; }
protected abstract BedWarsItemGenerator NetObject { get; }
protected abstract int GenerationInterval { get; }
protected abstract Item GeneratedItem { get; }
private long LastGenerationTime = Utils.TimeStamp;
private int Generated;
@@ -1156,12 +1169,14 @@ public static class BedWars
int oldNum = Generated;
long now = Utils.TimeStamp;
if (LastGenerationTime + GenerationInterval <= now)
bool onBase = GeneratedItem is Item.Iron or Item.Gold;
if ((GracePeriodEnd <= now || onBase) && LastGenerationTime + GenerationInterval <= now)
{
LastGenerationTime = now;
Generated++;
if (GeneratedItem is Item.Iron or Item.Gold)
if (onBase)
{
BedWarsTeam team = Enum.GetValues<BedWarsTeam>().MinBy(x => Vector2.Distance(Bases[Main.CurrentMap][x].BedPosition, NetObject.Position));
if (Upgrades.TryGetValue(team, out HashSet<Upgrade> upgrades) && upgrades.Contains(Upgrade.Forge)) Generated++;
@@ -1185,30 +1200,30 @@ public static class BedWars
private sealed class IronGenerator(BedWarsItemGenerator netObject) : ItemGenerator
{
public override BedWarsItemGenerator NetObject { get; set; } = netObject;
public override int GenerationInterval { get; set; } = IronGenerationInterval;
public override Item GeneratedItem { get; set; } = Item.Iron;
protected override BedWarsItemGenerator NetObject { get; } = netObject;
protected override int GenerationInterval { get; } = IronGenerationInterval;
protected override Item GeneratedItem => Item.Iron;
}
private sealed class GoldGenerator(BedWarsItemGenerator netObject) : ItemGenerator
{
public override BedWarsItemGenerator NetObject { get; set; } = netObject;
public override int GenerationInterval { get; set; } = GoldGenerationInterval;
public override Item GeneratedItem { get; set; } = Item.Gold;
protected override BedWarsItemGenerator NetObject { get; } = netObject;
protected override int GenerationInterval { get; } = GoldGenerationInterval;
protected override Item GeneratedItem => Item.Gold;
}
private sealed class EmeraldGenerator(BedWarsItemGenerator netObject) : ItemGenerator
{
public override BedWarsItemGenerator NetObject { get; set; } = netObject;
public override int GenerationInterval { get; set; } = EmeraldGenerationInterval;
public override Item GeneratedItem { get; set; } = Item.Emerald;
protected override BedWarsItemGenerator NetObject { get; } = netObject;
protected override int GenerationInterval { get; } = EmeraldGenerationInterval;
protected override Item GeneratedItem => Item.Emerald;
}
private sealed class DiamondGenerator(BedWarsItemGenerator netObject) : ItemGenerator
{
public override BedWarsItemGenerator NetObject { get; set; } = netObject;
public override int GenerationInterval { get; set; } = DiamondGenerationInterval;
public override Item GeneratedItem { get; set; } = Item.Diamond;
protected override BedWarsItemGenerator NetObject { get; } = netObject;
protected override int GenerationInterval { get; } = DiamondGenerationInterval;
protected override Item GeneratedItem => Item.Diamond;
}
public enum Item // Item count: 4+5+3+2+3+5 = 22
@@ -1471,9 +1486,14 @@ public static class BedWars
var sb = new StringBuilder();
sb.Append(Utils.ColorString(display.Color, display.Icon.ToString()));
sb.Append("<sub>");
sb.Append(count);
sb.Append("</sub>");
if (count > 1)
{
sb.Append("<sub>");
sb.Append(count);
sb.Append("</sub>");
}
itemsDisplays.Add(sb.ToString());
if (i++ == SelectedSlot) bottomText = display.Name.Invoke();
+8 -1
View File
@@ -295,6 +295,8 @@ public static class CaptureTheFlag
Main.AllPlayerKillCooldown.SetAllValues(TagCooldown.GetFloat());
yield return new WaitForSecondsRealtime(3f);
// Assign players to teams
List<PlayerControl> players = Main.AllAlivePlayerControls.Shuffle().ToList();
if (Main.GM.Value) players.RemoveAll(x => x.IsHost());
@@ -322,7 +324,7 @@ public static class CaptureTheFlag
yield return null;
}
yield return new WaitForSeconds(3f);
yield return new WaitForSeconds(0.5f);
// Create flags
(Vector2 Position, string RoomName) blueFlagBase = BlueFlagBase;
@@ -474,6 +476,11 @@ public static class CaptureTheFlag
AURoleOptions.PhantomCooldown = 5f;
}
public static bool IsNotInLocalPlayersTeam(PlayerControl pc)
{
return !PlayerTeams.TryGetValue(pc.PlayerId, out CTFTeam team) || !PlayerTeams.TryGetValue(PlayerControl.LocalPlayer.PlayerId, out CTFTeam lpTeam) || team != lpTeam;
}
private static void SendRPC()
{
var w = Utils.CreateRPC(CustomRPC.CTFSync);
+22 -1
View File
@@ -290,7 +290,7 @@ public static class KingOfTheZones
{
if (Options.CurrentGameMode != CustomGameMode.KingOfTheZones) yield break;
yield return new WaitForSeconds(3f);
yield return new WaitForSecondsRealtime(3f);
PlayerControl[] aapc = Main.AllAlivePlayerControls;
bool showTutorial = aapc.ExceptBy(PlayedFCs, x => x.FriendCode).Count() > aapc.Length / 2;
@@ -586,12 +586,15 @@ public static class KingOfTheZones
switch (aapc.Length)
{
case 0:
{
ResetSkins();
CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Draw);
CustomWinnerHolder.WinnerIds = Main.PlayerStates.Keys.ToHashSet();
reason = GameOverReason.CrewmateDisconnect;
return true;
}
case 1:
{
ResetSkins();
KOTZTeam winner = PlayerTeams[aapc[0].PlayerId];
Color color = winner.GetColor();
@@ -599,13 +602,31 @@ public static class KingOfTheZones
WinnerData = (color, Utils.ColorString(color, GetString($"KOTZ.EndScreen.Winner.{winner}")));
SendRPC();
return true;
}
default:
{
if (Options.IntegrateNaturalDisasters.GetBool() && Enum.GetValues<KOTZTeam>().FindFirst(x => Main.AllAlivePlayerControls.All(p => PlayerTeams[p.PlayerId] == x), out KOTZTeam team))
{
ResetSkins();
Color color = team.GetColor();
CustomWinnerHolder.WinnerIds = PlayerTeams.Where(x => x.Value == team).Select(x => x.Key).ToHashSet();
WinnerData = (color, Utils.ColorString(color, GetString($"KOTZ.EndScreen.Winner.{team}")));
SendRPC();
return true;
}
return WinnerData.Team != "No one wins";
}
}
void ResetSkins() => DefaultOutfits.Select(x => (pc: x.Key.GetPlayer(), outfit: x.Value)).DoIf(x => x.pc != null && x.outfit != null, x => Utils.RpcChangeSkin(x.pc, x.outfit));
}
public static bool IsNotInLocalPlayersTeam(PlayerControl pc)
{
return !PlayerTeams.TryGetValue(pc.PlayerId, out KOTZTeam team) || !PlayerTeams.TryGetValue(PlayerControl.LocalPlayer.PlayerId, out KOTZTeam lpTeam) || team != lpTeam;
}
private static void SendRPC()
{
var w = Utils.CreateRPC(CustomRPC.KOTZSync);
+14
View File
@@ -203,6 +203,20 @@ public static class NaturalDisasters
{
if (!AmongUsClient.Instance.AmHost || !GameStates.IsInTask || ExileController.Instance || AntiBlackout.SkipTasks || (Options.CurrentGameMode != CustomGameMode.NaturalDisasters && !Options.IntegrateNaturalDisasters.GetBool()) || !Main.IntroDestroyed || Main.HasJustStarted || GameStartTimeStamp + 15 > Utils.TimeStamp /* || __instance.PlayerId >= 254 || !__instance.IsHost()*/) return;
if (Options.CurrentGameMode != CustomGameMode.NaturalDisasters)
{
(int minimumWaitTime, bool shouldWait) = Options.CurrentGameMode switch
{
CustomGameMode.BedWars => (30, BedWars.IsGracePeriod),
CustomGameMode.HideAndSeek => (0, CustomHnS.IsBlindTime),
CustomGameMode.KingOfTheZones => (0, !KingOfTheZones.GameGoing),
CustomGameMode.RoomRush => (40, false),
_ => (0, false)
};
if (shouldWait || GameStartTimeStamp + minimumWaitTime > Utils.TimeStamp) return;
}
UpdatePreparingDisasters();
ActiveDisasters.ToArray().Do(x => x.Update());
+1
View File
@@ -387,6 +387,7 @@ public static class RoomRush
if (DisplayArrowToRoom.GetBool()) Main.AllPlayerControls.Do(x => LocateArrow.Add(x.PlayerId, goalPos));
Utils.NotifyRoles();
Utils.DirtyName.Add(PlayerControl.LocalPlayer.PlayerId);
if (WinByPointsInsteadOfDeaths.GetBool())
{
+1 -1
View File
@@ -782,7 +782,7 @@ public class Main : BasePlugin
PrivateTagManager.LoadTagsFromFile();
Harmony.PatchAll();
Harmony.PatchAll(Assembly.GetExecutingAssembly());
if (!DebugModeManager.AmDebugger)
ConsoleManager.DetachConsole();
+2 -2
View File
@@ -26,10 +26,10 @@ public static class AntiBlackout
if (CheckForEndVotingPatch.TempExiledPlayer != null) players = players.Where(x => x.PlayerId != CheckForEndVotingPatch.TempExiledPlayer.PlayerId).ToArray();
PlayerControl dummyImp = players.MinBy(x => x.PlayerId);
// There are only 2 players alive. We need to revive 1 dead player to have 2 living crewmates.
if (players.Length == 2)
{
PlayerControl revived = Main.AllPlayerControls.Where(x => !x.IsAlive() && !x.Data.Disconnected && x.PlayerId != CheckForEndVotingPatch.TempExiledPlayer?.PlayerId).MinBy(x => x.PlayerId);
// There are only 2 players alive. We need to revive 1 dead player to have 2 living crewmates.
PlayerControl revived = Main.AllPlayerControls.Where(x => !x.IsAlive() && !x.Data.Disconnected && x != CheckForEndVotingPatch.TempExiledPlayer?.Object).MaxBy(x => x.PlayerId);
// The black screen cannot be prevented if there are no players to revive in this case.
if (revived == null)
+3 -3
View File
@@ -43,7 +43,7 @@ namespace EHR
string skinId = PlayerControl.LocalPlayer.Data.Outfits[PlayerOutfitType.Default].SkinId;
string petId = PlayerControl.LocalPlayer.Data.Outfits[PlayerOutfitType.Default].PetId;
string visorId = PlayerControl.LocalPlayer.Data.Outfits[PlayerOutfitType.Default].VisorId;
var sender = CustomRpcSender.Create("SetFakeData", SendOption.Reliable);
var sender = CustomRpcSender.Create("SetFakeData", SendOption.Reliable, log: false);
MessageWriter writer = sender.stream;
sender.StartMessage();
PlayerControl.LocalPlayer.Data.Outfits[PlayerOutfitType.Default].PlayerName = "<size=14><br></size>" + sprite;
@@ -249,7 +249,7 @@ namespace EHR
string skinId = PlayerControl.LocalPlayer.Data.Outfits[PlayerOutfitType.Default].SkinId;
string petId = PlayerControl.LocalPlayer.Data.Outfits[PlayerOutfitType.Default].PetId;
string visorId = PlayerControl.LocalPlayer.Data.Outfits[PlayerOutfitType.Default].VisorId;
var sender = CustomRpcSender.Create("SetFakeData", SendOption.Reliable);
var sender = CustomRpcSender.Create("SetFakeData", SendOption.Reliable, log: false);
MessageWriter writer = sender.stream;
sender.StartMessage();
PlayerControl.LocalPlayer.Data.Outfits[PlayerOutfitType.Default].PlayerName = "<size=14><br></size>" + sprite;
@@ -301,7 +301,7 @@ namespace EHR
LateTask.New(() =>
{
var sender = CustomRpcSender.Create("SetFakeData", SendOption.Reliable);
var sender = CustomRpcSender.Create("SetFakeData", SendOption.Reliable, log: false);
MessageWriter writer = sender.stream;
sender.StartMessage(pc.GetClientId());
writer.StartMessage(1);
+11 -1
View File
@@ -53,7 +53,17 @@ public static class FixedUpdateCaller
{
if (GameStates.IsInTask && !ExileController.Instance && !AntiBlackout.SkipTasks && PlayerControl.LocalPlayer.CanUseKillButton())
{
List<PlayerControl> players = PlayerControl.LocalPlayer.GetPlayersInAbilityRangeSorted();
Predicate<PlayerControl> predicate = AmongUsClient.Instance.AmHost
? Options.CurrentGameMode switch
{
CustomGameMode.BedWars => BedWars.IsNotInLocalPlayersTeam,
CustomGameMode.CaptureTheFlag => CaptureTheFlag.IsNotInLocalPlayersTeam,
CustomGameMode.KingOfTheZones => KingOfTheZones.IsNotInLocalPlayersTeam,
_ => _ => true
}
: _ => true;
List<PlayerControl> players = PlayerControl.LocalPlayer.GetPlayersInAbilityRangeSorted(predicate);
PlayerControl closest = players.Count == 0 ? null : players[0];
KillButton killButton = hudManager.KillButton;
+2 -2
View File
@@ -24,6 +24,8 @@ public static class Statistics
PlayerControl[] apc = Main.AllPlayerControls;
PlayerControl[] aapc = Main.AllAlivePlayerControls;
WinCountsForOutro = string.Empty;
if (CustomWinnerHolder.WinnerTeam is CustomWinner.None or CustomWinner.Draw or CustomWinner.Error || apc.Length <= MinPlayers) return;
PlayerControl lp = PlayerControl.LocalPlayer;
@@ -34,8 +36,6 @@ public static class Statistics
CustomGameMode gm = Options.CurrentGameMode;
WinCountsForOutro = string.Empty;
if (gm != CustomGameMode.Standard)
{
try
+8 -3
View File
@@ -1586,7 +1586,11 @@ public static class Utils
return;
}
if (Options.CurrentGameMode != CustomGameMode.Standard) return;
if (Options.CurrentGameMode != CustomGameMode.Standard)
{
if (Statistics.WinCountsForOutro.Length > 0) SendMessage("\n", playerId, $"<size=80%>{Statistics.WinCountsForOutro}</size>");
return;
}
StringBuilder sb = new();
if (SetEverythingUpPatch.LastWinsText != string.Empty) sb.Append($"<size=90%>{GetString("LastResult")} {SetEverythingUpPatch.LastWinsText}</size>");
@@ -2895,7 +2899,8 @@ public static class Utils
}
var targetDeathReason = string.Empty;
if (seer.KnowDeathReason(target) && !GameStates.IsLobby) targetDeathReason = $"\n<size=1.7>({ColorString(GetRoleColor(CustomRoles.Doctor), GetVitalText(target.PlayerId))})</size>";
string newLineBeforeSuffix = !(Options.CurrentGameMode == CustomGameMode.BedWars && GameStates.InGame) ? "\r\n" : " - ";
if (seer.KnowDeathReason(target) && !GameStates.IsLobby) targetDeathReason = $"{newLineBeforeSuffix}<size=1.7>({ColorString(GetRoleColor(CustomRoles.Doctor), GetVitalText(target.PlayerId))})</size>";
// Devourer
if (Devourer.HideNameOfConsumedPlayer.GetBool() && !GameStates.IsLobby && Devourer.PlayerIdList.Any(x => Main.PlayerStates[x].Role is Devourer { IsEnable: true } dv && dv.PlayerSkinsCosumed.Contains(target.PlayerId)) && !camouflageIsForMeeting)
@@ -2908,7 +2913,7 @@ public static class Utils
targetPlayerName = EmptyMessage;
var targetName = $"{targetRoleText}{targetPlayerName}{targetDeathReason}{TargetMark}";
targetName += GameStates.IsLobby || TargetSuffix.ToString() == string.Empty ? string.Empty : $"\r\n{TargetSuffix}";
targetName += GameStates.IsLobby || TargetSuffix.ToString() == string.Empty ? string.Empty : $"{newLineBeforeSuffix}{TargetSuffix}";
targetName = targetName.Trim().Replace("color=", "").Replace("<#ffffff><#ffffff>", "<#ffffff>");
if (targetName.EndsWith("</size>")) targetName = targetName.Remove(targetName.Length - 7);
+7 -2
View File
@@ -155,7 +155,8 @@ internal static class ChangeRoleSettings
try
{
if (Options.CurrentGameMode == CustomGameMode.BedWars) Options.UsePets.SetValue(1);
if (Options.CurrentGameMode == CustomGameMode.BedWars)
Options.UsePets.SetValue(1);
}
catch (Exception e) { Utils.ThrowException(e); }
@@ -172,7 +173,11 @@ internal static class ChangeRoleSettings
RoleTypes.Tracker
}.Do(x => Main.NormalOptions.roleOptions.SetRoleRate(x, 0, 0));
if (Main.NormalOptions.MapId > 5) Logger.SendInGame(GetString("UnsupportedMap"));
if (Main.NormalOptions.MapId > 5)
{
Logger.SendInGame(GetString("UnsupportedMap"));
ErrorText.Instance.AddError(ErrorCode.UnsupportedMap);
}
Utils.GameStartTimeStamp = Utils.TimeStamp;
+283 -266
View File
@@ -281,7 +281,7 @@ internal static class SetEverythingUpPatch
}
case CustomGameMode.BedWars:
{
(Color Color, string Team) winnerData = BedWars.WinnerData;
(Color Color, string Team) winnerData = AmongUsClient.Instance.AmHost ? BedWars.Winner : (Color.black, string.Empty);
__instance.BackgroundBar.material.color = winnerData.Color;
winnerText.text = winnerData.Team;
winnerText.color = winnerData.Color;
@@ -386,299 +386,316 @@ internal static class SetEverythingUpPatch
EndOfText:
LastWinsText = winnerText.text /*.RemoveHtmlTags()*/;
//########################################
// ==The Final Result Indicates==
//########################################
Vector3 pos = Camera.main.ViewportToWorldPoint(new(0f, 1f, Camera.main.nearClipPlane));
GameObject roleSummaryObject = Object.Instantiate(__instance.WinText.gameObject);
roleSummaryObject.transform.position = new(__instance.Navigation.ExitButton.transform.position.x + 0.1f, pos.y - 0.1f, -15f);
roleSummaryObject.transform.localScale = new(1f, 1f, 1f);
StringBuilder sb = new($"<font=\"DIN_Pro_Bold_700 SDF\">{GetString("RoleSummaryText")}\n<b>");
List<byte> cloneRoles = [.. Main.PlayerStates.Keys];
foreach (byte id in Main.WinnerList)
{
if (EndGamePatch.SummaryText[id].Contains("<INVALID:NotAssigned>")) continue;
sb.Append('\n').Append(EndGamePatch.SummaryText[id]);
cloneRoles.Remove(id);
}
sb.Append("</b>\n");
switch (Options.CurrentGameMode)
{
case CustomGameMode.SoloKombat:
{
List<(int, byte)> list = [];
list.AddRange(cloneRoles.Select(id => (SoloPVP.GetRankFromScore(id), id)));
list.Sort();
foreach ((int, byte) id in list.Where(x => EndGamePatch.SummaryText.ContainsKey(x.Item2)))
sb.Append('\n').Append(EndGamePatch.SummaryText[id.Item2]);
break;
}
case CustomGameMode.FFA:
{
List<(int, byte)> list = [];
list.AddRange(cloneRoles.Select(id => (FreeForAll.GetRankFromScore(id), id)));
list.Sort();
foreach ((int, byte) id in list.Where(x => EndGamePatch.SummaryText.ContainsKey(x.Item2)))
sb.Append('\n').Append(EndGamePatch.SummaryText[id.Item2]);
break;
}
case CustomGameMode.MoveAndStop:
{
List<(int, byte)> list = [];
list.AddRange(cloneRoles.Select(id => (MoveAndStop.GetRankFromScore(id), id)));
list.Sort();
foreach ((int, byte) id in list.Where(x => EndGamePatch.SummaryText.ContainsKey(x.Item2)))
sb.Append('\n').Append(EndGamePatch.SummaryText[id.Item2]);
break;
}
case CustomGameMode.HotPotato:
{
IOrderedEnumerable<byte> list = cloneRoles.OrderByDescending(HotPotato.GetSurvivalTime);
foreach (byte id in list.Where(EndGamePatch.SummaryText.ContainsKey)) sb.Append('\n').Append(EndGamePatch.SummaryText[id]);
break;
}
case CustomGameMode.Speedrun:
{
IOrderedEnumerable<byte> list = cloneRoles.OrderByDescending(id => Main.PlayerStates[id].TaskState.CompletedTasksCount);
foreach (byte id in list.Where(EndGamePatch.SummaryText.ContainsKey)) sb.Append('\n').Append(EndGamePatch.SummaryText[id]);
break;
}
case CustomGameMode.CaptureTheFlag:
{
IOrderedEnumerable<byte> list = cloneRoles.OrderByDescending(CaptureTheFlag.GetFlagTime);
foreach (byte id in list.Where(EndGamePatch.SummaryText.ContainsKey)) sb.Append('\n').Append(EndGamePatch.SummaryText[id]);
break;
}
case CustomGameMode.NaturalDisasters:
{
IOrderedEnumerable<byte> list = cloneRoles.OrderByDescending(NaturalDisasters.SurvivalTime);
foreach (byte id in list.Where(EndGamePatch.SummaryText.ContainsKey)) sb.Append('\n').Append(EndGamePatch.SummaryText[id]);
break;
}
case CustomGameMode.RoomRush:
{
IOrderedEnumerable<byte> list = RoomRush.PointsSystem ? cloneRoles.OrderByDescending(x => int.TryParse(RoomRush.GetPoints(x).Split('/')[0], out var i) ? i : 0) : cloneRoles.OrderByDescending(RoomRush.GetSurvivalTime);
foreach (byte id in list.Where(EndGamePatch.SummaryText.ContainsKey)) sb.Append('\n').Append(EndGamePatch.SummaryText[id]);
break;
}
case CustomGameMode.KingOfTheZones:
{
IOrderedEnumerable<byte> list = cloneRoles.OrderByDescending(KingOfTheZones.GetZoneTime);
foreach (byte id in list.Where(EndGamePatch.SummaryText.ContainsKey)) sb.Append('\n').Append(EndGamePatch.SummaryText[id]);
break;
}
case CustomGameMode.BedWars:
case CustomGameMode.Quiz:
{
foreach (byte id in cloneRoles.Where(EndGamePatch.SummaryText.ContainsKey))
sb.Append('\n').Append(EndGamePatch.SummaryText[id]);
break;
}
case CustomGameMode.TheMindGame:
{
IOrderedEnumerable<byte> list = cloneRoles.OrderByDescending(TheMindGame.GetPoints);
foreach (byte id in list.Where(EndGamePatch.SummaryText.ContainsKey)) sb.Append('\n').Append(EndGamePatch.SummaryText[id]);
break;
}
default:
{
foreach (byte id in cloneRoles)
{
try
{
if (EndGamePatch.SummaryText[id].Contains("<INVALID:NotAssigned>")) continue;
sb.Append('\n').Append(EndGamePatch.SummaryText[id]);
}
catch { }
}
break;
}
}
if (Options.CurrentGameMode != CustomGameMode.Standard)
{
if (Statistics.WinCountsForOutro != string.Empty)
{
sb.Append("\n\n\n");
sb.Append(Statistics.WinCountsForOutro);
}
}
sb.Append("</font>");
var roleSummary = roleSummaryObject.GetComponent<TextMeshPro>();
roleSummary.alignment = TextAlignmentOptions.TopLeft;
roleSummary.color = Color.white;
roleSummary.outlineWidth *= 1.2f;
roleSummary.fontSizeMin = roleSummary.fontSizeMax = roleSummary.fontSize = 1.25f;
var roleSummaryRectTransform = roleSummary.GetComponent<RectTransform>();
roleSummaryRectTransform.anchoredPosition = new(pos.x + 3.5f, pos.y - 0.7f);
roleSummary.text = sb.ToString();
string[] lines = sb.ToString().Split('\n');
List<TextMeshPro> roleSummaryObjects = [];
for (int i = 0; i < lines.Length; i++)
{
GameObject lineObj = Object.Instantiate(roleSummaryObject, roleSummaryObject.transform.parent);
TextMeshPro lineText = lineObj.GetComponent<TextMeshPro>();
lineText.text = "<font=\"DIN_Pro_Bold_700 SDF\">" + lines[i];
lineText.alignment = TextAlignmentOptions.TopLeft;
RectTransform lineRect = lineObj.GetComponent<RectTransform>();
lineRect.anchoredPosition = new(pos.x + 3.5f - 5f, pos.y - 0.7f - (i * 0.15f)); // slide from the left
lineText.alpha = 0f;
roleSummaryObjects.Add(lineText);
__instance.StartCoroutine(SlideAndFadeIn(lineRect, lineText, i * 0.15f).WrapToIl2Cpp()); // stagger animation
continue;
static IEnumerator SlideAndFadeIn(RectTransform rect, TextMeshPro text, float delay)
{
yield return new WaitForSeconds(delay);
Vector2 start = rect.anchoredPosition;
Vector2 end = start + new Vector2(5f, 0); // target pos
const float duration = 0.5f;
float elapsed = 0f;
while (elapsed < duration)
{
elapsed += Time.deltaTime;
float t = elapsed / duration;
rect.anchoredPosition = Vector2.Lerp(start, end, Mathf.SmoothStep(0, 1, t));
text.alpha = t;
yield return null;
}
rect.anchoredPosition = end;
text.alpha = 1f;
}
}
Object.Destroy(roleSummaryObject);
bool showInitially = Main.ShowResult;
ResultsToggleButton = new SimpleButton(
__instance.transform,
"ShowHideResultsButton",
new(-4.5f, 2.6f, -14f),
new(0, 165, 255, 255),
new(0, 255, 255, 255),
() =>
{
bool setToActive = !roleSummaryObjects[0].gameObject.activeSelf;
roleSummaryObjects.ForEach(x => x.gameObject.SetActive(setToActive));
Main.ShowResult = setToActive;
ResultsToggleButton.Label.text = GetString(setToActive ? "HideResults" : "ShowResults");
},
GetString(showInitially ? "HideResults" : "ShowResults"))
{
Scale = new(1.5f, 0.5f),
FontSize = 2f
};
return;
IEnumerator SetupPoolablePlayers()
{
// ---------- Code from TOR (The Other Roles)! ----------
// https://github.com/TheOtherRolesAU/TheOtherRoles/blob/main/TheOtherRoles/Patches/EndGamePatch.cs
if (Options.CurrentGameMode != CustomGameMode.Standard) yield break;
if (Camera.main == null) yield break;
yield return null;
int num = Mathf.CeilToInt(7.5f);
Vector3 pos = Camera.main.ViewportToWorldPoint(new(0f, 1f, Camera.main.nearClipPlane));
GameObject roleSummaryObject = Object.Instantiate(__instance.WinText.gameObject);
roleSummaryObject.transform.position = new(__instance.Navigation.ExitButton.transform.position.x + 0.1f, pos.y - 0.1f, -15f);
roleSummaryObject.transform.localScale = new(1f, 1f, 1f);
roleSummaryObject.SetActive(false);
yield return null;
Il2CppArrayBase<PoolablePlayer> pbs = __instance?.transform.GetComponentsInChildren<PoolablePlayer>();
StringBuilder sb = new($"<font=\"DIN_Pro_Bold_700 SDF\">{GetString("RoleSummaryText")}\n<b>");
List<byte> cloneRoles = [.. Main.PlayerStates.Keys];
if (pbs != null)
foreach (byte id in Main.WinnerList)
{
foreach (PoolablePlayer pb in pbs)
if (pb != null)
pb.ToggleName(false);
if (EndGamePatch.SummaryText[id].Contains("<INVALID:NotAssigned>")) continue;
sb.Append('\n').Append(EndGamePatch.SummaryText[id]);
cloneRoles.Remove(id);
}
sb.Append("</b>\n");
yield return null;
switch (Options.CurrentGameMode)
{
case CustomGameMode.SoloKombat:
{
List<(int, byte)> list = [];
list.AddRange(cloneRoles.Select(id => (SoloPVP.GetRankFromScore(id), id)));
list.Sort();
foreach ((int, byte) id in list.Where(x => EndGamePatch.SummaryText.ContainsKey(x.Item2)))
sb.Append('\n').Append(EndGamePatch.SummaryText[id.Item2]);
break;
}
case CustomGameMode.FFA:
{
List<(int, byte)> list = [];
list.AddRange(cloneRoles.Select(id => (FreeForAll.GetRankFromScore(id), id)));
list.Sort();
foreach ((int, byte) id in list.Where(x => EndGamePatch.SummaryText.ContainsKey(x.Item2)))
sb.Append('\n').Append(EndGamePatch.SummaryText[id.Item2]);
break;
}
case CustomGameMode.MoveAndStop:
{
List<(int, byte)> list = [];
list.AddRange(cloneRoles.Select(id => (MoveAndStop.GetRankFromScore(id), id)));
list.Sort();
foreach ((int, byte) id in list.Where(x => EndGamePatch.SummaryText.ContainsKey(x.Item2)))
sb.Append('\n').Append(EndGamePatch.SummaryText[id.Item2]);
break;
}
case CustomGameMode.HotPotato:
{
IOrderedEnumerable<byte> list = cloneRoles.OrderByDescending(HotPotato.GetSurvivalTime);
foreach (byte id in list.Where(EndGamePatch.SummaryText.ContainsKey)) sb.Append('\n').Append(EndGamePatch.SummaryText[id]);
break;
}
case CustomGameMode.Speedrun:
{
IOrderedEnumerable<byte> list = cloneRoles.OrderByDescending(id => Main.PlayerStates[id].TaskState.CompletedTasksCount);
foreach (byte id in list.Where(EndGamePatch.SummaryText.ContainsKey)) sb.Append('\n').Append(EndGamePatch.SummaryText[id]);
break;
}
case CustomGameMode.CaptureTheFlag:
{
IOrderedEnumerable<byte> list = cloneRoles.OrderByDescending(CaptureTheFlag.GetFlagTime);
foreach (byte id in list.Where(EndGamePatch.SummaryText.ContainsKey)) sb.Append('\n').Append(EndGamePatch.SummaryText[id]);
break;
}
case CustomGameMode.NaturalDisasters:
{
IOrderedEnumerable<byte> list = cloneRoles.OrderByDescending(NaturalDisasters.SurvivalTime);
foreach (byte id in list.Where(EndGamePatch.SummaryText.ContainsKey)) sb.Append('\n').Append(EndGamePatch.SummaryText[id]);
break;
}
case CustomGameMode.RoomRush:
{
IOrderedEnumerable<byte> list = RoomRush.PointsSystem ? cloneRoles.OrderByDescending(x => int.TryParse(RoomRush.GetPoints(x).Split('/')[0], out int i) ? i : 0) : cloneRoles.OrderByDescending(RoomRush.GetSurvivalTime);
foreach (byte id in list.Where(EndGamePatch.SummaryText.ContainsKey)) sb.Append('\n').Append(EndGamePatch.SummaryText[id]);
break;
}
case CustomGameMode.KingOfTheZones:
{
IOrderedEnumerable<byte> list = cloneRoles.OrderByDescending(KingOfTheZones.GetZoneTime);
foreach (byte id in list.Where(EndGamePatch.SummaryText.ContainsKey)) sb.Append('\n').Append(EndGamePatch.SummaryText[id]);
break;
}
case CustomGameMode.BedWars:
case CustomGameMode.Quiz:
{
foreach (byte id in cloneRoles.Where(EndGamePatch.SummaryText.ContainsKey))
sb.Append('\n').Append(EndGamePatch.SummaryText[id]);
break;
}
case CustomGameMode.TheMindGame:
{
IOrderedEnumerable<byte> list = cloneRoles.OrderByDescending(TheMindGame.GetPoints);
foreach (byte id in list.Where(EndGamePatch.SummaryText.ContainsKey)) sb.Append('\n').Append(EndGamePatch.SummaryText[id]);
break;
}
default:
{
foreach (byte id in cloneRoles)
{
try
{
if (EndGamePatch.SummaryText[id].Contains("<INVALID:NotAssigned>")) continue;
sb.Append('\n').Append(EndGamePatch.SummaryText[id]);
}
catch { }
}
break;
}
}
yield return null;
List<CachedPlayerData> list = EndGameResult.CachedWinners.ToArray().ToList();
for (var i = 0; i < list.Count; i++)
if (Options.CurrentGameMode != CustomGameMode.Standard)
{
CachedPlayerData data = list[i];
int num2 = i % 2 == 0 ? -1 : 1;
int num3 = (i + 1) / 2;
float num4 = num3 / (float)num;
float num5 = Mathf.Lerp(1f, 0.75f, num4);
float num6 = i == 0 ? -8 : -1;
PoolablePlayer poolablePlayer = Object.Instantiate(__instance?.PlayerPrefab, __instance?.transform);
poolablePlayer.transform.localPosition = new Vector3(1f * num2 * num3 * num5, FloatRange.SpreadToEdges(-1.125f, 0f, num3, num), num6 + (num3 * 0.01f)) * 0.9f;
float num7 = Mathf.Lerp(1f, 0.65f, num4) * 0.9f;
Vector3 vector = new(num7, num7, 1f);
poolablePlayer.transform.localScale = vector;
poolablePlayer.UpdateFromPlayerOutfit(data.Outfit, PlayerMaterial.MaskType.ComplexUI, data.IsDead, true);
if (data.IsDead)
if (Statistics.WinCountsForOutro != string.Empty)
{
poolablePlayer.cosmetics.currentBodySprite.BodySprite.sprite = poolablePlayer.cosmetics.currentBodySprite.GhostSprite;
poolablePlayer.SetDeadFlipX(i % 2 == 0);
sb.Append("\n\n\n");
sb.Append(Statistics.WinCountsForOutro);
}
else
poolablePlayer.SetFlipX(i % 2 == 0);
}
bool lowered = i is 1 or 2 or 5 or 6 or 9 or 10 or 13 or 14;
sb.Append("</font>");
poolablePlayer.cosmetics.nameText.color = Color.white;
poolablePlayer.cosmetics.nameText.transform.localScale = new(1f / vector.x, 1f / vector.y, 1f / vector.z);
poolablePlayer.cosmetics.nameText.text = data.PlayerName;
yield return null;
Vector3 defaultPos = poolablePlayer.cosmetics.nameText.transform.localPosition;
var roleSummary = roleSummaryObject.GetComponent<TextMeshPro>();
roleSummary.alignment = TextAlignmentOptions.TopLeft;
roleSummary.color = Color.white;
roleSummary.outlineWidth *= 1.2f;
roleSummary.fontSizeMin = roleSummary.fontSizeMax = roleSummary.fontSize = 1.25f;
var roleSummaryRectTransform = roleSummary.GetComponent<RectTransform>();
roleSummaryRectTransform.anchoredPosition = new(pos.x + 3.5f, pos.y - 0.7f);
roleSummary.text = sb.ToString();
string[] lines = sb.ToString().Split('\n');
List<TextMeshPro> roleSummaryObjects = [];
for (var i = 0; i < lines.Length; i++)
{
GameObject lineObj = Object.Instantiate(roleSummaryObject, roleSummaryObject.transform.parent);
lineObj.SetActive(true);
var lineText = lineObj.GetComponent<TextMeshPro>();
lineText.text = "<font=\"DIN_Pro_Bold_700 SDF\">" + lines[i];
lineText.alignment = TextAlignmentOptions.TopLeft;
var lineRect = lineObj.GetComponent<RectTransform>();
lineRect.anchoredPosition = new(pos.x + 3.5f - 5f, pos.y - 0.7f - (i * 0.15f)); // slide from the left
lineText.alpha = 0f;
roleSummaryObjects.Add(lineText);
yield return null;
__instance.StartCoroutine(SlideAndFadeIn(lineRect, lineText, i * 0.15f).WrapToIl2Cpp()); // stagger animation
continue;
static IEnumerator SlideAndFadeIn(RectTransform rect, TextMeshPro text, float delay)
{
yield return new WaitForSeconds(delay);
Vector2 start = rect.anchoredPosition;
Vector2 end = start + new Vector2(5f, 0); // target pos
const float duration = 0.5f;
var elapsed = 0f;
while (elapsed < duration)
{
elapsed += Time.deltaTime;
float t = elapsed / duration;
rect.anchoredPosition = Vector2.Lerp(start, end, Mathf.SmoothStep(0, 1, t));
text.alpha = t;
yield return null;
}
rect.anchoredPosition = end;
text.alpha = 1f;
}
}
yield return null;
Object.Destroy(roleSummaryObject);
yield return null;
bool showInitially = Main.ShowResult;
ResultsToggleButton = new SimpleButton(
__instance.transform,
"ShowHideResultsButton",
new(-4.5f, 2.6f, -14f),
new(0, 165, 255, 255),
new(0, 255, 255, 255),
() =>
{
bool setToActive = !roleSummaryObjects[0].gameObject.activeSelf;
roleSummaryObjects.ForEach(x => x.gameObject.SetActive(setToActive));
Main.ShowResult = setToActive;
ResultsToggleButton.Label.text = GetString(setToActive ? "HideResults" : "ShowResults");
},
GetString(showInitially ? "HideResults" : "ShowResults"))
{
Scale = new(1.5f, 0.5f),
FontSize = 2f
};
if (Options.CurrentGameMode == CustomGameMode.Standard)
{
yield return null;
int num = Mathf.CeilToInt(7.5f);
try
{
Il2CppArrayBase<PoolablePlayer> pbs = __instance.transform.GetComponentsInChildren<PoolablePlayer>();
if (pbs != null)
{
foreach (PoolablePlayer pb in pbs)
{
if (pb != null)
pb.ToggleName(false);
}
}
}
catch (Exception e) { Utils.ThrowException(e); }
yield return null;
for (var j = 0; j < Main.WinnerList.Count; j++)
List<CachedPlayerData> cachedWinners = EndGameResult.CachedWinners.ToArray().ToList();
for (var i = 0; i < cachedWinners.Count; i++)
{
byte id = Main.WinnerList[j];
if (Main.WinnerNameList[j].RemoveHtmlTags() != data.PlayerName.RemoveHtmlTags() || data.PlayerName == GetString("Dead")) continue;
CachedPlayerData data = cachedWinners[i];
int num2 = i % 2 == 0 ? -1 : 1;
int num3 = (i + 1) / 2;
float num4 = num3 / (float)num;
float num5 = Mathf.Lerp(1f, 0.75f, num4);
float num6 = i == 0 ? -8 : -1;
CustomRoles role = Main.PlayerStates[id].MainRole;
PoolablePlayer poolablePlayer = Object.Instantiate(__instance.PlayerPrefab, __instance.transform);
poolablePlayer.transform.localPosition = new Vector3(1f * num2 * num3 * num5, FloatRange.SpreadToEdges(-1.125f, 0f, num3, num), num6 + (num3 * 0.01f)) * 0.9f;
float num7 = Mathf.Lerp(1f, 0.65f, num4) * 0.9f;
Vector3 vector = new(num7, num7, 1f);
poolablePlayer.transform.localScale = vector;
poolablePlayer.UpdateFromPlayerOutfit(data.Outfit, PlayerMaterial.MaskType.ComplexUI, data.IsDead, true);
string color = Main.RoleColors[role];
string rolename = Utils.GetRoleName(role);
if (data.IsDead)
{
poolablePlayer.cosmetics.currentBodySprite.BodySprite.sprite = poolablePlayer.cosmetics.currentBodySprite.GhostSprite;
poolablePlayer.SetDeadFlipX(i % 2 == 0);
}
else
poolablePlayer.SetFlipX(i % 2 == 0);
poolablePlayer.cosmetics.nameText.text += $"\n<color={color}>{rolename}</color>";
poolablePlayer.cosmetics.nameText.transform.localPosition = new(defaultPos.x, !lowered ? defaultPos.y - 0.6f : defaultPos.y - 1.4f, -15f);
bool lowered = i is 1 or 2 or 5 or 6 or 9 or 10 or 13 or 14;
poolablePlayer.cosmetics.nameText.color = Color.white;
poolablePlayer.cosmetics.nameText.transform.localScale = new(1f / vector.x, 1f / vector.y, 1f / vector.z);
poolablePlayer.cosmetics.nameText.text = data.PlayerName;
Vector3 defaultPos = poolablePlayer.cosmetics.nameText.transform.localPosition;
yield return null;
for (var j = 0; j < Main.WinnerList.Count; j++)
{
byte id = Main.WinnerList[j];
if (Main.WinnerNameList[j].RemoveHtmlTags() != data.PlayerName.RemoveHtmlTags() || data.PlayerName == GetString("Dead")) continue;
CustomRoles role = Main.PlayerStates[id].MainRole;
string color = Main.RoleColors[role];
string rolename = Utils.GetRoleName(role);
poolablePlayer.cosmetics.nameText.text += $"\n<color={color}>{rolename}</color>";
poolablePlayer.cosmetics.nameText.transform.localPosition = new(defaultPos.x, !lowered ? defaultPos.y - 0.6f : defaultPos.y - 1.4f, -15f);
}
yield return null;
}
yield return null;
}
}
+5 -4
View File
@@ -1581,7 +1581,7 @@ internal static class FixedUpdatePatch
bool self = lpId == __instance.PlayerId;
bool shouldUpdateRegardlessOfLowLoad = self && PlayerControl.AllPlayerControls.Count > 30 && LastSelfNameUpdateTS != now && GameStates.InGame && PlayerControl.LocalPlayer.IsAlive() && Options.CurrentGameMode is CustomGameMode.MoveAndStop or CustomGameMode.HotPotato or CustomGameMode.Speedrun or CustomGameMode.RoomRush or CustomGameMode.KingOfTheZones or CustomGameMode.Quiz;
bool shouldUpdateRegardlessOfLowLoad = self && ((PlayerControl.AllPlayerControls.Count > 30 && LastSelfNameUpdateTS != now) || DirtyName.Remove(lpId)) && GameStates.InGame && PlayerControl.LocalPlayer.IsAlive() && Options.CurrentGameMode is CustomGameMode.MoveAndStop or CustomGameMode.HotPotato or CustomGameMode.Speedrun or CustomGameMode.RoomRush or CustomGameMode.KingOfTheZones or CustomGameMode.Quiz;
if (roleText == null || __instance == null || (lowLoad && !shouldUpdateRegardlessOfLowLoad)) return;
@@ -1878,10 +1878,11 @@ internal static class FixedUpdatePatch
if (!self && Options.CurrentGameMode == CustomGameMode.KingOfTheZones && Main.IntroDestroyed && !KingOfTheZones.GameGoing)
realName = EmptyMessage;
string deathReason = !seer.IsAlive() && seer.KnowDeathReason(target) ? $"\n<size=1.5>『{ColorString(GetRoleColor(CustomRoles.Doctor), GetVitalText(target.PlayerId))}』</size>" : string.Empty;
string newLineBeforeSuffix = !(Options.CurrentGameMode == CustomGameMode.BedWars && !self && GameStates.InGame) ? "\r\n" : " - ";
string deathReason = !seer.IsAlive() && seer.KnowDeathReason(target) ? $"{newLineBeforeSuffix}<size=1.5>『{ColorString(GetRoleColor(CustomRoles.Doctor), GetVitalText(target.PlayerId))}』</size>" : string.Empty;
string currentText = target.cosmetics.nameText.text;
var changeTo = $"{realName}{deathReason}{Mark}\r\n{Suffix}";
var changeTo = $"{realName}{deathReason}{Mark}{newLineBeforeSuffix}{Suffix}";
bool needUpdate = currentText != changeTo;
if (needUpdate)
+1 -1
View File
@@ -3572,7 +3572,7 @@
"WhispererInfoLong": "(Crewmates):\\nAs the Whisperer, you can ask the souls of dead players for information. You'll see the souls of the players who have died (after the next meeting) and can question them by petting on them. You have to stay near the soul for a few seconds. You then get random details on the soul or the killer shown below your name.",
"WhispererCooldown": "Questioning Cooldown",
"WhispererDuration": "Questioning Duration",
"WhispererInfo.Color": "A {0} color killed me (<size=50%>{1}</color>)",
"WhispererInfo.Color": "A {0} color killed me\\n(<size=50%>{1}</color>)",
"WhispererInfo.ColorDark": "<#555555>darker</color>",
"WhispererInfo.ColorLight": "<#fdffbf>lighter</color>",
"WhispererInfo.Time": "I died {0} seconds before the meeting started",
+1 -2
View File
@@ -223,7 +223,6 @@ public class Whisperer : RoleBase
case 4:
Info.Add(reader.ReadString());
if (Info.Count > 5) Info.RemoveAt(0);
break;
case 5:
Souls.Add(new(reader.ReadByte().GetPlayer()));
@@ -235,7 +234,7 @@ public class Whisperer : RoleBase
{
if (seer.PlayerId != target.PlayerId || seer.PlayerId != WhispererId || meeting || (seer.IsModdedClient() && !hud)) return string.Empty;
return "<size=70%>" + string.Join('\n', Info) + (CurrentlyQuestioning.Percent > 0 ? string.Format(Translator.GetString("WhispererQuestioning"), CurrentlyQuestioning.Name, CurrentlyQuestioning.Percent) : string.Empty) + "</size>";
return "<size=70%>" + string.Join('\n', Info) + (CurrentlyQuestioning.Percent > 0 ? "\n" + string.Format(Translator.GetString("WhispererQuestioning"), CurrentlyQuestioning.Name, CurrentlyQuestioning.Percent) : string.Empty) + "</size>";
}
private class Soul(PlayerControl player)