Decompiled source of TheSageMod v0.1.0

BepInEx/plugins/TheSageMod/TheSageMod.dll

Decompiled 4 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[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("TheSageMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0")]
[assembly: AssemblyProduct("TheSageMod")]
[assembly: AssemblyTitle("TheSageMod")]
[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 TheSageMod
{
	internal static class MovementPolicy
	{
		internal static bool ShouldRecall(float separation, float verticalSeparation, float limit, bool teleporting, float reachableJumpHeight = 4f)
		{
			if (!teleporting && !(separation > limit))
			{
				return verticalSeparation > Math.Max(5f, reachableJumpHeight + 1f);
			}
			return true;
		}

		internal static bool ShouldFollow(float distance, bool moving)
		{
			return distance > (moving ? 0.08f : 0.18f);
		}

		internal static bool CanReturn(bool grounded, bool swimming, bool teleporting, bool safe, float stableSeconds)
		{
			if (grounded && !swimming && !teleporting && safe)
			{
				return stableSeconds >= 0.2f;
			}
			return false;
		}

		internal static bool ShouldRun(float distance)
		{
			return distance > 2.5f;
		}

		internal static bool OwnerMoving(float speed, bool moving)
		{
			return speed > (moving ? 0.15f : 0.3f);
		}

		internal static float TrailingOffset(bool moving)
		{
			if (!moving)
			{
				return 0f;
			}
			return 1.25f;
		}

		internal static bool ShouldTrail(float ownerAhead)
		{
			return ownerAhead > TrailingOffset(moving: true);
		}

		internal static bool ShouldCatchUpJump(float separation, float recallDistance)
		{
			return separation >= recallDistance * 0.5f;
		}

		internal static float JumpVelocityForExtraHeight(float velocity, float gravity, float height)
		{
			if (!(velocity <= 0f) && !(gravity <= 0f))
			{
				return (float)Math.Sqrt(velocity * velocity + 2f * gravity * height);
			}
			return velocity;
		}

		internal static float MatchingPace(float baseline, float ownerSpeed)
		{
			return Math.Max(baseline, ownerSpeed * 1.3f);
		}

		internal static bool WalkableStep(float rise, float distance, float normalY)
		{
			if (normalY >= 0.55f)
			{
				return Math.Abs(rise) <= Math.Max(0.22f, distance * 1.52f + 0.03f);
			}
			return false;
		}
	}
	public sealed class SageCompanion : MonoBehaviour
	{
		private enum Mode
		{
			Hidden,
			Idle,
			Walk,
			Run,
			Jump,
			Lap,
			Sleep,
			Back
		}

		private Player owner;

		private ZNetView view;

		private GameObject model;

		private Animator animator;

		private Transform head;

		private Transform hips;

		private Transform ownerHead;

		private Transform spine;

		private Transform platform;

		private Vector3 platformPoint;

		private Mode mode;

		private string clip;

		private float modeSince;

		private float stableGround;

		private float nextSync;

		private float blockedTime;

		private float nextLook;

		private float lookUntil;

		private bool visible;

		private bool following;

		private bool sleepAtHead;

		private bool jumpToBack;

		private Vector3 jumpStart;

		private Vector3 jumpEnd;

		private float jumpSince;

		private float jumpDuration;

		private float jumpHeight;

		private float ownerJumpHeight = 1.5f;

		private float speedBudget = 7f;

		private float nextCapabilityCheck;

		private float nextLeapAttempt;

		private float currentPace;

		private Vector3 lastOwnerPosition;

		private Vector3 travelDirection;

		private bool ownerMoving;

		private Transform jumpPlatform;

		private Vector3 jumpPlatformPoint;

		private int solidMask;

		private readonly RaycastHit[] hits = (RaycastHit[])(object)new RaycastHit[64];

		private readonly Collider[] overlaps = (Collider[])(object)new Collider[64];

		private static readonly FieldInfo AttachAnimation = AccessTools.Field(typeof(Player), "m_attachAnimation");

		internal void Initialize(Player player, ZNetView netView)
		{
			//IL_001a: 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_0030: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			owner = player;
			view = netView;
			((Component)this).transform.position = ((Component)player).transform.position;
			lastOwnerPosition = ((Component)player).transform.position;
			travelDirection = ((Component)player).transform.forward;
			model = Object.Instantiate<GameObject>(SagePlugin.SagePrefab, ((Component)this).transform);
			model.transform.localPosition = Vector3.zero;
			animator = model.GetComponentInChildren<Animator>();
			animator.applyRootMotion = false;
			animator.cullingMode = (AnimatorCullingMode)0;
			head = ((IEnumerable<Transform>)model.GetComponentsInChildren<Transform>()).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "head"));
			hips = Bone("Hips");
			spine = Bone("Spine2") ?? Bone("Spine1");
			ownerHead = Bone("Head");
			solidMask = LayerMask.GetMask(new string[6] { "Default", "static_solid", "Default_small", "piece", "terrain", "vehicle" });
			if (solidMask == 0)
			{
				solidMask = -5;
			}
			model.SetActive(false);
			mode = Mode.Hidden;
			nextLook = Time.time + 2f;
		}

		private Transform Bone(string name)
		{
			return ((IEnumerable<Transform>)((Component)owner).GetComponentsInChildren<Transform>()).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name.Equals(name, StringComparison.OrdinalIgnoreCase)));
		}

		private void LateUpdate()
		{
			if (!Object.op_Implicit((Object)(object)owner) || !Object.op_Implicit((Object)(object)view) || !view.IsValid())
			{
				Dismiss();
				return;
			}
			float dt = Mathf.Min(Time.deltaTime, 0.2f);
			if (view.IsOwner())
			{
				TickOwner(dt);
				if (Time.time >= nextSync)
				{
					Publish();
					nextSync = Time.time + 0.1f;
				}
			}
			else
			{
				ReadRemote(dt);
			}
			Animate();
			LookAtWearer();
		}

		private void TickOwner(float dt)
		{
			//IL_006e: 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_007e: 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_0095: 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_00a1: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_030a: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03df: Unknown result type (might be due to invalid IL or missing references)
			//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0491: Unknown result type (might be due to invalid IL or missing references)
			//IL_049f: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0544: Unknown result type (might be due to invalid IL or missing references)
			//IL_0549: Unknown result type (might be due to invalid IL or missing references)
			//IL_054d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0552: Unknown result type (might be due to invalid IL or missing references)
			//IL_0505: Unknown result type (might be due to invalid IL or missing references)
			//IL_0568: Unknown result type (might be due to invalid IL or missing references)
			//IL_057f: Unknown result type (might be due to invalid IL or missing references)
			UpdateCapabilities(dt);
			if (((Character)owner).IsDead())
			{
				Hide();
				return;
			}
			bool flag = ((Character)owner).IsOnGround() || ((Character)owner).IsAttached();
			stableGround = (flag ? (stableGround + dt) : 0f);
			if (((Character)owner).IsTeleporting())
			{
				Hide();
				return;
			}
			Vector3 val = ((Component)owner).transform.position - ((Component)this).transform.position;
			if (mode != Mode.Hidden && mode != Mode.Back)
			{
				Vector2 val2 = new Vector2(val.x, val.z);
				if (MovementPolicy.ShouldRecall(((Vector2)(ref val2)).magnitude, Mathf.Abs(val.y), SagePlugin.RecallDistance.Value, teleporting: false, ownerJumpHeight))
				{
					Hide();
					return;
				}
			}
			if (owner.IsSleeping() || (((Character)owner).IsAttached() && (((string)AttachAnimation.GetValue(owner)) ?? "").IndexOf("bed", StringComparison.OrdinalIgnoreCase) >= 0))
			{
				if (mode != Mode.Sleep)
				{
					sleepAtHead = Random.value < 0.5f;
				}
				SetMode(Mode.Sleep);
				PoseOnOwner();
				Show();
				return;
			}
			if (((Character)owner).IsSitting())
			{
				SetMode(Mode.Lap);
				PoseOnOwner();
				Show();
				return;
			}
			if (((Character)owner).IsSwimming())
			{
				if (mode == Mode.Jump)
				{
					UpdateJump();
				}
				else if (mode != Mode.Back)
				{
					if (!visible)
					{
						SetMode(Mode.Back);
						PoseOnOwner();
						Show();
						return;
					}
					Vector3 val3 = ((Component)owner).transform.position - ((Component)this).transform.position;
					val3.y = 0f;
					if (!TryLeap(((Vector3)(ref val3)).normalized, river: true))
					{
						StartJump(BackPosition(), 0.65f, toBack: true);
					}
				}
				else
				{
					PoseOnOwner();
				}
				return;
			}
			if (mode == Mode.Back || mode == Mode.Lap || mode == Mode.Sleep)
			{
				if (!SafeBesideOwner(out var point))
				{
					Hide();
					return;
				}
				StartJump(point, 0.55f, toBack: false);
			}
			if (mode == Mode.Hidden)
			{
				Vector3 point2;
				bool safe = SafeBesideOwner(out point2);
				if (MovementPolicy.CanReturn(flag, ((Character)owner).IsSwimming(), ((Character)owner).IsTeleporting(), safe, stableGround))
				{
					((Component)this).transform.SetPositionAndRotation(point2, ((Component)owner).transform.rotation);
					SetMode(Mode.Idle);
					Show();
				}
				return;
			}
			if (mode == Mode.Jump)
			{
				UpdateJump();
				return;
			}
			if (Object.op_Implicit((Object)(object)platform))
			{
				((Component)this).transform.position = platform.TransformPoint(platformPoint);
			}
			Vector3 val4 = FollowTarget() - ((Component)this).transform.position;
			val4.y = 0f;
			Vector3 val5 = ((Component)owner).transform.position - ((Component)this).transform.position;
			val5.y = 0f;
			if (MovementPolicy.ShouldCatchUpJump(((Vector3)(ref val5)).magnitude, SagePlugin.RecallDistance.Value) && TryLeap(((Vector3)(ref val5)).normalized, river: false, ((Vector3)(ref val5)).magnitude - MovementPolicy.TrailingOffset(ownerMoving)))
			{
				return;
			}
			following = MovementPolicy.ShouldFollow(((Vector3)(ref val4)).magnitude, following);
			if (!following)
			{
				SetMode(Mode.Idle);
				blockedTime = 0f;
				GroundHere();
				return;
			}
			Vector3 normalized = ((Vector3)(ref val4)).normalized;
			((Component)this).transform.rotation = Quaternion.RotateTowards(((Component)this).transform.rotation, Quaternion.LookRotation(normalized), 500f * dt);
			bool flag2 = ((Character)owner).IsRunning() || MovementPolicy.ShouldRun(((Vector3)(ref val4)).magnitude) || speedBudget > SagePlugin.WalkSpeed.Value * 1.3f;
			float num = (currentPace = (flag2 ? Mathf.Max(SagePlugin.RunSpeed.Value, speedBudget) : Mathf.Max(SagePlugin.WalkSpeed.Value, speedBudget))) * dt;
			num = Mathf.Min(num, ((Vector3)(ref val4)).magnitude);
			while (num > 0.001f)
			{
				float num2 = Mathf.Min(num, 0.15f);
				if (TryGroundStep(normalized, num2, out var floor))
				{
					MoveTo(floor);
					num -= num2;
					blockedTime = 0f;
					continue;
				}
				float[] array = new float[4] { 40f, -40f, 80f, -80f };
				foreach (float num3 in array)
				{
					Vector3 direction = Quaternion.Euler(0f, num3, 0f) * normalized;
					if (TryGroundStep(direction, num2, out var floor2))
					{
						MoveTo(floor2);
						SetMode(flag2 ? Mode.Run : Mode.Walk);
						blockedTime += dt * 0.25f;
						return;
					}
				}
				RaycastHit floor3;
				bool flag3 = Ground(((Component)this).transform.position + normalized * num2, out floor3) && Dry(((RaycastHit)(ref floor3)).point, ((RaycastHit)(ref floor3)).collider);
				if (!TryLeap(normalized, !flag3))
				{
					SetMode(Mode.Idle);
					blockedTime += dt;
					if (blockedTime > 2.5f)
					{
						Hide();
					}
				}
				return;
			}
			SetMode(flag2 ? Mode.Run : Mode.Walk);
		}

		private bool TryGroundStep(Vector3 direction, float distance, out RaycastHit floor)
		{
			//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_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_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_0029: 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_0043: 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_0049: 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_0052: 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_0067: 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_0076: 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_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_00a1: 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)
			Vector3 position = ((Component)this).transform.position;
			if (!Ground(position + direction * distance, out floor) || !Dry(((RaycastHit)(ref floor)).point, ((RaycastHit)(ref floor)).collider))
			{
				return false;
			}
			Vector3 val = ((RaycastHit)(ref floor)).point - position;
			if (!MovementPolicy.WalkableStep(val.y, distance, ((RaycastHit)(ref floor)).normal.y))
			{
				return false;
			}
			if (!Blocked(position + Vector3.up * 0.22f, ((Vector3)(ref val)).normalized, ((Vector3)(ref val)).magnitude))
			{
				return ClearBody(((RaycastHit)(ref floor)).point + Vector3.up * 0.22f);
			}
			return false;
		}

		private bool Ground(Vector3 point, out RaycastHit floor, float rise = 1.5f)
		{
			//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_0007: 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_0011: 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_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_006e: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			int num = Physics.RaycastNonAlloc(point + Vector3.up * rise, Vector3.down, hits, rise + Mathf.Max(2.5f, ownerJumpHeight), solidMask, (QueryTriggerInteraction)1);
			floor = default(RaycastHit);
			float num2 = float.MaxValue;
			for (int i = 0; i < num; i++)
			{
				RaycastHit val = hits[i];
				if (!Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Character>()) && !(((RaycastHit)(ref val)).normal.y < 0.55f) && !(((RaycastHit)(ref val)).distance >= num2))
				{
					num2 = ((RaycastHit)(ref val)).distance;
					floor = val;
				}
			}
			return num2 < float.MaxValue;
		}

		private bool Dry(Vector3 point, Collider surface)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)surface) && Object.op_Implicit((Object)(object)((Component)surface).GetComponentInParent<Ship>()))
			{
				return true;
			}
			WaterVolume val = null;
			float waterLevel = Floating.GetWaterLevel(point, ref val);
			if (Object.op_Implicit((Object)(object)val))
			{
				return point.y >= waterLevel + 0.025f;
			}
			return true;
		}

		private bool ClearBody(Vector3 point)
		{
			//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_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			int num = Physics.OverlapCapsuleNonAlloc(point + Vector3.up * 0.16f, point + Vector3.up * 0.36f, 0.12f, overlaps, solidMask, (QueryTriggerInteraction)1);
			for (int i = 0; i < num; i++)
			{
				if (!Object.op_Implicit((Object)(object)((Component)overlaps[i]).GetComponentInParent<Character>()))
				{
					return false;
				}
			}
			return true;
		}

		private bool SafeBesideOwner(out Vector3 point)
		{
			//IL_0016: 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_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_004b: 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_0051: 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_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: 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_007e: 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_00ae: 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)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < 12; i++)
			{
				Vector3 val = Quaternion.Euler(0f, (float)(i * 30), 0f) * ((Component)owner).transform.right * SagePlugin.FollowDistance.Value;
				Vector3 point2 = ((Component)owner).transform.position + val;
				if (Ground(point2, out var floor) && Mathf.Abs(((RaycastHit)(ref floor)).point.y - ((Component)owner).transform.position.y) < 1.25f && Dry(((RaycastHit)(ref floor)).point, ((RaycastHit)(ref floor)).collider) && ClearBody(((RaycastHit)(ref floor)).point))
				{
					point = ((RaycastHit)(ref floor)).point;
					return true;
				}
			}
			point = default(Vector3);
			return false;
		}

		private bool Blocked(Vector3 position, Vector3 direction, float distance)
		{
			//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_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0025: 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)
			int num = Physics.CapsuleCastNonAlloc(position + Vector3.up * 0.17f, position + Vector3.up * 0.35f, 0.12f, direction, hits, distance, solidMask, (QueryTriggerInteraction)1);
			for (int i = 0; i < num; i++)
			{
				if (!Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref hits[i])).collider).GetComponentInParent<Character>()))
				{
					return true;
				}
			}
			return false;
		}

		private Vector3 FollowTarget()
		{
			//IL_0048: 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_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_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_0086: 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)
			//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)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			if (!ownerMoving)
			{
				return ((Component)owner).transform.position + ((Component)owner).transform.right * SagePlugin.FollowDistance.Value;
			}
			if (!MovementPolicy.ShouldTrail(Vector3.Dot(((Component)owner).transform.position - ((Component)this).transform.position, travelDirection)))
			{
				return ((Component)this).transform.position;
			}
			return ((Component)owner).transform.position - travelDirection * MovementPolicy.TrailingOffset(moving: true);
		}

		private bool TryLeap(Vector3 direction, bool river, float catchUpDistance = 0f)
		{
			//IL_0025: 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_00ca: 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_00d2: 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_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: 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_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			if (Time.time < nextLeapAttempt)
			{
				return false;
			}
			nextLeapAttempt = Time.time + 0.25f;
			float num = Mathf.Max(0.1f, Mathf.Abs(Physics.gravity.y));
			float num2 = 2f * Mathf.Sqrt(2f * ownerJumpHeight / num);
			float num3 = Mathf.Max(river ? SagePlugin.RiverJump.Value : 2.2f, Mathf.Max(SagePlugin.RunSpeed.Value, speedBudget) * num2);
			num3 = Mathf.Min(num3, SagePlugin.RecallDistance.Value);
			bool flag = catchUpDistance > 0f;
			if (flag)
			{
				num3 = Mathf.Min(num3, catchUpDistance);
			}
			bool flag2 = false;
			for (float num4 = (flag ? num3 : 0.25f); num4 >= 0.25f && num4 <= num3; num4 += (flag ? (-0.25f) : 0.25f))
			{
				Vector3 point = ((Component)this).transform.position + direction * num4;
				if (!Ground(point, out var floor, ownerJumpHeight + 0.2f) || !Dry(((RaycastHit)(ref floor)).point, ((RaycastHit)(ref floor)).collider))
				{
					flag2 = true;
				}
				else
				{
					if (num4 < (flag ? 1.5f : 0.7f) || (river && !flag2) || !ClearBody(((RaycastHit)(ref floor)).point) || Mathf.Abs(((RaycastHit)(ref floor)).point.y - ((Component)this).transform.position.y) > ownerJumpHeight)
					{
						continue;
					}
					float height = Mathf.Max(0.7f, ownerJumpHeight);
					if (ArcClear(((Component)this).transform.position, ((RaycastHit)(ref floor)).point, height))
					{
						float num5 = (flag ? Mathf.Max(0.35f, num4 / (Mathf.Max(SagePlugin.RunSpeed.Value, speedBudget) * 1.5f)) : Mathf.Max(0.45f, num2));
						StartJump(((RaycastHit)(ref floor)).point, num5, toBack: false, height);
						if (flag)
						{
							nextLeapAttempt = Time.time + num5 + 0.75f;
						}
						Ship componentInParent = ((Component)((RaycastHit)(ref floor)).collider).GetComponentInParent<Ship>();
						if (Object.op_Implicit((Object)(object)componentInParent))
						{
							jumpPlatform = ((Component)componentInParent).transform;
							jumpPlatformPoint = jumpPlatform.InverseTransformPoint(((RaycastHit)(ref floor)).point);
						}
						return true;
					}
				}
			}
			return false;
		}

		private bool ArcClear(Vector3 from, Vector3 to, float height)
		{
			//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_000f: 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_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_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_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_003f: 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_0045: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = from;
			for (int i = 1; i <= 12; i++)
			{
				float num = (float)i / 12f;
				Vector3 val2 = Vector3.Lerp(from, to, num) + Vector3.up * (4f * height * num * (1f - num));
				Vector3 val3 = val2 - val;
				if (Blocked(val, ((Vector3)(ref val3)).normalized, ((Vector3)(ref val3)).magnitude))
				{
					return false;
				}
				val = val2;
			}
			return true;
		}

		private void StartJump(Vector3 end, float duration, bool toBack, float height = 0.7f)
		{
			//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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			platform = null;
			jumpPlatform = null;
			jumpStart = ((Component)this).transform.position;
			jumpEnd = end;
			jumpSince = Time.time;
			jumpDuration = duration;
			jumpHeight = height;
			jumpToBack = toBack;
			SetMode(Mode.Jump);
		}

		private void UpdateJump()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_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_008b: 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)
			//IL_0044: 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_004e: 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_00e6: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Clamp01((Time.time - jumpSince) / jumpDuration);
			if (jumpToBack)
			{
				jumpEnd = BackPosition();
			}
			else if (Object.op_Implicit((Object)(object)jumpPlatform))
			{
				jumpEnd = jumpPlatform.TransformPoint(jumpPlatformPoint);
			}
			Vector3 val = Vector3.Lerp(jumpStart, jumpEnd, num) + Vector3.up * (4f * jumpHeight * num * (1f - num));
			Vector3 val2 = val - ((Component)this).transform.position;
			if (((Vector3)(ref val2)).sqrMagnitude > 0.0001f && Blocked(((Component)this).transform.position, ((Vector3)(ref val2)).normalized, ((Vector3)(ref val2)).magnitude))
			{
				Hide();
				return;
			}
			((Component)this).transform.position = val;
			Vector3 val3 = jumpEnd - jumpStart;
			val3.y = 0f;
			if (((Vector3)(ref val3)).sqrMagnitude > 0.01f)
			{
				((Component)this).transform.rotation = Quaternion.LookRotation(val3);
			}
			if (!(num < 1f))
			{
				RaycastHit floor;
				if (jumpToBack && ((Character)owner).IsSwimming())
				{
					SetMode(Mode.Back);
					PoseOnOwner();
				}
				else if (Ground(((Component)this).transform.position, out floor) && Dry(((RaycastHit)(ref floor)).point, ((RaycastHit)(ref floor)).collider))
				{
					MoveTo(floor);
					SetMode(Mode.Idle);
				}
				else
				{
					Hide();
				}
			}
		}

		private void GroundHere()
		{
			//IL_0007: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			if (Ground(((Component)this).transform.position, out var floor) && Dry(((RaycastHit)(ref floor)).point, ((RaycastHit)(ref floor)).collider))
			{
				MoveTo(floor);
			}
			else
			{
				Hide();
			}
		}

		private void UpdateCapabilities(float dt)
		{
			//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_0023: 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_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_00b9: 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)
			//IL_008f: 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)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			Vector3 velocity = ((Character)owner).GetVelocity();
			velocity.y = 0f;
			Vector3 val = ((Component)owner).transform.position - lastOwnerPosition;
			val.y = 0f;
			float num = Mathf.Max(((Vector3)(ref velocity)).magnitude, ((Vector3)(ref val)).magnitude / Mathf.Max(0.001f, Time.deltaTime));
			ownerMoving = MovementPolicy.OwnerMoving(num, ownerMoving);
			if (ownerMoving)
			{
				Vector3 val2 = ((((Vector3)(ref val)).sqrMagnitude > 1E-06f) ? val : velocity);
				if (((Vector3)(ref val2)).sqrMagnitude > 1E-06f)
				{
					travelDirection = ((Vector3)(ref val2)).normalized;
				}
			}
			lastOwnerPosition = ((Component)owner).transform.position;
			if (num < SagePlugin.RecallDistance.Value / Mathf.Max(0.001f, Time.deltaTime))
			{
				speedBudget = Mathf.Max(MovementPolicy.MatchingPace(0f, num), Mathf.Lerp(speedBudget, MovementPolicy.MatchingPace(0f, num), 1f - Mathf.Exp(-12f * dt)));
			}
			if (!(Time.time < nextCapabilityCheck))
			{
				nextCapabilityCheck = Time.time + 0.25f;
				Vector3 val3 = Vector3.up * ((Character)owner).m_jumpForce * (1f + 0.4f * ((Character)owner).GetSkillFactor((SkillType)100));
				((Character)owner).GetSEMan().ApplyStatusEffectJumpMods(ref val3);
				float num2 = Mathf.Max(val3.y, ((Character)owner).GetVelocity().y);
				ownerJumpHeight = Mathf.Max(0.7f, num2 * num2 / (2f * Mathf.Max(0.1f, Mathf.Abs(Physics.gravity.y))));
			}
		}

		private void MoveTo(RaycastHit floor)
		{
			//IL_0008: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			((Component)this).transform.position = ((RaycastHit)(ref floor)).point;
			Ship componentInParent = ((Component)((RaycastHit)(ref floor)).collider).GetComponentInParent<Ship>();
			platform = (Object.op_Implicit((Object)(object)componentInParent) ? ((Component)componentInParent).transform : null);
			if (Object.op_Implicit((Object)(object)platform))
			{
				platformPoint = platform.InverseTransformPoint(((Component)this).transform.position);
			}
		}

		private Vector3 BackPosition()
		{
			//IL_003d: 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_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)
			if (!Object.op_Implicit((Object)(object)spine))
			{
				return ((Component)owner).transform.TransformPoint(new Vector3(0f, 0.8f, -0.2f));
			}
			return spine.TransformPoint(SagePlugin.BackOffset.Value);
		}

		private void PoseOnOwner()
		{
			//IL_0017: 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_003c: 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_00a1: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: 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_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_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: 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)
			platform = null;
			Quaternion val = Quaternion.Euler(0f, ((Component)owner).transform.eulerAngles.y, 0f);
			if (mode == Mode.Back)
			{
				((Component)this).transform.position = BackPosition();
				((Component)this).transform.rotation = val;
				return;
			}
			Transform val2 = ((mode == Mode.Sleep && sleepAtHead) ? ownerHead : hips);
			Vector3 val3 = ((mode == Mode.Lap) ? SagePlugin.LapOffset.Value : (sleepAtHead ? SagePlugin.BedHeadOffset.Value : SagePlugin.BedStomachOffset.Value));
			((Component)this).transform.position = (Object.op_Implicit((Object)(object)val2) ? val2.position : (((Component)owner).transform.position + Vector3.up * 0.5f)) + val * val3;
			((Component)this).transform.rotation = val * Quaternion.Euler(0f, (float)((mode == Mode.Lap) ? 90 : 0), 0f);
		}

		private void SetMode(Mode value)
		{
			if (mode != value)
			{
				mode = value;
				modeSince = Time.time;
				if (value != Mode.Walk && value != Mode.Run)
				{
					following = false;
				}
			}
		}

		private void Hide()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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)
			if (visible)
			{
				Poof.Emit(((Component)this).transform.position + Vector3.up * 0.15f);
			}
			visible = false;
			model.SetActive(false);
			platform = null;
			blockedTime = 0f;
			stableGround = 0f;
			SetMode(Mode.Hidden);
		}

		private void Show()
		{
			//IL_0029: 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_0038: 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)
			if (!visible)
			{
				visible = true;
				model.SetActive(true);
				clip = null;
				Poof.Emit(((Component)this).transform.position + Vector3.up * 0.15f);
			}
		}

		internal void Dismiss()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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)
			if (visible)
			{
				Poof.Emit(((Component)this).transform.position + Vector3.up * 0.15f);
			}
			if (Object.op_Implicit((Object)(object)view) && view.IsValid() && view.IsOwner())
			{
				view.GetZDO().Set("sage_visible", false);
			}
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}

		private void Animate()
		{
			if (visible && Object.op_Implicit((Object)(object)animator))
			{
				float num = Time.time - modeSince;
				string text = ((mode == Mode.Walk) ? "Sage_Walk" : ((mode == Mode.Run) ? "Sage_Run" : ((mode == Mode.Jump) ? "Sage_Jump" : ((mode != Mode.Lap) ? ((mode != Mode.Sleep) ? ((mode == Mode.Back) ? "Sage_LieIdle" : "Sage_Idle") : ((num < 3f) ? "Sage_CurlUp" : "Sage_CurlSleep")) : ((num < 1.5f) ? "Sage_LieDown" : "Sage_LieIdle")))));
				if (clip != text)
				{
					animator.CrossFadeInFixedTime(text, 0.12f);
					clip = text;
				}
				animator.speed = ((mode == Mode.Jump) ? (1.4f / Mathf.Max(0.4f, jumpDuration)) : ((mode == Mode.Run) ? Mathf.Clamp(currentPace / 7f, 0.5f, 3f) : ((mode == Mode.Walk) ? Mathf.Clamp(currentPace / 2.2f, 0.5f, 3f) : 1f)));
			}
		}

		private void LookAtWearer()
		{
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: 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)
			//IL_0098: 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_00b5: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			if (visible && Object.op_Implicit((Object)(object)head) && mode == Mode.Idle)
			{
				if (Time.time >= nextLook)
				{
					lookUntil = Time.time + 1.5f;
					nextLook = Time.time + Random.Range(4f, 8f);
				}
				if (!(Time.time > lookUntil))
				{
					Vector3 val = ((Component)this).transform.InverseTransformDirection((Object.op_Implicit((Object)(object)ownerHead) ? ownerHead.position : (((Component)owner).transform.position + Vector3.up * 1.6f)) - head.position);
					float num = Mathf.Clamp(Mathf.Atan2(val.x, val.z) * 57.29578f, -40f, 40f);
					float y = val.y;
					Vector2 val2 = new Vector2(val.x, val.z);
					float num2 = Mathf.Clamp((0f - Mathf.Atan2(y, ((Vector2)(ref val2)).magnitude)) * 57.29578f, -35f, 15f);
					float num3 = Mathf.Clamp01((lookUntil - Time.time) * 3f) * Mathf.Clamp01((Time.time - (lookUntil - 1.5f)) * 3f);
					Transform obj = head;
					obj.localRotation *= Quaternion.Euler(num2 * num3, num * num3, 0f);
				}
			}
		}

		private void Publish()
		{
			//IL_0044: 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_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_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)
			ZDO zDO = view.GetZDO();
			zDO.Set("sage_visible", visible);
			zDO.Set("sage_mode", (int)mode);
			zDO.Set("sage_offset", ((Component)owner).transform.InverseTransformPoint(((Component)this).transform.position));
			zDO.Set("sage_rotation", Quaternion.Inverse(((Component)owner).transform.rotation) * ((Component)this).transform.rotation);
			zDO.Set("sage_bed_head", sleepAtHead);
			zDO.Set("sage_jump_duration", jumpDuration);
			zDO.Set("sage_pace", currentPace);
		}

		private void ReadRemote(float dt)
		{
			//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_0044: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: 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_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			ZDO zDO = view.GetZDO();
			if (!zDO.GetBool("sage_visible", false))
			{
				if (visible)
				{
					Hide();
				}
				return;
			}
			Vector3 val = ((Component)owner).transform.TransformPoint(zDO.GetVec3("sage_offset", Vector3.zero));
			Quaternion val2 = ((Component)owner).transform.rotation * zDO.GetQuaternion("sage_rotation", Quaternion.identity);
			SetMode((Mode)Mathf.Clamp(zDO.GetInt("sage_mode", 0), 0, 7));
			sleepAtHead = zDO.GetBool("sage_bed_head", false);
			jumpDuration = zDO.GetFloat("sage_jump_duration", 0.7f);
			currentPace = zDO.GetFloat("sage_pace", 2.2f);
			((Component)this).transform.position = ((!visible || Vector3.Distance(((Component)this).transform.position, val) > 3f) ? val : Vector3.Lerp(((Component)this).transform.position, val, 1f - Mathf.Exp(-18f * dt)));
			((Component)this).transform.rotation = Quaternion.Slerp(((Component)this).transform.rotation, val2, 1f - Mathf.Exp(-18f * dt));
			if (mode == Mode.Lap || mode == Mode.Sleep || mode == Mode.Back)
			{
				PoseOnOwner();
			}
			Show();
		}
	}
	internal static class Poof
	{
		private static Material material;

		internal static void Emit(Vector3 position)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: 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: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_011c: 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_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Expected O, but got Unknown
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Expected O, but got Unknown
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			if ((int)SystemInfo.graphicsDeviceType == 4)
			{
				return;
			}
			if (!Object.op_Implicit((Object)(object)material))
			{
				Material val = SagePlugin.Assets.LoadAsset<Material>("SageCloud");
				if (!Object.op_Implicit((Object)(object)val))
				{
					return;
				}
				material = new Material(val);
				Texture2D val2 = new Texture2D(32, 32, (TextureFormat)4, false);
				for (int i = 0; i < 32; i++)
				{
					for (int j = 0; j < 32; j++)
					{
						float num = Vector2.Distance(new Vector2((float)j, (float)i), new Vector2(15.5f, 15.5f)) / 15.5f;
						val2.SetPixel(j, i, new Color(1f, 1f, 1f, Mathf.Pow(Mathf.Clamp01(1f - num), 1.5f)));
					}
				}
				((Texture)val2).wrapMode = (TextureWrapMode)1;
				val2.Apply();
				material.mainTexture = (Texture)(object)val2;
			}
			Color[] array = (Color[])(object)new Color[2]
			{
				new Color(1f, 0.32f, 0.025f),
				new Color(0.3f, 0.025f, 0.48f)
			};
			foreach (Color val3 in array)
			{
				GameObject val4 = new GameObject("Sage cloud");
				val4.transform.position = position;
				ParticleSystem val5 = val4.AddComponent<ParticleSystem>();
				val5.Stop(true, (ParticleSystemStopBehavior)0);
				MainModule main = val5.main;
				((MainModule)(ref main)).loop = false;
				((MainModule)(ref main)).duration = 1f;
				((MainModule)(ref main)).startLifetime = new MinMaxCurve(0.55f, 1f);
				((MainModule)(ref main)).startSpeed = new MinMaxCurve(0.1f, 0.65f);
				((MainModule)(ref main)).startSize = new MinMaxCurve(0.35f, 0.7f);
				((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(val3);
				((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1;
				((MainModule)(ref main)).maxParticles = 30;
				EmissionModule emission = val5.emission;
				((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(0f);
				ShapeModule shape = val5.shape;
				((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0;
				((ShapeModule)(ref shape)).radius = 0.22f;
				ColorOverLifetimeModule colorOverLifetime = val5.colorOverLifetime;
				((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true;
				Gradient val6 = new Gradient();
				val6.SetKeys((GradientColorKey[])(object)new GradientColorKey[2]
				{
					new GradientColorKey(Color.white, 0f),
					new GradientColorKey(Color.white, 1f)
				}, (GradientAlphaKey[])(object)new GradientAlphaKey[2]
				{
					new GradientAlphaKey(0.85f, 0f),
					new GradientAlphaKey(0f, 1f)
				});
				((ColorOverLifetimeModule)(ref colorOverLifetime)).color = MinMaxGradient.op_Implicit(val6);
				((Renderer)((Component)val5).GetComponent<ParticleSystemRenderer>()).sharedMaterial = material;
				val5.Play();
				val5.Emit(18);
				Object.Destroy((Object)(object)val4, 2f);
			}
		}
	}
	internal static class SageItemFlags
	{
		[HarmonyPatch(typeof(ItemDrop), "OnCreateNew", new Type[]
		{
			typeof(ItemDrop),
			typeof(bool)
		})]
		private static class Created
		{
			private static void Postfix(ItemDrop __0)
			{
				Clear(__0.m_itemData);
			}
		}

		[HarmonyPatch(typeof(ItemData), "Load", new Type[]
		{
			typeof(ZPackage),
			typeof(ItemData),
			typeof(Item)
		})]
		private static class Loaded
		{
			private static void Postfix(ItemData __1)
			{
				Clear(__1);
			}
		}

		[HarmonyPatch(typeof(ItemData), "Save")]
		private static class Saving
		{
			private static void Prefix(ItemData __instance)
			{
				Clear(__instance);
			}
		}

		[HarmonyPatch(typeof(Inventory), "Changed")]
		private static class InventoryChanged
		{
			private static void Prefix(Inventory __instance, ref bool __1)
			{
				bool flag = false;
				foreach (ItemData allItem in __instance.GetAllItems())
				{
					flag |= Clear(allItem);
				}
				if (flag && !__instance.AnyCheatedItem())
				{
					__1 = false;
				}
			}
		}

		internal static bool Clear(ItemData item)
		{
			if (item == null || !item.m_cheated || !Object.op_Implicit((Object)(object)item.m_dropPrefab))
			{
				return false;
			}
			string name = ((Object)item.m_dropPrefab).name;
			if (name != "SmooshboundAmulet" && name != "SageBestFriendsLove")
			{
				return false;
			}
			item.m_cheated = false;
			return true;
		}
	}
	[BepInPlugin("com.smooshbound.sage", "The Sage Mod", "0.1.0")]
	public sealed class SagePlugin : BaseUnityPlugin
	{
		public const string Id = "com.smooshbound.sage";

		internal static SagePlugin Instance;

		internal static AssetBundle Assets;

		internal static GameObject SagePrefab;

		internal static ConfigEntry<float> FollowDistance;

		internal static ConfigEntry<float> RecallDistance;

		internal static ConfigEntry<float> WalkSpeed;

		internal static ConfigEntry<float> RunSpeed;

		internal static ConfigEntry<float> RiverJump;

		internal static ConfigEntry<Vector3> LapOffset;

		internal static ConfigEntry<Vector3> BackOffset;

		internal static ConfigEntry<Vector3> BedStomachOffset;

		internal static ConfigEntry<Vector3> BedHeadOffset;

		private readonly Dictionary<Player, SageCompanion> companions = new Dictionary<Player, SageCompanion>();

		private Harmony harmony;

		private float scanAt;

		private void Awake()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Expected O, but got Unknown
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Expected O, but got Unknown
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: 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
			Instance = this;
			FollowDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Movement", "FollowDistance", 0.75f, new ConfigDescription("Preferred distance in metres beside the wearer.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 3f), Array.Empty<object>()));
			RecallDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Movement", "RecallDistance", 12f, new ConfigDescription("Poof away beyond this distance; return only on safe ground.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(4f, 40f), Array.Empty<object>()));
			WalkSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Movement", "WalkSpeed", 2.2f, new ConfigDescription("Walking metres per second.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 5f), Array.Empty<object>()));
			RunSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Movement", "RunSpeed", 7f, new ConfigDescription("Running metres per second.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(3f, 15f), Array.Empty<object>()));
			RiverJump = ((BaseUnityPlugin)this).Config.Bind<float>("Movement", "RiverJumpDistance", 3.5f, new ConfigDescription("Maximum dry-bank leap in metres.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 6f), Array.Empty<object>()));
			LapOffset = ((BaseUnityPlugin)this).Config.Bind<Vector3>("Poses", "LapOffset", new Vector3(0f, 0.12f, 0.23f), "Offset from wearer hips in wearer-facing coordinates; tune against chairs and armor.");
			BackOffset = ((BaseUnityPlugin)this).Config.Bind<Vector3>("Poses", "BackOffset", new Vector3(0f, 0.13f, -0.13f), "Offset from upper spine while swimming, in bone-local coordinates.");
			BedStomachOffset = ((BaseUnityPlugin)this).Config.Bind<Vector3>("Poses", "BedStomachOffset", new Vector3(0f, 0.16f, 0f), "World-upright offset from sleeping hips, in wearer-facing coordinates.");
			BedHeadOffset = ((BaseUnityPlugin)this).Config.Bind<Vector3>("Poses", "BedHeadOffset", new Vector3(0.3f, 0.04f, 0f), "Offset beside sleeping head, in wearer-facing coordinates.");
			Assets = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "sageassets"));
			if (!Object.op_Implicit((Object)(object)Assets))
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Cannot load sageassets. Install it beside TheSageMod.dll. Sage registration disabled.");
				return;
			}
			SagePrefab = Assets.LoadAsset<GameObject>("SageVisual");
			if (!Object.op_Implicit((Object)(object)SagePrefab))
			{
				throw new InvalidDataException("sageassets is missing SageVisual");
			}
			harmony = new Harmony("com.smooshbound.sage");
			harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Sage loaded. Best Friend's Love is console-only: spawn SageBestFriendsLove 1");
		}

		private void Update()
		{
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)SagePrefab) || Time.time < scanAt)
			{
				return;
			}
			scanAt = Time.time + 0.2f;
			List<Player> allPlayers = Player.GetAllPlayers();
			foreach (Player item in allPlayers)
			{
				if (!Object.op_Implicit((Object)(object)item))
				{
					continue;
				}
				ZNetView component = ((Component)item).GetComponent<ZNetView>();
				if (!Object.op_Implicit((Object)(object)component) || !component.IsValid())
				{
					continue;
				}
				ZDO zDO = component.GetZDO();
				bool flag;
				if (component.IsOwner())
				{
					flag = !((Character)item).IsDead() && ((Humanoid)item).GetInventory().GetEquippedItems().Any((ItemData i) => i.m_shared.m_name == "Smooshbound Amulet");
					zDO.Set("sage_equipped", flag);
				}
				else
				{
					flag = zDO.GetBool("sage_equipped", false) && !((Character)item).IsDead();
				}
				SageCompanion value;
				if (flag && !companions.ContainsKey(item))
				{
					SageCompanion sageCompanion = new GameObject("Sage companion").AddComponent<SageCompanion>();
					sageCompanion.Initialize(item, component);
					companions.Add(item, sageCompanion);
				}
				else if (!flag && companions.TryGetValue(item, out value))
				{
					value.Dismiss();
					companions.Remove(item);
				}
			}
			KeyValuePair<Player, SageCompanion>[] array = companions.ToArray();
			for (int num = 0; num < array.Length; num++)
			{
				KeyValuePair<Player, SageCompanion> keyValuePair = array[num];
				if (!Object.op_Implicit((Object)(object)keyValuePair.Key) || !allPlayers.Contains(keyValuePair.Key) || !Object.op_Implicit((Object)(object)keyValuePair.Value))
				{
					if (Object.op_Implicit((Object)(object)keyValuePair.Value))
					{
						keyValuePair.Value.Dismiss();
					}
					companions.Remove(keyValuePair.Key);
				}
			}
		}

		private void OnDestroy()
		{
			foreach (SageCompanion value in companions.Values)
			{
				if (Object.op_Implicit((Object)(object)value))
				{
					value.Dismiss();
				}
			}
			companions.Clear();
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			if (Object.op_Implicit((Object)(object)Assets))
			{
				Assets.Unload(false);
			}
		}

		internal static void Error(Exception error)
		{
			((BaseUnityPlugin)Instance).Logger.LogError((object)error);
		}
	}
	internal static class Items
	{
		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		private static class DatabaseAwake
		{
			private static void Postfix(ObjectDB __instance)
			{
				Register(__instance);
			}
		}

		[HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")]
		private static class DatabaseCopied
		{
			private static void Postfix(ObjectDB __instance)
			{
				Register(__instance);
			}
		}

		[HarmonyPatch(typeof(ZNetScene), "Awake")]
		private static class SceneAwake
		{
			private static void Postfix(ZNetScene __instance)
			{
				RegisterNetwork(__instance);
			}
		}

		internal const string AmuletId = "SmooshboundAmulet";

		internal const string LoveId = "SageBestFriendsLove";

		internal const string AmuletName = "Smooshbound Amulet";

		private static GameObject storage;

		private static GameObject amulet;

		private static GameObject love;

		private static SE_Smooshbound blessing;

		internal static void Register(ObjectDB db)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)SagePlugin.Assets) || !Object.op_Implicit((Object)(object)db) || !Object.op_Implicit((Object)(object)db.GetItemPrefab("Silver")) || !Object.op_Implicit((Object)(object)db.GetItemPrefab("WolfHairBundle")))
			{
				return;
			}
			try
			{
				if (!Object.op_Implicit((Object)(object)storage))
				{
					storage = new GameObject("Sage prefab storage");
					storage.SetActive(false);
					Object.DontDestroyOnLoad((Object)(object)storage);
				}
				if (!Object.op_Implicit((Object)(object)love))
				{
					love = Create(db.GetItemPrefab("Silver"), "SageBestFriendsLove", "Best Friend's Love", "A love that follows you everywhere.", "SageLoveVisual", "Best_Friends_Love_Icon", trinket: false);
				}
				if (!Object.op_Implicit((Object)(object)amulet))
				{
					amulet = Create(db.GetItemPrefab("TrinketSilverResist"), "SmooshboundAmulet", "Smooshbound Amulet", "Some bonds are forged long before they are understood.", "SageAmuletVisual", "Sage_Amulet_Icon", trinket: true);
				}
				if (!Object.op_Implicit((Object)(object)blessing))
				{
					blessing = SE_Smooshbound.Create(amulet.GetComponent<ItemDrop>().m_itemData.m_shared.m_icons[0]);
				}
				if (!db.m_StatusEffects.Contains((StatusEffect)(object)blessing))
				{
					db.m_StatusEffects.Add((StatusEffect)(object)blessing);
				}
				SharedData shared = amulet.GetComponent<ItemDrop>().m_itemData.m_shared;
				shared.m_maxAdrenaline = 50f;
				shared.m_fullAdrenalineSE = (StatusEffect)(object)blessing;
				GameObject[] array = (GameObject[])(object)new GameObject[2] { love, amulet };
				foreach (GameObject item in array)
				{
					if (!db.m_items.Contains(item))
					{
						db.m_items.Add(item);
					}
				}
				AccessTools.Method(typeof(ObjectDB), "UpdateRegisters", (Type[])null, (Type[])null).Invoke(db, null);
				if (!db.m_recipes.Any((Recipe r) => Object.op_Implicit((Object)(object)r) && ((Object)r).name == "Recipe_SmooshboundAmulet"))
				{
					Recipe val = ScriptableObject.CreateInstance<Recipe>();
					((Object)val).name = "Recipe_SmooshboundAmulet";
					val.m_item = amulet.GetComponent<ItemDrop>();
					val.m_amount = 1;
					val.m_enabled = true;
					val.m_craftingStation = null;
					val.m_repairStation = null;
					val.m_minStationLevel = 0;
					val.m_resources = (Requirement[])(object)new Requirement[3]
					{
						Requirement(db, "Silver", 5),
						Requirement(db, "WolfHairBundle", 3),
						Requirement(db, "SageBestFriendsLove", 1)
					};
					db.m_recipes.Add(val);
				}
				if (Object.op_Implicit((Object)(object)ZNetScene.instance))
				{
					RegisterNetwork(ZNetScene.instance);
				}
			}
			catch (Exception error)
			{
				SagePlugin.Error(error);
			}
		}

		private static Requirement Requirement(ObjectDB db, string name, int count)
		{
			//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_0017: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			return new Requirement
			{
				m_resItem = db.GetItemPrefab(name).GetComponent<ItemDrop>(),
				m_amount = count,
				m_amountPerLevel = 0,
				m_recover = true
			};
		}

		private static GameObject Create(GameObject template, string id, string title, string description, string visual, string icon, bool trinket)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)template))
			{
				throw new InvalidDataException("Missing vanilla template for " + id);
			}
			GameObject val = Object.Instantiate<GameObject>(template, storage.transform);
			((Object)val).name = id;
			ItemDrop component = val.GetComponent<ItemDrop>();
			ItemData itemData = component.m_itemData;
			SharedData val2 = new SharedData();
			val2.m_name = title;
			val2.m_description = description;
			val2.m_itemType = (ItemType)((!trinket) ? 1 : 24);
			val2.m_maxStackSize = (trinket ? 1 : 20);
			val2.m_maxQuality = 1;
			val2.m_weight = (trinket ? 0.1f : 0.05f);
			val2.m_teleportable = true;
			val2.m_useDurability = false;
			val2.m_armor = 0f;
			val2.m_armorPerLevel = 0f;
			val2.m_blockPower = 0f;
			val2.m_blockPowerPerLevel = 0f;
			val2.m_deflectionForce = 0f;
			val2.m_deflectionForcePerLevel = 0f;
			val2.m_timedBlockBonus = 1f;
			val2.m_perfectBlockStaminaRegen = 0f;
			val2.m_perfectBlockStatusEffect = null;
			val2.m_equipStatusEffect = null;
			val2.m_setStatusEffect = null;
			val2.m_setName = "";
			val2.m_setSize = 0;
			val2.m_damageModifiers = new List<DamageModPair>();
			val2.m_eitrRegenModifier = 0f;
			val2.m_movementModifier = 0f;
			val2.m_homeItemsStaminaModifier = 0f;
			val2.m_heatResistanceModifier = 0f;
			val2.m_jumpStaminaModifier = 0f;
			val2.m_attackStaminaModifier = 0f;
			val2.m_blockStaminaModifier = 0f;
			val2.m_dodgeStaminaModifier = 0f;
			val2.m_swimStaminaModifier = 0f;
			val2.m_sneakStaminaModifier = 0f;
			val2.m_runStaminaModifier = 0f;
			val2.m_iceSkates = false;
			val2.m_iceShoes = false;
			val2.m_icons = (Sprite[])(object)new Sprite[1] { LoadIcon(icon) };
			itemData.m_shared = val2;
			component.m_itemData.m_dropPrefab = val;
			Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].enabled = false;
			}
			GameObject obj = Object.Instantiate<GameObject>(SagePlugin.Assets.LoadAsset<GameObject>(visual), val.transform);
			((Object)obj).name = "sage_visual";
			obj.transform.localPosition = Vector3.zero;
			obj.transform.localRotation = Quaternion.identity;
			val.SetActive(true);
			return val;
		}

		private static Sprite LoadIcon(string name)
		{
			//IL_0052: 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)
			Texture2D val = SagePlugin.Assets.LoadAsset<Texture2D>("assets/source/" + name.ToLowerInvariant() + ".png");
			if (!Object.op_Implicit((Object)(object)val))
			{
				throw new InvalidDataException("Missing Sage icon texture: " + name);
			}
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
		}

		internal static void RegisterNetwork(ZNetScene scene)
		{
			if (!Object.op_Implicit((Object)(object)amulet) || !Object.op_Implicit((Object)(object)love))
			{
				Register(ObjectDB.instance);
			}
			Dictionary<int, GameObject> dictionary = (Dictionary<int, GameObject>)AccessTools.Field(typeof(ZNetScene), "m_namedPrefabs").GetValue(scene);
			GameObject[] array = (GameObject[])(object)new GameObject[2] { amulet, love };
			foreach (GameObject val in array)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					if (!scene.m_prefabs.Contains(val))
					{
						scene.m_prefabs.Add(val);
					}
					dictionary[StringExtensionMethods.GetStableHashCode(((Object)val).name)] = val;
				}
			}
		}
	}
	public sealed class SE_Smooshbound : SE_Stats
	{
		internal const string EffectId = "SE_SmooshboundLove";

		internal static SE_Smooshbound Create(Sprite icon)
		{
			SE_Smooshbound sE_Smooshbound = ScriptableObject.CreateInstance<SE_Smooshbound>();
			((Object)sE_Smooshbound).name = "SE_SmooshboundLove";
			((StatusEffect)sE_Smooshbound).m_name = "Smooshbound Love";
			((StatusEffect)sE_Smooshbound).m_icon = icon;
			((StatusEffect)sE_Smooshbound).m_ttl = 45f;
			((StatusEffect)sE_Smooshbound).m_tooltip = "Jump height: +0.75 m\nRunning speed: +4%";
			((SE_Stats)sE_Smooshbound).m_staminaRegenMultiplier = 1.15f;
			((SE_Stats)sE_Smooshbound).m_eitrRegenMultiplier = 1.15f;
			return sE_Smooshbound;
		}

		public override void ModifySpeed(float baseSpeed, ref float speed, Character character, Vector3 direction)
		{
			if (Object.op_Implicit((Object)(object)character) && character.IsRunning() && !character.IsSwimming())
			{
				speed += baseSpeed * 0.04f;
			}
		}

		public override void ModifyJump(Vector3 baseJump, ref Vector3 jump)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (!(jump.y <= 0f))
			{
				jump.y = MovementPolicy.JumpVelocityForExtraHeight(jump.y, Mathf.Abs(Physics.gravity.y), 0.75f);
			}
		}
	}
}