diff --git a/Strings.xlsx b/Strings.xlsx index 353dd48..5b16276 100644 Binary files a/Strings.xlsx and b/Strings.xlsx differ diff --git a/TheOtherRoles/Buttons.cs b/TheOtherRoles/Buttons.cs index 1c74130..96ddff2 100644 --- a/TheOtherRoles/Buttons.cs +++ b/TheOtherRoles/Buttons.cs @@ -2287,7 +2287,7 @@ public static void createButtonsPostfix(HudManager __instance) { AmongUsClient.Instance.FinishRpcImmediately(writer); BomberA.bombTarget = BomberA.tmpTarget; } - + _ = new StaticAchievementToken("bomberA.common1"); BomberA.tmpTarget = null; bomberAPlantBombButton.Timer = bomberAPlantBombButton.MaxTimer; SoundEffectsManager.play("bomberPlantBomb"); @@ -2349,7 +2349,7 @@ public static void createButtonsPostfix(HudManager __instance) { AmongUsClient.Instance.FinishRpcImmediately(writer); BomberB.bombTarget = BomberB.tmpTarget; } - + _ = new StaticAchievementToken("bomberA.common1"); BomberB.tmpTarget = null; bomberBPlantBombButton.Timer = bomberBPlantBombButton.MaxTimer; SoundEffectsManager.play("bomberPlantBomb"); @@ -2381,7 +2381,8 @@ public static void createButtonsPostfix(HudManager __instance) { writer.Write(target.PlayerId); AmongUsClient.Instance.FinishRpcImmediately(writer); RPCProcedure.releaseBomb(CachedPlayer.LocalPlayer.PlayerControl.PlayerId, target.PlayerId); - } + } + _ = new StaticAchievementToken("bomberA.challenge"); } else if (attempt == MurderAttemptResult.BlankKill) { @@ -2433,7 +2434,8 @@ public static void createButtonsPostfix(HudManager __instance) { writer.Write(target.PlayerId); AmongUsClient.Instance.FinishRpcImmediately(writer); RPCProcedure.releaseBomb(CachedPlayer.LocalPlayer.PlayerControl.PlayerId, target.PlayerId); - } + } + _ = new StaticAchievementToken("bomberA.challenge"); } else if (attempt == MurderAttemptResult.BlankKill) { @@ -2900,11 +2902,12 @@ public static void createButtonsPostfix(HudManager __instance) { writer.Write(CachedPlayer.LocalPlayer.PlayerControl.PlayerId); AmongUsClient.Instance.FinishRpcImmediately(writer); RPCProcedure.mimicResetMorph(CachedPlayer.LocalPlayer.PlayerControl.PlayerId); - } + } + MimicA.acTokenCommon.Value++; }, () => { return MimicA.mimicA != null && CachedPlayer.LocalPlayer.PlayerControl == MimicA.mimicA && !CachedPlayer.LocalPlayer.PlayerControl.Data.IsDead && MimicK.mimicK != null && !MimicK.mimicK.Data.IsDead; }, () => { return CachedPlayer.LocalPlayer.PlayerControl.CanMove && !CachedPlayer.LocalPlayer.PlayerControl.Data.IsDead && MimicK.mimicK != null && !MimicK.mimicK.Data.IsDead && !Helpers.MushroomSabotageActive(); }, - () => { }, + () => { MimicA.acTokenCommon.Value = 0; }, MimicA.getMorphSprite(), CustomButton.ButtonPositions.upperRowLeft, __instance, @@ -2921,8 +2924,8 @@ public static void createButtonsPostfix(HudManager __instance) { HudManager __instance = FastDestroyableSingleton.Instance; __instance.InitMap(); MapBehaviour.Instance.ShowCountOverlay(allowedToMove: true, showLivePlayerPosition: true, includeDeadBodies: true); - } - CachedPlayer.LocalPlayer.NetTransform.Halt(); + } + _ = new StaticAchievementToken("mimicA.common1"); }, () => { return MimicA.mimicA != null && CachedPlayer.LocalPlayer.PlayerControl == MimicA.mimicA && !CachedPlayer.LocalPlayer.PlayerControl.Data.IsDead @@ -4187,6 +4190,7 @@ Func fortuneTellerCouldUse(byte index) RPCProcedure.uncheckedMurderPlayer(thief.PlayerId, thief.PlayerId, 0); AmongUsClient.Instance.FinishRpcImmediately(writer2); if (!FreePlayGM.isFreePlayGM) Thief.thief.clearAllTasks(); + _ = new StaticAchievementToken("thief.another1"); } // Steal role if survived. @@ -4195,6 +4199,7 @@ Func fortuneTellerCouldUse(byte index) writer.Write(target.PlayerId); AmongUsClient.Instance.FinishRpcImmediately(writer); RPCProcedure.thiefStealsRole(target.PlayerId); + _ = new StaticAchievementToken("thief.challenge"); } // Kill the victim (after becoming their role - so that no win is triggered for other teams) if (result == MurderAttemptResult.PerformKill) { diff --git a/TheOtherRoles/CustomGameModes/FreePlayGM.cs b/TheOtherRoles/CustomGameModes/FreePlayGM.cs index 2878782..222449a 100644 --- a/TheOtherRoles/CustomGameModes/FreePlayGM.cs +++ b/TheOtherRoles/CustomGameModes/FreePlayGM.cs @@ -56,7 +56,7 @@ void SetWidget(int tab) if (tab == 0) { - inner = gui.Arrange(GUIAlignment.Center, RoleInfo.allRoleInfos.Where(x => x != RoleInfo.bomberB && !x.isModifier).Select(r => gui.RawButton(GUIAlignment.Center, roleMaskedTittleAttr, Helpers.cs(r.color, r.name), () => + inner = gui.Arrange(GUIAlignment.Center, RoleInfo.allRoleInfos.Where(x => x != RoleInfo.bomberB && 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(); diff --git a/TheOtherRoles/Helpers.cs b/TheOtherRoles/Helpers.cs index d83bf26..1eb4fcc 100644 --- a/TheOtherRoles/Helpers.cs +++ b/TheOtherRoles/Helpers.cs @@ -909,12 +909,6 @@ public static bool isChinese() } } - public static string getGithubUrl(this string url) - { - if (!isChinese()) return url; - return url.Replace("https://", "https://ghp.ci/"); - } - public static T FindAsset(string name) where T : Il2CppObjectBase { foreach (var asset in UnityEngine.Object.FindObjectsOfTypeIncludingAssets(Il2CppType.Of())) diff --git a/TheOtherRoles/Modules/Achievement.cs b/TheOtherRoles/Modules/Achievement.cs index 62d1eb1..0d4158c 100644 --- a/TheOtherRoles/Modules/Achievement.cs +++ b/TheOtherRoles/Modules/Achievement.cs @@ -268,7 +268,9 @@ public static void onAchievementStart() Swapper.evilSwapperOnAchievementActivate(); Trapper.onAchievementActivate(); Blackmailer.onAchievementActivate(); - Yasuna.evilYasunaOnAcheivementActivate(); + Yasuna.evilYasunaOnAcheivementActivate(); + MimicK.onAchievementActivate(); + MimicA.onAchievementActivate(); } public bool IsHidden diff --git a/TheOtherRoles/Modules/CustomHats/CustomHatManager.cs b/TheOtherRoles/Modules/CustomHats/CustomHatManager.cs index fd492f4..fccb538 100644 --- a/TheOtherRoles/Modules/CustomHats/CustomHatManager.cs +++ b/TheOtherRoles/Modules/CustomHats/CustomHatManager.cs @@ -21,7 +21,7 @@ internal static string RepositoryUrl get { var (owner, repository) = Repository; - return $"https://raw.githubusercontent.com/{owner}/{repository}/master".getGithubUrl(); + return Helpers.isChinese() ? "http://api.fangkuai.fun:2222/ModFiles/TheOtherHats" : $"https://raw.githubusercontent.com/{owner}/{repository}/master"; } } diff --git a/TheOtherRoles/Modules/ModUpdater.cs b/TheOtherRoles/Modules/ModUpdater.cs index a131304..61e666a 100644 --- a/TheOtherRoles/Modules/ModUpdater.cs +++ b/TheOtherRoles/Modules/ModUpdater.cs @@ -301,4 +301,4 @@ public async Task DownloadUpdate() return true; } } -} \ No newline at end of file +} diff --git a/TheOtherRoles/Patches/CredentialsPatch.cs b/TheOtherRoles/Patches/CredentialsPatch.cs index a86ac80..897b586 100644 --- a/TheOtherRoles/Patches/CredentialsPatch.cs +++ b/TheOtherRoles/Patches/CredentialsPatch.cs @@ -170,7 +170,7 @@ public static void Postfix() public static async Task loadMOTDs() { HttpClient client = new(); - HttpResponseMessage response = await client.GetAsync("https://raw.githubusercontent.com/dabao40/GMIAMOTDs/main/MOTDs.txt".getGithubUrl()); + HttpResponseMessage response = await client.GetAsync(Helpers.isChinese() ? "https://gitee.com/dabaoimp11/GMIAMOTDs/raw/master/MOTDs.txt" : "https://raw.githubusercontent.com/dabao40/GMIAMOTDs/main/MOTDs.txt"); response.EnsureSuccessStatusCode(); string motds = await response.Content.ReadAsStringAsync(); foreach (string line in motds.Split("\n", StringSplitOptions.RemoveEmptyEntries)) diff --git a/TheOtherRoles/Patches/EndGamePatch.cs b/TheOtherRoles/Patches/EndGamePatch.cs index 7197b7c..100a539 100644 --- a/TheOtherRoles/Patches/EndGamePatch.cs +++ b/TheOtherRoles/Patches/EndGamePatch.cs @@ -569,6 +569,9 @@ public static void Postfix(AmongUsClient __instance, [HarmonyArgument(0)]ref End if (CachedPlayer.LocalPlayer.PlayerControl == Pursuer.pursuer) _ = new StaticAchievementToken("pursuer.common2"); } + if (Lighter.lighter != null && !Lighter.lighter.Data.IsDead && CachedPlayer.LocalPlayer.PlayerControl == Lighter.lighter) + _ = new StaticAchievementToken("lighter.common1"); + // Possible Additional winner: Opportunist if (Opportunist.opportunist != null && !Opportunist.opportunist.Data.IsDead && !saboWin && !arsonistWin && !miniLose) { diff --git a/TheOtherRoles/Patches/PlayerControlPatch.cs b/TheOtherRoles/Patches/PlayerControlPatch.cs index ff5d929..94d0afa 100644 --- a/TheOtherRoles/Patches/PlayerControlPatch.cs +++ b/TheOtherRoles/Patches/PlayerControlPatch.cs @@ -2734,7 +2734,9 @@ public static void Postfix(PlayerControl __instance, [HarmonyArgument(0)]PlayerC // Block Mimic(Killer) from morphing if camo or mushroom is active if (Camouflager.camouflageTimer <= 0f && !Helpers.MushroomSabotageActive()) MimicK.mimicK.setLook(target.Data.PlayerName, target.Data.DefaultOutfit.ColorId, target.Data.DefaultOutfit.HatId, target.Data.DefaultOutfit.VisorId, target.Data.DefaultOutfit.SkinId, target.Data.DefaultOutfit.PetId); - MimicK.victim = target; + MimicK.victim = target; + + if (CachedPlayer.LocalPlayer.PlayerControl == __instance) MimicK.acTokenChallenge.Value++; } // Mimic morph and arrows diff --git a/TheOtherRoles/RPC.cs b/TheOtherRoles/RPC.cs index fa697d2..20b55d3 100644 --- a/TheOtherRoles/RPC.cs +++ b/TheOtherRoles/RPC.cs @@ -1164,8 +1164,14 @@ public static void shifterShift(byte targetId) Blackmailer.blackmailer = oldShifter; Blackmailer.onAchievementActivate(); } - if (player == MimicK.mimicK) MimicK.mimicK = oldShifter; - if (player == MimicA.mimicA) MimicA.mimicA = oldShifter; + if (player == MimicK.mimicK) { + MimicK.mimicK = oldShifter; + MimicK.onAchievementActivate(); + } + if (player == MimicA.mimicA) { + MimicA.mimicA = oldShifter; + MimicA.onAchievementActivate(); + } if (player == BomberA.bomberA) { if (CachedPlayer.LocalPlayer.PlayerControl == player) { resetPoolables(); diff --git a/TheOtherRoles/Resources/Achievements.dat b/TheOtherRoles/Resources/Achievements.dat index 0b5a18e..291433d 100644 --- a/TheOtherRoles/Resources/Achievements.dat +++ b/TheOtherRoles/Resources/Achievements.dat @@ -15,6 +15,7 @@ niceShifter.common1,0, niceShifter.challenge,2, bait.common1,0,once, bait.challenge,2, +lighter.common1,1,noHint, detective.common1,0, detective.challenge,2, timeMaster.challenge,2, @@ -108,6 +109,11 @@ undertaker.common1,0, undertaker.another1,1,once,secret, blackmailer.common1,0,once, blackmailer.challenge,2, +mimicK.challenge,2, +mimicA.common1,1,once, +mimicA.challenge,2, +bomber.common1,0, +bomber.challenge,2, evilYasuna.another1,1, jester.common1,0, jester.challenge,2, @@ -124,6 +130,8 @@ vulture.challenge,2, lawyer.another1,1,once,secret, lawyer.challenge1,2, lawyer.challenge2,2, +thief.challenge,2, +thief.another1,1,secret, pursuer.common1,1, pursuer.common2,1,noHint, opportunist.common1,1,noHint, diff --git a/TheOtherRoles/Resources/stringData.json b/TheOtherRoles/Resources/stringData.json index 227ea73..82e21dd 100644 --- a/TheOtherRoles/Resources/stringData.json +++ b/TheOtherRoles/Resources/stringData.json @@ -7642,6 +7642,18 @@ "11": "\u5fc5\u8981\u306a\u72a0\u7272", "13": "\u8d70\u4f60\uff01" }, + "lightercommon1AchievementCond": { + "0": "[BLANK]", + "13": "[BLANK]" + }, + "lightercommon1AchievementGoal": { + "0": "Survive The Game", + "13": "\u5728\u6e38\u620f\u7ed3\u675f\u65f6\u4e3a\u5b58\u6d3b\u72b6\u6001" + }, + "lightercommon1AchievementTitle": { + "0": "Why Am I Here", + "13": "\u6211\u662f\u6765\u5e72\u4ec0\u4e48\u7684" + }, "detectivecommon1AchievementCond": { "0": "[BLANK]", "11": "[BLANK]", @@ -9036,6 +9048,66 @@ "11": "\u6c88\u9ed9", "13": "\u95ed\u5634\uff01" }, + "mimicKchallengeAchievementCond": { + "0": "[BLANK]", + "13": "[BLANK]" + }, + "mimicKchallengeAchievementGoal": { + "0": "Kill At Least 3 Players", + "13": "\u51fb\u6740\u81f3\u5c113\u540d\u73a9\u5bb6" + }, + "mimicKchallengeAchievementTitle": { + "0": "Not A Trace", + "13": "\u4e0d\u7559\u4efb\u4f55\u75d5\u8ff9" + }, + "mimicAcommon1AchievementCond": { + "0": "[BLANK]", + "13": "[BLANK]" + }, + "mimicAcommon1AchievementGoal": { + "0": "View The Portable Admin", + "13": "\u89c2\u5bdf\u79fb\u52a8\u5f0f\u7ba1\u7406\u5730\u56fe" + }, + "mimicAcommon1AchievementTitle": { + "0": "Where Are You", + "13": "\u6765\u770b\u770b\u4f60\u5728\u54ea" + }, + "mimicAchallengeAchievementCond": { + "0": "[BLANK]", + "13": "[BLANK]" + }, + "mimicAchallengeAchievementGoal": { + "0": "Morph At Least 4 Times Before The Meeting", + "13": "\u5728\u4f1a\u8bae\u524d\u81f3\u5c11\u5316\u5f624\u6b21" + }, + "mimicAchallengeAchievementTitle": { + "0": "Fake The Alibi", + "13": "\u4f2a\u9020\u4e0d\u5728\u573a\u8bc1\u660e" + }, + "bombercommon1AchievementCond": { + "0": "[BLANK]", + "13": "[BLANK]" + }, + "bombercommon1AchievementGoal": { + "0": "Plant A Bomb On Someone", + "13": "\u7ed9\u4e00\u540d\u73a9\u5bb6\u653e\u7f6e\u70b8\u5f39" + }, + "bombercommon1AchievementTitle": { + "0": "Plant And Boom", + "13": "\u653e\u7f6e...\u5f15\u7206!" + }, + "bomberchallengeAchievementCond": { + "0": "[BLANK]", + "13": "[BLANK]" + }, + "bomberchallengeAchievementGoal": { + "0": "Meet The Other Bomber And Blast Your Bomb Target", + "13": "\u4e0e\u53e6\u4e00\u540d\u53cc\u5b50\u7206\u7834\u8005\u6c47\u5408\u5e76\u5f15\u7206\u4f60\u7684\u76ee\u6807" + }, + "bomberchallengeAchievementTitle": { + "0": "Boom!", + "13": "\u827a\u672f\u5c31\u662f\u7206\u70b8!" + }, "evilYasunaanother1AchievementCond": { "0": "[BLANK]", "11": "[BLANK]", @@ -9231,6 +9303,30 @@ "0": "Working For Nothing", "13": "\u767d\u767d\u6253\u5de5\uff01" }, + "thiefcommon1AchievementCond": { + "0": "You Must Die After The Killing Attempt", + "13": "\u4f60\u5fc5\u987b\u5728\u8bd5\u56fe\u51fb\u6740\u540e\u6b7b\u4ea1" + }, + "thiefcommon1AchievementGoal": { + "0": "Fail To Steal Someone's Role", + "13": "\u8bd5\u56fe\u7a83\u53d6\u8eab\u4efd\u4f46\u5931\u8d25" + }, + "thiefcommon1AchievementTitle": { + "0": "Tried... But Failed", + "13": "\u66fe\u7ecf\u5c1d\u8bd5\u8fc7" + }, + "thiefchallengeAchievementGoal": { + "0": "Steal A Killer's Role By Killing Them", + "13": "\u6210\u529f\u7a83\u53d6\u6267\u5203\u8005\u7684\u8eab\u4efd" + }, + "thiefchallengeAchievementCond": { + "0": "[BLANK]", + "13": "[BLANK]" + }, + "thiefchallengeAchievementTitle": { + "0": "I Have A Role", + "13": "\u542c\u6211\u8bf4, \u6211\u6709\u804c\u4e1a\u4e86" + }, "pursuercommon1AchievementCond": { "0": "[BLANK]", "13": "[BLANK]" diff --git a/TheOtherRoles/TheOtherRoles.cs b/TheOtherRoles/TheOtherRoles.cs index 0b41ace..ec09027 100644 --- a/TheOtherRoles/TheOtherRoles.cs +++ b/TheOtherRoles/TheOtherRoles.cs @@ -1954,11 +1954,12 @@ public static class MimicK public static bool hasOneVote = true; public static bool countAsOne = true; - public static string name = ""; - public static List arrows = new(); public static float updateTimer = 0f; - public static float arrowUpdateInterval = 0.5f; + public static float arrowUpdateInterval = 0.5f; + + public static AchievementToken acTokenChallenge; + public static PlayerControl victim; @@ -1986,25 +1987,8 @@ public static void arrowUpdate() UnityEngine.Object.Destroy(arrow1.arrow); } } - - //if (MimicK.mimicK == null) return; - // Arrows一覧 - arrows = new List(); - - // インポスターの位置を示すArrowsを描画 - /*foreach (PlayerControl p in CachedPlayer.AllPlayers) - { - if (p.Data.IsDead) continue; - Arrow arrow; - if (p == MimicA.mimicA) - { - arrow = MimicA.isMorph ? new Arrow(Palette.White) : new Arrow(Palette.ImpostorRed); - arrow.arrow.SetActive(true); - arrow.Update(p.transform.position); - arrows.Add(arrow); - } - }*/ + arrows = new List(); if (MimicA.mimicA.Data.IsDead || MimicA.mimicA == null) return; Arrow arrow; @@ -2016,6 +2000,12 @@ public static void arrowUpdate() // タイマーに時間をセット updateTimer = arrowUpdateInterval; } + } + + public static void onAchievementActivate() + { + if (mimicK == null || CachedPlayer.LocalPlayer.PlayerControl != mimicK) return; + acTokenChallenge = new("mimicK.challenge", 0, (val, _) => val >= 3); } public static void clearAndReload() @@ -2039,7 +2029,8 @@ public static void clearAndReload() if (arrow?.arrow != null) UnityEngine.Object.Destroy(arrow.arrow); } - arrows = new List(); + arrows = new List(); + acTokenChallenge = null; } } @@ -2072,6 +2063,14 @@ public static Sprite getAdminSprite() else if (Helpers.isFungle()) button = FastDestroyableSingleton.Instance.UseButton.fastUseSettings[ImageNames.AdminMapButton]; adminButtonSprite = button.Image; return adminButtonSprite; + } + + public static AchievementToken acTokenCommon; + + public static void onAchievementActivate() + { + if (mimicA == null || CachedPlayer.LocalPlayer.PlayerControl != mimicA) return; + acTokenCommon = new("mimicA.challenge", 0, (val, _) => val >= 4); } public static List arrows = new();