]> git.deb.at Git - rhonda/theotherroles.git/commitdiff
Add 2.1.0 changes
authorEisbison <eisbison.creator@gmail.com>
Thu, 8 Apr 2021 15:35:08 +0000 (17:35 +0200)
committerEisbison <eisbison.creator@gmail.com>
Thu, 8 Apr 2021 15:35:08 +0000 (17:35 +0200)
14 files changed:
README.md
Source Code/Buttons.cs
Source Code/CredentialsPatch.cs
Source Code/CustomOptions.cs
Source Code/IntroPatch.cs
Source Code/Main.cs
Source Code/MeetingPatch.cs
Source Code/PlayerControlPatch.cs
Source Code/RPC.cs
Source Code/RoleAssignmentPatch.cs
Source Code/RoleInfo.cs
Source Code/TheOtherRoles.cs
Source Code/TheOtherRoles.csproj
Source Code/UpdatePatch.cs

index 4f80d1f021d1646c20e51333e7be2a1a7ebcba43..690b6868b40016815f72d34dd05514ad7fdc4abe 100644 (file)
--- a/README.md
+++ b/README.md
@@ -38,14 +38,16 @@ Even more roles are coming soon :)
 - [Snitch](#snitch)\r
 - [Jackal](#jackal)\r
 - [Sidekick](#sidekick)\r
+- [Spy](#spy)\r
 \r
 The [Role Assignment](#role-assignment) sections explains how the roles are being distributed among the players.\r
 \r
 # Releases\r
 | Among Us - Version| Mod Version | Link |\r
 |----------|-------------|-----------------|\r
-| **2021.31.3s** | v2.0.1 | [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v2.0.1/TheOtherRoles.zip)\r
-| 2021.31.3s | v2.0.0 beta | [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v2.0.0/TheOtherRoles.zip)\r
+| 2021.3.31.3s| v2.1.0| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v2.1.0/TheOtherRoles.zip)\r
+| 2021.3.31.3s| v2.0.1 beta| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v2.0.1/TheOtherRoles.zip)\r
+| 2021.3.31.3s | v2.0.0 beta | [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v2.0.0/TheOtherRoles.zip)\r
 | 2021.3.5s | v1.8.2 | [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v1.8.2/TheOtherRoles.zip)\r
 | 2021.3.5s | v1.8.1 | [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v1.8.1/TheOtherRoles.zip)\r
 | 2021.3.5s | v1.8 | [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v1.8/TheOtherRoles.zip)\r
@@ -61,6 +63,11 @@ The [Role Assignment](#role-assignment) sections explains how the roles are bein
 <details>\r
   <summary>Click to show the Changelog</summary>\r
 \r
+**Version 2.1.0**\r
+- **New Role:** [Spy](#spy)\r
+- **Eraser:** The Eraser can now also remove the role of other Impostors. This enables him to reveal the Spy, but might result in removing the special ability of his partner.\r
+- **Camouflager:** The Child age/size will now also be hidden, to allow the Child Impostor to kill during camouflage\r
+\r
 **Hotfix 2.0.1**\r
 - Fixed a bug where camouflaged players would get stuck on ladders/platforms on the airship\r
 - Introduced a one second cooldown after the Morphling sampled another player\r
@@ -152,7 +159,7 @@ syncs your game options automatically.
 If you have problems with the AmongUsModUpdater, make sure To [contact us](https://discord.gg/csa3pHYdPU).\r
 \r
 ## Windows Manual Installation\r
-1. Download and unzip the newest [release](https://github.com/Eisbison/TheOtherRoles/releases/download/v2.0.1/TheOtherRoles.zip)\r
+1. Download and unzip the newest [release](https://github.com/Eisbison/TheOtherRoles/releases/download/v2.1.0/TheOtherRoles.zip)\r
 2. Find the folder of your game, for steams players you can right click in steam, on the game, a menu will appear proposing you to go to the folders.\r
 3. Make a copy of your game, it's not obligatory but advise, put it where you want.\r
 4. Drag or extract the files from the zip into your game, at the .exe level.\r
@@ -164,7 +171,7 @@ Not working? You might want to install the dependency [vc_redist](https://aka.ms
 \r
 **Linux Manual**\r
 1. Install Among Us via steam\r
-2. Download newest [release](https://github.com/Eisbison/TheOtherRoles/releases/download/v2.0.1/TheOtherRoles.zip) and extract it to ~/.steam/steam/steamapps/common/Among Us\r
+2. Download newest [release](https://github.com/Eisbison/TheOtherRoles/releases/download/v2.1.0/TheOtherRoles.zip) and extract it to ~/.steam/steam/steamapps/common/Among Us\r
 3. Enable winhttp.dll via the proton winecfg (https://bepinex.github.io/bepinex_docs/master/articles/advanced/steam_interop.html#protonwine)\r
 4. Launch the game via Steam\r
 \r
@@ -255,7 +262,7 @@ The camouflage mode lasts for 10s and while it is active, all player names/pets/
 are hidden and all players have the same color.\\r
 \\r
 **NOTE**\r
-- The Child (and Morphling when copying the child) remains small and show its age.\r
+- The Child will look like all the other players\r
 - The color of the footprints turns gray (also the ones that were already on the ground).\r
 - The Spy sees gray icons on the admin table\r
 - The shield is not visible anymore\r
@@ -289,7 +296,7 @@ If a victim is near a garlic, the "Bite Button" turns into the default "Kill But
 \r
 ## Eraser\r
 ### **Team: Impostors**\r
-The Eraser is an Impostor that can erase the role of every player that is not an Impostor.\\r
+The Eraser is an Impostor that can erase the role of every player.\\r
 The targeted players will lose their role after the meeting right before a player is exiled.\\r
 After every erase, the cooldown increases by 10 seconds.\\r
 The erase will be performed, even if the Eraser or his target die before the next meeting.\\r
@@ -300,6 +307,7 @@ The erase will be performed, even if the Eraser or his target die before the nex
 - Erasing a Jackal that has a Sidekick, triggers the Sidekick promotion if it's activated in the settings\r
 - As the erasing is being triggered before the eject of a player, erasing and voting out a Lover in the same round, would result in the\r
 ex lover surviving as the partnership was erased before. Also a Jester win would not happen, as the erase will be triggered before.\r
+- The Eraser can erase the role of other Impostors to reveal if they are a real Impostor or a Spy. When erasing a real Impostor, the Impostor loses its special ability.\r
 \r
 ### Game Options\r
 | Name | Description |\r
@@ -651,6 +659,24 @@ Upon the death of the Jackal (depending on the options), he might get promoted t
 | Sidekick can use vents | Yes/No |\r
 -----------------------\r
 \r
+## Spy\r
+### **Team: Crewmates**\r
+The Spy is a Crewmate, which has no special abilities.\\r
+The Spy looks like an additional Impostor to the Impostors, they can't tell the difference.\\r
+There are two possibilities (depending on the set options):\r
+- The Impostors can't kill the Spy (because otherwise their kill button would reveal, who the Spy is)\r
+- The Impostors can kill the Spy but they can also kill their Impostor partner (if they mistake another Impostor for the Spy)\r
+You can set whether the Sheriff can kill the Spy or not (in order to keep the lie alive).\r
+\r
+### Game Options\r
+| Name | Description\r
+|----------|:-------------:|\r
+| Spy Spawn Chance |\r
+| Spy Can Die To Sheriff | \r
+| Impostors Can Kill Anyone If There Is A Spy | This allows the Impostors to kill both the Spy and their Impostor partners\r
+-----------------------\r
+\r
+\r
 # Source code\r
 It's bad I know, this is a side project and my second week of modding. So there are no best practices around here.\r
 You can use parts of the codes but don't copy paste the whole thing. Make sure you give credits to the other developers, because some parts of the code are based on theirs.\r
index a435c393abae2816b93ef3357bc584aa7a5dbc96..11f5b26e16d5bb8cf107af4e1ad71bcfda999a46 100644 (file)
@@ -154,8 +154,8 @@ namespace TheOtherRoles
                     if ((Sheriff.currentTarget.IDOFAMCIJKE.CIDDOFDJHJH && (Sheriff.currentTarget != Child.child || Child.isGrownUp())) || 
                         Sheriff.currentTarget == Jackal.jackal || 
                         Sheriff.currentTarget == Sidekick.sidekick || 
-                        (Sheriff.jesterCanDieToSheriff && Jester.jester != null && Jester.jester == Sheriff.currentTarget))
-                        {
+                        (Sheriff.spyCanDieToSheriff && Spy.spy != null && Spy.spy == Sheriff.currentTarget) ||
+                        (Sheriff.jesterCanDieToSheriff && Jester.jester != null && Jester.jester == Sheriff.currentTarget)) {
                         targetId = Sheriff.currentTarget.PlayerId;
                     }
                     else {
index 3c24d598df32aa5164c4795e7735573d06ca9e91..566a4c1348a1d43e92b31af3a0fc0daf7783e30e 100644 (file)
@@ -15,7 +15,7 @@ namespace TheOtherRoles
         {
             static void Postfix(VersionShower __instance) {
                 string spacer = new String('\n', 21);
-                string fullCredentials = "[FCCE03FF]TheOtherRoles[] v2.0.1 beta:\n- Modded by [FCCE03FF]Eisbison[] and [FFEB91FF]Thunderstorm584[]\n- Balanced with [FFEB91FF]Dhalucard[]\n- Button design by [FFEB91FF]Bavari[]";
+                string fullCredentials = "[FCCE03FF]TheOtherRoles[] v2.1.0:\n- Modded by [FCCE03FF]Eisbison[] and [FFEB91FF]Thunderstorm584[]\n- Balanced with [FFEB91FF]Dhalucard[]\n- Button design by [FFEB91FF]Bavari[]";
                 if (__instance.text.Text.Contains(spacer))
                     __instance.text.Text += "\n" + fullCredentials;
                 else
index b8a26f827030a71de54463397dd58896a7eee527..fa86c9089d7df78818727cc392dbc0fd84818faa 100644 (file)
@@ -20,12 +20,16 @@ namespace TheOtherRoles {
         public static CustomOption presetSelection, crewmateRolesCount, impostorRolesCount;
         public static CustomOption mafiaSpawnRate, morphlingSpawnRate, camouflagerSpawnRate, vampireSpawnRate, eraserSpawnRate;
         public static CustomOption childSpawnRate, loversSpawnRate, jesterSpawnRate;
-        public static CustomOption shifterSpawnRate, mayorSpawnRate, engineerSpawnRate, sheriffSpawnRate, lighterSpawnRate, detectiveSpawnRate, timeMasterSpawnRate, medicSpawnRate, swapperSpawnRate, seerSpawnRate, hackerSpawnRate, trackerSpawnRate, snitchSpawnRate, jackalSpawnRate;
+        public static CustomOption shifterSpawnRate, mayorSpawnRate, engineerSpawnRate, sheriffSpawnRate, lighterSpawnRate, detectiveSpawnRate, timeMasterSpawnRate, medicSpawnRate, swapperSpawnRate, seerSpawnRate, hackerSpawnRate, trackerSpawnRate, snitchSpawnRate, jackalSpawnRate, spySpawnRate;
         public static CustomOption maxNumberOfMeetings;
         public static CustomOption janitorCooldown, morphlingCooldown, camouflagerCooldown, vampireKillDelay, vampireCooldown, vampireCanKillNearGarlics, eraserCooldown;
         public static CustomOption childGrowingUpDuration, loversImpLoverRate, loversBothDie;
-        public static CustomOption sheriffCooldown, jesterCanDieToSheriff, lighterModeLightsOnVision, lighterModeLightsOffVision, lighterCooldown, lighterDuration, detectiveAnonymousFootprints, detectiveFootprintIntervall, detectiveFootprintDuration, detectiveReportNameDuration, detectiveReportColorDuration, timeMasterCooldown, timeMasterRewindTime, medicShowShielded, medicShowAttemptToShielded, seerMode, seerSoulDuration, hackerCooldown, hackerHackeringDuration, hackerOnlyColorType, trackerUpdateIntervall, snitchLeftTasksForImpostors, jackalKillCooldown, jackalCreateSidekickCooldown, jackalCanUseVents, jackalCanCreateSidekick, sidekickPromotesToJackal, sidekickCanKill, sidekickCanUseVents, jackalPromotedFromSidekickCanCreateSidekick, jackalCanCreateSidekickFromImpostor;
-    
+        public static CustomOption sheriffCooldown, jesterCanDieToSheriff, lighterModeLightsOnVision, lighterModeLightsOffVision, lighterCooldown,
+        lighterDuration, detectiveAnonymousFootprints, detectiveFootprintIntervall, detectiveFootprintDuration, detectiveReportNameDuration, detectiveReportColorDuration,
+        timeMasterCooldown, timeMasterRewindTime, medicShowShielded, medicShowAttemptToShielded, seerMode, seerSoulDuration, hackerCooldown, hackerHackeringDuration, hackerOnlyColorType,
+        trackerUpdateIntervall, snitchLeftTasksForImpostors, jackalKillCooldown, jackalCreateSidekickCooldown, jackalCanUseVents, jackalCanCreateSidekick, sidekickPromotesToJackal, sidekickCanKill,
+        sidekickCanUseVents, jackalPromotedFromSidekickCanCreateSidekick, jackalCanCreateSidekickFromImpostor, spyCanDieToSheriff, spyImpostorsCanKillAnyone;
+
         public static string cs(Color c, string s) {
             return string.Format("[{0:X2}{1:X2}{2:X2}{3:X2}]{4}[]", ToByte(c.r), ToByte(c.g), ToByte(c.b), ToByte(c.a), s);
         }
@@ -64,6 +68,7 @@ namespace TheOtherRoles {
             trackerSpawnRate = CustomOption.Create(200, cs(Tracker.color, "Tracker"), rates);
             snitchSpawnRate = CustomOption.Create(210, cs(Snitch.color, "Snitch"), rates);
             jackalSpawnRate = CustomOption.Create(220, cs(Jackal.color, "Jackal"), rates);
+            spySpawnRate = CustomOption.Create(240, cs(Spy.color, "Spy"), rates);
 
             // Map settings
             maxNumberOfMeetings = CustomOption.Create(3, "Number Of Meetings (excluding Mayor meeting)", 10, 0, 15, 1);
@@ -105,13 +110,15 @@ namespace TheOtherRoles {
             snitchLeftTasksForImpostors = CustomOption.Create(211, "Task Count Where Impostors See Snitch", 1f, 0f, 5f, 1f);
             jackalKillCooldown = CustomOption.Create(221, "Jackal/Sidekick Kill Cooldown", 30f, 10f, 60f, 2.5f);
             jackalCreateSidekickCooldown = CustomOption.Create(222, "Jackal Create Sidekick Cooldown", 30f, 10f, 60f, 2.5f);
-            jackalCanUseVents = CustomOption.Create(223, "Jackal can use vents", true);
-            jackalCanCreateSidekick = CustomOption.Create(224, "Jackal can create a sidekick", false);
-            sidekickPromotesToJackal = CustomOption.Create(225, "Sidekick gets promoted to Jackal on Jackal death", false);
-            sidekickCanKill = CustomOption.Create(226, "Sidekick can kill", false);
-            sidekickCanUseVents = CustomOption.Create(227, "Sidekick can use vents", true);
-            jackalPromotedFromSidekickCanCreateSidekick = CustomOption.Create(228, "Jackals promoted from Sidekick can create a Sidekick", true);
-            jackalCanCreateSidekickFromImpostor = CustomOption.Create(229, "Jackals can make an Impostor to his Sidekick", true);
+            jackalCanUseVents = CustomOption.Create(223, "Jackal Can Use Vents", true);
+            jackalCanCreateSidekick = CustomOption.Create(224, "Jackal Can Create A Sidekick", false);
+            sidekickPromotesToJackal = CustomOption.Create(225, "Sidekick Gets Promoted To Jackal On Jackal Death", false);
+            sidekickCanKill = CustomOption.Create(226, "Sidekick Can Kill", false);
+            sidekickCanUseVents = CustomOption.Create(227, "Sidekick Can Use Vents", true);
+            jackalPromotedFromSidekickCanCreateSidekick = CustomOption.Create(228, "Jackals Promoted From Sidekick Can Create A Sidekick", true);
+            jackalCanCreateSidekickFromImpostor = CustomOption.Create(229, "Jackals Can Make An Impostor To His Sidekick", true);
+            spyCanDieToSheriff = CustomOption.Create(241, "Spy Can Die To Sheriff", false);
+            spyImpostorsCanKillAnyone = CustomOption.Create(242, "Impostors Can Kill Anyone If There Is A Spy", true);
         }
     }
 
@@ -324,8 +331,8 @@ namespace TheOtherRoles {
             var hudString = sb.ToString();
 
             int defaultSettingsLines = 19;
-            int roleSettingsLines = 19 + 25;
-            int detailedSettingsLines = 19 + 25 + 25;
+            int roleSettingsLines = 19 + 26;
+            int detailedSettingsLines = 19 + 26 + 25;
             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 => (detailedSettingsLines -= (c == '\n' ? 1 : 0)) > 0).Count();
index 26cb872c2cd09c677bf90e6efb5c1ea8df4345f3..6e262bb17f25825468630824b2a3ccb47605d814 100644 (file)
@@ -3,6 +3,7 @@ using System;
 using static TheOtherRoles.TheOtherRoles;
 using UnityEngine;
 using System.Collections.Generic;
+using System.Linq;
 
 namespace TheOtherRoles
 {
@@ -22,6 +23,17 @@ namespace TheOtherRoles
                 jackalTeam.Add(PlayerControl.LocalPlayer);
                 __instance.yourTeam = jackalTeam;
             }
+
+            // Add the Spy to the Impostor team (for the Impostors)
+            if (Spy.spy != null && PlayerControl.LocalPlayer.IDOFAMCIJKE.CIDDOFDJHJH) {
+                List<PlayerControl> players = PlayerControl.AllPlayerControls.ToArray().ToList().OrderBy(x => Guid.NewGuid()).ToList();
+                var fakeImpostorTeam = new Il2CppSystem.Collections.Generic.List<PlayerControl>();
+                foreach (PlayerControl p in players) {
+                    if (p == Spy.spy || p.IDOFAMCIJKE.CIDDOFDJHJH)
+                        fakeImpostorTeam.Add(p);
+                }
+                __instance.yourTeam = fakeImpostorTeam;
+            }
         }
 
         // Intro display role
index ea3310a8112de33e19ace404d9a812a12d5bdd20..010da71cef6ee8bafb5a8e24fc2fd468b2af5348 100644 (file)
@@ -15,7 +15,7 @@ using static TheOtherRoles.TheOtherRoles;
 
 namespace TheOtherRoles
 {
-    [BepInPlugin(Id, "The Other Roles", "2.0.1")]
+    [BepInPlugin(Id, "The Other Roles", "2.1.0")]
     [BepInProcess("Among Us.exe")]
     public class TheOtherRolesPlugin : BasePlugin
     {
index fad5f2e6a94deef027def6a337737a0a2f317360..1d08271c8aac3486fb61223427e1b54e712e7916 100644 (file)
@@ -433,6 +433,8 @@ namespace TheOtherRoles
                         __result = ExileController.Instance.KLHCDCKJHKC.HGGCLJHCDBM + " was The Jackal.";
                     else if(Sidekick.sidekick != null && ExileController.Instance.KLHCDCKJHKC.GPBBCHGPABL.PlayerId == Sidekick.sidekick.PlayerId)
                         __result = ExileController.Instance.KLHCDCKJHKC.HGGCLJHCDBM + " was The Sidekick.";
+                    else if(Spy.spy != null && ExileController.Instance.KLHCDCKJHKC.GPBBCHGPABL.PlayerId == Spy.spy.PlayerId)
+                        __result = ExileController.Instance.KLHCDCKJHKC.HGGCLJHCDBM + " was The Spy.";
                     else
                         __result = ExileController.Instance.KLHCDCKJHKC.HGGCLJHCDBM + " was not The Impostor.";
                 }
index 4c20f0c87f61f5f7fc6dfd8073714e91d6292e68..5e8aed7ca0084d1a6f264c0b9cceab6166f1194a 100644 (file)
@@ -116,7 +116,18 @@ namespace TheOtherRoles {
 
         static void vampireSetTarget() {
             if (Vampire.vampire == null || Vampire.vampire != PlayerControl.LocalPlayer) return;
-                   PlayerControl target = setTarget(true, true);
+
+                   PlayerControl target = null;
+            if (Spy.spy != null) {
+                if (Spy.impostorsCanKillAnyone) {
+                    target = setTarget(false, true);
+                } else {
+                    target = setTarget(true, true, new List<PlayerControl>() { Spy.spy });
+                }
+            } else {
+                target = setTarget(true, true);
+            }
+
             bool targetNearGarlic = false;
             if (target != null) {
                 foreach (Garlic garlic in Garlic.garlics) {
@@ -150,7 +161,7 @@ namespace TheOtherRoles {
 
         static void eraserSetTarget() {
             if (Eraser.eraser == null || Eraser.eraser != PlayerControl.LocalPlayer) return;
-            Eraser.currentTarget = setTarget(true);
+            Eraser.currentTarget = setTarget();
         }
 
         static void engineerUpdate() {
@@ -170,6 +181,26 @@ namespace TheOtherRoles {
             }
         }
 
+        static void impostorSetTarget() {
+            if (!PlayerControl.LocalPlayer.IDOFAMCIJKE.CIDDOFDJHJH ||!PlayerControl.LocalPlayer.AMDJMEEHNIG || PlayerControl.LocalPlayer.IDOFAMCIJKE.FGNJJFABIHJ) { // !isImpostor || !canMove || isDead
+                HudManager.CMJOLNCMAPD.KillButton.SetTarget(null);
+                return;
+            }
+            
+            PlayerControl target = null; 
+            if (Spy.spy != null) {
+                if (Spy.impostorsCanKillAnyone) {
+                    target = setTarget(false, true);
+                } else {
+                    target = setTarget(true, true, new List<PlayerControl>() { Spy.spy });
+                }
+            } else {
+                target = setTarget(true, true);
+            }
+
+            HudManager.CMJOLNCMAPD.KillButton.SetTarget(target);
+        }
+
         static void trackerUpdate() {
             if (Tracker.arrow?.arrow == null) return;
 
@@ -202,7 +233,7 @@ namespace TheOtherRoles {
         }
 
         public static void playerSizeUpdate(PlayerControl p) {
-            if (Child.child == null) return;
+            if (Child.child == null  || Camouflager.camouflageTimer > 0f) return;
 
             float growingProgress = Child.growingProgress();
             float scale = growingProgress * 0.35f + 0.35f;
@@ -256,6 +287,8 @@ namespace TheOtherRoles {
                 jackalSetTarget();
                 // Sidekick
                 sidekickSetTarget();
+                // Impostor
+                impostorSetTarget();
             } 
         }
     }
index fb5bf8519452e7129777e52bf97c134fd4de4160..3717b6705016c15727614676fd356d8578a7cd8b 100644 (file)
@@ -44,7 +44,8 @@ namespace TheOtherRoles
         Snitch,
         Jackal,
         Sidekick,
-        Eraser
+        Eraser,
+        Spy
     }
 
     enum CustomRPC
@@ -195,6 +196,9 @@ namespace TheOtherRoles
                     case RoleId.Eraser:
                         Eraser.eraser = player;
                         break;
+                    case RoleId.Spy:
+                        Spy.spy = player;
+                        break;
                     }
                 }
         }
@@ -352,7 +356,9 @@ namespace TheOtherRoles
                 Tracker.tracker = oldShifter;
             } else if (Snitch.snitch != null && Snitch.snitch == player) {
                 Snitch.snitch = oldShifter;
-            }else { // Crewmate
+            } else if (Spy.spy != null && Spy.spy == player) {
+                Spy.spy = oldShifter;
+            } else { // Crewmate
             }
             
             // Set cooldowns to max for both players
@@ -495,6 +501,7 @@ namespace TheOtherRoles
             if (player == Tracker.tracker) Tracker.clearAndReload();
             if (player == Snitch.snitch) Snitch.clearAndReload();
             if (player == Swapper.swapper) Swapper.clearAndReload();
+            if (player == Spy.spy) Spy.clearAndReload();
 
             // Impostor roles
             if (player == Morphling.morphling) Morphling.clearAndReload();
index 04bb8b3c858ad56556237e9c7db637a4a0ccda08..fb3e3586414486eaf3e54de42d667875d962149d 100644 (file)
@@ -72,6 +72,7 @@ namespace TheOtherRoles
             crewSettings.Add((byte)RoleId.Tracker, CustomOptionHolder.trackerSpawnRate.getSelection());
             crewSettings.Add((byte)RoleId.Snitch, CustomOptionHolder.snitchSpawnRate.getSelection());
             crewSettings.Add((byte)RoleId.Jackal, CustomOptionHolder.jackalSpawnRate.getSelection());
+            crewSettings.Add((byte)RoleId.Spy, CustomOptionHolder.spySpawnRate.getSelection());
 
             // Set special roles
             if (impostors.Count >= 3 && maxImpostorRoles >= 3 && (rnd.Next(1, 101) <= CustomOptionHolder.mafiaSpawnRate.getSelection() * 10)) {
index 0fee9f8f360da82178c1b0b8dbedbdd4fb88215e..bfb8a829744bebe9492576cb0251eb22654387c3 100644 (file)
@@ -169,7 +169,7 @@ namespace TheOtherRoles
             if (Jackal.jackal != null && p == Jackal.jackal) {
                 infos.Add(new RoleInfo("Jackal",
                 Jackal.color,
-                "Kill all Crewmates and [FF1919FF]Impostors[FFFFFFFF] to win",
+                "Kill all Crewmates and [FF1919FF]Impostors[] to win",
                 "Kill everyone"));                
             }
             if (Sidekick.sidekick != null && p == Sidekick.sidekick) {
@@ -184,7 +184,12 @@ namespace TheOtherRoles
                 "You are in [FC03BEFF]Love[]",
                 "You are in love"));
             }
-
+            if (Spy.spy != null && p == Spy.spy) {
+                infos.Add(new RoleInfo("Spy",
+                Spy.color,
+                "Confuse the [FF1919FF]Impostors[]",
+                "Confuse the Impostors"));
+            }
             if (infos.Count == 0 && p.IDOFAMCIJKE.CIDDOFDJHJH) { // Just Impostor
                 infos.Add(new RoleInfo("Impostor",
                 Palette.LDCHDOFJPGH,
index fe2f64960e3db60630d0987e220c60234dfd2de0..bd83ed4aa87946b239b2443fa5fbb19db18fe538 100644 (file)
@@ -46,6 +46,7 @@ namespace TheOtherRoles
             Jackal.clearAndReload();
             Sidekick.clearAndReload();
             Eraser.clearAndReload();
+            Spy.clearAndReload();
         }
 
         public static class Jester {
@@ -131,6 +132,7 @@ namespace TheOtherRoles
 
             public static float cooldown = 30f;
             public static bool jesterCanDieToSheriff = false;
+            public static bool spyCanDieToSheriff = false;
 
             public static PlayerControl currentTarget;
 
@@ -139,6 +141,7 @@ namespace TheOtherRoles
                 currentTarget = null;
                 cooldown = CustomOptionHolder.sheriffCooldown.getFloat();
                 jesterCanDieToSheriff = CustomOptionHolder.jesterCanDieToSheriff.getBool();
+                spyCanDieToSheriff = CustomOptionHolder.spyCanDieToSheriff.getBool();
             }
         }
 
@@ -670,4 +673,16 @@ namespace TheOtherRoles
             cooldown = CustomOptionHolder.eraserCooldown.getFloat();
         }
     }
+
+    public static class Spy {
+        public static PlayerControl spy;
+        public static Color color = Palette.LDCHDOFJPGH;
+
+        public static bool impostorsCanKillAnyone = true;
+
+        public static void clearAndReload() {
+            spy = null;
+            impostorsCanKillAnyone = CustomOptionHolder.spyImpostorsCanKillAnyone.getBool();
+        }
+    }
 }
\ No newline at end of file
index a13b5b3c2a012613ee1bcadec5a8596a6207c8ee..fe287ca12d5e21c3909e306f2f07e88ae6c0ddb3 100644 (file)
@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
     <PropertyGroup>
         <TargetFramework>netstandard2.1</TargetFramework>
-        <Version>2.0.1</Version>
+        <Version>2.1.0</Version>
 
         <Description>TheOtherRoles</Description>
         <Authors>Eisbison</Authors>
index c928765b51ee95614e5abbd608a45196c2cf127d..3c9664ee01281cffcd7dd4b096a0b94c9d73426c 100644 (file)
@@ -104,6 +104,9 @@ namespace TheOtherRoles
                     setPlayerNameColor(Jackal.fakeSidekick, Jackal.color);
                 }
             }
+            else if (Spy.spy != null && Spy.spy == PlayerControl.LocalPlayer) {
+                setPlayerNameColor(Spy.spy, Spy.color);
+            }
             
             // No else if here, as a Lover of team Jackal needs the colors
             if (Sidekick.sidekick != null && Sidekick.sidekick == PlayerControl.LocalPlayer) {
@@ -114,6 +117,11 @@ namespace TheOtherRoles
                 }
             }
 
+            // No else if here, as the Impostors need the Spy name to be colored
+            if (Spy.spy != null && PlayerControl.LocalPlayer.IDOFAMCIJKE.CIDDOFDJHJH) {
+                setPlayerNameColor(Spy.spy, Spy.color);
+            }
+
             // Crewmate roles with no changes: Child
             // Impostor roles with no changes: Morphling, Camouflager, Vampire, Godfather, Eraser, Janitor and Mafioso
         }
@@ -266,7 +274,7 @@ namespace TheOtherRoles
         }
 
         public static void childUpdate() {
-            if (Child.child == null) return;
+            if (Child.child == null || Camouflager.camouflageTimer > 0f) return;
                 
             float growingProgress = Child.growingProgress();
             float scale = growingProgress * 0.35f + 0.35f;