using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using FishNet.Object;
using FishNet.Object.Synchronizing;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace MutatedWhalePhases
{
internal static class BallisticUtils
{
public static Vector3 SolveVelocityForFlightTime(Vector3 start, Vector3 end, float flightTime, float gravity)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
flightTime = Mathf.Max(flightTime, 0.1f);
Vector3 val = end - start;
Vector3 val2 = new Vector3(val.x, 0f, val.z);
float y = val.y;
Vector3 val3 = val2 / flightTime;
float num = y / flightTime + 0.5f * gravity * flightTime;
return val3 + Vector3.up * num;
}
public static Vector3 PositionAtTime(Vector3 start, Vector3 initialVelocity, float gravity, float time)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
Vector3 result = start + initialVelocity * time;
result.y -= 0.5f * gravity * time * time;
return result;
}
}
[HarmonyPatch(typeof(PlayerHands))]
internal static class BoatHandVisualPatch
{
private static readonly FieldInfo PlayerField = AccessTools.Field(typeof(PlayerHands), "_player");
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
[HarmonyPrefix]
private static bool BeforeDrivenBoatGetter(PlayerHands __instance, ref Boat __result)
{
if (!BowheadWhaleAccess.IsSecondPhaseActive())
{
return true;
}
object? value = PlayerField.GetValue(__instance);
Player val = (Player)((value is Player) ? value : null);
if ((Object)(object)val == (Object)null || !Object.op_Implicit((Object)(object)val.Holding.HeldItem))
{
return true;
}
__result = null;
return false;
}
}
[HarmonyPatch]
internal static class BoatItemGatePatch
{
private static readonly MethodInfo IsDrivingLocallyGetter = AccessTools.PropertyGetter(typeof(Boat), "IsDrivingLocally");
private static readonly MethodInfo WantToDriveGetter = AccessTools.PropertyGetter(typeof(Boat), "WantToDrive");
private static readonly MethodInfo BypassIsDrivingLocallyMethod = AccessTools.Method(typeof(BoatItemGatePatch), "BypassIsDrivingLocally", (Type[])null, (Type[])null);
private static readonly MethodInfo BypassWantToDriveMethod = AccessTools.Method(typeof(BoatItemGatePatch), "BypassWantToDrive", (Type[])null, (Type[])null);
private static bool BypassIsDrivingLocally()
{
if (!BowheadWhaleAccess.IsSecondPhaseActive())
{
return Boat.IsDrivingLocally;
}
return false;
}
private static bool BypassWantToDrive()
{
if (!BowheadWhaleAccess.IsSecondPhaseActive())
{
return Boat.WantToDrive;
}
return false;
}
private static IEnumerable<CodeInstruction> Transpile(IEnumerable<CodeInstruction> instructions)
{
foreach (CodeInstruction instruction in instructions)
{
if (CodeInstructionExtensions.Calls(instruction, IsDrivingLocallyGetter))
{
yield return new CodeInstruction(OpCodes.Call, (object)BypassIsDrivingLocallyMethod);
}
else if (CodeInstructionExtensions.Calls(instruction, WantToDriveGetter))
{
yield return new CodeInstruction(OpCodes.Call, (object)BypassWantToDriveMethod);
}
else
{
yield return instruction;
}
}
}
[HarmonyPatch(typeof(PlayerInventory), "DeselectSlotInput")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> TranspileDeselectSlotInput(IEnumerable<CodeInstruction> instructions)
{
return Transpile(instructions);
}
[HarmonyPatch(typeof(PlayerInventory), "SelectSlotInput")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> TranspileSelectSlotInput(IEnumerable<CodeInstruction> instructions)
{
return Transpile(instructions);
}
[HarmonyPatch(typeof(PlayerInventory), "ScrollSlotInput")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> TranspileScrollSlotInput(IEnumerable<CodeInstruction> instructions)
{
return Transpile(instructions);
}
[HarmonyPatch(typeof(PlayerInventory), "ChangeBaitInput")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> TranspileChangeBaitInput(IEnumerable<CodeInstruction> instructions)
{
return Transpile(instructions);
}
[HarmonyPatch(typeof(PlayerHolding), "ScanForGrabbableItem")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> TranspileScanForGrabbableItem(IEnumerable<CodeInstruction> instructions)
{
return Transpile(instructions);
}
[HarmonyPatch(typeof(PlayerHolding), "ScanForInteractable")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> TranspileScanForInteractable(IEnumerable<CodeInstruction> instructions)
{
return Transpile(instructions);
}
[HarmonyPatch(typeof(PlayerPunching), "PunchInput")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> TranspilePunchInput(IEnumerable<CodeInstruction> instructions)
{
return Transpile(instructions);
}
}
[HarmonyPatch]
internal static class BoatPhaseTwoPatch
{
private static readonly FieldInfo DriverField = AccessTools.Field(typeof(Boat), "_driver");
[HarmonyPatch(typeof(Boat), "TrySetDriver")]
[HarmonyPrefix]
private static bool BeforeTrySetDriver(Boat __instance, Player newDriver)
{
if (!BowheadWhaleAccess.IsSecondPhaseActive())
{
return true;
}
if (Object.op_Implicit((Object)(object)__instance.Driver) && Object.op_Implicit((Object)(object)newDriver))
{
return false;
}
((SyncVar<Player>)DriverField.GetValue(__instance)).Value = newDriver;
return false;
}
}
internal static class BowheadWhaleAccess
{
private static readonly FieldInfo ActiveWhaleField = typeof(BowheadWhale).GetField("_whale", BindingFlags.Static | BindingFlags.NonPublic);
public static bool TryGetActiveBoss(out BowheadWhale whale)
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Invalid comparison between Unknown and I4
object? value = ActiveWhaleField.GetValue(null);
whale = (BowheadWhale)((value is BowheadWhale) ? value : null);
if ((Object)(object)whale != (Object)null && (int)((Creature)whale).BossType == 2)
{
return !((Creature)whale).IsDead;
}
return false;
}
public static bool IsSecondPhaseActive()
{
if (TryGetActiveBoss(out var whale))
{
return whale._inSecondPhase.Value;
}
return false;
}
}
internal static class DebugKeys
{
private static readonly MethodInfo SpawnMutatedWhaleMethod = AccessTools.Method(typeof(MainLava), "SpawnMutatedWhale", (Type[])null, (Type[])null);
private static readonly FieldInfo IsSpawningWhaleField = AccessTools.Field(typeof(MainLava), "_isSpawningWhale");
public static void Update()
{
Keyboard current = Keyboard.current;
if (current != null)
{
if (((ButtonControl)current.jKey).wasPressedThisFrame)
{
TrySpawnWhale();
}
if (((ButtonControl)current.kKey).wasPressedThisFrame)
{
TrySetBossHpPercent(0.49f);
}
if (((ButtonControl)current.lKey).wasPressedThisFrame)
{
TrySetBossHpPercent(0.09f);
}
}
}
private static void TrySpawnWhale()
{
if (!((Object)(object)BossManager.Boss != (Object)null))
{
MainLava val = Object.FindAnyObjectByType<MainLava>();
if (!((Object)(object)val == (Object)null) && !(bool)IsSpawningWhaleField.GetValue(val))
{
((MonoBehaviour)val).StartCoroutine((IEnumerator)SpawnMutatedWhaleMethod.Invoke(val, null));
}
}
}
private static void TrySetBossHpPercent(float targetPercent)
{
Creature boss = BossManager.Boss;
if (!((Object)(object)boss == (Object)null) && !boss.IsDead)
{
int num = Mathf.Max(1, Mathf.RoundToInt((float)BossManager.BossMaxHp * targetPercent));
int num2 = boss.Hp - num;
if (num2 > 0)
{
boss.ServerChangeHp(num2);
}
}
}
}
[BepInPlugin("community.howtofish.mutatedwhalephases", "Mutated Whale Phases", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
public const string PluginGuid = "community.howtofish.mutatedwhalephases";
public const string PluginName = "Mutated Whale Phases";
public const string PluginVersion = "1.0.0";
private Harmony _harmony;
private void Awake()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
_harmony = new Harmony("community.howtofish.mutatedwhalephases");
_harmony.PatchAll();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Mutated Whale Phases loaded: lava reflect + third phase patches applied.");
}
private void Update()
{
DebugKeys.Update();
}
private void OnDestroy()
{
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
}
[HarmonyPatch]
internal static class SecondPhaseLaunchPatch
{
private const float MinFlightTime = 3.5f;
private const float FlightSpeedCap = 40f;
private const float LaunchHeightBonus = 25f;
private const float LandingSnapDistance = 10f;
private const float ScreenShakeDuration = 3f;
private const float TargetDistanceMultiplier = 4f;
private static readonly FieldInfo RigField = AccessTools.Field(typeof(PlayerMovement), "_rig");
private static readonly FieldInfo ExtraGravityForceField = AccessTools.Field(typeof(PlayerMovement), "_extraGravityForce");
private static readonly FieldInfo PlayerField = AccessTools.Field(typeof(PlayerMovement), "_player");
private static float GetGravity(PlayerMovement movement)
{
return (float)ExtraGravityForceField.GetValue(movement);
}
[HarmonyPatch(typeof(BowheadWhale), "OnHealthChange")]
[HarmonyPostfix]
private static void AfterOnHealthChange(BowheadWhale __instance, bool asServer)
{
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Invalid comparison between Unknown and I4
if (asServer && (int)((Creature)__instance).BossType == 2 && __instance._inSecondPhase.Value && !SecondPhaseSequenceState.SequenceTriggered)
{
SecondPhaseSequenceState.SequenceTriggered = true;
((MonoBehaviour)__instance).StartCoroutine(RunLaunchSequence(__instance));
}
}
private static IEnumerator RunLaunchSequence(BowheadWhale whale)
{
Vector3 position = ((Component)whale).transform.position;
Vector3 targetPos = (SecondPhaseSequenceState.TargetPosition = ComputeOpenWaterTarget(position));
foreach (Player alivePlayer in PlayerManager.AlivePlayers)
{
alivePlayer.ScreenShake.ConstantShake(true);
}
yield return null;
LaunchAllPlayers(targetPos);
LaunchBoatToFollow(targetPos);
while (SecondPhaseSequenceState.FlyingPlayers.Count > 0)
{
yield return null;
}
SnapBoatAndPlayersToLanding(targetPos);
foreach (Player alivePlayer2 in PlayerManager.AlivePlayers)
{
alivePlayer2.ScreenShake.ConstantShake(false);
}
SecondPhaseWhaleFollowPatch.BeginFollow(whale, BoatManager.Boat);
}
private static Vector3 ComputeOpenWaterTarget(Vector3 whalePos)
{
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
int totalIslands = IslandManager.TotalIslands;
if (totalIslands <= 0)
{
Vector3 val = whalePos - Island.IslandPos;
Vector3 val2;
if (!(((Vector3)(ref val)).sqrMagnitude > 1f))
{
val2 = Vector3.forward;
}
else
{
val = whalePos - Island.IslandPos;
val2 = ((Vector3)(ref val)).normalized;
}
Vector3 val3 = val2;
Vector3 result = Island.IslandPos + val3 * (Island.IslandSize * 4f);
result.y = WaterManager.WaterHeight;
return result;
}
Vector3 val4 = Vector3.zero;
int num = 0;
for (int i = 0; i < totalIslands; i++)
{
IslandInfo islandInfo;
try
{
islandInfo = IslandManager.GetIslandInfo(i);
}
catch
{
continue;
}
if (islandInfo != null)
{
val4 += islandInfo.IslandPosition;
num++;
}
}
Vector3 result2 = ((num > 0) ? (val4 / (float)num) : Island.IslandPos);
result2.y = WaterManager.WaterHeight;
return result2;
}
private static void LaunchAllPlayers(Vector3 targetPos)
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
foreach (Player alivePlayer in PlayerManager.AlivePlayers)
{
Vector3 position = alivePlayer.Transform.position;
Vector3 val = targetPos + Vector3.up * 25f;
float num = Vector3.Distance(position, val);
float num2 = Mathf.Max(3.5f, num / 40f);
float gravity = GetGravity(alivePlayer.Movement);
Vector3 linearVelocity = BallisticUtils.SolveVelocityForFlightTime(position, val, num2, gravity);
Rigidbody rigidbody = alivePlayer.Rigidbody;
if ((Object)(object)rigidbody != (Object)null)
{
rigidbody.linearVelocity = linearVelocity;
}
SecondPhaseSequenceState.FlyingPlayers.Add(alivePlayer);
SecondPhaseSequenceState.LaunchTime[alivePlayer] = Time.time;
SecondPhaseSequenceState.FlightDuration[alivePlayer] = num2;
}
SecondPhaseSequenceState.PlayersAirborne = true;
}
private static void LaunchBoatToFollow(Vector3 targetPos)
{
Boat boat = BoatManager.Boat;
if (!((Object)(object)boat == (Object)null))
{
boat.HiddenPhysicsRig.isKinematic = true;
}
}
[HarmonyPatch(typeof(PlayerMovement), "Move")]
[HarmonyPrefix]
private static bool BeforeMove(PlayerMovement __instance)
{
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
object? value = PlayerField.GetValue(__instance);
Player val = (Player)((value is Player) ? value : null);
if ((Object)(object)val == (Object)null || !SecondPhaseSequenceState.FlyingPlayers.Contains(val))
{
return true;
}
object? value2 = RigField.GetValue(__instance);
Rigidbody val2 = (Rigidbody)((value2 is Rigidbody) ? value2 : null);
if ((Object)(object)val2 == (Object)null)
{
return true;
}
val2.linearVelocity += Vector3.down * (GetGravity(__instance) * Time.fixedDeltaTime);
TryLandPlayer(val, val2);
return false;
}
private static void TryLandPlayer(Player player, Rigidbody rig)
{
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
Boat boat = BoatManager.Boat;
if (!((Object)(object)boat == (Object)null))
{
FollowPlayersWithBoat(boat);
float value;
float num = (SecondPhaseSequenceState.LaunchTime.TryGetValue(player, out value) ? value : Time.time);
float value2;
float num2 = (SecondPhaseSequenceState.FlightDuration.TryGetValue(player, out value2) ? value2 : 3.5f);
bool num3 = Time.time - num >= num2 + 1.5f;
Vector3 val = rig.position - boat.HiddenPhysicsRig.position;
bool flag = ((Vector3)(ref val)).sqrMagnitude <= 100f && rig.position.y <= boat.HiddenPhysicsRig.position.y + 3f;
if (num3 || flag)
{
SecondPhaseSequenceState.FlyingPlayers.Remove(player);
rig.linearVelocity = Vector3.zero;
}
}
}
private static void FollowPlayersWithBoat(Boat boat)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
Vector3 val = Vector3.zero;
int num = 0;
foreach (Player flyingPlayer in SecondPhaseSequenceState.FlyingPlayers)
{
val += flyingPlayer.Transform.position;
num++;
}
if (num != 0)
{
Vector3 val2 = val / (float)num;
Vector3 val3 = default(Vector3);
((Vector3)(ref val3))..ctor(val2.x, WaterManager.WaterHeight, val2.z);
boat.HiddenPhysicsRig.MovePosition(val3);
}
}
private static void SnapBoatAndPlayersToLanding(Vector3 targetPos)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
Boat boat = BoatManager.Boat;
if ((Object)(object)boat != (Object)null)
{
Vector3 val = default(Vector3);
((Vector3)(ref val))..ctor(targetPos.x, WaterManager.WaterHeight, targetPos.z);
boat.HiddenPhysicsRig.MovePosition(val);
boat.HiddenPhysicsRig.isKinematic = false;
}
SecondPhaseSequenceState.PlayersAirborne = false;
}
}
internal static class SecondPhaseSequenceState
{
public static bool SequenceTriggered;
public static bool PlayersAirborne;
public static Vector3 TargetPosition;
public static readonly HashSet<Player> FlyingPlayers = new HashSet<Player>();
public static readonly Dictionary<Player, float> LaunchTime = new Dictionary<Player, float>();
public static readonly Dictionary<Player, float> FlightDuration = new Dictionary<Player, float>();
public static void Reset()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
SequenceTriggered = false;
PlayersAirborne = false;
TargetPosition = Vector3.zero;
FlyingPlayers.Clear();
LaunchTime.Clear();
FlightDuration.Clear();
}
}
[HarmonyPatch(typeof(BowheadWhale))]
internal static class SecondPhaseTargetPriorityPatch
{
private const int LethalDamage = 99999;
private static readonly FieldInfo TargetField = AccessTools.Field(typeof(AttackingFish), "_target");
private static Player _priorityTarget;
[HarmonyPatch("UpdateMovement")]
[HarmonyPostfix]
private static void AfterUpdateMovement(BowheadWhale __instance)
{
if (!BowheadWhaleAccess.IsSecondPhaseActive() || !((NetworkBehaviour)__instance).IsServerInitialized)
{
_priorityTarget = null;
return;
}
Player val = (_priorityTarget = FindPlayerInWater());
if ((Object)(object)val != (Object)null)
{
TargetField.SetValue(__instance, val);
}
}
private static Player FindPlayerInWater()
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
foreach (Player alivePlayer in PlayerManager.AlivePlayers)
{
bool num = (Object)(object)alivePlayer.Movement != (Object)null && alivePlayer.Movement.OnBoat;
bool flag = alivePlayer.Transform.position.y <= WaterManager.WaterHeight;
if (!num && flag)
{
return alivePlayer;
}
}
return null;
}
[HarmonyPatch("DamageOnCollision")]
[HarmonyPrefix]
private static bool BeforeDamageOnCollision(BowheadWhale __instance, Player player, Vector3 pos)
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
if (!BowheadWhaleAccess.IsSecondPhaseActive() || (Object)(object)_priorityTarget == (Object)null || (Object)(object)player != (Object)(object)_priorityTarget)
{
return true;
}
Server.Instance.HitPlayer(player, 99999, Vector3.zero, pos, (byte)2, (Player)null);
return false;
}
}
[HarmonyPatch(typeof(BowheadWhale))]
internal static class SecondPhaseWhaleFollowPatch
{
private const float RoarShakeDuration = 3f;
private const float BowOffsetDistance = 20f;
private const float MinFlightTime = 2.5f;
private const float SpeedCap = 60f;
private static readonly FieldInfo RigField = AccessTools.Field(typeof(Item), "_rig");
private static readonly FieldInfo JumpsLeftField = AccessTools.Field(typeof(BowheadWhale), "_jumpsLeft");
private static readonly FieldInfo AddedFlyingGravity2Field = AccessTools.Field(typeof(BowheadWhale), "_addedFlyingGravity2");
private static readonly MethodInfo FlyMethod = AccessTools.Method(typeof(BowheadWhale), "Fly", (Type[])null, (Type[])null);
private static readonly MethodInfo MakeNoiseSoundMethod = AccessTools.Method(typeof(BowheadWhale), "MakeNoiseSound", (Type[])null, (Type[])null);
private static float GetGravity(BowheadWhale whale)
{
return (float)AddedFlyingGravity2Field.GetValue(whale);
}
public static void BeginFollow(BowheadWhale whale, Boat boat)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
SecondPhaseWhaleFollowState secondPhaseWhaleFollowState = SecondPhaseWhaleFollowState.Get(whale);
Vector3 val = ComputeBowTarget(whale, boat);
secondPhaseWhaleFollowState.Active = true;
secondPhaseWhaleFollowState.HasSurfaced = false;
secondPhaseWhaleFollowState.TargetPosition = val;
secondPhaseWhaleFollowState.IsDescending = false;
object? value = RigField.GetValue(whale);
Rigidbody val2 = (Rigidbody)((value is Rigidbody) ? value : null);
Vector3 val3 = (((Object)(object)val2 != (Object)null) ? val2.worldCenterOfMass : ((Component)whale).transform.position);
float num = Vector3.Distance(val3, val);
float flightTime = Mathf.Max(2.5f, num / 60f);
Vector3 linearVelocity = BallisticUtils.SolveVelocityForFlightTime(val3, val, flightTime, GetGravity(whale));
JumpsLeftField.SetValue(whale, 1);
FlyMethod.Invoke(whale, null);
if ((Object)(object)val2 != (Object)null)
{
val2.linearVelocity = linearVelocity;
}
}
private static Vector3 ComputeBowTarget(BowheadWhale whale, Boat boat)
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
Vector3 val = (((Object)(object)boat != (Object)null && (Object)(object)boat.VisualBoat != (Object)null) ? boat.VisualBoat.forward : Vector3.forward);
Vector3 result = (((Object)(object)boat != (Object)null && (Object)(object)boat.VisualBoat != (Object)null) ? boat.VisualBoat.position : ((Component)whale).transform.position) + val * 20f;
result.y = WaterManager.WaterHeight;
return result;
}
[HarmonyPatch("InitializeMovement")]
[HarmonyPrefix]
private static bool BeforeInitializeMovement(BowheadWhale __instance)
{
return !SecondPhaseWhaleFollowState.Get(__instance).Active;
}
[HarmonyPatch("SetFlying")]
[HarmonyPrefix]
private static bool BeforeSetFlying(BowheadWhale __instance)
{
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_00be: Unknown result type (might be due to invalid IL or missing references)
SecondPhaseWhaleFollowState secondPhaseWhaleFollowState = SecondPhaseWhaleFollowState.Get(__instance);
if (!secondPhaseWhaleFollowState.Active || secondPhaseWhaleFollowState.HasSurfaced)
{
return true;
}
object? value = RigField.GetValue(__instance);
Rigidbody val = (Rigidbody)((value is Rigidbody) ? value : null);
if ((Object)(object)val == (Object)null)
{
return true;
}
Vector3 linearVelocity = val.linearVelocity;
linearVelocity.y -= GetGravity(__instance) * Time.fixedDeltaTime;
val.linearVelocity = linearVelocity;
if (!(val.worldCenterOfMass.y <= WaterManager.WaterHeight) || !(linearVelocity.y < -1f))
{
secondPhaseWhaleFollowState.IsDescending = false;
return false;
}
if (!secondPhaseWhaleFollowState.IsDescending)
{
secondPhaseWhaleFollowState.IsDescending = true;
secondPhaseWhaleFollowState.DescendStartTime = Time.time;
return false;
}
if (Time.time - secondPhaseWhaleFollowState.DescendStartTime >= 0.6f)
{
secondPhaseWhaleFollowState.HasSurfaced = true;
PlaySplashBurst(val.position, 6, 5f);
JumpsLeftField.SetValue(__instance, 1);
FlyMethod.Invoke(__instance, null);
((MonoBehaviour)__instance).StartCoroutine(RoarAfterSurfacing(__instance, val));
}
return false;
}
private static IEnumerator RoarAfterSurfacing(BowheadWhale whale, Rigidbody rig)
{
foreach (Player alivePlayer in PlayerManager.AlivePlayers)
{
alivePlayer.ScreenShake.ConstantShake(true);
}
MakeNoiseSoundMethod.Invoke(whale, new object[1] { true });
PlaySplashBurst(new Vector3(rig.position.x, WaterManager.WaterHeight, rig.position.z), 14, 9f);
yield return (object)new WaitForSeconds(3f);
foreach (Player alivePlayer2 in PlayerManager.AlivePlayers)
{
alivePlayer2.ScreenShake.ConstantShake(false);
}
SecondPhaseWhaleFollowState.Get(whale).Active = false;
}
private static void PlaySplashBurst(Vector3 center, int count, float radius)
{
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
for (int i = 0; i < count; i++)
{
Vector3 val = Random.insideUnitSphere * radius;
val.y = 0f;
Vector3 val2 = center + val;
val2.y = WaterManager.WaterHeight;
VFXManager.Play("WaterSplash", val2, Vector3.zero);
}
}
}
internal sealed class SecondPhaseWhaleFollowState
{
public bool Active;
public bool HasSurfaced;
public Vector3 TargetPosition;
public bool IsDescending;
public float DescendStartTime = -1f;
private static readonly ConditionalWeakTable<BowheadWhale, SecondPhaseWhaleFollowState> States = new ConditionalWeakTable<BowheadWhale, SecondPhaseWhaleFollowState>();
public static SecondPhaseWhaleFollowState Get(BowheadWhale whale)
{
return States.GetOrCreateValue(whale);
}
}
[HarmonyPatch(typeof(BowheadWhale))]
internal static class ThirdPhasePatch
{
private const float ThirdPhaseHpThreshold = 0.1f;
private const float FleeArrivalDistance = 4f;
private static readonly FieldInfo RigField = AccessTools.Field(typeof(Item), "_rig");
private static readonly FieldInfo IsFlyingField = AccessTools.Field(typeof(BowheadWhale), "_isFlying");
private static readonly FieldInfo IsShootingLavaField = AccessTools.Field(typeof(BowheadWhale), "_isShootingLava");
private static readonly FieldInfo ShootLavaChanceField = AccessTools.Field(typeof(BowheadWhale), "_shootLavaChance");
private static readonly FieldInfo LavaCountField = AccessTools.Field(typeof(BowheadWhale), "_lavaCount");
private static readonly FieldInfo JumpsLeftField = AccessTools.Field(typeof(BowheadWhale), "_jumpsLeft");
private static readonly FieldInfo FlyForceTowardsPlayerField = AccessTools.Field(typeof(BowheadWhale), "_flyForceTowardsPlayer");
private static readonly MethodInfo ShootLavaMethod = AccessTools.Method(typeof(BowheadWhale), "ShootLava", (Type[])null, (Type[])null);
private static readonly MethodInfo FlyMethod = AccessTools.Method(typeof(BowheadWhale), "Fly", (Type[])null, (Type[])null);
private static readonly MethodInfo OnLandedMethod = AccessTools.Method(typeof(BowheadWhale), "OnLanded", (Type[])null, (Type[])null);
private const float MaxFallSeconds = 4f;
[HarmonyPatch("Awake")]
[HarmonyPostfix]
private static void AfterAwake(BowheadWhale __instance)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
ThirdPhaseState thirdPhaseState = ThirdPhaseState.Get(__instance);
if (!thirdPhaseState.SpawnPositionCaptured)
{
thirdPhaseState.SpawnPosition = ((Component)__instance).transform.position;
thirdPhaseState.SpawnPositionCaptured = true;
}
}
[HarmonyPatch("OnHealthChange")]
[HarmonyPostfix]
private static void AfterHealthChange(BowheadWhale __instance, int next, bool asServer)
{
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Invalid comparison between Unknown and I4
if (!asServer || (int)((Creature)__instance).BossType != 2)
{
return;
}
ThirdPhaseState thirdPhaseState = ThirdPhaseState.Get(__instance);
if (!thirdPhaseState.PhaseActive && !thirdPhaseState.Resolved)
{
float num = (float)next / (float)BossManager.BossMaxHp;
if (num > 0f && num <= 0.1f)
{
thirdPhaseState.PhaseActive = true;
JumpsLeftField.SetValue(__instance, 1);
}
}
}
[HarmonyPatch("InitializeMovement")]
[HarmonyPrefix]
private static bool BeforeInitializeMovement(BowheadWhale __instance)
{
ThirdPhaseState thirdPhaseState = ThirdPhaseState.Get(__instance);
if (!thirdPhaseState.PhaseActive || thirdPhaseState.Resolved)
{
return true;
}
if (!(bool)IsFlyingField.GetValue(__instance))
{
JumpsLeftField.SetValue(__instance, 1);
FlyMethod.Invoke(__instance, null);
}
if (!(bool)IsShootingLavaField.GetValue(__instance))
{
float num = (float)ShootLavaChanceField.GetValue(__instance);
if (Random.Range(0f, 1f) <= num)
{
int num2 = (int)LavaCountField.GetValue(__instance);
((MonoBehaviour)__instance).StartCoroutine((IEnumerator)ShootLavaMethod.Invoke(__instance, new object[1] { num2 }));
}
}
return false;
}
[HarmonyPatch("UpdateMovement")]
[HarmonyPostfix]
private static void AfterUpdateMovement(BowheadWhale __instance)
{
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_0119: Unknown result type (might be due to invalid IL or missing references)
//IL_011c: Unknown result type (might be due to invalid IL or missing references)
//IL_0123: Unknown result type (might be due to invalid IL or missing references)
//IL_012a: Unknown result type (might be due to invalid IL or missing references)
//IL_0131: Unknown result type (might be due to invalid IL or missing references)
ThirdPhaseState thirdPhaseState = ThirdPhaseState.Get(__instance);
if (!thirdPhaseState.PhaseActive || thirdPhaseState.Resolved || !thirdPhaseState.SpawnPositionCaptured || !((NetworkBehaviour)__instance).IsServerInitialized)
{
return;
}
object? value = RigField.GetValue(__instance);
Rigidbody val = (Rigidbody)((value is Rigidbody) ? value : null);
if ((Object)(object)val == (Object)null)
{
return;
}
Vector3 val2 = thirdPhaseState.SpawnPosition - val.worldCenterOfMass;
val2.y = 0f;
float magnitude = ((Vector3)(ref val2)).magnitude;
Vector3 val3 = thirdPhaseState.SpawnPosition - val.worldCenterOfMass;
if (((Vector3)(ref val3)).magnitude <= 4f)
{
thirdPhaseState.Resolved = true;
((NetworkBehaviour)__instance).Despawn(((Component)__instance).gameObject, (DespawnType?)null);
}
else if ((bool)IsFlyingField.GetValue(__instance) && !(magnitude < 0.01f))
{
Vector3 val4 = val2 / magnitude;
Vector3 linearVelocity = val.linearVelocity;
Vector2 val5 = new Vector2(linearVelocity.x, linearVelocity.z);
float num = ((Vector2)(ref val5)).magnitude;
float num2 = (float)FlyForceTowardsPlayerField.GetValue(__instance) * 0.5f;
if (num < num2)
{
num = num2;
}
Vector3 val6 = val4 * num;
val.linearVelocity = new Vector3(val6.x, linearVelocity.y, val6.z);
}
}
[HarmonyPatch("SetFlying")]
[HarmonyPostfix]
private static void AfterSetFlying(BowheadWhale __instance)
{
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
ThirdPhaseState thirdPhaseState = ThirdPhaseState.Get(__instance);
if (!thirdPhaseState.PhaseActive || thirdPhaseState.Resolved)
{
return;
}
if (!(bool)IsFlyingField.GetValue(__instance))
{
thirdPhaseState.IsDescending = false;
return;
}
object? value = RigField.GetValue(__instance);
Rigidbody val = (Rigidbody)((value is Rigidbody) ? value : null);
if (!((Object)(object)val == (Object)null))
{
if (!(val.linearVelocity.y < -1f))
{
thirdPhaseState.IsDescending = false;
}
else if (!thirdPhaseState.IsDescending)
{
thirdPhaseState.IsDescending = true;
thirdPhaseState.DescendStartTime = Time.time;
}
else if (Time.time - thirdPhaseState.DescendStartTime >= 4f)
{
thirdPhaseState.IsDescending = false;
OnLandedMethod.Invoke(__instance, null);
}
}
}
[HarmonyPatch("OnLanded")]
[HarmonyPostfix]
private static void AfterOnLanded(BowheadWhale __instance)
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
ThirdPhaseState thirdPhaseState = ThirdPhaseState.Get(__instance);
if (!thirdPhaseState.PhaseActive || thirdPhaseState.Resolved)
{
return;
}
Vector3 position = ((Component)__instance).transform.position;
if (!(position.y > WaterManager.WaterHeight + 1f))
{
for (int i = 0; i < 6; i++)
{
Vector3 val = Random.insideUnitSphere * 4f;
val.y = 0f;
Vector3 val2 = position + val;
val2.y = WaterManager.WaterHeight;
VFXManager.Play("WaterSplash", val2, Vector3.zero);
}
}
}
}
internal sealed class ThirdPhaseState
{
public Vector3 SpawnPosition;
public bool SpawnPositionCaptured;
public bool PhaseActive;
public bool Resolved;
public bool IsDescending;
public float DescendStartTime = -1f;
private static readonly ConditionalWeakTable<BowheadWhale, ThirdPhaseState> States = new ConditionalWeakTable<BowheadWhale, ThirdPhaseState>();
public static ThirdPhaseState Get(BowheadWhale whale)
{
return States.GetOrCreateValue(whale);
}
}
}