diff --git a/Strings.xlsx b/Strings.xlsx index 30ccf2d..ba6e162 100644 Binary files a/Strings.xlsx and b/Strings.xlsx differ diff --git a/TheOtherRoles/Buttons.cs b/TheOtherRoles/Buttons.cs index 3f1f19a..872e6c0 100644 --- a/TheOtherRoles/Buttons.cs +++ b/TheOtherRoles/Buttons.cs @@ -248,8 +248,11 @@ public static void setCustomButtonCooldowns() { foxImmoralistButton.MaxTimer = 20f; immoralistButton.MaxTimer = 20f; buskerButton.MaxTimer = Busker.cooldown; + operateButton.MaxTimer = 0f; operateButton.Timer = 0f; + freePlayReviveButton.MaxTimer = 0f; freePlayReviveButton.Timer = 0f; + freePlaySuicideButton.MaxTimer = 0f; freePlaySuicideButton.Timer = 0f; //trapperButton.MaxTimer = Trapper.cooldown; //bomberButton.MaxTimer = Bomber.bombCooldown; @@ -4118,8 +4121,8 @@ Func fortuneTellerCouldUse(byte index) operateButton = new CustomButton( () => { FreePlayGM.OpenRoleWindow(); }, () => { return FreePlayGM.isFreePlayGM; }, - () => { return true; }, - () => { }, + () => { return FreePlayGM.roleScreen == null; }, + () => { operateButton.Timer = operateButton.MaxTimer = 0f; }, FreePlayGM.getOperateButtonSprite(), new Vector3(0f, 1f, 0f), __instance, @@ -4147,11 +4150,11 @@ Func fortuneTellerCouldUse(byte index) { return true; }, - () => { }, + () => { freePlayReviveButton.Timer = freePlayReviveButton.MaxTimer = 0f; }, FreePlayGM.getReviveButtonSprite(), new Vector3(1f, 1f, 0f), __instance, - KeyCode.X, + KeyCode.Y, true, buttonText: ModTranslation.getString("FreePlayReviveText"), abilityTexture: true @@ -4176,7 +4179,7 @@ Func fortuneTellerCouldUse(byte index) { return true; }, - () => { }, + () => { freePlaySuicideButton.Timer = freePlaySuicideButton.MaxTimer = 0f; }, __instance.KillButton.graphic.sprite, new Vector3(1f, 1f, 0f), __instance, @@ -4204,7 +4207,7 @@ Func fortuneTellerCouldUse(byte index) writer2.Write(0); RPCProcedure.uncheckedMurderPlayer(thief.PlayerId, thief.PlayerId, 0); AmongUsClient.Instance.FinishRpcImmediately(writer2); - Thief.thief.clearAllTasks(); + if (!FreePlayGM.isFreePlayGM) Thief.thief.clearAllTasks(); } // Steal role if survived. diff --git a/TheOtherRoles/CustomGameModes/FreePlayGM.cs b/TheOtherRoles/CustomGameModes/FreePlayGM.cs index 607eaf1..8536f46 100644 --- a/TheOtherRoles/CustomGameModes/FreePlayGM.cs +++ b/TheOtherRoles/CustomGameModes/FreePlayGM.cs @@ -19,6 +19,7 @@ public static class FreePlayGM public static bool isFreePlayGM = false; public static Sprite operateButtonSprite; public static Sprite reviveSprite; + public static MetaScreen roleScreen; public static Sprite getOperateButtonSprite() { @@ -36,7 +37,7 @@ public static Sprite getReviveButtonSprite() public static void OpenRoleWindow() { - var window = MetaScreen.GenerateWindow(new Vector2(7.5f, 4.5f), HudManager.Instance.transform, new Vector3(0, 0, -400f), true, false); + roleScreen = MetaScreen.GenerateWindow(new Vector2(7.5f, 4.5f), HudManager.Instance.transform, new Vector3(0, 0, -400f), true, false); var gui = TORGUIContextEngine.Instance; var roleMaskedTittleAttr = gui.GetAttribute(AttributeAsset.MetaRoleButton); @@ -58,11 +59,12 @@ void SetWidget(int tab) inner = gui.Arrange(GUIAlignment.Center, RoleInfo.allRoleInfos.Where(x => x != RoleInfo.bomberB && x != RoleInfo.bomberA && x != RoleInfo.jackal && x != RoleInfo.sidekick && x != RoleInfo.mimicA && x != RoleInfo.mimicK && x != RoleInfo.arsonist && x != RoleInfo.bountyHunter && !x.isModifier).Select(r => gui.RawButton(GUIAlignment.Center, roleMaskedTittleAttr, Helpers.cs(r.color, r.name), () => { + bool isImpostorFormer = PlayerControl.LocalPlayer.Data.Role.IsImpostor; var formerRole = RoleInfo.getRoleInfoForPlayer(PlayerControl.LocalPlayer, false).FirstOrDefault(); if (formerRole == r) return; // Do nothing if the same role was given RPCProcedure.erasePlayerRoles(PlayerControl.LocalPlayer.PlayerId); - if (r.isImpostor() && !formerRole.isImpostor()) PlayerControl.LocalPlayer.FastSetRole(RoleTypes.Impostor); - else if (!r.isImpostor() && formerRole.isImpostor()) PlayerControl.LocalPlayer.FastSetRole(RoleTypes.Crewmate); + if (r.isImpostor() && !isImpostorFormer) PlayerControl.LocalPlayer.FastSetRole(RoleTypes.Impostor); + else if (!r.isImpostor() && isImpostorFormer) PlayerControl.LocalPlayer.FastSetRole(RoleTypes.Crewmate); if (r == RoleInfo.chainshifter) Shifter.isNeutral = true; else if (r == RoleInfo.niceshifter) Shifter.isNeutral = false; @@ -70,7 +72,7 @@ void SetWidget(int tab) if (r.roleId == RoleId.Fox) { if (Shrine.allShrine?.FirstOrDefault() == null){ - Shrine.activateShrines(GameOptionsManager.Instance.currentNormalGameOptions.MapId);System.Console.WriteLine("1"); + Shrine.activateShrines(GameOptionsManager.Instance.currentNormalGameOptions.MapId); } List taskIdList = new(); Shrine.allShrine.ForEach(shrine => taskIdList.Add((byte)shrine.console.ConsoleId)); @@ -84,7 +86,7 @@ void SetWidget(int tab) PlayerControl.LocalPlayer.generateAndAssignTasks(options.NumCommonTasks, options.NumShortTasks, options.NumLongTasks); } RPCProcedure.resetAchievement(); - window.CloseScreen(); + roleScreen.CloseScreen(); })), 4); } else if (tab == 1) @@ -104,7 +106,7 @@ void SetWidget(int tab) })), 4)} ); } - window.SetContext(gui.VerticalHolder(GUIAlignment.Center, new List() { holder, gui.ScrollView(GUIAlignment.Center, new(7.4f, 3.5f), null, inner, out _) }), out _); + roleScreen.SetContext(gui.VerticalHolder(GUIAlignment.Center, new List() { holder, gui.ScrollView(GUIAlignment.Center, new(7.4f, 3.5f), null, inner, out _) }), out _); } SetWidget(0); @@ -185,6 +187,7 @@ public static PlayerControl SpawnDummy() public static void clearAndReload() { isFreePlayGM = TORMapOptions.gameMode == CustomGamemodes.FreePlay; + roleScreen = null; } [HarmonyPatch(typeof(GameStartManager), nameof(GameStartManager.BeginGame))] diff --git a/TheOtherRoles/Helpers.cs b/TheOtherRoles/Helpers.cs index 7da91af..27bd007 100644 --- a/TheOtherRoles/Helpers.cs +++ b/TheOtherRoles/Helpers.cs @@ -779,7 +779,7 @@ public static bool isChinese() public static string getGithubUrl(this string url) { if (!isChinese()) return url; - return url.Replace("https://", "https://mirror.ghproxy.com/"); + return url.Replace("https://", "https://ghp.ci/"); } public static T FindAsset(string name) where T : Il2CppObjectBase diff --git a/TheOtherRoles/MetaContext/MetaScreen.cs b/TheOtherRoles/MetaContext/MetaScreen.cs index cd64da9..c8bfc26 100644 --- a/TheOtherRoles/MetaContext/MetaScreen.cs +++ b/TheOtherRoles/MetaContext/MetaScreen.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -41,8 +41,10 @@ public bool ShowBorderLine { if (borderLine == null && value) { - var lineObj = new GameObject("BorderLine"); - lineObj.layer = LayerMask.NameToLayer("UI"); + var lineObj = new GameObject("BorderLine") + { + layer = LayerMask.NameToLayer("UI") + }; lineObj.transform.SetParent(transform); lineObj.transform.localPosition = new Vector3(0, 0, 0); borderLine = lineObj.AddComponent(); diff --git a/TheOtherRoles/Modules/CustomHats/CustomHatManager.cs b/TheOtherRoles/Modules/CustomHats/CustomHatManager.cs index 1d627f2..fd492f4 100644 --- a/TheOtherRoles/Modules/CustomHats/CustomHatManager.cs +++ b/TheOtherRoles/Modules/CustomHats/CustomHatManager.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -15,7 +15,7 @@ public static class CustomHatManager public const string InnerslothPackageName = "Innersloth Hats"; public const string DeveloperPackageName = "Developer Hats"; - internal static readonly Tuple Repository = new("TheOtherRolesAU", "TheOtherHats"); + internal static readonly Tuple Repository = new("dabao40", "TheOtherHats"); internal static string RepositoryUrl { get @@ -304,11 +304,13 @@ public static List loadHorseHats() int i = 0; foreach (var item in hatFilesSorted) { - CustomHat info = new(); - info.Name = $"April Hat {i++:D2}"; - info.Author = "A Fool"; - info.Resource = item.Value.FirstOrDefault(x => !x.Contains("back")); - info.BackResource = item.Value.FirstOrDefault(x => x.Contains("back")); + CustomHat info = new() + { + Name = $"April Hat {i++:D2}", + Author = "A Fool", + Resource = item.Value.FirstOrDefault(x => !x.Contains("back")), + BackResource = item.Value.FirstOrDefault(x => x.Contains("back")) + }; info.Adaptive = info.Resource != null && info.Resource.Contains("adaptive"); info.FlipResource = item.Value.FirstOrDefault(x => x.Contains("flip")); info.ClimbResource = item.Value.FirstOrDefault(x => x.Contains("climb")); @@ -319,4 +321,4 @@ public static List loadHorseHats() } return hatdatas; } -} \ No newline at end of file +} diff --git a/TheOtherRoles/Modules/CustomOverlay.cs b/TheOtherRoles/Modules/CustomOverlay.cs index 7d8b3d3..33fdd4a 100644 --- a/TheOtherRoles/Modules/CustomOverlay.cs +++ b/TheOtherRoles/Modules/CustomOverlay.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -44,7 +44,6 @@ public static bool initializeOverlays() if (infoOverlayRoles == null) { infoOverlayRoles = UnityEngine.Object.Instantiate(hudManager.TaskPanel.taskText, hudManager.transform); - infoOverlayRoles.maxVisibleLines = 28; infoOverlayRoles.fontSize = infoOverlayRoles.fontSizeMin = infoOverlayRoles.fontSizeMax = 1.15f; infoOverlayRoles.outlineWidth += 0.02f; infoOverlayRoles.autoSizeTextContainer = false; @@ -162,7 +161,7 @@ public static void hideInfoOverlay() var underlayTransparent = new Color(0.1f, 0.1f, 0.1f, 0.0f); var underlayOpaque = new Color(0.1f, 0.1f, 0.1f, 0.88f); - scroller.enabled = false; + if (scroller != null) scroller.enabled = false; FastDestroyableSingleton.Instance.StartCoroutine(Effects.Lerp(0.2f, new Action(t => { @@ -195,7 +194,8 @@ public static void resetOverlays() UnityEngine.Object.Destroy(meetingUnderlay); UnityEngine.Object.Destroy(infoUnderlay); UnityEngine.Object.Destroy(infoOverlayRoles); - UnityEngine.Object.Destroy(roleUnderlay); + UnityEngine.Object.Destroy(roleUnderlay); + UnityEngine.Object.Destroy(scroller); overlayShown = false; roleUnderlay = null; diff --git a/TheOtherRoles/Patches/IntroPatch.cs b/TheOtherRoles/Patches/IntroPatch.cs index 8fd69ff..2b81bae 100644 --- a/TheOtherRoles/Patches/IntroPatch.cs +++ b/TheOtherRoles/Patches/IntroPatch.cs @@ -449,7 +449,7 @@ static public void SetRoleTexts(IntroCutscene __instance) { // Don't override the intro of the vanilla roles List infos = RoleInfo.getRoleInfoForPlayer(CachedPlayer.LocalPlayer.PlayerControl); RoleInfo roleInfo = infos.Where(info => !info.isModifier).FirstOrDefault(); - RoleInfo modifierInfo = infos.Where(info => info.isModifier).FirstOrDefault(); + List modifierInfo = infos.Where(info => info.isModifier).ToList(); if (roleInfo == RoleInfo.fortuneTeller && FortuneTeller.numTasks > 0) { @@ -466,6 +466,9 @@ static public void SetRoleTexts(IntroCutscene __instance) { } __instance.RoleBlurbText.text = ""; + __instance.RoleBlurbText.transform.localPosition = new(0.0965f, -2.12f, -36f); + __instance.RoleBlurbText.rectTransform.sizeDelta = new(12.8673f, 0.7f); + __instance.RoleBlurbText.alignment = TMPro.TextAlignmentOptions.Top; if (roleInfo != null) { __instance.YouAreText.color = roleInfo.color; __instance.RoleText.text = roleInfo.name; @@ -486,11 +489,13 @@ static public void SetRoleTexts(IntroCutscene __instance) { } if (modifierInfo != null) { - if (modifierInfo.roleId != RoleId.Lover) - __instance.RoleBlurbText.text += Helpers.cs(modifierInfo.color, $"\n{modifierInfo.introDescription}"); - else { - PlayerControl otherLover = CachedPlayer.LocalPlayer.PlayerControl == Lovers.lover1 ? Lovers.lover2 : Lovers.lover1; - __instance.RoleBlurbText.text += "\n" + Helpers.cs(Lovers.color, String.Format(ModTranslation.getString("loversFlavor"), otherLover?.Data?.PlayerName ?? "")); + foreach (var info in modifierInfo) { + if (info.roleId != RoleId.Lover) + __instance.RoleBlurbText.text += Helpers.cs(info.color, $"\n{info.introDescription}"); + else { + PlayerControl otherLover = CachedPlayer.LocalPlayer.PlayerControl == Lovers.lover1 ? Lovers.lover2 : Lovers.lover1; + __instance.RoleBlurbText.text += "\n" + Helpers.cs(Lovers.color, String.Format(ModTranslation.getString("loversFlavor"), otherLover?.Data?.PlayerName ?? "")); + } } } if (Deputy.knowsSheriff && Deputy.deputy != null && Sheriff.sheriff != null) { diff --git a/TheOtherRoles/Patches/MainMenuPatch.cs b/TheOtherRoles/Patches/MainMenuPatch.cs index 0b0b1c4..56a2e19 100644 --- a/TheOtherRoles/Patches/MainMenuPatch.cs +++ b/TheOtherRoles/Patches/MainMenuPatch.cs @@ -228,7 +228,7 @@ public static class MainMenuSetUpPatch public static GameObject aboutScreen = null; public static Dictionary contributors = new() { { "Imp11", "mainMenuDeveloper" }, { "Amongus", "mainMenuDeveloper" }, - { "Fangkuai", "mainMenuArtist" }, { "Yuunozikkyou" , "mainMenuTranslator"} }; + { "Fangkuai", "mainMenuArtist" }, { "Yuunozikkyou" , "mainMenuTranslator"}, { "TAIK", "mainMenuTranslator"} }; public static void Postfix(MainMenuManager __instance) { diff --git a/TheOtherRoles/Patches/PlayerControlPatch.cs b/TheOtherRoles/Patches/PlayerControlPatch.cs index 605fd6e..5b2d3cb 100644 --- a/TheOtherRoles/Patches/PlayerControlPatch.cs +++ b/TheOtherRoles/Patches/PlayerControlPatch.cs @@ -2428,7 +2428,9 @@ public static void Postfix(PlayerControl __instance, [HarmonyArgument(0)]PlayerC { array[i].gameObject.active = false; } - } + } + DeadPlayer deadPlayerEntry = deadPlayers.Where(x => x.player.PlayerId == target.PlayerId).FirstOrDefault(); + if (deadPlayerEntry != null) deadPlayers.Remove(deadPlayerEntry); } else { @@ -2910,8 +2912,9 @@ public static bool Prefix(PlayerControl __instance) DestroyableSingleton.Instance.SetHudActive(true); DestroyableSingleton.Instance.Chat.ForceClosed(); DestroyableSingleton.Instance.Chat.SetVisible(false); - } - + } + DeadPlayer deadPlayerEntry = deadPlayers.Where(x => x.player.PlayerId == __instance.PlayerId).FirstOrDefault(); + if (deadPlayerEntry != null) deadPlayers.Remove(deadPlayerEntry); return false; } } diff --git a/TheOtherRoles/Resources/Contributors/TAIK.png b/TheOtherRoles/Resources/Contributors/TAIK.png new file mode 100644 index 0000000..e698667 Binary files /dev/null and b/TheOtherRoles/Resources/Contributors/TAIK.png differ diff --git a/TheOtherRoles/Resources/stringData.json b/TheOtherRoles/Resources/stringData.json index 5b9dbae..545adfd 100644 --- a/TheOtherRoles/Resources/stringData.json +++ b/TheOtherRoles/Resources/stringData.json @@ -548,6 +548,10 @@ "11": "\u4e00\u7dd2\u306b\u697d\u3057\u304fAmong Us\u3092\u3084\u308a\u307e\u3057\u3087\u3046!", "13": "\u8ba9\u6211\u4eec\u4e00\u8d77\u5f00\u5fc3\u5730\u505a Among Us \u5427\uff01" }, + "mainMenuTAIKAboutSection": { + "0": "The wind and the seeds of the story bring the prologue", + "13": "\u98ce\u4e0e\u6545\u4e8b\u7684\u79cd\u5b50\u5e26\u6765\u7684\u5e8f\u5e55" + }, "mainMenuDeveloper": { "0": "Developer", "11": "\u958b\u767a\u8005",