add judge ability as trigger

This commit is contained in:
Gurge44 committed 2026-08-20 17:43:07 +02:00
1 parent 5e2cc0fbea
commit 89139ff9b8
25 files changed
+103 -42

No files matched your search

+7
View File
@@ -922,6 +922,13 @@ internal static class CustomRolesHelper
return type.GetMethod("OnMeetingShapeshift")?.DeclaringType == type;
}
public bool UsesJudgeAbilityAsTrigger()
{
if (!Options.UseJudgeAbilityAsTrigger.GetBool()) return false;
Type type = role.GetRoleClass().GetType();
return type.GetMethod("OnJudge")?.DeclaringType == type;
}
public bool PetActivatedAbility()
{
if (Options.CurrentGameMode == CustomGameMode.CaptureTheFlag) return true;
+7
View File
@@ -61,6 +61,13 @@ internal static class ExtendedPlayerControl
return role.UsesMeetingShapeshift();
}
public bool UsesJudgeAbilityAsTrigger()
{
CustomRoles role = player.GetCustomRole();
if (player.IsModdedClient() && role is CustomRoles.Councillor or CustomRoles.Inspector or CustomRoles.JudgeOld or CustomRoles.Retributionist or CustomRoles.Starspawn or CustomRoles.Swapper or CustomRoles.Ventriloquist) return false;
return role.UsesJudgeAbilityAsTrigger();
}
public bool CanUseVent()
{
try { return player.CanUseVent(player.GetClosestVent()?.Id ?? int.MaxValue); }
+7 -1
View File
@@ -798,6 +798,7 @@ public static class Options
public static OptionItem EveryoneSeesDeadPlayersRoles;
public static OptionItem UsePhantomBasis;
public static OptionItem UsePhantomBasisForNKs;
public static OptionItem UseJudgeAbilityAsTrigger;
public static OptionItem UseMeetingShapeshift;
public static OptionItem UseMeetingShapeshiftForGuessing;
public static OptionItem AutoKickStart;
@@ -2502,7 +2503,12 @@ public static class Options
.SetParent(UsePhantomBasis)
.SetColor(new Color32(255, 255, 44, byte.MaxValue));
UseMeetingShapeshift = new BooleanOptionItem(23865, "UseMeetingShapeshift", true, TabGroup.TaskSettings)
UseJudgeAbilityAsTrigger = new BooleanOptionItem(23865, "UseJudgeAbilityAsTrigger", true, TabGroup.TaskSettings)
.SetGameMode(CustomGameMode.Standard)
.SetHeader(true)
.SetColor(Palette.Orange);
UseMeetingShapeshift = new BooleanOptionItem(23867, "UseMeetingShapeshift", false, TabGroup.TaskSettings)
.SetGameMode(CustomGameMode.Standard)
.SetHeader(true)
.SetColor(Palette.Orange);
+2 -1
View File
@@ -235,7 +235,8 @@ internal static class RPCHandlerPatch
[RpcCalls.CheckSpore] = 5,
[RpcCalls.CheckShapeshift] = 25,
[RpcCalls.CheckVanish] = 25,
[RpcCalls.CheckAppear] = 25
[RpcCalls.CheckAppear] = 25,
[RpcCalls.QueueOverruleVotes] = 3
};
public static void WhiteListFromRateLimitUntil(byte id, long timestamp)
+56 -22
View File
@@ -1067,7 +1067,16 @@ internal static class MeetingHudStartPatch
sender.SendMessage();
}, 3f, "SetName To Chat");
if (Options.UseMeetingShapeshift.GetBool())
if (Options.UseJudgeAbilityAsTrigger.GetBool())
{
LateTask.New(() =>
{
if (!MeetingHud.Instance || MeetingHud.Instance.state is MeetingHud.MeetingStates.Results or MeetingHud.MeetingStates.Proceeding) return;
Main.EnumerateAlivePlayerControls().DoIf(x => x.UsesJudgeAbilityAsTrigger(), x => x.RpcSetRoleDesync(RoleTypes.Judge, x.OwnerId));
}, 1f, "Set Shapeshifter Role For Meeting Use");
}
else if (Options.UseMeetingShapeshift.GetBool())
{
LateTask.New(() =>
{
@@ -1376,17 +1385,26 @@ internal static class MeetingHudOnDestroyPatch
Main.LastVotedPlayerInfo = null;
if (meetingSS && !AntiBlackout.SkipTasks)
if (!AntiBlackout.SkipTasks)
{
bool restrictions = Options.GuesserNumRestrictions.GetBool();
foreach (PlayerControl pc in Main.CachedAlivePlayerControls())
if (Options.UseJudgeAbilityAsTrigger.GetBool())
{
if (pc.UsesMeetingShapeshift() || (meetingSSForGuessing && !pc.IsModdedClient() && GuessManager.StartMeetingPatch.CanGuess(pc, restrictions)))
pc.RpcSetRoleDesync(pc.GetRoleTypes(), pc.OwnerId);
foreach (PlayerControl pc in Main.CachedAlivePlayerControls())
if (pc.UsesJudgeAbilityAsTrigger())
pc.RpcSetRoleDesync(pc.GetRoleTypes(), pc.OwnerId);
}
else if (meetingSS)
{
bool restrictions = Options.GuesserNumRestrictions.GetBool();
if (pc.IsImpostor())
pc.RpcSetRoleGlobal(pc.GetRoleTypes());
foreach (PlayerControl pc in Main.CachedAlivePlayerControls())
{
if (pc.UsesMeetingShapeshift() || (meetingSSForGuessing && !pc.IsModdedClient() && GuessManager.StartMeetingPatch.CanGuess(pc, restrictions)))
pc.RpcSetRoleDesync(pc.GetRoleTypes(), pc.OwnerId);
if (pc.IsImpostor())
pc.RpcSetRoleGlobal(pc.GetRoleTypes());
}
}
}
}
@@ -1603,30 +1621,46 @@ internal static class MeetingHudHandleRpcPatch
{
public static bool Prefix([HarmonyArgument(0)] byte callId, [HarmonyArgument(1)] MessageReader reader)
{
if (callId == (byte)RpcCalls.CloseMeeting)
switch (callId)
{
if (AmongUsClient.Instance.AmHost)
case (byte)RpcCalls.QueueOverruleVotes:
{
byte judgePlayerId = reader.ReadByte();
byte targetPlayerId = reader.ReadByte();
PlayerControl judge = judgePlayerId.GetPlayer();
PlayerControl target = targetPlayerId.GetPlayer();
if (judge && target && judge.UsesJudgeAbilityAsTrigger() && Main.PlayerStates.TryGetValue(judgePlayerId, out PlayerState state))
return !state.Role.OnJudge(judge, target);
break;
}
case (byte)RpcCalls.CloseMeeting when AmongUsClient.Instance.AmHost:
{
EAC.WarnHost(4);
Logger.Warn("MeetingHud.HandleRpc CloseMeeting is being called, impossible to receive as host.", "MeetingHudHandleRpcPatch");
return false;
}
Logger.Info("Received Close Meeting Rpc", "MeetingHudHandleRpcPatch");
if (reader.BytesRemaining > 6)
case (byte)RpcCalls.CloseMeeting:
{
try
{
string temp = reader.ReadString();
Logger.Info("Received Close Meeting Rpc", "MeetingHudHandleRpcPatch");
if (temp.Contains("<size"))
if (reader.BytesRemaining > 6)
{
try
{
Logger.Info($"Read Name From Rpc: {temp}", "MeetingHudHandleRpcPatch");
CheckForEndVotingPatch.EjectionText = temp;
string temp = reader.ReadString();
if (temp.Contains("<size"))
{
Logger.Info($"Read Name From Rpc: {temp}", "MeetingHudHandleRpcPatch");
CheckForEndVotingPatch.EjectionText = temp;
}
}
catch { }
}
catch { }
break;
}
}
+1
View File
@@ -9123,6 +9123,7 @@
"EveryoneSeesDeadPlayersRoles": "Everyone Sees Dead Players' Roles",
"UsePhantomBasis": "Use Vanish Button (Phantom basis) as Ability Trigger",
"UsePhantomBasisForNKs": "Even for <#ffab1b>Neutral</color> <#ff1919>Killing</color> (Desynced) roles <#ffff00>(EXPERIMENTAL)</color>",
"UseJudgeAbilityAsTrigger": "Use Judge Ability in Meetings to Select Targets Instead of Commands/Votes",
"UseMeetingShapeshift": "Use Shapeshift Menu in Meetings to Select Targets Instead of Commands/Votes",
"UseMeetingShapeshiftForGuessing": "Even For Guessing (can cause frequent disconnects) (EXTREMELY EXPERIMENTAL ALPHA VERSION)",
"EveryoneCanVent": "Everyone Can Vent",
+5
View File
@@ -156,6 +156,11 @@ public abstract class RoleBase : IComparable<RoleBase>
return false;
}
public virtual bool OnJudge(PlayerControl voter, PlayerControl target)
{
return false;
}
public virtual void OnReportDeadBody() { }
public virtual bool CheckReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target, PlayerControl killer)
+1 -1
View File
@@ -99,7 +99,7 @@ public class Empress : CovenBase
SetKillCooldown(EmpressId);
}
public override bool OnVote(PlayerControl voter, PlayerControl target)
public override bool OnJudge(PlayerControl voter, PlayerControl target)
{
if (Starspawn.IsDayBreak || voter == null || target == null || Main.DontCancelVoteList.Contains(voter.PlayerId) || voter.PlayerId != target.PlayerId || Empowered) return false;
@@ -40,7 +40,7 @@ public class Captain : RoleBase
TargetRooms = [];
}
public override bool OnVote(PlayerControl voter, PlayerControl target)
public override bool OnJudge(PlayerControl voter, PlayerControl target)
{
if (Starspawn.IsDayBreak) return false;
if (voter == null || target == null || voter.PlayerId == target.PlayerId || Main.DontCancelVoteList.Contains(voter.PlayerId)) return false;
@@ -93,7 +93,7 @@ public class FortuneTeller : RoleBase
}, 8f, log: false);
}
public override bool OnVote(PlayerControl player, PlayerControl target)
public override bool OnJudge(PlayerControl player, PlayerControl target)
{
if (Starspawn.IsDayBreak) return false;
if (player == null || target == null) return false;
@@ -35,7 +35,7 @@ public class Inquisitor : RoleBase
playerId.SetAbilityUseLimit(AbilityUseLimit.GetFloat());
}
public override bool OnVote(PlayerControl voter, PlayerControl target)
public override bool OnJudge(PlayerControl voter, PlayerControl target)
{
if (Starspawn.IsDayBreak) return false;
if (!voter || !target || voter.PlayerId == target.PlayerId || Main.DontCancelVoteList.Contains(voter.PlayerId)) return false;
@@ -46,7 +46,7 @@ internal class Markseeker : RoleBase
}
/*
public override bool OnVote(PlayerControl player, PlayerControl target)
public override bool OnJudge(PlayerControl player, PlayerControl target)
{
if (Starspawn.IsDayBreak) return false;
if (player == null || target == null || player.PlayerId == target.PlayerId || MarkedId != byte.MaxValue || Main.DontCancelVoteList.Contains(player.PlayerId)) return false;
@@ -57,7 +57,7 @@ public class Oracle : RoleBase
playerId.SetAbilityUseLimit(CheckLimitOpt.GetFloat());
}
public override bool OnVote(PlayerControl player, PlayerControl target)
public override bool OnJudge(PlayerControl player, PlayerControl target)
{
if (Starspawn.IsDayBreak) return false;
if (player == null || target == null) return false;
+1 -1
View File
@@ -97,7 +97,7 @@ public class Scout : RoleBase
return TrackerTarget != null && TrackerTarget.ContainsKey(seer.PlayerId) && TrackerTarget[seer.PlayerId].Contains(target.PlayerId) ? Utils.ColorString(seer.GetRoleColor(), "◀") : string.Empty;
}
public override bool OnVote(PlayerControl player, PlayerControl target)
public override bool OnJudge(PlayerControl player, PlayerControl target)
{
if (Starspawn.IsDayBreak) return false;
if (!player || !target || player.GetAbilityUseLimit() < 1f || player.PlayerId == target.PlayerId || TrackerTarget == null || TrackerTarget[player.PlayerId].Contains(target.PlayerId) || Main.DontCancelVoteList.Contains(player.PlayerId)) return false;
@@ -102,7 +102,7 @@ public class Socialite : RoleBase
return true;
}
public override bool OnVote(PlayerControl pc, PlayerControl target)
public override bool OnJudge(PlayerControl pc, PlayerControl target)
{
if (Starspawn.IsDayBreak) return false;
if (pc == null || target == null || pc.PlayerId == target.PlayerId || Main.DontCancelVoteList.Contains(pc.PlayerId)) return false;
@@ -41,7 +41,7 @@ public class Soothsayer : RoleBase
Instances?.Remove(this);
}
public override bool OnVote(PlayerControl player, PlayerControl target)
public override bool OnJudge(PlayerControl player, PlayerControl target)
{
if (Starspawn.IsDayBreak) return false;
if (player == null || target == null || player.PlayerId == target.PlayerId) return false;
@@ -92,7 +92,7 @@ public class Ricochet : RoleBase
return true;
}
public override bool OnVote(PlayerControl pc, PlayerControl target)
public override bool OnJudge(PlayerControl pc, PlayerControl target)
{
if (Starspawn.IsDayBreak) return false;
if (target == null || pc == null || pc.PlayerId == target.PlayerId || Main.DontCancelVoteList.Contains(pc.PlayerId)) return false;
@@ -114,7 +114,7 @@ public class Tether : RoleBase
AURoleOptions.EngineerInVentMaxTime = 1f;
}
public override bool OnVote(PlayerControl pc, PlayerControl target)
public override bool OnJudge(PlayerControl pc, PlayerControl target)
{
if (Starspawn.IsDayBreak) return false;
if (pc == null || target == null || pc.PlayerId == target.PlayerId || Main.DontCancelVoteList.Contains(pc.PlayerId)) return false;
+1 -1
View File
@@ -57,7 +57,7 @@ internal class NiceEraser : RoleBase
PlayerIdList.Remove(playerId);
}
public override bool OnVote(PlayerControl player, PlayerControl target)
public override bool OnJudge(PlayerControl player, PlayerControl target)
{
if (Starspawn.IsDayBreak) return false;
if (player == null || target == null) return false;
+1 -1
View File
@@ -240,7 +240,7 @@ public class President : RoleBase
return target.PlayerId == PresidentId && IsRevealed;
}
public override bool OnVote(PlayerControl voter, PlayerControl target)
public override bool OnJudge(PlayerControl voter, PlayerControl target)
{
if (Starspawn.IsDayBreak) return false;
if (voter.PlayerId != PresidentId || !IsRecruiting || Main.DontCancelVoteList.Contains(voter.PlayerId)) return false;
+1 -1
View File
@@ -90,7 +90,7 @@ public class Cleanser : RoleBase
cs.CleanserUses = Limit;
}
public override bool OnVote(PlayerControl voter, PlayerControl target)
public override bool OnJudge(PlayerControl voter, PlayerControl target)
{
if (Starspawn.IsDayBreak) return false;
if (DidVote[voter.PlayerId] || Main.DontCancelVoteList.Contains(voter.PlayerId)) return false;
@@ -124,7 +124,7 @@ public class Negotiator : RoleBase
}
}
public override bool OnVote(PlayerControl voter, PlayerControl target)
public override bool OnJudge(PlayerControl voter, PlayerControl target)
{
if (Starspawn.IsDayBreak) return false;
if (target == null || voter == null || voter.PlayerId == target.PlayerId || TargetId != byte.MaxValue || voter.GetAbilityUseLimit() < 1f || MinVotingTimeLeftToNegotiate.GetInt() > MeetingTimeManager.VotingTimeLeft || Main.DontCancelVoteList.Contains(voter.PlayerId)) return false;
@@ -98,7 +98,7 @@ internal class EvilEraser : RoleBase
return true;
}
public override bool OnVote(PlayerControl player, PlayerControl target)
public override bool OnJudge(PlayerControl player, PlayerControl target)
{
if (Starspawn.IsDayBreak) return false;
if (player == null || target == null || EraseMethod.GetInt() == 0) return false;
+1 -1
View File
@@ -22,7 +22,7 @@ internal class Godfather : RoleBase
On = false;
}
public override bool OnVote(PlayerControl voter, PlayerControl target)
public override bool OnJudge(PlayerControl voter, PlayerControl target)
{
if (Starspawn.IsDayBreak) return false;
if (voter == null || target == null || voter.PlayerId == target.PlayerId || Main.DontCancelVoteList.Contains(voter.PlayerId)) return false;
+1 -1
View File
@@ -42,7 +42,7 @@ public class Clerk : RoleBase
playerId.SetAbilityUseLimit(AbilityUseLimit.GetInt());
}
public override bool OnVote(PlayerControl voter, PlayerControl target)
public override bool OnJudge(PlayerControl voter, PlayerControl target)
{
if (Starspawn.IsDayBreak) return false;
if (Main.DontCancelVoteList.Contains(voter.PlayerId)) return false;