mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-19 15:51:58 +00:00
136 lines
5.3 KiB
C#
136 lines
5.3 KiB
C#
using System;
|
|
using AmongUs.GameOptions;
|
|
using EHR.Roles;
|
|
using HarmonyLib;
|
|
using Hazel;
|
|
|
|
namespace EHR.Patches;
|
|
// By TommyXL & NikoCat233
|
|
|
|
[HarmonyPatch(typeof(PlayerControl))]
|
|
public static class PhantomRolePatch
|
|
{
|
|
[HarmonyPatch(nameof(PlayerControl.CmdCheckVanish))]
|
|
[HarmonyPrefix]
|
|
private static bool CmdCheckVanish_Prefix(PlayerControl __instance, float maxDuration)
|
|
{
|
|
if (AmongUsClient.Instance.AmHost)
|
|
{
|
|
__instance.CheckVanish();
|
|
return false;
|
|
}
|
|
|
|
__instance.SetRoleInvisibility(true);
|
|
MessageWriter messageWriter = AmongUsClient.Instance.StartRpcImmediately(__instance.NetId, (byte)RpcCalls.CheckVanish, SendOption.Reliable, AmongUsClient.Instance.HostId);
|
|
messageWriter.Write(maxDuration);
|
|
AmongUsClient.Instance.FinishRpcImmediately(messageWriter);
|
|
return false;
|
|
}
|
|
|
|
[HarmonyPatch(nameof(PlayerControl.CmdCheckAppear))]
|
|
[HarmonyPrefix]
|
|
private static bool CmdCheckAppear_Prefix(PlayerControl __instance, bool shouldAnimate)
|
|
{
|
|
if (AmongUsClient.Instance.AmHost)
|
|
{
|
|
__instance.CheckAppear(shouldAnimate);
|
|
return false;
|
|
}
|
|
|
|
MessageWriter messageWriter = AmongUsClient.Instance.StartRpcImmediately(__instance.NetId, (byte)RpcCalls.CheckAppear, SendOption.Reliable, AmongUsClient.Instance.HostId);
|
|
messageWriter.Write(shouldAnimate);
|
|
AmongUsClient.Instance.FinishRpcImmediately(messageWriter);
|
|
return false;
|
|
}
|
|
|
|
[HarmonyPatch(nameof(PlayerControl.CheckVanish))] // This doesn't always get called for non-hosts, so we invoke CheckTrigger directly when the CheckVanish RPC is received
|
|
[HarmonyPrefix]
|
|
private static bool CheckVanish_Prefix(PlayerControl __instance)
|
|
{
|
|
if (!AmongUsClient.Instance.AmHost) return true;
|
|
Logger.Info($" {__instance.GetNameWithRole()}", "CheckVanish");
|
|
return __instance.AmOwner && CheckTrigger(__instance); // This is assuming that all non-host vanish requests are for ability triggers and should be cancelled
|
|
}
|
|
|
|
public static bool CheckTrigger(PlayerControl phantom)
|
|
{
|
|
if (!HudManager.InstanceExists) return true;
|
|
|
|
RoleBase roleBase = Main.PlayerStates[phantom.PlayerId].Role;
|
|
|
|
if (phantom.Is(CustomRoles.Trainee) && MeetingStates.FirstMeeting || !Rhapsode.CheckAbilityUse(phantom) || Stasis.IsTimeFrozen || TimeMaster.Rewinding || IntroCutsceneDestroyPatch.PreventKill || !roleBase.OnVanish(phantom))
|
|
{
|
|
if (phantom.AmOwner)
|
|
{
|
|
try
|
|
{
|
|
HudManager.Instance.AbilityButton.SetFromSettings(phantom.Data.Role.Ability);
|
|
}
|
|
catch { }
|
|
if (Utils.ShouldNotApplyAbilityCooldown(roleBase)) return false;
|
|
phantom.RpcResetAbilityCooldown();
|
|
return false;
|
|
}
|
|
|
|
var sender = CustomRpcSender.Create($"Cancel vanish for {phantom.GetRealName()}", SendOption.Reliable);
|
|
sender.StartMessage(phantom.OwnerId);
|
|
|
|
sender.StartRpc(phantom.NetId, RpcCalls.SetRole)
|
|
.Write((ushort)RoleTypes.Phantom)
|
|
.Write(true)
|
|
.EndRpc();
|
|
|
|
if (!Utils.ShouldNotApplyAbilityCooldown(roleBase))
|
|
{
|
|
sender.StartRpc(phantom.NetId, RpcCalls.ProtectPlayer)
|
|
.WriteNetObject(phantom)
|
|
.Write(0)
|
|
.EndRpc();
|
|
}
|
|
|
|
sender.EndMessage();
|
|
sender.SendMessage();
|
|
|
|
LateTask.New(() => phantom.SetKillCooldown(Math.Max(Main.KillTimers[phantom.PlayerId], 0.001f)), 0.2f);
|
|
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// Fixed vanilla bug for host (from TOH-Y)
|
|
[HarmonyPatch(typeof(PhantomRole), nameof(PhantomRole.UseAbility))]
|
|
public static class PhantomRoleUseAbilityPatch
|
|
{
|
|
public static bool Prefix(PhantomRole __instance)
|
|
{
|
|
if (!AmongUsClient.Instance.AmHost || !HudManager.InstanceExists) return true;
|
|
|
|
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;
|
|
|
|
#if IL2CPP
|
|
if (!__instance.Player.currentRoleAnimations.Find((Il2CppSystem.Predicate<RoleEffectAnimation>)RoleEffectAnimation) && !__instance.Player.walkingToVent && !__instance.Player.inMovingPlat)
|
|
#else
|
|
if (!__instance.Player.currentRoleAnimations.Find(RoleEffectAnimation) && !__instance.Player.walkingToVent && !__instance.Player.inMovingPlat)
|
|
#endif
|
|
{
|
|
if (__instance.isInvisible)
|
|
{
|
|
__instance.MakePlayerVisible();
|
|
return false;
|
|
}
|
|
|
|
HudManager.Instance.AbilityButton.SetSecondImage(__instance.Ability);
|
|
HudManager.Instance.AbilityButton.OverrideText(TranslationController.Instance.GetString(StringNames.PhantomAbilityUndo));
|
|
__instance.Player.CmdCheckVanish(GameManager.Instance.LogicOptions.GetRoleFloat(FloatOptionNames.PhantomDuration));
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|