]> git.deb.at Git - rhonda/theotherroles.git/commitdiff
v3.2.3
authorEisbison <eisbison.creator@gmail.com>
Mon, 29 Nov 2021 18:38:56 +0000 (19:38 +0100)
committerEisbison <eisbison.creator@gmail.com>
Mon, 29 Nov 2021 18:38:56 +0000 (19:38 +0100)
README.md
TheOtherRoles/Buttons.cs
TheOtherRoles/Helpers.cs
TheOtherRoles/Main.cs
TheOtherRoles/Patches/ExileControllerPatch.cs
TheOtherRoles/Patches/MeetingPatch.cs
TheOtherRoles/Patches/PlayerControlPatch.cs
TheOtherRoles/Patches/UpdatePatch.cs
TheOtherRoles/RPC.cs
TheOtherRoles/TheOtherRoles.cs
TheOtherRoles/TheOtherRoles.csproj

index 41c62c7c55f5eb0818b05d5ff20ea9dec8c20913..41e4b300317ee0b6aeec63883687be902a46653d 100644 (file)
--- a/README.md
+++ b/README.md
@@ -38,6 +38,7 @@ The [Role Assignment](#role-assignment) sections explains how the roles are bein
 # Releases
 | Among Us - Version| Mod Version | Link |
 |----------|-------------|-----------------|
+| 2021.11.9.5s| v3.2.3| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v3.2.3/TheOtherRoles.zip)
 | 2021.11.9.5s| v3.2.2| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v3.2.2/TheOtherRoles.zip)
 | 2021.11.9.5s| v3.2.1| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v3.2.1/TheOtherRoles.zip)
 | 2021.11.9.5s| v3.2.0| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v3.2.0/TheOtherRoles.zip)
@@ -86,12 +87,19 @@ The [Role Assignment](#role-assignment) sections explains how the roles are bein
 <details>
   <summary>Click to show the Changelog</summary>
 
+**Version 3.2.3**
+- Fixed a bug where the role of a dead client was visible to the Pursuer
+- Fixed a bug where the Morphling changed their color when killing players
+- Fixed a bug where voting the Lover partner of a Lover Witch did not safe the spellbound players
+- Fixed a bug where the Vampire would teleport to the bitten player in some cases
+- When the Lawyer dies, the client doesn't have the client mark (§) anymore, making the client aware of the fact that the Lawyer can't steal the win anymore (only relevant if the "Client Knows" option is on)
+
 **Version 3.2.2**
 - Add new option "Play On A Random Map" created by [Alex2911](https://github.com/Alex2911)
 - Add Witch option "Voting The Witch Saves All The Targets"
 - Add Lawyer option "Lawyer Knows Target Role"
 - We changed the win conditions of the [Lawyer](#lawyer), to make it more viable
-- Bug fix: The Medium now shows the roles of players in the rigth format
+- Bug fix: The Medium now shows the roles of players in the right format
 - The name and the role of all winners is now being displayed on the end screen
 - We changed the way settings are being shared among the players (which caused some people to be unable to join the lobby). This might resolve the problem or make it even worse... we'll see.
 
index 4beb5862930238e4bb0a617f8725e48695fcf392..e36c52656a92a1059cbcf2d1514729ae000baa62 100644 (file)
@@ -197,8 +197,9 @@ namespace TheOtherRoles
                         MessageWriter killWriter = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.UncheckedMurderPlayer, Hazel.SendOption.Reliable, -1);
                         killWriter.Write(Sheriff.sheriff.Data.PlayerId);
                         killWriter.Write(targetId);
+                        killWriter.Write(byte.MaxValue);
                         AmongUsClient.Instance.FinishRpcImmediately(killWriter);
-                        RPCProcedure.uncheckedMurderPlayer(Sheriff.sheriff.Data.PlayerId, targetId);
+                        RPCProcedure.uncheckedMurderPlayer(Sheriff.sheriff.Data.PlayerId, targetId, Byte.MaxValue);
                     }
 
                     sheriffKillButton.Timer = sheriffKillButton.MaxTimer;
@@ -406,8 +407,9 @@ namespace TheOtherRoles
                             MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.UncheckedMurderPlayer, Hazel.SendOption.Reliable, -1);
                             writer.Write(Vampire.vampire.PlayerId);
                             writer.Write(Vampire.currentTarget.PlayerId);
+                            writer.Write(Byte.MaxValue);
                             AmongUsClient.Instance.FinishRpcImmediately(writer);
-                            RPCProcedure.uncheckedMurderPlayer(Vampire.vampire.PlayerId, Vampire.currentTarget.PlayerId);
+                            RPCProcedure.uncheckedMurderPlayer(Vampire.vampire.PlayerId, Vampire.currentTarget.PlayerId, Byte.MaxValue);
 
                             vampireKillButton.HasEffect = false; // Block effect on this click
                             vampireKillButton.Timer = vampireKillButton.MaxTimer;
@@ -416,7 +418,7 @@ namespace TheOtherRoles
                             // Notify players about bitten
                             MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.VampireSetBitten, Hazel.SendOption.Reliable, -1);
                             writer.Write(Vampire.bitten.PlayerId);
-                            writer.Write(0);
+                            writer.Write((byte)0);
                             AmongUsClient.Instance.FinishRpcImmediately(writer);
                             RPCProcedure.vampireSetBitten(Vampire.bitten.PlayerId, 0);
 
@@ -678,14 +680,13 @@ namespace TheOtherRoles
                         if (murder == MurderAttemptResult.SuppressKill) return; 
 
                         // Curse Kill
-                        // Not using Helpers.checkMuderAttemptAndKill here directly, since we need to share the Warlock.curseKillTarget
-
                         if (murder == MurderAttemptResult.PerformKill) {
-                            MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.WarlockCurseKill, Hazel.SendOption.Reliable, -1);
-                            writer.Write(Warlock.curseVictimTarget.PlayerId);
-                            AmongUsClient.Instance.FinishRpcImmediately(writer);
-                            RPCProcedure.warlockCurseKill(Warlock.curseVictimTarget.PlayerId);
-
+                            MessageWriter killWriter = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.UncheckedMurderPlayer, Hazel.SendOption.Reliable, -1);
+                            killWriter.Write(Warlock.warlock.Data.PlayerId);
+                            killWriter.Write(Warlock.curseVictimTarget.PlayerId);
+                            killWriter.Write((byte)0);
+                            AmongUsClient.Instance.FinishRpcImmediately(killWriter);
+                            RPCProcedure.uncheckedMurderPlayer(Warlock.warlock.Data.PlayerId, Warlock.curseVictimTarget.PlayerId, (byte)0);
                         }  
 
                         if(Warlock.rootTime > 0) {
index 4fe62843502aa149f9937c1d8a160a445270945d..0f6dd9df62f24f332ae4f16f3cf9ed4a19ea1f6c 100644 (file)
@@ -86,7 +86,7 @@ namespace TheOtherRoles {
 
         public static void handleVampireBiteOnBodyReport() {
             // Murder the bitten player and reset bitten (regardless whether the kill was successful or not)
-            Helpers.checkMuderAttemptAndKill(Vampire.vampire, Vampire.bitten, true);
+            Helpers.checkMuderAttemptAndKill(Vampire.vampire, Vampire.bitten, true, false);
             MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.VampireSetBitten, Hazel.SendOption.Reliable, -1);
             writer.Write(byte.MaxValue);
             writer.Write(byte.MaxValue);
@@ -313,7 +313,7 @@ namespace TheOtherRoles {
             return MurderAttemptResult.PerformKill;
         }
 
-        public static MurderAttemptResult checkMuderAttemptAndKill(PlayerControl killer, PlayerControl target, bool isMeetingStart = false)  {
+        public static MurderAttemptResult checkMuderAttemptAndKill(PlayerControl killer, PlayerControl target, bool isMeetingStart = false, bool showAnimation = true)  {
             // The local player checks for the validity of the kill and performs it afterwards (different to vanilla, where the host performs all the checks)
             // The kill attempt will be shared using a custom RPC, hence combining modded and unmodded versions is impossible
 
@@ -322,8 +322,9 @@ namespace TheOtherRoles {
                 MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.UncheckedMurderPlayer, Hazel.SendOption.Reliable, -1);
                 writer.Write(killer.PlayerId);
                 writer.Write(target.PlayerId);
+                writer.Write(showAnimation ? Byte.MaxValue : 0);
                 AmongUsClient.Instance.FinishRpcImmediately(writer);
-                RPCProcedure.uncheckedMurderPlayer(killer.PlayerId, target.PlayerId);
+                RPCProcedure.uncheckedMurderPlayer(killer.PlayerId, target.PlayerId, showAnimation ? Byte.MaxValue : (byte)0);
             }
             return murder;            
         }
index 3dc088604a82a5cf9ce4792d10f6528461451e8d..ccf8c701e9031e3a6626d5e217fad2dabb1c37e8 100644 (file)
@@ -21,7 +21,7 @@ namespace TheOtherRoles
     public class TheOtherRolesPlugin : BasePlugin
     {
         public const string Id = "me.eisbison.theotherroles";
-        public const string VersionString = "3.2.2";
+        public const string VersionString = "3.2.3";
         public static System.Version Version = System.Version.Parse(VersionString);
         internal static BepInEx.Logging.ManualLogSource Logger;
 
index 3f6a2c4998c8d12bf82d0e9fb99c7daf099a08d8..6ec25badbf660d9d0ed962ff43fa8e627bafef39 100644 (file)
@@ -53,14 +53,17 @@ namespace TheOtherRoles.Patches {
 
             // Witch execute casted spells
             if (Witch.witch != null && Witch.futureSpelled != null && AmongUsClient.Instance.AmHost) {
-                if (!Witch.witchVoteSavesTargets || exiled == null || exiled.PlayerId != Witch.witch.PlayerId) {
-                    foreach (PlayerControl target in Witch.futureSpelled) {
-                        if (target != null && !target.Data.IsDead && Helpers.checkMuderAttempt(Witch.witch, target, true) == MurderAttemptResult.PerformKill) {
-                            MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.UncheckedExilePlayer, Hazel.SendOption.Reliable, -1);
-                            writer.Write(target.PlayerId);
-                            AmongUsClient.Instance.FinishRpcImmediately(writer);
-                            RPCProcedure.uncheckedExilePlayer(target.PlayerId);
-                        }
+                bool exiledIsWitch = exiled != null && exiled.PlayerId == Witch.witch.PlayerId;
+                bool witchDiesWithExiledLover = exiled != null && Lovers.existing() && Lovers.bothDie && (Lovers.lover1.PlayerId == Witch.witch.PlayerId || Lovers.lover2.PlayerId == Witch.witch.PlayerId) && (exiled.PlayerId == Lovers.lover1.PlayerId || exiled.PlayerId == Lovers.lover2.PlayerId);
+
+                if ((witchDiesWithExiledLover || exiledIsWitch) && Witch.witchVoteSavesTargets) Witch.futureSpelled = new List<PlayerControl>();
+                foreach (PlayerControl target in Witch.futureSpelled) {
+                    if (target != null && !target.Data.IsDead && Helpers.checkMuderAttempt(Witch.witch, target, true) == MurderAttemptResult.PerformKill)
+                    {
+                        MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.UncheckedExilePlayer, Hazel.SendOption.Reliable, -1);
+                        writer.Write(target.PlayerId);
+                        AmongUsClient.Instance.FinishRpcImmediately(writer);
+                        RPCProcedure.uncheckedExilePlayer(target.PlayerId);
                     }
                 }
             }
index d14070a6ba8280258c3bb7e85f8480800b9f4f1b..e9c09cde356d0546994240b3436d281a309a11f9 100644 (file)
@@ -259,6 +259,7 @@ namespace TheOtherRoles.Patches {
                 Transform button = UnityEngine.Object.Instantiate(buttonTemplate, buttonParent);
                 Transform buttonMask = UnityEngine.Object.Instantiate(maskTemplate, buttonParent);
                 TMPro.TextMeshPro label = UnityEngine.Object.Instantiate(textTemplate, button);
+                button.GetComponent<SpriteRenderer>().sprite = DestroyableSingleton<HatManager>.Instance.AllNamePlates[0].Image;
                 buttons.Add(button);
                 int row = i/5, col = i%5;
                 buttonParent.localPosition = new Vector3(-3.47f + 1.75f * col, 1.5f - 0.45f * row, -5);
index 53371b827549e95736bd06b21c6db942e7d8d4b2..953b5accffcf1217cc89f3d7013e070802fc414d 100644 (file)
@@ -962,15 +962,29 @@ namespace TheOtherRoles.Patches {
 
     [HarmonyPatch(typeof(KillAnimation), nameof(KillAnimation.CoPerformKill))]
     class KillAnimationCoPerformKillPatch {
+        public static bool hideNextAnimation = true;
         public static void Prefix(KillAnimation __instance, [HarmonyArgument(0)]ref PlayerControl source, [HarmonyArgument(1)]ref PlayerControl target) {
-            if (Vampire.vampire != null && Vampire.vampire == source && Vampire.bitten != null && Vampire.bitten == target)
+            if (hideNextAnimation)
                 source = target;
-            
-            if (Warlock.warlock != null && Warlock.warlock == source && Warlock.curseKillTarget != null && Warlock.curseKillTarget == target) {
-                source = target;
-                Warlock.curseKillTarget = null; // Reset here
+            hideNextAnimation = false;
+        }
+    }
+
+    [HarmonyPatch(typeof(KillAnimation), nameof(KillAnimation.SetMovement))]
+    class KillAnimationSetMovementPatch {
+        private static int? colorId = null;
+        public static void Prefix(PlayerControl source, bool canMove) {
+            Color color = source.myRend.material.GetColor("_BodyColor");
+            if (color != null && Morphling.morphling != null && source.Data.PlayerId == Morphling.morphling.PlayerId) {
+                var index = Palette.PlayerColors.IndexOf(color);
+                if (index != -1) colorId = index;
             }
         }
+
+        public static void Postfix(PlayerControl source, bool canMove) {
+            if (colorId.HasValue) source.RawSetColor(colorId.Value);
+            colorId = null;
+        }
     }
 
     [HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.Exiled))]
index 3e1d6fae007d6edefc90c737b9be857e613827b5..d081c1bd2fa776ff917d83c292d88f59ef3e2717 100644 (file)
@@ -174,7 +174,7 @@ namespace TheOtherRoles.Patches {
             // Lawyer
             bool localIsLawyer = Lawyer.lawyer != null && Lawyer.target != null && Lawyer.lawyer == PlayerControl.LocalPlayer;
             bool localIsKnowingTarget = Lawyer.lawyer != null && Lawyer.target != null && Lawyer.targetKnows && Lawyer.target == PlayerControl.LocalPlayer;
-            if (localIsLawyer || localIsKnowingTarget) {
+            if (localIsLawyer || (localIsKnowingTarget && !Lawyer.lawyer.Data.IsDead)) {
                 string suffix = Helpers.cs(Lawyer.color, " §");
                 Lawyer.target.nameText.text += suffix;
 
index b028ff848dcd5df59187ca44e92ad3da568e9982..d550f9b6905a7de1f79e637c024d52f5fdb52d95 100644 (file)
@@ -96,7 +96,6 @@ namespace TheOtherRoles
         SetFutureSpelled,
         PlaceJackInTheBox,
         LightsOut,
-        WarlockCurseKill,
         PlaceCamera,
         SealVent,
         ArsonistWin,
@@ -296,10 +295,13 @@ namespace TheOtherRoles
             player.MyPhysics.HandleRpc(isEnter != 0 ? (byte)19 : (byte)20, reader);
         }
 
-        public static void uncheckedMurderPlayer(byte sourceId, byte targetId) {
+        public static void uncheckedMurderPlayer(byte sourceId, byte targetId, byte showAnimation) {
             PlayerControl source = Helpers.playerById(sourceId);
             PlayerControl target = Helpers.playerById(targetId);
-            if (source != null && target != null) source.MurderPlayer(target);
+            if (source != null && target != null) {
+                if (showAnimation == 0) KillAnimationCoPerformKillPatch.hideNextAnimation = true;
+                source.MurderPlayer(target);
+            }
         }
 
         public static void uncheckedCmdReportDeadBody(byte sourceId, byte targetId) {
@@ -491,8 +493,8 @@ namespace TheOtherRoles
                 player.setLook("", 6, "", "", "", "");
         }
 
-        public static void vampireSetBitten(byte targetId, byte reset) {
-            if (reset != 0) {
+        public static void vampireSetBitten(byte targetId, byte performReset) {
+            if (performReset != 0) {
                 Vampire.bitten = null;
                 return;
             }
@@ -642,16 +644,6 @@ namespace TheOtherRoles
             }
         }
 
-        public static void warlockCurseKill(byte targetId) {
-            foreach (PlayerControl player in PlayerControl.AllPlayerControls) {
-                if (player.PlayerId == targetId) {
-                    Warlock.curseKillTarget = player;
-                    Warlock.warlock.MurderPlayer(player);
-                    return;
-                }
-            }
-        }
-
         public static void placeCamera(byte[] buff) {
             var referenceCamera = UnityEngine.Object.FindObjectOfType<SurvCamera>(); 
             if (referenceCamera == null) return; // Mira HQ
@@ -716,9 +708,15 @@ namespace TheOtherRoles
 
         public static void lawyerPromotesToPursuer() {
             PlayerControl player = Lawyer.lawyer;
+            PlayerControl client = Lawyer.target;
             Lawyer.clearAndReload();
             Pursuer.pursuer = player;
-            return;
+
+            if (player.PlayerId == PlayerControl.LocalPlayer.PlayerId && client != null) {
+                    Transform playerInfoTransform = client.nameText.transform.parent.FindChild("Info");
+                    TMPro.TextMeshPro playerInfo = playerInfoTransform != null ? playerInfoTransform.GetComponent<TMPro.TextMeshPro>() : null;
+                    if (playerInfo != null) playerInfo.text = "";
+            }
         }
 
         public static void guesserShoot(byte dyingTargetId, byte guessedTargetId, byte guessedRoleId) {
@@ -816,7 +814,8 @@ namespace TheOtherRoles
                 case (byte)CustomRPC.UncheckedMurderPlayer:
                     byte source = reader.ReadByte();
                     byte target = reader.ReadByte();
-                    RPCProcedure.uncheckedMurderPlayer(source, target);
+                    byte showAnimation = reader.ReadByte();
+                    RPCProcedure.uncheckedMurderPlayer(source, target, showAnimation);
                     break;
                 case (byte)CustomRPC.UncheckedExilePlayer:
                     byte exileTarget = reader.ReadByte();
@@ -900,9 +899,6 @@ namespace TheOtherRoles
                 case (byte)CustomRPC.LightsOut:
                     RPCProcedure.lightsOut();
                     break;
-                case (byte)CustomRPC.WarlockCurseKill:
-                    RPCProcedure.warlockCurseKill(reader.ReadByte());
-                    break;
                 case (byte)CustomRPC.PlaceCamera:
                     RPCProcedure.placeCamera(reader.ReadBytesAndSize());
                     break;
index 7daa584a68c318b3b832496cc39affa0b7fee809..6190ec5edb520806ac4eed1c1d337b0e8cdc46bc 100644 (file)
@@ -835,7 +835,6 @@ namespace TheOtherRoles
         public static PlayerControl currentTarget;
         public static PlayerControl curseVictim;
         public static PlayerControl curseVictimTarget;
-        public static PlayerControl curseKillTarget;
 
         public static float cooldown = 30f;
         public static float rootTime = 5f;
@@ -860,7 +859,6 @@ namespace TheOtherRoles
             currentTarget = null;
             curseVictim = null;
             curseVictimTarget = null;
-            curseKillTarget = null;
             cooldown = CustomOptionHolder.warlockCooldown.getFloat();
             rootTime = CustomOptionHolder.warlockRootTime.getFloat();
         }
@@ -872,7 +870,6 @@ namespace TheOtherRoles
             currentTarget = null;
             curseVictim = null;
             curseVictimTarget = null;
-            curseKillTarget = null;
         }
     }
 
index fa3ebc8626478855e9b6a562b3980c4b0af6af3e..07832d180d9c0e259f84eacf9b8a13c093f2a13e 100644 (file)
@@ -1,7 +1,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
     <PropertyGroup>
         <TargetFramework>netstandard2.1</TargetFramework>
-        <Version>3.2.2</Version>
+        <Version>3.2.3</Version>
         <Description>TheOtherRoles</Description>
         <Authors>Eisbison</Authors>
     </PropertyGroup>