using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("GordionRescue")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("GordionRescue")]
[assembly: AssemblyTitle("GordionRescue")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
}
[BepInPlugin("POTATOH.GordionVoidRescue", "Gordion Void Rescue", "1.3.1")]
public class GordionVoidRescue : BaseUnityPlugin
{
[HarmonyPatch(typeof(PlayerControllerB), "Update")]
private static class PlayerUpdatePatch
{
private static readonly Dictionary<ulong, float> Cooldowns = new Dictionary<ulong, float>();
private static readonly Dictionary<ulong, float> LastRescueTime = new Dictionary<ulong, float>();
private static readonly Dictionary<ulong, int> RescueStreak = new Dictionary<ulong, int>();
private static void Postfix(PlayerControllerB __instance)
{
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)__instance == (Object)null || !__instance.isPlayerControlled || __instance.isPlayerDead || !((NetworkBehaviour)__instance).IsOwner || (OnlyOnGordion.Value && !IsGordionSafe()))
{
return;
}
ulong actualClientId = __instance.actualClientId;
float time = Time.time;
if (Cooldowns.TryGetValue(actualClientId, out var value) && time < value)
{
return;
}
float y = ((Component)__instance).transform.position.y;
if (y >= YThreshold.Value)
{
return;
}
if (AlwaysRescueToShip.Value)
{
RescueToShip(__instance, y);
RescueStreak[actualClientId] = 0;
LastRescueTime[actualClientId] = time;
Cooldowns[actualClientId] = time + CooldownSeconds.Value;
return;
}
int num = 1;
if (LastRescueTime.TryGetValue(actualClientId, out var value2))
{
num = ((!(time - value2 <= ShipRescueWindowSeconds.Value)) ? 1 : (((!RescueStreak.TryGetValue(actualClientId, out var value3)) ? 1 : value3) + 1));
}
LastRescueTime[actualClientId] = time;
RescueStreak[actualClientId] = num;
if (num >= ShipRescueAfterStreak.Value)
{
RescueToShip(__instance, y);
RescueStreak[actualClientId] = 0;
}
else
{
RescueLift(__instance, y);
}
Cooldowns[actualClientId] = time + CooldownSeconds.Value;
}
}
internal static GordionVoidRescue Instance;
internal static ConfigEntry<float> YThreshold;
internal static ConfigEntry<float> RescueY;
internal static ConfigEntry<float> CooldownSeconds;
internal static ConfigEntry<bool> OnlyOnGordion;
internal static ConfigEntry<bool> DebugLog;
internal static ConfigEntry<bool> AlwaysRescueToShip;
internal static ConfigEntry<int> ShipRescueAfterStreak;
internal static ConfigEntry<float> ShipRescueWindowSeconds;
internal static ConfigEntry<float> ShipX;
internal static ConfigEntry<float> ShipY;
internal static ConfigEntry<float> ShipZ;
private void Awake()
{
//IL_0187: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
YThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("General", "YThreshold", -17f, "If player Y goes below this value, they will be rescued.");
RescueY = ((BaseUnityPlugin)this).Config.Bind<float>("General", "RescueY", 3.5f, "Target Y to move player to (keeps X/Z) for normal rescues (used only when AlwaysRescueToShip=false).");
CooldownSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "CooldownSeconds", 0.5f, "Cooldown between rescues per-player (seconds). Keep small so it can react fast.");
OnlyOnGordion = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "OnlyOnGordion", true, "If true, rescue only works on Company/Gordion.");
DebugLog = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DebugLog", false, "If true, logs rescues.");
AlwaysRescueToShip = ((BaseUnityPlugin)this).Config.Bind<bool>("ShipRescue", "AlwaysRescueToShip", true, "If true (default), any rescue immediately teleports you to ship coords. If false, uses lift+streak logic.");
ShipRescueAfterStreak = ((BaseUnityPlugin)this).Config.Bind<int>("ShipRescue", "ShipRescueAfterStreak", 3, "If rescues happen this many times within ShipRescueWindowSeconds, teleport to ship coords (when AlwaysRescueToShip=false).");
ShipRescueWindowSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("ShipRescue", "ShipRescueWindowSeconds", 2f, "Time window for the rescue streak check (when AlwaysRescueToShip=false).");
ShipX = ((BaseUnityPlugin)this).Config.Bind<float>("ShipRescue", "ShipX", -8f, "Ship teleport X (Gordion).");
ShipY = ((BaseUnityPlugin)this).Config.Bind<float>("ShipRescue", "ShipY", 0f, "Ship teleport Y (Gordion).");
ShipZ = ((BaseUnityPlugin)this).Config.Bind<float>("ShipRescue", "ShipZ", -14f, "Ship teleport Z (Gordion).");
new Harmony("POTATOH.GordionVoidRescue").PatchAll();
((BaseUnityPlugin)this).Logger.LogInfo((object)($"GVR 1.3.1 loaded. YThreshold={YThreshold.Value}, OnlyOnGordion={OnlyOnGordion.Value}, " + $"AlwaysRescueToShip={AlwaysRescueToShip.Value}, ShipPos=({ShipX.Value},{ShipY.Value},{ShipZ.Value})"));
}
internal static bool IsGordionSafe()
{
SelectableLevel val = StartOfRound.Instance?.currentLevel;
if ((Object)(object)val == (Object)null)
{
return true;
}
string text = (val.PlanetName ?? "").ToLowerInvariant();
if (!text.Contains("gordion"))
{
return text.Contains("company");
}
return true;
}
internal static Vector3 GetShipPosFallback()
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
return new Vector3(ShipX.Value, ShipY.Value, ShipZ.Value);
}
internal static void RescueLift(PlayerControllerB p, float fromY)
{
//IL_0006: 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_001e: 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_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
Vector3 position = ((Component)p).transform.position;
position.y = RescueY.Value;
HardMoveAndWake(p, position);
if (DebugLog.Value && (Object)(object)Instance != (Object)null)
{
ManualLogSource logger = ((BaseUnityPlugin)Instance).Logger;
object[] obj = new object[4] { p.playerUsername, fromY, position.y, null };
Scene activeScene = SceneManager.GetActiveScene();
obj[3] = ((Scene)(ref activeScene)).name;
logger.LogInfo((object)string.Format("[RescueLift] {0} y={1:F1} -> {2:F1} scene={3}", obj));
}
}
internal static void RescueToShip(PlayerControllerB p, float fromY)
{
//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_0015: 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_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
Vector3 shipPosFallback = GetShipPosFallback();
p.isInsideFactory = false;
p.isInHangarShipRoom = true;
try
{
p.TeleportPlayer(shipPosFallback, true, 0f, false, true);
}
catch
{
}
HardMoveAndWake(p, shipPosFallback);
if (DebugLog.Value && (Object)(object)Instance != (Object)null)
{
ManualLogSource logger = ((BaseUnityPlugin)Instance).Logger;
object[] obj2 = new object[6] { p.playerUsername, fromY, shipPosFallback.x, shipPosFallback.y, shipPosFallback.z, null };
Scene activeScene = SceneManager.GetActiveScene();
obj2[5] = ((Scene)(ref activeScene)).name;
logger.LogInfo((object)string.Format("[RescueShip] {0} y={1:F1} -> ship({2:F1},{3:F1},{4:F1}) scene={5}", obj2));
}
}
internal static void HardMoveAndWake(PlayerControllerB p, Vector3 pos)
{
//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)
//IL_006a: 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)
//IL_004e: 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_005d: Unknown result type (might be due to invalid IL or missing references)
p.averageVelocity = 0f;
p.velocityLastFrame = Vector3.zero;
if ((Object)(object)p.thisController != (Object)null)
{
((Collider)p.thisController).enabled = false;
((Component)p).transform.position = pos;
((Collider)p.thisController).enabled = true;
p.thisController.Move(Vector3.down * 0.2f);
}
else
{
((Component)p).transform.position = pos;
}
}
}