Decompiled source of ShieldGolf v2.2.7

ShieldGolf.dll

Decompiled an hour ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using ShieldGolf.Core;
using ShieldGolf.Server;
using Splatform;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("ShieldGolf")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+731fc8a59a067e2ba21a3bcf33c7768e8b30665b")]
[assembly: AssemblyProduct("ShieldGolf")]
[assembly: AssemblyTitle("ShieldGolf")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ShieldGolf
{
	public static class AimHud
	{
		private const int X = 24;

		private const int FontSize = 20;

		private const int LineGap = 26;

		private const int UnderHotbar = 8;

		private const int FallbackY = 150;

		private const float RemeasureSec = 0.5f;

		private static GUIStyle _text;

		private static GUIStyle _shadow;

		private static readonly string[] NoLines = new string[0];

		private const int TopMargin = 12;

		private static float _top = 150f;

		private static float _measured = -10f;

		public static void Draw()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Invalid comparison between Unknown and I4
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_00a0: 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_00b9: Expected O, but got Unknown
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Expected O, but got Unknown
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: 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_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			if ((int)Event.current.type != 7)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead())
			{
				return;
			}
			bool flag = Plugin.AimReadoutOn.Value && PlayerPatches.Input.Tilting;
			string text = ((PlayerPatches.Input.Armed || TournamentClient.HoldsLie) ? TournamentClient.Status(localPlayer) : null);
			if (flag || text != null)
			{
				if (_text == null)
				{
					_text = new GUIStyle(GUI.skin.label)
					{
						fontSize = 20
					};
					_text.normal.textColor = new Color(1f, 0.95f, 0.8f);
					_shadow = new GUIStyle(_text);
					_shadow.normal.textColor = new Color(0f, 0f, 0f, 0.8f);
				}
				if (Time.unscaledTime - _measured > 0.5f)
				{
					_measured = Time.unscaledTime;
					_top = UnderTheHotbar();
				}
				string[] array = (flag ? AimReadout.Lines(PlayerPatches.Input.TiltDeg, PlayerPatches.Input.NoseDeg, PlayerPatches.Input.Forehand) : NoLines);
				if (text != null)
				{
					float x = _text.CalcSize(new GUIContent(text)).x;
					Rect val = default(Rect);
					((Rect)(ref val))..ctor(Mathf.Max(0f, ((float)Screen.width - x) / 2f), 12f, x + 8f, 30f);
					GUI.Label(new Rect(((Rect)(ref val)).x + 2f, ((Rect)(ref val)).y + 2f, ((Rect)(ref val)).width, ((Rect)(ref val)).height), text, _shadow);
					GUI.Label(val, text, _text);
				}
				Rect val2 = default(Rect);
				for (int i = 0; i < array.Length; i++)
				{
					((Rect)(ref val2))..ctor(24f, _top + (float)(i * 26), 700f, 30f);
					GUI.Label(new Rect(((Rect)(ref val2)).x + 2f, ((Rect)(ref val2)).y + 2f, ((Rect)(ref val2)).width, ((Rect)(ref val2)).height), array[i], _shadow);
					GUI.Label(val2, array[i], _text);
				}
			}
		}

		private static float UnderTheHotbar()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)Hud.instance == (Object)null)
				{
					return 150f;
				}
				HotkeyBar componentInChildren = ((Component)Hud.instance).GetComponentInChildren<HotkeyBar>(true);
				if ((Object)(object)componentInChildren == (Object)null)
				{
					return 150f;
				}
				Canvas componentInParent = ((Component)componentInChildren).GetComponentInParent<Canvas>();
				Camera val = (((Object)(object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0) ? componentInParent.rootCanvas.worldCamera : null);
				float num = float.MaxValue;
				Vector3[] array = (Vector3[])(object)new Vector3[4];
				RectTransform[] componentsInChildren = ((Component)componentInChildren).GetComponentsInChildren<RectTransform>(false);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].GetWorldCorners(array);
					Vector3[] array2 = array;
					foreach (Vector3 val2 in array2)
					{
						Vector2 val3 = RectTransformUtility.WorldToScreenPoint(val, val2);
						if (val3.y < num)
						{
							num = val3.y;
						}
					}
				}
				if (num == float.MaxValue)
				{
					return 150f;
				}
				return Mathf.Clamp((float)Screen.height - num + 8f, 0f, (float)(Screen.height - 52));
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[shieldgolf] aim readout: hotbar not measured: " + ex.Message));
				return 150f;
			}
		}
	}
	public static class BasketCommand
	{
		[HarmonyPatch(typeof(Terminal), "InitTerminal")]
		private static class InitTerminalPatch
		{
			[Serializable]
			[CompilerGenerated]
			private sealed class <>c
			{
				public static readonly <>c <>9 = new <>c();

				public static ConsoleEvent <>9__1_0;

				public static ConsoleOptionsFetcher <>9__1_1;

				internal void <Postfix>b__1_0(ConsoleEventArgs args)
				{
					Run(args);
				}

				internal List<string> <Postfix>b__1_1()
				{
					return new List<string>
					{
						"1", "2", "3", "4", "5", "6", "7", "8", "9", "remove",
						"help"
					};
				}
			}

			private static bool _added;

			private static void Postfix()
			{
				//IL_006b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0070: Unknown result type (might be due to invalid IL or missing references)
				//IL_0076: Expected O, but got Unknown
				//IL_009e: 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_0095: Unknown result type (might be due to invalid IL or missing references)
				//IL_009b: Expected O, but got Unknown
				if (_added)
				{
					return;
				}
				_added = true;
				string text = string.Format("[design] [distance] | remove | help - {0}: build basket 1 (iron funnel and chains), 2 (flat iron tray), 3 (gallows: a tray hanging from a curtain), 4 (backboard over a funnel), 5 (wood funnel, the default), 6 to 9 (raised and ring baskets, see discbasket help) from vanilla pieces this many metres ahead (default {1}, {2}-{3}); the pieces cost what the hammer charges; remove takes the nearest basket down", "ShieldGolf", Plugin.BasketDistance.Value, 3f, 20f);
				object obj = <>c.<>9__1_0;
				if (obj == null)
				{
					ConsoleEvent val = delegate(ConsoleEventArgs args)
					{
						Run(args);
					};
					<>c.<>9__1_0 = val;
					obj = (object)val;
				}
				object obj2 = <>c.<>9__1_1;
				if (obj2 == null)
				{
					ConsoleOptionsFetcher val2 = () => new List<string>
					{
						"1", "2", "3", "4", "5", "6", "7", "8", "9", "remove",
						"help"
					};
					<>c.<>9__1_1 = val2;
					obj2 = (object)val2;
				}
				new ConsoleCommand("discbasket", text, (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)obj2, false, false, false);
			}
		}

		[HarmonyPatch(typeof(Piece), "DropResources")]
		private static class DropResourcesPatch
		{
			private static bool Prefix(Piece __instance)
			{
				ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
				ZDO val = ((component != null) ? component.GetZDO() : null);
				if (val != null)
				{
					return !val.GetBool("shieldgolf_free", false);
				}
				return true;
			}
		}

		private const float MinDistance = 3f;

		private const float MaxDistance = 20f;

		private const int Designs = 9;

		private const string BasketKey = "shieldgolf_basket";

		private const string FreeKey = "shieldgolf_free";

		private const string DesignKey = "shieldgolf_design";

		private const float RemoveReach = 8f;

		private const float BasketSpan = 6f;

		private static readonly HashSet<string> SizesLogged = new HashSet<string>();

		private static void Run(ConsoleEventArgs args)
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)ZNetScene.instance == (Object)null || (Object)(object)ZoneSystem.instance == (Object)null)
			{
				return;
			}
			try
			{
				((BaseUnityPlugin)Plugin.Instance).Config.Reload();
				List<string> list = CommandArgs.Words(args.Args);
				if (list.Count > 0 && list[0] == "remove")
				{
					Remove(localPlayer);
					return;
				}
				int result = Mathf.Clamp(Plugin.BasketDesign.Value, 1, 9);
				float result2 = Plugin.BasketDistance.Value;
				if (list.Count > 0 && (!int.TryParse(list[0], out result) || result < 1 || result > 9))
				{
					string text = $"discbasket [design 1-{9}] [distance {3f}-{20f} m] builds a basket ahead of you from ordinary pieces, " + $"at the hammer's price: 1 iron funnel and chains, 2 flat iron tray, 3 gallows, 4 backboard, 5 wood funnel, 6 wood ring, 7 small wood ring, 8 light wood ring, 9 lowered light wood ring (no number: {Plugin.BasketDesign.Value}); " + $"discbasket 2 8 is design 2, 8 m ahead; discbasket remove takes the nearest basket (within {8f} m) down and refunds it";
					args.Context.AddString(text);
					return;
				}
				if (list.Count > 1 && !float.TryParse(list[1], NumberStyles.Float, CultureInfo.InvariantCulture, out result2))
				{
					args.Context.AddString("discbasket: the second number is the distance in metres, got " + list[1]);
					return;
				}
				bool globalKey = ZoneSystem.instance.GetGlobalKey((GlobalKeys)24);
				bool flag = !globalKey && (Plugin.BasketFree.Value || localPlayer.NoCostCheat());
				if (flag && !args.Context.IsCheatsEnabled())
				{
					args.Context.AddString("discbasket: free baskets ([basket] free) need devcommands in a world this game hosts; set free = false to pay for the parts");
				}
				else
				{
					Build(localPlayer, result, Mathf.Clamp(result2, 3f, 20f), flag, globalKey);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("discbasket failed: " + ex));
				Notify.Refusal("ShieldGolf: basket failed, see the BepInEx log");
			}
		}

		private static void Build(Player p, int design, float distance, bool free, bool worldFree)
		{
			//IL_0025: 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)
			//IL_004e: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: 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_00dd: 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)
			if (!Resolve(design, out var pieces, out var layout, out var missing))
			{
				Notify.Refusal("No building piece called " + missing);
				return;
			}
			Vector3 val = ((Component)p).transform.forward;
			val.y = 0f;
			val = ((((Vector3)(ref val)).sqrMagnitude < 0.0001f) ? Vector3.forward : ((Vector3)(ref val)).normalized);
			Vector3 val2 = ((Component)p).transform.position + val * distance;
			float y = default(float);
			if (!ZoneSystem.instance.GetSolidHeight(val2, ref y, 1000))
			{
				Notify.Refusal("$msg_invalidplacement");
				return;
			}
			val2.y = y;
			if (Location.IsInsideNoBuildLocation(val2))
			{
				Notify.Refusal("$msg_nobuildzone");
			}
			else if (!PrivateArea.CheckAccess(val2, 3f, true, false))
			{
				Notify.Refusal("$msg_privatezone");
			}
			else if (free || worldFree || Pay(p, layout, pieces))
			{
				PlaceParts(p, design, pieces, layout, val2, Quaternion.LookRotation(val), free);
				Notify.Result($"Basket {design} built" + (worldFree ? " (no build cost in this world)" : ""));
			}
		}

		private static void Remove(Player p)
		{
			//IL_0006: 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)
			Piece val = NearestBasketPiece(((Component)p).transform.position, 8f);
			if ((Object)(object)val == (Object)null)
			{
				Notify.Refusal($"No basket within {8f} m (baskets built before this version are removed with the hammer)");
				return;
			}
			if (!PrivateArea.CheckAccess(((Component)val).transform.position, 2f, true, false))
			{
				Notify.Refusal("$msg_privatezone");
				return;
			}
			int num = RemoveBasket(BasketId(val), ((Component)val).transform.position, null);
			Plugin.Log.LogInfo((object)$"discbasket remove: {num} pieces");
			Notify.Result($"Basket removed ({num} pieces)");
		}

		internal static bool Resolve(int design, out Dictionary<string, Piece> pieces, out List<BasketPart> layout, out string missing)
		{
			Catch c;
			return Resolve(design, out pieces, out layout, out c, out missing);
		}

		internal static bool Resolve(int design, out Dictionary<string, Piece> pieces, out List<BasketPart> layout, out Catch c, out string missing)
		{
			layout = null;
			missing = null;
			c = default(Catch);
			string[] names;
			switch (design)
			{
			case 1:
				names = new string[5]
				{
					Plugin.FunnelPole.Value,
					Plugin.FunnelRoof.Value,
					Plugin.FunnelCrown.Value,
					Plugin.FunnelHanger.Value,
					Plugin.FunnelRim.Value
				};
				break;
			case 5:
				names = new string[5]
				{
					Plugin.WoodPole.Value,
					Plugin.WoodRoof.Value,
					Plugin.WoodCrown.Value,
					Plugin.WoodHanger.Value,
					Plugin.WoodRim.Value
				};
				break;
			case 6:
				names = new string[6]
				{
					Plugin.WoodPole.Value,
					Plugin.WoodCrown.Value,
					Plugin.RingHanger.Value,
					Plugin.RingBeam.Value,
					Plugin.RingTile.Value,
					Plugin.WoodPole.Value
				};
				break;
			case 7:
				names = new string[6]
				{
					Plugin.WoodPole.Value,
					Plugin.RingBeam.Value,
					Plugin.RingHanger.Value,
					Plugin.RingBeam.Value,
					Plugin.RingTile.Value,
					Plugin.RingHanger.Value
				};
				break;
			case 8:
			case 9:
				names = new string[6]
				{
					Plugin.WoodPole.Value,
					Plugin.WoodCrown.Value,
					Plugin.RingHanger.Value,
					Plugin.RingBeam.Value,
					Plugin.RingTile.Value,
					Plugin.LightRingChain.Value
				};
				break;
			case 2:
				names = new string[4]
				{
					Plugin.TrayPole.Value,
					Plugin.TrayTile.Value,
					Plugin.TrayRim.Value,
					Plugin.TrayCrown.Value
				};
				break;
			case 3:
				names = new string[5]
				{
					Plugin.GallowsPost.Value,
					Plugin.GallowsBeam.Value,
					Plugin.GallowsHanger.Value,
					Plugin.GallowsTray.Value,
					Plugin.GallowsRim.Value
				};
				break;
			default:
				names = new string[5]
				{
					Plugin.BoardPole.Value,
					Plugin.BoardPost.Value,
					Plugin.BoardRoof.Value,
					Plugin.BoardWall.Value,
					Plugin.BoardBeam.Value
				};
				break;
			}
			pieces = new Dictionary<string, Piece>();
			string[] array = names;
			foreach (string text in array)
			{
				if (!string.IsNullOrEmpty(text))
				{
					GameObject prefab = ZNetScene.instance.GetPrefab(text);
					Piece val = (((Object)(object)prefab == (Object)null) ? null : prefab.GetComponent<Piece>());
					if ((Object)(object)val == (Object)null)
					{
						missing = text;
						return false;
					}
					pieces[text] = val;
				}
			}
			Dictionary<string, Piece> found = pieces;
			Func<int, Box> func = (int num2) => LocalBox(((Component)found[names[num2]]).gameObject);
			switch (design)
			{
			case 6:
			case 7:
			case 8:
			case 9:
			{
				RingBasketPieces p5 = new RingBasketPieces
				{
					Pole = names[0],
					Crown = names[1],
					Hanger = names[2],
					Beam = names[3],
					Tile = names[4],
					LongHanger = names[5],
					PoleBox = func(0),
					CrownBox = func(1),
					HangerBox = func(2),
					BeamBox = func(3),
					TileBox = func(4),
					LongHangerBox = func(5)
				};
				LogSizesOnce(names, func);
				if (design >= 8)
				{
					if (!SlantOf(((Component)found[names[5]]).gameObject, out p5.SlantAxis, out p5.SlantLength))
					{
						missing = names[5] + " (no long collider)";
						return false;
					}
					p5.SlantSink = ((design == 9) ? 1f : 0.3f);
				}
				float num = ((design == 6) ? 2f : 1.5f);
				float bandOverRim = ((design == 6) ? float.NaN : Plugin.SmallRingOverRim.Value);
				float leanDeg = ((design == 6) ? Plugin.RingLean.Value : Plugin.SmallRingLean.Value);
				layout = BasketLayout.BuildRing(p5, Plugin.RingTrayLow.Value, Plugin.RingSlope.Value, leanDeg, num, bandOverRim, (design >= 8) ? 8 : 16);
				c = BasketCatch.Ring(p5, Plugin.RingTrayLow.Value, Plugin.RingSlope.Value, num);
				break;
			}
			case 1:
			case 5:
			{
				FunnelBasketPieces p4 = new FunnelBasketPieces
				{
					Pole = names[0],
					Roof = names[1],
					Crown = names[2],
					Hanger = names[3],
					Rim = names[4],
					PoleBox = func(0),
					RoofEdges = RoofEdges(((Component)pieces[names[1]]).gameObject),
					CrownBox = func(2),
					HangerBox = func(3),
					RimBox = (string.IsNullOrEmpty(names[4]) ? default(Box) : func(4))
				};
				float funnelLow = ((design == 1) ? Plugin.FunnelLow.Value : Plugin.WoodFunnelLow.Value);
				layout = BasketLayout.BuildFunnel(p4, funnelLow);
				c = BasketCatch.Funnel(p4, funnelLow);
				break;
			}
			case 2:
			{
				TrayBasketPieces p3 = new TrayBasketPieces
				{
					Pole = names[0],
					Tray = names[1],
					Rim = names[2],
					Crown = names[3],
					PoleBox = func(0),
					TrayBox = func(1),
					RimBox = func(2),
					CrownBox = func(3)
				};
				layout = BasketLayout.BuildTray(p3, Plugin.TrayHeight.Value, Plugin.TrayTiles.Value);
				c = BasketCatch.Tray(p3, Plugin.TrayHeight.Value, Plugin.TrayTiles.Value);
				break;
			}
			case 3:
			{
				GallowsPieces p2 = new GallowsPieces
				{
					Post = names[0],
					Beam = names[1],
					Hanger = names[2],
					Tray = names[3],
					Rim = names[4],
					PostBox = func(0),
					BeamBox = func(1),
					HangerBox = func(2),
					TrayBox = func(3),
					RimBox = func(4)
				};
				layout = BasketLayout.BuildGallows(p2, Plugin.GallowsHangers.Value);
				c = BasketCatch.Gallows(p2);
				break;
			}
			default:
			{
				BackboardPieces p = new BackboardPieces
				{
					Pole = names[0],
					Post = names[1],
					Roof = names[2],
					Wall = names[3],
					Beam = names[4],
					PoleBox = func(0),
					PostBox = func(1),
					RoofEdges = RoofEdges(((Component)pieces[names[2]]).gameObject),
					WallBox = func(3),
					BeamBox = func(4)
				};
				layout = BasketLayout.BuildBackboard(p, Plugin.BoardFunnelLow.Value, Plugin.BoardRows.Value);
				c = BasketCatch.Backboard(p, Plugin.BoardFunnelLow.Value);
				break;
			}
			}
			return true;
		}

		internal static void PlaceParts(Player p, int design, Dictionary<string, Piece> pieces, List<BasketPart> layout, Vector3 origin, Quaternion facing, bool free)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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_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_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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_00a9: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: 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_016f: 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)
			long num = ((long)Random.Range(1, int.MaxValue) << 31) | (uint)Random.Range(1, int.MaxValue);
			PlatformUserID platformUserID = ((IUser)PlatformManager.DistributionPlatform.LocalUser).PlatformUserID;
			Piece val = null;
			foreach (BasketPart item in layout)
			{
				Piece val2 = pieces[item.Prefab];
				if ((Object)(object)val == (Object)null)
				{
					val = val2;
				}
				Vector3 val3 = origin + facing * UnityV3.ToUnity(item.Pivot);
				Quaternion val4 = facing * Quaternion.Euler(0f, item.Yaw, 0f) * Quaternion.Euler(item.Pitch, 0f, 0f);
				GameObject obj = Object.Instantiate<GameObject>(((Component)val2).gameObject, val3, val4);
				Piece component = obj.GetComponent<Piece>();
				if (component != null)
				{
					component.SetCreator(p.GetPlayerID(), platformUserID);
				}
				ZNetView component2 = obj.GetComponent<ZNetView>();
				ZDO val5 = ((component2 != null) ? component2.GetZDO() : null);
				if (val5 != null)
				{
					val5.Set("shieldgolf_basket", num);
					val5.Set("shieldgolf_design", design);
					if (free)
					{
						val5.Set("shieldgolf_free", true);
						CheatMark.Apply(val5);
					}
				}
				WearNTear component3 = obj.GetComponent<WearNTear>();
				if (component3 != null)
				{
					component3.OnPlaced();
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				val.m_placeEffect.Create(origin, facing, (Transform)null, 1f, -1, default(ZDOID));
			}
			Plugin.Log.LogInfo((object)$"discbasket: {layout.Count} pieces at {origin}");
		}

		internal static List<KeyValuePair<ItemDrop, int>> Cost(List<BasketPart> layout, Dictionary<string, Piece> pieces)
		{
			Dictionary<string, KeyValuePair<ItemDrop, int>> dictionary = new Dictionary<string, KeyValuePair<ItemDrop, int>>();
			foreach (KeyValuePair<string, int> item in BasketLayout.Count(layout))
			{
				Requirement[] resources = pieces[item.Key].m_resources;
				foreach (Requirement val in resources)
				{
					if (!((Object)(object)val.m_resItem == (Object)null) && val.m_amount > 0)
					{
						string name = val.m_resItem.m_itemData.m_shared.m_name;
						KeyValuePair<ItemDrop, int> value;
						int num = (dictionary.TryGetValue(name, out value) ? value.Value : 0);
						dictionary[name] = new KeyValuePair<ItemDrop, int>(val.m_resItem, num + val.m_amount * item.Value);
					}
				}
			}
			return dictionary.Values.ToList();
		}

		private static bool Pay(Player p, List<BasketPart> layout, Dictionary<string, Piece> pieces)
		{
			Dictionary<string, int> dictionary = Cost(layout, pieces).ToDictionary((KeyValuePair<ItemDrop, int> kv) => kv.Key.m_itemData.m_shared.m_name, (KeyValuePair<ItemDrop, int> kv) => kv.Value);
			Inventory inv = ((Humanoid)p).GetInventory();
			List<string> list = (from kv in dictionary
				where inv.CountItems(kv.Key, -1, true) < kv.Value
				select $"{kv.Value - inv.CountItems(kv.Key, -1, true)} {kv.Key}").ToList();
			if (list.Count > 0)
			{
				Notify.Refusal("A basket needs " + string.Join(", ", list) + " more");
				return false;
			}
			foreach (KeyValuePair<string, int> item in dictionary)
			{
				inv.RemoveItem(item.Key, item.Value, -1, true);
			}
			return true;
		}

		private static void LogSizesOnce(string[] names, Func<int, Box> box)
		{
			for (int i = 0; i < names.Length; i++)
			{
				if (!string.IsNullOrEmpty(names[i]) && SizesLogged.Add(names[i]))
				{
					Box box2 = box(i);
					Plugin.Log.LogInfo((object)$"[shieldgolf] piece size {names[i]}: min ({box2.Min.X:0.###}, {box2.Min.Y:0.###}, {box2.Min.Z:0.###}) max ({box2.Max.X:0.###}, {box2.Max.Y:0.###}, {box2.Max.Z:0.###})");
				}
			}
		}

		internal static bool SlantOf(GameObject prefab, out V3 axis, out float length)
		{
			//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_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: 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_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: 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_0133: 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)
			//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_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: 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_016c: 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_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: 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_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: 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_01b3: Unknown result type (might be due to invalid IL or missing references)
			axis = default(V3);
			length = 0f;
			Transform transform = prefab.transform;
			Vector3 val = Vector3.zero;
			Collider[] componentsInChildren = prefab.GetComponentsInChildren<Collider>(true);
			foreach (Collider val2 in componentsInChildren)
			{
				if (val2.isTrigger)
				{
					continue;
				}
				_ = Vector3.zero;
				BoxCollider val3 = (BoxCollider)(object)((val2 is BoxCollider) ? val2 : null);
				CapsuleCollider val4 = (CapsuleCollider)(object)((val2 is CapsuleCollider) ? val2 : null);
				MeshCollider val5 = (MeshCollider)(object)((val2 is MeshCollider) ? val2 : null);
				Vector3 val6;
				if ((Object)(object)val3 != (Object)null)
				{
					val6 = val3.size;
				}
				else if ((Object)(object)val4 != (Object)null)
				{
					val6 = ((val4.direction == 0) ? new Vector3(val4.height, 0f, 0f) : ((val4.direction == 1) ? new Vector3(0f, val4.height, 0f) : new Vector3(0f, 0f, val4.height)));
				}
				else
				{
					if (!((Object)(object)val5 != (Object)null) || !((Object)(object)val5.sharedMesh != (Object)null))
					{
						continue;
					}
					Bounds bounds = val5.sharedMesh.bounds;
					val6 = ((Bounds)(ref bounds)).size;
				}
				Vector3 val7 = ((val6.x >= val6.y && val6.x >= val6.z) ? new Vector3(val6.x, 0f, 0f) : ((val6.y >= val6.z) ? new Vector3(0f, val6.y, 0f) : new Vector3(0f, 0f, val6.z)));
				Vector3 val8 = transform.InverseTransformVector(((Component)val2).transform.TransformVector(val7));
				if (((Vector3)(ref val8)).magnitude > ((Vector3)(ref val)).magnitude)
				{
					val = val8;
				}
			}
			if (((Vector3)(ref val)).magnitude < 0.5f)
			{
				return false;
			}
			if (val.y < 0f)
			{
				val = -val;
			}
			length = ((Vector3)(ref val)).magnitude;
			Vector3 val9 = val / length;
			axis = UnityV3.ToV3(val9);
			if (SizesLogged.Add(((Object)prefab).name + "#slant"))
			{
				Plugin.Log.LogInfo((object)$"[shieldgolf] piece slant {((Object)prefab).name}: axis ({val9.x:0.###}, {val9.y:0.###}, {val9.z:0.###}) = {Mathf.Acos(val9.y) * 57.29578f:0.#}° from upright, length {length:0.###}");
			}
			return true;
		}

		internal static Box LocalBox(GameObject prefab)
		{
			//IL_0022: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: 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_0124: Unknown result type (might be due to invalid IL or missing references)
			Transform root = prefab.transform;
			Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
			Vector3 max = -min;
			bool any = false;
			Action<Transform, Bounds> action = delegate(Transform t, Bounds b)
			{
				//IL_001e: 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_003d: 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_005c: 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_0072: 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_0078: Unknown result type (might be due to invalid IL or missing references)
				//IL_007d: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_0086: 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_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)
				Vector3 val5 = default(Vector3);
				for (int i = 0; i < 8; i++)
				{
					((Vector3)(ref val5))..ctor(((i & 1) == 0) ? ((Bounds)(ref b)).min.x : ((Bounds)(ref b)).max.x, ((i & 2) == 0) ? ((Bounds)(ref b)).min.y : ((Bounds)(ref b)).max.y, ((i & 4) == 0) ? ((Bounds)(ref b)).min.z : ((Bounds)(ref b)).max.z);
					Vector3 val6 = root.InverseTransformPoint(t.TransformPoint(val5));
					min = Vector3.Min(min, val6);
					max = Vector3.Max(max, val6);
				}
				any = true;
			};
			Collider[] componentsInChildren = prefab.GetComponentsInChildren<Collider>(true);
			foreach (Collider val in componentsInChildren)
			{
				if (!val.isTrigger)
				{
					BoxCollider val2 = (BoxCollider)(object)((val is BoxCollider) ? val : null);
					MeshCollider val3 = (MeshCollider)(object)((val is MeshCollider) ? val : null);
					if ((Object)(object)val2 != (Object)null)
					{
						action(((Component)val).transform, new Bounds(val2.center, val2.size));
					}
					else if ((Object)(object)val3 != (Object)null && (Object)(object)val3.sharedMesh != (Object)null)
					{
						action(((Component)val).transform, val3.sharedMesh.bounds);
					}
				}
			}
			if (!any)
			{
				MeshFilter[] componentsInChildren2 = prefab.GetComponentsInChildren<MeshFilter>(true);
				foreach (MeshFilter val4 in componentsInChildren2)
				{
					if ((Object)(object)val4.sharedMesh != (Object)null)
					{
						action(((Component)val4).transform, val4.sharedMesh.bounds);
					}
				}
			}
			if (!any)
			{
				throw new InvalidOperationException(((Object)prefab).name + " has no collider or mesh to measure");
			}
			return new Box(UnityV3.ToV3(min), UnityV3.ToV3(max));
		}

		private static Roof RoofEdges(GameObject prefab)
		{
			Transform root = prefab.transform;
			List<Vector3> list = (from t in prefab.GetComponentsInChildren<Transform>(true)
				where ((Object)t).name.StartsWith("$hud_snappoint", StringComparison.Ordinal)
				select root.InverseTransformPoint(t.position)).ToList();
			if (list.Count < 2)
			{
				throw new InvalidOperationException(((Object)prefab).name + " has no snap points to find its slope");
			}
			float lo = list.Min((Vector3 v) => v.y);
			float hi = list.Max((Vector3 v) => v.y);
			if (hi - lo < 0.1f)
			{
				throw new InvalidOperationException(((Object)prefab).name + " is not sloped");
			}
			Func<IEnumerable<Vector3>, V3> func = delegate(IEnumerable<Vector3> vs)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				List<Vector3> list2 = vs.ToList();
				return UnityV3.ToV3(list2.Aggregate(Vector3.zero, (Vector3 a, Vector3 b) => a + b) / (float)list2.Count);
			};
			V3 low = func(list.Where((Vector3 v) => v.y < lo + 0.05f));
			float reach = list.Max((Vector3 v) => Math.Max(Math.Abs(v.x - low.X), Math.Abs(v.z - low.Z)));
			return new Roof
			{
				LowEdge = low,
				HighEdge = func(list.Where((Vector3 v) => v.y > hi - 0.05f)),
				Reach = reach
			};
		}

		internal static Piece NearestBasketPiece(Vector3 at, float reach)
		{
			//IL_0006: 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)
			List<Piece> list = new List<Piece>();
			Piece.GetAllPiecesInRadius(at, reach, list);
			Piece result = null;
			float num = float.MaxValue;
			foreach (Piece item in list)
			{
				if (BasketId(item) != 0L)
				{
					float num2 = Vector3.Distance(((Component)item).transform.position, at);
					if (num2 < num)
					{
						num = num2;
						result = item;
					}
				}
			}
			return result;
		}

		internal static List<Piece> PiecesOf(long id, Vector3 at, float radius = 6f)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			List<Piece> list = new List<Piece>();
			Piece.GetAllPiecesInRadius(at, radius, list);
			list.RemoveAll((Piece x) => BasketId(x) != id);
			return list;
		}

		internal static int DesignOf(List<Piece> parts)
		{
			foreach (Piece part in parts)
			{
				ZNetView component = ((Component)part).GetComponent<ZNetView>();
				ZDO val = ((component != null) ? component.GetZDO() : null);
				int num = ((val != null) ? val.GetInt("shieldgolf_design", 0) : 0);
				if (num > 0)
				{
					return num;
				}
			}
			HashSet<string> hashSet = new HashSet<string>();
			foreach (Piece part2 in parts)
			{
				hashSet.Add(Utils.GetPrefabName(((Component)part2).gameObject));
			}
			int num2 = 0;
			foreach (Piece part3 in parts)
			{
				if (Utils.GetPrefabName(((Component)part3).gameObject) == Plugin.RingBeam.Value)
				{
					num2++;
				}
			}
			if (num2 > 0)
			{
				if (!hashSet.Contains(Plugin.LightRingChain.Value))
				{
					if (!hashSet.Contains(Plugin.WoodCrown.Value))
					{
						return 7;
					}
					return 6;
				}
				return 8;
			}
			if (hashSet.Contains(Plugin.WoodRoof.Value) || hashSet.Contains(Plugin.FunnelRoof.Value) || hashSet.Contains(Plugin.BoardRoof.Value))
			{
				if (hashSet.Contains(Plugin.BoardWall.Value))
				{
					return 4;
				}
				if (!hashSet.Contains(Plugin.WoodCrown.Value) || hashSet.Contains(Plugin.FunnelCrown.Value))
				{
					return 1;
				}
				return 5;
			}
			if (hashSet.Contains(Plugin.GallowsBeam.Value))
			{
				return 3;
			}
			if (hashSet.Contains(Plugin.TrayTile.Value))
			{
				return 2;
			}
			return 0;
		}

		internal static bool Frame(List<Piece> parts, List<BasketPart> layout, out Vector3 origin, out Quaternion facing)
		{
			//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_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_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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: 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_0091: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: 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_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: 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_014a: 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_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			origin = Vector3.zero;
			facing = Quaternion.identity;
			string pole = layout[0].Prefab;
			List<Piece> list = parts.FindAll((Piece x) => Utils.GetPrefabName(((Component)x).gameObject) == pole && ((Component)x).transform.up.y > 0.99f);
			List<BasketPart> list2 = layout.FindAll((BasketPart x) => x.Prefab == pole && x.Yaw == 0f && x.Pitch == 0f);
			if (list.Count == 0 || list2.Count == 0)
			{
				return false;
			}
			Vector3 val = Vector3.zero;
			foreach (Piece item in list)
			{
				val += ((Component)item).transform.position;
			}
			val /= (float)list.Count;
			V3 zero = V3.Zero;
			foreach (BasketPart item2 in list2)
			{
				zero += item2.Pivot;
			}
			zero /= (float)list2.Count;
			Quaternion rotation = ((Component)list[0]).transform.rotation;
			facing = Quaternion.Euler(0f, ((Quaternion)(ref rotation)).eulerAngles.y, 0f);
			origin = val - facing * UnityV3.ToUnity(zero);
			return true;
		}

		internal static long BasketId(Piece piece)
		{
			object obj;
			if (!((Object)(object)piece == (Object)null))
			{
				ZNetView component = ((Component)piece).GetComponent<ZNetView>();
				obj = ((component != null) ? component.GetZDO() : null);
			}
			else
			{
				obj = null;
			}
			ZDO val = (ZDO)obj;
			if (val != null)
			{
				return val.GetLong("shieldgolf_basket", 0L);
			}
			return 0L;
		}

		internal static int RemoveBasket(long id, Vector3 at, Piece skip, float radius = 6f)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			List<Piece> list = new List<Piece>();
			Piece.GetAllPiecesInRadius(at, radius, list);
			int num = 0;
			foreach (Piece item in list)
			{
				if (!((Object)(object)item == (Object)(object)skip))
				{
					ZNetView component = ((Component)item).GetComponent<ZNetView>();
					ZDO val = (((Object)(object)component == (Object)null) ? null : component.GetZDO());
					if (val != null && val.GetLong("shieldgolf_basket", 0L) == id)
					{
						component.ClaimOwnership();
						item.DropResources((HitData)null);
						ZNetScene.instance.Destroy(((Component)item).gameObject);
						num++;
					}
				}
			}
			return num;
		}
	}
	public class BasketStandIn : MonoBehaviour
	{
		public int Design;
	}
	public static class BasketHammer
	{
		[HarmonyPatch(typeof(Player), "PlacePiece")]
		private static class PlacePiecePatch
		{
			private static bool Prefix(Player __instance, Piece piece, Vector3 pos, Quaternion rot, bool cheated)
			{
				//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_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_004f: Unknown result type (might be due to invalid IL or missing references)
				BasketStandIn basketStandIn = (((Object)(object)piece == (Object)null) ? null : ((Component)piece).GetComponent<BasketStandIn>());
				if ((Object)(object)basketStandIn == (Object)null)
				{
					return true;
				}
				try
				{
					if (BasketCommand.Resolve(basketStandIn.Design, out var pieces, out var layout, out var missing))
					{
						Anchor(layout[0], pos, rot, out var origin, out var facing);
						BasketCommand.PlaceParts(__instance, basketStandIn.Design, pieces, layout, origin, facing, cheated);
					}
					else
					{
						Plugin.Log.LogError((object)$"hammer: basket {basketStandIn.Design} not built, no building piece called {missing}");
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)("hammer: basket not built: " + ex));
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(Player), "RemovePiece")]
		private static class RemovePiecePatch
		{
			internal sealed class Target
			{
				public Piece Piece;

				public long Id;

				public Vector3 At;
			}

			private static readonly FieldRef<Player, int> RemoveMask = AccessTools.FieldRefAccess<Player, int>("m_removeRayMask");

			private const float HammerReach = 10f;

			private static void Prefix(Player __instance, out Target __state)
			{
				//IL_0018: 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_0076: Unknown result type (might be due to invalid IL or missing references)
				//IL_007b: Unknown result type (might be due to invalid IL or missing references)
				__state = null;
				try
				{
					GameCamera instance = GameCamera.instance;
					RaycastHit val = default(RaycastHit);
					if (!((Object)(object)instance == (Object)null) && Physics.Raycast(((Component)instance).transform.position, ((Component)instance).transform.forward, ref val, 50f, RemoveMask.Invoke(__instance)))
					{
						Piece componentInParent = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Piece>();
						long num = BasketCommand.BasketId(componentInParent);
						if (num != 0L)
						{
							__state = new Target
							{
								Piece = componentInParent,
								Id = num,
								At = ((Component)componentInParent).transform.position
							};
						}
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)("hammer: basket lookup failed: " + ex));
				}
			}

			private static void Postfix(bool __result, Target __state)
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				if (!__result || __state == null)
				{
					return;
				}
				try
				{
					int num = BasketCommand.RemoveBasket(__state.Id, __state.At, __state.Piece, 10f);
					Plugin.Log.LogInfo((object)$"hammer: basket removed ({num + 1} pieces)");
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)("hammer: basket removal failed: " + ex));
				}
			}
		}

		private static readonly int[] Order = new int[9] { 5, 6, 7, 8, 9, 1, 2, 3, 4 };

		private static readonly string[] Titles = new string[10] { "", "Disc basket: iron funnel", "Disc basket: iron tray", "Disc basket: gallows", "Disc basket: backboard", "Disc basket: wood funnel", "Disc basket: wood ring", "Disc basket: small wood ring", "Disc basket: light wood ring", "Disc basket: lowered light wood ring" };

		private static readonly string[] Blurbs = new string[10] { "", "Iron crown and chains over a thatch funnel that slides a shield to the pole.", "A flat iron tray on a pole, with a rim and a crossed crown.", "An iron tray hanging from a curtain of iron poles between two posts.", "A thatch funnel with a wooden wall behind it: bank it off the wall.", "Wood crown and wooden chains over a thatch funnel. No iron needed.", "A round basket: a ring of wood beams on a tray sloping to the pole, a spoked top with log chains leaning in to the pole. No iron needed.", "The wood ring's harder little sister: 3.6 m across, its top set low, sixteen short log chains ending at the rim. No iron needed.", "An hourglass of eight slanted logs crossing beside the pole, a wide band over their tops: the whole tray is open under it. No iron needed.", "The light wood ring a metre deep in the ground: its tray at knee height. No iron needed." };

		private static readonly MethodInfo UpdateKnown = AccessTools.Method(typeof(Player), "UpdateKnownRecipesList", (Type[])null, (Type[])null);

		private static GameObject _holder;

		private static readonly List<GameObject> StandIns = new List<GameObject>();

		private static bool _failed;

		private static readonly MethodInfo LoadImage = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule")?.GetMethod("LoadImage", new Type[2]
		{
			typeof(Texture2D),
			typeof(byte[])
		});

		public static void Tick(Player p)
		{
			if (_failed || (Object)(object)p == (Object)null || (Object)(object)ZNetScene.instance == (Object)null || (Object)(object)ObjectDB.instance == (Object)null)
			{
				return;
			}
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("Hammer");
			PieceTable val = (((Object)(object)itemPrefab == (Object)null) ? null : itemPrefab.GetComponent<ItemDrop>()?.m_itemData?.m_shared?.m_buildPieces);
			if ((Object)(object)val == (Object)null || (StandIns.Count > 0 && StandIns.All(val.m_pieces.Contains)))
			{
				return;
			}
			try
			{
				if (StandIns.Count == 0)
				{
					Make();
				}
				if (StandIns.Count == 0)
				{
					_failed = true;
					Plugin.Log.LogWarning((object)"hammer: no disc basket could be laid out, none in the Misc tab");
					return;
				}
				foreach (GameObject standIn in StandIns)
				{
					if (!val.m_pieces.Contains(standIn))
					{
						val.m_pieces.Add(standIn);
					}
				}
				UpdateKnown?.Invoke(p, null);
				Plugin.Log.LogInfo((object)$"hammer: {StandIns.Count} disc baskets in the Misc tab");
			}
			catch (Exception ex)
			{
				_failed = true;
				Plugin.Log.LogError((object)("hammer baskets failed, use discbasket instead: " + ex));
			}
		}

		private static void Make()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			_holder = new GameObject("shieldgolf_basket_standins");
			_holder.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)_holder);
			int[] order = Order;
			foreach (int num in order)
			{
				try
				{
					if (!BasketCommand.Resolve(num, out var pieces, out var layout, out var missing))
					{
						Plugin.Log.LogWarning((object)$"hammer: basket {num} left out, no building piece called {missing}");
					}
					else
					{
						StandIns.Add(StandIn(num, pieces, layout));
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)$"hammer: basket {num} left out: {ex.Message}");
				}
			}
		}

		private static GameObject StandIn(int design, Dictionary<string, Piece> pieces, List<BasketPart> layout)
		{
			//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_00ea: 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_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			BasketPart basketPart = layout[0];
			Piece val = pieces[basketPart.Prefab];
			GameObject val2 = Object.Instantiate<GameObject>(((Component)val).gameObject, _holder.transform);
			((Object)val2).name = "shieldgolf_basket" + design;
			Quaternion val3 = Quaternion.Euler(0f, 0f - basketPart.Yaw, 0f);
			Vector3 val4 = default(Vector3);
			for (int i = 1; i < layout.Count; i++)
			{
				BasketPart basketPart2 = layout[i];
				GameObject obj = Object.Instantiate<GameObject>(((Component)pieces[basketPart2.Prefab]).gameObject, val2.transform);
				((Object)obj).name = basketPart2.Prefab;
				((Vector3)(ref val4))..ctor(basketPart2.Pivot.X - basketPart.Pivot.X, basketPart2.Pivot.Y - basketPart.Pivot.Y, basketPart2.Pivot.Z - basketPart.Pivot.Z);
				obj.transform.localPosition = val3 * val4;
				obj.transform.localRotation = Quaternion.Euler(0f, basketPart2.Yaw - basketPart.Yaw, 0f) * Quaternion.Euler(basketPart2.Pitch, 0f, 0f);
				StripToModel(obj);
			}
			Piece component = val2.GetComponent<Piece>();
			component.m_name = Titles[design];
			component.m_description = Blurbs[design] + " Place it by its pole. Built from ordinary pieces; removing any of them with the hammer takes down the whole basket.";
			component.m_icon = Icon(design) ?? val.m_icon;
			component.m_category = (PieceCategory)0;
			component.m_usage = (UsageTagFlags)1;
			component.m_resources = ((IEnumerable<KeyValuePair<ItemDrop, int>>)BasketCommand.Cost(layout, pieces)).Select((Func<KeyValuePair<ItemDrop, int>, Requirement>)((KeyValuePair<ItemDrop, int> kv) => new Requirement
			{
				m_resItem = kv.Key,
				m_amount = kv.Value,
				m_recover = true
			})).ToArray();
			val2.AddComponent<BasketStandIn>().Design = design;
			return val2;
		}

		internal static void Anchor(BasketPart anchor, Vector3 pos, Quaternion rot, out Vector3 origin, out Quaternion facing)
		{
			//IL_0002: 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_0019: 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_0024: 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_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_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)
			facing = rot * Quaternion.Euler(0f, 0f - anchor.Yaw, 0f);
			origin = pos - facing * UnityV3.ToUnity(anchor.Pivot);
		}

		private static void StripToModel(GameObject model)
		{
			foreach (Transform item in model.GetComponentsInChildren<Transform>(true).ToList())
			{
				if ((Object)(object)item != (Object)null && (Object)(object)item != (Object)(object)model.transform && ((Component)item).CompareTag("snappoint"))
				{
					Object.DestroyImmediate((Object)(object)((Component)item).gameObject);
				}
			}
			for (int i = 0; i < 6; i++)
			{
				List<Component> list = (from c in model.GetComponentsInChildren<Component>(true)
					where (Object)(object)c != (Object)null && !(c is Transform) && !(c is MeshFilter) && !(c is Renderer) && !(c is LODGroup)
					select c).ToList();
				if (list.Count == 0)
				{
					return;
				}
				foreach (Component item2 in list)
				{
					try
					{
						Object.DestroyImmediate((Object)(object)item2);
					}
					catch
					{
					}
				}
			}
			foreach (Component item3 in from c in model.GetComponentsInChildren<Component>(true)
				where (Object)(object)c != (Object)null && !(c is Transform) && !(c is MeshFilter) && !(c is Renderer) && !(c is LODGroup)
				select c)
			{
				Plugin.Log.LogWarning((object)("hammer: " + ((Object)model).name + " preview keeps " + ((object)item3).GetType().Name));
			}
		}

		private static Sprite Icon(int design)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			using Stream stream = typeof(BasketHammer).Assembly.GetManifestResourceStream($"ShieldGolf.icons.basket-{design}.png");
			if (stream == null)
			{
				return null;
			}
			MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			if (LoadImage == null || !(bool)LoadImage.Invoke(null, new object[2]
			{
				val,
				memoryStream.ToArray()
			}))
			{
				return null;
			}
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
		}
	}
	public static class CheatMark
	{
		private const int CheatRevision = 2;

		private static MethodInfo _set;

		private static bool _looked;

		public static void Apply(ZDO zdo)
		{
			if (zdo == null || PlayerProfile.s_bypassCheatChecks)
			{
				return;
			}
			if (!_looked)
			{
				_looked = true;
				_set = typeof(ZNet).Assembly.GetType("CheatUtils")?.GetMethod("SetCheated", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2]
				{
					typeof(ZDO),
					typeof(bool)
				}, null);
				if (_set == null)
				{
					Plugin.Log.LogWarning((object)"CheatUtils.SetCheated not found; marking cheated objects with the l-1.0.20 literal");
				}
			}
			if (_set != null)
			{
				_set.Invoke(null, new object[2] { zdo, true });
			}
			else
			{
				zdo.Set(ZDOVars.s_cheated, 2, false);
			}
		}
	}
	public static class ConfirmCheats
	{
		[HarmonyPatch(typeof(ConsoleCommand), "RunAction")]
		private static class RunActionPatch
		{
			private static bool Prefix(ConsoleCommand __instance, ConsoleEventArgs args)
			{
				try
				{
					if (!Plugin.ConfirmCheatsOn.Value || !__instance.IsCheat)
					{
						return true;
					}
					if ((Object)(object)Game.instance == (Object)null || args == null || args.Length == 0)
					{
						return true;
					}
					PlayerProfile playerProfile = Game.instance.GetPlayerProfile();
					if (playerProfile == null || playerProfile.m_usedCheats)
					{
						return true;
					}
					if (args[0].ToLower() == "confirmcheats")
					{
						return true;
					}
					Terminal context = args.Context;
					if (context != null)
					{
						context.AddString(Localization.instance.Localize("$achievements_confirm_cheat"));
					}
					return false;
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)("confirmcheats guard failed, command runs as vanilla: " + ex));
					return true;
				}
			}
		}
	}
	public static class CourseMarks
	{
		private static readonly Color TeeGreen = new Color(0.1f, 1f, 0.2f);

		private static readonly Color[] FindColours = (Color[])(object)new Color[3]
		{
			new Color(0.95f, 0.85f, 0.25f),
			new Color(0.95f, 0.6f, 0.2f),
			new Color(0.9f, 0.3f, 0.25f)
		};

		private const float Width = 0.2f;

		private const float FindSec = 30f;

		private const float TeeInset = 0.15f;

		private static LineRenderer _tee;

		private static LineRenderer[] _find;

		private static string _teeKey;

		private static float _findUntil = -1f;

		public static ZDOID LastThrown = ZDOID.None;

		public static void Tick(Player p)
		{
			TickTee(p);
			if (_find != null && Time.time > _findUntil)
			{
				LineRenderer[] find = _find;
				for (int i = 0; i < find.Length; i++)
				{
					((Renderer)find[i]).enabled = false;
				}
			}
		}

		private static void TickTee(Player p)
		{
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			Round round = TournamentClient.State?.Mine;
			if (!((Object)(object)p != (Object)null) || ((Character)p).IsDead() || !TournamentClient.On || round == null || (round.Status != RoundStatus.Idle && (round.Status != RoundStatus.Playing || round.HoleOpen)) || round.HoleIndex >= round.Holes.Count || !round.Holes[round.HoleIndex].HasTee)
			{
				if ((Object)(object)_tee != (Object)null)
				{
					((Renderer)_tee).enabled = false;
				}
				_teeKey = null;
				return;
			}
			TeeBox tee = round.Holes[round.HoleIndex].Tee;
			string text = $"{tee.MinX:0.0},{tee.MinZ:0.0},{tee.MaxX:0.0},{tee.MaxZ:0.0}";
			if ((Object)(object)_tee == (Object)null)
			{
				_tee = GroundLine.New("shieldgolf_next_tee", TeeGreen, 0.2f);
			}
			if (text != _teeKey)
			{
				_teeKey = text;
				GroundLine.Drape(_tee, Rings.TeeOutline(tee, 0.5f, 0.15f), tee.Y, terrain: false);
			}
			((Renderer)_tee).enabled = true;
		}

		public static string Find(Player p)
		{
			//IL_0020: 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_0069: 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_0109: 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_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			Vector3? val = null;
			if (!((ZDOID)(ref LastThrown)).IsNone())
			{
				ZDOMan instance = ZDOMan.instance;
				ZDO val2 = ((instance != null) ? instance.GetZDO(LastThrown) : null);
				if (val2 != null)
				{
					val = val2.GetPosition();
				}
			}
			Round round = TournamentClient.State?.Mine;
			if (!val.HasValue && round != null && round.HasLie)
			{
				val = UnityV3.ToUnity(round.Lie);
			}
			if (!val.HasValue)
			{
				return "no thrown shield to find (or it is too far for this game to know)";
			}
			if (_find == null)
			{
				_find = (LineRenderer[])(object)new LineRenderer[FindColours.Length];
				for (int i = 0; i < _find.Length; i++)
				{
					_find[i] = GroundLine.New("shieldgolf_find_" + i, FindColours[i], 0.2f);
				}
			}
			for (int j = 0; j < _find.Length; j++)
			{
				GroundLine.Drape(_find[j], Rings.Circle(UnityV3.ToV3(val.Value), Rings.FindRadii[j]), val.Value.y, terrain: true);
				((Renderer)_find[j]).enabled = true;
			}
			_findUntil = Time.time + 30f;
			float num = (((Object)(object)p != (Object)null) ? Vector3.Distance(new Vector3(((Component)p).transform.position.x, 0f, ((Component)p).transform.position.z), new Vector3(val.Value.x, 0f, val.Value.z)) : 0f);
			return $"your shield is {num:0} m away: rings at 10, 20 and 50 m around it for {30f:0} s";
		}
	}
	public static class DiscCamera
	{
		[HarmonyPatch(typeof(GameCamera), "UpdateCamera")]
		private static class UpdateCameraPatch
		{
			private static void Postfix(GameCamera __instance, float dt)
			{
				Apply(((Component)__instance).transform, dt);
			}
		}

		private const float Back = 6f;

		private const float Up = 2.5f;

		private const float AboveGround = 1f;

		private const float Smooth = 6f;

		private static readonly FollowState State = new FollowState(1.5f);

		private static Rigidbody _target;

		private static Vector3 _line;

		private static Vector3 _pos;

		private static Vector3 _lastTarget;

		private static readonly FieldRef<Character, Quaternion> LookYaw = AccessTools.FieldRefAccess<Character, Quaternion>("m_lookYaw");

		private static readonly FieldRef<Player, float> LookPitch = AccessTools.FieldRefAccess<Player, float>("m_lookPitch");

		public static void Follow(Rigidbody target, Vector3 line, Vector3 cameraNow)
		{
			//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_0023: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.FollowCamera.Value && !((Object)(object)target == (Object)null))
			{
				_target = target;
				_line = line;
				_pos = cameraNow;
				State.Start();
			}
		}

		public static void Landed(Rigidbody target)
		{
			if ((Object)(object)target == (Object)(object)_target)
			{
				State.Landed();
			}
		}

		private static void Apply(Transform cam, float dt)
		{
			//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_009e: 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_00a4: 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_00aa: 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_00bf: 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_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: 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_012b: 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_013c: 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_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: 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_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)_target == (Object)null || (Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || GameCamera.InFreeFly())
			{
				State.Cancel();
			}
			int num;
			if ((Object)(object)localPlayer != (Object)null)
			{
				Vector3 moveDir = ((Character)localPlayer).GetMoveDir();
				num = ((((Vector3)(ref moveDir)).sqrMagnitude > 0.01f) ? 1 : 0);
			}
			else
			{
				num = 0;
			}
			bool moving = (byte)num != 0;
			if (!State.Tick(dt, PlayerPatches.Input.Armed, moving))
			{
				if (State.TakeEndedAtRest() && (Object)(object)localPlayer != (Object)null && !((Character)localPlayer).IsDead())
				{
					Face(localPlayer, _lastTarget);
				}
				return;
			}
			Vector3 val = (_lastTarget = _target.position);
			Vector3 val2 = UnityV3.ToUnity(ChaseCam.Position(UnityV3.ToV3(val), UnityV3.ToV3(_target.linearVelocity), UnityV3.ToV3(_line), 6f, 2.5f));
			if ((Object)(object)ZoneSystem.instance != (Object)null)
			{
				val2.y = Mathf.Max(val2.y, ZoneSystem.instance.GetGroundHeight(val2) + 1f);
			}
			_pos = Vector3.Lerp(_pos, val2, 1f - Mathf.Exp(-6f * dt));
			cam.position = _pos;
			cam.rotation = Quaternion.LookRotation(val - _pos, Vector3.up);
		}

		private static void Face(Player p, Vector3 at)
		{
			//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_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)
			try
			{
				ChaseCam.LookAt(UnityV3.ToV3(((Character)p).GetEyePoint()), UnityV3.ToV3(at), out var yawDeg, out var pitchDeg);
				LookYaw.Invoke((Character)(object)p) = Quaternion.Euler(0f, yawDeg, 0f);
				LookPitch.Invoke(p) = pitchDeg;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[shieldgolf] could not turn the view to the shield: " + ex.Message));
			}
		}
	}
	public class DiscFlight : MonoBehaviour
	{
		public struct Impact
		{
			public float Time;

			public float TiltDeg;

			public Vector3 Position;

			public Vector3 VelocityIn;

			public Vector3 Normal;

			public Vector3 VelocityOut;

			public string Kind;
		}

		private const float IgnoreThrowerSec = 0.3f;

		private readonly StillTimer _stall = new StillTimer(0.3f, 1f);

		private readonly StillTimer _rest = new StillTimer(0.3f, 0.5f);

		private readonly StillTimer _watchRest = new StillTimer(0.3f, 0.5f);

		private const float MaxSec = 20f;

		public const float MaxRollSec = 6f;

		public const float RollEdgeDeg = 80f;

		public const float RollStopSpeed = 1f;

		private const int MaxGlances = 3;

		private const float DiscRadius = 0.1055f;

		private const float LandingSpin = 15f;

		public const string StateKey = "shieldgolf_state";

		public const string StampKey = "shieldgolf_stamp";

		public const string CarryKey = "shieldgolf_carry";

		private const float StateEverySec = 0.1f;

		private static readonly Action<ItemDrop> SaveDrop = AccessTools.MethodDelegate<Action<ItemDrop>>(AccessTools.Method(typeof(ItemDrop), "Save", (Type[])null, (Type[])null), (object)null, true);

		private DiscClass _class;

		private DiscBody _disc;

		private Player _thrower;

		private float _tilt;

		private float _attitude;

		private float _rollT;

		private Vector3 _lastVel;

		private Vector3 _rollVel;

		private int _glances;

		private float _spinDeg;

		private int _restoreFrames;

		private Transform _model;

		private Vector3 _modelPos;

		private Quaternion _modelRot;

		private Vector3 _release;

		private Vector3 _line;

		private Collider[] _ignore;

		private Collider[] _own;

		private string _logPrefix;

		private Rigidbody _body;

		private ZNetView _nview;

		private float _origDamping;

		private float _origAngular;

		private CollisionDetectionMode _origMode;

		private bool _origFreeze;

		private float _t;

		private float _carry;

		private float _contactTime;

		private float _wind;

		private Vector3 _windSum;

		private int _windN;

		private FlightPhase _phase;

		private bool _contacted;

		private bool _ignoring;

		private bool _landedElsewhere;

		private float _stateTimer;

		private Vector3 _watchLastPos;

		private Vector3 _contactPos;

		private string _landing = "";

		private Impact _impact;

		private readonly List<Impact> _glanceImpacts = new List<Impact>();

		private bool _rolled;

		private float _rollEnd;

		private Vector3 _rollEndPos;

		private Vector3 _restNormal = Vector3.up;

		private int _sinceContact;

		private bool _slideBlocked;

		private readonly SlideState _slide = new SlideState();

		private Vector3 _slideStart;

		public static bool NoWind;

		public static bool ForceWind;

		private bool Begun
		{
			get
			{
				if (_phase != FlightPhase.None)
				{
					return _phase != FlightPhase.Ended;
				}
				return false;
			}
		}

		public bool Finished { get; private set; }

		public float Distance { get; private set; }

		public Player Thrower => _thrower;

		public Vector3 ReleasePoint => _release;

		public ZDOID ShieldId
		{
			get
			{
				//IL_001b: 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)(object)_nview != (Object)null) || !_nview.IsValid())
				{
					return ZDOID.None;
				}
				return _nview.GetZDO().m_uid;
			}
		}

		public bool Contacted => _contacted;

		public float ContactTime => _contactTime;

		public Vector3 ContactPosition => _contactPos;

		public float Carry => _carry;

		public float TiltDeg => _tilt * 57.29578f;

		public int Glances => _glances;

		public string FirstContact => _landing;

		public float FlightTime => _t;

		public Impact FirstImpact => _impact;

		public List<Impact> GlanceImpacts => _glanceImpacts;

		public bool Rolled => _rolled;

		public float RollEndTime => _rollEnd;

		public Vector3 RollEndPosition => _rollEndPos;

		public static event Action<DiscFlight> Ended;

		private bool StepAir(float dt, bool trace)
		{
			//IL_005b: 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_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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: 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_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: 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_01b6: 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_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: 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_009c: 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_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: 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_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_039c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03af: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			Vector3 linearVelocity;
			if (_restoreFrames > 0)
			{
				_restoreFrames--;
				_body.useGravity = true;
				linearVelocity = _body.linearVelocity;
				if (((Vector3)(ref linearVelocity)).magnitude < 0.5f * ((Vector3)(ref _lastVel)).magnitude)
				{
					_body.linearVelocity = _lastVel;
				}
			}
			Vector3 val = Vector3.zero;
			if ((Plugin.WindOn.Value || ForceWind) && !NoWind && (Object)(object)EnvMan.instance != (Object)null)
			{
				val = EnvMan.instance.GetWindForce() * Plugin.Flight.WindScale;
			}
			_wind = Mathf.Max(_wind, ((Vector3)(ref val)).magnitude);
			_windSum += val;
			_windN++;
			float tiltRate;
			V3 v = FlightModel.AeroAccel(UnityV3.ToV3(_body.linearVelocity), _class, _disc, _tilt, _attitude, UnityV3.ToV3(val), Plugin.Flight, out tiltRate, UnityV3.ToV3(_line));
			_tilt = FlightModel.ClampTilt(_tilt + tiltRate * FlightModel.RollRamp(_t, Plugin.Flight) * dt);
			Vector3 v2 = default(Vector3);
			((Vector3)(ref v2))..ctor(_body.linearVelocity.x, 0f, _body.linearVelocity.z);
			_spinDeg = Mathf.Repeat(_spinDeg + FlightModel.VisualSpinDegPerSec(_disc.Spin) * dt, 360f);
			if (((Vector3)(ref v2)).sqrMagnitude > 0.01f)
			{
				_body.MoveRotation(FlightRotation(UnityV3.ToUnity(FlightModel.Frame(UnityV3.ToV3(v2), UnityV3.ToV3(_line), Plugin.Flight)), _tilt * 57.29578f, _attitude * 57.29578f) * Quaternion.AngleAxis(_spinDeg, Vector3.up));
			}
			v.Y += FlightGuard.GravityCorrection(Physics.gravity.y);
			_body.AddForce(UnityV3.ToUnity(v), (ForceMode)5);
			StillTimer stall = _stall;
			linearVelocity = _body.linearVelocity;
			if (stall.Feed(((Vector3)(ref linearVelocity)).magnitude, dt, _t > 0.5f))
			{
				if (Plugin.TuningLog.Value)
				{
					Plugin.Log.LogInfo((object)$"[shieldgolf] stalled t={_t:0.00} pos={((Component)this).transform.position:F2}: landed where it stuck");
				}
				_landing = "stuck";
				_impact = new Impact
				{
					Time = _t,
					TiltDeg = _tilt * 57.29578f,
					Position = ((Component)this).transform.position,
					VelocityIn = _lastVel,
					Normal = Vector3.up,
					VelocityOut = Vector3.zero,
					Kind = _landing
				};
				_restNormal = Vector3.up;
				Contact(0f);
				return false;
			}
			_lastVel = _body.linearVelocity;
			_stateTimer += dt;
			if (_stateTimer >= 0.1f)
			{
				_stateTimer = 0f;
				WriteState();
			}
			if (trace)
			{
				Plugin.Log.LogInfo((object)$"[shieldgolf] trace t={_t:0.00} pos={((Component)this).transform.position:F2} vel={_body.linearVelocity:F2} aero={UnityV3.ToUnity(v):F2} tilt={_tilt * 57.29578f:0}");
			}
			return true;
		}

		private void OnCollisionStay(Collision collision)
		{
			//IL_0013: 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_001f: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_004a: 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_003c: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			if (_phase != FlightPhase.Landed && _phase != FlightPhase.Sliding)
			{
				return;
			}
			Vector3 val = Vector3.zero;
			for (int i = 0; i < collision.contactCount; i++)
			{
				ContactPoint contact = collision.GetContact(i);
				Vector3 normal = ((ContactPoint)(ref contact)).normal;
				if (normal.y > val.y)
				{
					val = normal;
				}
			}
			if (!(val.y <= 0f))
			{
				if (_sinceContact > 0 || val.y > _restNormal.y)
				{
					_restNormal = val;
				}
				_sinceContact = 0;
			}
		}

		private void OnCollisionEnter(Collision collision)
		{
			//IL_020a: 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_007b: 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_0084: 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_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: 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_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_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: 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_014e: 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_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0332: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_0348: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0423: Unknown result type (might be due to invalid IL or missing references)
			//IL_0457: Unknown result type (might be due to invalid IL or missing references)
			//IL_045c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0474: Unknown result type (might be due to invalid IL or missing references)
			if (!Begun || _phase == FlightPhase.Watching)
			{
				return;
			}
			string text = LayerMask.LayerToName(((Component)collision.collider).gameObject.layer);
			bool flag = text == "terrain";
			if (_phase == FlightPhase.Rolling)
			{
				if (!flag)
				{
					StopRolling();
				}
			}
			else
			{
				if (_contacted)
				{
					return;
				}
				ContactPoint contact;
				Impact item;
				if (!flag && collision.contactCount > 0 && _glances < 3)
				{
					V3 vel = UnityV3.ToV3(_lastVel);
					contact = collision.GetContact(0);
					LandingOutcome landingOutcome = Landing.Hit(vel, UnityV3.ToV3(((ContactPoint)(ref contact)).normal));
					if (landingOutcome.Kind == LandingKind.Glance)
					{
						_glances++;
						List<Impact> glanceImpacts = _glanceImpacts;
						item = new Impact
						{
							Time = _t,
							TiltDeg = _tilt * 57.29578f,
							Position = ((Component)this).transform.position,
							VelocityIn = _lastVel
						};
						contact = collision.GetContact(0);
						item.Normal = ((ContactPoint)(ref contact)).normal;
						item.VelocityOut = UnityV3.ToUnity(landingOutcome.Velocity);
						item.Kind = "glance";
						glanceImpacts.Add(item);
						_body.linearVelocity = (_lastVel = UnityV3.ToUnity(landingOutcome.Velocity));
						Wear(Plugin.WearPerHit.Value);
						if (Plugin.TuningLog.Value)
						{
							Plugin.Log.LogInfo((object)$"[shieldgolf] glance t={_t:0.00} with={((Object)collision.collider).name} layer={text} speed={((Vector3)(ref _lastVel)).magnitude:0.0}");
						}
						return;
					}
				}
				if (Plugin.TuningLog.Value)
				{
					Plugin.Log.LogInfo((object)$"[shieldgolf] contact t={_t:0.00} with={((Object)collision.collider).name} layer={text} pos={((Component)this).transform.position:F2}");
				}
				_landing = (flag ? "ground" : ("hit:" + ((Object)collision.collider).name));
				item = new Impact
				{
					Time = _t,
					TiltDeg = _tilt * 57.29578f,
					Position = ((Component)this).transform.position,
					VelocityIn = _lastVel
				};
				Vector3 normal;
				if (collision.contactCount <= 0)
				{
					normal = Vector3.up;
				}
				else
				{
					contact = collision.GetContact(0);
					normal = ((ContactPoint)(ref contact)).normal;
				}
				item.Normal = normal;
				item.VelocityOut = _body.linearVelocity;
				item.Kind = _landing;
				_impact = item;
				Contact(flag ? Plugin.WearPerLanding.Value : Plugin.WearPerHit.Value);
				if (flag && collision.contactCount != 0)
				{
					float tiltRad = FlightModel.HeadingTilt(UnityV3.ToV3(_lastVel), _tilt, _attitude, UnityV3.ToV3(_line), Plugin.Flight);
					V3 vel2 = UnityV3.ToV3(_lastVel);
					contact = collision.GetContact(0);
					LandingOutcome landingOutcome2 = Landing.Outcome(vel2, tiltRad, UnityV3.ToV3(((ContactPoint)(ref contact)).normal), _disc.Spin);
					if (landingOutcome2.Kind != LandingKind.Stop)
					{
						_landing = (_impact.Kind = landingOutcome2.Kind.ToString().ToLowerInvariant());
						_impact.VelocityOut = UnityV3.ToUnity(landingOutcome2.Velocity);
					}
					if (Plugin.TuningLog.Value && landingOutcome2.Kind != LandingKind.Stop)
					{
						Plugin.Log.LogInfo((object)$"[shieldgolf] {landingOutcome2.Kind.ToString().ToLowerInvariant()} tilt={_tilt * 57.29578f:0} speed={((Vector3)(ref _lastVel)).magnitude:0.0}");
					}
					if (landingOutcome2.Kind == LandingKind.Skip)
					{
						_body.linearVelocity = UnityV3.ToUnity(landingOutcome2.Velocity);
					}
					else if (landingOutcome2.Kind == LandingKind.Roll)
					{
						_phase = FlightPhase.Rolling;
						_rolled = true;
						_rollT = 0f;
						_rollVel = UnityV3.ToUnity(landingOutcome2.Velocity);
						_body.freezeRotation = true;
						_body.linearVelocity = _rollVel;
					}
				}
			}
		}

		private void Contact(float wear)
		{
			//IL_0021: 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_0032: 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)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: 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)
			_contacted = true;
			_phase = FlightPhase.Landed;
			_contactTime = _t;
			_contactPos = ((Component)this).transform.position;
			Vector3 val = Horizontal(((Component)this).transform.position - _release);
			_carry = ((Vector3)(ref val)).magnitude;
			if ((Object)(object)_nview != (Object)null && _nview.IsValid() && _nview.IsOwner())
			{
				ZDO zDO = _nview.GetZDO();
				zDO.Set("shieldgolf_state", "");
				zDO.Set("shieldgolf_carry", _carry);
			}
			_body.freezeRotation = _origFreeze;
			_body.angularVelocity = ((Component)this).transform.up * Mathf.Clamp(_disc.Spin, -15f, 15f);
			Wear(wear);
			if ((Object)(object)_thrower != (Object)null && (Object)(object)_thrower == (Object)(object)Player.m_localPlayer)
			{
				((Character)_thrower).RaiseSkill((SkillType)6, ThrowMath.SkillXp(_carry, Plugin.MetresPerBlock.Value));
			}
		}

		private void Wear(float amount)
		{
			ItemDrop component = ((Component)this).GetComponent<ItemDrop>();
			if (!((Object)(object)component == (Object)null) && !(amount <= 0f) && component.m_itemData != null && component.m_itemData.m_shared.m_useDurability)
			{
				component.m_itemData.m_durability = Mathf.Max(0f, component.m_itemData.m_durability - amount);
				SaveDrop(component);
			}
		}

		private void Roll(float dt)
		{
			//IL_0022: 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_003e: 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_0076: 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_0089: 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_00ec: 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_0101: Unknown result type (might be due to invalid IL or missing references)
			_rollT += dt;
			float num = Mathf.Sign(_tilt) * 80f;
			_rollVel = UnityV3.ToUnity(Landing.RollStep(UnityV3.ToV3(_rollVel), num * ((float)Math.PI / 180f), dt));
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(_rollVel.x, _body.linearVelocity.y, _rollVel.z);
			_body.linearVelocity = val;
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(val.x, 0f, val.z);
			_spinDeg = Mathf.Repeat(_spinDeg + Mathf.Sign(_tilt) * FlightModel.VisualSpinDegPerSec(((Vector3)(ref val2)).magnitude / 0.1055f) * dt, 360f);
			if (((Vector3)(ref val2)).sqrMagnitude > 0.01f)
			{
				_body.MoveRotation(FlightRotation(((Vector3)(ref val2)).normalized, num) * Quaternion.AngleAxis(_spinDeg, Vector3.up));
			}
			if (FlightRules.RollStops(((Vector3)(ref val2)).magnitude, _rollT))
			{
				StopRolling();
			}
		}

		private void StartSlide()
		{
			//IL_0013: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
			_phase = FlightPhase.Sliding;
			_slide.Start(UnityV3.ToV3(((Component)this).transform.position));
			_slideStart = ((Component)this).transform.position;
			_rest.Reset();
			_body.freezeRotation = true;
			_body.angularVelocity = Vector3.zero;
			_body.WakeUp();
			_sinceContact = 0;
			if (Plugin.TuningLog.Value)
			{
				Plugin.Log.LogInfo((object)$"[shieldgolf] slide t={_t:0.00} angle={Vector3.Angle(_restNormal, Vector3.up):0} pos={((Component)this).transform.position:F2}");
			}
		}

		private void Slide(float dt)
		{
			//IL_000e: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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)
			//IL_00ad: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			SlideVerdict slideVerdict = _slide.Step(dt, _sinceContact, Landing.TooSteep(UnityV3.ToV3(_restNormal), 38f), UnityV3.ToV3(((Component)this).transform.position));
			if (slideVerdict != SlideVerdict.Push)
			{
				if (SlideState.Blocks(slideVerdict))
				{
					_slideBlocked = true;
				}
				StopSlide(slideVerdict.ToString().ToLowerInvariant());
			}
			else
			{
				Vector3 val = UnityV3.ToUnity(Landing.SlideVelocity(UnityV3.ToV3(_restNormal), 1f));
				Vector3 val2 = new Vector3(val.x, 0f, val.z);
				Vector3 val3 = ((Vector3)(ref val2)).normalized * 2f;
				_body.linearVelocity = new Vector3(val3.x, Mathf.Min(_body.linearVelocity.y, 0f), val3.z);
			}
		}

		private void StopSlide(string why)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			_phase = FlightPhase.Landed;
			_rest.Reset();
			_body.freezeRotation = _origFreeze;
			if (Plugin.TuningLog.Value)
			{
				ManualLogSource log = Plugin.Log;
				object[] obj = new object[4] { _t, why, null, null };
				Vector3 val = ((Component)this).transform.position - _slideStart;
				obj[2] = ((Vector3)(ref val)).magnitude;
				obj[3] = Vector3.Angle(_restNormal, Vector3.up);
				log.LogInfo((object)string.Format("[shieldgolf] slide_end t={0:0.00} why={1} dist={2:0.0} angle={3:0}", obj));
			}
		}

		private void StopRolling()
		{
			//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_003b: Unknown result type (might be due to invalid IL or missing references)
			_phase = FlightPhase.Landed;
			_rollEnd = _t;
			_rollEndPos = ((Component)this).transform.position;
			_body.freezeRotation = _origFreeze;
			_body.angularVelocity = Vector3.zero;
		}

		public static Quaternion FlightRotation(Vector3 flat, float tiltDeg, float pitchDeg = 0f)
		{
			//IL_0000: 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)
			return DiscRotation(flat, tiltDeg, pitchDeg, Plugin.FlightOffsetX.Value);
		}

		public static Quaternion HeldRotation(Vector3 flat, float tiltDeg, float pitchDeg)
		{
			//IL_0000: 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)
			return DiscRotation(flat, tiltDeg, pitchDeg, Plugin.HeldOffsetX.Value);
		}

		private static Quaternion DiscRotation(Vector3 flat, float tiltDeg, float pitchDeg, float offsetX)
		{
			//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_0006: 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_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_002d: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			return Quaternion.LookRotation(flat, Vector3.up) * Quaternion.Euler(0f - pitchDeg, 0f, 0f) * Quaternion.AngleAxis(0f - tiltDeg, Vector3.forward) * Quaternion.Euler(offsetX, 0f, 0f);
		}

		public void Begin(DiscClass c, DiscBody disc, float tiltRad, float attitudeRad, Vector3 releasePos, Vector3 line, Collider[] ignore, Player thrower, string logPrefix)
		{
			//IL_0026: 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_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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			_class = c;
			_disc = disc;
			_thrower = thrower;
			_tilt = tiltRad;
			_attitude = attitudeRad;
			_release = releasePos;
			_line = ((Vector3)(ref line)).normalized;
			_ignore = ignore;
			_logPrefix = logPrefix;
			Setup();
			if ((Object)(object)Camera.main != (Object)null && (Object)(object)thrower == (Object)(object)Player.m_localPlayer)