mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-24 16:46:53 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4e80042324 | ||
|
|
e135e75efc | ||
|
|
ed02400090 | ||
|
|
15f229e458 | ||
|
|
f7dffc84e8 | ||
|
|
3c0b86ab14 | ||
|
|
ef8f0e1337 | ||
|
|
28da21dfb4 | ||
|
|
81e2d4e2d5 | ||
|
|
2c05cd6b99 | ||
|
|
c458d15c02 | ||
|
|
4ba0049bf3 | ||
|
|
a962374eeb |
No files matched your search
+5
-1
@@ -1,5 +1,9 @@
|
||||
# Thank you so much for finding and using EHR!
|
||||
|
||||
- Another attempt at fixing the host getting kicked on vanilla regions
|
||||
- Fixed flaws with kick-prevention logic
|
||||
- Fixed messages sometimes not appearing (HTML tag = entire message gone, ty innersloth)
|
||||
- Fixed non-ASCII characters in the host's name causing errors
|
||||
|
||||
(you better not complain about the frequency of updates)
|
||||
|
||||
---
|
||||
@@ -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.1.2";
|
||||
public const string PluginDisplayVersion = "7.1.2";
|
||||
public const string PluginVersion = "7.1.4";
|
||||
public const string PluginDisplayVersion = "7.1.4";
|
||||
public const bool TestBuild = false;
|
||||
|
||||
public const string NeutralColor = "#ffab1b";
|
||||
|
||||
@@ -25,7 +25,7 @@ public static class AntiBlackout
|
||||
|
||||
PlayerControl[] players = Main.AllAlivePlayerControls;
|
||||
if (CheckForEndVotingPatch.TempExiledPlayer != null) players = players.Where(x => x.PlayerId != CheckForEndVotingPatch.TempExiledPlayer.PlayerId).ToArray();
|
||||
PlayerControl dummyImp = players.OrderByDescending(x => x.GetRoleMap().RoleType != RoleTypes.Detective).ThenByDescending(x => x.IsModdedClient()).MinBy(x => x.PlayerId);
|
||||
PlayerControl dummyImp = players.OrderByDescending(x => x.GetCustomRole() is not (CustomRoles.DetectiveEHR or CustomRoles.Detective) && !x.Is(CustomRoles.Examiner)).ThenByDescending(x => x.IsModdedClient()).MinBy(x => x.PlayerId);
|
||||
|
||||
if (players.Length == 2)
|
||||
{
|
||||
@@ -49,9 +49,9 @@ public static class AntiBlackout
|
||||
}
|
||||
|
||||
dummyImp.RpcSetRoleGlobal(RoleTypes.Impostor);
|
||||
players.Without(dummyImp).Where(x => x.GetRoleMap().RoleType != RoleTypes.Detective).Do(x => x.RpcSetRoleGlobal(RoleTypes.Crewmate));
|
||||
players.Without(dummyImp).Where(x => x.GetCustomRole() is not (CustomRoles.DetectiveEHR or CustomRoles.Detective) && !x.Is(CustomRoles.Examiner)).Do(x => x.RpcSetRoleGlobal(RoleTypes.Crewmate));
|
||||
|
||||
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));
|
||||
Main.AllPlayerControls.DoIf(x => !x.IsAlive() && x.Data != null && x.Data.IsDead && (!x.AmOwner || !Utils.TempReviveHostRunning), 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.
|
||||
@@ -69,6 +69,8 @@ public static class AntiBlackout
|
||||
{
|
||||
try
|
||||
{
|
||||
if (pc.AmOwner && Utils.TempReviveHostRunning) continue;
|
||||
|
||||
NetworkedPlayerInfo data = pc.Data;
|
||||
|
||||
if (data != null && !data.IsDead && !data.Disconnected && !pc.IsAlive())
|
||||
@@ -87,7 +89,7 @@ public static class AntiBlackout
|
||||
{
|
||||
PlayerControl seer = seerId.GetPlayer();
|
||||
PlayerControl target = targetId.GetPlayer();
|
||||
if (seer == null || target == null) continue;
|
||||
if (seer == null || target == null || (seerId == targetId && seer.AmOwner && Utils.TempReviveHostRunning)) continue;
|
||||
|
||||
if (target.IsAlive()) target.RpcSetRoleDesync(roleType, 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);
|
||||
@@ -123,6 +125,8 @@ public static class AntiBlackout
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pc.AmOwner && Utils.TempReviveHostRunning) continue;
|
||||
|
||||
// Ensure that the players who are considered dead by the mod are actually dead in the game.
|
||||
pc.Exiled();
|
||||
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(pc.NetId, 4, SendOption.Reliable);
|
||||
|
||||
@@ -103,8 +103,9 @@ internal static class CustomRoleSelector
|
||||
|
||||
switch (role)
|
||||
{
|
||||
case CustomRoles.Ventriloquist when GameStates.CurrentServerType == GameStates.ServerType.Vanilla:
|
||||
case CustomRoles.Weatherman when Main.LIMap || GameStates.CurrentServerType == GameStates.ServerType.Vanilla:
|
||||
case CustomRoles.RoomRusher when Main.LIMap:
|
||||
case CustomRoles.Weatherman when Main.LIMap:
|
||||
case CustomRoles.Doctor when Options.EveryoneSeesDeathReasons.GetBool():
|
||||
case CustomRoles.LovingCrewmate or CustomRoles.LovingImpostor when !loversData.Spawning:
|
||||
case CustomRoles.Commander when optImpNum <= 1 && Commander.CannotSpawnAsSoloImp.GetBool():
|
||||
|
||||
@@ -594,7 +594,7 @@ public sealed class PlayerGameOptionsSender(PlayerControl player) : GameOptionsS
|
||||
}
|
||||
|
||||
state.TaskState.HasTasks = Utils.HasTasks(player.Data, false);
|
||||
if (Options.GhostCanSeeOtherVotes.GetBool() && player.Data.IsDead) opt.SetBool(BoolOptionNames.AnonymousVotes, false);
|
||||
if (Options.GhostCanSeeOtherVotes.GetBool() && !player.IsAlive()) opt.SetBool(BoolOptionNames.AnonymousVotes, false);
|
||||
|
||||
if (Options.AdditionalEmergencyCooldown.GetBool() &&
|
||||
Options.AdditionalEmergencyCooldownThreshold.GetInt() <= Utils.AllAlivePlayersCount)
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
using HarmonyLib;
|
||||
using InnerNet;
|
||||
using UnityEngine;
|
||||
@@ -54,7 +55,7 @@ public static class LobbySharingAPI
|
||||
};
|
||||
|
||||
request.SetRequestHeader("Content-Type", "application/json");
|
||||
request.SetRequestHeader("User-Agent", $"{Main.ModName} v{Main.PluginVersion} - {hostName}");
|
||||
request.SetRequestHeader("User-Agent", $"{Main.ModName} v{Main.PluginVersion} - {Regex.Replace(hostName, @"[^\x20-\x7E]", "")}");
|
||||
yield return request.SendWebRequest();
|
||||
|
||||
LastRequestTimeStamp = Utils.TimeStamp;
|
||||
|
||||
+72
-9
@@ -1037,7 +1037,7 @@ public static class Utils
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((Main.VisibleTasksCount && !PlayerControl.LocalPlayer.IsAlive() && Options.GhostCanSeeOtherRoles.GetBool() && (!IsRevivingRoleAlive() || !Main.DiedThisRound.Contains(PlayerControl.LocalPlayer.PlayerId))) || (PlayerControl.LocalPlayer.Is(CustomRoles.Mimic) && Main.VisibleTasksCount && __instance.Data.IsDead && Options.MimicCanSeeDeadRoles.GetBool())) return true;
|
||||
if ((Main.VisibleTasksCount && !PlayerControl.LocalPlayer.IsAlive() && Options.GhostCanSeeOtherRoles.GetBool() && (!IsRevivingRoleAlive() || !Main.DiedThisRound.Contains(PlayerControl.LocalPlayer.PlayerId))) || (PlayerControl.LocalPlayer.Is(CustomRoles.Mimic) && Main.VisibleTasksCount && !__instance.IsAlive() && Options.MimicCanSeeDeadRoles.GetBool())) return true;
|
||||
|
||||
if (__instance.AmOwner) return true;
|
||||
|
||||
@@ -1796,17 +1796,23 @@ public static class Utils
|
||||
catch (Exception e) { ThrowException(e); }
|
||||
}
|
||||
|
||||
public static bool TempReviveHostRunning;
|
||||
private static Stopwatch TempReviveHostStopwatch = new();
|
||||
|
||||
public static void SendMultipleMessages(this IEnumerable<Message> messages, SendOption sendOption = SendOption.Reliable)
|
||||
{
|
||||
var sender = CustomRpcSender.Create("Utils.SendMultipleMessages", sendOption);
|
||||
sender = messages.Aggregate(sender, (current, message) => SendMessage(message.Text, message.SendTo, message.Title, writer: current, multiple: true, sendOption: sendOption));
|
||||
sender.SendMessage(dispose: sender.stream.Length <= 3);
|
||||
messages.Do(x => SendMessage(x.Text, x.SendTo, x.Title, sendOption: sendOption));
|
||||
}
|
||||
|
||||
public static CustomRpcSender SendMessage(string text, byte sendTo = byte.MaxValue, string title = "", bool noSplit = false, CustomRpcSender writer = null, bool final = false, bool multiple = false, SendOption sendOption = SendOption.Reliable, bool addtoHistory = true)
|
||||
public static CustomRpcSender SendMessage(string text, byte sendTo = byte.MaxValue, string title = "", bool noSplit = false, CustomRpcSender writer = null, bool final = false, bool multiple = false, SendOption sendOption = SendOption.Reliable, bool addToHistory = true, [CallerFilePath] string callerFilePath = "", [CallerLineNumber] int callerLineNumber = 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
Logger.Info($"SendMessage called from {callerFilePath.Split('\\')[^1]} at line {callerLineNumber}", "SendMessage");
|
||||
|
||||
if (GameStates.CurrentServerType == GameStates.ServerType.Vanilla)
|
||||
text = text.RemoveHtmlTags();
|
||||
|
||||
PlayerControl receiver = GetPlayerById(sendTo, false);
|
||||
if (sendTo != byte.MaxValue && receiver == null || title.RemoveHtmlTags().Trim().Length == 0 && text.RemoveHtmlTags().Trim().Length == 0) return writer;
|
||||
|
||||
@@ -1838,7 +1844,64 @@ public static class Utils
|
||||
text = text.Replace("color=", string.Empty);
|
||||
title = title.Replace("color=", string.Empty);
|
||||
|
||||
PlayerControl sender = !addtoHistory ? PlayerControl.LocalPlayer : Main.AllAlivePlayerControls.MinBy(x => x.PlayerId) ?? Main.AllPlayerControls.MinBy(x => x.PlayerId) ?? PlayerControl.LocalPlayer;
|
||||
PlayerControl sender = !addToHistory || GameStates.CurrentServerType == GameStates.ServerType.Vanilla ? PlayerControl.LocalPlayer : Main.AllAlivePlayerControls.MinBy(x => x.PlayerId) ?? Main.AllPlayerControls.MinBy(x => x.PlayerId) ?? PlayerControl.LocalPlayer;
|
||||
|
||||
if (sender.AmOwner && sender.Data.IsDead)
|
||||
{
|
||||
bool delayMessage = false;
|
||||
|
||||
if (!TempReviveHostRunning)
|
||||
{
|
||||
delayMessage = true;
|
||||
Main.Instance.StartCoroutine(TempReviveHost());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TempReviveHostStopwatch.ElapsedMilliseconds < 200)
|
||||
delayMessage = true;
|
||||
|
||||
TempReviveHostStopwatch.Restart();
|
||||
}
|
||||
|
||||
if (delayMessage)
|
||||
{
|
||||
Main.Instance.StartCoroutine(DelaySend());
|
||||
return writer;
|
||||
|
||||
IEnumerator DelaySend()
|
||||
{
|
||||
yield return new WaitForSeconds(0.3f);
|
||||
SendMessage(text, sendTo, title, noSplit, writer, final, multiple, sendOption, addToHistory);
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator TempReviveHost()
|
||||
{
|
||||
TempReviveHostRunning = true;
|
||||
TempReviveHostStopwatch = Stopwatch.StartNew();
|
||||
|
||||
Logger.Msg("Temporarily reviving host to send message....", "TempReviveHost");
|
||||
|
||||
sender.Data.IsDead = false;
|
||||
sender.Data.SendGameData();
|
||||
|
||||
while (TempReviveHostStopwatch.ElapsedMilliseconds < 1000)
|
||||
yield return null;
|
||||
|
||||
Logger.Msg("Re-killing host after message sent.", "TempReviveHost");
|
||||
|
||||
if (!AmongUsClient.Instance.AmHost || GameStates.IsEnded || GameStates.IsLobby)
|
||||
{
|
||||
TempReviveHostRunning = false;
|
||||
yield break;
|
||||
}
|
||||
|
||||
sender.Data.IsDead = true;
|
||||
sender.Data.SendGameData();
|
||||
|
||||
TempReviveHostRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (sendTo != byte.MaxValue && receiver.AmOwner)
|
||||
{
|
||||
@@ -1858,7 +1921,7 @@ public static class Utils
|
||||
}
|
||||
catch { Logger.Info(" Message sent", "SendMessage"); }
|
||||
|
||||
if (addtoHistory) ChatUpdatePatch.LastMessages.Add((text, sendTo, title, TimeStamp));
|
||||
if (addToHistory) ChatUpdatePatch.LastMessages.Add((text, sendTo, title, TimeStamp));
|
||||
return writer;
|
||||
}
|
||||
|
||||
@@ -1967,7 +2030,7 @@ public static class Utils
|
||||
}
|
||||
catch { Logger.Info(" Message sent", "SendMessage"); }
|
||||
|
||||
if (addtoHistory) ChatUpdatePatch.LastMessages.Add(("\n", sendTo, tempTitle, TimeStamp));
|
||||
if (addToHistory) ChatUpdatePatch.LastMessages.Add(("\n", sendTo, tempTitle, TimeStamp));
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
@@ -2075,7 +2138,7 @@ public static class Utils
|
||||
}
|
||||
catch (Exception e) { ThrowException(e); }
|
||||
|
||||
if (addtoHistory) ChatUpdatePatch.LastMessages.Add((text, sendTo, title, TimeStamp));
|
||||
if (addToHistory) ChatUpdatePatch.LastMessages.Add((text, sendTo, title, TimeStamp));
|
||||
return writer;
|
||||
|
||||
void RestartMessageIfTooLong()
|
||||
|
||||
@@ -125,6 +125,8 @@ internal static class ChatCommands
|
||||
|
||||
public static bool HasMessageDuringEjectionScreen;
|
||||
|
||||
private static bool WaitingToSend;
|
||||
|
||||
public static void LoadCommands()
|
||||
{
|
||||
Command.AllCommands = new Dictionary<string, Command>
|
||||
@@ -451,7 +453,7 @@ internal static class ChatCommands
|
||||
if (!Main.AllPlayerNames.TryGetValue(PlayerControl.LocalPlayer.PlayerId, out string name))
|
||||
Utils.ApplySuffix(PlayerControl.LocalPlayer, out name);
|
||||
|
||||
Utils.SendMessage(text.Insert(0, new('\n', name.Count(x => x == '\n'))), title: name, addtoHistory: false);
|
||||
Utils.SendMessage(text.Insert(0, new('\n', name.Count(x => x == '\n'))), title: name, addToHistory: false);
|
||||
|
||||
canceled = true;
|
||||
__instance.freeChatField.textArea.Clear();
|
||||
@@ -466,6 +468,22 @@ internal static class ChatCommands
|
||||
if (text.Contains("666") && PlayerControl.LocalPlayer.Is(CustomRoles.Demon))
|
||||
Achievements.Type.WhatTheHell.Complete();
|
||||
|
||||
if (!canceled && AmongUsClient.Instance.AmHost && Utils.TempReviveHostRunning)
|
||||
{
|
||||
if (!WaitingToSend) Main.Instance.StartCoroutine(Wait());
|
||||
return false;
|
||||
|
||||
IEnumerator Wait()
|
||||
{
|
||||
WaitingToSend = true;
|
||||
while (Utils.TempReviveHostRunning && AmongUsClient.Instance.AmHost) yield return null;
|
||||
yield return new WaitForSeconds(0.5f);
|
||||
if (GameStates.IsEnded || GameStates.IsLobby) yield break;
|
||||
WaitingToSend = false;
|
||||
if (HudManager.InstanceExists) HudManager.Instance.Chat.SendChat();
|
||||
}
|
||||
}
|
||||
|
||||
return !canceled;
|
||||
}
|
||||
|
||||
|
||||
@@ -72,10 +72,10 @@ internal static class GameEndChecker
|
||||
Ended = true;
|
||||
LoadingEndScreen = true;
|
||||
|
||||
//Main.AllPlayerControls.Do(pc => Camouflage.RpcSetSkin(pc, true, true, true));
|
||||
Main.AllPlayerControls.Do(pc => Camouflage.RpcSetSkin(pc, true, true, true));
|
||||
|
||||
NameNotifyManager.Reset();
|
||||
//NotifyRoles(ForceLoop: true);
|
||||
NotifyRoles(ForceLoop: true);
|
||||
|
||||
CustomSabotage.Reset();
|
||||
|
||||
@@ -359,13 +359,6 @@ internal static class GameEndChecker
|
||||
try { LobbySharingAPI.NotifyLobbyStatusChanged(LobbyStatus.Ended); }
|
||||
catch (Exception e) { ThrowException(e); }
|
||||
|
||||
string msg = GetString("NotifyGameEnding");
|
||||
|
||||
Main.AllPlayerControls
|
||||
.Where(x => x.GetClient() != null && !x.Data.Disconnected)
|
||||
.Select(x => new Message("\n", x.PlayerId, msg))
|
||||
.SendMultipleMessages();
|
||||
|
||||
SetEverythingUpPatch.LastWinsReason = WinnerTeam is CustomWinner.Crewmate or CustomWinner.Impostor ? GetString($"GameOverReason.{reason}") : string.Empty;
|
||||
var self = AmongUsClient.Instance;
|
||||
self.StartCoroutine(CoEndGame(self, reason).WrapToIl2Cpp());
|
||||
|
||||
@@ -1192,7 +1192,7 @@ public static class GameSettingMenuPatch
|
||||
gms.Remove(CustomGameMode.Deathrace);
|
||||
}
|
||||
|
||||
int totalCols = 2;
|
||||
int totalCols = 3;
|
||||
|
||||
GMButtons = [];
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ public class FallFromLadder
|
||||
|
||||
if (TargetLadderData.TryGetValue(player.PlayerId, out Vector3 targetLadderData) && Vector2.Distance(targetLadderData, player.Pos()) < 0.5f)
|
||||
{
|
||||
if (player.Data.IsDead) return;
|
||||
if (player.Data.IsDead || !player.IsAlive()) return;
|
||||
|
||||
// To insert LateTask, first enter the death judgment.
|
||||
player.Data.IsDead = true;
|
||||
|
||||
+18
-12
@@ -44,7 +44,7 @@ internal static class CheckForEndVotingPatch
|
||||
// Dictators who are not dead have already voted.
|
||||
|
||||
// Take the initiative to rebel
|
||||
if (pva.DidVote && pc.PlayerId == pva.VotedFor && pva.VotedFor < 253 && !pc.Data.IsDead)
|
||||
if (pva.DidVote && pc.PlayerId == pva.VotedFor && pva.VotedFor < 253 && pc.IsAlive())
|
||||
{
|
||||
if (Options.MadmateSpawnMode.GetInt() == 2 && Main.MadmateNum < CustomRoles.Madmate.GetCount() && pc.CanBeMadmate())
|
||||
{
|
||||
@@ -121,7 +121,7 @@ internal static class CheckForEndVotingPatch
|
||||
|
||||
if (Options.VoteMode.GetBool())
|
||||
{
|
||||
if (ps.VotedFor == 253 && !voter.Data.IsDead &&
|
||||
if (ps.VotedFor == 253 && voter.IsAlive() &&
|
||||
!(Options.WhenSkipVoteIgnoreFirstMeeting.GetBool() && MeetingStates.FirstMeeting) &&
|
||||
!(Options.WhenSkipVoteIgnoreNoDeadBody.GetBool() && !MeetingStates.IsExistDeadBody) &&
|
||||
!(Options.WhenSkipVoteIgnoreEmergency.GetBool() && MeetingStates.IsEmergencyMeeting)
|
||||
@@ -140,7 +140,7 @@ internal static class CheckForEndVotingPatch
|
||||
}
|
||||
}
|
||||
|
||||
if (ps.VotedFor == 254 && !voter.Data.IsDead)
|
||||
if (ps.VotedFor == 254 && voter.IsAlive())
|
||||
{
|
||||
switch (Options.GetWhenNonVote())
|
||||
{
|
||||
@@ -160,7 +160,7 @@ internal static class CheckForEndVotingPatch
|
||||
}
|
||||
}
|
||||
|
||||
if (ps.VotedFor == 254 && !voter.Data.IsDead && voter.Is(CustomRoles.Compelled))
|
||||
if (ps.VotedFor == 254 && voter.IsAlive() && voter.Is(CustomRoles.Compelled))
|
||||
TryAddAfterMeetingDeathPlayers(PlayerState.DeathReason.DidntVote, ps.TargetPlayerId);
|
||||
|
||||
if (CheckRole(ps.TargetPlayerId, CustomRoles.FortuneTeller) && FortuneTeller.HideVote.GetBool()) continue;
|
||||
@@ -886,9 +886,9 @@ internal static class MeetingHudStartPatch
|
||||
|
||||
roleTextMeeting.enabled =
|
||||
target.AmOwner ||
|
||||
(Main.VisibleTasksCount && seer.Data.IsDead && Options.GhostCanSeeOtherRoles.GetBool()) ||
|
||||
(seer.Is(CustomRoles.Mimic) && Main.VisibleTasksCount && target.Data.IsDead && Options.MimicCanSeeDeadRoles.GetBool()) ||
|
||||
(target.Is(CustomRoles.Gravestone) && Main.VisibleTasksCount && target.Data.IsDead) ||
|
||||
(Main.VisibleTasksCount && !seer.IsAlive() && Options.GhostCanSeeOtherRoles.GetBool()) ||
|
||||
(seer.Is(CustomRoles.Mimic) && Main.VisibleTasksCount && !target.IsAlive() && Options.MimicCanSeeDeadRoles.GetBool()) ||
|
||||
(target.Is(CustomRoles.Gravestone) && Main.VisibleTasksCount && !target.IsAlive()) ||
|
||||
(Main.LoversPlayers.TrueForAll(x => x.PlayerId == target.PlayerId || x.PlayerId == seer.PlayerId) && Main.LoversPlayers.Count == 2 && Lovers.LoverKnowRoles.GetBool()) ||
|
||||
(seer.Is(CustomRoleTypes.Coven) && target.Is(CustomRoleTypes.Coven)) ||
|
||||
(target.Is(CustomRoleTypes.Impostor) && seer.Is(CustomRoleTypes.Impostor) && Options.ImpKnowAlliesRole.GetBool() && CustomTeamManager.ArentInCustomTeam(seer.PlayerId, target.PlayerId)) ||
|
||||
@@ -914,7 +914,7 @@ internal static class MeetingHudStartPatch
|
||||
Main.GodMode.Value;
|
||||
|
||||
|
||||
if (!seer.Data.IsDead && seer.IsRevealedPlayer(target) && target.Is(CustomRoles.Trickster))
|
||||
if (seer.IsAlive() && seer.IsRevealedPlayer(target) && target.Is(CustomRoles.Trickster))
|
||||
{
|
||||
roleTextMeeting.text = Investigator.RandomRole[seer.PlayerId];
|
||||
roleTextMeeting.text += Investigator.GetTaskState();
|
||||
@@ -1086,7 +1086,7 @@ internal static class MeetingHudStartPatch
|
||||
case CustomRoles.Revolutionist when seer.IsDrawPlayer(target):
|
||||
sb.Append(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Revolutionist), "●"));
|
||||
break;
|
||||
case CustomRoles.Psychic when Psychic.IsRedForPsy(target, seer) && !seer.Data.IsDead:
|
||||
case CustomRoles.Psychic when Psychic.IsRedForPsy(target, seer) && seer.IsAlive():
|
||||
pva.NameText.text = Utils.ColorString(Utils.GetRoleColor(CustomRoles.Impostor), pva.NameText.text);
|
||||
break;
|
||||
case CustomRoles.Demon:
|
||||
@@ -1101,7 +1101,7 @@ internal static class MeetingHudStartPatch
|
||||
if (Silencer.ForSilencer.Contains(target.PlayerId))
|
||||
sb.Append(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Silencer), "╳"));
|
||||
|
||||
if (Main.LoversPlayers.Exists(x => x.PlayerId == target.PlayerId) && (Main.LoversPlayers.Exists(x => x.PlayerId == seer.PlayerId) || seer.Data.IsDead))
|
||||
if (Main.LoversPlayers.Exists(x => x.PlayerId == target.PlayerId) && (Main.LoversPlayers.Exists(x => x.PlayerId == seer.PlayerId) || !seer.IsAlive()))
|
||||
sb.Append(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Lovers), "♥"));
|
||||
|
||||
sb.Append(Executioner.TargetMark(seer, target));
|
||||
@@ -1122,7 +1122,7 @@ internal static class MeetingHudStartPatch
|
||||
if (seer.Is(CustomRoles.Medic) && (Medic.InProtect(target.PlayerId) || Medic.TempMarkProtectedList.Contains(target.PlayerId)) && Medic.WhoCanSeeProtect.GetInt() is 0 or 1)
|
||||
sb.Append(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Medic), " ●"));
|
||||
|
||||
if (seer.Data.IsDead && Medic.InProtect(target.PlayerId) && !seer.Is(CustomRoles.Medic))
|
||||
if (!seer.IsAlive() && Medic.InProtect(target.PlayerId) && !seer.Is(CustomRoles.Medic))
|
||||
sb.Append(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Medic), " ●"));
|
||||
|
||||
sb.Append(Follower.TargetMark(seer, target));
|
||||
@@ -1206,7 +1206,7 @@ internal static class MeetingHudUpdatePatch
|
||||
{
|
||||
PlayerControl player = Utils.GetPlayerById(x.TargetPlayerId);
|
||||
|
||||
if (player != null && !player.Data.IsDead)
|
||||
if (player != null && player.IsAlive())
|
||||
{
|
||||
Main.PlayerStates[player.PlayerId].deathReason = PlayerState.DeathReason.Execution;
|
||||
player.RpcExileV2();
|
||||
@@ -1381,6 +1381,12 @@ internal static class MeetingHudCastVotePatch
|
||||
skip = true;
|
||||
}
|
||||
|
||||
if (!pcSrc.IsAlive())
|
||||
{
|
||||
ShouldCancelVoteList.TryAdd(srcPlayerId, (__instance, pvaSrc, pcSrc));
|
||||
return false;
|
||||
}
|
||||
|
||||
var voteCanceled = false;
|
||||
|
||||
if (!Main.DontCancelVoteList.Contains(srcPlayerId) && !skip && pcSrc.GetCustomRole().CancelsVote() && !pcSrc.UsesMeetingShapeshift() && Main.PlayerStates[srcPlayerId].Role.OnVote(pcSrc, pcTarget))
|
||||
|
||||
@@ -105,7 +105,7 @@ public static class PhantomRoleUseAbilityPatch
|
||||
{
|
||||
if (!AmongUsClient.Instance.AmHost || !HudManager.InstanceExists) return true;
|
||||
|
||||
if (__instance.Player.AmOwner && !__instance.Player.Data.IsDead && __instance.Player.moveable && !Minigame.Instance && !__instance.IsCoolingDown && !__instance.fading)
|
||||
if (__instance.Player.AmOwner && !__instance.Player.Data.IsDead && __instance.Player.IsAlive() && __instance.Player.moveable && !Minigame.Instance && !__instance.IsCoolingDown && !__instance.fading)
|
||||
{
|
||||
bool RoleEffectAnimation(RoleEffectAnimation x) => x.effectType == global::RoleEffectAnimation.EffectType.Vanish_Charge;
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ internal static class CheckProtectPatch
|
||||
{
|
||||
public static bool Prefix(PlayerControl __instance, [HarmonyArgument(0)] PlayerControl target)
|
||||
{
|
||||
if (!AmongUsClient.Instance.AmHost || target.Data.IsDead) return false;
|
||||
if (!AmongUsClient.Instance.AmHost || target.Data.IsDead || !target.IsAlive()) return false;
|
||||
|
||||
Logger.Info($"CheckProtect: {__instance.GetNameWithRole().RemoveHtmlTags()} => {target.GetNameWithRole().RemoveHtmlTags()}", "CheckProtect");
|
||||
|
||||
@@ -990,7 +990,7 @@ internal static class ReportDeadBodyPatch
|
||||
try
|
||||
{
|
||||
// If the caller is dead, this process will cancel the meeting, so stop here.
|
||||
if (__instance.Data.IsDead) return false;
|
||||
if (__instance.Data.IsDead || !__instance.IsAlive()) return false;
|
||||
|
||||
//=============================================
|
||||
// Next, check whether this meeting is allowed
|
||||
@@ -1378,7 +1378,7 @@ internal static class ReportDeadBodyPatch
|
||||
if (Main.CheckShapeshift.ContainsKey(pc.PlayerId))
|
||||
pc.RpcShapeshift(pc, false);
|
||||
}
|
||||
else if (!pc.Data.IsDead)
|
||||
else if (!pc.Data.IsDead && (!pc.AmOwner || !TempReviveHostRunning))
|
||||
pc.RpcExileV2();
|
||||
}
|
||||
catch (Exception e) { ThrowException(e); }
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"LanguageID": "0",
|
||||
"TextBelowVersionText": "",
|
||||
"HostText": "مضيف - EHR",
|
||||
"IconColor": "",
|
||||
"IconColor": "00a5ff",
|
||||
"HostColor": "#00ffa5",
|
||||
"Icon": " | ",
|
||||
"NameColor": "#00ffff",
|
||||
@@ -59,19 +59,19 @@
|
||||
"ROT.Impostor_Killing": "★ الأدوار القاتلة",
|
||||
"ROT.Impostor_Support": "★ الأدوار الداعمة",
|
||||
"ROT.Impostor_Concealing": "أدوار الإخفاء",
|
||||
"ROT.Impostor_Miscellaneous": "★ Miscellaneous Roles",
|
||||
"ROT.Impostor_Miscellaneous": "أدوار متنوعة",
|
||||
"ROT.Impostor_Madmate": "ادوار الطاقم الغاضب",
|
||||
"ROT.Crewmate_Investigate": "★ أدوار التحقق",
|
||||
"ROT.Crewmate_Support": "★ أدوار الدعم",
|
||||
"ROT.Crewmate_Power": "★ أدوار القوة",
|
||||
"ROT.Crewmate_Killing": "★ الأدوار القاتلة",
|
||||
"ROT.Crewmate_Chaos": "★ أدوار الفوضى",
|
||||
"ROT.Crewmate_Miscellaneous": "★ Miscellaneous Roles",
|
||||
"ROT.Crewmate_Miscellaneous": "أدوار متنوعة",
|
||||
"ROT.Neutral_Evil": "★ الأدوار الشريرة",
|
||||
"ROT.Neutral_Pariah": "★ Pariah Roles",
|
||||
"ROT.Neutral_Benign": "★ Benign Roles",
|
||||
"ROT.Neutral_Killing": "★ الأدوار القاتلة",
|
||||
"ROT.Coven_Miscellaneous": "★ Miscellaneous Roles",
|
||||
"ROT.Coven_Miscellaneous": "أدوار متنوعة",
|
||||
"ROT.Vanilla": "★ Vanilla Roles",
|
||||
"ROT.Basic": "★ الأدوار العادية",
|
||||
"ROT.AddonType.ImpOnly": "★ زوائد المحتال-فقط",
|
||||
@@ -121,8 +121,8 @@
|
||||
"RoleSubCategoryLimitOptions.Neutral_Pariah.Max": "Maximum Neutral Pariah Roles",
|
||||
"RoleSubCategoryLimitOptions.Neutral_Benign.Min": "Minimum Neutral Benign Roles",
|
||||
"RoleSubCategoryLimitOptions.Neutral_Benign.Max": "Maximum Neutral Benign Roles",
|
||||
"RoleSubCategoryLimitOptions.Neutral_Killing.Min": "Minimum Neutral Killing Roles",
|
||||
"RoleSubCategoryLimitOptions.Neutral_Killing.Max": "Maximum Neutral Killing Roles",
|
||||
"RoleSubCategoryLimitOptions.Neutral_Killing.Min": "أدنى حد للأدوار القاتلين المحايدين",
|
||||
"RoleSubCategoryLimitOptions.Neutral_Killing.Max": "أقصى حد للأدوار القاتلين المحايدين",
|
||||
"FactionLimits.Impostor.Min": "<#00ffa5>Minimum</color> <#ffffff>amount of</color> Impostor Roles",
|
||||
"FactionLimits.Impostor.Max": "<#00a5ff>Maximum</color> <#ffffff>amount of</color> Impostor Roles",
|
||||
"FactionLimits.Neutral.Min": "<#00ffa5>Minimum</color> <#ffffff>amount of</color> Neutral Roles",
|
||||
@@ -10232,7 +10232,7 @@
|
||||
"EnableAutoFactionMinMaxSettings": "Enable Automatic Team Size Adjustment Based on Player Count",
|
||||
"AutoFactionMinMaxSettings.PlayerCap": "Minimum Player Threshold for These Settings to Apply (0 = unused)",
|
||||
"AutoFactionMinMaxSettings.Applied": "[Auto Team Sizes] {0} players (>={1}) = {2} (<#ffff00>NNK</color>: <#ffffff>{3}-{4}</color>)",
|
||||
"GMPoll.Allow": "Show {gm} in /gmpoll choices",
|
||||
"GMPoll.Allow": "عرض {gm} في خيارات /gmpoll",
|
||||
"MPoll.Allow": "Show {m} in /mpoll choices",
|
||||
"MenuTitle.GMPoll": "Game Mode Poll",
|
||||
"MenuTitle.MPoll": "Map Poll",
|
||||
@@ -10268,6 +10268,6 @@
|
||||
"Hungarian": "Hungarian",
|
||||
"Polish": "Polish",
|
||||
"Indonesian": "Indonesian",
|
||||
"Persian": "Persian",
|
||||
"Persian": "الفارسية",
|
||||
"NotAssigned": "-"
|
||||
}
|
||||
@@ -32,11 +32,9 @@ public abstract class CovenBase : RoleBase
|
||||
|
||||
LateTask.New(() =>
|
||||
{
|
||||
var sender = CustomRpcSender.Create("CovenGiveNecronomicon", SendOption.Reliable);
|
||||
string[] holders = Main.PlayerStates.Where(s => s.Value.Role is CovenBase { HasNecronomicon: true }).Select(s => s.Key.ColoredPlayerName()).ToArray();
|
||||
Main.AllPlayerControls.Where(x => x.Is(Team.Coven)).Select(x => x.PlayerId).Without(receiver.Key).Do(x => sender = Utils.SendMessage("\n", x, string.Format(Translator.GetString("PlayerReceivedTheNecronomicon"), receiver.Key.ColoredPlayerName(), Main.CovenColor, holders.Length, string.Join(", ", holders)), writer: sender, multiple: true));
|
||||
sender = Utils.SendMessage("\n", receiver.Key, string.Format(Translator.GetString("YouReceivedTheNecronomicon"), Main.CovenColor), writer: sender, multiple: true);
|
||||
sender.SendMessage(dispose: sender.stream.Length <= 3);
|
||||
Main.AllPlayerControls.Where(x => x.Is(Team.Coven)).Select(x => x.PlayerId).Without(receiver.Key).Do(x => Utils.SendMessage("\n", x, string.Format(Translator.GetString("PlayerReceivedTheNecronomicon"), receiver.Key.ColoredPlayerName(), Main.CovenColor, holders.Length, string.Join(", ", holders))));
|
||||
Utils.SendMessage("\n", receiver.Key, string.Format(Translator.GetString("YouReceivedTheNecronomicon"), Main.CovenColor));
|
||||
}, 12f, log: false);
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ public class Disperser : RoleBase
|
||||
|
||||
foreach (PlayerControl pc in PlayerControl.AllPlayerControls)
|
||||
{
|
||||
if (player.PlayerId == pc.PlayerId || pc.Data.IsDead || pc.onLadder || pc.inMovingPlat || pc.inVent || GameStates.IsMeeting)
|
||||
if (player.PlayerId == pc.PlayerId || pc.Data.IsDead || !pc.IsAlive() || pc.onLadder || pc.inMovingPlat || pc.inVent || GameStates.IsMeeting)
|
||||
{
|
||||
if (!pc.Is(CustomRoles.Disperser)) pc.Notify(ColorString(GetRoleColor(CustomRoles.Disperser), string.Format(GetString("ErrorTeleport"), pc.GetRealName())));
|
||||
continue;
|
||||
|
||||
@@ -193,7 +193,7 @@ internal class Revolutionist : RoleBase
|
||||
}
|
||||
}
|
||||
|
||||
if (GameStates.IsInTask && player.IsDrawDone() && player.IsAlive() && !player.Data.IsDead)
|
||||
if (GameStates.IsInTask && player.IsDrawDone() && player.IsAlive() && player.IsAlive())
|
||||
{
|
||||
if (RevolutionistStart.TryGetValue(playerId, out var start))
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user