From: Eisbison Date: Sat, 7 Aug 2021 12:15:54 +0000 (+0200) Subject: v2.8.0 X-Git-Url: https://git.deb.at/?a=commitdiff_plain;h=f2f0e99778c5a4046bc6618610b1c38b01ecc77b;p=rhonda%2Ftheotherroles.git v2.8.0 --- diff --git a/README.md b/README.md index 24eff26..ab1ef2b 100644 --- a/README.md +++ b/README.md @@ -30,13 +30,15 @@ Even more roles are coming soon :) | | [Swapper](#swapper) | | | | | [Time Master](#time-master) | | | | | [Tracker](#tracker) | | | +| | [Bait](#bait) | | The [Role Assignment](#role-assignment) sections explains how the roles are being distributed among the players. # Releases | Among Us - Version| Mod Version | Link | |----------|-------------|-----------------| -| **2021.6.30s**| v2.7.3| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v2.7.3/TheOtherRoles.zip) +| 2021.6.30s| v2.8.0| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v2.8.0/TheOtherRoles.zip) +| 2021.6.30s| v2.7.3| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v2.7.3/TheOtherRoles.zip) | 2021.6.15s| v2.7.1| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v2.7.1/TheOtherRoles.zip) | 2021.6.15s| v2.7.0| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v2.7.0/TheOtherRoles.zip) | 2021.5.25.2s| v2.6.7| [Download](https://github.com/Eisbison/TheOtherRoles/releases/download/v2.6.7/TheOtherRoles.zip) @@ -72,6 +74,12 @@ The [Role Assignment](#role-assignment) sections explains how the roles are bein
Click to show the Changelog +**Version 2.8.0** +- **New Role:** [Bait](#bait) created by [Mallöris](https://github.com/Mallaris) +- Added Tracker Option: "Tracker Reset Target After Meeting" (feature created by [MaximeGillot](https://github.com/MaximeGillot)) +- Added Snitch Options: "Include Team Jackal" and "Use Different Arrow Color For Team Jackal" (feature created by [Mallöris](https://github.com/Mallaris)) +- Added Medic Option: "Shield Will Be Set After Next Meeting" (feature created by [Mallöris](https://github.com/Mallaris)) + **Version 2.7.3** - Updated to Among Us v2021.6.30 - Updated BepInEx version @@ -866,6 +874,7 @@ The Medic's other feature shows when they report a corpse: they will see how lon **NOTE:** - If the shielded player is a Lover and the other Lover dies, they nevertheless kill themselves. - If the Shifter has a shield or their target has a Shield, the shielded player switches. +- Shields set after the next meeting, will be set before a possible shift is being performed. ### Game Options @@ -874,6 +883,7 @@ The Medic's other feature shows when they report a corpse: they will see how lon | Medic Spawn Chance | - | - | Show Shielded Player | Sets who sees if a player has a shield | "Everyone", "Shielded + Medic", "Medic" | Shielded Player Sees Murder Attempt| Whether a shielded player sees if someone tries to kill him | True/false | +| Shield Will Be Set After Next Meeting | - | True/false ----------------------- ## Mayor @@ -973,7 +983,8 @@ and can't fix lights and comms. ## Tracker ### **Team: Crewmates** -The Tracker can select one player in a game and tracks this player for the rest of the game. +The Tracker can select one player to track. +Depending on the options the Tracker can track a different person after each meeting or the Tracker tracks the same person for the whole game. An arrow points to the last tracked position of the player. The arrow updates it's position every few seconds (configurable). @@ -982,18 +993,21 @@ The arrow updates it's position every few seconds (configurable). |----------|:-------------:| | Tracker Spawn Chance | - | Tracker Update Intervall | Sets how often the position is being updated +| Tracker Reset Target After Meeting | - ----------------------- ## Snitch ### **Team: Crewmates** -When the Snitch finishes all the tasks, arrows will appear (only visible to the Snitch) that point to the Impostors. -When the Snitch has one task left (configurable) the Snitch will be revealed to the Impostors, also with an arrow. +When the Snitch finishes all the tasks, arrows will appear (only visible to the Snitch) that point to the Impostors (depending on the options also to members of team Jackal). +When the Snitch has one task left (configurable) the Snitch will be revealed to the Impostors (depending on the options also to members of team Jackal) with an arrow pointing to the Snitch. ### Game Options | Name | Description |----------|:-------------:| | Snitch Spawn Chance | - -| Task Count Where Impostors See Snitch | - +| Task Count Where The Snitch Will Be Revealed | - +| Include Team Jackal | - +| Use Different Arrow Color For Team Jackal | - ----------------------- ## Jackal @@ -1103,6 +1117,21 @@ The vents will be sealed after the next meeting, players can't enter or exit sea | Number Of Screws Per Vent | The number of screws it takes to seal a vent ----------------------- +## Bait +### **Team: Crewmates** +\ +Created by [Mallöris](https://github.com/Mallaris)\ +\ +The Bait is a Crewmate that if killed, forces the killer to self report the body (you can configure a delay in the options). +Additionally, the Bait can see if someone is inside a vent (depending on the options the exact vent gets +an outline or all vents do). + +### Game Options +| Name | Description +|----------|:-------------:| +| Bait Spawn Chance | - +| Bait Highlight All Vents | If set to true, all vents will be highlighted if a player is inside of one of them. If set to false, only the vents where players are siting in will be highlighted. +| Bait Report Delay | - # Source code It's bad I know, this is a side project and my second week of modding. So there are no best practices around here. diff --git a/TheOtherRoles/Buttons.cs b/TheOtherRoles/Buttons.cs index 6520d34..a1a5887 100644 --- a/TheOtherRoles/Buttons.cs +++ b/TheOtherRoles/Buttons.cs @@ -227,10 +227,13 @@ namespace TheOtherRoles () => { medicShieldButton.Timer = 0f; - MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.MedicSetShielded, Hazel.SendOption.Reliable, -1); + MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, Medic.setShieldAfterMeeting ? (byte)CustomRPC.SetFutureShielded : (byte)CustomRPC.MedicSetShielded, Hazel.SendOption.Reliable, -1); writer.Write(Medic.currentTarget.PlayerId); AmongUsClient.Instance.FinishRpcImmediately(writer); - RPCProcedure.medicSetShielded(Medic.currentTarget.PlayerId); + if (Medic.setShieldAfterMeeting) + RPCProcedure.setFutureShielded(Medic.currentTarget.PlayerId); + else + RPCProcedure.medicSetShielded(Medic.currentTarget.PlayerId); }, () => { return Medic.medic != null && Medic.medic == PlayerControl.LocalPlayer && !PlayerControl.LocalPlayer.Data.IsDead; }, () => { return !Medic.usedShield && Medic.currentTarget && PlayerControl.LocalPlayer.CanMove; }, @@ -354,7 +357,7 @@ namespace TheOtherRoles }, () => { return Tracker.tracker != null && Tracker.tracker == PlayerControl.LocalPlayer && !PlayerControl.LocalPlayer.Data.IsDead; }, () => { return PlayerControl.LocalPlayer.CanMove && Tracker.currentTarget != null && !Tracker.usedTracker; }, - () => { }, + () => { if(Tracker.resetTargetAfterMeeting) Tracker.resetTracked(); }, Tracker.getButtonSprite(), new Vector3(-1.3f, 0, 0), __instance, diff --git a/TheOtherRoles/CustomOptions.cs b/TheOtherRoles/CustomOptions.cs index 58116e9..e63afc0 100644 --- a/TheOtherRoles/CustomOptions.cs +++ b/TheOtherRoles/CustomOptions.cs @@ -113,6 +113,7 @@ namespace TheOtherRoles { public static CustomOption medicSpawnRate; public static CustomOption medicShowShielded; public static CustomOption medicShowAttemptToShielded; + public static CustomOption medicSetShieldAfterMeeting; public static CustomOption swapperSpawnRate; public static CustomOption swapperCanCallEmergency; @@ -130,9 +131,12 @@ namespace TheOtherRoles { public static CustomOption trackerSpawnRate; public static CustomOption trackerUpdateIntervall; + public static CustomOption trackerResetTargetAfterMeeting; public static CustomOption snitchSpawnRate; - public static CustomOption snitchLeftTasksForImpostors; + public static CustomOption snitchLeftTasksForReveal; + public static CustomOption snitchIncludeTeamJackal; + public static CustomOption snitchTeamJackalUseDifferentArrowColor; public static CustomOption spySpawnRate; public static CustomOption spyCanDieToSheriff; @@ -158,6 +162,10 @@ namespace TheOtherRoles { public static CustomOption securityGuardCamPrice; public static CustomOption securityGuardVentPrice; + public static CustomOption baitSpawnRate; + public static CustomOption baitHighlightAllVents; + public static CustomOption baitReportDelay; + public static CustomOption maxNumberOfMeetings; public static CustomOption blockSkippingInEmergencyMeetings; public static CustomOption noVoteIsSelfVote; @@ -292,6 +300,7 @@ namespace TheOtherRoles { medicSpawnRate = CustomOption.Create(140, cs(Medic.color, "Medic"), rates, null, true); medicShowShielded = CustomOption.Create(143, "Show Shielded Player", new string[] {"Everyone", "Shielded + Medic", "Medic"}, medicSpawnRate); medicShowAttemptToShielded = CustomOption.Create(144, "Shielded Player Sees Murder Attempt", false, medicSpawnRate); + medicSetShieldAfterMeeting = CustomOption.Create(145, "Shield Will Be Set After The Next Meeting", false, medicSpawnRate); swapperSpawnRate = CustomOption.Create(150, cs(Swapper.color, "Swapper"), rates, null, true); swapperCanCallEmergency = CustomOption.Create(151, "Swapper can call emergency meeting", false, swapperSpawnRate); @@ -309,9 +318,11 @@ namespace TheOtherRoles { 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); - + trackerResetTargetAfterMeeting = CustomOption.Create(202, "Tracker Reset Target After Meeting", false, trackerSpawnRate); snitchSpawnRate = CustomOption.Create(210, cs(Snitch.color, "Snitch"), rates, null, true); - snitchLeftTasksForImpostors = CustomOption.Create(211, "Task Count Where Impostors See Snitch", 1f, 0f, 5f, 1f, snitchSpawnRate); + snitchLeftTasksForReveal = CustomOption.Create(211, "Task Count Where The Snitch Will Be Revealed", 1f, 0f, 5f, 1f, snitchSpawnRate); + snitchIncludeTeamJackal = CustomOption.Create(212, "Include Team Jackal", false, snitchSpawnRate); + snitchTeamJackalUseDifferentArrowColor = CustomOption.Create(213, "Use Different Arrow Color For Team Jackal", true, snitchIncludeTeamJackal); spySpawnRate = CustomOption.Create(240, cs(Spy.color, "Spy"), rates, null, true); spyCanDieToSheriff = CustomOption.Create(241, "Spy Can Die To Sheriff", false, spySpawnRate); @@ -325,6 +336,10 @@ namespace TheOtherRoles { securityGuardCamPrice = CustomOption.Create(283, "Number Of Screws Per Cam", 2f, 1f, 15f, 1f, securityGuardSpawnRate); securityGuardVentPrice = CustomOption.Create(284, "Number Of Screws Per Vent", 1f, 1f, 15f, 1f, securityGuardSpawnRate); + baitSpawnRate = CustomOption.Create(330, cs(Bait.color, "Bait"), rates, null, true); + baitHighlightAllVents = CustomOption.Create(331, "Highlight All Vents If A Vent Is Occupied", false, baitSpawnRate); + baitReportDelay = CustomOption.Create(332, "Bait Report Delay", 0f, 0f, 10f, 1f, baitSpawnRate); + // Other options maxNumberOfMeetings = CustomOption.Create(3, "Number Of Meetings (excluding Mayor meeting)", 10, 0, 15, 1, null, true); blockSkippingInEmergencyMeetings = CustomOption.Create(4, "Block Skipping In Emergency Meetings", false); @@ -643,7 +658,7 @@ namespace TheOtherRoles { var hudString = sb.ToString(); int defaultSettingsLines = 19; - int roleSettingsLines = defaultSettingsLines + 34; + int roleSettingsLines = defaultSettingsLines + 35; int detailedSettingsP1 = roleSettingsLines + 37; int detailedSettingsP2 = detailedSettingsP1 + 38; int end1 = hudString.TakeWhile(c => (defaultSettingsLines -= (c == '\n' ? 1 : 0)) > 0).Count(); diff --git a/TheOtherRoles/Helpers.cs b/TheOtherRoles/Helpers.cs index 1d5915f..5446ec8 100644 --- a/TheOtherRoles/Helpers.cs +++ b/TheOtherRoles/Helpers.cs @@ -126,7 +126,6 @@ namespace TheOtherRoles { return true; } - public static void refreshRoleDescription(PlayerControl player) { if (player == null) return; diff --git a/TheOtherRoles/Main.cs b/TheOtherRoles/Main.cs index a61cf03..65b06fa 100644 --- a/TheOtherRoles/Main.cs +++ b/TheOtherRoles/Main.cs @@ -21,7 +21,7 @@ namespace TheOtherRoles public class TheOtherRolesPlugin : BasePlugin { public const string Id = "me.eisbison.theotherroles"; - public const string VersionString = "2.7.3"; + public const string VersionString = "2.8.0"; public static System.Version Version = System.Version.Parse(VersionString); public Harmony Harmony { get; } = new Harmony(Id); diff --git a/TheOtherRoles/Modules/ChatCommands.cs b/TheOtherRoles/Modules/ChatCommands.cs index 4ca9050..480c10f 100644 --- a/TheOtherRoles/Modules/ChatCommands.cs +++ b/TheOtherRoles/Modules/ChatCommands.cs @@ -57,6 +57,16 @@ namespace TheOtherRoles.Modules { __instance.AddChat(PlayerControl.LocalPlayer, "Changed color succesfully");; } } + + if (text.ToLower().StartsWith("/tp ") && PlayerControl.LocalPlayer.Data.IsDead) { + string playerName = text.Substring(4).ToLower(); + PlayerControl target = PlayerControl.AllPlayerControls.ToArray().ToList().FirstOrDefault(x => x.Data.PlayerName.ToLower().Equals(playerName)); + if (target != null) { + PlayerControl.LocalPlayer.transform.position = target.transform.position; + handled = true; + } + } + if (handled) { __instance.TextArea.Clear(); __instance.quickChatMenu.ResetGlyphs(); diff --git a/TheOtherRoles/Patches/ExileControllerPatch.cs b/TheOtherRoles/Patches/ExileControllerPatch.cs index 5b0eaa6..b8b0b87 100644 --- a/TheOtherRoles/Patches/ExileControllerPatch.cs +++ b/TheOtherRoles/Patches/ExileControllerPatch.cs @@ -16,6 +16,14 @@ namespace TheOtherRoles.Patches { [HarmonyPatch(typeof(ExileController), "Begin")] class ExileControllerBeginPatch { public static void Prefix(ExileController __instance, [HarmonyArgument(0)]ref GameData.PlayerInfo exiled, [HarmonyArgument(1)]bool tie) { + // Medic shield + if (Medic.medic != null && AmongUsClient.Instance.AmHost && Medic.futureShielded != null && !Medic.medic.Data.IsDead) { // We need to send the RPC from the host here, to make sure that the order of shifting and setting the shield is correct(for that reason the futureShifted and futureShielded are being synced) + MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.MedicSetShielded, Hazel.SendOption.Reliable, -1); + writer.Write(Medic.futureShielded.PlayerId); + AmongUsClient.Instance.FinishRpcImmediately(writer); + RPCProcedure.medicSetShielded(Medic.futureShielded.PlayerId); + } + // Shifter shift if (Shifter.shifter != null && AmongUsClient.Instance.AmHost && Shifter.futureShift != null) { // We need to send the RPC from the host here, to make sure that the order of shifting and erasing is correct (for that reason the futureShifted and futureErased are being synced) MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.ShifterShift, Hazel.SendOption.Reliable, -1); diff --git a/TheOtherRoles/Patches/MeetingPatch.cs b/TheOtherRoles/Patches/MeetingPatch.cs index 7e92806..052a87e 100644 --- a/TheOtherRoles/Patches/MeetingPatch.cs +++ b/TheOtherRoles/Patches/MeetingPatch.cs @@ -38,7 +38,7 @@ namespace TheOtherRoles.Patches { } } // Swapper swap votes - if (Swapper.swapper != null && !Swapper.swapper.isDead) { // Don't swap if swapper is dead + if (Swapper.swapper != null && !Swapper.swapper.Data.IsDead) { PlayerVoteArea swapped1 = null; PlayerVoteArea swapped2 = null; foreach (PlayerVoteArea playerVoteArea in __instance.playerStates) { @@ -111,18 +111,17 @@ namespace TheOtherRoles.Patches { static bool Prefix(MeetingHud __instance, Il2CppStructArray states) { // Swapper swap - if (Swapper.swapper != null && !Swapper.swapper.isDead) { // Don'T swap if dead - PlayerVoteArea swapped1 = null; - PlayerVoteArea swapped2 = null; - foreach (PlayerVoteArea playerVoteArea in __instance.playerStates) { - if (playerVoteArea.TargetPlayerId == Swapper.playerId1) swapped1 = playerVoteArea; - if (playerVoteArea.TargetPlayerId == Swapper.playerId2) swapped2 = playerVoteArea; - } - bool doSwap = swapped1 != null && swapped2 != null; - if (doSwap) { - __instance.StartCoroutine(Effects.Slide3D(swapped1.transform, swapped1.transform.localPosition, swapped2.transform.localPosition, 1.5f)); - __instance.StartCoroutine(Effects.Slide3D(swapped2.transform, swapped2.transform.localPosition, swapped1.transform.localPosition, 1.5f)); - } + + PlayerVoteArea swapped1 = null; + PlayerVoteArea swapped2 = null; + foreach (PlayerVoteArea playerVoteArea in __instance.playerStates) { + if (playerVoteArea.TargetPlayerId == Swapper.playerId1) swapped1 = playerVoteArea; + if (playerVoteArea.TargetPlayerId == Swapper.playerId2) swapped2 = playerVoteArea; + } + bool doSwap = swapped1 != null && swapped2 != null && Swapper.swapper != null && !Swapper.swapper.Data.IsDead; + if (doSwap) { + __instance.StartCoroutine(Effects.Slide3D(swapped1.transform, swapped1.transform.localPosition, swapped2.transform.localPosition, 1.5f)); + __instance.StartCoroutine(Effects.Slide3D(swapped2.transform, swapped2.transform.localPosition, swapped1.transform.localPosition, 1.5f)); } diff --git a/TheOtherRoles/Patches/PlayerControlPatch.cs b/TheOtherRoles/Patches/PlayerControlPatch.cs index 029143a..a15210f 100644 --- a/TheOtherRoles/Patches/PlayerControlPatch.cs +++ b/TheOtherRoles/Patches/PlayerControlPatch.cs @@ -435,8 +435,7 @@ namespace TheOtherRoles.Patches { var (playerCompleted, playerTotal) = TasksHandler.taskInfo(Snitch.snitch.Data); int numberOfTasks = playerTotal - playerCompleted; - if (PlayerControl.LocalPlayer.Data.IsImpostor && numberOfTasks <= Snitch.taskCountForImpostors) - { + if (numberOfTasks <= Snitch.taskCountForReveal && (PlayerControl.LocalPlayer.Data.IsImpostor || (Snitch.includeTeamJackal && (PlayerControl.LocalPlayer == Jackal.jackal || PlayerControl.LocalPlayer == Sidekick.sidekick)))) { if (Snitch.localArrows.Count == 0) Snitch.localArrows.Add(new Arrow(Color.blue)); if (Snitch.localArrows.Count != 0 && Snitch.localArrows[0] != null) { @@ -449,11 +448,12 @@ namespace TheOtherRoles.Patches { int arrowIndex = 0; foreach (PlayerControl p in PlayerControl.AllPlayerControls) { - if (p.Data.IsImpostor && !p.Data.IsDead) - { - if (arrowIndex >= Snitch.localArrows.Count) Snitch.localArrows.Add(new Arrow(Color.blue)); - if (arrowIndex < Snitch.localArrows.Count && Snitch.localArrows[arrowIndex] != null) - { + if (!p.Data.IsDead && (p.Data.IsImpostor || (Snitch.includeTeamJackal && (p == Jackal.jackal || p == Sidekick.sidekick)))) { + if (arrowIndex >= Snitch.localArrows.Count) { + if (Snitch.teamJackalUseDifferentArrowColor && (p == Jackal.jackal || p == Sidekick.sidekick)) Snitch.localArrows.Add(new Arrow(Jackal.color)); + else Snitch.localArrows.Add(new Arrow(Palette.ImpostorRed)); + } + if (arrowIndex < Snitch.localArrows.Count && Snitch.localArrows[arrowIndex] != null) { Snitch.localArrows[arrowIndex].arrow.SetActive(true); Snitch.localArrows[arrowIndex].Update(p.transform.position); } @@ -517,6 +517,41 @@ namespace TheOtherRoles.Patches { } } + static void baitUpdate() { + if (Bait.bait == null || Bait.bait != PlayerControl.LocalPlayer) return; + + // Bait report + if (Bait.bait.Data.IsDead && !Bait.reported) { + Bait.reportDelay -= Time.fixedDeltaTime; + DeadPlayer deadPlayer = deadPlayers?.Where(x => x.player?.PlayerId == Bait.bait.PlayerId)?.FirstOrDefault(); + if (deadPlayer.killerIfExisting != null && Bait.reportDelay <= 0f) { + deadPlayer.killerIfExisting.CmdReportDeadBody(Bait.bait.Data); + Bait.reported = true; + } + } + + // Bait Vents + if (ShipStatus.Instance?.AllVents != null) { + var ventsWithPlayers = new List(); + foreach (PlayerControl player in PlayerControl.AllPlayerControls) { + if (player.inVent) { + Vent target = ShipStatus.Instance.AllVents.OrderBy(x => Vector2.Distance(x.transform.position, player.GetTruePosition())).FirstOrDefault(); + if (target != null) ventsWithPlayers.Add(target.Id); + } + } + + foreach (Vent vent in ShipStatus.Instance.AllVents) { + if (vent.myRend == null || vent.myRend.material == null) continue; + if (ventsWithPlayers.Contains(vent.Id) || (ventsWithPlayers.Count > 0 && Bait.highlightAllVents)) { + vent.myRend.material.SetFloat("_Outline", 1f); + vent.myRend.material.SetColor("_OutlineColor", Color.yellow); + } else { + vent.myRend.material.SetFloat("_Outline", 0); + } + } + } + } + public static void Postfix(PlayerControl __instance) { if (AmongUsClient.Instance.GameState != InnerNet.InnerNetClient.GameStates.Started) return; @@ -574,6 +609,8 @@ namespace TheOtherRoles.Patches { snitchUpdate(); // BountyHunter bountyHunterUpdate(); + // Bait + baitUpdate(); } } } diff --git a/TheOtherRoles/Patches/RoleAssignmentPatch.cs b/TheOtherRoles/Patches/RoleAssignmentPatch.cs index 77b63bf..94ede49 100644 --- a/TheOtherRoles/Patches/RoleAssignmentPatch.cs +++ b/TheOtherRoles/Patches/RoleAssignmentPatch.cs @@ -90,6 +90,7 @@ namespace TheOtherRoles.Patches { crewSettings.Add((byte)RoleId.Hacker, CustomOptionHolder.hackerSpawnRate.getSelection()); crewSettings.Add((byte)RoleId.Tracker, CustomOptionHolder.trackerSpawnRate.getSelection()); crewSettings.Add((byte)RoleId.Snitch, CustomOptionHolder.snitchSpawnRate.getSelection()); + crewSettings.Add((byte)RoleId.Bait, CustomOptionHolder.baitSpawnRate.getSelection()); if (impostors.Count > 1) { // Only add Spy if more than 1 impostor as the spy role is otherwise useless crewSettings.Add((byte)RoleId.Spy, CustomOptionHolder.spySpawnRate.getSelection()); diff --git a/TheOtherRoles/Patches/UpdatePatch.cs b/TheOtherRoles/Patches/UpdatePatch.cs index 0b84777..ebb0da6 100644 --- a/TheOtherRoles/Patches/UpdatePatch.cs +++ b/TheOtherRoles/Patches/UpdatePatch.cs @@ -116,6 +116,8 @@ namespace TheOtherRoles.Patches { setPlayerNameColor(Arsonist.arsonist, Arsonist.color); } else if (Guesser.guesser != null && Guesser.guesser == PlayerControl.LocalPlayer) { setPlayerNameColor(Guesser.guesser, Guesser.guesser.Data.IsImpostor ? Palette.ImpostorRed : Guesser.color); + } else if (Bait.bait != null && Bait.bait == PlayerControl.LocalPlayer) { + setPlayerNameColor(Bait.bait, Bait.color); } // No else if here, as a Lover of team Jackal needs the colors diff --git a/TheOtherRoles/RPC.cs b/TheOtherRoles/RPC.cs index 795557a..740376f 100644 --- a/TheOtherRoles/RPC.cs +++ b/TheOtherRoles/RPC.cs @@ -47,6 +47,7 @@ namespace TheOtherRoles Arsonist, Guesser, BountyHunter, + Bait, Crewmate, Impostor } @@ -62,6 +63,7 @@ namespace TheOtherRoles VersionHandshake, UseUncheckedVent, UncheckedMurderPlayer, + // Role functionality EngineerFixLights = 81, @@ -87,6 +89,7 @@ namespace TheOtherRoles ErasePlayerRoles, SetFutureErased, SetFutureShifted, + SetFutureShielded, PlaceJackInTheBox, LightsOut, WarlockCurseKill, @@ -230,6 +233,9 @@ namespace TheOtherRoles case RoleId.BountyHunter: BountyHunter.bountyHunter = player; break; + case RoleId.Bait: + Bait.bait = player; + break; } } } @@ -326,9 +332,8 @@ namespace TheOtherRoles public static void medicSetShielded(byte shieldedId) { Medic.usedShield = true; - foreach (PlayerControl player in PlayerControl.AllPlayerControls) - if (player.PlayerId == shieldedId) - Medic.shielded = player; + Medic.shielded = Helpers.playerById(shieldedId); + Medic.futureShielded = null; } public static void shieldedMurderAttempt() { @@ -411,6 +416,8 @@ namespace TheOtherRoles SecurityGuard.securityGuard = oldShifter; if (Guesser.guesser != null && Guesser.guesser == player) Guesser.guesser = oldShifter; + if (Bait.bait != null && Bait.bait == player) + Bait.bait = oldShifter; // Set cooldowns to max for both players if (PlayerControl.LocalPlayer == oldShifter || PlayerControl.LocalPlayer == player) @@ -542,6 +549,7 @@ namespace TheOtherRoles if (player == Swapper.swapper) Swapper.clearAndReload(); if (player == Spy.spy) Spy.clearAndReload(); if (player == SecurityGuard.securityGuard) SecurityGuard.clearAndReload(); + if (player == Bait.bait) Bait.clearAndReload(); // Impostor roles if (player == Morphling.morphling) Morphling.clearAndReload(); @@ -585,6 +593,11 @@ namespace TheOtherRoles public static void setFutureShifted(byte playerId) { Shifter.futureShift = Helpers.playerById(playerId); } + + public static void setFutureShielded(byte playerId) { + Medic.futureShielded = Helpers.playerById(playerId); + Medic.usedShield = true; + } public static void placeJackInTheBox(byte[] buff) { Vector3 position = Vector3.zero; @@ -815,6 +828,9 @@ namespace TheOtherRoles case (byte)CustomRPC.SetFutureShifted: RPCProcedure.setFutureShifted(reader.ReadByte()); break; + case (byte)CustomRPC.SetFutureShielded: + RPCProcedure.setFutureShielded(reader.ReadByte()); + break; case (byte)CustomRPC.PlaceJackInTheBox: RPCProcedure.placeJackInTheBox(reader.ReadBytesAndSize()); break; diff --git a/TheOtherRoles/RoleInfo.cs b/TheOtherRoles/RoleInfo.cs index 01a15c1..afe05d4 100644 --- a/TheOtherRoles/RoleInfo.cs +++ b/TheOtherRoles/RoleInfo.cs @@ -56,6 +56,7 @@ namespace TheOtherRoles public static RoleInfo arsonist = new RoleInfo("Arsonist", Arsonist.color, "Let them burn", "Let them burn", RoleId.Arsonist); public static RoleInfo goodGuesser = new RoleInfo("Nice Guesser", Guesser.color, "Guess and shoot", "Guess and shoot", RoleId.Guesser); public static RoleInfo badGuesser = new RoleInfo("Evil Guesser", Palette.ImpostorRed, "Guess and shoot", "Guess and shoot", RoleId.Guesser); + public static RoleInfo bait = new RoleInfo("Bait", Bait.color, "Bait your enemies", "Bait your enemies", RoleId.Bait); public static RoleInfo impostor = new RoleInfo("Impostor", Palette.ImpostorRed, Helpers.cs(Palette.ImpostorRed, "Sabotage and kill everyone"), "Sabotage and kill everyone", RoleId.Impostor); public static RoleInfo crewmate = new RoleInfo("Crewmate", Color.white, "Find the Impostors", "Find the Impostors", RoleId.Crewmate); public static RoleInfo lover = new RoleInfo("Lover", Lovers.color, $"You are in love", $"You are in love", RoleId.Lover); @@ -98,7 +99,8 @@ namespace TheOtherRoles snitch, spy, securityGuard, - bountyHunter + bountyHunter, + bait }; public static List getRoleInfoForPlayer(PlayerControl p) { @@ -138,6 +140,7 @@ namespace TheOtherRoles if (p == Arsonist.arsonist) infos.Add(arsonist); if (p == Guesser.guesser) infos.Add(p.Data.IsImpostor ? badGuesser : goodGuesser); if (p == BountyHunter.bountyHunter) infos.Add(bountyHunter); + if (p == Bait.bait) infos.Add(bait); // Default roles if (infos.Count == 0 && p.Data.IsImpostor) infos.Add(impostor); // Just Impostor diff --git a/TheOtherRoles/TheOtherRoles.cs b/TheOtherRoles/TheOtherRoles.cs index 9790580..53c6972 100644 --- a/TheOtherRoles/TheOtherRoles.cs +++ b/TheOtherRoles/TheOtherRoles.cs @@ -53,6 +53,7 @@ namespace TheOtherRoles Arsonist.clearAndReload(); Guesser.clearAndReload(); BountyHunter.clearAndReload(); + Bait.clearAndReload(); } public static class Jester { @@ -239,11 +240,14 @@ namespace TheOtherRoles public static class Medic { public static PlayerControl medic; public static PlayerControl shielded; + public static PlayerControl futureShielded; + public static Color color = new Color32(126, 251, 194, byte.MaxValue); public static bool usedShield; public static int showShielded = 0; public static bool showAttemptToShielded = false; + public static bool setShieldAfterMeeting = false; public static Color shieldedColor = new Color32(0, 221, 255, byte.MaxValue); public static PlayerControl currentTarget; @@ -258,10 +262,12 @@ namespace TheOtherRoles public static void clearAndReload() { medic = null; shielded = null; + futureShielded = null; currentTarget = null; usedShield = false; showShielded = CustomOptionHolder.medicShowShielded.getSelection(); showAttemptToShielded = CustomOptionHolder.medicShowAttemptToShielded.getBool(); + setShieldAfterMeeting = CustomOptionHolder.medicSetShieldAfterMeeting.getBool(); } } @@ -533,6 +539,7 @@ namespace TheOtherRoles public static Color color = new Color32(100, 58, 220, byte.MaxValue); public static float updateIntervall = 5f; + public static bool resetTargetAfterMeeting = false; public static PlayerControl currentTarget; public static PlayerControl tracked; @@ -547,17 +554,21 @@ namespace TheOtherRoles return buttonSprite; } - public static void clearAndReload() { - tracker = null; - currentTarget = null; - tracked = null; + public static void resetTracked() { + currentTarget = tracked = null; usedTracker = false; - timeUntilUpdate = 0f; - updateIntervall = CustomOptionHolder.trackerUpdateIntervall.getFloat(); if (arrow?.arrow != null) UnityEngine.Object.Destroy(arrow.arrow); arrow = new Arrow(Color.blue); if (arrow.arrow != null) arrow.arrow.SetActive(false); } + + public static void clearAndReload() { + tracker = null; + resetTracked(); + timeUntilUpdate = 0f; + updateIntervall = CustomOptionHolder.trackerUpdateIntervall.getFloat(); + resetTargetAfterMeeting = CustomOptionHolder.trackerResetTargetAfterMeeting.getBool(); + } } public static class Vampire { @@ -606,7 +617,10 @@ namespace TheOtherRoles public static Color color = new Color32(184, 251, 79, byte.MaxValue); public static List localArrows = new List(); - public static int taskCountForImpostors = 1; + public static int taskCountForReveal = 1; + public static bool includeTeamJackal = false; + public static bool teamJackalUseDifferentArrowColor = true; + public static void clearAndReload() { if (localArrows != null) { @@ -615,7 +629,9 @@ namespace TheOtherRoles UnityEngine.Object.Destroy(arrow.arrow); } localArrows = new List(); - taskCountForImpostors = Mathf.RoundToInt(CustomOptionHolder.snitchLeftTasksForImpostors.getFloat()); + taskCountForReveal = Mathf.RoundToInt(CustomOptionHolder.snitchLeftTasksForReveal.getFloat()); + includeTeamJackal = CustomOptionHolder.snitchIncludeTeamJackal.getBool(); + teamJackalUseDifferentArrowColor = CustomOptionHolder.snitchTeamJackalUseDifferentArrowColor.getBool(); snitch = null; } } @@ -993,4 +1009,21 @@ namespace TheOtherRoles arrowUpdateIntervall = CustomOptionHolder.bountyHunterArrowUpdateIntervall.getFloat(); } } + + public static class Bait { + public static PlayerControl bait; + public static Color color = new Color32(0, 247, 255, byte.MaxValue); + + public static bool highlightAllVents = false; + public static float reportDelay = 0f; + + public static bool reported = false; + + public static void clearAndReload() { + bait = null; + reported = false; + highlightAllVents = CustomOptionHolder.baitHighlightAllVents.getBool(); + reportDelay = CustomOptionHolder.baitReportDelay.getFloat(); + } + } } \ No newline at end of file diff --git a/TheOtherRoles/TheOtherRoles.csproj b/TheOtherRoles/TheOtherRoles.csproj index aa25c6e..cc663b5 100644 --- a/TheOtherRoles/TheOtherRoles.csproj +++ b/TheOtherRoles/TheOtherRoles.csproj @@ -1,13 +1,12 @@ netstandard2.1 - 2.7.3 + 2.8.0 TheOtherRoles Eisbison - 2021.6.15 $(DefineConstants);STEAM true