Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 24 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ Join our [Discord](https://discord.gg/ugyc4EVUYZ) if you have any problems or wa
| [Janitor](#janitor) | [Haunter](#haunter) | [Guardian Angel](#guardian-angel)| [Disperser](#disperser) |
| [Miner](#miner) | [Hunter](#hunter) | [Jester](#jester) | [Double Shot](#double-shot) |
| [Morphling](#morphling) | [Imitator](#imitator) | [Juggernaut](#juggernaut) | [Flash](#flash) |
| [Swooper](#swooper) | [Investigator](#investigator) | [Phantom](#phantom) | [Frosty](#frosty) |
| [Traitor](#traitor) | [Mayor](#mayor) | [Plaguebearer](#plaguebearer) | [Giant](#giant) |
| [Undertaker](#undertaker) | [Medic](#medic) | [Survivor](#survivor) | [Lovers](#lovers) |
| [Venerer](#venerer) | [Medium](#medium) | [The Glitch](#the-glitch) | [Multitasker](#multitasker)|
| [Warlock](#warlock) | [Mystic](#mystic) | [Vampire](#vampire) | [Radar](#radar) |
| | [Oracle](#oracle) | [Werewolf](#werewolf) | [Sleuth](#sleuth) |
| | [Prosecutor](#prosecutor) | | [Tiebreaker](#tiebreaker) |
| [Swooper](#swooper) | [Investigator](#investigator) | [Lawyer](#lawyer) | [Frosty](#frosty) |
| [Traitor](#traitor) | [Mayor](#mayor) | [Phantom](#phantom) | [Giant](#giant) |
| [Undertaker](#undertaker) | [Medic](#medic) | [Plaguebearer](#plaguebearer) | [Lovers](#lovers) |
| [Venerer](#venerer) | [Medium](#medium) | [Survivor](#survivor) | [Multitasker](#multitasker)|
| [Warlock](#warlock) | [Mystic](#mystic) | [The Glitch](#the-glitch) | [Radar](#radar) |
| | [Oracle](#oracle) | [Vampire](#vampire) | [Sleuth](#sleuth) |
| | [Prosecutor](#prosecutor) | [Werewolf](#werewolf) | [Tiebreaker](#tiebreaker) |
| | [Seer](#seer) | | [Torch](#torch) |
| | [Sheriff](#sheriff) | | [Underdog](#underdog) |
| | [Snitch](#snitch) | | |
Expand Down Expand Up @@ -1253,9 +1253,25 @@ However, if Lovers, or a Neutral Evil role wins the game, the survivor loses.
| Survivor | The percentage probability of the Survivor appearing | Percentage | 0% |
| Vest Cooldown | The cooldown of the Survivor's Vest button | Time | 25s |
| Vest Duration | How long The Survivor's Vest lasts | Time | 10s |
| Kill Cooldown Reset on Attack | The attackers kill cooldown after they attacked the veste Survivor | Time | 2.5s |
| Kill Cooldown Reset on Attack | The attackers kill cooldown after they attacked the vested Survivor | Time | 2.5s |
| Max Uses | The amount of times the Vest ability can be used | Number | 5 |

-----------------------
## Lawyer
### **Team: Neutral**
The Lawyer is a Neutral role which wins if their assigned defendant survives. If their defendant is exiled, they are also killed.\
The Lawyer can win with any team that does not explicitly win alone, as long as their defendant survives.

### Game Options
| Name | Description | Type | Default |
|----------|:-------------:|:------:|:------:|
| Lawyer | The percentage probability of the Lawyer appearing | Percentage | 0% |
| Lawyer Dies With Defendant | Whether the Lawyer dies when their defendant is exiled | Toggle | True |
| Evil Defendant Probability | The chances of the Lawyer's defendant being evil | Percentage | 20% |
| Neutral Roles Can Be Defendants | Whether neutral benign & evil roles can be defendants | Toggle | False |
| Lawyer And Defendant Can Talk | Whether the Lawyer and their defendant can chat outside of meetings | Toggle | False |
| Lawyer becomes on Defendant Dead | Which role the Lawyer becomes when their target dies | Crewmate / Amnesiac / Survivor / Jester | Crewmate |

-----------------------
## Doomsayer
### **Team: Neutral**
Expand Down
17 changes: 17 additions & 0 deletions source/Patches/AmongUsClient_OnGameEnd.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ public static void Prefix()
var exe = (Executioner)role;
losers.Add(exe.Player.GetDefaultOutfit().ColorId);
}
foreach (var role in Role.GetRoles(RoleEnum.Lawyer))
{
var lwyr = (Lawyer)role;
losers.Add(lwyr.Player.GetDefaultOutfit().ColorId);
}
foreach (var role in Role.GetRoles(RoleEnum.Jester))
{
var jest = (Jester)role;
Expand Down Expand Up @@ -285,6 +290,18 @@ public static void Prefix()
TempData.winners.Add(survWinData);
}
}
foreach (var role in Role.GetRoles(RoleEnum.Lawyer))
{
var lwyr = (Lawyer)role;
if (!lwyr.TargetVotedOut && !lwyr.Player.Data.IsDead)
{
var isImp = TempData.winners[0].IsImpostor;
var lwyrWinData = new WinningPlayerData(lwyr.Player.Data);
if (isImp) lwyrWinData.IsImpostor = true;
if (PlayerControl.LocalPlayer != lwyr.Player) lwyrWinData.IsYou = false;
TempData.winners.Add(lwyrWinData);
}
}
foreach (var role in Role.GetRoles(RoleEnum.GuardianAngel))
{
var ga = (GuardianAngel)role;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using HarmonyLib;

namespace TownOfUs.Modifiers.LoversMod
namespace TownOfUs.Patches
{
public static class Chat
{
Expand All @@ -23,8 +23,9 @@ public static bool Prefix(ChatController __instance, [HarmonyArgument(0)] Player
if (__instance != HudManager.Instance.Chat) return true;
var localPlayer = PlayerControl.LocalPlayer;
if (localPlayer == null) return true;
Boolean shouldSeeMessage = localPlayer.Data.IsDead || localPlayer.IsLover() ||
sourcePlayer.PlayerId == PlayerControl.LocalPlayer.PlayerId;
bool shouldSeeMessage = localPlayer.Data.IsDead || localPlayer.IsOtherLover(sourcePlayer)
|| localPlayer.IsLegalCounsel(sourcePlayer)
|| sourcePlayer.PlayerId == PlayerControl.LocalPlayer.PlayerId;
if (DateTime.UtcNow - MeetingStartTime < TimeSpan.FromSeconds(1))
{
return shouldSeeMessage;
Expand All @@ -38,7 +39,7 @@ public static class EnableChat
{
public static void Postfix(HudManager __instance)
{
if (PlayerControl.LocalPlayer.IsLover() & !__instance.Chat.isActiveAndEnabled)
if ((PlayerControl.LocalPlayer.HasLegalCounsel() || PlayerControl.LocalPlayer.IsLover()) & !__instance.Chat.isActiveAndEnabled)
__instance.Chat.SetVisible(true);
}
}
Expand Down
1 change: 1 addition & 0 deletions source/Patches/Colors.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class Colors {
// Neutral Colors
public readonly static Color Jester = new Color(1f, 0.75f, 0.8f, 1f);
public readonly static Color Executioner = new Color(0.55f, 0.25f, 0.02f, 1f);
public readonly static Color Lawyer = new Color(0.93f, 0.7f, 0.55f, 1f);
public readonly static Color Glitch = Color.green;
public readonly static Color Arsonist = new Color(1f, 0.3f, 0f);
public readonly static Color Phantom = new Color(0.4f, 0.16f, 0.38f, 1f);
Expand Down
8 changes: 8 additions & 0 deletions source/Patches/CustomGameOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using TownOfUs.CrewmateRoles.MediumMod;
using TownOfUs.CrewmateRoles.VampireHunterMod;
using TownOfUs.NeutralRoles.GuardianAngelMod;
using TownOfUs.NeutralRoles.LawyerMod;

namespace TownOfUs
{
Expand Down Expand Up @@ -62,6 +63,7 @@ public static class CustomGameOptions
public static int TransporterOn => (int)Generate.TransporterOn.Get();
public static int MediumOn => (int)Generate.MediumOn.Get();
public static int SurvivorOn => (int)Generate.SurvivorOn.Get();
public static int LawyerOn => (int)Generate.LawyerOn.Get();
public static int GuardianAngelOn => (int)Generate.GuardianAngelOn.Get();
public static int MysticOn => (int)Generate.MysticOn.Get();
public static int BlackmailerOn => (int)Generate.BlackmailerOn.Get();
Expand Down Expand Up @@ -151,6 +153,11 @@ public static class CustomGameOptions
public static OnTargetDead OnTargetDead => (OnTargetDead)Generate.OnTargetDead.Get();
public static bool ExecutionerButton => Generate.ExecutionerButton.Get();
public static bool ExecutionerTorment => Generate.ExecutionerTorment.Get();
public static OnDefendantDead OnDefendantDead => (OnDefendantDead)Generate.OnDefendantDead.Get();
public static bool LawyerDies => Generate.LawyerDies.Get();
public static int DefendantImpPercent => (int)Generate.DefendantImpPercent.Get();
public static bool NeutralDefendant => Generate.NeutralDefendant.Get();
public static bool LawyerCanTalkDefendant => Generate.LawyerCanTalkDefendant.Get();
public static bool SnitchSeesNeutrals => Generate.SnitchSeesNeutrals.Get();
public static int SnitchTasksRemaining => (int)Generate.SnitchTasksRemaining.Get();
public static bool SnitchSeesImpInMeeting => Generate.SnitchSeesImpInMeeting.Get();
Expand Down Expand Up @@ -358,6 +365,7 @@ public static class CustomGameOptions
public static int SeerCultistOn => (int)Generate.SeerCultistOn.Get();
public static int SheriffCultistOn => (int)Generate.SheriffCultistOn.Get();
public static int SurvivorCultistOn => (int)Generate.SurvivorCultistOn.Get();
public static int LawyerCultistOn => (int)Generate.LawyerCultistOn.Get();
public static int SpecialRoleCount => (int)Generate.NumberOfSpecialRoles.Get();
public static int MaxChameleons => (int)Generate.MaxChameleons.Get();
public static int MaxEngineers => (int)Generate.MaxEngineers.Get();
Expand Down
23 changes: 23 additions & 0 deletions source/Patches/CustomOption/Generate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public class Generate
public static CustomNumberOption AmnesiacOn;
public static CustomNumberOption GuardianAngelOn;
public static CustomNumberOption SurvivorOn;
public static CustomNumberOption LawyerOn;

public static CustomHeaderOption NeutralEvilRoles;
public static CustomNumberOption DoomsayerOn;
Expand Down Expand Up @@ -156,6 +157,7 @@ public class Generate
public static CustomNumberOption SeerCultistOn;
public static CustomNumberOption SheriffCultistOn;
public static CustomNumberOption SurvivorCultistOn;
public static CustomNumberOption LawyerCultistOn;
public static CustomNumberOption NumberOfSpecialRoles;
public static CustomNumberOption MaxChameleons;
public static CustomNumberOption MaxEngineers;
Expand Down Expand Up @@ -384,6 +386,13 @@ public class Generate
public static CustomNumberOption VestKCReset;
public static CustomNumberOption MaxVests;

public static CustomHeaderOption Lawyer;
public static CustomToggleOption LawyerDies;
public static CustomNumberOption DefendantImpPercent;
public static CustomToggleOption NeutralDefendant;
public static CustomToggleOption LawyerCanTalkDefendant;
public static CustomStringOption OnDefendantDead;

public static CustomHeaderOption GuardianAngel;
public static CustomNumberOption ProtectCd;
public static CustomNumberOption ProtectDuration;
Expand Down Expand Up @@ -583,6 +592,8 @@ public static void GenerateAll()
PercentFormat);
SurvivorOn = new CustomNumberOption(num++, MultiMenu.neutral, "<color=#FFE64DFF>Survivor</color>", 0f, 0f, 100f, 10f,
PercentFormat);
LawyerOn = new CustomNumberOption(num++, MultiMenu.neutral, "<color=#D2B48CFF>Lawyer</color>", 0f, 0f, 100f, 10f,
PercentFormat);

NeutralEvilRoles = new CustomHeaderOption(num++, MultiMenu.neutral, "Neutral Evil Roles");
DoomsayerOn = new CustomNumberOption(num++, MultiMenu.neutral, "<color=#00FF80FF>Doomsayer</color>", 0f, 0f, 100f, 10f,
Expand Down Expand Up @@ -718,6 +729,8 @@ public static void GenerateAll()
PercentFormat);
SurvivorCultistOn = new CustomNumberOption(num++, MultiMenu.main, "<color=#FFE64DFF>Survivor</color> (Cultist Mode)", 100f, 0f, 100f, 10f,
PercentFormat);
LawyerCultistOn = new CustomNumberOption(num++, MultiMenu.main, "<color=#D2B48CFF>Lawyer</color> (Cultist Mode)", 100f, 0f, 100f, 10f,
PercentFormat);
NumberOfSpecialRoles =
new CustomNumberOption(num++, MultiMenu.main, "Number Of Special Roles", 4, 0, 4, 1);
MaxChameleons =
Expand Down Expand Up @@ -1099,6 +1112,16 @@ public static void GenerateAll()
MaxVests =
new CustomNumberOption(num++, MultiMenu.neutral, "Maximum Number Of Vests", 5, 1, 15, 1);

Lawyer =
new CustomHeaderOption(num++, MultiMenu.neutral, "<color=#D2B48CFF>Lawyer</color>");
LawyerDies = new CustomToggleOption(num++, MultiMenu.neutral, "Lawyer Dies With Defendant");
DefendantImpPercent = new CustomNumberOption(num++, MultiMenu.neutral, "Killer Defendant Probability", 20f, 0f, 100f, 10f,
PercentFormat);
NeutralDefendant = new CustomToggleOption(num++, MultiMenu.neutral, "Neutral Evil Roles Can Be Defendants", false);
LawyerCanTalkDefendant = new CustomToggleOption(num++, MultiMenu.neutral, "Lawyer And Defendant Can Talk", false);
OnDefendantDead = new CustomStringOption(num++, MultiMenu.neutral, "Lawyer Becomes On Defendant Dead",
new[] { "Crew", "Amnesiac", "Survivor", "Jester" });

Doomsayer = new CustomHeaderOption(num++, MultiMenu.neutral, "<color=#00FF80FF>Doomsayer</color>");
ObserveCooldown =
new CustomNumberOption(num++, MultiMenu.neutral, "Observe Cooldown", 25f, 10f, 60f, 2.5f, CooldownFormat);
Expand Down
2 changes: 2 additions & 0 deletions source/Patches/CustomRPC.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public enum CustomRPC
SetCouple,
SetAssassin,
SetTarget,
SetDefendant,
SetGATarget,

SetPhantom,
Expand Down Expand Up @@ -83,6 +84,7 @@ public enum CustomRPC
SetHacked,

ExecutionerToJester,
LawyerToJester,
GAToSurv,

Start,
Expand Down
1 change: 1 addition & 0 deletions source/Patches/EndGamePatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ public static void Postfix(AmongUsClient __instance, [HarmonyArgument(0)] EndGam
else if (role.Value == RoleEnum.Trapper) { playerRole += "<color=#" + Patches.Colors.Trapper.ToHtmlStringRGBA() + ">Trapper</color> > "; }
else if (role.Value == RoleEnum.Survivor) { playerRole += "<color=#" + Patches.Colors.Survivor.ToHtmlStringRGBA() + ">Survivor</color> > "; }
else if (role.Value == RoleEnum.GuardianAngel) { playerRole += "<color=#" + Patches.Colors.GuardianAngel.ToHtmlStringRGBA() + ">Guardian Angel</color> > "; }
else if (role.Value == RoleEnum.Lawyer) { playerRole += "<color=#" + Patches.Colors.Lawyer.ToHtmlStringRGBA() + ">Lawyer</color> > "; }
else if (role.Value == RoleEnum.Mystic || role.Value == RoleEnum.CultistMystic) { playerRole += "<color=#" + Patches.Colors.Mystic.ToHtmlStringRGBA() + ">Mystic</color> > "; }
else if (role.Value == RoleEnum.Blackmailer) { playerRole += "<color=#" + Patches.Colors.Impostor.ToHtmlStringRGBA() + ">Blackmailer</color> > "; }
else if (role.Value == RoleEnum.Plaguebearer) { playerRole += "<color=#" + Patches.Colors.Plaguebearer.ToHtmlStringRGBA() + ">Plaguebearer</color> > "; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ public static void Remember(Amnesiac amneRole, PlayerControl other)

case RoleEnum.Jester:
case RoleEnum.Executioner:
case RoleEnum.Lawyer:
case RoleEnum.Arsonist:
case RoleEnum.Amnesiac:
case RoleEnum.Glitch:
Expand Down
8 changes: 5 additions & 3 deletions source/Patches/NeutralRoles/DoomsayerMod/MeetingStart.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ public static string PlayerReportFeedback(PlayerControl player)
|| player.Is(RoleEnum.Prosecutor) || player.Is(RoleEnum.Seer) || player.Is(RoleEnum.Transporter))
return $"You observe that {player.GetDefaultOutfit().PlayerName} spreads fear amonst the group";
else if (player.Is(RoleEnum.Engineer) || player.Is(RoleEnum.Escapist) || player.Is(RoleEnum.Grenadier)
|| player.Is(RoleEnum.GuardianAngel) || player.Is(RoleEnum.Medic) || player.Is(RoleEnum.Survivor))
|| player.Is(RoleEnum.GuardianAngel) || player.Is(RoleEnum.Medic) || player.Is(RoleEnum.Survivor)
|| player.Is(RoleEnum.Lawyer))
return $"You observe that {player.GetDefaultOutfit().PlayerName} hides to guard themself or others";
else if (player.Is(RoleEnum.Executioner) || player.Is(RoleEnum.Jester) || player.Is(RoleEnum.Mayor)
|| player.Is(RoleEnum.Swapper) || player.Is(RoleEnum.Traitor) || player.Is(RoleEnum.Veteran))
Expand Down Expand Up @@ -75,8 +76,9 @@ public static string RoleReportFeedback(PlayerControl player)
|| player.Is(RoleEnum.Prosecutor) || player.Is(RoleEnum.Seer) || player.Is(RoleEnum.Transporter))
return "(Arsonist, Miner, Plaguebearer, Prosecutor, Seer or Transporter)";
else if (player.Is(RoleEnum.Engineer) || player.Is(RoleEnum.Escapist) || player.Is(RoleEnum.Grenadier)
|| player.Is(RoleEnum.GuardianAngel) || player.Is(RoleEnum.Medic) || player.Is(RoleEnum.Survivor))
return "(Engineer, Escapist, Grenadier, Guardian Angel, Medic or Survivor)";
|| player.Is(RoleEnum.GuardianAngel) || player.Is(RoleEnum.Medic) || player.Is(RoleEnum.Survivor)
|| player.Is(RoleEnum.Lawyer))
return "(Engineer, Escapist, Grenadier, Guardian Angel, Medic, Lawyer or Survivor)";
else if (player.Is(RoleEnum.Executioner) || player.Is(RoleEnum.Jester) || player.Is(RoleEnum.Mayor)
|| player.Is(RoleEnum.Swapper) || player.Is(RoleEnum.Traitor) || player.Is(RoleEnum.Veteran))
return "(Executioner, Jester, Mayor, Swapper, Traitor or Veteran)";
Expand Down
Loading