More Custom Button Images (#5) + Additional Meeting UI for some roles (#636)

* More custom buttons (Meeting SS and Client buttons)

* more additions...

* since its not needed, reverted it

* hmm what?

* bruh, literally blocked meeting shapeshift button having custom buttons
This commit is contained in:
Newchan authored and GitHub committed 2026-06-28 18:28:00 +02:00
1 parent a0256694a4
commit 4d6f697dbc
27 files changed
+491 -118

No files matched your search

+1 -1
View File
@@ -56,7 +56,7 @@ internal static class ExtendedPlayerControl
public bool UsesMeetingShapeshift()
{
CustomRoles role = player.GetCustomRole();
if (player.IsModdedClient() && role is CustomRoles.Councillor or CustomRoles.Inspector or CustomRoles.Judge or CustomRoles.Retributionist or CustomRoles.Starspawn or CustomRoles.Swapper or CustomRoles.Ventriloquist) return false;
// if (player.IsModdedClient() && role is CustomRoles.Councillor or CustomRoles.Inspector or CustomRoles.Judge or CustomRoles.Retributionist or CustomRoles.Starspawn or CustomRoles.Swapper or CustomRoles.Ventriloquist) return false;
return role.UsesMeetingShapeshift();
}
+44 -9
View File
@@ -795,7 +795,7 @@ public static class GuessManager
}
}
private static void GuesserOnClick(byte playerId, MeetingHud __instance)
public static void GuesserOnClick(byte playerId, MeetingHud __instance, bool specificRoleChoosing = false)
{
PlayerControl pc = Utils.GetPlayerById(playerId);
if (!pc || !pc.IsAlive() || GuesserUI || MeetingHud.Instance.state is MeetingHud.VoteStates.Results or MeetingHud.VoteStates.Proceeding || Starspawn.IsDayBreak) return;
@@ -855,6 +855,13 @@ public static class GuessManager
case (CustomRoles.EvilGuesser, 4) when !Options.EGCanGuessAdt.GetBool():
case (CustomRoles.NiceGuesser, 0) when !Options.GGCanGuessCrew.GetBool() && !PlayerControl.LocalPlayer.IsMadmate():
case (CustomRoles.NiceGuesser, 4) when !Options.GGCanGuessAdt.GetBool():
case (CustomRoles.Loner, 0) when specificRoleChoosing:
case (CustomRoles.Loner, 2) when specificRoleChoosing:
case (CustomRoles.Loner, 3) when specificRoleChoosing:
case (CustomRoles.Loner, 4) when specificRoleChoosing:
case (CustomRoles.Inquirer, 4) when specificRoleChoosing:
case (CustomRoles.Forger, 4) when specificRoleChoosing:
case (CustomRoles.Pawn, 4) when specificRoleChoosing:
continue;
}
@@ -971,7 +978,7 @@ public static class GuessManager
foreach (CustomRoles role in Main.CustomRoleValues)
{
if (!ShowRoleOnUI(role)) continue;
if (!ShowRoleOnUI(role, specificRoleChoosing)) continue;
CreateRole(role);
}
@@ -1024,8 +1031,35 @@ public static class GuessManager
Logger.Msg($"Click: {pc.GetNameWithRole()} => {role}", "Guesser UI");
if (AmongUsClient.Instance.AmHost) GuesserMsg(PlayerControl.LocalPlayer, $"/bt {playerId} {GetString(role.ToString())}", true);
else SendRPC(playerId, role);
if (specificRoleChoosing)
switch(PlayerControl.LocalPlayer.GetCustomRole())
{
case CustomRoles.Loner:
{
Loner.ProcessGuesserUI(playerId, role);
break;
}
case CustomRoles.Inquirer:
{
Inquirer.ProcessGuesserUI(playerId, role);
break;
}
case CustomRoles.Forger:
{
Forger.ProcessGuesserUI(playerId, role);
break;
}
case CustomRoles.Pawn:
{
Pawn.ProcessGuesserUI(role);
break;
}
}
else
{
if (AmongUsClient.Instance.AmHost) GuesserMsg(PlayerControl.LocalPlayer, $"/bt {playerId} {GetString(role.ToString())}", true);
else SendRPC(playerId, role);
}
// Reset the GUI
__instance.playerStates.ToList().ForEach(x => x.gameObject.SetActive(true));
@@ -1039,7 +1073,7 @@ public static class GuessManager
}
container.transform.localScale *= 0.75f;
GuesserSelectRole(CustomRoleTypes.Neutral);
GuesserSelectRole(specificRoleChoosing ? CustomRoleTypes.Impostor : CustomRoleTypes.Neutral);
ReloadPage();
}
catch (Exception ex)
@@ -1051,10 +1085,12 @@ public static class GuessManager
CustomSoundsManager.Play("Gunload");
}
private static bool ShowRoleOnUI(CustomRoles role)
private static bool ShowRoleOnUI(CustomRoles role, bool specificRoleChoosing = false)
{
if (role is CustomRoles.GM or CustomRoles.NotAssigned )
return false;
if (role is
CustomRoles.GM or
CustomRoles.Ankylosaurus or
CustomRoles.BananaMan or
CustomRoles.Car or
@@ -1062,12 +1098,11 @@ public static class GuessManager
CustomRoles.Flash or
CustomRoles.Giant or
CustomRoles.LastImpostor or
CustomRoles.NotAssigned or
CustomRoles.Shifter or
CustomRoles.Specter or
CustomRoles.SuperStar
)
return false;
return specificRoleChoosing;
if (role.IsForOtherGameMode()) return false;
if (!role.IsEnable() && !role.RoleExist(true) && !CanMakeRoleSpawn(role)) return false;
-4
View File
@@ -724,7 +724,6 @@ public static class Options
public static OptionItem AnagramLanguage;
public static OptionItem AnagramWordLength;
public static OptionItem AnagramDifficulty;
public static OptionItem EightballCommandIndexes;
public static OptionItem LadderDeath;
public static OptionItem LadderDeathChance;
@@ -3039,9 +3038,6 @@ public static class Options
], 0, TabGroup.GameSettings)
.SetColor(new Color32(100, 220, 255, byte.MaxValue));
EightballCommandIndexes = new IntegerOptionItem(23820, "EightballCommandIndexes", new(1, 100, 1), 20, TabGroup.GameSettings)
.SetColor(new Color32(100, 220, 255, byte.MaxValue));
new TextOptionItem(100028, "MenuTitle.Other", TabGroup.GameSettings)
.SetHeader(true)
+5 -5
View File
@@ -658,7 +658,7 @@ internal static class ChatCommands
HudManagerStartPatch.TryResizeUI(scale);
}
private static void SelectCommand(PlayerControl player, string text, string[] args)
public static void SelectCommand(PlayerControl player, string text, string[] args)
{
if (Starspawn.IsDayBreak) return;
@@ -900,7 +900,7 @@ internal static class ChatCommands
}
}
private static void ChooseCommand(PlayerControl player, string text, string[] args)
public static void ChooseCommand(PlayerControl player, string text, string[] args)
{
if (!Main.PlayerStates.TryGetValue(player.PlayerId, out var state) || state.IsDead || state.Role is not Pawn pawn) return;
@@ -916,7 +916,7 @@ internal static class ChatCommands
MeetingManager.SendCommandUsedMessage(args[0]);
}
private static void ForgeCommand(PlayerControl player, string text, string[] args)
public static void ForgeCommand(PlayerControl player, string text, string[] args)
{
if (Starspawn.IsDayBreak) return;
@@ -1024,7 +1024,7 @@ internal static class ChatCommands
return;
}
Utils.SendMessage(GetString($"8BallResponse.{IRandom.Instance.Next(Options.EightballCommandIndexes.GetInt())}"), player.IsAlive() ? byte.MaxValue : player.PlayerId, GetString("8BallResponseTitle"));
Utils.SendMessage(GetString($"8BallResponse.{IRandom.Instance.Next(20)}"), player.IsAlive() ? byte.MaxValue : player.PlayerId, GetString("8BallResponseTitle"));
}
public static void GameModePollCommand(PlayerControl player, string text, string[] args)
@@ -2194,7 +2194,7 @@ internal static class ChatCommands
AmongUsClient.Instance.KickPlayer(kickedPlayer.OwnerId, args[0] == "/ban");
}
private static void CheckCommand(PlayerControl player, string text, string[] args)
public static void CheckCommand(PlayerControl player, string text, string[] args)
{
if (Starspawn.IsDayBreak) return;
+141 -6
View File
@@ -33,7 +33,7 @@ public static class HudSpritePatch
PlayerControl player = PlayerControl.LocalPlayer;
if (!player) return;
if (!Main.EnableCustomButton.Value || !Main.ProcessShapeshifts || Mastermind.ManipulatedPlayers.ContainsKey(player.PlayerId) || ExileController.Instance || GameStates.IsMeeting) return;
if (!Main.EnableCustomButton.Value || Mastermind.ManipulatedPlayers.ContainsKey(player.PlayerId) || ExileController.Instance) return;
if (!SetHudActivePatch.IsActive && !MeetingStates.FirstMeeting) return;
if (!AmongUsClient.Instance.IsGameStarted || !Main.IntroDestroyed || GameStates.IsLobby || GameStates.IsNotJoined || !GameStates.InGame || IntroCutsceneDestroyPatch.PreventKill) return;
@@ -51,11 +51,130 @@ public static class HudSpritePatch
{
if (!GhostRolesManager.AssignedGhostRoles.TryGetValue(player.PlayerId, out (CustomRoles Role, IGhostRole Instance) ghostRole)) return;
if (!GhostRolesWithSprites.Contains(ghostRole.Role)) return;
newAbilityButton = CustomButton.Get(ghostRole.Role.ToString());
goto Skip;
}
if (GameStates.IsMeeting)
{
if (player.UsesMeetingShapeshift())
{
switch (player.GetCustomRole())
{
case CustomRoles.Starspawn:
{
newAbilityButton = CustomButton.Get("StarspawnShift");
break;
}
case CustomRoles.Loner:
{
newAbilityButton = CustomButton.Get("Sidekick");
break;
}
case CustomRoles.Exorcist: // temp
{
newAbilityButton = CustomButton.Get("Assassinate");
break;
}
case CustomRoles.Ventriloquist:
{
newAbilityButton = CustomButton.Get("Hack");
break;
}
case CustomRoles.Cleanser:
{
newAbilityButton = CustomButton.Get("Drink");
break;
}
case CustomRoles.Clerk: // temp
{
newAbilityButton = CustomButton.Get("Clerk");
break;
}
case CustomRoles.Godfather:
{
newAbilityButton = CustomButton.Get("EvilNearby");
break;
}
case CustomRoles.EvilEraser: // temp
case CustomRoles.NiceEraser:
{
newAbilityButton = CustomButton.Get("Erase");
break;
}
case CustomRoles.Councillor:
{
newAbilityButton = CustomButton.Get("Assassinate");
break;
}
case CustomRoles.Negotiator: // temp
{
newAbilityButton = CustomButton.Get("Attack");
break;
}
case CustomRoles.Swapper:
{
newAbilityButton = CustomButton.Get("PetToSwap");
break;
}
case CustomRoles.Tether:
{
newAbilityButton = CustomButton.Get("Track");
break;
}
case CustomRoles.Ricochet: // temp
{
newAbilityButton = CustomButton.Get("Shield");
break;
}
case CustomRoles.President:
case CustomRoles.Retributionist:
{
newAbilityButton = CustomButton.Get("Kill");
break;
}
case CustomRoles.Judge:
{
newAbilityButton = CustomButton.Get("JudgeIcon");
break;
}
case CustomRoles.Socialite: // temp
{
newAbilityButton = CustomButton.Get("Bestower");
break;
}
case CustomRoles.Soothsayer:
case CustomRoles.Oracle:
case CustomRoles.Markseeker:
case CustomRoles.FortuneTeller:
{
newAbilityButton = CustomButton.Get("prophecies");
break;
}
case CustomRoles.Scout:
case CustomRoles.Captain:
{
newAbilityButton = CustomButton.Get("Track");
break;
}
case CustomRoles.Inspector:
case CustomRoles.Inquisitor: // temp
{
newAbilityButton = CustomButton.Get("InspectorIcon");
break;
}
case CustomRoles.Empress:
{
newAbilityButton = CustomButton.Get("Facilitator");
break;
}
}
goto Skip;
}
else return;
}
bool usesPetInsteadOfKill = player.UsesPetInsteadOfKill();
bool shapeshifting = player.IsShifted();
@@ -93,6 +212,12 @@ public static class HudSpritePatch
{
newAbilityButton = CustomButton.Get("Up");
newPetButton = CustomButton.Get("PetToSwap");
newKillButton = CustomButton.Get("Wand");
break;
}
case CustomRoles.Tar:
{
newPetButton = CustomButton.Get("Tar");
break;
}
case CustomRoles.Socialite:
@@ -123,6 +248,13 @@ public static class HudSpritePatch
else newVentButton = CustomButton.Get("PetToSwap");
break;
}
case CustomRoles.Silencer:
case CustomRoles.Blackmailer:
{
if (Silencer.SilenceMode.GetValue() >= 1 && player.Is(CustomRoles.Silencer)) newAbilityButton = CustomButton.Get("Blackmail");
else newKillButton = CustomButton.Get("Blackmail");
break;
}
case CustomRoles.Vulture:
{
newReportButton = CustomButton.Get("Eat");
@@ -690,7 +822,7 @@ public static class HudSpritePatch
case CustomRoles.Swooper:
case CustomRoles.Wraith:
{
if (Options.UsePhantomBasis.GetBool()) newAbilityButton = CustomButton.Get("Swoop");
if (Options.UsePhantomBasis.GetBool()) newAbilityButton = CustomButton.Get("invisible");
else if (Options.UsePets.GetBool()) newPetButton = CustomButton.Get("invisible");
else newVentButton = CustomButton.Get("invisible");
break;
@@ -735,7 +867,7 @@ public static class HudSpritePatch
}
default:
{
if (ForceUpdate || usesPetInsteadOfKill) break;
if (player.Is(CustomRoles.Sleuth) || player.Is(CustomRoles.Bloodlust) || ForceUpdate || usesPetInsteadOfKill) break;
SetButtonColors();
return;
}
@@ -745,13 +877,16 @@ public static class HudSpritePatch
newPetButton = newKillButton;
// shows default pet button if the ability can't be used yet due to cooldowns or if they no longer have uses left
if (player.HasAbilityCD() || player.GetAbilityUseLimit() < 1) // conditions with float.NaN always evaluate to false, which is good in this case
if (!Options.UsePets.GetBool() || player.HasAbilityCD() || player.GetAbilityUseLimit() < 1) // conditions with float.NaN always evaluate to false, which is good in this case
newPetButton = DefaultIcons[4];
// for Bloodlust, due to it using the impostor vent button instead of the engineer vent button, show it on the vent button instead of the ability button, and only if the ability button is not the default button
if (Main.PlayerStates[player.PlayerId].SubRoles.Contains(CustomRoles.Bloodlust) && newAbilityButton != DefaultIcons[1] && !player.Is(CustomRoles.Scanner) && !player.Is(CustomRoles.Transporter))
if (player.Is(CustomRoles.Bloodlust) && newAbilityButton != DefaultIcons[1] && !player.Is(CustomRoles.Scanner) && !player.Is(CustomRoles.Transporter))
newVentButton = newAbilityButton;
if (player.Is(CustomRoles.Sleuth) && newReportButton == DefaultIcons[5])
newReportButton = CustomButton.Get("ExamineBody");
Skip:
SetButtonColors();
+8
View File
@@ -1182,6 +1182,7 @@ internal static class MeetingHudStartPatch
// -------------------------------------------------------------------------------------------
CovenBase.CovenMeetingStartPatch.Postfix();
GuessManager.StartMeetingPatch.Postfix(__instance);
Inspector.StartMeetingPatch.Postfix(__instance);
Judge.StartMeetingPatch.Postfix(__instance);
@@ -1192,6 +1193,13 @@ internal static class MeetingHudStartPatch
Retributionist.StartMeetingPatch.Postfix(__instance);
Starspawn.StartMeetingPatch.Postfix(__instance);
Ventriloquist.StartMeetingPatch.Postfix(__instance);
Exorcist.StartMeetingPatch.Postfix(__instance);
Summoner.StartMeetingPatch.Postfix(__instance);
Loner.StartMeetingPatch.Postfix(__instance);
Forger.StartMeetingPatch.Postfix(__instance);
Inquirer.StartMeetingPatch.Postfix(__instance);
Pawn.StartMeetingPatch.Postfix(__instance);
ShowHostMeetingPatch.Setup_Postfix(__instance);
Crowded.MeetingHudStartPatch.Postfix(__instance);
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

+1 -82
View File
@@ -8366,87 +8366,7 @@
"8BallResponse.17": "My sources say no.",
"8BallResponse.18": "Outlook not so good.",
"8BallResponse.19": "Very doubtful.",
"8BallResponse.20": "\\n",
"8BallResponse.21": "\\n",
"8BallResponse.22": "\\n",
"8BallResponse.23": "\\n",
"8BallResponse.24": "\\n",
"8BallResponse.25": "\\n",
"8BallResponse.26": "\\n",
"8BallResponse.27": "\\n",
"8BallResponse.28": "\\n",
"8BallResponse.29": "\\n",
"8BallResponse.30": "\\n",
"8BallResponse.31": "\\n",
"8BallResponse.32": "\\n",
"8BallResponse.33": "\\n",
"8BallResponse.34": "\\n",
"8BallResponse.35": "\\n",
"8BallResponse.36": "\\n",
"8BallResponse.37": "\\n",
"8BallResponse.38": "\\n",
"8BallResponse.39": "\\n",
"8BallResponse.40": "\\n",
"8BallResponse.41": "\\n",
"8BallResponse.42": "\\n",
"8BallResponse.43": "\\n",
"8BallResponse.44": "\\n",
"8BallResponse.45": "\\n",
"8BallResponse.46": "\\n",
"8BallResponse.47": "\\n",
"8BallResponse.48": "\\n",
"8BallResponse.49": "\\n",
"8BallResponse.50": "\\n",
"8BallResponse.51": "\\n",
"8BallResponse.52": "\\n",
"8BallResponse.53": "\\n",
"8BallResponse.54": "\\n",
"8BallResponse.55": "\\n",
"8BallResponse.56": "\\n",
"8BallResponse.57": "\\n",
"8BallResponse.58": "\\n",
"8BallResponse.59": "\\n",
"8BallResponse.60": "\\n",
"8BallResponse.61": "\\n",
"8BallResponse.62": "\\n",
"8BallResponse.63": "\\n",
"8BallResponse.64": "\\n",
"8BallResponse.65": "\\n",
"8BallResponse.66": "\\n",
"8BallResponse.67": "\\n",
"8BallResponse.68": "\\n",
"8BallResponse.69": "\\n",
"8BallResponse.70": "\\n",
"8BallResponse.71": "\\n",
"8BallResponse.72": "\\n",
"8BallResponse.73": "\\n",
"8BallResponse.74": "\\n",
"8BallResponse.75": "\\n",
"8BallResponse.76": "\\n",
"8BallResponse.77": "\\n",
"8BallResponse.78": "\\n",
"8BallResponse.79": "\\n",
"8BallResponse.80": "\\n",
"8BallResponse.81": "\\n",
"8BallResponse.82": "\\n",
"8BallResponse.83": "\\n",
"8BallResponse.84": "\\n",
"8BallResponse.85": "\\n",
"8BallResponse.86": "\\n",
"8BallResponse.87": "\\n",
"8BallResponse.88": "\\n",
"8BallResponse.89": "\\n",
"8BallResponse.90": "\\n",
"8BallResponse.91": "\\n",
"8BallResponse.92": "\\n",
"8BallResponse.93": "\\n",
"8BallResponse.94": "\\n",
"8BallResponse.95": "\\n",
"8BallResponse.96": "\\n",
"8BallResponse.97": "\\n",
"8BallResponse.98": "\\n",
"8BallResponse.99": "\\n",
"AAWarning": "<#ffff00>You must move away from this device or you die!</color>",
"Admin": "Admin",
"AdminTag": "<#ff0000>Admin</color>",
@@ -9060,7 +8980,6 @@
"AnagramDiff.Medium": "Medium",
"AnagramDiff.MediumHard": "Medium-Hard",
"AnagramDiff.Hard": "Hard",
"EightballCommandIndexes": "Number of responses for /8ball command (Use the custom translate file to import additional responses. These responses will return blank if no definitions are made)",
"MenuTitle.Other": "★ Different ★",
"LadderDeath": "Fall From Ladders",
"LadderDeathChance": "Fall To Death Chance",
+44
View File
@@ -4,6 +4,7 @@ using AmongUs.GameOptions;
using EHR.Modules;
using EHR.Modules.Extensions;
using Hazel;
using UnityEngine;
namespace EHR.Roles;
@@ -262,4 +263,47 @@ public class Summoner : CovenBase
if (seer.PlayerId == SummonerId) return string.Format(Translator.GetString("Summoner.SelfSuffix"), SummonedPlayerId.ColoredPlayerName(), (int)SummonedPlayerTimer.Remaining.TotalSeconds);
return seer.PlayerId == SummonedPlayerId ? string.Format(Translator.GetString("Summoner.SummonedPlayerSuffix"), SummonerId.ColoredPlayerName(), CustomRoles.Summoner.ToColoredString(), (int)SummonedPlayerTimer.Remaining.TotalSeconds) : string.Empty;
}
private static void SummonerOnClick(byte playerId /*, MeetingHud __instance*/)
{
Logger.Msg($"Click: ID {playerId}", "Summoner UI");
PlayerControl pc = Utils.GetPlayerById(playerId);
if (pc == null || pc.IsAlive() || !GameStates.IsVoting || Starspawn.IsDayBreak) return;
var command = $"/summon {playerId}";
if (AmongUsClient.Instance.AmHost)
ChatCommands.SummonCommand(PlayerControl.LocalPlayer, command, command.Split(' '));
else
ChatCommands.RequestCommandProcessingFromHost(command, "Summon");
}
private static void CreateSummonerButton(MeetingHud __instance)
{
foreach (PlayerVoteArea pva in __instance.playerStates)
{
PlayerControl pc = Utils.GetPlayerById(pva.TargetPlayerId);
if (!pc || pc.IsAlive()) continue;
GameObject template = pva.Buttons.transform.Find("CancelButton").gameObject;
GameObject targetBox = Object.Instantiate(template, pva.transform);
targetBox.name = "SummonerButton";
targetBox.transform.localPosition = new(-0.35f, 0.03f, -1.31f);
var renderer = targetBox.GetComponent<SpriteRenderer>();
renderer.sprite = Utils.LoadSprite("EHR.Resources.Images.Skills.Summon.png", 130f);
var button = targetBox.GetComponent<PassiveButton>();
button.OnClick.RemoveAllListeners();
button.OnClick.AddListener((Action)(() => SummonerOnClick(pva.TargetPlayerId)));
}
}
//[HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.Start))]
public static class StartMeetingPatch
{
public static void Postfix(MeetingHud __instance)
{
if (PlayerControl.LocalPlayer.IsAlive() && PlayerControl.LocalPlayer.Is(CustomRoles.Summoner))
CreateSummonerButton(__instance);
}
}
}
@@ -91,7 +91,7 @@ public class Imitator : RoleBase
targetBox.name = "ImitatorButton";
targetBox.transform.localPosition = new(-0.35f, 0.03f, -1.31f);
var renderer = targetBox.GetComponent<SpriteRenderer>();
renderer.sprite = Utils.LoadSprite("EHR.Resources.Images.Skills.TargetIcon.png", 130f);
renderer.sprite = Utils.LoadSprite("EHR.Resources.Images.Skills.Imitate.png", 130f);
var button = targetBox.GetComponent<PassiveButton>();
button.OnClick.RemoveAllListeners();
button.OnClick.AddListener((Action)(() => ImitatorOnClick(pva.TargetPlayerId)));
@@ -1,4 +1,9 @@
namespace EHR.Roles;
using System;
using EHR.Modules;
using UnityEngine;
using static EHR.Translator;
namespace EHR.Roles;
public class Inquirer : RoleBase
{
@@ -36,4 +41,46 @@ public class Inquirer : RoleBase
{
playerId.SetAbilityUseLimit(AbilityUseLimit.GetFloat());
}
public static void CreateInquirerButton(MeetingHud __instance)
{
foreach (PlayerVoteArea pva in __instance.playerStates)
{
PlayerControl pc = Utils.GetPlayerById(pva.TargetPlayerId);
if (!pc || !pc.IsAlive()) continue;
GameObject template = pva.Buttons.transform.Find("CancelButton").gameObject;
GameObject targetBox = Object.Instantiate(template, pva.transform);
targetBox.name = "ShootButton";
targetBox.transform.localPosition = new(-0.35f, 0.03f, -1.31f);
var renderer = targetBox.GetComponent<SpriteRenderer>();
renderer.sprite = Utils.LoadSprite("EHR.Resources.Images.Skills.InspectorIcon.png", 160f);
var button = targetBox.GetComponent<PassiveButton>();
button.OnClick.RemoveAllListeners();
button.OnClick.AddListener((Action)(() => GuessManager.GuesserOnClick(pva.TargetPlayerId, __instance, true)));
}
}
//[HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.Start))]
public static class StartMeetingPatch
{
public static void Postfix(MeetingHud __instance)
{
if (PlayerControl.LocalPlayer.Is(CustomRoles.Inquirer) && PlayerControl.LocalPlayer.IsAlive())
CreateInquirerButton(__instance);
}
}
public static void ProcessGuesserUI(byte playerId, CustomRoles role)
{
PlayerControl pc = Utils.GetPlayerById(playerId);
if (pc == null || !pc.IsAlive() || Starspawn.IsDayBreak) return;
var command = $"/check {playerId} {GetString(role.ToString())}";
if (AmongUsClient.Instance.AmHost)
ChatCommands.CheckCommand(PlayerControl.LocalPlayer, command, command.Split(' '));
else
ChatCommands.RequestCommandProcessingFromHost(command, "Check");
}
}
@@ -1,4 +1,7 @@
using System.Collections.Generic;
using System;
using UnityEngine;
using static EHR.Translator;
namespace EHR.Roles;
@@ -31,4 +34,46 @@ public class Forger : RoleBase
On = true;
playerId.SetAbilityUseLimit(AbilityUseLimit.GetFloat());
}
public static void CreateForgerButton(MeetingHud __instance)
{
foreach (PlayerVoteArea pva in __instance.playerStates)
{
PlayerControl pc = Utils.GetPlayerById(pva.TargetPlayerId);
if (!pc || !pc.IsAlive()) continue;
GameObject template = pva.Buttons.transform.Find("CancelButton").gameObject;
GameObject targetBox = Object.Instantiate(template, pva.transform);
targetBox.name = "ShootButton";
targetBox.transform.localPosition = new(-0.35f, 0.03f, -1.31f);
var renderer = targetBox.GetComponent<SpriteRenderer>();
renderer.sprite = Utils.LoadSprite("EHR.Resources.Images.Skills.ForgerIcon.png", 160f);
var button = targetBox.GetComponent<PassiveButton>();
button.OnClick.RemoveAllListeners();
button.OnClick.AddListener((Action)(() => GuessManager.GuesserOnClick(pva.TargetPlayerId, __instance, true)));
}
}
//[HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.Start))]
public static class StartMeetingPatch
{
public static void Postfix(MeetingHud __instance)
{
if (PlayerControl.LocalPlayer.Is(CustomRoles.Forger) && PlayerControl.LocalPlayer.IsAlive())
CreateForgerButton(__instance);
}
}
public static void ProcessGuesserUI(byte playerId, CustomRoles role)
{
PlayerControl pc = Utils.GetPlayerById(playerId);
if (pc == null || !pc.IsAlive() || Starspawn.IsDayBreak) return;
var command = $"/forge {playerId} {GetString(role.ToString())}";
if (AmongUsClient.Instance.AmHost)
ChatCommands.ForgeCommand(PlayerControl.LocalPlayer, command, command.Split(' '));
else
ChatCommands.RequestCommandProcessingFromHost(command, "Forge");
}
}
@@ -1,4 +1,8 @@
namespace EHR.Roles;
using System;
using TMPro;
using UnityEngine;
namespace EHR.Roles;
public class Exorcist : RoleBase
{
@@ -37,4 +41,54 @@ public class Exorcist : RoleBase
const string command = "/exo";
ChatCommands.ExoCommand(shapeshifter, command, command.Split(' '));
}
private static void ExorcistOnClick(GameObject exorcistButton)
{
Logger.Msg($"Exorcist Click: ID {PlayerControl.LocalPlayer.PlayerId}", "Exorcist UI");
if (PlayerControl.LocalPlayer == null || !PlayerControl.LocalPlayer.IsAlive() || !GameStates.IsVoting) return;
const string command = "/exo";
if (AmongUsClient.Instance.AmHost)
ChatCommands.ExoCommand(PlayerControl.LocalPlayer, command, command.Split(' '));
else
ChatCommands.RequestCommandProcessingFromHost(command, "Exo");
exorcistButton.SetActive(false);
LateTask.New(() => exorcistButton.SetActive(true), 1f, "ExorcistButton");
}
private static void CreateExorcistButton(MeetingHud __instance)
{
GameObject existingButton = GameObject.Find("ExorcistButton");
if (existingButton) Object.Destroy(existingButton.gameObject);
if (!PlayerControl.LocalPlayer || !PlayerControl.LocalPlayer.IsAlive()) return;
GameObject parent = GameObject.Find("Main Camera").transform.Find("Hud").Find("ChatUi").Find("ChatScreenRoot").Find("ChatScreenContainer").gameObject;
GameObject template = __instance.transform.Find("MeetingContents").Find("ButtonStuff").Find("button_skipVoting").gameObject;
GameObject exorcistButton = Object.Instantiate(template, parent.transform);
exorcistButton.name = "ExorcistButton";
exorcistButton.transform.localPosition = new(3.46f, 0f, 45f);
exorcistButton.SetActive(true);
var renderer = exorcistButton.GetComponent<SpriteRenderer>();
renderer.sprite = CustomButton.Get("ExorcistIcon");
renderer.color = Color.white;
GameObject Text_TMP = exorcistButton.GetComponentInChildren<TextMeshPro>().gameObject;
Text_TMP.SetActive(false);
var button = exorcistButton.GetComponent<PassiveButton>();
button.OnClick.RemoveAllListeners();
button.OnClick.AddListener((Action)(() => ExorcistOnClick(exorcistButton)));
GameObject ControllerHighlight = exorcistButton.transform.Find("ControllerHighlight").gameObject;
ControllerHighlight.transform.localScale = new(0.5f, 2f, 0.5f);
}
//[HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.Start))]
public static class StartMeetingPatch
{
public static void Postfix(MeetingHud __instance)
{
if (PlayerControl.LocalPlayer.IsAlive() && PlayerControl.LocalPlayer.Is(CustomRoles.Exorcist))
CreateExorcistButton(__instance);
}
}
}
+47 -2
View File
@@ -1,5 +1,8 @@
using System.Linq;
using System;
using System.Linq;
using EHR.Modules;
using UnityEngine;
using static EHR.Translator;
namespace EHR.Roles;
@@ -46,7 +49,7 @@ public class Loner : RoleBase
public override void AfterMeetingTasks()
{
var pc = PickedPlayer.GetPlayer();
if (!Done && PickedPlayer != byte.MaxValue && PickedRole != CustomRoles.Crewmate && pc != null)
{
Done = true;
@@ -54,4 +57,46 @@ public class Loner : RoleBase
pc.RpcChangeRoleBasis(PickedRole);
}
}
public static void CreateLonerButton(MeetingHud __instance)
{
foreach (PlayerVoteArea pva in __instance.playerStates)
{
PlayerControl pc = Utils.GetPlayerById(pva.TargetPlayerId);
if (!pc || !pc.IsAlive()) continue;
GameObject template = pva.Buttons.transform.Find("CancelButton").gameObject;
GameObject targetBox = Object.Instantiate(template, pva.transform);
targetBox.name = "ShootButton";
targetBox.transform.localPosition = new(-0.35f, 0.03f, -1.31f);
var renderer = targetBox.GetComponent<SpriteRenderer>();
renderer.sprite = Utils.LoadSprite("EHR.Resources.Images.Skills.Sidekick.png", 160f);
var button = targetBox.GetComponent<PassiveButton>();
button.OnClick.RemoveAllListeners();
button.OnClick.AddListener((Action)(() => GuessManager.GuesserOnClick(pva.TargetPlayerId, __instance, true)));
}
}
//[HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.Start))]
public static class StartMeetingPatch
{
public static void Postfix(MeetingHud __instance)
{
if (PlayerControl.LocalPlayer.Is(CustomRoles.Loner) && PlayerControl.LocalPlayer.IsAlive())
CreateLonerButton(__instance);
}
}
public static void ProcessGuesserUI(byte playerId, CustomRoles role)
{
PlayerControl pc = Utils.GetPlayerById(playerId);
if (pc == null || !pc.IsAlive() || Starspawn.IsDayBreak) return;
var command = $"/select {playerId} {GetString(role.ToString())}";
if (AmongUsClient.Instance.AmHost)
ChatCommands.SelectCommand(PlayerControl.LocalPlayer, command, command.Split(' '));
else
ChatCommands.RequestCommandProcessingFromHost(command, "Select");
}
}
@@ -44,12 +44,12 @@ public class Ventriloquist : RoleBase
ChatCommands.TargetCommand(shapeshifter, command, command.Split(' '));
}
private static void VentriloquisttOnClick(byte playerId /*, MeetingHud __instance*/)
private static void VentriloquistOnClick(byte playerId /*, MeetingHud __instance*/)
{
Logger.Msg($"Click: ID {playerId}", "Ventriloquist UI");
PlayerControl pc = Utils.GetPlayerById(playerId);
if (pc == null || !pc.IsAlive() || !GameStates.IsVoting || Starspawn.IsDayBreak) return;
var command = $"/target {playerId}";
if (AmongUsClient.Instance.AmHost)
@@ -73,7 +73,7 @@ public class Ventriloquist : RoleBase
renderer.sprite = Utils.LoadSprite("EHR.Resources.Images.Skills.Hack.png", 160f);
var button = targetBox.GetComponent<PassiveButton>();
button.OnClick.RemoveAllListeners();
button.OnClick.AddListener((Action)(() => VentriloquisttOnClick(pva.TargetPlayerId)));
button.OnClick.AddListener((Action)(() => VentriloquistOnClick(pva.TargetPlayerId)));
}
}
+48 -3
View File
@@ -1,4 +1,8 @@
using EHR.Modules;
using System.Linq;
using EHR.Modules;
using System;
using UnityEngine;
using static EHR.Translator;
namespace EHR.Roles;
@@ -48,13 +52,54 @@ public class Pawn : RoleBase
{
var pc = PawnId.GetPlayer();
if (pc == null || !pc.IsAlive()) return;
if (!pc.AllTasksCompleted() || ChosenRole == CustomRoles.NotAssigned || ChosenRole.IsAdditionRole() || ChosenRole.IsForOtherGameMode()) return;
pc.RpcSetCustomRole(ChosenRole);
pc.RpcChangeRoleBasis(ChosenRole);
if (pc.AmOwner && ChosenRole is CustomRoles.Crewmate or CustomRoles.CrewmateEHR)
Achievements.Type.Why.Complete();
}
public static void CreatePawnButton(MeetingHud __instance)
{
PlayerVoteArea localPva = __instance.playerStates
.FirstOrDefault(pva => pva.TargetPlayerId == PlayerControl.LocalPlayer.PlayerId);
PlayerControl pc = Utils.GetPlayerById(localPva.TargetPlayerId);
if (!pc || !pc.IsAlive()) return;
GameObject template = localPva.Buttons.transform.Find("CancelButton").gameObject;
GameObject targetBox = Object.Instantiate(template, localPva.transform);
targetBox.name = "ShootButton";
targetBox.transform.localPosition = new(-0.35f, 0.03f, -1.31f);
var renderer = targetBox.GetComponent<SpriteRenderer>();
renderer.sprite = Utils.LoadSprite("EHR.Resources.Images.Skills.PawnPromotion.png", 160f);
var button = targetBox.GetComponent<PassiveButton>();
button.OnClick.RemoveAllListeners();
button.OnClick.AddListener((Action)(() => GuessManager.GuesserOnClick(localPva.TargetPlayerId, __instance, true)));
}
//[HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.Start))]
public static class StartMeetingPatch
{
public static void Postfix(MeetingHud __instance)
{
if (PlayerControl.LocalPlayer.Is(CustomRoles.Pawn) && PlayerControl.LocalPlayer.IsAlive())
CreatePawnButton(__instance);
}
}
public static void ProcessGuesserUI(CustomRoles role)
{
PlayerControl pc = PlayerControl.LocalPlayer;
var command = $"/choose {GetString(role.ToString())}";
if (AmongUsClient.Instance.AmHost)
ChatCommands.ChooseCommand(PlayerControl.LocalPlayer, command, command.Split(' '));
else
ChatCommands.RequestCommandProcessingFromHost(command, "Choose");
}
}