Decompiled source of SentryBallista Ymiron v0.1.1

SentryBallista.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using SentryBallista.Visuals;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("SentryBallista")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.1.0")]
[assembly: AssemblyInformationalVersion("0.1.1")]
[assembly: AssemblyProduct("SentryBallista")]
[assembly: AssemblyTitle("SentryBallista")]
[assembly: AssemblyVersion("0.1.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SentryBallista
{
	public class AutoBallista : MonoBehaviour, Hoverable, Interactable, IPieceMarker
	{
		private const float ScanInterval = 0.5f;

		private const float LoseSightAfter = 1.5f;

		private const float AimTolerance = 2f;

		private const float MarkerHideTime = 0.5f;

		private static readonly KeyValuePair<int, int> TargetKey = ZDO.GetHashZDOID("ymiron_sb_target");

		private static readonly int ShotsKey = StringExtensionMethods.GetStableHashCode("ymiron_sb_shots");

		private static readonly int LastShotKey = StringExtensionMethods.GetStableHashCode("ymiron_sb_lastshot");

		private static readonly int OffKey = StringExtensionMethods.GetStableHashCode("ymiron_sb_off");

		private const string RpcToggle = "ymiron_sb_toggle";

		private static int _sightMask;

		private static int _sightMaskBuildings;

		private static readonly RaycastHit[] Hits = (RaycastHit[])(object)new RaycastHit[32];

		public int m_tier;

		public Transform m_neck;

		public Transform m_body;

		public Transform m_eye;

		public GameObject m_armed;

		public GameObject m_unarmed;

		public GameObject m_bolt;

		public CircleProjector m_marker;

		private ZNetView _nview;

		private TierDef _def;

		private float _yaw;

		private float _pitch;

		private Character _target;

		private ZDOID _targetId = ZDOID.None;

		private float _nextScan;

		private float _lastSeen;

		private int _shotsSeen = -1;

		private float _coolingUntil;

		private bool _wasCooling;

		private float _nextOwnerCheck;

		private bool _aimed;

		private TierDef Def => _def ?? (_def = TierDef.All[Mathf.Clamp(m_tier, 1, TierDef.All.Length) - 1]);

		private TierConfig Cfg => ModConfig.Tier(Def);

		private bool IsOff
		{
			get
			{
				if ((Object)(object)_nview != (Object)null && _nview.IsValid())
				{
					return _nview.GetZDO().GetBool(OffKey, false);
				}
				return false;
			}
		}

		private bool IsCooling => Time.time < _coolingUntil;

		private void Awake()
		{
			_nview = ((Component)this).GetComponent<ZNetView>();
			if ((Object)(object)m_marker != (Object)null)
			{
				((Component)m_marker).gameObject.SetActive(false);
			}
			if (!((Object)(object)_nview == (Object)null) && _nview.IsValid())
			{
				_nview.Register<bool>("ymiron_sb_toggle", (Action<long, bool>)RPC_Toggle);
				_shotsSeen = _nview.GetZDO().GetInt(ShotsKey, 0);
				_nextScan = Random.Range(0f, 0.5f);
			}
		}

		public string GetHoverText()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_nview == (Object)null || !_nview.IsValid())
			{
				return string.Empty;
			}
			TierConfig cfg = Cfg;
			string name = Def.Name;
			if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, false, false))
			{
				return Localization.instance.Localize(name + "\n$piece_noaccess");
			}
			string text = (IsOff ? "<color=#999999>Off</color>" : ((!((Object)(object)_target != (Object)null) || _target.IsDead()) ? "<color=#A0E0A0>On guard</color>" : ("<color=#FF9060>Shooting at " + Localization.instance.Localize(_target.m_name) + "</color>")));
			return name + " (" + text + ")\n" + $"Damage {cfg.Damage.Value:0} · range {cfg.Range.Value:0} m · one shot every {cfg.FireInterval.Value:0.#} s\n" + Localization.instance.Localize("[<color=yellow><b>$KEY_Use</b></color>] " + (IsOff ? "Turn on" : "Turn off"));
		}

		public string GetHoverName()
		{
			return Def.Name;
		}

		public float GetHoverOffset()
		{
			return 0f;
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			if (hold || (Object)(object)_nview == (Object)null || !_nview.IsValid())
			{
				return false;
			}
			if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false))
			{
				return false;
			}
			bool flag = !IsOff;
			_nview.InvokeRPC("ymiron_sb_toggle", new object[1] { flag });
			((Character)user).Message((MessageType)2, Def.Name + ": " + (flag ? "off" : "on guard"), 0, (Sprite)null, false);
			return true;
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			return false;
		}

		private void RPC_Toggle(long sender, bool off)
		{
			if (_nview.IsOwner())
			{
				_nview.GetZDO().Set(OffKey, off);
				if (off)
				{
					SetTarget(null);
				}
			}
		}

		public void ShowBuildMarker()
		{
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)m_marker == (Object)null))
			{
				float value = Cfg.Range.Value;
				float value2 = ModConfig.Arc.Value;
				m_marker.m_radius = value;
				m_marker.m_nrOfSegments = Mathf.Clamp(Mathf.RoundToInt(value * 2f * MathF.PI / 2.5f * Mathf.Min(1f, value2 / 180f)), 12, 120);
				m_marker.m_turns = Mathf.Min(1f, value2 * 2f / 360f);
				CircleProjector marker = m_marker;
				Quaternion rotation = ((Component)this).transform.rotation;
				marker.m_start = ((Quaternion)(ref rotation)).eulerAngles.y - ((value2 >= 180f) ? 0f : value2);
				((Component)m_marker).gameObject.SetActive(true);
				((MonoBehaviour)this).CancelInvoke("HideMarker");
				((MonoBehaviour)this).Invoke("HideMarker", 0.5f);
			}
		}

		public void ShowHoverMarker()
		{
			ShowBuildMarker();
		}

		private void HideMarker()
		{
			if ((Object)(object)m_marker != (Object)null)
			{
				((Component)m_marker).gameObject.SetActive(false);
			}
		}

		private void Update()
		{
			if (!((Object)(object)_nview == (Object)null) && _nview.IsValid() && !((Object)(object)m_body == (Object)null))
			{
				float deltaTime = Time.deltaTime;
				TakeOverIfOrphaned();
				if (_nview.IsOwner())
				{
					OwnerThink();
				}
				else
				{
					ReadTarget();
				}
				Aim(deltaTime);
				if (_nview.IsOwner() && _aimed && (Object)(object)_target != (Object)null && !IsOff && !IsCooling && CanFireNow())
				{
					Shoot();
				}
				WatchShots();
				UpdateLook();
			}
		}

		private void OwnerThink()
		{
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			if (IsOff)
			{
				if ((Object)(object)_target != (Object)null)
				{
					SetTarget(null);
				}
				return;
			}
			float value = Cfg.Range.Value;
			if ((Object)(object)_target != (Object)null)
			{
				if (!Targeting.IsHostile(_target) || !InReach(_target, value))
				{
					SetTarget(null);
					TurretEffects.LostTarget(((Component)this).transform);
				}
				else if (CanSee(_target))
				{
					_lastSeen = Time.time;
				}
				else if (Time.time - _lastSeen > 1.5f)
				{
					SetTarget(null);
				}
			}
			if (Time.time < _nextScan)
			{
				return;
			}
			_nextScan = Time.time + 0.5f;
			if ((Object)(object)_target != (Object)null)
			{
				return;
			}
			Character val = null;
			float num = float.MaxValue;
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				if (Targeting.IsHostile(allCharacter) && InReach(allCharacter, value))
				{
					float num2 = Vector3.Distance(((Component)allCharacter).transform.position, ((Component)this).transform.position);
					if (num2 < num && CanSee(allCharacter))
					{
						val = allCharacter;
						num = num2;
					}
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				SetTarget(val);
				_lastSeen = Time.time;
				TurretEffects.NewTarget(((Component)this).transform);
			}
		}

		private void SetTarget(Character target)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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)
			_target = target;
			_targetId = (((Object)(object)target != (Object)null) ? target.GetZDOID() : ZDOID.None);
			if (_nview.IsOwner())
			{
				_nview.GetZDO().Set(TargetKey, _targetId);
			}
		}

		private void ReadTarget()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			ZDOID zDOID = _nview.GetZDO().GetZDOID(TargetKey);
			if (!(zDOID == _targetId) || (!((Object)(object)_target != (Object)null) && !(zDOID == ZDOID.None)))
			{
				_targetId = zDOID;
				GameObject val = ((zDOID == ZDOID.None || (Object)(object)ZNetScene.instance == (Object)null) ? null : ZNetScene.instance.FindInstance(zDOID));
				_target = (((Object)(object)val != (Object)null) ? val.GetComponent<Character>() : null);
			}
		}

		private bool InReach(Character character, float range)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ((Component)character).transform.position - ((Component)this).transform.position;
			if (((Vector3)(ref val)).magnitude > range)
			{
				return false;
			}
			float value = ModConfig.Arc.Value;
			if (value >= 180f)
			{
				return true;
			}
			Vector3 val2 = ((Component)this).transform.InverseTransformDirection(val);
			return Mathf.Abs(Mathf.Atan2(val2.x, val2.z) * 57.29578f) <= value;
		}

		private bool CanSee(Character target)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_0091: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			if (_sightMask == 0)
			{
				_sightMask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "Default_small", "terrain", "viewblock" });
				_sightMaskBuildings = _sightMask | LayerMask.GetMask(new string[2] { "piece", "vehicle" });
			}
			int num = (ModConfig.ShootThroughBuildings.Value ? _sightMask : _sightMaskBuildings);
			Vector3 position = m_eye.position;
			Vector3 val = target.GetCenterPoint() - position;
			int num2 = Physics.RaycastNonAlloc(position, ((Vector3)(ref val)).normalized, Hits, ((Vector3)(ref val)).magnitude, num, (QueryTriggerInteraction)1);
			for (int i = 0; i < num2; i++)
			{
				Collider collider = ((RaycastHit)(ref Hits[i])).collider;
				if (!((Object)(object)collider == (Object)null) && !((Object)(object)((Component)collider).GetComponentInParent<AutoBallista>() == (Object)(object)this) && !((Object)(object)((Component)collider).GetComponentInParent<Character>() == (Object)(object)target))
				{
					return false;
				}
			}
			return true;
		}

		private void Aim(float dt)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: 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_0099: 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_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			float num = ModConfig.TurnSpeed.Value * dt;
			float value = ModConfig.Arc.Value;
			_aimed = false;
			float num2;
			float num3;
			if ((Object)(object)_target != (Object)null && !_target.IsDead() && !IsOff)
			{
				Vector3 direction;
				bool flag = Solve(_target, out direction);
				Vector3 val = ((Component)this).transform.InverseTransformDirection(direction);
				num2 = Mathf.Atan2(val.x, val.z) * 57.29578f;
				float y = val.y;
				Vector2 val2 = new Vector2(val.x, val.z);
				num3 = Mathf.Atan2(y, ((Vector2)(ref val2)).magnitude) * 57.29578f;
				float num4 = ((value >= 180f) ? num2 : Mathf.Clamp(num2, 0f - value, value));
				float num5 = Mathf.Clamp(num3, ModConfig.MinPitch.Value, ModConfig.MaxPitch.Value);
				_aimed = flag && Mathf.Approximately(num5, num3) && Mathf.Approximately(num4, num2);
				num2 = num4;
				num3 = num5;
			}
			else
			{
				num2 = _yaw;
				num3 = (IsOff ? (-12f) : 0f);
			}
			_yaw = ((value >= 180f) ? Mathf.MoveTowardsAngle(_yaw, num2, num) : Mathf.MoveTowards(_yaw, num2, num));
			_yaw = Mathf.DeltaAngle(0f, _yaw);
			_pitch = Mathf.MoveTowards(_pitch, num3, num);
			_aimed = _aimed && Mathf.Abs(Mathf.DeltaAngle(_yaw, num2)) < 2f && Mathf.Abs(_pitch - num3) < 2f;
			m_neck.localRotation = Quaternion.Euler(0f, _yaw, 0f);
			m_body.localRotation = Quaternion.Euler(0f - _pitch, _yaw, 0f);
		}

		private bool Solve(Character target, out Vector3 direction)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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: 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_0101: 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_0114: 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_012e: 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_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: 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_0169: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = m_body.position;
			float num = BoltSpeed();
			float num2 = BoltGravity();
			Vector3 val = target.GetCenterPoint();
			Vector3 velocity = target.GetVelocity();
			bool result = true;
			direction = val - position;
			Vector3 val2 = default(Vector3);
			for (int i = 0; i < 2; i++)
			{
				((Vector3)(ref val2))..ctor(val.x - position.x, 0f, val.z - position.z);
				float magnitude = ((Vector3)(ref val2)).magnitude;
				float num3 = val.y - position.y;
				float num4 = Mathf.Atan2(num3, Mathf.Max(magnitude, 0.01f));
				if (num2 > 0.01f && magnitude > 0.01f)
				{
					float num5 = num * num;
					float num6 = num5 * num5 - num2 * (num2 * magnitude * magnitude + 2f * num3 * num5);
					if (num6 < 0f)
					{
						result = false;
						num4 = MathF.PI / 4f;
					}
					else
					{
						num4 = Mathf.Atan((num5 - Mathf.Sqrt(num6)) / (num2 * magnitude));
					}
				}
				Vector3 val3 = ((magnitude > 0.01f) ? (val2 / magnitude) : ((Component)this).transform.forward);
				direction = val3 * Mathf.Cos(num4) + Vector3.up * Mathf.Sin(num4);
				float num7 = magnitude / Mathf.Max(0.1f, num * Mathf.Cos(num4));
				val = target.GetCenterPoint() + velocity * num7;
			}
			return result;
		}

		private bool CanFireNow()
		{
			float num = _nview.GetZDO().GetFloat(LastShotKey, -1000f);
			if ((Object)(object)ZNet.instance != (Object)null)
			{
				return ZNet.instance.GetTimeSeconds() >= (double)(num + Cfg.FireInterval.Value);
			}
			return false;
		}

		private void Shoot()
		{
			//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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: 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_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: 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_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Expected O, but got Unknown
			//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_0143: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: 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)
			ItemData val = Ammo();
			GameObject val2 = val?.m_shared.m_attack.m_attackProjectile;
			if (!((Object)(object)val2 == (Object)null))
			{
				Vector3 val3 = m_eye.forward;
				float num = val.m_shared.m_attack.m_projectileAccuracy * 0.5f;
				if (num > 0f)
				{
					Vector3 val4 = Vector3.Cross(val3, Vector3.up);
					val3 = Quaternion.AngleAxis(Random.Range(0f - num, num), Vector3.up) * (Quaternion.AngleAxis(Random.Range(0f - num, num), val4) * val3);
				}
				HitData val5 = new HitData
				{
					m_toolTier = (short)val.m_shared.m_toolTier,
					m_pushForce = ModConfig.PushForce.Value,
					m_backstabBonus = val.m_shared.m_backstabBonus,
					m_staggerMultiplier = val.m_shared.m_attack.m_staggerMultiplier,
					m_blockable = val.m_shared.m_blockable,
					m_dodgeable = val.m_shared.m_dodgeable,
					m_skill = (SkillType)0,
					m_itemWorldLevel = (byte)Game.m_worldLevel,
					m_hitType = (HitType)16
				};
				val5.m_damage.m_pierce = Cfg.Damage.Value;
				GameObject obj = Object.Instantiate<GameObject>(val2, m_eye.position, Quaternion.LookRotation(val3));
				IProjectile component = obj.GetComponent<IProjectile>();
				if (component != null)
				{
					component.Setup((Character)null, val3 * BoltSpeed(), 10f, val5, (ItemData)null, val);
				}
				BallistaShots.Register(obj);
				ZDO zDO = _nview.GetZDO();
				zDO.Set(LastShotKey, (float)ZNet.instance.GetTimeSeconds());
				zDO.Set(ShotsKey, zDO.GetInt(ShotsKey, 0) + 1, false);
				TurretEffects.Shoot(m_eye.position, m_eye.rotation, fromOwner: true);
				_shotsSeen = zDO.GetInt(ShotsKey, 0);
				StartCooldown();
			}
		}

		private void WatchShots()
		{
			//IL_003f: 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)
			int num = _nview.GetZDO().GetInt(ShotsKey, 0);
			if (_shotsSeen < 0)
			{
				_shotsSeen = num;
			}
			else if (num != _shotsSeen)
			{
				_shotsSeen = num;
				TurretEffects.Shoot(m_eye.position, m_eye.rotation, fromOwner: false);
				StartCooldown();
			}
		}

		private void StartCooldown()
		{
			_coolingUntil = Time.time + Mathf.Max(0.3f, Cfg.FireInterval.Value * 0.7f);
			_wasCooling = true;
		}

		private void UpdateLook()
		{
			//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)
			bool isCooling = IsCooling;
			if (_wasCooling && !isCooling)
			{
				TurretEffects.Reload(((Component)this).transform.position, ((Component)this).transform.rotation);
			}
			_wasCooling = isCooling;
			SetActive(m_armed, !isCooling);
			SetActive(m_unarmed, isCooling);
			SetActive(m_bolt, !isCooling && !IsOff);
		}

		private static void SetActive(GameObject go, bool active)
		{
			if ((Object)(object)go != (Object)null && go.activeSelf != active)
			{
				go.SetActive(active);
			}
		}

		private ItemData Ammo()
		{
			GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(Def.Ammo) : null);
			ItemData val2 = ((!((Object)(object)val != (Object)null)) ? null : val.GetComponent<ItemDrop>()?.m_itemData);
			if (val2 == null && (Object)(object)ZNetScene.instance != (Object)null)
			{
				GameObject prefab = ZNetScene.instance.GetPrefab("TurretBoltWood");
				val2 = ((prefab == null) ? null : prefab.GetComponent<ItemDrop>()?.m_itemData);
			}
			return val2;
		}

		private float BoltSpeed()
		{
			float num = Ammo()?.m_shared.m_attack.m_projectileVel ?? 60f;
			return Mathf.Max(5f, num * ModConfig.BoltSpeedMultiplier.Value);
		}

		private float BoltGravity()
		{
			GameObject val = Ammo()?.m_shared.m_attack.m_attackProjectile;
			Projectile val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Projectile>() : null);
			if (!((Object)(object)val2 != (Object)null))
			{
				return 0f;
			}
			return val2.m_gravity;
		}

		private void TakeOverIfOrphaned()
		{
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			if (Time.time < _nextOwnerCheck || _nview.IsOwner())
			{
				return;
			}
			_nextOwnerCheck = Time.time + 2f;
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && ModNetwork.Ready && !((Object)(object)ZNet.instance == (Object)null))
			{
				long owner = _nview.GetZDO().GetOwner();
				if (owner != 0L && !ModNetwork.HasMod(owner) && ZNet.instance.GetPlayerList().Any((PlayerInfo p) => ((ZDOID)(ref p.m_characterID)).UserID == owner) && Vector3.Distance(((Component)localPlayer).transform.position, ((Component)this).transform.position) < 80f)
				{
					_nview.ClaimOwnership();
					SentryBallistaPlugin.Log.LogInfo((object)$"{Def.Name}: owner {owner} has no mod, taking it over.");
				}
			}
		}
	}
	internal static class BallistaPrefabs
	{
		internal const string SourcePrefab = "piece_turret";

		private static readonly FieldInfo NamedPrefabsField = typeof(ZNetScene).GetField("m_namedPrefabs", BindingFlags.Instance | BindingFlags.NonPublic);

		private static readonly List<(TierDef Tier, GameObject Prefab)> Built = new List<(TierDef, GameObject)>();

		private static GameObject _holder;

		private static ZNetScene _scene;

		internal static void Build(ZNetScene scene)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			GameObject prefab = scene.GetPrefab("piece_turret");
			if ((Object)(object)prefab == (Object)null || (Object)(object)prefab.GetComponent<Piece>() == (Object)null || (Object)(object)prefab.GetComponent<WearNTear>() == (Object)null)
			{
				SentryBallistaPlugin.Log.LogError((object)"Base prefab 'piece_turret' not found: the ballistas will not be available.");
				return;
			}
			_scene = scene;
			Built.Clear();
			ModelKit.ReleaseCreated();
			if ((Object)(object)_holder != (Object)null)
			{
				Object.Destroy((Object)(object)_holder);
			}
			_holder = new GameObject("SentryBallista_Holder");
			_holder.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)_holder);
			TierDef[] all = TierDef.All;
			foreach (TierDef tierDef in all)
			{
				try
				{
					GameObject val = BuildTier(scene, prefab, tierDef);
					RegisterInScene(scene, val);
					Built.Add((tierDef, val));
				}
				catch (Exception arg)
				{
					SentryBallistaPlugin.Log.LogError((object)$"Building the {tierDef.Name} failed: {arg}");
				}
			}
			SentryBallistaPlugin.Log.LogInfo((object)string.Format("{0} ballistas created from '{1}'.", Built.Count, "piece_turret"));
			TryFinalize();
		}

		private static GameObject BuildTier(ZNetScene scene, GameObject source, TierDef tier)
		{
			//IL_006f: 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_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: 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_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(source, _holder.transform, false);
			((Object)val).name = tier.PrefabName;
			Transform transform = val.transform;
			Turret component = val.GetComponent<Turret>();
			CircleProjector val2 = (((Object)(object)component != (Object)null && (Object)(object)component.m_marker != (Object)null) ? component.m_marker : val.GetComponentInChildren<CircleProjector>(true));
			if ((Object)(object)val2 != (Object)null)
			{
				((Component)val2).transform.SetParent(transform, true);
				((Component)val2).transform.localPosition = Vector3.zero;
				((Component)val2).transform.localRotation = Quaternion.identity;
			}
			MonoBehaviour[] components = val.GetComponents<MonoBehaviour>();
			foreach (MonoBehaviour val3 in components)
			{
				if (!(val3 is ZNetView) && !(val3 is Piece) && !(val3 is WearNTear))
				{
					Object.DestroyImmediate((Object)(object)val3);
				}
			}
			for (int num = transform.childCount - 1; num >= 0; num--)
			{
				Transform child = transform.GetChild(num);
				if ((Object)(object)val2 == (Object)null || (Object)(object)child != (Object)(object)((Component)val2).transform)
				{
					Object.DestroyImmediate((Object)(object)((Component)child).gameObject);
				}
			}
			Collider[] components2 = val.GetComponents<Collider>();
			for (int i = 0; i < components2.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)components2[i]);
			}
			int layer = val.layer;
			Transform transform2 = new GameObject("model")
			{
				layer = layer
			}.transform;
			transform2.SetParent(transform, false);
			transform2.localScale = Vector3.one * tier.Size;
			BallistaParts ballistaParts = new BallistaModel(scene, tier).Build(transform2, layer);
			Piece component2 = val.GetComponent<Piece>();
			component2.m_name = tier.Name;
			component2.m_description = tier.Description + " (" + tier.Biome + ")";
			component2.m_enabled = true;
			TierConfig tierConfig = ModConfig.Tier(tier);
			WearNTear component3 = val.GetComponent<WearNTear>();
			component3.m_new = null;
			component3.m_worn = null;
			component3.m_broken = null;
			component3.m_wet = null;
			component3.m_snow = null;
			component3.m_snowWorn = null;
			component3.m_snowBroken = null;
			component3.m_fragmentRoots = null;
			component3.m_nonSolidRenderers?.Clear();
			component3.m_health = tierConfig.Health.Value;
			component3.m_materialType = tier.Material;
			AutoBallista autoBallista = val.AddComponent<AutoBallista>();
			autoBallista.m_tier = tier.Number;
			autoBallista.m_neck = ballistaParts.Neck;
			autoBallista.m_body = ballistaParts.Body;
			autoBallista.m_eye = ballistaParts.Eye;
			autoBallista.m_armed = ballistaParts.Armed;
			autoBallista.m_unarmed = ballistaParts.Unarmed;
			autoBallista.m_bolt = ballistaParts.Bolt;
			autoBallista.m_marker = val2;
			return val;
		}

		internal static void TryFinalize()
		{
			if (Built.Count == 0)
			{
				return;
			}
			foreach (var item3 in Built)
			{
				var (tierDef, _) = item3;
				item3.Prefab.GetComponent<Piece>().m_name = tierDef.Name;
			}
			ObjectDB instance = ObjectDB.instance;
			if ((Object)(object)instance == (Object)null || instance.m_items.Count == 0)
			{
				return;
			}
			GameObject itemPrefab = 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)
			{
				return;
			}
			HashSet<string> ours = new HashSet<string>(TierDef.All.Select((TierDef t) => t.PrefabName));
			val.m_pieces.RemoveAll((GameObject p) => (Object)(object)p == (Object)null || ours.Contains(((Object)p).name));
			int num = val.m_pieces.FindIndex((GameObject p) => ((Object)p).name == "piece_turret");
			num = ((num >= 0) ? (num + 1) : val.m_pieces.Count);
			foreach (var item4 in Built)
			{
				TierDef item = item4.Tier;
				GameObject item2 = item4.Prefab;
				TierConfig tierConfig = ModConfig.Tier(item);
				Piece component = item2.GetComponent<Piece>();
				component.m_resources = ParseRequirements(instance, tierConfig.Requirements.Value, item);
				component.m_craftingStation = FindStation(tierConfig.Station.Value, item);
				if (tierConfig.Enabled.Value)
				{
					val.m_pieces.Insert(num++, item2);
				}
			}
		}

		internal static void RenderIcons()
		{
			foreach (var item2 in Built)
			{
				GameObject item = item2.Prefab;
				AutoBallista component = item.GetComponent<AutoBallista>();
				GameObject obj = (((Object)(object)component != (Object)null) ? component.m_bolt : null);
				if (obj != null)
				{
					obj.SetActive(true);
				}
				Sprite val = IconRenderer.Render(item);
				if (obj != null)
				{
					obj.SetActive(false);
				}
				if ((Object)(object)val != (Object)null)
				{
					item.GetComponent<Piece>().m_icon = val;
				}
			}
		}

		private static CraftingStation FindStation(string name, TierDef tier)
		{
			name = (name ?? string.Empty).Trim();
			if (name.Length == 0)
			{
				return null;
			}
			object obj;
			if (!((Object)(object)_scene != (Object)null))
			{
				obj = null;
			}
			else
			{
				GameObject prefab = _scene.GetPrefab(name);
				obj = ((prefab != null) ? prefab.GetComponent<CraftingStation>() : null);
			}
			if ((Object)obj == (Object)null)
			{
				SentryBallistaPlugin.Log.LogWarning((object)(tier.Name + ": crafting station '" + name + "' not found, none required."));
			}
			return (CraftingStation)obj;
		}

		private static Requirement[] ParseRequirements(ObjectDB odb, string raw, TierDef tier)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_0081: Expected O, but got Unknown
			List<Requirement> list = Parse(odb, raw, tier, warn: true);
			if (list.Count == 0 && raw != tier.Requirements)
			{
				SentryBallistaPlugin.Log.LogWarning((object)(tier.Name + ": no valid requirements, using the default cost."));
				list = Parse(odb, tier.Requirements, tier, warn: true);
			}
			if (list.Count == 0)
			{
				list.Add(new Requirement
				{
					m_resItem = odb.GetItemPrefab("Wood").GetComponent<ItemDrop>(),
					m_amount = 20,
					m_recover = true
				});
			}
			return list.ToArray();
		}

		private static List<Requirement> Parse(ObjectDB odb, string raw, TierDef tier, bool warn)
		{
			//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_00e5: 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_00f9: Expected O, but got Unknown
			List<Requirement> list = new List<Requirement>();
			string[] array = (raw ?? string.Empty).Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string text in array)
			{
				string[] array2 = text.Trim().Split(':');
				if (array2.Length != 2 || !int.TryParse(array2[1].Trim(), out var result) || result <= 0)
				{
					if (warn)
					{
						SentryBallistaPlugin.Log.LogWarning((object)(tier.Name + ": invalid requirement '" + text + "'. Expected format Prefab:Amount."));
					}
					continue;
				}
				GameObject itemPrefab = odb.GetItemPrefab(array2[0].Trim());
				ItemDrop val = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null);
				if ((Object)(object)val == (Object)null)
				{
					if (warn)
					{
						SentryBallistaPlugin.Log.LogWarning((object)(tier.Name + ": item '" + array2[0].Trim() + "' not found in ObjectDB, skipped."));
					}
				}
				else
				{
					list.Add(new Requirement
					{
						m_resItem = val,
						m_amount = result,
						m_recover = true
					});
				}
			}
			return list;
		}

		private static void RegisterInScene(ZNetScene scene, GameObject prefab)
		{
			scene.m_prefabs.RemoveAll((GameObject p) => (Object)(object)p == (Object)null || ((Object)(object)p != (Object)(object)prefab && ((Object)p).name == ((Object)prefab).name));
			if (!scene.m_prefabs.Contains(prefab))
			{
				scene.m_prefabs.Add(prefab);
			}
			if (NamedPrefabsField?.GetValue(scene) is Dictionary<int, GameObject> dictionary)
			{
				dictionary[StringExtensionMethods.GetStableHashCode(((Object)prefab).name)] = prefab;
			}
			else
			{
				SentryBallistaPlugin.Log.LogError((object)("Cannot access ZNetScene.m_namedPrefabs: '" + ((Object)prefab).name + "' will not be buildable."));
			}
		}
	}
	internal sealed class TierConfig
	{
		internal ConfigEntry<bool> Enabled;

		internal ConfigEntry<string> Requirements;

		internal ConfigEntry<string> Station;

		internal ConfigEntry<float> Health;

		internal ConfigEntry<float> Damage;

		internal ConfigEntry<float> Range;

		internal ConfigEntry<float> FireInterval;
	}
	internal static class ModConfig
	{
		internal static ConfigEntry<float> Arc;

		internal static ConfigEntry<float> TurnSpeed;

		internal static ConfigEntry<float> MinPitch;

		internal static ConfigEntry<float> MaxPitch;

		internal static ConfigEntry<bool> ShootThroughBuildings;

		internal static ConfigEntry<bool> TargetSleeping;

		internal static ConfigEntry<bool> TargetBosses;

		internal static ConfigEntry<float> BoltSpeedMultiplier;

		internal static ConfigEntry<float> PushForce;

		private static TierConfig[] _tiers;

		internal static TierConfig Tier(TierDef tier)
		{
			return _tiers[tier.Number - 1];
		}

		internal static void Bind(ConfigFile cfg)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Expected O, but got Unknown
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Expected O, but got Unknown
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Expected O, but got Unknown
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Expected O, but got Unknown
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Expected O, but got Unknown
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Expected O, but got Unknown
			Arc = cfg.Bind<float>("0 - General", "Arc", 180f, new ConfigDescription("Each ballista turns this many degrees left and right of the way it was built facing. 180 = all around.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(15f, 180f), Array.Empty<object>()));
			TurnSpeed = cfg.Bind<float>("0 - General", "TurnSpeed", 110f, new ConfigDescription("How fast a ballista swings onto its target, in degrees per second.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 720f), Array.Empty<object>()));
			MinPitch = cfg.Bind<float>("0 - General", "MinPitch", -35f, new ConfigDescription("Lowest a ballista can aim, in degrees (negative = down, to shoot from walls).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-80f, 0f), Array.Empty<object>()));
			MaxPitch = cfg.Bind<float>("0 - General", "MaxPitch", 60f, new ConfigDescription("Highest a ballista can aim, in degrees (flying creatures).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 85f), Array.Empty<object>()));
			ShootThroughBuildings = cfg.Bind<bool>("0 - General", "ShootThroughBuildings", true, "Bolts fly through player-built pieces (your own walls, roofs and the ballista itself) and the ballistas see over them: a ballista behind a palisade still defends it. If false, buildings block the view and the bolts.");
			TargetSleeping = cfg.Bind<bool>("0 - General", "TargetSleeping", false, "Also shoot creatures that are asleep.");
			TargetBosses = cfg.Bind<bool>("0 - General", "TargetBosses", true, "Also shoot the bosses.");
			BoltSpeedMultiplier = cfg.Bind<float>("0 - General", "BoltSpeedMultiplier", 1f, new ConfigDescription("Speed of the bolts compared to a vanilla ballista.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 4f), Array.Empty<object>()));
			PushForce = cfg.Bind<float>("0 - General", "PushForce", 20f, new ConfigDescription("How hard a bolt knocks back what it hits.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f), Array.Empty<object>()));
			_tiers = new TierConfig[TierDef.All.Length];
			TierDef[] all = TierDef.All;
			foreach (TierDef tierDef in all)
			{
				string section = tierDef.Section;
				_tiers[tierDef.Number - 1] = new TierConfig
				{
					Enabled = cfg.Bind<bool>(section, "Enabled", true, "The " + tierDef.Name + " (" + tierDef.Biome + ") can be built with the hammer."),
					Requirements = cfg.Bind<string>(section, "Requirements", tierDef.Requirements, "Cost, as Prefab:Amount separated by commas."),
					Station = cfg.Bind<string>(section, "CraftingStation", tierDef.Station, "Crafting station that must be nearby to build it (prefab name: piece_workbench, forge, blackforge, piece_artisanstation, piece_magetable...). Empty = none."),
					Health = cfg.Bind<float>(section, "Health", tierDef.Health, new ConfigDescription("Hit points of the piece. Creatures can break it; repair it with the hammer. Applied on the next world load.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(50f, 50000f), Array.Empty<object>())),
					Damage = cfg.Bind<float>(section, "Damage", tierDef.Damage, new ConfigDescription("Pierce damage of each bolt.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5000f), Array.Empty<object>())),
					Range = cfg.Bind<float>(section, "Range", tierDef.Range, new ConfigDescription("Distance, in meters, at which it starts shooting.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 120f), Array.Empty<object>())),
					FireInterval = cfg.Bind<float>(section, "FireInterval", tierDef.FireInterval, new ConfigDescription("Seconds between two shots.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 30f), Array.Empty<object>()))
				};
			}
		}
	}
	internal class ModNetwork : MonoBehaviour
	{
		private const string RpcHello = "ymiron_sentryballista_hello";

		private const float CheckInterval = 2f;

		private const float HelloGracePeriod = 8f;

		private const float WarnAfter = 20f;

		private static readonly Dictionary<long, string> Versions = new Dictionary<long, string>();

		private static float _readySince = float.MaxValue;

		private readonly HashSet<long> _knownPlayers = new HashSet<long>();

		private readonly Dictionary<long, float> _firstSeen = new Dictionary<long, float>();

		private readonly HashSet<long> _warned = new HashSet<long>();

		private float _timer;

		private bool _helloSent;

		internal static bool Ready => Time.time - _readySince > 8f;

		internal static bool HasMod(long peer)
		{
			if (peer != ZDOMan.GetSessionID())
			{
				return Versions.ContainsKey(peer);
			}
			return true;
		}

		private void Start()
		{
			Versions.Clear();
			_readySince = float.MaxValue;
			if (ZRoutedRpc.instance == null)
			{
				SentryBallistaPlugin.Log.LogError((object)"ZRoutedRpc not available: mod detection between players will not work.");
			}
			else
			{
				ZRoutedRpc.instance.Register<string>("ymiron_sentryballista_hello", (Action<long, string>)RPC_Hello);
			}
		}

		private void Update()
		{
			_timer -= Time.deltaTime;
			if (_timer > 0f)
			{
				return;
			}
			_timer = 2f;
			if ((Object)(object)ZNet.instance == (Object)null || ZRoutedRpc.instance == null || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				return;
			}
			if (_readySince == float.MaxValue)
			{
				_readySince = Time.time;
			}
			long me = ZDOMan.GetSessionID();
			List<long> list = (from p in ZNet.instance.GetPlayerList()
				select ((ZDOID)(ref p.m_characterID)).UserID into id
				where id != 0L && id != me
				select id).ToList();
			if (!_helloSent || list.Any((long id) => !_knownPlayers.Contains(id)))
			{
				_helloSent = true;
				ZRoutedRpc.instance.InvokeRoutedRPC(0L, "ymiron_sentryballista_hello", new object[1] { "0.1.1" });
			}
			_knownPlayers.Clear();
			_knownPlayers.UnionWith(list);
			foreach (long item in list)
			{
				if (_warned.Contains(item))
				{
					continue;
				}
				float value2;
				if (Versions.TryGetValue(item, out var value))
				{
					if (value != "0.1.1")
					{
						Warn(item, "has SentryBallista-Ymiron " + value + " instead of 0.1.1: the ballistas may not work right near them.");
					}
				}
				else if (!_firstSeen.TryGetValue(item, out value2))
				{
					_firstSeen[item] = Time.time;
				}
				else if (Time.time - value2 > 20f)
				{
					Warn(item, "does not have SentryBallista-Ymiron: they cannot see the ballistas.");
				}
			}
		}

		private static void RPC_Hello(long sender, string version)
		{
			if (sender != ZDOMan.GetSessionID())
			{
				if (!Versions.ContainsKey(sender))
				{
					SentryBallistaPlugin.Log.LogInfo((object)$"Peer {sender} has SentryBallista-Ymiron {version}.");
				}
				Versions[sender] = version;
			}
		}

		private void Warn(long id, string problem)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			_warned.Add(id);
			string text = ((IEnumerable<PlayerInfo>)ZNet.instance.GetPlayerList()).FirstOrDefault((Func<PlayerInfo, bool>)((PlayerInfo p) => ((ZDOID)(ref p.m_characterID)).UserID == id)).m_name ?? $"Player {id}";
			string text2 = "[SentryBallista] " + text + " " + problem;
			SentryBallistaPlugin.Log.LogWarning((object)text2);
			if ((Object)(object)Chat.instance != (Object)null)
			{
				((Terminal)Chat.instance).AddString(text2);
			}
		}
	}
	[HarmonyPatch(typeof(ZNetScene), "Awake")]
	internal static class ZNetScene_Awake_Patch
	{
		private static void Postfix(ZNetScene __instance)
		{
			BallistaPrefabs.Build(__instance);
		}
	}
	[HarmonyPatch(typeof(ObjectDB), "Awake")]
	internal static class ObjectDB_Awake_Patch
	{
		private static void Postfix()
		{
			BallistaPrefabs.TryFinalize();
		}
	}
	[HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")]
	internal static class ObjectDB_CopyOtherDB_Patch
	{
		private static void Postfix()
		{
			BallistaPrefabs.TryFinalize();
		}
	}
	[HarmonyPatch(typeof(Game), "Start")]
	internal static class Game_Start_Patch
	{
		private static void Postfix(Game __instance)
		{
			((Component)__instance).gameObject.AddComponent<ModNetwork>();
			BallistaPrefabs.RenderIcons();
		}
	}
	[HarmonyPatch(typeof(Projectile), "OnHit")]
	internal static class Projectile_OnHit_Patch
	{
		private static bool Prefix(Projectile __instance, Collider collider)
		{
			return !BallistaShots.Ignores(__instance, collider);
		}
	}
	[BepInPlugin("ymiron.valheim.sentryballista", "SentryBallista-Ymiron", "0.1.1")]
	[BepInProcess("valheim.exe")]
	[BepInProcess("valheim_server.exe")]
	public class SentryBallistaPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "ymiron.valheim.sentryballista";

		public const string PluginName = "SentryBallista-Ymiron";

		public const string PluginVersion = "0.1.1";

		private Harmony _harmony;

		private FileSystemWatcher _watcher;

		private volatile bool _configChanged;

		internal static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			ModConfig.Bind(((BaseUnityPlugin)this).Config);
			_harmony = new Harmony("ymiron.valheim.sentryballista");
			Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(typeof(SentryBallistaPlugin).Assembly);
			foreach (Type type in typesFromAssembly)
			{
				try
				{
					_harmony.CreateClassProcessor(type).Patch();
				}
				catch (Exception ex)
				{
					Log.LogError((object)("Patch " + type.Name + " failed: " + ex.Message));
				}
			}
			WatchConfigFile();
			Log.LogInfo((object)"SentryBallista-Ymiron 0.1.1 loaded.");
		}

		private void WatchConfigFile()
		{
			_watcher = new FileSystemWatcher(Path.GetDirectoryName(((BaseUnityPlugin)this).Config.ConfigFilePath), Path.GetFileName(((BaseUnityPlugin)this).Config.ConfigFilePath))
			{
				NotifyFilter = (NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite),
				IncludeSubdirectories = false
			};
			_watcher.Changed += delegate
			{
				_configChanged = true;
			};
			_watcher.Created += delegate
			{
				_configChanged = true;
			};
			_watcher.Renamed += delegate
			{
				_configChanged = true;
			};
			_watcher.EnableRaisingEvents = true;
		}

		private void Update()
		{
			if (!_configChanged)
			{
				return;
			}
			_configChanged = false;
			try
			{
				((BaseUnityPlugin)this).Config.Reload();
				Log.LogInfo((object)"Config reloaded (health changes on the next world load).");
				BallistaPrefabs.TryFinalize();
			}
			catch (IOException)
			{
				_configChanged = true;
			}
		}

		private void OnDestroy()
		{
			_watcher?.Dispose();
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	internal static class Targeting
	{
		internal static bool IsHostile(Character character)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Invalid comparison between Unknown and I4
			//IL_0035: 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_004d: Expected I4, but got Unknown
			if ((Object)(object)character == (Object)null || character.IsDead() || character.IsPlayer() || character.IsTamed())
			{
				return false;
			}
			BaseAI baseAI = character.GetBaseAI();
			Faction faction = character.GetFaction();
			if ((int)faction > 1)
			{
				switch (faction - 8)
				{
				case 3:
					break;
				case 2:
					if ((Object)(object)baseAI == (Object)null || !baseAI.IsAggravated())
					{
						return false;
					}
					goto default;
				case 0:
					if (!ModConfig.TargetBosses.Value)
					{
						return false;
					}
					goto default;
				default:
					if (!ModConfig.TargetSleeping.Value && !((Object)(object)baseAI == (Object)null))
					{
						return !baseAI.IsSleeping();
					}
					return true;
				}
			}
			return false;
		}
	}
	internal static class BallistaShots
	{
		private static readonly ConditionalWeakTable<Projectile, object> Shots = new ConditionalWeakTable<Projectile, object>();

		private static readonly object Mark = new object();

		internal static void Register(GameObject projectile)
		{
			Projectile val = (((Object)(object)projectile != (Object)null) ? projectile.GetComponent<Projectile>() : null);
			if ((Object)(object)val != (Object)null)
			{
				Shots.Remove(val);
				Shots.Add(val, Mark);
			}
		}

		internal static bool Ignores(Projectile projectile, Collider collider)
		{
			if ((Object)(object)collider == (Object)null || !Shots.TryGetValue(projectile, out var _))
			{
				return false;
			}
			Character componentInParent = ((Component)collider).GetComponentInParent<Character>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				return !Targeting.IsHostile(componentInParent);
			}
			if ((Object)(object)((Component)collider).GetComponentInParent<AutoBallista>() != (Object)null)
			{
				return true;
			}
			if (!ModConfig.ShootThroughBuildings.Value)
			{
				return false;
			}
			Piece componentInParent2 = ((Component)collider).GetComponentInParent<Piece>();
			if ((Object)(object)componentInParent2 != (Object)null)
			{
				return componentInParent2.IsPlacedByPlayer();
			}
			return false;
		}
	}
	internal static class TurretEffects
	{
		private static Turret _turret;

		private static Turret Source
		{
			get
			{
				if ((Object)(object)_turret == (Object)null && (Object)(object)ZNetScene.instance != (Object)null)
				{
					GameObject prefab = ZNetScene.instance.GetPrefab("piece_turret");
					_turret = ((prefab != null) ? prefab.GetComponent<Turret>() : null);
				}
				return _turret;
			}
		}

		internal static void Shoot(Vector3 position, Quaternion rotation, bool fromOwner)
		{
			//IL_0011: 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)
			Play(Source?.m_shootEffect, position, rotation, fromOwner);
		}

		internal static void Reload(Vector3 position, Quaternion rotation)
		{
			//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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			Camera mainCamera = Utils.GetMainCamera();
			if ((Object)(object)mainCamera != (Object)null && Vector3.Distance(((Component)mainCamera).transform.position, position) < 50f)
			{
				Play(Source?.m_reloadEffect, position, rotation, fromOwner: false);
			}
		}

		internal static void NewTarget(Transform at)
		{
			//IL_0012: 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)
			Play(Source?.m_newTargetEffect, at.position, at.rotation, fromOwner: true);
		}

		internal static void LostTarget(Transform at)
		{
			//IL_0012: 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)
			Play(Source?.m_lostTargetEffect, at.position, at.rotation, fromOwner: true);
		}

		private static void Play(EffectList effects, Vector3 position, Quaternion rotation, bool fromOwner)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if (effects?.m_effectPrefabs != null)
			{
				new EffectList
				{
					m_effectPrefabs = effects.m_effectPrefabs.Where((EffectData e) => e != null && (Object)(object)e.m_prefab != (Object)null && (fromOwner || (Object)(object)e.m_prefab.GetComponent<ZNetView>() == (Object)null)).ToArray()
				}.Create(position, rotation, (Transform)null, 1f, -1, default(ZDOID));
			}
		}
	}
	internal enum BaseStyle
	{
		Tripod,
		Pedestal,
		Plinth
	}
	internal sealed class TierDef
	{
		internal int Number;

		internal string Key;

		internal string Name;

		internal string Biome;

		internal string Description;

		internal string Requirements;

		internal string Station;

		internal float Health;

		internal float Damage;

		internal float Range;

		internal float FireInterval;

		internal MaterialType Material;

		internal string Ammo;

		internal float Size;

		internal BaseStyle Base;

		internal bool Torsion;

		internal bool Mantlet;

		internal bool MantletWood;

		internal bool MetalFittings;

		internal Color Cord = new Color(0.7f, 0.58f, 0.4f);

		internal Color WoodTint = Color.white;

		internal bool DarkWood;

		internal Color Metal;

		internal float MetalGloss = 0.45f;

		internal Color Stone = new Color(0.55f, 0.55f, 0.55f);

		internal Color Glow = Color.clear;

		internal bool IceCrystals;

		internal static readonly TierDef[] All = new TierDef[8]
		{
			new TierDef
			{
				Number = 1,
				Key = "meadows",
				Name = "Hunter's Ballista",
				Biome = "Meadows",
				Description = "Poles and hide lashings around a big bent bow. Shoots by itself at hostile creatures that come near.",
				Requirements = "Wood:20,Flint:8,DeerHide:4,Resin:6",
				Station = "piece_workbench",
				Health = 300f,
				Damage = 18f,
				Range = 18f,
				FireInterval = 4f,
				Material = (MaterialType)0,
				Ammo = "TurretBoltWood",
				Size = 0.8f,
				Base = BaseStyle.Tripod,
				Torsion = false,
				Mantlet = false,
				MetalFittings = false,
				WoodTint = new Color(1f, 0.95f, 0.88f),
				Metal = new Color(0.45f, 0.42f, 0.38f),
				MetalGloss = 0.2f,
				Cord = new Color(0.52f, 0.38f, 0.26f)
			},
			new TierDef
			{
				Number = 2,
				Key = "blackforest",
				Name = "Bronze Ballista",
				Biome = "Black Forest",
				Description = "A sturdier bow on a squared tripod, with bronze caps and claw. Shoots by itself at hostile creatures that come near.",
				Requirements = "FineWood:15,Bronze:4,TrollHide:2,Resin:6",
				Station = "piece_workbench",
				Health = 500f,
				Damage = 32f,
				Range = 22f,
				FireInterval = 3.6f,
				Material = (MaterialType)0,
				Ammo = "TurretBoltWood",
				Size = 0.85f,
				Base = BaseStyle.Tripod,
				Torsion = false,
				Mantlet = false,
				MetalFittings = true,
				WoodTint = new Color(0.95f, 0.85f, 0.72f),
				Metal = new Color(0.62f, 0.4f, 0.18f),
				MetalGloss = 0.55f,
				Cord = new Color(0.45f, 0.36f, 0.3f)
			},
			new TierDef
			{
				Number = 3,
				Key = "swamp",
				Name = "Iron Ballista",
				Biome = "Swamp",
				Description = "A torsion ballista: two rope springs in an iron-banded frame, on a braced post. Shoots by itself at hostile creatures that come near.",
				Requirements = "ElderBark:10,Iron:6,Chain:1,Guck:2",
				Station = "forge",
				Health = 800f,
				Damage = 50f,
				Range = 26f,
				FireInterval = 3.3f,
				Material = (MaterialType)2,
				Ammo = "TurretBoltWood",
				Size = 0.92f,
				Base = BaseStyle.Pedestal,
				Torsion = true,
				Mantlet = false,
				MetalFittings = true,
				DarkWood = true,
				Metal = new Color(0.32f, 0.32f, 0.34f)
			},
			new TierDef
			{
				Number = 4,
				Key = "mountain",
				Name = "Silver Ballista",
				Biome = "Mountain",
				Description = "A torsion ballista with silver fittings and studs. Shoots by itself at hostile creatures that come near.",
				Requirements = "FineWood:10,Silver:6,WolfPelt:4,Obsidian:6",
				Station = "forge",
				Health = 1100f,
				Damage = 70f,
				Range = 30f,
				FireInterval = 3f,
				Material = (MaterialType)2,
				Ammo = "TurretBolt",
				Size = 0.97f,
				Base = BaseStyle.Pedestal,
				Torsion = true,
				Mantlet = false,
				MetalFittings = true,
				DarkWood = true,
				WoodTint = new Color(0.92f, 0.92f, 0.95f),
				Metal = new Color(0.78f, 0.8f, 0.84f),
				MetalGloss = 0.7f
			},
			new TierDef
			{
				Number = 5,
				Key = "plains",
				Name = "Black Metal Ballista",
				Biome = "Plains",
				Description = "A torsion ballista behind a black metal mantlet. Shoots by itself at hostile creatures that come near.",
				Requirements = "FineWood:10,BlackMetal:8,LinenThread:6,LoxPelt:2",
				Station = "forge",
				Health = 1400f,
				Damage = 95f,
				Range = 34f,
				FireInterval = 2.8f,
				Material = (MaterialType)2,
				Ammo = "TurretBolt",
				Size = 1f,
				Base = BaseStyle.Pedestal,
				Torsion = true,
				Mantlet = true,
				MetalFittings = true,
				DarkWood = true,
				Metal = new Color(0.13f, 0.13f, 0.14f),
				MetalGloss = 0.5f,
				Cord = new Color(0.86f, 0.83f, 0.72f)
			},
			new TierDef
			{
				Number = 6,
				Key = "mistlands",
				Name = "Dvergr Ballista",
				Biome = "Mistlands",
				Description = "Dvergr work: yggdrasil wood, black marble and blue runes. Shoots by itself at hostile creatures that come near.",
				Requirements = "YggdrasilWood:10,BlackMarble:8,MechanicalSpring:2,Carapace:6",
				Station = "blackforge",
				Health = 1800f,
				Damage = 125f,
				Range = 38f,
				FireInterval = 2.5f,
				Material = (MaterialType)2,
				Ammo = "TurretBolt",
				Size = 1.05f,
				Base = BaseStyle.Plinth,
				Torsion = true,
				Mantlet = true,
				MetalFittings = true,
				DarkWood = true,
				WoodTint = new Color(0.62f, 0.66f, 0.85f),
				Metal = new Color(0.2f, 0.21f, 0.24f),
				MetalGloss = 0.6f,
				Stone = new Color(0.16f, 0.16f, 0.18f),
				Glow = new Color(0.3f, 0.75f, 1f, 1f),
				Cord = new Color(0.3f, 0.32f, 0.38f)
			},
			new TierDef
			{
				Number = 7,
				Key = "ashlands",
				Name = "Flametal Ballista",
				Biome = "Ashlands",
				Description = "Blackwood and flametal on a grausten plinth, glowing like embers. Shoots by itself at hostile creatures that come near.",
				Requirements = "Blackwood:10,FlametalNew:6,Grausten:10,AskHide:4",
				Station = "blackforge",
				Health = 2300f,
				Damage = 160f,
				Range = 42f,
				FireInterval = 2.3f,
				Material = (MaterialType)2,
				Ammo = "TurretBoltFlametal",
				Size = 1.1f,
				Base = BaseStyle.Plinth,
				Torsion = true,
				Mantlet = true,
				MetalFittings = true,
				DarkWood = true,
				WoodTint = new Color(0.42f, 0.36f, 0.34f),
				Metal = new Color(0.22f, 0.2f, 0.2f),
				MetalGloss = 0.55f,
				Stone = new Color(0.36f, 0.3f, 0.29f),
				Glow = new Color(1f, 0.45f, 0.1f, 1f),
				Cord = new Color(0.42f, 0.3f, 0.24f)
			},
			new TierDef
			{
				Number = 8,
				Key = "deepnorth",
				Name = "Frost Ballista",
				Biome = "Deep North",
				Description = "Frostwood, gold and ice that never melts. Shoots by itself at hostile creatures that come near.",
				Requirements = "Frostwood:10,Gold:6,MooseSinew:4,Ice:10",
				Station = "blackforge",
				Health = 2800f,
				Damage = 200f,
				Range = 46f,
				FireInterval = 2f,
				Material = (MaterialType)2,
				Ammo = "TurretBoltBloodgold",
				Size = 1.15f,
				Base = BaseStyle.Plinth,
				Torsion = true,
				Mantlet = true,
				MetalFittings = true,
				DarkWood = false,
				WoodTint = new Color(0.78f, 0.86f, 0.95f),
				Metal = new Color(0.9f, 0.68f, 0.22f),
				MetalGloss = 0.75f,
				Stone = new Color(0.72f, 0.8f, 0.88f),
				Glow = new Color(0.55f, 0.85f, 1f, 1f),
				IceCrystals = true,
				MantletWood = true,
				Cord = new Color(0.6f, 0.45f, 0.35f)
			}
		};

		internal string PrefabName => "ymiron_ballista_" + Key;

		internal string Section => $"{Number} - {Biome}";
	}
}
namespace SentryBallista.Visuals
{
	internal sealed class BallistaParts
	{
		internal Transform Neck;

		internal Transform Body;

		internal Transform Eye;

		internal GameObject Armed;

		internal GameObject Unarmed;

		internal GameObject Bolt;
	}
	internal sealed class BallistaModel
	{
		private const float StockFront = 1f;

		private const float StockBack = 1.15f;

		private const float HeadZ = 0.8f;

		private const float NockZ = -0.5f;

		private const float WinchZ = -0.95f;

		private const float StringY = 0.15f;

		private const float BoltY = 0.18f;

		private const float HandleLength = 0.22f;

		private const float SpringX = 0.4f;

		private const float FrameHalfWidth = 0.66f;

		private static readonly Vector3 CockedTip = new Vector3(1.1f, 0.12f, 0.2f);

		private static readonly Vector3 RestTip = new Vector3(1.2f, 0.12f, 0.5f);

		private const float BowRoot = 0.13f;

		private const float BowTip = 1.15f;

		private readonly TierDef _tier;

		private readonly Material _wood;

		private readonly Material _frameWood;

		private readonly Material _cord;

		private readonly Material _metal;

		private readonly Material _feather;

		private readonly Material _stone;

		private readonly Material _glow;

		private const float PlinthTop = 0.36f;

		internal float PivotHeight { get; }

		internal BallistaModel(ZNetScene scene, TierDef tier)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: 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_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			_tier = tier;
			Material val = ModelKit.DarkWood(scene);
			Material val2 = ModelKit.FindMaterial(scene, "wood_pole", "wood_beam", "wood_floor") ?? val;
			Material val3 = (tier.DarkWood ? val : val2);
			string key = tier.Key;
			_wood = ((tier.WoodTint == Color.white) ? val3 : ModelKit.Tinted(val3, "sb_" + key + "_wood", tier.WoodTint));
			_frameWood = ModelKit.Tinted(val3, "sb_" + key + "_framewood", tier.WoodTint * 0.78f);
			_cord = ModelKit.Tinted(val2, "sb_" + key + "_cord", tier.Cord);
			_metal = ModelKit.Metal(val, "sb_" + key + "_metal", tier.Metal, tier.MetalFittings ? 0.75f : 0.1f, tier.MetalGloss);
			_feather = ModelKit.Painted(val2, "sb_" + key + "_fletching", new Color(0.88f, 0.86f, 0.8f));
			if (tier.Base == BaseStyle.Plinth)
			{
				Material val4 = ModelKit.FindMaterial(scene, "Rock_3", "Rock_4", "rock4_forest", "Rock_7");
				_stone = (((Object)(object)val4 != (Object)null) ? ModelKit.Tinted(val4, "sb_" + key + "_stone", tier.Stone) : ModelKit.Painted(val, "sb_" + key + "_stone", tier.Stone));
			}
			if (tier.Glow.a > 0f)
			{
				_glow = ModelKit.Glow(val2, "sb_" + key + "_glow", new Color(tier.Glow.r, tier.Glow.g, tier.Glow.b), 2.5f);
			}
			switch (tier.Base)
			{
			case BaseStyle.Tripod:
				PivotHeight = 1f;
				break;
			case BaseStyle.Pedestal:
				PivotHeight = 1.2f;
				break;
			default:
				PivotHeight = 1.45f;
				break;
			}
		}

		internal BallistaParts Build(Transform model, int layer)
		{
			//IL_0061: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: 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)
			float pivotHeight = PivotHeight;
			switch (_tier.Base)
			{
			case BaseStyle.Tripod:
				BuildTripod(model, pivotHeight);
				break;
			case BaseStyle.Pedestal:
				BuildPedestal(model, pivotHeight, 0f);
				break;
			default:
				BuildPlinth(model);
				BuildPedestal(model, pivotHeight, 0.36f);
				break;
			}
			BallistaParts ballistaParts = new BallistaParts();
			ballistaParts.Neck = Part(model, "fork", new Vector3(0f, pivotHeight, 0f), layer);
			BuildFork(ballistaParts.Neck);
			ballistaParts.Body = Part(model, "body", new Vector3(0f, pivotHeight, 0f), layer);
			BuildStock(ballistaParts.Body);
			if (_tier.Torsion)
			{
				BuildTorsionFrame(ballistaParts.Body);
				ballistaParts.Armed = TorsionLimbs(ballistaParts.Body, "armed", CockedTip, (Vector3?)new Vector3(0f, 0.15f, -0.5f), layer);
				ballistaParts.Unarmed = TorsionLimbs(ballistaParts.Body, "unarmed", RestTip, null, layer);
			}
			else
			{
				BuildRiser(ballistaParts.Body);
				ballistaParts.Armed = Bow(ballistaParts.Body, "armed", 0.55f, 1.6f, drawn: true, layer);
				ballistaParts.Unarmed = Bow(ballistaParts.Body, "unarmed", 0.2f, 2f, drawn: false, layer);
			}
			ballistaParts.Unarmed.SetActive(false);
			if (_tier.Mantlet)
			{
				BuildMantlet(ballistaParts.Body);
			}
			ballistaParts.Bolt = Bolt(ballistaParts.Body, layer);
			ballistaParts.Bolt.SetActive(false);
			ballistaParts.Eye = new GameObject("eye").transform;
			ballistaParts.Eye.SetParent(ballistaParts.Body, false);
			ballistaParts.Eye.localPosition = new Vector3(0f, 0.18f, 1.55f);
			float num = ((_tier.Base == BaseStyle.Plinth) ? 1.45f : 1.1f);
			ModelKit.AddBoxCollider(model, new Vector3(0f, (pivotHeight - 0.2f) * 0.5f, 0f), new Vector3(num, pivotHeight - 0.2f, num), Quaternion.identity);
			ModelKit.AddBoxCollider(model, new Vector3(0f, pivotHeight + 0.12f, 0f), new Vector3(1.1f, 0.65f, 1.3f), Quaternion.identity);
			return ballistaParts;
		}

		private static Transform Part(Transform parent, string name, Vector3 position, int layer)
		{
			//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_001b: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = new GameObject(name)
			{
				layer = layer
			}.transform;
			transform.SetParent(parent, false);
			transform.localPosition = position;
			return transform;
		}

		private void BuildTripod(Transform model, float h)
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: 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_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_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: 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_0138: 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_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: 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_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: 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_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			MeshBuilder meshBuilder = new MeshBuilder();
			MeshBuilder meshBuilder2 = new MeshBuilder();
			MeshBuilder meshBuilder3 = new MeshBuilder();
			bool metalFittings = _tier.MetalFittings;
			float num = h - 0.44f;
			float num2 = h - 0.2f;
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(0f, h - 0.3f, 0f);
			Vector3[] array = (Vector3[])(object)new Vector3[3];
			Vector3 val2 = default(Vector3);
			for (int i = 0; i < 3; i++)
			{
				float num3 = MathF.PI + (float)i * 2f * MathF.PI / 3f;
				((Vector3)(ref val2))..ctor(Mathf.Sin(num3), 0f, Mathf.Cos(num3));
				array[i] = val2 * 0.64f;
				Vector3 to = val - val2 * 0.08f + Vector3.up * 0.06f;
				Pole(meshBuilder, array[i], to, metalFittings ? 0.1f : 0.055f, metalFittings);
				if (metalFittings)
				{
					meshBuilder3.Prism(array[i], 0.075f, 0f, 0.09f, 8);
				}
			}
			for (int j = 0; j < 3; j++)
			{
				Vector3 val3 = Vector3.Lerp(array[j], val, 0.32f);
				Vector3 to2 = Vector3.Lerp(array[(j + 1) % 3], val, 0.32f);
				Pole(meshBuilder, val3, to2, metalFittings ? 0.07f : 0.04f, metalFittings);
				if (!metalFittings)
				{
					meshBuilder2.Prism(val3, 0.07f, val3.y - 0.05f, val3.y + 0.05f, 8);
				}
			}
			meshBuilder.Prism(Vector3.zero, 0.13f, num, num2, 8);
			MeshBuilder obj = (metalFittings ? meshBuilder3 : meshBuilder2);
			obj.Prism(Vector3.zero, 0.145f, num + 0.03f, num + 0.09f, 8);
			obj.Prism(Vector3.zero, 0.145f, num2 - 0.09f, num2 - 0.03f, 8);
			ModelKit.Emit(model, "tripod", meshBuilder, _wood);
			ModelKit.Emit(model, "tripod_lashings", meshBuilder2, _cord);
			ModelKit.Emit(model, "tripod_fittings", meshBuilder3, _metal);
		}

		private static void Pole(MeshBuilder b, Vector3 from, Vector3 to, float thickness, bool squared)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_0063: 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_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if (squared)
			{
				Vector3 val = to - from;
				Vector3 val2 = Vector3.Cross(((Vector3)(ref val)).normalized, Vector3.up);
				b.Beam(from, to, thickness, thickness, (((Vector3)(ref val2)).sqrMagnitude > 0.0001f) ? val2 : Vector3.right);
				return;
			}
			b.Tube((IList<Vector3>)(object)new Vector3[3]
			{
				from,
				Vector3.Lerp(from, to, 0.5f),
				to
			}, new float[3]
			{
				thickness,
				thickness * 0.92f,
				thickness * 0.85f
			}, 8);
		}

		private void BuildPlinth(Transform model)
		{
			//IL_0007: 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_00b5: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0118: 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_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_033b: 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_0347: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0352: Unknown result type (might be due to invalid IL or missing references)
			//IL_0359: Unknown result type (might be due to invalid IL or missing references)
			//IL_035e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Unknown result type (might be due to invalid IL or missing references)
			//IL_0376: Unknown result type (might be due to invalid IL or missing references)
			//IL_037b: Unknown result type (might be due to invalid IL or missing references)
			//IL_037d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0382: 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_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			MeshBuilder meshBuilder = new MeshBuilder();
			meshBuilder.Frustum(Vector3.zero, 0.78f, 0.66f, 0f, 0.3f, 8);
			meshBuilder.Prism(Vector3.zero, 0.7f, 0.3f, 0.36f, 8);
			ModelKit.Emit(model, "plinth", meshBuilder, _stone);
			MeshBuilder meshBuilder2 = new MeshBuilder();
			if ((Object)(object)_glow != (Object)null && !_tier.IceCrystals)
			{
				float num = Mathf.Cos(MathF.PI / 8f);
				Vector3 val = default(Vector3);
				for (int i = 0; i < 8; i++)
				{
					float num2 = MathF.PI / 4f * (float)(i + 1);
					((Vector3)(ref val))..ctor(Mathf.Cos(num2), 0f, Mathf.Sin(num2));
					Vector3 tangent = new Vector3(0f - val.z, 0f, val.x);
					Vector3 bottom = val * (0.78f * num + 0.008f);
					Vector3 top = val * (0.66f * num + 0.008f) + Vector3.up * 0.3f;
					if (_tier.Number == 6)
					{
						meshBuilder2.Beam(At(0.2f, 0f), At(0.82f, 0f), 0.03f, 0.016f, val);
						meshBuilder2.Beam(At(0.82f, 0f), At(0.58f, -0.07f), 0.026f, 0.016f, val);
						meshBuilder2.Beam(At(0.82f, 0f), At(0.58f, 0.07f), 0.026f, 0.016f, val);
					}
					else
					{
						float num3 = ((i % 2 == 0) ? 1f : (-1f));
						meshBuilder2.Beam(At(0.1f, -0.1f * num3), At(0.4f, 0.04f * num3), 0.022f, 0.016f, val);
						meshBuilder2.Beam(At(0.4f, 0.04f * num3), At(0.62f, -0.05f * num3), 0.02f, 0.016f, val);
						meshBuilder2.Beam(At(0.62f, -0.05f * num3), At(0.92f, 0.08f * num3), 0.016f, 0.016f, val);
					}
					Vector3 At(float t, float across)
					{
						//IL_0001: Unknown result type (might be due to invalid IL or missing references)
						//IL_0007: Unknown result type (might be due to invalid IL or missing references)
						//IL_000d: Unknown result type (might be due to invalid IL or missing references)
						//IL_0013: Unknown result type (might be due to invalid IL or missing references)
						//IL_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)
						return Vector3.Lerp(bottom, top, t) + tangent * across;
					}
				}
			}
			if (_tier.IceCrystals)
			{
				MeshBuilder meshBuilder3 = new MeshBuilder();
				Vector3 val2 = default(Vector3);
				for (int j = 0; j < 8; j++)
				{
					float num4 = MathF.PI / 8f + (float)j * MathF.PI / 4f;
					((Vector3)(ref val2))..ctor(Mathf.Cos(num4), 0f, Mathf.Sin(num4));
					float num5 = ((j % 2 == 0) ? 0.42f : 0.28f);
					MeshBuilder meshBuilder4 = new MeshBuilder();
					meshBuilder4.Crystal(Vector3.zero, num5, num5 * 0.22f, 6);
					Quaternion val3 = Quaternion.AngleAxis(25f + 10f * (float)(j % 3), new Vector3(0f - val2.z, 0f, val2.x));
					meshBuilder3.Append(meshBuilder4, Matrix4x4.TRS(val2 * 0.68f + Vector3.up * (0.36f + num5 * 0.25f), val3, Vector3.one));
				}
				ModelKit.Emit(model, "plinth_ice", meshBuilder3, _glow);
			}
			ModelKit.Emit(model, "plinth_glow", meshBuilder2, _glow);
		}

		private void BuildPedestal(Transform model, float h, float floor)
		{
			//IL_0177: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00a2: 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_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_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: 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_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: 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_0104: 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_012c: 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_0138: 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_015b: 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_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: 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_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_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: 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_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: 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_0356: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Unknown result type (might be due to invalid IL or missing references)
			//IL_0376: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			MeshBuilder meshBuilder = new MeshBuilder();
			MeshBuilder meshBuilder2 = new MeshBuilder();
			float num = h - 0.26f;
			Vector3[] array;
			if (floor <= 0f)
			{
				meshBuilder.Box(new Vector3(0f, 0.05f, 0f), new Vector3(1.1f, 0.1f, 0.15f));
				meshBuilder.Box(new Vector3(0f, 0.05f, 0f), new Vector3(0.15f, 0.1f, 1.1f));
				floor = 0.1f;
				array = (Vector3[])(object)new Vector3[4]
				{
					Vector3.right,
					Vector3.left,
					Vector3.forward,
					Vector3.back
				};
				foreach (Vector3 val in array)
				{
					meshBuilder2.Box(val * 0.53f + Vector3.up * 0.05f, new Vector3(0.17f, 0.12f, 0.17f) - Abs(val) * 0.1f);
					if (_tier.Number >= 4)
					{
						meshBuilder2.Box(val * 0.3f + Vector3.up * 0.105f, new Vector3(0.05f, 0.02f, 0.05f));
					}
				}
			}
			meshBuilder.Prism(Vector3.zero, 0.16f, floor, num, 8);
			float num2 = ((floor <= 0.1f) ? 0.46f : 0.5f);
			array = (Vector3[])(object)new Vector3[4]
			{
				Vector3.right,
				Vector3.left,
				Vector3.forward,
				Vector3.back
			};
			foreach (Vector3 val2 in array)
			{
				Vector3 val3 = val2 * num2 + Vector3.up * floor;
				Vector3 to = val2 * 0.12f + Vector3.up * (floor + (num - floor) * 0.55f);
				meshBuilder.Beam(val3, to, 0.085f, 0.085f, new Vector3(0f - val2.z, 0f, val2.x));
				meshBuilder2.Box(val3 + Vector3.up * 0.025f, new Vector3(0.12f, 0.05f, 0.12f));
			}
			meshBuilder2.Prism(Vector3.zero, 0.175f, floor + 0.2f, floor + 0.26f, 8);
			meshBuilder2.Prism(Vector3.zero, 0.175f, num - 0.26f, num - 0.2f, 8);
			meshBuilder2.Prism(Vector3.zero, 0.24f, num, num + 0.06f, 12);
			if (_tier.Number == 5)
			{
				meshBuilder2.Prism(Vector3.zero, 0.185f, floor, floor + 0.18f, 8);
			}
			if (_tier.Number >= 4)
			{
				for (int j = 0; j < 8; j++)
				{
					float num3 = MathF.PI / 8f + (float)j * MathF.PI / 4f;
					meshBuilder2.Box(new Vector3(Mathf.Cos(num3), 0f, Mathf.Sin(num3)) * 0.178f + Vector3.up * (num - 0.23f), new Vector3(0.035f, 0.035f, 0.035f));
				}
			}
			ModelKit.Emit(model, "pedestal", meshBuilder, _frameWood);
			ModelKit.Emit(model, "pedestal_fittings", meshBuilder2, _metal);
		}

		private static Vector3 Abs(Vector3 v)
		{
			//IL_0000: 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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(Mathf.Abs(v.x), Mathf.Abs(v.y), Mathf.Abs(v.z));
		}

		private void BuildFork(Transform neck)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			MeshBuilder meshBuilder = new MeshBuilder();
			MeshBuilder meshBuilder2 = new MeshBuilder();
			meshBuilder.Prism(Vector3.zero, 0.23f, -0.2f, -0.14f, 12);
			float[] array = new float[2] { -1f, 1f };
			foreach (float num in array)
			{
				meshBuilder.Box(new Vector3(num * 0.16f, -0.03f, 0f), new Vector3(0.06f, 0.22f, 0.26f));
			}
			meshBuilder2.Tube((IList<Vector3>)(object)new Vector3[2]
			{
				new Vector3(-0.23f, 0f, 0f),
				new Vector3(0.23f, 0f, 0f)
			}, new float[2] { 0.035f, 0.035f }, 8);
			ModelKit.Emit(neck, "fork", meshBuilder, _frameWood);
			ModelKit.Emit(neck, "fork_axle", meshBuilder2, _tier.MetalFittings ? _metal : _frameWood);
		}

		private void BuildStock(Transform body)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: 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_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			//IL_036d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: 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_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: 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_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: 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_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: 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_02a7: 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_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			MeshBuilder meshBuilder = new MeshBuilder();
			MeshBuilder meshBuilder2 = new MeshBuilder();
			MeshBuilder meshBuilder3 = new MeshBuilder();
			MeshBuilder meshBuilder4 = new MeshBuilder();
			MeshBuilder meshBuilder5 = new MeshBuilder();
			float num = 2.15f;
			float num2 = -0.07499999f;
			meshBuilder.Box(new Vector3(0f, 0.04f, num2), new Vector3(0.2f, 0.16f, num));
			float[] array = new float[2] { -1f, 1f };
			foreach (float num3 in array)
			{
				meshBuilder.Box(new Vector3(num3 * 0.065f, 0.135f, num2), new Vector3(0.03f, 0.03f, num - 0.1f));
				if ((Object)(object)_glow != (Object)null)
				{
					meshBuilder5.Box(new Vector3(num3 * 0.102f, 0.04f, num2 + 0.1f), new Vector3(0.008f, 0.03f, num - 0.6f));
				}
			}
			(_tier.MetalFittings ? meshBuilder3 : meshBuilder2).Box(new Vector3(0f, 0.17f, -0.5f), new Vector3(0.12f, 0.06f, 0.14f));
			if (_tier.MetalFittings)
			{
				meshBuilder3.Box(new Vector3(0f, 0.04f, 1.012f), new Vector3(0.22f, 0.18f, 0.025f));
				meshBuilder3.Box(new Vector3(0f, 0.04f, -1.162f), new Vector3(0.22f, 0.18f, 0.025f));