Decompiled source of DroneAutoRepair v1.1.1

DroneAutoRepair/DroneAutoRepair.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using EntityStates;
using EntityStates.Drone;
using EntityStates.Turret1;
using HG;
using IL;
using IL.RoR2;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using On.RoR2;
using R2API;
using RoR2;
using RoR2.Audio;
using RoR2.Stats;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("DroneAutoRepair")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+9a2470ad51893e2ca38ddaab4e31219b86343cea")]
[assembly: AssemblyProduct("DroneAutoRepair")]
[assembly: AssemblyTitle("DroneAutoRepair")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 DroneAutoRepair
{
	internal class BaseDownedState : BaseState
	{
		private static List<BaseDownedState> instances = new List<BaseDownedState>();

		public static string[] costIngoredStages;

		public static Dictionary<string, float> specificRepairTimes = new Dictionary<string, float>();

		public float repairTime;

		public float healStartTime = 0f;

		public int repairCost = 0;

		public bool costPaid = false;

		public string baseNameToken;

		public override void OnEnter()
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Expected I4, but got Unknown
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Invalid comparison between Unknown and I4
			((BaseState)this).OnEnter();
			instances.Add(this);
			if (Object.op_Implicit((Object)(object)((EntityState)this).characterBody) && Object.op_Implicit((Object)(object)((EntityState)this).characterBody.GetOwnerBody()))
			{
				DroneTechController component = ((Component)((EntityState)this).characterBody.GetOwnerBody()).GetComponent<DroneTechController>();
				if (component != null)
				{
					component.OnBodyDestroyGlobal(((EntityState)this).characterBody);
				}
			}
			((EntityState)this).characterBody.baseRegen = 0f;
			((EntityState)this).characterBody.levelRegen = 0f;
			((EntityState)this).characterBody.regen = 0f;
			((EntityState)this).healthComponent.isRepairing = true;
			DroneDef droneDef = DroneCatalog.GetDroneDef(DroneCatalog.GetDroneIndexFromBodyIndex(((EntityState)this).characterBody.bodyIndex));
			if (Object.op_Implicit((Object)(object)droneDef))
			{
				if (specificRepairTimes.TryGetValue(((Object)droneDef).name, out var value))
				{
					repairTime = value;
				}
				else
				{
					DroneType droneType = droneDef.droneType;
					if (1 == 0)
					{
					}
					int num = (int)droneType switch
					{
						1 => (Plugin.combatRepairTime.Value >= 0) ? Plugin.combatRepairTime.Value : Plugin.baseRepairTime.Value, 
						0 => (Plugin.healingRepairTime.Value >= 0) ? Plugin.healingRepairTime.Value : Plugin.baseRepairTime.Value, 
						2 => (Plugin.utilityRepairTime.Value >= 0) ? Plugin.utilityRepairTime.Value : Plugin.baseRepairTime.Value, 
						_ => Plugin.baseRepairTime.Value, 
					};
					if (1 == 0)
					{
					}
					repairTime = num;
				}
			}
			else
			{
				string name = ((Object)((EntityState)this).characterBody.master.bodyPrefab).name;
				name = ((name.Substring(name.Length - 4, 4) == "Body") ? name.Remove(name.Length - 4) : name);
				if (specificRepairTimes.TryGetValue(name, out var value2))
				{
					repairTime = value2;
				}
				else
				{
					repairTime = Plugin.baseRepairTime.Value;
				}
			}
			if (Plugin.repairingCostsMoney.Value && !costIngoredStages.Contains(Stage.instance.sceneDef.baseSceneName))
			{
				if (Object.op_Implicit((Object)(object)droneDef) && Object.op_Implicit((Object)(object)droneDef.droneBrokenSpawnCard))
				{
					GameObject prefab = droneDef.droneBrokenSpawnCard.prefab;
					PurchaseInteraction val = default(PurchaseInteraction);
					if (prefab.TryGetComponent<PurchaseInteraction>(ref val) && (int)val.costType == 1)
					{
						repairCost = (int)((float)Run.instance.GetDifficultyScaledCost(val.cost) * Plugin.repairCostMult.Value);
					}
				}
			}
			else
			{
				costPaid = true;
			}
			baseNameToken = ((EntityState)this).characterBody.baseNameToken;
			if (!costPaid && repairCost > 0)
			{
				Color val2 = Color32.op_Implicit(CostTypeCatalog.GetCostTypeDef((CostTypeIndex)1).GetCostColor(false));
				string @string = Language.GetString(baseNameToken);
				string text = $"<color=#{ColorUtility.ToHtmlStringRGB(val2)}>${repairCost}</color>";
				((EntityState)this).characterBody.baseNameToken = text ?? "";
			}
		}

		public override void FixedUpdate()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			((EntityState)this).FixedUpdate();
			if (repairCost > 0 && ((EntityState)this).healthComponent.health > 0f && ((EntityState)this).characterBody.baseNameToken != baseNameToken)
			{
				Color val = Color32.op_Implicit(CostTypeCatalog.GetCostTypeDef((CostTypeIndex)1).GetCostColor(false));
				((EntityState)this).characterBody.baseNameToken = baseNameToken;
			}
		}

		public override void OnExit()
		{
			instances.Remove(this);
			((EntityState)this).OnExit();
		}

		public void TryPayCost()
		{
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: 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)
			CharacterBody characterBody = ((EntityState)this).characterBody;
			object obj;
			if (characterBody == null)
			{
				obj = null;
			}
			else
			{
				CharacterMaster master = characterBody.master;
				if (master == null)
				{
					obj = null;
				}
				else
				{
					MinionOwnership minionOwnership = master.minionOwnership;
					obj = ((minionOwnership != null) ? minionOwnership.ownerMaster : null);
				}
			}
			CharacterMaster val = (CharacterMaster)obj;
			Interactor val2 = default(Interactor);
			if (!Object.op_Implicit((Object)(object)val) || !val.hasBody || !((Component)val.GetBody()).TryGetComponent<Interactor>(ref val2))
			{
				return;
			}
			CharacterBody body = val.GetBody();
			int num = TeamManager.AdjustCostForLongstandingSolitude((CostTypeIndex)1, repairCost, body);
			CostTypeDef costTypeDef = CostTypeCatalog.GetCostTypeDef((CostTypeIndex)1);
			if (!costTypeDef.IsAffordable(num, val2))
			{
				return;
			}
			if (repairCost > 0 && body.GetBuffCount(Buffs.FreeUnlocks) > 0)
			{
				body.RemoveBuff(Buffs.FreeUnlocks);
				Util.PlaySound("Play_item_proc_onLevelUpFreeUnlock_activate", ((EntityState)this).gameObject);
				val.trackedFreeUnlocks--;
			}
			PayCostContext val3 = default(PayCostContext);
			DisposableRental<PayCostContext> val4 = ((BasePool<PayCostContext>)(object)PayCostContext.pool).Request(ref val3);
			try
			{
				val3.activator = val2;
				val3.activatorBody = body;
				val3.activatorMaster = val;
				val3.activatorInventory = body.inventory;
				val3.purchasedObject = ((EntityState)this).gameObject;
				val3.costTypeDef = costTypeDef;
				val3.cost = num;
				PayCostResults val5 = default(PayCostResults);
				DisposableRental<PayCostResults> val6 = ((BasePool<PayCostResults>)(object)PayCostResults.pool).Request(ref val5);
				try
				{
					costTypeDef.PayCost(val3, val5);
					string[] source = new string[1] { "totalDronesPurchased" };
					IEnumerable<StatDef> enumerable = ((IEnumerable<string>)source).Select((Func<string, StatDef>)StatDef.Find);
					StatManager.OnPurchase<IEnumerable<StatDef>>(body, (CostTypeIndex)1, enumerable);
				}
				finally
				{
					val6.Dispose();
				}
			}
			finally
			{
				val4.Dispose();
			}
			costPaid = true;
		}

		public void FixedHeal()
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			((EntityState)this).healthComponent.health = Mathf.Max(1f, ((EntityState)this).healthComponent.health);
			((EntityState)this).healthComponent.Heal(((EntityState)this).healthComponent.fullHealth * Mathf.Clamp01((((EntityState)this).fixedAge - healStartTime) / repairTime) - ((EntityState)this).healthComponent.health, default(ProcChainMask), false);
			if (((EntityState)this).fixedAge - healStartTime >= repairTime)
			{
				((EntityState)this).characterBody.master.Respawn(((EntityState)this).characterBody.transform.position, ((EntityState)this).characterBody.transform.rotation, false);
			}
		}

		public static void KillUnboughtDrones()
		{
			if (!NetworkServer.active)
			{
				return;
			}
			foreach (BaseDownedState instance in instances)
			{
				if (!instance.costPaid)
				{
					Plugin.Logger.LogInfo((object)("destroying drone master: " + ((Object)((EntityState)instance).characterBody.masterObject).name));
				}
				instance.Kill();
			}
		}

		public virtual void Kill()
		{
			CharacterMaster master = ((EntityState)this).characterBody.master;
			master.DestroyBody();
			EntityState.Destroy((Object)(object)((Component)master).gameObject);
		}

		public override InterruptPriority GetMinimumInterruptPriority()
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return (InterruptPriority)9;
		}
	}
	internal class DroneDownedState : BaseDownedState
	{
		public class RigidbodyCollisionListener : MonoBehaviour
		{
			public DroneDownedState deathState;

			private void OnCollisionEnter(Collision collision)
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				DroneDownedState droneDownedState = deathState;
				ContactPoint contact = collision.GetContact(0);
				droneDownedState.OnImpactServer(((ContactPoint)(ref contact)).point);
				if (!deathState.exploded)
				{
					deathState.Explode();
					deathState.exploded = true;
				}
			}
		}

		public static GameObject droneExplosion = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Common/VFX/OmniExplosionVFXDroneDeath.prefab").WaitForCompletion();

		public static GameObject megaDroneExplosion = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Common/VFX/OmniExplosionVFXMegaDrone.prefab").WaitForCompletion();

		public GameObject deathExplosionEffect;

		public string initialSoundString = "Play_drone_deathpt1";

		public string deathSoundString = "Play_drone_deathpt2";

		public float deathEffectRadius = 2f;

		public float forceAmount = 30f;

		[SerializeField]
		public float deathDuration = 5f;

		private RigidbodyCollisionListener rigidbodyCollisionListener;

		private bool hasImpacted;

		private Vector3 impactPoint;

		private Quaternion impactRotation;

		public bool exploded;

		private bool isMegaDrone;

		public override void OnEnter()
		{
			//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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Expected O, but got Unknown
			base.OnEnter();
			isMegaDrone = (Object)(object)DroneCatalog.GetDroneDef(DroneCatalog.GetDroneIndexFromBodyIndex(((EntityState)this).characterBody.bodyIndex)) == (Object)(object)DroneDefs.MegaDrone;
			Util.PlaySound(initialSoundString, ((EntityState)this).gameObject);
			if (Object.op_Implicit((Object)(object)((EntityState)this).rigidbodyMotor))
			{
				((Behaviour)((EntityState)this).rigidbodyMotor.forcePID).enabled = false;
			}
			((EntityState)this).rigidbody.useGravity = true;
			((EntityState)this).rigidbody.AddForce(Vector3.up * forceAmount, (ForceMode)0);
			((EntityState)this).rigidbody.collisionDetectionMode = (CollisionDetectionMode)1;
			if (Object.op_Implicit((Object)(object)((EntityState)this).rigidbodyDirection))
			{
				((Behaviour)((EntityState)this).rigidbodyDirection).enabled = false;
			}
			deathExplosionEffect = (isMegaDrone ? megaDroneExplosion : droneExplosion);
			deathEffectRadius = (isMegaDrone ? 6f : 2.5f);
			if (Object.op_Implicit((Object)(object)deathExplosionEffect))
			{
				EffectManager.SpawnEffect(deathExplosionEffect, new EffectData
				{
					origin = ((EntityState)this).characterBody.corePosition,
					scale = ((EntityState)this).characterBody.radius + deathEffectRadius
				}, false);
			}
			if (((EntityState)this).isAuthority)
			{
				rigidbodyCollisionListener = ((EntityState)this).gameObject.AddComponent<RigidbodyCollisionListener>();
				rigidbodyCollisionListener.deathState = this;
			}
		}

		public override void FixedUpdate()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			base.FixedUpdate();
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(((EntityState)this).characterBody.corePosition, Vector3.down, ref val, ((EntityState)this).characterBody.radius + 1f, LayerMask.op_Implicit(((LayerIndex)(ref LayerIndex.world)).mask), (QueryTriggerInteraction)1))
			{
				OnImpactServer(((RaycastHit)(ref val)).point);
				if (!exploded)
				{
					Explode();
					exploded = true;
				}
			}
			if (!NetworkServer.active)
			{
				return;
			}
			if (hasImpacted)
			{
				((EntityState)this).rigidbody.velocity = new Vector3(0f, 0f, 0f);
				((EntityState)this).rigidbody.angularVelocity = new Vector3(0f, 0f, 0f);
				((EntityState)this).rigidbody.position = impactPoint;
				((EntityState)this).rigidbody.rotation = impactRotation;
				if (!costPaid)
				{
					TryPayCost();
				}
				if (costPaid)
				{
					FixedHeal();
				}
			}
			else if (((EntityState)this).fixedAge > deathDuration)
			{
				OnImpactServer(((EntityState)this).rigidbody.position);
			}
		}

		public void Explode()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			if (Object.op_Implicit((Object)(object)deathExplosionEffect))
			{
				EffectManager.SpawnEffect(deathExplosionEffect, new EffectData
				{
					origin = ((EntityState)this).characterBody.corePosition,
					scale = ((EntityState)this).characterBody.radius + deathEffectRadius
				}, false);
			}
			PointSoundManager.EmitSoundLocal((AkEventIdArg)deathSoundString, ((EntityState)this).gameObject.transform.position);
		}

		public virtual void OnImpactServer(Vector3 contactPoint)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: 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)
			if (hasImpacted)
			{
				return;
			}
			hasImpacted = true;
			if (NetworkServer.active)
			{
				impactPoint = contactPoint;
				healStartTime = ((EntityState)this).fixedAge;
				if (Object.op_Implicit((Object)(object)((EntityState)this).characterBody) && Object.op_Implicit((Object)(object)((EntityState)this).characterBody.master) && Object.op_Implicit((Object)(object)((EntityState)this).rigidbodyMotor))
				{
					((EntityState)this).rigidbodyMotor.rigid.useGravity = false;
					((EntityState)this).rigidbodyMotor.rigid.velocity = new Vector3(0f, 0f, 0f);
					((EntityState)this).rigidbodyMotor.rigid.angularVelocity = new Vector3(0f, 0f, 0f);
					((EntityState)this).rigidbodyMotor.rigid.position = impactPoint;
					impactRotation = ((EntityState)this).rigidbodyMotor.rigid.rotation;
					((EntityState)this).rigidbodyMotor.rigid.detectCollisions = false;
				}
			}
		}

		public override void OnExit()
		{
			if (!((EntityState)this).healthComponent.alive)
			{
				Explode();
			}
			if (Object.op_Implicit((Object)(object)rigidbodyCollisionListener))
			{
				EntityState.Destroy((Object)(object)rigidbodyCollisionListener);
			}
			EntityState.Destroy((Object)(object)((Component)((EntityState)this).GetModelTransform()).gameObject);
			base.OnExit();
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("zombieseatflesh7.DroneAutoRepair", "DroneAutoRepair", "1.1.1")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGUID = "zombieseatflesh7.DroneAutoRepair";

		public const string PluginAuthor = "zombieseatflesh7";

		public const string PluginName = "DroneAutoRepair";

		public const string PluginVersion = "1.1.1";

		public static ManualLogSource Logger;

		public static ConfigEntry<float> initialCostMult;

		public static ConfigEntry<bool> repairingCostsMoney;

		public static ConfigEntry<float> repairCostMult;

		public static ConfigEntry<string> repairCostIgnoredStages;

		public static ConfigEntry<int> baseRepairTime;

		public static ConfigEntry<int> combatRepairTime;

		public static ConfigEntry<int> healingRepairTime;

		public static ConfigEntry<int> utilityRepairTime;

		public static ConfigEntry<string> overrideRepairTime;

		public static ConfigEntry<string> repairBlacklistConfig;

		public static string[] repairBlacklist;

		public void Awake()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			CharacterDeathBehavior.OnDeath += new hook_OnDeath(On_Death);
			PurchaseInteraction.Awake += new hook_Awake(On_PurchaseInteraction_Awake);
			DroneTechController.GetAllDrones += new Manipulator(IL_GetAllDrones);
			DroneVendorTerminalBehavior.DispatchDrone += new Manipulator(IL_VendorDispatchDrone);
			DroneVendorMultiShopController.Start += new Manipulator(IL_DroneMultishopStart);
			SceneExitController.Begin += new hook_Begin(On_SceneExit_Begin);
			bool flag = default(bool);
			ContentAddition.AddEntityState<DroneDownedState>(ref flag);
			ContentAddition.AddEntityState<TurretDownedState>(ref flag);
			initialCostMult = ((BaseUnityPlugin)this).Config.Bind<float>("Cost", "Drone Purchase Cost Multiplier", 1f, "Multiplier to the cost of purchasing drones for the first time.");
			repairingCostsMoney = ((BaseUnityPlugin)this).Config.Bind<bool>("Cost", "Drone Repair Costs Money", false, "Should drones take money from the owning player to revive themselves? This is automatic, and requires the player to be alive or a remote operated drone. if the player can't afford the fee before the next stage, the drone is destroyed.");
			repairCostMult = ((BaseUnityPlugin)this).Config.Bind<float>("Cost", "Drone Repair Cost Multiplier", 1f, "Multiplier to the cost of repairing drones after they die.");
			repairCostIgnoredStages = ((BaseUnityPlugin)this).Config.Bind<string>("Cost", "Drone Repair Cost Ignored Stages", "goldshores,meridian,solutionalhaunt,computationalexchange,solusweb,moon,moon2,voidraid,limbo", "Stages where repair cost is ignored, usually because it is a boss stage, time doesn't progress, or it is a hidden realm.");
			BaseDownedState.costIngoredStages = repairCostIgnoredStages.Value.Split(',');
			DroneCatalog.SetDroneDefs += new hook_SetDroneDefs(On_SetDroneDefs);
		}

		private void On_Death(orig_OnDeath orig, CharacterDeathBehavior self)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			TeamComponent val = default(TeamComponent);
			CharacterBody val2 = default(CharacterBody);
			if (((Component)self).gameObject.TryGetComponent<TeamComponent>(ref val) && (int)val.teamIndex == 1 && ((Component)self).gameObject.TryGetComponent<CharacterBody>(ref val2) && Object.op_Implicit((Object)(object)val2.master) && !Object.op_Implicit((Object)(object)val2.master.playerCharacterMasterController) && ShouldReviveDrone(val2))
			{
				Type stateType = ((SerializableEntityStateType)(ref self.deathState)).stateType;
				if (stateType == typeof(DeathState) || stateType.IsSubclassOf(typeof(DeathState)) || stateType == typeof(MegaDroneDeathState))
				{
					self.deathState = new SerializableEntityStateType(typeof(DroneDownedState));
					val2.master.destroyOnBodyDeath = false;
				}
				else if (stateType == typeof(DeathState))
				{
					self.deathState = new SerializableEntityStateType(typeof(TurretDownedState));
					val2.master.destroyOnBodyDeath = false;
				}
			}
			orig.Invoke(self);
		}

		private bool ShouldReviveDrone(CharacterBody body)
		{
			//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)
			string name = ((Object)body.master.bodyPrefab).name;
			if (name == "BackupDroneBody")
			{
				return false;
			}
			DroneDef droneDef = DroneCatalog.GetDroneDef(DroneCatalog.GetDroneIndexFromBodyIndex(body.bodyIndex));
			if (Object.op_Implicit((Object)(object)droneDef))
			{
				return !repairBlacklist.Contains(((Object)droneDef).name);
			}
			name = ((name.Substring(name.Length - 4, 4) == "Body") ? name.Remove(name.Length - 4) : name);
			return !repairBlacklist.Contains(name);
		}

		private void IL_GetAllDrones(ILContext il)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			try
			{
				val.GotoNext(new Func<Instruction, bool>[3]
				{
					(Instruction i) => ILPatternMatchingExt.MatchLdloc(i, 2),
					(Instruction i) => ILPatternMatchingExt.MatchCallOrCallvirt<CharacterBody>(i, "get_IsDrone"),
					(Instruction i) => ILPatternMatchingExt.Match(i, OpCodes.Brfalse_S)
				});
				val.Goto(val.Index + 3, (MoveType)0, false);
				object operand = val.Prev.Operand;
				ILLabel val2 = (ILLabel)((operand is ILLabel) ? operand : null);
				val.Emit(OpCodes.Ldloc_2);
				val.EmitDelegate<Func<CharacterBody, bool>>((Func<CharacterBody, bool>)delegate(CharacterBody droneBody)
				{
					CharacterDeathBehavior component = ((Component)droneBody).GetComponent<CharacterDeathBehavior>();
					object obj;
					if (component == null)
					{
						obj = null;
					}
					else
					{
						EntityStateMachine deathStateMachine = component.deathStateMachine;
						obj = ((deathStateMachine != null) ? deathStateMachine.state : null);
					}
					return !(obj is BaseDownedState);
				});
				val.Emit(OpCodes.Brfalse_S, (object)val2);
			}
			catch (Exception ex)
			{
				Logger.LogError((object)ex);
			}
		}

		private void On_PurchaseInteraction_Awake(orig_Awake orig, PurchaseInteraction self)
		{
			orig.Invoke(self);
			SummonMasterBehavior val = default(SummonMasterBehavior);
			bool flag = ((Component)self).gameObject.TryGetComponent<SummonMasterBehavior>(ref val) && ((Object)val.masterPrefab).name == "Turret1Master";
			if (self.isDrone || flag)
			{
				self.Networkcost = (int)Mathf.Floor((float)self.Networkcost * initialCostMult.Value);
			}
		}

		private void IL_VendorDispatchDrone(ILContext il)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			try
			{
				val.GotoNext(new Func<Instruction, bool>[2]
				{
					(Instruction i) => ILPatternMatchingExt.MatchLdloc(i, 2),
					(Instruction i) => ILPatternMatchingExt.MatchCallOrCallvirt<CharacterMaster>(i, "get_inventory")
				});
				val.Emit(OpCodes.Ldloc_2);
				val.EmitDelegate<Action<CharacterMaster>>((Action<CharacterMaster>)delegate(CharacterMaster master)
				{
					//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_0018: Unknown result type (might be due to invalid IL or missing references)
					//IL_001e: Invalid comparison between Unknown and I4
					DroneDef droneDef = DroneCatalog.GetDroneDef(DroneCatalog.GetDroneIndexFromBodyIndex(master.GetBody().bodyIndex));
					if ((int)master.teamIndex == 1 && master.hasBody && Object.op_Implicit((Object)(object)droneDef) && (Object)(object)droneDef != (Object)(object)DroneDefs.EquipmentDrone)
					{
						master.destroyOnBodyDeath = false;
					}
				});
			}
			catch (Exception ex)
			{
				Logger.LogError((object)ex);
			}
		}

		private void IL_DroneMultishopStart(ILContext il)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			ILCursor val = new ILCursor(il);
			try
			{
				val.GotoNext(new Func<Instruction, bool>[1]
				{
					(Instruction i) => ILPatternMatchingExt.MatchCallOrCallvirt<DroneVendorMultiShopController>(i, "set_Networkcost")
				});
				val.EmitDelegate<Func<int, int>>((Func<int, int>)((int cost) => (int)((float)cost * initialCostMult.Value)));
			}
			catch (Exception ex)
			{
				Logger.LogError((object)ex);
			}
		}

		private void On_SceneExit_Begin(orig_Begin orig, SceneExitController self)
		{
			orig.Invoke(self);
			BaseDownedState.KillUnboughtDrones();
		}

		private void On_SetDroneDefs(orig_SetDroneDefs orig, DroneDef[] newDroneDefs)
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Expected I4, but got Unknown
			orig.Invoke(newDroneDefs);
			List<string> list = new List<string>();
			List<string> list2 = new List<string>();
			List<string> list3 = new List<string>();
			List<string> list4 = new List<string>();
			foreach (DroneDef val in newDroneDefs)
			{
				list4.Add("[" + Language.GetString(val.nameToken).Replace(' ', '_') + "](" + ((Object)val).name + ")");
				DroneType droneType = val.droneType;
				DroneType val2 = droneType;
				switch ((int)val2)
				{
				case 1:
					list.Add(Language.GetString(val.nameToken));
					break;
				case 0:
					list2.Add(Language.GetString(val.nameToken));
					break;
				case 2:
					list3.Add(Language.GetString(val.nameToken));
					break;
				}
			}
			list4.Add("[Delighted_Probe](RoboBallGreen)");
			list4.Add("[Quiet_Probe](RoboBallRed)");
			baseRepairTime = ((BaseUnityPlugin)this).Config.Bind<int>("Repair", "Drone Repair Time", 20, "Default drone repair time. How many seconds it takes a drone to repair itself.");
			combatRepairTime = ((BaseUnityPlugin)this).Config.Bind<int>("Repair", "Combat Drone Repair Time", -1, "Repair time for drones with the COMBAT flag. -1 means it uses the DEFAULT value. Change value to 20s to mimic Operator's Gunner Drone Mk.2 (CROSSHAIRS). List of COMBAT Drones: " + string.Join(", ", list));
			healingRepairTime = ((BaseUnityPlugin)this).Config.Bind<int>("Repair", "Healing Drone Repair Time", -1, "Repair time for drones with the HEALING flag. -1 means it uses the DEFAULT value. Change value to 20s to mimic Operator's Healing Drone Mk.2 (DOC). List of HEALING Drones: " + string.Join(", ", list2));
			utilityRepairTime = ((BaseUnityPlugin)this).Config.Bind<int>("Repair", "Utility Drone Repair Time", -1, "Repair time for drones with the UTILITY flag. -1 means it uses the DEFAULT value. Change value to 12s to mimic Operator's Transport Drone Mk.2 (CHIRP). List of UTILITY Drones: " + string.Join(", ", list3));
			overrideRepairTime = ((BaseUnityPlugin)this).Config.Bind<string>("Repair", "Override Repair Time", "Turret1:30,HaulerDrone:12,MegaDrone:90,RoboBallGreen:30,RoboBallRed:30", "Specify repair time for individual drones. Entries should look like this: [DroneName]:[seconds] and be separated with a comma. List of all Drones with their [Display_Name](InternalName): " + string.Join(", ", list4));
			repairBlacklistConfig = ((BaseUnityPlugin)this).Config.Bind<string>("Repair", "Drone Blacklist", "", "Specify drones that should not auto repair. Entries should be separated with a comma. List of all Drones by their internal names: " + string.Join(", ", list4));
			string[] array = overrideRepairTime.Value.Split(",");
			foreach (string text in array)
			{
				try
				{
					string[] array2 = text.Trim().Split(":");
					BaseDownedState.specificRepairTimes.Add(array2[0], int.Parse(array2[1]));
				}
				catch
				{
					Logger.LogError((object)("Failed to parse \"" + text + "\" in the Override Repair Time config"));
				}
			}
			repairBlacklist = repairBlacklistConfig.Value.Split(",");
		}
	}
	internal class TurretDownedState : BaseDownedState
	{
		public GameObject deathExplosion = DroneDownedState.droneExplosion;

		private Transform cachedModelTransform;

		public string initialSoundString = "Play_drone_deathpt1";

		public string deathSoundString = "Play_drone_deathpt2";

		private float deathDuration;

		private bool exploded;

		public override void OnEnter()
		{
			base.OnEnter();
			cachedModelTransform = (Object.op_Implicit((Object)(object)((EntityState)this).modelLocator) ? ((EntityState)this).modelLocator.modelTransform : null);
			Util.PlaySound(initialSoundString, ((EntityState)this).gameObject);
			PlayDeathAnimation();
		}

		protected void PlayDeathAnimation(float crossfadeDuration = 0.1f)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			Animator modelAnimator = ((EntityState)this).GetModelAnimator();
			if (Object.op_Implicit((Object)(object)modelAnimator))
			{
				int layerIndex = modelAnimator.GetLayerIndex("Body");
				modelAnimator.PlayInFixedTime("Death", layerIndex);
				modelAnimator.Update(0f);
				AnimatorStateInfo currentAnimatorStateInfo = modelAnimator.GetCurrentAnimatorStateInfo(layerIndex);
				deathDuration = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).length;
				healStartTime = deathDuration;
			}
		}

		public override void FixedUpdate()
		{
			base.FixedUpdate();
			if (NetworkServer.active && ((EntityState)this).fixedAge > deathDuration)
			{
				if (!exploded)
				{
					exploded = true;
					Explode();
				}
				if (!costPaid)
				{
					TryPayCost();
				}
				if (costPaid)
				{
					FixedHeal();
				}
			}
		}

		public void Explode()
		{
			//IL_0047: 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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			if (Object.op_Implicit((Object)(object)deathExplosion))
			{
				EffectManager.SpawnEffect(deathExplosion, new EffectData
				{
					origin = ((EntityState)this).transform.position,
					scale = 2.5f
				}, true);
			}
			PointSoundManager.EmitSoundLocal((AkEventIdArg)deathSoundString, ((EntityState)this).gameObject.transform.position);
		}

		public override void OnExit()
		{
			if (Object.op_Implicit((Object)(object)cachedModelTransform))
			{
				EntityState.Destroy((Object)(object)((Component)cachedModelTransform).gameObject);
			}
			if (!((EntityState)this).healthComponent.alive)
			{
				Explode();
			}
			base.OnExit();
		}
	}
}