diff --git a/CTA/CustomTeamAssigner/CustomRoles.cs b/CTA/CustomTeamAssigner/CustomRoles.cs
index 43f905769..d72134182 100644
--- a/CTA/CustomTeamAssigner/CustomRoles.cs
+++ b/CTA/CustomTeamAssigner/CustomRoles.cs
@@ -218,7 +218,7 @@ public enum CustomRoles
Marshall,
Mathematician,
Mayor,
- SabotageMaster, // Mechanic
+ Mechanic,
Medic,
Mediumshiper,
Merchant,
@@ -372,7 +372,7 @@ public enum CustomRoles
Spirit,
Spiritcaller,
Sprayer,
- DarkHide, // Stalker
+ Stalker, // Stalker
Starspawn,
Cultist,
Sunnyboy,
diff --git a/EHR.csproj b/EHR.csproj
index 04ad23bf5..54738d0e0 100644
--- a/EHR.csproj
+++ b/EHR.csproj
@@ -8,7 +8,7 @@
EHR
Gurge44
preview
- C:\Program Files\Epic Games\AmongUs
+ D:\SteamLibrary\steamapps\common\Among Us
true
True
$(MSBuildProjectName)
diff --git a/Modules/AFKDetector.cs b/Modules/AFKDetector.cs
index dbadf588a..ef9218d6b 100644
--- a/Modules/AFKDetector.cs
+++ b/Modules/AFKDetector.cs
@@ -81,6 +81,7 @@ public static class AFKDetector
{
Logger.SendInGame(Translator.GetString("AFKTooMany"));
PlayerData.Clear();
+ Utils.NotifyRoles(ForceLoop: true);
}
}
diff --git a/Modules/Utils.cs b/Modules/Utils.cs
index b3a1f0ee0..edf7c7112 100644
--- a/Modules/Utils.cs
+++ b/Modules/Utils.cs
@@ -2797,33 +2797,7 @@ public static class Utils
bool shouldSeeTargetAddons = seer.PlayerId == target.PlayerId || new[] { seer, target }.All(x => x.Is(Team.Impostor));
string targetRoleText =
- (!seer.IsAlive() && Options.GhostCanSeeOtherRoles.GetBool()) ||
- (seer.Is(CustomRoles.Mimic) && !target.IsAlive() && Options.MimicCanSeeDeadRoles.GetBool()) ||
- (target.Is(CustomRoles.Gravestone) && !target.IsAlive()) ||
- (Main.LoversPlayers.TrueForAll(x => x.PlayerId == seer.PlayerId || x.PlayerId == target.PlayerId) && Main.LoversPlayers.Count == 2 && Lovers.LoverKnowRoles.GetBool()) ||
- (seer.Is(CustomRoleTypes.Coven) && target.Is(CustomRoleTypes.Coven)) ||
- (seer.Is(CustomRoleTypes.Impostor) && target.Is(CustomRoleTypes.Impostor) && Options.ImpKnowAlliesRole.GetBool() && CustomTeamManager.ArentInCustomTeam(seer.PlayerId, target.PlayerId)) ||
- (seer.IsMadmate() && target.Is(CustomRoleTypes.Impostor) && Options.MadmateKnowWhosImp.GetBool()) ||
- (seer.Is(CustomRoleTypes.Impostor) && target.IsMadmate() && Options.ImpKnowWhosMadmate.GetBool()) ||
- (seer.Is(CustomRoles.Crewpostor) && target.Is(CustomRoleTypes.Impostor) && Options.CrewpostorKnowsAllies.GetBool()) ||
- (seer.Is(CustomRoles.Hypocrite) && target.Is(CustomRoleTypes.Impostor) && Hypocrite.KnowsAllies.GetBool()) ||
- (seer.Is(CustomRoleTypes.Impostor) && target.Is(CustomRoles.Hypocrite) && Hypocrite.AlliesKnowHypocrite.GetBool()) ||
- (seer.Is(CustomRoleTypes.Impostor) && target.Is(CustomRoles.Crewpostor) && Options.AlliesKnowCrewpostor.GetBool()) ||
- (seer.IsMadmate() && target.IsMadmate() && Options.MadmateKnowWhosMadmate.GetBool()) ||
- ((seer.Is(CustomRoles.Sidekick) || seer.Is(CustomRoles.Recruit) || seer.Is(CustomRoles.Jackal)) && (target.Is(CustomRoles.Sidekick) || target.Is(CustomRoles.Recruit) || target.Is(CustomRoles.Jackal))) ||
- (target.Is(CustomRoles.Workaholic) && Workaholic.WorkaholicVisibleToEveryone.GetBool()) ||
- (target.Is(CustomRoles.Doctor) && !target.HasEvilAddon() && Options.DoctorVisibleToEveryone.GetBool()) ||
- (target.Is(CustomRoles.Mayor) && Mayor.MayorRevealWhenDoneTasks.GetBool() && target.GetTaskState().IsTaskFinished) ||
- (Marshall.CanSeeMarshall(seer) && target.Is(CustomRoles.Marshall) && target.GetTaskState().IsTaskFinished) ||
- (Main.PlayerStates[target.PlayerId].deathReason == PlayerState.DeathReason.Vote && Options.SeeEjectedRolesInMeeting.GetBool()) ||
- (CustomTeamManager.AreInSameCustomTeam(seer.PlayerId, target.PlayerId) && CustomTeamManager.IsSettingEnabledForPlayerTeam(seer.PlayerId, CTAOption.KnowRoles)) ||
- Main.PlayerStates.Values.Any(x => x.Role.KnowRole(seer, target)) ||
- Markseeker.PlayerIdList.Any(x => Main.PlayerStates[x].Role is Markseeker { IsEnable: true, TargetRevealed: true } ms && ms.MarkedId == target.PlayerId) ||
- Options.CurrentGameMode is CustomGameMode.FFA or CustomGameMode.MoveAndStop or CustomGameMode.HotPotato or CustomGameMode.Speedrun ||
- (Options.CurrentGameMode == CustomGameMode.HideAndSeek && CustomHnS.IsRoleTextEnabled(seer, target)) ||
- (seer.IsRevealedPlayer(target) && !target.Is(CustomRoles.Trickster)) ||
- (seer.Is(CustomRoles.God) && God.KnowInfo.GetValue() == 2) ||
- target.Is(CustomRoles.GM)
+ KnowsTargetRole(seer, target)
? $"{target.GetDisplayRoleName(seeTargetBetrayalAddons: shouldSeeTargetAddons)}{GetProgressText(target)}\r\n"
: string.Empty;
@@ -2942,7 +2916,7 @@ public static class Utils
additionalSuffixes.Add(AFKDetector.GetSuffix(seer, target));
if (!forMeeting && Options.CurrentGameMode == CustomGameMode.Standard && Main.Invisible.Contains(target.PlayerId))
- additionalSuffixes.Add(ColorString(Palette.White_75Alpha, GetString("Invisible")));
+ additionalSuffixes.Add(ColorString(Palette.White_75Alpha, "\n" + GetString("Invisible")));
TargetSuffix.Append(BuildSuffix(seer, target, meeting: forMeeting));
@@ -3012,6 +2986,37 @@ public static class Utils
return hasValue;
}
+ public static bool KnowsTargetRole(PlayerControl seer, PlayerControl target)
+ {
+ return (!seer.IsAlive() && Options.GhostCanSeeOtherRoles.GetBool()) ||
+ (seer.Is(CustomRoles.Mimic) && !target.IsAlive() && Options.MimicCanSeeDeadRoles.GetBool()) ||
+ (target.Is(CustomRoles.Gravestone) && !target.IsAlive()) ||
+ (Main.LoversPlayers.TrueForAll(x => x.PlayerId == seer.PlayerId || x.PlayerId == target.PlayerId) && Main.LoversPlayers.Count == 2 && Lovers.LoverKnowRoles.GetBool()) ||
+ (seer.Is(CustomRoleTypes.Coven) && target.Is(CustomRoleTypes.Coven)) ||
+ (seer.Is(CustomRoleTypes.Impostor) && target.Is(CustomRoleTypes.Impostor) && Options.ImpKnowAlliesRole.GetBool() && CustomTeamManager.ArentInCustomTeam(seer.PlayerId, target.PlayerId)) ||
+ (seer.IsMadmate() && target.Is(CustomRoleTypes.Impostor) && Options.MadmateKnowWhosImp.GetBool()) ||
+ (seer.Is(CustomRoleTypes.Impostor) && target.IsMadmate() && Options.ImpKnowWhosMadmate.GetBool()) ||
+ (seer.Is(CustomRoles.Crewpostor) && target.Is(CustomRoleTypes.Impostor) && Options.CrewpostorKnowsAllies.GetBool()) ||
+ (seer.Is(CustomRoles.Hypocrite) && target.Is(CustomRoleTypes.Impostor) && Hypocrite.KnowsAllies.GetBool()) ||
+ (seer.Is(CustomRoleTypes.Impostor) && target.Is(CustomRoles.Hypocrite) && Hypocrite.AlliesKnowHypocrite.GetBool()) ||
+ (seer.Is(CustomRoleTypes.Impostor) && target.Is(CustomRoles.Crewpostor) && Options.AlliesKnowCrewpostor.GetBool()) ||
+ (seer.IsMadmate() && target.IsMadmate() && Options.MadmateKnowWhosMadmate.GetBool()) ||
+ ((seer.Is(CustomRoles.Sidekick) || seer.Is(CustomRoles.Recruit) || seer.Is(CustomRoles.Jackal)) && (target.Is(CustomRoles.Sidekick) || target.Is(CustomRoles.Recruit) || target.Is(CustomRoles.Jackal))) ||
+ (target.Is(CustomRoles.Workaholic) && Workaholic.WorkaholicVisibleToEveryone.GetBool()) ||
+ (target.Is(CustomRoles.Doctor) && !target.HasEvilAddon() && Options.DoctorVisibleToEveryone.GetBool()) ||
+ (target.Is(CustomRoles.Mayor) && Mayor.MayorRevealWhenDoneTasks.GetBool() && target.GetTaskState().IsTaskFinished) ||
+ (Marshall.CanSeeMarshall(seer) && target.Is(CustomRoles.Marshall) && target.GetTaskState().IsTaskFinished) ||
+ (Main.PlayerStates[target.PlayerId].deathReason == PlayerState.DeathReason.Vote && Options.SeeEjectedRolesInMeeting.GetBool()) ||
+ (CustomTeamManager.AreInSameCustomTeam(seer.PlayerId, target.PlayerId) && CustomTeamManager.IsSettingEnabledForPlayerTeam(seer.PlayerId, CTAOption.KnowRoles)) ||
+ Main.PlayerStates.Values.Any(x => x.Role.KnowRole(seer, target)) ||
+ Markseeker.PlayerIdList.Any(x => Main.PlayerStates[x].Role is Markseeker { IsEnable: true, TargetRevealed: true } ms && ms.MarkedId == target.PlayerId) ||
+ Options.CurrentGameMode is CustomGameMode.FFA or CustomGameMode.MoveAndStop or CustomGameMode.HotPotato or CustomGameMode.Speedrun ||
+ (Options.CurrentGameMode == CustomGameMode.HideAndSeek && CustomHnS.IsRoleTextEnabled(seer, target)) ||
+ (seer.IsRevealedPlayer(target) && !target.Is(CustomRoles.Trickster)) ||
+ (seer.Is(CustomRoles.God) && God.KnowInfo.GetValue() == 2) ||
+ target.Is(CustomRoles.GM);
+ }
+
public static void MarkEveryoneDirtySettings()
{
PlayerGameOptionsSender.SetDirtyToAll();
@@ -3238,6 +3243,8 @@ public static class Utils
public static void AddAbilityCD(CustomRoles role, byte playerId, bool includeDuration = true)
{
+ if (Options.UsePhantomBasis.GetBool() && (!role.IsNK() || Options.UsePhantomBasisForNKs.GetBool()) && role.SimpleAbilityTrigger()) return;
+
if (role.UsesPetInsteadOfKill())
{
var kcd = (int)Math.Round(Main.AllPlayerKillCooldown.TryGetValue(playerId, out float killCd) ? killCd : Options.AdjustedDefaultKillCooldown);
diff --git a/Patches/ChatCommandPatch.cs b/Patches/ChatCommandPatch.cs
index 053426e9a..efe4c7fc1 100644
--- a/Patches/ChatCommandPatch.cs
+++ b/Patches/ChatCommandPatch.cs
@@ -220,6 +220,7 @@ internal static class ChatCommands
new(["imitate", "имитировать", "模仿"], "{id}", GetString("CommandDescription.Imitate"), Command.UsageLevels.Everyone, Command.UsageTimes.InMeeting, ImitateCommand, true, true, [GetString("CommandArgs.Imitate.Id")]),
new(["retribute", "воздать", "报复"], "{id}", GetString("CommandDescription.Retribute"), Command.UsageLevels.Everyone, Command.UsageTimes.InMeeting, RetributeCommand, true, true, [GetString("CommandArgs.Retribute.Id")]),
new(["revive", "воскрешение", "воскрешать", "复活", "reviver"], "{id}", GetString("CommandDescription.Revive"), Command.UsageLevels.Host, Command.UsageTimes.InGame, ReviveCommand, true, false, [GetString("CommandArgs.Revive.Id")]),
+ new(["select", "выбратьигрока", "选择玩家", "selecionar"], "{id} {role}", GetString("CommandDescription.Select"), Command.UsageLevels.Everyone, Command.UsageTimes.InMeeting, SelectCommand, true, true, [GetString("CommandArgs.Select.Id"), GetString("CommandArgs.Select.Role")]),
new(["confirmauth"], "{uuid}", GetString("CommandDescription.ConfirmAuth"), Command.UsageLevels.Everyone, Command.UsageTimes.Always, ConfirmAuthCommand, true, false, [GetString("CommandArgs.ConfirmAuth.UUID")]),
diff --git a/Patches/MeetingHudPatch.cs b/Patches/MeetingHudPatch.cs
index 2d7534a03..bd0f4294b 100644
--- a/Patches/MeetingHudPatch.cs
+++ b/Patches/MeetingHudPatch.cs
@@ -661,7 +661,7 @@ internal static class MeetingHudStartPatch
{
private static void NotifyRoleSkillOnMeetingStart()
{
- if (!AmongUsClient.Instance.AmHost) return;
+ if (!AmongUsClient.Instance.AmHost || GameStates.IsEnded) return;
List msgToSend = [];
diff --git a/Patches/PlayerControlPatch.cs b/Patches/PlayerControlPatch.cs
index a9dbb81bf..e69b0d507 100644
--- a/Patches/PlayerControlPatch.cs
+++ b/Patches/PlayerControlPatch.cs
@@ -1846,7 +1846,7 @@ internal static class FixedUpdatePatch
additionalSuffixes.Add(AFKDetector.GetSuffix(seer, target));
if (!GameStates.IsMeeting && Options.CurrentGameMode == CustomGameMode.Standard && Main.Invisible.Contains(target.PlayerId) && (self || (seer.IsImpostor() && target.IsImpostor())))
- additionalSuffixes.Add(ColorString(Palette.White_75Alpha, GetString("Invisible")));
+ additionalSuffixes.Add(ColorString(Palette.White_75Alpha, "\n" + GetString("Invisible")));
switch (target.GetCustomRole())
{
@@ -2042,7 +2042,7 @@ internal static class FixedUpdatePatch
if (Suffix.ToString() != string.Empty)
{
- offset += moveandstop ? 0.15f : 0.1f;
+ offset += moveandstop ? 0.15f : 0.2f;
offset += moveandstop ? 0f : Suffix.ToString().Count(x => x == '\n') * 0.15f;
}
diff --git a/Resources/Lang/en_US.json b/Resources/Lang/en_US.json
index 1e87b7a27..343adf784 100644
--- a/Resources/Lang/en_US.json
+++ b/Resources/Lang/en_US.json
@@ -2490,6 +2490,7 @@
"CommandDescription.Retribute": "Guess who killed the player you camped as the Retributionist",
"CommandDescription.ConfirmAuth": "Command required to register a new EHR account",
"CommandDescription.Revive": "Revives a dead player. Requires special access or No Game End enabled.",
+ "CommandDescription.Select": "Select your impostor partner and their role.",
"CommandArgs.ChangeSetting.Name": "The setting's name to change (leave blank to view all settings)",
"CommandArgs.ChangeSetting.UnknownValue": "(leave blank to view what to put here)",
"CommandArgs.Rename.Name": "Your new name",
@@ -2583,6 +2584,8 @@
"CommandArgs.Retribute.Id": "The potential killer's ID to guess",
"CommandArgs.ConfirmAuth.UUID": "The unique token provided by the server",
"CommandArgs.Revive.Id": "The dead player's ID to revive",
+ "CommandArgs.Select.Id": "The player's ID to select as your impostor partner",
+ "CommandArgs.Select.Role": "The role to select for your impostor partner",
"Commands.ChangeSettingHelp": "Arguments:\\n- map (theskeld/mirahq/polus/dlekseht/airship/thefungle/custom)\\n- impostors (number)\\n- players (number)\\n- recommended (on/off)\\n- confirmejects (on/off)\\n- emergencymeetings (number)\\n- anonymousvotes (on/off)\\n- emergencycooldown (number)\\n- discussiontime (number)\\n- votingtime (number)\\n- playerspeed (float)\\n- crewmatevision (float)\\n- impostorvision (float)\\n- killcooldown (float)\\n- killdistance (short/medium/long/custom)\\n- taskbarupdates (always/meetings/never)\\n- visualtasks (on/off)\\n- commontasks (number)\\n- longtasks (number)\\n- shorttasks (number)\\n- scientistcount (number)\\n- scientistchance (number)\\n- vitalsdisplaycooldown (float)\\n- batteryduration (float)\\n- engineercount (number)\\n- engineerchance (number)\\n- ventusecooldown (float)\\n- maxtimeinvents (float)\\n- guardianangelcount (number)\\n- guardianangelchance (number)\\n- protectcooldown (float)\\n- protectduration (float)\\n- protectvisibletoimpostors (on/off)\\n- shapeshiftercount (number)\\n- shapeshifterchance (number)\\n- shapeshiftduration (float)\\n- shapeshiftcooldown (float)\\n- leaveshapeshiftevidence (on/off)\\n- phantomcount (number)\\n- phantomchance (number)\\n- inviscooldown (float)\\n- invisduration (float)\\n- noisemakercount (number)\\n- noisemakerchance (number)\\n- noisemakerimpostoralert (on/off)\\n- noisemakeralertduration (number)\\n- trackercount (number)\\n- trackerchance (number)\\n- trackduration (float)\\n- trackcooldown (float)\\n- trackdelay (float)\\n- ghostdotasks (on/off)\\n\\nNotes:\\n1. Upper and lowercase matters\\n2. Where it says custom, you obviously put a number argument after it\\n3. A float is a single precision floating number, like 1.7\\n4. \"ghostdotasks\" causes issues if you set it\\n5. Example uses:\\n - \"/cs map polus\"\\n - \"/cs killdistance custom 4\"\\n - \"/cs trackdelay 1,7\"\\n - \"/cs confirmejects on\"",
"AddTagSuccess": "<#00ffa5>✓ Suceessfully created the tag {0} for {1}. If you want to change it, just use this command again and it will override the current tag. To delete it, simply type <#00a5ff>/deletetag {2}!",
"DeleteTagSuccess": "<#00ffa5>✓ Successfully deleted {0}'s tag.",
@@ -9007,6 +9010,7 @@
"Postponer": "Postponer",
"PostponerInfo": "Postpone Dead Body Spawning",
"PostponerInfoLong": "(Impostors):\\nAs the Postponer, when you kill, no dead body spawns instantly. Instead, it will spawn after a delay (in the same place as the murder).",
+ "Postponer.BodyDelay": "Body Spawm Delay",
"Tree": "Tree",
"TreeInfo": "You are a Tree",
"TreeInfoLong": "(Crewmates):\\nAs a Tree, you can pet to act like one (become anonymous and invisible). After a few seconds, you will fall down, killing or stunning everyone nearby, and making you visible again.",
diff --git a/Roles/Crewmate/Captain.cs b/Roles/Crewmate/Captain.cs
index 8fea21cc9..2fb31bda1 100644
--- a/Roles/Crewmate/Captain.cs
+++ b/Roles/Crewmate/Captain.cs
@@ -63,7 +63,7 @@ public class Captain : RoleBase
var room = pc.GetPlainShipRoom();
- if (room != null && (TargetRooms.Count == 0 || TargetRooms[^1] != room.RoomId))
+ if (room != null && room.RoomId != SystemTypes.Hallway && (TargetRooms.Count == 0 || TargetRooms[^1] != room.RoomId))
TargetRooms.Add(room.RoomId);
}
@@ -73,7 +73,7 @@ public class Captain : RoleBase
LateTask.New(() =>
{
- string msg = string.Format(Translator.GetString("Captain.TargetInfo"), TargetId.ColoredPlayerName(), string.Join(" ➔ ", TargetRooms.ConvertAll(x => Translator.GetString(x.ToString()))));
+ string msg = string.Format(Translator.GetString("Captain.TargetInfo"), TargetId.ColoredPlayerName(), string.Join(" ➡ ", TargetRooms.ConvertAll(x => Translator.GetString(x.ToString()))));
Utils.SendMessage(msg, CaptainId, CustomRoles.Captain.ToColoredString());
TargetRooms = [];
}, 10f, "Captain Message");
@@ -110,6 +110,6 @@ public class Captain : RoleBase
public override string GetSuffix(PlayerControl seer, PlayerControl target, bool hud = false, bool meeting = false)
{
if (seer.PlayerId != CaptainId || seer.PlayerId != target.PlayerId || (seer.IsModdedClient() && !hud) || meeting) return string.Empty;
- return string.Format(Translator.GetString("Captain.Suffix"), LastNotify);
+ return string.Format(Translator.GetString("Captain.Suffix"), string.IsNullOrEmpty(LastNotify) ? Translator.GetString("None") : LastNotify);
}
}
\ No newline at end of file
diff --git a/Roles/Crewmate/Inquisitor.cs b/Roles/Crewmate/Inquisitor.cs
index b37ce6523..5a7e4bc55 100644
--- a/Roles/Crewmate/Inquisitor.cs
+++ b/Roles/Crewmate/Inquisitor.cs
@@ -43,7 +43,7 @@ public class Inquisitor : RoleBase
if (voter == null || target == null || voter.PlayerId == target.PlayerId || Main.DontCancelVoteList.Contains(voter.PlayerId)) return false;
PlayerControl[] players = ExcludeDeadPlayers.GetBool() ? Main.AllAlivePlayerControls : Main.AllPlayerControls;
- List<(byte Id, CustomRoles Role)> knownRoles = Main.PlayerStates.Values.SelectMany(s => from pc in players where s.Role.KnowRole(target, pc) select (pc.PlayerId, pc.GetCustomRole())).DistinctBy(x => x.PlayerId).ToList();
+ List<(byte Id, CustomRoles Role)> knownRoles = [.. from pc in players where Utils.KnowsTargetRole(target, pc) select (pc.PlayerId, pc.GetCustomRole())];
string result;
diff --git a/Roles/Crewmate/Tree.cs b/Roles/Crewmate/Tree.cs
index 281fe69aa..6d79470b2 100644
--- a/Roles/Crewmate/Tree.cs
+++ b/Roles/Crewmate/Tree.cs
@@ -25,7 +25,7 @@ public class Tree : RoleBase
public override void SetupCustomOption()
{
StartSetup(655100)
- .AutoSetupOption(ref TreeSpriteVisible, true)
+ .AutoSetupOption(ref TreeSpriteVisible, false)
.AutoSetupOption(ref FallDelay, 5, new IntegerValueRule(1, 60, 1), OptionFormat.Seconds)
.AutoSetupOption(ref AbilityUseLimit, 1f, new FloatValueRule(0, 20, 0.05f), OptionFormat.Times)
.AutoSetupOption(ref AbilityUseGainWithEachTaskCompleted, 0.5f, new FloatValueRule(0f, 5f, 0.05f), OptionFormat.Times)
@@ -56,8 +56,14 @@ public class Tree : RoleBase
pc.MarkDirtySettings();
bool treeSpriteVisible = TreeSpriteVisible.GetBool();
- if (treeSpriteVisible) TreeSpriteActive = true;
- else pc.RpcMakeInvisible();
+
+ if (treeSpriteVisible)
+ {
+ TreeSpriteActive = true;
+ Utils.NotifyRoles(SpecifyTarget: pc);
+ }
+ else
+ pc.RpcMakeInvisible();
LateTask.New(() =>
{
@@ -66,7 +72,11 @@ public class Tree : RoleBase
Main.AllPlayerSpeed[pc.PlayerId] = Main.RealOptionsData.GetFloat(FloatOptionNames.PlayerSpeedMod);
pc.MarkDirtySettings();
- if (treeSpriteVisible) TreeSpriteActive = false;
+ if (treeSpriteVisible)
+ {
+ TreeSpriteActive = false;
+ Utils.NotifyRoles(SpecifyTarget: pc);
+ }
else pc.RpcMakeVisible();
int chance = FallKillChance.GetInt();
diff --git a/Roles/Impostor/Ambusher.cs b/Roles/Impostor/Ambusher.cs
index 88d4fd0a6..0a7ab4e2e 100644
--- a/Roles/Impostor/Ambusher.cs
+++ b/Roles/Impostor/Ambusher.cs
@@ -117,9 +117,10 @@ public class Ambusher : RoleBase
if (!DontCheck)
{
- var pos = pc.Pos();
- var radius = FollowRadius.GetFloat();
- var closestPlayer = Main.AllAlivePlayerControls.Without(pc).Select(x => (pc: x, distance: Vector2.Distance(x.Pos(), pos))).Where(x => x.distance <= radius).MinBy(x => x.distance).pc;
+ Vector2 pos = pc.Pos();
+ float radius = FollowRadius.GetFloat();
+ (PlayerControl pc, float distance)[] nearPlayers = Main.AllAlivePlayerControls.Without(pc).Select(x => (pc: x, distance: Vector2.Distance(x.Pos(), pos))).Where(x => x.distance <= radius).ToArray();
+ PlayerControl closestPlayer = nearPlayers.Length == 0 ? null : nearPlayers.MinBy(x => x.distance).pc;
if (closestPlayer == null)
{
@@ -169,11 +170,12 @@ public class Ambusher : RoleBase
Count = 0;
Utils.NotifyRoles(SpecifySeer: pc, SpecifyTarget: pc);
+ if (pc.AmOwner) Utils.DirtyName.Add(pc.PlayerId);
}
public override void OnGlobalFixedUpdate(PlayerControl pc, bool lowLoad)
{
- if (!lowLoad && FragilePlayers.TryGetValue(pc.PlayerId, out var endTS) && Utils.TimeStamp >= endTS)
+ if (!lowLoad && FragilePlayers.TryGetValue(pc.PlayerId, out long endTS) && Utils.TimeStamp >= endTS)
FragilePlayers.Remove(pc.PlayerId);
}
diff --git a/Roles/Impostor/Loner.cs b/Roles/Impostor/Loner.cs
index 6369fcb9a..a4f7bb681 100644
--- a/Roles/Impostor/Loner.cs
+++ b/Roles/Impostor/Loner.cs
@@ -40,6 +40,7 @@ public class Loner : RoleBase
PickedPlayer = target.PlayerId;
PickedRole = Enum.GetValues().Where(x => x.IsImpostor() && !x.IsVanilla() && !CustomRoleSelector.RoleResult.ContainsValue(x) && x.GetMode() != 0).RandomElement();
+ if (PickedRole == CustomRoles.Crewmate) PickedRole = CustomRoles.ImpostorEHR;
Utils.SendMessage("\n", shapeshifter.PlayerId, string.Format(Translator.GetString("Loner.Picked"), PickedPlayer.ColoredPlayerName(), PickedRole.ToColoredString()));
}