From c893c040458a0e8553db925393069685bed5c22f Mon Sep 17 00:00:00 2001 From: Gurge44 Date: Sat, 2 Nov 2024 11:52:30 +0100 Subject: [PATCH] 3/99 --- EHR.sln.DotSettings | 23 ++-- Modules/Achievement.cs | 43 -------- Modules/Achievements.cs | 171 ++++++++++++++++++++++++++++++ Modules/ChatBubbleShower.cs | 73 +++++++++++++ Modules/LateTask.cs | 3 +- Modules/Statistics.cs | 28 ++++- Modules/Utils.cs | 39 ------- Patches/CheckGameEndPatch.cs | 2 + Patches/CredentialsPatch.cs | 1 + Patches/MeetingHudPatch.cs | 22 ++-- Patches/PlayerJoinAndLeftPatch.cs | 2 + Resources/Lang/en_US.json | 1 + 12 files changed, 301 insertions(+), 107 deletions(-) delete mode 100644 Modules/Achievement.cs create mode 100644 Modules/Achievements.cs create mode 100644 Modules/ChatBubbleShower.cs diff --git a/EHR.sln.DotSettings b/EHR.sln.DotSettings index 6e7e96eea..cc0424b77 100644 --- a/EHR.sln.DotSettings +++ b/EHR.sln.DotSettings @@ -1,14 +1,9 @@ - + SOLUTION - 1 - 1 + 1 + 1 1 - TOGETHER_SAME_LINE + TOGETHER_SAME_LINE AFK ATK AU @@ -51,10 +46,12 @@ TS UI VN - False - try + True + True + True + True + False + try { $SELECTION$ } diff --git a/Modules/Achievement.cs b/Modules/Achievement.cs deleted file mode 100644 index 3a84e9570..000000000 --- a/Modules/Achievement.cs +++ /dev/null @@ -1,43 +0,0 @@ -namespace EHR.Modules -{ - public class Achievement - { - public enum AchievementType - { - IdeasLiveOn, // As Undead, win with at least 3 Necromancers - HowCouldIBelieveThem, // Vote for Jester that was ejected - WhatKindOfGeniusCameUpWithThisRoleIdea, // Get Dad role - StabbingTheBack, // Kill a Crewmate as Backstabber - Honk, // Drag someone as Goose - Bruh, // Get vanilla Crewmate role - HowDoICraftThisAgain, // Craft something as Adventurer - ImCrewISwear, // Kill the last Impostor with all Neutral Killers dead - Covid20, // Infect 2 people as Virus - TheresThisGameMyDadTaughtMeItsCalledSwitch, // Swap as or be Swapped by Shifter at least 3 times in one round - FirstDayOnTheJob, // As an Amnesiac, remember that you were a Sidekick or Deathknight - UnderNewManagement, // As an Amnesiac, remember that you were a Cultist or Virus - OutOfTime, // Suicide or lose due to your role or an addon - TooCold, // Get frozen by Freezer, Beartrap, etc. - APerfectTimeToRewindIt, // Rewind time as Time Master - SerialKiller, // Kill everyone in FFA mode - PVPMaster, // Win in Solo PVP mode - HarderThanDrivingThroughTrafficLightsRight, // Win in Stop and Go mode - TwoFast4You, // Win in Speedrun mode - TooHotForMe, // Win in Hot Potato mode - SeekAndHide, // Win in Hide and Seek mode - Two012, // Win in Natural Disasters mode - YourFlagIsMine, // Win in Capture The Flag mode - BestReactionTime, // Win in Room Rush mode - KimJongUnExperience, // Vote for someone as Dictator - ImUnstoppable, // Get Medic's shield as Snitch - ThereCanOnlyBeOne, // Kill someone who had the same role as you - CantTouchThis, // As Detour, redirect at least 3 interactions - ItsMorbinTime, // Shapeshift into someone - WhatHaveIDone, // Kill your Lover, Romantic, Lawyer or Follower - BetrayalLevel100, // Kill Madmate as Impostor or Impostor as Madmate - TheRealTraitor, // Kill renegade as traitor (the neutral one) - DiePleaseDie, // Try to kill the same player with Medic's shield 2 times, both unsuccessfully - MasterDetective, // As Crewmate, vote only for Impostors and Neutral Killers - } - } -} \ No newline at end of file diff --git a/Modules/Achievements.cs b/Modules/Achievements.cs new file mode 100644 index 000000000..c4afd4254 --- /dev/null +++ b/Modules/Achievements.cs @@ -0,0 +1,171 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace EHR.Modules +{ + public static class Achievements + { + public static HashSet WaitingAchievements = []; + public static HashSet CompletedAchievements = []; + + public static void Complete(this Type type) + { + if (!CompletedAchievements.Add(type)) return; + + if (type.IsDisplayedAfterGameEnd()) + { + WaitingAchievements.Add(type); + return; + } + + ShowAchievementCompletion(type); + } + + public static void CompleteAfterDelay(this Type type, float delay) + { + if (!CompletedAchievements.Add(type)) return; + Main.Instance.StartCoroutine(CompleteAchievementAfterDelayAsync()); + return; + + System.Collections.IEnumerator CompleteAchievementAfterDelayAsync() + { + float timer = 0f; + while (!GameStates.IsEnded && timer < delay) + { + yield return null; + timer += Time.deltaTime; + } + + if (GameStates.IsEnded) + { + WaitingAchievements.Add(type); + yield break; + } + + ShowAchievementCompletion(type); + } + } + + public static void ShowWaitingAchievements() + { + WaitingAchievements.Do(ShowAchievementCompletion); + WaitingAchievements.Clear(); + } + + private static void ShowAchievementCompletion(Type type) + { + var title = Translator.GetString("AchievementCompletedTitle"); + var description = Translator.GetString($"Achievement.{type}.Description"); + var message = $"{Translator.GetString($"Achievement.{type}")}\\n{description}"; + ChatBubbleShower.ShowChatBubbleInRound(message, title); + } + + public static bool IsDisplayedAfterGameEnd(this Type type) => type is + Type.IdeasLiveOn or + Type.Awww or + Type.Ohhh; + + public enum Type + { + IdeasLiveOn, // As Undead, win with at least 3 Necromancers + HowCouldIBelieveThem, // Vote for Jester that was ejected + WhatKindOfGeniusCameUpWithThisRoleIdea, // Get Dad role + StabbingTheBack, // Kill a Crewmate as Backstabber + Honk, // Drag someone as Goose + Bruh, // Get vanilla Crewmate role + HowDoICraftThisAgain, // Craft something as Adventurer + ImCrewISwear, // Kill the last Impostor with all Neutral Killers dead + Covid20, // Infect 2 people as Virus + TheresThisGameMyDadTaughtMeItsCalledSwitch, // Swap as or be Swapped by Shifter at least 3 times in one round + FirstDayOnTheJob, // As an Amnesiac, remember that you were a Sidekick or Deathknight + UnderNewManagement, // As an Amnesiac, remember that you were a Cultist or Virus + OutOfTime, // Suicide or lose due to your role or an addon + TooCold, // Get frozen by Freezer, Beartrap, etc. + APerfectTimeToRewindIt, // Rewind time as Time Master + SerialKiller, // Kill everyone in FFA mode + PVPMaster, // Win in Solo PVP mode + HarderThanDrivingThroughTrafficLightsRight, // Win in Stop and Go mode + TwoFast4You, // Win in Speedrun mode + TooHotForMe, // Win in Hot Potato mode + SeekAndHide, // Win in Hide and Seek mode + Two012, // Win in Natural Disasters mode + YourFlagIsMine, // Win in Capture The Flag mode + BestReactionTime, // Win in Room Rush mode + KimJongUnExperience, // Vote for someone as Dictator + ImUnstoppable, // Get Medic's shield as Snitch + ThereCanOnlyBeOne, // Kill someone who had the same role as you + CantTouchThis, // As Detour, redirect at least 3 interactions + ItsMorbinTime, // Shapeshift into someone + WhatHaveIDone, // Kill your Lover, Romantic, Lawyer or Follower + BetrayalLevel100, // Kill Madmate as Impostor or Impostor as Madmate + TheRealTraitor, // Kill renegade as traitor (the neutral one) + DiePleaseDie, // Try to kill the same player with Medic's shield 2 times, both unsuccessfully + MasterDetective, // As Crewmate, vote only for Impostors and Neutral Killers + Superhero, // Kill all Impostors (including Renegade and Parasite) and Neutral Killers alone as Sheriff + TheKillingMachine2Point0, // Kill >= 7 players in the same game as Impostor/Neutral Killer + ALightInTheShadows, // Walk near the Beacon during the lights sabotage so they increase your vision + IForgotThisRoleExists, // Try to kill someone who is protected by Guardian Angel + TheLastSurvivor, // Win as a Crewmate, when you are the only alive player left + YouDidTheExactOppositeOfWhatYouWereSupposedToDo, // Die first as Maverick or Opportunist + WheresTheBlueShell, // Finish second in Room Rush + InnocentKiller, // Kill 2 players as a non-killing role (for example due to the Warlock's curse) + YouWontTellAnyone, // Silence Snitch with all tasks done as Silencer + ExpertControl, // As Spurt, avoid reaching 0% and 100% speed for a round (If it was only to avoid 0 then they could just afk. Having to avoid both forces them to keep moving) + YoureMyFriendNow, // Recruit anyone as Gangster/Jackal/Infection/Virus/Cultist + ThatWasClose, // As a killer, kill Snitch with all their tasks done (or when Snitch is revealed) + CrewHero, // As Snitch, complete all your tasks, eject all Impostors and Neutral Killers, be alive until the end and win with crewmates + Transformer, // Complete at least 3 transformations in the same game (transformation is changing roles. For example Amnesiac => Sheriff => Sidekick) + InnocentImpostor, // Win as Impostor, not making any kill + ImpostorGang, // Win as Impostor with all your partners alive + FuriousAvenger, // Find yourself in a situation when Butcher kills Avenger and everyone dies + BrainStorm, // Get rid of all killers as a Crewmate and win with crewmates in less than 3 meetings (there must be at least 2 killers at the start of the game) + NothingCanStopLove, // Win as Lover/Loving Impostor with your partner alone (not with other teams) + SimonSays, // Complete the Simon's instruction + Unsuspected, // Win a game as a killer, not being voted by anyone in all meetings + YoureTooLate, // As Pestilence, have a killer try to kill you, but unsuccessfully for them + Armageddon, // Survive the Tremor's doom + GetDownMrPresident, // Protect the President as the Bodyguard + SecureFooted, // Get dragged into a tornado and escape it + EconomicCompetition, // Kill Merchant as Bargainer, or kill Bargainer as Merchant + Gotcha, // Kill Bait and then get ejected + Speedrun, // Have a game end in under 1 minute + Backfired, // Get killed by your own ability, somehow + Carried, // Win as a madmate while the other impostors are dead + SorryToBurstYourBubble, // Explode 5 people in one round as bubble + GetLynched, // Successfully guess 3 roles as lyncher + FlagMaster, // Carry the flag the longest in your team in CTF + Tag, // Tag the most players in CTF + Vectory, // Vent 50 times in one game + Bloodbath, // Kill 8 people in the same game as Killing Machine + AntiSaboteur, // Fix all types of sabotages (Reactor, o2, Lights, Comms) as Technician (not necessarily in the same game) + TheBestInSchool, // Be the first who answer the Mathematician's question correctly + Awww, // Drag Penguin as Goose (this achievement is gain after the game end) + Ohhh, // Drag Goose as Penguin (this achievement is gain after the game end) + Hypnosis, // Try to report a dead body during the Hypnotist's ability + Mimicry, // Change your appearance at least 3 times as Doppelganger + P2W, // Buy all items as Bargainer and win in the same game + LuckOrObservation, // Guess 1 player correctly + BeginnerGuesser, // Guess 5 players correctly + GuessMaster, // Guess 15 players correctly + BestGuesserAward, // Guess 50 players correctly + BadLuckOrBadObservation, // Guess incorrectly and die + Duel, // Find yourself in a situation when you are 1vs1 against another killer + Delicious, // Get Donut Delivery's donut and a Chef's dish + Inquisition, // Kill Vampire/Witch/Warlock/Hex Master as Crusadeur + Censorship, // Silence 5 people in the same game as Silencer + LiarLiar, // As Lawyer, fail to protect your client that is crewmate, and then win with impostors somehow + IWishIReported, // Revive an Impostor/Converted Crewmate/Neutral Killer as Altruist + WellMeetAgainSomeSunnyDay, // Mark someone as Hookshot + FirstTimeUsingComputer, // Don't send any commands for the entire game + Expert, // Don't use F1, /m or /r for 5 rounds straight + AndForWhatDidICodeThereCommandsForIfYouDontUseThemAtAll, // Don't use any command for 10 rounds straight + Prankster, // Shapeshift or Vanish as a different color as Disco + WhatTheHell, // Type 666 in chat as Demon. Will others notice this? >:) + WhyJustWhy, // As Dictator, vote out the Jester + CommonEnemyNo1, // Win as any NK + CoordinatedAttack, // As Jester, Executioner or Innocent, win with any of the other 2 roles + ItsJustAPrankBro, // As Bomber, Kill half the lobby in 1 bomb + MindReader, // As doomsayer, guess 3 people in 1 meeting + } + } +} \ No newline at end of file diff --git a/Modules/ChatBubbleShower.cs b/Modules/ChatBubbleShower.cs new file mode 100644 index 000000000..1fe9b4042 --- /dev/null +++ b/Modules/ChatBubbleShower.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using TMPro; +using UnityEngine; + +namespace EHR.Modules +{ + public static class ChatBubbleShower + { + private static long LastChatBubbleShowTS; + private static HashSet<(string Message, string Title)> Queue = []; + + public static void Update() + { + try + { + if (Queue.Count == 0) return; + + long now = Utils.TimeStamp; + if (LastChatBubbleShowTS + 4 > now) return; + LastChatBubbleShowTS = now; + + (string message, string title) = Queue.First(); + Queue.Remove((message, title)); + + ChatController chat = DestroyableSingleton.Instance.Chat; + NetworkedPlayerInfo data = PlayerControl.LocalPlayer.Data; + ChatBubble bubble = chat.GetPooledBubble(); + + try + { + bubble.transform.SetParent(chat.scroller.Inner); + bubble.transform.localScale = Vector3.one; + bubble.SetCosmetics(data); + bubble.gameObject.transform.Find("PoolablePlayer").gameObject.SetActive(false); + bubble.ColorBlindName.gameObject.SetActive(false); + bubble.SetLeft(); + bubble.gameObject.transform.Find("NameText (TMP)").transform.localPosition += new Vector3(-0.7f, 0f); + bubble.gameObject.transform.Find("ChatText (TMP)").transform.localPosition += new Vector3(-0.7f, 0f); + chat.SetChatBubbleName(bubble, data, data.IsDead, false, PlayerNameColor.Get(data)); + bubble.SetText(message); + bubble.AlignChildren(); + chat.AlignAllBubbles(); + bubble.NameText.text = title; + bubble.transform.Find("ChatText (TMP)").GetComponent().color = new(1f, 1f, 1f, 1f); + bubble.transform.Find("Background").GetComponent().color = new(0.05f, 0.05f, 0.05f, 1f); + Transform xMark = bubble.transform.Find("PoolablePlayer/xMark"); + if (xMark && xMark.GetComponent().enabled) bubble.transform.Find("Background").GetComponent().color = new(0.05f, 0.05f, 0.05f, 0.5f); + } + catch (Exception e) + { + chat.chatBubblePool.Reclaim(bubble); + Utils.ThrowException(e); + } + } + catch (Exception e) + { + Utils.ThrowException(e); + } + } + + /// + /// Displays a chat bubble with a message and a title during the round for the local player. + /// + /// The message to display in the chat bubble. + /// The title of the chat bubble. + public static void ShowChatBubbleInRound(string message, string title) + { + Queue.Add((message, title)); + } + } +} \ No newline at end of file diff --git a/Modules/LateTask.cs b/Modules/LateTask.cs index a5f5c6a69..36a0b77b1 100644 --- a/Modules/LateTask.cs +++ b/Modules/LateTask.cs @@ -57,7 +57,8 @@ namespace EHR { if (task.Run(deltaTime)) { - if (task.name is not "" and not "No Name Task" && task.log) Logger.Info($"\"{task.name}\" is finished", "LateTask"); + if (task.name is not "" and not "No Name Task" && task.log) + Logger.Info($"\"{task.name}\" is finished", "LateTask"); Tasks.Remove(task); } diff --git a/Modules/Statistics.cs b/Modules/Statistics.cs index 08054484a..1784b4c94 100644 --- a/Modules/Statistics.cs +++ b/Modules/Statistics.cs @@ -1,7 +1,31 @@ -namespace EHR.Modules +using System.Linq; + +namespace EHR.Modules { public static class Statistics { - + public static void OnGameEnd() + { + var lp = PlayerControl.LocalPlayer; + var role = lp.GetCustomRole(); + var addons = lp.GetCustomSubRoles(); + + bool won = CustomWinnerHolder.WinnerIds.Contains(lp.PlayerId) || CustomWinnerHolder.WinnerRoles.Contains(role) || (CustomWinnerHolder.WinnerTeam == CustomWinner.Bloodlust && addons.Contains(CustomRoles.Bloodlust)); + + if (won && addons.Contains(CustomRoles.Undead) && CustomWinnerHolder.WinnerIds.ToValidPlayers().Count(x => x.Is(CustomRoles.Necromancer)) >= 3) + Achievements.Type.IdeasLiveOn.Complete(); + } + + public static void OnVotingComplete(MeetingHud.VoterState[] states, NetworkedPlayerInfo exiledPlayer, bool tie, bool dictator) + { + if (!tie && exiledPlayer != null && exiledPlayer.Object != null && exiledPlayer.Object.Is(CustomRoles.Jester)) + { + if (states.Any(x => x.VoterId == PlayerControl.LocalPlayer.PlayerId && x.VotedForId == exiledPlayer.PlayerId)) + Achievements.Type.HowCouldIBelieveThem.CompleteAfterDelay(8f); + + if (dictator && PlayerControl.LocalPlayer.Is(CustomRoles.Dictator) && states.FindFirst(x => x.VoterId == PlayerControl.LocalPlayer.PlayerId, out var lpVS) && lpVS.VotedForId == exiledPlayer.PlayerId) + Achievements.Type.WhyJustWhy.CompleteAfterDelay(8f); + } + } } } \ No newline at end of file diff --git a/Modules/Utils.cs b/Modules/Utils.cs index 43e043838..ffa035a7f 100644 --- a/Modules/Utils.cs +++ b/Modules/Utils.cs @@ -3065,45 +3065,6 @@ other: ∟ ⌠ ⌡ ╬ ╨ ▓ ▒ ░ « » █ ▄ ▌▀▐│ ┤ ╡ ╢ return (draw, all); } - // Will be used for displaying achievement completions later - /// - /// Displays a chat bubble with a message and a title during the round for the local player. - /// - /// The message to display in the chat bubble. - /// The title of the chat bubble. - public static void ShowChatBubbleInRound(string message, string title) - { - ChatController chat = DestroyableSingleton.Instance.Chat; - NetworkedPlayerInfo data = PlayerControl.LocalPlayer.Data; - ChatBubble bubble = chat.GetPooledBubble(); - - try - { - bubble.transform.SetParent(chat.scroller.Inner); - bubble.transform.localScale = Vector3.one; - bubble.SetCosmetics(data); - bubble.gameObject.transform.Find("PoolablePlayer").gameObject.SetActive(false); - bubble.ColorBlindName.gameObject.SetActive(false); - bubble.SetLeft(); - bubble.gameObject.transform.Find("NameText (TMP)").transform.localPosition += new Vector3(-0.7f, 0f); - bubble.gameObject.transform.Find("ChatText (TMP)").transform.localPosition += new Vector3(-0.7f, 0f); - chat.SetChatBubbleName(bubble, data, data.IsDead, false, PlayerNameColor.Get(data)); - bubble.SetText(message); - bubble.AlignChildren(); - chat.AlignAllBubbles(); - bubble.NameText.text = title; - bubble.transform.Find("ChatText (TMP)").GetComponent().color = new(1f, 1f, 1f, 1f); - bubble.transform.Find("Background").GetComponent().color = new(0.05f, 0.05f, 0.05f, 1f); - Transform xMark = bubble.transform.Find("PoolablePlayer/xMark"); - if (xMark && xMark.GetComponent().enabled) bubble.transform.Find("Background").GetComponent().color = new(0.05f, 0.05f, 0.05f, 0.5f); - } - catch (Exception e) - { - chat.chatBubblePool.Reclaim(bubble); - ThrowException(e); - } - } - public static string SummaryTexts(byte id, bool disableColor = true, bool check = false) { //var RolePos = TranslationController.Instance.currentLanguage.languageID is SupportedLangs.English or SupportedLangs.Russian ? 37 : 34; diff --git a/Patches/CheckGameEndPatch.cs b/Patches/CheckGameEndPatch.cs index f325411f9..218a5f984 100644 --- a/Patches/CheckGameEndPatch.cs +++ b/Patches/CheckGameEndPatch.cs @@ -328,6 +328,8 @@ namespace EHR SetEverythingUpPatch.LastWinsReason = WinnerTeam is CustomWinner.Crewmate or CustomWinner.Impostor ? GetString($"GameOverReason.{reason}") : string.Empty; var self = AmongUsClient.Instance; self.StartCoroutine(CoEndGame(self, reason).WrapToIl2Cpp()); + + Statistics.OnGameEnd(); } private static IEnumerator CoEndGame(InnerNetClient self, GameOverReason reason) diff --git a/Patches/CredentialsPatch.cs b/Patches/CredentialsPatch.cs index eb8174871..6c04e6bcc 100644 --- a/Patches/CredentialsPatch.cs +++ b/Patches/CredentialsPatch.cs @@ -226,6 +226,7 @@ namespace EHR LateTask.Update(Time.deltaTime); CheckMurderPatch.Update(); + ChatBubbleShower.Update(); return false; } diff --git a/Patches/MeetingHudPatch.cs b/Patches/MeetingHudPatch.cs index 26b186203..e1e6f658f 100644 --- a/Patches/MeetingHudPatch.cs +++ b/Patches/MeetingHudPatch.cs @@ -74,6 +74,8 @@ namespace EHR.Patches states = [.. statesList]; __instance.RpcVotingComplete(states.ToArray(), voteTarget.Data, false); + + Statistics.OnVotingComplete(states.ToArray(), voteTarget.Data, false, true); Logger.Info($"{voteTarget.GetNameWithRole().RemoveHtmlTags()} expelled by dictator", "Dictator"); CheckForDeathOnExile(PlayerState.DeathReason.Vote, pva.VotedFor); @@ -309,6 +311,8 @@ namespace EHR.Patches exiledPlayer?.Object.SetRealKiller(null); __instance.RpcVotingComplete(states.ToArray(), exiledPlayer, tie); + + Statistics.OnVotingComplete(states.ToArray(), exiledPlayer, tie, false); CheckForDeathOnExile(PlayerState.DeathReason.Vote, exileId); Utils.CheckAndSpawnAdditionalRefugee(exiledPlayer); @@ -638,22 +642,22 @@ namespace EHR.Patches } if (CheckForEndVotingPatch.CheckRole(ps.TargetPlayerId, CustomRoles.Mayor)) VoteNum += Mayor.MayorAdditionalVote.GetInt(); - if (CheckForEndVotingPatch.CheckRole(ps.TargetPlayerId, CustomRoles.Knighted)) VoteNum += 1; - if (CheckForEndVotingPatch.CheckRole(ps.TargetPlayerId, CustomRoles.Glitch) && !Glitch.CanVote.GetBool()) VoteNum = 0; - if (CheckForEndVotingPatch.CheckRole(ps.TargetPlayerId, CustomRoles.Vindicator)) VoteNum += Options.VindicatorAdditionalVote.GetInt(); - if (CheckForEndVotingPatch.CheckRole(ps.TargetPlayerId, CustomRoles.DualPersonality) && Options.DualVotes.GetBool()) VoteNum += VoteNum; - if (CheckForEndVotingPatch.CheckRole(ps.TargetPlayerId, CustomRoles.TicketsStealer)) VoteNum += (int)(Main.AllPlayerControls.Count(x => x.GetRealKiller()?.PlayerId == ps.TargetPlayerId) * Options.TicketsPerKill.GetFloat()); - if (CheckForEndVotingPatch.CheckRole(ps.TargetPlayerId, CustomRoles.Pickpocket)) VoteNum += (int)(Main.AllPlayerControls.Count(x => x.GetRealKiller()?.PlayerId == ps.TargetPlayerId) * Pickpocket.VotesPerKill.GetFloat()); - if (Main.PlayerStates[ps.TargetPlayerId].Role is Adventurer { IsEnable: true } av && av.ActiveWeapons.Contains(Adventurer.Weapon.Proxy)) VoteNum++; - - if (Main.PlayerStates[ps.TargetPlayerId].Role is Dad { IsEnable: true } dad && dad.UsingAbilities.Contains(Dad.Ability.GoForMilk)) VoteNum = 0; + switch (Main.PlayerStates[ps.TargetPlayerId].Role) + { + case Adventurer { IsEnable: true } av when av.ActiveWeapons.Contains(Adventurer.Weapon.Proxy): + VoteNum++; + break; + case Dad { IsEnable: true } dad when dad.UsingAbilities.Contains(Dad.Ability.GoForMilk): + VoteNum = 0; + break; + } if (ps.TargetPlayerId == ps.VotedFor && Options.MadmateSpawnMode.GetInt() == 2 && CustomRoles.Madmate.IsEnable() && MeetingStates.FirstMeeting) VoteNum = 0; diff --git a/Patches/PlayerJoinAndLeftPatch.cs b/Patches/PlayerJoinAndLeftPatch.cs index 075548bf8..8e1a2aba5 100644 --- a/Patches/PlayerJoinAndLeftPatch.cs +++ b/Patches/PlayerJoinAndLeftPatch.cs @@ -31,6 +31,8 @@ namespace EHR ChatUpdatePatch.DoBlockChat = false; GameStates.InGame = false; ErrorText.Instance?.Clear(); + + Achievements.ShowWaitingAchievements(); if (AmongUsClient.Instance.AmHost) { diff --git a/Resources/Lang/en_US.json b/Resources/Lang/en_US.json index 2316201e8..a2aaace4e 100644 --- a/Resources/Lang/en_US.json +++ b/Resources/Lang/en_US.json @@ -3336,6 +3336,7 @@ "Allergic.Time": "Time in which the allergy level goes from 0% to 100%", "Allergic.Range": "Maximum distance from the target that is considered nearby", "Allergic.Suffix": "<#ffff44>Allergy Level: {0}%", + "BetrayalAddonsCanGuess": "Players With <#ffab1b>Betrayal Add-ons Can Guess", "Enigma": "Enigma", "EnigmaInfo": "Get Clues about Killers", "EnigmaInfoLong": "(Crewmates):\\nAs the Enigma, you get a random clue about the killer each meeting, depending on the setting, you may have to report the body to receive a clue. The more tasks you complete the preciser the clues get.\\n\\nLight colors: Red, Pink, Orange, Yellow, White, Cyan, Lime, Rose, Banana, Coral\\nDark colors: Blue, Green, Black, Purple, Brown, Maroon, Gray, Tan",