From 5b89ee0b72b159f4b469769b28628424fd8852b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mall=C3=B6ris?= <|||||@||.||> Date: Fri, 24 Jun 2022 00:43:01 +0200 Subject: [PATCH 1/2] update --- TheOtherRoles/Buttons.cs | 13 ++-- TheOtherRoles/CustomOptionHolder.cs | 18 ++--- TheOtherRoles/Helpers.cs | 22 +++---- TheOtherRoles/Main.cs | 40 ++++++++---- TheOtherRoles/Modules/CustomHats.cs | 8 +-- TheOtherRoles/Objects/Bloodytrail.cs | 2 +- TheOtherRoles/Objects/Portal.cs | 6 +- .../Patches/AirShipSetAntiTpPosition.cs | 21 ++++++ TheOtherRoles/Patches/ClientOptionsPatch.cs | 11 ---- TheOtherRoles/Patches/CredentialsPatch.cs | 2 +- TheOtherRoles/Patches/EndGamePatch.cs | 14 ++-- .../Patches/GameStartManagerPatch.cs | 65 ++++++++++--------- TheOtherRoles/Patches/IntroPatch.cs | 8 +-- TheOtherRoles/Patches/MeetingPatch.cs | 60 ++++++++++------- TheOtherRoles/Patches/PlayerControlPatch.cs | 25 +++---- TheOtherRoles/Patches/RoleAssignmentPatch.cs | 4 +- TheOtherRoles/Patches/ShipStatusPatch.cs | 2 +- TheOtherRoles/Patches/UpdatePatch.cs | 22 +++---- TheOtherRoles/Patches/UsablesPatch.cs | 8 +-- TheOtherRoles/RPC.cs | 10 +-- TheOtherRoles/TheOtherRoles.csproj | 2 +- TheOtherRoles/packages.lock.json | 6 +- 22 files changed, 207 insertions(+), 162 deletions(-) create mode 100644 TheOtherRoles/Patches/AirShipSetAntiTpPosition.cs diff --git a/TheOtherRoles/Buttons.cs b/TheOtherRoles/Buttons.cs index 11439b9fd..e47eb8871 100644 --- a/TheOtherRoles/Buttons.cs +++ b/TheOtherRoles/Buttons.cs @@ -26,8 +26,8 @@ static class HudManagerStartPatch private static CustomButton portalmakerPlacePortalButton; private static CustomButton usePortalButton; private static CustomButton hackerButton; - private static CustomButton hackerVitalsButton; - private static CustomButton hackerAdminTableButton; + public static CustomButton hackerVitalsButton; + public static CustomButton hackerAdminTableButton; private static CustomButton trackerTrackPlayerButton; private static CustomButton trackerTrackCorpsesButton; public static CustomButton vampireKillButton; @@ -436,11 +436,11 @@ public static void Postfix(HudManager __instance) morphlingButton.actionButton.cooldownTimerText.transform.localPosition = new Vector3(0, 0, -1f); // Before the poolable player morphTargetDisplay = UnityEngine.Object.Instantiate(Patches.IntroCutsceneOnDestroyPatch.playerPrefab, morphlingButton.actionButton.transform); GameData.PlayerInfo data = Morphling.sampledTarget.Data; - PlayerControl.SetPlayerMaterialColors(data.DefaultOutfit.ColorId, morphTargetDisplay.CurrentBodySprite.BodySprite); + Morphling.sampledTarget.SetPlayerMaterialColors(morphTargetDisplay.cosmetics.currentBodySprite.BodySprite); morphTargetDisplay.SetSkin(data.DefaultOutfit.SkinId, data.DefaultOutfit.ColorId); - morphTargetDisplay.HatSlot.SetHat(data.DefaultOutfit.HatId, data.DefaultOutfit.ColorId); - PlayerControl.SetPetImage(data.DefaultOutfit.PetId, data.DefaultOutfit.ColorId, morphTargetDisplay.PetSlot); - morphTargetDisplay.NameText.text = ""; // Hide the name! + morphTargetDisplay.SetHat(data.DefaultOutfit.HatId, data.DefaultOutfit.ColorId); + // PlayerControl.SetPetImage(data.DefaultOutfit.PetId, data.DefaultOutfit.ColorId, morphTargetDisplay.PetSlot); + morphTargetDisplay.cosmetics.nameText.text = ""; // Hide the name! morphTargetDisplay.transform.localPosition = new Vector3(0f, 0.22f, -0.01f); morphTargetDisplay.transform.localScale = Vector3.one * 0.33f; morphTargetDisplay.setSemiTransparent(false); @@ -1009,6 +1009,7 @@ public static void Postfix(HudManager __instance) // If blanked or killed if(Warlock.rootTime > 0) { + AntiTeleport.position = CachedPlayer.LocalPlayer.transform.position; CachedPlayer.LocalPlayer.PlayerControl.moveable = false; CachedPlayer.LocalPlayer.NetTransform.Halt(); // Stop current movement so the warlock is not just running straight into the next object FastDestroyableSingleton.Instance.StartCoroutine(Effects.Lerp(Warlock.rootTime, new Action((p) => { // Delayed action diff --git a/TheOtherRoles/CustomOptionHolder.cs b/TheOtherRoles/CustomOptionHolder.cs index 2f8d90b4c..6571201de 100644 --- a/TheOtherRoles/CustomOptionHolder.cs +++ b/TheOtherRoles/CustomOptionHolder.cs @@ -294,14 +294,14 @@ public static void Load() { activateRoles = CustomOption.Create(1, Types.General, cs(new Color(204f / 255f, 204f / 255f, 0, 1f), "Enable Mod Roles And Block Vanilla Roles"), true, null, true); // Using new id's for the options to not break compatibilty with older versions - crewmateRolesCountMin = CustomOption.Create(300, Types.General, cs(new Color(204f / 255f, 204f / 255f, 0, 1f), "Minimum Crewmate Roles"), 0f, 0f, 15f, 1f, null, true); - crewmateRolesCountMax = CustomOption.Create(301, Types.General, cs(new Color(204f / 255f, 204f / 255f, 0, 1f), "Maximum Crewmate Roles"), 0f, 0f, 15f, 1f); - neutralRolesCountMin = CustomOption.Create(302, Types.General, cs(new Color(204f / 255f, 204f / 255f, 0, 1f), "Minimum Neutral Roles"), 0f, 0f, 15f, 1f); - neutralRolesCountMax = CustomOption.Create(303, Types.General, cs(new Color(204f / 255f, 204f / 255f, 0, 1f), "Maximum Neutral Roles"), 0f, 0f, 15f, 1f); - impostorRolesCountMin = CustomOption.Create(304, Types.General, cs(new Color(204f / 255f, 204f / 255f, 0, 1f), "Minimum Impostor Roles"), 0f, 0f, 3f, 1f); - impostorRolesCountMax = CustomOption.Create(305, Types.General, cs(new Color(204f / 255f, 204f / 255f, 0, 1f), "Maximum Impostor Roles"), 0f, 0f, 3f, 1f); - modifiersCountMin = CustomOption.Create(306, Types.General, cs(new Color(204f / 255f, 204f / 255f, 0, 1f), "Minimum Modifiers"), 0f, 0f, 15f, 1f); - modifiersCountMax = CustomOption.Create(307, Types.General, cs(new Color(204f / 255f, 204f / 255f, 0, 1f), "Maximum Modifiers"), 0f, 0f, 15f, 1f); + crewmateRolesCountMin = CustomOption.Create(300, Types.General, cs(new Color(204f / 255f, 204f / 255f, 0, 1f), "Minimum Crewmate Roles"), 15f, 0f, 15f, 1f, null, true); + crewmateRolesCountMax = CustomOption.Create(301, Types.General, cs(new Color(204f / 255f, 204f / 255f, 0, 1f), "Maximum Crewmate Roles"), 15f, 0f, 15f, 1f); + neutralRolesCountMin = CustomOption.Create(302, Types.General, cs(new Color(204f / 255f, 204f / 255f, 0, 1f), "Minimum Neutral Roles"), 15f, 0f, 15f, 1f); + neutralRolesCountMax = CustomOption.Create(303, Types.General, cs(new Color(204f / 255f, 204f / 255f, 0, 1f), "Maximum Neutral Roles"), 15f, 0f, 15f, 1f); + impostorRolesCountMin = CustomOption.Create(304, Types.General, cs(new Color(204f / 255f, 204f / 255f, 0, 1f), "Minimum Impostor Roles"), 15f, 0f, 3f, 1f); + impostorRolesCountMax = CustomOption.Create(305, Types.General, cs(new Color(204f / 255f, 204f / 255f, 0, 1f), "Maximum Impostor Roles"), 15f, 0f, 3f, 1f); + modifiersCountMin = CustomOption.Create(306, Types.General, cs(new Color(204f / 255f, 204f / 255f, 0, 1f), "Minimum Modifiers"), 15f, 0f, 15f, 1f); + modifiersCountMax = CustomOption.Create(307, Types.General, cs(new Color(204f / 255f, 204f / 255f, 0, 1f), "Maximum Modifiers"), 15f, 0f, 15f, 1f); mafiaSpawnRate = CustomOption.Create(10, Types.Impostor, cs(Janitor.color, "Mafia"), rates, null, true); janitorCooldown = CustomOption.Create(11, Types.Impostor, "Janitor Cooldown", 30f, 10f, 60f, 2.5f, mafiaSpawnRate); @@ -355,7 +355,7 @@ public static void Load() { ninjaKnowsTargetLocation = CustomOption.Create(382, Types.Impostor, "Ninja Knows Location Of Target", true, ninjaSpawnRate); ninjaTraceTime = CustomOption.Create(383, Types.Impostor, "Trace Duration", 5f, 1f, 20f, 0.5f, ninjaSpawnRate); ninjaTraceColorTime = CustomOption.Create(384, Types.Impostor, "Time Till Trace Color Has Faded", 2f, 0f, 20f, 0.5f, ninjaSpawnRate); - ninjaInvisibleDuration = CustomOption.Create(385, Types.Impostor, "Time The Ninja Is Invisble", 3f, 0f, 20f, 1f, ninjaSpawnRate); + ninjaInvisibleDuration = CustomOption.Create(385, Types.Impostor, "Time The Ninja Is Invisible", 3f, 0f, 20f, 1f, ninjaSpawnRate); guesserSpawnRate = CustomOption.Create(310, Types.Neutral, cs(Guesser.color, "Guesser"), rates, null, true); guesserIsImpGuesserRate = CustomOption.Create(311, Types.Neutral, "Chance That The Guesser Is An Impostor", rates, guesserSpawnRate); diff --git a/TheOtherRoles/Helpers.cs b/TheOtherRoles/Helpers.cs index c83495c46..1f78ae7c7 100644 --- a/TheOtherRoles/Helpers.cs +++ b/TheOtherRoles/Helpers.cs @@ -180,7 +180,7 @@ public static void setSemiTransparent(this PoolablePlayer player, bool value) { float alpha = value ? 0.25f : 1f; foreach (SpriteRenderer r in player.gameObject.GetComponentsInChildren()) r.color = new Color(r.color.r, r.color.g, r.color.b, alpha); - player.NameText.color = new Color(player.NameText.color.r, player.NameText.color.g, player.NameText.color.b, alpha); + player.cosmetics.nameText.color = new Color(player.cosmetics.nameText.color.r, player.cosmetics.nameText.color.g, player.cosmetics.nameText.color.b, alpha); } public static string GetString(this TranslationController t, StringNames key, params Il2CppSystem.Object[] parts) { @@ -240,7 +240,7 @@ public static void setLook(this PlayerControl target, String playerName, int col SkinViewData nextSkin = FastDestroyableSingleton.Instance.GetSkinById(skinId).viewData.viewData; PlayerPhysics playerPhysics = target.MyPhysics; AnimationClip clip = null; - var spriteAnim = playerPhysics.Skin.animator; + var spriteAnim = playerPhysics.myPlayer.cosmetics.skin.animator; var currentPhysicsAnim = playerPhysics.Animator.GetCurrentAnimation(); if (currentPhysicsAnim == playerPhysics.CurrentAnimationGroup.RunAnim) clip = nextSkin.RunAnim; else if (currentPhysicsAnim == playerPhysics.CurrentAnimationGroup.SpawnAnim) clip = nextSkin.SpawnAnim; @@ -249,19 +249,19 @@ public static void setLook(this PlayerControl target, String playerName, int col else if (currentPhysicsAnim == playerPhysics.CurrentAnimationGroup.IdleAnim) clip = nextSkin.IdleAnim; else clip = nextSkin.IdleAnim; float progress = playerPhysics.Animator.m_animator.GetCurrentAnimatorStateInfo(0).normalizedTime; - playerPhysics.Skin.skin = nextSkin; - if (playerPhysics.Skin.layer.material == FastDestroyableSingleton.Instance.PlayerMaterial) - PlayerControl.SetPlayerMaterialColors(colorId, playerPhysics.Skin.layer); + playerPhysics.myPlayer.cosmetics.skin.skin = nextSkin; + if (playerPhysics.myPlayer.cosmetics.skin.layer.material == FastDestroyableSingleton.Instance.PlayerMaterial) + target.SetPlayerMaterialColors(playerPhysics.myPlayer.cosmetics.skin.layer); spriteAnim.Play(clip, 1f); spriteAnim.m_animator.Play("a", 0, progress % 1); spriteAnim.m_animator.Update(0f); - if (target.CurrentPet) UnityEngine.Object.Destroy(target.CurrentPet.gameObject); - target.CurrentPet = UnityEngine.Object.Instantiate(FastDestroyableSingleton.Instance.GetPetById(petId).viewData.viewData); - target.CurrentPet.transform.position = target.transform.position; - target.CurrentPet.Source = target; - target.CurrentPet.Visible = target.Visible; - PlayerControl.SetPlayerMaterialColors(colorId, target.CurrentPet.rend); + if (target.cosmetics.currentPet) UnityEngine.Object.Destroy(target.cosmetics.currentPet.gameObject); + target.cosmetics.currentPet = UnityEngine.Object.Instantiate(FastDestroyableSingleton.Instance.GetPetById(petId).viewData.viewData); + target.cosmetics.currentPet.transform.position = target.transform.position; + target.cosmetics.currentPet.Source = target; + target.cosmetics.currentPet.Visible = target.Visible; + target.SetPlayerMaterialColors(target.cosmetics.currentPet.rend); } public static void showFlash(Color color, float duration=1f) { diff --git a/TheOtherRoles/Main.cs b/TheOtherRoles/Main.cs index fca6ba9a3..db449b6ea 100644 --- a/TheOtherRoles/Main.cs +++ b/TheOtherRoles/Main.cs @@ -23,7 +23,7 @@ namespace TheOtherRoles public class TheOtherRolesPlugin : BasePlugin { public const string Id = "me.eisbison.theotherroles"; - public const string VersionString = "4.1.4"; + public const string VersionString = "4.1.5"; public static Version Version = Version.Parse(VersionString); internal static BepInEx.Logging.ManualLogSource Logger; @@ -34,7 +34,6 @@ public class TheOtherRolesPlugin : BasePlugin public static int optionsPage = 2; public static ConfigEntry DebugMode { get; private set; } - public static ConfigEntry StreamerMode { get; set; } public static ConfigEntry GhostsSeeTasks { get; set; } public static ConfigEntry GhostsSeeRoles { get; set; } public static ConfigEntry GhostsSeeModifier { get; set; } @@ -42,8 +41,6 @@ public class TheOtherRolesPlugin : BasePlugin public static ConfigEntry ShowRoleSummary { get; set; } public static ConfigEntry ShowLighterDarker { get; set; } public static ConfigEntry EnableHorseMode { get; set; } - public static ConfigEntry StreamerModeReplacementText { get; set; } - public static ConfigEntry StreamerModeReplacementColor { get; set; } public static ConfigEntry Ip { get; set; } public static ConfigEntry Port { get; set; } public static ConfigEntry ShowPopUpVersion { get; set; } @@ -51,14 +48,34 @@ public class TheOtherRolesPlugin : BasePlugin public static Sprite ModStamp; public static IRegionInfo[] defaultRegions; + + // This is part of the Mini.RegionInstaller, Licensed under GPLv3 + // file="RegionInstallPlugin.cs" company="miniduikboot"> public static void UpdateRegions() { ServerManager serverManager = FastDestroyableSingleton.Instance; - IRegionInfo[] regions = defaultRegions; + var regions = new IRegionInfo[] { + new DnsRegionInfo(Ip.Value, "Custom", StringNames.NoTranslation, Ip.Value, Port.Value, false).CastFast(), + new DnsRegionInfo("mods.hopto.org", "Modded NA (MNA)", StringNames.NoTranslation, "mods.hopto.org", 443, false).CastFast(), + new DnsRegionInfo("au-eu.duikbo.at", "Modded EU (MEU)", StringNames.NoTranslation, "au-eu.duikbo.at", 22023, false).CastFast() + }; + + IRegionInfo ? currentRegion = serverManager.CurrentRegion; + Logger.LogInfo($"Adding {regions.Length} regions"); + foreach (IRegionInfo region in regions) { + if (region == null) + Logger.LogError("Could not add region"); + else { + if (currentRegion != null && region.Name.Equals(currentRegion.Name, StringComparison.OrdinalIgnoreCase)) + currentRegion = region; + serverManager.AddOrUpdateRegion(region); + } + } - var CustomRegion = new DnsRegionInfo(Ip.Value, "Custom", StringNames.NoTranslation, Ip.Value, Port.Value, false); - regions = regions.Concat(new IRegionInfo[] { CustomRegion.CastFast() }).ToArray(); - ServerManager.DefaultRegions = regions; - serverManager.AvailableRegions = regions; + // AU remembers the previous region that was set, so we need to restore it + if (currentRegion != null) { + Logger.LogDebug("Resetting previous region"); + serverManager.SetRegion(currentRegion); + } } public override void Load() { @@ -66,7 +83,6 @@ public override void Load() { Instance = this; DebugMode = Config.Bind("Custom", "Enable Debug Mode", false); - StreamerMode = Config.Bind("Custom", "Enable Streamer Mode", false); GhostsSeeTasks = Config.Bind("Custom", "Ghosts See Remaining Tasks", true); GhostsSeeRoles = Config.Bind("Custom", "Ghosts See Roles", true); GhostsSeeModifier = Config.Bind("Custom", "Ghosts See Modifier", true); @@ -75,8 +91,6 @@ public override void Load() { ShowLighterDarker = Config.Bind("Custom", "Show Lighter / Darker", true); EnableHorseMode = Config.Bind("Custom", "Enable Horse Mode", false); ShowPopUpVersion = Config.Bind("Custom", "Show PopUp", "0"); - StreamerModeReplacementText = Config.Bind("Custom", "Streamer Mode Replacement Text", "\n\nThe Other Roles"); - StreamerModeReplacementColor = Config.Bind("Custom", "Streamer Mode Replacement Text Hex Color", "#87AAF5FF"); Ip = Config.Bind("Custom", "Custom Server IP", "127.0.0.1"); @@ -122,7 +136,7 @@ public static void Postfix(out bool __result) [HarmonyPatch(typeof(ChatController), nameof(ChatController.Awake))] public static class ChatControllerAwakePatch { private static void Prefix() { - if (!EOSManager.Instance.IsMinor()) { + if (!EOSManager.Instance.isKWSMinor) { SaveManager.chatModeType = 1; SaveManager.isGuest = false; } diff --git a/TheOtherRoles/Modules/CustomHats.cs b/TheOtherRoles/Modules/CustomHats.cs index 616e7b182..2a950b07a 100644 --- a/TheOtherRoles/Modules/CustomHats.cs +++ b/TheOtherRoles/Modules/CustomHats.cs @@ -203,19 +203,19 @@ private static class PlayerPhysicsHandleAnimationPatch { private static void Postfix(PlayerPhysics __instance) { AnimationClip currentAnimation = __instance.Animator.GetCurrentAnimation(); if (currentAnimation == __instance.CurrentAnimationGroup.ClimbAnim || currentAnimation == __instance.CurrentAnimationGroup.ClimbDownAnim) return; - HatParent hp = __instance.myPlayer.HatRenderer; + HatParent hp = __instance.myPlayer.cosmetics.hat; if (hp.Hat == null) return; HatExtension extend = hp.Hat.getHatExtension(); if (extend == null) return; if (extend.FlipImage != null) { - if (__instance.rend.flipX) { + if (__instance.FlipX) { hp.FrontLayer.sprite = extend.FlipImage; } else { hp.FrontLayer.sprite = hp.hatView.MainImage; } } if (extend.BackFlipImage != null) { - if (__instance.rend.flipX) { + if (__instance.FlipX) { hp.BackLayer.sprite = extend.BackFlipImage; } else { hp.BackLayer.sprite = hp.hatView.BackImage; @@ -286,7 +286,7 @@ static bool Prefix(HatParent __instance, HatData hat, HatViewData hatViewData, i __instance.PopulateFromHatViewData(); - __instance.SetColor(color); + __instance.SpriteColor = Palette.PlayerColors[color]; return false; } } diff --git a/TheOtherRoles/Objects/Bloodytrail.cs b/TheOtherRoles/Objects/Bloodytrail.cs index 1619a3a33..5090e4aac 100644 --- a/TheOtherRoles/Objects/Bloodytrail.cs +++ b/TheOtherRoles/Objects/Bloodytrail.cs @@ -38,7 +38,7 @@ public Bloodytrail(PlayerControl player, PlayerControl bloodyPlayer) { spriteRenderer = blood.AddComponent(); spriteRenderer.sprite = sp[index]; spriteRenderer.material = FastDestroyableSingleton.Instance.PlayerMaterial; - PlayerControl.SetPlayerMaterialColors(color, spriteRenderer); + player.SetPlayerMaterialColors(spriteRenderer); // spriteRenderer.color = color; blood.SetActive(true); diff --git a/TheOtherRoles/Objects/Portal.cs b/TheOtherRoles/Objects/Portal.cs index 07c36d9d7..7ee7467f3 100644 --- a/TheOtherRoles/Objects/Portal.cs +++ b/TheOtherRoles/Objects/Portal.cs @@ -43,7 +43,7 @@ public static void startTeleport(byte playerId) { // Generate log info PlayerControl playerControl = Helpers.playerById(playerId); - bool flip = playerControl.MyRend.flipX; // use the original player control here, not the morhpTarget. + bool flip = playerControl.cosmetics.currentBodySprite.BodySprite.flipX; // use the original player control here, not the morhpTarget. firstPortal.animationFgRenderer.flipX = flip; secondPortal.animationFgRenderer.flipX = flip; if (Morphling.morphling != null && Morphling.morphTimer > 0) playerControl = Morphling.morphTarget; // Will output info of morph-target instead @@ -61,8 +61,8 @@ public static void startTeleport(byte playerId) { if (firstPortal != null && firstPortal.animationFgRenderer != null && secondPortal != null && secondPortal.animationFgRenderer != null) { firstPortal.animationFgRenderer.sprite = getFgAnimationSprite((int)(p * portalFgAnimationSprites.Length)); secondPortal.animationFgRenderer.sprite = getFgAnimationSprite((int)(p * portalFgAnimationSprites.Length)); - PlayerControl.SetPlayerMaterialColors(colorId, firstPortal.animationFgRenderer); - PlayerControl.SetPlayerMaterialColors(colorId, secondPortal.animationFgRenderer); + playerControl.SetPlayerMaterialColors(firstPortal.animationFgRenderer); + playerControl.SetPlayerMaterialColors(secondPortal.animationFgRenderer); if (p == 1f) { firstPortal.animationFgRenderer.sprite = null; secondPortal.animationFgRenderer.sprite = null; diff --git a/TheOtherRoles/Patches/AirShipSetAntiTpPosition.cs b/TheOtherRoles/Patches/AirShipSetAntiTpPosition.cs new file mode 100644 index 000000000..fcfd22d1c --- /dev/null +++ b/TheOtherRoles/Patches/AirShipSetAntiTpPosition.cs @@ -0,0 +1,21 @@ +using HarmonyLib; +using System; + +namespace TheOtherRoles.Patches { + [HarmonyPatch] + public static class AirShipSetAntiTpPosition { + + // Save the position of the player prior to starting the climb / gap platform + [HarmonyPrefix] + [HarmonyPatch(typeof(PlayerPhysics), nameof(PlayerPhysics.ClimbLadder))] + public static void prefix() { + AntiTeleport.position = Players.CachedPlayer.LocalPlayer.transform.position; + } + + [HarmonyPrefix] + [HarmonyPatch(typeof(MovingPlatformBehaviour), nameof(MovingPlatformBehaviour.UsePlatform))] + public static void prefix2() { + AntiTeleport.position = Players.CachedPlayer.LocalPlayer.transform.position; + } + } +} diff --git a/TheOtherRoles/Patches/ClientOptionsPatch.cs b/TheOtherRoles/Patches/ClientOptionsPatch.cs index b34ddd564..57ab847d8 100644 --- a/TheOtherRoles/Patches/ClientOptionsPatch.cs +++ b/TheOtherRoles/Patches/ClientOptionsPatch.cs @@ -14,7 +14,6 @@ namespace TheOtherRoles.Patches public static class ClientOptionsPatch { private static SelectionBehaviour[] AllOptions = { - new SelectionBehaviour("Streamer Mode", () => TheOtherRolesPlugin.StreamerMode.Value = !TheOtherRolesPlugin.StreamerMode.Value, TheOtherRolesPlugin.StreamerMode.Value), new SelectionBehaviour("Ghosts See Remaining Tasks", () => MapOptions.ghostsSeeTasks = TheOtherRolesPlugin.GhostsSeeTasks.Value = !TheOtherRolesPlugin.GhostsSeeTasks.Value, TheOtherRolesPlugin.GhostsSeeTasks.Value), new SelectionBehaviour("Ghosts Can See Votes", () => MapOptions.ghostsSeeVotes = TheOtherRolesPlugin.GhostsSeeVotes.Value = !TheOtherRolesPlugin.GhostsSeeVotes.Value, TheOtherRolesPlugin.GhostsSeeVotes.Value), new SelectionBehaviour("Ghosts Can See Roles", () => MapOptions.ghostsSeeRoles = TheOtherRolesPlugin.GhostsSeeRoles.Value = !TheOtherRolesPlugin.GhostsSeeRoles.Value, TheOtherRolesPlugin.GhostsSeeRoles.Value), @@ -214,14 +213,4 @@ public SelectionBehaviour(string title, Func onClick, bool defaultValue) } } } - - [HarmonyPatch(typeof(TextBoxTMP), nameof(TextBoxTMP.SetText))] - public static class HiddenTextPatch - { - private static void Postfix(TextBoxTMP __instance) - { - bool flag = TheOtherRolesPlugin.StreamerMode.Value && (__instance.name == "GameIdText" || __instance.name == "IpTextBox" || __instance.name == "PortTextBox"); - if (flag) __instance.outputText.text = new string('*', __instance.text.Length); - } - } } diff --git a/TheOtherRoles/Patches/CredentialsPatch.cs b/TheOtherRoles/Patches/CredentialsPatch.cs index 9c18874d3..7f61b0733 100644 --- a/TheOtherRoles/Patches/CredentialsPatch.cs +++ b/TheOtherRoles/Patches/CredentialsPatch.cs @@ -19,7 +19,7 @@ public static class CredentialsPatch { public static string contributorsCredentials = $@" Special thanks to K3ndo & Smeggy -GitHub Contributors: Gendelo, Alex2911, amsyarasyiq, MaximeGillot, Psynomit, probablyadnf"; +GitHub Contributors: Gendelo, Alex2911, amsyarasyiq, MaximeGillot, Psynomit, probablyadnf, JustASysAdmin"; [HarmonyPatch(typeof(VersionShower), nameof(VersionShower.Start))] private static class VersionShowerPatch diff --git a/TheOtherRoles/Patches/EndGamePatch.cs b/TheOtherRoles/Patches/EndGamePatch.cs index 6df2a096d..d46243480 100644 --- a/TheOtherRoles/Patches/EndGamePatch.cs +++ b/TheOtherRoles/Patches/EndGamePatch.cs @@ -244,23 +244,23 @@ public static void Postfix(EndGameManager __instance) { float num7 = Mathf.Lerp(1f, 0.65f, num4) * 0.9f; Vector3 vector = new Vector3(num7, num7, 1f); poolablePlayer.transform.localScale = vector; - poolablePlayer.UpdateFromPlayerOutfit(winningPlayerData2, winningPlayerData2.IsDead); + poolablePlayer.UpdateFromPlayerOutfit((GameData.PlayerOutfit) winningPlayerData2, PlayerMaterial.MaskType.ComplexUI, winningPlayerData2.IsDead, true); if (winningPlayerData2.IsDead) { - poolablePlayer.CurrentBodySprite.BodySprite.sprite = poolablePlayer.CurrentBodySprite.GhostSprite; + poolablePlayer.cosmetics.currentBodySprite.BodySprite.sprite = poolablePlayer.cosmetics.currentBodySprite.GhostSprite; poolablePlayer.SetDeadFlipX(i % 2 == 0); } else { poolablePlayer.SetFlipX(i % 2 == 0); } - poolablePlayer.NameText.color = Color.white; - poolablePlayer.NameText.transform.localScale = new Vector3(1f / vector.x, 1f / vector.y, 1f / vector.z); - poolablePlayer.NameText.transform.localPosition = new Vector3(poolablePlayer.NameText.transform.localPosition.x, poolablePlayer.NameText.transform.localPosition.y, -15f); - poolablePlayer.NameText.text = winningPlayerData2.PlayerName; + poolablePlayer.cosmetics.nameText.color = Color.white; + poolablePlayer.cosmetics.nameText.transform.localScale = new Vector3(1f / vector.x, 1f / vector.y, 1f / vector.z); + poolablePlayer.cosmetics.nameText.transform.localPosition = new Vector3(poolablePlayer.cosmetics.nameText.transform.localPosition.x, poolablePlayer.cosmetics.nameText.transform.localPosition.y, -15f); + poolablePlayer.cosmetics.nameText.text = winningPlayerData2.PlayerName; foreach(var data in AdditionalTempData.playerRoles) { if (data.PlayerName != winningPlayerData2.PlayerName) continue; var roles = - poolablePlayer.NameText.text += $"\n{string.Join("\n", data.Roles.Select(x => Helpers.cs(x.color, x.name)))}"; + poolablePlayer.cosmetics.nameText.text += $"\n{string.Join("\n", data.Roles.Select(x => Helpers.cs(x.color, x.name)))}"; } } diff --git a/TheOtherRoles/Patches/GameStartManagerPatch.cs b/TheOtherRoles/Patches/GameStartManagerPatch.cs index fde958c00..c2e0a5423 100644 --- a/TheOtherRoles/Patches/GameStartManagerPatch.cs +++ b/TheOtherRoles/Patches/GameStartManagerPatch.cs @@ -53,39 +53,42 @@ public static void Prefix(GameStartManager __instance) { public static void Postfix(GameStartManager __instance) { // Send version as soon as CachedPlayer.LocalPlayer.PlayerControl exists - if (CachedPlayer.LocalPlayer != null && !versionSent) { + if (PlayerControl.LocalPlayer != null && !versionSent) { versionSent = true; Helpers.shareGameVersion(); } - // Host update with version handshake infos - if (AmongUsClient.Instance.AmHost) { - bool blockStart = false; - string message = ""; - foreach (InnerNet.ClientData client in AmongUsClient.Instance.allClients.ToArray()) { - if (client.Character == null) continue; - var dummyComponent = client.Character.GetComponent(); - if (dummyComponent != null && dummyComponent.enabled) - continue; - else if (!playerVersions.ContainsKey(client.Id)) { - blockStart = true; - message += $"{client.Character.Data.PlayerName} has a different or no version of The Other Roles\n"; - } else { - PlayerVersion PV = playerVersions[client.Id]; - int diff = TheOtherRolesPlugin.Version.CompareTo(PV.version); - if (diff > 0) { - message += $"{client.Character.Data.PlayerName} has an older version of The Other Roles (v{playerVersions[client.Id].version.ToString()})\n"; - blockStart = true; - } else if (diff < 0) { - message += $"{client.Character.Data.PlayerName} has a newer version of The Other Roles (v{playerVersions[client.Id].version.ToString()})\n"; - blockStart = true; - } else if (!PV.GuidMatches()) { // version presumably matches, check if Guid matches - message += $"{client.Character.Data.PlayerName} has a modified version of TOR v{playerVersions[client.Id].version.ToString()} ({PV.guid.ToString()})\n"; - blockStart = true; - } + // Check version handshake infos + + bool versionMismatch = false; + string message = ""; + foreach (InnerNet.ClientData client in AmongUsClient.Instance.allClients.ToArray()) { + if (client.Character == null) continue; + var dummyComponent = client.Character.GetComponent(); + if (dummyComponent != null && dummyComponent.enabled) + continue; + else if (!playerVersions.ContainsKey(client.Id)) { + versionMismatch = true; + message += $"{client.Character.Data.PlayerName} has a different or no version of The Other Roles\n"; + } else { + PlayerVersion PV = playerVersions[client.Id]; + int diff = TheOtherRolesPlugin.Version.CompareTo(PV.version); + if (diff > 0) { + message += $"{client.Character.Data.PlayerName} has an older version of The Other Roles (v{playerVersions[client.Id].version.ToString()})\n"; + versionMismatch = true; + } else if (diff < 0) { + message += $"{client.Character.Data.PlayerName} has a newer version of The Other Roles (v{playerVersions[client.Id].version.ToString()})\n"; + versionMismatch = true; + } else if (!PV.GuidMatches()) { // version presumably matches, check if Guid matches + message += $"{client.Character.Data.PlayerName} has a modified version of TOR v{playerVersions[client.Id].version.ToString()} ({PV.guid.ToString()})\n"; + versionMismatch = true; } } - if (blockStart) { + } + + // Display message to the host + if (AmongUsClient.Instance.AmHost) { + if (versionMismatch) { __instance.StartButton.color = __instance.startLabelText.color = Palette.DisabledClear; __instance.GameStartText.text = message; __instance.GameStartText.transform.localPosition = __instance.StartButton.transform.localPosition + Vector3.up * 2; @@ -96,7 +99,7 @@ public static void Postfix(GameStartManager __instance) { } // Client update with handshake infos - if (!AmongUsClient.Instance.AmHost) { + else { if (!playerVersions.ContainsKey(AmongUsClient.Instance.HostId) || TheOtherRolesPlugin.Version.CompareTo(playerVersions[AmongUsClient.Instance.HostId].version) != 0) { kickingTimer += Time.deltaTime; if (kickingTimer > 10) { @@ -107,6 +110,9 @@ public static void Postfix(GameStartManager __instance) { __instance.GameStartText.text = $"The host has no or a different version of The Other Roles\nYou will be kicked in {Math.Round(10 - kickingTimer)}s"; __instance.GameStartText.transform.localPosition = __instance.StartButton.transform.localPosition + Vector3.up * 2; + } else if (versionMismatch) { + __instance.GameStartText.text = $"Players With Different Versions:\n" + message; + __instance.GameStartText.transform.localPosition = __instance.StartButton.transform.localPosition + Vector3.up * 2; } else { __instance.GameStartText.transform.localPosition = __instance.StartButton.transform.localPosition; if (__instance.startState != GameStartManager.StartingStates.Countdown) { @@ -115,9 +121,6 @@ public static void Postfix(GameStartManager __instance) { } } - // Lobby code replacement - __instance.GameRoomName.text = TheOtherRolesPlugin.StreamerMode.Value ? $"{TheOtherRolesPlugin.StreamerModeReplacementText.Value}" : lobbyCodeText; - // Lobby timer if (!AmongUsClient.Instance.AmHost || !GameData.Instance) return; // Not host or no instance diff --git a/TheOtherRoles/Patches/IntroPatch.cs b/TheOtherRoles/Patches/IntroPatch.cs index e2e5ee6e8..4e22adab7 100644 --- a/TheOtherRoles/Patches/IntroPatch.cs +++ b/TheOtherRoles/Patches/IntroPatch.cs @@ -22,11 +22,11 @@ public static void Prefix(IntroCutscene __instance) { GameData.PlayerInfo data = p.Data; PoolablePlayer player = UnityEngine.Object.Instantiate(__instance.PlayerPrefab, FastDestroyableSingleton.Instance.transform); playerPrefab = __instance.PlayerPrefab; - PlayerControl.SetPlayerMaterialColors(data.DefaultOutfit.ColorId, player.CurrentBodySprite.BodySprite); + p.SetPlayerMaterialColors(player.cosmetics.currentBodySprite.BodySprite); player.SetSkin(data.DefaultOutfit.SkinId, data.DefaultOutfit.ColorId); - player.HatSlot.SetHat(data.DefaultOutfit.HatId, data.DefaultOutfit.ColorId); - PlayerControl.SetPetImage(data.DefaultOutfit.PetId, data.DefaultOutfit.ColorId, player.PetSlot); - player.NameText.text = data.PlayerName; + player.cosmetics.SetHat(data.DefaultOutfit.HatId, data.DefaultOutfit.ColorId); + // PlayerControl.SetPetImage(data.DefaultOutfit.PetId, data.DefaultOutfit.ColorId, player.PetSlot); + player.cosmetics.nameText.text = data.PlayerName; player.SetFlipX(true); MapOptions.playerIcons[p.PlayerId] = player; diff --git a/TheOtherRoles/Patches/MeetingPatch.cs b/TheOtherRoles/Patches/MeetingPatch.cs index 061d62bc3..5e7d40179 100644 --- a/TheOtherRoles/Patches/MeetingPatch.cs +++ b/TheOtherRoles/Patches/MeetingPatch.cs @@ -78,20 +78,20 @@ static bool Prefix(MeetingHud __instance) { GameData.PlayerInfo exiled = GameData.Instance.AllPlayers.ToArray().FirstOrDefault(v => !tie && v.PlayerId == max.Key && !v.IsDead); // TieBreaker - Tiebreaker.isTiebreak = false; - int maxVoteValue = self.Values.Max(); List potentialExiled = new List(); - - - PlayerVoteArea tb = null; - if (Tiebreaker.tiebreaker != null) - tb = __instance.playerStates.ToArray().FirstOrDefault(x => x.TargetPlayerId == Tiebreaker.tiebreaker.PlayerId); - bool isTiebreakerSkip = tb == null || tb.VotedFor == 253; - if (tb != null && tb.AmDead) isTiebreakerSkip = true; - - foreach (KeyValuePair pair in self) - if (pair.Value == maxVoteValue && !isTiebreakerSkip && pair.Key != 253) - potentialExiled.Add(GameData.Instance.AllPlayers.ToArray().FirstOrDefault(x => x.PlayerId == pair.Key)); + if (self.Count > 0) { + Tiebreaker.isTiebreak = false; + int maxVoteValue = self.Values.Max(); + PlayerVoteArea tb = null; + if (Tiebreaker.tiebreaker != null) + tb = __instance.playerStates.ToArray().FirstOrDefault(x => x.TargetPlayerId == Tiebreaker.tiebreaker.PlayerId); + bool isTiebreakerSkip = tb == null || tb.VotedFor == 253; + if (tb != null && tb.AmDead) isTiebreakerSkip = true; + + foreach (KeyValuePair pair in self) + if (pair.Value == maxVoteValue && !isTiebreakerSkip && pair.Key != 253) + potentialExiled.Add(GameData.Instance.AllPlayers.ToArray().FirstOrDefault(x => x.PlayerId == pair.Key)); + } MeetingHud.VoterState[] array = new MeetingHud.VoterState[__instance.playerStates.Length]; for (int i = 0; i < __instance.playerStates.Length; i++) @@ -123,14 +123,15 @@ static bool Prefix(MeetingHud __instance) { class MeetingHudBloopAVoteIconPatch { public static bool Prefix(MeetingHud __instance, [HarmonyArgument(0)]GameData.PlayerInfo voterPlayer, [HarmonyArgument(1)]int index, [HarmonyArgument(2)]Transform parent) { SpriteRenderer spriteRenderer = UnityEngine.Object.Instantiate(__instance.PlayerVotePrefab); - if (!PlayerControl.GameOptions.AnonymousVotes || (CachedPlayer.LocalPlayer.Data.IsDead && MapOptions.ghostsSeeVotes) || Mayor.mayor != null && CachedPlayer.LocalPlayer.PlayerControl == Mayor.mayor && Mayor.canSeeVoteColors && TasksHandler.taskInfo(CachedPlayer.LocalPlayer.Data).Item1 >= Mayor.tasksNeededToSeeVoteColors) - PlayerControl.SetPlayerMaterialColors(voterPlayer.DefaultOutfit.ColorId, spriteRenderer); - else - PlayerControl.SetPlayerMaterialColors(Palette.DisabledGrey, spriteRenderer); + int cId = voterPlayer.DefaultOutfit.ColorId; + if (!(!PlayerControl.GameOptions.AnonymousVotes || (CachedPlayer.LocalPlayer.Data.IsDead && MapOptions.ghostsSeeVotes) || Mayor.mayor != null && CachedPlayer.LocalPlayer.PlayerControl == Mayor.mayor && Mayor.canSeeVoteColors && TasksHandler.taskInfo(CachedPlayer.LocalPlayer.Data).Item1 >= Mayor.tasksNeededToSeeVoteColors)) + voterPlayer.Object.SetColor(6); + voterPlayer.Object.SetPlayerMaterialColors(spriteRenderer); spriteRenderer.transform.SetParent(parent); spriteRenderer.transform.localScale = Vector3.zero; __instance.StartCoroutine(Effects.Bloop((float)index * 0.3f, spriteRenderer.transform, 1f, 0.5f)); parent.GetComponent().AddVote(spriteRenderer); + voterPlayer.Object.SetColor(cId); return false; } } @@ -307,7 +308,16 @@ static void guesserOnClick(int buttonTarget, MeetingHud __instance) { foreach (RoleInfo roleInfo in RoleInfo.allRoleInfos) { RoleId guesserRole = (Guesser.niceGuesser != null && CachedPlayer.LocalPlayer.PlayerId == Guesser.niceGuesser.PlayerId) ? RoleId.NiceGuesser : RoleId.EvilGuesser; if (roleInfo.isModifier || roleInfo.roleId == guesserRole || (!Guesser.evilGuesserCanGuessSpy && guesserRole == RoleId.EvilGuesser && roleInfo.roleId == RoleId.Spy)) continue; // Not guessable roles & modifier - + // remove all roles that cannot spawn due to the settings from the ui. + RoleManagerSelectRolesPatch.RoleAssignmentData roleData = RoleManagerSelectRolesPatch.getRoleAssignmentData(); + if (roleData.neutralSettings.ContainsKey((byte)roleInfo.roleId) && roleData.neutralSettings[(byte)roleInfo.roleId] == 0) continue; + else if (roleData.impSettings.ContainsKey((byte)roleInfo.roleId) && roleData.impSettings[(byte)roleInfo.roleId] == 0) continue; + else if (roleData.crewSettings.ContainsKey((byte)roleInfo.roleId) && roleData.crewSettings[(byte)roleInfo.roleId] == 0) continue; + else if (new List() { RoleId.Janitor, RoleId.Godfather, RoleId.Mafioso }.Contains(roleInfo.roleId) && CustomOptionHolder.mafiaSpawnRate.getSelection() == 0) continue; + else if (roleInfo.roleId == RoleId.Sidekick && (!CustomOptionHolder.jackalCanCreateSidekick.getBool() || CustomOptionHolder.jackalSpawnRate.getSelection() == 0)) continue; + if (roleInfo.roleId == RoleId.Deputy && (CustomOptionHolder.deputySpawnRate.getSelection() == 0 || CustomOptionHolder.sheriffSpawnRate.getSelection() == 0)) continue; + if (roleInfo.roleId == RoleId.Spy && roleData.impostors.Count <= 1) continue; + if (Guesser.guesserCantGuessSnitch && Snitch.snitch != null) { var (playerCompleted, playerTotal) = TasksHandler.taskInfo(Snitch.snitch.Data); int numberOfLeftTasks = playerTotal - playerCompleted; @@ -456,11 +466,12 @@ static void populateButtonsPostfix(MeetingHud __instance) { } //Fix visor in Meetings + /** foreach (PlayerVoteArea pva in __instance.playerStates) { if(pva.PlayerIcon != null && pva.PlayerIcon.VisorSlot != null){ pva.PlayerIcon.VisorSlot.transform.position += new Vector3(0, 0, -1f); } - } + } */ // Add overlay for spelled players if (Witch.witch != null && Witch.futureSpelled != null) { @@ -514,13 +525,18 @@ static void Postfix(MeetingHud __instance, [HarmonyArgument(0)]MessageReader rea } } - [HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.CoStartMeeting))] + [HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.StartMeeting))] class StartMeetingPatch { public static void Prefix(PlayerControl __instance, [HarmonyArgument(0)]GameData.PlayerInfo meetingTarget) { // Resett Bait list Bait.active = new Dictionary(); - // Safe AntiTeleport positions - AntiTeleport.position = CachedPlayer.LocalPlayer.transform.position; + // Save AntiTeleport position, if the player is able to move (i.e. not on a ladder or a gap thingy) + if (CachedPlayer.LocalPlayer.PlayerPhysics.enabled && CachedPlayer.LocalPlayer.PlayerControl.moveable || CachedPlayer.LocalPlayer.PlayerControl.inVent + || HudManagerStartPatch.hackerVitalsButton.isEffectActive || HudManagerStartPatch.hackerAdminTableButton.isEffectActive || HudManagerStartPatch.securityGuardCamButton.isEffectActive + || Portal.isTeleporting && Portal.teleportedPlayers.Last().playerId == CachedPlayer.LocalPlayer.PlayerId) { + AntiTeleport.position = CachedPlayer.LocalPlayer.transform.position; + } + // Medium meeting start time Medium.meetingStartTime = DateTime.UtcNow; // Reset vampire bitten diff --git a/TheOtherRoles/Patches/PlayerControlPatch.cs b/TheOtherRoles/Patches/PlayerControlPatch.cs index 41d26bc08..5835a4dab 100644 --- a/TheOtherRoles/Patches/PlayerControlPatch.cs +++ b/TheOtherRoles/Patches/PlayerControlPatch.cs @@ -46,17 +46,17 @@ static PlayerControl setTarget(bool onlyCrewmates = false, bool targetPlayersInV } static void setPlayerOutline(PlayerControl target, Color color) { - if (target == null || target.MyRend == null) return; + if (target == null || target.cosmetics?.currentBodySprite?.BodySprite == null) return; - target.MyRend.material.SetFloat("_Outline", 1f); - target.MyRend.material.SetColor("_OutlineColor", color); + target.cosmetics.currentBodySprite.BodySprite.material.SetFloat("_Outline", 1f); + target.cosmetics.currentBodySprite.BodySprite.material.SetColor("_OutlineColor", color); } // Update functions static void setBasePlayerOutlines() { foreach (PlayerControl target in CachedPlayer.AllPlayers) { - if (target == null || target.MyRend == null) continue; + if (target == null || target.cosmetics?.currentBodySprite?.BodySprite == null) continue; bool isMorphedMorphling = target == Morphling.morphling && Morphling.morphTarget != null && Morphling.morphTimer > 0f; bool hasVisibleShield = false; @@ -75,11 +75,11 @@ static void setBasePlayerOutlines() { } if (hasVisibleShield) { - target.MyRend.material.SetFloat("_Outline", 1f); - target.MyRend.material.SetColor("_OutlineColor", color); + target.cosmetics.currentBodySprite.BodySprite.material.SetFloat("_Outline", 1f); + target.cosmetics.currentBodySprite.BodySprite.material.SetColor("_OutlineColor", color); } else { - target.MyRend.material.SetFloat("_Outline", 0f); + target.cosmetics.currentBodySprite.BodySprite.material.SetFloat("_Outline", 0f); } } } @@ -457,10 +457,10 @@ public static void playerSizeUpdate(PlayerControl p) { public static void updatePlayerInfo() { foreach (PlayerControl p in CachedPlayer.AllPlayers) { if ((Lawyer.lawyerKnowsRole && CachedPlayer.LocalPlayer.PlayerControl == Lawyer.lawyer && p == Lawyer.target) || p == CachedPlayer.LocalPlayer.PlayerControl || CachedPlayer.LocalPlayer.Data.IsDead) { - Transform playerInfoTransform = p.nameText.transform.parent.FindChild("Info"); + Transform playerInfoTransform = p.cosmetics.nameText.transform.parent.FindChild("Info"); TMPro.TextMeshPro playerInfo = playerInfoTransform != null ? playerInfoTransform.GetComponent() : null; if (playerInfo == null) { - playerInfo = UnityEngine.Object.Instantiate(p.nameText, p.nameText.transform.parent); + playerInfo = UnityEngine.Object.Instantiate(p.cosmetics.nameText, p.cosmetics.nameText.transform.parent); playerInfo.transform.localPosition += Vector3.up * 0.5f; playerInfo.fontSize *= 0.75f; playerInfo.gameObject.name = "Info"; @@ -781,7 +781,7 @@ static void ninjaSetTarget() if (Ninja.ninja == null || Ninja.ninja != CachedPlayer.LocalPlayer.PlayerControl) return; List untargetables = new List(); if (Spy.spy != null && !Spy.impostorsCanKillAnyone) untargetables.Add(Spy.spy); - if (Mini.mini != null) untargetables.Add(Mini.mini); + if (Mini.mini != null && !Mini.isGrownUp()) untargetables.Add(Mini.mini); if (Sidekick.wasTeamRed && !Spy.impostorsCanKillAnyone) untargetables.Add(Sidekick.sidekick); if (Jackal.wasTeamRed && !Spy.impostorsCanKillAnyone) untargetables.Add(Jackal.jackal); Ninja.currentTarget = setTarget(onlyCrewmates: true, untargetablePlayers: untargetables); @@ -796,7 +796,7 @@ static void baitUpdate() { Bait.active[entry.Key] = entry.Value - Time.fixedDeltaTime; if (entry.Value <= 0) { Bait.active.Remove(entry.Key); - if (entry.Key.killerIfExisting != null) { + if (entry.Key.killerIfExisting != null && entry.Key.killerIfExisting.PlayerId == CachedPlayer.LocalPlayer.PlayerId) { Helpers.handleVampireBiteOnBodyReport(); // Manually call Vampire handling, since the CmdReportDeadBody Prefix won't be called RPCProcedure.uncheckedCmdReportDeadBody(entry.Key.killerIfExisting.PlayerId, entry.Key.player.PlayerId); @@ -835,6 +835,7 @@ public static void miniCooldownUpdate() { HudManagerStartPatch.warlockCurseButton.MaxTimer = Warlock.cooldown * multiplier; HudManagerStartPatch.cleanerCleanButton.MaxTimer = Cleaner.cooldown * multiplier; HudManagerStartPatch.witchSpellButton.MaxTimer = (Witch.cooldown + Witch.currentCooldownAddition) * multiplier; + HudManagerStartPatch.ninjaButton.MaxTimer = Ninja.cooldown * multiplier; } } public static void Postfix(PlayerControl __instance) { @@ -1161,7 +1162,7 @@ public static void Prefix(KillAnimation __instance, [HarmonyArgument(0)]ref Play class KillAnimationSetMovementPatch { private static int? colorId = null; public static void Prefix(PlayerControl source, bool canMove) { - Color color = source.MyRend.material.GetColor("_BodyColor"); + Color color = source.cosmetics.currentBodySprite.BodySprite.material.GetColor("_BodyColor"); if (color != null && Morphling.morphling != null && source.Data.PlayerId == Morphling.morphling.PlayerId) { var index = Palette.PlayerColors.IndexOf(color); if (index != -1) colorId = index; diff --git a/TheOtherRoles/Patches/RoleAssignmentPatch.cs b/TheOtherRoles/Patches/RoleAssignmentPatch.cs index 7157cea5e..0f82bef72 100644 --- a/TheOtherRoles/Patches/RoleAssignmentPatch.cs +++ b/TheOtherRoles/Patches/RoleAssignmentPatch.cs @@ -41,7 +41,7 @@ private static void assignRoles() { assignModifiers(); } - private static RoleAssignmentData getRoleAssignmentData() { + public static RoleAssignmentData getRoleAssignmentData() { // Get the players that we want to assign the roles to. Crewmate and Neutral roles are assigned to natural crewmates. Impostor roles to impostors. List crewmates = PlayerControl.AllPlayerControls.ToArray().ToList().OrderBy(x => Guid.NewGuid()).ToList(); crewmates.RemoveAll(x => x.Data.Role.IsImpostor); @@ -511,7 +511,7 @@ private static int getSelectionForRoleId(RoleId roleId, bool multiplyQuantity = } - private class RoleAssignmentData { + public class RoleAssignmentData { public List crewmates {get;set;} public List impostors {get;set;} public Dictionary impSettings = new Dictionary(); diff --git a/TheOtherRoles/Patches/ShipStatusPatch.cs b/TheOtherRoles/Patches/ShipStatusPatch.cs index 29f6fb53d..cd20d65cb 100644 --- a/TheOtherRoles/Patches/ShipStatusPatch.cs +++ b/TheOtherRoles/Patches/ShipStatusPatch.cs @@ -28,7 +28,7 @@ public static bool Prefix(ref float __result, ShipStatus __instance, [HarmonyArg // If player is Lighter with ability active if (Lighter.lighter != null && Lighter.lighter.PlayerId == player.PlayerId && Lighter.lighterTimer > 0f) { - float unlerped = Mathf.InverseLerp(__instance.MinLightRadius, __instance.MaxLightRadius, GetNeutralLightRadius(__instance, true)); + float unlerped = Mathf.InverseLerp(__instance.MinLightRadius, __instance.MaxLightRadius, GetNeutralLightRadius(__instance, false)); __result = Mathf.Lerp(__instance.MaxLightRadius * Lighter.lighterModeLightsOffVision, __instance.MaxLightRadius * Lighter.lighterModeLightsOnVision, unlerped); } diff --git a/TheOtherRoles/Patches/UpdatePatch.cs b/TheOtherRoles/Patches/UpdatePatch.cs index 6423cce00..7e0fac9d6 100644 --- a/TheOtherRoles/Patches/UpdatePatch.cs +++ b/TheOtherRoles/Patches/UpdatePatch.cs @@ -32,7 +32,7 @@ static void resetNameTagsAndColors() { { var playerName = text; if (morphTimerNotUp && morphTargetNotNull && Morphling.morphling == player) playerName = Morphling.morphTarget.Data.PlayerName; - var nameText = player.nameText; + var nameText = player.cosmetics.nameText; nameText.text = Helpers.hidePlayerName(localPlayer, player) ? "" : playerName; nameText.color = color = amImpostor && data.Role.IsImpostor ? Palette.ImpostorRed : Color.white; @@ -59,7 +59,7 @@ static void resetNameTagsAndColors() { } static void setPlayerNameColor(PlayerControl p, Color color) { - p.nameText.color = color; + p.cosmetics.nameText.color = color; if (MeetingHud.Instance != null) foreach (PlayerVoteArea player in MeetingHud.Instance.playerStates) if (player.NameText != null && p.PlayerId == player.TargetPlayerId) @@ -166,11 +166,11 @@ static void setNameTags() { if (CachedPlayer.LocalPlayer != null && CachedPlayer.LocalPlayer.Data.Role.IsImpostor) { foreach (PlayerControl player in CachedPlayer.AllPlayers) if (Godfather.godfather != null && Godfather.godfather == player) - player.nameText.text = player.Data.PlayerName + " (G)"; + player.cosmetics.nameText.text = player.Data.PlayerName + " (G)"; else if (Mafioso.mafioso != null && Mafioso.mafioso == player) - player.nameText.text = player.Data.PlayerName + " (M)"; + player.cosmetics.nameText.text = player.Data.PlayerName + " (M)"; else if (Janitor.janitor != null && Janitor.janitor == player) - player.nameText.text = player.Data.PlayerName + " (J)"; + player.cosmetics.nameText.text = player.Data.PlayerName + " (J)"; if (MeetingHud.Instance != null) foreach (PlayerVoteArea player in MeetingHud.Instance.playerStates) if (Godfather.godfather != null && Godfather.godfather.PlayerId == player.TargetPlayerId) @@ -184,8 +184,8 @@ static void setNameTags() { // Lovers if (Lovers.lover1 != null && Lovers.lover2 != null && (Lovers.lover1 == CachedPlayer.LocalPlayer.PlayerControl || Lovers.lover2 == CachedPlayer.LocalPlayer.PlayerControl)) { string suffix = Helpers.cs(Lovers.color, " ♥"); - Lovers.lover1.nameText.text += suffix; - Lovers.lover2.nameText.text += suffix; + Lovers.lover1.cosmetics.nameText.text += suffix; + Lovers.lover2.cosmetics.nameText.text += suffix; if (MeetingHud.Instance != null) foreach (PlayerVoteArea player in MeetingHud.Instance.playerStates) @@ -196,7 +196,7 @@ static void setNameTags() { // Lawyer if (Lawyer.lawyer != null && Lawyer.target != null && Lawyer.lawyer == CachedPlayer.LocalPlayer.PlayerControl) { string suffix = Helpers.cs(Lawyer.color, " §"); - Lawyer.target.nameText.text += suffix; + Lawyer.target.cosmetics.nameText.text += suffix; if (MeetingHud.Instance != null) foreach (PlayerVoteArea player in MeetingHud.Instance.playerStates) @@ -233,7 +233,7 @@ static void timerUpdate() { } public static void miniUpdate() { - if (Mini.mini == null || Camouflager.camouflageTimer > 0f || Mini.mini == Morphling.morphling && Morphling.morphTimer > 0f) return; + if (Mini.mini == null || Camouflager.camouflageTimer > 0f || Mini.mini == Morphling.morphling && Morphling.morphTimer > 0f || Mini.mini == Ninja.ninja && Ninja.isInvisble) return; float growingProgress = Mini.growingProgress(); float scale = growingProgress * 0.35f + 0.35f; @@ -241,7 +241,7 @@ public static void miniUpdate() { if (growingProgress != 1f) suffix = " (" + Mathf.FloorToInt(growingProgress * 18) + ")"; - Mini.mini.nameText.text += suffix; + Mini.mini.cosmetics.nameText.text += suffix; if (MeetingHud.Instance != null) { foreach (PlayerVoteArea player in MeetingHud.Instance.playerStates) if (player.NameText != null && Mini.mini.PlayerId == player.TargetPlayerId) @@ -249,7 +249,7 @@ public static void miniUpdate() { } if (Morphling.morphling != null && Morphling.morphTarget == Mini.mini && Morphling.morphTimer > 0f) - Morphling.morphling.nameText.text += suffix; + Morphling.morphling.cosmetics.nameText.text += suffix; } static void updateImpostorKillButton(HudManager __instance) { diff --git a/TheOtherRoles/Patches/UsablesPatch.cs b/TheOtherRoles/Patches/UsablesPatch.cs index 728d2d0f6..0970d130b 100644 --- a/TheOtherRoles/Patches/UsablesPatch.cs +++ b/TheOtherRoles/Patches/UsablesPatch.cs @@ -300,8 +300,8 @@ static void Postfix(VitalsMinigame __instance) { //Fix Visor in Vitals foreach (VitalsPanel panel in __instance.vitals) { - if (panel.PlayerIcon != null && panel.PlayerIcon.Skin != null) { - panel.PlayerIcon.Skin.transform.position = new Vector3(0, 0, 0f); + if (panel.PlayerIcon != null && panel.PlayerIcon.cosmetics.skin != null) { + panel.PlayerIcon.cosmetics.skin.transform.position = new Vector3(0, 0, 0f); } } } @@ -394,8 +394,8 @@ static bool Prefix(MapCountOverlay __instance) { if (!component || component.Data == null || component.Data.Disconnected || component.Data.IsDead) { num2--; - } else if (component?.MyRend?.material != null) { - Color color = component.MyRend.material.GetColor("_BodyColor"); + } else if (component?.cosmetics?.currentBodySprite?.BodySprite?.material != null) { + Color color = component.cosmetics.currentBodySprite.BodySprite.material.GetColor("_BodyColor"); if (Hacker.onlyColorType) { var id = Mathf.Max(0, Palette.PlayerColors.IndexOf(color)); color = Helpers.isLighterColor((byte)id) ? Palette.PlayerColors[7] : Palette.PlayerColors[6]; diff --git a/TheOtherRoles/RPC.cs b/TheOtherRoles/RPC.cs index 470ff3519..a56ee34ea 100644 --- a/TheOtherRoles/RPC.cs +++ b/TheOtherRoles/RPC.cs @@ -612,7 +612,7 @@ public static void jackalCreatesSidekick(byte targetId) { FastDestroyableSingleton.Instance.SetRole(player, RoleTypes.Crewmate); if (player == Lawyer.lawyer && Lawyer.target != null) { - Transform playerInfoTransform = Lawyer.target.nameText.transform.parent.FindChild("Info"); + Transform playerInfoTransform = Lawyer.target.cosmetics.nameText.transform.parent.FindChild("Info"); TMPro.TextMeshPro playerInfo = playerInfoTransform != null ? playerInfoTransform.GetComponent() : null; if (playerInfo != null) playerInfo.text = ""; } @@ -747,8 +747,8 @@ public static void setInvisible(byte playerId, byte flag) if (target == null) return; if (flag == byte.MaxValue) { - target.MyRend.color = Color.white; - target.setDefaultLook(); + target.cosmetics.currentBodySprite.BodySprite.color = Color.white; + if (Camouflager.camouflageTimer <= 0) target.setDefaultLook(); Ninja.isInvisble = false; return; } @@ -756,7 +756,7 @@ public static void setInvisible(byte playerId, byte flag) target.setLook("", 6, "", "", "", ""); Color color = Color.clear; if (CachedPlayer.LocalPlayer.Data.Role.IsImpostor || CachedPlayer.LocalPlayer.Data.IsDead) color.a = 0.1f; - target.MyRend.color = color; + target.cosmetics.currentBodySprite.BodySprite.color = color; Ninja.invisibleTimer = Ninja.invisibleDuration; Ninja.isInvisble = true; } @@ -868,7 +868,7 @@ public static void lawyerPromotesToPursuer() { Pursuer.pursuer = player; if (player.PlayerId == CachedPlayer.LocalPlayer.PlayerId && client != null) { - Transform playerInfoTransform = client.nameText.transform.parent.FindChild("Info"); + Transform playerInfoTransform = client.cosmetics.nameText.transform.parent.FindChild("Info"); TMPro.TextMeshPro playerInfo = playerInfoTransform != null ? playerInfoTransform.GetComponent() : null; if (playerInfo != null) playerInfo.text = ""; } diff --git a/TheOtherRoles/TheOtherRoles.csproj b/TheOtherRoles/TheOtherRoles.csproj index 45b2ac5e9..6133669af 100644 --- a/TheOtherRoles/TheOtherRoles.csproj +++ b/TheOtherRoles/TheOtherRoles.csproj @@ -14,7 +14,7 @@ - + diff --git a/TheOtherRoles/packages.lock.json b/TheOtherRoles/packages.lock.json index a92cbd226..911b1d51e 100644 --- a/TheOtherRoles/packages.lock.json +++ b/TheOtherRoles/packages.lock.json @@ -4,9 +4,9 @@ ".NETStandard,Version=v2.1": { "AmongUs.GameLibs.Steam": { "type": "Direct", - "requested": "[2022.3.29, )", - "resolved": "2022.3.29", - "contentHash": "EStKwHGq8MMvSRxIHjlh31VJmCZrGHZ/xoDDN33L5gh7XJLWBFufo6+5ueezndSRpanoCkqLwuTkG73KCS2J1A==" + "requested": "[2022.6.21, )", + "resolved": "2022.6.21", + "contentHash": "l5lB5cTEBRWW+WNOso11mT8csmoZK7CUEqTkACSTwQbxtMQyZN9YORNxkJmtOD7pZnNkbWJ3dLAvQ6pMUsFDsQ==" }, "BepInEx.IL2CPP": { "type": "Direct", From 598aa73249bb836fa5f803f6bbfd7eebfd7ec5f8 Mon Sep 17 00:00:00 2001 From: Mallaris <85371585+Mallaris@users.noreply.github.com> Date: Fri, 24 Jun 2022 00:44:21 +0200 Subject: [PATCH 2/2] Update README.md --- README.md | 101 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 53 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index e6d142184..1df8c68f3 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ The [Role Assignment](#role-assignment) sections explains how the roles are bein # Releases | Among Us - Version| Mod Version | Link | |----------|-------------|-----------------| +| 2022.6.21| v4.1.5| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v4.1.5/TheOtherRoles.zip) | 2022.3.29| v4.1.4| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v4.1.4/TheOtherRoles.zip) | 2022.3.29| v4.1.3| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v4.1.3/TheOtherRoles.zip) | 2022.3.29| v4.1.2| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v4.1.2/TheOtherRoles.zip) @@ -106,6 +107,21 @@ The [Role Assignment](#role-assignment) sections explains how the roles are bein
Click to show the Changelog +**Version 4.1.5** +- Updated to Among Us version 2022.6.21 +- Added Custom servers (Modded EU & Modded NA). Thanks to [miniduikboot](https://github.com/miniduikboot) & GD +- Changed that the Guesser can only guess roles > 0% +- Changed min/max default values +- Fixed a bug where the Lighter's vision did not work properly +- Fixed a bug where a Mini Ninja revealed themself +- Fixed a bug where a Mini Ninja's cooldown did not work properly +- Fixed a bug where a camouflaged Ninja revealed themself +- Fixed a bug where a Vampire reported the Bait multiple times +- Fixed a bug where a last second guess locked the Meeting +- Fixed a bug where the version handshake did not work properly +- Fixed a bug where players with Anti TP were stuck on Airship +- Removed streamer mode + **Version 4.1.4** - Added auto updating for BepInEx - Fixed hat testing in freeplay for meetings / exile etc. @@ -565,76 +581,63 @@ The [Role Assignment](#role-assignment) sections explains how the roles are bein
# Installation -## Windows Auto Installation/Updating Using The AmongUsModUpdater -This tool was made by [Narua](https://github.com/Narua2010) and [Jolle](https://github.com/joelweih). It automatically installs/updates the TheOtherRoles mod to the newest version, runs the game and -syncs your game options automatically. -1. Simply get the newest [release](https://github.com/Narua2010/AmongUsModUpdater/releases/latest) of the [AmongUsModUpdater](https://github.com/Narua2010/AmongUsModUpdater) -2. Unzip the folder and run the **setup.exe** +## Windows Installation Steam +1. Download the newest [release](https://github.com/Eisbison/TheOtherRoles/releases/latest) +2. Find the folder of your game. You can right click on the game in your library, a menu will appear, click on properties, local data, browse +3. Go back one folder to common and make a copy of your Among Us game folder and paste it somewhere on the same drive. +4. Now unzip and drag or extract the files from the .zip into your Among Us game folder that you just copied, at the `.exe` level (just into the folder). +5. Run the game by starting the .exe from this folder (the first launch might take a while). -If you have problems with the AmongUsModUpdater, make sure to [contact us](https://discord.gg/csa3pHYdPU). +Not working? You might want to install the dependency [vc_redist](https://aka.ms/vs/16/release/vc_redist.x86.exe) -## Windows Manual Installation -1. Download and unzip the newest [release](https://github.com/Eisbison/TheOtherRoles/releases/latest) -2. Find the folder of your game, for Steam players you can right click in Steam, on the game, a menu will appear proposing you to go to the folders. -3. Make a copy of your game, it's not obligatory but advised, put it where you want. -4. Drag or extract the files from the zip into your game, at the `.exe` level. -5. Run the game (the first launch might take a while) +## Windows Installation Epic +1. Download the newest [release](https://github.com/Eisbison/TheOtherRoles/releases/latest) +2. Find the folder of your game. Should be stored in "Epic/AmongUs" (wherever you installed Epic on your PC) +3. Now unzip and drag or extract the files from the .zip into the original Epic Among Us game folder. +4. Run the game by starting the game in your Epic Games launcher (the first launch might take a while). Not working? You might want to install the dependency [vc_redist](https://aka.ms/vs/16/release/vc_redist.x86.exe) ![Install](https://i.imgur.com/pvBAyZN.png) -**Linux Manual** +## Linux Installation 1. Install Among Us via Steam 2. Download newest [release](https://github.com/Eisbison/TheOtherRoles/releases/latest) and extract it to ~/.steam/steam/steamapps/common/Among Us 3. Enable `winhttp.dll` via the proton winecfg (https://docs.bepinex.dev/articles/advanced/steam_interop.html#open-winecfg-for-the-target-game) 4. Launch the game via Steam -# Custom Servers and 10+ Players -We always recommend you to play on custom servers rather than on the official ones. If you want to play with more than 10 players in one lobby, you're required to use a custom server. Credits for the original implementation that allowed 10+ player lobbies go to the creators of the [CrowdedMod](https://github.com/CrowdedMods/CrowdedMod). - -**Setup the Clients:** -1. Open the region menu where you can choose between the different regions -2. Select the region *Custom* -3. Enter the ip/domain and the port of your custom server in the corresponding text fields +## The Other Roles Custom Servers +**A custom server is not necessary and official servers are working just fine with the mod, but in case you want to set up and host your own server, here's a guide for you to follow.** **Setup the Server:** -1. Get the [Impostor](https://github.com/Impostor/Impostor) release for the Among Us version **2021.3.31 - 2021.4.2** -2. Follow the steps (using the server release you just downloaded) on the official [Impostor-Documentation](https://github.com/Impostor/Impostor/wiki/Running-the-server) -3. Make sure to set the following values to false in the `config.json` file: -``` - ... - "AntiCheat": { - "Enabled": false, - "BanIpFromGame": false +1. Get the Impostor release (https://github.com/Impostor/Impostor) +2. Follow the steps (using the server release you just downloaded) on the official Impostor-Documentation (https://github.com/Impostor/Impostor/wiki/Running-the-server) +3. Make sure to set the following values to false in the config.json file: +``` ... + 'AntiCheat': { + 'Enabled': false, + 'BanIpFromGame': false } ``` -4. Make sure to forward the right ports on the hosting machine -5. Run the server and setup the client - -**Setting up Server as Docker Container:** \ +4. Make sure to forward the right ports on the hosting machine. +5. Run the server and setup the client. +Setting up Server as Docker Container: If you want to run the server as a docker container you'll need to use the image -``` aeonlucid/impostor:nightly -``` -(Currently only the "nightly" tag is starting a server supporting 2021.3.31 or later) -In addition to running it, the environment variables to disable the AntiCheat feature need to be set. -``` -IMPOSTOR_AntiCheat__Enabled=false -IMPOSTOR_AntiCheat__BanIpFromGame=false -``` +(Currently only the 'nightly' tag is starting a server supporting 2021.3.31 or later) +In addition to running it we need to set the environment variables to disable the AntiCheat feature. +IMPOSTOR_AntiCheatEnabled=false +IMPOSTOR_AntiCheatBanIpFromGame=false Example to docker run command: -``` -docker run -p 22023:22023/udp --env IMPOSTOR_AntiCheat__Enabled=false --env IMPOSTOR_AntiCheat__BanIpFromGame=false aeonlucid/impostor:nightly -``` +docker run -p 22023:22023/udp --env IMPOSTOR_AntiCheatEnabled=false --env IMPOSTOR_AntiCheatBanIpFromGame=false aeonlucid/impostor:nightly Or use to run it in the background -``` -docker run -d -p 22023:22023/udp --env IMPOSTOR_AntiCheat__Enabled=false --env IMPOSTOR_AntiCheat__BanIpFromGame=false aeonlucid/impostor:nightly -``` +docker run -d -p 22023:22023/udp --env IMPOSTOR_AntiCheatEnabled=false --env IMPOSTOR_AntiCheatBanIpFromGame=false aeonlucid/impostor:nightly + +**If you have any problems regarding custom servers, please contact https://github.com/Impostor/Impostor or https://discord.gg/ThJUGAsz** # Credits & Resources @@ -988,8 +991,6 @@ Depending on the options, the Guesser can't guess the shielded player and depend \ **NOTE:** - If a player gets shot, you'll get back your votes -- You can't guess the role **Nice Mini** for obvious reasons -- You can't guess the role **Lover**, you'll have to guess the primary role of one of the Lovers, to kill both of them - Jester wins won't be triggered, if the Guesser shoots the Jester before the Jester gets voted out ### Game Options @@ -1625,6 +1626,9 @@ In a 2 Crewmates vs 2 Impostors (or 2 members of team Jackal) and the Lovers are | Enable Lover Chat | - ----------------------- +**NOTE:** +- The role **Lover** can't be guessed, you'll have to guess the primary role of one of the Lovers, to kill both of them. + ## Sunglasses The Sunglasses will lower the Crewmate's vision by small percentage. The percentage is configurable in the options.\ @@ -1663,6 +1667,7 @@ The Mini cannot be killed until it turns 18 years old, however it can be voted o **NOTE:** - If the Sheriff tries to kill the Mini before it's fully grown, nothing happens. - The Sheriff can kill the Impostor/Neutral Mini, but only if it's fully grown up. +- If the Mini's primary role is guessed correctly, it dies like every other role and nothing further happens. ### Game Options | Name | Description |