Decompiled source of Zarkow Turret Defense v1.7.1135

plugins\ZarkowTurretDefense.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using SimpleJson;
using UnityEngine;
using ZarkowTurretDefense.Models;
using ZarkowTurretDefense.Scripts;
using ZarkowTurretDefense.Services;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ZarkowTurretDefense")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Digital Software")]
[assembly: AssemblyProduct("ZarkowTurretDefense")]
[assembly: AssemblyCopyright("Copyright © 2023-2026 Johan Munkestam/Digital Software")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("1.2.0.1020")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.0.1020")]
namespace ZarkowTurretDefense
{
	[BepInPlugin("com.digitalsoftware.zarkowturretdefense", "Zarkow's Turret Defense", "1.7.1135")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	internal class ZTurretDefense : BaseUnityPlugin
	{
		private class RegisteredTurret
		{
			public GameObject Prefab;

			public TurretBase Turret;
		}

		private class RegisteredBuildingpart
		{
			public GameObject Prefab;

			public BuildingpartBase Buildingpart;
		}

		public const string PluginGUID = "com.digitalsoftware.zarkowturretdefense";

		public const string PluginName = "Zarkow's Turret Defense";

		public const string PluginVersion = "1.7.1135";

		public static ConfigEntry<int> TurretVolume;

		public static ConfigEntry<int> TurretStyle;

		public static ConfigEntry<float> DamageModifier;

		public static ConfigEntry<float> CostModifier;

		public static ConfigEntry<bool> DisableTurretLight;

		public static ConfigEntry<bool> DisableDroneLight;

		public static ConfigEntry<bool> DisableBuildingpartsLight;

		public static ConfigEntry<bool> TurretsShouldFullyIgnorePlayers;

		public static ConfigEntry<bool> ShowHeightMapDebugLogEntries;

		public static ConfigEntry<bool> ShowObjectDestroyDebugLogEntries;

		public static ConfigEntry<bool> ExportBuiltinConfigFiles;

		public static ConfigEntry<string> TurretListFile;

		public static ConfigEntry<string> BuildingpartListFile;

		private readonly Harmony _harmony = new Harmony("com.digitalsoftware.zarkowturretdefense");

		private readonly Dictionary<string, AssetBundle> _assetBundles = new Dictionary<string, AssetBundle>();

		private List<TurretConfig> _turretConfigs = new List<TurretConfig>();

		private List<BuildingpartConfig> _buildingpartConfigs = new List<BuildingpartConfig>();

		private readonly Dictionary<string, RegisteredTurret> _turrets = new Dictionary<string, RegisteredTurret>();

		private readonly Dictionary<string, RegisteredBuildingpart> _buildingparts = new Dictionary<string, RegisteredBuildingpart>();

		private string _turretOverrideText = string.Empty;

		private string _buildingpartOverrideText = string.Empty;

		private string _lastAppliedTurretJson;

		private string _lastAppliedBuildingpartJson;

		private CustomRPC _listSyncRpc;

		public static CustomLocalization Localization = LocalizationManager.Instance.GetLocalization();

		private void Awake()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Expected O, but got Unknown
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Expected O, but got Unknown
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Expected O, but got Unknown
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Expected O, but got Unknown
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Expected O, but got Unknown
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Expected O, but got Unknown
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Expected O, but got Unknown
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Expected O, but got Unknown
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Expected O, but got Unknown
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Expected O, but got Unknown
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_037b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0385: Expected O, but got Unknown
			//IL_0385: Expected O, but got Unknown
			TurretVolume = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Turret Volume", 100, new ConfigDescription("Custom Turret Volume", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			TurretStyle = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Turret Style", 0, new ConfigDescription("Turret Style (Not active yet)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 4), Array.Empty<object>()));
			DamageModifier = ((BaseUnityPlugin)this).Config.Bind<float>("Difficulty", "Damage Modifier", 1f, new ConfigDescription("Difficulty: Optionally Modify Damage of Turrets", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 100f), Array.Empty<object>()));
			CostModifier = ((BaseUnityPlugin)this).Config.Bind<float>("Difficulty", "Cost Modifier", 1f, new ConfigDescription("Difficulty: Optionally Modify the Material Cost of Turrets", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 100f), Array.Empty<object>()));
			TurretsShouldFullyIgnorePlayers = ((BaseUnityPlugin)this).Config.Bind<bool>("BehaviorTweaks", "Turrets Should Fully Ignore Players", false, new ConfigDescription("Tweak: Turrets should no longer even look at players for targeting purpose", (AcceptableValueBase)(object)new AcceptableValueRange<bool>(false, true), Array.Empty<object>()));
			DisableTurretLight = ((BaseUnityPlugin)this).Config.Bind<bool>("PerformanceTweaks", "Disable Lights - Turrets", false, new ConfigDescription("Tweak: Disable Lights - Turrets", (AcceptableValueBase)(object)new AcceptableValueRange<bool>(false, true), Array.Empty<object>()));
			DisableDroneLight = ((BaseUnityPlugin)this).Config.Bind<bool>("PerformanceTweaks", "Disable Lights - Drones", false, new ConfigDescription("Tweak: Disable Lights - Drones", (AcceptableValueBase)(object)new AcceptableValueRange<bool>(false, true), Array.Empty<object>()));
			DisableBuildingpartsLight = ((BaseUnityPlugin)this).Config.Bind<bool>("PerformanceTweaks", "Disable Lights - Buildingparts", false, new ConfigDescription("Tweak: Disable Lights - Buildingparts", (AcceptableValueBase)(object)new AcceptableValueRange<bool>(false, true), Array.Empty<object>()));
			ShowHeightMapDebugLogEntries = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Show HeightMap Debug Log Entries", false, new ConfigDescription("Debug: Show HeightMap Warning and Info log lines", (AcceptableValueBase)(object)new AcceptableValueRange<bool>(false, true), Array.Empty<object>()));
			ShowObjectDestroyDebugLogEntries = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Show Object Destroy Debug Log Entries", false, new ConfigDescription("Debug: Show log lines when an object from the mod pack is de-loaded as player move out of range", (AcceptableValueBase)(object)new AcceptableValueRange<bool>(false, true), Array.Empty<object>()));
			ExportBuiltinConfigFiles = ((BaseUnityPlugin)this).Config.Bind<bool>("CustomLists", "Export Built-in Config Files", false, new ConfigDescription("When true, the built-in turret and building-part lists are written to BepInEx/config as *.default.json at startup, to copy from when making an override file. See README.", (AcceptableValueBase)null, Array.Empty<object>()));
			TurretListFile = ((BaseUnityPlugin)this).Config.Bind<string>("CustomLists", "Turret List File", ConfigFileService.DefaultOverrideFileName("turrets"), new ConfigDescription("JSON file with the complete turret list; when it exists it replaces the built-in list. A file name is looked up in BepInEx/config, an absolute path is used as given. Empty, or no such file: the built-in list. On a server the server's file is sent to every client.", (AcceptableValueBase)null, Array.Empty<object>()));
			BuildingpartListFile = ((BaseUnityPlugin)this).Config.Bind<string>("CustomLists", "Buildingpart List File", ConfigFileService.DefaultOverrideFileName("buildingparts"), new ConfigDescription("JSON file with the complete building-part list; when it exists it replaces the built-in list. A file name is looked up in BepInEx/config, an absolute path is used as given. Empty, or no such file: the built-in list. On a server the server's file is sent to every client.", (AcceptableValueBase)null, Array.Empty<object>()));
			if (ExportBuiltinConfigFiles.Value)
			{
				ConfigFileService.ExportBuiltin("turrets", "ZarkowTurretDefense.Assets.Configs.turretsconfigs.json");
				ConfigFileService.ExportBuiltin("buildingparts", "ZarkowTurretDefense.Assets.Configs.buildingpartsconfigs.json");
			}
			_turretOverrideText = ConfigFileService.ReadOverrideText("turrets", TurretListFile.Value);
			_buildingpartOverrideText = ConfigFileService.ReadOverrideText("buildingparts", BuildingpartListFile.Value);
			_lastAppliedTurretJson = _turretOverrideText;
			_lastAppliedBuildingpartJson = _buildingpartOverrideText;
			_turretConfigs = SelectTurretConfigs(_turretOverrideText);
			_buildingpartConfigs = SelectBuildingpartConfigs(_buildingpartOverrideText);
			LoadAssetBundles();
			LoadLocalization("English");
			LoadLocalization("German");
			AddTurrets();
			AddBuildingParts();
			UnloadAssetBundles();
			_listSyncRpc = NetworkManager.Instance.AddRPC("ZarkowTurretDefense_CustomLists", new CoroutineHandler(ListSyncServerReceive), new CoroutineHandler(ListSyncClientReceive));
			SynchronizationManager.Instance.AddInitialSynchronization(_listSyncRpc, (Func<ZNetPeer, ZPackage>)BuildListSyncPackage);
			_harmony.PatchAll();
			Logger.LogInfo((object)"### RELEASE 1.7.1135 ### Zarkow's Turret Defense Loaded.");
		}

		private void LoadAssetBundles()
		{
			_assetBundles.Add("turrets", AssetUtils.LoadAssetBundleFromResources("turrets"));
		}

		private void UnloadAssetBundles()
		{
			foreach (KeyValuePair<string, AssetBundle> assetBundle in _assetBundles)
			{
				assetBundle.Value.Unload(false);
			}
		}

		private void LoadLocalization(string languageName)
		{
			Logger.LogInfo((object)("### Load Localization language " + languageName));
			string text = LoadLocalizationJsonFromResource("ZarkowTurretDefense.Assets.Localizations." + languageName + ".json");
			Localization.AddJsonFile(languageName, text);
		}

		public static string LoadLocalizationJsonFromResource(string resourceName)
		{
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
			using StreamReader streamReader = new StreamReader(stream);
			return streamReader.ReadToEnd();
		}

		private void AddTurrets()
		{
			Logger.LogInfo((object)"### --- Added Turrets ---");
			_turretConfigs.ForEach(delegate(TurretConfig turretConfig)
			{
				if (turretConfig.enabled)
				{
					Logger.LogDebug((object)("### Get assetBundle for '" + turretConfig.bundleName + "'"));
					AssetBundle val = _assetBundles[turretConfig.bundleName];
					if ((Object)(object)val == (Object)null)
					{
						Logger.LogWarning((object)"### assetBundle is null");
					}
					else
					{
						Logger.LogDebug((object)("### Read asset from " + turretConfig.prefabPath));
						GameObject val2 = val.LoadAsset<GameObject>(turretConfig.prefabPath);
						if ((Object)(object)val2 == (Object)null)
						{
							Logger.LogFatal((object)("### Missing prefab " + turretConfig.prefabPath + " in bundle"));
						}
						else
						{
							Logger.LogDebug((object)"### Add component script to prefab based on type");
							TurretBase turretBase = (TurretType)Enum.Parse(typeof(TurretType), turretConfig.type, ignoreCase: true) switch
							{
								TurretType.SignalTurret => val2.AddComponent<SignalTurret>(), 
								TurretType.MineTurret => val2.AddComponent<MineTurret>(), 
								TurretType.LightGun => val2.AddComponent<LightGunTurret>(), 
								TurretType.Gun => val2.AddComponent<GunTurret>(), 
								TurretType.HeavyGun => val2.AddComponent<HeavyGunTurret>(), 
								TurretType.AdvancedGun => val2.AddComponent<AdvancedGunTurret>(), 
								TurretType.MissileGun => val2.AddComponent<MissileTurret>(), 
								TurretType.Drone => val2.AddComponent<DroneTurret>(), 
								TurretType.RepairDrone => val2.AddComponent<RepairDroneTurret>(), 
								TurretType.GatherDrone => val2.AddComponent<GatherDroneTurret>(), 
								TurretType.FishingDrone => val2.AddComponent<FishingDroneTurret>(), 
								TurretType.LoggerDrone => val2.AddComponent<LoggerDroneTurret>(), 
								TurretType.InertTurret => val2.AddComponent<InertTurret>(), 
								_ => val2.AddComponent<TurretBase>(), 
							};
							Logger.LogDebug((object)("### Init Turret Config '" + turretConfig.name + "'"));
							turretBase.Initialize(turretConfig);
							Logger.LogDebug((object)$"### Apply Config and Create CustomPiece '{turretBase}'");
							CustomPiece val3 = TurretConfig.Convert(val2, turretConfig);
							Logger.LogDebug((object)"### Add piece to PieceManager");
							PieceManager.Instance.AddPiece(val3);
							_turrets[turretConfig.name] = new RegisteredTurret
							{
								Prefab = val2,
								Turret = turretBase
							};
							Logger.LogDebug((object)"### --- Turret Added ---");
						}
					}
				}
			});
		}

		private void AddBuildingParts()
		{
			Logger.LogInfo((object)"### --- Added BuildingParts ---");
			_buildingpartConfigs.ForEach(delegate(BuildingpartConfig buildingpartConfig)
			{
				if (buildingpartConfig.enabled)
				{
					Logger.LogDebug((object)("### Get assetBundle for '" + buildingpartConfig.bundleName + "'"));
					AssetBundle val = _assetBundles[buildingpartConfig.bundleName];
					if ((Object)(object)val == (Object)null)
					{
						Logger.LogWarning((object)"### assetBundle is null");
					}
					else
					{
						Logger.LogDebug((object)("### Read asset from " + buildingpartConfig.prefabPath));
						GameObject val2 = val.LoadAsset<GameObject>(buildingpartConfig.prefabPath);
						Logger.LogDebug((object)"### Add component script to prefab based on type");
						BuildingpartBase buildingpartBase = (((BuildingpartType)Enum.Parse(typeof(BuildingpartType), buildingpartConfig.type, ignoreCase: true) != BuildingpartType.HoverCart) ? val2.AddComponent<BuildingpartBase>() : val2.AddComponent<HoverCart>());
						Logger.LogDebug((object)("### Init Buildingpart config '" + buildingpartConfig.name + "'"));
						buildingpartBase.Initialize(buildingpartConfig);
						Logger.LogDebug((object)$"### Apply Config and Create CustomPiece '{buildingpartBase}'");
						CustomPiece val3 = BuildingpartConfig.Convert(val2, buildingpartConfig);
						Logger.LogDebug((object)"### Add piece to PieceManager");
						PieceManager.Instance.AddPiece(val3);
						_buildingparts[buildingpartConfig.name] = new RegisteredBuildingpart
						{
							Prefab = val2,
							Buildingpart = buildingpartBase
						};
						Logger.LogDebug((object)"### --- BuildingPart Added ---");
					}
				}
			});
		}

		private static List<TurretConfig> SelectTurretConfigs(string overrideJson)
		{
			return ConfigFileService.SelectList("turrets", "ZarkowTurretDefense.Assets.Configs.turretsconfigs.json", overrideJson, TurretConfigManager.Parse, (TurretConfig config) => config.name, ConfigValidation.ValidateTurrets);
		}

		private static List<BuildingpartConfig> SelectBuildingpartConfigs(string overrideJson)
		{
			return ConfigFileService.SelectList("buildingparts", "ZarkowTurretDefense.Assets.Configs.buildingpartsconfigs.json", overrideJson, BuildingpartConfigManager.Parse, (BuildingpartConfig config) => config.name, ConfigValidation.ValidateBuildingparts);
		}

		private ZPackage BuildListSyncPackage(ZNetPeer peer)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			ZPackage val = new ZPackage();
			val.Write(_turretOverrideText ?? string.Empty);
			val.Write(_buildingpartOverrideText ?? string.Empty);
			return val;
		}

		private IEnumerator ListSyncServerReceive(long sender, ZPackage package)
		{
			yield break;
		}

		private IEnumerator ListSyncClientReceive(long sender, ZPackage package)
		{
			string overrideJson = package.ReadString();
			string overrideJson2 = package.ReadString();
			Logger.LogInfo((object)"### Config: turret and building-part lists received from the server, applying");
			ReapplyTurretConfigs(overrideJson);
			ReapplyBuildingpartConfigs(overrideJson2);
			yield break;
		}

		private void ReapplyTurretConfigs(string overrideJson)
		{
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			if (overrideJson == _lastAppliedTurretJson)
			{
				return;
			}
			_lastAppliedTurretJson = overrideJson;
			_turretConfigs = SelectTurretConfigs(overrideJson);
			Dictionary<string, TurretConfig> dictionary = new Dictionary<string, TurretConfig>();
			foreach (TurretConfig turretConfig in _turretConfigs)
			{
				if (!string.IsNullOrEmpty(turretConfig.name) && !dictionary.ContainsKey(turretConfig.name))
				{
					dictionary.Add(turretConfig.name, turretConfig);
				}
			}
			foreach (KeyValuePair<string, RegisteredTurret> turret in _turrets)
			{
				CustomPiece piece = PieceManager.Instance.GetPiece(((Object)turret.Value.Prefab).name);
				if (dictionary.TryGetValue(turret.Key, out var value))
				{
					turret.Value.Turret.Initialize(value);
					if (piece != null)
					{
						piece.Piece.m_resources = new PieceConfig
						{
							Requirements = value.resources.Select(TurretConfigRequirement.Convert).ToArray()
						}.GetRequirements();
						piece.Piece.m_enabled = value.enabled;
					}
				}
				else if (piece != null)
				{
					piece.Piece.m_enabled = false;
				}
			}
			foreach (string item in dictionary.Keys.Except(_turrets.Keys))
			{
				Logger.LogWarning((object)("### Config 'turrets': '" + item + "' is in the active list but was not registered at startup; restart with the same list to use it"));
			}
		}

		private void ReapplyBuildingpartConfigs(string overrideJson)
		{
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			if (overrideJson == _lastAppliedBuildingpartJson)
			{
				return;
			}
			_lastAppliedBuildingpartJson = overrideJson;
			_buildingpartConfigs = SelectBuildingpartConfigs(overrideJson);
			Dictionary<string, BuildingpartConfig> dictionary = new Dictionary<string, BuildingpartConfig>();
			foreach (BuildingpartConfig buildingpartConfig in _buildingpartConfigs)
			{
				if (!string.IsNullOrEmpty(buildingpartConfig.name) && !dictionary.ContainsKey(buildingpartConfig.name))
				{
					dictionary.Add(buildingpartConfig.name, buildingpartConfig);
				}
			}
			foreach (KeyValuePair<string, RegisteredBuildingpart> buildingpart in _buildingparts)
			{
				CustomPiece piece = PieceManager.Instance.GetPiece(((Object)buildingpart.Value.Prefab).name);
				if (dictionary.TryGetValue(buildingpart.Key, out var value))
				{
					buildingpart.Value.Buildingpart.Initialize(value);
					if (piece != null)
					{
						piece.Piece.m_resources = new PieceConfig
						{
							Requirements = value.resources.Select(BuildingpartConfigRequirement.Convert).ToArray()
						}.GetRequirements();
						piece.Piece.m_enabled = value.enabled;
					}
				}
				else if (piece != null)
				{
					piece.Piece.m_enabled = false;
				}
			}
			foreach (string item in dictionary.Keys.Except(_buildingparts.Keys))
			{
				Logger.LogWarning((object)("### Config 'buildingparts': '" + item + "' is in the active list but was not registered at startup; restart with the same list to use it"));
			}
		}
	}
}
namespace ZarkowTurretDefense.Services
{
	internal class BuildingpartConfigManager
	{
		public static List<BuildingpartConfig> LoadBuildingpartConfigJsonFromResource(string resourceName)
		{
			string json;
			using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
			{
				using StreamReader streamReader = new StreamReader(stream);
				json = streamReader.ReadToEnd();
			}
			return Parse(json);
		}

		public static List<BuildingpartConfig> Parse(string json)
		{
			return SimpleJson.DeserializeObject<List<BuildingpartConfig>>(json);
		}
	}
	internal static class ConfigFileService
	{
		public const string TurretsKind = "turrets";

		public const string BuildingpartsKind = "buildingparts";

		public const string TurretsResource = "ZarkowTurretDefense.Assets.Configs.turretsconfigs.json";

		public const string BuildingpartsResource = "ZarkowTurretDefense.Assets.Configs.buildingpartsconfigs.json";

		public static string DefaultOverrideFileName(string kind)
		{
			return "com.digitalsoftware.zarkowturretdefense." + kind + ".json";
		}

		public static string ExportPath(string kind)
		{
			return Path.Combine(Paths.ConfigPath, "com.digitalsoftware.zarkowturretdefense." + kind + ".default.json");
		}

		public static string ResolveOverridePath(string setting)
		{
			if (string.IsNullOrWhiteSpace(setting))
			{
				return null;
			}
			string text = setting.Trim();
			if (!Path.IsPathRooted(text))
			{
				return Path.Combine(Paths.ConfigPath, text);
			}
			return text;
		}

		public static string ReadResourceText(string resourceName)
		{
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
			if (stream == null)
			{
				throw new FileNotFoundException("Embedded resource not found", resourceName);
			}
			using StreamReader streamReader = new StreamReader(stream);
			return streamReader.ReadToEnd();
		}

		public static string ReadOverrideText(string kind, string setting)
		{
			string text = ResolveOverridePath(setting);
			if (text == null)
			{
				return string.Empty;
			}
			if (!File.Exists(text))
			{
				Logger.LogDebug((object)("### Config '" + kind + "': no list file at " + text));
				return string.Empty;
			}
			try
			{
				Logger.LogInfo((object)("### Config '" + kind + "': reading list file " + text));
				return File.ReadAllText(text);
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("### Config '" + kind + "': could not read " + text + ": " + ex.Message));
				return string.Empty;
			}
		}

		public static void ExportBuiltin(string kind, string resourceName)
		{
			string text = ExportPath(kind);
			try
			{
				File.WriteAllText(text, ReadResourceText(resourceName));
				Logger.LogInfo((object)("### Config '" + kind + "': built-in list exported to " + text));
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("### Config '" + kind + "': could not export built-in list to " + text + ": " + ex.Message));
			}
		}

		public static List<T> SelectList<T>(string kind, string resourceName, string overrideJson, Func<string, List<T>> parse, Func<T, string> nameOf, Func<List<T>, List<string>> validate)
		{
			string arg = ReadResourceText(resourceName);
			if (string.IsNullOrWhiteSpace(overrideJson))
			{
				Logger.LogInfo((object)("### Config '" + kind + "': built-in list (no list file)"));
				return parse(arg) ?? new List<T>();
			}
			try
			{
				List<T> list = parse(overrideJson);
				if (list == null)
				{
					throw new FormatException("root is not a JSON array");
				}
				List<string> list2 = validate(list) ?? new List<string>();
				List<string> list3 = (parse(arg) ?? new List<T>()).Select(nameOf).Except(list.Select(nameOf)).ToList();
				Logger.LogInfo((object)$"### Config '{kind}': list file in use, {list.Count} entries, {list2.Count} warning(s)");
				foreach (string item in list2)
				{
					Logger.LogWarning((object)("### Config '" + kind + "': " + item));
				}
				if (list3.Count > 0)
				{
					Logger.LogInfo((object)("### Config '" + kind + "': built-in entries not in the list file, so not in the game: " + string.Join(", ", list3)));
				}
				return list;
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("### Config '" + kind + "': list file unreadable, built-in list in use: " + ex.Message));
				return parse(arg) ?? new List<T>();
			}
		}
	}
	internal static class ConfigValidation
	{
		public static List<string> ValidateTurrets(List<TurretConfig> list)
		{
			List<string> list2 = new List<string>();
			HashSet<string> hashSet = new HashSet<string>();
			for (int num = list.Count - 1; num >= 0; num--)
			{
				TurretConfig turretConfig = list[num];
				string text = (string.IsNullOrEmpty(turretConfig.name) ? $"entry #{num}" : turretConfig.name);
				TurretType result;
				if (string.IsNullOrEmpty(turretConfig.name))
				{
					list2.Add(text + ": missing name, entry skipped");
					list.RemoveAt(num);
				}
				else if (!hashSet.Add(turretConfig.name))
				{
					list2.Add(text + ": duplicate name, later entry skipped");
					list.RemoveAt(num);
				}
				else if (string.IsNullOrEmpty(turretConfig.type) || !Enum.TryParse<TurretType>(turretConfig.type, ignoreCase: true, out result))
				{
					list2.Add(text + ": unknown type '" + turretConfig.type + "', entry skipped");
					list.RemoveAt(num);
				}
				else if (string.IsNullOrEmpty(turretConfig.bundleName) || string.IsNullOrEmpty(turretConfig.prefabPath))
				{
					list2.Add(text + ": bundleName and prefabPath are required, entry skipped");
					list.RemoveAt(num);
				}
				else
				{
					if (turretConfig.range < 0f)
					{
						list2.Add($"{text}: range {turretConfig.range} clamped to 0");
						turretConfig.range = 0f;
					}
					if (turretConfig.minimumRange < 0f)
					{
						list2.Add($"{text}: minimumRange {turretConfig.minimumRange} clamped to 0");
						turretConfig.minimumRange = 0f;
					}
					if (turretConfig.fireInterval <= 0f)
					{
						list2.Add($"{text}: fireInterval {turretConfig.fireInterval} set to 0.1");
						turretConfig.fireInterval = 0.1f;
					}
					if (turretConfig.reloadTime < 0f)
					{
						list2.Add($"{text}: reloadTime {turretConfig.reloadTime} clamped to 0");
						turretConfig.reloadTime = 0f;
					}
					if (turretConfig.ammoCount < 0)
					{
						list2.Add($"{text}: ammoCount {turretConfig.ammoCount} clamped to 0");
						turretConfig.ammoCount = 0;
					}
					if (turretConfig.maximumNumberOfTrackedTargets < 1)
					{
						list2.Add($"{text}: maximumNumberOfTrackedTargets {turretConfig.maximumNumberOfTrackedTargets} set to 1");
						turretConfig.maximumNumberOfTrackedTargets = 1;
					}
					if (turretConfig.damageRadius < 0f)
					{
						list2.Add($"{text}: damageRadius {turretConfig.damageRadius} clamped to 0");
						turretConfig.damageRadius = 0f;
					}
					ClampDamage(text, "damage", ref turretConfig.damage, list2);
					ClampDamage(text, "bluntDamage", ref turretConfig.bluntDamage, list2);
					ClampDamage(text, "pierceDamage", ref turretConfig.pierceDamage, list2);
					ClampDamage(text, "chopDamage", ref turretConfig.chopDamage, list2);
					ClampDamage(text, "pickaxeDamage", ref turretConfig.pickaxeDamage, list2);
					ClampDamage(text, "fireDamage", ref turretConfig.fireDamage, list2);
					ClampDamage(text, "frostDamage", ref turretConfig.frostDamage, list2);
					ClampDamage(text, "lightningDamage", ref turretConfig.lightningDamage, list2);
					ClampDamage(text, "poisonDamage", ref turretConfig.poisonDamage, list2);
					ClampDamage(text, "spiritDamage", ref turretConfig.spiritDamage, list2);
					ClampDamage(text, "rangedDamage", ref turretConfig.rangedDamage, list2);
					ClampDamage(text, "rangedBluntDamage", ref turretConfig.rangedBluntDamage, list2);
					ClampDamage(text, "rangedPierceDamage", ref turretConfig.rangedPierceDamage, list2);
					ClampDamage(text, "rangedChopDamage", ref turretConfig.rangedChopDamage, list2);
					ClampDamage(text, "rangedPickaxeDamage", ref turretConfig.rangedPickaxeDamage, list2);
					ClampDamage(text, "rangedFireDamage", ref turretConfig.rangedFireDamage, list2);
					ClampDamage(text, "rangedFrostDamage", ref turretConfig.rangedFrostDamage, list2);
					ClampDamage(text, "rangedLightningDamage", ref turretConfig.rangedLightningDamage, list2);
					ClampDamage(text, "rangedPoisonDamage", ref turretConfig.rangedPoisonDamage, list2);
					ClampDamage(text, "rangedSpiritDamage", ref turretConfig.rangedSpiritDamage, list2);
					if (turretConfig.resources == null)
					{
						list2.Add(text + ": resources missing, piece will have no build cost");
						turretConfig.resources = new List<TurretConfigRequirement>();
					}
					else
					{
						for (int num2 = turretConfig.resources.Count - 1; num2 >= 0; num2--)
						{
							TurretConfigRequirement turretConfigRequirement = turretConfig.resources[num2];
							if (turretConfigRequirement == null || string.IsNullOrEmpty(turretConfigRequirement.item))
							{
								list2.Add(text + ": resource without item name removed");
								turretConfig.resources.RemoveAt(num2);
							}
							else if (turretConfigRequirement.amount < 1)
							{
								list2.Add($"{text}: resource '{turretConfigRequirement.item}' amount {turretConfigRequirement.amount} set to 1");
								turretConfigRequirement.amount = 1;
							}
						}
					}
				}
			}
			return list2;
		}

		public static List<string> ValidateBuildingparts(List<BuildingpartConfig> list)
		{
			List<string> list2 = new List<string>();
			HashSet<string> hashSet = new HashSet<string>();
			for (int num = list.Count - 1; num >= 0; num--)
			{
				BuildingpartConfig buildingpartConfig = list[num];
				string text = (string.IsNullOrEmpty(buildingpartConfig.name) ? $"entry #{num}" : buildingpartConfig.name);
				BuildingpartType result;
				if (string.IsNullOrEmpty(buildingpartConfig.name))
				{
					list2.Add(text + ": missing name, entry skipped");
					list.RemoveAt(num);
				}
				else if (!hashSet.Add(buildingpartConfig.name))
				{
					list2.Add(text + ": duplicate name, later entry skipped");
					list.RemoveAt(num);
				}
				else if (string.IsNullOrEmpty(buildingpartConfig.type) || !Enum.TryParse<BuildingpartType>(buildingpartConfig.type, ignoreCase: true, out result))
				{
					list2.Add(text + ": unknown type '" + buildingpartConfig.type + "', entry skipped");
					list.RemoveAt(num);
				}
				else if (string.IsNullOrEmpty(buildingpartConfig.bundleName) || string.IsNullOrEmpty(buildingpartConfig.prefabPath))
				{
					list2.Add(text + ": bundleName and prefabPath are required, entry skipped");
					list.RemoveAt(num);
				}
				else if (buildingpartConfig.resources == null)
				{
					list2.Add(text + ": resources missing, piece will have no build cost");
					buildingpartConfig.resources = new List<BuildingpartConfigRequirement>();
				}
				else
				{
					for (int num2 = buildingpartConfig.resources.Count - 1; num2 >= 0; num2--)
					{
						BuildingpartConfigRequirement buildingpartConfigRequirement = buildingpartConfig.resources[num2];
						if (buildingpartConfigRequirement == null || string.IsNullOrEmpty(buildingpartConfigRequirement.item))
						{
							list2.Add(text + ": resource without item name removed");
							buildingpartConfig.resources.RemoveAt(num2);
						}
						else if (buildingpartConfigRequirement.amount < 1)
						{
							list2.Add($"{text}: resource '{buildingpartConfigRequirement.item}' amount {buildingpartConfigRequirement.amount} set to 1");
							buildingpartConfigRequirement.amount = 1;
						}
					}
				}
			}
			return list2;
		}

		private static void ClampDamage(string label, string field, ref float value, List<string> warnings)
		{
			if (value < 0f)
			{
				warnings.Add($"{label}: {field} {value} clamped to 0");
				value = 0f;
			}
		}
	}
	internal class TurretConfigManager
	{
		public static List<TurretConfig> LoadTurretConfigJsonFromResource(string resourceName)
		{
			string json;
			using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
			{
				using StreamReader streamReader = new StreamReader(stream);
				json = streamReader.ReadToEnd();
			}
			return Parse(json);
		}

		public static List<TurretConfig> Parse(string json)
		{
			return SimpleJson.DeserializeObject<List<TurretConfig>>(json);
		}
	}
}
namespace ZarkowTurretDefense.Scripts
{
	internal class AdvancedGunTurret : TurretBase
	{
		private GameObject _projectilePrefabGameObject;

		private GameObject _projectileExplosionEffectPrefab;

		private GameObject _projectileExplosionEffectLightPrefab;

		private readonly List<Projectile> _projectileList = new List<Projectile>();

		protected override void RegisterRemoteProcedureCalls()
		{
			_zNetView.Register<int, int>("ZTD_LaunchAdvancedProjectile", (Action<long, int, int>)RPC_LaunchAdvancedProjectile);
			_zNetView.Register<int, Vector3, Vector3, bool>("ZTD_DetonateAdvancedProjectile", (Method<int, Vector3, Vector3, bool>)RPC_DetonateAdvancedProjectile);
		}

		protected override void GetSpecialBodyPartsOfTurret()
		{
			_lightYellow = HelperLib.GetChildGameObject(((Component)this).gameObject, "Light (Yellow)");
			_lightRed = HelperLib.GetChildGameObject(((Component)this).gameObject, "Light (Red)");
			_lightLaser = HelperLib.GetChildGameObject(((Component)this).gameObject, "Light (Laser)");
			if (ZTurretDefense.DisableTurretLight.Value)
			{
				HelperLib.DisableLightsOnGameObjectAndChildren(_lightYellow);
				HelperLib.DisableLightsOnGameObjectAndChildren(_lightRed);
			}
			_projectilePrefabGameObject = HelperLib.GetChildGameObject(((Component)this).gameObject, "ProjectilePrefab");
			_projectileExplosionEffectPrefab = HelperLib.GetChildGameObject(((Component)this).gameObject, "ProjectileImpactEffect");
			_projectileExplosionEffectLightPrefab = HelperLib.GetChildGameObject(((Component)this).gameObject, "ProjectileImpactEffectLight");
		}

		protected override void SetUpTurretSpecificData()
		{
			_rotationDefinitions.MaxRotationHorizontalLeft = 90f;
			_rotationDefinitions.MaxRotationHorizontalRight = 90f;
			_rotationDefinitions.MaxRotationVerticalUp = 15f;
			_rotationDefinitions.MaxRotationVerticalDown = 20f;
			_rotationDefinitions.RotationSpeed = 60f;
			_rotationDefinitions.AllowedAimDeviance = 15f;
			int num = 50;
			for (int i = 0; i < num; i++)
			{
				Projectile projectile = new Projectile
				{
					Id = i,
					ProjectileGameObject = Object.Instantiate<GameObject>(_projectilePrefabGameObject, ((Component)this).transform.root)
				};
				projectile.ProjectileGameObject.SetActive(false);
				_projectileList.Add(projectile);
			}
		}

		protected override void SwitchOwnershipHandling()
		{
			AddDebugMsg($"AdvancedGunTurret.SwitchOwnershipHandling({base.IsOwner})");
			foreach (Projectile projectile in _projectileList)
			{
				projectile.OwnerHasActiveControl = false;
				if (projectile.AnnouncedAndVisible)
				{
					RemoveProjectileFromWorld(projectile);
				}
			}
		}

		protected override void SyncTurretNetData()
		{
			//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_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			if (!_netDataObjectHandler.HasDataToRead)
			{
				return;
			}
			base.SyncTurretNetData();
			foreach (Projectile projectile in _projectileList)
			{
				if (projectile.AnnouncedAndVisible)
				{
					projectile.ProjectileGameObject.transform.position = _netDataObjectHandler.Data.GetVec3($"projectile_{projectile.Id}.position", Vector3.zero);
					projectile.ProjectileGameObject.transform.rotation = _netDataObjectHandler.Data.GetQuaternion($"projectile_{projectile.Id}.rotation", Quaternion.identity);
				}
			}
		}

		protected override bool UpdateAimInfoForCurrentTarget()
		{
			return HelperLib.UpdateAimInfoForCurrentTarget(_targetList[0], _turretAimPoint, _aimResult, _aimResultTempCalcHolder, ProjectileVelocity);
		}

		protected override void TriggerTurretFiring()
		{
			if (_barrelList == null)
			{
				AddWarningMsg("AdvancedGunTurret.TriggerTurretFiring() - _barrelList == null");
				return;
			}
			if (_nextBarrelIdToUse > _barrelList.Count)
			{
				AddWarningMsg($"AdvancedGunTurret.TriggerTurretFiring() - if (_nextBarrelIdToUse > _barrelList.Count) : if ({_nextBarrelIdToUse} > {_barrelList.Count})");
				return;
			}
			_nextShootDelayTimer += FireInterval;
			if (_nextShootDelayTimer < FireInterval / 2f)
			{
				_nextShootDelayTimer = FireInterval / 2f;
			}
			Projectile nextAvailableProjectile = GetNextAvailableProjectile();
			if (nextAvailableProjectile == null)
			{
				AddWarningMsg($"AdvancedGunTurret.TriggerTurretFiring() - No projectiles available, skipping (We have {_projectileList.Count} projectiles cached)");
			}
			if (nextAvailableProjectile != null)
			{
				nextAvailableProjectile.OwnerHasActiveControl = true;
				_zNetView.InvokeRPC(ZNetView.Everybody, "ZTD_LaunchAdvancedProjectile", new object[2] { _nextBarrelIdToUse, nextAvailableProjectile.Id });
			}
			_nextBarrelIdToUse++;
			if (_nextBarrelIdToUse >= _barrelList.Count)
			{
				_nextBarrelIdToUse = 0;
			}
		}

		private Projectile GetNextAvailableProjectile()
		{
			foreach (Projectile projectile in _projectileList)
			{
				if (!projectile.OwnerHasActiveControl)
				{
					return projectile;
				}
			}
			return null;
		}

		protected override void ControlAndMoveMissilesOrProjectilesOrDrones()
		{
			foreach (Projectile projectile in _projectileList)
			{
				if (projectile.OwnerHasActiveControl)
				{
					ControlAndMoveProjectile(projectile);
				}
			}
		}

		private void ControlAndMoveProjectile(Projectile projectile)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = projectile.ProjectileGameObject.transform.position;
			Transform transform = projectile.ProjectileGameObject.transform;
			transform.position += projectile.ProjectileGameObject.transform.forward * ProjectileVelocity * Time.deltaTime;
			float num = Vector3.Distance(position, projectile.ProjectileGameObject.transform.position);
			RaycastHit[] array = Physics.RaycastAll(new Ray(position, projectile.ProjectileGameObject.transform.forward), num, _rayMaskSolids);
			if (array.Length == 0 || !HandleProjectileHits(array, projectile))
			{
				SetDataToDataObject(projectile);
				if (Vector3.Distance(((Component)this).transform.position, projectile.ProjectileGameObject.transform.position) > Range * 5f)
				{
					DetonateProjectile(projectile, projectile.ProjectileGameObject.transform.position, destroyProjectile: true);
				}
			}
		}

		private bool HandleProjectileHits(RaycastHit[] hits, Projectile projectile)
		{
			//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_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: 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_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: 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)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: 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_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: 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_02d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_034e: 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_0364: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_0424: Unknown result type (might be due to invalid IL or missing references)
			//IL_0430: Unknown result type (might be due to invalid IL or missing references)
			//IL_043a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0452: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
			List<RaycastHit> list = new List<RaycastHit>(hits);
			list.Sort((RaycastHit x, RaycastHit y) => ((RaycastHit)(ref x)).distance.CompareTo(((RaycastHit)(ref y)).distance));
			foreach (RaycastHit item in list)
			{
				RaycastHit current = item;
				Character component = ((Component)((Component)((RaycastHit)(ref current)).collider).transform.root).gameObject.GetComponent<Character>();
				if ((Object)(object)component != (Object)null)
				{
					HitData val = _hitData.Clone();
					val.m_hitCollider = ((RaycastHit)(ref current)).collider;
					val.m_point = ((RaycastHit)(ref current)).point;
					Quaternion rotation = projectile.ProjectileGameObject.transform.rotation;
					val.m_dir = ((Quaternion)(ref rotation)).eulerAngles;
					ApplyDamageToCharacterHit(component, val);
					DetonateProjectile(projectile, new Vector3(((RaycastHit)(ref current)).point.x, ((RaycastHit)(ref current)).point.y, ((RaycastHit)(ref current)).point.z), destroyProjectile: false);
					continue;
				}
				float num = (_hitData.m_damage.m_blunt + _hitData.m_damage.m_pierce + _hitData.m_damage.m_fire) * 0.75f;
				HitData val2 = _hitData.Clone();
				val2.m_hitCollider = ((RaycastHit)(ref current)).collider;
				val2.m_point = ((RaycastHit)(ref current)).point;
				val2.m_damage.m_blunt = 0f;
				val2.m_damage.m_slash = 0f;
				val2.m_damage.m_pierce = 0f;
				val2.m_damage.m_chop = num * 0.35f;
				val2.m_damage.m_pickaxe = num * 0.35f;
				val2.m_damage.m_fire = num;
				val2.m_damage.m_frost = 0f;
				val2.m_damage.m_lightning = 0f;
				val2.m_damage.m_poison = 0f;
				val2.m_damage.m_spirit = 0f;
				val2.m_toolTier = 10;
				val2.m_pushForce = 0f;
				TreeBase component2 = ((Component)((RaycastHit)(ref current)).transform.root).gameObject.GetComponent<TreeBase>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.Damage(val2);
					DetonateProjectile(projectile, new Vector3(((RaycastHit)(ref current)).point.x, ((RaycastHit)(ref current)).point.y, ((RaycastHit)(ref current)).point.z), destroyProjectile: true);
					projectile.ProjectileGameObject.transform.position = ((RaycastHit)(ref current)).point;
					SetDataToDataObject(projectile);
					return true;
				}
				TreeLog component3 = ((Component)((RaycastHit)(ref current)).transform.root).gameObject.GetComponent<TreeLog>();
				if ((Object)(object)component3 != (Object)null)
				{
					component3.Damage(val2);
					DetonateProjectile(projectile, new Vector3(((RaycastHit)(ref current)).point.x, ((RaycastHit)(ref current)).point.y, ((RaycastHit)(ref current)).point.z), destroyProjectile: true);
					projectile.ProjectileGameObject.transform.position = ((RaycastHit)(ref current)).point;
					SetDataToDataObject(projectile);
					return true;
				}
				Destructible component4 = ((Component)((RaycastHit)(ref current)).transform.root).gameObject.GetComponent<Destructible>();
				if ((Object)(object)component4 != (Object)null)
				{
					component4.Damage(val2);
					DetonateProjectile(projectile, new Vector3(((RaycastHit)(ref current)).point.x, ((RaycastHit)(ref current)).point.y, ((RaycastHit)(ref current)).point.z), destroyProjectile: true);
					projectile.ProjectileGameObject.transform.position = ((RaycastHit)(ref current)).point;
					SetDataToDataObject(projectile);
					return true;
				}
				MineRock5 component5 = ((Component)((RaycastHit)(ref current)).transform.root).gameObject.GetComponent<MineRock5>();
				if ((Object)(object)component5 != (Object)null)
				{
					component5.Damage(val2);
					DetonateProjectile(projectile, new Vector3(((RaycastHit)(ref current)).point.x, ((RaycastHit)(ref current)).point.y, ((RaycastHit)(ref current)).point.z), destroyProjectile: true);
					projectile.ProjectileGameObject.transform.position = ((RaycastHit)(ref current)).point;
					SetDataToDataObject(projectile);
					return true;
				}
				DetonateProjectile(projectile, new Vector3(((RaycastHit)(ref current)).point.x, ((RaycastHit)(ref current)).point.y, ((RaycastHit)(ref current)).point.z), destroyProjectile: true);
				projectile.ProjectileGameObject.transform.position = ((RaycastHit)(ref current)).point;
				SetDataToDataObject(projectile);
				return true;
			}
			return false;
		}

		private void SetDataToDataObject(Projectile projectile)
		{
			//IL_002b: 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)
			_netDataObjectHandler.Data.Set($"projectile_{projectile.Id}.position", projectile.ProjectileGameObject.transform.position);
			_netDataObjectHandler.Data.Set($"projectile_{projectile.Id}.rotation", projectile.ProjectileGameObject.transform.rotation);
		}

		private void DetonateProjectile(Projectile projectile, Vector3 impactLocation, bool destroyProjectile)
		{
			//IL_0030: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			if (destroyProjectile)
			{
				projectile.OwnerHasActiveControl = false;
			}
			_zNetView.InvokeRPC(ZNetView.Everybody, "ZTD_DetonateAdvancedProjectile", new object[4]
			{
				projectile.Id,
				impactLocation,
				Vector3.up,
				destroyProjectile
			});
			DamageAreaTargets(impactLocation, _rangedHitData, onlyDamageCharacters: false);
		}

		private void RPC_LaunchAdvancedProjectile(long sender, int barrelId, int projectileId)
		{
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			if (_barrelList != null && barrelId + 1 <= _barrelList.Count)
			{
				Barrel barrel = _barrelList[barrelId];
				GameObject obj = Object.Instantiate<GameObject>(barrel.LaunchEffectGameObject, barrel.ThisBarrelGameObject.transform, false);
				obj.transform.SetParent((Transform)null);
				Object.Destroy((Object)(object)obj, 5f);
				obj.SetActive(true);
				GameObject obj2 = Object.Instantiate<GameObject>(barrel.LaunchAudioGameObject, barrel.ThisBarrelGameObject.transform, false);
				obj2.transform.SetParent((Transform)null);
				Object.Destroy((Object)(object)obj2, 5f);
				obj2.SetActive(true);
				Projectile projectileFromId = GetProjectileFromId(projectileId);
				if (projectileFromId == null)
				{
					AddWarningMsg($"AdvancedGunTurret.RPC_LaunchAdvancedProjectile: projectile is null, as it cannot be found from id {projectileId} -- aborting visual");
					return;
				}
				projectileFromId.ProjectileGameObject.transform.SetPositionAndRotation(barrel.ThisBarrelGameObject.transform.position, barrel.ThisBarrelGameObject.transform.rotation);
				projectileFromId.ProjectileGameObject.SetActive(false);
				projectileFromId.ProjectileGameObject.SetActive(true);
				projectileFromId.AnnouncedAndVisible = true;
			}
		}

		private Projectile GetProjectileFromId(int id)
		{
			foreach (Projectile projectile in _projectileList)
			{
				if (id == projectile.Id)
				{
					return projectile;
				}
			}
			return null;
		}

		private void RPC_DetonateAdvancedProjectile(long sender, int projectileId, Vector3 detonateLocation, Vector3 direction, bool destroyProjectile)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0080: 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)
			if (destroyProjectile)
			{
				Projectile projectileFromId = GetProjectileFromId(projectileId);
				RemoveProjectileFromWorld(projectileFromId);
			}
			Quaternion rotation = default(Quaternion);
			((Quaternion)(ref rotation)).SetLookRotation(direction);
			GameObject obj = Object.Instantiate<GameObject>(_projectileExplosionEffectPrefab, (Transform)null);
			obj.transform.position = detonateLocation;
			obj.transform.rotation = rotation;
			obj.SetActive(false);
			obj.SetActive(true);
			Object.Destroy((Object)(object)obj, 5f);
			if ((Object)(object)_projectileExplosionEffectLightPrefab != (Object)null)
			{
				GameObject obj2 = Object.Instantiate<GameObject>(_projectileExplosionEffectLightPrefab, (Transform)null);
				obj2.transform.position = detonateLocation;
				obj2.transform.rotation = rotation;
				obj2.SetActive(false);
				obj2.SetActive(true);
				Object.Destroy((Object)(object)obj2, 0.6f);
			}
		}

		private void RemoveProjectileFromWorld(Projectile projectile)
		{
			projectile.ProjectileGameObject.SetActive(false);
			projectile.AnnouncedAndVisible = false;
		}
	}
	public class Barrel
	{
		public int Id;

		public GameObject ThisBarrelGameObject;

		public GameObject LaunchEffectGameObject;

		public GameObject LaunchAudioGameObject;

		public Barrel(int id, GameObject thisGameObject, GameObject launchEffectGameObject, GameObject launchAudioGameObject)
		{
			Id = id;
			ThisBarrelGameObject = thisGameObject;
			LaunchEffectGameObject = launchEffectGameObject;
			LaunchAudioGameObject = launchAudioGameObject;
		}
	}
	public class BuildingpartBase : MonoBehaviour
	{
		public float Range = 20f;

		public float MinimumRange;

		public BuildingpartType BuildingpartTypeOfThisBuildingpart;

		protected HitData _hitData;

		private readonly int _viewBlockMask = LayerMask.GetMask(new string[7] { "Default", "static_solid", "Default_small", "piece", "terrain", "viewblock", "vehicle" });

		private readonly int _viewBlockMaskPlayersCharactersOnly = LayerMask.GetMask(new string[4] { "character", "character_net", "character_ghost", "character_noenv" });

		protected readonly int _rayMaskSolids = LayerMask.GetMask(new string[12]
		{
			"Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "terrain", "character", "character_net", "character_ghost", "hitbox",
			"character_noenv", "vehicle"
		});

		protected DegreesSpecifier _aimResult;

		protected DegreesSpecifier _aimResultTempCalcHolder;

		protected RotationDefinitions _rotationDefinitions;

		protected RotationData _rotationData = new RotationData();

		protected ZNetView _zNetView;

		protected ZDO _zDataObject;

		protected NetDataObjectHandler _netDataObjectHandler;

		private bool _everSeenHeightmap;

		public bool IsOwner
		{
			get
			{
				if ((Object)(object)_zNetView == (Object)null || !_zNetView.IsOwner())
				{
					return false;
				}
				return true;
			}
		}

		private void Awake()
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			_zNetView = ((Component)this).GetComponent<ZNetView>();
			_zDataObject = _zNetView.GetZDO();
			_netDataObjectHandler = new NetDataObjectHandler(_zDataObject);
			RegisterRemoteProcedureCalls();
			GetBasicBodyPartsOfBuildingpart();
			GetSpecialBodyPartsOfBuildingpart();
			_aimResult = new DegreesSpecifier();
			_aimResultTempCalcHolder = new DegreesSpecifier();
			Heightmap val = Heightmap.FindHeightmap(((Component)this).transform.position);
			if (ZTurretDefense.ShowHeightMapDebugLogEntries.Value)
			{
				string message = string.Format("{0}.Awake() ({1}) -- Heightmap loaded: {2} ({3} heightmaps loaded), position: {4}{5}", BuildingpartTypeOfThisBuildingpart, ((Object)((Component)this).gameObject).name, (Object)(object)val != (Object)null, Heightmap.s_heightmaps.Count, ((Component)this).transform.position, _zNetView.m_distant ? "-- Flagged as distant" : "");
				if ((Object)(object)val == (Object)null)
				{
					AddWarningMsg(message);
				}
				else
				{
					AddLogInfo(message);
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				_everSeenHeightmap = true;
			}
		}

		protected virtual void RegisterRemoteProcedureCalls()
		{
		}

		protected virtual void GetBasicBodyPartsOfBuildingpart()
		{
			if (ZTurretDefense.DisableBuildingpartsLight.Value)
			{
				HelperLib.DisableLightsOnGameObjectAndChildren(((Component)this).gameObject);
			}
		}

		protected virtual void GetSpecialBodyPartsOfBuildingpart()
		{
		}

		protected void AddLogMsg(string message)
		{
			Logger.LogMessage((object)$"{DateTime.Now:o} ### Buildingpart[{((Object)((Component)this).gameObject).GetInstanceID()}]: {message}");
		}

		protected void AddDebugMsg(string message)
		{
			Logger.LogDebug((object)$"{DateTime.Now:o} ### Buildingpart[{((Object)((Component)this).gameObject).GetInstanceID()}]: {message}");
		}

		protected void AddLogInfo(string message)
		{
			Logger.LogInfo((object)$"{DateTime.Now:o} ### Buildingpart[{((Object)((Component)this).gameObject).GetInstanceID()}]: {message}");
		}

		protected void AddWarningMsg(string message)
		{
			Logger.LogWarning((object)$"{DateTime.Now:o} ### Buildingpart[{((Object)((Component)this).gameObject).GetInstanceID()}]: {message}");
		}

		public void Initialize(BuildingpartConfig buildingpartConfig)
		{
			BuildingpartTypeOfThisBuildingpart = (BuildingpartType)Enum.Parse(typeof(BuildingpartType), buildingpartConfig.type, ignoreCase: true);
		}

		private void OnDestroy()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (ZTurretDefense.ShowObjectDestroyDebugLogEntries.Value)
			{
				AddLogInfo($"OnDestroy({((Object)((Component)this).gameObject).name}, {((Component)this).transform.position}) ");
			}
		}

		private void Update()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			if (!_everSeenHeightmap)
			{
				Heightmap val = Heightmap.FindHeightmap(((Component)this).transform.position);
				if ((Object)(object)val != (Object)null)
				{
					if (ZTurretDefense.ShowHeightMapDebugLogEntries.Value)
					{
						AddWarningMsg($"{BuildingpartTypeOfThisBuildingpart}.Update() -- Finally got it >> Heightmap.FindHeightmap{((Component)this).transform.position} return  map {((Object)val).GetInstanceID()}, distantLod: {val.IsDistantLod}, bounds: {val.m_bounds}, width: {val.m_width}");
					}
					((Component)this).gameObject.GetComponent<WearNTear>().Start();
					_everSeenHeightmap = true;
				}
			}
			if ((Object)(object)_zNetView == (Object)null || !_zNetView.IsOwner())
			{
				SyncTurretNetData();
				_netDataObjectHandler.ReceiveDone();
			}
		}

		protected virtual void SyncTurretNetData()
		{
			_ = _netDataObjectHandler.HasDataToRead;
		}
	}
	public class DegreesSpecifier
	{
		public float DegreesY { get; set; }

		public float DegreesX { get; set; }

		public float Distance { get; set; }
	}
	public class DroneTurret : TurretBase
	{
		protected GameObject _droneGameObject;

		protected GameObject _droneSensorGameObject;

		protected GameObject _droneTurn;

		protected GameObject _droneTilt;

		protected GameObject _droneAimPoint;

		protected GameObject _droneLight;

		protected RotationDefinitions _droneRotationDefinitions;

		protected DegreesSpecifier _droneAimResult;

		private readonly RotationData _droneRotationData = new RotationData();

		protected Target _droneTarget;

		protected readonly float _droneMaxSpeed = 10f;

		protected float _droneSpeed;

		protected TurretPatrolType _droneMode = TurretPatrolType.ScanTarget;

		protected readonly int _rayMaskDroneDownCheck = LayerMask.GetMask(new string[5] { "Default", "static_solid", "Default_small", "piece", "terrain" });

		protected int _inactivityToRestCounter = 3;

		protected override void RegisterRemoteProcedureCalls()
		{
			_zNetView.Register<Vector3, Vector3>("ZTD_LaunchDroneCannonProjectile", (Action<long, Vector3, Vector3>)RPC_LaunchDroneCannonProjectile);
		}

		protected override void GetSpecialBodyPartsOfTurret()
		{
			_lightYellow = HelperLib.GetChildGameObject(((Component)this).gameObject, "Light (Yellow)");
			_lightRed = HelperLib.GetChildGameObject(((Component)this).gameObject, "Light (Red)");
			_lightLaser = HelperLib.GetChildGameObject(((Component)this).gameObject, "Light (Laser)");
			_dirtImpactPrefab = HelperLib.GetChildGameObject(((Component)this).gameObject, "DirtImpact");
			_droneGameObject = HelperLib.GetChildGameObject(((Component)this).gameObject, "Drone");
			_droneSensorGameObject = HelperLib.GetChildGameObject(_droneGameObject, "DroneSensor");
			if (ZTurretDefense.DisableDroneLight.Value)
			{
				HelperLib.DisableLightsOnGameObjectAndChildren(_droneSensorGameObject);
			}
			_droneTurn = HelperLib.GetChildGameObject(_droneGameObject, "DroneTurn");
			_droneTilt = HelperLib.GetChildGameObject(_droneGameObject, "DroneTilt");
			_droneAimPoint = HelperLib.GetChildGameObject(_droneGameObject, "DroneAimPoint");
			_droneLight = HelperLib.GetChildGameObject(_droneGameObject, "DroneSensorLight");
		}

		protected override void SetUpTurretSpecificData()
		{
			_rotationDefinitions.MaxRotationHorizontalLeft = 180f;
			_rotationDefinitions.MaxRotationHorizontalRight = 180f;
			_rotationDefinitions.MaxRotationVerticalUp = 0.1f;
			_rotationDefinitions.MaxRotationVerticalDown = 0.1f;
			_rotationDefinitions.RotationSpeed = 360f;
			_rotationDefinitions.AllowedAimDeviance = 180f;
			_droneRotationDefinitions.MaxRotationHorizontalLeft = 45f;
			_droneRotationDefinitions.MaxRotationHorizontalRight = 45f;
			_droneRotationDefinitions.MaxRotationVerticalUp = 5f;
			_droneRotationDefinitions.MaxRotationVerticalDown = 65f;
			_droneRotationDefinitions.RotationSpeed = 35f;
			_droneRotationDefinitions.AllowedAimDeviance = 25f;
			_droneAimResult = new DegreesSpecifier();
		}

		protected override void SyncTurretNetData()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			if (_netDataObjectHandler.HasDataToRead)
			{
				base.SyncTurretNetData();
				_droneGameObject.transform.position = _netDataObjectHandler.Data.GetVec3("_droneGameObject.position", Vector3.zero);
				_droneGameObject.transform.rotation = _netDataObjectHandler.Data.GetQuaternion("_droneGameObject.rotation", Quaternion.identity);
				_droneTurn.transform.rotation = _netDataObjectHandler.Data.GetQuaternion("_droneTurn.rotation", Quaternion.identity);
				_droneTilt.transform.rotation = _netDataObjectHandler.Data.GetQuaternion("_droneTilt.rotation", Quaternion.identity);
				_droneSensorGameObject.transform.rotation = _netDataObjectHandler.Data.GetQuaternion("_droneSensorGameObject.rotation", Quaternion.identity);
			}
		}

		protected override void ControlAndMoveMissilesOrProjectilesOrDrones()
		{
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			if (_droneTarget == null)
			{
				_droneTarget = _targetList.FirstOrDefault();
				if (_droneTarget != null)
				{
					_inactivityToRestCounter = 3;
					if (_droneTarget.TimeToLive <= 0f)
					{
						_droneTarget.TimeToLive = 10f;
					}
					UpdateDroneMode(TurretPatrolType.ScanTarget);
				}
			}
			if (_droneTarget == null && _inactivityToRestCounter > 0)
			{
				if (PatrolCloseToTurret && _inactivityToRestCounter > 0)
				{
					_inactivityToRestCounter--;
				}
				Vector2 val = Random.insideUnitCircle * (PatrolCloseToTurret ? (Range * 0.1f) : Range);
				Vector3 val2 = default(Vector3);
				((Vector3)(ref val2))..ctor(((Component)this).transform.position.x + val.x, ((Component)this).transform.position.y + 250f, ((Component)this).transform.position.z + val.y);
				RaycastHit val3 = default(RaycastHit);
				if (Physics.Raycast(new Ray(val2, Vector3.down), ref val3, 500f, _rayMaskDroneDownCheck))
				{
					float num = ((RaycastHit)(ref val3)).point.y + 5f;
					if (num < 35f)
					{
						num = 35f;
					}
					Vector3 location = default(Vector3);
					((Vector3)(ref location))..ctor(((RaycastHit)(ref val3)).point.x, num, ((RaycastHit)(ref val3)).point.z);
					Target droneTarget = new Target
					{
						Location = location,
						IsMoveOrder = true,
						TimeToLive = 15f
					};
					_droneTarget = droneTarget;
					UpdateDroneMode(TurretPatrolType.NoTarget);
				}
			}
			else if (_droneTarget == null && _inactivityToRestCounter == 0)
			{
				Target droneTarget2 = new Target
				{
					Location = new Vector3(_turretAimPoint.transform.position.x, _turretAimPoint.transform.position.y + 2f, _turretAimPoint.transform.position.z),
					IsMoveOrder = true,
					TimeToLive = 10f
				};
				_droneTarget = droneTarget2;
				UpdateDroneMode(TurretPatrolType.NoTarget);
				_inactivityToRestCounter--;
			}
			else if (_droneTarget == null && _inactivityToRestCounter == -1)
			{
				Target droneTarget3 = new Target
				{
					Location = new Vector3(_turretAimPoint.transform.position.x, _turretAimPoint.transform.position.y, _turretAimPoint.transform.position.z),
					IsMoveOrder = true,
					TimeToLive = 10f
				};
				_droneTarget = droneTarget3;
				UpdateDroneMode(TurretPatrolType.NoTarget);
				_inactivityToRestCounter--;
			}
			if (_droneTarget == null)
			{
				return;
			}
			if (_droneTarget.TimeToLive > 0f)
			{
				_droneTarget.TimeToLive -= Time.deltaTime;
			}
			if (_droneTarget.IsMoveOrder)
			{
				if (MoveTowardsTargetDestination(_droneTarget) && _droneTarget.TimeToLive <= 0f)
				{
					_droneTarget = null;
				}
				else if (_targetList.Count > 0)
				{
					_droneTarget.TimeToLive = -999f;
				}
				SetDataToDataObject();
			}
			else if (_droneTarget.IsTargetWearAndTearOrder)
			{
				if (MoveAndHandleWearAndTear(_droneTarget))
				{
					_targetList.Remove(_droneTarget);
					_droneTarget = null;
				}
				SetDataToDataObject();
			}
			else if (_droneTarget.IsTargetLoggerOrder)
			{
				if (MoveAndHandleTreesAndLogsAndStubs(_droneTarget))
				{
					_targetList.Remove(_droneTarget);
					_droneTarget = null;
				}
				SetDataToDataObject();
			}
			else if (_droneTarget.IsGatherItemOrder)
			{
				if (MoveAndHandleGather(_droneTarget) || (!_droneTarget.OnGatherItemDropReturnTrip && _droneTarget.TimeToLive < 0f))
				{
					_targetList.Remove(_droneTarget);
					_droneTarget = null;
				}
				SetDataToDataObject();
			}
			else if ((Object)(object)_droneTarget.Character != (Object)null && _droneTarget.Character.GetHealth() <= 0f)
			{
				_droneTarget = null;
			}
			else
			{
				bool num2 = MoveAndAttackTarget(_droneTarget);
				SetDataToDataObject();
				if (num2)
				{
					_targetList.Remove(_droneTarget);
					_droneTarget = null;
				}
			}
		}

		private void SetDataToDataObject()
		{
			//IL_001b: 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)
			//IL_0065: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			_netDataObjectHandler.Data.Set("_droneGameObject.position", _droneGameObject.transform.position);
			_netDataObjectHandler.Data.Set("_droneGameObject.rotation", _droneGameObject.transform.rotation);
			_netDataObjectHandler.Data.Set("_droneTurn.rotation", _droneTurn.transform.rotation);
			_netDataObjectHandler.Data.Set("_droneTilt.rotation", _droneTilt.transform.rotation);
			_netDataObjectHandler.Data.Set("_droneSensorGameObject.rotation", _droneSensorGameObject.transform.rotation);
		}

		private bool MoveTowardsTargetDestination(Target target)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: 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_0163: 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_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: 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_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			if (target == null)
			{
				AddWarningMsg("DroneTurret.MoveTowardsTargetDestination() -- target is null");
				return true;
			}
			if ((Object)(object)_droneGameObject == (Object)null)
			{
				AddWarningMsg("DroneTurret.MoveTowardsTargetDestination() -- _droneGameObject is null");
				return true;
			}
			float num = Vector3.Distance(_droneGameObject.transform.position, target.Location);
			if (num > _droneSpeed + 0.1f)
			{
				_droneSpeed += Time.deltaTime * 3f;
				if (_droneSpeed > _droneMaxSpeed)
				{
					_droneSpeed = _droneMaxSpeed;
				}
			}
			else
			{
				_droneSpeed -= Time.deltaTime * 5f;
				if (_droneSpeed < 0f)
				{
					_droneSpeed = ((num > 0.45f) ? 0.25f : 0f);
				}
			}
			Vector3 val = target.Location - _droneGameObject.transform.position;
			((Vector3)(ref val)).Normalize();
			if (num > 5f)
			{
				Vector3 val2 = target.Location - _droneGameObject.transform.position;
				val2.y = 0f;
				_droneGameObject.transform.rotation = Quaternion.Slerp(_droneGameObject.transform.rotation, Quaternion.LookRotation(val2), 2.5f * Time.deltaTime);
			}
			Transform transform = _droneGameObject.transform;
			transform.position += val * _droneSpeed * Time.deltaTime;
			if (Vector3.Distance(_droneGameObject.transform.position, target.Location) < 0.5f)
			{
				target.TimeToLive -= Time.deltaTime;
				return true;
			}
			return false;
		}

		protected virtual bool MoveAndHandleWearAndTear(Target target)
		{
			AddWarningMsg($"DroneTurret.MoveAndHandleWearAndTear({target.GetHashCode()}, {target.WearAndTearPiece.m_piece.m_name}) -- Virtual, not implemented");
			return true;
		}

		protected virtual bool MoveAndHandleGather(Target target)
		{
			AddWarningMsg($"DroneTurret.MoveAndHandleGather({target.GetHashCode()}) -- Virtual, not implemented");
			return true;
		}

		protected virtual bool MoveAndHandleTreesAndLogsAndStubs(Target target)
		{
			AddWarningMsg($"DroneTurret.MoveAndHandleTreesAndLogs({target.GetHashCode()}) -- Virtual, not implemented");
			return true;
		}

		protected virtual float SetDroneMovementHeight(float heightIn)
		{
			return heightIn + (HealingTarget ? 2f : 4f);
		}

		private bool MoveAndAttackTarget(Target target)
		{
			//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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: 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_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: 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)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: 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_01d7: 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)
			if ((Object)(object)target.Character == (Object)null)
			{
				return true;
			}
			if ((Object)(object)target.Character.m_collider == (Object)null)
			{
				AddWarningMsg($"{TurretTypeOfThisTurret}.MoveAndAttackTarget({target.GetHashCode()}, {target.Character.m_name} [{((Object)target.Character).GetInstanceID()}], {target.Character.GetHealth()} hp), lacks capsule collider...");
				return false;
			}
			Vector3 centerPoint = target.Character.GetCenterPoint();
			target.Location = new Vector3(centerPoint.x, SetDroneMovementHeight(centerPoint.y), centerPoint.z);
			float num = Vector3.Distance(_droneGameObject.transform.position, target.Location);
			if (num - DroneAttackRange > _droneSpeed - 1f)
			{
				_droneSpeed += Time.deltaTime * 3f;
				if (_droneSpeed > _droneMaxSpeed)
				{
					_droneSpeed = _droneMaxSpeed;
				}
			}
			else
			{
				_droneSpeed -= Time.deltaTime * 5f;
				if (_droneSpeed < 0f)
				{
					_droneSpeed = ((num > DroneAttackRange * 0.3f) ? 0.25f : 0f);
				}
			}
			Vector3 val = target.Location - _droneGameObject.transform.position;
			((Vector3)(ref val)).Normalize();
			if (num > 0.5f)
			{
				Vector3 val2 = target.Location - _droneGameObject.transform.position;
				val2.y = 0f;
				_droneGameObject.transform.rotation = Quaternion.Slerp(_droneGameObject.transform.rotation, Quaternion.LookRotation(val2), 2.5f * Time.deltaTime);
			}
			Transform transform = _droneGameObject.transform;
			transform.position += val * _droneSpeed * Time.deltaTime;
			bool flag = CanSeeCharacter(target.Character, _droneAimPoint);
			if (Vector3.Distance(_droneGameObject.transform.position, target.Location) < DroneAttackRange && flag)
			{
				UpdateDroneMode(TurretPatrolType.AttackTarget);
			}
			else
			{
				UpdateDroneMode(TurretPatrolType.ScanTarget);
			}
			if (_droneTarget.Character.GetHealth() <= 0f)
			{
				UpdateDroneMode(TurretPatrolType.NoTarget);
				return true;
			}
			if (HealingTarget && _droneTarget.Character.GetHealthPercentage() >= 1f)
			{
				UpdateDroneMode(TurretPatrolType.NoTarget);
				return true;
			}
			if (_droneTarget.TimeToLive <= 0f)
			{
				UpdateDroneMode(TurretPatrolType.NoTarget);
				return true;
			}
			return false;
		}

		protected override void UpdateShootingIntervalAndDetermineIfWeShouldShoot()
		{
			if (_nextShootDelayTimer > 0f)
			{
				_nextShootDelayTimer -= Time.deltaTime;
			}
			if (_droneMode != TurretPatrolType.AttackTarget)
			{
				return;
			}
			if (_droneTarget.IsGatherItemOrder && _droneTarget.OnGatherItemDropReturnTrip)
			{
				if (_nextShootDelayTimer <= 0f)
				{
					TriggerTurretFiring();
				}
				return;
			}
			_droneRotationData.DistanceRotY = _droneRotationData.CurrentRotationY - _droneAimResult.DegreesY;
			_droneRotationData.DistanceRotX = _droneRotationData.CurrentRotationX - _droneAimResult.DegreesX;
			if (_nextShootDelayTimer > 0f || Math.Abs(_droneRotationData.DistanceRotY) > _droneRotationDefinitions.AllowedAimDeviance || Math.Abs(_droneRotationData.DistanceRotX) > _droneRotationDefinitions.AllowedAimDeviance || !(_nextShootDelayTimer <= 0f) || (AmmoCount > 0 && _ammoInGun == 0))
			{
				return;
			}
			TriggerTurretFiring();
			if (AmmoCount > 0)
			{
				_ammoInGun--;
				if (_ammoInGun <= 0)
				{
					_reloadGunTimer = ReloadTime;
				}
			}
		}

		protected override void TriggerTurretFiring()
		{
			//IL_0045: 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)
			_nextShootDelayTimer += FireInterval;
			if (_nextShootDelayTimer < FireInterval / 2f)
			{
				_nextShootDelayTimer = FireInterval / 2f;
			}
			LaunchProjectileAndRegisterHitPosition(_droneTilt.transform.rotation, _barrelList[0].ThisBarrelGameObject.transform.position);
		}

		protected override void LaunchProjectileAndRegisterHitPosition(Quaternion directionQuat, Vector3 barrelEdgePosition)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			RaycastHit val = default(RaycastHit);
			if (!Physics.Raycast(new Ray(barrelEdgePosition, directionQuat * Vector3.forward), ref val, Range * 2f, _rayMaskSolids))
			{
				return;
			}
			if (_hitData == null)
			{
				AddWarningMsg("LaunchProjectileAndShowHitPosition() - _hitData is null");
				return;
			}
			Character component = ((Component)((Component)((RaycastHit)(ref val)).collider).transform.root).gameObject.GetComponent<Character>();
			if ((Object)(object)component != (Object)null)
			{
				if (HealingTarget)
				{
					component.Heal(HealingAmount, true);
				}
				else
				{
					HitData val2 = _hitData.Clone();
					val2.m_hitCollider = ((RaycastHit)(ref val)).collider;
					val2.m_point = ((RaycastHit)(ref val)).point;
					val2.m_dir = ((Quaternion)(ref directionQuat)).eulerAngles;
					ApplyDamageToCharacterHit(component, val2);
				}
			}
			_zNetView.InvokeRPC(ZNetView.Everybody, "ZTD_LaunchDroneCannonProjectile", new object[2]
			{
				((RaycastHit)(ref val)).point,
				((RaycastHit)(ref val)).normal
			});
		}

		protected override void CleanTargetListAndUpdateAimInfo()
		{
			if (_targetList.Count > 0)
			{
				List<Target> list = new List<Target>();
				foreach (Target target in _targetList)
				{
					if ((Object)(object)target.Character != (Object)null && target.Character.GetHealth() <= 0f)
					{
						list.Add(target);
					}
				}
				foreach (Target item in list)
				{
					_targetList.Remove(item);
				}
			}
			if (_droneTarget == null)
			{
				UpdateDroneMode(TurretPatrolType.NoTarget);
			}
			else if (!UpdateAimInfoForCurrentTarget())
			{
				UpdateDroneMode(TurretPatrolType.NoTarget);
			}
		}

		protected void UpdateDroneMode(TurretPatrolType newMode)
		{
			if (newMode == _droneMode)
			{
				return;
			}
			_droneMode = newMode;
			if (_droneMode == TurretPatrolType.AttackTarget || _droneMode == TurretPatrolType.ScanTarget)
			{
				if ((Object)(object)_droneLight != (Object)null)
				{
					_droneLight.SetActive(true);
				}
			}
			else if ((Object)(object)_droneLight != (Object)null)
			{
				_droneLight.SetActive(false);
			}
		}

		protected override bool UpdateAimInfoForCurrentTarget()
		{
			if (_droneTarget == null)
			{
				return false;
			}
			return HelperLib.UpdateAimInfoForCurrentTarget(_droneTarget, _droneAimPoint, _droneAimResult, _aimResultTempCalcHolder);
		}

		protected override void RotateTurretTowardsTarget()
		{
			//IL_0039: 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_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			HelperLib.RotateTurretTowardsTarget(_droneTurn, _droneTilt, _droneAimResult, _droneRotationDefinitions, _droneRotationData);
			_droneSensorGameObject.transform.rotation = _droneTilt.transform.rotation;
			_netDataObjectHandler.Data.Set("_droneTurn.rotation", _droneTurn.transform.rotation);
			_netDataObjectHandler.Data.Set("_droneTilt.rotation", _droneTilt.transform.rotation);
			_netDataObjectHandler.Data.Set("_droneSensorGameObject.rotation", _droneSensorGameObject.transform.rotation);
		}

		private void RPC_LaunchDroneCannonProjectile(long sender, Vector3 impactLocation, Vector3 impactNormal)
		{
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: 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)
			if (_barrelList != null && _barrelList.Count != 0)
			{
				Barrel barrel = _barrelList.FirstOrDefault();
				if (barrel == null)
				{
					AddWarningMsg("DroneTurret.RPC_LaunchDroneCannonProjectile: FAIL - no barrelObject found");
					return;
				}
				GameObject obj = Object.Instantiate<GameObject>(barrel.LaunchEffectGameObject, barrel.ThisBarrelGameObject.transform, false);
				obj.transform.SetParent((Transform)null);
				obj.SetActive(false);
				obj.SetActive(true);
				Object.Destroy((Object)(object)obj, 5f);
				GameObject obj2 = Object.Instantiate<GameObject>(barrel.LaunchAudioGameObject, barrel.ThisBarrelGameObject.transform, false);
				obj2.transform.SetParent((Transform)null);
				obj2.SetActive(false);
				obj2.SetActive(true);
				Object.Destroy((Object)(object)obj2, 1f);
				Quaternion rotation = default(Quaternion);
				((Quaternion)(ref rotation)).SetLookRotation(impactNormal);
				GameObject obj3 = Object.Instantiate<GameObject>(_dirtImpactPrefab, (Transform)null);
				obj3.transform.position = impactLocation;
				obj3.transform.rotation = rotation;
				obj3.SetActive(false);
				obj3.SetActive(true);
				Object.Destroy((Object)(object)obj3, 10f);
			}
		}
	}
	public class FishingDroneTurret : GatherDroneTurret
	{
		protected override float SetDroneMovementHeight(float heightIn)
		{
			if (_droneTarget.OnGatherItemDropReturnTrip)
			{
				return heightIn + 3f;
			}
			return 30.5f;
		}

		protected override void FindNewTarget()
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Invalid comparison between Unknown and I4
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			float num = float.MaxValue;
			List<Target> list = new List<Target>();
			foreach (ItemDrop s_instance in ItemDrop.s_instances)
			{
				if ((Object)(object)s_instance == (Object)null)
				{
					continue;
				}
				if (!((Behaviour)s_instance).enabled)
				{
					AddDebugMsg("itemDrop, Target search: Item " + ((Object)s_instance).name + " is not enabled -- skipping");
				}
				else if ((int)s_instance.m_itemData.m_shared.m_itemType == 21)
				{
					float rangeToItemDrop = GetRangeToItemDrop(s_instance);
					if (!(rangeToItemDrop >= Range) && !(rangeToItemDrop <= MinimumRange) && (_droneTarget == null || !((Object)(object)_droneTarget.GatherItemDrop == (Object)(object)s_instance)) && !(((Component)s_instance).transform.position.y >= 30f) && rangeToItemDrop < num)
					{
						num = AddItemToTargetList(list, s_instance, rangeToItemDrop, MaximumNumberOfTrackedTargets);
					}
				}
			}
			if (list.Count > 0)
			{
				num = list[0].DistanceRating;
			}
			SetTargets(list, num);
			_updateTargetTimer += 5f;
		}
	}
	public class GatherDroneTurret : DroneTurret
	{
		protected readonly int _rayMaskGatherObjects = LayerMask.GetMask(new string[1] { "item" });

		private GameObject _droneCarryPoint;

		private GameObject _droneDropOffAimPoint;

		private Container _container;

		protected override void GetSpecialBodyPartsOfTurret()
		{
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Expected O, but got Unknown
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			_lightYellow = HelperLib.GetChildGameObject(((Component)this).gameObject, "Light (Yellow)");
			_lightRed = HelperLib.GetChildGameObject(((Component)this).gameObject, "Light (Red)");
			_lightLaser = HelperLib.GetChildGameObject(((Component)this).gameObject, "Light (Laser)");
			_dirtImpactPrefab = HelperLib.GetChildGameObject(((Component)this).gameObject, "DirtImpact");
			_droneGameObject = HelperLib.GetChildGameObject(((Component)this).gameObject, "Drone");
			_droneSensorGameObject = HelperLib.GetChildGameObject(_droneGameObject, "DroneSensor");
			if (ZTurretDefense.DisableDroneLight.Value)
			{
				HelperLib.DisableLightsOnGameObjectAndChildren(_droneSensorGameObject);
			}
			_droneTurn = HelperLib.GetChildGameObject(_droneGameObject, "DroneTurn");
			_droneTilt = HelperLib.GetChildGameObject(_droneGameObject, "DroneTilt");
			_droneAimPoint = HelperLib.GetChildGameObject(_droneGameObject, "DroneAimPoint");
			_droneCarryPoint = HelperLib.GetChildGameObject(_droneGameObject, "DroneCarryPoint");
			_droneDropOffAimPoint = HelperLib.GetChildGameObject(((Component)this).gameObject, "DropoffAimPoint");
			if ((Object)(object)_droneDropOffAimPoint == (Object)null)
			{
				AddLogInfo("UNEXPECTED: _droneDropOffAimPoint is null -- fixing");
				_droneDropOffAimPoint = new GameObject();
				_droneDropOffAimPoint.transform.SetParent(((Component)this).gameObject.transform);
				_droneDropOffAimPoint.transform.localPosition = new Vector3(0f, 0.5f, -4f);
			}
			_droneLight = HelperLib.GetChildGameObject(_droneGameObject, "DroneSensorLight");
		}

		protected override void SetUpTurretSpecificData()
		{
			_rotationDefinitions.MaxRotationHorizontalLeft = 180f;
			_rotationDefinitions.MaxRotationHorizontalRight = 180f;
			_rotationDefinitions.MaxRotationVerticalUp = 0.1f;
			_rotationDefinitions.MaxRotationVerticalDown = 0.1f;
			_rotationDefinitions.RotationSpeed = 360f;
			_rotationDefinitions.AllowedAimDeviance = 180f;
			_droneRotationDefinitions.MaxRotationHorizontalLeft = 120f;
			_droneRotationDefinitions.MaxRotationHorizontalRight = 120f;
			_droneRotationDefinitions.MaxRotationVerticalUp = 1f;
			_droneRotationDefinitions.MaxRotationVerticalDown = 89.9f;
			_droneRotationDefinitions.RotationSpeed = 35f;
			_droneRotationDefinitions.AllowedAimDeviance = 5f;
			_droneAimResult = new DegreesSpecifier();
			_container = ((Component)((Component)this).transform).GetComponent<Container>();
		}

		protected override float SetDroneMovementHeight(float heightIn)
		{
			return heightIn + 3f;
		}

		protected override bool MoveAndHandleGather(Target target)
		{
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: 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_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: 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_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)target.GatherItemDrop == (Object)null)
			{
				return true;
			}
			if (!target.OnGatherItemDropReturnTrip)
			{
				if ((Object)(object)target.RigidBody == (Object)null)
				{
					AddLogInfo("Rigidbody missing on target, skipping it.");
					return true;
				}
				if (target.RigidBody.isKinematic)
				{
					return true;
				}
				if ((Object)(object)((Component)target.GatherItemDrop).transform == (Object)null)
				{
					AddLogInfo("target.GatherItemDrop.transform == null");
				}
				if ((Object)(object)_droneDropOffAimPoint == (Object)null)
				{
					AddLogInfo("_droneDropOffAimPoint == null");
				}
				if ((Object)(object)_droneDropOffAimPoint.transform == (Object)null)
				{
					AddLogInfo("_droneDropOffAimPoint.transform == null");
				}
				if (Vector3.Distance(((Component)target.GatherItemDrop).transform.position, _droneDropOffAimPoint.transform.position) <= MinimumRange)
				{
					return true;
				}
			}
			Vector3 val = ((!target.OnGatherItemDropReturnTrip) ? ((Component)target.GatherItemDrop).transform.position : _droneDropOffAimPoint.transform.position);
			target.Location = new Vector3(val.x, SetDroneMovementHeight(val.y), val.z);
			float num = Vector3.Distance(_droneGameObject.transform.position, target.Location);
			if (num - DroneAttackRange > _droneSpeed - 1f)
			{
				_droneSpeed += Time.deltaTime * 3f;
				if (_droneSpeed > _droneMaxSpeed)
				{
					_droneSpeed = _droneMaxSpeed;
				}
			}
			else
			{
				_droneSpeed -= Time.deltaTime * 5f;
				if (_droneSpeed < 0f)
				{
					_droneSpeed = ((num > DroneAttackRange * 0.3f) ? 0.25f : 0f);
				}
			}
			Vector3 val2 = target.Location - _droneGameObject.transform.position;
			((Vector3)(ref val2)).Normalize();
			if (num > 0.5f)
			{
				Vector3 val3 = target.Location - _droneGameObject.transform.position;
				val3.y = 0f;
				_droneGameObject.transform.rotation = Quaternion.Slerp(_droneGameObject.transform.rotation, Quaternion.LookRotation(val3), 2.5f * Time.deltaTime);
			}
			Transform transform = _droneGameObject.transform;
			transform.position += val2 * _droneSpeed * Time.deltaTime;
			if (Vector3.Distance(_droneGameObject.transform.position, target.Location) < ((!target.OnGatherItemDropReturnTrip) ? DroneAttackRange : (DroneAttackRange * 1.2f)))
			{
				UpdateDroneMode(TurretPatrolType.AttackTarget);
			}
			else if (!target.OnGatherItemDropReturnTrip)
			{
				UpdateDroneMode(TurretPatrolType.ScanTarget);
			}
			else
			{
				UpdateDroneMode(TurretPatrolType.NoTarget);
			}
			if (_droneTarget.OnGatherItemDropReturnTrip)
			{
				SyncItemToDrone(_droneTarget.RigidBody, turnOffUsageOfGravity: true, turnOnUsageOfGravity: false);
				return false;
			}
			if (!_droneTarget.GatherItemDrop.CanPickup(false))
			{
				UpdateDroneMode(TurretPatrolType.NoTarget);
				return true;
			}
			if (_droneTarget.TimeToLive <= 0f)
			{
				UpdateDroneMode(TurretPatrolType.NoTarget);
				return true;
			}
			return false;
		}

		protected override void FindNewTarget()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Invalid comparison between Unknown and I4
			float num = float.MaxValue;
			List<Target> list = new List<Target>();
			List<ItemDrop> s_instances = ItemDrop.s_instances;
			List<ItemData> inventory = _container.GetInventory().m_inventory;
			foreach (ItemDrop item in s_instances)
			{
				if (!((Object)(object)item == (Object)null) && ((Behaviour)item).enabled && (int)item.m_itemData.m_shared.m_itemType != 21 && !IsItemInExclusionList(item, inventory))
				{
					float rangeToItemDrop = GetRangeToItemDrop(item);
					if (!(rangeToItemDrop >= Range) && !(rangeToItemDrop <= MinimumRange) && IsWithinDirection(item) && (_droneTarget == null || !((Object)(object)_droneTarget.GatherItemDrop == (Object)(object)item)) && rangeToItemDrop < num)
					{
						num = AddItemToTargetList(list, item, rangeToItemDrop, MaximumNumberOfTrackedTargets);
					}
				}
			}
			if (list.Count > 0)
			{
				num = list[0].DistanceRating;
			}
			SetTargets(list, num);
			_updateTargetTimer += 5f;
		}

		private bool IsWithinDirection(ItemDrop item)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Cos(60f * ((float)Math.PI / 180f));
			Vector3 val = ((Component)item).transform.position - ((Component)this).transform.position;
			if (((Vector3)(ref val)).sqrMagnitude < Mathf.Epsilon)
			{
				return false;
			}
			((Vector3)(ref val)).Normalize();
			if (Vector3.Dot(((Component)this).transform.forward, val) >= num)
			{
				return true;
			}
			return false;
		}

		private bool IsItemInExclusionList(ItemDrop item, List<ItemData> exclusionList)
		{
			foreach (ItemData exclusion in exclusionList)
			{
				if (item.m_itemData.m_shared.m_name == exclusion.m_shared.m_name)
				{
					return true;
				}
			}
			return false;
		}

		protected float GetRangeToItemDrop(ItemDrop itemDrop)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			return Vector3.Distance(((Component)itemDrop).transform.position, _turretAimPoint.transform.position);
		}

		protected float AddItemToTargetList(List<Target> newTargetList, ItemDrop item, float distanceRating, int maxTargets)
		{
			float num = float.MaxValue;
			if (newTargetList.Count > 0)
			{
				num = newTargetList[newTargetList.Count - 1].DistanceRating;
			}
			if (distanceRating >= num && newTargetList.Count >= MaximumNumberOfTrackedTargets)
			{
				return num;
			}
			int targetListIndexBasedOnDistance = GetTargetListIndexBasedOnDistance(newTargetList, distanceRating);
			if (targetListIndexBasedOnDistance > newTargetList.Count - 1)
			{
				if (newTargetList.Count < maxTargets)
				{
					newTargetList.Add(CreateGatherTarget(item, distanceRating));
					num = distanceRating;
				}
				return num;
			}
			newTargetList.Insert(targetListIndexBasedOnDistance, CreateGatherTarget(item, distanceRating));
			if (newTargetList.Count > maxTargets)
			{
				newTargetList.RemoveAt(maxTargets);
				num = newTargetList[newTargetList.Count - 1].DistanceRating;
			}
			return num;
		}

		protected Target CreateGatherTarget(ItemDrop item, float distanceRating)
		{
			//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)
			return new Target
			{
				Character = null,
				GatherItemDrop = item,
				IsGatherItemOrder = true,
				Location = ((Component)item).gameObject.transform.position,
				DistanceRating = distanceRating,
				RigidBody = ((Component)item).gameObject.GetComponent<Rigidbody>()
			};
		}

		protected override bool UpdateAimInfoForCurrentTarget()
		{
			if (_droneTarget == null)
			{
				return false;
			}
			if ((Object)(object)_droneTarget.GatherItemDrop == (Object)null)
			{
				return false;