mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-19 15:51:58 +00:00
some fixes (not tested)
This commit is contained in:
1 parent
cd26c179b9
commit
80289cc9fe
12 files changed
+127
-41
No files matched your search
+87
-9
@@ -4,13 +4,16 @@ using System.Linq;
|
||||
using AmongUs.GameOptions;
|
||||
using EHR.Modules;
|
||||
using EHR.Patches;
|
||||
using EHR.Roles;
|
||||
using Hazel;
|
||||
using UnityEngine;
|
||||
|
||||
namespace EHR;
|
||||
|
||||
public static class AntiBlackout
|
||||
{
|
||||
public static bool SkipTasks;
|
||||
public static bool AllowSyncSettings;
|
||||
private static Dictionary<(byte SeerID, byte TargetID), (RoleTypes RoleType, CustomRoles CustomRole)> CachedRoleMap = [];
|
||||
|
||||
// Optimally, there's 1 living impostor and at least 2 living crewmates in everyone's POV.
|
||||
@@ -128,35 +131,102 @@ public static class AntiBlackout
|
||||
|
||||
LateTask.New(() =>
|
||||
{
|
||||
List<PlayerControl> rpcGuardAndKill = [];
|
||||
var elapsedSeconds = (int)ExileControllerWrapUpPatch.Stopwatch.Elapsed.TotalSeconds;
|
||||
var sender = CustomRpcSender.Create("Exile Dead Players After Meeting", SendOption.Reliable);
|
||||
var hasValue = false;
|
||||
var senderPacked = CustomRpcSender.Create("AntiBlackout Packed Sender", SendOption.Reliable).StartPackedMessage();
|
||||
var senderToAll = CustomRpcSender.Create("Exile Dead Players After Meeting", SendOption.Reliable);
|
||||
var hasValuePacked = false;
|
||||
var hasValueToAll = false;
|
||||
|
||||
foreach (PlayerControl pc in Main.EnumeratePlayerControls())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (pc.OwnerId < 0) continue;
|
||||
|
||||
if (pc.IsAlive())
|
||||
{
|
||||
// Due to the role base change, we need to reset the cooldowns for abilities.
|
||||
if (!Utils.ShouldNotApplyAbilityCooldownAfterMeeting(pc))
|
||||
pc.RpcResetAbilityCooldown();
|
||||
{
|
||||
if (senderPacked.RpcResetAbilityCooldown(pc))
|
||||
hasValuePacked = true;
|
||||
}
|
||||
|
||||
float time = -1f;
|
||||
|
||||
if (Main.AllPlayerKillCooldown.TryGetValue(pc.PlayerId, out float kcd))
|
||||
{
|
||||
float time = kcd - elapsedSeconds;
|
||||
if (time > 0) pc.SetKillCooldown(time);
|
||||
time = kcd - elapsedSeconds;
|
||||
if (time <= 0) continue;
|
||||
}
|
||||
|
||||
if (!Mathf.Approximately(time, -1f) && Committed.ReduceKCD != null && Committed.ReduceKCD.TryGetValue(pc.PlayerId, out float reduction))
|
||||
{
|
||||
time -= reduction;
|
||||
if (time <= 0) continue;
|
||||
}
|
||||
|
||||
Logger.Info($"{pc.GetNameWithRole()}'s KCD set to {(time < 0f ? Main.AllPlayerKillCooldown[pc.PlayerId] : time)}s", "SetKCD");
|
||||
|
||||
if (pc.GetCustomRole().UsesPetInsteadOfKill())
|
||||
{
|
||||
if (time < 0f)
|
||||
pc.AddKCDAsAbilityCD();
|
||||
else
|
||||
pc.AddAbilityCD((int)Math.Round(time));
|
||||
|
||||
if (pc.GetCustomRole() is not CustomRoles.Necromancer and not CustomRoles.Deathknight and not CustomRoles.Renegade and not CustomRoles.Sidekick) continue;
|
||||
}
|
||||
|
||||
pc.AddKillTimerToDict(cd: time);
|
||||
|
||||
if (time >= 0f)
|
||||
Main.AllPlayerKillCooldown[pc.PlayerId] = time * 2;
|
||||
else
|
||||
Main.AllPlayerKillCooldown[pc.PlayerId] *= 2;
|
||||
|
||||
if (pc.Is(CustomRoles.Glitch) && Main.PlayerStates[pc.PlayerId].Role is Glitch gc)
|
||||
{
|
||||
gc.LastKill = Utils.TimeStamp + ((int)(time / 2) - Glitch.KillCooldown.GetInt());
|
||||
gc.KCDTimer = (int)(time / 2);
|
||||
}
|
||||
else if (!pc.IsModdedClient() || !Options.DisableShieldAnimations.GetBool())
|
||||
{
|
||||
pc.MarkDirtySettings();
|
||||
rpcGuardAndKill.Add(pc);
|
||||
}
|
||||
else
|
||||
pc.SetKillCooldown();
|
||||
{
|
||||
time = Main.AllPlayerKillCooldown[pc.PlayerId] / 2;
|
||||
|
||||
if (pc.AmOwner)
|
||||
PlayerControl.LocalPlayer.SetKillTimer(time);
|
||||
else
|
||||
{
|
||||
senderPacked.AutoStartRpc(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SetKillTimer, pc.OwnerId);
|
||||
senderPacked.Write(time);
|
||||
senderPacked.EndRpc();
|
||||
hasValuePacked = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (pc.GetCustomRole() is not CustomRoles.Inhibitor and not CustomRoles.Saboteur)
|
||||
{
|
||||
LateTask.New(() =>
|
||||
{
|
||||
pc.ResetKillCooldown(sync: false);
|
||||
pc.MarkDirtySettings();
|
||||
}, 0.3f, log: false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pc.AmOwner && Utils.TempReviveHostRunning) continue;
|
||||
|
||||
// Ensure that the players who are considered dead by the mod are actually dead in the game.
|
||||
sender.RpcExiled(pc);
|
||||
hasValue = true;
|
||||
senderToAll.RpcExiled(pc);
|
||||
hasValueToAll = true;
|
||||
|
||||
if (GhostRolesManager.AssignedGhostRoles.TryGetValue(pc.PlayerId, out var ghostRole) && ghostRole.Instance.RoleTypes == RoleTypes.GuardianAngel)
|
||||
pc.AddAbilityCD(ghostRole.Instance.Cooldown);
|
||||
@@ -164,8 +234,16 @@ public static class AntiBlackout
|
||||
}
|
||||
catch (Exception e) { Utils.ThrowException(e); }
|
||||
}
|
||||
|
||||
AllowSyncSettings = true;
|
||||
PlayerGameOptionsSender.SendAllImmediately();
|
||||
AllowSyncSettings = false;
|
||||
|
||||
sender.SendMessage(dispose: !hasValue);
|
||||
rpcGuardAndKill.ForEach(pc => hasValuePacked |= senderPacked.RpcGuardAndKill(pc, fromSetKCD: true));
|
||||
|
||||
LateTask.New(() => senderPacked.SendMessage(dispose: !hasValuePacked), 0.1f);
|
||||
|
||||
senderToAll.SendMessage(dispose: !hasValueToAll);
|
||||
|
||||
// Only execute AfterMeetingTasks after everything is reset.
|
||||
LateTask.New(() =>
|
||||
|
||||
@@ -349,8 +349,8 @@ namespace EHR
|
||||
if (PlayerControl.AllPlayerControls.Contains(playerControl))
|
||||
PlayerControl.AllPlayerControls.Remove(playerControl);
|
||||
|
||||
playerControl.cosmetics.currentBodySprite.BodySprite.color = Color.clear;
|
||||
playerControl.cosmetics.colorBlindText.color = Color.clear;
|
||||
try { playerControl.cosmetics.currentBodySprite.BodySprite.color = Color.clear; } catch { }
|
||||
try { playerControl.cosmetics.colorBlindText.color = Color.clear; } catch { }
|
||||
Position = position;
|
||||
Sprite = sprite;
|
||||
++MaxId;
|
||||
|
||||
@@ -707,6 +707,9 @@ public static class CustomRpcSenderExtensions
|
||||
{
|
||||
if (!player) return false;
|
||||
|
||||
if (!Mathf.Approximately(time, -1f) && Committed.ReduceKCD != null && Committed.ReduceKCD.TryGetValue(player.PlayerId, out float reduction))
|
||||
time = Math.Max(time - reduction, 0.01f);
|
||||
|
||||
Logger.Info($"{player.GetNameWithRole()}'s KCD set to {(Math.Abs(time - -1f) < 0.5f ? Main.AllPlayerKillCooldown[player.PlayerId] : time)}s", "SetKCD");
|
||||
|
||||
if (player.GetCustomRole().UsesPetInsteadOfKill())
|
||||
|
||||
@@ -1135,14 +1135,16 @@ internal static class ExtendedPlayerControl
|
||||
{
|
||||
try
|
||||
{
|
||||
if (NameWithRoleCache.TryGetValue(player?.PlayerId ?? 250, out string cache)) return cache;
|
||||
if (!player) return "Unknown Player";
|
||||
if (NameWithRoleCache.TryGetValue(player.PlayerId, out string cache)) return cache;
|
||||
if (!player.Data) return "Unknown Player";
|
||||
bool addRoleName = GameStates.IsInGame && Options.CurrentGameMode is not CustomGameMode.FFA and not CustomGameMode.StopAndGo and not CustomGameMode.HotPotato and not CustomGameMode.Speedrun and not CustomGameMode.CaptureTheFlag and not CustomGameMode.NaturalDisasters and not CustomGameMode.RoomRush and not CustomGameMode.Quiz and not CustomGameMode.TheMindGame and not CustomGameMode.BedWars and not CustomGameMode.Deathrace and not CustomGameMode.Mingle and not CustomGameMode.Snowdown;
|
||||
return NameWithRoleCache[player?.PlayerId ?? 250] = $"{player?.Data?.PlayerName}" + (addRoleName ? $" ({player?.GetAllRoleName(forUser).RemoveHtmlTags().Replace('\n', ' ')})" : string.Empty);
|
||||
return NameWithRoleCache[player.PlayerId] = $"{player.Data.PlayerName}" + (addRoleName ? $" ({player.GetAllRoleName(forUser).RemoveHtmlTags().Replace('\n', ' ')})" : string.Empty);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ThrowException(e);
|
||||
return !player || !player.Data ? "Unknown Player" : player.Data.PlayerName;
|
||||
return "Unknown Player";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ public sealed class PlayerGameOptionsSender(PlayerControl player) : GameOptionsS
|
||||
|
||||
public static DataFlagRateLimiter.QueuedAction SendAllImmediately()
|
||||
{
|
||||
if (AntiBlackout.SkipTasks) return null;
|
||||
if (AntiBlackout.SkipTasks && !AntiBlackout.AllowSyncSettings) return null;
|
||||
|
||||
ForceWaitFrame = true;
|
||||
|
||||
@@ -264,7 +264,7 @@ public sealed class PlayerGameOptionsSender(PlayerControl player) : GameOptionsS
|
||||
|
||||
protected override void SendOptionsArray(Il2CppStructArray<byte> optionArray, byte logicOptionsIndex)
|
||||
{
|
||||
if (AntiBlackout.SkipTasks) return;
|
||||
if (AntiBlackout.SkipTasks && !AntiBlackout.AllowSyncSettings) return;
|
||||
|
||||
if (PackedWriter == null) // Single write
|
||||
{
|
||||
|
||||
@@ -1110,7 +1110,7 @@ internal static class ChatCommands
|
||||
{
|
||||
GMPollGameModes = Main.CustomGameModeValues[..^1].Where(x => Options.GMPollGameModesSettings[x].GetBool()).ToList();
|
||||
if (GMPollGameModes.Contains(CustomGameMode.HideAndSeek)) GMPollGameModes.Add((CustomGameMode)100);
|
||||
string gmNames = GMPollGameModes.Join(' ', x => GetString((int)x == 100 ? "HNS.ShiftAndSeek" : x.ToString().Replace(' ', '_')));
|
||||
string gmNames = GMPollGameModes.Join(' ', x => GetString((int)x == 100 ? "HNS.ShiftAndSeek" : x.ToString().Replace(' ', '-')));
|
||||
var msg = $"/poll {GetString("GameModePoll.Question").TrimEnd('?')}? {gmNames}";
|
||||
PollCommand(player, msg, msg.Split(' '));
|
||||
}
|
||||
@@ -1118,7 +1118,7 @@ internal static class ChatCommands
|
||||
public static void MapPollCommand(PlayerControl player, string text, string[] args)
|
||||
{
|
||||
MPollMaps = Main.MapNamesValues.Where(x => Options.MPollMapsSettings[x].GetBool()).ToList();
|
||||
string mNames = MPollMaps.Join(' ', x => GetString(x.ToString().Replace(' ', '_')));
|
||||
string mNames = MPollMaps.Join(' ', x => GetString(x.ToString().Replace(' ', '-')));
|
||||
var msg = $"/poll {GetString("MapPoll.Question").TrimEnd('?')}? {mNames}";
|
||||
PollCommand(player, msg, msg.Split(' '));
|
||||
}
|
||||
@@ -1126,7 +1126,7 @@ internal static class ChatCommands
|
||||
public static void PresetPollCommand(PlayerControl player, string text, string[] args)
|
||||
{
|
||||
var presetConfigs = new[] { Main.Preset1, Main.Preset2, Main.Preset3, Main.Preset4, Main.Preset5, Main.Preset6, Main.Preset7, Main.Preset8, Main.Preset9, Main.Preset10, Main.Preset11, Main.Preset12, Main.Preset13, Main.Preset14, Main.Preset15, Main.Preset16, Main.Preset17, Main.Preset18, Main.Preset19, Main.Preset20 };
|
||||
string presetNames = string.Join(' ', presetConfigs.Select((cfg, i) => (cfg.Value == (string)cfg.DefaultValue ? GetString($"Preset_{i + 1}") : cfg.Value).Replace(' ', '_')));
|
||||
string presetNames = string.Join(' ', presetConfigs.Select((cfg, i) => (cfg.Value == (string)cfg.DefaultValue ? GetString($"Preset_{i + 1}") : cfg.Value).Replace(' ', '-')));
|
||||
|
||||
var msg = $"/poll {GetString("PresetPoll.Question").TrimEnd('?')}? {presetNames}";
|
||||
PollCommand(player, msg, msg.Split(' '));
|
||||
|
||||
@@ -426,17 +426,7 @@ internal static class GameEndChecker
|
||||
void SetGhostRole(bool toGhostImpostor)
|
||||
{
|
||||
if (!pc.Data.IsDead) playersToRevive.Add(pc.PlayerId);
|
||||
|
||||
if (toGhostImpostor)
|
||||
{
|
||||
Logger.Info($"{pc.GetNameWithRole()}: changed to ImpostorGhost", "ResetRoleAndEndGame");
|
||||
pc.RpcSetRole(RoleTypes.ImpostorGhost);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Info($"{pc.GetNameWithRole()}: changed to CrewmateGhost", "ResetRoleAndEndGame");
|
||||
pc.RpcSetRole(RoleTypes.CrewmateGhost);
|
||||
}
|
||||
pc.RpcSetRole(toGhostImpostor ? RoleTypes.ImpostorGhost : RoleTypes.CrewmateGhost);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -494,6 +494,8 @@ internal static class StartGameHostPatch
|
||||
}
|
||||
catch (Exception e) { Utils.ThrowException(e); }
|
||||
|
||||
yield return null;
|
||||
|
||||
try
|
||||
{
|
||||
GC.Collect();
|
||||
|
||||
@@ -118,9 +118,9 @@ public class Sheriff : RoleBase
|
||||
|
||||
public override bool CanUseKillButton(PlayerControl pc)
|
||||
{
|
||||
return !Main.PlayerStates[pc.PlayerId].IsDead
|
||||
&& (CanKillAllAlive.GetBool() || GameStates.AlreadyDied)
|
||||
&& pc.GetAbilityUseLimit() is float.NaN or > 0;
|
||||
if (!CanKillAllAlive.GetBool() && !GameStates.AlreadyDied) return false;
|
||||
float abilityUseLimit = pc.GetAbilityUseLimit();
|
||||
return float.IsNaN(abilityUseLimit) || abilityUseLimit > 0 || pc.Is(CustomRoles.Bloodlust);
|
||||
}
|
||||
|
||||
public override bool OnCheckMurder(PlayerControl killer, PlayerControl target)
|
||||
@@ -139,6 +139,9 @@ public class Sheriff : RoleBase
|
||||
{
|
||||
killer.RpcRemoveAbilityUse();
|
||||
Logger.Info($"{killer.GetNameWithRole()} : Number of kills left: {killer.GetAbilityUseLimit()}", "Sheriff");
|
||||
|
||||
if (killer.Is(CustomRoles.Bloodlust)) return;
|
||||
|
||||
if (killer.PlayerId != target.PlayerId)
|
||||
Main.PlayerStates[target.PlayerId].deathReason = PlayerState.DeathReason.Shot;
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ internal class TimeMaster : RoleBase
|
||||
|
||||
public override void OnPet(PlayerControl pc)
|
||||
{
|
||||
if (pc.GetAbilityUseLimit() < 1) return;
|
||||
if (Rewinding || pc.GetAbilityUseLimit() < 1) return;
|
||||
pc.RpcRemoveAbilityUse(notify: false);
|
||||
|
||||
Main.Instance.StartCoroutine(Rewind());
|
||||
@@ -120,7 +120,7 @@ internal class TimeMaster : RoleBase
|
||||
public override void OnEnterVent(PlayerControl pc, Vent vent)
|
||||
{
|
||||
if (UsePets.GetBool()) return;
|
||||
if (pc.GetAbilityUseLimit() < 1) return;
|
||||
if (Rewinding || pc.GetAbilityUseLimit() < 1) return;
|
||||
pc.RpcRemoveAbilityUse(notify: false);
|
||||
|
||||
Main.Instance.StartCoroutine(Rewind());
|
||||
|
||||
@@ -305,7 +305,7 @@ public class Penguin : RoleBase
|
||||
|
||||
if (AbductVictim)
|
||||
{
|
||||
if (!Penguin_.IsAlive() || Pelican.IsEaten(PenguinId) || !AbductVictim.IsAlive())
|
||||
if (!Penguin_ || !Penguin_.IsAlive() || Pelican.IsEaten(PenguinId) || !AbductVictim.IsAlive())
|
||||
{
|
||||
RemoveVictim();
|
||||
return;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using AmongUs.GameOptions;
|
||||
using System.Collections.Generic;
|
||||
using AmongUs.GameOptions;
|
||||
using EHR.Modules;
|
||||
using EHR.Modules.Extensions;
|
||||
using Hazel;
|
||||
@@ -69,6 +70,8 @@ public class Duality : RoleBase
|
||||
|
||||
public override void OnMurder(PlayerControl killer, PlayerControl target)
|
||||
{
|
||||
if (!killer.IsAlive()) return;
|
||||
|
||||
LateTask.New(() =>
|
||||
{
|
||||
KillingPhase = false;
|
||||
@@ -80,8 +83,13 @@ public class Duality : RoleBase
|
||||
|
||||
public override void OnTaskComplete(PlayerControl pc, int completedTaskCount, int totalTaskCount)
|
||||
{
|
||||
if (!pc.IsAlive()) return;
|
||||
|
||||
KillingPhase = true;
|
||||
pc.RpcSetRoleDesync(RoleTypes.Impostor, pc.OwnerId, setRoleMap: true);
|
||||
var sender = CustomRpcSender.Create($"Duality to killing phase ({Main.AllPlayerNames.GetValueOrDefault(pc.PlayerId, "Someone")})", SendOption.Reliable);
|
||||
sender.RpcSetRole(pc, RoleTypes.Impostor, pc.OwnerId);
|
||||
if (!pc.IsImpostor()) Main.CachedAlivePlayerControls().DoIf(x => x.IsImpostor(), x => sender.RpcSetRole(x, RoleTypes.Crewmate, pc.OwnerId));
|
||||
sender.SendMessage();
|
||||
ResetTimer();
|
||||
}
|
||||
|
||||
@@ -93,17 +101,17 @@ public class Duality : RoleBase
|
||||
void ResetTimer(int add = 0)
|
||||
{
|
||||
var pc = DualityId.GetPlayer();
|
||||
if (pc == null || !pc.IsAlive()) return;
|
||||
if (!pc || !pc.IsAlive()) return;
|
||||
Timer?.Dispose();
|
||||
Timer = new CountdownTimer(Time.GetInt() + add, () =>
|
||||
{
|
||||
if (pc == null || !pc.IsAlive()) return;
|
||||
if (!pc || !pc.IsAlive()) return;
|
||||
pc.Suicide();
|
||||
if (pc.AmOwner) Achievements.Type.OutOfTime.Complete();
|
||||
Timer = null;
|
||||
}, onTick: () =>
|
||||
{
|
||||
if (pc == null || !pc.IsAlive())
|
||||
if (!pc || !pc.IsAlive())
|
||||
{
|
||||
Timer.Dispose();
|
||||
return;
|
||||
|
||||
Reference in new issue
Block a user