]> git.deb.at Git - rhonda/theotherroles.git/commitdiff
Version v2.6.5
authorNicholas Marty <nicholas.marty@f24.com>
Tue, 25 May 2021 14:37:16 +0000 (16:37 +0200)
committerNicholas Marty <nicholas.marty@f24.com>
Tue, 25 May 2021 14:37:16 +0000 (16:37 +0200)
14 files changed:
README.md
Source Code/ClientOptionsPatch.cs
Source Code/CustomColors.cs
Source Code/CustomOptions.cs
Source Code/EndGamePatch.cs
Source Code/IntroPatch.cs
Source Code/Main.cs
Source Code/MapOptions.cs
Source Code/RoleInfo.cs
Source Code/ShipStatusPatch.cs
Source Code/TasksHandler.cs
Source Code/TheOtherRoles.cs
Source Code/TheOtherRoles.csproj
Source Code/UsablesPatch.cs

index 3ec2f2a3cb5c408bb5b552743a68171d67d343d9..8d8d1deb6a95819e4f04b7bb791b24427d6239bd 100644 (file)
--- 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
 <details>
   <summary>Click to show the Changelog</summary>
 
+**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
index 681e7e8f8befa83194af3bf5fedcfa13b7a288bd..2dd829c3f145159f1cd8e39e90d5b25d9dc600d7 100644 (file)
@@ -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
+}
index 88c51db51066629ff710c4411253ce8cd841c8c4..42b279da2fd11a5e7bb7d4f8908a6e2a4f83a101 100644 (file)
@@ -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();
+                        }
                     }
                 }
             }
index 58456068230ef5d7dd265857ce78bf00b450bfc4..f7fa2db86a400bd9f741166b1c0699c5465da38c 100644 (file)
@@ -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<NumberOption>();
+            if(commonTasksOption != null) commonTasksOption.ValidRange = new FloatRange(0f, 4f);
+
+            var shortTasksOption = allOptions.FirstOrDefault(x => x.name == "NumShortTasks").TryCast<NumberOption>();
+            if(shortTasksOption != null) shortTasksOption.ValidRange = new FloatRange(0f, 23f);
+
+            var longTasksOption = allOptions.FirstOrDefault(x => x.name == "NumLongTasks").TryCast<NumberOption>();
+            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();
index e1e7c26c1b11c561ad2e7e3e3c17a4e98cc1b135..ebbc974071ab76ed64aeffe63e390ca2a0c9b5ec 100644 (file)
@@ -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<PlayerRoleInfo> playerRoles = new List<PlayerRoleInfo>();
 
         public static void clear() {
+            playerRoles.Clear();
             winCondition = WinCondition.Default;
         }
+
+        internal class PlayerRoleInfo {
+            public string PlayerName { get; set; }
+            public List<RoleInfo> 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<PlayerControl> notWinners = new List<PlayerControl>();
             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 ? $" - <color=#FAD934FF>({data.TasksCompleted}/{data.TasksTotal})</color>" : "";
+                    roleSummaryText.AppendLine($"{data.PlayerName} - {roles}{taskInfo}");
+                }
+                TMPro.TMP_Text roleSummaryTextMesh = roleSummary.GetComponent<TMPro.TMP_Text>();
+                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<RectTransform>();
+                roleSummaryTextMeshRectTransform.anchoredPosition = new Vector2(position.x + 3.5f, position.y - 0.1f);
+                roleSummaryTextMesh.text = roleSummaryText.ToString();
+            }
             AdditionalTempData.clear();
         }
     }
index 182fd643ab49eb80ba65ddaec81e0e3a3fd577a3..d16851a7e0f4505974c343faec913200b6e52b0a 100644 (file)
@@ -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<TMPro.TextMeshPro>(__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 ?? ""} ❤");
             }
         }
 
index c8522ad3170346183c4d333f1d96774fc9f5faf2..8694ea6bf5e6cf71aee848ab0134d4f0400984a0 100644 (file)
@@ -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<bool> GhostsSeeTasks { get; set; }
         public static ConfigEntry<bool> GhostsSeeRoles { get; set; }
         public static ConfigEntry<bool> GhostsSeeVotes{ get; set; }
+        public static ConfigEntry<bool> ShowRoleSummary { get; set; }
         public static ConfigEntry<string> StreamerModeReplacementText { get; set; }
         public static ConfigEntry<string> StreamerModeReplacementColor { get; set; }
         public static ConfigEntry<string> 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");
             
index 2deb0c55b6b3116c1e37f1d9a43028ece8413aed..4a165debc7f6ff265b304979059253a39953f5e4 100644 (file)
@@ -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
index 0d82d7bbb066de37b7d9c38b867c8d1ba2aeba99..1ead17e8f882f3d8199f4273ed0c318df5671e2f 100644 (file)
@@ -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 <color=#FC03BEFF>Love</color>",
-                "You are in love",
+                $"You are in <color=#FC03BEFF>Love</color> with <color=#FC03BEFF>{partnerName}</color>",
+                $"You are in love with {partnerName}",
                 RoleId.Lover));
             }
 
index afe57019dfa8fde9822278cce92ac18d5065a831..0ab4fb6a3c3f81d8d5cbb78da746d2524d2bc50a 100644 (file)
@@ -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
index 43d24fb03ea4fa528dd4465b0e3c2e892820d83a..fc00fe9e3c669318ff5eb21d82012ccbc4bb6f65 100644 (file)
@@ -44,5 +44,6 @@ namespace TheOtherRoles {
                 return false;
             }
         }
+        
     }
 }
index 9b9108aa93f5f7e5846297f7b163ca30bf6dfab2..848664f59c45a5648ceb9baa7a95afd4ad50a619 100644 (file)
@@ -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();
         }
     }
 
index c1b0032664e4402ce27bf49042a0eb457b77670a..5c580c247158583073e64ffe1d19d58cda7b2b45 100644 (file)
@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
     <PropertyGroup>
         <TargetFramework>netstandard2.1</TargetFramework>
-        <Version>2.6.4</Version>
+        <Version>2.6.5</Version>
         <Description>TheOtherRoles</Description>
         <Authors>Eisbison</Authors>
     </PropertyGroup>
index 1d4fff4a05083af85472e05687cdb23f51bfd765..1eeeef7a296427ba9486eed72c89a459b8c19f7c 100644 (file)
@@ -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;
         }
     }