diff --git a/GameMode/SpeedrunManager.cs b/GameMode/SpeedrunManager.cs index a6d5f36a6..a4492626f 100644 --- a/GameMode/SpeedrunManager.cs +++ b/GameMode/SpeedrunManager.cs @@ -52,7 +52,7 @@ namespace EHR if (TaskFinishWins.GetBool()) return; CanKill.Add(pc.PlayerId); - // pc.ChangeRoleBasis(RoleTypes.Impostor); + pc.RpcChangeRoleBasis(CustomRoles.Runner); pc.Notify(Translator.GetString("Speedrun_CompletedTasks")); } diff --git a/Modules/CustomRolesHelper.cs b/Modules/CustomRolesHelper.cs index efe0ffd06..85a10c5df 100644 --- a/Modules/CustomRolesHelper.cs +++ b/Modules/CustomRolesHelper.cs @@ -29,8 +29,6 @@ internal static class CustomRolesHelper CustomRoles.Evolver, CustomRoles.ToiletMaster, CustomRoles.Telekinetic, - CustomRoles.Necromancer, - CustomRoles.Deathknight, CustomRoles.Dad, CustomRoles.Whisperer, @@ -42,13 +40,6 @@ internal static class CustomRolesHelper CustomRoles.Dasher ]; - // private static readonly List ExperimentalRoleList = - // [ - // CustomRoles.Shifter - // ]; - // - // public static bool IsExperimental(this CustomRoles role) => ExperimentalRoleList.Contains(role); - public static bool IsForOtherGameMode(this CustomRoles role) => HnSManager.AllHnSRoles.Contains(role) || role is CustomRoles.KB_Normal or CustomRoles.Killer or @@ -274,6 +265,7 @@ internal static class CustomRolesHelper CustomRoles.BallLightning => CustomRoles.Impostor, CustomRoles.Greedier => CustomRoles.Impostor, CustomRoles.Workaholic => CustomRoles.Engineer, + CustomRoles.Amnesiac => Amnesiac.RoleBasis.GetValue() == 0 ? CustomRoles.Engineer : CustomRoles.Crewmate, CustomRoles.Speedrunner => CustomRoles.Crewmate, CustomRoles.CursedWolf => CustomRoles.Impostor, CustomRoles.Collector => CustomRoles.Crewmate, @@ -301,7 +293,6 @@ internal static class CustomRolesHelper CustomRoles.Deathpact => CustomRoles.Shapeshifter, CustomRoles.Bloodhound => CustomRoles.Crewmate, CustomRoles.Tracker => CustomRoles.Crewmate, - CustomRoles.Deathknight => CustomRoles.Crewmate, CustomRoles.Merchant => CustomRoles.Crewmate, CustomRoles.Lookout => CustomRoles.Crewmate, CustomRoles.Guardian => CustomRoles.Crewmate, @@ -388,7 +379,6 @@ internal static class CustomRolesHelper CustomRoles.Crusader => UsePets && Crusader.UsePet.GetBool() ? RoleTypes.GuardianAngel : RoleTypes.Impostor, CustomRoles.CopyCat => UsePets && CopyCat.UsePet.GetBool() ? RoleTypes.GuardianAngel : RoleTypes.Impostor, CustomRoles.Refugee => RoleTypes.Impostor, - CustomRoles.Amnesiac => RoleTypes.Impostor, CustomRoles.Agitater => RoleTypes.Impostor, CustomRoles.Monarch => UsePets && Monarch.UsePet.GetBool() ? RoleTypes.GuardianAngel : RoleTypes.Impostor, CustomRoles.Deputy => UsePets && Deputy.UsePet.GetBool() ? RoleTypes.GuardianAngel : RoleTypes.Impostor, @@ -468,6 +458,7 @@ internal static class CustomRolesHelper CustomRoles.RuthlessRomantic => RoleTypes.Impostor, CustomRoles.Succubus => RoleTypes.Impostor, CustomRoles.Necromancer => RoleTypes.Impostor, + CustomRoles.Deathknight => RoleTypes.Impostor, CustomRoles.Virus => RoleTypes.Impostor, CustomRoles.Farseer => UsePets && Farseer.UsePet.GetBool() ? RoleTypes.GuardianAngel : RoleTypes.Impostor, CustomRoles.Ritualist => RoleTypes.Impostor, @@ -706,11 +697,6 @@ internal static class CustomRolesHelper CustomRoles.Crusader when Crusader.UsePet.GetBool() => true, CustomRoles.Witness when Options.WitnessUsePet.GetBool() => true, - CustomRoles.Refugee => true, - CustomRoles.Necromancer => true, - CustomRoles.Deathknight => true, - CustomRoles.Sidekick => true, - // Speedrun CustomRoles.Runner => true, @@ -959,7 +945,7 @@ internal static class CustomRolesHelper public static RoleTypes GetRoleTypes(this CustomRoles role) { - if (Enum.TryParse(role.GetVNRole(checkDesyncRole: true).ToString(), ignoreCase: true, out var type)) return type; + if (Enum.TryParse(role.GetVNRole(checkDesyncRole: true).ToString().Replace("EHR", ""), ignoreCase: true, out var type)) return type; return role.IsImpostor() ? RoleTypes.Impostor : RoleTypes.Crewmate; } diff --git a/Modules/ExtendedPlayerControl.cs b/Modules/ExtendedPlayerControl.cs index 65033140c..3bd00a51c 100644 --- a/Modules/ExtendedPlayerControl.cs +++ b/Modules/ExtendedPlayerControl.cs @@ -279,13 +279,17 @@ static class ExtendedPlayerControl var newRoleType = newCustomRole.GetRoleTypes(); RoleTypes remeberRoleType; + if (Options.CurrentGameMode == CustomGameMode.Speedrun && newCustomRole == CustomRoles.Runner) + newRoleType = SpeedrunManager.CanKill.Contains(player.PlayerId) ? RoleTypes.Impostor : RoleTypes.Crewmate; + // Desync role to normal role if (playerRole.IsDesyncRole() && !newCustomRole.IsDesyncRole()) { foreach (var seer in Main.AllPlayerControls) { var isSelf = player.PlayerId == seer.PlayerId; - if (!isSelf && seer.HasDesyncRole() && !(seer.AmOwner || seer.IsModClient())) remeberRoleType = newCustomRole.GetVNRole() is CustomRoles.Noisemaker ? RoleTypes.Noisemaker : RoleTypes.Scientist; + if (!isSelf && seer.HasDesyncRole() && !(seer.AmOwner || seer.IsModClient())) + remeberRoleType = newCustomRole.GetVNRole() is CustomRoles.Noisemaker ? RoleTypes.Noisemaker : RoleTypes.Scientist; else remeberRoleType = newRoleType; SelectRolesPatch.RpcSetRoleReplacer.RoleMap[(seer.PlayerId, playerId)] = (remeberRoleType, newCustomRole); @@ -305,9 +309,7 @@ static class ExtendedPlayerControl // For Desync Shapeshifter if (newCustomRole.GetDYRole() is RoleTypes.Shapeshifter) - { remeberRoleType = RoleTypes.Shapeshifter; - } } else { @@ -330,8 +332,7 @@ static class ExtendedPlayerControl { remeberRoleType = SelectRolesPatch.RpcSetRoleReplacer.RoleMap[(seer.PlayerId, playerId)].roleType; } - else - remeberRoleType = newRoleType; + else remeberRoleType = newRoleType; SelectRolesPatch.RpcSetRoleReplacer.RoleMap[(seer.PlayerId, playerId)] = (remeberRoleType, newCustomRole); player.RpcSetRoleDesync(remeberRoleType, seer.GetClientId()); @@ -344,8 +345,8 @@ static class ExtendedPlayerControl { foreach (var target in Main.AllPlayerControls) { - SelectRolesPatch.RpcSetRoleReplacer.RoleMap.TryGetValue((seer.PlayerId, target.PlayerId), out var map); - Logger.Info($"seer {seer.Data?.PlayerName}-{seer.PlayerId}, target {target.Data?.PlayerName}-{target.PlayerId} => {map.roleType}, {map.customRole}", "Role Map"); + if (SelectRolesPatch.RpcSetRoleReplacer.RoleMap.TryGetValue((seer.PlayerId, target.PlayerId), out var map)) + Logger.Info($"seer {seer.Data?.PlayerName}-{seer.PlayerId}, target {target.Data?.PlayerName}-{target.PlayerId} => {map.roleType}, {map.customRole}", "Role Map"); } } } diff --git a/Modules/GameOptionsSender/PlayerGameOptionsSender.cs b/Modules/GameOptionsSender/PlayerGameOptionsSender.cs index de7b8d953..c30e6138b 100644 --- a/Modules/GameOptionsSender/PlayerGameOptionsSender.cs +++ b/Modules/GameOptionsSender/PlayerGameOptionsSender.cs @@ -231,7 +231,7 @@ public sealed class PlayerGameOptionsSender(PlayerControl player) : GameOptionsS if (role.IsDesyncRole() && role.IsCrewmate() && !CrewmateVanillaRoles.NoiseMakerImpostorAlert.GetBool()) AURoleOptions.NoisemakerImpostorAlert = true; else AURoleOptions.NoisemakerImpostorAlert = CrewmateVanillaRoles.NoiseMakerImpostorAlert.GetBool(); - // if (Shifter.WasShifter.Contains(player.PlayerId) && role.IsImpostor()) opt.SetVision(true); + if (Shifter.WasShifter.Contains(player.PlayerId) && role.IsImpostor()) opt.SetVision(true); Main.PlayerStates[player.PlayerId].Role.ApplyGameOptions(opt, player.PlayerId); diff --git a/Modules/GameState.cs b/Modules/GameState.cs index df705620d..2bfddb57d 100644 --- a/Modules/GameState.cs +++ b/Modules/GameState.cs @@ -88,7 +88,7 @@ public class PlayerState(byte playerId) public bool IsBlackOut { get; set; } public bool IsSuicide => deathReason == DeathReason.Suicide; - public TaskState TaskState { get; } = new(); + public TaskState TaskState { get; set; } = new(); public void SetMainRole(CustomRoles role) { @@ -109,6 +109,9 @@ public class PlayerState(byte playerId) SubRoles.ForEach(SetAddonCountTypes); + if (!Player.HasKillButton() && role == CustomRoles.Refugee) + Player.RpcChangeRoleBasis(CustomRoles.Refugee); + Role = role.GetRoleClass(); if (!role.RoleExist(countDead: true)) diff --git a/Modules/Utils.cs b/Modules/Utils.cs index fa12bca07..cca1cbf1a 100644 --- a/Modules/Utils.cs +++ b/Modules/Utils.cs @@ -665,7 +665,7 @@ public static class Utils case CustomGameMode.HideAndSeek: return HnSManager.HasTasks(p); } - // if (Shifter.ForceDisableTasks(p.PlayerId)) return false; + if (false) return false; var role = States.MainRole; switch (role) diff --git a/Patches/OnGameStartedPatch.cs b/Patches/OnGameStartedPatch.cs index 5c2835848..e07f2e38e 100644 --- a/Patches/OnGameStartedPatch.cs +++ b/Patches/OnGameStartedPatch.cs @@ -246,12 +246,6 @@ internal class ChangeRoleSettings Revolutionist.CurrentDrawTarget = byte.MaxValue; Main.PlayerColors = []; - if (Options.CurrentGameMode == CustomGameMode.Speedrun && !Options.UsePets.GetBool()) - { - Options.UsePets.SetValue(1); - PlayerControl.LocalPlayer.ShowPopUp(GetString("PetsForceEnabled")); - } - RPC.SyncAllPlayerNames(); RPC.SyncAllClientRealNames(); diff --git a/Patches/PlayerControlPatch.cs b/Patches/PlayerControlPatch.cs index 6c8f67fe5..5cee97b72 100644 --- a/Patches/PlayerControlPatch.cs +++ b/Patches/PlayerControlPatch.cs @@ -936,6 +936,7 @@ class ReportDeadBodyPatch if (!Librarian.OnAnyoneReport(__instance)) return false; if (!Hypnotist.OnAnyoneReport()) return false; if (!Altruist.OnAnyoneCheckReportDeadBody(__instance, target)) return false; + if (!BoobyTrap.OnAnyoneCheckReportDeadBody(__instance, target)) return false; if (!Main.PlayerStates[__instance.PlayerId].Role.CheckReportDeadBody(__instance, target, killer)) return false; @@ -1434,7 +1435,7 @@ static class FixedUpdatePatch ApplySuffix(__instance); } - if (__instance.AmOwner && inTask && ((Main.ChangedRole && localPlayer && AmongUsClient.Instance.AmHost) || (!__instance.Is(CustomRoleTypes.Impostor) /* || Shifter.WasShifter.Contains(__instance.PlayerId)*/) && __instance.CanUseKillButton() && !__instance.Data.IsDead)) + if (__instance.AmOwner && inTask && ((Main.ChangedRole && localPlayer && AmongUsClient.Instance.AmHost) || (!__instance.Is(CustomRoleTypes.Impostor)) && __instance.CanUseKillButton() && !__instance.Data.IsDead)) { var players = __instance.GetPlayersInAbilityRangeSorted(); PlayerControl closest = players.Count == 0 ? null : players[0]; diff --git a/Resources/Lang/en_US.json b/Resources/Lang/en_US.json index edd60d073..881126f62 100644 --- a/Resources/Lang/en_US.json +++ b/Resources/Lang/en_US.json @@ -4527,6 +4527,7 @@ "Prefix.Haunter": "Haunter", "GotGhostRoleNotify": "<#ffff00>You were assigned a ghost role!", "NumOfTasks": "Number of Tasks to Finish", + "AmnesiacRoleBasis": "Role Basis", "RememberCooldown": "Remember Cooldown", "RefugeeKillCD": "Renegade's Kill Cooldown", "AmnesiacRemembered": "An Amnesiac remembered your role!", diff --git a/Roles/Crewmate/SwordsMan.cs b/Roles/Crewmate/SwordsMan.cs index e31dc5c8d..21dca3fa0 100644 --- a/Roles/Crewmate/SwordsMan.cs +++ b/Roles/Crewmate/SwordsMan.cs @@ -43,7 +43,7 @@ public class SwordsMan : RoleBase => !Main.PlayerStates[pc.PlayerId].IsDead && !IsKilled(pc.PlayerId); - public static bool IsKilled(byte playerId) => Killed.Contains(playerId); + private static bool IsKilled(byte playerId) => Killed.Contains(playerId); public override void Add(byte playerId) { @@ -72,6 +72,7 @@ public class SwordsMan : RoleBase SendRPC(killer.PlayerId); Killed.Add(killer.PlayerId); SetKillCooldown(killer.PlayerId); + killer.RpcChangeRoleBasis(CustomRoles.CrewmateEHR); Utils.NotifyRoles(SpecifySeer: killer, SpecifyTarget: killer); } } \ No newline at end of file diff --git a/Roles/Impostor/BoobyTrap.cs b/Roles/Impostor/BoobyTrap.cs index a9b4e768d..34c34df58 100644 --- a/Roles/Impostor/BoobyTrap.cs +++ b/Roles/Impostor/BoobyTrap.cs @@ -67,7 +67,7 @@ namespace EHR.Impostor } } - public override bool CheckReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target, PlayerControl killer) + public static bool OnAnyoneCheckReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { if (BoobyTrapBody.Contains(target.PlayerId) && reporter.IsAlive()) { diff --git a/Roles/Neutral/Amnesiac.cs b/Roles/Neutral/Amnesiac.cs index 33a919761..0b1c178d3 100644 --- a/Roles/Neutral/Amnesiac.cs +++ b/Roles/Neutral/Amnesiac.cs @@ -17,6 +17,7 @@ public class Amnesiac : RoleBase private static OptionItem IncompatibleNeutralMode; private static OptionItem CanVent; public static OptionItem RememberMode; + public static OptionItem RoleBasis; public static readonly CustomRoles[] AmnesiacIncompatibleNeutralMode = [ @@ -50,6 +51,8 @@ public class Amnesiac : RoleBase .SetParent(CustomRoleSpawnChances[CustomRoles.Amnesiac]); CanVent = new BooleanOptionItem(Id + 13, "CanVent", false, TabGroup.NeutralRoles) .SetParent(CustomRoleSpawnChances[CustomRoles.Amnesiac]); + RoleBasis = new StringOptionItem(Id + 14, "AmnesiacRoleBasis", [CustomRoles.Engineer.ToColoredString(), CustomRoles.Crewmate.ToColoredString()], 1, TabGroup.NeutralRoles) + .SetParent(CustomRoleSpawnChances[CustomRoles.Amnesiac]); } public override void Init() @@ -151,16 +154,16 @@ public class Amnesiac : RoleBase amneNotifyString = Utils.ColorString(Utils.GetRoleColor(CustomRoles.Amnesiac), GetString("RememberedImpostor")); break; case Team.Crewmate: - RememberedRole = !targetRole.IsTaskBasedCrewmate() && (CanRememberCrewPower.GetBool() || targetRole.GetCrewmateRoleCategory() != RoleOptionType.Crewmate_Power) ? targetRole : CustomRoles.Sheriff; + RememberedRole = CanRememberCrewPower.GetBool() || targetRole.GetCrewmateRoleCategory() != RoleOptionType.Crewmate_Power ? targetRole : CustomRoles.Sheriff; amneNotifyString = Utils.ColorString(Utils.GetRoleColor(CustomRoles.Amnesiac), GetString("RememberedCrewmate")); break; case Team.Neutral: - if (targetRole.IsNK()) + if (!SingleRoles.Contains(targetRole)) { RememberedRole = targetRole; amneNotifyString = Utils.ColorString(Utils.GetRoleColor(CustomRoles.Amnesiac), GetString("RememberedNeutralKiller")); } - else if (targetRole.IsNonNK()) + else { RememberedRole = AmnesiacIncompatibleNeutralMode[IncompatibleNeutralMode.GetValue()]; amneNotifyString = Utils.ColorString(Utils.GetRoleColor(CustomRoles.Amnesiac), GetString($"Remembered{RememberedRole}")); @@ -173,15 +176,16 @@ public class Amnesiac : RoleBase } - if (RememberedRole == null) + if (!RememberedRole.HasValue) { amnesiac.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Amnesiac), GetString("AmnesiacInvalidTarget"))); return; } - var role = (CustomRoles)RememberedRole; + var role = RememberedRole.Value; amnesiac.RpcSetCustomRole(role); + amnesiac.RpcChangeRoleBasis(role); amnesiac.Notify(amneNotifyString); target.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Amnesiac), GetString("AmnesiacRemembered"))); diff --git a/Roles/Neutral/Jackal.cs b/Roles/Neutral/Jackal.cs index 433614a87..b8e48c2a4 100644 --- a/Roles/Neutral/Jackal.cs +++ b/Roles/Neutral/Jackal.cs @@ -115,11 +115,11 @@ public class Jackal : RoleBase public override bool OnCheckMurder(PlayerControl killer, PlayerControl target) { - if (killer.GetAbilityUseLimit() < 1 || !CanBeSidekick(target, out var needBasisChange, out var targetRoleType) || (needBasisChange && SKCanKill.GetBool() && !UsePets.GetBool())) return true; + if (killer.GetAbilityUseLimit() < 1 || !CanBeSidekick(target, out var needBasisChange, out var targetRoleType)) return true; killer.RpcRemoveAbilityUse(); target.RpcSetCustomRole(targetRoleType == RoleTypes.Shapeshifter ? CustomRoles.Recruit : CustomRoles.Sidekick); - // if (needBasisChange) target.ChangeRoleBasis(RoleTypes.Impostor); + if (needBasisChange) target.RpcChangeRoleBasis(CustomRoles.Sidekick); SidekickId = target.PlayerId; Main.ResetCamPlayerList.Add(target.PlayerId); diff --git a/Roles/Neutral/Necromancer.cs b/Roles/Neutral/Necromancer.cs index e96d796d0..24fd2a3d4 100644 --- a/Roles/Neutral/Necromancer.cs +++ b/Roles/Neutral/Necromancer.cs @@ -76,6 +76,7 @@ namespace EHR.Neutral { if (Deathknight.DeathknightId == byte.MaxValue) { + if (!target.HasKillButton()) target.RpcChangeRoleBasis(CustomRoles.Deathknight); target.RpcSetCustomRole(CustomRoles.Deathknight); killer.SetKillCooldown(); diff --git a/Roles/Neutral/Shifter.cs b/Roles/Neutral/Shifter.cs index d5a30e291..f84edc435 100644 --- a/Roles/Neutral/Shifter.cs +++ b/Roles/Neutral/Shifter.cs @@ -1,4 +1,4 @@ -/*using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using AmongUs.GameOptions; using EHR.Crewmate; @@ -13,15 +13,12 @@ namespace EHR.Neutral public static bool On; public static List WasShifter = []; - private static Dictionary AllPlayerBasis = []; private static OptionItem KillCooldown; private static OptionItem CanVent; private static OptionItem HasImpostorVision; - private static OptionItem TryChangeBasis; public override bool IsEnable => On; - public static bool ForceDisableTasks(byte id) => !TryChangeBasis.GetBool() && WasShifter.Contains(id) && AllPlayerBasis.TryGetValue(id, out var basis) && basis is RoleTypes.Impostor or RoleTypes.Shapeshifter; public override void SetupCustomOption() { @@ -33,10 +30,6 @@ namespace EHR.Neutral .SetParent(Options.CustomRoleSpawnChances[CustomRoles.Shifter]); HasImpostorVision = new BooleanOptionItem(Id + 4, "ImpostorVision", true, TabGroup.NeutralRoles) .SetParent(Options.CustomRoleSpawnChances[CustomRoles.Shifter]); - TryChangeBasis = new BooleanOptionItem(Id + 5, "TryChangeBasis", false, TabGroup.NeutralRoles) - .SetHidden(true) - .SetParent(Options.CustomRoleSpawnChances[CustomRoles.Shifter]); - TryChangeBasis.SetValue(0); } public override void Init() @@ -46,16 +39,11 @@ namespace EHR.Neutral On = false; WasShifter = []; - AllPlayerBasis = []; - LateTask.New(() => AllPlayerBasis = Main.AllPlayerControls.ToDictionary(x => x.PlayerId, x => x.GetRoleTypes()), 10f, log: false); } public override void Add(byte playerId) { On = true; - - if (!TryChangeBasis.GetBool() || playerId == 0) - WasShifter.Add(playerId); } public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); @@ -85,8 +73,7 @@ namespace EHR.Neutral } killer.RpcSetCustomRole(targetRole); - if (TryChangeBasis.GetBool()) - killer.ChangeRoleBasis(target.GetRoleTypes()); + killer.RpcChangeRoleBasis(targetRole); var targetRoleBase = Main.PlayerStates[target.PlayerId].Role; LateTask.New(() => Main.PlayerStates[killer.PlayerId].Role = targetRoleBase, 0.5f, "Change RoleBase"); @@ -94,7 +81,7 @@ namespace EHR.Neutral killer.SetAbilityUseLimit(target.GetAbilityUseLimit()); var taskState = target.GetTaskState(); - if (taskState.hasTasks) Main.PlayerStates[killer.PlayerId].taskState = taskState; + if (taskState.HasTasks) Main.PlayerStates[killer.PlayerId].TaskState = taskState; var killerSubRoles = killer.GetCustomSubRoles().ToList(); var targetSubRoles = target.GetCustomSubRoles().ToList(); @@ -126,6 +113,8 @@ namespace EHR.Neutral Utils.NotifyRoles(SpecifyTarget: killer); Utils.NotifyRoles(SpecifyTarget: target); + WasShifter.Add(killer.PlayerId); + return false; } @@ -134,6 +123,4 @@ namespace EHR.Neutral OnCheckMurder(pc, ExternalRpcPetPatch.SelectKillButtonTarget(pc)); } } -} -*/ - +} \ No newline at end of file