Decompiled source of KaijuNukem v1.0.0

BepInEx/plugins/KaijuNukem/KaijuNukem.dll

Decompiled a day ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Mirage;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NuclearOption.MissionEditorScripts;
using NuclearOption.Networking;
using NuclearOption.SavedMission;
using NuclearOption.SavedMission.Objectives;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
[CompilerGenerated]
[EditorBrowsable(EditorBrowsableState.Never)]
[GeneratedCode("Unity.MonoScriptGenerator.MonoScriptInfoGenerator", null)]
internal class UnitySourceGeneratedAssemblyMonoScriptTypes_v1
{
	private struct MonoScriptData
	{
		public byte[] FilePathsData;

		public byte[] TypesData;

		public int TotalTypes;

		public int TotalFiles;

		public bool IsEditorOnly;
	}

	[MethodImpl(MethodImplOptions.AggressiveInlining)]
	private static MonoScriptData Get()
	{
		return new MonoScriptData
		{
			FilePathsData = new byte[657]
			{
				0, 0, 0, 1, 0, 0, 0, 33, 92, 65,
				115, 115, 101, 116, 115, 92, 75, 97, 105, 106,
				117, 78, 117, 107, 101, 109, 92, 75, 97, 105,
				106, 117, 65, 115, 115, 101, 116, 115, 46, 99,
				115, 0, 0, 0, 1, 0, 0, 0, 31, 92,
				65, 115, 115, 101, 116, 115, 92, 75, 97, 105,
				106, 117, 78, 117, 107, 101, 109, 92, 75, 97,
				105, 106, 117, 66, 111, 100, 121, 46, 99, 115,
				0, 0, 0, 1, 0, 0, 0, 32, 92, 65,
				115, 115, 101, 116, 115, 92, 75, 97, 105, 106,
				117, 78, 117, 107, 101, 109, 92, 75, 97, 105,
				106, 117, 66, 114, 97, 105, 110, 46, 99, 115,
				0, 0, 0, 1, 0, 0, 0, 33, 92, 65,
				115, 115, 101, 116, 115, 92, 75, 97, 105, 106,
				117, 78, 117, 107, 101, 109, 92, 75, 97, 105,
				106, 117, 67, 111, 110, 102, 105, 103, 46, 99,
				115, 0, 0, 0, 1, 0, 0, 0, 38, 92,
				65, 115, 115, 101, 116, 115, 92, 75, 97, 105,
				106, 117, 78, 117, 107, 101, 109, 92, 75, 97,
				105, 106, 117, 68, 105, 97, 103, 110, 111, 115,
				116, 105, 99, 115, 46, 99, 115, 0, 0, 0,
				1, 0, 0, 0, 36, 92, 65, 115, 115, 101,
				116, 115, 92, 75, 97, 105, 106, 117, 78, 117,
				107, 101, 109, 92, 75, 97, 105, 106, 117, 72,
				101, 97, 108, 116, 104, 66, 97, 114, 46, 99,
				115, 0, 0, 0, 1, 0, 0, 0, 31, 92,
				65, 115, 115, 101, 116, 115, 92, 75, 97, 105,
				106, 117, 78, 117, 107, 101, 109, 92, 75, 97,
				105, 106, 117, 72, 111, 115, 116, 46, 99, 115,
				0, 0, 0, 2, 0, 0, 0, 47, 92, 65,
				115, 115, 101, 116, 115, 92, 75, 97, 105, 106,
				117, 78, 117, 107, 101, 109, 92, 75, 97, 105,
				106, 117, 77, 105, 115, 115, 105, 111, 110, 83,
				101, 114, 105, 97, 108, 105, 122, 97, 116, 105,
				111, 110, 46, 99, 115, 0, 0, 0, 1, 0,
				0, 0, 38, 92, 65, 115, 115, 101, 116, 115,
				92, 75, 97, 105, 106, 117, 78, 117, 107, 101,
				109, 92, 75, 97, 105, 106, 117, 78, 117, 107,
				101, 109, 80, 108, 117, 103, 105, 110, 46, 99,
				115, 0, 0, 0, 1, 0, 0, 0, 44, 92,
				65, 115, 115, 101, 116, 115, 92, 75, 97, 105,
				106, 117, 78, 117, 107, 101, 109, 92, 75, 97,
				105, 106, 117, 79, 98, 106, 101, 99, 116, 105,
				118, 101, 80, 114, 111, 103, 114, 101, 115, 115,
				46, 99, 115, 0, 0, 0, 2, 0, 0, 0,
				33, 92, 65, 115, 115, 101, 116, 115, 92, 75,
				97, 105, 106, 117, 78, 117, 107, 101, 109, 92,
				75, 97, 105, 106, 117, 80, 97, 114, 97, 109,
				115, 46, 99, 115, 0, 0, 0, 1, 0, 0,
				0, 35, 92, 65, 115, 115, 101, 116, 115, 92,
				75, 97, 105, 106, 117, 78, 117, 107, 101, 109,
				92, 75, 97, 105, 106, 117, 82, 101, 103, 105,
				115, 116, 114, 121, 46, 99, 115, 0, 0, 0,
				1, 0, 0, 0, 34, 92, 65, 115, 115, 101,
				116, 115, 92, 75, 97, 105, 106, 117, 78, 117,
				107, 101, 109, 92, 75, 97, 105, 106, 117, 83,
				112, 97, 119, 110, 101, 114, 46, 99, 115, 0,
				0, 0, 1, 0, 0, 0, 32, 92, 65, 115,
				115, 101, 116, 115, 92, 75, 97, 105, 106, 117,
				78, 117, 107, 101, 109, 92, 75, 97, 105, 106,
				117, 83, 119, 105, 112, 101, 46, 99, 115, 0,
				0, 0, 3, 0, 0, 0, 40, 92, 65, 115,
				115, 101, 116, 115, 92, 75, 97, 105, 106, 117,
				78, 117, 107, 101, 109, 92, 75, 97, 105, 106,
				117, 85, 110, 105, 116, 80, 97, 110, 101, 108,
				73, 110, 102, 111, 46, 99, 115
			},
			TypesData = new byte[595]
			{
				0, 0, 0, 0, 22, 75, 97, 105, 106, 117,
				78, 117, 107, 101, 109, 124, 75, 97, 105, 106,
				117, 65, 115, 115, 101, 116, 115, 0, 0, 0,
				0, 20, 75, 97, 105, 106, 117, 78, 117, 107,
				101, 109, 124, 75, 97, 105, 106, 117, 66, 111,
				100, 121, 0, 0, 0, 0, 21, 75, 97, 105,
				106, 117, 78, 117, 107, 101, 109, 124, 75, 97,
				105, 106, 117, 66, 114, 97, 105, 110, 0, 0,
				0, 0, 22, 75, 97, 105, 106, 117, 78, 117,
				107, 101, 109, 124, 75, 97, 105, 106, 117, 67,
				111, 110, 102, 105, 103, 0, 0, 0, 0, 27,
				75, 97, 105, 106, 117, 78, 117, 107, 101, 109,
				124, 75, 97, 105, 106, 117, 68, 105, 97, 103,
				110, 111, 115, 116, 105, 99, 115, 0, 0, 0,
				0, 25, 75, 97, 105, 106, 117, 78, 117, 107,
				101, 109, 124, 75, 97, 105, 106, 117, 72, 101,
				97, 108, 116, 104, 66, 97, 114, 0, 0, 0,
				0, 20, 75, 97, 105, 106, 117, 78, 117, 107,
				101, 109, 124, 75, 97, 105, 106, 117, 72, 111,
				115, 116, 0, 0, 0, 0, 34, 75, 97, 105,
				106, 117, 78, 117, 107, 101, 109, 124, 75, 97,
				105, 106, 117, 67, 111, 110, 116, 97, 105, 110,
				101, 114, 67, 111, 110, 118, 101, 114, 116, 101,
				114, 0, 0, 0, 0, 36, 75, 97, 105, 106,
				117, 78, 117, 107, 101, 109, 124, 75, 97, 105,
				106, 117, 77, 105, 115, 115, 105, 111, 110, 83,
				101, 114, 105, 97, 108, 105, 122, 97, 116, 105,
				111, 110, 0, 0, 0, 0, 27, 75, 97, 105,
				106, 117, 78, 117, 107, 101, 109, 124, 75, 97,
				105, 106, 117, 78, 117, 107, 101, 109, 80, 108,
				117, 103, 105, 110, 0, 0, 0, 0, 33, 75,
				97, 105, 106, 117, 78, 117, 107, 101, 109, 124,
				75, 97, 105, 106, 117, 79, 98, 106, 101, 99,
				116, 105, 118, 101, 80, 114, 111, 103, 114, 101,
				115, 115, 0, 0, 0, 0, 22, 75, 97, 105,
				106, 117, 78, 117, 107, 101, 109, 124, 75, 97,
				105, 106, 117, 80, 97, 114, 97, 109, 115, 0,
				0, 0, 0, 26, 75, 97, 105, 106, 117, 78,
				117, 107, 101, 109, 124, 75, 97, 105, 106, 117,
				80, 97, 114, 97, 109, 83, 116, 111, 114, 101,
				0, 0, 0, 0, 24, 75, 97, 105, 106, 117,
				78, 117, 107, 101, 109, 124, 75, 97, 105, 106,
				117, 82, 101, 103, 105, 115, 116, 114, 121, 0,
				0, 0, 0, 23, 75, 97, 105, 106, 117, 78,
				117, 107, 101, 109, 124, 75, 97, 105, 106, 117,
				83, 112, 97, 119, 110, 101, 114, 0, 0, 0,
				0, 21, 75, 97, 105, 106, 117, 78, 117, 107,
				101, 109, 124, 75, 97, 105, 106, 117, 83, 119,
				105, 112, 101, 0, 0, 0, 0, 29, 75, 97,
				105, 106, 117, 78, 117, 107, 101, 109, 124, 75,
				97, 105, 106, 117, 85, 110, 105, 116, 80, 97,
				110, 101, 108, 73, 110, 102, 111, 0, 0, 0,
				0, 33, 75, 97, 105, 106, 117, 78, 117, 107,
				101, 109, 46, 75, 97, 105, 106, 117, 85, 110,
				105, 116, 80, 97, 110, 101, 108, 73, 110, 102,
				111, 124, 82, 111, 119, 0, 0, 0, 0, 35,
				75, 97, 105, 106, 117, 78, 117, 107, 101, 109,
				46, 75, 97, 105, 106, 117, 85, 110, 105, 116,
				80, 97, 110, 101, 108, 73, 110, 102, 111, 124,
				66, 108, 111, 99, 107
			},
			TotalFiles = 15,
			TotalTypes = 19,
			IsEditorOnly = false
		};
	}
}
namespace KaijuNukem;

public static class KaijuAssets
{
	private const string BundleName = "kaiju";

	private const string KaijuPrefabName = "KaijuCharacter";

	private static AssetBundle _bundle;

	private const string KaijuDefinitionName = "KaijuDefinition";

	public static bool Loaded => (Object)(object)_bundle != (Object)null;

	public static GameObject KaijuPrefab { get; private set; }

	public static UnitDefinition KaijuDefinition { get; private set; }

	public static bool Load(ManualLogSource log)
	{
		if ((Object)(object)_bundle != (Object)null)
		{
			return true;
		}
		string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
		if (string.IsNullOrEmpty(directoryName))
		{
			log.LogError((object)"[assets] could not resolve the plugin directory");
			return false;
		}
		string text = Path.Combine(directoryName, "kaiju");
		if (!File.Exists(text))
		{
			log.LogError((object)("[assets] bundle missing at " + text + " — run the ThunderKit Deploy pipeline"));
			return false;
		}
		_bundle = AssetBundle.LoadFromFile(text);
		if ((Object)(object)_bundle == (Object)null)
		{
			log.LogError((object)("[assets] AssetBundle.LoadFromFile returned null for " + text));
			return false;
		}
		KaijuPrefab = _bundle.LoadAsset<GameObject>("KaijuCharacter");
		if ((Object)(object)KaijuPrefab == (Object)null)
		{
			log.LogError((object)("[assets] 'KaijuCharacter' not found in bundle. Contents: " + string.Join(", ", _bundle.GetAllAssetNames())));
			return false;
		}
		KaijuDefinition = _bundle.LoadAsset<UnitDefinition>("KaijuDefinition");
		if ((Object)(object)KaijuDefinition == (Object)null)
		{
			log.LogWarning((object)"[assets] 'KaijuDefinition' not in bundle — Mission Editor registration will be skipped");
		}
		log.LogInfo((object)($"[assets] bundle loaded, {_bundle.GetAllAssetNames().Length} assets, " + $"prefab '{((Object)KaijuPrefab).name}' animator={(Object)(object)KaijuPrefab.GetComponentInChildren<Animator>() != (Object)null}, " + "definition=" + (((Object)(object)KaijuDefinition != (Object)null) ? KaijuDefinition.jsonKey : "MISSING")));
		return true;
	}
}
[DisallowMultipleComponent]
public class KaijuBody : MonoBehaviour, IDamageable
{
	private Unit _unit;

	private Rigidbody _rb;

	private ArmorProperties _armor;

	private byte _damageableId;

	private bool _damageableRegistered;

	private readonly Dictionary<PersistentID, float> _unpaidDamage = new Dictionary<PersistentID, float>();

	private float _hitPoints;

	private float _maxHitPoints;

	private bool _dead;

	public static readonly List<KaijuBody> Live = new List<KaijuBody>();

	public string DisplayName
	{
		get
		{
			if (!((Object)(object)_unit != (Object)null) || string.IsNullOrEmpty(_unit.unitName))
			{
				return "Kaiju";
			}
			return _unit.unitName;
		}
	}

	public float HitPoints => _hitPoints;

	public float HealthFraction
	{
		get
		{
			EnsureHealthInitialised();
			if (!(_maxHitPoints > 0f))
			{
				return 0f;
			}
			return Mathf.Clamp01(_hitPoints / _maxHitPoints);
		}
	}

	public bool IsDead => _dead;

	public event Action OnKaijuKilled;

	private void OnEnable()
	{
		if (!Live.Contains(this))
		{
			Live.Add(this);
		}
	}

	private void OnDisable()
	{
		Live.Remove(this);
	}

	private void EnsureHealthInitialised()
	{
		if (!(_maxHitPoints > 0f))
		{
			_maxHitPoints = (_hitPoints = KaijuParamStore.ForUnit(_unit).Health);
			if (KaijuConfig.VerboseLogging.Value)
			{
				KaijuNukemPlugin.Log.LogInfo((object)$"[body] health initialised to {_maxHitPoints:F0}");
			}
		}
	}

	private void Awake()
	{
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Expected O, but got Unknown
		if ((Object)(object)_unit == (Object)null)
		{
			_unit = ((Component)this).GetComponent<Unit>();
		}
		if ((Object)(object)_rb == (Object)null)
		{
			_rb = ((Component)this).GetComponent<Rigidbody>();
		}
		if ((Object)(object)_unit != (Object)null && string.IsNullOrEmpty(_unit.unitName))
		{
			_unit.unitName = "Kaiju";
		}
		if (_armor == null)
		{
			_armor = new ArmorProperties
			{
				pierceArmor = 20f,
				blastArmor = 50f,
				fireArmor = 10f,
				overpressureLimit = 1000f
			};
		}
	}

	public void Initialize(Unit unit, float hitPoints, ArmorProperties armor)
	{
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		_unit = (((Object)(object)unit != (Object)null) ? unit : ((Component)this).GetComponent<Unit>());
		_rb = (((Object)(object)_unit != (Object)null) ? ((Component)_unit).GetComponent<Rigidbody>() : ((Component)this).GetComponent<Rigidbody>());
		_maxHitPoints = (_hitPoints = hitPoints);
		_armor = (ArmorProperties)(((object)armor) ?? ((object)new ArmorProperties()));
	}

	private void Start()
	{
		if ((Object)(object)_unit == (Object)null)
		{
			_unit = ((Component)this).GetComponent<Unit>();
		}
		if (!((Object)(object)_unit == (Object)null))
		{
			EnsureHealthInitialised();
			_damageableId = _unit.RegisterDamageable((IDamageable)(object)this);
			_damageableRegistered = true;
		}
	}

	public void TakeDamage(float pierceDamage, float blastDamage, float amountAffected, float fireDamage, float ImpactDamage, PersistentID dealerID)
	{
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		if (_dead || (Object)(object)_unit == (Object)null || !((NetworkBehaviour)_unit).IsServer)
		{
			return;
		}
		float num = NetDamage(pierceDamage, blastDamage, amountAffected, fireDamage, ImpactDamage);
		if (!(num <= 0f))
		{
			if (_damageableRegistered)
			{
				_unit.Damage(_damageableId, new DamageInfo(pierceDamage, blastDamage, fireDamage, ImpactDamage));
			}
			ReduceHealth(num, dealerID);
		}
	}

	private float NetDamage(float pierceDamage, float blastDamage, float amountAffected, float fireDamage, float impactDamage)
	{
		KaijuParams kaijuParams = KaijuParamStore.ForUnit(_unit);
		float num = Mathf.Max(pierceDamage - _armor.pierceArmor, 0f) / _armor.pierceTolerance * Mathf.Max(kaijuParams.RoundDamageScale, 0f);
		float num2 = Mathf.Max(blastDamage - _armor.blastArmor, 0f) * amountAffected / _armor.blastTolerance * Mathf.Max(kaijuParams.BlastDamageScale, 0f);
		float num3 = Mathf.Max(fireDamage - _armor.fireArmor, 0f) / _armor.fireTolerance;
		return num + num2 + num3 + impactDamage;
	}

	public void ApplyDamage(float pierceDamage, float blastDamage, float fireDamage, float impactDamage)
	{
		if (!((Object)(object)_unit != (Object)null) || !((NetworkBehaviour)_unit).IsServer)
		{
			_hitPoints = Mathf.Max(0f, _hitPoints - NetDamage(pierceDamage, blastDamage, 1f, fireDamage, impactDamage));
		}
	}

	private void ReduceHealth(float amount, PersistentID dealerID)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		EnsureHealthInitialised();
		_hitPoints -= amount;
		PayForDamage(amount, dealerID);
		if (KaijuConfig.VerboseLogging.Value)
		{
			KaijuNukemPlugin.Log.LogInfo((object)$"[body] -{amount:F0} hp, {_hitPoints:F0}/{_maxHitPoints:F0} remaining");
		}
		if (!(_hitPoints > 0f))
		{
			_dead = true;
			_hitPoints = 0f;
			KaijuNukemPlugin.Log.LogInfo((object)"[body] Kaiju killed");
			_unit.Networkdisabled = true;
			_unit.ReportKilled();
			this.OnKaijuKilled?.Invoke();
		}
	}

	private void PayForDamage(float amount, PersistentID dealerID)
	{
		//IL_0029: 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_0061: Unknown result type (might be due to invalid IL or missing references)
		if (amount <= 0f)
		{
			return;
		}
		float moneyPer1000Damage = KaijuParamStore.ForUnit(_unit).MoneyPer1000Damage;
		if (moneyPer1000Damage <= 0f)
		{
			return;
		}
		_unpaidDamage.TryGetValue(dealerID, out var value);
		value += amount;
		float num = Mathf.Floor(value / 1000f);
		_unpaidDamage[dealerID] = value - num * 1000f;
		PersistentUnit val = default(PersistentUnit);
		if (num <= 0f || !UnitRegistry.TryGetPersistentUnit(dealerID, ref val))
		{
			return;
		}
		Player val2 = val?.player;
		if ((Object)(object)val2 == (Object)null)
		{
			return;
		}
		FactionHQ hQ = val2.HQ;
		if (!((Object)(object)hQ == (Object)null))
		{
			float num2 = num * moneyPer1000Damage;
			hQ.RewardPlayer(val2, _unit, num2, num2, (RewardType)0);
			if (KaijuConfig.VerboseLogging.Value)
			{
				KaijuNukemPlugin.Log.LogInfo((object)$"[body] paid ${num2:F0} for {num * 1000f:F0} damage");
			}
		}
	}

	public void TakeShockwave(Vector3 origin, float overpressure, float blastPower)
	{
	}

	public void Detach(Vector3 velocity, Vector3 relativePos)
	{
	}

	public ArmorProperties GetArmorProperties()
	{
		return _armor;
	}

	public Unit GetUnit()
	{
		return _unit;
	}

	public float GetMass()
	{
		if (!((Object)(object)_rb != (Object)null))
		{
			return 1000f;
		}
		return _rb.mass;
	}

	public Transform GetTransform()
	{
		return ((Component)this).transform;
	}
}
[DisallowMultipleComponent]
public class KaijuBrain : MonoBehaviour
{
	private static readonly int IsWalkingParam = Animator.StringToHash("IsWalking");

	private static readonly int AttackParam = Animator.StringToHash("Attack");

	private static readonly int RoarParam = Animator.StringToHash("Roar");

	private static readonly int AttackStateHash = Animator.StringToHash("Attack");

	private const float SwipeWindowStart = 0.35f;

	private const float SwipeWindowEnd = 0.55f;

	private Unit _unit;

	private Rigidbody _rb;

	private bool _scaleApplied;

	private bool _bodyMeasured;

	private float _soleOffsetLocal;

	private float _bodyHeightLocal;

	private float _soleOffsetFromCollider;

	private Renderer[] _renderers;

	private float _soleSettleAt;

	private bool _soleLogged;

	private static bool _loggedKinematicFix;

	private Animator _animator;

	private KaijuSwipe _swipe;

	private KaijuBody _body;

	private GlobalPosition _destination;

	private bool _hasDestination;

	private float _nextTargetRefresh;

	private const float TargetRefreshSeconds = 2f;

	private float _nextSwipeTime;

	private bool _swipeFiredThisAttack;

	private bool _roared;

	private bool _destinationSearched;

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

	private KaijuParams Tuning => KaijuParamStore.ForUnit(((Object)(object)_unit != (Object)null) ? _unit : (_unit = ((Component)this).GetComponent<Unit>()));

	private void EnsureBodyMetrics()
	{
		//IL_0032: 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_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		if (_bodyMeasured)
		{
			return;
		}
		_bodyMeasured = true;
		BoxCollider component = ((Component)this).GetComponent<BoxCollider>();
		if ((Object)(object)component == (Object)null)
		{
			KaijuNukemPlugin.Log.LogWarning((object)"[brain] no BoxCollider on the Kaiju root — cannot place its feet on the ground.");
			return;
		}
		_bodyHeightLocal = Mathf.Abs(component.size.y);
		_soleOffsetLocal = (_soleOffsetFromCollider = _bodyHeightLocal * 0.5f - component.center.y);
		_renderers = ((Component)this).GetComponentsInChildren<Renderer>(true);
		SkinnedMeshRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>(true);
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			componentsInChildren[i].updateWhenOffscreen = true;
		}
		_soleSettleAt = Time.time + 3f;
		KaijuNukemPlugin.Log.LogInfo((object)($"[brain] body measured from its collider: {_bodyHeightLocal * ((Component)this).transform.localScale.y:F0} m tall, " + $"pivot {_soleOffsetLocal * ((Component)this).transform.localScale.y:F0} m above the soles."));
	}

	private void RefineSoleOffsetFromPose()
	{
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_006c: Unknown result type (might be due to invalid IL or missing references)
		if (_renderers == null || _renderers.Length == 0)
		{
			return;
		}
		float scale = Tuning.Scale;
		if (scale <= 0f)
		{
			return;
		}
		float num = float.MaxValue;
		Renderer[] renderers = _renderers;
		foreach (Renderer val in renderers)
		{
			if (!((Object)(object)val == (Object)null))
			{
				Bounds bounds = val.bounds;
				if (((Bounds)(ref bounds)).min.y < num)
				{
					bounds = val.bounds;
					num = ((Bounds)(ref bounds)).min.y;
				}
			}
		}
		if (num == float.MaxValue)
		{
			return;
		}
		float num2 = (((Component)this).transform.position.y - num) / scale;
		if (!(num2 <= 0f) && !(num2 > _bodyHeightLocal))
		{
			_soleOffsetLocal = Mathf.Lerp(_soleOffsetLocal, num2, 0.1f);
			if (!_soleLogged && !(Time.time < _soleSettleAt))
			{
				_soleLogged = true;
				KaijuNukemPlugin.Log.LogInfo((object)($"[brain] sole line from the animated pose: pivot {_soleOffsetLocal * scale:F0} m above the " + $"soles (the collider alone said {_soleOffsetFromCollider * scale:F0} m, so the feet were " + $"{(_soleOffsetFromCollider - _soleOffsetLocal) * scale:F0} m off the ground)."));
			}
		}
	}

	private void HoldGround()
	{
		//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_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		SetWalking(walking: false);
		if (!((Object)(object)_rb == (Object)null))
		{
			Vector3 position = ((Component)this).transform.position;
			position.y = GroundHeight(position);
			_rb.MovePosition(position);
		}
	}

	private void EnforceKinematicBody()
	{
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Invalid comparison between Unknown and I4
		if ((Object)(object)_rb == (Object)null)
		{
			return;
		}
		if (!_rb.isKinematic)
		{
			_rb.isKinematic = true;
			if (!_loggedKinematicFix)
			{
				_loggedKinematicFix = true;
				KaijuNukemPlugin.Log.LogInfo((object)"[brain] Container turned the Kaiju's rigidbody dynamic; forcing it kinematic so terrain depenetration and buoyancy cannot launch it.");
			}
		}
		if ((int)_rb.interpolation != 1)
		{
			_rb.interpolation = (RigidbodyInterpolation)1;
		}
		if (_rb.useGravity)
		{
			_rb.useGravity = false;
		}
	}

	private void ApplyPlacementScaleOnce()
	{
		//IL_002b: 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_004a: Unknown result type (might be due to invalid IL or missing references)
		if (_scaleApplied)
		{
			return;
		}
		_scaleApplied = true;
		float scale = Tuning.Scale;
		if (!(scale <= 0f) && !Mathf.Approximately(((Component)this).transform.localScale.x, scale))
		{
			((Component)this).transform.localScale = Vector3.one * scale;
			if (KaijuConfig.VerboseLogging.Value)
			{
				KaijuNukemPlugin.Log.LogInfo((object)$"[brain] applied placement scale {scale:F1}x");
			}
		}
	}

	private void Awake()
	{
		if ((Object)(object)_unit == (Object)null)
		{
			_unit = ((Component)this).GetComponent<Unit>();
		}
		if ((Object)(object)_rb == (Object)null)
		{
			_rb = ((Component)this).GetComponent<Rigidbody>();
		}
		if ((Object)(object)_animator == (Object)null)
		{
			_animator = ((Component)this).GetComponentInChildren<Animator>();
		}
		if ((Object)(object)_swipe == (Object)null)
		{
			_swipe = ((Component)this).GetComponent<KaijuSwipe>();
		}
		if ((Object)(object)_body == (Object)null)
		{
			_body = ((Component)this).GetComponent<KaijuBody>();
		}
		ConfigureAnimator();
	}

	public void Initialize(Unit unit, Animator animator, KaijuSwipe swipe, KaijuBody body)
	{
		_unit = (((Object)(object)unit != (Object)null) ? unit : ((Component)this).GetComponent<Unit>());
		_rb = (((Object)(object)_unit != (Object)null) ? ((Component)_unit).GetComponent<Rigidbody>() : ((Component)this).GetComponent<Rigidbody>());
		_animator = (((Object)(object)animator != (Object)null) ? animator : ((Component)this).GetComponentInChildren<Animator>());
		_swipe = (((Object)(object)swipe != (Object)null) ? swipe : ((Component)this).GetComponent<KaijuSwipe>());
		_body = (((Object)(object)body != (Object)null) ? body : ((Component)this).GetComponent<KaijuBody>());
		ConfigureAnimator();
	}

	private void ConfigureAnimator()
	{
		if (!((Object)(object)_animator == (Object)null))
		{
			_animator.applyRootMotion = false;
			_animator.cullingMode = (AnimatorCullingMode)0;
		}
	}

	private void AcquireDestinationIfNeeded()
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: 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_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		if (TryAcquireMissionTarget() || _hasDestination || _destinationSearched)
		{
			return;
		}
		_destinationSearched = true;
		MapBuildingSet[] array = Object.FindObjectsOfType<MapBuildingSet>();
		if (array == null || array.Length == 0)
		{
			return;
		}
		Vector3 position = ((Component)this).transform.position;
		float num = float.MaxValue;
		Vector3 val = default(Vector3);
		bool flag = false;
		MapBuildingSet[] array2 = array;
		foreach (MapBuildingSet val2 in array2)
		{
			if ((Object)(object)val2 == (Object)null)
			{
				continue;
			}
			MapBuilding[] componentsInChildren = ((Component)val2).GetComponentsInChildren<MapBuilding>(false);
			if (componentsInChildren.Length != 0)
			{
				Vector3 val3 = Vector3.zero;
				MapBuilding[] array3 = componentsInChildren;
				foreach (MapBuilding val4 in array3)
				{
					val3 += ((Component)val4).transform.position;
				}
				Vector3 val5 = val3 / (float)componentsInChildren.Length;
				Vector3 val6 = val5 - position;
				float sqrMagnitude = ((Vector3)(ref val6)).sqrMagnitude;
				if (!(sqrMagnitude >= num))
				{
					num = sqrMagnitude;
					val = val5;
					flag = true;
				}
			}
		}
		if (flag)
		{
			SetDestination(GlobalPositionExtensions.ToGlobalPosition(val));
			KaijuNukemPlugin.Log.LogInfo((object)$"[brain] marching on the nearest settlement, {Mathf.Sqrt(num) / 1000f:F1} km away");
		}
	}

	private bool TryAcquireMissionTarget()
	{
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		string targetUnitName = Tuning.TargetUnitName;
		if (string.IsNullOrEmpty(targetUnitName))
		{
			return false;
		}
		if (Time.time < _nextTargetRefresh && _hasDestination)
		{
			return true;
		}
		_nextTargetRefresh = Time.time + 2f;
		if (!UnitRegistry.customIDLookup.TryGetValue(targetUnitName, out var value) || (Object)(object)value == (Object)null)
		{
			if (!_hasDestination && KaijuConfig.VerboseLogging.Value)
			{
				KaijuNukemPlugin.Log.LogInfo((object)("[brain] target '" + targetUnitName + "' not in the unit registry yet"));
			}
			return _hasDestination;
		}
		SetDestination(GlobalPositionExtensions.ToGlobalPosition(((Component)value).transform.position));
		return true;
	}

	public void SetDestination(GlobalPosition destination)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		_destination = destination;
		_hasDestination = true;
	}

	private void FixedUpdate()
	{
		//IL_00b1: 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)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: 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_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_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: 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_0158: Unknown result type (might be due to invalid IL or missing references)
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_0189: Unknown result type (might be due to invalid IL or missing references)
		//IL_0190: Unknown result type (might be due to invalid IL or missing references)
		//IL_0195: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: Unknown result type (might be due to invalid IL or missing references)
		//IL_019f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01be: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_unit == (Object)null || (Object)(object)_body == (Object)null || _body.IsDead)
		{
			SetWalking(walking: false);
			return;
		}
		EnforceKinematicBody();
		if (!_unit.LocalSim)
		{
			return;
		}
		ApplyPlacementScaleOnce();
		EnsureBodyMetrics();
		RefineSoleOffsetFromPose();
		KaijuDiagnostics.DumpUnitOnce(_unit, ((Component)this).transform);
		if (!_roared && (Object)(object)_animator != (Object)null)
		{
			_animator.SetTrigger(RoarParam);
			_roared = true;
		}
		TryStrike();
		AcquireDestinationIfNeeded();
		if (!_hasDestination)
		{
			HoldGround();
			return;
		}
		Vector3 val = GlobalPositionExtensions.ToLocalPosition(_destination);
		Vector3 position = ((Component)this).transform.position;
		Vector3 val2 = default(Vector3);
		((Vector3)(ref val2))..ctor(val.x - position.x, 0f, val.z - position.z);
		float magnitude = ((Vector3)(ref val2)).magnitude;
		if (magnitude < Tuning.SwipeRange * 0.5f)
		{
			HoldGround();
			return;
		}
		Vector3 val3 = val2 / magnitude;
		Quaternion val4 = Quaternion.LookRotation(val3, Vector3.up);
		Quaternion val5 = Quaternion.RotateTowards(((Component)this).transform.rotation, val4, Tuning.TurnRateDegPerSec * Time.fixedDeltaTime);
		float num = ((Vector3.Angle(((Component)this).transform.forward, val3) < 45f) ? (Tuning.WalkSpeed * Time.fixedDeltaTime) : 0f);
		Vector3 val6 = position + ((Component)this).transform.forward * num;
		val6.y = GroundHeight(val6);
		_rb.MoveRotation(val5);
		_rb.MovePosition(val6);
		SetWalking(num > 0f);
	}

	private float GroundHeight(Vector3 at)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: 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)
		float localSeaY = Datum.LocalSeaY;
		Vector3 val = at + Vector3.up * 6000f;
		Vector3 val2 = at - Vector3.up * 6000f;
		float num = KaijuConfig.WadeDepthFraction.Value * _bodyHeightLocal * Tuning.Scale;
		float value = KaijuConfig.GroundOffset.Value;
		RaycastHit val3 = default(RaycastHit);
		float num2 = (Physics.Linecast(val, val2, ref val3, LayerMask.op_Implicit(PhysicsLayers.StaticsMask)) ? Mathf.Max(((RaycastHit)(ref val3)).point.y, localSeaY - num) : (localSeaY - num));
		float num3 = num2 + value + _soleOffsetLocal * Tuning.Scale;
		if (KaijuConfig.VerboseLogging.Value && Time.frameCount % 120 == 0)
		{
			KaijuNukemPlugin.Log.LogInfo((object)$"[brain] soles y={num2:F1} seaY={localSeaY:F1} wade={num:F1} offset={value:F1} -> pivot y={num3:F1}");
		}
		return num3;
	}

	private void SetWalking(bool walking)
	{
		if ((Object)(object)_animator != (Object)null)
		{
			_animator.SetBool(IsWalkingParam, walking);
		}
	}

	private void TryStrike()
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_animator == (Object)null || (Object)(object)_swipe == (Object)null)
		{
			return;
		}
		AnimatorStateInfo currentAnimatorStateInfo = _animator.GetCurrentAnimatorStateInfo(0);
		if (((AnimatorStateInfo)(ref currentAnimatorStateInfo)).shortNameHash == AttackStateHash)
		{
			float num = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime % 1f;
			if (!_swipeFiredThisAttack && num >= 0.35f && num <= 0.55f)
			{
				_swipeFiredThisAttack = true;
				_swipe.Strike();
			}
		}
		else
		{
			_swipeFiredThisAttack = false;
			if (!(Time.time < _nextSwipeTime) && AnythingWorthHitting())
			{
				_nextSwipeTime = Time.time + Tuning.SwipeCooldown;
				_animator.SetTrigger(AttackParam);
			}
		}
	}

	private bool AnythingWorthHitting()
	{
		//IL_0012: 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_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		float swipeRange = Tuning.SwipeRange;
		int num = Physics.OverlapSphereNonAlloc(((Component)this).transform.position + ((Component)this).transform.forward * (swipeRange * 0.5f), swipeRange, ProbeBuffer, ~LayerMask.op_Implicit(PhysicsLayers.ExclusionZonesMask));
		IDamageable val2 = default(IDamageable);
		for (int i = 0; i < num; i++)
		{
			Collider val = ProbeBuffer[i];
			if (!((Object)(object)val == (Object)null) && ((Component)val).gameObject.TryGetComponent<IDamageable>(ref val2) && val2.GetUnit() != _unit)
			{
				return true;
			}
		}
		return false;
	}
}
public static class KaijuConfig
{
	public static ConfigEntry<bool> Enabled;

	public static ConfigEntry<bool> AutoSpawn;

	public static ConfigEntry<float> WadeDepthFraction;

	public static ConfigEntry<float> GroundOffset;

	public static ConfigEntry<float> SpawnDistanceFromPlayer;

	public static ConfigEntry<float> SpawnDistanceFromShore;

	public static ConfigEntry<float> KaijuScale;

	public static ConfigEntry<float> WalkSpeed;

	public static ConfigEntry<float> TurnRateDegPerSec;

	public static ConfigEntry<float> Health;

	public static ConfigEntry<float> SwipeRange;

	public static ConfigEntry<float> SwipeArcDegrees;

	public static ConfigEntry<float> SwipeDamage;

	public static ConfigEntry<float> SwipeCooldown;

	public static ConfigEntry<float> RoundDamageScale;

	public static ConfigEntry<float> BlastDamageScale;

	public static ConfigEntry<float> MoneyPer1000Damage;

	public static ConfigEntry<bool> VerboseLogging;

	public static void Bind(ConfigFile cfg)
	{
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Expected O, but got Unknown
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Expected O, but got Unknown
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Expected O, but got Unknown
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_0111: Expected O, but got Unknown
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: Expected O, but got Unknown
		//IL_0177: Unknown result type (might be due to invalid IL or missing references)
		//IL_0181: Expected O, but got Unknown
		//IL_01af: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b9: Expected O, but got Unknown
		//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f1: Expected O, but got Unknown
		//IL_021f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0229: Expected O, but got Unknown
		//IL_0257: Unknown result type (might be due to invalid IL or missing references)
		//IL_0261: Expected O, but got Unknown
		//IL_028f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0299: Expected O, but got Unknown
		//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d1: Expected O, but got Unknown
		//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0309: Expected O, but got Unknown
		//IL_0337: Unknown result type (might be due to invalid IL or missing references)
		//IL_0341: Expected O, but got Unknown
		//IL_036f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0379: Expected O, but got Unknown
		Enabled = cfg.Bind<bool>("Master", "Enabled", true, "Master switch. When false the mod does nothing at all.");
		AutoSpawn = cfg.Bind<bool>("Master", "AutoSpawn", false, "Spawn a Kaiju automatically on any mission. Off by design — the Kaiju is meant to be placed deliberately in the Mission Editor, not to gatecrash every flight. Turn it on only to test the creature without authoring a mission. A Kaiju spawned this way is not registered under a UniqueName, so mission objectives cannot target it — testing objective wiring needs an editor-placed Kaiju.");
		GroundOffset = cfg.Bind<float>("Placement", "GroundOffset", 0f, new ConfigDescription("Vertical correction in metres, applied on land AND water. Leave this at 0: the Kaiju's feet are now placed from its own collider, which the prefab authors to enclose the model exactly, so the geometry is already right. It stays here only to nudge art that sits slightly off its own bounds. Negative sinks it, positive raises it.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-500f, 500f), Array.Empty<object>()));
		WadeDepthFraction = cfg.Bind<float>("Placement", "WadeDepthFraction", 0.22f, new ConfigDescription("How deep the Kaiju sinks when standing in water, as a fraction of its full height. 0 walks on the surface; 0.22 is roughly thigh-deep. It still stands properly on land, and never sinks below the actual seabed in shallow water. Keep it well under 1.0 — the game discards weapon hits below sea level as splashes, so a submerged Kaiju is progressively harder to shoot.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.9f), Array.Empty<object>()));
		SpawnDistanceFromPlayer = cfg.Bind<float>("Scenario", "SpawnDistanceFromPlayer", 8000f, new ConfigDescription("Metres from your own airbase that the Kaiju surfaces. Kept short on purpose so it is a quick flight away rather than somewhere unfindable on the map.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(500f, 60000f), Array.Empty<object>()));
		SpawnDistanceFromShore = cfg.Bind<float>("Scenario", "SpawnDistanceFromShore", 3000f, new ConfigDescription("Metres out to sea the Kaiju surfaces, measured from its target on land.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(200f, 20000f), Array.Empty<object>()));
		KaijuScale = cfg.Bind<float>("Scenario", "KaijuScale", 300f, new ConfigDescription("Uniform scale applied to the Synty prefab, which is authored at roughly 2.5 m. 300 gives a creature about 755 m tall — properly kaiju-sized against aircraft. Collider and wade depth scale with it; the movement and swipe defaults below are tuned for this value, so raise them together if you go much larger.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 1000f), Array.Empty<object>()));
		WalkSpeed = cfg.Bind<float>("Movement", "WalkSpeed", 120f, new ConfigDescription("Ground speed in metres per second while advancing on the target.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 500f), Array.Empty<object>()));
		TurnRateDegPerSec = cfg.Bind<float>("Movement", "TurnRateDegPerSec", 10f, new ConfigDescription("How fast the Kaiju can yaw toward its target. Low values read as heavy.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 180f), Array.Empty<object>()));
		Health = cfg.Bind<float>("Combat", "Health", 20000f, new ConfigDescription("Total damage the Kaiju absorbs before it dies. Whether that kill ends the mission is decided by the mission's own objectives, not by this mod.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(100f, 1000000f), Array.Empty<object>()));
		SwipeRange = cfg.Bind<float>("Combat", "SwipeRange", 700f, new ConfigDescription("Reach of the left-hand swipe, in metres from the Kaiju's centre.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 5000f), Array.Empty<object>()));
		SwipeArcDegrees = cfg.Bind<float>("Combat", "SwipeArcDegrees", 120f, new ConfigDescription("Total width of the swipe arc. Anything destructible inside the arc and within range is hit.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 360f), Array.Empty<object>()));
		SwipeDamage = cfg.Bind<float>("Combat", "SwipeDamage", 5000f, new ConfigDescription("Damage applied to each entity caught in the swipe.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 100000f), Array.Empty<object>()));
		SwipeCooldown = cfg.Bind<float>("Combat", "SwipeCooldown", 6f, new ConfigDescription("Seconds between swipes.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 60f), Array.Empty<object>()));
		RoundDamageScale = cfg.Bind<float>("Combat", "RoundDamageScale", 0.5f, new ConfigDescription("How much damage GUN ROUNDS do to the Kaiju, as a multiplier. 1 is vanilla, 0.5 halves it, 0 makes it immune to guns. Rounds are the one weapon the game does not scale by target size, so against a creature this large they are worth far more per second than anything else a pilot can carry — this is the dial that puts cannon back in proportion with ordnance.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
		BlastDamageScale = cfg.Bind<float>("Combat", "BlastDamageScale", 25f, new ConfigDescription("How much damage BLAST does to the Kaiju — bombs, rockets and missile warheads — as a multiplier. Far above 1 on purpose, and it is a correction rather than a buff: the game scales blast by how much of the target the explosion engulfs, so a creature with a ~261 m mean extent absorbs roughly a fiftieth of what a tank would take, purely for being big. At 1 a direct bomb hit is worth about four cannon rounds. Raise it if bombing still feels pointless.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 200f), Array.Empty<object>()));
		MoneyPer1000Damage = cfg.Bind<float>("Rewards", "MoneyPer1000Damage", 100f, new ConfigDescription("Default payout, in dollars, per 1000 points of damage a pilot deals to a Kaiju. This is only the starting value for a NEW placement — each Kaiju placed in the Mission Editor owns its own rate, so changing this does not alter existing missions.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 1000f), Array.Empty<object>()));
		VerboseLogging = cfg.Bind<bool>("Diagnostics", "VerboseLogging", false, "Log per-step scenario state. Noisy; for diagnosing a Kaiju that will not spawn or move.");
	}
}
internal static class KaijuDiagnostics
{
	private static bool _dumpedUnit;

	private static bool _dumpedObjective;

	private static bool _dumpedPercent;

	public static void DumpUnitOnce(Unit unit, Transform root)
	{
		//IL_0039: 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_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: 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_010d: 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_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: 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_01b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0257: Unknown result type (might be due to invalid IL or missing references)
		//IL_0263: 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_0285: Unknown result type (might be due to invalid IL or missing references)
		//IL_0287: Unknown result type (might be due to invalid IL or missing references)
		//IL_0289: Unknown result type (might be due to invalid IL or missing references)
		//IL_0293: Unknown result type (might be due to invalid IL or missing references)
		//IL_0298: Unknown result type (might be due to invalid IL or missing references)
		//IL_029f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e6: 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_01f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0208: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0211: Unknown result type (might be due to invalid IL or missing references)
		//IL_021d: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d9: 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)
		if (_dumpedUnit || (Object)(object)unit == (Object)null || (Object)(object)root == (Object)null)
		{
			return;
		}
		_dumpedUnit = true;
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.AppendLine("[diag] ===== KAIJU UNIT =====");
		stringBuilder.AppendLine($"[diag] transform.position = {root.position}  (y={root.position.y:F1})");
		stringBuilder.AppendLine($"[diag] localScale         = {root.localScale}");
		stringBuilder.AppendLine($"[diag] seaY               = {Datum.LocalSeaY:F1}");
		BoxCollider component = ((Component)root).GetComponent<BoxCollider>();
		Bounds bounds;
		if ((Object)(object)component != (Object)null)
		{
			stringBuilder.AppendLine($"[diag] box.center(local)  = {component.center}  size={component.size}");
			bounds = ((Collider)component).bounds;
			object arg = ((Bounds)(ref bounds)).min.y;
			bounds = ((Collider)component).bounds;
			object arg2 = ((Bounds)(ref bounds)).center.y;
			bounds = ((Collider)component).bounds;
			stringBuilder.AppendLine($"[diag] box.bounds(world)  = min.y {arg:F1} / centre.y {arg2:F1} / max.y {((Bounds)(ref bounds)).max.y:F1}");
		}
		else
		{
			stringBuilder.AppendLine("[diag] NO BoxCollider on the root");
		}
		Renderer[] componentsInChildren = ((Component)root).GetComponentsInChildren<Renderer>(true);
		if (componentsInChildren.Length != 0)
		{
			Bounds bounds2 = componentsInChildren[0].bounds;
			Renderer[] array = componentsInChildren;
			foreach (Renderer val in array)
			{
				((Bounds)(ref bounds2)).Encapsulate(val.bounds);
			}
			stringBuilder.AppendLine($"[diag] model bounds(world) = min.y {((Bounds)(ref bounds2)).min.y:F1} / max.y {((Bounds)(ref bounds2)).max.y:F1} (height {((Bounds)(ref bounds2)).size.y:F0} m, {componentsInChildren.Length} renderers)");
			if ((Object)(object)component != (Object)null)
			{
				float y = ((Bounds)(ref bounds2)).min.y;
				bounds = ((Collider)component).bounds;
				float num = y - ((Bounds)(ref bounds)).min.y;
				bounds = ((Collider)component).bounds;
				float num2 = ((Bounds)(ref bounds)).max.y - ((Bounds)(ref bounds2)).max.y;
				stringBuilder.AppendLine($"[diag] model vs collider   = feet {num:F1} m, head {num2:F1} m " + "(both near 0 = collider wraps the creature; large = something is misaligned)");
			}
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(((Bounds)(ref bounds2)).center.x, ((Bounds)(ref bounds2)).min.y + 10f, ((Bounds)(ref bounds2)).center.z);
			RaycastHit val3 = default(RaycastHit);
			stringBuilder.AppendLine(Physics.Linecast(val2, val2 - Vector3.up * 12000f, ref val3, LayerMask.op_Implicit(PhysicsLayers.StaticsMask)) ? $"[diag] feet above ground   = {((Bounds)(ref bounds2)).min.y - ((RaycastHit)(ref val3)).point.y:F1} m (ground '{((Object)((RaycastHit)(ref val3)).collider).name}' y={((RaycastHit)(ref val3)).point.y:F1})" : $"[diag] feet above ground   = no terrain below; sea is at y={Datum.LocalSeaY:F1}");
		}
		else
		{
			stringBuilder.AppendLine("[diag] NO Renderers under the root");
		}
		UnitDefinition definition = unit.definition;
		if ((Object)(object)definition != (Object)null)
		{
			stringBuilder.AppendLine($"[diag] definition dims    = L {definition.length:F0} W {definition.width:F0} H {definition.height:F0}");
			stringBuilder.AppendLine($"[diag] definition.jsonKey = {definition.jsonKey}  iconSize={definition.iconSize}");
		}
		else
		{
			stringBuilder.AppendLine("[diag] unit.definition IS NULL  <-- maxRadius would stay 0");
		}
		stringBuilder.AppendLine($"[diag] unit.maxRadius      = {unit.maxRadius:F1}   (missiles aim at transform.position when < 20)");
		stringBuilder.AppendLine("[diag] unit.SavedUnit      = " + ((unit.SavedUnit != null) ? ("'" + unit.SavedUnit.UniqueName + "' type=" + unit.SavedUnit.type) : "NULL  <-- per-placement values cannot resolve"));
		bool flag = unit.SavedUnit != null && UnitRegistry.customIDLookup.ContainsKey(unit.SavedUnit.UniqueName);
		stringBuilder.AppendLine($"[diag] in customIDLookup   = {flag}   (objectives resolve targets through this)");
		KaijuBody component2 = ((Component)root).GetComponent<KaijuBody>();
		stringBuilder.AppendLine(((Object)(object)component2 != (Object)null) ? $"[diag] KaijuBody hp         = {component2.HitPoints:F0} fraction={component2.HealthFraction:F3}" : "[diag] NO KaijuBody on the root");
		stringBuilder.Append("[diag] ======================");
		KaijuNukemPlugin.Log.LogInfo((object)stringBuilder.ToString());
	}

	public static void DumpObjectiveOnce(string objectiveName, List<SavedUnit> items)
	{
		if (_dumpedObjective)
		{
			return;
		}
		_dumpedObjective = true;
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.AppendLine("[diag] ===== DESTROY OBJECTIVE =====");
		stringBuilder.AppendLine($"[diag] objective '{objectiveName}' targets={items?.Count ?? (-1)}");
		if (items != null)
		{
			foreach (SavedUnit item in items)
			{
				if (item == null)
				{
					stringBuilder.AppendLine("[diag]   <null target>");
					continue;
				}
				Unit value;
				bool flag = UnitRegistry.customIDLookup.TryGetValue(item.UniqueName, out value);
				KaijuBody kaijuBody = ((flag && (Object)(object)value != (Object)null) ? ((Component)value).GetComponent<KaijuBody>() : null);
				stringBuilder.AppendLine($"[diag]   '{item.UniqueName}' type={item.type} isKaiju={KaijuParamStore.IsKaiju(item)} " + $"inRegistry={flag} live={(Object)(object)value != (Object)null} body={(Object)(object)kaijuBody != (Object)null} " + "frac=" + (((Object)(object)kaijuBody != (Object)null) ? kaijuBody.HealthFraction.ToString("F3") : "-"));
			}
		}
		stringBuilder.Append("[diag] =============================");
		KaijuNukemPlugin.Log.LogInfo((object)stringBuilder.ToString());
	}

	public static void DumpPercentOnce(float ours, float vanilla)
	{
		if (!_dumpedPercent)
		{
			_dumpedPercent = true;
			KaijuNukemPlugin.Log.LogInfo((object)$"[diag] percentage hook REACHED: vanilla={vanilla:F3} ours={ours:F3}");
		}
	}
}
internal class KaijuHealthBar : MonoBehaviour
{
	private const float BarWidth = 900f;

	private const float BarHeight = 26f;

	private const float TopMargin = 90f;

	private const int SortingOrder = 5000;

	private Canvas _canvas;

	private CanvasGroup _group;

	private RectTransform _fill;

	private Image _fillImage;

	private TextMeshProUGUI _label;

	private static readonly Color BackColor = new Color(0f, 0f, 0f, 0.55f);

	private static readonly Color HealthyColor = new Color(0.85f, 0.25f, 0.18f, 0.95f);

	private static readonly Color HurtColor = new Color(0.95f, 0.65f, 0.1f, 0.95f);

	public static KaijuHealthBar Install(GameObject host)
	{
		return host.AddComponent<KaijuHealthBar>();
	}

	private void Awake()
	{
		BuildUi();
		SetVisible(visible: false);
	}

	private void BuildUi()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: 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_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0111: Unknown result type (might be due to invalid IL or missing references)
		//IL_0132: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0171: Unknown result type (might be due to invalid IL or missing references)
		//IL_0186: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ae: 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_01e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_023b: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("KaijuNukem.HealthBar");
		val.transform.SetParent(((Component)this).transform, false);
		_canvas = val.AddComponent<Canvas>();
		_canvas.renderMode = (RenderMode)0;
		_canvas.sortingOrder = 5000;
		CanvasScaler obj = val.AddComponent<CanvasScaler>();
		obj.uiScaleMode = (ScaleMode)1;
		obj.referenceResolution = new Vector2(1920f, 1080f);
		obj.matchWidthOrHeight = 0.5f;
		_group = val.AddComponent<CanvasGroup>();
		_group.interactable = false;
		_group.blocksRaycasts = false;
		RectTransform val2 = NewRect("Root", val.transform);
		Vector2 val3 = default(Vector2);
		((Vector2)(ref val3))..ctor(0.5f, 1f);
		val2.anchorMax = val3;
		val2.anchorMin = val3;
		val2.pivot = new Vector2(0.5f, 1f);
		val2.anchoredPosition = new Vector2(0f, -90f);
		val2.sizeDelta = new Vector2(900f, 26f);
		((Graphic)((Component)val2).gameObject.AddComponent<Image>()).color = BackColor;
		RectTransform val4 = NewRect("Fill", (Transform)(object)val2);
		val4.anchorMin = new Vector2(0f, 0f);
		val4.anchorMax = new Vector2(1f, 1f);
		val4.pivot = new Vector2(0f, 0.5f);
		val4.offsetMin = new Vector2(2f, 2f);
		val4.offsetMax = new Vector2(-2f, -2f);
		_fill = val4;
		_fillImage = ((Component)val4).gameObject.AddComponent<Image>();
		((Graphic)_fillImage).color = HealthyColor;
		RectTransform val5 = NewRect("Label", (Transform)(object)val2);
		val5.anchorMin = new Vector2(0f, 0f);
		val5.anchorMax = new Vector2(1f, 1f);
		val5.offsetMin = Vector2.zero;
		val5.offsetMax = Vector2.zero;
		_label = ((Component)val5).gameObject.AddComponent<TextMeshProUGUI>();
		((TMP_Text)_label).alignment = (TextAlignmentOptions)514;
		((TMP_Text)_label).fontSize = 17f;
		((Graphic)_label).color = Color.white;
		((Graphic)_label).raycastTarget = false;
		((TMP_Text)_label).text = "";
	}

	private static RectTransform NewRect(string name, Transform parent)
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Expected O, but got Unknown
		GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
		val.transform.SetParent(parent, false);
		return (RectTransform)val.transform;
	}

	private void Update()
	{
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		KaijuBody kaijuBody = PickTarget();
		if ((Object)(object)kaijuBody == (Object)null)
		{
			SetVisible(visible: false);
			return;
		}
		SetVisible(visible: true);
		float num = Mathf.Clamp01(kaijuBody.HealthFraction);
		((Transform)_fill).localScale = new Vector3(num, 1f, 1f);
		((Graphic)_fillImage).color = ((num > 0.35f) ? HealthyColor : HurtColor);
		((TMP_Text)_label).text = $"{kaijuBody.DisplayName}   {100f * num:F0}%   ({kaijuBody.HitPoints:N0} HP)";
	}

	private static KaijuBody PickTarget()
	{
		//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_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_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)
		if (KaijuBody.Live.Count == 0)
		{
			return null;
		}
		Aircraft val = default(Aircraft);
		if (!GameManager.GetLocalAircraft(ref val) || (Object)(object)val == (Object)null)
		{
			return null;
		}
		WeaponManager weaponManager = val.weaponManager;
		if ((Object)(object)weaponManager == (Object)null)
		{
			return null;
		}
		KaijuBody result = null;
		float num = float.MaxValue;
		Vector3 position = ((Component)val).transform.position;
		for (int i = 0; i < KaijuBody.Live.Count; i++)
		{
			KaijuBody kaijuBody = KaijuBody.Live[i];
			if ((Object)(object)kaijuBody == (Object)null || kaijuBody.IsDead)
			{
				continue;
			}
			Unit unit = kaijuBody.GetUnit();
			if (!((Object)(object)unit == (Object)null) && weaponManager.CheckIsTarget(unit))
			{
				Vector3 val2 = ((Component)kaijuBody).transform.position - position;
				float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
				if (!(sqrMagnitude >= num))
				{
					num = sqrMagnitude;
					result = kaijuBody;
				}
			}
		}
		return result;
	}

	private void SetVisible(bool visible)
	{
		if ((Object)(object)_group != (Object)null)
		{
			_group.alpha = (visible ? 1f : 0f);
		}
	}
}
public class KaijuHost : MonoBehaviour
{
	private bool _spawned;

	public static KaijuHost Install()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Expected O, but got Unknown
		//IL_0010: 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_001e: Expected O, but got Unknown
		GameObject val = new GameObject("KaijuNukem.Host");
		Object.DontDestroyOnLoad((Object)val);
		((Object)val).hideFlags = (HideFlags)61;
		KaijuHealthBar.Install(val);
		return val.AddComponent<KaijuHost>();
	}

	private void Start()
	{
		((MonoBehaviour)this).StartCoroutine(KaijuRegistry.RegisterWhenReady());
		((MonoBehaviour)this).StartCoroutine(RunTestSpawnerWhenReady());
	}

	private IEnumerator RunTestSpawnerWhenReady()
	{
		FactionHQ val = default(FactionHQ);
		while (!_spawned)
		{
			yield return (object)new WaitForSeconds(2f);
			if (!KaijuConfig.Enabled.Value || !KaijuConfig.AutoSpawn.Value)
			{
				continue;
			}
			NetworkManagerNuclearOption i = NetworkManagerNuclearOption.i;
			if ((Object)(object)i == (Object)null || !((NetworkManager)i).Server.Active || (Object)(object)Datum.origin == (Object)null || (Object)(object)NetworkSceneSingleton<LevelInfo>.i == (Object)null)
			{
				continue;
			}
			if (!GameManager.GetLocalHQ(ref val) || (Object)(object)val == (Object)null)
			{
				if (KaijuConfig.VerboseLogging.Value)
				{
					KaijuNukemPlugin.Log.LogInfo((object)"[testspawn] waiting for the player to join a faction");
				}
			}
			else
			{
				TryTestSpawn();
			}
		}
	}

	private void TryTestSpawn()
	{
		//IL_0031: 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_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_004d: 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_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: 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_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		if (!TryFindCity(out var city))
		{
			if (KaijuConfig.VerboseLogging.Value)
			{
				KaijuNukemPlugin.Log.LogInfo((object)"[testspawn] no building cluster found yet, waiting");
			}
			return;
		}
		GlobalPosition anchor;
		GlobalPosition val = (TryFindPlayerAnchor(out anchor) ? anchor : city);
		if (!TryFindSeaSpawn(val, out var sea))
		{
			KaijuNukemPlugin.Log.LogWarning((object)"[testspawn] could not find open water near the spawn anchor");
		}
		else if (!((Object)(object)KaijuSpawner.Spawn(sea, city) == (Object)null))
		{
			_spawned = true;
			Vector3 val2 = GlobalPositionExtensions.ToLocalPosition(val);
			Vector3 val3 = GlobalPositionExtensions.ToLocalPosition(sea);
			Vector3 val4 = default(Vector3);
			((Vector3)(ref val4))..ctor(val3.x - val2.x, 0f, val3.z - val2.z);
			float num = Mathf.Repeat(Mathf.Atan2(val4.x, val4.z) * 57.29578f, 360f);
			KaijuNukemPlugin.Log.LogInfo((object)($"[testspawn] test Kaiju — bearing {num:F0}° at {((Vector3)(ref val4)).magnitude / 1000f:F1} km " + "from you, heading for the city."));
		}
	}

	private static bool TryFindPlayerAnchor(out GlobalPosition anchor)
	{
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		Aircraft val = default(Aircraft);
		if (GameManager.GetLocalAircraft(ref val) && (Object)(object)val != (Object)null)
		{
			anchor = GlobalPositionExtensions.ToGlobalPosition(((Component)val).transform.position);
			return true;
		}
		FactionHQ val2 = default(FactionHQ);
		if (GameManager.GetLocalHQ(ref val2) && (Object)(object)val2 != (Object)null)
		{
			foreach (Airbase airbasis in val2.GetAirbases())
			{
				if (!((Object)(object)airbasis == (Object)null))
				{
					anchor = GlobalPositionExtensions.ToGlobalPosition(((Component)airbasis).transform.position);
					return true;
				}
			}
		}
		anchor = default(GlobalPosition);
		return false;
	}

	private static bool TryFindCity(out GlobalPosition city)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		city = default(GlobalPosition);
		MapBuildingSet[] array = Object.FindObjectsOfType<MapBuildingSet>();
		if (array == null || array.Length == 0)
		{
			return false;
		}
		MapBuildingSet val = null;
		int num = 0;
		MapBuildingSet[] array2 = array;
		foreach (MapBuildingSet val2 in array2)
		{
			if (!((Object)(object)val2 == (Object)null))
			{
				int num2 = ((Component)val2).GetComponentsInChildren<MapBuilding>(false).Length;
				if (num2 > num)
				{
					num = num2;
					val = val2;
				}
			}
		}
		if ((Object)(object)val == (Object)null || num == 0)
		{
			return false;
		}
		Vector3 val3 = Vector3.zero;
		int num3 = 0;
		MapBuilding[] componentsInChildren = ((Component)val).GetComponentsInChildren<MapBuilding>(false);
		foreach (MapBuilding val4 in componentsInChildren)
		{
			if (!((Object)(object)val4 == (Object)null))
			{
				val3 += ((Component)val4).transform.position;
				num3++;
			}
		}
		if (num3 == 0)
		{
			return false;
		}
		city = GlobalPositionExtensions.ToGlobalPosition(val3 / (float)num3);
		if (KaijuConfig.VerboseLogging.Value)
		{
			KaijuNukemPlugin.Log.LogInfo((object)$"[testspawn] target city: {((Object)val).name}, {num} buildings");
		}
		return true;
	}

	private static bool TryFindSeaSpawn(GlobalPosition anchor, out GlobalPosition sea)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: 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_004f: 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_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = GlobalPositionExtensions.ToLocalPosition(anchor);
		float value = KaijuConfig.SpawnDistanceFromPlayer.Value;
		for (int i = 0; i < 3; i++)
		{
			float num = value * (1f - (float)i * 0.25f);
			for (int j = 0; j < 360; j += 15)
			{
				float num2 = (float)j * (MathF.PI / 180f);
				Vector3 val2 = val + new Vector3(Mathf.Sin(num2) * num, 0f, Mathf.Cos(num2) * num);
				val2.y = Datum.LocalSeaY;
				if (IsOpenWater(val2))
				{
					sea = GlobalPositionExtensions.ToGlobalPosition(val2);
					return true;
				}
			}
		}
		sea = default(GlobalPosition);
		return false;
	}

	private static bool IsOpenWater(Vector3 p)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: 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)
		Vector3 val = p + Vector3.up * 1000f;
		Vector3 val2 = p - Vector3.up * 1000f;
		RaycastHit val3 = default(RaycastHit);
		if (!Physics.Linecast(val, val2, ref val3, LayerMask.op_Implicit(PhysicsLayers.StaticsMask)))
		{
			return true;
		}
		return ((RaycastHit)(ref val3)).point.y < Datum.LocalSeaY;
	}
}
internal class KaijuContainerConverter : JsonConverter<SavedContainer>
{
	private const string PropertyName = "kaijuParams";

	[ThreadStatic]
	private static bool _isWriting;

	public override bool CanWrite => !_isWriting;

	public override void WriteJson(JsonWriter writer, SavedContainer value, JsonSerializer serializer)
	{
		if (value == null)
		{
			writer.WriteNull();
			return;
		}
		_isWriting = true;
		try
		{
			JObject val = JObject.FromObject((object)value, serializer);
			if (KaijuParamStore.IsKaiju((SavedUnit)(object)value) && KaijuParamStore.TryGet((SavedUnit)(object)value, out var parameters) && parameters != null)
			{
				val["kaijuParams"] = (JToken)(object)JObject.FromObject((object)parameters, serializer);
			}
			((JToken)val).WriteTo(writer, Array.Empty<JsonConverter>());
		}
		finally
		{
			_isWriting = false;
		}
	}

	public override SavedContainer ReadJson(JsonReader reader, Type objectType, SavedContainer existingValue, bool hasExistingValue, JsonSerializer serializer)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Invalid comparison between Unknown and I4
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Expected O, but got Unknown
		if ((int)reader.TokenType == 11)
		{
			return null;
		}
		JObject val = JObject.Load(reader);
		JToken val2 = val["kaijuParams"];
		if (val2 != null)
		{
			val.Remove("kaijuParams");
		}
		SavedContainer val3 = (SavedContainer)((hasExistingValue && existingValue != null) ? ((object)existingValue) : ((object)new SavedContainer()));
		JsonReader val4 = ((JToken)val).CreateReader();
		try
		{
			serializer.Populate(val4, (object)val3);
		}
		finally
		{
			((IDisposable)val4)?.Dispose();
		}
		if (val2 != null)
		{
			try
			{
				KaijuParams kaijuParams = val2.ToObject<KaijuParams>(serializer);
				if (kaijuParams != null)
				{
					KaijuParamStore.Set((SavedUnit)(object)val3, kaijuParams);
				}
			}
			catch (Exception ex)
			{
				KaijuNukemPlugin.Log.LogWarning((object)("[mission] ignoring unreadable kaijuParams on container '" + ((SavedUnit)val3).UniqueName + "': " + ex.GetType().Name + ": " + ex.Message));
			}
		}
		return val3;
	}
}
public static class KaijuMissionSerialization
{
	private static bool _installed;

	public static void Install()
	{
		if (_installed)
		{
			return;
		}
		try
		{
			JsonSerializerSettings val = NewtonsoftHelper.Default;
			if (((val != null) ? val.Converters : null) == null)
			{
				KaijuNukemPlugin.Log.LogError((object)"[mission] NewtonsoftHelper.Default has no converter list — per-placement Kaiju values will not be saved into missions.");
				_installed = true;
				return;
			}
			foreach (JsonConverter converter in val.Converters)
			{
				if (converter is KaijuContainerConverter)
				{
					_installed = true;
					return;
				}
			}
			val.Converters.Add((JsonConverter)(object)new KaijuContainerConverter());
			_installed = true;
			KaijuNukemPlugin.Log.LogInfo((object)"[mission] per-placement Kaiju parameters will be saved into mission.json.");
		}
		catch (Exception ex)
		{
			_installed = true;
			KaijuNukemPlugin.Log.LogError((object)("[mission] could not install the mission converter (" + ex.GetType().Name + ": " + ex.Message + ") — Kaiju parameters will be editable but will not persist."));
		}
	}
}
[BepInPlugin("hendev.kaijunukem", "KaijuNukem", "1.0.0")]
public class KaijuNukemPlugin : BaseUnityPlugin
{
	public const string Guid = "hendev.kaijunukem";

	public const string Name = "KaijuNukem";

	public const string Version = "1.0.0";

	public static KaijuNukemPlugin Instance { get; private set; }

	public static ManualLogSource Log { get; private set; }

	private void Awake()
	{
		Instance = this;
		Log = ((BaseUnityPlugin)this).Logger;
		KaijuConfig.Bind(((BaseUnityPlugin)this).Config);
		if (!KaijuConfig.Enabled.Value)
		{
			Log.LogInfo((object)"KaijuNukem 1.0.0 loaded but disabled by config.");
			return;
		}
		if (!KaijuAssets.Load(Log))
		{
			Log.LogError((object)"KaijuNukem 1.0.0 could not load its assets — the Kaiju will not run.");
			return;
		}
		KaijuHost.Install();
		KaijuMissionSerialization.Install();
		KaijuUnitPanelInfo.Apply();
		KaijuObjectiveProgress.Apply();
		Log.LogInfo((object)"KaijuNukem 1.0.0 loaded.");
	}
}
internal static class KaijuObjectiveProgress
{
	private const string PatchId = "hendev.kaijunukem.objectiveprogress";

	private static bool _patched;

	private static bool _loggedFailure;

	private static FieldInfo _allItemsField;

	public static void Apply()
	{
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Expected O, but got Unknown
		if (_patched)
		{
			return;
		}
		try
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(ObjectiveInfoList_ObjEntry), "Refresh", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				KaijuNukemPlugin.Log.LogWarning((object)"[objective] ObjectiveInfoList_ObjEntry.Refresh not found — the Kaiju damage percentage is disabled. The objective itself still works normally.");
				_patched = true;
				return;
			}
			_allItemsField = AccessTools.Field(typeof(DestroyUnitObjective), "allItems");
			new Harmony("hendev.kaijunukem.objectiveprogress").Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(KaijuObjectiveProgress), "RefreshPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			_patched = true;
			KaijuNukemPlugin.Log.LogInfo((object)"[objective] Kaiju destroy-objectives will show live damage progress.");
		}
		catch (Exception ex)
		{
			_patched = true;
			KaijuNukemPlugin.Log.LogError((object)("[objective] could not patch the objective HUD (" + ex.GetType().Name + ": " + ex.Message + ") — continuing without the damage percentage."));
		}
	}

	private static void RefreshPostfix(ObjectiveInfoList_ObjEntry __instance, Objective obj)
	{
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Invalid comparison between Unknown and I4
		try
		{
			if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.OBJ_Complete == (Object)null)
			{
				return;
			}
			DestroyUnitObjective val = (DestroyUnitObjective)(object)((obj is DestroyUnitObjective) ? obj : null);
			if (val != null)
			{
				if (_allItemsField != null && _allItemsField.GetValue(val) is List<SavedUnit> items)
				{
					KaijuDiagnostics.DumpObjectiveOnce(((Objective)val).SavedObjective?.DisplayName ?? "?", items);
				}
				if ((int)obj.Status != 2 && TryDamagePercent(val, out var percent))
				{
					KaijuDiagnostics.DumpPercentOnce(percent, obj.CompletePercent);
					((TMP_Text)__instance.OBJ_Complete).text = $"{100f * percent:F0}%";
				}
			}
		}
		catch (Exception ex)
		{
			if (!_loggedFailure)
			{
				_loggedFailure = true;
				KaijuNukemPlugin.Log.LogError((object)("[objective] damage percentage failed and is now inert (" + ex.GetType().Name + ": " + ex.Message + "). The objective HUD is otherwise unaffected."));
			}
		}
	}

	private static bool TryDamagePercent(DestroyUnitObjective destroy, out float percent)
	{
		percent = 0f;
		if (destroy == null || _allItemsField == null)
		{
			return false;
		}
		if (!(_allItemsField.GetValue(destroy) is List<SavedUnit> { Count: not 0 } list))
		{
			return false;
		}
		float num = 0f;
		int num2 = 0;
		bool flag = false;
		foreach (SavedUnit item in list)
		{
			if (item != null)
			{
				if (KaijuParamStore.IsKaiju(item))
				{
					flag = true;
					num += DamageFraction(item);
				}
				else
				{
					num += (IsDead(item) ? 1f : 0f);
				}
				num2++;
			}
		}
		if (!flag || num2 == 0)
		{
			return false;
		}
		percent = Mathf.Clamp01(num / (float)num2);
		return true;
	}

	private static float DamageFraction(SavedUnit saved)
	{
		if (IsDead(saved))
		{
			return 1f;
		}
		if (!UnitRegistry.customIDLookup.TryGetValue(saved.UniqueName, out var value) || (Object)(object)value == (Object)null)
		{
			return 0f;
		}
		KaijuBody component = ((Component)value).GetComponent<KaijuBody>();
		if ((Object)(object)component == (Object)null)
		{
			return 0f;
		}
		return Mathf.Clamp01(1f - component.HealthFraction);
	}

	private static bool IsDead(SavedUnit saved)
	{
		if (UnitRegistry.customIDLookup.TryGetValue(saved.UniqueName, out var value))
		{
			if (!((Object)(object)value == (Object)null))
			{
				return value.disabled;
			}
			return true;
		}
		return false;
	}
}
public class KaijuParams
{
	public float Health;

	public float Scale;

	public float WalkSpeed;

	public float TurnRateDegPerSec;

	public float SwipeRange;

	public float SwipeArcDegrees;

	public float SwipeDamage;

	public float SwipeCooldown;

	public string TargetUnitName = "";

	public float MoneyPer1000Damage = 100f;

	public float RoundDamageScale = 0.5f;

	public float BlastDamageScale = 25f;

	public static KaijuParams Defaults()
	{
		return new KaijuParams
		{
			Health = Cfg(KaijuConfig.Health, 20000f),
			Scale = Cfg(KaijuConfig.KaijuScale, 300f),
			WalkSpeed = Cfg(KaijuConfig.WalkSpeed, 120f),
			TurnRateDegPerSec = Cfg(KaijuConfig.TurnRateDegPerSec, 10f),
			SwipeRange = Cfg(KaijuConfig.SwipeRange, 700f),
			SwipeArcDegrees = Cfg(KaijuConfig.SwipeArcDegrees, 120f),
			SwipeDamage = Cfg(KaijuConfig.SwipeDamage, 5000f),
			SwipeCooldown = Cfg(KaijuConfig.SwipeCooldown, 6f),
			TargetUnitName = "",
			MoneyPer1000Damage = Cfg(KaijuConfig.MoneyPer1000Damage, 100f),
			RoundDamageScale = Cfg(KaijuConfig.RoundDamageScale, 0.5f),
			BlastDamageScale = Cfg(KaijuConfig.BlastDamageScale, 25f)
		};
	}

	private static float Cfg(ConfigEntry<float> entry, float fallback)
	{
		return entry?.Value ?? fallback;
	}

	public KaijuParams Clone()
	{
		return (KaijuParams)MemberwiseClone();
	}
}
public static class KaijuParamStore
{
	private static readonly ConditionalWeakTable<SavedUnit, KaijuParams> _byUnit = new ConditionalWeakTable<SavedUnit, KaijuParams>();

	public static bool IsKaiju(SavedUnit saved)
	{
		if (saved != null)
		{
			return saved.type == "kaiju_nukem";
		}
		return false;
	}

	public static KaijuParams Get(SavedUnit saved)
	{
		if (saved == null)
		{
			return KaijuParams.Defaults();
		}
		return _byUnit.GetValue(saved, (SavedUnit _) => KaijuParams.Defaults());
	}

	public static bool TryGet(SavedUnit saved, out KaijuParams parameters)
	{
		parameters = null;
		if (saved != null)
		{
			return _byUnit.TryGetValue(saved, out parameters);
		}
		return false;
	}

	public static void Set(SavedUnit saved, KaijuParams parameters)
	{
		if (saved != null && parameters != null)
		{
			_byUnit.Remove(saved);
			_byUnit.Add(saved, parameters);
		}
	}

	public static KaijuParams ForUnit(Unit unit)
	{
		if ((Object)(object)unit == (Object)null)
		{
			return KaijuParams.Defaults();
		}
		SavedUnit savedUnit = unit.SavedUnit;
		if (savedUnit == null)
		{
			return KaijuParams.Defaults();
		}
		return Get(savedUnit);
	}
}
public static class KaijuRegistry
{
	private const int KaijuPrefabHash = 1262569802;

	public const string JsonKey = "kaiju_nukem";

	public static bool Registered { get; private set; }

	public static IEnumerator RegisterWhenReady()
	{
		while (!Registered)
		{
			yield return (object)new WaitForSeconds(1f);
			if (!((Object)(object)Encyclopedia.i == (Object)null) && Encyclopedia.Lookup != null)
			{
				TryRegister();
			}
		}
	}

	private static void TryRegister()
	{
		UnitDefinition kaijuDefinition = KaijuAssets.KaijuDefinition;
		if ((Object)(object)kaijuDefinition == (Object)null)
		{
			KaijuNukemPlugin.Log.LogError((object)"[registry] no KaijuDefinition in the bundle — not registering");
			Registered = true;
			return;
		}
		if (Encyclopedia.Lookup.ContainsKey("kaiju_nukem"))
		{
			Registered = true;
			return;
		}
		if ((Object)(object)kaijuDefinition.unitPrefab == (Object)null)
		{
			Abort("definition has no unitPrefab");
			return;
		}
		NetworkIdentity component = kaijuDefinition.unitPrefab.GetComponent<NetworkIdentity>();
		if ((Object)(object)component == (Object)null)
		{
			Abort("prefab has no NetworkIdentity — refusing to inject");
			return;
		}
		if ((Object)(object)kaijuDefinition.unitPrefab.GetComponent<Unit>() == (Object)null)
		{
			Abort("prefab has no Unit component (expected Container) — refusing to inject");
			return;
		}
		if (HashCollides(1262569802))
		{
			Abort($"prefab hash 0x{1262569802:X} already used by a vanilla prefab");
			return;
		}
		try
		{
			component.PrefabHash = 1262569802;
			kaijuDefinition.jsonKey = "kaiju_nukem";
			if (kaijuDefinition.mass <= 0f)
			{
				kaijuDefinition.mass = 500000f;
			}
			EnsureDimensions(kaijuDefinition);
			BorrowIcons(kaijuDefinition);
			Encyclopedia.i.otherUnits.Add(kaijuDefinition);
			Encyclopedia.Lookup.Add("kaiju_nukem", kaijuDefinition);
			((INetworkDefinition)kaijuDefinition).LookupIndex = Encyclopedia.i.IndexLookup.Count;
			Encyclopedia.i.IndexLookup.Add((INetworkDefinition)(object)kaijuDefinition);
			Registered = true;
			KaijuNukemPlugin.Log.LogInfo((object)(string.Format("[registry] Kaiju registered as '{0}' (index {1}) ", "kaiju_nukem", ((INetworkDefinition)kaijuDefinition).LookupIndex) + "— it should now appear in the Mission Editor under Other Units."));
		}
		catch (Exception ex)
		{
			Encyclopedia.i.otherUnits.Remove(kaijuDefinition);
			Encyclopedia.Lookup.Remove("kaiju_nukem");
			Encyclopedia.i.IndexLookup.Remove((INetworkDefinition)(object)kaijuDefinition);
			Abort("injection threw and was rolled back: " + ex.GetType().Name + ": " + ex.Message);
		}
	}

	private static void Abort(string reason)
	{
		Registered = true;
		KaijuNukemPlugin.Log.LogError((object)("[registry] NOT registering the Kaiju: " + reason + ". The Mission Editor will not list it; enable Master/AutoSpawn to test the creature via the legacy spawner instead."));
	}

	private static void EnsureDimensions(UnitDefinition def)
	{
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: 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_0066: 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_0083: 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)
		BoxCollider component = def.unitPrefab.GetComponent<BoxCollider>();
		if ((Object)(object)component == (Object)null)
		{
			def.length = (def.width = 300f);
			def.height = 570f;
		}
		else
		{
			Vector3 localScale = def.unitPrefab.transform.localScale;
			def.width = Mathf.Abs(component.size.x * localScale.x);
			def.height = Mathf.Abs(component.size.y * localScale.y);
			def.length = Mathf.Abs(component.size.z * localScale.z);
		}
		KaijuNukemPlugin.Log.LogInfo((object)($"[registry] dimensions set to {def.width:F0} x {def.length:F0} x {def.height:F0} m " + $"(maxRadius {Mathf.Max(Mathf.Max(def.length, def.width), def.height) * 0.5f:F0} m) — " + "missiles will aim at the body instead of the pivot between its feet."));
	}

	private static bool HashCollides(int hash)
	{
		foreach (INetworkDefinition item in Encyclopedia.i.IndexLookup)
		{
			UnitDefinition val = (UnitDefinition)(object)((item is UnitDefinition) ? item : null);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val.unitPrefab == (Object)null))
			{
				NetworkIdentity component = val.unitPrefab.GetComponent<NetworkIdentity>();
				if ((Object)(object)component != (Object)null && component.PrefabHash == hash)
				{
					return true;
				}
			}
		}
		return false;
	}

	private static void BorrowIcons(UnitDefinition def)
	{
		if ((Object)(object)def.mapIcon != (Object)null)
		{
			return;
		}
		Encyclopedia i = Encyclopedia.i;
		if (i?.vehicles != null && i.vehicles.Count != 0)
		{
			VehicleDefinition val = i.vehicles[0];
			if (!((Object)(object)val == (Object)null))
			{
				def.mapIcon = ((UnitDefinition)val).mapIcon;
				def.friendlyIcon = ((UnitDefinition)val).friendlyIcon;
				def.hostileIcon = ((UnitDefinition)val).hostileIcon;
				def.mapOrient = ((UnitDefinition)val).mapOrient;
			}
		}
	}
}
public static class KaijuSpawner
{
	private const int KaijuPrefabHash = 1262569802;

	public static GameObject Spawn(GlobalPosition where, GlobalPosition walkTarget)
	{
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: 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_01cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01db: 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_020c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0217: Unknown result type (might be due to invalid IL or missing references)
		//IL_0222: 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_0238: Unknown result type (might be due to invalid IL or missing references)
		//IL_0243: Unknown result type (might be due to invalid IL or missing references)
		//IL_0250: Expected O, but got Unknown
		//IL_028a: 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_00bc: 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_031e: Unknown result type (might be due to invalid IL or missing references)
		//IL_037c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0381: Unknown result type (might be due to invalid IL or missing references)
		//IL_0395: Unknown result type (might be due to invalid IL or missing references)
		//IL_039a: Unknown result type (might be due to invalid IL or missing references)
		NetworkManagerNuclearOption i = NetworkManagerNuclearOption.i;
		if ((Object)(object)i == (Object)null || !((NetworkManager)i).Server.Active)
		{
			KaijuNukemPlugin.Log.LogWarning((object)"[spawn] not the server/host — Kaiju spawn skipped");
			return null;
		}
		if ((Object)(object)KaijuAssets.KaijuPrefab == (Object)null)
		{
			KaijuNukemPlugin.Log.LogError((object)"[spawn] no prefab loaded");
			return null;
		}
		GameObject val = Object.Instantiate<GameObject>(KaijuAssets.KaijuPrefab);
		val.SetActive(false);
		Transform[] componentsInChildren = val.GetComponentsInChildren<Transform>(true);
		for (int j = 0; j < componentsInChildren.Length; j++)
		{
			((Component)componentsInChildren[j]).gameObject.layer = PhysicsLayers.Default;
		}
		val.transform.SetParent((Transform)null, true);
		Scene val2;
		if ((Object)(object)Datum.origin != (Object)null)
		{
			val2 = ((Component)Datum.origin).gameObject.scene;
			if (((Scene)(ref val2)).IsValid())
			{
				SceneManager.MoveGameObjectToScene(val, ((Component)Datum.origin).gameObject.scene);
			}
		}
		((Object)val).name = "Kaiju";
		val.transform.localScale = Vector3.one * KaijuConfig.KaijuScale.Value;
		Rigidbody val3 = val.AddComponent<Rigidbody>();
		val3.isKinematic = true;
		val3.useGravity = false;
		val3.mass = 500000f;
		val3.interpolation = (RigidbodyInterpolation)1;
		CapsuleCollider obj = val.AddComponent<CapsuleCollider>();
		obj.direction = 1;
		obj.radius = 0.45f;
		obj.height = 1.9f;
		obj.center = new Vector3(0f, 0.95f, 0f);
		NetworkIdentity val4 = val.AddComponent<NetworkIdentity>();
		Unit unit = val.AddComponent<Unit>();
		KaijuBody kaijuBody = val.AddComponent<KaijuBody>();
		KaijuSwipe kaijuSwipe = val.AddComponent<KaijuSwipe>();
		KaijuBrain kaijuBrain = val.AddComponent<KaijuBrain>();
		unit.definition = BuildDefinition(val);
		unit.MapUniqueName = string.Empty;
		unit.unitName = "Kaiju";
		val.transform.position = GlobalPositionExtensions.ToLocalPosition(where);
		val.transform.rotation = Quaternion.identity;
		Animator componentInChildren = val.GetComponentInChildren<Animator>();
		Transform val5 = FindHandBone(componentInChildren, val.transform);
		kaijuBody.Initialize(armor: new ArmorProperties
		{
			pierceArmor = 20f,
			blastArmor = 50f,
			fireArmor = 10f,
			pierceTolerance = 1f,
			blastTolerance = 1f,
			fireTolerance = 1f,
			overpressureLimit = 1000f
		}, unit: unit, hitPoints: KaijuConfig.Health.Value);
		kaijuSwipe.Initialize(unit, val5);
		kaijuBrain.Initialize(unit, componentInChildren, kaijuSwipe, kaijuBody);
		kaijuBrain.SetDestination(walkTarget);
		SkinnedMeshRenderer[] componentsInChildren2 = val.GetComponentsInChildren<SkinnedMeshRenderer>(true);
		for (int j = 0; j < componentsInChildren2.Length; j++)
		{
			componentsInChildren2[j].updateWhenOffscreen = true;
		}
		val.SetActive(true);
		val3.ResetCenterOfMass();
		val3.ResetInertiaTensor();
		val4.PrefabHash = 1262569802;
		AssignHostileFaction(unit);
		val4.OnStartClient.AddListener((Action)delegate
		{
			OnKaijuStartClient(unit);
		});
		((NetworkManager)i).ServerObjectManager.Spawn(val4);
		ManualLogSource log = KaijuNukemPlugin.Log;
		string[] obj2 = new string[6]
		{
			$"[spawn] Kaiju spawned at {val.transform.position} scale={KaijuConfig.KaijuScale.Value} ",
			string.Format("hp={0} hand={1} ", KaijuConfig.Health.Value, ((Object)(object)val5 != (Object)null) ? ((Object)val5).name : "NONE"),
			"scene=",
			null,
			null,
			null
		};
		val2 = val.scene;
		obj2[3] = ((Scene)(ref val2)).name;
		obj2[4] = " active=";
		val2 = SceneManager.GetActiveScene();
		obj2[5] = ((Scene)(ref val2)).name;
		log.LogInfo((object)string.Concat(obj2));
		return val;
	}

	private static void AssignHostileFaction(Unit unit)
	{
		FactionHQ val = default(FactionHQ);
		if (!GameManager.GetLocalHQ(ref val) || (Object)(object)val == (Object)null)
		{
			KaijuNukemPlugin.Log.LogWarning((object)"[spawn] player has no faction yet — leaving the Kaiju factionless");
			return;
		}
		FactionHQ val2 = null;
		foreach (FactionHQ allHQ in FactionRegistry.GetAllHQs())
		{
			if (!((Object)(object)allHQ == (Object)null) && !((Object)(object)allHQ == (Object)(object)val))
			{
				val2 = allHQ;
				break;
			}
		}
		if ((Object)(object)val2 == (Object)null)
		{
			KaijuNukemPlugin.Log.LogWarning((object)("[spawn] '" + ((Object)val).name + "' is the only faction — Kaiju left factionless"));
			return;
		}
		unit.NetworkHQ = val2;
		KaijuNukemPlugin.Log.LogInfo((object)("[spawn] you are '" + ((Object)val).name + "'; Kaiju assigned to hostile faction '" + ((Object)val2).name + "'"));
	}

	private static void OnKaijuStartClient(Unit unit)
	{
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		NetworkManagerNuclearOption i = NetworkManagerNuclearOption.i;
		unit.SetLocalSim((Object)(object)i != (Object)null && ((NetworkManager)i).Server.Active);
		unit.RegisterUnit((float?)4f);
		unit.InitializeUnit();
		DynamicMap i2 = SceneSingleton<DynamicMap>.i;
		if ((Object)(object)i2 != (Object)null)
		{
			i2.GetOrAddIcon(unit);
			KaijuNukemPlugin.Log.LogInfo((object)"[spawn] map icon requested for the Kaiju");
		}
		else
		{
			KaijuNukemPlugin.Log.LogWarning((object)"[spawn] DynamicMap not available — no map pin");
		}
		if (KaijuConfig.VerboseLogging.Value)
		{
			KaijuNukemPlugin.Log.LogInfo((object)$"[spawn] OnStartClient localSim={unit.LocalSim} id={unit.persistentID}");
		}
	}

	private static UnitDefinition BuildDefinition(GameObject go)
	{
		float value = KaijuConfig.KaijuScale.Value;
		UnitDefinition obj = ScriptableObject.CreateInstance<UnitDefinition>();
		((Object)obj).name = "KaijuDefinition";
		obj.unitName = "Kaiju";
		obj.bogeyName = "Kaiju";
		obj.description = "Something very large has come ashore.";
		obj.jsonKey = "kaijunukem_kaiju";
		obj.unitPrefab = go;
		obj.length = 1.2f * value;
		obj.width = 1.2f * value;
		obj.height = 1.9f * value;
		obj.mass = 500000f;
		obj.value = 1000f;
		obj.visibleRange = 40000f;
		obj.iconRange = 40000f;
		obj.radarSize = 200f;
		obj.armorTier = 2f;
		obj.damageTolerance = 1f;
		obj.IsObstacle = false;
		obj.dontAutomaticallyAddToEncyclopedia = true;
		BorrowIcons(obj);
		return obj;
	}

	private static void BorrowIcons(UnitDefinition def)
	{
		Encyclopedia i = Encyclopedia.i;
		if (!((Object)(object)i == (Object)null) && i.vehicles != null && i.vehicles.Count != 0)
		{
			VehicleDefinition val = i.vehicles[0];
			if (!((Object)(object)val == (Object)null))
			{
				def.mapIcon = ((UnitDefinition)val).mapIcon;
				def.friendlyIcon = ((UnitDefinition)val).friendlyIcon;
				def.hostileIcon = ((UnitDefinition)val).hostileIcon;
				def.iconSize = ((UnitDefinition)val).iconSize;
				def.mapIconSize = ((UnitDefinition)val).mapIconSize * 2f;
				def.mapOrient = ((UnitDefinition)val).mapOrient;
			}
		}
	}

	private static Transform FindHandBone(Animator animator, Transform root)
	{
		if ((Object)(object)animator != (Object)null && animator.isHuman)
		{
			Transform boneTransform = animator.GetBoneTransform((HumanBodyBones)17);
			if ((Object)(object)boneTransform != (Object)null)
			{
				return boneTransform;
			}
		}
		Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true);
		foreach (Transform val in componentsInChildren)
		{
			if (((Object)val).name == "Hand_L")
			{
				return val;
			}
		}
		KaijuNukemPlugin.Log.LogWarning((object)"[spawn] left-hand bone not found; swipe will originate from the root");
		return null;
	}
}
public class KaijuSwipe : MonoBehaviour
{
	private static readonly Collider[] Buffer = (Collider[])(object)new Collider[512];

	private Unit _unit;

	private Transform _handBone;

	private void Awake()
	{
		if ((Object)(object)_unit == (Object)null)
		{
			_unit = ((Component)this).GetComponent<Unit>();
		}
		if ((Object)(object)_handBone == (Object)null)
		{
			_handBone = FindHandBone();
		}
	}

	public void Initialize(Unit unit, Transform handBone)
	{
		_unit = (((Object)(object)unit != (Object)null) ? unit : ((Component)this).GetComponent<Unit>());
		_handBone = (((Object)(object)handBone != (Object)null) ? handBone : FindHandBone());
	}

	private Transform FindHandBone()
	{
		Animator componentInChildren = ((Component)this).GetComponentInChildren<Animator>();
		if ((Object)(object)componentInChildren != (Object)null && componentInChildren.isHuman)
		{
			Transform boneTransform = componentInChildren.GetBoneTransform((HumanBodyBones)17);
			if ((Object)(object)boneTransform != (Object)null)
			{
				return boneTransform;
			}
		}
		Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true);
		foreach (Transform val in componentsInChildren)
		{
			if (((Object)val).name == "Hand_L")
			{
				return val;
			}
		}
		return null;
	}

	public void Strike()
	{
		//IL_004f: 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_0054: 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_0060: 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_008e: Unknown result type (