mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-25 12:46:53 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
31fa873101 | ||
|
|
8fb609da02 | ||
|
|
d5dff9d184 | ||
|
|
476bf3329a | ||
|
|
d5501713a3 | ||
|
|
36d0791abc |
No files matched your search
+3
-15
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Hazel;
|
||||
using UnityEngine;
|
||||
|
||||
namespace EHR;
|
||||
@@ -242,6 +243,7 @@ public static class Snowdown
|
||||
|
||||
public static void OnCheckMurder(PlayerControl killer, PlayerControl target)
|
||||
{
|
||||
killer.SetKillCooldown(5f);
|
||||
if (!Data.TryGetValue(killer.PlayerId, out PlayerData killerData) || !Data.TryGetValue(target.PlayerId, out PlayerData targetData) || killerData.SnowballsReady < 1 || targetData.SnowballsReady >= targetData.MaxSnowballsReady) return;
|
||||
killerData.SnowballsReady--;
|
||||
targetData.SnowballsReady++;
|
||||
@@ -279,20 +281,7 @@ public static class Snowdown
|
||||
data.LastPosition = pos;
|
||||
}
|
||||
|
||||
foreach (PlayerControl target in Main.AllAlivePlayerControls)
|
||||
{
|
||||
string suffix = GetSuffix(__instance, target);
|
||||
|
||||
if (!data.LastSuffix.TryGetValue(target.PlayerId, out string lastSuffix))
|
||||
goto Skip;
|
||||
|
||||
if (lastSuffix != suffix)
|
||||
Utils.NotifyRoles(SpecifySeer: __instance, SpecifyTarget: target);
|
||||
|
||||
Skip:
|
||||
|
||||
data.LastSuffix[target.PlayerId] = suffix;
|
||||
}
|
||||
Utils.NotifyRoles(SpecifySeer: __instance, SendOption: SendOption.None);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,7 +299,6 @@ public static class Snowdown
|
||||
private int ShopSelectedIndex;
|
||||
public int Points;
|
||||
private bool ShowHelp;
|
||||
public readonly Dictionary<byte, string> LastSuffix = [];
|
||||
|
||||
public void OnSabotage(PlayerControl pc)
|
||||
{
|
||||
|
||||
@@ -42,8 +42,8 @@ public class Main : BasePlugin
|
||||
private const string DebugKeyHash = "c0fd562955ba56af3ae20d7ec9e64c664f0facecef4b3e366e109306adeae29d";
|
||||
private const string DebugKeySalt = "59687b";
|
||||
private const string PluginGuid = "com.gurge44.endlesshostroles";
|
||||
public const string PluginVersion = "7.0.1";
|
||||
public const string PluginDisplayVersion = "7.0.1";
|
||||
public const string PluginVersion = "7.0.2";
|
||||
public const string PluginDisplayVersion = "7.0.2";
|
||||
public const bool TestBuild = false;
|
||||
|
||||
public const string NeutralColor = "#ffab1b";
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AmongUs.GameOptions;
|
||||
using EHR.Modules;
|
||||
using EHR.Patches;
|
||||
using Hazel;
|
||||
|
||||
@@ -50,7 +51,7 @@ public static class AntiBlackout
|
||||
dummyImp.RpcSetRoleGlobal(RoleTypes.Impostor);
|
||||
players.Without(dummyImp).Where(x => x.GetRoleMap().RoleType != RoleTypes.Detective).Do(x => x.RpcSetRoleGlobal(RoleTypes.Crewmate));
|
||||
|
||||
Main.AllPlayerControls.DoIf(x => !x.IsAlive() && x.Data != null && x.Data.IsDead, x => x.RpcSetRoleGlobal(x.HasGhostRole() ? RoleTypes.GuardianAngel : RoleTypes.CrewmateGhost));
|
||||
Main.AllPlayerControls.DoIf(x => !x.IsAlive() && x.Data != null && x.Data.IsDead, x => x.RpcSetRoleGlobal(GhostRolesManager.AssignedGhostRoles.TryGetValue(x.PlayerId, out var ghostRole) ? ghostRole.Instance.RoleTypes : RoleTypes.CrewmateGhost));
|
||||
}
|
||||
|
||||
// After the ejection screen, we revert the role types to their actual values.
|
||||
@@ -89,7 +90,7 @@ public static class AntiBlackout
|
||||
if (seer == null || target == null) continue;
|
||||
|
||||
if (target.IsAlive()) target.RpcSetRoleDesync(roleType, seer.OwnerId);
|
||||
else target.RpcSetRoleDesync(target.HasGhostRole() ? RoleTypes.GuardianAngel : seer.PlayerId == target.PlayerId && !(target.Is(CustomRoleTypes.Impostor) && Options.DeadImpCantSabotage.GetBool()) && Main.PlayerStates.TryGetValue(target.PlayerId, out var state) && state.Role.CanUseSabotage(target) ? RoleTypes.ImpostorGhost : RoleTypes.CrewmateGhost, seer.OwnerId);
|
||||
else target.RpcSetRoleDesync(GhostRolesManager.AssignedGhostRoles.TryGetValue(targetId, out var ghostRole) ? ghostRole.Instance.RoleTypes : seerId == targetId && !(target.Is(CustomRoleTypes.Impostor) && Options.DeadImpCantSabotage.GetBool()) && Main.PlayerStates.TryGetValue(targetId, out var state) && state.Role.CanUseSabotage(target) ? RoleTypes.ImpostorGhost : RoleTypes.CrewmateGhost, seer.OwnerId);
|
||||
}
|
||||
catch (Exception e) { Utils.ThrowException(e); }
|
||||
}
|
||||
@@ -126,7 +127,9 @@ public static class AntiBlackout
|
||||
pc.Exiled();
|
||||
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(pc.NetId, 4, SendOption.Reliable);
|
||||
AmongUsClient.Instance.FinishRpcImmediately(writer);
|
||||
if (pc.HasGhostRole()) pc.RpcResetAbilityCooldown();
|
||||
|
||||
if (GhostRolesManager.AssignedGhostRoles.TryGetValue(pc.PlayerId, out var ghostRole) && ghostRole.Instance.RoleTypes == RoleTypes.GuardianAngel)
|
||||
pc.RpcResetAbilityCooldown();
|
||||
}
|
||||
}
|
||||
catch (Exception e) { Utils.ThrowException(e); }
|
||||
|
||||
@@ -33,12 +33,13 @@ internal static class GhostRolesManager
|
||||
|
||||
IGhostRole instance = CreateGhostRoleInstance(suitableRole);
|
||||
pc.RpcSetCustomRole(suitableRole);
|
||||
pc.RpcSetRoleDesync(RoleTypes.GuardianAngel, pc.OwnerId);
|
||||
pc.RpcSetRoleDesync(instance.RoleTypes, pc.OwnerId);
|
||||
instance.OnAssign(pc);
|
||||
Main.ResetCamPlayerList.Add(pc.PlayerId);
|
||||
AssignedGhostRoles[pc.PlayerId] = (suitableRole, instance);
|
||||
|
||||
if (suitableRole == CustomRoles.Haunter) GhostRoles.Remove(suitableRole);
|
||||
if (suitableRole == CustomRoles.Haunter)
|
||||
GhostRoles.Remove(suitableRole);
|
||||
|
||||
NotifyAboutGhostRole(pc, true);
|
||||
}
|
||||
|
||||
@@ -1026,7 +1026,7 @@ public static class Options
|
||||
sb.AppendLine("| Command | Description | Arguments | Usage Level | Usage Time | Hidden |");
|
||||
sb.AppendLine("|---------|-------------|-----------|-------------|------------|--------|");
|
||||
|
||||
foreach (Command command in ChatCommands.AllCommands)
|
||||
foreach ((String key, Command command) in Command.AllCommands)
|
||||
{
|
||||
string forms = command.CommandForms.TakeWhile(x => x.All(char.IsAscii)).Join(x => $"/{x}", "<br>");
|
||||
string description = command.Description;
|
||||
@@ -1077,7 +1077,7 @@ public static class Options
|
||||
}
|
||||
|
||||
sb.AppendLine("| | | | | | |");
|
||||
sb.Append($"| {ChatCommands.AllCommands.Count} | | | | | |");
|
||||
sb.Append($"| {Command.AllCommands.Count} | | | | | |");
|
||||
|
||||
const string path = "./commands.txt";
|
||||
if (!File.Exists(path)) File.Create(path).Close();
|
||||
|
||||
+15
-10
@@ -666,18 +666,23 @@ internal static class RPCHandlerPatch
|
||||
{
|
||||
if (!AmongUsClient.Instance.AmHost) break;
|
||||
|
||||
string methodName = reader.ReadString();
|
||||
string commandKey = reader.ReadString();
|
||||
PlayerControl player = reader.ReadByte().GetPlayer();
|
||||
string text = reader.ReadString();
|
||||
bool modCommand = reader.ReadBoolean();
|
||||
bool adminCommand = reader.ReadBoolean();
|
||||
|
||||
if (modCommand && !ChatCommands.IsPlayerModerator(player.FriendCode)) break;
|
||||
if (adminCommand && !ChatCommands.IsPlayerAdmin(player.FriendCode)) break;
|
||||
if (!Command.AllCommands.TryGetValue(commandKey, out Command command))
|
||||
{
|
||||
Logger.Error($"Invalid Command {commandKey}.", "RequestCommandProcessingFromHost");
|
||||
break;
|
||||
}
|
||||
|
||||
const BindingFlags flags = BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public;
|
||||
typeof(ChatCommands).GetMethod(methodName, flags)?.Invoke(null, [player, text, text.Split(' ')]);
|
||||
Logger.Info($"Invoke Command: {methodName} ({player?.Data?.PlayerName}, {text})", "RequestCommandProcessing");
|
||||
if (!command.CanUseCommand(player)) break;
|
||||
|
||||
command.Action(player, commandKey, text, text.Split(' '));
|
||||
|
||||
// const BindingFlags flags = BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public;
|
||||
// typeof(ChatCommands).GetMethod(methodName, flags)?.Invoke(null, [player, text, text.Split(' ')]);
|
||||
Logger.Info($"Invoke Command: {command.Action.Method.Name} ({player?.Data?.PlayerName}, {text})", "RequestCommandProcessing");
|
||||
break;
|
||||
}
|
||||
case CustomRPC.SyncPostman:
|
||||
@@ -1360,13 +1365,13 @@ internal static class RPCHandlerPatch
|
||||
{
|
||||
int playerId = reader.ReadByte();
|
||||
var command = $"/retribute {playerId}";
|
||||
ChatCommands.RetributeCommand(__instance, command, command.Split(' '));
|
||||
ChatCommands.RetributeCommand(__instance, "Command.Retribute", command, command.Split(' '));
|
||||
break;
|
||||
}
|
||||
case CustomRPC.StarspawnClick:
|
||||
{
|
||||
var command = $"/daybreak";
|
||||
ChatCommands.DayBreakCommand(__instance, command, command.Split(' '));
|
||||
ChatCommands.DayBreakCommand(__instance, "Command.DayBreak", command, command.Split(' '));
|
||||
break;
|
||||
}
|
||||
case CustomRPC.VentriloquistClick:
|
||||
|
||||
+2
-5
@@ -1721,7 +1721,7 @@ public static class Utils
|
||||
public static void ShowHelp(byte id)
|
||||
{
|
||||
PlayerControl player = GetPlayerById(id);
|
||||
SendMessage(ChatCommands.AllCommands.Where(x => x.CanUseCommand(player, false) && !x.CommandForms.Contains("help")).Aggregate("<size=70%>", (s, c) => s + $"\n<b>/{c.CommandForms.TakeWhile(f => f.All(char.IsAscii)).MinBy(f => f.Length)}{(c.Arguments.Length == 0 ? string.Empty : $" {c.Arguments.Split(' ').Select((x, i) => id == 0 ? ColorString(GetColor(i), x) : x).Join(delimiter: " ")}")}</b> \u2192 {c.Description}"), id, GetString("CommandList"));
|
||||
SendMessage(Command.AllCommands.Values.Where(x => x.CanUseCommand(player, false) && !x.CommandForms.Contains("help")).Aggregate("<size=70%>", (s, c) => s + $"\n<b>/{c.CommandForms.TakeWhile(f => f.All(char.IsAscii)).MinBy(f => f.Length)}{(c.Arguments.Length == 0 ? string.Empty : $" {c.Arguments.Split(' ').Select((x, i) => id == 0 ? ColorString(GetColor(i), x) : x).Join(delimiter: " ")}")}</b> \u2192 {c.Description}"), id, GetString("CommandList"));
|
||||
return;
|
||||
|
||||
Color GetColor(int i) =>
|
||||
@@ -3539,16 +3539,13 @@ public static class Utils
|
||||
}
|
||||
|
||||
Main.PlayerStates[pc.PlayerId].Role.AfterMeetingTasks();
|
||||
|
||||
if (pc.Is(CustomRoles.Phantasm) || pc.Is(CustomRoles.Haunter))
|
||||
pc.RpcResetAbilityCooldown();
|
||||
|
||||
if (pc.Is(CustomRoles.TaskMaster))
|
||||
TaskMaster.AfterMeetingTasks(pc);
|
||||
|
||||
Main.CheckShapeshift[pc.PlayerId] = false;
|
||||
}
|
||||
catch (System.Exception e) { ThrowException(e); }
|
||||
catch (Exception e) { ThrowException(e); }
|
||||
}
|
||||
|
||||
LateTask.New(() => Main.ProcessShapeshifts = true, 1f, log: false);
|
||||
|
||||
+302
-303
File diff suppressed because it is too large.
Load diff
@@ -1,7 +1,5 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using HarmonyLib;
|
||||
using InnerNet;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -79,16 +77,6 @@ public static class HostInfoPanelSetUpPatch
|
||||
}
|
||||
}
|
||||
|
||||
public static class LobbyPatch
|
||||
{
|
||||
public static bool IsGlitchedRoomCode()
|
||||
{
|
||||
string roomCode = GameCode.IntToGameName(AmongUsClient.Instance.GameId).ToUpper();
|
||||
string[] badEndings = ["IJPG", "SZAF", "LDQG", "ALGG", "UMPG", "GFXG", "JTFG", "PATG", "WMPG", "FUGG", "YTHG", "UFLG", "FBGG", "ZCQG", "RGGG", "ZHLG", "PJDG", "KJQG", "VDXG", "LCAF"];
|
||||
return badEndings.Any(roomCode.EndsWith);
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/SuperNewRoles/SuperNewRoles/blob/master/SuperNewRoles/Patches/LobbyBehaviourPatch.cs
|
||||
//[HarmonyPatch(typeof(LobbyBehaviour), nameof(LobbyBehaviour.Update))]
|
||||
internal static class LobbyBehaviourUpdatePatch
|
||||
@@ -110,5 +98,4 @@ internal static class LobbyBehaviourUpdatePatch
|
||||
SoundManager.Instance.CrossFadeSound("MapTheme", __instance.MapTheme, 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -108,7 +108,7 @@ internal static class CheckForEndVotingPatch
|
||||
}
|
||||
}
|
||||
|
||||
if (!shouldSkip && !__instance.playerStates.All(ps => ps == null || !Main.PlayerStates.TryGetValue(ps.TargetPlayerId, out PlayerState st) || st.IsDead || ps.AmDead || ps.DidVote || Utils.GetPlayerById(ps.TargetPlayerId) == null || Utils.GetPlayerById(ps.TargetPlayerId).Data == null || Utils.GetPlayerById(ps.TargetPlayerId).Data.Disconnected)) return false;
|
||||
if (!shouldSkip && !__instance.playerStates.All(ps => ps == null || Silencer.ForSilencer.Contains(ps.TargetPlayerId) || !Main.PlayerStates.TryGetValue(ps.TargetPlayerId, out PlayerState st) || st.IsDead || ps.AmDead || ps.DidVote || Utils.GetPlayerById(ps.TargetPlayerId) == null || Utils.GetPlayerById(ps.TargetPlayerId).Data == null || Utils.GetPlayerById(ps.TargetPlayerId).Data.Disconnected)) return false;
|
||||
|
||||
NetworkedPlayerInfo exiledPlayer = PlayerControl.LocalPlayer.Data;
|
||||
var tie = false;
|
||||
@@ -1372,6 +1372,12 @@ internal static class MeetingHudCastVotePatch
|
||||
voteCanceled = true;
|
||||
}
|
||||
|
||||
if (Silencer.ForSilencer.Contains(srcPlayerId))
|
||||
{
|
||||
ShouldCancelVoteList.TryAdd(srcPlayerId, (__instance, pvaSrc, pcSrc));
|
||||
voteCanceled = true;
|
||||
}
|
||||
|
||||
Logger.Info($"{pcSrc.GetNameWithRole()} => {(skip ? "Skip" : pcTarget.GetNameWithRole())}{(voteCanceled ? " (Canceled)" : string.Empty)}", "Vote");
|
||||
|
||||
return skip || !voteCanceled; // return false to use the vote as a trigger; skips and invalid votes are never canceled
|
||||
@@ -1545,7 +1551,7 @@ internal static class ExileControllerBeginPatch
|
||||
{
|
||||
public static void Postfix(ExileController __instance, [HarmonyArgument(0)] ExileController.InitProperties init)
|
||||
{
|
||||
if (Options.CurrentGameMode is CustomGameMode.Standard or CustomGameMode.TheMindGame && init is { outfit: not null })
|
||||
if (CheckForEndVotingPatch.EjectionText.EndsWith("<size=0>") && Options.CurrentGameMode is CustomGameMode.Standard or CustomGameMode.TheMindGame && init is { outfit: not null })
|
||||
__instance.completeString = CheckForEndVotingPatch.EjectionText[..^8];
|
||||
}
|
||||
|
||||
|
||||
@@ -1542,7 +1542,7 @@ internal static class FixedUpdatePatch
|
||||
if (!BanManager.TempBanWhiteList.Contains(hashedPuid)) BanManager.TempBanWhiteList.Add(hashedPuid);
|
||||
}
|
||||
|
||||
if (!Main.AllPlayerControls.All(x => x.Data.PlayerLevel <= 1) && !LobbyPatch.IsGlitchedRoomCode())
|
||||
if (!Main.AllPlayerControls.All(x => x.Data.PlayerLevel <= 1))
|
||||
{
|
||||
string msg = string.Format(GetString("KickBecauseLowLevel"), player.GetRealName().RemoveHtmlTags());
|
||||
Logger.SendInGame(msg, Color.yellow);
|
||||
@@ -2259,6 +2259,35 @@ internal static class PlayerControlCompleteTaskPatch
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(GameManager), nameof(GameManager.OnPlayerDeath))]
|
||||
static class GameManagerOnPlayerDeathPatch
|
||||
{
|
||||
public static void Prefix([HarmonyArgument(0)] PlayerControl player, [HarmonyArgument(1)] ref bool assignGhostRole)
|
||||
{
|
||||
if (!ReportDeadBodyPatch.MeetingStarted && !GameStates.IsMeeting && Main.PlayerStates.Values.Any(x => x.Role is SoulCollector sc && sc.ToExile.Contains(player.PlayerId)))
|
||||
assignGhostRole = false;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(LogicRoleSelectionNormal), nameof(LogicRoleSelectionNormal.OnPlayerDeath))]
|
||||
static class LogicRoleSelectionNormalOnPlayerDeathPatch
|
||||
{
|
||||
public static void Prefix([HarmonyArgument(0)] PlayerControl player, [HarmonyArgument(1)] ref bool assignGhostRole)
|
||||
{
|
||||
if (!ReportDeadBodyPatch.MeetingStarted && !GameStates.IsMeeting && Main.PlayerStates.Values.Any(x => x.Role is SoulCollector sc && sc.ToExile.Contains(player.PlayerId)))
|
||||
assignGhostRole = false;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(RoleManager), nameof(RoleManager.AssignRoleOnDeath))]
|
||||
static class RoleManagerAssignRoleOnDeathPatch
|
||||
{
|
||||
public static bool Prefix([HarmonyArgument(0)] PlayerControl player)
|
||||
{
|
||||
return ReportDeadBodyPatch.MeetingStarted || GameStates.IsMeeting || !Main.PlayerStates.Values.Any(x => x.Role is SoulCollector sc && sc.ToExile.Contains(player.PlayerId));
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.Die))]
|
||||
public static class PlayerControlDiePatch
|
||||
{
|
||||
@@ -2345,7 +2374,9 @@ internal static class PlayerControlSetRolePatch
|
||||
|
||||
if (roleType is RoleTypes.CrewmateGhost or RoleTypes.ImpostorGhost)
|
||||
{
|
||||
if (__instance.HasGhostRole() || GhostRolesManager.ShouldHaveGhostRole(__instance))
|
||||
if (GhostRolesManager.AssignedGhostRoles.TryGetValue(__instance.PlayerId, out var ghostRole))
|
||||
roleType = ghostRole.Instance.RoleTypes;
|
||||
else if (GhostRolesManager.ShouldHaveGhostRole(__instance))
|
||||
roleType = RoleTypes.GuardianAngel;
|
||||
else if (!(__instance.Is(CustomRoleTypes.Impostor) && Options.DeadImpCantSabotage.GetBool()) && Main.PlayerStates.TryGetValue(__instance.PlayerId, out var state) && state.Role.CanUseSabotage(__instance))
|
||||
roleType = RoleTypes.ImpostorGhost;
|
||||
|
||||
@@ -141,7 +141,7 @@ internal static class OnGameJoinedPatch
|
||||
}
|
||||
|
||||
if (Options.AutoGMPollCommandAfterJoin.GetBool() && !Options.AutoGMRotationEnabled)
|
||||
ChatCommands.GameModePollCommand(PlayerControl.LocalPlayer, "/gmpoll", ["/gmpoll"]);
|
||||
ChatCommands.GameModePollCommand(PlayerControl.LocalPlayer, "Command.GameModePoll", "/gmpoll", ["/gmpoll"]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ internal static class OnGameJoinedPatch
|
||||
}
|
||||
|
||||
if (Options.AutoMPollCommandAfterJoin.GetBool() && !Options.RandomMapsMode.GetBool())
|
||||
ChatCommands.MapPollCommand(PlayerControl.LocalPlayer, "/mpoll", ["/mpoll"]);
|
||||
ChatCommands.MapPollCommand(PlayerControl.LocalPlayer, "Command.MapPoll", "/mpoll", ["/mpoll"]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ internal static class OnGameJoinedPatch
|
||||
}
|
||||
|
||||
if (Options.AutoDraftStartCommandAfterJoin.GetBool())
|
||||
ChatCommands.DraftStartCommand(PlayerControl.LocalPlayer, "/draftstart", ["/draftstart"]);
|
||||
ChatCommands.DraftStartCommand(PlayerControl.LocalPlayer, "Command.DraftStart", "/draftstart", ["/draftstart"]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,7 +217,7 @@ internal static class OnGameJoinedPatch
|
||||
|
||||
if (Options.AutoGMRotationEnabled)
|
||||
{
|
||||
if (nextGM == CustomGameMode.All) ChatCommands.GameModePollCommand(PlayerControl.LocalPlayer, "/gmpoll", ["/gmpoll"]);
|
||||
if (nextGM == CustomGameMode.All) ChatCommands.GameModePollCommand(PlayerControl.LocalPlayer, "Command.GameModePoll", "/gmpoll", ["/gmpoll"]);
|
||||
else Options.GameMode.SetValue((int)nextGM - 1);
|
||||
|
||||
Logger.Info($"Auto GM Rotation: Next Game Mode = {nextGM}", "Auto GM Rotation");
|
||||
|
||||
@@ -132,9 +132,9 @@ public static class TextBoxPatch
|
||||
var exactMatch = false;
|
||||
bool english = TranslationController.Instance.currentLanguage.languageID == SupportedLangs.English;
|
||||
|
||||
foreach (Command cmd in ChatCommands.AllCommands)
|
||||
foreach ((string key, Command cmd) in Command.AllCommands)
|
||||
{
|
||||
string[] commandForms = english ? cmd.CommandForms.TakeWhile(x => x.All(char.IsAscii)).ToArray() : cmd.CommandForms;
|
||||
string[] commandForms = english ? [.. cmd.CommandForms.TakeWhile(x => x.All(char.IsAscii))] : cmd.CommandForms;
|
||||
|
||||
foreach (string form in commandForms)
|
||||
{
|
||||
|
||||
@@ -92,8 +92,9 @@ pinbrittle#1538 | 4955c179f | Moralmaser | Cheating | Cheating and disrupting lo
|
||||
dollfly#4791 | 5ba449454 | Mari | Cheating | Spamming RPCs to crash lobbies
|
||||
|
||||
byechic#6270 | 91e0145f1 | (Contains n word) | Harassing a streamer with a slur in the IGN |
|
||||
waiverfore#0496 | b493df896 | | Hacking in syl's lobby |
|
||||
whaleutter#4768 | 9e04dc5d5 | | Cheaing in syl's lobby | no name hacker
|
||||
waiverfore#0496 | b493df896 | | Cheating in Syl's lobby |
|
||||
whaleutter#4768 | 9e04dc5d5 | | Cheating in Syl's lobby | No name cheater
|
||||
whimrecent#6558 | f8452a9d1 | | Cheating | no name cheater
|
||||
## Griefers, Toxic, harrasing, morons
|
||||
setmolar#4374 | | 藏族顶针 | Toxic |
|
||||
overtfeast#5802 | | 黑影 | Toxic |
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AmongUs.GameOptions;
|
||||
using Hazel;
|
||||
|
||||
namespace EHR.AddOns.GhostRoles;
|
||||
@@ -18,6 +19,7 @@ internal class Bloodmoon : IGhostRole
|
||||
private byte BloodmoonID;
|
||||
|
||||
public Team Team => Team.Impostor | Team.Neutral;
|
||||
public RoleTypes RoleTypes => RoleTypes.GuardianAngel;
|
||||
public int Cooldown => CD.GetInt() + Main.PlayerStates.Values.Count(x => x.GetRealKiller() == BloodmoonID && x.deathReason == PlayerState.DeathReason.LossOfBlood) * CDIncreasePerUse.GetInt();
|
||||
|
||||
public void OnAssign(PlayerControl pc)
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
namespace EHR.AddOns.GhostRoles;
|
||||
using AmongUs.GameOptions;
|
||||
|
||||
namespace EHR.AddOns.GhostRoles;
|
||||
|
||||
public class Facilitator : IGhostRole
|
||||
{
|
||||
private static OptionItem CD;
|
||||
|
||||
public Team Team => Team.Coven;
|
||||
public RoleTypes RoleTypes => RoleTypes.GuardianAngel;
|
||||
public int Cooldown => CD.GetInt();
|
||||
|
||||
public void OnProtect(PlayerControl pc, PlayerControl target)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using AmongUs.GameOptions;
|
||||
|
||||
namespace EHR.AddOns.GhostRoles;
|
||||
|
||||
@@ -10,6 +11,7 @@ internal class GA : IGhostRole
|
||||
public HashSet<byte> ProtectionList = [];
|
||||
|
||||
public Team Team => Team.Crewmate;
|
||||
public RoleTypes RoleTypes => RoleTypes.GuardianAngel;
|
||||
public int Cooldown => CD.GetInt();
|
||||
|
||||
public void OnProtect(PlayerControl pc, PlayerControl target)
|
||||
|
||||
@@ -14,7 +14,7 @@ internal class Haunter : IGhostRole
|
||||
private static OptionItem RevealNeutralKillers;
|
||||
private static OptionItem RevealMadmates;
|
||||
private static OptionItem NumberOfReveals;
|
||||
public static OptionItem CanWinWithCrewmates;
|
||||
private static OptionItem CanWinWithCrewmates;
|
||||
|
||||
private static readonly string[] WinWithCrewOpts =
|
||||
[
|
||||
@@ -28,6 +28,7 @@ internal class Haunter : IGhostRole
|
||||
private long WarnTimeStamp;
|
||||
|
||||
public Team Team => Team.Crewmate | Team.Neutral;
|
||||
public RoleTypes RoleTypes => RoleTypes.CrewmateGhost;
|
||||
public int Cooldown => 900;
|
||||
|
||||
public void OnProtect(PlayerControl pc, PlayerControl target) { }
|
||||
@@ -47,7 +48,6 @@ internal class Haunter : IGhostRole
|
||||
|
||||
pc.RpcResetTasks();
|
||||
pc.SyncSettings();
|
||||
pc.RpcResetAbilityCooldown();
|
||||
Utils.NotifyRoles(SpecifySeer: pc, SpecifyTarget: pc);
|
||||
}, 1f, "Haunter Assign");
|
||||
}
|
||||
@@ -95,14 +95,14 @@ internal class Haunter : IGhostRole
|
||||
};
|
||||
});
|
||||
|
||||
WarnTimeStamp = Utils.TimeStamp + 2;
|
||||
|
||||
foreach (PlayerControl imp in filtered)
|
||||
{
|
||||
TargetArrow.Add(imp.PlayerId, pc.PlayerId);
|
||||
WarnedImps.Add(imp.PlayerId);
|
||||
imp.Notify(Translator.GetString("Haunter1TaskLeft"), 10f);
|
||||
}
|
||||
|
||||
WarnTimeStamp = Utils.TimeStamp;
|
||||
}
|
||||
|
||||
public void OnFinishedTasks(PlayerControl pc)
|
||||
@@ -123,15 +123,17 @@ internal class Haunter : IGhostRole
|
||||
|
||||
AllHauntedPlayers.UnionWith(targets);
|
||||
|
||||
targets.ForEach(x => Utils.GetPlayerById(x)?.Notify(Translator.GetString("HaunterRevealedYou"), 7f));
|
||||
WarnedImps.ForEach(x => Utils.GetPlayerById(x)?.Notify(Translator.GetString("HaunterFinishedTasks"), 7f));
|
||||
var targetPcs = targets.ToValidPlayers();
|
||||
|
||||
targets.ToValidPlayers().ForEach(x => Utils.NotifyRoles(SpecifyTarget: x));
|
||||
targetPcs.ForEach(x => x.Notify(Translator.GetString("HaunterRevealedYou"), 10f));
|
||||
WarnedImps.ToValidPlayers().ForEach(x => x.Notify(Translator.GetString("HaunterFinishedTasks"), 10f));
|
||||
|
||||
targetPcs.ForEach(x => Utils.NotifyRoles(SpecifyTarget: x));
|
||||
}
|
||||
|
||||
public void Update(PlayerControl pc)
|
||||
{
|
||||
if (WarnedImps.Count == 0 || WarnTimeStamp == Utils.TimeStamp) return;
|
||||
if (WarnedImps.Count == 0 || WarnTimeStamp >= Utils.TimeStamp) return;
|
||||
|
||||
if (WarnedImps.Any(imp => TargetArrow.GetArrows(Utils.GetPlayerById(imp), pc.PlayerId) == "・"))
|
||||
{
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
namespace EHR.AddOns.GhostRoles;
|
||||
using AmongUs.GameOptions;
|
||||
|
||||
namespace EHR.AddOns.GhostRoles;
|
||||
|
||||
public interface IGhostRole
|
||||
{
|
||||
public Team Team { get; }
|
||||
public RoleTypes RoleTypes { get; }
|
||||
public int Cooldown { get; }
|
||||
public void OnProtect(PlayerControl pc, PlayerControl target);
|
||||
public void OnAssign(PlayerControl pc);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using AmongUs.GameOptions;
|
||||
using EHR.Modules;
|
||||
|
||||
namespace EHR.AddOns.GhostRoles;
|
||||
@@ -11,6 +12,7 @@ internal class Minion : IGhostRole
|
||||
private static OptionItem CD;
|
||||
|
||||
public Team Team => Team.Impostor;
|
||||
public RoleTypes RoleTypes => RoleTypes.GuardianAngel;
|
||||
public int Cooldown => CD.GetInt();
|
||||
|
||||
public void OnProtect(PlayerControl pc, PlayerControl target)
|
||||
|
||||
@@ -10,6 +10,7 @@ internal class Phantasm : IGhostRole
|
||||
|
||||
public bool IsWon;
|
||||
public Team Team => Team.Neutral;
|
||||
public RoleTypes RoleTypes => RoleTypes.CrewmateGhost;
|
||||
public int Cooldown => 900;
|
||||
|
||||
public void OnAssign(PlayerControl pc)
|
||||
@@ -27,7 +28,6 @@ internal class Phantasm : IGhostRole
|
||||
|
||||
pc.RpcResetTasks();
|
||||
pc.SyncSettings();
|
||||
pc.RpcResetAbilityCooldown();
|
||||
Utils.NotifyRoles(SpecifySeer: pc, SpecifyTarget: pc);
|
||||
}, 1f, "Phantasm Assign");
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using AmongUs.GameOptions;
|
||||
|
||||
namespace EHR.AddOns.GhostRoles;
|
||||
|
||||
@@ -9,6 +10,7 @@ public class Shade : IGhostRole
|
||||
public HashSet<byte> Protected = [];
|
||||
|
||||
public Team Team => Team.Neutral;
|
||||
public RoleTypes RoleTypes => RoleTypes.GuardianAngel;
|
||||
public int Cooldown => CD.GetInt();
|
||||
|
||||
public void OnProtect(PlayerControl pc, PlayerControl target)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using AmongUs.GameOptions;
|
||||
|
||||
namespace EHR.AddOns.GhostRoles;
|
||||
|
||||
@@ -13,6 +14,7 @@ internal class Warden : IGhostRole
|
||||
private readonly Dictionary<byte, (long StartTimeStamp, float OriginalSpeed)> SpeedList = [];
|
||||
|
||||
public Team Team => Team.Crewmate;
|
||||
public RoleTypes RoleTypes => RoleTypes.GuardianAngel;
|
||||
public int Cooldown => CD.GetInt();
|
||||
|
||||
public void OnProtect(PlayerControl pc, PlayerControl target)
|
||||
|
||||
@@ -63,7 +63,7 @@ public class Imitator : RoleBase
|
||||
{
|
||||
int playerId = reader.ReadByte();
|
||||
var command = $"/imitate {playerId}";
|
||||
ChatCommands.ImitateCommand(pc, command, command.Split(' '));
|
||||
ChatCommands.ImitateCommand(pc, "Command.Imitate", command, command.Split(' '));
|
||||
}
|
||||
|
||||
private static void ImitatorOnClick(byte playerId /*, MeetingHud __instance*/)
|
||||
@@ -75,7 +75,7 @@ public class Imitator : RoleBase
|
||||
if (AmongUsClient.Instance.AmHost)
|
||||
{
|
||||
var command = $"/imitate {playerId}";
|
||||
ChatCommands.ImitateCommand(PlayerControl.LocalPlayer, command, command.Split(' '));
|
||||
ChatCommands.ImitateCommand(PlayerControl.LocalPlayer, "Command.Imitate", command, command.Split(' '));
|
||||
|
||||
if (ImitatingRole.ContainsKey(PlayerControl.LocalPlayer.PlayerId))
|
||||
{
|
||||
|
||||
@@ -107,7 +107,7 @@ public class Retributionist : RoleBase
|
||||
public override void OnMeetingShapeshift(PlayerControl shapeshifter, PlayerControl target)
|
||||
{
|
||||
var command = $"/retribute {target.PlayerId}";
|
||||
ChatCommands.RetributeCommand(shapeshifter, command, command.Split(' '));
|
||||
ChatCommands.RetributeCommand(shapeshifter, "Command.Retribute", command, command.Split(' '));
|
||||
}
|
||||
|
||||
public void ReceiveRPC(MessageReader reader)
|
||||
@@ -124,7 +124,7 @@ public class Retributionist : RoleBase
|
||||
if (AmongUsClient.Instance.AmHost)
|
||||
{
|
||||
var command = $"/retribute {playerId}";
|
||||
ChatCommands.RetributeCommand(PlayerControl.LocalPlayer, command, command.Split(' '));
|
||||
ChatCommands.RetributeCommand(PlayerControl.LocalPlayer, "Command.Retribute", command, command.Split(' '));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -91,11 +91,6 @@ public class Sapper : RoleBase
|
||||
return PlaceBomb(shapeshifter);
|
||||
}
|
||||
|
||||
public override bool OnCheckMurder(PlayerControl killer, PlayerControl target)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool CanUseKillButton(PlayerControl pc)
|
||||
{
|
||||
return CanKill.GetBool();
|
||||
|
||||
@@ -34,7 +34,7 @@ public class Silencer : RoleBase
|
||||
|
||||
public override void SetupCustomOption()
|
||||
{
|
||||
SetupRoleOptions(Id, TabGroup.ImpostorRoles, CustomRoles.Silencer, zeroOne: true);
|
||||
SetupSingleRoleOptions(Id, TabGroup.ImpostorRoles, CustomRoles.Silencer);
|
||||
|
||||
SkillCooldown = new FloatOptionItem(Id + 5, "AbilityCooldown", new(2.5f, 60f, 0.5f), 30f, TabGroup.ImpostorRoles)
|
||||
.SetParent(CustomRoleSpawnChances[CustomRoles.Silencer])
|
||||
@@ -169,18 +169,4 @@ public class Silencer : RoleBase
|
||||
ForSilencer.Clear();
|
||||
PlayerIdList.ForEach(x => Utils.SendRPC(CustomRPC.SyncRoleData, x, 2));
|
||||
}
|
||||
|
||||
public override void OnReportDeadBody()
|
||||
{
|
||||
if (ForSilencer.Count == 0) return;
|
||||
Main.Instance.StartCoroutine(WaitForVote());
|
||||
return;
|
||||
|
||||
System.Collections.IEnumerator WaitForVote()
|
||||
{
|
||||
while (MeetingHud.Instance && MeetingHud.Instance.state is not (MeetingHud.VoteStates.NotVoted or MeetingHud.VoteStates.Voted) && !GameStates.IsEnded && GameStates.InGame && !ExileController.Instance) yield return null;
|
||||
if (!MeetingHud.Instance || GameStates.IsEnded || !GameStates.InGame || ExileController.Instance) yield break;
|
||||
ForSilencer.ForEach(x => MeetingHud.Instance.CastVote(x, 253)); // 253 is skip vote
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,14 +44,14 @@ public class Ventriloquist : RoleBase
|
||||
public override void OnMeetingShapeshift(PlayerControl shapeshifter, PlayerControl target)
|
||||
{
|
||||
var command = $"/target {target.PlayerId}";
|
||||
ChatCommands.TargetCommand(shapeshifter, command, command.Split(' '));
|
||||
ChatCommands.TargetCommand(shapeshifter, "Command.Target", command, command.Split(' '));
|
||||
}
|
||||
|
||||
public static void ReceiveRPC(MessageReader reader, PlayerControl pc)
|
||||
{
|
||||
int playerId = reader.ReadByte();
|
||||
var command = $"/target {playerId}";
|
||||
ChatCommands.TargetCommand(pc, command, command.Split(' '));
|
||||
ChatCommands.TargetCommand(pc, "Command.Target", command, command.Split(' '));
|
||||
}
|
||||
|
||||
private static void VentriloquisttOnClick(byte playerId /*, MeetingHud __instance*/)
|
||||
@@ -63,7 +63,7 @@ public class Ventriloquist : RoleBase
|
||||
if (AmongUsClient.Instance.AmHost)
|
||||
{
|
||||
var command = $"/target {playerId}";
|
||||
ChatCommands.TargetCommand(PlayerControl.LocalPlayer, command, command.Split(' '));
|
||||
ChatCommands.TargetCommand(PlayerControl.LocalPlayer, "Command.Target", command, command.Split(' '));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -109,14 +109,16 @@ public class SoulCollector : RoleBase
|
||||
{
|
||||
var sender = CustomRpcSender.Create("SoulCollector Post Exile", SendOption.Reliable);
|
||||
sender.StartMessage();
|
||||
ToExile.ToValidPlayers().ForEach(x =>
|
||||
List<PlayerControl> toExile = ToExile.ToValidPlayers();
|
||||
ToExile = [];
|
||||
toExile.ForEach(x =>
|
||||
{
|
||||
Main.AllPlayerSpeed[x.PlayerId] = Main.RealOptionsData.GetFloat(FloatOptionNames.PlayerSpeedMod);
|
||||
x.Exiled();
|
||||
sender.StartRpc(x.NetId, RpcCalls.Exiled)
|
||||
.EndRpc();
|
||||
});
|
||||
sender.SendMessage();
|
||||
ToExile = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,7 +77,7 @@ public class Starspawn : RoleBase
|
||||
public override void OnMeetingShapeshift(PlayerControl shapeshifter, PlayerControl target)
|
||||
{
|
||||
const string command = "/daybreak";
|
||||
ChatCommands.DayBreakCommand(shapeshifter, command, command.Split(' '));
|
||||
ChatCommands.DayBreakCommand(shapeshifter, "Command.Daybreak", command, command.Split(' '));
|
||||
}
|
||||
|
||||
public void ReceiveRPC(MessageReader reader)
|
||||
@@ -93,7 +93,7 @@ public class Starspawn : RoleBase
|
||||
if (AmongUsClient.Instance.AmHost)
|
||||
{
|
||||
var command = $"/daybreak";
|
||||
ChatCommands.DayBreakCommand(PlayerControl.LocalPlayer, command, command.Split(' '));
|
||||
ChatCommands.DayBreakCommand(PlayerControl.LocalPlayer, "Command.Daybreak", command, command.Split(' '));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+1
-1
@@ -134,7 +134,7 @@ public abstract class RoleBase : IComparable<RoleBase>
|
||||
if (Imitator.PlayerIdList.Contains(pc.PlayerId))
|
||||
{
|
||||
string command = $"/imitate {target.PlayerId}";
|
||||
ChatCommands.ImitateCommand(pc, command, command.Split(' '));
|
||||
ChatCommands.ImitateCommand(pc, "Command.Imitate", command, command.Split(' '));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user