]> git.deb.at Git - rhonda/theotherroles.git/commitdiff
Version 3.4.1
authordwd0tcom <info@dominikwierl.com>
Wed, 26 Jan 2022 19:11:23 +0000 (20:11 +0100)
committerdwd0tcom <info@dominikwierl.com>
Wed, 26 Jan 2022 19:11:23 +0000 (20:11 +0100)
15 files changed:
README.md
TheOtherRoles/Buttons.cs
TheOtherRoles/CustomOptionHolder.cs
TheOtherRoles/Main.cs
TheOtherRoles/MapOptions.cs
TheOtherRoles/Modules/ModUpdater.cs
TheOtherRoles/Patches/ClientOptionsPatch.cs
TheOtherRoles/Patches/GameStartManagerPatch.cs
TheOtherRoles/Patches/PlayerControlPatch.cs
TheOtherRoles/Patches/RoleAssignmentPatch.cs
TheOtherRoles/Patches/ShipStatusPatch.cs
TheOtherRoles/Patches/UpdatePatch.cs
TheOtherRoles/RPC.cs
TheOtherRoles/TheOtherRoles.cs
TheOtherRoles/TheOtherRoles.csproj

index 1eba5e90c5ea0ca68046d2bbb5b8cea0b0adb40b..ad1daef8529d8a5232d5cd39566a188f29c6a72a 100644 (file)
--- a/README.md
+++ b/README.md
@@ -41,8 +41,8 @@ The [Role Assignment](#role-assignment) sections explains how the roles are bein
 # Releases
 | Among Us - Version| Mod Version | Link |
 |----------|-------------|-----------------|
+| 2021.12.15s| v3.4.1| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v3.4.1/TheOtherRoles.zip)
 | 2021.12.15s| v3.4.0| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v3.4.0/TheOtherRoles.zip)
-| 2021.12.15s| v3.3.4| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v3.3.4/TheOtherRoles.zip)
 | 2021.12.15s| v3.3.3| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v3.3.3/TheOtherRoles.zip)
 | 2021.12.15s| v3.3.2| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v3.3.2/TheOtherRoles.zip)
 | 2021.12.14s| v3.3.1| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v3.3.1/TheOtherRoles.zip)
@@ -97,20 +97,29 @@ The [Role Assignment](#role-assignment) sections explains how the roles are bein
 <details>
   <summary>Click to show the Changelog</summary>
   
+**Version 3.4.1**
+- Added a new mod option "Show Lighter/Darker" for meetings
+- Added options for choosing which maps are enabled for random maps thanks [EvilScum](https://github.com/JustASysAdmin)
+- Added Jester option "Jester Has Impostor Vision" thanks [EvilScum](https://github.com/JustASysAdmin)
+- Fixed a bug where the Bounty Hunter had no bounty
+- Fixed a bug where the Guesser & Sheriff were not assigned properly (fingers crossed)
+- Fixed a bug where Hacker buttons didn't work as intended with "random map" option
+- Fixed a bug where the Security Guard could not access cams on Skeld, dlekS & Airship
+- Changed Tracker update intervall to a minimum of 1 thanks [LaicosVK](https://github.com/LaicosVK)
+
 **Version 3.4.0**
 - Added new Role [Deputy](#deputy) thanks [gendelo3](https://github.com/gendelo3)
 - Added Hacker option "Cant Move During Mobile Gadget Duration"
 - Added Security Guard mobile cams after placing all screws
 - Added Lover option "Enable Lover Chat"
 - Added return votes in meetings: You'll now get your votes back if your target got shot by the Guesser
-- Added New Option for Guesser: Guesser can't guess Snitch if they has done all tasks (created by Mr_Fluff)
+- Added New Option for Guesser: Guesser can't guess Snitch if they has done all tasks (created by [MaximeGillot](https://github.com/MaximeGillot)
 - Added The Other Roles changelog announcement popup
 - Changed that the Bounty Hunter exclude their Lover
 - Changed the position of the Witch icon in meetings for better visibility
 - Fixed a bug where the spy had a white name for Impostors in chat
 - Fixed a bug where the Guesser and Swapper UI in meetings was behind the visor cosmetics
 
-
 **Version 3.3.3**
 - Fixed a bug where a guessed Guesser could guess
 - Fixed a bug where buttons were visible during the meeting
@@ -566,6 +575,7 @@ The mod adds a few new settings to Among Us (in addition to the role settings):
 - **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
+- **Darker/Lighter:** Displays color type of each player in meetings
 
 ### Task Count Limits per map
 You can configure:
index 2687284f1d4818b6f2b096f3853d1d26cf61a0e3..0fca0e40be6310b14a6e5fa7a99e1bf99e39a0d9 100644 (file)
@@ -185,7 +185,6 @@ namespace TheOtherRoles
             engineerRepairButton = new CustomButton(
                 () => {
                     engineerRepairButton.Timer = 0f;
-
                     MessageWriter usedRepairWriter = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.EngineerUsedRepair, Hazel.SendOption.Reliable, -1);
                     AmongUsClient.Instance.FinishRpcImmediately(usedRepairWriter);
                     RPCProcedure.engineerUsedRepair();
@@ -462,7 +461,7 @@ namespace TheOtherRoles
                     Hacker.hackerTimer = Hacker.duration;
                 },
                 () => { return Hacker.hacker != null && Hacker.hacker == PlayerControl.LocalPlayer && !PlayerControl.LocalPlayer.Data.IsDead; },
-                () => { return PlayerControl.LocalPlayer.CanMove; },
+                () => { return true; },
                 () => {
                     hackerButton.Timer = hackerButton.MaxTimer;
                     hackerButton.isEffectActive = false;
@@ -484,7 +483,6 @@ namespace TheOtherRoles
 
                    if (Hacker.cantMove) PlayerControl.LocalPlayer.moveable = false;
                    PlayerControl.LocalPlayer.NetTransform.Halt(); // Stop current movement 
-
                    Hacker.chargesAdminTable--;
                },
                () => { return Hacker.hacker != null && Hacker.hacker == PlayerControl.LocalPlayer && !PlayerControl.LocalPlayer.Data.IsDead;},
@@ -982,7 +980,10 @@ namespace TheOtherRoles
                 () => {
                     if (PlayerControl.GameOptions.MapId != 1) {
                         if (SecurityGuard.minigame == null) {
+                            byte mapId = PlayerControl.GameOptions.MapId;
                             var e = UnityEngine.Object.FindObjectsOfType<SystemConsole>().FirstOrDefault(x => x.gameObject.name.Contains("Surv_Panel"));
+                            if (mapId == 0 || mapId == 3) e = UnityEngine.Object.FindObjectsOfType<SystemConsole>().FirstOrDefault(x => x.gameObject.name.Contains("SurvConsole"));
+                            else if (mapId == 4) e = UnityEngine.Object.FindObjectsOfType<SystemConsole>().FirstOrDefault(x => x.gameObject.name.Contains("task_cams"));
                             if (e == null || Camera.main == null) return;
                             SecurityGuard.minigame = UnityEngine.Object.Instantiate(e.MinigamePrefab, Camera.main.transform, false);
                         }
index c9c80f6fd037d20cc214fae2a6ad28b68b1874df..1089c27e04c774c28e1477744b5dbf06184a561f 100644 (file)
@@ -64,6 +64,7 @@ namespace TheOtherRoles {
 
         public static CustomOption jesterSpawnRate;
         public static CustomOption jesterCanCallEmergency;
+        public static CustomOption jesterHasImpostorVision;
 
         public static CustomOption arsonistSpawnRate;
         public static CustomOption arsonistCooldown;
@@ -229,7 +230,13 @@ namespace TheOtherRoles {
         public static CustomOption noVoteIsSelfVote;
         public static CustomOption hidePlayerNames;
         public static CustomOption allowParallelMedBayScans;
+
         public static CustomOption dynamicMap;
+        public static CustomOption dynamicMapEnableSkeld;
+        public static CustomOption dynamicMapEnableMira;
+        public static CustomOption dynamicMapEnablePolus;
+        public static CustomOption dynamicMapEnableDleks;
+        public static CustomOption dynamicMapEnableAirShip;
 
 
         internal static Dictionary<byte, byte[]> blockedRolePairings = new Dictionary<byte, byte[]>();
@@ -324,7 +331,8 @@ namespace TheOtherRoles {
             guesserCantGuessSnitchIfTaksDone = CustomOption.Create(318, "Guesser Can't Guess Snitch When Tasks Completed", true, guesserSpawnRate);
 
             jesterSpawnRate = CustomOption.Create(60, cs(Jester.color, "Jester"), rates, null, true);
-            jesterCanCallEmergency = CustomOption.Create(61, "Jester can call emergency meeting", true, jesterSpawnRate);
+            jesterCanCallEmergency = CustomOption.Create(61, "Jester Can Call Emergency Meeting", true, jesterSpawnRate);
+            jesterCanCallEmergency = CustomOption.Create(62, "Jester Has Impostor Vision", false, jesterSpawnRate);
 
             arsonistSpawnRate = CustomOption.Create(290, cs(Arsonist.color, "Arsonist"), rates, null, true);
             arsonistCooldown = CustomOption.Create(291, "Arsonist Cooldown", 12.5f, 2.5f, 60f, 2.5f, arsonistSpawnRate);
@@ -420,7 +428,7 @@ namespace TheOtherRoles {
             hackerNoMove = CustomOption.Create(176, "Cant Move During Mobile Gadget Duration", true, hackerSpawnRate);
 
             trackerSpawnRate = CustomOption.Create(200, cs(Tracker.color, "Tracker"), rates, null, true);
-            trackerUpdateIntervall = CustomOption.Create(201, "Tracker Update Intervall", 5f, 2.5f, 30f, 2.5f, trackerSpawnRate);
+            trackerUpdateIntervall = CustomOption.Create(201, "Tracker Update Intervall", 5f, 1f, 30f, 1f, trackerSpawnRate);
             trackerResetTargetAfterMeeting = CustomOption.Create(202, "Tracker Reset Target After Meeting", false, trackerSpawnRate);
             trackerCanTrackCorpses = CustomOption.Create(203, "Tracker Can Track Corpses", true, trackerSpawnRate);
             trackerCorpsesTrackingCooldown = CustomOption.Create(204, "Corpses Tracking Cooldown", 30f, 5f, 120f, 5f, trackerCanTrackCorpses);
@@ -463,7 +471,13 @@ namespace TheOtherRoles {
             noVoteIsSelfVote = CustomOption.Create(5, "No Vote Is Self Vote", false, blockSkippingInEmergencyMeetings);
             hidePlayerNames = CustomOption.Create(6, "Hide Player Names", false);
             allowParallelMedBayScans = CustomOption.Create(7, "Allow Parallel MedBay Scans", false);
+
             dynamicMap = CustomOption.Create(8, "Play On A Random Map", false, null, false);
+            dynamicMapEnableSkeld = CustomOption.Create(501, "Enable Skeld Rotation", true, dynamicMap, false);
+            dynamicMapEnableMira = CustomOption.Create(502, "Enable Mira Rotation", true, dynamicMap, false);
+            dynamicMapEnablePolus = CustomOption.Create(503, "Enable Polus Rotation", true, dynamicMap, false);
+            dynamicMapEnableAirShip = CustomOption.Create(504, "Enable Airship Rotation", true, dynamicMap, false);
+            dynamicMapEnableDleks = CustomOption.Create(505, "Enable dlekS Rotation", false, dynamicMap, false);
 
             blockedRolePairings.Add((byte)RoleId.Vampire, new [] { (byte)RoleId.Warlock});
             blockedRolePairings.Add((byte)RoleId.Warlock, new [] { (byte)RoleId.Vampire});
index 580f705188bc31c1ccc4cc59729b8cedd578b85e..f312ba71156a7bbe4ac88d89cd9ac1be7fbbd159 100644 (file)
@@ -21,7 +21,7 @@ namespace TheOtherRoles
     public class TheOtherRolesPlugin : BasePlugin
     {
         public const string Id = "me.eisbison.theotherroles";
-        public const string VersionString = "3.4.0";
+        public const string VersionString = "3.4.1";
 
         public static System.Version Version = System.Version.Parse(VersionString);
         internal static BepInEx.Logging.ManualLogSource Logger;
@@ -37,6 +37,7 @@ namespace TheOtherRoles
         public static ConfigEntry<bool> GhostsSeeRoles { get; set; }
         public static ConfigEntry<bool> GhostsSeeVotes{ get; set; }
         public static ConfigEntry<bool> ShowRoleSummary { get; set; }
+        public static ConfigEntry<bool> ShowLighterDarker { get; set; }
         public static ConfigEntry<string> StreamerModeReplacementText { get; set; }
         public static ConfigEntry<string> StreamerModeReplacementColor { get; set; }
         public static ConfigEntry<string> Ip { get; set; }
@@ -64,6 +65,7 @@ namespace TheOtherRoles
             GhostsSeeRoles = Config.Bind("Custom", "Ghosts See Roles", true);
             GhostsSeeVotes = Config.Bind("Custom", "Ghosts See Votes", true);
             ShowRoleSummary = Config.Bind("Custom", "Show Role Summary", true);
+            ShowLighterDarker = Config.Bind("Custom", "Show Lighter / Darker", true);
             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");
index 94531fe7d0c811957ddc9e6651fc14217ede6858..2c69f53df08ade673d048aca88462cf313be92b0 100644 (file)
@@ -16,6 +16,7 @@ namespace TheOtherRoles{
         public static bool ghostsSeeVotes = true;
         public static bool showRoleSummary = true;
         public static bool allowParallelMedBayScans = false;
+        public static bool showLighterDarker = true;
 
         // Updating values
         public static int meetingsCount = 0;
@@ -38,6 +39,7 @@ public static void clearAndReloadMapOptions() {
             ghostsSeeTasks = TheOtherRolesPlugin.GhostsSeeTasks.Value;
             ghostsSeeVotes = TheOtherRolesPlugin.GhostsSeeVotes.Value;
             showRoleSummary = TheOtherRolesPlugin.ShowRoleSummary.Value;
+            showLighterDarker = TheOtherRolesPlugin.ShowLighterDarker.Value;
         }
     }
-} 
\ No newline at end of file
+}
\ No newline at end of file
index 512a6c1c2b37b19d2b547c9e7913e7646f682b72..87b9b5bc2ed57c6c6337170e5d052efb17fcc92e 100644 (file)
@@ -158,7 +158,7 @@ update to v{ver} is available</size>
                         }
                     }
                 }  else {
-                    announcement = $@"<size=150%>Version {ver}:</size>
+                    announcement = $@"<size=150%><color=#FC0303>THE OTHER ROLES</color> Version {ver}:</size>
 
 {announcement}";
                 }
index 2e50869aef8a080bfcc67cdec74e5ff35b079dc6..9f5a77bcfad8704e688f78710d395d0c20ac26fe 100644 (file)
@@ -19,6 +19,7 @@ namespace TheOtherRoles.Patches
             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),
             new SelectionBehaviour("Show Role Summary", () => MapOptions.showRoleSummary = TheOtherRolesPlugin.ShowRoleSummary.Value = !TheOtherRolesPlugin.ShowRoleSummary.Value, TheOtherRolesPlugin.ShowRoleSummary.Value),
+            new SelectionBehaviour("Show Lighter / Darker", () => MapOptions.showLighterDarker = TheOtherRolesPlugin.ShowLighterDarker.Value = !TheOtherRolesPlugin.ShowLighterDarker.Value, TheOtherRolesPlugin.ShowLighterDarker.Value),
         };
         
         private static GameObject popUp;
index 0f895fb95d21f1d60a2b2bab0834b1bb4cfc7c3c..5229a8123bd71f82226705a4ffca37095efd05ed 100644 (file)
@@ -158,18 +158,32 @@ namespace TheOtherRoles.Patches {
                             break;
                         }
                     }
-                }
 
-                if (CustomOptionHolder.dynamicMap.getBool()) {
-                    // 0 = Skeld
-                    // 1 = Mira HQ
-                    // 2 = Polus
-                    // 3 = Dleks - deactivated
-                    // 4 = Airship
-                    List<byte> possibleMaps = new List<byte>(){0, 1, 2, 4};
-                    PlayerControl.GameOptions.MapId = possibleMaps[TheOtherRoles.rnd.Next(possibleMaps.Count)];
+                    if (CustomOptionHolder.dynamicMap.getBool() && continueStart) {
+                        // 0 = Skeld
+                        // 1 = Mira HQ
+                        // 2 = Polus
+                        // 3 = Dleks - deactivated
+                        // 4 = Airship
+                        List<byte> possibleMaps = new List<byte>();
+                        if (CustomOptionHolder.dynamicMapEnableSkeld.getBool())
+                            possibleMaps.Add(0);
+                        if (CustomOptionHolder.dynamicMapEnableMira.getBool())
+                            possibleMaps.Add(1);
+                        if (CustomOptionHolder.dynamicMapEnablePolus.getBool())
+                            possibleMaps.Add(2);
+                        if (CustomOptionHolder.dynamicMapEnableDleks.getBool())
+                            possibleMaps.Add(3);
+                        if (CustomOptionHolder.dynamicMapEnableAirShip.getBool())
+                            possibleMaps.Add(4);
+                        byte chosenMapId  = possibleMaps[TheOtherRoles.rnd.Next(possibleMaps.Count)];
+
+                        MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.DynamicMapOption, Hazel.SendOption.Reliable, -1);
+                        writer.Write(chosenMapId);
+                        AmongUsClient.Instance.FinishRpcImmediately(writer);
+                        RPCProcedure.dynamicMapOption(chosenMapId);
+                    }
                 }
-
                 return continueStart;
             }
         }
index c9667ba29cd6a940e0ac8384e45ae6ef13053021..cbc9e8da43368065e510b02e0aeb57922c428778 100644 (file)
@@ -565,7 +565,6 @@ namespace TheOtherRoles.Patches {
                 BountyHunter.arrowUpdateTimer = 0f; // Force arrow to update
                 BountyHunter.bountyUpdateTimer = BountyHunter.bountyDuration;
                 var possibleTargets = new List<PlayerControl>();
-                if (Lovers.getPartner(BountyHunter.bountyHunter) != null) 
                 foreach (PlayerControl p in PlayerControl.AllPlayerControls) {
                     if (!p.Data.IsDead && !p.Data.Disconnected && p != p.Data.Role.IsImpostor && p != Spy.spy && (p != Mini.mini || Mini.isGrownUp()) && (Lovers.getPartner(BountyHunter.bountyHunter) == null || p != Lovers.getPartner(BountyHunter.bountyHunter))) possibleTargets.Add(p);
                 }
index cf672a533cc7b397065f2a9dd954706508cb40f4..c642d1c38e599b2135ba54340df4d415585827bf 100644 (file)
@@ -235,110 +235,75 @@ namespace TheOtherRoles.Patches {
         }
 
         private static void assignDependentRoles(RoleAssignmentData data) {
+            // Roles that prob have a dependent role
+            bool guesserFlag = CustomOptionHolder.guesserSpawnBothRate.getSelection() > 0 && CustomOptionHolder.guesserSpawnRate.getSelection() > 0;
+            bool sheriffFlag = CustomOptionHolder.deputySpawnRate.getSelection() > 0 && CustomOptionHolder.sheriffSpawnRate.getSelection() > 0;
+            if (!guesserFlag && !sheriffFlag) return; // assignDependentRoles is not needed
+
+            int crew = data.crewmates.Count < data.maxCrewmateRoles ? data.crewmates.Count : data.maxCrewmateRoles; // Max number of crew loops
+            int imp = data.impostors.Count < data.maxImpostorRoles ? data.impostors.Count : data.maxImpostorRoles; // Max number of imp loops
+            int crewSteps = crew / data.crewSettings.Keys.Count(); // Avarage crewvalues deducted after each loop
+            int impSteps = imp / data.impSettings.Keys.Count(); // Avarage impvalues deducted after each loop
+
+            // set to false if needed, otherwise we can skip the loop
+            bool isSheriff = !sheriffFlag; 
+            bool isGuesser = !guesserFlag;
+
+            bool isEvilGuesser = (rnd.Next(1, 101) <= CustomOptionHolder.guesserIsImpGuesserRate.getSelection() * 10);
+
+            // --- Simulate Crew & Imp ticket system ---
+            while (crew > 0 && (!isSheriff || (!isEvilGuesser && !isGuesser))) {
+                if (!isSheriff && rnd.Next(crewValues) < CustomOptionHolder.sheriffSpawnRate.getSelection()) isSheriff = true;
+                if (!isEvilGuesser && !isGuesser && rnd.Next(crewValues) < CustomOptionHolder.guesserSpawnRate.getSelection()) isGuesser = true;
+                crew--;
+                crewValues -= crewSteps;
+            }
+            while (imp > 0 && (isEvilGuesser && !isGuesser)) { 
+                if (rnd.Next(crewValues) < CustomOptionHolder.guesserSpawnRate.getSelection()) isGuesser = true;
+                imp--;
+                impValues -= impSteps;
+            }
 
-            int crew = data.crewmates.Count < data.maxCrewmateRoles ? data.crewmates.Count : data.maxCrewmateRoles;
-            int imp = data.impostors.Count < data.maxImpostorRoles ? data.impostors.Count : data.maxImpostorRoles;
-            int leftCrewRolesCount = crew - data.crewSettings.Where(x => x.Value != 0 && x.Value != 10).ToList().Count;
-            int leftImpRolesCount = imp - data.impSettings.Where(x => x.Value != 0 && x.Value != 10).ToList().Count;
-
-            // Other Guesser
-            if (CustomOptionHolder.guesserSpawnBothRate.getSelection() > 0) {
-                bool isEvilGuesser = (rnd.Next(1, 101) <= CustomOptionHolder.guesserIsImpGuesserRate.getSelection() * 10);
-                int guesserSpawnValues = isEvilGuesser ? impValues : crewValues;
-
-                if (Guesser.evilGuesser != null || Guesser.niceGuesser != null) {
-                    if (CustomOptionHolder.guesserSpawnBothRate.getSelection() == 10) { // Force both Guesser
-                        if (Guesser.niceGuesser == null && data.crewmates.Count > 0 && data.maxCrewmateRoles > 0) { // Other Guesser = Nice Guesser
-                            byte niceGuesser = setRoleToRandomPlayer((byte)RoleId.NiceGuesser, data.crewmates);
-                            data.crewmates.ToList().RemoveAll(x => x.PlayerId == niceGuesser);
-                            data.maxCrewmateRoles--;
-                            leftCrewRolesCount--;
-                        }
-                        else if (Guesser.evilGuesser == null && data.impostors.Count > 0 && data.maxImpostorRoles > 0) { // Other Guesser = Evil Guesser
-                            byte evilGuesser = setRoleToRandomPlayer((byte)RoleId.EvilGuesser, data.impostors);
-                            data.impostors.ToList().RemoveAll(x => x.PlayerId == evilGuesser);
-                            data.maxImpostorRoles--;
-                            leftImpRolesCount--;
-                        }
-                    }
-                    else if (Guesser.niceGuesser == null && data.crewmates.Count > 0 && data.maxCrewmateRoles > 0) {  // Dont force, add other guesser (nice) to pool
-                        data.crewSettings.Add((byte)RoleId.NiceGuesser, CustomOptionHolder.guesserSpawnBothRate.getSelection());
-                        crewValues += CustomOptionHolder.guesserSpawnBothRate.getSelection();
-                        leftCrewRolesCount--;
-                    }
-                    else if (Guesser.evilGuesser == null && data.impostors.Count > 0 && data.maxImpostorRoles > 0) { // Dont force, add other guesser (evil) to pool
-                        data.impSettings.Add((byte)RoleId.EvilGuesser, CustomOptionHolder.guesserSpawnBothRate.getSelection());
-                        impValues += CustomOptionHolder.guesserSpawnBothRate.getSelection();
-                        leftImpRolesCount--;
-                    }
-                }
-                else if ((CustomOptionHolder.guesserSpawnRate.getSelection() < 10 && rnd.Next(guesserSpawnValues + CustomOptionHolder.guesserSpawnRate.getSelection()) < CustomOptionHolder.guesserSpawnRate.getSelection()) 
-                    || (isEvilGuesser && leftImpRolesCount > 0) || 
-                    (!isEvilGuesser && leftCrewRolesCount > 0)) { // Guesser is < 100%, but won the lottery or there are roles left to assign
-                    if (isEvilGuesser && data.impostors.Count > 0 && data.maxImpostorRoles > 0) { // Add Evil Guesser
-                        byte evilGuesser = setRoleToRandomPlayer((byte)RoleId.EvilGuesser, data.impostors);
-                        data.impostors.ToList().RemoveAll(x => x.PlayerId == evilGuesser);
-                        data.maxImpostorRoles--;
-                        leftImpRolesCount--;
-                        if (CustomOptionHolder.guesserSpawnBothRate.getSelection() == 10 && data.crewmates.Count > 0 && data.maxCrewmateRoles > 0) { // Force Other Guesser (nice)
-                            byte niceGuesser = setRoleToRandomPlayer((byte)RoleId.NiceGuesser, data.crewmates);
-                            data.crewmates.ToList().RemoveAll(x => x.PlayerId == niceGuesser);
-                            data.maxCrewmateRoles--;
-                            leftCrewRolesCount--;
-                        }
-                        else if (CustomOptionHolder.guesserSpawnBothRate.getSelection() < 10) { // Dont force, add other guesser (nice) to pool
-                            data.crewSettings.Add((byte)RoleId.NiceGuesser, CustomOptionHolder.guesserSpawnBothRate.getSelection());
-                            crewValues += CustomOptionHolder.guesserSpawnBothRate.getSelection();
-                            leftCrewRolesCount--;
-                        }
-                    }
-                    else if (!isEvilGuesser && data.crewmates.Count > 0 && data.maxCrewmateRoles > 0) { // Add Nice Guesser
-                        byte niceGuesser = setRoleToRandomPlayer((byte)RoleId.NiceGuesser, data.crewmates);
-                        data.crewmates.ToList().RemoveAll(x => x.PlayerId == niceGuesser);
-                        data.maxCrewmateRoles--;
-                        leftCrewRolesCount--;
-                        if (CustomOptionHolder.guesserSpawnBothRate.getSelection() == 10 && data.impostors.Count > 0 && data.maxImpostorRoles > 0) { // Force Other Guesser (evil)
-                            byte evilGuesser = setRoleToRandomPlayer((byte)RoleId.EvilGuesser, data.impostors);
-                            data.impostors.ToList().RemoveAll(x => x.PlayerId == evilGuesser);
-                            data.maxImpostorRoles--;
-                            leftImpRolesCount--;
-                        }
-                        else if (CustomOptionHolder.guesserSpawnBothRate.getSelection() < 10) { // Dont force, add other guesser (evil) to pool
-                            data.impSettings.Add((byte)RoleId.EvilGuesser, CustomOptionHolder.guesserSpawnBothRate.getSelection());
-                            impValues += CustomOptionHolder.guesserSpawnBothRate.getSelection();
-                            leftImpRolesCount--;
-                        }
-                    }
-                }
+            // --- Assign Main Roles if they won the lottery ---
+            if (isSheriff && Sheriff.sheriff == null && data.crewmates.Count > 0 && data.maxCrewmateRoles > 0 && sheriffFlag) { // Set Sheriff cause he won the lottery
+                byte sheriff = setRoleToRandomPlayer((byte)RoleId.Sheriff, data.crewmates);
+                data.crewmates.ToList().RemoveAll(x => x.PlayerId == sheriff);
+                data.maxCrewmateRoles--;
+            }
+            if (!isEvilGuesser && isGuesser && Guesser.niceGuesser == null && data.crewmates.Count > 0 && data.maxCrewmateRoles > 0 && guesserFlag) { // Set Nice Guesser cause he won the lottery
+                byte niceGuesser = setRoleToRandomPlayer((byte)RoleId.NiceGuesser, data.crewmates);
+                data.crewmates.ToList().RemoveAll(x => x.PlayerId == niceGuesser);
+                data.maxCrewmateRoles--;
+            } else if (isEvilGuesser && isGuesser && Guesser.evilGuesser == null && data.impostors.Count > 0 && data.maxImpostorRoles > 0 && guesserFlag) { // Set Evil Guesser cause he won the lottery
+                byte evilGuesser = setRoleToRandomPlayer((byte)RoleId.EvilGuesser, data.impostors);
+                data.impostors.ToList().RemoveAll(x => x.PlayerId == evilGuesser);
+                data.maxImpostorRoles--;
             }
 
-            // Deputy
-            if (CustomOptionHolder.deputySpawnRate.getSelection() > 0 && data.crewmates.Count > 0 && data.maxCrewmateRoles > 0) {
-                if (Sheriff.sheriff != null) {
-                    if (CustomOptionHolder.deputySpawnRate.getSelection() == 10) { // Force Deputy
-                        byte deputy = setRoleToRandomPlayer((byte)RoleId.Deputy, data.crewmates);
-                        data.crewmates.ToList().RemoveAll(x => x.PlayerId == deputy);
-                        data.maxCrewmateRoles--;
-                    } else if (CustomOptionHolder.deputySpawnRate.getSelection() < 10) { // Dont force, add Deputy to pool
-                        data.crewSettings.Add((byte)RoleId.Deputy, CustomOptionHolder.deputySpawnRate.getSelection()); 
-                    }
-                } else if ((CustomOptionHolder.sheriffSpawnRate.getSelection() < 10 && rnd.Next(crewValues + CustomOptionHolder.sheriffSpawnRate.getSelection()) < CustomOptionHolder.sheriffSpawnRate.getSelection())
-                    || leftCrewRolesCount > 0) { // Sheriff is < 100%, but won the lottery or there are roles left to assign
-                    byte sheriff = setRoleToRandomPlayer((byte)RoleId.Sheriff, data.crewmates);
-                    data.crewmates.ToList().RemoveAll(x => x.PlayerId == sheriff);
+            // --- Assign Dependent Roles if main role exists ---
+            if (Sheriff.sheriff != null) { // Deputy
+                if (CustomOptionHolder.deputySpawnRate.getSelection() == 10 && data.crewmates.Count > 0 && data.maxCrewmateRoles > 0) { // Force Deputy
+                    byte deputy = setRoleToRandomPlayer((byte)RoleId.Deputy, data.crewmates);
+                    data.crewmates.ToList().RemoveAll(x => x.PlayerId == deputy);
+                    data.maxCrewmateRoles--;
+                } else if (CustomOptionHolder.deputySpawnRate.getSelection() < 10) // Dont force, add Deputy to the ticket system
+                    data.crewSettings.Add((byte)RoleId.Deputy, CustomOptionHolder.deputySpawnRate.getSelection());
+            }
+            if (!isEvilGuesser && Guesser.niceGuesser != null) { // Other Guesser (evil)
+                if (CustomOptionHolder.guesserSpawnBothRate.getSelection() == 10 && data.impostors.Count > 0 && data.maxImpostorRoles > 0) { // Force other guesser (evil)
+                    byte bothGuesser = setRoleToRandomPlayer((byte)RoleId.EvilGuesser, data.impostors);
+                    data.impostors.ToList().RemoveAll(x => x.PlayerId == bothGuesser);
+                    data.maxImpostorRoles--;
+                } else if (CustomOptionHolder.guesserSpawnBothRate.getSelection() < 10) // Dont force, add Guesser (evil) to the ticket system
+                    data.impSettings.Add((byte)RoleId.EvilGuesser, CustomOptionHolder.guesserSpawnBothRate.getSelection());
+            } else if (isEvilGuesser && Guesser.evilGuesser != null) { // ELSE other Guesser (nice)
+                if (CustomOptionHolder.guesserSpawnBothRate.getSelection() == 10 && data.crewmates.Count > 0 && data.maxCrewmateRoles > 0) { // Force other guesser (nice)
+                    byte bothGuesser = setRoleToRandomPlayer((byte)RoleId.NiceGuesser, data.crewmates);
+                    data.crewmates.ToList().RemoveAll(x => x.PlayerId == bothGuesser);
                     data.maxCrewmateRoles--;
-                    leftCrewRolesCount--;
-                    if (CustomOptionHolder.deputySpawnRate.getSelection() == 10 && data.crewmates.Count > 0 && data.maxCrewmateRoles > 0) { // Force Deputy
-                        byte deputy = setRoleToRandomPlayer((byte)RoleId.Deputy, data.crewmates);
-                        data.crewmates.ToList().RemoveAll(x => x.PlayerId == deputy);
-                        data.maxCrewmateRoles--;
-                        leftCrewRolesCount--;
-                    } else { // Dont force, add Deputy to pool
-                        data.crewSettings.Add((byte)RoleId.Deputy, CustomOptionHolder.deputySpawnRate.getSelection());
-                        crewValues += CustomOptionHolder.deputySpawnRate.getSelection();
-                        leftCrewRolesCount--;
-                    }
                 }
+                else if (CustomOptionHolder.guesserSpawnBothRate.getSelection() < 10) // Dont force, add Guesser (nice) to the ticket system
+                    data.crewSettings.Add((byte)RoleId.NiceGuesser, CustomOptionHolder.guesserSpawnBothRate.getSelection());
             }
         }
         private static void assignChanceRoles(RoleAssignmentData data) {
index 23fbcc42e09651638571063026babf25dca27c2e..896239a457c6a688924ad2f6ed645e6f2f858c21 100644 (file)
@@ -22,7 +22,8 @@ namespace TheOtherRoles.Patches {
             else if (player.Role.IsImpostor
                 || (Jackal.jackal != null && Jackal.jackal.PlayerId == player.PlayerId && Jackal.hasImpostorVision)
                 || (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
+                || (Spy.spy != null && Spy.spy.PlayerId == player.PlayerId && Spy.hasImpostorVision)
+                || (Jester.jester != null && Jester.jester.PlayerId == player.PlayerId && Jester.hasImpostorVision)) // Impostor, Jackal/Sidekick, Spy or Jester 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);
index 34243014b63edafb38bedd9e0c959f76ff2b8814..cb49551034fd4eee6ed48b33216261fadad2cd12 100644 (file)
@@ -196,9 +196,9 @@ namespace TheOtherRoles.Patches {
                             player.NameText.text += suffix;
             }
 
-            // Hacker and Detective
-            if (PlayerControl.LocalPlayer != null && !PlayerControl.LocalPlayer.Data.IsDead && (PlayerControl.LocalPlayer == Hacker.hacker || PlayerControl.LocalPlayer == Detective.detective || PlayerControl.LocalPlayer == Medium.medium)) {
-                if (MeetingHud.Instance != null) {
+            // Display lighter / darker color for all alive players
+            if (PlayerControl.LocalPlayer != null && !PlayerControl.LocalPlayer.Data.IsDead) {
+                if (MeetingHud.Instance != null && MapOptions.showLighterDarker) {
                     foreach (PlayerVoteArea player in MeetingHud.Instance.playerStates) {
                         var target = Helpers.playerById(player.TargetPlayerId);
                         if (target != null)  player.NameText.text += $" ({(Helpers.isLighterColor(target.Data.DefaultOutfit.ColorId) ? "L" : "D")})";
index 207a4ffa285e29b74bce33e857bf9690cfc1dfb0..5a020137480ac7a2830ab3726b110f3d539041e4 100644 (file)
@@ -72,6 +72,7 @@ namespace TheOtherRoles
         UncheckedMurderPlayer,
         UncheckedCmdReportDeadBody,
         UncheckedExilePlayer,
+        DynamicMapOption,
 
         // Role functionality
 
@@ -325,6 +326,10 @@ namespace TheOtherRoles
             if (target != null) target.Exiled();
         }
 
+        public static void dynamicMapOption(byte mapId) {
+            PlayerControl.GameOptions.MapId = mapId;
+        }
+
         // Role functionality
 
         public static void engineerFixLights() {
@@ -866,6 +871,10 @@ namespace TheOtherRoles
                     byte reportTarget = reader.ReadByte();
                     RPCProcedure.uncheckedCmdReportDeadBody(reportSource, reportTarget);
                     break;
+                case (byte)CustomRPC.DynamicMapOption:
+                    byte mapId = reader.ReadByte();
+                    RPCProcedure.dynamicMapOption(mapId);
+                    break;
 
                 // Role functionality
 
index da9785a8f38cf102f80a447e751570b6a7702843..298b52e3eefa2eb99d24c0d815a0b506146981b3 100644 (file)
@@ -68,11 +68,13 @@ namespace TheOtherRoles
 
             public static bool triggerJesterWin = false;
             public static bool canCallEmergency = true;
+            public static bool hasImpostorVision = false;
 
             public static void clearAndReload() {
                 jester = null;
                 triggerJesterWin = false;
                 canCallEmergency = CustomOptionHolder.jesterCanCallEmergency.getBool();
+                hasImpostorVision = CustomOptionHolder.jesterHasImpostorVision.getBool();
             }
         }
 
index aebc258d80b617700072926912a142f1c4cd247f..a7c3121d99eabd972e72ff2dc7fe96e3efd59d07 100644 (file)
@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
     <PropertyGroup>
         <TargetFramework>netstandard2.1</TargetFramework>
-        <Version>3.4.0</Version>
+        <Version>3.4.1</Version>
         <Description>TheOtherRoles</Description>
         <Authors>Eisbison</Authors>
     </PropertyGroup>