Decompiled source of BiomassConstructor v1.0.0

BiomassConstructor.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using EntityStates;
using EntityStates.Engi.EngiBubbleShield;
using Microsoft.CodeAnalysis;
using On.EntityStates.Engi.EngiBubbleShield;
using On.RoR2;
using On.RoR2.CharacterAI;
using R2API;
using RoR2;
using RoR2.CharacterAI;
using RoR2.Navigation;
using RoR2.Projectile;
using RoR2.Skills;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BiomassConstructor
{
	[BepInPlugin("com.bmqrt.biomassconstructor", "BiomassConstructor", "3.5.1")]
	public class BiomassConstructorPlugin : BaseUnityPlugin
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static Action<Run> <>9__15_1;

			public static Action<Stage> <>9__15_2;

			public static Action<TeleporterInteraction> <>9__15_3;

			public static Action<SceneExitController> <>9__15_4;

			public static hook_RecalculateStats <>9__18_0;

			public static hook_OnBodyDeath <>9__18_1;

			public static Action <>9__22_0;

			internal void <Awake>b__15_1(Run run)
			{
				ConstructorPylonController.ResetSavedProgress();
			}

			internal void <Awake>b__15_2(Stage stage)
			{
				ConstructorPylonController.PurgeAllModSummonsGlobal();
			}

			internal void <Awake>b__15_3(TeleporterInteraction tp)
			{
				ConstructorPylonController.StripStageSpawnerItemsFromAllSummons();
			}

			internal void <Awake>b__15_4(SceneExitController exitController)
			{
				ConstructorPylonController.PurgeAllModSummonsGlobal();
			}

			internal void <RegisterSafeMMHooks>b__18_0(orig_RecalculateStats orig, CharacterBody self)
			{
				orig.Invoke(self);
				if (!((Object)(object)self != (Object)null) || !((Object)(object)self.skillLocator != (Object)null) || !((Object)(object)self.skillLocator.special != (Object)null))
				{
					return;
				}
				GenericSkill special = self.skillLocator.special;
				if ((Object)(object)special.skillDef == (Object)(object)PylonSkillDef)
				{
					if (special.maxStock > 1)
					{
						special.SetBonusStockFromBody(0);
					}
					if (special.stock > 1)
					{
						special.stock = 1;
					}
				}
			}

			internal void <RegisterSafeMMHooks>b__18_1(orig_OnBodyDeath orig, CharacterMaster self, CharacterBody body)
			{
				BiomassSummonMarker biomassSummonMarker = (((Object)(object)self != (Object)null) ? ((Component)self).GetComponent<BiomassSummonMarker>() : null);
				if ((Object)(object)biomassSummonMarker != (Object)null && (biomassSummonMarker.isCloneUnit || biomassSummonMarker.isGuardTurret || biomassSummonMarker.isSurvivorAlly))
				{
					if ((Object)(object)self.minionOwnership != (Object)null)
					{
						self.minionOwnership.SetOwner((CharacterMaster)null);
					}
					self.teamIndex = (TeamIndex)(-1);
					biomassSummonMarker.pendingSafeDestroy = true;
				}
				orig.Invoke(self, body);
			}

			internal void <RegisterLanguageTokens>b__22_0()
			{
				Language currentLanguage = Language.currentLanguage;
				if (currentLanguage != null)
				{
					currentLanguage.SetStringByToken("BMQRT_PYLON_NAME", "Constructor Pylon");
				}
				Language currentLanguage2 = Language.currentLanguage;
				if (currentLanguage2 != null)
				{
					currentLanguage2.SetStringByToken("BMQRT_PYLON_DESC", "Deploy a <style=cIsUtility>Constructor Pylon</style> (Max 1) that inherits your items and fabricates enemy clones every <style=cIsUtility>9.5s</style> <style=cStack>(-0.16s per level, base 2 clones)</style>. Levels up to <style=cIsHealing>30</style> via kills, granting <style=cIsUtility>1 Evolution Point</style> every 5 levels.");
				}
			}
		}

		public const string ModGUID = "com.bmqrt.biomassconstructor";

		public const string ModName = "BiomassConstructor";

		public const string ModVersion = "3.5.1";

		public static SkillDef PylonSkillDef;

		public static GameObject SpawnVfxPrefab;

		public static GameObject HealVfxPrefab;

		public static GameObject BubbleShieldPrefab;

		public static GameObject MushroomWardPrefab;

		public static Material HologramBlueprintMaterial;

		public static Texture2D CustomPylonIconTex;

		public static Sprite CustomPylonIconSprite;

		public static ConfigEntry<int> CfgBaseCloneCapacity;

		public static ConfigEntry<float> CfgBiomassGainMultiplier;

		public static ConfigEntry<float> CfgBaseCloneInterval;

		public static ConfigEntry<bool> CfgEnableLiveItemSync;

		private void Awake()
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"BiomassConstructor v3.5.1 initializing...");
			InitConfig();
			RegisterLanguageTokens();
			CreatePylonSkill();
			AddSkillToEngineerImmediate();
			RegisterSafeMMHooks();
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, (Action)delegate
			{
				LoadAddressableAssets();
				BuildTurretHeadOnlyIconFromVanilla();
			});
			Run.onRunStartGlobal += delegate
			{
				ConstructorPylonController.ResetSavedProgress();
			};
			Stage.onStageStartGlobal += delegate
			{
				ConstructorPylonController.PurgeAllModSummonsGlobal();
			};
			TeleporterInteraction.onTeleporterFinishGlobal += delegate
			{
				ConstructorPylonController.StripStageSpawnerItemsFromAllSummons();
			};
			SceneExitController.onBeginExit += delegate
			{
				ConstructorPylonController.PurgeAllModSummonsGlobal();
			};
			((BaseUnityPlugin)this).Logger.LogInfo((object)"BiomassConstructor v3.5.1 loaded successfully!");
		}

		private void InitConfig()
		{
			CfgBaseCloneCapacity = ((BaseUnityPlugin)this).Config.Bind<int>("Balance", "BaseCloneCapacity", 2, "Base clone capacity at Level 1 (+1 capacity every 6 Pylon levels).");
			CfgBiomassGainMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Balance", "BiomassGainMultiplier", 1f, "Biomass gained per kill multiplier.");
			CfgBaseCloneInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Balance", "BaseCloneInterval", 9.5f, "Base clone fabrication interval in seconds at Level 1.");
			CfgEnableLiveItemSync = ((BaseUnityPlugin)this).Config.Bind<bool>("Features", "EnableLiveItemSync", true, "Immediately syncs newly acquired player items to active Pylon, clones, and summoned Survivor.");
		}

		private void LoadAddressableAssets()
		{
			//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_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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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_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)
			try
			{
				SpawnVfxPrefab = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Common/VFX/TeleportOutBoom.prefab").WaitForCompletion();
				HealVfxPrefab = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Common/VFX/HealEffect.prefab").WaitForCompletion();
				BubbleShieldPrefab = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Engi/EngiBubbleShield.prefab").WaitForCompletion();
				MushroomWardPrefab = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Mushroom/MushroomWard.prefab").WaitForCompletion();
				HologramBlueprintMaterial = Addressables.LoadAssetAsync<Material>((object)"RoR2/Base/Common/VFX/matBlueprintsOk.mat").WaitForCompletion();
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Addressables fallback triggered: " + ex.Message));
			}
			if ((Object)(object)SpawnVfxPrefab == (Object)null)
			{
				SpawnVfxPrefab = LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/TeleportOutBoom");
			}
			if ((Object)(object)HealVfxPrefab == (Object)null)
			{
				HealVfxPrefab = LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/HealEffect");
			}
			if ((Object)(object)BubbleShieldPrefab == (Object)null)
			{
				BubbleShieldPrefab = LegacyResourcesAPI.Load<GameObject>("Prefabs/Projectiles/EngiBubbleShield");
			}
			if ((Object)(object)HologramBlueprintMaterial == (Object)null)
			{
				HologramBlueprintMaterial = LegacyResourcesAPI.Load<Material>("Materials/matBlueprintsOk");
			}
		}

		private void RegisterSafeMMHooks()
		{
			//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_001f: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			object obj = <>c.<>9__18_0;
			if (obj == null)
			{
				hook_RecalculateStats val = delegate(orig_RecalculateStats orig, CharacterBody self)
				{
					orig.Invoke(self);
					if ((Object)(object)self != (Object)null && (Object)(object)self.skillLocator != (Object)null && (Object)(object)self.skillLocator.special != (Object)null)
					{
						GenericSkill special = self.skillLocator.special;
						if ((Object)(object)special.skillDef == (Object)(object)PylonSkillDef)
						{
							if (special.maxStock > 1)
							{
								special.SetBonusStockFromBody(0);
							}
							if (special.stock > 1)
							{
								special.stock = 1;
							}
						}
					}
				};
				<>c.<>9__18_0 = val;
				obj = (object)val;
			}
			CharacterBody.RecalculateStats += (hook_RecalculateStats)obj;
			object obj2 = <>c.<>9__18_1;
			if (obj2 == null)
			{
				hook_OnBodyDeath val2 = delegate(orig_OnBodyDeath orig, CharacterMaster self, CharacterBody body)
				{
					BiomassSummonMarker biomassSummonMarker = (((Object)(object)self != (Object)null) ? ((Component)self).GetComponent<BiomassSummonMarker>() : null);
					if ((Object)(object)biomassSummonMarker != (Object)null && (biomassSummonMarker.isCloneUnit || biomassSummonMarker.isGuardTurret || biomassSummonMarker.isSurvivorAlly))
					{
						if ((Object)(object)self.minionOwnership != (Object)null)
						{
							self.minionOwnership.SetOwner((CharacterMaster)null);
						}
						self.teamIndex = (TeamIndex)(-1);
						biomassSummonMarker.pendingSafeDestroy = true;
					}
					orig.Invoke(self, body);
				};
				<>c.<>9__18_1 = val2;
				obj2 = (object)val2;
			}
			CharacterMaster.OnBodyDeath += (hook_OnBodyDeath)obj2;
		}

		public static Vector3 SnapPositionToGround(Vector3 targetPos, float verticalOffset = 0.05f)
		{
			//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_001a: 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_002e: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_006c: 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)
			Ray val = new Ray(targetPos + Vector3.up * 3f, Vector3.down);
			LayerIndex world = LayerIndex.world;
			RaycastHit val2 = default(RaycastHit);
			if (Physics.Raycast(val, ref val2, 18f, LayerMask.op_Implicit(((LayerIndex)(ref world)).mask), (QueryTriggerInteraction)1) && Mathf.Abs(((RaycastHit)(ref val2)).point.y - targetPos.y) <= 8f)
			{
				return ((RaycastHit)(ref val2)).point + Vector3.up * verticalOffset;
			}
			return targetPos + Vector3.up * verticalOffset;
		}

		public static uint ResolveTurretSkinIndexFromOwner(CharacterBody ownerBody)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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_00f8: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ownerBody == (Object)null)
			{
				return 0u;
			}
			uint skinIndex = ownerBody.skinIndex;
			GameObject val = BodyCatalog.FindBodyPrefab("EngiTurretBody");
			if ((Object)(object)val == (Object)null)
			{
				return 0u;
			}
			ModelLocator component = val.GetComponent<ModelLocator>();
			ModelSkinController val2 = (((Object)(object)component != (Object)null && (Object)(object)component.modelTransform != (Object)null) ? ((Component)component.modelTransform).GetComponent<ModelSkinController>() : val.GetComponentInChildren<ModelSkinController>());
			if ((Object)(object)val2 == (Object)null || val2.skins == null || val2.skins.Length == 0)
			{
				return 0u;
			}
			SkinDef bodySkinDef = SkinCatalog.GetBodySkinDef(ownerBody.bodyIndex, (int)skinIndex);
			if ((Object)(object)bodySkinDef != (Object)null && bodySkinDef.minionSkinReplacements != null)
			{
				for (int i = 0; i < bodySkinDef.minionSkinReplacements.Length; i++)
				{
					MinionSkinReplacement val3 = bodySkinDef.minionSkinReplacements[i];
					if (!((Object)(object)val3.minionBodyPrefab != (Object)null) || !((Object)(object)val3.minionSkin != (Object)null) || ((Object)val3.minionBodyPrefab).name.IndexOf("EngiTurret", StringComparison.OrdinalIgnoreCase) < 0)
					{
						continue;
					}
					for (int j = 0; j < val2.skins.Length; j++)
					{
						if ((Object)(object)val2.skins[j] == (Object)(object)val3.minionSkin)
						{
							return (uint)j;
						}
					}
				}
			}
			if (skinIndex < val2.skins.Length)
			{
				return skinIndex;
			}
			return 0u;
		}

		private void BuildTurretHeadOnlyIconFromVanilla()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			//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_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Expected O, but got Unknown
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			int num = 128;
			CustomPylonIconTex = new Texture2D(num, num, (TextureFormat)4, false);
			((Texture)CustomPylonIconTex).filterMode = (FilterMode)1;
			SkillDef val = null;
			try
			{
				val = Addressables.LoadAssetAsync<SkillDef>((object)"RoR2/Base/Engi/EngiBodyPlaceTurret.asset").WaitForCompletion();
			}
			catch
			{
			}
			if ((Object)(object)val == (Object)null)
			{
				val = LegacyResourcesAPI.Load<SkillDef>("SkillDefs/EngiBody/EngiBodyPlaceTurret");
			}
			Texture2D val2 = null;
			Rect textureRect = default(Rect);
			((Rect)(ref textureRect))..ctor(0f, 0f, (float)num, (float)num);
			if ((Object)(object)val != (Object)null && (Object)(object)val.icon != (Object)null && (Object)(object)val.icon.texture != (Object)null)
			{
				Sprite icon = val.icon;
				Texture texture = (Texture)(object)icon.texture;
				RenderTexture temporary = RenderTexture.GetTemporary(texture.width, texture.height, 0, (RenderTextureFormat)7, (RenderTextureReadWrite)1);
				Graphics.Blit(texture, temporary);
				RenderTexture active = RenderTexture.active;
				RenderTexture.active = temporary;
				val2 = new Texture2D(texture.width, texture.height, (TextureFormat)4, false);
				val2.ReadPixels(new Rect(0f, 0f, (float)texture.width, (float)texture.height), 0, 0);
				val2.Apply();
				RenderTexture.active = active;
				RenderTexture.ReleaseTemporary(temporary);
				textureRect = icon.textureRect;
			}
			Color val3 = default(Color);
			((Color)(ref val3))..ctor(0.1f, 0.12f, 0.15f, 1f);
			Color val4 = default(Color);
			((Color)(ref val4))..ctor(0.32f, 0.92f, 0.72f, 1f);
			for (int i = 0; i < num; i++)
			{
				for (int j = 0; j < num; j++)
				{
					if (j < 4 || j >= num - 4 || i < 4 || i >= num - 4)
					{
						CustomPylonIconTex.SetPixel(j, i, val4);
						continue;
					}
					Color val5 = val3;
					if ((Object)(object)val2 != (Object)null)
					{
						float num2 = (float)j / (float)(num - 1);
						float num3 = (float)i / (float)(num - 1);
						if (num2 >= 0.08f && num2 <= 0.92f && num3 >= 0.18f && num3 <= 0.88f)
						{
							float num4 = Mathf.Lerp(0.1f, 0.9f, (num2 - 0.08f) / 0.84f);
							float num5 = Mathf.Lerp(0.48f, 0.93f, (num3 - 0.18f) / 0.7f);
							float num6 = (num2 - 0.5f) * 2f;
							float num7 = (num3 - 0.5f) * 2f;
							if ((!(num3 < 0.32f) || !(Mathf.Abs(num6) > 0.4f)) && num6 * num6 * 0.65f + num7 * num7 * 0.85f <= 1.05f)
							{
								int num8 = Mathf.Clamp(Mathf.RoundToInt(((Rect)(ref textureRect)).x + num4 * ((Rect)(ref textureRect)).width), 0, ((Texture)val2).width - 1);
								int num9 = Mathf.Clamp(Mathf.RoundToInt(((Rect)(ref textureRect)).y + num5 * ((Rect)(ref textureRect)).height), 0, ((Texture)val2).height - 1);
								val5 = val2.GetPixel(num8, num9);
							}
						}
					}
					CustomPylonIconTex.SetPixel(j, i, val5);
				}
			}
			if ((Object)(object)val2 != (Object)null)
			{
				Object.Destroy((Object)(object)val2);
			}
			CustomPylonIconTex.Apply();
			CustomPylonIconSprite = Sprite.Create(CustomPylonIconTex, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f));
			if ((Object)(object)PylonSkillDef != (Object)null)
			{
				PylonSkillDef.icon = CustomPylonIconSprite;
			}
		}

		private void RegisterLanguageTokens()
		{
			Language.onCurrentLanguageChanged += delegate
			{
				Language currentLanguage = Language.currentLanguage;
				if (currentLanguage != null)
				{
					currentLanguage.SetStringByToken("BMQRT_PYLON_NAME", "Constructor Pylon");
				}
				Language currentLanguage2 = Language.currentLanguage;
				if (currentLanguage2 != null)
				{
					currentLanguage2.SetStringByToken("BMQRT_PYLON_DESC", "Deploy a <style=cIsUtility>Constructor Pylon</style> (Max 1) that inherits your items and fabricates enemy clones every <style=cIsUtility>9.5s</style> <style=cStack>(-0.16s per level, base 2 clones)</style>. Levels up to <style=cIsHealing>30</style> via kills, granting <style=cIsUtility>1 Evolution Point</style> every 5 levels.");
				}
			};
		}

		private void CreatePylonSkill()
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			PylonSkillDef = ScriptableObject.CreateInstance<SkillDef>();
			PylonSkillDef.skillName = "ConstructorPylon";
			((Object)PylonSkillDef).name = "ConstructorPylon";
			PylonSkillDef.skillNameToken = "BMQRT_PYLON_NAME";
			PylonSkillDef.skillDescriptionToken = "BMQRT_PYLON_DESC";
			PylonSkillDef.activationState = new SerializableEntityStateType(typeof(PlaceConstructorPylonState));
			PylonSkillDef.activationStateMachineName = "Weapon";
			PylonSkillDef.baseMaxStock = 1;
			PylonSkillDef.baseRechargeInterval = 16f;
			PylonSkillDef.beginSkillCooldownOnSkillEnd = true;
			PylonSkillDef.canceledFromSprinting = false;
			PylonSkillDef.cancelSprintingOnActivation = true;
			PylonSkillDef.fullRestockOnAssign = true;
			PylonSkillDef.interruptPriority = (InterruptPriority)1;
			PylonSkillDef.isCombatSkill = false;
			PylonSkillDef.mustKeyPress = true;
			PylonSkillDef.rechargeStock = 1;
			PylonSkillDef.requiredStock = 1;
			PylonSkillDef.stockToConsume = 1;
			ContentAddition.AddSkillDef(PylonSkillDef);
			bool flag = default(bool);
			ContentAddition.AddEntityState<PlaceConstructorPylonState>(ref flag);
		}

		private void AddSkillToEngineerImmediate()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Expected O, but got Unknown
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = null;
			try
			{
				val = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Engi/EngiBody.prefab").WaitForCompletion();
			}
			catch
			{
			}
			if ((Object)(object)val == (Object)null)
			{
				val = LegacyResourcesAPI.Load<GameObject>("Prefabs/CharacterBodies/EngiBody");
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			SkillLocator component = val.GetComponent<SkillLocator>();
			object obj2;
			if (component == null)
			{
				obj2 = null;
			}
			else
			{
				GenericSkill special = component.special;
				obj2 = ((special != null) ? special.skillFamily : null);
			}
			if (!((Object)obj2 != (Object)null))
			{
				return;
			}
			SkillFamily skillFamily = component.special.skillFamily;
			for (int i = 0; i < skillFamily.variants.Length; i++)
			{
				if ((Object)(object)skillFamily.variants[i].skillDef == (Object)(object)PylonSkillDef)
				{
					return;
				}
			}
			Array.Resize(ref skillFamily.variants, skillFamily.variants.Length + 1);
			Variant[] variants = skillFamily.variants;
			int num = skillFamily.variants.Length - 1;
			Variant val2 = new Variant
			{
				skillDef = PylonSkillDef,
				unlockableDef = null
			};
			((Variant)(ref val2)).viewableNode = new Node(PylonSkillDef.skillNameToken, false, (Node)null);
			variants[num] = val2;
		}
	}
	public class BiomassSummonMarker : MonoBehaviour
	{
		public bool isMainPylon;

		public bool isGuardTurret;

		public bool isCloneUnit;

		public bool isSurvivorAlly;

		public bool pendingSafeDestroy;

		public float maxLifetime;

		public CharacterBody linkedPylonBody;

		private Stage spawnedStageInstance;

		private float aliveGraceTimer;

		private float deathDestroyDelayTimer;

		private bool isPurged;

		public float RemainingLifetime
		{
			get
			{
				if (!(maxLifetime > 0f))
				{
					return 0f;
				}
				return Mathf.Max(0f, maxLifetime - aliveGraceTimer);
			}
		}

		private void Start()
		{
			spawnedStageInstance = Stage.instance;
		}

		private void FixedUpdate()
		{
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Expected O, but got Unknown
			if (!NetworkServer.active || isPurged)
			{
				return;
			}
			aliveGraceTimer += Time.fixedDeltaTime;
			if (pendingSafeDestroy)
			{
				deathDestroyDelayTimer += Time.fixedDeltaTime;
				if (deathDestroyDelayTimer >= 0.25f)
				{
					PurgeSelfFromServer();
				}
				return;
			}
			if ((Object)(object)Stage.instance != (Object)null && (Object)(object)spawnedStageInstance != (Object)null && (Object)(object)Stage.instance != (Object)(object)spawnedStageInstance)
			{
				PurgeSelfFromServer();
				return;
			}
			if (maxLifetime > 0f && aliveGraceTimer >= maxLifetime)
			{
				CharacterMaster component = ((Component)this).GetComponent<CharacterMaster>();
				CharacterBody val = (((Object)(object)component != (Object)null) ? component.GetBody() : null);
				if ((Object)(object)val != (Object)null && (Object)(object)BiomassConstructorPlugin.SpawnVfxPrefab != (Object)null)
				{
					EffectManager.SpawnEffect(BiomassConstructorPlugin.SpawnVfxPrefab, new EffectData
					{
						origin = val.corePosition,
						scale = 2.5f
					}, true);
				}
				PurgeSelfFromServer();
				return;
			}
			if ((isCloneUnit || isGuardTurret || isSurvivorAlly) && aliveGraceTimer > 0.5f)
			{
				CharacterMaster component2 = ((Component)this).GetComponent<CharacterMaster>();
				if ((Object)(object)component2 != (Object)null)
				{
					CharacterBody body = component2.GetBody();
					if ((Object)(object)body == (Object)null || (Object)(object)body.healthComponent == (Object)null || !body.healthComponent.alive)
					{
						PurgeSelfFromServer();
						return;
					}
				}
			}
			if (isGuardTurret && ((Object)(object)linkedPylonBody == (Object)null || (Object)(object)linkedPylonBody.healthComponent == (Object)null || !linkedPylonBody.healthComponent.alive))
			{
				PurgeSelfFromServer();
			}
		}

		public void PurgeSelfFromServer()
		{
			if (isPurged || (Object)(object)this == (Object)null || (Object)(object)((Component)this).gameObject == (Object)null)
			{
				return;
			}
			isPurged = true;
			CharacterMaster component = ((Component)this).GetComponent<CharacterMaster>();
			if ((Object)(object)component != (Object)null)
			{
				if ((Object)(object)component.inventory != (Object)null)
				{
					ConstructorPylonController.StripForbiddenItemsFromInventory(component.inventory);
				}
				if ((Object)(object)component.minionOwnership != (Object)null)
				{
					component.minionOwnership.SetOwner((CharacterMaster)null);
				}
				component.teamIndex = (TeamIndex)(-1);
				CharacterBody body = component.GetBody();
				if ((Object)(object)body != (Object)null && (Object)(object)((Component)body).gameObject != (Object)null)
				{
					if (NetworkServer.active)
					{
						NetworkServer.Destroy(((Component)body).gameObject);
					}
					else
					{
						Object.Destroy((Object)(object)((Component)body).gameObject);
					}
				}
			}
			if (NetworkServer.active)
			{
				NetworkServer.Destroy(((Component)this).gameObject);
			}
			else
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}
	}
	public class PlaceConstructorPylonState : BaseSkillState
	{
		public static CharacterMaster ActivePylonMaster;

		public override void OnEnter()
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			((BaseState)this).OnEnter();
			if ((Object)(object)((EntityState)this).skillLocator != (Object)null && (Object)(object)((EntityState)this).skillLocator.special != (Object)null)
			{
				((EntityState)this).skillLocator.special.SetBonusStockFromBody(0);
				if (((EntityState)this).skillLocator.special.stock > 0)
				{
					((EntityState)this).skillLocator.special.stock = 0;
				}
			}
			if (NetworkServer.active && (Object)(object)((EntityState)this).characterBody != (Object)null)
			{
				Vector3 val = (((Object)(object)((EntityState)this).characterBody.inputBank != (Object)null) ? ((EntityState)this).characterBody.inputBank.aimDirection : ((Component)((EntityState)this).characterBody).transform.forward);
				Vector3 forward = default(Vector3);
				((Vector3)(ref forward))..ctor(val.x, 0f, val.z);
				if (((Vector3)(ref forward)).sqrMagnitude < 0.01f)
				{
					forward = ((Component)((EntityState)this).characterBody).transform.forward;
				}
				((Vector3)(ref forward)).Normalize();
				Vector3 position = BiomassConstructorPlugin.SnapPositionToGround(((EntityState)this).characterBody.footPosition + forward * 3.8f);
				if (!((EntityState)this).characterBody.isPlayerControlled || !((Object)(object)((EntityState)this).characterBody.master != (Object)null) || !((Object)(object)((Component)((EntityState)this).characterBody.master).GetComponent<PlayerCharacterMasterController>() != (Object)null))
				{
					SpawnStandardTurretForAllyEngineer(position);
				}
				else
				{
					if ((Object)(object)ActivePylonMaster != (Object)null)
					{
						BiomassSummonMarker component = ((Component)ActivePylonMaster).GetComponent<BiomassSummonMarker>();
						if ((Object)(object)component != (Object)null)
						{
							component.PurgeSelfFromServer();
						}
						else
						{
							if ((Object)(object)ActivePylonMaster.minionOwnership != (Object)null)
							{
								ActivePylonMaster.minionOwnership.SetOwner((CharacterMaster)null);
							}
							ActivePylonMaster.teamIndex = (TeamIndex)(-1);
							CharacterBody body = ActivePylonMaster.GetBody();
							if ((Object)(object)body != (Object)null)
							{
								NetworkServer.Destroy(((Component)body).gameObject);
							}
							NetworkServer.Destroy(((Component)ActivePylonMaster).gameObject);
						}
						ActivePylonMaster = null;
					}
					SpawnPylonViaMasterSummon(position, ((EntityState)this).characterBody.footPosition);
				}
			}
			((EntityState)this).outer.SetNextStateToMain();
		}

		private void SpawnStandardTurretForAllyEngineer(Vector3 position)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			GameObject masterPrefab = MasterCatalog.GetMasterPrefab(MasterCatalog.FindMasterIndex("EngiTurretMaster"));
			if ((Object)(object)masterPrefab == (Object)null)
			{
				return;
			}
			CharacterMaster val = new MasterSummon
			{
				masterPrefab = masterPrefab,
				position = position,
				rotation = Quaternion.identity,
				summonerBodyObject = ((Component)((EntityState)this).characterBody).gameObject,
				ignoreTeamMemberLimit = true,
				useAmbientLevel = true
			}.Perform();
			if ((Object)(object)val != (Object)null)
			{
				((Component)val).gameObject.AddComponent<BiomassSummonMarker>();
				if ((Object)(object)val.inventory != (Object)null)
				{
					ConstructorPylonController.StripForbiddenItemsFromInventory(val.inventory);
				}
			}
		}

		private void SpawnPylonViaMasterSummon(Vector3 position, Vector3 fallbackFootPosition)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: 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_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			GameObject masterPrefab = MasterCatalog.GetMasterPrefab(MasterCatalog.FindMasterIndex("EngiTurretMaster"));
			if ((Object)(object)masterPrefab == (Object)null)
			{
				return;
			}
			CharacterMaster val = new MasterSummon
			{
				masterPrefab = masterPrefab,
				position = position,
				rotation = Quaternion.identity,
				summonerBodyObject = ((Component)((EntityState)this).characterBody).gameObject,
				ignoreTeamMemberLimit = true,
				useAmbientLevel = true
			}.Perform();
			if (!((Object)(object)val == (Object)null))
			{
				BiomassSummonMarker biomassSummonMarker = ((Component)val).gameObject.AddComponent<BiomassSummonMarker>();
				biomassSummonMarker.isMainPylon = true;
				CharacterMaster master = ((EntityState)this).characterBody.master;
				if ((Object)(object)((master != null) ? master.inventory : null) != (Object)null && (Object)(object)val.inventory != (Object)null)
				{
					ConstructorPylonController.CopySafeCombatItems(val.inventory, ((EntityState)this).characterBody.master.inventory, copyEquipment: true);
				}
				CharacterBody val2 = val.GetBody();
				if ((Object)(object)val2 == (Object)null)
				{
					((Component)val).transform.position = fallbackFootPosition + Vector3.up * 0.25f;
					val2 = val.SpawnBody(((Component)val).transform.position, Quaternion.identity);
				}
				if ((Object)(object)val2 != (Object)null)
				{
					ActivePylonMaster = val;
					ConfigurePylonBody(val2, ((Component)val).gameObject, ((EntityState)this).characterBody.master, ((EntityState)this).characterBody);
				}
				else
				{
					biomassSummonMarker.PurgeSelfFromServer();
				}
			}
		}

		private static void ConfigurePylonBody(CharacterBody turretBody, GameObject turretMasterObj, CharacterMaster ownerMasterRef, CharacterBody ownerBodyRef)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			if ((Object)(object)turretBody == (Object)null)
			{
				return;
			}
			if ((Object)(object)BiomassConstructorPlugin.CustomPylonIconTex != (Object)null)
			{
				turretBody.portraitIcon = (Texture)(object)BiomassConstructorPlugin.CustomPylonIconTex;
			}
			EntityStateMachine val = EntityStateMachine.FindByCustomName(((Component)turretBody).gameObject, "Body");
			if ((Object)(object)val != (Object)null)
			{
				val.initialStateType = new SerializableEntityStateType(typeof(Idle));
				val.SetNextState((EntityState)new Idle());
			}
			SkillLocator component = ((Component)turretBody).GetComponent<SkillLocator>();
			if ((Object)(object)component != (Object)null)
			{
				if (Object.op_Implicit((Object)(object)component.primary))
				{
					((Behaviour)component.primary).enabled = false;
				}
				if (Object.op_Implicit((Object)(object)component.secondary))
				{
					((Behaviour)component.secondary).enabled = false;
				}
				if (Object.op_Implicit((Object)(object)component.special))
				{
					((Behaviour)component.special).enabled = false;
				}
			}
			if ((Object)(object)turretMasterObj != (Object)null)
			{
				BaseAI component2 = turretMasterObj.GetComponent<BaseAI>();
				if ((Object)(object)component2 != (Object)null)
				{
					((Behaviour)component2).enabled = false;
				}
				AISkillDriver[] components = turretMasterObj.GetComponents<AISkillDriver>();
				foreach (AISkillDriver val2 in components)
				{
					if ((Object)(object)val2 != (Object)null)
					{
						((Behaviour)val2).enabled = false;
					}
				}
			}
			ConstructorPylonController constructorPylonController = ((Component)turretBody).GetComponent<ConstructorPylonController>();
			if ((Object)(object)constructorPylonController == (Object)null)
			{
				constructorPylonController = ((Component)turretBody).gameObject.AddComponent<ConstructorPylonController>();
			}
			constructorPylonController.ownerMaster = ownerMasterRef;
			constructorPylonController.ownerBody = ownerBodyRef;
		}

		public override InterruptPriority GetMinimumInterruptPriority()
		{
			return (InterruptPriority)1;
		}
	}
	public class ConstructorPylonController : MonoBehaviour
	{
		public const int MaxPylonLevel = 30;

		public const int MaxPathTier = 5;

		public const float SurvivorAllyLifetimeSeconds = 40f;

		public const float SurvivorAllyCooldownSeconds = 100f;

		public static float SavedBiomass = 0f;

		public static int SavedLevel = 1;

		public static int PendingUpgradePoints = 0;

		public static int PathA_ApexRank = 0;

		public static int PathB_FortressRank = 0;

		public static int PathC_NexusRank = 0;

		public static float SurvivorSummonCooldownTimer = 0f;

		public static CharacterMaster ActiveSurvivorAllyMaster = null;

		public static MasterIndex LastValidMasterIndex = MasterIndex.none;

		public static readonly List<CharacterMaster> ActiveClones = new List<CharacterMaster>();

		public static readonly List<CharacterMaster> ActiveGuardTurrets = new List<CharacterMaster>();

		private static readonly string[] SurvivorMonsterMasterNames = new string[16]
		{
			"CommandoMonsterMaster", "HuntressMonsterMaster", "Bandit2MonsterMaster", "ToolbotMonsterMaster", "EngiMonsterMaster", "MageMonsterMaster", "MercMonsterMaster", "TreebotMonsterMaster", "LoaderMonsterMaster", "CrocoMonsterMaster",
			"CaptainMonsterMaster", "RailgunnerMonsterMaster", "VoidSurvivorMonsterMaster", "SeekerMonsterMaster", "ChefMonsterMaster", "FalseSonMonsterMaster"
		};

		private static readonly string[] IgnoredCloneKeywords = new string[40]
		{
			"VoidInfestor", "UrchinTurret", "AffixEarthHealer", "LynxTotem", "MinorConstructOnKill", "MinorConstructAttachable", "SquidTurret", "BeetleWard", "WispSoul", "Shopkeeper",
			"PotMobile", "ArtifactShell", "Geode", "HealerPod", "GummyClone", "Solus", "SolusWing", "SolusHeart", "Alloyed", "RoboBallBoss",
			"SuperRoboBall", "FalseSon", "Meridian", "VoidRaid", "MiniVoidRaid", "Brother", "TitanGold", "MegaConstruct", "MajorConstruct", "XiConstruct",
			"MagmaWorm", "ElectricWorm", "Grandparent", "Vagrant", "Gravekeeper", "Direseeker", "Battery", "Beacon", "Shrine", "Turret1"
		};

		private static readonly string[] ForbiddenClonedItemNames = new string[16]
		{
			"FreeChest", "TreasureCache", "TreasureCacheVoid", "ExtraLife", "ExtraLifeVoid", "RegeneratingScrap", "RegeneratingScrapConsumed", "ScrapWhite", "ScrapGreen", "ScrapRed",
			"ScrapYellow", "GummyCloneIdentifier", "MinionLeash", "TeleportWhenOob", "CaptainDefenseMatrix", "TeleportOnLowHealth"
		};

		private static bool s_uiTexturesInitialized = false;

		private static Texture2D s_texInspectSlateBg;

		private static Texture2D s_texInspectBorderLight;

		private static Texture2D s_texInspectRecessDark;

		private static Texture2D s_texInspectCardHover;

		private static Texture2D s_texWhiteLine;

		private static Texture2D s_texMutedBorder;

		private static Texture2D s_texGoldBorder;

		private static Texture2D s_texRedRarity;

		private static Texture2D s_texBlueRarity;

		private static Texture2D s_texGreenRarity;

		public CharacterMaster ownerMaster;

		public CharacterBody ownerBody;

		private CharacterBody pylonBody;

		private CharacterBody currentAttackTarget;

		private BodyIndex lastPreviewBodyIndex = (BodyIndex)(-1);

		private SkinnedMeshRenderer nativeTurretSmr;

		private Mesh lastBoundTurretMesh;

		private Material nativeTurretMaterial;

		private Transform turretHeadBone;

		private Transform turretBaseBone;

		private readonly List<Transform> legBonesToCollapse = new List<Transform>();

		private GameObject thrusterEffectHolder;

		private ParticleSystem thrusterJetParticles;

		private Light thrusterFlameLight;

		private Highlight nativePylonHighlight;

		private float headSpinAngle;

		private GameObject targetHologramObj;

		private float hologramSpinAngle;

		private GameObject activeBubbleShieldObj;

		private float shieldRespawnCooldownTimer;

		private GameObject nativeHealingWardIndicatorObj;

		private Light pylonLight;

		private bool isUpgradeWindowOpen;

		private bool isPlayerLookingOrNearPylon;

		private bool isTabKeyHeld;

		private int lastHoveredCard = -1;

		private float lastInteractToggleTime;

		private Transform cachedScoreboardPanel;

		private bool subscribedToInventory;

		private bool guardSkinSyncedOnce;

		private float aliveTime;

		private float scanTimer;

		private float cloneTimer;

		private float healPulseTimer;

		private float cleansePulseTimer;

		private float turretCheckTimer;

		public static void CopySafeCombatItems(Inventory targetInv, Inventory sourceInv, bool copyEquipment)
		{
			if (!((Object)(object)targetInv == (Object)null) && !((Object)(object)sourceInv == (Object)null))
			{
				targetInv.CopyItemsFrom(sourceInv);
				if (copyEquipment)
				{
					targetInv.CopyEquipmentFrom(sourceInv);
				}
				StripForbiddenItemsFromInventory(targetInv);
			}
		}

		public static void StripForbiddenItemsFromInventory(Inventory inv)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Invalid comparison between Unknown and I4
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)inv == (Object)null)
			{
				return;
			}
			for (int i = 0; i < ForbiddenClonedItemNames.Length; i++)
			{
				ItemIndex val = ItemCatalog.FindItemIndex(ForbiddenClonedItemNames[i]);
				if ((int)val != -1)
				{
					int itemCount = inv.GetItemCount(val);
					if (itemCount > 0)
					{
						inv.RemoveItem(val, itemCount);
					}
				}
			}
		}

		public static void StripStageSpawnerItemsFromAllSummons()
		{
			CharacterMaster activePylonMaster = PlaceConstructorPylonState.ActivePylonMaster;
			if ((Object)(object)((activePylonMaster != null) ? activePylonMaster.inventory : null) != (Object)null)
			{
				StripForbiddenItemsFromInventory(PlaceConstructorPylonState.ActivePylonMaster.inventory);
				EnsurePylonExclusiveMicrobots(PlaceConstructorPylonState.ActivePylonMaster.inventory);
			}
			for (int i = 0; i < ActiveClones.Count; i++)
			{
				CharacterMaster obj = ActiveClones[i];
				if ((Object)(object)((obj != null) ? obj.inventory : null) != (Object)null)
				{
					StripForbiddenItemsFromInventory(ActiveClones[i].inventory);
				}
			}
			for (int j = 0; j < ActiveGuardTurrets.Count; j++)
			{
				CharacterMaster obj2 = ActiveGuardTurrets[j];
				if ((Object)(object)((obj2 != null) ? obj2.inventory : null) != (Object)null)
				{
					StripForbiddenItemsFromInventory(ActiveGuardTurrets[j].inventory);
				}
			}
			CharacterMaster activeSurvivorAllyMaster = ActiveSurvivorAllyMaster;
			if ((Object)(object)((activeSurvivorAllyMaster != null) ? activeSurvivorAllyMaster.inventory : null) != (Object)null)
			{
				StripForbiddenItemsFromInventory(ActiveSurvivorAllyMaster.inventory);
			}
		}

		public static void EnsurePylonExclusiveMicrobots(Inventory pylonInventory)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)pylonInventory == (Object)null)
			{
				return;
			}
			ItemIndex val = ItemCatalog.FindItemIndex("CaptainDefenseMatrix");
			if ((int)val == -1)
			{
				return;
			}
			int itemCount = pylonInventory.GetItemCount(val);
			if (PathB_FortressRank >= 5)
			{
				if (itemCount < 1)
				{
					pylonInventory.GiveItem(val, 1 - itemCount);
				}
			}
			else if (itemCount > 0)
			{
				pylonInventory.RemoveItem(val, itemCount);
			}
		}

		public static void ResetSavedProgress()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			SavedBiomass = 0f;
			SavedLevel = 1;
			PendingUpgradePoints = 0;
			PathA_ApexRank = 0;
			PathB_FortressRank = 0;
			PathC_NexusRank = 0;
			SurvivorSummonCooldownTimer = 0f;
			ActiveSurvivorAllyMaster = null;
			LastValidMasterIndex = MasterIndex.none;
			PurgeAllModSummonsGlobal();
		}

		public static void PurgeAllModSummonsGlobal()
		{
			DestroySummonListServer(ActiveGuardTurrets);
			DestroySummonListServer(ActiveClones);
			if ((Object)(object)ActiveSurvivorAllyMaster != (Object)null)
			{
				BiomassSummonMarker component = ((Component)ActiveSurvivorAllyMaster).GetComponent<BiomassSummonMarker>();
				if ((Object)(object)component != (Object)null)
				{
					component.PurgeSelfFromServer();
				}
				else
				{
					if ((Object)(object)ActiveSurvivorAllyMaster.minionOwnership != (Object)null)
					{
						ActiveSurvivorAllyMaster.minionOwnership.SetOwner((CharacterMaster)null);
					}
					ActiveSurvivorAllyMaster.teamIndex = (TeamIndex)(-1);
					CharacterBody body = ActiveSurvivorAllyMaster.GetBody();
					if ((Object)(object)body != (Object)null && NetworkServer.active)
					{
						NetworkServer.Destroy(((Component)body).gameObject);
					}
					if (NetworkServer.active)
					{
						NetworkServer.Destroy(((Component)ActiveSurvivorAllyMaster).gameObject);
					}
				}
				ActiveSurvivorAllyMaster = null;
			}
			if ((Object)(object)PlaceConstructorPylonState.ActivePylonMaster != (Object)null)
			{
				BiomassSummonMarker component2 = ((Component)PlaceConstructorPylonState.ActivePylonMaster).GetComponent<BiomassSummonMarker>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.PurgeSelfFromServer();
				}
				else
				{
					if ((Object)(object)PlaceConstructorPylonState.ActivePylonMaster.minionOwnership != (Object)null)
					{
						PlaceConstructorPylonState.ActivePylonMaster.minionOwnership.SetOwner((CharacterMaster)null);
					}
					PlaceConstructorPylonState.ActivePylonMaster.teamIndex = (TeamIndex)(-1);
					CharacterBody body2 = PlaceConstructorPylonState.ActivePylonMaster.GetBody();
					if ((Object)(object)body2 != (Object)null && NetworkServer.active)
					{
						NetworkServer.Destroy(((Component)body2).gameObject);
					}
					if (NetworkServer.active)
					{
						NetworkServer.Destroy(((Component)PlaceConstructorPylonState.ActivePylonMaster).gameObject);
					}
				}
				PlaceConstructorPylonState.ActivePylonMaster = null;
			}
			BiomassSummonMarker[] array = Object.FindObjectsOfType<BiomassSummonMarker>();
			for (int i = 0; i < array.Length; i++)
			{
				if ((Object)(object)array[i] != (Object)null)
				{
					array[i].PurgeSelfFromServer();
				}
			}
		}

		private static void DestroySummonListServer(List<CharacterMaster> list)
		{
			for (int num = list.Count - 1; num >= 0; num--)
			{
				CharacterMaster val = list[num];
				if ((Object)(object)val != (Object)null)
				{
					BiomassSummonMarker component = ((Component)val).GetComponent<BiomassSummonMarker>();
					if ((Object)(object)component != (Object)null)
					{
						component.PurgeSelfFromServer();
					}
					else
					{
						if ((Object)(object)val.minionOwnership != (Object)null)
						{
							val.minionOwnership.SetOwner((CharacterMaster)null);
						}
						val.teamIndex = (TeamIndex)(-1);
						CharacterBody body = val.GetBody();
						if ((Object)(object)body != (Object)null && NetworkServer.active)
						{
							NetworkServer.Destroy(((Component)body).gameObject);
						}
						if (NetworkServer.active)
						{
							NetworkServer.Destroy(((Component)val).gameObject);
						}
					}
				}
			}
			list.Clear();
		}

		private static void PruneDeadMastersAndDestroyServer(List<CharacterMaster> list)
		{
			for (int num = list.Count - 1; num >= 0; num--)
			{
				CharacterMaster val = list[num];
				if ((Object)(object)val == (Object)null)
				{
					list.RemoveAt(num);
				}
				else
				{
					CharacterBody body = val.GetBody();
					if ((Object)(object)body == (Object)null || (Object)(object)body.healthComponent == (Object)null || !body.healthComponent.alive)
					{
						BiomassSummonMarker component = ((Component)val).GetComponent<BiomassSummonMarker>();
						if ((Object)(object)component != (Object)null)
						{
							if ((Object)(object)val.minionOwnership != (Object)null)
							{
								val.minionOwnership.SetOwner((CharacterMaster)null);
							}
							val.teamIndex = (TeamIndex)(-1);
							component.pendingSafeDestroy = true;
						}
						else
						{
							if ((Object)(object)val.minionOwnership != (Object)null)
							{
								val.minionOwnership.SetOwner((CharacterMaster)null);
							}
							val.teamIndex = (TeamIndex)(-1);
							if ((Object)(object)body != (Object)null && NetworkServer.active)
							{
								NetworkServer.Destroy(((Component)body).gameObject);
							}
							if (NetworkServer.active)
							{
								NetworkServer.Destroy(((Component)val).gameObject);
							}
						}
						list.RemoveAt(num);
					}
				}
			}
		}

		public static int GetRequiredBiomassForNextLevel(int currentLevel)
		{
			if (currentLevel >= 30)
			{
				return 999999;
			}
			return 6 + currentLevel * 5 + currentLevel * currentLevel / 2;
		}

		public static int GetMaxCloneCapacity()
		{
			int num = ((BiomassConstructorPlugin.CfgBaseCloneCapacity != null) ? BiomassConstructorPlugin.CfgBaseCloneCapacity.Value : 2) + SavedLevel / 6;
			int num2 = ((PathA_ApexRank >= 3) ? 1 : 0);
			return Mathf.Max(1, num + num2);
		}

		public static float GetCloneInterval()
		{
			float num = ((BiomassConstructorPlugin.CfgBaseCloneInterval != null) ? BiomassConstructorPlugin.CfgBaseCloneInterval.Value : 9.5f) - (float)(SavedLevel - 1) * 0.16f;
			if (PathA_ApexRank >= 4)
			{
				num -= 0.8f;
			}
			return Mathf.Max(3.2f, num);
		}

		public static float GetEliteSpawnChance()
		{
			return PathA_ApexRank switch
			{
				2 => 0.06f, 
				3 => 0.12f, 
				4 => 0.18f, 
				5 => 0.25f, 
				_ => 0f, 
			};
		}

		public static int GetTargetGuardTurretCount()
		{
			if (PathB_FortressRank >= 4)
			{
				return 4;
			}
			if (PathB_FortressRank >= 2)
			{
				return 2;
			}
			return 0;
		}

		public static float GetHealRadius()
		{
			if (PathC_NexusRank >= 4)
			{
				return 28f;
			}
			if (PathC_NexusRank >= 3)
			{
				return 24f;
			}
			if (PathC_NexusRank >= 2)
			{
				return 18f;
			}
			return 0f;
		}

		private void Start()
		{
			pylonBody = ((Component)this).GetComponent<CharacterBody>();
			GlobalEventManager.onCharacterDeathGlobal += OnCharacterDeathGlobal;
			if ((Object)(object)BiomassConstructorPlugin.CustomPylonIconTex != (Object)null && (Object)(object)pylonBody != (Object)null)
			{
				pylonBody.portraitIcon = (Texture)(object)BiomassConstructorPlugin.CustomPylonIconTex;
			}
			if ((Object)(object)ownerMaster != (Object)null && (Object)(object)ownerMaster.inventory != (Object)null && (BiomassConstructorPlugin.CfgEnableLiveItemSync == null || BiomassConstructorPlugin.CfgEnableLiveItemSync.Value))
			{
				ownerMaster.inventory.onInventoryChanged += OnOwnerInventoryChanged;
				subscribedToInventory = true;
			}
			cloneTimer = Mathf.Max(0f, GetCloneInterval() - 3f);
			EnsureStaticUiTextures();
			SetupLeglessTurretHeadWithThrusterRig();
			ApplyLevelAndPathStats();
			RecallAndRebindExistingClonesToNewPylon();
			UpdateHudDisplay();
		}

		private void OnDestroy()
		{
			GlobalEventManager.onCharacterDeathGlobal -= OnCharacterDeathGlobal;
			if (subscribedToInventory && (Object)(object)ownerMaster != (Object)null && (Object)(object)ownerMaster.inventory != (Object)null)
			{
				ownerMaster.inventory.onInventoryChanged -= OnOwnerInventoryChanged;
			}
			isUpgradeWindowOpen = false;
			DestroyBubbleShield();
			if ((Object)(object)nativeHealingWardIndicatorObj != (Object)null)
			{
				Object.Destroy((Object)(object)nativeHealingWardIndicatorObj);
			}
			DestroySummonListServer(ActiveGuardTurrets);
		}

		private void DestroyBubbleShield()
		{
			if ((Object)(object)activeBubbleShieldObj != (Object)null)
			{
				if (NetworkServer.active)
				{
					NetworkServer.Destroy(activeBubbleShieldObj);
				}
				else
				{
					Object.Destroy((Object)(object)activeBubbleShieldObj);
				}
				activeBubbleShieldObj = null;
			}
		}

		private void OnOwnerInventoryChanged()
		{
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Invalid comparison between Unknown and I4
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active)
			{
				return;
			}
			CharacterMaster obj = ownerMaster;
			if ((Object)(object)((obj != null) ? obj.inventory : null) == (Object)null)
			{
				return;
			}
			if ((Object)(object)pylonBody != (Object)null && (Object)(object)pylonBody.master != (Object)null && (Object)(object)pylonBody.master.inventory != (Object)null)
			{
				CopySafeCombatItems(pylonBody.master.inventory, ownerMaster.inventory, copyEquipment: true);
				EnsurePylonExclusiveMicrobots(pylonBody.master.inventory);
			}
			for (int i = 0; i < ActiveClones.Count; i++)
			{
				CharacterMaster val = ActiveClones[i];
				if ((Object)(object)val != (Object)null && (Object)(object)val.inventory != (Object)null)
				{
					EquipmentIndex currentEquipmentIndex = val.inventory.currentEquipmentIndex;
					CopySafeCombatItems(val.inventory, ownerMaster.inventory, copyEquipment: false);
					if ((int)currentEquipmentIndex != -1)
					{
						val.inventory.SetEquipmentIndex(currentEquipmentIndex);
					}
					else
					{
						val.inventory.CopyEquipmentFrom(ownerMaster.inventory);
					}
				}
			}
			if ((Object)(object)ActiveSurvivorAllyMaster != (Object)null && (Object)(object)ActiveSurvivorAllyMaster.inventory != (Object)null)
			{
				CopySafeCombatItems(ActiveSurvivorAllyMaster.inventory, ownerMaster.inventory, copyEquipment: true);
			}
		}

		private static void EnsureStaticUiTextures()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			if (!s_uiTexturesInitialized || !((Object)(object)s_texInspectSlateBg != (Object)null))
			{
				s_texInspectSlateBg = MakeStaticSolidTex(new Color(0.24f, 0.28f, 0.33f, 0.96f));
				s_texInspectBorderLight = MakeStaticSolidTex(new Color(0.48f, 0.54f, 0.62f, 0.96f));
				s_texInspectRecessDark = MakeStaticSolidTex(new Color(0.14f, 0.17f, 0.21f, 0.98f));
				s_texInspectCardHover = MakeStaticSolidTex(new Color(0.2f, 0.25f, 0.31f, 0.99f));
				s_texWhiteLine = MakeStaticSolidTex(new Color(0.94f, 0.96f, 0.98f, 0.92f));
				s_texMutedBorder = MakeStaticSolidTex(new Color(0.38f, 0.43f, 0.49f, 0.85f));
				s_texGoldBorder = MakeStaticSolidTex(new Color(0.96f, 0.82f, 0.32f, 0.98f));
				s_texRedRarity = MakeStaticSolidTex(new Color(0.9f, 0.3f, 0.25f, 0.95f));
				s_texBlueRarity = MakeStaticSolidTex(new Color(0.25f, 0.72f, 0.95f, 0.95f));
				s_texGreenRarity = MakeStaticSolidTex(new Color(0.32f, 0.88f, 0.45f, 0.95f));
				s_uiTexturesInitialized = true;
			}
		}

		private static Texture2D MakeStaticSolidTex(Color col)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false)
			{
				hideFlags = (HideFlags)32
			};
			val.SetPixel(0, 0, col);
			val.Apply();
			return val;
		}

		private void SyncSkinMaterialToGuardTurrets()
		{
			if ((Object)(object)nativeTurretSmr != (Object)null && (Object)(object)((Renderer)nativeTurretSmr).sharedMaterial != (Object)null)
			{
				nativeTurretMaterial = ((Renderer)nativeTurretSmr).sharedMaterial;
			}
			if ((Object)(object)nativeTurretMaterial == (Object)null)
			{
				return;
			}
			for (int i = 0; i < ActiveGuardTurrets.Count; i++)
			{
				CharacterMaster obj = ActiveGuardTurrets[i];
				CharacterBody val = ((obj != null) ? obj.GetBody() : null);
				if (!((Object)(object)val != (Object)null))
				{
					continue;
				}
				ModelLocator modelLocator = val.modelLocator;
				if (!((Object)(object)((modelLocator != null) ? modelLocator.modelTransform : null) != (Object)null))
				{
					continue;
				}
				SkinnedMeshRenderer[] componentsInChildren = ((Component)val.modelLocator.modelTransform).GetComponentsInChildren<SkinnedMeshRenderer>(true);
				foreach (SkinnedMeshRenderer val2 in componentsInChildren)
				{
					if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).GetComponentInParent<ItemDisplay>() == (Object)null)
					{
						((Renderer)val2).sharedMaterial = nativeTurretMaterial;
					}
				}
			}
		}

		private void SetupLeglessTurretHeadWithThrusterRig()
		{
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ec: Expected O, but got Unknown
			//IL_031d: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: Expected O, but got Unknown
			//IL_0361: 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_039e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0414: Unknown result type (might be due to invalid IL or missing references)
			//IL_0419: Unknown result type (might be due to invalid IL or missing references)
			//IL_0422: Unknown result type (might be due to invalid IL or missing references)
			//IL_0432: Unknown result type (might be due to invalid IL or missing references)
			//IL_0437: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0534: Unknown result type (might be due to invalid IL or missing references)
			//IL_053b: Expected O, but got Unknown
			//IL_0564: Unknown result type (might be due to invalid IL or missing references)
			//IL_059c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0487: Unknown result type (might be due to invalid IL or missing references)
			//IL_048e: Expected O, but got Unknown
			//IL_04bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f4: Unknown result type (might be due to invalid IL or missing references)
			CharacterBody obj = pylonBody;
			object obj2;
			if (obj == null)
			{
				obj2 = null;
			}
			else
			{
				ModelLocator modelLocator = obj.modelLocator;
				obj2 = ((modelLocator != null) ? modelLocator.modelTransform : null);
			}
			if ((Object)obj2 == (Object)null)
			{
				return;
			}
			Transform modelTransform = pylonBody.modelLocator.modelTransform;
			CharacterModel component = ((Component)modelTransform).GetComponent<CharacterModel>();
			if ((Object)(object)component != (Object)null)
			{
				component.itemDisplayRuleSet = null;
			}
			SkinnedMeshRenderer[] componentsInChildren = ((Component)modelTransform).GetComponentsInChildren<SkinnedMeshRenderer>(true);
			SkinnedMeshRenderer val = null;
			foreach (SkinnedMeshRenderer val2 in componentsInChildren)
			{
				if (!((Object)(object)val2 == (Object)null) && val2.bones != null && !((Object)(object)((Component)val2).GetComponentInParent<ItemDisplay>() != (Object)null) && ((Component)val2).gameObject.activeInHierarchy && (((Object)val2).name.IndexOf("EngiTurret", StringComparison.OrdinalIgnoreCase) >= 0 || val2.bones.Length >= 8))
				{
					val = val2;
					break;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				foreach (SkinnedMeshRenderer val3 in componentsInChildren)
				{
					if ((Object)(object)val3 != (Object)null && (Object)(object)((Component)val3).GetComponentInParent<ItemDisplay>() == (Object)null && val3.bones != null && val3.bones.Length >= 8)
					{
						val = val3;
						break;
					}
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				nativeTurretSmr = val;
				lastBoundTurretMesh = nativeTurretSmr.sharedMesh;
				nativeTurretSmr.updateWhenOffscreen = true;
				((Renderer)nativeTurretSmr).enabled = true;
				nativeTurretMaterial = ((Renderer)nativeTurretSmr).sharedMaterial;
				nativePylonHighlight = ((Component)this).gameObject.GetComponent<Highlight>();
				if ((Object)(object)nativePylonHighlight == (Object)null)
				{
					nativePylonHighlight = ((Component)this).gameObject.AddComponent<Highlight>();
				}
				nativePylonHighlight.targetRenderer = (Renderer)(object)nativeTurretSmr;
				nativePylonHighlight.strength = 1f;
				nativePylonHighlight.highlightColor = (HighlightColor)0;
				turretHeadBone = null;
				turretBaseBone = null;
				Transform[] bones = nativeTurretSmr.bones;
				foreach (Transform val4 in bones)
				{
					if (!((Object)(object)val4 == (Object)null))
					{
						string name = ((Object)val4).name;
						if (string.Equals(name, "Head", StringComparison.OrdinalIgnoreCase) || ((Object)(object)turretHeadBone == (Object)null && name.IndexOf("Head", StringComparison.OrdinalIgnoreCase) >= 0))
						{
							turretHeadBone = val4;
						}
						else if (string.Equals(name, "Base", StringComparison.OrdinalIgnoreCase))
						{
							turretBaseBone = val4;
						}
					}
				}
				if ((Object)(object)turretHeadBone != (Object)null)
				{
					legBonesToCollapse.Clear();
					foreach (Transform val5 in bones)
					{
						if (!((Object)(object)val5 == (Object)null) && !((Object)(object)val5 == (Object)(object)turretHeadBone) && !val5.IsChildOf(turretHeadBone) && !turretHeadBone.IsChildOf(val5))
						{
							legBonesToCollapse.Add(val5);
						}
					}
				}
			}
			if ((Object)(object)thrusterEffectHolder == (Object)null)
			{
				thrusterEffectHolder = new GameObject("HoverThrusterFX");
				thrusterEffectHolder.transform.SetParent(((Component)this).transform, false);
				thrusterEffectHolder.transform.localPosition = new Vector3(0f, 0.34f, 0f);
				GameObject val6 = new GameObject("ThrusterPlasmaParticles");
				val6.transform.SetParent(thrusterEffectHolder.transform, false);
				val6.transform.localPosition = new Vector3(0f, -0.05f, 0f);
				val6.transform.localRotation = Quaternion.Euler(90f, 0f, 0f);
				thrusterJetParticles = val6.AddComponent<ParticleSystem>();
				MainModule main = thrusterJetParticles.main;
				((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(0.25f);
				((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(3.8f);
				((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.28f);
				((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(0.25f, 1f, 0.72f, 0.8f));
				((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1;
				((MainModule)(ref main)).maxParticles = 50;
				EmissionModule emission = thrusterJetParticles.emission;
				((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(38f);
				ShapeModule shape = thrusterJetParticles.shape;
				((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)4;
				((ShapeModule)(ref shape)).angle = 16f;
				((ShapeModule)(ref shape)).radius = 0.15f;
				ParticleSystemRenderer component2 = val6.GetComponent<ParticleSystemRenderer>();
				if ((Object)(object)component2 != (Object)null)
				{
					((Renderer)component2).sharedMaterial = BiomassConstructorPlugin.HologramBlueprintMaterial ?? nativeTurretMaterial;
				}
				GameObject val7 = new GameObject("ThrusterJetGlow");
				val7.transform.SetParent(thrusterEffectHolder.transform, false);
				val7.transform.localPosition = new Vector3(0f, -0.35f, 0f);
				thrusterFlameLight = val7.AddComponent<Light>();
				thrusterFlameLight.type = (LightType)2;
				thrusterFlameLight.color = new Color(0.2f, 1f, 0.65f);
				thrusterFlameLight.range = 6f;
				thrusterFlameLight.intensity = 6f;
			}
			if ((Object)(object)pylonLight == (Object)null)
			{
				GameObject val8 = new GameObject("PylonBioLight");
				val8.transform.SetParent(((Component)this).transform, false);
				val8.transform.localPosition = new Vector3(0f, 1.4f, 0f);
				pylonLight = val8.AddComponent<Light>();
				pylonLight.type = (LightType)2;
				pylonLight.color = new Color(0.15f, 1f, 0.55f);
				pylonLight.range = 13f;
				pylonLight.intensity = 5f;
			}
			UpdateNativeHealingZoneVisual();
			RefreshThrusterDominantColor();
		}

		private void RefreshThrusterDominantColor()
		{
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			Color val = default(Color);
			((Color)(ref val))..ctor(0.2f, 1f, 0.65f);
			if (PathA_ApexRank > PathB_FortressRank && PathA_ApexRank >= PathC_NexusRank && PathA_ApexRank > 0)
			{
				((Color)(ref val))..ctor(1f, 0.38f, 0.22f);
			}
			else if (PathB_FortressRank >= PathA_ApexRank && PathB_FortressRank > PathC_NexusRank && PathB_FortressRank > 0)
			{
				((Color)(ref val))..ctor(0.22f, 0.78f, 1f);
			}
			else if (PathC_NexusRank > 0)
			{
				((Color)(ref val))..ctor(0.25f, 1f, 0.45f);
			}
			if ((Object)(object)thrusterFlameLight != (Object)null)
			{
				thrusterFlameLight.color = val;
			}
			if ((Object)(object)thrusterJetParticles != (Object)null)
			{
				MainModule main = thrusterJetParticles.main;
				((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(val.r, val.g, val.b, 0.8f));
			}
		}

		private void HideAnySpawnedItemDisplaysOnPylon()
		{
			CharacterBody obj = pylonBody;
			object obj2;
			if (obj == null)
			{
				obj2 = null;
			}
			else
			{
				ModelLocator modelLocator = obj.modelLocator;
				obj2 = ((modelLocator != null) ? modelLocator.modelTransform : null);
			}
			if ((Object)obj2 == (Object)null)
			{
				return;
			}
			ItemDisplay[] componentsInChildren = ((Component)pylonBody.modelLocator.modelTransform).GetComponentsInChildren<ItemDisplay>(true);
			foreach (ItemDisplay val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null && ((Component)val).gameObject.activeSelf)
				{
					((Component)val).gameObject.SetActive(false);
				}
			}
		}

		private void UpdateNativeHealingZoneVisual()
		{
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			float healRadius = GetHealRadius();
			if (healRadius <= 0f)
			{
				if ((Object)(object)nativeHealingWardIndicatorObj != (Object)null)
				{
					nativeHealingWardIndicatorObj.SetActive(false);
				}
				return;
			}
			if ((Object)(object)nativeHealingWardIndicatorObj == (Object)null && (Object)(object)BiomassConstructorPlugin.MushroomWardPrefab != (Object)null)
			{
				try
				{
					Transform val = BiomassConstructorPlugin.MushroomWardPrefab.transform.Find("Indicator");
					if ((Object)(object)val != (Object)null)
					{
						nativeHealingWardIndicatorObj = Object.Instantiate<GameObject>(((Component)val).gameObject, ((Component)this).transform);
						((Object)nativeHealingWardIndicatorObj).name = "NativeMushroomWardIndicator";
						nativeHealingWardIndicatorObj.transform.localPosition = Vector3.zero;
						nativeHealingWardIndicatorObj.transform.localRotation = Quaternion.identity;
					}
				}
				catch
				{
				}
			}
			if ((Object)(object)nativeHealingWardIndicatorObj != (Object)null)
			{
				nativeHealingWardIndicatorObj.SetActive(true);
				float num = ((((Component)this).transform.localScale.x > 0.01f) ? (1f / ((Component)this).transform.localScale.x) : 1f);
				nativeHealingWardIndicatorObj.transform.localScale = Vector3.one * (healRadius * num);
			}
		}

		private void UpdateTargetHologram(CharacterBody target)
		{
			//IL_000b: 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_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_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Expected O, but got Unknown
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: 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_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: 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_01ea: 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_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: 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_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)target == (Object)null || (target.bodyIndex == lastPreviewBodyIndex && (Object)(object)targetHologramObj != (Object)null))
			{
				return;
			}
			lastPreviewBodyIndex = target.bodyIndex;
			if ((Object)(object)targetHologramObj != (Object)null)
			{
				Object.Destroy((Object)(object)targetHologramObj);
			}
			ModelLocator component = ((Component)target).GetComponent<ModelLocator>();
			Transform val = (((Object)(object)component != (Object)null && (Object)(object)component.modelTransform != (Object)null) ? component.modelTransform : ((Component)target).transform);
			Mesh val2 = null;
			Material val3 = null;
			SkinnedMeshRenderer componentInChildren = ((Component)val).GetComponentInChildren<SkinnedMeshRenderer>(false);
			if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.sharedMesh != (Object)null)
			{
				val2 = componentInChildren.sharedMesh;
				val3 = ((Renderer)componentInChildren).sharedMaterial;
			}
			else
			{
				MeshFilter componentInChildren2 = ((Component)val).GetComponentInChildren<MeshFilter>(false);
				if ((Object)(object)componentInChildren2 != (Object)null && (Object)(object)componentInChildren2.sharedMesh != (Object)null)
				{
					val2 = componentInChildren2.sharedMesh;
					MeshRenderer component2 = ((Component)componentInChildren2).GetComponent<MeshRenderer>();
					if ((Object)(object)component2 != (Object)null)
					{
						val3 = ((Renderer)component2).sharedMaterial;
					}
				}
			}
			if (!((Object)(object)val2 == (Object)null))
			{
				Material val4 = BiomassConstructorPlugin.HologramBlueprintMaterial ?? val3 ?? nativeTurretMaterial;
				targetHologramObj = new GameObject("TargetClonePreview");
				targetHologramObj.transform.SetParent(((Component)this).transform, false);
				targetHologramObj.transform.localPosition = new Vector3(0f, 1.85f, 0f);
				targetHologramObj.transform.localRotation = Quaternion.Euler(0f, hologramSpinAngle, 0f);
				GameObject val5 = new GameObject("HologramCenteredMesh");
				val5.transform.SetParent(targetHologramObj.transform, false);
				Bounds bounds = val2.bounds;
				Vector3 size = ((Bounds)(ref bounds)).size;
				float num = Mathf.Max(0.5f, ((Vector3)(ref size)).magnitude);
				float num2 = Mathf.Clamp(1.25f / num, 0.12f, 1.35f);
				val5.transform.localScale = Vector3.one * num2;
				Transform transform = val5.transform;
				bounds = val2.bounds;
				transform.localPosition = -((Bounds)(ref bounds)).center * num2;
				val5.transform.localRotation = Quaternion.identity;
				val5.AddComponent<MeshFilter>().sharedMesh = val2;
				MeshRenderer val6 = val5.AddComponent<MeshRenderer>();
				if ((Object)(object)val4 != (Object)null)
				{
					((Renderer)val6).sharedMaterial = val4;
				}
			}
		}

		private void LateUpdate()
		{
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: 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_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: 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_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)turretHeadBone == (Object)null || (Object)(object)nativeTurretSmr == (Object)null || (Object)(object)nativeTurretSmr.sharedMesh != (Object)(object)lastBoundTurretMesh)
			{
				SetupLeglessTurretHeadWithThrusterRig();
			}
			HideAnySpawnedItemDisplaysOnPylon();
			if ((Object)(object)turretHeadBone != (Object)null)
			{
				headSpinAngle += (30f + (float)SavedLevel * 3f + (float)PathA_ApexRank * 8f) * Time.deltaTime;
				float num = Mathf.Sin(Time.time * 2.8f) * 0.08f;
				float num2 = 2.1f + (float)SavedLevel * 0.01f;
				Vector3 position = ((Component)this).transform.position + new Vector3(0f, 0.36f + num, 0f);
				Vector3 position2 = ((Component)this).transform.position + new Vector3(0f, 0.74f + num, 0f);
				Quaternion rotation = Quaternion.Euler(0f, headSpinAngle, 0f);
				if ((Object)(object)turretBaseBone != (Object)null && (Object)(object)turretBaseBone != (Object)(object)turretHeadBone)
				{
					turretBaseBone.position = position;
					turretBaseBone.localScale = Vector3.one;
				}
				if ((Object)(object)thrusterEffectHolder != (Object)null)
				{
					thrusterEffectHolder.transform.position = position;
				}
				if ((Object)(object)thrusterFlameLight != (Object)null)
				{
					thrusterFlameLight.intensity = 5f + Mathf.Sin(Time.time * 18f) * 1.5f;
				}
				turretHeadBone.position = position2;
				turretHeadBone.rotation = rotation;
				turretHeadBone.localScale = Vector3.one * num2;
				for (int i = 0; i < legBonesToCollapse.Count; i++)
				{
					Transform val = legBonesToCollapse[i];
					if ((Object)(object)val != (Object)null)
					{
						val.position = position;
						val.localScale = Vector3.zero;
					}
				}
			}
			if ((Object)(object)targetHologramObj != (Object)null)
			{
				float cloneInterval = GetCloneInterval();
				hologramSpinAngle = (hologramSpinAngle + 75f * Time.deltaTime) % 360f;
				float num3 = 1.85f + Mathf.Sin(Time.time * 3f) * 0.06f;
				targetHologramObj.transform.localPosition = new Vector3(0f, num3, 0f);
				targetHologramObj.transform.localRotation = Quaternion.Euler(0f, hologramSpinAngle, 0f);
				float num4 = Mathf.Clamp01(cloneTimer / cloneInterval);
				float num5 = Mathf.Lerp(0.28f, 0.92f, num4);
				targetHologramObj.transform.localScale = Vector3.one * num5;
			}
			if ((Object)(object)nativePylonHighlight != (Object)null)
			{
				nativePylonHighlight.isOn = isPlayerLookingOrNearPylon || PendingUpgradePoints > 0;
			}
			if (isUpgradeWindowOpen && Time.timeScale > 0.01f)
			{
				Cursor.visible = true;
				Cursor.lockState = (CursorLockMode)0;
			}
		}

		private void RecallAndRebindExistingClonesToNewPylon()
		{
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Expected O, but got Unknown
			if ((Object)(object)pylonBody == (Object)null || (Object)(object)pylonBody.master == (Object)null)
			{
				return;
			}
			PruneDeadMastersAndDestroyServer(ActiveClones);
			int count = ActiveClones.Count;
			Vector3 val2 = default(Vector3);
			for (int i = 0; i < count; i++)
			{
				CharacterMaster val = ActiveClones[i];
				CharacterBody body = val.GetBody();
				if ((Object)(object)val.minionOwnership != (Object)null)
				{
					val.minionOwnership.SetOwner(pylonBody.master);
				}
				BaseAI component = ((Component)val).GetComponent<BaseAI>();
				if ((Object)(object)component != (Object)null && (Object)(object)ownerBody != (Object)null)
				{
					component.leader.gameObject = ((Component)ownerBody).gameObject;
				}
				if (NetworkServer.active && (Object)(object)body != (Object)null)
				{
					float num = (float)i / (float)Mathf.Max(1, count) * MathF.PI * 2f;
					float num2 = 4.5f + Mathf.Clamp(body.radius * 1.2f, 0f, 6f);
					((Vector3)(ref val2))..ctor(Mathf.Cos(num) * num2, 0f, Mathf.Sin(num) * num2);
					Vector3 val3 = BiomassConstructorPlugin.SnapPositionToGround(((Component)this).transform.position + val2, 1.2f);
					TeleportHelper.TeleportBody(body, val3);
					if ((Object)(object)BiomassConstructorPlugin.SpawnVfxPrefab != (Object)null)
					{
						EffectManager.SpawnEffect(BiomassConstructorPlugin.SpawnVfxPrefab, new EffectData
						{
							origin = val3,
							scale = 2f
						}, true);
					}
				}
			}
			if ((Object)(object)ActiveSurvivorAllyMaster != (Object)null && (Object)(object)ActiveSurvivorAllyMaster.GetBody() != (Object)null)
			{
				if ((Object)(object)ActiveSurvivorAllyMaster.minionOwnership != (Object)null)
				{
					ActiveSurvivorAllyMaster.minionOwnership.SetOwner(pylonBody.master);
				}
				CharacterBody body2 = ActiveSurvivorAllyMaster.GetBody();
				Vector3 val4 = BiomassConstructorPlugin.SnapPositionToGround(((Component)this).transform.position + Vector3.forward * 3.5f, 1.2f);
				TeleportHelper.TeleportBody(body2, val4);
			}
		}

		private void ToggleUpgradeWindow()
		{
			if (!(Time.unscaledTime - lastInteractToggleTime < 0.25f))
			{
				lastInteractToggleTime = Time.unscaledTime;
				isUpgradeWindowOpen = !isUpgradeWindowOpen;
				Util.PlaySound(isUpgradeWindowOpen ? "Play_UI_obj_casinoChest_open" : "Play_UI_menuClick", ((Component)this).gameObject);
			}
		}

		private void CheckPylonFocusAndInteraction()
		{
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: 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_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			if (Time.timeScale <= 0.01f)
			{
				isUpgradeWindowOpen = false;
				isPlayerLookingOrNearPylon = false;
				return;
			}
			if ((Object)(object)ownerBody == (Object)null)
			{
				foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances)
				{
					if ((Object)(object)instance != (Object)null && (Object)(object)instance.master != (Object)null && (Object)(object)instance.master.GetBody() != (Object)null)
					{
						ownerBody = instance.master.GetBody();
						ownerMaster = instance.master;
						break;
					}
				}
			}
			if ((Object)(object)ownerBody == (Object)null)
			{
				isPlayerLookingOrNearPylon = false;
				return;
			}
			Vector3 val = ((Component)this).transform.position + Vector3.up * 0.85f;
			float num = Vector3.Distance(ownerBody.corePosition, val);
			if (num > 14f)
			{
				isPlayerLookingOrNearPylon = false;
				if (isUpgradeWindowOpen)
				{
					isUpgradeWindowOpen = false;
				}
				return;
			}
			bool flag = false;
			Camera main = Camera.main;
			Vector3 val2;
			if ((Object)(object)main != (Object)null)
			{
				val2 = val - ((Component)main).transform.position;
				Vector3 normalized = ((Vector3)(ref val2)).normalized;
				flag = Vector3.Angle(((Component)main).transform.forward, normalized) <= 36f;
			}
			else if ((Object)(object)ownerBody.inputBank != (Object)null)
			{
				val2 = val - ownerBody.corePosition;
				Vector3 normalized2 = ((Vector3)(ref val2)).normalized;
				flag = Vector3.Angle(ownerBody.inputBank.aimDirection, normalized2) <= 42f;
			}
			isPlayerLookingOrNearPylon = num <= 5.5f || (num <= 13.5f && flag);
			if (PendingUpgradePoints <= 0)
			{
				isUpgradeWindowOpen = false;
			}
			else if (isPlayerLookingOrNearPylon && (Object)(object)ownerBody.inputBank != (Object)null && ((ButtonState)(ref ownerBody.inputBank.interact)).justPressed)
			{
				ToggleUpgradeWindow();
			}
		}

		private void Update()
		{
			//IL_0084: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: 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_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			aliveTime += Time.deltaTime;
			if (!guardSkinSyncedOnce && aliveTime >= 0.35f)
			{
				guardSkinSyncedOnce = true;
				SetupLeglessTurretHeadWithThrusterRig();
				SyncSkinMaterialToGuardTurrets();
				UpdateHudDisplay();
			}
			if ((Object)(object)pylonLight != (Object)null)
			{
				if (PendingUpgradePoints > 0)
				{
					float num = Mathf.PingPong(Time.time * 4f, 1f);
					pylonLight.color = Color.Lerp(new Color(1f, 0.85f, 0.1f), new Color(0f, 1f, 0.9f), num);
					pylonLight.intensity = Mathf.Lerp(7f, 14f, num);
					pylonLight.range = 18f;
				}
				else
				{
					pylonLight.color = (Color)(((Object)(object)thrusterFlameLight != (Object)null) ? thrusterFlameLight.color : new Color(0.15f, 1f, 0.55f));
					pylonLight.intensity = 5f;
					pylonLight.range = 13f;
				}
			}
			CheckPylonFocusAndInteraction();
			if (!NetworkServer.active || (Object)(object)pylonBody == (Object)null || (Object)(object)pylonBody.healthComponent == (Object)null || !pylonBody.healthComponent.alive)
			{
				return;
			}
			if (isUpgradeWindowOpen)
			{
				pylonBody.AddTimedBuff(Buffs.HiddenInvincibility, 0.5f);
				if ((Object)(object)ownerBody != (Object)null)
				{
					ownerBody.AddTimedBuff(Buffs.HiddenInvincibility, 0.5f);
				}
			}
			PruneDeadMastersAndDestroyServer(ActiveClones);
			PruneDeadMastersAndDestroyServer(ActiveGuardTurrets);
			if ((Object)(object)ActiveSurvivorAllyMaster != (Object)null)
			{
				CharacterBody body = ActiveSurvivorAllyMaster.GetBody();
				if ((Object)(object)body == (Object)null || (Object)(object)body.healthComponent == (Object)null || !body.healthComponent.alive)
				{
					ActiveSurvivorAllyMaster = null;
				}
			}
			if (PathA_ApexRank >= 5)
			{
				if (SurvivorSummonCooldownTimer > 0f)
				{
					SurvivorSummonCooldownTimer -= Time.deltaTime;
				}
				if (SurvivorSummonCooldownTimer <= 0f && (Object)(object)ActiveSurvivorAllyMaster == (Object)null)
				{
					SpawnRandomSurvivorAlly();
					SurvivorSummonCooldownTimer = 100f;
				}
			}
			scanTimer += Time.deltaTime;
			if (scanTimer >= 1f)
			{
				scanTimer = 0f;
				FindTargetGlobalAndDirectClones();
				UpdateHudDisplay();
			}
			float cloneInterval = GetCloneInterval();
			int maxCloneCapacity = GetMaxCloneCapacity();
			if (ActiveClones.Count < maxCloneCapacity && ((Object)(object)currentAttackTarget != (Object)null || LastValidMasterIndex != MasterIndex.none))
			{
				cloneTimer += Time.deltaTime;
				if (cloneTimer >= cloneInterval)
				{
					cloneTimer = 0f;
					SpawnClone();
				}
			}
			healPulseTimer += Time.deltaTime;
			if (healPulseTimer >= 1.2f)
			{
				healPulseTimer = 0f;
				if (PathB_FortressRank >= 1)
				{
					pylonBody.healthComponent.HealFraction(0.025f, default(ProcChainMask));
				}
				if (PathC_NexusRank >= 2)
				{
					PulseHealingZone();
				}
			}
			if (PathC_NexusRank >= 5)
			{
				cleansePulseTimer += Time.deltaTime;
				if (cleansePulseTimer >= 3f)
				{
					cleansePulseTimer = 0f;
					PulseCleanseZone();
				}
			}
			if (GetTargetGuardTurretCount() > 0)
			{
				turretCheckTimer += Time.deltaTime;
				if (turretCheckTimer >= 2.5f)
				{
					turretCheckTimer = 0f;
					MaintainGuardTurrets();
				}
			}
			if (PathB_FortressRank < 3)
			{
				return;
			}
			if ((Object)(object)activeBubbleShieldObj == (Object)null)
			{
				shieldRespawnCooldownTimer += Time.deltaTime;
				if (shieldRespawnCooldownTimer >= 2f)
				{
					shieldRespawnCooldownTimer = 0f;
					SpawnInfiniteBubbleShield();
				}
			}
			else
			{
				shieldRespawnCooldownTimer = 0f;
			}
		}

		private void SpawnInfiniteBubbleShield()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)BiomassConstructorPlugin.BubbleShieldPrefab == (Object)null || (Object)(object)pylonBody == (Object)null)
			{
				return;
			}
			activeBubbleShieldObj = Object.Instantiate<GameObject>(BiomassConstructorPlugin.BubbleShieldPrefab, ((Component)this).transform.position, Quaternion.identity);
			activeBubbleShieldObj.transform.SetParent(((Component)this).transform, true);
			ProjectileController component = activeBubbleShieldObj.GetComponent<ProjectileController>();
			if ((Object)(object)component != (Object)null)
			{
				component.owner = ((Component)pylonBody).gameObject;
				component.cannotBeDeleted = true;
			}
			TeamFilter component2 = activeBubbleShieldObj.GetComponent<TeamFilter>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.teamIndex = (TeamIndex)1;
			}
			HurtBox[] componentsInChildren = activeBubbleShieldObj.GetComponentsInChildren<HurtBox>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if ((Object)(object)componentsInChildren[i] != (Object)null)
				{
					componentsInChildren[i].healthComponent = pylonBody.healthComponent;
					componentsInChildren[i].teamIndex = (TeamIndex)1;
				}
			}
			MonoBehaviour[] componentsInChildren2 = activeBubbleShieldObj.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val in componentsInChildren2)
			{
				if (!((Object)(object)val == (Object)null))
				{
					string name = ((object)val).GetType().Name;
					if (name.IndexOf("DestroyOnTimer", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("BeginRapidlyActivatingAndDeactivating", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						((Behaviour)val).enabled = false;
						Object.Destroy((Object)(object)val);
					}
				}
			}
			Transform[] componentsInChildren3 = activeBubbleShieldObj.GetComponentsInChildren<Transform>(true);
			foreach (Transform val2 in componentsInChildren3)
			{
				if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).gameObject != (Object)null)
				{
					((Component)val2).gameObject.SetActive(true);
				}
			}
			NetworkServer.Spawn(activeBubbleShieldObj);
		}

		private void SpawnRandomSurvivorAlly()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: 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_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Expected O, but got Unknown
			List<MasterIndex> list = new List<MasterIndex>();
			for (int i = 0; i < SurvivorMonsterMasterNames.Length; i++)
			{
				MasterIndex val = MasterCatalog.FindMasterIndex(SurvivorMonsterMasterNames[i]);
				if (val != MasterIndex.none)
				{
					list.Add(val);
				}
			}
			if (list.Count == 0)
			{
				return;
			}
			GameObject masterPrefab = MasterCatalog.GetMasterPrefab(list[Random.Range(0, list.Count)]);
			if ((Object)(object)masterPrefab == (Object)null)
			{
				return;
			}
			Vector2 insideUnitCircle = Random.insideUnitCircle;
			Vector2 val2 = ((Vector2)(ref insideUnitCircle)).normalized * 3.5