mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-20 01:46:25 +00:00
1179 lines
59 KiB
C#
1179 lines
59 KiB
C#
using EHR.Modules;
|
||
using EHR.Roles.AddOns.Common;
|
||
using EHR.Roles.Crewmate;
|
||
using EHR.Roles.Neutral;
|
||
using HarmonyLib;
|
||
using Hazel;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text.RegularExpressions;
|
||
using TMPro;
|
||
using UnityEngine;
|
||
using UnityEngine.Events;
|
||
using static EHR.Translator;
|
||
using Object = UnityEngine.Object;
|
||
|
||
namespace EHR;
|
||
|
||
public static class GuessManager
|
||
{
|
||
public static string GetFormatString()
|
||
{
|
||
string text = GetString("PlayerIdList");
|
||
foreach (PlayerControl pc in Main.AllAlivePlayerControls)
|
||
{
|
||
string id = pc.PlayerId.ToString();
|
||
string name = pc.GetRealName();
|
||
text += $"\n{id} → {name}";
|
||
}
|
||
|
||
return text;
|
||
}
|
||
|
||
public static bool CheckCommand(ref string msg, string command, bool exact = true)
|
||
{
|
||
var comList = command.Split('|');
|
||
foreach (string str in comList)
|
||
{
|
||
if (exact)
|
||
{
|
||
if (msg == "/" + str) return true;
|
||
}
|
||
else
|
||
{
|
||
if (msg.StartsWith("/" + str))
|
||
{
|
||
msg = msg.Replace("/" + str, string.Empty);
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
public static byte GetColorFromMsg(string msg)
|
||
{
|
||
if (ConfirmIncludeMsg(msg, "红|紅|red")) return 0;
|
||
if (ConfirmIncludeMsg(msg, "蓝|藍|深蓝|blue")) return 1;
|
||
if (ConfirmIncludeMsg(msg, "绿|綠|深绿|green")) return 2;
|
||
if (ConfirmIncludeMsg(msg, "粉红|粉紅|pink")) return 3;
|
||
if (ConfirmIncludeMsg(msg, "橘|橘|orange")) return 4;
|
||
if (ConfirmIncludeMsg(msg, "黄|黃|yellow")) return 5;
|
||
if (ConfirmIncludeMsg(msg, "黑|黑|black")) return 6;
|
||
if (ConfirmIncludeMsg(msg, "白|白|white")) return 7;
|
||
if (ConfirmIncludeMsg(msg, "紫|紫|perple")) return 8;
|
||
if (ConfirmIncludeMsg(msg, "棕|棕|brown")) return 9;
|
||
if (ConfirmIncludeMsg(msg, "青|青|cyan")) return 10;
|
||
if (ConfirmIncludeMsg(msg, "黄绿|黃綠|浅绿|lime")) return 11;
|
||
if (ConfirmIncludeMsg(msg, "红褐|紅褐|深红|maroon")) return 12;
|
||
if (ConfirmIncludeMsg(msg, "玫红|玫紅|浅粉|rose")) return 13;
|
||
if (ConfirmIncludeMsg(msg, "焦黄|焦黃|淡黄|banana")) return 14;
|
||
if (ConfirmIncludeMsg(msg, "灰|灰|gray")) return 15;
|
||
if (ConfirmIncludeMsg(msg, "茶|茶|tan")) return 16;
|
||
if (ConfirmIncludeMsg(msg, "珊瑚|珊瑚|coral")) return 17;
|
||
return byte.MaxValue;
|
||
}
|
||
|
||
private static bool ConfirmIncludeMsg(string msg, string key)
|
||
{
|
||
var keys = key.Split('|');
|
||
return keys.Any(msg.Contains);
|
||
}
|
||
|
||
public static bool GuesserMsg(PlayerControl pc, string msg, bool isUI = false)
|
||
{
|
||
var originMsg = msg;
|
||
|
||
if (!AmongUsClient.Instance.AmHost) return false;
|
||
if (!GameStates.IsVoting || pc == null) return false;
|
||
if (!pc.Is(CustomRoles.NiceGuesser) && !pc.Is(CustomRoles.EvilGuesser) && !pc.Is(CustomRoles.Doomsayer) && !pc.Is(CustomRoles.Judge) && !pc.Is(CustomRoles.NiceSwapper) && !pc.Is(CustomRoles.Councillor) && !pc.Is(CustomRoles.Guesser) && !Options.GuesserMode.GetBool()) return false;
|
||
|
||
int operate; // 1: ID, 2: Guess
|
||
msg = msg.ToLower().TrimStart().TrimEnd();
|
||
if (CheckCommand(ref msg, "id|guesslist|gl编号|玩家编号|玩家id|id列表|玩家列表|列表|所有id|全部id")) operate = 1;
|
||
else if (CheckCommand(ref msg, "shoot|guess|bet|st|gs|bt|猜|赌", false)) operate = 2;
|
||
else return false;
|
||
|
||
Logger.Msg(msg, "Msg Guesser");
|
||
Logger.Msg($"{operate}", "Operate");
|
||
|
||
if (!pc.IsAlive())
|
||
{
|
||
if (!isUI) Utils.SendMessage(GetString("GuessDead"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessDead"));
|
||
return true;
|
||
}
|
||
|
||
if (!pc.Is(CustomRoles.NiceGuesser))
|
||
{
|
||
if (pc.IsCrewmate() && !Options.CrewmatesCanGuess.GetBool() && !pc.Is(CustomRoles.Guesser) && !pc.Is(CustomRoles.Judge) && !pc.Is(CustomRoles.NiceSwapper))
|
||
{
|
||
if (!isUI) Utils.SendMessage(GetString("GuessNotAllowed"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessNotAllowed"));
|
||
return true;
|
||
}
|
||
}
|
||
|
||
if (!pc.Is(CustomRoles.EvilGuesser))
|
||
{
|
||
if (pc.GetCustomRole().IsImpostor() && !Options.ImpostorsCanGuess.GetBool() && !pc.Is(CustomRoles.Guesser) && !pc.Is(CustomRoles.Councillor))
|
||
{
|
||
if (!isUI) Utils.SendMessage(GetString("GuessNotAllowed"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessNotAllowed"));
|
||
return true;
|
||
}
|
||
}
|
||
|
||
if (pc.IsNeutralKiller() && !Options.NeutralKillersCanGuess.GetBool() && !pc.Is(CustomRoles.Guesser))
|
||
{
|
||
if (!isUI) Utils.SendMessage(GetString("GuessNotAllowed"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessNotAllowed"));
|
||
return true;
|
||
}
|
||
|
||
if (pc.GetCustomRole().IsNonNK() && !Options.PassiveNeutralsCanGuess.GetBool() && !pc.Is(CustomRoles.Guesser) && !pc.Is(CustomRoles.Doomsayer))
|
||
{
|
||
if (!isUI) Utils.SendMessage(GetString("GuessNotAllowed"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessNotAllowed"));
|
||
return true;
|
||
}
|
||
|
||
switch (operate)
|
||
{
|
||
case 1:
|
||
Utils.SendMessage(GetFormatString(), pc.PlayerId);
|
||
return true;
|
||
case 2:
|
||
{
|
||
if (
|
||
(pc.Is(CustomRoles.NiceGuesser) && Options.GGTryHideMsg.GetBool()) ||
|
||
(pc.Is(CustomRoles.EvilGuesser) && Options.EGTryHideMsg.GetBool()) ||
|
||
(pc.Is(CustomRoles.Doomsayer) && Doomsayer.DoomsayerTryHideMsg.GetBool()) ||
|
||
(pc.Is(CustomRoles.Guesser) && Options.GTryHideMsg.GetBool()) || (Options.GuesserMode.GetBool() && Options.HideGuesserCommands.GetBool())
|
||
) /*TryHideMsg();*/ ChatManager.SendPreviousMessagesToAll();
|
||
else if (pc.AmOwner && !isUI) Utils.SendMessage(originMsg, 255, pc.GetRealName());
|
||
|
||
if (!MsgToPlayerAndRole(msg, out byte targetId, out CustomRoles role, out string error))
|
||
{
|
||
if (!isUI) Utils.SendMessage(error, pc.PlayerId);
|
||
else pc.ShowPopUp(error);
|
||
return true;
|
||
}
|
||
|
||
var target = Utils.GetPlayerById(targetId);
|
||
if (target != null)
|
||
{
|
||
bool guesserSuicide = false;
|
||
if (CopyCat.PlayerIdList.Contains(pc.PlayerId))
|
||
{
|
||
if (!isUI) Utils.SendMessage(GetString("GuessDisabled"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessDisabled"));
|
||
return true;
|
||
}
|
||
|
||
Main.GuesserGuessed.TryAdd(pc.PlayerId, 0);
|
||
|
||
switch (pc.GetCustomRole())
|
||
{
|
||
case CustomRoles.NiceGuesser when Main.GuesserGuessed[pc.PlayerId] >= Options.GGCanGuessTime.GetInt():
|
||
if (!isUI) Utils.SendMessage(GetString("GGGuessMax"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GGGuessMax"));
|
||
return true;
|
||
case CustomRoles.EvilGuesser when Main.GuesserGuessed[pc.PlayerId] >= Options.EGCanGuessTime.GetInt():
|
||
if (!isUI) Utils.SendMessage(GetString("EGGuessMax"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("EGGuessMax"));
|
||
return true;
|
||
case CustomRoles.Phantom when !Options.PhantomCanGuess.GetBool():
|
||
if (!isUI) Utils.SendMessage(GetString("GuessDisabled"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessDisabled"));
|
||
return true;
|
||
case CustomRoles.Terrorist when !Options.TerroristCanGuess.GetBool():
|
||
if (!isUI) Utils.SendMessage(GetString("GuessDisabled"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessDisabled"));
|
||
return true;
|
||
case CustomRoles.Workaholic when !Options.WorkaholicCanGuess.GetBool():
|
||
if (!isUI) Utils.SendMessage(GetString("GuessDisabled"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessDisabled"));
|
||
return true;
|
||
case CustomRoles.God when !Options.GodCanGuess.GetBool():
|
||
if (!isUI) Utils.SendMessage(GetString("GuessDisabled"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessDisabled"));
|
||
return true;
|
||
case CustomRoles.Monarch when role == CustomRoles.Knighted:
|
||
if (!isUI) Utils.SendMessage(GetString("GuessKnighted"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessKnighted"));
|
||
return true;
|
||
case CustomRoles.Doomsayer:
|
||
if (Doomsayer.CantGuess)
|
||
{
|
||
if (!isUI) Utils.SendMessage(GetString("DoomsayerCantGuess"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("DoomsayerCantGuess"));
|
||
return true;
|
||
}
|
||
|
||
if (role.IsImpostor() && !Doomsayer.DCanGuessImpostors.GetBool())
|
||
{
|
||
if (!isUI) Utils.SendMessage(GetString("GuessNotAllowed"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessNotAllowed"));
|
||
return true;
|
||
}
|
||
|
||
if (target.IsCrewmate() && !Doomsayer.DCanGuessCrewmates.GetBool())
|
||
{
|
||
if (!isUI) Utils.SendMessage(GetString("GuessNotAllowed"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessNotAllowed"));
|
||
return true;
|
||
}
|
||
|
||
if (role.IsNeutral() && !Doomsayer.DCanGuessNeutrals.GetBool())
|
||
{
|
||
if (!isUI) Utils.SendMessage(GetString("GuessNotAllowed"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessNotAllowed"));
|
||
return true;
|
||
}
|
||
|
||
if (role.IsAdditionRole() && !Doomsayer.DCanGuessAdt.GetBool())
|
||
{
|
||
if (!isUI) Utils.SendMessage(GetString("GuessAdtRole"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessAdtRole"));
|
||
return true;
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
if (Medic.ProtectList.Contains(target.PlayerId) && !Medic.GuesserIgnoreShield.GetBool())
|
||
{
|
||
if (!isUI) Utils.SendMessage(GetString("GuessShielded"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessShielded"));
|
||
return true;
|
||
}
|
||
|
||
switch (target.GetCustomRole())
|
||
{
|
||
case CustomRoles.Workaholic when Options.WorkaholicVisibleToEveryone.GetBool():
|
||
if (!isUI) Utils.SendMessage(GetString("GuessWorkaholic"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessWorkaholic"));
|
||
return true;
|
||
case CustomRoles.Doctor when Options.DoctorVisibleToEveryone.GetBool() && !target.HasEvilAddon():
|
||
if (!isUI) Utils.SendMessage(GetString("GuessDoctor"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessDoctor"));
|
||
return true;
|
||
case CustomRoles.Monarch when role == CustomRoles.Monarch && pc.Is(CustomRoles.Knighted):
|
||
if (!isUI) Utils.SendMessage(GetString("GuessMonarch"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessMonarch"));
|
||
return true;
|
||
case CustomRoles.Mayor when Mayor.MayorRevealWhenDoneTasks.GetBool() && target.GetTaskState().IsTaskFinished:
|
||
if (!isUI) Utils.SendMessage(GetString("GuessMayor"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessMayor"));
|
||
return true;
|
||
case CustomRoles.Bait when role == CustomRoles.Bait && Options.BaitNotification.GetBool():
|
||
if (!isUI) Utils.SendMessage(GetString("GuessNotifiedBait"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessNotifiedBait"));
|
||
return true;
|
||
case CustomRoles.Pestilence:
|
||
if (!isUI) Utils.SendMessage(GetString("GuessPestilence"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessPestilence"));
|
||
guesserSuicide = true;
|
||
break;
|
||
case CustomRoles.Phantom when role == CustomRoles.Phantom:
|
||
if (!isUI) Utils.SendMessage(GetString("GuessPhantom"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessPhantom"));
|
||
return true;
|
||
case CustomRoles.Snitch when target.GetTaskState().RemainingTasksCount <= Snitch.RemainingTasksToBeFound:
|
||
if (!isUI) Utils.SendMessage(GetString("EGGuessSnitchTaskDone"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("EGGuessSnitchTaskDone"));
|
||
return true;
|
||
case CustomRoles.Merchant when Merchant.IsBribedKiller(pc, target):
|
||
if (!isUI) Utils.SendMessage(GetString("BribedByMerchant2"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("BribedByMerchant2"));
|
||
return true;
|
||
case CustomRoles.SuperStar:
|
||
if (!isUI) Utils.SendMessage(GetString("GuessSuperStar"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessSuperStar"));
|
||
return true;
|
||
case CustomRoles.Disco:
|
||
case CustomRoles.Glow:
|
||
case CustomRoles.LastImpostor:
|
||
if (!isUI) Utils.SendMessage(GetString("GuessObviousAddon"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessObviousAddon"));
|
||
return true;
|
||
case CustomRoles.GM:
|
||
Utils.SendMessage(GetString("GuessGM"), pc.PlayerId);
|
||
return true;
|
||
default:
|
||
switch (role)
|
||
{
|
||
case CustomRoles.SuperStar:
|
||
if (!isUI) Utils.SendMessage(GetString("GuessSuperStar"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessSuperStar"));
|
||
return true;
|
||
case CustomRoles.GM:
|
||
Utils.SendMessage(GetString("GuessGM"), pc.PlayerId);
|
||
return true;
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
|
||
if (target.Is(CustomRoles.Onbound))
|
||
{
|
||
if (!isUI) Utils.SendMessage(GetString("GuessOnbound"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessOnbound"));
|
||
return true;
|
||
}
|
||
|
||
if (Jailor.playerIdList.Any(x => Main.PlayerStates[x].Role is Jailor { IsEnable: true } jl && jl.JailorTarget == target.PlayerId))
|
||
{
|
||
if (!isUI) Utils.SendMessage(GetString("CantGuessJailed"), pc.PlayerId, title: Utils.ColorString(Utils.GetRoleColor(CustomRoles.Jailor), GetString("JailorTitle")));
|
||
else pc.ShowPopUp(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Jailor), GetString("JailorTitle")) + "\n" + GetString("CantGuessJailed"));
|
||
return true;
|
||
}
|
||
|
||
if (Jailor.playerIdList.Any(x => Main.PlayerStates[x].Role is Jailor { IsEnable: true } jl && jl.JailorTarget == pc.PlayerId && role != CustomRoles.Jailor))
|
||
{
|
||
if (!isUI) Utils.SendMessage(GetString("JailedCanOnlyGuessJailor"), pc.PlayerId, title: Utils.ColorString(Utils.GetRoleColor(CustomRoles.Jailor), GetString("JailorTitle")));
|
||
else pc.ShowPopUp(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Jailor), GetString("JailorTitle")) + "\n" + GetString("JailedCanOnlyGuessJailor"));
|
||
return true;
|
||
}
|
||
|
||
// Check whether add-on guessing is allowed
|
||
switch (pc.GetCustomRole())
|
||
{
|
||
// Assassin Cant Guess Addons
|
||
case CustomRoles.EvilGuesser when role.IsAdditionRole() && !Options.EGCanGuessAdt.GetBool():
|
||
if (!isUI) Utils.SendMessage(GetString("GuessAdtRole"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessAdtRole"));
|
||
return true;
|
||
// Nice Guesser Cant Guess Addons
|
||
case CustomRoles.NiceGuesser when role.IsAdditionRole() && !Options.GGCanGuessAdt.GetBool():
|
||
if (!isUI) Utils.SendMessage(GetString("GuessAdtRole"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessAdtRole"));
|
||
return true;
|
||
// Guesser (add-on) Cant Guess Addons
|
||
default:
|
||
if (role.IsAdditionRole() && pc.Is(CustomRoles.Guesser) && !Options.GCanGuessAdt.GetBool())
|
||
{
|
||
if (!isUI) Utils.SendMessage(GetString("GuessAdtRole"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessAdtRole"));
|
||
return true;
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
// Guesser Mode Can/Cant Guess Addons
|
||
if (Options.GuesserMode.GetBool())
|
||
{
|
||
if (role.IsAdditionRole() && !Options.CanGuessAddons.GetBool())
|
||
{
|
||
// Impostors Cant Guess Addons
|
||
if (Options.ImpostorsCanGuess.GetBool() && pc.Is(CustomRoleTypes.Impostor) && !(pc.GetCustomRole() == CustomRoles.EvilGuesser || pc.Is(CustomRoles.Guesser)))
|
||
{
|
||
if (!isUI) Utils.SendMessage(GetString("GuessAdtRole"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessAdtRole"));
|
||
return true;
|
||
}
|
||
|
||
// Crewmates Cant Guess Addons
|
||
if (Options.CrewmatesCanGuess.GetBool() && pc.Is(CustomRoleTypes.Crewmate) && !(pc.GetCustomRole() == CustomRoles.NiceGuesser || pc.Is(CustomRoles.Guesser)))
|
||
{
|
||
if (!isUI) Utils.SendMessage(GetString("GuessAdtRole"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessAdtRole"));
|
||
return true;
|
||
}
|
||
|
||
// Neutrals Cant Guess Addons
|
||
if ((Options.NeutralKillersCanGuess.GetBool() || Options.PassiveNeutralsCanGuess.GetBool()) && pc.Is(CustomRoleTypes.Neutral) && !(pc.GetCustomRole() is CustomRoles.Ritualist or CustomRoles.Doomsayer || pc.Is(CustomRoles.Guesser)))
|
||
{
|
||
if (!isUI) Utils.SendMessage(GetString("GuessAdtRole"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessAdtRole"));
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (pc.PlayerId == target.PlayerId)
|
||
{
|
||
if (pc.Is(CustomRoles.DoubleShot) && !DoubleShot.IsActive.Contains(pc.PlayerId))
|
||
{
|
||
DoubleShot.IsActive.Add(pc.PlayerId);
|
||
|
||
Logger.Msg($"{pc.PlayerId}", "GuesserDoubleShotIsActive-1");
|
||
|
||
if (!isUI) Utils.SendMessage(GetString("GuessDoubleShot"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessDoubleShot"));
|
||
return true;
|
||
}
|
||
|
||
if (pc.Is(CustomRoles.DoubleShot) && DoubleShot.IsActive.Contains(pc.PlayerId))
|
||
DoubleShot.IsActive.Remove(pc.PlayerId);
|
||
|
||
if (!isUI) Utils.SendMessage(GetString("LaughToWhoGuessSelf"), pc.PlayerId, Utils.ColorString(Color.cyan, GetString("MessageFromKPD")));
|
||
else pc.ShowPopUp(Utils.ColorString(Color.cyan, GetString("MessageFromKPD")) + "\n" + GetString("LaughToWhoGuessSelf"));
|
||
guesserSuicide = true;
|
||
}
|
||
else if (pc.Is(CustomRoles.NiceGuesser) && target.Is(CustomRoleTypes.Crewmate) && !Options.GGCanGuessCrew.GetBool() && !pc.Is(CustomRoles.Madmate))
|
||
{
|
||
if (pc.Is(CustomRoles.DoubleShot) && !DoubleShot.IsActive.Contains(pc.PlayerId))
|
||
{
|
||
DoubleShot.IsActive.Add(pc.PlayerId);
|
||
|
||
Logger.Msg($"{pc.PlayerId}", "GuesserDoubleShotIsActive-2");
|
||
|
||
if (!isUI) Utils.SendMessage(GetString("GuessDoubleShot"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessDoubleShot"));
|
||
return true;
|
||
}
|
||
|
||
if (pc.Is(CustomRoles.DoubleShot) && DoubleShot.IsActive.Contains(pc.PlayerId))
|
||
DoubleShot.IsActive.Remove(pc.PlayerId);
|
||
|
||
guesserSuicide = true;
|
||
Logger.Msg($"{guesserSuicide}", "guesserSuicide1");
|
||
}
|
||
else if (pc.Is(CustomRoles.EvilGuesser) && target.Is(CustomRoleTypes.Impostor) && !Options.EGCanGuessImp.GetBool())
|
||
{
|
||
if (pc.Is(CustomRoles.DoubleShot) && !DoubleShot.IsActive.Contains(pc.PlayerId))
|
||
{
|
||
DoubleShot.IsActive.Add(pc.PlayerId);
|
||
|
||
Logger.Msg($"{pc.PlayerId}", "GuesserDoubleShotIsActive-3");
|
||
|
||
if (!isUI) Utils.SendMessage(GetString("GuessDoubleShot"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessDoubleShot"));
|
||
return true;
|
||
}
|
||
|
||
if (pc.Is(CustomRoles.DoubleShot) && DoubleShot.IsActive.Contains(pc.PlayerId))
|
||
DoubleShot.IsActive.Remove(pc.PlayerId);
|
||
|
||
guesserSuicide = true;
|
||
Logger.Msg($"{guesserSuicide}", "guesserSuicide2");
|
||
}
|
||
// else if (pc.Is(CustomRoles.Guesser)/* && role.IsImpostor() && !Options.GCanGuessImp.GetBool()*/) guesserSuicide = true;
|
||
// else if (pc.Is(CustomRoles.Guesser)/* && role.IsCrewmate() && !pc.Is(CustomRoles.Madmate) && !Options.GCanGuessCrew.GetBool() */) guesserSuicide = true;
|
||
else if (!target.Is(role))
|
||
{
|
||
if (pc.Is(CustomRoles.DoubleShot) && !DoubleShot.IsActive.Contains(pc.PlayerId))
|
||
{
|
||
DoubleShot.IsActive.Add(pc.PlayerId);
|
||
|
||
Logger.Msg($"{pc.PlayerId}", "GuesserDoubleShotIsActive-4");
|
||
|
||
if (!isUI) Utils.SendMessage(GetString("GuessDoubleShot"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("GuessDoubleShot"));
|
||
return true;
|
||
}
|
||
|
||
if (pc.Is(CustomRoles.DoubleShot) && DoubleShot.IsActive.Contains(pc.PlayerId))
|
||
DoubleShot.IsActive.Remove(pc.PlayerId);
|
||
|
||
guesserSuicide = true;
|
||
Logger.Msg($"{guesserSuicide}", "guesserSuicide3");
|
||
}
|
||
|
||
|
||
// -----------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
|
||
Logger.Info($"{pc.GetNameWithRole().RemoveHtmlTags()} guessed {target.GetNameWithRole().RemoveHtmlTags()}", "Guesser");
|
||
|
||
var dp = guesserSuicide ? pc : target;
|
||
target = dp;
|
||
|
||
Logger.Info($"Player:{target.GetRealName().RemoveHtmlTags()} was guessed by {pc.GetRealName().RemoveHtmlTags()}", "Guesser");
|
||
|
||
Main.GuesserGuessed[pc.PlayerId]++;
|
||
|
||
if (pc.Is(CustomRoles.Doomsayer) && Doomsayer.AdvancedSettings.GetBool())
|
||
{
|
||
if (Doomsayer.GuessesCountPerMeeting >= Doomsayer.MaxNumberOfGuessesPerMeeting.GetInt() && pc.PlayerId != dp.PlayerId)
|
||
{
|
||
if (!isUI) Utils.SendMessage(GetString("DoomsayerCantGuess"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("DoomsayerCantGuess"));
|
||
return true;
|
||
}
|
||
|
||
Doomsayer.GuessesCountPerMeeting++;
|
||
|
||
if (Doomsayer.GuessesCountPerMeeting >= Doomsayer.MaxNumberOfGuessesPerMeeting.GetInt())
|
||
Doomsayer.CantGuess = true;
|
||
|
||
if (!Doomsayer.KillCorrectlyGuessedPlayers.GetBool() && pc.PlayerId != dp.PlayerId)
|
||
{
|
||
if (!isUI) Utils.SendMessage(GetString("DoomsayerCorrectlyGuessRole"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("DoomsayerCorrectlyGuessRole"));
|
||
|
||
if (Doomsayer.GuessedRoles.Contains(role))
|
||
{
|
||
_ = new LateTask(() => { Utils.SendMessage(GetString("DoomsayerGuessSameRoleAgainMsg"), pc.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Doomsayer), GetString("DoomsayerGuessCountTitle"))); }, 0.7f, "Doomsayer Guess Same Role Again Msg");
|
||
}
|
||
else
|
||
{
|
||
Doomsayer.GuessingToWin[pc.PlayerId]++;
|
||
Doomsayer.SendRPC(pc);
|
||
Doomsayer.GuessedRoles.Add(role);
|
||
|
||
_ = new LateTask(() => { Utils.SendMessage(string.Format(GetString("DoomsayerGuessCountMsg"), Doomsayer.GuessingToWin[pc.PlayerId]), pc.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Doomsayer), GetString("DoomsayerGuessCountTitle"))); }, 0.7f, "Doomsayer Guess Msg 1");
|
||
}
|
||
|
||
Doomsayer.CheckCountGuess(pc);
|
||
|
||
return true;
|
||
}
|
||
|
||
if (Doomsayer.DoesNotSuicideWhenMisguessing.GetBool() && pc.PlayerId == dp.PlayerId)
|
||
{
|
||
if (!isUI) Utils.SendMessage(GetString("DoomsayerNotCorrectlyGuessRole"), pc.PlayerId);
|
||
else pc.ShowPopUp(GetString("DoomsayerNotCorrectlyGuessRole"));
|
||
|
||
if (Doomsayer.MisguessRolePrevGuessRoleUntilNextMeeting.GetBool())
|
||
{
|
||
Doomsayer.CantGuess = true;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
}
|
||
|
||
string Name = dp.GetRealName();
|
||
if (!Options.DisableKillAnimationOnGuess.GetBool()) CustomSoundsManager.RPCPlayCustomSoundAll("Gunfire");
|
||
|
||
_ = new LateTask(() =>
|
||
{
|
||
Main.PlayerStates[dp.PlayerId].deathReason = PlayerState.DeathReason.Gambled;
|
||
dp.SetRealKiller(pc);
|
||
dp.RpcGuesserMurderPlayer();
|
||
|
||
if (dp.Is(CustomRoles.Medic))
|
||
Medic.IsDead(dp);
|
||
|
||
if (pc.Is(CustomRoles.Doomsayer) && pc.PlayerId != dp.PlayerId)
|
||
{
|
||
Doomsayer.GuessingToWin[pc.PlayerId]++;
|
||
Doomsayer.SendRPC(pc);
|
||
|
||
if (!Doomsayer.GuessedRoles.Contains(role))
|
||
Doomsayer.GuessedRoles.Add(role);
|
||
|
||
Doomsayer.CheckCountGuess(pc);
|
||
}
|
||
|
||
GuessManagerRole.OnGuess(dp, pc);
|
||
|
||
Utils.AfterPlayerDeathTasks(dp, true);
|
||
|
||
Utils.NotifyRoles(isForMeeting: GameStates.IsMeeting, NoCache: true);
|
||
|
||
_ = new LateTask(() => { Utils.SendMessage(string.Format(GetString("GuessKill"), Name), 255, Utils.ColorString(Utils.GetRoleColor(CustomRoles.NiceGuesser), GetString("GuessKillTitle"))); }, 0.6f, "Guess Msg");
|
||
|
||
if (pc.Is(CustomRoles.Doomsayer) && pc.PlayerId != dp.PlayerId)
|
||
{
|
||
_ = new LateTask(() => { Utils.SendMessage(string.Format(GetString("DoomsayerGuessCountMsg"), Doomsayer.GuessingToWin[pc.PlayerId]), pc.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Doomsayer), GetString("DoomsayerGuessCountTitle"))); }, 0.7f, "Doomsayer Guess Msg 2");
|
||
}
|
||
}, 0.2f, "Guesser Kill");
|
||
}
|
||
|
||
break;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
public static TextMeshPro NameText(this PlayerControl p) => p.cosmetics.nameText;
|
||
public static TextMeshPro NameText(this PoolablePlayer p) => p.cosmetics.nameText;
|
||
|
||
public static void RpcGuesserMurderPlayer(this PlayerControl pc /*, float delay = 0f*/)
|
||
{
|
||
// DEATH STUFF //
|
||
var amOwner = pc.AmOwner;
|
||
pc.Data.IsDead = true;
|
||
pc.RpcExileV2();
|
||
Main.PlayerStates[pc.PlayerId].SetDead();
|
||
var meetingHud = MeetingHud.Instance;
|
||
var hudManager = DestroyableSingleton<HudManager>.Instance;
|
||
SoundManager.Instance.PlaySound(pc.KillSfx, false, 0.8f);
|
||
if (!Options.DisableKillAnimationOnGuess.GetBool()) hudManager.KillOverlay.ShowKillAnimation(pc.Data, pc.Data);
|
||
if (amOwner)
|
||
{
|
||
hudManager.ShadowQuad.gameObject.SetActive(false);
|
||
pc.NameText().GetComponent<MeshRenderer>().material.SetInt("_Mask", 0);
|
||
pc.RpcSetScanner(false);
|
||
ImportantTextTask importantTextTask = new GameObject("_Player").AddComponent<ImportantTextTask>();
|
||
importantTextTask.transform.SetParent(AmongUsClient.Instance.transform, false);
|
||
meetingHud.SetForegroundForDead();
|
||
}
|
||
|
||
PlayerVoteArea voteArea = MeetingHud.Instance.playerStates.First(
|
||
x => x.TargetPlayerId == pc.PlayerId
|
||
);
|
||
if (voteArea.DidVote) voteArea.UnsetVote();
|
||
voteArea.AmDead = true;
|
||
voteArea.Overlay.gameObject.SetActive(true);
|
||
voteArea.Overlay.color = Color.white;
|
||
voteArea.XMark.gameObject.SetActive(true);
|
||
voteArea.XMark.transform.localScale = Vector3.one;
|
||
foreach (var playerVoteArea in meetingHud.playerStates)
|
||
{
|
||
if (playerVoteArea.VotedFor != pc.PlayerId) continue;
|
||
playerVoteArea.UnsetVote();
|
||
var voteAreaPlayer = Utils.GetPlayerById(playerVoteArea.TargetPlayerId);
|
||
if (!voteAreaPlayer.AmOwner) continue;
|
||
meetingHud.ClearVote();
|
||
}
|
||
|
||
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.GuessKill, SendOption.Reliable);
|
||
writer.Write(pc.PlayerId);
|
||
AmongUsClient.Instance.FinishRpcImmediately(writer);
|
||
}
|
||
|
||
public static void RpcClientGuess(PlayerControl pc)
|
||
{
|
||
var amOwner = pc.AmOwner;
|
||
var meetingHud = MeetingHud.Instance;
|
||
var hudManager = DestroyableSingleton<HudManager>.Instance;
|
||
SoundManager.Instance.PlaySound(pc.KillSfx, false, 0.8f);
|
||
if (!Options.DisableKillAnimationOnGuess.GetBool()) hudManager.KillOverlay.ShowKillAnimation(pc.Data, pc.Data);
|
||
if (amOwner)
|
||
{
|
||
hudManager.ShadowQuad.gameObject.SetActive(false);
|
||
pc.NameText().GetComponent<MeshRenderer>().material.SetInt("_Mask", 0);
|
||
pc.RpcSetScanner(false);
|
||
ImportantTextTask importantTextTask = new GameObject("_Player").AddComponent<ImportantTextTask>();
|
||
importantTextTask.transform.SetParent(AmongUsClient.Instance.transform, false);
|
||
meetingHud.SetForegroundForDead();
|
||
}
|
||
|
||
PlayerVoteArea voteArea = MeetingHud.Instance.playerStates.First(
|
||
x => x.TargetPlayerId == pc.PlayerId
|
||
);
|
||
if (voteArea.DidVote) voteArea.UnsetVote();
|
||
voteArea.AmDead = true;
|
||
voteArea.Overlay.gameObject.SetActive(true);
|
||
voteArea.Overlay.color = Color.white;
|
||
voteArea.XMark.gameObject.SetActive(true);
|
||
voteArea.XMark.transform.localScale = Vector3.one;
|
||
foreach (var playerVoteArea in meetingHud.playerStates)
|
||
{
|
||
if (playerVoteArea.VotedFor != pc.PlayerId) continue;
|
||
playerVoteArea.UnsetVote();
|
||
var voteAreaPlayer = Utils.GetPlayerById(playerVoteArea.TargetPlayerId);
|
||
if (!voteAreaPlayer.AmOwner) continue;
|
||
meetingHud.ClearVote();
|
||
}
|
||
}
|
||
|
||
public static bool MsgToPlayerAndRole(string msg, out byte id, out CustomRoles role, out string error)
|
||
{
|
||
if (msg.StartsWith("/")) msg = msg.Replace("/", string.Empty);
|
||
|
||
Regex r = new("\\d+");
|
||
MatchCollection mc = r.Matches(msg);
|
||
string result = string.Empty;
|
||
for (int i = 0; i < mc.Count; i++)
|
||
{
|
||
result += mc[i]; // The matching result is a complete number, and no splicing is required here.
|
||
}
|
||
|
||
if (byte.TryParse(result, out byte num))
|
||
{
|
||
id = num;
|
||
}
|
||
else
|
||
{
|
||
// It is not the player number, it determines whether it is the color or not.
|
||
//byte color = GetColorFromMsg(msg);
|
||
// Okay, I don’t know how to get the color of a certain player. I’ll fill it in later.
|
||
id = byte.MaxValue;
|
||
error = GetString("GuessHelp");
|
||
role = new();
|
||
return false;
|
||
}
|
||
|
||
// Determine whether the selected player is reasonable
|
||
PlayerControl target = Utils.GetPlayerById(id);
|
||
if (target == null || target.Data.IsDead)
|
||
{
|
||
error = GetString("GuessNull");
|
||
role = new();
|
||
return false;
|
||
}
|
||
|
||
if (!ChatCommands.GetRoleByName(msg, out role))
|
||
{
|
||
error = GetString("GuessHelp");
|
||
return false;
|
||
}
|
||
|
||
error = string.Empty;
|
||
return true;
|
||
}
|
||
|
||
/*
|
||
public static void TryHideMsg()
|
||
{
|
||
ChatUpdatePatch.DoBlockChat = true;
|
||
List<CustomRoles> roles = Enum.GetValues(typeof(CustomRoles)).Cast<CustomRoles>().Where(x => x is not CustomRoles.NotAssigned and not CustomRoles.KB_Normal).ToList();
|
||
var rd = IRandom.Instance;
|
||
string msg = Utils.EmptyMessage();
|
||
string[] command = ["bet", "bt", "guess", "gs", "shoot", "st", "赌", "猜", "审判", "tl", "判", "审"];
|
||
var x = Main.AllAlivePlayerControls;
|
||
var totalAlive = Main.AllAlivePlayerControls.Length;
|
||
for (int i = 0; i < 20; i++)
|
||
{
|
||
//msg = "/";
|
||
//if (rd.Next(1, 100) < 20)
|
||
//{
|
||
// msg += "id";
|
||
//}
|
||
//else
|
||
//{
|
||
// msg += command[rd.Next(0, command.Length - 1)];
|
||
// msg += rd.Next(1, 100) < 50 ? string.Empty : " ";
|
||
// msg += rd.Next(0, 15).ToString();
|
||
// msg += rd.Next(1, 100) < 50 ? string.Empty : " ";
|
||
// CustomRoles role = roles[rd.Next(0, roles.Count)];
|
||
// msg += rd.Next(1, 100) < 50 ? string.Empty : " ";
|
||
// msg += Utils.GetRoleName(role);
|
||
//}
|
||
var player = x[rd.Next(0, totalAlive)];
|
||
DestroyableSingleton<HudManager>.Instance.Chat.AddChat(player, msg);
|
||
var writer = CustomRpcSender.Create("MessagesToSend");
|
||
writer.StartMessage();
|
||
writer.StartRpc(player.NetId, (byte)RpcCalls.SendChat)
|
||
.Write(msg)
|
||
.EndRpc();
|
||
writer.EndMessage();
|
||
writer.SendMessage();
|
||
}
|
||
|
||
ChatUpdatePatch.DoBlockChat = false;
|
||
}
|
||
*/
|
||
|
||
[HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.Start))]
|
||
class StartMeetingPatch
|
||
{
|
||
public static void Postfix(MeetingHud __instance)
|
||
{
|
||
var lp = PlayerControl.LocalPlayer;
|
||
bool alive = lp.IsAlive();
|
||
if (Options.GuesserMode.GetBool())
|
||
{
|
||
CustomRoles role = lp.GetCustomRole();
|
||
if (alive && role.IsImpostor() && Options.ImpostorsCanGuess.GetBool())
|
||
CreateGuesserButton(__instance);
|
||
else if (role is CustomRoles.EvilGuesser && !Options.ImpostorsCanGuess.GetBool())
|
||
CreateGuesserButton(__instance);
|
||
|
||
if (alive && lp.IsCrewmate() && Options.CrewmatesCanGuess.GetBool())
|
||
CreateGuesserButton(__instance);
|
||
else if (role is CustomRoles.NiceGuesser && !Options.CrewmatesCanGuess.GetBool())
|
||
CreateGuesserButton(__instance);
|
||
|
||
if (alive && lp.IsNeutralKiller() && Options.NeutralKillersCanGuess.GetBool())
|
||
CreateGuesserButton(__instance);
|
||
if (alive && role.IsNonNK() && Options.PassiveNeutralsCanGuess.GetBool())
|
||
CreateGuesserButton(__instance);
|
||
else if (role is CustomRoles.Doomsayer && !Options.PassiveNeutralsCanGuess.GetBool() && !Doomsayer.CantGuess)
|
||
CreateGuesserButton(__instance);
|
||
}
|
||
else
|
||
{
|
||
if (alive && lp.Is(CustomRoles.EvilGuesser))
|
||
CreateGuesserButton(__instance);
|
||
|
||
if (alive && lp.Is(CustomRoles.NiceGuesser))
|
||
CreateGuesserButton(__instance);
|
||
|
||
if (alive && lp.Is(CustomRoles.Doomsayer) && !Doomsayer.CantGuess)
|
||
CreateGuesserButton(__instance);
|
||
|
||
if (alive && lp.Is(CustomRoles.Guesser))
|
||
CreateGuesserButton(__instance);
|
||
}
|
||
}
|
||
}
|
||
|
||
public static void CreateGuesserButton(MeetingHud __instance)
|
||
{
|
||
foreach (var pva in __instance.playerStates)
|
||
{
|
||
var pc = Utils.GetPlayerById(pva.TargetPlayerId);
|
||
if (pc == null || !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.95f, 0.03f, -1.31f);
|
||
SpriteRenderer renderer = targetBox.GetComponent<SpriteRenderer>();
|
||
renderer.sprite = CustomButton.Get("TargetIcon");
|
||
PassiveButton button = targetBox.GetComponent<PassiveButton>();
|
||
button.OnClick.RemoveAllListeners();
|
||
var pva1 = pva;
|
||
button.OnClick.AddListener((Action)(() => GuesserOnClick(pva1.TargetPlayerId, __instance)));
|
||
}
|
||
}
|
||
|
||
public const int MaxOneScreenRole = 40;
|
||
public static int Page;
|
||
public static PassiveButton ExitButton;
|
||
public static GameObject guesserUI;
|
||
private static Dictionary<CustomRoleTypes, List<Transform>> RoleButtons;
|
||
private static Dictionary<CustomRoleTypes, SpriteRenderer> RoleSelectButtons;
|
||
private static List<SpriteRenderer> PageButtons;
|
||
public static CustomRoleTypes currentTeamType;
|
||
|
||
static void GuesserSelectRole(CustomRoleTypes Role, bool SetPage = true)
|
||
{
|
||
currentTeamType = Role;
|
||
if (SetPage) Page = 1;
|
||
foreach (var RoleButton in RoleButtons)
|
||
{
|
||
int index = 0;
|
||
foreach (var RoleBtn in RoleButton.Value)
|
||
{
|
||
if (RoleBtn == null) continue;
|
||
index++;
|
||
if (index <= (Page - 1) * 40)
|
||
{
|
||
RoleBtn.gameObject.SetActive(false);
|
||
continue;
|
||
}
|
||
|
||
if ((Page * 40) < index)
|
||
{
|
||
RoleBtn.gameObject.SetActive(false);
|
||
continue;
|
||
}
|
||
|
||
RoleBtn.gameObject.SetActive(RoleButton.Key == Role);
|
||
}
|
||
}
|
||
|
||
foreach (var RoleButton in RoleSelectButtons)
|
||
{
|
||
if (RoleButton.Value == null) continue;
|
||
RoleButton.Value.color = new(0, 0, 0, RoleButton.Key == Role ? 1 : 0.25f);
|
||
}
|
||
}
|
||
|
||
public static TextMeshPro textTemplate;
|
||
|
||
static void GuesserOnClick(byte playerId, MeetingHud __instance)
|
||
{
|
||
var pc = Utils.GetPlayerById(playerId);
|
||
if (pc == null || !pc.IsAlive() || guesserUI != null || !GameStates.IsVoting) return;
|
||
|
||
try
|
||
{
|
||
Page = 1;
|
||
RoleButtons = [];
|
||
RoleSelectButtons = [];
|
||
PageButtons = [];
|
||
__instance.playerStates.ToList().ForEach(x => x.gameObject.SetActive(false));
|
||
|
||
Transform container = Object.Instantiate(GameObject.Find("PhoneUI").transform, __instance.transform);
|
||
container.transform.localPosition = new(0, 0, -200f);
|
||
guesserUI = container.gameObject;
|
||
|
||
List<int> i = [0, 0, 0, 0];
|
||
var buttonTemplate = __instance.playerStates[0].transform.FindChild("votePlayerBase");
|
||
var maskTemplate = __instance.playerStates[0].transform.FindChild("MaskArea");
|
||
var smallButtonTemplate = __instance.playerStates[0].Buttons.transform.Find("CancelButton");
|
||
textTemplate.enabled = true;
|
||
if (textTemplate.transform.FindChild("RoleTextMeeting") != null) Object.Destroy(textTemplate.transform.FindChild("RoleTextMeeting").gameObject);
|
||
|
||
Transform exitButtonParent = new GameObject().transform;
|
||
exitButtonParent.SetParent(container);
|
||
Transform exitButton = Object.Instantiate(buttonTemplate, exitButtonParent);
|
||
exitButton.FindChild("ControllerHighlight").gameObject.SetActive(false);
|
||
Transform exitButtonMask = Object.Instantiate(maskTemplate, exitButtonParent);
|
||
exitButtonMask.transform.localScale = new(2.88f, 0.8f, 1f);
|
||
exitButtonMask.transform.localPosition = new(0f, 0f, 1f);
|
||
exitButton.gameObject.GetComponent<SpriteRenderer>().sprite = smallButtonTemplate.GetComponent<SpriteRenderer>().sprite;
|
||
exitButtonParent.transform.localPosition = new(3.88f, 2.12f, -200f);
|
||
exitButtonParent.transform.localScale = new(0.22f, 0.9f, 1f);
|
||
exitButtonParent.transform.SetAsFirstSibling();
|
||
exitButton.GetComponent<PassiveButton>().OnClick.RemoveAllListeners();
|
||
exitButton.GetComponent<PassiveButton>().OnClick.AddListener((Action)(() =>
|
||
{
|
||
__instance.playerStates.ToList().ForEach(x => x.gameObject.SetActive(true));
|
||
Object.Destroy(container.gameObject);
|
||
}));
|
||
ExitButton = exitButton.GetComponent<PassiveButton>();
|
||
|
||
List<Transform> buttons = [];
|
||
Transform selectedButton = null;
|
||
|
||
int tabCount = 0;
|
||
for (int index = 0; index < 4; index++)
|
||
{
|
||
if (PlayerControl.LocalPlayer.Is(CustomRoles.EvilGuesser))
|
||
{
|
||
if (!Options.EGCanGuessImp.GetBool() && index == 1) continue;
|
||
if (!Options.EGCanGuessAdt.GetBool() && index == 3) continue;
|
||
}
|
||
else if (PlayerControl.LocalPlayer.Is(CustomRoles.NiceGuesser))
|
||
{
|
||
if (!Options.GGCanGuessCrew.GetBool() && index == 0) continue;
|
||
if (!Options.GGCanGuessAdt.GetBool() && index == 3) continue;
|
||
}
|
||
else if (PlayerControl.LocalPlayer.Is(CustomRoles.Doomsayer))
|
||
{
|
||
if (!Doomsayer.DCanGuessCrewmates.GetBool() && index == 0) continue;
|
||
if (!Doomsayer.DCanGuessImpostors.GetBool() && index == 1) continue;
|
||
if (!Doomsayer.DCanGuessNeutrals.GetBool() && index == 2) continue;
|
||
if (!Doomsayer.DCanGuessAdt.GetBool() && index == 3) continue;
|
||
}
|
||
else if (PlayerControl.LocalPlayer.Is(CustomRoles.Guesser))
|
||
{
|
||
if (!Options.GCanGuessCrew.GetBool() && PlayerControl.LocalPlayer.Is(CustomRoleTypes.Crewmate) && index == 0) continue;
|
||
if (!Options.GCanGuessImp.GetBool() && PlayerControl.LocalPlayer.Is(CustomRoleTypes.Impostor) && index == 1) continue;
|
||
if (!Options.GCanGuessAdt.GetBool() && index == 3) continue;
|
||
}
|
||
else if (Options.GuesserMode.GetBool())
|
||
{
|
||
if (!Options.CrewCanGuessCrew.GetBool() && PlayerControl.LocalPlayer.Is(CustomRoleTypes.Crewmate) && index == 0) continue;
|
||
if (!Options.ImpCanGuessImp.GetBool() && PlayerControl.LocalPlayer.Is(CustomRoleTypes.Impostor) && index == 1) continue;
|
||
// if (index == 2) continue;
|
||
if (!Options.CanGuessAddons.GetBool() && index == 3) continue;
|
||
}
|
||
|
||
Transform TeambuttonParent = new GameObject().transform;
|
||
TeambuttonParent.SetParent(container);
|
||
Transform Teambutton = Object.Instantiate(buttonTemplate, TeambuttonParent);
|
||
Teambutton.FindChild("ControllerHighlight").gameObject.SetActive(false);
|
||
Transform TeambuttonMask = Object.Instantiate(maskTemplate, TeambuttonParent);
|
||
TextMeshPro Teamlabel = Object.Instantiate(textTemplate, Teambutton);
|
||
Teambutton.GetComponent<SpriteRenderer>().sprite = CustomButton.Get("GuessPlateWithKPD");
|
||
RoleSelectButtons.Add((CustomRoleTypes)index, Teambutton.GetComponent<SpriteRenderer>());
|
||
TeambuttonParent.localPosition = new(-2.75f + (tabCount++ * 1.73f), 2.225f, -200);
|
||
TeambuttonParent.localScale = new(0.53f, 0.53f, 1f);
|
||
Teamlabel.color = (CustomRoleTypes)index switch
|
||
{
|
||
CustomRoleTypes.Crewmate => new(140, 255, 255, byte.MaxValue),
|
||
CustomRoleTypes.Impostor => new(255, 25, 25, byte.MaxValue),
|
||
CustomRoleTypes.Neutral => new(255, 171, 27, byte.MaxValue),
|
||
CustomRoleTypes.Addon => new Color32(255, 154, 206, byte.MaxValue),
|
||
_ => throw new NotImplementedException(),
|
||
};
|
||
Logger.Info(Teamlabel.color.ToString(), ((CustomRoleTypes)index).ToString());
|
||
Teamlabel.text = GetString("Type" + ((CustomRoleTypes)index));
|
||
Teamlabel.alignment = TextAlignmentOptions.Center;
|
||
Teamlabel.transform.localPosition = new(0, 0, Teamlabel.transform.localPosition.z);
|
||
Teamlabel.transform.localScale *= 1.6f;
|
||
Teamlabel.autoSizeTextContainer = true;
|
||
|
||
if (PlayerControl.LocalPlayer.IsAlive()) CreateTeamButton(Teambutton, (CustomRoleTypes)index);
|
||
continue;
|
||
|
||
static void CreateTeamButton(Component Teambutton, CustomRoleTypes type)
|
||
{
|
||
Teambutton.GetComponent<PassiveButton>().OnClick.AddListener((UnityAction)(() =>
|
||
{
|
||
GuesserSelectRole(type);
|
||
ReloadPage();
|
||
}));
|
||
}
|
||
}
|
||
|
||
static void ReloadPage()
|
||
{
|
||
PageButtons[0].color = new(1, 1, 1, 1f);
|
||
PageButtons[1].color = new(1, 1, 1, 1f);
|
||
if ((RoleButtons[currentTeamType].Count / MaxOneScreenRole + (RoleButtons[currentTeamType].Count % MaxOneScreenRole != 0 ? 1 : 0)) < Page)
|
||
{
|
||
Page -= 1;
|
||
PageButtons[1].color = new(1, 1, 1, 0.1f);
|
||
}
|
||
else if ((RoleButtons[currentTeamType].Count / MaxOneScreenRole + (RoleButtons[currentTeamType].Count % MaxOneScreenRole != 0 ? 1 : 0)) < Page + 1)
|
||
{
|
||
PageButtons[1].color = new(1, 1, 1, 0.1f);
|
||
}
|
||
|
||
if (Page <= 1)
|
||
{
|
||
Page = 1;
|
||
PageButtons[0].color = new(1, 1, 1, 0.1f);
|
||
}
|
||
|
||
GuesserSelectRole(currentTeamType, false);
|
||
}
|
||
|
||
static void CreatePage(bool IsNext, MeetingHud __instance, Transform container)
|
||
{
|
||
var buttonTemplate = __instance.playerStates[0].transform.FindChild("votePlayerBase");
|
||
var maskTemplate = __instance.playerStates[0].transform.FindChild("MaskArea");
|
||
var smallButtonTemplate = __instance.playerStates[0].Buttons.transform.Find("CancelButton");
|
||
Transform PagebuttonParent = new GameObject().transform;
|
||
PagebuttonParent.SetParent(container);
|
||
Transform Pagebutton = Object.Instantiate(buttonTemplate, PagebuttonParent);
|
||
Pagebutton.FindChild("ControllerHighlight").gameObject.SetActive(false);
|
||
Transform PagebuttonMask = Object.Instantiate(maskTemplate, PagebuttonParent);
|
||
TextMeshPro Pagelabel = Object.Instantiate(textTemplate, Pagebutton);
|
||
Pagebutton.GetComponent<SpriteRenderer>().sprite = CustomButton.Get("GuessPlateWithKPD");
|
||
PagebuttonParent.localPosition = IsNext ? new(3.535f, -2.2f, -200) : new(-3.475f, -2.2f, -200);
|
||
PagebuttonParent.localScale = new(0.55f, 0.55f, 1f);
|
||
Pagelabel.color = Color.white;
|
||
Pagelabel.text = GetString(IsNext ? "NextPage" : "PreviousPage");
|
||
Pagelabel.alignment = TextAlignmentOptions.Center;
|
||
Pagelabel.transform.localPosition = new(0, 0, Pagelabel.transform.localPosition.z);
|
||
Pagelabel.transform.localScale *= 1.6f;
|
||
Pagelabel.autoSizeTextContainer = true;
|
||
if (!IsNext && Page <= 1) Pagebutton.GetComponent<SpriteRenderer>().color = new(1, 1, 1, 0.1f);
|
||
Pagebutton.GetComponent<PassiveButton>().OnClick.AddListener((Action)(() => ClickEvent()));
|
||
|
||
PageButtons.Add(Pagebutton.GetComponent<SpriteRenderer>());
|
||
return;
|
||
|
||
void ClickEvent()
|
||
{
|
||
if (IsNext) Page += 1;
|
||
else Page -= 1;
|
||
if (Page < 1) Page = 1;
|
||
ReloadPage();
|
||
}
|
||
}
|
||
|
||
if (PlayerControl.LocalPlayer.IsAlive())
|
||
{
|
||
CreatePage(false, __instance, container);
|
||
CreatePage(true, __instance, container);
|
||
}
|
||
|
||
var sortedRoles = EnumHelper.GetAllValues<CustomRoles>().OrderBy(x => GetString($"{x}")).ToArray();
|
||
foreach (var role in sortedRoles)
|
||
{
|
||
if (role is CustomRoles.GM
|
||
or CustomRoles.SpeedBooster
|
||
or CustomRoles.Engineer
|
||
or CustomRoles.Crewmate
|
||
or CustomRoles.Oblivious
|
||
or CustomRoles.Rogue
|
||
or CustomRoles.Scientist
|
||
or CustomRoles.Impostor
|
||
or CustomRoles.Shapeshifter
|
||
or CustomRoles.Flashman
|
||
or CustomRoles.Disco
|
||
or CustomRoles.Giant
|
||
or CustomRoles.NotAssigned
|
||
or CustomRoles.KB_Normal
|
||
or CustomRoles.Paranoia
|
||
or CustomRoles.SuperStar
|
||
or CustomRoles.Konan
|
||
or CustomRoles.Oblivious
|
||
or CustomRoles.GuardianAngelEHR
|
||
) continue;
|
||
|
||
if (!role.IsEnable() && !role.RoleExist(countDead: true) && !role.IsConverted()) continue;
|
||
|
||
CreateRole(role);
|
||
}
|
||
|
||
void CreateRole(CustomRoles role)
|
||
{
|
||
if (40 <= i[(int)role.GetCustomRoleTypes()]) i[(int)role.GetCustomRoleTypes()] = 0;
|
||
Transform buttonParent = new GameObject().transform;
|
||
buttonParent.SetParent(container);
|
||
Transform button = Object.Instantiate(buttonTemplate, buttonParent);
|
||
button.FindChild("ControllerHighlight").gameObject.SetActive(false);
|
||
Transform buttonMask = Object.Instantiate(maskTemplate, buttonParent);
|
||
TextMeshPro label = Object.Instantiate(textTemplate, button);
|
||
button.GetComponent<SpriteRenderer>().sprite = CustomButton.Get("GuessPlate");
|
||
if (!RoleButtons.ContainsKey(role.GetCustomRoleTypes()))
|
||
{
|
||
RoleButtons.Add(role.GetCustomRoleTypes(), []);
|
||
}
|
||
|
||
RoleButtons[role.GetCustomRoleTypes()].Add(button);
|
||
buttons.Add(button);
|
||
int row = i[(int)role.GetCustomRoleTypes()] / 5;
|
||
int col = i[(int)role.GetCustomRoleTypes()] % 5;
|
||
buttonParent.localPosition = new(-3.47f + 1.75f * col, 1.5f - 0.45f * row, -200f);
|
||
buttonParent.localScale = new(0.55f, 0.55f, 1f);
|
||
label.text = GetString(role.ToString());
|
||
label.color = Utils.GetRoleColor(role);
|
||
label.alignment = TextAlignmentOptions.Center;
|
||
label.transform.localPosition = new(0, 0, label.transform.localPosition.z);
|
||
label.transform.localScale *= 1.6f;
|
||
label.autoSizeTextContainer = true;
|
||
_ = i[(int)role.GetCustomRoleTypes()];
|
||
|
||
button.GetComponent<PassiveButton>().OnClick.RemoveAllListeners();
|
||
if (PlayerControl.LocalPlayer.IsAlive())
|
||
button.GetComponent<PassiveButton>().OnClick.AddListener((Action)(() =>
|
||
{
|
||
if (selectedButton != button)
|
||
{
|
||
selectedButton = button;
|
||
buttons.ForEach(x => x.GetComponent<SpriteRenderer>().color = x == selectedButton ? Utils.GetRoleColor(PlayerControl.LocalPlayer.GetCustomRole()) : Color.white);
|
||
}
|
||
else
|
||
{
|
||
if (!(__instance.state == MeetingHud.VoteStates.Voted || __instance.state == MeetingHud.VoteStates.NotVoted) || !PlayerControl.LocalPlayer.IsAlive()) return;
|
||
|
||
Logger.Msg($"Click: {pc.GetNameWithRole().RemoveHtmlTags()} => {role}", "Guesser UI");
|
||
|
||
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));
|
||
Object.Destroy(container.gameObject);
|
||
textTemplate.enabled = false;
|
||
}
|
||
}));
|
||
i[(int)role.GetCustomRoleTypes()]++;
|
||
}
|
||
|
||
container.transform.localScale *= 0.75f;
|
||
GuesserSelectRole(CustomRoleTypes.Crewmate);
|
||
ReloadPage();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.Exception(ex, "Guesser UI");
|
||
return;
|
||
}
|
||
|
||
PlayerControl.LocalPlayer.RPCPlayCustomSound("Gunload");
|
||
}
|
||
|
||
[HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.OnDestroy))]
|
||
class MeetingHudOnDestroyGuesserUIClose
|
||
{
|
||
public static void Postfix()
|
||
{
|
||
Object.Destroy(textTemplate.gameObject);
|
||
}
|
||
}
|
||
|
||
// Modded non-host client guess role/add-on
|
||
private static void SendRPC(int playerId, CustomRoles role)
|
||
{
|
||
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (int)CustomRPC.Guess, SendOption.Reliable);
|
||
writer.Write(playerId);
|
||
writer.Write((int)role);
|
||
AmongUsClient.Instance.FinishRpcImmediately(writer);
|
||
}
|
||
|
||
public static void ReceiveRPC(MessageReader reader, PlayerControl pc)
|
||
{
|
||
Logger.Msg($"{reader}", "MessageReader reader");
|
||
Logger.Msg($"{pc}", "PlayerControl pc");
|
||
|
||
int PlayerId = reader.ReadInt32();
|
||
Logger.Msg($"{PlayerId}", "Player Id");
|
||
|
||
CustomRoles role = (CustomRoles)reader.ReadInt32();
|
||
Logger.Msg($"{role}", "Role Int32");
|
||
Logger.Msg($"{GetString(role.ToString())}", "Role String");
|
||
|
||
GuesserMsg(pc, $"/bt {PlayerId} {GetString(role.ToString())}", true);
|
||
}
|
||
} |