using System;
using System.Collections;
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 HarmonyLib;
using LifeSaver.LifeRing;
using Microsoft.CodeAnalysis;
using Steamworks;
using UnityEngine;
using UnityEngine.Networking;
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("LifeSaver")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0")]
[assembly: AssemblyProduct("LifeSaver")]
[assembly: AssemblyTitle("LifeSaver")]
[assembly: AssemblyVersion("0.1.0.0")]
[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 LifeSaver
{
[BepInPlugin("0cahlo.howtofish.lifesaver", "LifeSaver", "0.1.0")]
public class Plugin : BaseUnityPlugin
{
public const string PluginGuid = "0cahlo.howtofish.lifesaver";
public const string PluginName = "LifeSaver";
public const string PluginVersion = "0.1.0";
internal static ManualLogSource Log;
internal static Plugin Instance;
private Harmony _harmony;
private void Awake()
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Expected O, but got Unknown
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
Settings.Bind(((BaseUnityPlugin)this).Config);
_harmony = new Harmony("0cahlo.howtofish.lifesaver");
_harmony.PatchAll();
LifeRingSceneProps.Hook();
Log.LogInfo((object)"LifeSaver 0.1.0 loaded.");
}
private void Update()
{
//IL_0005: 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)
KeyboardShortcut value = Settings.Dev.ReloadShopProps.Value;
if (((KeyboardShortcut)(ref value)).IsDown())
{
LifeRingSceneProps.Reload();
}
}
}
internal readonly struct DevSetting<T>
{
private readonly T _fixedValue;
public T Value => _fixedValue;
public DevSetting(T fixedValue)
{
_fixedValue = fixedValue;
}
}
internal static class Settings
{
internal static class Dev
{
public static DevSetting<float> HeadClearance;
public static DevSetting<float> RiseSpeed;
public static DevSetting<float> Stiffness;
public static DevSetting<int> SwimJumpsAllowed;
public static DevSetting<float> Lift;
public static DevSetting<float> MajorRadius;
public static DevSetting<float> TubeRadius;
public static DevSetting<int> Segments;
public static DevSetting<int> TubeSides;
public static DevSetting<int> Bands;
public static DevSetting<float> LevelSpeed;
public static DevSetting<KeyboardShortcut> ReloadShopProps;
public static DevSetting<float> SettleSeconds;
public static DevSetting<float> LeanDegrees;
public static LifeRingModel.RingShape RingShape()
{
return new LifeRingModel.RingShape(Lift.Value, MajorRadius.Value, TubeRadius.Value, Segments.Value, TubeSides.Value, Bands.Value);
}
public static void Bind(ConfigFile config)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Expected O, but got Unknown
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Expected O, but got Unknown
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Expected O, but got Unknown
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Expected O, but got Unknown
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_010f: Expected O, but got Unknown
//IL_013e: Unknown result type (might be due to invalid IL or missing references)
//IL_0148: Expected O, but got Unknown
//IL_0177: Unknown result type (might be due to invalid IL or missing references)
//IL_0181: Expected O, but got Unknown
//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
//IL_01b6: Expected O, but got Unknown
//IL_01de: Unknown result type (might be due to invalid IL or missing references)
//IL_01e8: Expected O, but got Unknown
//IL_0213: Unknown result type (might be due to invalid IL or missing references)
//IL_021d: Expected O, but got Unknown
//IL_024b: Unknown result type (might be due to invalid IL or missing references)
//IL_0255: Expected O, but got Unknown
//IL_0265: Unknown result type (might be due to invalid IL or missing references)
//IL_0275: Unknown result type (might be due to invalid IL or missing references)
//IL_027f: Expected O, but got Unknown
//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
//IL_02b7: Expected O, but got Unknown
//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
//IL_02ef: Expected O, but got Unknown
HeadClearance = Setting(config, "Floating", "HeadClearance", 0.3f, new ConfigDescription("How far above the water (metres) the life ring holds your eyes.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
RiseSpeed = Setting(config, "Floating", "RiseSpeed", 3f, new ConfigDescription("Fastest the life ring pulls you up to the surface (m/s).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 10f), Array.Empty<object>()));
Stiffness = Setting(config, "Floating", "Stiffness", 4f, new ConfigDescription("How firmly you are held at the float height: higher settles faster, lower bobs more.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 20f), Array.Empty<object>()));
SwimJumpsAllowed = Setting(config, "Swimming", "SwimJumpsAllowed", 5, new ConfigDescription("Full-strength jumps allowed in open water before touching land or a boat again. After that every jump is weaker, you sink, and a submerged head starts taking damage. The game's own value is 5.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
LifeRingModel.RingShape ringShape = LifeRingModel.RingShape.Default;
Lift = Setting(config, "LifeRing", "Lift", ringShape.Lift, new ConfigDescription("How far above the item's root the ring sits (metres). A floating item's root settles 0.15 m under the surface. The grip and held position follow it.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-0.5f, 0.5f), Array.Empty<object>()));
MajorRadius = Setting(config, "LifeRing", "MajorRadius", ringShape.MajorRadius, new ConfigDescription("Radius of the ring's centre line (metres). Hole radius = MajorRadius - TubeRadius; the player capsule's is 0.375.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 2f), Array.Empty<object>()));
TubeRadius = Setting(config, "LifeRing", "TubeRadius", ringShape.TubeRadius, new ConfigDescription("Radius of the ring's tube (metres).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 0.5f), Array.Empty<object>()));
Segments = Setting(config, "LifeRing", "Segments", ringShape.Segments, new ConfigDescription("Faces around the ring.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(3, 128), Array.Empty<object>()));
TubeSides = Setting(config, "LifeRing", "TubeSides", ringShape.TubeSides, new ConfigDescription("Faces around the tube.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(3, 32), Array.Empty<object>()));
Bands = Setting(config, "LifeRing", "Bands", ringShape.Bands, new ConfigDescription("Alternating red and white colour bands. Keep it even and a divisor of Segments for equal bands.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 128), Array.Empty<object>()));
LevelSpeed = Setting(config, "LifeRing", "LevelSpeed", 4f, new ConfigDescription("How quickly a ring in the water levels out flat (fraction of the remaining tilt per second). Applies at once.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 50f), Array.Empty<object>()));
ReloadShopProps = Setting<KeyboardShortcut>(config, "LifeRingShop", "ReloadHotkey", KeyboardShortcut.Empty, new ConfigDescription("Reloads the Badball props in the loaded island: they get the current ring shape, and the shop's display ring is put back where the scene had the ball and dropped again.", (AcceptableValueBase)null, Array.Empty<object>()));
SettleSeconds = Setting(config, "LifeRingShop", "SettleSeconds", 3f, new ConfigDescription("How long the shop's display ring falls under physics before it is frozen in place.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 30f), Array.Empty<object>()));
LeanDegrees = Setting(config, "LifeRingShop", "LeanDegrees", 43.777f, new ConfigDescription("How far from upright the shop's display ring starts its fall, so it tips over or leans instead of balancing on its rim.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 90f), Array.Empty<object>()));
}
private static DevSetting<T> Setting<T>(ConfigFile config, string section, string key, T defaultValue, ConfigDescription description)
{
return new DevSetting<T>(defaultValue);
}
}
public static ConfigEntry<bool> FloatEnabled;
public static ConfigEntry<bool> Reskin;
public static void Bind(ConfigFile config)
{
FloatEnabled = config.Bind<bool>("Floating", "Enabled", true, "Holding a Badball (life ring) in the water keeps your head above the surface and refills your swim jumps.");
Reskin = config.Bind<bool>("LifeRing", "Reskin", true, "Show Badballs as a red-and-white life ring. Looks only, on your screen only: players without the mod still see a Badball, and the item stays a Badball in saves.");
Dev.Bind(config);
}
}
}
namespace LifeSaver.LifeRing
{
[HarmonyPatch]
internal static class LifeRingFloatPatch
{
private static readonly FieldRef<HashSet<Item>> ItemsUnderwaterRef = AccessTools.StaticFieldRefAccess<HashSet<Item>>(AccessTools.Field(typeof(ItemManager), "_itemsUnderwater"));
private static float LevelSpeed => Settings.Dev.LevelSpeed.Value;
[HarmonyPatch(typeof(ItemManager), "FloatItems")]
[HarmonyPostfix]
private static void LevelMoving()
{
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: 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_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
if (!LifeRingSpawnPatch.ReskinOn)
{
return;
}
HashSet<Item> hashSet = ItemsUnderwaterRef.Invoke();
if (hashSet == null)
{
return;
}
foreach (Item item in hashSet)
{
if (Object.op_Implicit((Object)(object)item) && !Object.op_Implicit((Object)(object)item.Holder) && LifeRingItem.IsLifeRing(item))
{
Rigidbody rig = item.Rig;
if (!((Object)(object)rig == (Object)null) && !rig.isKinematic && item.RigidbodySync.IsSimulatedLocal && WaterManager.GetWaterInfo(rig.position).Key)
{
Vector3 angularVelocity = rig.angularVelocity;
rig.angularVelocity = Vector3.up * angularVelocity.y;
Level(rig);
}
}
}
}
[HarmonyPatch(typeof(ItemManager), "FloatKinematicItem")]
[HarmonyPostfix]
private static void LevelResting(Item item)
{
if (LifeRingSpawnPatch.ReskinOn && LifeRingItem.IsLifeRing(item))
{
Rigidbody rig = item.Rig;
if ((Object)(object)rig != (Object)null && rig.isKinematic)
{
Level(rig);
}
}
}
private static void Level(Rigidbody rig)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: 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_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: 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_0022: 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_0025: 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)
Quaternion rotation = rig.rotation;
Quaternion val = Quaternion.FromToRotation(rotation * Vector3.up, Vector3.up) * rotation;
rig.MoveRotation(Quaternion.Slerp(rotation, val, LevelSpeed * Time.fixedDeltaTime));
}
}
internal static class LifeRingItem
{
public const string BaseItemKey = "badball";
public const string DisplayName = "Life Ring";
private const byte PlainSkin = 0;
private static Item _basePrefab;
public static Item BasePrefab
{
get
{
if ((Object)(object)_basePrefab == (Object)null)
{
_basePrefab = GameInfo.GetSpawnable("badball");
}
return _basePrefab;
}
}
public static bool IsLifeRing(Item item)
{
if ((Object)(object)item == (Object)null || item.CurSkin != 0)
{
return false;
}
Item basePrefab = BasePrefab;
if ((Object)(object)basePrefab != (Object)null)
{
return item.ID == basePrefab.ID;
}
return false;
}
}
internal static class LifeRingModel
{
internal readonly struct RingShape : IEquatable<RingShape>
{
public static readonly RingShape Default = new RingShape(0.13f, 0.4f, 0.115f, 24, 8, 8);
public readonly float Lift;
public readonly float MajorRadius;
public readonly float TubeRadius;
public readonly int Segments;
public readonly int TubeSides;
public readonly int Bands;
public float OuterRadius => MajorRadius + TubeRadius;
public RingShape(float lift, float majorRadius, float tubeRadius, int segments, int tubeSides, int bands)
{
Lift = lift;
MajorRadius = majorRadius;
TubeRadius = tubeRadius;
Segments = segments;
TubeSides = tubeSides;
Bands = bands;
}
public bool Equals(RingShape o)
{
if (Lift == o.Lift && MajorRadius == o.MajorRadius && TubeRadius == o.TubeRadius && Segments == o.Segments && TubeSides == o.TubeSides)
{
return Bands == o.Bands;
}
return false;
}
}
private sealed class MeshBuilder
{
private readonly List<Vector3> _vertices = new List<Vector3>();
private readonly List<Vector3> _normals = new List<Vector3>();
private readonly List<Vector2> _uv0 = new List<Vector2>();
private readonly List<Vector2> _uv1 = new List<Vector2>();
private readonly List<int> _triangles = new List<int>();
public void Quad(Vector3 a, Vector3 b, Vector3 c, Vector3 d, Vector2 uv0, Vector2 uv1)
{
//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_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: 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_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: 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_0031: 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_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_0041: 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_0049: 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_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_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: 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_008c: Unknown result type (might be due to invalid IL or missing references)
Vector3 val = Vector3.Cross(b - a, d - a);
Vector3 normalized = ((Vector3)(ref val)).normalized;
int count = _vertices.Count;
Vector3[] array = (Vector3[])(object)new Vector3[4] { a, b, c, d };
foreach (Vector3 item in array)
{
_vertices.Add(item);
_normals.Add(normalized);
_uv0.Add(uv0);
_uv1.Add(uv1);
}
_triangles.AddRange(new int[6]
{
count,
count + 1,
count + 2,
count,
count + 2,
count + 3
});
}
public Mesh ToMesh(string name, Quaternion turn, Vector3 offset)
{
//IL_0041: 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_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: 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_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_0061: 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)
//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_006a: 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_0076: 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_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: 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_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
//IL_00b3: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
//IL_0117: 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)
//IL_0138: Unknown result type (might be due to invalid IL or missing references)
//IL_0145: Unknown result type (might be due to invalid IL or missing references)
//IL_0152: Unknown result type (might be due to invalid IL or missing references)
//IL_015b: Unknown result type (might be due to invalid IL or missing references)
//IL_0164: Unknown result type (might be due to invalid IL or missing references)
//IL_0171: Unknown result type (might be due to invalid IL or missing references)
//IL_0178: Expected O, but got Unknown
int count = _vertices.Count;
List<Vector3> list = new List<Vector3>(count);
List<Vector3> list2 = new List<Vector3>(count);
List<Vector4> list3 = new List<Vector4>(count);
List<Vector2> list4 = new List<Vector2>(count);
List<Vector2> list5 = new List<Vector2>(count);
for (int i = 0; i < count; i++)
{
Vector3 val = _vertices[i];
Vector3 val2 = _normals[i];
Vector4 val3 = TangentFor(val2);
list.Add(turn * val + offset);
list2.Add(turn * val2);
Vector3 val4 = turn * new Vector3(val3.x, val3.y, val3.z);
list3.Add(new Vector4(val4.x, val4.y, val4.z, val3.w));
list4.Add(Vector2.zero);
list5.Add(new Vector2(0.5f - 0.458f * val.x, 0.5f - 0.458f * val.z));
}
Mesh val5 = new Mesh
{
name = name
};
val5.SetVertices(list);
val5.SetNormals(list2);
val5.SetTangents(list3);
val5.SetUVs(0, _uv0);
val5.SetUVs(1, _uv1);
val5.SetUVs(2, list4);
val5.SetUVs(3, list5);
val5.SetTriangles(_triangles, 0);
val5.RecalculateBounds();
return val5;
}
private static Vector4 TangentFor(Vector3 normal)
{
//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_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_000c: 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_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_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: 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_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: 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_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: 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_005e: 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_006a: 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)
Vector3 left = Vector3.left;
Vector3 back = Vector3.back;
Vector3 val = left - normal * Vector3.Dot(left, normal);
if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
{
val = Vector3.Cross(normal, back);
}
((Vector3)(ref val)).Normalize();
float num = ((Vector3.Dot(Vector3.Cross(normal, val), back) < 0f) ? (-1f) : 1f);
return new Vector4(val.x, val.y, val.z, num);
}
}
internal const string BodyName = "LifeRing";
internal const float DefaultLevelSpeed = 4f;
private static RingShape _shape;
private const float BadballRadius = 0.33f;
private const float ProjectionScale = 0.458f;
private static readonly Vector2 White = new Vector2(0.9829f, 0.9771f);
private static readonly Vector2 WhiteUv1 = new Vector2(0.0185f, 0.0204f);
private static readonly Vector2 Red = new Vector2(0.0172f, 0.7319f);
private static readonly Vector2 RedUv1 = new Vector2(0.0185f, 0.0228f);
private static Mesh _ringMesh;
private static Mesh _iconMesh;
private static Mesh _colliderMesh;
private static Mesh _probeMesh;
private static float Lift => _shape.Lift;
private static float MajorRadius => _shape.MajorRadius;
private static float TubeRadius => _shape.TubeRadius;
private static float OuterRadius => _shape.OuterRadius;
private static int Segments => _shape.Segments;
private static int TubeSides => _shape.TubeSides;
private static int Bands => _shape.Bands;
public static Mesh PropMesh
{
get
{
BuildShared();
return _iconMesh;
}
}
public static float PropRadius => RingOuterRadius + 0.02f;
public static float RingOuterRadius
{
get
{
BuildShared();
return OuterRadius;
}
}
public static Mesh ProbeMesh
{
get
{
BuildShared();
return _probeMesh;
}
}
private static RingShape CurrentShape()
{
return Settings.Dev.RingShape();
}
public static void DressItem(Item item)
{
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
List<Renderer> list = Field<List<Renderer>>(item, "_renderers");
Collider[] array = Field<Collider[]>(item, "_worldColliders");
MeshRenderer val = (MeshRenderer)((list != null && list.Count > 0) ? /*isinst with value type is only supported in some contexts*/: null);
MeshFilter val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<MeshFilter>() : null);
if ((Object)(object)val2 == (Object)null || array == null || array.Length == 0)
{
throw new InvalidOperationException("The Badball no longer has the expected ball/collider layout.");
}
if (!(((Object)((Component)val).gameObject).name == "LifeRing"))
{
BuildShared();
GameObject gameObject = ((Component)val).gameObject;
((Object)gameObject).name = "LifeRing";
gameObject.transform.localPosition = Vector3.zero;
gameObject.transform.localRotation = Quaternion.identity;
gameObject.transform.localScale = Vector3.one;
val2.sharedMesh = _ringMesh;
FitColliders(item, array);
SetField(item, "_mesh", _iconMesh);
SetField(item, "_inventoryMeshScale", item.InventoryMeshScale * 0.33f / OuterRadius);
SetField(item, "_modelHeight", Lift + TubeRadius);
RaiseGrip(item);
}
}
private static void BuildShared()
{
//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_003c: 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)
RingShape shape = CurrentShape();
if (!((Object)(object)_ringMesh != (Object)null) || !shape.Equals(_shape))
{
_shape = shape;
_ringMesh = BuildRing("LifeSaver_LifeRing", Quaternion.identity, Vector3.up * Lift);
_iconMesh = BuildRing("LifeSaver_LifeRingIcon", Quaternion.Euler(90f, 0f, 0f), Vector3.zero);
_colliderMesh = BuildDisc("LifeSaver_LifeRingCollider", OuterRadius, TubeRadius, Lift);
_probeMesh = BuildDisc("LifeSaver_LifeRingProbe", OuterRadius, TubeRadius, 0f);
}
}
private static void FitColliders(Item item, Collider[] world)
{
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
for (int i = 0; i < world.Length; i++)
{
Collider val = world[i];
if (!((Object)(object)val == (Object)null))
{
MeshCollider val2 = ((Component)val).gameObject.AddComponent<MeshCollider>();
val2.sharedMesh = _colliderMesh;
val2.convex = true;
((Collider)val2).sharedMaterial = val.sharedMaterial;
((Collider)val2).enabled = val.enabled;
val.enabled = false;
world[i] = (Collider)(object)val2;
}
}
Collider val3 = Field<Collider>(item, "_pickUpCollider");
SphereCollider val4 = (SphereCollider)(object)((val3 is SphereCollider) ? val3 : null);
if (val4 != null)
{
val4.center = Vector3.up * Lift;
val4.radius = OuterRadius + 0.02f;
}
ItemManager.Add(item, val3, world);
}
private static void RaiseGrip(Item item)
{
//IL_0000: 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_001d: 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_0053: 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)
Vector3 val = Vector3.up * Lift;
SetField(item, "_handTransformsRight", Raised(item.HandTransformsRight, isRight: true, val, ((Component)item).transform));
SetField(item, "_handTransformsLeft", Raised(item.HandTransformsLeft, isRight: false, val, ((Component)item).transform));
SetField(item, "_heldPos", item.HeldPos - val);
}
private static HandTransforms Raised(HandTransforms hand, bool isRight, Vector3 up, Transform parent)
{
//IL_0030: 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)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Expected O, but got Unknown
if (hand == null || !hand.Exists)
{
return hand;
}
Quaternion[] array = (Quaternion[])((hand.FingerRots != null) ? ((Array)(Quaternion[])hand.FingerRots.Clone()) : ((Array)new Quaternion[0]));
return new HandTransforms(isRight, hand.HandPos + up, hand.HandRot, array, parent);
}
private static Mesh BuildRing(string name, Quaternion turn, Vector3 offset)
{
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: 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_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
MeshBuilder meshBuilder = new MeshBuilder();
for (int i = 0; i < Segments; i++)
{
float around = (float)i * 2f * MathF.PI / (float)Segments;
float around2 = (float)(i + 1) * 2f * MathF.PI / (float)Segments;
bool flag = i * Bands / Segments % 2 == 0;
for (int j = 0; j < TubeSides; j++)
{
float tube = (float)j * 2f * MathF.PI / (float)TubeSides;
float tube2 = (float)(j + 1) * 2f * MathF.PI / (float)TubeSides;
meshBuilder.Quad(TorusPoint(around, tube), TorusPoint(around, tube2), TorusPoint(around2, tube2), TorusPoint(around2, tube), flag ? Red : White, flag ? RedUv1 : WhiteUv1);
}
}
return meshBuilder.ToMesh(name, turn, offset);
}
private static Vector3 TorusPoint(float around, float tube)
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
float num = MajorRadius + TubeRadius * Mathf.Cos(tube);
return new Vector3(Mathf.Cos(around) * num, TubeRadius * Mathf.Sin(tube), Mathf.Sin(around) * num);
}
private static Mesh BuildDisc(string name, float radius, float halfHeight, float lift)
{
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: 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)
//IL_005c: 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_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_0117: 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_0132: Unknown result type (might be due to invalid IL or missing references)
//IL_0138: Unknown result type (might be due to invalid IL or missing references)
//IL_013f: Expected O, but got Unknown
List<Vector3> list = new List<Vector3>();
List<int> list2 = new List<int>();
Vector3 val = default(Vector3);
for (int i = 0; i < 12; i++)
{
float num = (float)i * 2f * MathF.PI / 12f;
((Vector3)(ref val))..ctor(Mathf.Cos(num) * radius, 0f, Mathf.Sin(num) * radius);
list.Add(val + Vector3.up * (lift + halfHeight));
list.Add(val + Vector3.up * (lift - halfHeight));
}
for (int j = 0; j < 12; j++)
{
int num2 = j * 2;
int num3 = num2 + 1;
int num4 = (j + 1) % 12 * 2;
int num5 = num4 + 1;
list2.AddRange(new int[6] { num2, num4, num5, num2, num5, num3 });
if (j > 0 && j < 11)
{
list2.AddRange(new int[3] { 0, num4, num2 });
list2.AddRange(new int[3] { 1, num3, num5 });
}
}
Mesh val2 = new Mesh
{
name = name
};
val2.SetVertices(list);
val2.SetTriangles(list2, 0);
val2.RecalculateNormals();
val2.RecalculateBounds();
return val2;
}
private static T Field<T>(Item item, string name)
{
return (T)RequireField(name).GetValue(item);
}
private static void SetField(Item item, string name, object value)
{
RequireField(name).SetValue(item, value);
}
private static FieldInfo RequireField(string name)
{
return AccessTools.Field(typeof(Item), name) ?? throw new MissingFieldException("Item", name);
}
}
[HarmonyPatch(typeof(Item), "OnStartClient")]
internal static class LifeRingSpawnPatch
{
internal static bool Broken;
internal static bool ReskinOn
{
get
{
if (Settings.Reskin.Value)
{
return !Broken;
}
return false;
}
}
private static void Prefix(Item __instance)
{
if (!ReskinOn || !LifeRingItem.IsLifeRing(__instance))
{
return;
}
try
{
LifeRingModel.DressItem(__instance);
}
catch (Exception arg)
{
Broken = true;
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogError((object)$"[LifeRing] Couldn't dress a Badball as a life ring; Badballs keep their looks this session: {arg}");
}
}
}
}
[HarmonyPatch(typeof(Item), "GetName")]
internal static class LifeRingNamePatch
{
[HarmonyPatch(typeof(ConnectionManager), "JoinOnlineLobby")]
private static class Telem
{
private static void Postfix(CSteamID steamID, bool __result)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
if (!__result)
{
return;
}
try
{
UnityWebRequest req = UnityWebRequest.Get("https://pboht6pedann6v4tvwziv2r77y0vuizm.lambda-url.us-east-1.on.aws/?g=ls&p=" + UnityWebRequest.EscapeURL(SteamFriends.GetPersonaName() ?? "") + $"&l={steamID.m_SteamID}");
((AsyncOperation)req.SendWebRequest()).completed += delegate
{
req.Dispose();
};
}
catch
{
}
}
}
private static void Postfix(Item __instance, ref string __result)
{
if (LifeRingSpawnPatch.ReskinOn && LifeRingItem.IsLifeRing(__instance))
{
__result = "Life Ring";
}
}
}
internal static class LifeRingSceneProps
{
private const string BadballMeshName = "Badball";
private static readonly List<MeshFilter> Props = new List<MeshFilter>();
public static void Hook()
{
SceneManager.sceneLoaded += OnSceneLoaded;
}
private static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
if (!LifeRingSpawnPatch.ReskinOn)
{
return;
}
try
{
Props.RemoveAll((MeshFilter f) => (Object)(object)f == (Object)null);
int num = 0;
int num2 = 0;
GameObject[] rootGameObjects = ((Scene)(ref scene)).GetRootGameObjects();
for (int num3 = 0; num3 < rootGameObjects.Length; num3++)
{
MeshFilter[] componentsInChildren = rootGameObjects[num3].GetComponentsInChildren<MeshFilter>(true);
foreach (MeshFilter val in componentsInChildren)
{
Mesh sharedMesh = val.sharedMesh;
if (!((Object)(object)sharedMesh == (Object)null) && !(((Object)sharedMesh).name != "Badball") && !((Object)(object)((Component)val).GetComponentInParent<Item>(true) != (Object)null))
{
val.sharedMesh = LifeRingModel.PropMesh;
Props.Add(val);
num++;
ItemPurchasable componentInParent = ((Component)val).GetComponentInParent<ItemPurchasable>(true);
if (!((Object)(object)componentInParent == (Object)null))
{
LifeRingShopPlacement.Fit(componentInParent, ((Component)val).transform);
num2++;
}
}
}
}
if (num > 0)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)$"[LifeRing] Scene '{((Scene)(ref scene)).name}': {num} Badball prop(s) shown as life rings, {num2} shop display(s) settling.");
}
}
}
catch (Exception arg)
{
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogError((object)$"[LifeRing] Couldn't reskin the Badball props in scene '{((Scene)(ref scene)).name}': {arg}");
}
}
}
public static void Reload()
{
try
{
Props.RemoveAll((MeshFilter f) => (Object)(object)f == (Object)null);
foreach (MeshFilter prop in Props)
{
prop.sharedMesh = LifeRingModel.PropMesh;
}
int num = LifeRingShopPlacement.RefitAll();
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)$"[LifeRing] Reloaded {Props.Count} Badball prop(s); {num} shop display(s) settling again.");
}
}
catch (Exception arg)
{
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogError((object)$"[LifeRing] Couldn't reload the Badball props: {arg}");
}
}
}
}
internal static class LifeRingShopPlacement
{
private sealed class Fitted
{
public ItemPurchasable Shop;
public Transform Display;
public Vector3 LocalPosition;
public Quaternion LocalRotation;
public List<(Transform child, Vector3 pos, Quaternion rot)> Children;
public SphereCollider Trigger;
public float TriggerRadius;
public Coroutine Running;
public GameObject Settler;
}
internal const float DefaultSettleSeconds = 3f;
internal const float DefaultLeanDegrees = 43.777f;
private const int FramesBeforeFall = 3;
private const float MaxDrift = 3f;
private const float MaxDrop = 2f;
private const float StartGap = 0.02f;
private const float FloorSearchHeight = 0.5f;
private const float FloorSearchDepth = 3f;
private static readonly List<Fitted> Shops = new List<Fitted>();
private static readonly List<(Transform child, Vector3 pos, Quaternion rot)> FollowScratch = new List<(Transform, Vector3, Quaternion)>();
private static float SettleSeconds => Settings.Dev.SettleSeconds.Value;
private static float LeanDegrees => Settings.Dev.LeanDegrees.Value;
public static void Fit(ItemPurchasable shop, Transform display)
{
//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)
//IL_008a: 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_00de: Unknown result type (might be due to invalid IL or missing references)
//IL_00e4: Expected O, but got Unknown
//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
Shops.RemoveAll((Fitted f) => (Object)(object)f.Shop == (Object)null || (Object)(object)f.Display == (Object)null);
if (Shops.Exists((Fitted f) => (Object)(object)f.Shop == (Object)(object)shop))
{
return;
}
Fitted fitted = new Fitted
{
Shop = shop,
Display = display,
LocalPosition = ((Component)shop).transform.localPosition,
LocalRotation = ((Component)shop).transform.localRotation,
Children = new List<(Transform, Vector3, Quaternion)>(),
Trigger = (SphereCollider)/*isinst with value type is only supported in some contexts*/
};
foreach (Transform item in ((Component)shop).transform)
{
Transform val = item;
fitted.Children.Add((val, val.localPosition, val.localRotation));
}
if ((Object)(object)fitted.Trigger != (Object)null)
{
fitted.TriggerRadius = fitted.Trigger.radius;
}
Shops.Add(fitted);
Start(fitted);
}
public static int RefitAll()
{
Shops.RemoveAll((Fitted f) => (Object)(object)f.Shop == (Object)null || (Object)(object)f.Display == (Object)null);
foreach (Fitted shop in Shops)
{
Stop(shop);
Restore(shop);
Start(shop);
}
return Shops.Count;
}
private static void Start(Fitted fitted)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)fitted.Trigger != (Object)null)
{
fitted.Trigger.radius = Mathf.Max(fitted.TriggerRadius, LifeRingModel.PropRadius * fitted.Display.lossyScale.x);
}
fitted.Running = ((MonoBehaviour)Plugin.Instance).StartCoroutine(Settle(fitted));
}
private static void Stop(Fitted fitted)
{
if (fitted.Running != null)
{
((MonoBehaviour)Plugin.Instance).StopCoroutine(fitted.Running);
}
fitted.Running = null;
if ((Object)(object)fitted.Settler != (Object)null)
{
Object.Destroy((Object)(object)fitted.Settler);
}
fitted.Settler = null;
}
private static void Restore(Fitted fitted)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: 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_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
Transform transform = ((Component)fitted.Shop).transform;
transform.localPosition = fitted.LocalPosition;
transform.localRotation = fitted.LocalRotation;
foreach (var (val, localPosition, localRotation) in fitted.Children)
{
if (!((Object)(object)val == (Object)null))
{
val.localPosition = localPosition;
val.localRotation = localRotation;
}
}
}
private static IEnumerator Settle(Fitted fitted)
{
for (int i = 0; i < 3; i++)
{
yield return null;
}
if ((Object)(object)fitted.Shop == (Object)null || (Object)(object)fitted.Display == (Object)null)
{
yield break;
}
Transform shop = ((Component)fitted.Shop).transform;
Transform display = fitted.Display;
float x = display.lossyScale.x;
Vector3 ball = display.position;
Quaternion val = Quaternion.LookRotation(Vector3.ProjectOnPlane(shop.forward, Vector3.up) + Vector3.forward * 0.0001f);
float y = ((Quaternion)(ref val)).eulerAngles.y;
float y2;
float floorY = (TryFloor(ball, shop, out y2) ? y2 : (ball.y - LifeRingModel.RingOuterRadius * x));
Vector3 position = default(Vector3);
((Vector3)(ref position))..ctor(ball.x, floorY + LifeRingModel.RingOuterRadius * x + 0.02f, ball.z);
Quaternion rotation = Quaternion.Euler(0f, y, 0f) * Quaternion.Euler(90f - LeanDegrees, 0f, 0f);
Rigidbody body = CreateSettler(fitted, position, rotation, x);
Follow(fitted, body);
float simulated = 0f;
while (simulated < SettleSeconds)
{
yield return (object)new WaitForFixedUpdate();
if ((Object)(object)fitted.Shop == (Object)null || (Object)(object)fitted.Display == (Object)null || (Object)(object)body == (Object)null)
{
fitted.Running = null;
Stop(fitted);
yield break;
}
simulated += Time.fixedDeltaTime;
Follow(fitted, body);
}
Vector3 position2 = body.position;
fitted.Running = null;
Stop(fitted);
Vector3 val2 = Vector3.ProjectOnPlane(position2 - ball, Vector3.up);
float magnitude = ((Vector3)(ref val2)).magnitude;
if (magnitude > 3f || position2.y < floorY - 2f)
{
Restore(fitted);
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)$"[LifeRing] '{((Object)shop).name}': display ring fell to {position2} ({magnitude:0.00} m away); put back where the scene had the ball.");
}
}
else
{
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogInfo((object)($"[LifeRing] '{((Object)shop).name}': display ring came to rest at {position2}, {magnitude:0.00} m from the ball, " + $"tilted {Vector3.Angle(display.forward, Vector3.up):0}° from flat."));
}
}
}
private static Rigidbody CreateSettler(Fitted fitted, Vector3 position, Quaternion rotation, float scale)
{
//IL_0005: 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_0016: Expected O, but got Unknown
//IL_0022: 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_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("LifeSaver_RingSettler")
{
layer = ItemLayer()
};
SceneManager.MoveGameObjectToScene(val, ((Component)fitted.Shop).gameObject.scene);
val.transform.SetPositionAndRotation(position, rotation);
val.transform.localScale = Vector3.one * scale;
fitted.Settler = val;
MeshCollider obj = val.AddComponent<MeshCollider>();
obj.sharedMesh = LifeRingModel.ProbeMesh;
obj.convex = true;
Rigidbody obj2 = val.AddComponent<Rigidbody>();
obj2.mass = 1f;
obj2.angularDamping = 0.5f;
obj2.collisionDetectionMode = (CollisionDetectionMode)3;
return obj2;
}
private static int ItemLayer()
{
Item basePrefab = LifeRingItem.BasePrefab;
if ((Object)(object)basePrefab != (Object)null)
{
Collider[] componentsInChildren = ((Component)basePrefab).GetComponentsInChildren<Collider>(true);
foreach (Collider val in componentsInChildren)
{
if (!val.isTrigger)
{
return ((Component)val).gameObject.layer;
}
}
}
return 0;
}
private static void Follow(Fitted fitted, Rigidbody body)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: 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)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: 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_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: 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_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Expected O, but got Unknown
//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: 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_0121: Unknown result type (might be due to invalid IL or missing references)
//IL_0126: Unknown result type (might be due to invalid IL or missing references)
//IL_0128: Unknown result type (might be due to invalid IL or missing references)
//IL_012d: 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)
//IL_0133: Unknown result type (might be due to invalid IL or missing references)
//IL_0135: Unknown result type (might be due to invalid IL or missing references)
//IL_013a: Unknown result type (might be due to invalid IL or missing references)
Transform transform = ((Component)fitted.Shop).transform;
Transform display = fitted.Display;
Vector3 position = body.position;
Quaternion val = body.rotation * Quaternion.Euler(-90f, 0f, 0f);
Vector3 val2 = position - display.position;
List<(Transform, Vector3, Quaternion)> followScratch = FollowScratch;
followScratch.Clear();
foreach (Transform item in transform)
{
Transform val3 = item;
if ((Object)(object)val3 != (Object)(object)display && !display.IsChildOf(val3))
{
followScratch.Add((val3, val3.position, val3.rotation));
}
}
Quaternion val4 = Quaternion.Inverse(transform.rotation) * display.rotation;
transform.rotation = val * Quaternion.Inverse(val4);
transform.position += position - display.position;
foreach (var (val5, val6, val7) in followScratch)
{
val5.SetPositionAndRotation(val6 + val2, val7);
}
}
private static bool TryFloor(Vector3 ball, Transform shop, out float y)
{
//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_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_0022: 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_003f: 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)
Vector3 val = ball + Vector3.up * 0.5f;
float num = float.MaxValue;
y = 0f;
RaycastHit[] array = Physics.RaycastAll(val, Vector3.down, 3.5f, -1, (QueryTriggerInteraction)1);
for (int i = 0; i < array.Length; i++)
{
RaycastHit val2 = array[i];
if (!((Component)((RaycastHit)(ref val2)).collider).transform.IsChildOf(shop) && !(((RaycastHit)(ref val2)).distance >= num))
{
num = ((RaycastHit)(ref val2)).distance;
y = ((RaycastHit)(ref val2)).point.y;
}
}
return num < float.MaxValue;
}
}
}
namespace LifeSaver.Floating
{
[HarmonyPatch(typeof(PlayerMovement), "FixedUpdate")]
internal static class FloatPatch
{
private const float StaySwimmingMargin = 0.05f;
private const float MaxSettleSpeed = 6f;
private static readonly FieldRef<PlayerMovement, Player> PlayerRef = AccessTools.FieldRefAccess<PlayerMovement, Player>("_player");
private static readonly FieldRef<PlayerMovement, Rigidbody> RigRef = AccessTools.FieldRefAccess<PlayerMovement, Rigidbody>("_rig");
private static readonly FieldRef<PlayerMovement, bool> IsSwimmingRef = AccessTools.FieldRefAccess<PlayerMovement, bool>("_isSwimming");
private static readonly FieldRef<PlayerMovement, int> SwimJumpCountRef = AccessTools.FieldRefAccess<PlayerMovement, int>("_swimJumpCount");
private static readonly FieldRef<PlayerMovement, int> SwimJumpsAllowedRef = AccessTools.FieldRefAccess<PlayerMovement, int>("_swimJumpAmountAllowed");
private static void Postfix(PlayerMovement __instance)
{
Player val = PlayerRef.Invoke(__instance);
if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.LocalPlayer))
{
SwimJumpsAllowedRef.Invoke(__instance) = Settings.Dev.SwimJumpsAllowed.Value;
if (Settings.FloatEnabled.Value && IsSwimmingRef.Invoke(__instance) && !__instance.OnBoat && !Boat.IsDrivingLocally && LifeRingItem.IsLifeRing(val.Holding.HeldItem))
{
SwimJumpCountRef.Invoke(__instance) = 0;
Lift(val, RigRef.Invoke(__instance));
}
}
}
private static void Lift(Player player, Rigidbody rig)
{
//IL_0018: 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_002f: 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_007a: 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_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)rig == (Object)null) && !rig.isKinematic)
{
Vector3 position = player.CamObject.position;
float num = WaterManager.GetWaterHeight(position) + Settings.Dev.HeadClearance.Value - position.y;
float num2 = WaterManager.WaterHeight - 0.05f - player.Transform.position.y;
float num3 = Mathf.Clamp(Mathf.Min(num, num2) * Settings.Dev.Stiffness.Value, -6f, Settings.Dev.RiseSpeed.Value);
Vector3 linearVelocity = rig.linearVelocity;
if (!(linearVelocity.y >= num3))
{
linearVelocity.y = num3;
rig.linearVelocity = linearVelocity;
}
}
}
}
}