From: Nicholas Marty Date: Tue, 25 May 2021 14:37:16 +0000 (+0200) Subject: Version v2.6.5 X-Git-Url: https://git.deb.at/?a=commitdiff_plain;h=d08a31ae413d70a97d5daabb6fdbb2f1d0e23407;p=rhonda%2Ftheotherroles.git Version v2.6.5 --- diff --git a/README.md b/README.md index 3ec2f2a..8d8d1de 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ The [Role Assignment](#role-assignment) sections explains how the roles are bein # Releases | Among Us - Version| Mod Version | Link | |----------|-------------|-----------------| +| 2021.5.10s| v2.6.5| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v2.6.5/TheOtherRoles.zip) | 2021.5.10s| v2.6.4| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v2.6.4/TheOtherRoles.zip) | 2021.5.10s| v2.6.3| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v2.6.3/TheOtherRoles.zip) | 2021.5.10s| v2.6.2| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v2.6.2/TheOtherRoles.zip) @@ -63,6 +64,14 @@ The [Role Assignment](#role-assignment) sections explains how the roles are bein
Click to show the Changelog +**Version 2.6.5** +- Added the ability to increase the number of tasks assigned to crewmates +- New option: A role summary in the end screen (Client option) +- **[Spy](#spy):** New option for spy to have the same vision as impostors +- **[Spy](#spy):** New option for spy to be able to jump into vents (but he can't move between them) +- Fixed a bug causing a crewmate task win when lovers were in the game even when not all crewmates had completed all their tasks +- Restored the original Among Us color for crewmates in the intro cutscene + **Version 2.6.4** - **[Lovers](#lovers):** You can now select that Lovers may have a second role (could be a Crewmate, Neutral or Impostor role) - **[Seer](#seer):** Fixed souls and flash sometimes not being visible (Thanks to [orangeNKeks](https://github.com/orangeNKeks)) @@ -356,8 +365,28 @@ The mod adds a few new settings to Among Us (in addition to the role settings): - **Hide Player Names:** Hides the names of all players that have role which is unknown to you. Team Lovers/Impostors/Jackal still see the names of their teammates. Impostors can alse see the name of the Spy and everyone can still see the age of the child. - **Ghosts Can See Roles** - **Ghosts Can See Votes** -- **Ghosts Can See The Number Ofe Remaining Tasks** +- **Ghosts Can See The Number Of Remaining Tasks** - **Dleks:** You are now able to select the Dleks map. +- **Task Counts:** You are now able to select more tasks. +- **Role Summary:** When a game ends there will be a list of all players and their roles and their task progress + +### Task Count Limits per map +You can configure: +- Up to 4 common tasks +- Up to 23 short tasks +- Up to 15 long tasks + +Please note, that if the configured option exceeds the available number of tasks of a map, the tasks will be limited to that number of tasks. \ +Example: If you configure 4 common tasks on Airship crewmates will only receive 2 common tasks, as airship doesn't offer more than 2 common tasks. + +| Map | Common Tasks | Short Tasks | Long Tasks | +|----------|:-------------:|:-------------:|:-------------:| +| Skeld / Dleks | 2 | 19 | 8 +| Mira HQ | 2 | 13 | 11 +| Polus | 4 | 14 | 15 +| Airship | 2 | 23 | 15 +----------------------- + # Custom Hats ## Create and submit new hat designs @@ -949,6 +978,8 @@ You can set whether the Sheriff can kill the Spy or not (in order to keep the li | Spy Spawn Chance | | Spy Can Die To Sheriff | | Impostors Can Kill Anyone If There Is A Spy | This allows the Impostors to kill both the Spy and their Impostor partners +| Spy Can Enter Vents | Allow the Spy to enter/exit vents (but not actually move to connected vents) +| Spy Has Impostor Vision | Give the Spy the same vision as the Impostors have ----------------------- ## Security Guard diff --git a/Source Code/ClientOptionsPatch.cs b/Source Code/ClientOptionsPatch.cs index 681e7e8..2dd829c 100644 --- a/Source Code/ClientOptionsPatch.cs +++ b/Source Code/ClientOptionsPatch.cs @@ -15,6 +15,7 @@ namespace TheOtherRoles { private static ToggleButtonBehaviour ghostsSeeTasksButton; private static ToggleButtonBehaviour ghostsSeeRolesButton; private static ToggleButtonBehaviour ghostsSeeVotesButton; + private static ToggleButtonBehaviour showRoleSummaryButton; public static float xOffset = 1.75f; public static float yOffset = -0.5f; @@ -79,12 +80,22 @@ namespace TheOtherRoles { } if ((ghostsSeeVotesButton == null || ghostsSeeVotesButton.gameObject == null)) { - ghostsSeeVotesButton = createCustomToggle("Ghosts See votes: ", TheOtherRolesPlugin.GhostsSeeVotes.Value, new Vector2(0, yOffset), (UnityEngine.Events.UnityAction)ghostsSeeVotesToggle, __instance); + ghostsSeeVotesButton = createCustomToggle("Ghosts See Votes: ", TheOtherRolesPlugin.GhostsSeeVotes.Value, new Vector2(0, yOffset), (UnityEngine.Events.UnityAction)ghostsSeeVotesToggle, __instance); void ghostsSeeVotesToggle() { TheOtherRolesPlugin.GhostsSeeVotes.Value = !TheOtherRolesPlugin.GhostsSeeVotes.Value; MapOptions.ghostsSeeVotes = TheOtherRolesPlugin.GhostsSeeVotes.Value; - updateToggle(ghostsSeeVotesButton, "Ghosts See Roles: ", TheOtherRolesPlugin.GhostsSeeVotes.Value); + updateToggle(ghostsSeeVotesButton, "Ghosts See Votes: ", TheOtherRolesPlugin.GhostsSeeVotes.Value); + } + } + + if ((showRoleSummaryButton == null || showRoleSummaryButton.gameObject == null)) { + showRoleSummaryButton = createCustomToggle("Role Summary: ", TheOtherRolesPlugin.ShowRoleSummary.Value, new Vector2(xOffset, yOffset), (UnityEngine.Events.UnityAction)showRoleSummaryToggle, __instance); + + void showRoleSummaryToggle() { + TheOtherRolesPlugin.ShowRoleSummary.Value = !TheOtherRolesPlugin.ShowRoleSummary.Value; + MapOptions.showRoleSummary = TheOtherRolesPlugin.ShowRoleSummary.Value; + updateToggle(showRoleSummaryButton, "Role Summary: ", TheOtherRolesPlugin.ShowRoleSummary.Value); } } } @@ -99,4 +110,4 @@ namespace TheOtherRoles { if (flag) __instance.outputText.text = new string('*', __instance.text.Length); } } -} \ No newline at end of file +} diff --git a/Source Code/CustomColors.cs b/Source Code/CustomColors.cs index 88c51db..42b279d 100644 --- a/Source Code/CustomColors.cs +++ b/Source Code/CustomColors.cs @@ -158,8 +158,12 @@ namespace TheOtherRoles { chip.transform.localPosition = new Vector3(1.46f + (col * 0.6f), -0.43f - (row * 0.55f), chip.transform.localPosition.z); chip.transform.localScale *= 0.9f; - if (i >= pickableColors) + if (i >= pickableColors) { chip.transform.localScale *= 0f; // Needs to exist for PlayerTab + chip.enabled = false; + chip.Button.enabled = false; + chip.Button.OnClick.RemoveAllListeners(); + } } } } diff --git a/Source Code/CustomOptions.cs b/Source Code/CustomOptions.cs index 5845606..f7fa2db 100644 --- a/Source Code/CustomOptions.cs +++ b/Source Code/CustomOptions.cs @@ -125,6 +125,8 @@ namespace TheOtherRoles { public static CustomOption spySpawnRate; public static CustomOption spyCanDieToSheriff; public static CustomOption spyImpostorsCanKillAnyone; + public static CustomOption spyCanEnterVents; + public static CustomOption spyHasImpostorVision; public static CustomOption tricksterSpawnRate; public static CustomOption tricksterPlaceBoxCooldown; @@ -289,6 +291,8 @@ namespace TheOtherRoles { spySpawnRate = CustomOption.Create(240, cs(Spy.color, "Spy"), rates, null, true); spyCanDieToSheriff = CustomOption.Create(241, "Spy Can Die To Sheriff", false, spySpawnRate); spyImpostorsCanKillAnyone = CustomOption.Create(242, "Impostors Can Kill Anyone If There Is A Spy", true, spySpawnRate); + spyCanEnterVents = CustomOption.Create(243, "Spy Can Enter Vents", false, spySpawnRate); + spyHasImpostorVision = CustomOption.Create(244, "Spy Has Impostor Vision", false, spySpawnRate); securityGuardSpawnRate = CustomOption.Create(280, cs(SecurityGuard.color, "Security Guard"), rates, null, true); securityGuardCooldown = CustomOption.Create(281, "Security Guard Cooldown", 30f, 10f, 60f, 2.5f, securityGuardSpawnRate); @@ -436,6 +440,16 @@ namespace TheOtherRoles { } option.optionBehaviour.gameObject.SetActive(true); } + + var commonTasksOption = allOptions.FirstOrDefault(x => x.name == "NumCommonTasks").TryCast(); + if(commonTasksOption != null) commonTasksOption.ValidRange = new FloatRange(0f, 4f); + + var shortTasksOption = allOptions.FirstOrDefault(x => x.name == "NumShortTasks").TryCast(); + if(shortTasksOption != null) shortTasksOption.ValidRange = new FloatRange(0f, 23f); + + var longTasksOption = allOptions.FirstOrDefault(x => x.name == "NumLongTasks").TryCast(); + if(longTasksOption != null) longTasksOption.ValidRange = new FloatRange(0f, 15f); + __instance.Children = allOptions.ToArray(); } } @@ -604,7 +618,7 @@ namespace TheOtherRoles { int defaultSettingsLines = 19; int roleSettingsLines = defaultSettingsLines + 32; int detailedSettingsP1 = roleSettingsLines + 34; - int detailedSettingsP2 = detailedSettingsP1 + 36; + int detailedSettingsP2 = detailedSettingsP1 + 35; int end1 = hudString.TakeWhile(c => (defaultSettingsLines -= (c == '\n' ? 1 : 0)) > 0).Count(); int end2 = hudString.TakeWhile(c => (roleSettingsLines -= (c == '\n' ? 1 : 0)) > 0).Count(); int end3 = hudString.TakeWhile(c => (detailedSettingsP1 -= (c == '\n' ? 1 : 0)) > 0).Count(); diff --git a/Source Code/EndGamePatch.cs b/Source Code/EndGamePatch.cs index e1e7c26..ebbc974 100644 --- a/Source Code/EndGamePatch.cs +++ b/Source Code/EndGamePatch.cs @@ -33,13 +33,22 @@ namespace TheOtherRoles { static class AdditionalTempData { // Should be implemented using a proper GameOverReason in the future public static WinCondition winCondition = WinCondition.Default; - + public static List playerRoles = new List(); public static void clear() { + playerRoles.Clear(); winCondition = WinCondition.Default; } + + internal class PlayerRoleInfo { + public string PlayerName { get; set; } + public List Roles {get;set;} + public int TasksCompleted {get;set;} + public int TasksTotal {get;set;} + } } + [HarmonyPatch(typeof(AmongUsClient), nameof(AmongUsClient.OnGameEnd))] public class OnGameEndPatch { private static GameOverReason gameOverReason; @@ -51,6 +60,12 @@ namespace TheOtherRoles { public static void Postfix(AmongUsClient __instance, [HarmonyArgument(0)]ref GameOverReason reason, [HarmonyArgument(1)]bool showAd) { AdditionalTempData.clear(); + foreach(var playerControl in PlayerControl.AllPlayerControls) { + var roles = RoleInfo.getRoleInfoForPlayer(playerControl); + var (tasksCompleted, tasksTotal) = TasksHandler.taskInfo(playerControl.Data); + AdditionalTempData.playerRoles.Add(new AdditionalTempData.PlayerRoleInfo() { PlayerName = playerControl.Data.PlayerName, Roles = roles, TasksTotal = tasksTotal, TasksCompleted = tasksCompleted }); + } + // Remove Jester, Arsonist, Jackal, former Jackals and Sidekick from winners (if they win, they'll be readded) List notWinners = new List(); if (Jester.jester != null) notWinners.Add(Jester.jester); @@ -180,7 +195,31 @@ namespace TheOtherRoles { textRenderer.text = "Child died"; textRenderer.color = Child.color; } - + + if(MapOptions.showRoleSummary) { + var position = Camera.main.ViewportToWorldPoint(new Vector3(0f, 1f, Camera.main.nearClipPlane)); + GameObject roleSummary = UnityEngine.Object.Instantiate(__instance.WinText.gameObject); + roleSummary.transform.position = new Vector3(__instance.ExitButton.transform.position.x + 0.1f, position.y - 0.1f, -14f); + roleSummary.transform.localScale = new Vector3(1f, 1f, 1f); + + var roleSummaryText = new StringBuilder(); + roleSummaryText.AppendLine("Players and roles at the end of the game:"); + foreach(var data in AdditionalTempData.playerRoles) { + var roles = string.Join(" ", data.Roles.Select(x => Helpers.cs(x.color, x.name))); + var taskInfo = data.TasksTotal > 0 ? $" - ({data.TasksCompleted}/{data.TasksTotal})" : ""; + roleSummaryText.AppendLine($"{data.PlayerName} - {roles}{taskInfo}"); + } + TMPro.TMP_Text roleSummaryTextMesh = roleSummary.GetComponent(); + roleSummaryTextMesh.alignment = TMPro.TextAlignmentOptions.TopLeft; + roleSummaryTextMesh.color = Color.white; + roleSummaryTextMesh.fontSizeMin = 1.5f; + roleSummaryTextMesh.fontSizeMax = 1.5f; + roleSummaryTextMesh.fontSize = 1.5f; + + var roleSummaryTextMeshRectTransform = roleSummaryTextMesh.GetComponent(); + roleSummaryTextMeshRectTransform.anchoredPosition = new Vector2(position.x + 3.5f, position.y - 0.1f); + roleSummaryTextMesh.text = roleSummaryText.ToString(); + } AdditionalTempData.clear(); } } diff --git a/Source Code/IntroPatch.cs b/Source Code/IntroPatch.cs index 182fd64..d16851a 100644 --- a/Source Code/IntroPatch.cs +++ b/Source Code/IntroPatch.cs @@ -64,17 +64,20 @@ namespace TheOtherRoles if (roleInfo != null) { __instance.Title.text = roleInfo.name; - __instance.Title.color = roleInfo.color; __instance.ImpostorText.gameObject.SetActive(true); __instance.ImpostorText.text = roleInfo.introDescription; - __instance.BackgroundBar.material.color = roleInfo.color; + if (roleInfo.roleId != RoleId.Crewmate && roleInfo.roleId != RoleId.Impostor) { + // For native Crewmate or Impostor do not modify the colors + __instance.Title.color = roleInfo.color; + __instance.BackgroundBar.material.color = roleInfo.color; + } } if (infos.Any(info => info.roleId == RoleId.Lover)) { var loversText = UnityEngine.Object.Instantiate(__instance.ImpostorText, __instance.ImpostorText.transform.parent); loversText.transform.localPosition += Vector3.down * 3f; PlayerControl otherLover = PlayerControl.LocalPlayer == Lovers.lover1 ? Lovers.lover2 : Lovers.lover1; - loversText.text = Helpers.cs(Lovers.color, $"❤ You are in lover with {otherLover?.Data?.PlayerName ?? ""} ❤"); + loversText.text = Helpers.cs(Lovers.color, $"❤ You are in love with {otherLover?.Data?.PlayerName ?? ""} ❤"); } } diff --git a/Source Code/Main.cs b/Source Code/Main.cs index c8522ad..8694ea6 100644 --- a/Source Code/Main.cs +++ b/Source Code/Main.cs @@ -19,7 +19,7 @@ namespace TheOtherRoles public class TheOtherRolesPlugin : BasePlugin { public const string Id = "me.eisbison.theotherroles"; - public const string VersionString = "2.6.4"; + public const string VersionString = "2.6.5"; public static System.Version Version = System.Version.Parse(VersionString); public Harmony Harmony { get; } = new Harmony(Id); @@ -32,6 +32,7 @@ namespace TheOtherRoles public static ConfigEntry GhostsSeeTasks { get; set; } public static ConfigEntry GhostsSeeRoles { get; set; } public static ConfigEntry GhostsSeeVotes{ get; set; } + public static ConfigEntry ShowRoleSummary { get; set; } public static ConfigEntry StreamerModeReplacementText { get; set; } public static ConfigEntry StreamerModeReplacementColor { get; set; } public static ConfigEntry Ip { get; set; } @@ -56,6 +57,7 @@ namespace TheOtherRoles GhostsSeeTasks = Config.Bind("Custom", "Ghosts See Remaining Tasks", true); GhostsSeeRoles = Config.Bind("Custom", "Ghosts See Roles", true); GhostsSeeVotes = Config.Bind("Custom", "Ghosts See Votes", true); + ShowRoleSummary = Config.Bind("Custom", "Show Role Summary", true); StreamerModeReplacementText = Config.Bind("Custom", "Streamer Mode Replacement Text", "\n\nThe Other Roles"); StreamerModeReplacementColor = Config.Bind("Custom", "Streamer Mode Replacement Text Hex Color", "#87AAF5FF"); diff --git a/Source Code/MapOptions.cs b/Source Code/MapOptions.cs index 2deb0c5..4a165de 100644 --- a/Source Code/MapOptions.cs +++ b/Source Code/MapOptions.cs @@ -14,6 +14,7 @@ namespace TheOtherRoles{ public static bool ghostsSeeRoles = true; public static bool ghostsSeeTasks = true; public static bool ghostsSeeVotes = true; + public static bool showRoleSummary = true; // Updating values public static int meetingsCount = 0; @@ -32,6 +33,7 @@ namespace TheOtherRoles{ ghostsSeeRoles = TheOtherRolesPlugin.GhostsSeeRoles.Value; ghostsSeeTasks = TheOtherRolesPlugin.GhostsSeeTasks.Value; ghostsSeeVotes = TheOtherRolesPlugin.GhostsSeeVotes.Value; + showRoleSummary = TheOtherRolesPlugin.ShowRoleSummary.Value; } } } \ No newline at end of file diff --git a/Source Code/RoleInfo.cs b/Source Code/RoleInfo.cs index 0d82d7b..1ead17e 100644 --- a/Source Code/RoleInfo.cs +++ b/Source Code/RoleInfo.cs @@ -255,10 +255,11 @@ namespace TheOtherRoles // Modifier if ((Lovers.lover1 != null && p == Lovers.lover1) || (Lovers.lover2 != null && p == Lovers.lover2)) { + var partnerName = (p == Lovers.lover1) ? Lovers.lover2.Data.PlayerName : Lovers.lover1.Data.PlayerName; infos.Add(new RoleInfo("Lover", Lovers.color, - "You are in Love", - "You are in love", + $"You are in Love with {partnerName}", + $"You are in love with {partnerName}", RoleId.Lover)); } diff --git a/Source Code/ShipStatusPatch.cs b/Source Code/ShipStatusPatch.cs index afe5701..0ab4fb6 100644 --- a/Source Code/ShipStatusPatch.cs +++ b/Source Code/ShipStatusPatch.cs @@ -1,4 +1,3 @@ - using HarmonyLib; using static TheOtherRoles.TheOtherRoles; using UnityEngine; @@ -8,8 +7,8 @@ namespace TheOtherRoles { [HarmonyPatch(typeof(ShipStatus))] public class ShipStatusPatch { - [HarmonyPostfix] - [HarmonyPatch(typeof(ShipStatus), nameof(ShipStatus.CalculateLightRadius))] + [HarmonyPostfix] + [HarmonyPatch(typeof(ShipStatus), nameof(ShipStatus.CalculateLightRadius))] public static bool Prefix(ref float __result, ShipStatus __instance, [HarmonyArgument(0)] GameData.PlayerInfo player) { ISystemType systemType = __instance.Systems.ContainsKey(SystemTypes.Electrical) ? __instance.Systems[SystemTypes.Electrical] : null; if (systemType == null) return true; @@ -22,7 +21,8 @@ namespace TheOtherRoles { __result = __instance.MaxLightRadius; else if (player.IsImpostor || (Jackal.jackal != null && Jackal.jackal.PlayerId == player.PlayerId && Jackal.hasImpostorVision) - || (Sidekick.sidekick != null && Sidekick.sidekick.PlayerId == player.PlayerId && Sidekick.hasImpostorVision)) // Impostor or Jackal/Sidekick with Impostor vision + || (Sidekick.sidekick != null && Sidekick.sidekick.PlayerId == player.PlayerId && Sidekick.hasImpostorVision) + || (Spy.spy != null && Spy.spy.PlayerId == player.PlayerId && Spy.hasImpostorVision)) // Impostor, Jackal/Sidekick or Spy with Impostor vision __result = __instance.MaxLightRadius * PlayerControl.GameOptions.ImpostorLightMod; else if (Lighter.lighter != null && Lighter.lighter.PlayerId == player.PlayerId && Lighter.lighterTimer > 0f) // if player is Lighter and Lighter has his ability active __result = Mathf.Lerp(__instance.MaxLightRadius * Lighter.lighterModeLightsOffVision, __instance.MaxLightRadius * Lighter.lighterModeLightsOnVision, num); @@ -38,11 +38,42 @@ namespace TheOtherRoles { } [HarmonyPostfix] - [HarmonyPatch(typeof(ShipStatus), nameof(ShipStatus.IsGameOverDueToDeath))] - public static void Postfix2(ShipStatus __instance, ref bool __result) - { - __result = false; - } + [HarmonyPatch(typeof(ShipStatus), nameof(ShipStatus.IsGameOverDueToDeath))] + public static void Postfix2(ShipStatus __instance, ref bool __result) + { + __result = false; + } + + private static int originalNumCommonTasksOption = 0; + private static int originalNumShortTasksOption = 0; + private static int originalNumLongTasksOption = 0; + + [HarmonyPrefix] + [HarmonyPatch(typeof(ShipStatus), nameof(ShipStatus.Begin))] + public static bool Prefix(ShipStatus __instance) + { + var commonTaskCount = __instance.CommonTasks.Count; + var normalTaskCount = __instance.NormalTasks.Count; + var longTaskCount = __instance.LongTasks.Count; + originalNumCommonTasksOption = PlayerControl.GameOptions.NumCommonTasks; + originalNumShortTasksOption = PlayerControl.GameOptions.NumShortTasks; + originalNumLongTasksOption = PlayerControl.GameOptions.NumLongTasks; + if(PlayerControl.GameOptions.NumCommonTasks > commonTaskCount) PlayerControl.GameOptions.NumCommonTasks = commonTaskCount; + if(PlayerControl.GameOptions.NumShortTasks > normalTaskCount) PlayerControl.GameOptions.NumShortTasks = normalTaskCount; + if(PlayerControl.GameOptions.NumLongTasks > longTaskCount) PlayerControl.GameOptions.NumLongTasks = longTaskCount; + return true; + } + + [HarmonyPostfix] + [HarmonyPatch(typeof(ShipStatus), nameof(ShipStatus.Begin))] + public static void Postfix3(ShipStatus __instance) + { + // Restore original settings after the tasks have been selected + PlayerControl.GameOptions.NumCommonTasks = originalNumCommonTasksOption; + PlayerControl.GameOptions.NumShortTasks = originalNumShortTasksOption; + PlayerControl.GameOptions.NumLongTasks = originalNumLongTasksOption; + } + } } \ No newline at end of file diff --git a/Source Code/TasksHandler.cs b/Source Code/TasksHandler.cs index 43d24fb..fc00fe9 100644 --- a/Source Code/TasksHandler.cs +++ b/Source Code/TasksHandler.cs @@ -44,5 +44,6 @@ namespace TheOtherRoles { return false; } } + } } diff --git a/Source Code/TheOtherRoles.cs b/Source Code/TheOtherRoles.cs index 9b9108a..848664f 100644 --- a/Source Code/TheOtherRoles.cs +++ b/Source Code/TheOtherRoles.cs @@ -327,15 +327,15 @@ namespace TheOtherRoles } public static bool existingWithKiller() { - return existing() && (lover1 == Jackal.jackal || lover2 == Jackal.jackal - || lover1 == Sidekick.sidekick || lover2 == Sidekick.sidekick + return existing() && (lover1 == Jackal.jackal || lover2 == Jackal.jackal + || lover1 == Sidekick.sidekick || lover2 == Sidekick.sidekick || lover1.Data.IsImpostor || lover2.Data.IsImpostor); } public static bool hasAliveKillingLover(this PlayerControl player) { if (!Lovers.existingAndAlive() || !existingWithKiller()) return false; - return (player != null && player != lover1 && player != lover2); + return (player != null && (player == lover1 || player == lover2)); } public static void clearAndReload() { @@ -707,10 +707,14 @@ namespace TheOtherRoles public static Color color = Palette.ImpostorRed; public static bool impostorsCanKillAnyone = true; + public static bool canEnterVents = false; + public static bool hasImpostorVision = false; public static void clearAndReload() { spy = null; impostorsCanKillAnyone = CustomOptionHolder.spyImpostorsCanKillAnyone.getBool(); + canEnterVents = CustomOptionHolder.spyCanEnterVents.getBool(); + hasImpostorVision = CustomOptionHolder.spyHasImpostorVision.getBool(); } } diff --git a/Source Code/TheOtherRoles.csproj b/Source Code/TheOtherRoles.csproj index c1b0032..5c580c2 100644 --- a/Source Code/TheOtherRoles.csproj +++ b/Source Code/TheOtherRoles.csproj @@ -1,7 +1,7 @@ netstandard2.1 - 2.6.4 + 2.6.5 TheOtherRoles Eisbison diff --git a/Source Code/UsablesPatch.cs b/Source Code/UsablesPatch.cs index 1d4fff4..1eeeef7 100644 --- a/Source Code/UsablesPatch.cs +++ b/Source Code/UsablesPatch.cs @@ -28,6 +28,8 @@ namespace TheOtherRoles roleCouldUse = true; else if (Sidekick.canUseVents && Sidekick.sidekick != null && Sidekick.sidekick == @object) roleCouldUse = true; + else if (Spy.canEnterVents && Spy.canEnterVents) + roleCouldUse = true; else if (pc.IsImpostor) { if (Janitor.janitor != null && Janitor.janitor == PlayerControl.LocalPlayer) roleCouldUse = false; @@ -73,22 +75,33 @@ namespace TheOtherRoles [HarmonyPatch(typeof(Vent), "Use")] public static class VentUsePatch { public static bool Prefix(Vent __instance) { - bool flag; - bool flag2; - __instance.CanUse(PlayerControl.LocalPlayer.Data, out flag, out flag2); - - if (!flag || !__instance.name.StartsWith("JackInTheBoxVent_")) return true; // Continue with default method - + bool canUse; + bool couldUse; + __instance.CanUse(PlayerControl.LocalPlayer.Data, out canUse, out couldUse); + bool canMoveInVents = true; + if (!canUse) return false; // No need to execute the native method as using is disallowed anyways + if (Spy.spy == PlayerControl.LocalPlayer) { + canMoveInVents = false; + } bool isEnter = !PlayerControl.LocalPlayer.inVent; + + if (__instance.name.StartsWith("JackInTheBoxVent_")) { + __instance.SetButtons(isEnter && canMoveInVents); + MessageWriter writer = AmongUsClient.Instance.StartRpc(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.UseUncheckedVent, Hazel.SendOption.Reliable); + writer.WritePacked(__instance.Id); + writer.Write(PlayerControl.LocalPlayer.PlayerId); + writer.Write(isEnter ? byte.MaxValue : (byte)0); + writer.EndMessage(); + RPCProcedure.useUncheckedVent(__instance.Id, PlayerControl.LocalPlayer.PlayerId, isEnter ? byte.MaxValue : (byte)0); + return false; + } - __instance.SetButtons(isEnter); - MessageWriter writer = AmongUsClient.Instance.StartRpc(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.UseUncheckedVent, Hazel.SendOption.Reliable); - writer.WritePacked(__instance.Id); - writer.Write(PlayerControl.LocalPlayer.PlayerId); - writer.Write(isEnter ? byte.MaxValue : (byte)0); - writer.EndMessage(); - RPCProcedure.useUncheckedVent(__instance.Id, PlayerControl.LocalPlayer.PlayerId, isEnter ? byte.MaxValue : (byte)0); - + if(isEnter) { + PlayerControl.LocalPlayer.MyPhysics.RpcEnterVent(__instance.Id); + } else { + PlayerControl.LocalPlayer.MyPhysics.RpcExitVent(__instance.Id); + } + __instance.SetButtons(isEnter && canMoveInVents); return false; } }