Decompiled source of DroneLogistics v1.1.1

DroneLogistics.dll

Decompiled 5 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("DroneLogistics")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("DroneLogistics")]
[assembly: AssemblyTitle("DroneLogistics")]
[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 DroneLogistics
{
	public class DroneController : MonoBehaviour
	{
		private static int nextDroneId;

		private float speed;

		private int capacity;

		private float range;

		private float chargeRate;

		private float charge = 1f;

		private Vector3 assignedDockingPosition;

		private bool hasDockingAssignment = false;

		private List<CargoData> cargo = new List<CargoData>();

		private Vector3 targetPosition;

		private DeliveryRequest currentDelivery;

		private float hoverHeight = 5f;

		private float arrivalThreshold = 2f;

		private Vector3 smoothVelocity;

		private Light droneLight;

		private ParticleSystem thrusterParticles;

		private float bobOffset;

		private float bobSpeed = 2f;

		private float bobAmount = 0.3f;

		public DroneType DroneType { get; private set; }

		public DronePadController HomePad { get; set; }

		public int DroneId { get; private set; }

		public DroneState State { get; private set; } = DroneState.Idle;


		public bool IsAvailable => State == DroneState.Idle && charge >= 0.2f;

		public float Charge => charge;

		public float ChargePercent => charge * 100f;

		public IReadOnlyList<CargoData> Cargo => cargo;

		public bool HasCargo => cargo.Count > 0;

		public int CargoCount => cargo.Count;

		public Vector3 Velocity { get; private set; }

		public void Initialize(DroneType type, DronePadController pad)
		{
			DroneType = type;
			HomePad = pad;
			DroneId = nextDroneId++;
			switch (type)
			{
			case DroneType.Scout:
				speed = DroneLogisticsPlugin.DroneSpeed.Value * 1.5f;
				capacity = 1;
				range = DroneLogisticsPlugin.DroneRange.Value * 0.5f;
				chargeRate = 1f / (DroneLogisticsPlugin.ChargingTime.Value * 0.5f);
				break;
			case DroneType.Cargo:
				speed = DroneLogisticsPlugin.DroneSpeed.Value;
				capacity = DroneLogisticsPlugin.DroneCapacity.Value;
				range = DroneLogisticsPlugin.DroneRange.Value;
				chargeRate = 1f / DroneLogisticsPlugin.ChargingTime.Value;
				break;
			case DroneType.HeavyLifter:
				speed = DroneLogisticsPlugin.DroneSpeed.Value * 0.6f;
				capacity = DroneLogisticsPlugin.DroneCapacity.Value * 4;
				range = DroneLogisticsPlugin.DroneRange.Value * 1.5f;
				chargeRate = 1f / (DroneLogisticsPlugin.ChargingTime.Value * 2f);
				break;
			case DroneType.Combat:
				speed = DroneLogisticsPlugin.DroneSpeed.Value * 1.2f;
				capacity = 2;
				range = DroneLogisticsPlugin.DroneRange.Value;
				chargeRate = 1f / DroneLogisticsPlugin.ChargingTime.Value;
				break;
			}
			SetupVisuals();
		}

		private void SetupVisuals()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0024: 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_007b: 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_0091: Expected O, but got Unknown
			//IL_00a9: 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_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_00dd: 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_0101: 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_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("DroneLight");
			val.transform.SetParent(((Component)this).transform);
			val.transform.localPosition = Vector3.down * 0.5f;
			droneLight = val.AddComponent<Light>();
			droneLight.type = (LightType)2;
			droneLight.range = 8f;
			droneLight.intensity = 1f;
			droneLight.color = GetDroneColor();
			GameObject val2 = new GameObject("Thrusters");
			val2.transform.SetParent(((Component)this).transform);
			val2.transform.localPosition = Vector3.down * 0.3f;
			thrusterParticles = val2.AddComponent<ParticleSystem>();
			MainModule main = thrusterParticles.main;
			((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(0.3f);
			((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(3f);
			((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.2f);
			((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(0.5f, 0.8f, 1f, 0.5f));
			((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1;
			EmissionModule emission = thrusterParticles.emission;
			((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(20f);
			ShapeModule shape = thrusterParticles.shape;
			((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)4;
			((ShapeModule)(ref shape)).angle = 15f;
			((ShapeModule)(ref shape)).radius = 0.1f;
			ParticleSystemRenderer component = val2.GetComponent<ParticleSystemRenderer>();
			((Renderer)component).material = DroneLogisticsPlugin.GetEffectMaterial(new Color(0.5f, 0.8f, 1f, 0.5f));
		}

		private Color GetDroneColor()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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)
			return (Color)(DroneType switch
			{
				DroneType.Scout => new Color(0.3f, 0.8f, 1f), 
				DroneType.Cargo => new Color(0.3f, 1f, 0.5f), 
				DroneType.HeavyLifter => new Color(1f, 0.8f, 0.3f), 
				DroneType.Combat => new Color(1f, 0.3f, 0.3f), 
				_ => Color.white, 
			});
		}

		private void Update()
		{
			switch (State)
			{
			case DroneState.Idle:
				UpdateIdle();
				break;
			case DroneState.Departing:
				UpdateDeparting();
				break;
			case DroneState.Traveling:
				UpdateTraveling();
				break;
			case DroneState.Loading:
				UpdateLoading();
				break;
			case DroneState.Unloading:
				UpdateUnloading();
				break;
			case DroneState.Returning:
				UpdateReturning();
				break;
			case DroneState.Charging:
				UpdateCharging();
				break;
			}
			UpdateVisuals();
			DrainCharge();
		}

		private void UpdateIdle()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)HomePad != (Object)null)
			{
				Vector3 val = ((Component)HomePad).transform.position + Vector3.up * hoverHeight;
				val.y += Mathf.Sin(Time.time * bobSpeed + bobOffset) * bobAmount;
				((Component)this).transform.position = Vector3.Lerp(((Component)this).transform.position, val, Time.deltaTime * 2f);
			}
			if (charge < 0.3f)
			{
				RequestCharging();
			}
		}

		private void RequestCharging()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)HomePad != (Object)null && HomePad.RequestCharging(this))
			{
				State = DroneState.Charging;
				return;
			}
			DronePadController dronePadController = DroneLogisticsPlugin.FindNearestPad(((Component)this).transform.position);
			if ((Object)(object)dronePadController != (Object)null && dronePadController.RequestCharging(this))
			{
				State = DroneState.Charging;
			}
		}

		private void UpdateDeparting()
		{
			//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_0021: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)this).transform.position;
			position.y = hoverHeight + 2f;
			if (MoveToward(position, speed * 0.5f))
			{
				State = DroneState.Traveling;
			}
		}

		private void UpdateTraveling()
		{
			//IL_0034: 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_0039: 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)
			if (currentDelivery == null)
			{
				State = DroneState.Returning;
				return;
			}
			Vector3 target = (HasCargo ? currentDelivery.DeliveryLocation : currentDelivery.PickupLocation);
			target.y = hoverHeight;
			if (MoveToward(target, speed))
			{
				State = (HasCargo ? DroneState.Unloading : DroneState.Loading);
			}
		}

		private void UpdateLoading()
		{
			//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_001e: Unknown result type (might be due to invalid IL or missing references)
			Vector3 pickupLocation = currentDelivery.PickupLocation;
			pickupLocation.y += 1f;
			if (MoveToward(pickupLocation, speed * 0.3f))
			{
				CargoData cargoData = DroneLogisticsPlugin.PackItems(currentDelivery.Resource, currentDelivery.Quantity);
				cargo.Add(cargoData);
				DroneLogisticsPlugin.Log($"Drone {DroneId} loaded {cargoData.Quantity}x {currentDelivery.Resource.displayName}");
				State = DroneState.Departing;
			}
		}

		private void UpdateUnloading()
		{
			//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_001e: Unknown result type (might be due to invalid IL or missing references)
			Vector3 deliveryLocation = currentDelivery.DeliveryLocation;
			deliveryLocation.y += 1f;
			if (MoveToward(deliveryLocation, speed * 0.3f))
			{
				if (cargo.Count > 0)
				{
					CargoData cargoData = cargo[0];
					cargo.RemoveAt(0);
					DroneLogisticsPlugin.Log($"Drone {DroneId} delivered {cargoData.Quantity}x {currentDelivery.Resource.displayName}");
				}
				currentDelivery = null;
				State = DroneState.Returning;
			}
		}

		private void UpdateReturning()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)HomePad == (Object)null)
			{
				HomePad = DroneLogisticsPlugin.FindNearestPad(((Component)this).transform.position);
				if ((Object)(object)HomePad == (Object)null)
				{
					State = DroneState.Disabled;
					return;
				}
			}
			Vector3 target = ((Component)HomePad).transform.position + Vector3.up * hoverHeight;
			if (MoveToward(target, speed))
			{
				if (charge < 0.5f)
				{
					RequestCharging();
				}
				else
				{
					State = DroneState.Idle;
				}
			}
		}

		private void UpdateCharging()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			Vector3 target;
			if (hasDockingAssignment)
			{
				target = assignedDockingPosition;
			}
			else if ((Object)(object)HomePad != (Object)null)
			{
				target = ((Component)HomePad).transform.position + Vector3.up * (hoverHeight * 0.5f);
				target.x += Mathf.Sin(Time.time + (float)DroneId) * 1.5f;
				target.z += Mathf.Cos(Time.time + (float)DroneId) * 1.5f;
			}
			else
			{
				target = ((Component)this).transform.position;
			}
			MoveToward(target, speed * 0.3f);
		}

		private bool MoveToward(Vector3 target, float moveSpeed)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_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)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: 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_00fd: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = target - ((Component)this).transform.position;
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (magnitude < arrivalThreshold)
			{
				Velocity = Vector3.zero;
				return true;
			}
			Vector3 val2 = ((Vector3)(ref val)).normalized * moveSpeed;
			Velocity = Vector3.SmoothDamp(Velocity, val2, ref smoothVelocity, 0.3f);
			Transform transform = ((Component)this).transform;
			transform.position += Velocity * Time.deltaTime;
			Vector3 velocity = Velocity;
			if (((Vector3)(ref velocity)).sqrMagnitude > 0.1f)
			{
				Vector3 velocity2 = Velocity;
				velocity2.y = 0f;
				if (((Vector3)(ref velocity2)).sqrMagnitude > 0.1f)
				{
					Quaternion val3 = Quaternion.LookRotation(velocity2);
					((Component)this).transform.rotation = Quaternion.Slerp(((Component)this).transform.rotation, val3, Time.deltaTime * 5f);
				}
			}
			return false;
		}

		private void DrainCharge()
		{
			if (State != DroneState.Charging && State != 0)
			{
				float num = 0.01f;
				if (HasCargo)
				{
					num *= 1.5f;
				}
				charge -= num * Time.deltaTime;
				if (charge <= 0f)
				{
					charge = 0f;
					State = DroneState.Disabled;
					DroneLogisticsPlugin.LogWarning($"Drone {DroneId} ran out of charge!");
				}
			}
		}

		public bool AssignDelivery(DeliveryRequest delivery)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			if (!IsAvailable)
			{
				return false;
			}
			float num = Vector3.Distance(((Component)this).transform.position, delivery.PickupLocation);
			float num2 = Vector3.Distance(delivery.PickupLocation, delivery.DeliveryLocation);
			Vector3 deliveryLocation = delivery.DeliveryLocation;
			DronePadController homePad = HomePad;
			float num3 = Vector3.Distance(deliveryLocation, (homePad != null) ? ((Component)homePad).transform.position : ((Component)this).transform.position);
			float num4 = num + num2 + num3;
			if (num4 > range)
			{
				DroneLogisticsPlugin.LogWarning($"Delivery too far for drone {DroneId} ({num4:F0}m > {range:F0}m)");
				return false;
			}
			currentDelivery = delivery;
			State = DroneState.Departing;
			DroneLogisticsPlugin.Log($"Drone {DroneId} assigned delivery: {delivery.Resource.displayName}");
			return true;
		}

		public void RecallToBase()
		{
			if (State != DroneState.Disabled)
			{
				currentDelivery = null;
				cargo.Clear();
				State = DroneState.Returning;
			}
		}

		public void EmergencyStop()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			Velocity = Vector3.zero;
			State = DroneState.Idle;
		}

		public void OnDockingAssigned(Vector3 dockingPosition)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			assignedDockingPosition = dockingPosition;
			hasDockingAssignment = true;
			DroneLogisticsPlugin.Log($"Drone {DroneId} assigned docking position");
		}

		public void AddCharge(float amount)
		{
			charge = Mathf.Clamp01(charge + amount);
		}

		public void OnChargingComplete()
		{
			charge = 1f;
			hasDockingAssignment = false;
			State = DroneState.Idle;
			DroneLogisticsPlugin.Log($"Drone {DroneId} charging complete, returning to idle");
		}

		public void CancelCharging()
		{
			if (State == DroneState.Charging)
			{
				hasDockingAssignment = false;
				HomePad?.CancelCharging(this);
				State = DroneState.Idle;
			}
		}

		private void UpdateVisuals()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: 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_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)droneLight != (Object)null)
			{
				Color droneColor = GetDroneColor();
				switch (State)
				{
				case DroneState.Charging:
					droneLight.color = Color.Lerp(Color.red, droneColor, charge);
					droneLight.intensity = 0.5f + charge * 0.5f;
					break;
				case DroneState.Disabled:
					droneLight.color = Color.red;
					droneLight.intensity = 0.3f;
					break;
				case DroneState.Loading:
				case DroneState.Unloading:
					droneLight.color = Color.yellow;
					droneLight.intensity = 1.5f;
					break;
				default:
					droneLight.color = droneColor;
					droneLight.intensity = 1f;
					break;
				}
			}
			if (!((Object)(object)thrusterParticles != (Object)null))
			{
				return;
			}
			EmissionModule emission = thrusterParticles.emission;
			if (State == DroneState.Charging || State == DroneState.Disabled)
			{
				((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(5f);
				return;
			}
			Vector3 velocity = Velocity;
			if (((Vector3)(ref velocity)).magnitude > 1f)
			{
				velocity = Velocity;
				((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(30f + ((Vector3)(ref velocity)).magnitude * 2f);
			}
			else
			{
				((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(15f);
			}
		}

		private void OnDestroy()
		{
			DroneLogisticsPlugin.ActiveDrones.Remove(this);
		}
	}
	public class DronePadController : MonoBehaviour
	{
		private static int nextPadId;

		private List<DroneController> drones = new List<DroneController>();

		private List<DroneController> chargingDrones = new List<DroneController>();

		private Queue<DroneController> chargingQueue = new Queue<DroneController>();

		private Vector3[] dockingPositions;

		private Queue<DeliveryRequest> requestQueue = new Queue<DeliveryRequest>();

		private Light padLight;

		private LineRenderer rangeIndicator;

		public int PadId { get; private set; }

		public int MaxDrones => DroneLogisticsPlugin.MaxDronesPerPad.Value;

		public DroneRelayType RelayType { get; private set; } = DroneRelayType.Standard;


		public bool RequiresPower { get; set; } = false;


		public int PowerDraw { get; set; } = 50;


		public bool IsPowered { get; private set; } = true;


		public bool IsCharging => chargingDrones.Count > 0 && (IsPowered || !RequiresPower);

		public float ChargeMultiplier
		{
			get
			{
				DroneRelayType relayType = RelayType;
				if (1 == 0)
				{
				}
				float result = relayType switch
				{
					DroneRelayType.FastCharge => 2f, 
					DroneRelayType.DockingBay => 1.5f, 
					_ => 1f, 
				};
				if (1 == 0)
				{
				}
				return result;
			}
		}

		public int MaxChargingSlots
		{
			get
			{
				DroneRelayType relayType = RelayType;
				if (1 == 0)
				{
				}
				int result = relayType switch
				{
					DroneRelayType.DockingBay => 4, 
					DroneRelayType.FastCharge => 2, 
					_ => 1, 
				};
				if (1 == 0)
				{
				}
				return result;
			}
		}

		public IReadOnlyList<DroneController> Drones => drones;

		public int DroneCount => drones.Count;

		public int AvailableDroneCount => drones.FindAll((DroneController d) => (Object)(object)d != (Object)null && d.IsAvailable).Count;

		public int ChargingCount => chargingDrones.Count;

		public int QueuedForCharging => chargingQueue.Count;

		public int QueuedRequests => requestQueue.Count;

		public bool HasChargingCapacity => chargingDrones.Count < MaxChargingSlots || chargingQueue.Count < 10;

		public float EstimatedWaitTime
		{
			get
			{
				if (chargingDrones.Count < MaxChargingSlots)
				{
					return 0f;
				}
				float num = DroneLogisticsPlugin.DroneBatteryCapacity.Value / (DroneLogisticsPlugin.DroneChargeRate.Value * ChargeMultiplier);
				return (float)chargingQueue.Count * num / (float)MaxChargingSlots;
			}
		}

		public void Initialize()
		{
			Initialize(DroneRelayType.Standard);
		}

		public void Initialize(DroneRelayType type)
		{
			PadId = nextPadId++;
			RelayType = type;
			SetupDockingPositions();
			SetupVisuals();
			DroneLogisticsPlugin.Log($"Drone Relay {PadId} ({type}) initialized - {MaxChargingSlots} charging slots");
		}

		private void SetupDockingPositions()
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			int maxChargingSlots = MaxChargingSlots;
			dockingPositions = (Vector3[])(object)new Vector3[maxChargingSlots];
			float num = ((RelayType == DroneRelayType.DockingBay) ? 2f : 1f);
			float num2 = 0.5f;
			for (int i = 0; i < maxChargingSlots; i++)
			{
				float num3 = (float)i * 360f / (float)maxChargingSlots * ((float)Math.PI / 180f);
				dockingPositions[i] = new Vector3(Mathf.Cos(num3) * num, num2, Mathf.Sin(num3) * num);
			}
		}

		private void SetupVisuals()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0024: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("PadLight");
			val.transform.SetParent(((Component)this).transform);
			val.transform.localPosition = Vector3.up * 0.5f;
			padLight = val.AddComponent<Light>();
			padLight.type = (LightType)2;
			padLight.range = 10f;
			padLight.intensity = 2f;
			padLight.color = new Color(0.3f, 0.5f, 1f);
			CreateRangeIndicator();
		}

		private void CreateRangeIndicator()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0024: 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_008e: 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)
			GameObject val = new GameObject("RangeIndicator");
			val.transform.SetParent(((Component)this).transform);
			val.transform.localPosition = Vector3.up * 0.1f;
			rangeIndicator = val.AddComponent<LineRenderer>();
			rangeIndicator.useWorldSpace = false;
			rangeIndicator.startWidth = 0.1f;
			rangeIndicator.endWidth = 0.1f;
			((Renderer)rangeIndicator).material = DroneLogisticsPlugin.GetEffectMaterial(new Color(0.3f, 0.5f, 1f, 0.3f));
			rangeIndicator.loop = true;
			int num = 64;
			rangeIndicator.positionCount = num + 1;
			float value = DroneLogisticsPlugin.DroneRange.Value;
			for (int i = 0; i <= num; i++)
			{
				float num2 = (float)i * (360f / (float)num) * ((float)Math.PI / 180f);
				float num3 = Mathf.Cos(num2) * value;
				float num4 = Mathf.Sin(num2) * value;
				rangeIndicator.SetPosition(i, new Vector3(num3, 0f, num4));
			}
			((Renderer)rangeIndicator).enabled = false;
		}

		private void Update()
		{
			drones.RemoveAll((DroneController d) => (Object)(object)d == (Object)null);
			chargingDrones.RemoveAll((DroneController d) => (Object)(object)d == (Object)null);
			ProcessCharging();
			ProcessQueue();
			UpdateVisuals();
		}

		private void ProcessCharging()
		{
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			if (RequiresPower && !IsPowered)
			{
				return;
			}
			float num = DroneLogisticsPlugin.DroneChargeRate.Value * ChargeMultiplier * Time.deltaTime;
			float value = DroneLogisticsPlugin.DroneBatteryCapacity.Value;
			for (int num2 = chargingDrones.Count - 1; num2 >= 0; num2--)
			{
				DroneController droneController = chargingDrones[num2];
				if ((Object)(object)droneController == (Object)null)
				{
					chargingDrones.RemoveAt(num2);
				}
				else
				{
					droneController.AddCharge(num / value);
					if (droneController.Charge >= 1f)
					{
						droneController.OnChargingComplete();
						chargingDrones.RemoveAt(num2);
						DroneLogisticsPlugin.Log($"Drone {droneController.DroneId} fully charged at Relay {PadId}");
					}
				}
			}
			while (chargingDrones.Count < MaxChargingSlots && chargingQueue.Count > 0)
			{
				DroneController droneController2 = chargingQueue.Dequeue();
				if ((Object)(object)droneController2 != (Object)null)
				{
					int count = chargingDrones.Count;
					chargingDrones.Add(droneController2);
					droneController2.OnDockingAssigned(GetDockingPosition(count));
					DroneLogisticsPlugin.Log($"Drone {droneController2.DroneId} assigned to charging slot {count} at Relay {PadId}");
				}
			}
		}

		public Vector3 GetDockingPosition(int slotIndex)
		{
			//IL_0046: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//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_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			if (dockingPositions == null || slotIndex >= dockingPositions.Length)
			{
				return ((Component)this).transform.position + Vector3.up * 0.5f;
			}
			return ((Component)this).transform.position + dockingPositions[slotIndex];
		}

		private void ProcessQueue()
		{
			while (requestQueue.Count > 0)
			{
				DroneController droneController = drones.Find((DroneController d) => (Object)(object)d != (Object)null && d.IsAvailable);
				if ((Object)(object)droneController == (Object)null)
				{
					break;
				}
				DeliveryRequest delivery = requestQueue.Peek();
				if (droneController.AssignDelivery(delivery))
				{
					requestQueue.Dequeue();
					continue;
				}
				break;
			}
		}

		private void UpdateVisuals()
		{
			//IL_00b8: 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)
			if ((Object)(object)padLight != (Object)null)
			{
				if (drones.Exists((DroneController d) => (Object)(object)d != (Object)null && d.Charge < 1f))
				{
					padLight.intensity = 1.5f + Mathf.Sin(Time.time * 3f) * 0.5f;
					padLight.color = new Color(1f, 0.8f, 0.3f);
				}
				else
				{
					padLight.intensity = 2f;
					padLight.color = new Color(0.3f, 0.5f, 1f);
				}
			}
		}

		public bool RequestCharging(DroneController drone)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)drone == (Object)null)
			{
				return false;
			}
			if (chargingDrones.Contains(drone) || chargingQueue.Contains(drone))
			{
				return true;
			}
			if (chargingDrones.Count < MaxChargingSlots)
			{
				int count = chargingDrones.Count;
				chargingDrones.Add(drone);
				drone.OnDockingAssigned(GetDockingPosition(count));
				DroneLogisticsPlugin.Log($"Drone {drone.DroneId} immediately assigned to charging slot {count}");
				return true;
			}
			chargingQueue.Enqueue(drone);
			DroneLogisticsPlugin.Log($"Drone {drone.DroneId} queued for charging (queue: {chargingQueue.Count})");
			return true;
		}

		public void CancelCharging(DroneController drone)
		{
			if (chargingDrones.Contains(drone))
			{
				chargingDrones.Remove(drone);
			}
			Queue<DroneController> queue = new Queue<DroneController>();
			while (chargingQueue.Count > 0)
			{
				DroneController droneController = chargingQueue.Dequeue();
				if ((Object)(object)droneController != (Object)(object)drone)
				{
					queue.Enqueue(droneController);
				}
			}
			chargingQueue = queue;
		}

		public DroneController SpawnDrone(DroneType type)
		{
			//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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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)
			if (DroneCount >= MaxDrones)
			{
				DroneLogisticsPlugin.LogWarning($"Pad {PadId} at max capacity ({MaxDrones} drones)");
				return null;
			}
			Vector3 val = ((Component)this).transform.position + Vector3.up * 2f;
			val += Random.insideUnitSphere * 1f;
			val.y = ((Component)this).transform.position.y + 2f;
			DroneController droneController = DroneLogisticsPlugin.SpawnDrone(type, val, this);
			if ((Object)(object)droneController != (Object)null)
			{
				drones.Add(droneController);
				DroneLogisticsPlugin.Log($"Pad {PadId} spawned drone (total: {DroneCount})");
			}
			return droneController;
		}

		public void RemoveDrone(DroneController drone)
		{
			if (drones.Contains(drone))
			{
				drones.Remove(drone);
				if ((Object)(object)drone != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)drone).gameObject);
				}
			}
		}

		public void RecallAllDrones()
		{
			foreach (DroneController drone in drones)
			{
				if ((Object)(object)drone != (Object)null)
				{
					drone.RecallToBase();
				}
			}
		}

		public bool RequestDelivery(DeliveryRequest request)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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)
			float num = Vector3.Distance(((Component)this).transform.position, request.PickupLocation);
			float num2 = Vector3.Distance(request.PickupLocation, request.DeliveryLocation);
			if (num > DroneLogisticsPlugin.DroneRange.Value || num2 > DroneLogisticsPlugin.DroneRange.Value)
			{
				return false;
			}
			DroneController droneController = drones.Find((DroneController d) => (Object)(object)d != (Object)null && d.IsAvailable);
			if ((Object)(object)droneController != (Object)null && droneController.AssignDelivery(request))
			{
				return true;
			}
			requestQueue.Enqueue(request);
			DroneLogisticsPlugin.Log($"Pad {PadId} queued delivery (queue: {QueuedRequests})");
			return true;
		}

		public void CancelRequest(DeliveryRequest request)
		{
			List<DeliveryRequest> list = new List<DeliveryRequest>(requestQueue);
			list.Remove(request);
			requestQueue = new Queue<DeliveryRequest>(list);
		}

		public void ClearQueue()
		{
			requestQueue.Clear();
		}

		public void ShowRange(bool show)
		{
			if ((Object)(object)rangeIndicator != (Object)null)
			{
				((Renderer)rangeIndicator).enabled = show;
			}
		}

		public string GetStatusText()
		{
			int availableDroneCount = AvailableDroneCount;
			int count = drones.FindAll((DroneController d) => (Object)(object)d != (Object)null && d.State != 0 && d.State != DroneState.Charging).Count;
			string text = ((!RequiresPower) ? "" : (IsPowered ? "Powered" : "No Power!"));
			string text2 = $"{ChargingCount}/{MaxChargingSlots} charging";
			if (QueuedForCharging > 0)
			{
				text2 += $" (+{QueuedForCharging} queued)";
			}
			return $"Relay {PadId} ({RelayType}): {availableDroneCount}/{DroneCount} available, {count} working, {text2} {text}";
		}

		private void OnDestroy()
		{
			foreach (DroneController drone in drones)
			{
				if ((Object)(object)drone != (Object)null)
				{
					drone.HomePad = null;
					drone.RecallToBase();
				}
			}
			DroneLogisticsPlugin.ActivePads.Remove(this);
		}
	}
	public class PackingStationController : MonoBehaviour
	{
		private static int nextStationId;

		public float PackingTime = 2f;

		public int MaxOutputCrates = 8;

		private float processTimer;

		private Dictionary<ResourceInfo, int> inputBuffer = new Dictionary<ResourceInfo, int>();

		private List<CargoData> outputBuffer = new List<CargoData>();

		private ResourceInfo currentResource;

		private int currentQuantity;

		private Light statusLight;

		public int StationId { get; private set; }

		public bool IsProcessing { get; private set; }

		public bool HasOutput => outputBuffer.Count > 0;

		public int OutputCount => outputBuffer.Count;

		public int InputTypes => inputBuffer.Count;

		private void Awake()
		{
			StationId = nextStationId++;
			SetupVisuals();
		}

		private void SetupVisuals()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0024: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("StatusLight");
			val.transform.SetParent(((Component)this).transform);
			val.transform.localPosition = Vector3.up * 1.5f;
			statusLight = val.AddComponent<Light>();
			statusLight.type = (LightType)2;
			statusLight.range = 5f;
			statusLight.intensity = 1f;
			statusLight.color = Color.green;
		}

		private void Update()
		{
			if (IsProcessing)
			{
				processTimer -= Time.deltaTime;
				if (processTimer <= 0f)
				{
					FinishPacking();
				}
			}
			else
			{
				TryStartPacking();
			}
			UpdateVisuals();
		}

		private void TryStartPacking()
		{
			if (outputBuffer.Count >= MaxOutputCrates)
			{
				return;
			}
			foreach (KeyValuePair<ResourceInfo, int> item in inputBuffer)
			{
				if (item.Value >= item.Key.maxStackCount)
				{
					StartPacking(item.Key, item.Key.maxStackCount);
					break;
				}
			}
		}

		private void StartPacking(ResourceInfo resource, int quantity)
		{
			currentResource = resource;
			currentQuantity = quantity;
			inputBuffer[resource] -= quantity;
			if (inputBuffer[resource] <= 0)
			{
				inputBuffer.Remove(resource);
			}
			IsProcessing = true;
			processTimer = PackingTime;
			DroneLogisticsPlugin.Log($"Station {StationId} packing {quantity}x {resource.displayName}");
		}

		private void FinishPacking()
		{
			CargoData item = DroneLogisticsPlugin.PackItems(currentResource, currentQuantity);
			outputBuffer.Add(item);
			IsProcessing = false;
			currentResource = null;
			currentQuantity = 0;
			DroneLogisticsPlugin.Log($"Station {StationId} packed cargo ({outputBuffer.Count}/{MaxOutputCrates})");
		}

		public bool AddItems(ResourceInfo resource, int quantity)
		{
			if (!inputBuffer.ContainsKey(resource))
			{
				inputBuffer[resource] = 0;
			}
			inputBuffer[resource] += quantity;
			return true;
		}

		public CargoData TakeCargo()
		{
			if (outputBuffer.Count == 0)
			{
				return null;
			}
			CargoData result = outputBuffer[0];
			outputBuffer.RemoveAt(0);
			return result;
		}

		public int GetInputCount(ResourceInfo resource)
		{
			int value;
			return inputBuffer.TryGetValue(resource, out value) ? value : 0;
		}

		private void UpdateVisuals()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)statusLight == (Object)null))
			{
				if (IsProcessing)
				{
					statusLight.color = Color.yellow;
					statusLight.intensity = 1f + Mathf.Sin(Time.time * 5f) * 0.3f;
				}
				else if (outputBuffer.Count >= MaxOutputCrates)
				{
					statusLight.color = Color.red;
					statusLight.intensity = 1f;
				}
				else if (outputBuffer.Count > 0)
				{
					statusLight.color = Color.green;
					statusLight.intensity = 1f;
				}
				else
				{
					statusLight.color = new Color(0.5f, 0.5f, 0.5f);
					statusLight.intensity = 0.5f;
				}
			}
		}

		private void OnDestroy()
		{
			DroneLogisticsPlugin.ActivePackingStations.Remove(this);
		}
	}
	public class UnpackingStationController : MonoBehaviour
	{
		private static int nextStationId;

		public float UnpackingTime = 1f;

		public int MaxInputCrates = 8;

		private float processTimer;

		private List<CargoData> inputBuffer = new List<CargoData>();

		private Dictionary<ResourceInfo, int> outputBuffer = new Dictionary<ResourceInfo, int>();

		private CargoData currentCargo;

		public int StationId { get; private set; }

		public bool IsProcessing { get; private set; }

		private void Awake()
		{
			StationId = nextStationId++;
		}

		private void Update()
		{
			if (IsProcessing)
			{
				processTimer -= Time.deltaTime;
				if (processTimer <= 0f)
				{
					FinishUnpacking();
				}
			}
			else
			{
				TryStartUnpacking();
			}
		}

		private void TryStartUnpacking()
		{
			if (inputBuffer.Count != 0)
			{
				currentCargo = inputBuffer[0];
				inputBuffer.RemoveAt(0);
				IsProcessing = true;
				processTimer = UnpackingTime;
			}
		}

		private void FinishUnpacking()
		{
			if (currentCargo != null && (Object)(object)currentCargo.ResourceType != (Object)null)
			{
				if (!outputBuffer.ContainsKey(currentCargo.ResourceType))
				{
					outputBuffer[currentCargo.ResourceType] = 0;
				}
				outputBuffer[currentCargo.ResourceType] += currentCargo.Quantity;
			}
			IsProcessing = false;
			currentCargo = null;
		}

		public bool AddCargo(CargoData cargo)
		{
			if (inputBuffer.Count >= MaxInputCrates)
			{
				return false;
			}
			inputBuffer.Add(cargo);
			return true;
		}

		public int TakeItems(ResourceInfo resource, int maxQuantity)
		{
			if (!outputBuffer.TryGetValue(resource, out var value))
			{
				return 0;
			}
			int num = Mathf.Min(value, maxQuantity);
			outputBuffer[resource] -= num;
			if (outputBuffer[resource] <= 0)
			{
				outputBuffer.Remove(resource);
			}
			return num;
		}

		public bool HasResource(ResourceInfo resource)
		{
			return outputBuffer.ContainsKey(resource) && outputBuffer[resource] > 0;
		}

		public int GetAvailable(ResourceInfo resource)
		{
			int value;
			return outputBuffer.TryGetValue(resource, out value) ? value : 0;
		}
	}
	[BepInPlugin("com.certifried.dronelogistics", "DroneLogistics", "1.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class DroneLogisticsPlugin : BaseUnityPlugin
	{
		public const string GUID = "com.certifried.dronelogistics";

		public const string NAME = "DroneLogistics";

		public const string VERSION = "1.1.0";

		private static DroneLogisticsPlugin instance;

		private Harmony harmony;

		public static ConfigEntry<int> MaxDronesPerPad;

		public static ConfigEntry<float> DroneSpeed;

		public static ConfigEntry<float> DroneRange;

		public static ConfigEntry<int> DroneCapacity;

		public static ConfigEntry<bool> UseCargoCrates;

		public static ConfigEntry<float> ChargingTime;

		public static ConfigEntry<bool> EnableBiofuel;

		public static ConfigEntry<int> RelayPowerDraw;

		public static ConfigEntry<float> DroneChargeRate;

		public static ConfigEntry<float> DroneBatteryCapacity;

		private static Dictionary<string, AssetBundle> loadedBundles = new Dictionary<string, AssetBundle>();

		private static Dictionary<string, GameObject> prefabCache = new Dictionary<string, GameObject>();

		public static List<DronePadController> ActivePads = new List<DronePadController>();

		public static List<DroneController> ActiveDrones = new List<DroneController>();

		public static List<PackingStationController> ActivePackingStations = new List<PackingStationController>();

		private static Material cachedMaterial;

		private static Material cachedEffectMaterial;

		public static RouteManager Routes { get; private set; }

		private void Awake()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			instance = this;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"DroneLogistics v1.1.0 loading...");
			InitializeConfig();
			LoadAssetBundles();
			harmony = new Harmony("com.certifried.dronelogistics");
			harmony.PatchAll();
			Routes = new RouteManager();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"DroneLogistics loaded successfully!");
		}

		private void InitializeConfig()
		{
			MaxDronesPerPad = ((BaseUnityPlugin)this).Config.Bind<int>("Drones", "MaxDronesPerPad", 4, "Maximum number of drones that can operate from a single pad");
			DroneSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Drones", "DroneSpeed", 15f, "Base drone flight speed (m/s)");
			DroneRange = ((BaseUnityPlugin)this).Config.Bind<float>("Drones", "DroneRange", 200f, "Maximum drone operating range from pad (meters)");
			DroneCapacity = ((BaseUnityPlugin)this).Config.Bind<int>("Drones", "DroneCapacity", 1, "Number of stacks/crates a drone can carry");
			UseCargoCrates = ((BaseUnityPlugin)this).Config.Bind<bool>("Advanced", "UseCargoCrates", false, "Enable cargo crate system (requires packing stations). When disabled, drones carry items directly.");
			ChargingTime = ((BaseUnityPlugin)this).Config.Bind<float>("Drones", "ChargingTime", 10f, "Time in seconds for a drone to fully recharge");
			EnableBiofuel = ((BaseUnityPlugin)this).Config.Bind<bool>("Advanced", "EnableBiofuel", false, "Enable biofuel-powered drones (requires BioProcessing mod)");
			RelayPowerDraw = ((BaseUnityPlugin)this).Config.Bind<int>("Power", "RelayPowerDraw", 50, "Power draw (kW) when a relay is actively charging drones");
			DroneChargeRate = ((BaseUnityPlugin)this).Config.Bind<float>("Power", "DroneChargeRate", 10f, "Battery charge per second when docked at a powered relay");
			DroneBatteryCapacity = ((BaseUnityPlugin)this).Config.Bind<float>("Power", "DroneBatteryCapacity", 100f, "Maximum battery capacity for drones");
		}

		private void LoadAssetBundles()
		{
			string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "Bundles");
			if (!Directory.Exists(text))
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Bundles folder not found at " + text));
				return;
			}
			string[] array = new string[6] { "drones_voodooplay", "drones_scifi", "drones_simple", "robot_sphere", "scifi_machines", "icons_skymon" };
			string[] array2 = array;
			foreach (string text2 in array2)
			{
				string text3 = Path.Combine(text, text2);
				if (!File.Exists(text3))
				{
					continue;
				}
				try
				{
					AssetBundle val = AssetBundle.LoadFromFile(text3);
					if ((Object)(object)val != (Object)null)
					{
						loadedBundles[text2] = val;
						((BaseUnityPlugin)this).Logger.LogInfo((object)("Loaded bundle: " + text2));
					}
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("Failed to load bundle " + text2 + ": " + ex.Message));
				}
			}
		}

		private void Update()
		{
			ActivePads.RemoveAll((DronePadController p) => (Object)(object)p == (Object)null);
			ActiveDrones.RemoveAll((DroneController d) => (Object)(object)d == (Object)null);
			ActivePackingStations.RemoveAll((PackingStationController s) => (Object)(object)s == (Object)null);
		}

		private void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			foreach (AssetBundle value in loadedBundles.Values)
			{
				if (value != null)
				{
					value.Unload(true);
				}
			}
			loadedBundles.Clear();
		}

		public static GameObject GetPrefab(string bundleName, string prefabName)
		{
			string key = bundleName + "/" + prefabName;
			if (prefabCache.TryGetValue(key, out var value))
			{
				return value;
			}
			if (!loadedBundles.TryGetValue(bundleName, out var value2))
			{
				DroneLogisticsPlugin droneLogisticsPlugin = instance;
				if (droneLogisticsPlugin != null)
				{
					((BaseUnityPlugin)droneLogisticsPlugin).Logger.LogWarning((object)("Bundle not loaded: " + bundleName));
				}
				return null;
			}
			GameObject val = value2.LoadAsset<GameObject>(prefabName);
			if ((Object)(object)val == (Object)null)
			{
				val = value2.LoadAsset<GameObject>(prefabName + ".prefab");
			}
			if ((Object)(object)val == (Object)null)
			{
				string[] allAssetNames = value2.GetAllAssetNames();
				foreach (string text in allAssetNames)
				{
					if (!text.ToLower().Contains(prefabName.ToLower()) || !text.EndsWith(".prefab"))
					{
						continue;
					}
					val = value2.LoadAsset<GameObject>(text);
					if ((Object)(object)val != (Object)null)
					{
						DroneLogisticsPlugin droneLogisticsPlugin2 = instance;
						if (droneLogisticsPlugin2 != null)
						{
							((BaseUnityPlugin)droneLogisticsPlugin2).Logger.LogInfo((object)("Found prefab " + prefabName + " as " + text));
						}
						break;
					}
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				prefabCache[key] = val;
			}
			return val;
		}

		public static void FixPrefabMaterials(GameObject obj)
		{
			//IL_0138: 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_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: 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_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0386: Unknown result type (might be due to invalid IL or missing references)
			//IL_038d: Expected O, but got Unknown
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0521: Unknown result type (might be due to invalid IL or missing references)
			//IL_0523: Unknown result type (might be due to invalid IL or missing references)
			//IL_057f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0587: Unknown result type (might be due to invalid IL or missing references)
			//IL_0589: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)cachedMaterial == (Object)null)
			{
				Renderer[] array = Object.FindObjectsOfType<Renderer>();
				Renderer[] array2 = array;
				foreach (Renderer val in array2)
				{
					if ((Object)(object)val.material != (Object)null && (Object)(object)val.material.shader != (Object)null && ((Object)val.material.shader).name.Contains("Universal"))
					{
						cachedMaterial = val.material;
						break;
					}
				}
			}
			if ((Object)(object)cachedMaterial == (Object)null)
			{
				return;
			}
			Renderer[] componentsInChildren = obj.GetComponentsInChildren<Renderer>(true);
			Renderer[] array3 = componentsInChildren;
			foreach (Renderer val2 in array3)
			{
				Material[] materials = val2.materials;
				for (int k = 0; k < materials.Length; k++)
				{
					Material val3 = materials[k];
					if (!((Object)(object)val3 != (Object)null) || !((Object)(object)val3.shader != (Object)null) || ((Object)val3.shader).name.Contains("Universal") || ((Object)val3.shader).name.Contains("URP"))
					{
						continue;
					}
					Color white = Color.white;
					Texture val4 = null;
					Texture val5 = null;
					Texture val6 = null;
					Texture val7 = null;
					Texture val8 = null;
					Color val9 = Color.black;
					float num = 0f;
					float num2 = 0.5f;
					float num3 = 1f;
					white = (val3.HasProperty("_Color") ? val3.GetColor("_Color") : ((!val3.HasProperty("_BaseColor")) ? val3.color : val3.GetColor("_BaseColor")));
					if (val3.HasProperty("_MainTex"))
					{
						val4 = val3.GetTexture("_MainTex");
					}
					else if (val3.HasProperty("_BaseMap"))
					{
						val4 = val3.GetTexture("_BaseMap");
					}
					else if (val3.HasProperty("_Albedo"))
					{
						val4 = val3.GetTexture("_Albedo");
					}
					if (val3.HasProperty("_BumpMap"))
					{
						val5 = val3.GetTexture("_BumpMap");
					}
					else if (val3.HasProperty("_NormalMap"))
					{
						val5 = val3.GetTexture("_NormalMap");
					}
					if (val3.HasProperty("_BumpScale"))
					{
						num3 = val3.GetFloat("_BumpScale");
					}
					if (val3.HasProperty("_MetallicGlossMap"))
					{
						val6 = val3.GetTexture("_MetallicGlossMap");
					}
					else if (val3.HasProperty("_MetallicMap"))
					{
						val6 = val3.GetTexture("_MetallicMap");
					}
					if (val3.HasProperty("_Metallic"))
					{
						num = val3.GetFloat("_Metallic");
					}
					if (val3.HasProperty("_Glossiness"))
					{
						num2 = val3.GetFloat("_Glossiness");
					}
					else if (val3.HasProperty("_Smoothness"))
					{
						num2 = val3.GetFloat("_Smoothness");
					}
					if (val3.HasProperty("_EmissionMap"))
					{
						val7 = val3.GetTexture("_EmissionMap");
					}
					if (val3.HasProperty("_EmissionColor"))
					{
						val9 = val3.GetColor("_EmissionColor");
					}
					if (val3.HasProperty("_OcclusionMap"))
					{
						val8 = val3.GetTexture("_OcclusionMap");
					}
					Material val10 = new Material(cachedMaterial);
					val10.color = white;
					if (val10.HasProperty("_BaseColor"))
					{
						val10.SetColor("_BaseColor", white);
					}
					if (val10.HasProperty("_Color"))
					{
						val10.SetColor("_Color", white);
					}
					if ((Object)(object)val4 != (Object)null)
					{
						if (val10.HasProperty("_MainTex"))
						{
							val10.SetTexture("_MainTex", val4);
						}
						if (val10.HasProperty("_BaseMap"))
						{
							val10.SetTexture("_BaseMap", val4);
						}
					}
					if ((Object)(object)val5 != (Object)null && val10.HasProperty("_BumpMap"))
					{
						val10.SetTexture("_BumpMap", val5);
						val10.SetFloat("_BumpScale", num3);
						val10.EnableKeyword("_NORMALMAP");
					}
					if ((Object)(object)val6 != (Object)null && val10.HasProperty("_MetallicGlossMap"))
					{
						val10.SetTexture("_MetallicGlossMap", val6);
						val10.EnableKeyword("_METALLICGLOSSMAP");
					}
					if (val10.HasProperty("_Metallic"))
					{
						val10.SetFloat("_Metallic", num);
					}
					if (val10.HasProperty("_Smoothness"))
					{
						val10.SetFloat("_Smoothness", num2);
					}
					if (val10.HasProperty("_Glossiness"))
					{
						val10.SetFloat("_Glossiness", num2);
					}
					if ((Object)(object)val7 != (Object)null || val9 != Color.black)
					{
						if (val10.HasProperty("_EmissionMap") && (Object)(object)val7 != (Object)null)
						{
							val10.SetTexture("_EmissionMap", val7);
						}
						if (val10.HasProperty("_EmissionColor"))
						{
							val10.SetColor("_EmissionColor", val9);
							if (val9 != Color.black || (Object)(object)val7 != (Object)null)
							{
								val10.EnableKeyword("_EMISSION");
							}
						}
					}
					if ((Object)(object)val8 != (Object)null && val10.HasProperty("_OcclusionMap"))
					{
						val10.SetTexture("_OcclusionMap", val8);
						val10.EnableKeyword("_OCCLUSIONMAP");
					}
					materials[k] = val10;
				}
				val2.materials = materials;
			}
		}

		public static Material GetEffectMaterial(Color color)
		{
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Expected O, but got Unknown
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: 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_0033: Expected O, but got Unknown
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Expected O, but got Unknown
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Expected O, but got Unknown
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Expected O, but got Unknown
			if ((Object)(object)cachedEffectMaterial == (Object)null)
			{
				if ((Object)(object)cachedMaterial != (Object)null)
				{
					cachedEffectMaterial = new Material(cachedMaterial);
				}
				else
				{
					Renderer[] array = Object.FindObjectsOfType<Renderer>();
					Renderer[] array2 = array;
					foreach (Renderer val in array2)
					{
						if ((Object)(object)val.material != (Object)null && (Object)(object)val.material.shader != (Object)null && (((Object)val.material.shader).name.Contains("Universal") || ((Object)val.material.shader).name.Contains("URP")))
						{
							cachedEffectMaterial = new Material(val.material);
							break;
						}
					}
					if ((Object)(object)cachedEffectMaterial == (Object)null)
					{
						Shader val2 = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Sprites/Default");
						if ((Object)(object)val2 != (Object)null)
						{
							cachedEffectMaterial = new Material(val2);
						}
						else
						{
							cachedEffectMaterial = new Material(Shader.Find("Sprites/Default"));
						}
					}
				}
			}
			Material val3 = new Material(cachedEffectMaterial);
			val3.color = color;
			if (val3.HasProperty("_BaseColor"))
			{
				val3.SetColor("_BaseColor", color);
			}
			return val3;
		}

		private static GameObject CreatePrimitiveDrone(DroneType type)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: 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_0102: 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_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_033b: Expected O, but got Unknown
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0398: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject($"FallbackDrone_{type}");
			if (1 == 0)
			{
			}
			Color val2 = (Color)(type switch
			{
				DroneType.Scout => new Color(0.3f, 0.5f, 1f), 
				DroneType.Cargo => new Color(0.8f, 0.6f, 0.2f), 
				DroneType.HeavyLifter => new Color(0.4f, 0.4f, 0.5f), 
				DroneType.Combat => new Color(1f, 0.3f, 0.3f), 
				_ => new Color(0.5f, 0.5f, 0.5f), 
			});
			if (1 == 0)
			{
			}
			Color val3 = val2;
			GameObject val4 = GameObject.CreatePrimitive((PrimitiveType)0);
			val4.transform.SetParent(val.transform);
			val4.transform.localPosition = Vector3.zero;
			val4.transform.localScale = new Vector3(0.8f, 0.4f, 0.8f);
			val4.GetComponent<Renderer>().material = GetEffectMaterial(val3);
			Object.Destroy((Object)(object)val4.GetComponent<Collider>());
			GameObject val5 = GameObject.CreatePrimitive((PrimitiveType)0);
			val5.transform.SetParent(val.transform);
			val5.transform.localPosition = Vector3.up * 0.15f;
			val5.transform.localScale = Vector3.one * 0.4f;
			val5.GetComponent<Renderer>().material = GetEffectMaterial(val3 * 1.2f);
			Object.Destroy((Object)(object)val5.GetComponent<Collider>());
			Vector3 val6 = default(Vector3);
			for (int i = 0; i < 4; i++)
			{
				float num = (float)i * 90f * ((float)Math.PI / 180f);
				((Vector3)(ref val6))..ctor(Mathf.Cos(num) * 0.5f, 0f, Mathf.Sin(num) * 0.5f);
				GameObject val7 = GameObject.CreatePrimitive((PrimitiveType)2);
				val7.transform.SetParent(val.transform);
				val7.transform.localPosition = val6 * 0.5f;
				val7.transform.localScale = new Vector3(0.1f, 0.25f, 0.1f);
				val7.transform.localRotation = Quaternion.Euler(0f, 0f, 90f) * Quaternion.Euler(0f, (float)i * 90f, 0f);
				val7.GetComponent<Renderer>().material = GetEffectMaterial(new Color(0.3f, 0.3f, 0.3f));
				Object.Destroy((Object)(object)val7.GetComponent<Collider>());
				GameObject val8 = GameObject.CreatePrimitive((PrimitiveType)2);
				val8.transform.SetParent(val.transform);
				val8.transform.localPosition = val6;
				val8.transform.localScale = new Vector3(0.3f, 0.02f, 0.3f);
				val8.GetComponent<Renderer>().material = GetEffectMaterial(new Color(0.2f, 0.2f, 0.2f, 0.5f));
				Object.Destroy((Object)(object)val8.GetComponent<Collider>());
			}
			GameObject val9 = new GameObject("DroneLight");
			val9.transform.SetParent(val.transform);
			val9.transform.localPosition = Vector3.down * 0.2f;
			Light val10 = val9.AddComponent<Light>();
			val10.type = (LightType)2;
			val10.range = 5f;
			val10.intensity = 1f;
			val10.color = val3;
			return val;
		}

		private static GameObject CreatePrimitiveRelay(DroneRelayType type)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: 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_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: 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_0160: 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_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Expected O, but got Unknown
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject($"FallbackRelay_{type}");
			if (1 == 0)
			{
			}
			Color val2 = (Color)(type switch
			{
				DroneRelayType.Standard => new Color(0.2f, 0.4f, 0.8f), 
				DroneRelayType.FastCharge => new Color(1f, 0.8f, 0.2f), 
				DroneRelayType.DockingBay => new Color(0.3f, 0.7f, 0.4f), 
				DroneRelayType.Hub => new Color(0.6f, 0.3f, 0.8f), 
				_ => new Color(0.4f, 0.4f, 0.6f), 
			});
			if (1 == 0)
			{
			}
			Color val3 = val2;
			GameObject val4 = GameObject.CreatePrimitive((PrimitiveType)2);
			val4.transform.SetParent(val.transform);
			val4.transform.localPosition = Vector3.up * 0.1f;
			val4.transform.localScale = new Vector3(3f, 0.2f, 3f);
			val4.GetComponent<Renderer>().material = GetEffectMaterial(new Color(0.3f, 0.3f, 0.35f));
			Object.Destroy((Object)(object)val4.GetComponent<Collider>());
			GameObject val5 = GameObject.CreatePrimitive((PrimitiveType)2);
			val5.transform.SetParent(val.transform);
			val5.transform.localPosition = Vector3.up * 0.8f;
			val5.transform.localScale = new Vector3(0.5f, 0.6f, 0.5f);
			val5.GetComponent<Renderer>().material = GetEffectMaterial(val3);
			Object.Destroy((Object)(object)val5.GetComponent<Collider>());
			GameObject val6 = GameObject.CreatePrimitive((PrimitiveType)0);
			val6.transform.SetParent(val.transform);
			val6.transform.localPosition = Vector3.up * 1.5f;
			val6.transform.localScale = Vector3.one * 0.6f;
			val6.GetComponent<Renderer>().material = GetEffectMaterial(val3 * 1.5f);
			Object.Destroy((Object)(object)val6.GetComponent<Collider>());
			int num = ((type == DroneRelayType.DockingBay) ? 4 : 2);
			Vector3 localPosition = default(Vector3);
			for (int i = 0; i < num; i++)
			{
				float num2 = (float)i / (float)num * (float)Math.PI * 2f;
				((Vector3)(ref localPosition))..ctor(Mathf.Cos(num2) * 1.2f, 0.15f, Mathf.Sin(num2) * 1.2f);
				GameObject val7 = GameObject.CreatePrimitive((PrimitiveType)3);
				val7.transform.SetParent(val.transform);
				val7.transform.localPosition = localPosition;
				val7.transform.localScale = new Vector3(0.5f, 0.1f, 0.5f);
				val7.GetComponent<Renderer>().material = GetEffectMaterial(val3 * 0.7f);
				Object.Destroy((Object)(object)val7.GetComponent<Collider>());
			}
			GameObject val8 = new GameObject("RelayLight");
			val8.transform.SetParent(val.transform);
			val8.transform.localPosition = Vector3.up * 1.5f;
			Light val9 = val8.AddComponent<Light>();
			val9.type = (LightType)2;
			val9.range = 10f;
			val9.intensity = 2f;
			val9.color = val3;
			return val;
		}

		public static DroneController SpawnDrone(DroneType type, Vector3 position, DronePadController homePad)
		{
			//IL_007e: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
			string text = "drones_simple";
			string text2 = "drone";
			switch (type)
			{
			case DroneType.Scout:
				text = "drones_simple";
				text2 = "drone blue";
				break;
			case DroneType.Cargo:
				text = "drones_voodooplay";
				text2 = "Drone";
				break;
			case DroneType.HeavyLifter:
				text = "drones_scifi";
				text2 = "Robot_Collector";
				break;
			case DroneType.Combat:
				text = "drones_scifi";
				text2 = "Robot_Guardian";
				break;
			}
			GameObject val = null;
			GameObject prefab = GetPrefab(text, text2);
			if ((Object)(object)prefab != (Object)null)
			{
				val = Object.Instantiate<GameObject>(prefab, position, Quaternion.identity);
				FixPrefabMaterials(val);
			}
			else
			{
				DroneLogisticsPlugin droneLogisticsPlugin = instance;
				if (droneLogisticsPlugin != null)
				{
					((BaseUnityPlugin)droneLogisticsPlugin).Logger.LogWarning((object)("Could not find drone prefab: " + text + "/" + text2 + " - using fallback"));
				}
				val = CreatePrimitiveDrone(type);
				val.transform.position = position;
			}
			((Object)val).name = $"Drone_{type}_{ActiveDrones.Count}";
			DroneController droneController = val.AddComponent<DroneController>();
			droneController.Initialize(type, homePad);
			ActiveDrones.Add(droneController);
			return droneController;
		}

		public static DronePadController SpawnDronePad(Vector3 position, DroneRelayType relayType = DroneRelayType.Standard)
		{
			//IL_0070: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = null;
			string text = "scifi_machines";
			if (1 == 0)
			{
			}
			string text2 = relayType switch
			{
				DroneRelayType.Standard => "Battery", 
				DroneRelayType.FastCharge => "Battery_big", 
				DroneRelayType.DockingBay => "torpedo_docking_station_1_side", 
				DroneRelayType.Hub => "computer_station", 
				_ => "Battery", 
			};
			if (1 == 0)
			{
			}
			string text3 = text2;
			GameObject prefab = GetPrefab(text, text3);
			if ((Object)(object)prefab != (Object)null)
			{
				val = Object.Instantiate<GameObject>(prefab, position, Quaternion.identity);
				FixPrefabMaterials(val);
			}
			else
			{
				DroneLogisticsPlugin droneLogisticsPlugin = instance;
				if (droneLogisticsPlugin != null)
				{
					((BaseUnityPlugin)droneLogisticsPlugin).Logger.LogWarning((object)("Could not find relay prefab: " + text + "/" + text3 + " - using fallback"));
				}
				val = CreatePrimitiveRelay(relayType);
			}
			val.transform.position = position;
			((Object)val).name = $"DroneRelay_{relayType}_{ActivePads.Count}";
			if ((Object)(object)val.GetComponent<Collider>() == (Object)null)
			{
				BoxCollider val2 = val.AddComponent<BoxCollider>();
				((Collider)val2).isTrigger = true;
				val2.size = new Vector3(2f, 3f, 2f);
			}
			DronePadController dronePadController = val.AddComponent<DronePadController>();
			dronePadController.Initialize(relayType);
			ActivePads.Add(dronePadController);
			return dronePadController;
		}

		public static DronePadController SpawnPoweredRelay(Vector3 position, DroneRelayType relayType = DroneRelayType.Standard)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			DronePadController dronePadController = SpawnDronePad(position, relayType);
			if ((Object)(object)dronePadController != (Object)null)
			{
				dronePadController.RequiresPower = true;
				DronePadController dronePadController2 = dronePadController;
				if (1 == 0)
				{
				}
				int powerDraw = relayType switch
				{
					DroneRelayType.Standard => RelayPowerDraw.Value, 
					DroneRelayType.FastCharge => RelayPowerDraw.Value * 2, 
					DroneRelayType.DockingBay => RelayPowerDraw.Value * 3, 
					DroneRelayType.Hub => RelayPowerDraw.Value / 2, 
					_ => RelayPowerDraw.Value, 
				};
				if (1 == 0)
				{
				}
				dronePadController2.PowerDraw = powerDraw;
			}
			return dronePadController;
		}

		public static CargoData PackItems(ResourceInfo resource, int quantity)
		{
			CargoData cargoData = new CargoData
			{
				ResourceType = resource,
				Quantity = quantity,
				IsCrate = UseCargoCrates.Value
			};
			if (UseCargoCrates.Value)
			{
				cargoData.MaxQuantity = resource.maxStackCount * 2;
			}
			else
			{
				cargoData.MaxQuantity = resource.maxStackCount;
			}
			cargoData.Quantity = Mathf.Min(quantity, cargoData.MaxQuantity);
			return cargoData;
		}

		public static DronePadController FindNearestPad(Vector3 position)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			DronePadController result = null;
			float num = float.MaxValue;
			foreach (DronePadController activePad in ActivePads)
			{
				if (!((Object)(object)activePad == (Object)null))
				{
					float num2 = Vector3.Distance(position, ((Component)activePad).transform.position);
					if (num2 < num)
					{
						num = num2;
						result = activePad;
					}
				}
			}
			return result;
		}

		public static DroneController FindAvailableDrone(Vector3 position, float maxRange = -1f)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if (maxRange < 0f)
			{
				maxRange = DroneRange.Value;
			}
			foreach (DroneController activeDrone in ActiveDrones)
			{
				if (!((Object)(object)activeDrone == (Object)null) && activeDrone.IsAvailable)
				{
					float num = Vector3.Distance(position, ((Component)activeDrone).transform.position);
					if (num <= maxRange)
					{
						return activeDrone;
					}
				}
			}
			return null;
		}

		public static void Log(string message)
		{
			DroneLogisticsPlugin droneLogisticsPlugin = instance;
			if (droneLogisticsPlugin != null)
			{
				((BaseUnityPlugin)droneLogisticsPlugin).Logger.LogInfo((object)message);
			}
		}

		public static void LogWarning(string message)
		{
			DroneLogisticsPlugin droneLogisticsPlugin = instance;
			if (droneLogisticsPlugin != null)
			{
				((BaseUnityPlugin)droneLogisticsPlugin).Logger.LogWarning((object)message);
			}
		}
	}
	public enum DroneType
	{
		Scout,
		Cargo,
		HeavyLifter,
		Combat
	}
	public enum DroneRelayType
	{
		Standard,
		FastCharge,
		DockingBay,
		Hub
	}
	public enum DroneState
	{
		Idle,
		Departing,
		Traveling,
		Loading,
		Unloading,
		Returning,
		Charging,
		Disabled
	}
	public class CargoData
	{
		public ResourceInfo ResourceType;

		public int Quantity;

		public int MaxQuantity;

		public bool IsCrate;

		public bool IsFull => Quantity >= MaxQuantity;

		public bool IsEmpty => Quantity <= 0;
	}
	public class DeliveryRequest
	{
		public Vector3 PickupLocation;

		public Vector3 DeliveryLocation;

		public ResourceInfo Resource;

		public int Quantity;

		public int Priority;

		public float TimeRequested;

		public DeliveryRequest(Vector3 pickup, Vector3 delivery, ResourceInfo resource, int qty, int priority = 0)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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)
			PickupLocation = pickup;
			DeliveryLocation = delivery;
			Resource = resource;
			Quantity = qty;
			Priority = priority;
			TimeRequested = Time.time;
		}
	}
	public class RouteManager
	{
		private Dictionary<int, LogisticsNode> nodes = new Dictionary<int, LogisticsNode>();

		private int nextNodeId = 0;

		private List<DeliveryRoute> routes = new List<DeliveryRoute>();

		private List<DeliveryRequest> pendingRequests = new List<DeliveryRequest>();

		private float lastOptimizeTime;

		private float optimizeInterval = 5f;

		public int TotalNodes => nodes.Count;

		public int TotalRoutes => routes.Count;

		public int ActiveRoutes => routes.Count((DeliveryRoute r) => r.IsActive);

		public int PendingRequests => pendingRequests.Count;

		public RouteManager()
		{
			DroneLogisticsPlugin.Log("RouteManager initialized");
		}

		public void Update()
		{
			if (Time.time - lastOptimizeTime > optimizeInterval)
			{
				OptimizeRoutes();
				lastOptimizeTime = Time.time;
			}
			ProcessPendingRequests();
		}

		public int RegisterNode(Vector3 position, LogisticsNodeType type, string name = null)
		{
			//IL_001e: 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_0070: Unknown result type (might be due to invalid IL or missing references)
			LogisticsNode logisticsNode = new LogisticsNode
			{
				Id = nextNodeId++,
				Position = position,
				Type = type,
				Name = (name ?? $"{type}_{nextNodeId}")
			};
			nodes[logisticsNode.Id] = logisticsNode;
			DroneLogisticsPlugin.Log($"Registered logistics node: {logisticsNode.Name} at {position}");
			return logisticsNode.Id;
		}

		public void UnregisterNode(int nodeId)
		{
			if (nodes.ContainsKey(nodeId))
			{
				nodes.Remove(nodeId);
				routes.RemoveAll((DeliveryRoute r) => r.SourceNodeId == nodeId || r.DestinationNodeId == nodeId);
			}
		}

		public LogisticsNode GetNode(int nodeId)
		{
			LogisticsNode value;
			return nodes.TryGetValue(nodeId, out value) ? value : null;
		}

		public List<LogisticsNode> GetNodesInRange(Vector3 position, float range)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			return nodes.Values.Where((LogisticsNode n) => Vector3.Distance(n.Position, position) <= range).ToList();
		}

		public DeliveryRoute CreateRoute(int sourceId, int destId, ResourceInfo resource, int quantity, int priority = 0)
		{
			if (!nodes.ContainsKey(sourceId) || !nodes.ContainsKey(destId))
			{
				DroneLogisticsPlugin.LogWarning($"Invalid node IDs for route: {sourceId} -> {destId}");
				return null;
			}
			DeliveryRoute deliveryRoute = new DeliveryRoute
			{
				SourceNodeId = sourceId,
				DestinationNodeId = destId,
				Resource = resource,
				QuantityPerTrip = quantity,
				Priority = priority,
				IsActive = true
			};
			routes.Add(deliveryRoute);
			DroneLogisticsPlugin.Log("Created route: " + nodes[sourceId].Name + " -> " + nodes[destId].Name + " (" + resource.displayName + ")");
			return deliveryRoute;
		}

		public void RemoveRoute(DeliveryRoute route)
		{
			routes.Remove(route);
		}

		public void SetRouteActive(DeliveryRoute route, bool active)
		{
			route.IsActive = active;
		}

		public List<DeliveryRoute> GetRoutesForNode(int nodeId)
		{
			return routes.Where((DeliveryRoute r) => r.SourceNodeId == nodeId || r.DestinationNodeId == nodeId).ToList();
		}

		public void RequestDelivery(Vector3 pickup, Vector3 delivery, ResourceInfo resource, int quantity, int priority = 0)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			DeliveryRequest item = new DeliveryRequest(pickup, delivery, resource, quantity, priority);
			pendingRequests.Add(item);
			pendingRequests.Sort((DeliveryRequest a, DeliveryRequest b) => b.Priority.CompareTo(a.Priority));
		}

		private void ProcessPendingRequests()
		{
			if (pendingRequests.Count == 0)
			{
				return;
			}
			for (int num = pendingRequests.Count - 1; num >= 0; num--)
			{
				DeliveryRequest request = pendingRequests[num];
				DronePadController dronePadController = FindBestPadForRequest(request);
				if ((Object)(object)dronePadController != (Object)null && dronePadController.RequestDelivery(request))
				{
					pendingRequests.RemoveAt(num);
				}
			}
			float maxAge = 300f;
			pendingRequests.RemoveAll((DeliveryRequest r) => Time.time - r.TimeRequested > maxAge);
		}

		private DronePadController FindBestPadForRequest(DeliveryRequest request)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			DronePadController result = null;
			float num = float.MaxValue;
			foreach (DronePadController activePad in DroneLogisticsPlugin.ActivePads)
			{
				if ((Object)(object)activePad == (Object)null)
				{
					continue;
				}
				float num2 = Vector3.Distance(((Component)activePad).transform.position, request.PickupLocation);
				float num3 = Vector3.Distance(((Component)activePad).transform.position, request.DeliveryLocation);
				if (!(num2 > DroneLogisticsPlugin.DroneRange.Value) && !(num3 > DroneLogisticsPlugin.DroneRange.Value))
				{
					float num4 = num2 + num3;
					num4 += (float)(activePad.DroneCount - activePad.AvailableDroneCount) * 50f;
					num4 += (float)activePad.QueuedRequests * 20f;
					if (num4 < num)
					{
						num = num4;
						result = activePad;
					}
				}
			}
			return result;
		}

		private void OptimizeRoutes()
		{
			//IL_0071: 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)
			foreach (DeliveryRoute route in routes)
			{
				if (!route.IsActive)
				{
					continue;
				}
				LogisticsNode node = GetNode(route.SourceNodeId);
				LogisticsNode node2 = GetNode(route.DestinationNodeId);
				if (node != null && node2 != null && route.PendingDeliveries < 3)
				{
					DeliveryRequest request = new DeliveryRequest(node.Position, node2.Position, route.Resource, route.QuantityPerTrip, route.Priority);
					DronePadController dronePadController = FindBestPadForRequest(request);
					if ((Object)(object)dronePadController != (Object)null && dronePadController.RequestDelivery(request))
					{
						route.PendingDeliveries++;
						route.TotalDeliveries++;
					}
				}
			}
		}

		public string GetStatsSummary()
		{
			return $"Nodes: {TotalNodes}, Routes: {ActiveRoutes}/{TotalRoutes}, Pending: {PendingRequests}";
		}
	}
	public enum LogisticsNodeType
	{
		Storage,
		Machine,
		Packing,
		Unpacking,
		TurretAmmo,
		Custom
	}
	public class LogisticsNode
	{
		public int Id;

		public Vector3 Position;

		public LogisticsNodeType Type;

		public string Name;

		public bool IsActive = true;

		public List<ResourceInfo> AllowedResources = new List<ResourceInfo>();

		public bool AllowAll => AllowedResources.Count == 0;
	}
	public class DeliveryRoute
	{
		public int SourceNodeId;

		public int DestinationNodeId;

		public ResourceInfo Resource;

		public int QuantityPerTrip;

		public int Priority;

		public bool IsActive;

		public int TotalDeliveries;

		public int PendingDeliveries;
	}
}