Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove Incompatible Add-Ons when Changing Roles in most situations #1374

Merged
Merged
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
16 changes: 15 additions & 1 deletion Modules/ExtendedPlayerControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,21 @@ namespace TOHE;

static class ExtendedPlayerControl
{
public static void RpcSetCustomRole(this PlayerControl player, CustomRoles role)
public static void RpcSetCustomRole(this PlayerControl player, CustomRoles role, bool checkAddons = true)
{
if (role < CustomRoles.NotAssigned)
{
Main.PlayerStates[player.PlayerId].SetMainRole(role);
// player.GetRoleClass()?.OnAdd(player.PlayerId);
// Remember to manually add OnAdd if you are setting role mid game
if (checkAddons) player.RemoveIncompatibleAddOns();
}
else if (role >= CustomRoles.NotAssigned) //500:NoSubRole 501~:SubRole
{
if (Cleanser.CantGetAddon() && player.Is(CustomRoles.Cleansed)) return;
if (role == CustomRoles.Cleansed) Main.PlayerStates[player.PlayerId].SetSubRole(role, pc: player);
else Main.PlayerStates[player.PlayerId].SetSubRole(role);
if (checkAddons) player.RemoveIncompatibleAddOns();
}
if (AmongUsClient.Instance.AmHost)
{
Expand All @@ -40,6 +42,7 @@ public static void RpcSetCustomRole(this PlayerControl player, CustomRoles role)
writer.WritePacked((int)role);
AmongUsClient.Instance.FinishRpcImmediately(writer);
}

}
public static void RpcSetCustomRole(byte PlayerId, CustomRoles role)
{
Expand All @@ -51,6 +54,17 @@ public static void RpcSetCustomRole(byte PlayerId, CustomRoles role)
AmongUsClient.Instance.FinishRpcImmediately(writer);
}
}
public static void RemoveIncompatibleAddOns(this PlayerControl player)
{
foreach (var addon in player.GetCustomSubRoles())
{
if (!CustomRolesHelper.CheckAddonConfilct(addon, player))
{
Main.PlayerStates[player.PlayerId].RemoveSubRole(addon);
Logger.Info($"{player.GetNameWithRole()} had incompatible addon {addon.ToString()}, removing addon", $"{player.GetCustomRole().ToString()}");
}
}
}
public static void SetRole(this PlayerControl player, RoleTypes role, bool canOverride)
{
player.StartCoroutine(player.CoSetRole(role, canOverride));
Expand Down
1 change: 1 addition & 0 deletions Patches/PlayerControlPatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ public static bool RpcCheckAndMurder(PlayerControl killer, PlayerControl target,
Main.MadmateNum++;
target.RpcSetCustomRole(CustomRoles.Madmate);
ExtendedPlayerControl.RpcSetCustomRole(target.PlayerId, CustomRoles.Madmate);
target.RemoveIncompatibleAddOns();
target.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Madmate), GetString("BecomeMadmateCuzMadmateMode")));
killer.SetKillCooldown();
killer.RpcGuardAndKill(target);
Expand Down
28 changes: 26 additions & 2 deletions Roles/Coven/Necromancer.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using MS.Internal.Xml.XPath;
using TOHE.Roles.Core;
using TOHE.Roles.Crewmate;
using TOHE.Roles.Neutral;
Expand Down Expand Up @@ -32,6 +33,7 @@ internal class Necromancer : CovenManager
private static float tempKillTimer = 0;

private static readonly Dictionary<byte, List<CustomRoles>> UsedRoles = [];
private static readonly Dictionary<byte, List<CustomRoles>> OldAddons = [];
private static float AbilityTimer;
private static bool canUseAbility;

Expand All @@ -56,13 +58,15 @@ public override void Init()
Killer = null;
tempKillTimer = 0;
UsedRoles.Clear();
OldAddons.Clear();
canUseAbility = false;
AbilityTimer = 0;
}
public override void Add(byte playerId)
{
Timer = RevengeTime.GetInt();
UsedRoles[playerId] = [];
OldAddons[playerId] = [];
}
//public override void ApplyGameOptions(IGameOptions opt, byte id) => opt.SetVision(HasImpostorVision.GetBool());
public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat();
Expand Down Expand Up @@ -135,9 +139,24 @@ public override void UnShapeShiftButton(PlayerControl nm)
}
var role = deadRoles.RandomElement();
nm.RpcChangeRoleBasis(role);
nm.RpcSetCustomRole(role);
nm.RpcSetCustomRole(role, checkAddons: false);
nm.GetRoleClass()?.OnAdd(nm.PlayerId);
nm.SyncSettings();
Dictionary<byte, List<CustomRoles>> CurrentAddons = new();
CurrentAddons[nm.PlayerId] = [];
foreach (var addon in nm.GetCustomSubRoles())
{
CurrentAddons[nm.PlayerId].Add(addon);
}
foreach (var addon in CurrentAddons[nm.PlayerId])
{
if (!CustomRolesHelper.CheckAddonConfilct(addon, nm))
{
OldAddons[nm.PlayerId].Add(addon);
Main.PlayerStates[nm.PlayerId].RemoveSubRole(addon);
Logger.Info($"{nm.GetNameWithRole()} had incompatible addon {addon.ToString()}, removing addon", "Necromancer");
}
}
Main.PlayerStates[nm.PlayerId].InitTask(nm);
nm.RpcGuardAndKill(nm);
nm.Notify(string.Format(GetString("CopyCatRoleChange"), Utils.GetRoleName(role)));
Expand All @@ -156,7 +175,12 @@ private static void RevertRole(PlayerControl nm, CustomRoles role)
}
if (nm.IsAlive())
nm.RpcChangeRoleBasis(CustomRoles.Necromancer);
nm.RpcSetCustomRole(CustomRoles.Necromancer);
nm.RpcSetCustomRole(CustomRoles.Necromancer, checkAddons: false);
foreach (var addon in OldAddons[nm.PlayerId])
{
nm.RpcSetCustomRole(addon, checkAddons: false);
}
OldAddons[nm.PlayerId].Clear();
nm.ResetKillCooldown();
nm.SyncSettings();
nm.RpcGuardAndKill(nm);
Expand Down
2 changes: 1 addition & 1 deletion Roles/Coven/Ritualist.cs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ public void ConvertRole(PlayerControl killer, PlayerControl target)
target.RpcSetCustomRole(CustomRoles.Contagious);
killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Contagious), GetString("RitualistSuccessfullyRecruited")));
target.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Contagious), GetString("BeRecruitedByRitualist")));
}
}
}
private static bool MsgToPlayerAndRole(string msg, out byte id, out CustomRoles role, out string error)
{
Expand Down
6 changes: 3 additions & 3 deletions Roles/Crewmate/ChiefOfPolice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerContr
target.RpcChangeRoleBasis(CustomRoles.Sheriff);
target.RpcSetCustomRole(CustomRoles.Sheriff);
target.GetRoleClass()?.OnAdd(target.PlayerId);

target.ResetKillCooldown();
target.SetKillCooldown(forceAnime: true);

Expand Down Expand Up @@ -117,7 +117,7 @@ public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerContr
target.RpcChangeRoleBasis(CustomRoles.Sheriff);
target.RpcSetCustomRole(CustomRoles.Sheriff);
target.GetRoleClass()?.OnAdd(target.PlayerId);

target.ResetKillCooldown();
target.SetKillCooldown(forceAnime: true);

Expand Down Expand Up @@ -146,7 +146,7 @@ public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerContr
{
var role = killer.GetCustomSubRoles().FirstOrDefault(x => (x.IsConverted() || x is CustomRoles.Admired) && x is not CustomRoles.Egoist);
Logger.Info($"Giving addon {role} to {target.GetNameWithRole()}", "ChiefOfPolice");
target.RpcSetCustomRole(role);
target.RpcSetCustomRole(role);
}
}
}
Expand Down
27 changes: 25 additions & 2 deletions Roles/Crewmate/CopyCat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ internal class CopyCat : RoleBase
private static OptionItem CopyTeamChangingAddon;

private static float CurrentKillCooldown = new();
private static readonly Dictionary<byte, List<CustomRoles>> OldAddons = [];

public override void SetupCustomOption()
{
Expand All @@ -37,13 +38,15 @@ public override void Init()
{
playerIdList.Clear();
CurrentKillCooldown = new();
OldAddons.Clear();
}

public override void Add(byte playerId)
{
if (!playerIdList.Contains(playerId))
playerIdList.Add(playerId);
CurrentKillCooldown = KillCooldown.GetFloat();
OldAddons[playerId] = [];
}
public override void Remove(byte playerId) //only to be used when copycat's role is going to be changed permanently
{
Expand Down Expand Up @@ -79,11 +82,16 @@ public static void UnAfterMeetingTasks()
{
pc.GetRoleClass()?.OnRemove(pc.PlayerId);
pc.RpcChangeRoleBasis(CustomRoles.CopyCat);
pc.RpcSetCustomRole(CustomRoles.CopyCat);
pc.RpcSetCustomRole(CustomRoles.CopyCat, checkAddons: false);
foreach (var addon in OldAddons[pc.PlayerId])
{
pc.RpcSetCustomRole(addon, checkAddons: false);
}
}
}
pc.ResetKillCooldown();
pc.SetKillCooldown();
OldAddons[pc.PlayerId].Clear();
}
}

Expand Down Expand Up @@ -147,9 +155,24 @@ CustomRoles.PotionMaster when PotionMaster.CurrentPotion() is 1 => CustomRoles.M
if (role != CustomRoles.CopyCat)
{
killer.RpcChangeRoleBasis(role);
killer.RpcSetCustomRole(role);
killer.RpcSetCustomRole(role, checkAddons: false);
killer.GetRoleClass()?.OnAdd(killer.PlayerId);
killer.SyncSettings();
Dictionary<byte, List<CustomRoles>> CurrentAddons = new();
CurrentAddons[killer.PlayerId] = [];
foreach (var addon in killer.GetCustomSubRoles())
{
CurrentAddons[killer.PlayerId].Add(addon);
}
foreach (var addon in CurrentAddons[killer.PlayerId])
{
if (!CustomRolesHelper.CheckAddonConfilct(addon, killer))
{
OldAddons[killer.PlayerId].Add(addon);
Main.PlayerStates[killer.PlayerId].RemoveSubRole(addon);
Logger.Info($"{killer.GetNameWithRole()} had incompatible addon {addon.ToString()}, removing addon", "CopyCat");
}
}
}
if (CopyTeamChangingAddon.GetBool())
{
Expand Down
Loading