Decompiled source of TGCore v1.1.0

TGCore.dll

Decompiled 4 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using DM;
using HarmonyLib;
using Landfall.MonoBatch;
using Landfall.TABS;
using Landfall.TABS.AI;
using Landfall.TABS.AI.Components;
using Landfall.TABS.AI.Components.Modifiers;
using Landfall.TABS.AI.Components.Tags;
using Landfall.TABS.AI.Systems;
using Landfall.TABS.GameMode;
using Landfall.TABS.GameState;
using Landfall.TABS.RuntimeCleanup;
using Landfall.TABS.UnitEditor;
using Landfall.TABS.Workshop;
using Landfall.TABS_Input;
using Microsoft.CodeAnalysis;
using RootMotion;
using RootMotion.FinalIK;
using TFBGames;
using TGCore.Library;
using TGCore.Localization;
using Unity.Entities;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace TGCore
{
	public static class TGAddons
	{
		public static object InvokeMethod<T>(this T obj, string methodName, params object[] args)
		{
			Type typeFromHandle = typeof(T);
			MethodInfo declaredMethod = typeFromHandle.GetTypeInfo().GetDeclaredMethod(methodName);
			return declaredMethod.Invoke(obj, args);
		}

		public static T SetField<T>(this T self, string name, object value) where T : class
		{
			FieldInfo field = typeof(T).GetField(name, (BindingFlags)(-1));
			if (field != null)
			{
				field.SetValue(self, value);
			}
			return self;
		}

		public static object GetField<T>(this T self, string name) where T : class
		{
			FieldInfo field = typeof(T).GetField(name, (BindingFlags)(-1));
			if (field != null)
			{
				return field.GetValue(self);
			}
			return null;
		}

		public static string DeepString(this GameObject self)
		{
			string text = "\nGameObject '" + ((Object)self).name + "':\n{\n\tComponents:\n\t{\n";
			text = string.Concat(text, string.Concat(from Component component in self.GetComponents<Component>()
				select "\t\t" + ((object)component).GetType().Name + "\n"));
			text += "\t}\n";
			if (self.transform.childCount > 0)
			{
				text += "\tChildren:\n\t{\n";
				text = string.Concat(text, string.Concat(from Transform child in (IEnumerable)self.transform
					select ((Component)child).gameObject.DeepString().Replace("\n", "\n\t\t")));
				text += "\n\t}\n";
			}
			return text + "}\n";
		}

		public static T DeepCopyOf<T>(this T self, T from) where T : class
		{
			FieldInfo[] fields = typeof(T).GetFields((BindingFlags)(-1));
			foreach (FieldInfo fieldInfo in fields)
			{
				try
				{
					fieldInfo.SetValue(self, fieldInfo.GetValue(from));
				}
				catch
				{
				}
			}
			PropertyInfo[] properties = typeof(T).GetProperties((BindingFlags)(-1));
			foreach (PropertyInfo propertyInfo in properties)
			{
				if (propertyInfo.CanWrite && propertyInfo.CanRead)
				{
					try
					{
						propertyInfo.SetValue(self, propertyInfo.GetValue(from));
					}
					catch
					{
					}
				}
			}
			return self;
		}

		public static SettingsInstance CreateSetting(SettingsType settingsType, string settingName, string toolTip, string settingListToAddTo, float defaultValue, float currentValue, string[] options = null, float min = 0f, float max = 1f)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			SettingsInstance val = new SettingsInstance
			{
				settingName = settingName,
				toolTip = toolTip,
				m_settingsKey = settingName,
				settingsType = settingsType,
				options = options,
				min = min,
				max = max,
				defaultValue = (int)defaultValue,
				currentValue = (int)currentValue,
				defaultSliderValue = defaultValue,
				currentSliderValue = currentValue
			};
			GlobalSettingsHandler service = ServiceLocator.GetService<GlobalSettingsHandler>();
			List<SettingsInstance> list = (settingListToAddTo switch
			{
				"BUG" => service.BugsSettings, 
				"VIDEO" => service.VideoSettings, 
				"AUDIO" => service.AudioSettings, 
				"CONTROLS" => service.ControlSettings, 
				_ => service.GameplaySettings, 
			}).ToList();
			list.Add(val);
			switch (settingListToAddTo)
			{
			case "BUG":
				typeof(GlobalSettingsHandler).GetField("m_bugsSettings", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(service, list.ToArray());
				break;
			case "VIDEO":
				typeof(GlobalSettingsHandler).GetField("m_videoSettings", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(service, list.ToArray());
				break;
			case "AUDIO":
				typeof(GlobalSettingsHandler).GetField("m_audioSettings", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(service, list.ToArray());
				break;
			case "CONTROLS":
				typeof(GlobalSettingsHandler).GetField("m_controlSettings", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(service, list.ToArray());
				break;
			default:
				typeof(GlobalSettingsHandler).GetField("m_gameplaySettings", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(service, list.ToArray());
				break;
			}
			return val;
		}

		public static void AddItems(IEnumerable<UnitBlueprint> newUnits, IEnumerable<Faction> newFactions, IEnumerable<TABSCampaignAsset> newCampaigns, IEnumerable<TABSCampaignLevelAsset> newCampaignLevels, IEnumerable<VoiceBundle> newVoiceBundles, IEnumerable<FactionIcon> newFactionIcons, IEnumerable<Unit> newUnitBases, IEnumerable<PropItem> newProps, IEnumerable<SpecialAbility> newAbilities, IEnumerable<WeaponItem> newWeapons, IEnumerable<ProjectileEntity> newProjectiles)
		{
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0485: Unknown result type (might be due to invalid IL or missing references)
			//IL_049a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0553: Unknown result type (might be due to invalid IL or missing references)
			//IL_0566: Unknown result type (might be due to invalid IL or missing references)
			//IL_0626: Unknown result type (might be due to invalid IL or missing references)
			//IL_0640: Unknown result type (might be due to invalid IL or missing references)
			//IL_06fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0718: Unknown result type (might be due to invalid IL or missing references)
			//IL_07d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_07f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_08c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0986: Unknown result type (might be due to invalid IL or missing references)
			//IL_09a0: Unknown result type (might be due to invalid IL or missing references)
			LandfallContentDatabase landfallContentDatabase = ContentDatabase.Instance().LandfallContentDatabase;
			Dictionary<DatabaseID, Object> dictionary = (Dictionary<DatabaseID, Object>)(typeof(AssetLoader).GetField("m_nonStreamableAssets", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(ContentDatabase.Instance().AssetLoader));
			Dictionary<DatabaseID, UnitBlueprint> units = (Dictionary<DatabaseID, UnitBlueprint>)(typeof(LandfallContentDatabase).GetField("m_unitBlueprints", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(landfallContentDatabase));
			foreach (UnitBlueprint item in newUnits.Where((UnitBlueprint unit) => Object.op_Implicit((Object)(object)unit) && units != null && !units.ContainsKey(unit.Entity.GUID)))
			{
				units.Add(item.Entity.GUID, item);
				dictionary.Add(item.Entity.GUID, (Object)(object)item);
			}
			typeof(LandfallContentDatabase).GetField("m_unitBlueprints", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(landfallContentDatabase, units);
			Dictionary<DatabaseID, Faction> factions = (Dictionary<DatabaseID, Faction>)(typeof(LandfallContentDatabase).GetField("m_factions", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(landfallContentDatabase));
			List<DatabaseID> list = (List<DatabaseID>)(typeof(LandfallContentDatabase).GetField("m_defaultHotbarFactionIds", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(landfallContentDatabase));
			foreach (Faction item2 in newFactions.Where((Faction faction) => Object.op_Implicit((Object)(object)faction) && factions != null && !factions.ContainsKey(faction.Entity.GUID)))
			{
				factions.Add(item2.Entity.GUID, item2);
				dictionary.Add(item2.Entity.GUID, (Object)(object)item2);
				list.Add(item2.Entity.GUID);
			}
			typeof(LandfallContentDatabase).GetField("m_factions", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(landfallContentDatabase, factions);
			typeof(LandfallContentDatabase).GetField("m_defaultHotbarFactionIds", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(landfallContentDatabase, list.OrderBy((DatabaseID x) => factions[x].index).ToList());
			Dictionary<DatabaseID, TABSCampaignAsset> campaigns = (Dictionary<DatabaseID, TABSCampaignAsset>)(typeof(LandfallContentDatabase).GetField("m_campaigns", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(landfallContentDatabase));
			foreach (TABSCampaignAsset item3 in newCampaigns.Where((TABSCampaignAsset campaign) => Object.op_Implicit((Object)(object)campaign) && campaigns != null && !campaigns.ContainsKey(campaign.Entity.GUID)))
			{
				campaigns.Add(item3.Entity.GUID, item3);
				dictionary.Add(item3.Entity.GUID, (Object)(object)item3);
			}
			typeof(LandfallContentDatabase).GetField("m_campaigns", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(landfallContentDatabase, campaigns);
			Dictionary<DatabaseID, TABSCampaignLevelAsset> campaignLevels = (Dictionary<DatabaseID, TABSCampaignLevelAsset>)typeof(LandfallContentDatabase).GetField("m_campaignLevels", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(landfallContentDatabase);
			foreach (TABSCampaignLevelAsset item4 in newCampaignLevels.Where((TABSCampaignLevelAsset campaignLevel) => Object.op_Implicit((Object)(object)campaignLevel) && campaignLevels != null && !campaignLevels.ContainsKey(campaignLevel.Entity.GUID)))
			{
				campaignLevels.Add(item4.Entity.GUID, item4);
				dictionary.Add(item4.Entity.GUID, (Object)(object)item4);
			}
			typeof(LandfallContentDatabase).GetField("m_campaignLevels", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(landfallContentDatabase, campaignLevels);
			Dictionary<DatabaseID, VoiceBundle> voiceBundles = (Dictionary<DatabaseID, VoiceBundle>)typeof(LandfallContentDatabase).GetField("m_voiceBundles", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(landfallContentDatabase);
			foreach (VoiceBundle item5 in newVoiceBundles.Where((VoiceBundle voiceBundle) => Object.op_Implicit((Object)(object)voiceBundle) && voiceBundles != null && !voiceBundles.ContainsKey(voiceBundle.Entity.GUID)))
			{
				voiceBundles.Add(item5.Entity.GUID, item5);
				dictionary.Add(item5.Entity.GUID, (Object)(object)item5);
			}
			typeof(LandfallContentDatabase).GetField("m_voiceBundles", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(landfallContentDatabase, voiceBundles);
			List<DatabaseID> factionIcons = (List<DatabaseID>)typeof(LandfallContentDatabase).GetField("m_factionIconIds", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(landfallContentDatabase);
			foreach (FactionIcon item6 in newFactionIcons.Where((FactionIcon factionIcon) => Object.op_Implicit((Object)(object)factionIcon) && factionIcons != null && !factionIcons.Contains(factionIcon.Entity.GUID)))
			{
				factionIcons.Add(item6.Entity.GUID);
				dictionary.Add(item6.Entity.GUID, (Object)(object)item6);
			}
			typeof(LandfallContentDatabase).GetField("m_factionIconIds", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(landfallContentDatabase, factionIcons);
			Dictionary<DatabaseID, GameObject> unitBases = (Dictionary<DatabaseID, GameObject>)(typeof(LandfallContentDatabase).GetField("m_unitBases", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(landfallContentDatabase));
			foreach (Unit item7 in newUnitBases.Where((Unit unitBase) => Object.op_Implicit((Object)(object)unitBase) && unitBases != null && !unitBases.ContainsKey(unitBase.Entity.GUID)))
			{
				unitBases.Add(item7.Entity.GUID, ((Component)item7).gameObject);
				dictionary.Add(item7.Entity.GUID, (Object)(object)((Component)item7).gameObject);
			}
			typeof(LandfallContentDatabase).GetField("m_unitBases", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(landfallContentDatabase, unitBases);
			Dictionary<DatabaseID, GameObject> props = (Dictionary<DatabaseID, GameObject>)typeof(LandfallContentDatabase).GetField("m_characterProps", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(landfallContentDatabase);
			foreach (PropItem item8 in newProps.Where((PropItem prop) => Object.op_Implicit((Object)(object)prop) && props != null && !props.ContainsKey(((CharacterItem)prop).Entity.GUID)))
			{
				props.Add(((CharacterItem)item8).Entity.GUID, ((Component)item8).gameObject);
				dictionary.Add(((CharacterItem)item8).Entity.GUID, (Object)(object)((Component)item8).gameObject);
			}
			typeof(LandfallContentDatabase).GetField("m_characterProps", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(landfallContentDatabase, props);
			Dictionary<DatabaseID, GameObject> abilities = (Dictionary<DatabaseID, GameObject>)typeof(LandfallContentDatabase).GetField("m_combatMoves", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(landfallContentDatabase);
			foreach (SpecialAbility item9 in newAbilities.Where((SpecialAbility ability) => Object.op_Implicit((Object)(object)ability) && abilities != null && !abilities.ContainsKey(((CharacterItem)ability).Entity.GUID)))
			{
				abilities.Add(((CharacterItem)item9).Entity.GUID, ((Component)item9).gameObject);
				dictionary.Add(((CharacterItem)item9).Entity.GUID, (Object)(object)((Component)item9).gameObject);
			}
			typeof(LandfallContentDatabase).GetField("m_combatMoves", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(landfallContentDatabase, abilities);
			Dictionary<DatabaseID, GameObject> weapons = (Dictionary<DatabaseID, GameObject>)typeof(LandfallContentDatabase).GetField("m_weapons", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(landfallContentDatabase);
			foreach (WeaponItem item10 in newWeapons.Where((WeaponItem weapon) => Object.op_Implicit((Object)(object)weapon) && weapons != null && !weapons.ContainsKey(((CharacterItem)weapon).Entity.GUID)))
			{
				weapons.Add(((CharacterItem)item10).Entity.GUID, ((Component)item10).gameObject);
				dictionary.Add(((CharacterItem)item10).Entity.GUID, (Object)(object)((Component)item10).gameObject);
			}
			typeof(LandfallContentDatabase).GetField("m_weapons", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(landfallContentDatabase, weapons);
			Dictionary<DatabaseID, GameObject> projectiles = (Dictionary<DatabaseID, GameObject>)typeof(LandfallContentDatabase).GetField("m_projectiles", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(landfallContentDatabase);
			foreach (ProjectileEntity item11 in newProjectiles.Where((ProjectileEntity proj) => Object.op_Implicit((Object)(object)proj) && projectiles != null && !projectiles.ContainsKey(proj.Entity.GUID)))
			{
				projectiles.Add(item11.Entity.GUID, ((Component)item11).gameObject);
				dictionary.Add(item11.Entity.GUID, (Object)(object)((Component)item11).gameObject);
			}
			typeof(LandfallContentDatabase).GetField("m_projectiles", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(landfallContentDatabase, projectiles);
		}
	}
	[BepInPlugin("teamgrad.core", "Team Grad Core", "1.1.0")]
	public class TGMain : BaseUnityPlugin
	{
		public static TGMain instance;

		public static List<TGMod> modList = new List<TGMod>();

		public static List<SoundBank> newSounds = new List<SoundBank>();

		public static ContentDatabase DB => ContentDatabase.Instance();

		public static LandfallContentDatabase landfallDb => ContentDatabase.Instance().LandfallContentDatabase;

		private void Awake()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			instance = this;
			Debug.Log((object)"LOADING TGCORE...");
			new Harmony("TGCore").PatchAll();
			((MonoBehaviour)this).StartCoroutine(InitializeMods());
		}

		private IEnumerator InitializeMods()
		{
			yield return (object)new WaitUntil((Func<bool>)(() => (Object)(object)Object.FindObjectOfType<ServiceLocator>() != (Object)null));
			ServiceLocator.GetService<CustomContentLoaderModIO>().QuickRefresh((WorkshopContentType)0, (Action)null);
			LocalizationHolder languageHolder = ((Component)this).gameObject.AddComponent<LocalizationHolder>();
			modList = Chainloader.ManagerObject.GetComponents<TGMod>().ToList();
			List<TGMod> failedModList = new List<TGMod>();
			foreach (TGMod mod2 in modList)
			{
				try
				{
					Debug.Log((object)"LOADING MOD...");
					mod2.Launch();
					mod2.AddSettings();
					mod2.Localize(languageHolder);
					SceneManager.sceneLoaded += mod2.SceneManager;
				}
				catch (Exception exc2)
				{
					failedModList.Add(mod2);
					Debug.LogError((object)"A MOD HAS FAILED TO LAUNCH:");
					Debug.LogError((object)exc2);
				}
			}
			modList.RemoveAll((TGMod x) => failedModList.Contains(x));
			UpdateSoundBank();
			languageHolder.ReadLocalization();
			foreach (TGMod mod in modList)
			{
				try
				{
					mod.LateLaunch();
				}
				catch (Exception exc)
				{
					Debug.LogError((object)"A MOD HAS FAILED TO LAUNCH:");
					Debug.LogError((object)exc);
				}
			}
			modList.RemoveAll((TGMod x) => failedModList.Contains(x));
		}

		public void UpdateSoundBank()
		{
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Expected O, but got Unknown
			Debug.Log((object)"UPDATING SOUNDS...");
			foreach (SoundBank newSound in newSounds)
			{
				try
				{
					if (((Object)newSound).name.Contains("Sound"))
					{
						SoundBank soundBank = ServiceLocator.GetService<SoundPlayer>().soundBank;
						SoundBankCategory[] categories = newSound.Categories;
						foreach (SoundBankCategory val in categories)
						{
							val.categoryMixerGroup = soundBank.Categories[0].categoryMixerGroup;
						}
						List<SoundBankCategory> list = soundBank.Categories.ToList();
						list.AddRange(newSound.Categories);
						soundBank.Categories = list.ToArray();
					}
					else
					{
						if (!((Object)newSound).name.Contains("Music"))
						{
							continue;
						}
						SoundBank bank = ServiceLocator.GetService<MusicHandler>().bank;
						List<SoundBankCategory> list2 = bank.Categories.ToList();
						list2.AddRange(newSound.Categories);
						SoundBankCategory[] categories2 = newSound.Categories;
						foreach (SoundBankCategory val2 in categories2)
						{
							SoundEffectInstance[] soundEffects = val2.soundEffects;
							foreach (SoundEffectInstance val3 in soundEffects)
							{
								SongInstance val4 = new SongInstance
								{
									clip = val3.clipTypes[0].clips[0],
									soundEffectInstance = val3,
									songRef = val2.categoryName + "/" + val3.soundRef
								};
								ServiceLocator.GetService<MusicHandler>().m_songs.Add(val4.songRef, val4);
							}
						}
						bank.Categories = list2.ToArray();
						continue;
					}
				}
				catch (Exception ex)
				{
					Debug.LogError((object)"UPDATING SOUNDS HAS FAILED:");
					Debug.LogError((object)ex);
				}
			}
		}
	}
	public class TGMod : BaseUnityPlugin
	{
		private void Awake()
		{
			EarlyLaunch();
		}

		public virtual void EarlyLaunch()
		{
		}

		public virtual void Launch()
		{
		}

		public virtual void LateLaunch()
		{
		}

		public virtual void AddSettings()
		{
		}

		public virtual void SceneManager(Scene scene, LoadSceneMode loadSceneMode)
		{
		}

		public virtual void Localize(LocalizationHolder languageHolder)
		{
		}
	}
}
namespace TGCore.Localization
{
	public class LocalizationEntry : MonoBehaviour
	{
		public Language langage;

		public List<string> key;

		public List<string> value;
	}
	public class LocalizationHolder : MonoBehaviour
	{
		public List<LocalizationEntry> languages = new List<LocalizationEntry>();

		public void ReadLocalization()
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			Debug.Log((object)"LOCALIZING...");
			Dictionary<Language, Dictionary<string, string>> dictionary = (Dictionary<Language, Dictionary<string, string>>)(typeof(Localizer).GetField("m_localization", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null));
			try
			{
				foreach (LocalizationEntry item in languages.Where((LocalizationEntry x) => x.key.Count > 0 && x.value.Count > 0))
				{
					for (int i = 0; i < item.key.Count; i++)
					{
						dictionary?[item.langage].Add(item.key[i], item.value[i]);
					}
				}
			}
			catch (Exception ex)
			{
				Debug.LogError((object)"LOCALIZATION HAS FAILED:");
				Debug.LogError((object)ex);
			}
		}
	}
}
namespace TGCore.Library
{
	public class AddDamageToUnitPart : MonoBehaviour
	{
		public enum BodyTarget
		{
			Head,
			RightFoot,
			LeftFoot,
			RightHand,
			LeftHand,
			MainRig,
			Hip
		}

		private CollisionWeapon NewDamage;

		private CollisionWeaponToggleable NewToggleableDamage;

		private CollisionSound NewSound;

		private MeleeWeaponAddEffect NewEffect;

		private MeleeWeaponSpawn NewSpawn;

		private Unit OwnUnit;

		public BodyTarget bodyTarget;

		private void Start()
		{
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_0398: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03aa: Unknown result type (might be due to invalid IL or missing references)
			OwnUnit = ((Component)((Component)this).transform.root).GetComponent<Unit>();
			GameObject val = (GameObject)(bodyTarget switch
			{
				BodyTarget.Head => ((Component)OwnUnit.data.head).gameObject, 
				BodyTarget.LeftFoot => ((Component)OwnUnit.data.footLeft).gameObject, 
				BodyTarget.RightFoot => ((Component)OwnUnit.data.footRight).gameObject, 
				BodyTarget.LeftHand => ((Component)OwnUnit.data.leftHand).gameObject, 
				BodyTarget.RightHand => ((Component)OwnUnit.data.rightHand).gameObject, 
				BodyTarget.Hip => ((Component)OwnUnit.data.hip).gameObject, 
				_ => ((Component)OwnUnit.data.mainRig).gameObject, 
			});
			CollisionWeapon component = ((Component)this).GetComponent<CollisionWeapon>();
			if (Object.op_Implicit((Object)(object)component))
			{
				NewDamage = val.AddComponent<CollisionWeapon>();
				NewDamage.damage = component.damage;
				NewDamage.impactMultiplier = component.impactMultiplier;
				NewDamage.onImpactForce = component.onImpactForce;
				NewDamage.massCap = component.massCap;
				NewDamage.ignoreTeamMates = component.ignoreTeamMates;
				NewDamage.staticDamageValue = component.staticDamageValue;
				NewDamage.onlyOncePerData = component.onlyOncePerData;
				NewDamage.cooldown = component.cooldown;
				NewDamage.onlyCollideWithRigs = true;
				NewDamage.dealDamageEvent = component.dealDamageEvent;
				NewDamage.callEffectsOn = component.callEffectsOn;
				Object.Destroy((Object)(object)component);
			}
			CollisionWeaponToggleable component2 = ((Component)this).GetComponent<CollisionWeaponToggleable>();
			if (Object.op_Implicit((Object)(object)component2))
			{
				NewToggleableDamage = val.AddComponent<CollisionWeaponToggleable>();
				NewToggleableDamage.damage = component2.damage;
				NewToggleableDamage.impactMultiplier = component2.impactMultiplier;
				NewToggleableDamage.onImpactForce = component2.onImpactForce;
				NewToggleableDamage.massCap = component2.massCap;
				NewToggleableDamage.ignoreTeamMates = component2.ignoreTeamMates;
				NewToggleableDamage.staticDamageValue = component2.staticDamageValue;
				NewToggleableDamage.onlyOncePerData = component2.onlyOncePerData;
				NewToggleableDamage.cooldown = component2.cooldown;
				NewToggleableDamage.dealDamageEvent = component2.dealDamageEvent;
				NewToggleableDamage.canDealDamage = component2.canDealDamage;
				NewToggleableDamage.callEffectsOn = component2.callEffectsOn;
				Object.Destroy((Object)(object)component2);
			}
			CollisionSound component3 = ((Component)this).GetComponent<CollisionSound>();
			if (Object.op_Implicit((Object)(object)component3))
			{
				NewSound = val.AddComponent<CollisionSound>();
				NewSound.SoundEffectRef = component3.SoundEffectRef;
				NewSound.multiplier = component3.multiplier;
				Object.Destroy((Object)(object)component3);
			}
			MeleeWeaponAddEffect component4 = ((Component)this).GetComponent<MeleeWeaponAddEffect>();
			if (Object.op_Implicit((Object)(object)component4))
			{
				NewEffect = val.AddComponent<MeleeWeaponAddEffect>();
				NewEffect.EffectPrefab = component4.EffectPrefab;
				NewEffect.ignoreTeamMates = component4.ignoreTeamMates;
				Object.Destroy((Object)(object)component4);
			}
			MeleeWeaponSpawn component5 = ((Component)this).GetComponent<MeleeWeaponSpawn>();
			if (Object.op_Implicit((Object)(object)component5))
			{
				NewSpawn = val.AddComponent<MeleeWeaponSpawn>();
				NewSpawn.objectToSpawn = component5.objectToSpawn;
				NewSpawn.pos = component5.pos;
				NewSpawn.rot = component5.rot;
				NewSpawn.cd = component5.cd;
				NewSpawn.SpawnEvent = component5.SpawnEvent;
				Object.Destroy((Object)(object)component5);
			}
		}

		public void RemoveDamage()
		{
			if (Object.op_Implicit((Object)(object)NewDamage))
			{
				Object.Destroy((Object)(object)NewDamage);
			}
			if (Object.op_Implicit((Object)(object)NewToggleableDamage))
			{
				Object.Destroy((Object)(object)NewDamage);
			}
			if (Object.op_Implicit((Object)(object)NewSound))
			{
				Object.Destroy((Object)(object)NewSound);
			}
			if (Object.op_Implicit((Object)(object)NewEffect))
			{
				Object.Destroy((Object)(object)NewEffect);
			}
			if (Object.op_Implicit((Object)(object)NewSpawn))
			{
				Object.Destroy((Object)(object)NewSpawn);
			}
		}

		public void Release()
		{
			if (Object.op_Implicit((Object)(object)NewDamage))
			{
				NewDamage.Release();
			}
			if (Object.op_Implicit((Object)(object)NewToggleableDamage))
			{
				NewToggleableDamage.Release();
			}
		}

		public void SetCanDealDamage(bool value)
		{
			if (Object.op_Implicit((Object)(object)NewToggleableDamage))
			{
				NewToggleableDamage.SetCanDealDamage(value);
			}
		}

		private void OnDestroy()
		{
			RemoveDamage();
		}
	}
	public class AddEffectToRandomUnits : MonoBehaviour
	{
		public enum SelectionType
		{
			Percentage,
			Specific
		}

		private Team Team;

		private TeamSystem TeamSystem;

		private List<Unit> HitList = new List<Unit>();

		[Header("Selection Settings")]
		public SelectionType selectionType;

		public int value;

		public float delay;

		public bool enemyTeam = true;

		[Header("Effect Settings")]
		public UnitEffectBase effectToAdd;

		public bool addEffectOnce;

		private void Start()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			Team = ((Component)((Component)this).transform.root).GetComponent<Unit>().Team;
			TeamSystem = World.Active.GetOrCreateManager<TeamSystem>();
		}

		public void AddEffectToUnits()
		{
			//IL_0011: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			ClearHitList();
			((MonoBehaviour)this).StartCoroutine(DoEffect(TeamSystem.GetTeamUnits((Team)(((int)Team != 0) ? ((!enemyTeam) ? ((int)Team) : 0) : (enemyTeam ? 1 : ((int)Team))))));
		}

		private IEnumerator DoEffect(List<Unit> enemyUnits)
		{
			if (selectionType == SelectionType.Percentage && enemyUnits.Count / value > 0)
			{
				for (int i = 0; i < enemyUnits.Count / value; i++)
				{
					if (!HitList.Contains(enemyUnits[i]))
					{
						AddEffect(((Component)((Component)this).transform.root).GetComponent<Unit>(), enemyUnits[i].data);
						HitList.Add(enemyUnits[i]);
						yield return (object)new WaitForSeconds(delay);
					}
				}
			}
			else
			{
				if (selectionType != SelectionType.Specific)
				{
					yield break;
				}
				for (int j = 0; j < value; j++)
				{
					if (enemyUnits.Count <= 0)
					{
						break;
					}
					Unit chosenUnit = enemyUnits[Random.Range(0, enemyUnits.Count - 1)];
					if (!HitList.Contains(chosenUnit))
					{
						AddEffect(((Component)((Component)this).transform.root).GetComponent<Unit>(), chosenUnit.data);
						HitList.Add(chosenUnit);
						yield return (object)new WaitForSeconds(delay);
					}
				}
			}
		}

		public void ClearHitList()
		{
			HitList.Clear();
		}

		public void AddEffect(Unit attacker, DataHandler targetData)
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)attacker != (Object)null && (!Object.op_Implicit((Object)(object)targetData) || !targetData.Dead) && Object.op_Implicit((Object)(object)targetData))
			{
				UnitEffectBase val = UnitEffectBase.AddEffectToTarget(((Component)((Component)targetData.unit).transform).gameObject, effectToAdd);
				if (!Object.op_Implicit((Object)(object)val))
				{
					GameObject val2 = Object.Instantiate<GameObject>(((Component)effectToAdd).gameObject, ((Component)targetData.unit).transform.root);
					val2.transform.position = ((Component)targetData.unit).transform.position;
					val2.transform.rotation = Quaternion.LookRotation(targetData.mainRig.position - attacker.data.mainRig.position);
					val = val2.GetComponent<UnitEffectBase>();
					TeamHolder.AddTeamHolder(val2, ((Component)((Component)this).transform.root).gameObject);
					val.DoEffect();
				}
				else if (!addEffectOnce)
				{
					((Component)val).transform.rotation = Quaternion.LookRotation(targetData.mainRig.position - attacker.data.mainRig.position);
					val.Ping();
				}
			}
		}
	}
	public class AddEffectToTargetOnce : MonoBehaviour
	{
		private Unit OwnUnit;

		public UnitEffectBase effectPrefab;

		public bool onlyOnce;

		private void Start()
		{
			OwnUnit = ((Component)((Component)this).transform.root).GetComponent<Unit>();
		}

		public void Go()
		{
			AddEffect(OwnUnit.data.targetData);
		}

		public void GoWithRandomTarget(float radius)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			RaycastHit[] source = Physics.SphereCastAll(((Component)this).transform.position, radius, Vector3.up, 0.1f, LayerMask.GetMask(new string[1] { "MainRig" }));
			Unit[] array = (from hit in source
				select ((Component)((RaycastHit)(ref hit)).transform.root).GetComponent<Unit>() into x
				where Object.op_Implicit((Object)(object)x) && !x.data.Dead && x.Team != OwnUnit.Team
				select x).Distinct().ToArray();
			if (array.Length != 0)
			{
				AddEffect(array[Random.Range(0, array.Length)].data);
			}
		}

		public void AddEffect(DataHandler targetData)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)OwnUnit) && Object.op_Implicit((Object)(object)targetData) && !targetData.Dead)
			{
				UnitEffectBase val = UnitEffectBase.AddEffectToTarget(((Component)targetData.unit).gameObject, effectPrefab);
				if (!Object.op_Implicit((Object)(object)val))
				{
					GameObject val2 = Object.Instantiate<GameObject>(((Component)effectPrefab).gameObject, ((Component)targetData.unit).transform);
					val2.transform.position = ((Component)targetData.unit).transform.position;
					val2.transform.rotation = Quaternion.LookRotation(targetData.mainRig.position - OwnUnit.data.mainRig.position);
					TeamHolder.AddTeamHolder(val2, ((Component)((Component)this).transform.root).gameObject);
					val = val2.GetComponent<UnitEffectBase>();
					val.DoEffect();
				}
				else if (!onlyOnce)
				{
					((Component)val).transform.rotation = Quaternion.LookRotation(targetData.mainRig.position - OwnUnit.data.mainRig.position);
					val.Ping();
				}
			}
		}
	}
	public class AddMountOnStart : MonoBehaviour
	{
		public List<GameObject> mountPositions = new List<GameObject>();

		private void Start()
		{
			//IL_00b1: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
			foreach (GameObject mountPosition in mountPositions)
			{
				mountPosition.SetActive(true);
			}
			Unit component = ((Component)this).GetComponent<Unit>();
			List<GameObject> list = new List<GameObject>();
			if (Object.op_Implicit((Object)(object)component.unitBlueprint) && component.unitBlueprint.UnitRiders != null && component.unitBlueprint.UnitRiders.Length != 0)
			{
				RiderHolder val = ((Component)this).gameObject.AddComponent<RiderHolder>();
				List<GameObject> list2 = new List<GameObject>();
				Unit val2 = default(Unit);
				for (int i = 0; i < component.unitBlueprint.UnitRiders.Length; i++)
				{
					GameObject[] array = component.unitBlueprint.UnitRiders[i].Spawn(((Component)this).transform.position, ((Component)this).transform.rotation, component.Team, ref val2, 1f, false, false, 0, (UnitPoolInfo?)null);
					if (component.CampaignUnit)
					{
						val2.SetCampaignUnit();
					}
					list2.Add(array[0]);
					list.AddRange(array);
					((Component)val2).gameObject.AddComponent<Mount>().EnterMount((UnitBlueprint)null, component, i);
					list.AddRange(array);
					val2.IsRider = true;
					if (component.RemoteInstanceId != 0)
					{
						val2.IsRiderWithLinkedMount = true;
					}
				}
				val.Addriders(list2);
			}
			ServiceLocator.GetService<RuntimeGarbageCollector>().AddGameObjects(list.ToArray());
			List<GameObject> list3 = component.spawnedObjects.ToList();
			list3.AddRange(list);
			component.spawnedObjects = list3.ToArray();
			Mount component2 = ((Component)this).GetComponent<Mount>();
			if (Object.op_Implicit((Object)(object)component2) && Object.op_Implicit((Object)(object)component2.OtherData) && component2.IsMounted)
			{
				List<GameObject> list4 = component2.OtherData.unit.spawnedObjects.ToList();
				list4.AddRange(component.spawnedObjects);
				component2.OtherData.unit.spawnedObjects = list4.ToArray();
			}
		}
	}
	public class AddRigidbodyThenSinkOnDeath : MonoBehaviour
	{
		private Unit OwnUnit;

		private bool HasDied;

		private Rigidbody Rig;

		[Header("Rigidbody Settings")]
		public bool addRigidbody;

		public float mass = 200f;

		public float drag;

		public float angularDrag;

		public RigidbodyInterpolation interpolation = (RigidbodyInterpolation)1;

		[Header("Sink Settings")]
		public float sinkDelay = 2f;

		public float sinkMultiplier = 0.3f;

		public bool scaleAfterDelay = true;

		public float scaleDelay = 15f;

		private float ScaleMultiplier;

		private void Start()
		{
			OwnUnit = ((Component)((Component)this).transform.root).GetComponent<Unit>();
			OwnUnit.data.healthHandler.AddDieAction((Action)Die);
		}

		public void Die()
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			if (!HasDied)
			{
				Rig = (addRigidbody ? ((Component)this).gameObject.AddComponent<Rigidbody>() : ((Component)this).GetComponent<Rigidbody>());
				Rig.mass = mass;
				Rig.drag = drag;
				Rig.angularDrag = angularDrag;
				Rig.interpolation = interpolation;
				HasDied = true;
				((Component)this).transform.SetParent(((Component)OwnUnit.data).transform, true);
				((MonoBehaviour)this).StartCoroutine(DoSink());
			}
		}

		private IEnumerator DoSink()
		{
			yield return (object)new WaitForSeconds(sinkDelay);
			float t2 = 0f;
			while (t2 < 3f)
			{
				Rigidbody rig = Rig;
				rig.drag *= 2f;
				Vector3 velocity = Rig.velocity;
				if (((Vector3)(ref velocity)).magnitude < 1f)
				{
					t2 += Time.deltaTime;
				}
				yield return null;
			}
			Rig.isKinematic = true;
			t2 = 0f;
			while (t2 < 30f)
			{
				Transform transform = ((Component)this).transform;
				transform.position += Vector3.down * Mathf.Clamp(t2 * 0.1f, 0f, 1f) * Time.deltaTime * sinkMultiplier;
				t2 += Time.deltaTime;
				if (scaleAfterDelay && t2 > scaleDelay)
				{
					ScaleMultiplier += Time.deltaTime * 0.35f;
					Transform transform2 = ((Component)this).transform;
					transform2.localScale *= Mathf.Lerp(1f, 0f, ScaleMultiplier);
				}
				yield return null;
			}
		}
	}
	public class AimForUnitTarget : MonoBehaviour
	{
		private Unit Unit;

		private Vector3 StartForward;

		public AnimationCurve lerpCurve;

		public float lerpSpeed;

		private void Start()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			Unit = ((Component)((Component)this).transform.root).GetComponent<Unit>();
			StartForward = ((Component)this).transform.parent.InverseTransformDirection(((Component)this).transform.forward);
		}

		private void Update()
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: 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_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)Unit) && Object.op_Implicit((Object)(object)Unit.data) && Object.op_Implicit((Object)(object)Unit.data.targetData) && Object.op_Implicit((Object)(object)Unit.data.targetData.mainRig))
			{
				Vector3 val = ((Component)this).transform.parent.TransformDirection(StartForward);
				Vector3 val2 = Unit.data.targetData.mainRig.position - ((Component)this).transform.position;
				Vector3 normalized = ((Vector3)(ref val2)).normalized;
				normalized.y = 0f;
				float num = Vector3.Angle(normalized, val);
				((Component)this).transform.rotation = Quaternion.LookRotation(Vector3.Lerp(((Component)this).transform.forward, Vector3.Lerp(val, normalized, lerpCurve.Evaluate(num)), lerpSpeed * Time.deltaTime));
			}
		}
	}
	public class AimForRandomUnit : MonoBehaviour
	{
		private TeamHolder OwnTeamHolder;

		public float maxRange = 30f;

		public float spread;

		public bool useRandom = true;

		private void Start()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			OwnTeamHolder = ((Component)this).GetComponent<TeamHolder>();
			Unit val = SetTarget();
			if (!Object.op_Implicit((Object)(object)val))
			{
				return;
			}
			Rigidbody mainRig = val.data.mainRig;
			Compensation component = ((Component)this).GetComponent<Compensation>();
			MoveTransform component2 = ((Component)this).GetComponent<MoveTransform>();
			if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component2))
			{
				((Component)this).transform.rotation = Quaternion.LookRotation(component.GetCompensation(mainRig.position, mainRig.velocity, 0f) + 0.01f * spread * Random.insideUnitSphere);
				Unit component3 = OwnTeamHolder.spawner.GetComponent<Unit>();
				RangeWeapon componentInParent = OwnTeamHolder.spawnerWeapon.GetComponentInParent<RangeWeapon>();
				if (componentInParent.extraSpreadInMelee != 0f && Object.op_Implicit((Object)(object)component3) && component3.data.distanceToTarget < 5f)
				{
					((Component)this).transform.Rotate(componentInParent.extraSpreadInMelee * Random.insideUnitSphere);
				}
				component2.Initialize();
			}
		}

		private Unit SetTarget()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			Collider[] source = Physics.OverlapSphere(((Component)this).transform.position, maxRange, LayerMask.GetMask(new string[1] { "MainRig" }));
			Unit[] array = (from hit in source
				select ((Component)((Component)hit).transform.root).GetComponent<Unit>() into x
				where Object.op_Implicit((Object)(object)x) && !x.data.Dead && x.Team != OwnTeamHolder.team
				select x).OrderBy(delegate(Unit x)
			{
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val = ((Component)x.data.mainRig).transform.position - ((Component)this).transform.position;
				return ((Vector3)(ref val)).magnitude;
			}).Distinct().ToArray();
			if (array.Length != 0)
			{
				return array[useRandom ? Random.Range(0, array.Length - 1) : 0];
			}
			return null;
		}
	}
	public class AssignMeshToParticleSystem : MonoBehaviour
	{
		public enum MeshType
		{
			MeshRenderer,
			SkinnedMeshRenderer,
			NonUnitMeshRenderer
		}

		private MeshRenderer[] AllMeshRenderers;

		private MeshRenderer MeshRenderer;

		private SkinnedMeshRenderer[] AllSkinnedMeshRenderers;

		private SkinnedMeshRenderer SkinnedMeshRend;

		private ParticleSystem[] ParticleSystems;

		private ParticleSystem Part;

		private bool MeshAssigned;

		public MeshType meshType;

		public UnityEvent findEvent;

		public bool disableMesh;

		public bool disableParticles;

		public bool play = true;

		private void Start()
		{
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			Part = ((Component)this).GetComponent<ParticleSystem>();
			switch (meshType)
			{
			case MeshType.MeshRenderer:
			{
				AllMeshRenderers = ((Component)((Component)this).transform.root).GetComponentsInChildren<MeshRenderer>();
				MeshRenderer[] allMeshRenderers = AllMeshRenderers;
				foreach (MeshRenderer val2 in allMeshRenderers)
				{
					if (((Component)val2).CompareTag("UnitMesh") && !MeshAssigned)
					{
						MeshRenderer = val2;
						MeshAssigned = true;
					}
					if (disableMesh)
					{
						((Renderer)val2).enabled = false;
					}
				}
				if (Object.op_Implicit((Object)(object)MeshRenderer))
				{
					ShapeModule shape2 = Part.shape;
					((ShapeModule)(ref shape2)).meshRenderer = MeshRenderer;
					findEvent.Invoke();
					if (play)
					{
						Part.Play();
					}
				}
				if (!disableParticles)
				{
					return;
				}
				ParticleSystems = ((Component)((Component)this).transform.root).GetComponentsInChildren<ParticleSystem>();
				ParticleSystem[] particleSystems = ParticleSystems;
				foreach (ParticleSystem val3 in particleSystems)
				{
					if (!((Component)val3).CompareTag("DontRemove"))
					{
						val3.Stop();
					}
				}
				return;
			}
			case MeshType.SkinnedMeshRenderer:
			{
				AllSkinnedMeshRenderers = ((Component)((Component)this).transform.root).GetComponentsInChildren<SkinnedMeshRenderer>();
				SkinnedMeshRenderer[] allSkinnedMeshRenderers = AllSkinnedMeshRenderers;
				foreach (SkinnedMeshRenderer val in allSkinnedMeshRenderers)
				{
					if (((Component)val).CompareTag("UnitMesh"))
					{
						SkinnedMeshRend = val;
						break;
					}
				}
				if (Object.op_Implicit((Object)(object)SkinnedMeshRend))
				{
					ShapeModule shape = ((Component)this).GetComponent<ParticleSystem>().shape;
					((ShapeModule)(ref shape)).skinnedMeshRenderer = SkinnedMeshRend;
					findEvent.Invoke();
					if (play)
					{
						Part.Play();
					}
				}
				return;
			}
			}
			AllMeshRenderers = ((Component)((Component)this).transform.root).GetComponentsInChildren<MeshRenderer>();
			MeshRenderer[] allMeshRenderers2 = AllMeshRenderers;
			foreach (MeshRenderer val4 in allMeshRenderers2)
			{
				if (!MeshAssigned)
				{
					MeshRenderer = val4;
					MeshAssigned = true;
				}
				if (disableMesh)
				{
					((Renderer)val4).enabled = false;
				}
			}
			if (Object.op_Implicit((Object)(object)MeshRenderer))
			{
				ShapeModule shape3 = Part.shape;
				((ShapeModule)(ref shape3)).meshRenderer = MeshRenderer;
				findEvent.Invoke();
				if (play)
				{
					Part.Play();
				}
			}
		}
	}
	public class CallCodeAnimationInRoot : MonoBehaviour
	{
		public AnimationUse animationType;

		public void CallAnimation(string objName)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected I4, but got Unknown
			CodeAnimation val = ((Component)((Component)this).transform.root).GetComponentsInChildren<CodeAnimation>().First((CodeAnimation x) => ((Object)((Component)x).gameObject).name == objName);
			if (Object.op_Implicit((Object)(object)val))
			{
				AnimationUse val2 = animationType;
				AnimationUse val3 = val2;
				switch ((int)val3)
				{
				case 0:
					val.PlayIn();
					break;
				case 1:
					val.PlayOut();
					break;
				case 3:
					val.PlayBoop();
					break;
				case 2:
					break;
				}
			}
		}
	}
	public class CannotDrown : MonoBehaviour
	{
		public float upForceMultiplier = 2f;
	}
	public class ChangeMaterial : MonoBehaviour
	{
		private List<Material> OriginalMaterials = new List<Material>();

		private Team Team;

		private bool hasChanged;

		[Header("Material Settings")]
		public Renderer renderer;

		public int index;

		public Material newMaterial;

		[Header("Team Color Settings")]
		public Material redMaterial;

		public Material blueMaterial;

		public void Start()
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			Material[] sharedMaterials = renderer.sharedMaterials;
			foreach (Material val in sharedMaterials)
			{
				OriginalMaterials.Add(Object.Instantiate<Material>(val));
			}
			Unit component = ((Component)((Component)this).transform.root).GetComponent<Unit>();
			TeamHolder component2 = ((Component)this).GetComponent<TeamHolder>();
			TeamHolder componentInParent = ((Component)this).GetComponentInParent<TeamHolder>();
			TeamHolder componentInChildren = ((Component)this).GetComponentInChildren<TeamHolder>();
			if (Object.op_Implicit((Object)(object)component))
			{
				Team = component.Team;
			}
			else if (Object.op_Implicit((Object)(object)component2))
			{
				Team = component2.team;
			}
			else if (Object.op_Implicit((Object)(object)componentInParent))
			{
				Team = componentInParent.team;
			}
			else if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				Team = componentInChildren.team;
			}
		}

		public void MaterialChange(float speed)
		{
			hasChanged = true;
			((MonoBehaviour)this).StartCoroutine(DoMaterialChange(index, Object.Instantiate<Material>(renderer.materials[index]), newMaterial, speed));
		}

		public void MaterialRevert(float speed)
		{
			if (hasChanged)
			{
				((MonoBehaviour)this).StopAllCoroutines();
				((MonoBehaviour)this).StartCoroutine(DoMaterialChange(index, newMaterial, OriginalMaterials[index], speed));
			}
		}

		public void MaterialTeamChange(float speed)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			((MonoBehaviour)this).StopAllCoroutines();
			((MonoBehaviour)this).StartCoroutine(DoMaterialChange(index, Object.Instantiate<Material>(renderer.materials[index]), ((int)Team == 0) ? redMaterial : blueMaterial, speed));
		}

		public void MaterialTeamRevert(float speed)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			((MonoBehaviour)this).StopAllCoroutines();
			((MonoBehaviour)this).StartCoroutine(DoMaterialChange(index, ((int)Team == 0) ? redMaterial : blueMaterial, OriginalMaterials[index], speed));
		}

		public void AllMaterialsChange(float speed)
		{
			((MonoBehaviour)this).StopAllCoroutines();
			for (int i = 0; i < renderer.materials.Length; i++)
			{
				((MonoBehaviour)this).StartCoroutine(DoMaterialChange(i, Object.Instantiate<Material>(renderer.materials[i]), newMaterial, speed));
			}
		}

		public void AllMaterialsRevert(float speed)
		{
			((MonoBehaviour)this).StopAllCoroutines();
			for (int i = 0; i < renderer.materials.Length; i++)
			{
				((MonoBehaviour)this).StartCoroutine(DoMaterialChange(i, newMaterial, OriginalMaterials[i], speed));
			}
		}

		public void AllMaterialsTeamChange(float speed)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			((MonoBehaviour)this).StopAllCoroutines();
			for (int i = 0; i < renderer.materials.Length; i++)
			{
				((MonoBehaviour)this).StartCoroutine(DoMaterialChange(i, Object.Instantiate<Material>(renderer.materials[i]), ((int)Team == 0) ? redMaterial : blueMaterial, speed));
			}
		}

		public void AllMaterialsTeamRevert(float speed)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			((MonoBehaviour)this).StopAllCoroutines();
			for (int i = 0; i < renderer.materials.Length; i++)
			{
				((MonoBehaviour)this).StartCoroutine(DoMaterialChange(i, ((int)Team == 0) ? redMaterial : blueMaterial, OriginalMaterials[i], speed));
			}
		}

		public void Stop()
		{
			((MonoBehaviour)this).StopAllCoroutines();
		}

		private IEnumerator DoMaterialChange(int indexToLerp, Material materialToStartWith, Material matToLerpTo, float lerpSpeed)
		{
			float t = 0f;
			while (t < 1f && !Object.op_Implicit((Object)(object)((Component)((Component)this).transform.root).GetComponentsInChildren<UnitEffectBase>().ToList().Find((UnitEffectBase x) => x.effectID == 1987)))
			{
				t += Time.deltaTime * lerpSpeed;
				renderer.materials[indexToLerp].Lerp(materialToStartWith, matToLerpTo, Mathf.Clamp(t, 0f, 1f));
				yield return null;
			}
		}
	}
	public class ChangeOutline : MonoBehaviour
	{
		public Mode outlineMode;

		public Color outlineColor = Color.white;

		[Range(0f, 10f)]
		public float outlineWidth = 1f;

		public void Start()
		{
			//IL_001f: 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)
			Outline component = ((Component)((Component)this).transform.root).GetComponent<Outline>();
			if (Object.op_Implicit((Object)(object)component))
			{
				component.OutlineMode = outlineMode;
				component.SetHighlightColor(outlineColor);
				component.OutlineWidth = outlineWidth;
			}
		}
	}
	public class CollisionStick : MonoBehaviour
	{
		public class IsStuck : MonoBehaviour
		{
			private float Counter;

			public float removeTime;

			public ConfigurableJoint joint;

			public CollisionStick stickParent;

			private void Update()
			{
				Counter += Time.deltaTime;
				if (Counter >= removeTime || !Object.op_Implicit((Object)(object)joint))
				{
					Break();
				}
			}

			public void Break()
			{
				if (Object.op_Implicit((Object)(object)joint))
				{
					Object.Destroy((Object)(object)joint);
				}
				if (Object.op_Implicit((Object)(object)stickParent))
				{
					stickParent.hitList.Remove(this);
				}
				Object.Destroy((Object)(object)this);
			}
		}

		private Rigidbody Rig;

		private TeamHolder TeamHolder;

		private bool Disabled;

		private List<Unit> HasBeenHitList = new List<Unit>();

		public List<IsStuck> hitList = new List<IsStuck>();

		public float breakForce = 30000f;

		public float thresholdMultiplier = 10f;

		public int hitLimit = 10;

		public float removeJointAfterSeconds = 10f;

		public LayerMask hitLayer;

		private void Start()
		{
			Rig = ((Component)this).GetComponent<Rigidbody>();
			TeamHolder = ((Component)this).GetComponent<TeamHolder>();
		}

		public void OnCollisionEnter(Collision col)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			Unit component = ((Component)col.transform.root).GetComponent<Unit>();
			if (!Disabled && Object.op_Implicit((Object)(object)col.rigidbody) && Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)TeamHolder) && component.Team != TeamHolder.team && hitList.Count < hitLimit && !HasBeenHitList.Contains(component) && !Object.op_Implicit((Object)(object)((Component)component).GetComponent<IsStuck>()) && (LayerMask.op_Implicit(hitLayer) & (1 << col.gameObject.layer)) == 0 && Rig.mass > col.rigidbody.mass * thresholdMultiplier)
			{
				HasBeenHitList.Add(component);
				ConfigurableJoint val = JointActions.AttachJoint(col.rigidbody, Rig, 25f, 15f, false, true, 15f);
				((Joint)val).breakForce = breakForce;
				((Joint)val).breakTorque = breakForce;
				IsStuck isStuck = ((Component)component).gameObject.AddComponent<IsStuck>();
				isStuck.joint = val;
				isStuck.removeTime = removeJointAfterSeconds;
				isStuck.stickParent = this;
				hitList.Add(isStuck);
			}
		}

		public void DestroyJoints()
		{
			foreach (IsStuck item in hitList.Where((IsStuck enemy) => Object.op_Implicit((Object)(object)enemy)))
			{
				item.Break();
			}
			hitList.Clear();
			Disabled = true;
		}
	}
	public class CollisionWeaponToggleable : BatchedMonobehaviour, IPoolable
	{
		public enum CallEffectsOn
		{
			Rigidbodies,
			Ground,
			All
		}

		private MeleeWeaponMultiplierPoint MultiplierPoint;

		public bool canDealDamage;

		public float damage = 80f;

		public float selfDamageMultiplier;

		public float impactMultiplier = 1f;

		public float minVelocity;

		public float screenShakeMultiplier = 1f;

		public float onImpactForce;

		public float massCap = 5f;

		public bool ignoreTeamMates;

		public float teamDamage = 0.1f;

		public bool staticDamageValue;

		public bool onlyOncePerData;

		public bool hitFasterAfterDealDamage = true;

		public bool useHitDirection;

		public bool playSoundWhenHitNonRigidbodies = true;

		private readonly List<DataHandler> HitDatas = new List<DataHandler>();

		private Holdable Holdable;

		private DataHandler ConnectedData;

		[HideInInspector]
		public List<Rigidbody> protectedRigs = new List<Rigidbody>();

		private CollisionWeaponEffect[] MeleeWeaponEffects;

		public Weapon weapon;

		public UnityEvent dealDamageEvent;

		private CollisionSound CollisionSound;

		public Damagable lastHitHealth;

		public float cooldown;

		private float SinceLastDamage;

		[HideInInspector]
		public bool onlyCollideWithRigs;

		private Level MyLevel;

		private Unit OwnUnit;

		public CallEffectsOn callEffectsOn;

		private Rigidbody Rig;

		private Action<Collision, float> CollisionAction;

		private Action<Collision, float, Vector3> DealDamageAction;

		public Action ReleaseSelf { get; set; }

		public bool IsManagedByPool { get; set; }

		protected override void Start()
		{
			((BatchedMonobehaviour)this).Start();
			CollisionSound = ((Component)this).GetComponent<CollisionSound>();
			Rig = ((Component)this).GetComponent<Rigidbody>();
			Holdable = ((Component)this).GetComponent<Holdable>();
			OwnUnit = GetOwnUnit();
			if (!Object.op_Implicit((Object)(object)weapon) && Object.op_Implicit((Object)(object)((Component)this).GetComponent<Weapon>()))
			{
				weapon = ((Component)this).GetComponent<Weapon>();
			}
			MeleeWeaponEffects = ((Component)this).GetComponents<CollisionWeaponEffect>();
			MultiplierPoint = ((Component)this).GetComponentInChildren<MeleeWeaponMultiplierPoint>();
			if (Object.op_Implicit((Object)(object)weapon))
			{
				damage *= weapon.levelMultiplier;
			}
			MyLevel = ((Component)this).GetComponent<Level>();
			if (Object.op_Implicit((Object)(object)MyLevel))
			{
				onImpactForce *= Mathf.Pow((float)MyLevel.level, 1.5f);
				massCap *= Mathf.Pow((float)MyLevel.level, 1.5f);
			}
		}

		private Unit GetOwnUnit()
		{
			TeamHolder component = ((Component)this).GetComponent<TeamHolder>();
			if (Object.op_Implicit((Object)(object)component))
			{
				return ((Component)component.spawner.transform.root).GetComponent<Unit>();
			}
			Unit component2 = ((Component)((Component)this).transform.root).GetComponent<Unit>();
			if (Object.op_Implicit((Object)(object)component2))
			{
				return component2;
			}
			if (Object.op_Implicit((Object)(object)ConnectedData))
			{
				return ConnectedData.unit;
			}
			return null;
		}

		public override void BatchedUpdate()
		{
			if (cooldown != 0f)
			{
				SinceLastDamage += Time.deltaTime;
			}
		}

		private void OnCollisionEnter(Collision collision)
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_044e: Unknown result type (might be due to invalid IL or missing references)
			//IL_045e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04db: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0500: Unknown result type (might be due to invalid IL or missing references)
			//IL_0505: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0539: Unknown result type (might be due to invalid IL or missing references)
			//IL_053b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0546: Unknown result type (might be due to invalid IL or missing references)
			//IL_0633: Unknown result type (might be due to invalid IL or missing references)
			//IL_064a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0579: Unknown result type (might be due to invalid IL or missing references)
			//IL_057b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0586: Unknown result type (might be due to invalid IL or missing references)
			//IL_069b: Unknown result type (might be due to invalid IL or missing references)
			if (onlyCollideWithRigs && !Object.op_Implicit((Object)(object)collision.rigidbody))
			{
				return;
			}
			CollisionAction?.Invoke(collision, 0f);
			if (!canDealDamage || (Object.op_Implicit((Object)(object)weapon) && ((object)weapon).GetType() == typeof(MeleeWeapon) && !((MeleeWeapon)weapon).canDealDamage))
			{
				return;
			}
			float num = 0f;
			Vector3 val;
			if (Object.op_Implicit((Object)(object)Rig))
			{
				if (Object.op_Implicit((Object)(object)collision.rigidbody))
				{
					val = collision.impulse;
					num = ((Vector3)(ref val)).magnitude / (Rig.mass + 10f) * 0.3f;
				}
				else
				{
					val = collision.impulse;
					num = ((Vector3)(ref val)).magnitude / Rig.mass * 0.3f;
				}
			}
			num *= impactMultiplier;
			num = Mathf.Clamp(num, 0f, 2f);
			if (num < 1f)
			{
				return;
			}
			if (!Object.op_Implicit((Object)(object)collision.rigidbody))
			{
				DoScreenShake(num, collision);
				if (callEffectsOn == CallEffectsOn.All || callEffectsOn == CallEffectsOn.Ground)
				{
					DoCollisionEffects(collision.transform, collision);
				}
				if (Object.op_Implicit((Object)(object)CollisionSound) && playSoundWhenHitNonRigidbodies)
				{
					CollisionSound.DoEffect(collision.transform, collision, num);
				}
			}
			if (minVelocity != 0f && Object.op_Implicit((Object)(object)Rig))
			{
				val = Rig.velocity;
				if (((Vector3)(ref val)).magnitude < minVelocity)
				{
					return;
				}
			}
			if (!Object.op_Implicit((Object)(object)ConnectedData) && Object.op_Implicit((Object)(object)Holdable) && Holdable.held)
			{
				ConnectedData = Holdable.holderData;
			}
			if ((Object)(object)collision.transform.root == (Object)(object)((Component)this).transform.root || (Object.op_Implicit((Object)(object)ConnectedData) && (Object)(object)((Component)ConnectedData).transform.root == (Object)(object)collision.transform.root) || !Object.op_Implicit((Object)(object)collision.rigidbody) || protectedRigs.Contains(collision.rigidbody) || SinceLastDamage < cooldown)
			{
				return;
			}
			SinceLastDamage = 0f;
			DataHandler componentInParent = ((Component)collision.rigidbody).GetComponentInParent<DataHandler>();
			Damagable componentInParent2 = ((Component)collision.rigidbody).GetComponentInParent<Damagable>();
			if (Object.op_Implicit((Object)(object)componentInParent2))
			{
				if (Object.op_Implicit((Object)(object)componentInParent) && onlyOncePerData)
				{
					if (HitDatas.Contains(componentInParent))
					{
						return;
					}
					HitDatas.Add(componentInParent);
				}
				if (Object.op_Implicit((Object)(object)weapon) && (Object)(object)lastHitHealth == (Object)(object)componentInParent2)
				{
					return;
				}
				lastHitHealth = componentInParent2;
				if (Object.op_Implicit((Object)(object)CollisionSound))
				{
					CollisionSound.DoEffect(collision.transform, collision, num);
				}
				Unit val2 = null;
				if (Object.op_Implicit((Object)(object)componentInParent))
				{
					val2 = ((Component)componentInParent).GetComponentInParent<Unit>();
				}
				if (Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)OwnUnit) && val2.Team == OwnUnit.Team && ignoreTeamMates)
				{
					return;
				}
				if (!Object.op_Implicit((Object)(object)Holdable) && Object.op_Implicit((Object)(object)OwnUnit) && OwnUnit.data.Dead)
				{
					Object.Destroy((Object)(object)this);
					return;
				}
				float num2 = num;
				if (staticDamageValue)
				{
					num2 = 1f;
				}
				if (Object.op_Implicit((Object)(object)MultiplierPoint) && Vector3.Distance(((ContactPoint)(ref collision.contacts[0])).point, ((Component)MultiplierPoint).transform.position) < MultiplierPoint.range)
				{
					num2 *= MultiplierPoint.multiplier;
				}
				if (Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)OwnUnit) && val2.Team == OwnUnit.Team)
				{
					num2 *= teamDamage;
				}
				Vector3 val3 = ((Component)this).transform.forward;
				if (useHitDirection)
				{
					val3 = collision.transform.position - ((Component)this).transform.position;
				}
				if (Object.op_Implicit((Object)(object)componentInParent))
				{
					WilhelmPhysicsFunctions.AddForceWithMinWeight(componentInParent.mainRig, (staticDamageValue ? 5f : Mathf.Sqrt(num * 50f)) * val3 * onImpactForce, (ForceMode)1, massCap);
					WilhelmPhysicsFunctions.AddForceWithMinWeight(collision.rigidbody, (staticDamageValue ? 5f : Mathf.Sqrt(num * 50f)) * val3 * onImpactForce, (ForceMode)1, massCap);
				}
				if (collision.rigidbody.mass < Rig.mass)
				{
					Rigidbody rigidbody = collision.rigidbody;
					rigidbody.velocity *= 0.6f;
					if (Object.op_Implicit((Object)(object)componentInParent))
					{
						Rigidbody mainRig = componentInParent.mainRig;
						mainRig.velocity *= 0.6f;
					}
				}
				if (!Object.op_Implicit((Object)(object)OwnUnit))
				{
					OwnUnit = GetOwnUnit();
				}
				DealDamageAction?.Invoke(collision, damage * num2, val3);
				lastHitHealth.TakeDamage(damage * num2, val3, OwnUnit, (DamageType)0);
				if (selfDamageMultiplier != 0f && Object.op_Implicit((Object)(object)OwnUnit))
				{
					((Damagable)OwnUnit.data.healthHandler).TakeDamage(damage * num2 * selfDamageMultiplier, val3, (Unit)null, (DamageType)0);
				}
				UnityEvent obj = dealDamageEvent;
				if (obj != null)
				{
					obj.Invoke();
				}
				if (Object.op_Implicit((Object)(object)weapon) && hitFasterAfterDealDamage)
				{
					Weapon obj2 = weapon;
					obj2.internalCounter += Random.Range(0f, weapon.internalCooldown * 0.5f);
				}
				if (Object.op_Implicit((Object)(object)componentInParent) && (callEffectsOn == CallEffectsOn.All || callEffectsOn == CallEffectsOn.Rigidbodies))
				{
					DoCollisionEffects(((Component)componentInParent.mainRig).transform, collision);
				}
			}
			else if (Object.op_Implicit((Object)(object)CollisionSound))
			{
				CollisionSound.DoEffect(collision.transform, collision, num);
			}
			DoScreenShake(num, collision);
		}

		private void DoCollisionEffects(Transform targetTransform, Collision collision)
		{
			if (MeleeWeaponEffects != null && MeleeWeaponEffects.Length != 0)
			{
				CollisionWeaponEffect[] meleeWeaponEffects = MeleeWeaponEffects;
				foreach (CollisionWeaponEffect val in meleeWeaponEffects)
				{
					val.DoEffect(targetTransform, collision);
				}
			}
		}

		private void DoScreenShake(float impact, Collision collision)
		{
			//IL_001c: 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_0037: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ScreenShake.Instance != (Object)null)
			{
				ScreenShake.Instance.AddForce(((Component)this).transform.forward * Mathf.Sqrt(impact * 0.5f) * 0.5f * screenShakeMultiplier, ((ContactPoint)(ref collision.contacts[0])).point);
			}
		}

		public void AddCollisionAction(Action<Collision, float> action)
		{
			CollisionAction = (Action<Collision, float>)Delegate.Combine(CollisionAction, action);
		}

		public void AddDealDamageAction(Action<Collision, float, Vector3> action)
		{
			DealDamageAction = (Action<Collision, float, Vector3>)Delegate.Combine(DealDamageAction, action);
		}

		public void Initialize()
		{
		}

		public void Reset()
		{
		}

		public void Release()
		{
			HitDatas.Clear();
		}

		public void SetCanDealDamage(bool value)
		{
			canDealDamage = value;
		}
	}
	public class ConditionalProjectileHitEvent : MonoBehaviour
	{
		private ProjectileHit Hit;

		public UnityEvent hitEvent = new UnityEvent();

		public float delay;

		private void Awake()
		{
			Hit = ((Component)this).GetComponent<ProjectileHit>();
		}

		public void AddEvent()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			List<HitEvents> list = new List<HitEvents>(Hit.hitEvents)
			{
				new HitEvents
				{
					hitEvent = hitEvent,
					eventDelay = delay
				}
			};
			Hit.hitEvents = list.ToArray();
		}
	}
	public class ConnectJointToUnitPart : MonoBehaviour
	{
		public enum BodyPart
		{
			Head,
			Torso,
			Hip,
			ArmLeft,
			ArmRight,
			ElbowLeft,
			ElbowRight,
			LegLeft,
			LegRight,
			KneeLeft,
			KneeRight
		}

		private bool Done;

		private DataHandler OwnData;

		public BodyPart bodyPart;

		public void Go()
		{
			if (!Done)
			{
				Done = true;
				OwnData = ((Component)((Component)this).transform.root).GetComponent<Unit>().data;
				Transform val = (Transform)(bodyPart switch
				{
					BodyPart.Head => OwnData.head, 
					BodyPart.Torso => OwnData.torso, 
					BodyPart.Hip => ((Component)OwnData.hip).transform, 
					BodyPart.ArmLeft => OwnData.leftArm, 
					BodyPart.ArmRight => OwnData.rightArm, 
					BodyPart.ElbowLeft => OwnData.leftHand, 
					BodyPart.ElbowRight => OwnData.rightHand, 
					BodyPart.LegLeft => OwnData.legLeft, 
					BodyPart.LegRight => OwnData.legRight, 
					BodyPart.KneeLeft => OwnData.footLeft, 
					BodyPart.KneeRight => OwnData.footRight, 
					_ => OwnData.torso, 
				});
				ConfigurableJoint component = ((Component)this).GetComponent<ConfigurableJoint>();
				if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)component))
				{
					((Joint)component).connectedBody = ((Component)val).GetComponent<Rigidbody>();
				}
			}
		}
	}
	public class DestroyRootUnit : MonoBehaviour
	{
		private Unit Unit;

		private void Start()
		{
			Unit = ((Component)((Component)this).transform.root).GetComponent<Unit>();
		}

		public void DoDestruction()
		{
			Unit unit = Unit;
			if (unit != null)
			{
				unit.DestroyUnit();
			}
		}
	}
	public class Effect_Bleed : UnitEffectBase
	{
		private Unit Unit;

		private UnitColorHandler ColorHandler;

		private float Counter;

		private float CounterPerStack;

		private int Stacks;

		private float TotalBleedDamage;

		private float TotalDuration;

		private bool Done;

		public float bleedDamage = 10f;

		public float baseDuration = 5f;

		public float durationPerStack = 1f;

		public int maxStacks = 5;

		public UnitColorInstance bleedColor;

		public AnimationCurve colorPerStack;

		public UnityEvent tickEvent;

		private void Update()
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			if (Unit.data.Dead && !Done)
			{
				Done = true;
			}
			if (Done)
			{
				return;
			}
			Counter += Time.deltaTime;
			CounterPerStack += Time.deltaTime;
			if (CounterPerStack >= 1f)
			{
				((Damagable)Unit.data.healthHandler).TakeDamage(TotalBleedDamage, Vector3.zero, (Unit)null, (DamageType)0);
				((MonoBehaviour)this).StartCoroutine(DoColor());
				tickEvent.Invoke();
				CounterPerStack = 0f;
				if (Counter >= TotalDuration)
				{
					Done = true;
				}
			}
		}

		public override void DoEffect()
		{
			Unit = ((Component)((Component)this).transform.root).GetComponent<Unit>();
			ColorHandler = ((Component)Unit.data).GetComponent<UnitColorHandler>();
			TotalDuration = baseDuration;
			AddStack();
		}

		public override void Ping()
		{
			AddStack();
		}

		public void AddStack()
		{
			if (Stacks != maxStacks && !Done)
			{
				Stacks++;
				TotalBleedDamage += bleedDamage;
				TotalDuration += durationPerStack;
			}
		}

		private IEnumerator DoColor()
		{
			if (Object.op_Implicit((Object)(object)ColorHandler))
			{
				float counter = 0f;
				while (counter < ((Keyframe)(ref colorPerStack.keys[colorPerStack.keys.Length - 1])).time)
				{
					ColorHandler.SetColor(bleedColor, colorPerStack.Evaluate(counter));
					counter += Time.deltaTime;
					yield return null;
				}
				if (Done)
				{
					Object.Destroy((Object)(object)((Component)this).gameObject);
				}
			}
		}
	}
	public class Effect_Disintegrate : UnitEffectBase
	{
		private Unit OwnUnit;

		private UnitColorHandler ColorHandler;

		private bool Destroying;

		public float damage;

		public UnityEvent destroyEvent = new UnityEvent();

		public bool destroyRoot = true;

		public bool alwaysDestroy;

		public float destroyDelay;

		public float effectDelay = 0.01f;

		public Material mat;

		private void Awake()
		{
			OwnUnit = ((Component)((Component)this).transform.root).GetComponent<Unit>();
			ColorHandler = ((Component)OwnUnit.data).GetComponent<UnitColorHandler>();
		}

		public override void DoEffect()
		{
			OwnUnit = ((Component)((Component)this).transform.root).GetComponent<Unit>();
			ColorHandler = ((Component)OwnUnit.data).GetComponent<UnitColorHandler>();
			((MonoBehaviour)this).StartCoroutine(AddEffect());
		}

		public override void Ping()
		{
			((MonoBehaviour)this).StartCoroutine(AddEffect());
		}

		private IEnumerator AddEffect()
		{
			yield return (object)new WaitForSeconds(effectDelay);
			if (Object.op_Implicit((Object)(object)OwnUnit))
			{
				((Damagable)OwnUnit.data.healthHandler).TakeDamage(damage, Vector3.zero, (Unit)null, (DamageType)0);
				if (OwnUnit.data.Dead || alwaysDestroy)
				{
					((MonoBehaviour)this).StartCoroutine(DestroyUnit());
				}
			}
		}

		private IEnumerator DestroyUnit()
		{
			if (!Object.op_Implicit((Object)(object)OwnUnit) || Destroying)
			{
				yield break;
			}
			Destroying = true;
			destroyEvent.Invoke();
			yield return (object)new WaitForSeconds(destroyDelay);
			ColorHandler.SetMaterial(mat);
			if (destroyRoot)
			{
				if (Object.op_Implicit((Object)(object)OwnUnit) && Object.op_Implicit((Object)(object)((Component)OwnUnit).GetComponent<GameObjectEntity>()) && World.Active.GetOrCreateManager<TeamSystem>().GetTeamUnits(OwnUnit.Team).Contains(OwnUnit))
				{
					World.Active.GetOrCreateManager<TeamSystem>().RemoveEntity(((Component)OwnUnit).GetComponent<GameObjectEntity>().Entity, OwnUnit.Team, OwnUnit);
				}
				OwnUnit.DestroyUnit();
			}
		}
	}
	public class Effect_Frostbite : UnitEffectBase
	{
		private DataHandler Data;

		private MovementHandler Movement;

		private RotationHandler Rotation;

		private UnitColorHandler ColorHandler;

		private bool Done;

		private CurveAnimation[] AllRigs;

		private MeleeWeapon[] Weapons;

		private float[] DefaultForceMultipliers;

		private float[] DefaultWeaponForces;

		private float DefaultMovementMultiplier;

		private float DefaultTurnMultiplier;

		private float Amount;

		private float HealthMultiplier;

		private INetworkService NetworkService;

		private NetworkBattleController m_networkBattle;

		public float coldAmount = 40f;

		public float slowPerAmount;

		public float removeSlowSpeed = 0.1f;

		public float weaponMultiplier = 1f;

		public UnitColorInstance color;

		[Header("Freezing")]
		public Material iceMaterial;

		public UnityEvent freezeEvent;

		public float frozenMassMultiplier = 1f;

		public float frozenDrag = 1f;

		public float frozenSinkTime = 5f;

		private NetworkBattleController NetworkBattle
		{
			get
			{
				if ((Object)(object)m_networkBattle == (Object)null)
				{
					m_networkBattle = ServiceLocator.GetService<NetworkBattleController>();
				}
				return m_networkBattle;
			}
		}

		private void Start()
		{
			Data = ((Component)((Component)this).transform.root).GetComponentInChildren<DataHandler>();
			Weapons = ((Component)((Component)this).transform.root).GetComponentsInChildren<MeleeWeapon>();
			AllRigs = ((Component)((Component)this).transform.root).GetComponentsInChildren<CurveAnimation>();
			Movement = ((Component)Data).GetComponent<MovementHandler>();
			Rotation = ((Component)Data).GetComponent<RotationHandler>();
			ColorHandler = ((Component)Data).GetComponent<UnitColorHandler>();
			NetworkService = ServiceLocator.GetService<INetworkService>();
			m_networkBattle = ServiceLocator.GetService<NetworkBattleController>();
			DefaultForceMultipliers = new float[AllRigs.Length];
			for (int i = 0; i < AllRigs.Length; i++)
			{
				DefaultForceMultipliers[i] = AllRigs[i].multiplier;
			}
			DefaultWeaponForces = new float[Weapons.Length];
			for (int j = 0; j < Weapons.Length; j++)
			{
				DefaultWeaponForces[j] = Weapons[j].curveForce;
			}
			DefaultMovementMultiplier = Movement.multiplier;
			DefaultTurnMultiplier = Rotation.rotationMultiplier;
			HealthMultiplier = 1f / Mathf.Clamp(Data.maxHealth * 0.01f, 1f, float.PositiveInfinity);
		}

		private void Update()
		{
			if (Done || (Data.Dead && !((UnitEffectBase)this).ShouldSkipDeadTests))
			{
				return;
			}
			bool flag = false;
			for (int i = 0; i < AllRigs.Length; i++)
			{
				if (AllRigs[i].multiplier < DefaultForceMultipliers[i])
				{
					flag = true;
					CurveAnimation obj = AllRigs[i];
					obj.multiplier += Time.deltaTime * removeSlowSpeed;
				}
			}
			for (int j = 0; j < Weapons.Length; j++)
			{
				if (Weapons[j].curveForce < DefaultWeaponForces[j])
				{
					flag = true;
					MeleeWeapon obj2 = Weapons[j];
					obj2.curveForce += Time.deltaTime * removeSlowSpeed * weaponMultiplier;
				}
			}
			if (Movement.multiplier < DefaultMovementMultiplier)
			{
				flag = true;
				MovementHandler movement = Movement;
				movement.multiplier += Time.deltaTime * removeSlowSpeed;
			}
			if (Rotation.rotationMultiplier < DefaultTurnMultiplier)
			{
				flag = true;
				RotationHandler rotation = Rotation;
				rotation.rotationMultiplier += Time.deltaTime * removeSlowSpeed;
			}
			if (flag)
			{
				Amount -= Time.deltaTime * removeSlowSpeed * slowPerAmount;
			}
			if ((Object)(object)ColorHandler != (Object)null)
			{
				ColorHandler.SetColor(color, Mathf.Clamp(Amount * 0.03f, 0f, 1f));
			}
		}

		public override void DoEffect()
		{
			if (!Object.op_Implicit((Object)(object)Data))
			{
				Start();
			}
			Add(coldAmount);
		}

		public override void Ping()
		{
			Add(coldAmount);
		}

		private void Add(float a)
		{
			if ((!Data.Dead || ((UnitEffectBase)this).ShouldSkipDeadTests) && !Done)
			{
				a *= HealthMultiplier;
				Amount += a;
				for (int i = 0; i < AllRigs.Length; i++)
				{
					AllRigs[i].multiplier = DefaultForceMultipliers[i] / (1f + Amount * slowPerAmount);
				}
				for (int j = 0; j < Weapons.Length; j++)
				{
					Weapons[j].curveForce = DefaultWeaponForces[j] / (1f + Amount * slowPerAmount * weaponMultiplier);
				}
				Movement.multiplier = DefaultMovementMultiplier / (1f + Amount * slowPerAmount);
				Rotation.rotationMultiplier = DefaultTurnMultiplier / (1f + Amount * slowPerAmount);
				if (Amount * 0.03f >= 1f)
				{
					FreezeUnit();
				}
			}
		}

		private void FreezeUnit()
		{
			if (!Done && (!Object.op_Implicit((Object)(object)Data) || !Data.Dead || ((UnitEffectBase)this).ShouldSkipDeadTests))
			{
				freezeEvent.Invoke();
				Done = true;
				((MonoBehaviour)this).StartCoroutine(DelayFreeze());
			}
		}

		private IEnumerator DelayFreeze()
		{
			yield return (object)new WaitForSeconds(0.1f);
			if ((Object)(object)Data != (Object)null && (Object)(object)Data.healthHandler != (Object)null && Data.healthHandler.DiedLocally)
			{
				yield break;
			}
			if ((Object)(object)NetworkBattle != (Object)null && NetworkService != null && NetworkService.IsClient)
			{
				if ((Object)(object)ColorHandler != (Object)null)
				{
					ColorHandler.SetMaterial(iceMaterial);
				}
				((UnitEffectBase)this).ShouldSkipDeadTests = false;
				Data.healthHandler.DiedLocally = true;
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
			else
			{
				((UnitEffectBase)this).ShouldSkipDeadTests = false;
				StandardDeath();
			}
		}

		private void StandardDeath()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			ConfigurableJoint[] componentsInChildren = ((Component)((Component)this).transform.root).GetComponentsInChildren<ConfigurableJoint>();
			ConfigurableJoint[] array = componentsInChildren;
			foreach (ConfigurableJoint val in array)
			{
				Object.Destroy((Object)(object)val);
			}
			float num = 0f;
			Vector3 velocity = Data.mainRig.velocity;
			Vector3 val2 = Vector3.zero;
			Rigidbody[] componentsInChildren2 = ((Component)((Component)this).transform.root).GetComponentsInChildren<Rigidbody>();
			foreach (Rigidbody val3 in componentsInChildren2)
			{
				num += val3.mass;
				val2 += val3.velocity / (float)Data.allRigs.AllDrags.Length;
				Object.Destroy((Object)(object)val3);
			}
			if (Object.op_Implicit((Object)(object)ColorHandler))
			{
				ColorHandler.SetMaterial(iceMaterial);
			}
			Rigidbody val4 = ((Component)((Component)Data).transform.root).gameObject.AddComponent<Rigidbody>();
			Data.mainRig = val4;
			val4.mass = num * frozenMassMultiplier;
			val4.velocity = velocity;
			SinkOnDeath val5 = ((Component)val4).gameObject.AddComponent<SinkOnDeath>();
			val5.time = frozenSinkTime;
			val5.Sink();
			val4.drag = frozenDrag;
			val4.angularDrag = frozenDrag;
			val4.interpolation = (RigidbodyInterpolation)1;
			Collider component = ((Component)val4).GetComponent<Collider>();
			if (Object.op_Implicit((Object)(object)component))
			{
				Object.Destroy((Object)(object)component);
			}
			val4.ResetCenterOfMass();
			Data.healthHandler.Die((Unit)null);
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}
	}
	public class Effect_ShareDamage : UnitEffectBase
	{
		private UnitColorHandler ColorHandler;

		private GameModeService GameModeService;

		private SettingsInstance BugUnitsDying;

		private bool ChangingColor;

		[HideInInspector]
		public Unit unit;

		[HideInInspector]
		public Effect_ShareDamage[] connectedUnits;

		public UnitColorInstance damageColor;

		public AnimationCurve colorCurve;

		public override void DoEffect()
		{
			unit = ((Component)((Component)this).transform.root).GetComponent<Unit>();
			ColorHandler = ((Component)unit.data).GetComponent<UnitColorHandler>();
			GameModeService = ServiceLocator.GetService<GameModeService>();
			BugUnitsDying = ServiceLocator.GetService<GlobalSettingsHandler>().GetSettingsInstance("BUG_UNITS_NOT_DYING");
			Unit obj = unit;
			obj.WasDealtDamageAction = (Action<float>)Delegate.Combine(obj.WasDealtDamageAction, new Action<float>(SendDamageToUnits));
		}

		public override void Ping()
		{
			Debug.LogError((object)"Share damage has been pinged??????");
		}

		private IEnumerator DoColor()
		{
			if (Object.op_Implicit((Object)(object)ColorHandler))
			{
				ChangingColor = true;
				float counter = 0f;
				while (counter < ((Keyframe)(ref colorCurve.keys[colorCurve.keys.Length - 1])).time)
				{
					ColorHandler.SetColor(damageColor, colorCurve.Evaluate(counter));
					counter += Time.deltaTime;
					yield return null;
				}
				ChangingColor = false;
			}
		}

		public void SendDamageToUnits(float damage)
		{
			Effect_ShareDamage[] array = connectedUnits;
			foreach (Effect_ShareDamage effect_ShareDamage in array)
			{
				if ((Object)(object)effect_ShareDamage != (Object)null && (Object)(object)effect_ShareDamage != (Object)(object)this)
				{
					effect_ShareDamage.ReceiveDamage(damage, base.damageMultiplier);
				}
			}
		}

		public void ReceiveDamage(float damage, float multiplier)
		{
			if (damage > 0f && unit.data.immunityForSeconds <= 0f && !(unit.data.lifeTime < 0.3f) && !unit.WasDamaged((Rigidbody)null, (Rigidbody)null) && !unit.data.Dead)
			{
				bool flag = true;
				if (Bugs._DLC_ACTIVATED && BugUnitsDying.currentValue == 1)
				{
					flag = GameModeService.IsGameModeRestricted();
				}
				if (flag)
				{
					DataHandler data = unit.data;
					data.health -= damage * multiplier;
					unit.data.health = Mathf.Clamp(unit.data.health, float.NegativeInfinity, unit.data.maxHealth);
				}
				if (unit.data.health <= 0f)
				{
					unit.data.healthHandler.Die((Unit)null);
				}
				if (!ChangingColor)
				{
					((MonoBehaviour)this).StartCoroutine(DoColor());
				}
			}
		}

		private void OnDestroy()
		{
			if (Object.op_Implicit((Object)(object)ColorHandler))
			{
				ColorHandler.colors.RemoveAll((UnitColorInstance x) => x.colorName == damageColor.colorName);
			}
		}
	}
	public class Effect_Shield : UnitEffectBase
	{
		private Unit Unit;

		private UnitColorHandler ColorHandler;

		private GameStateManager m_gameStateManager;

		private float CurrentShield;

		public float shieldAmount = 50f;

		public float shieldDecaySpeed = 5f;

		public float maxShield = 500f;

		public float maxAbsorbedDamage = 1000f;

		public UnitColorInstance shieldColor;

		public AnimationCurve colorByHealthCurve;

		private void Update()
		{
			ModifyCurrentShield((0f - Time.deltaTime) * shieldDecaySpeed);
			if (CurrentShield < maxShield)
			{
				ColorHandler.SetColor(shieldColor, colorByHealthCurve.Evaluate(CurrentShield / maxShield));
			}
		}

		public override void DoEffect()
		{
			Unit = ((Component)((Component)this).transform.root).GetComponent<Unit>();
			ColorHandler = ((Component)Unit.data).GetComponent<UnitColorHandler>();
			m_gameStateManager = ServiceLocator.GetService<GameStateManager>();
			Unit unit = Unit;
			unit.WasDealtDamageAction = (Action<float>)Delegate.Combine(unit.WasDealtDamageAction, new Action<float>(ProtectAgainstDamage));
			HealForAmount(shieldAmount);
		}

		public override void Ping()
		{
			HealForAmount(shieldAmount);
		}

		public void HealForAmount(float amount)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Invalid comparison between Unknown and I4
			if (Object.op_Implicit((Object)(object)Unit) && (m_gameStateManager == null || (int)m_gameStateManager.GameState != 1))
			{
				Unit.WasDamaged(0f - shieldAmount);
				ModifyCurrentShield(amount);
			}
		}

		public void ProtectAgainstDamage(float damage)
		{
			if (!(CurrentShield <= 0f))
			{
				DataHandler data = Unit.data;
				data.health += Mathf.Clamp(damage, 0f, maxAbsorbedDamage);
				ModifyCurrentShield(0f - damage);
			}
		}

		public void ModifyCurrentShield(float amount)
		{
			CurrentShield += amount;
			CurrentShield = Mathf.Clamp(CurrentShield, 0f, maxShield);
		}
	}
	public class Effect_Transformation : UnitEffectBase
	{
		public enum TransformState
		{
			None,
			Transforming,
			Transformed,
			Reverted
		}

		private TransformState CurrentState;

		private float EffectDealt;

		private float StoredHealth;

		private bool StoredAlive;

		private Unit Unit;

		private CameraAbilityPossess Possess;

		private DragHandler DragHandler;

		private RigidbodyHolder RigHolder;

		private List<Vector2> OriginalDrags;

		private UnitColorHandler ColorHandler;

		private Unparent Unparent;

		public UnityEvent globalEvent = new UnityEvent();

		public float globalDelay = 0.3f;

		[Header("Pre-Transform Settings")]
		[Range(0f, 1f)]
		public float percentAffectedThreshold;

		public float transformDelay = 3f;

		public float damageOverTime = 100f;

		public float effectOverTime = 100f;

		public float dragOverTime = 1f;

		[Header("Transform Settings")]
		public UnitBlueprint unitToTransformInto;

		public UnitColorInstance color = new UnitColorInstance();

		[Header("Revert Settings")]
		public float revertDelay = 6f;

		public bool keepOldHealth = true;

		private void Awake()
		{
			Unit = ((Component)((Component)this).transform.root).GetComponent<Unit>();
			DragHandler = ((Component)Unit).GetComponentInChildren<DragHandler>();
			RigHolder = Unit.data.allRigs;
			ColorHandler = ((Component)Unit).GetComponentInChildren<UnitColorHandler>();
			Possess = ((Component)MainCam.instance).GetComponentInParent<CameraAbilityPossess>();
			Unparent = ((Component)this).GetComponent<Unparent>();
			OriginalDrags = new List<Vector2>(RigHolder.AllDrags);
		}

		public override void DoEffect()
		{
			if (!Object.op_Implicit((Object)(object)((Component)Unit).GetComponent<SpawnerBlueprintHolder>()))
			{
				((MonoBehaviour)this).StartCoroutine(BeginTransformation());
			}
		}

		public override void Ping()
		{
		}

		private IEnumerator BeginTransformation()
		{
			yield return (object)new WaitForSeconds(SetState(TransformState.Transforming, doEvent: false));
			if (!Object.op_Implicit((Object)(object)Unit) || Unit.data.Dead || Unit.data.immunityForSeconds > 0f || Object.op_Implicit((Object)(object)((Component)Unit).GetComponentInChildren<UnKillable>()))
			{
				yield break;
			}
			float t = 0f;
			while (t < transformDelay && Object.op_Implicit((Object)(object)Unit) && !Unit.data.Dead)
			{
				EffectDealt += effectOverTime * Time.deltaTime;
				((Damagable)Unit.data.healthHandler).TakeDamage(damageOverTime * Time.deltaTime, Vector3.zero, (Unit)null, (DamageType)0);
				for (int i = 0; i < RigHolder.AllDrags.Length; i++)
				{
					RigHolder.AllDrags[i].x += dragOverTime * Time.deltaTime;
					RigHolder.AllDrags[i].y += dragOverTime * Time.deltaTime;
				}
				if (Object.op_Implicit((Object)(object)DragHandler))
				{
					DragHandler.UpdateDrag();
				}
				ColorHandler.SetColor(color, EffectDealt / (Unit.data.maxHealth * percentAffectedThreshold));
				t += Time.deltaTime;
				yield return null;
			}
			if (Object.op_Implicit((Object)(object)Unit))
			{
				if (EffectDealt / Unit.data.maxHealth >= percentAffectedThreshold)
				{
					StoredHealth = Unit.data.health;
					((MonoBehaviour)this).StartCoroutine(DoTransform());
				}
				else
				{
					((MonoBehaviour)this).StartCoroutine(DontTransform());
				}
			}
		}

		private IEnumerator DoTransform()
		{
			if (!Object.op_Implicit((Object)(object)Unit))
			{
				yield break;
			}
			yield return (object)new WaitForSeconds(SetState(TransformState.Transformed));
			if (!Object.op_Implicit((Object)(object)Unit))
			{
				yield break;
			}
			Unit newUnit = unitToTransformInto.Spawn(Unit.data.mainRig.position, Unit.data.mainRig.rotation, Unit.Team, 1f, (UnitPoolInfo?)null)[0].GetComponent<Unit>();
			((Component)newUnit).gameObject.AddComponent<SpawnerBlueprintHolder>().unitBlueprint = Unit.unitBlueprint;
			if (Object.op_Implicit((Object)(object)Possess) && (Object)(object)Possess.currentUnit == (Object)(object)Unit)
			{
				Possess.EnterUnit(newUnit);
			}
			Rigidbody[] allRigs = newUnit.data.allRigs.AllRigs;
			foreach (Rigidbody rig in allRigs)
			{
				rig.velocity = Unit.data.mainRig.velocity;
			}
			((Component)this).transform.SetParent(((Component)newUnit.data.mainRig).transform);
			((Component)this).transform.localPosition = Vector3.zero;
			StoredAlive = !Unit.data.Dead;
			Unit.DestroyUnit();
			yield return (object)new WaitForSeconds(revertDelay);
			if (!StoredAlive)
			{
				newUnit.data.healthHandler.Die((Unit)null);
			}
			if (!Object.op_Implicit((Object)(object)newUnit))
			{
				yield break;
			}
			yield return (object)new WaitForSeconds(SetState(TransformState.Reverted));
			if (!Object.op_Implicit((Object)(object)newUnit))
			{
				yield break;
			}
			if (StoredAlive)
			{
				Unit = ((Component)newUnit).GetComponent<SpawnerBlueprintHolder>().unitBlueprint.Spawn(newUnit.data.mainRig.position, newUnit.data.mainRig.rotation, Unit.Team, 1f, (UnitPoolInfo?)null)[0].GetComponent<Unit>();
				if (Object.op_Implicit((Object)(object)Possess) && (Object)(object)Possess.currentUnit == (Object)(object)Unit)
				{
					Possess.EnterUnit(Unit);
				}
				Rigidbody[] allRigs2 = Unit.data.allRigs.AllRigs;
				foreach (Rigidbody rig2 in allRigs2)
				{
					rig2.velocity = newUnit.data.mainRig.velocity;
				}
			}
			if (Object.op_Implicit((Object)(object)Unparent))
			{
				Unparent.Go();
			}
			newUnit.DestroyUnit();
			yield return (object)new WaitUntil((Func<bool>)(() => !Object.op_Implicit((Object)(object)Unit) || Unit.data.lifeTime > 0.3f || Unit.data.Dead));
			if (Object.op_Implicit((Object)(object)Unit) && !Unit.data.Dead && keepOldHealth)
			{
				((Damagable)Unit.data.healthHandler).TakeDamage(Unit.data.maxHealth - StoredHealth, Vector3.zero, (Unit)null, (DamageType)0);
			}
		}

		private IEnumerator DontTransform()
		{
			yield return (object)new WaitForSeconds(SetState(TransformState.None, doEvent: false));
			if (!Object.op_Implicit((Object)(object)Unit) || Unit.data.Dead)
			{
				yield break;
			}
			float t = 0f;
			while (t < 1f)
			{
				for (int i = 0; i < RigHolder.AllDrags.Length; i++)
				{
					RigHolder.AllDrags[i].x = Mathf.Lerp(RigHolder.AllDrags[i].x, OriginalDrags[i].x, t);
					RigHolder.AllDrags[i].y = Mathf.Lerp(RigHolder.AllDrags[i].y, OriginalDrags[i].y, t);
				}
				if (Object.op_Implicit((Object)(object)DragHandler))
				{
					DragHandler.UpdateDrag();
				}
				ColorHandler.SetColor(color, 1f - t);
				t += Time.deltaTime;
				yield return null;
			}
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}

		public float SetState(TransformState state, bool doEvent = true)
		{
			CurrentState = state;
			if (doEvent)
			{
				globalEvent.Invoke();
			}
			return globalDelay;
		}
	}
	public class Effect_Weakening : UnitEffectBase
	{
		private int WeakenCount;

		public float dragMultiplier;

		public float speedMultiplier;

		public Material mat;

		public UnitColorInstance color;

		public int weakenLimit = 6;

		public override void DoEffect()
		{
			((UnitEffectBase)this).Ping();
		}

		public override void Ping()
		{
			UnitBlueprint unitBlueprint = ((Component)((Component)this).transform.root).GetComponent<Unit>().unitBlueprint;
			if (unitBlueprint.Name.Contains("One Punch Man") || unitBlueprint.Name.Contains("Seraphim") || ((Object)((Component)this).transform.root).name == "AFTERIMAGE")
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
			WeakenCount++;
			if (weakenLimit > WeakenCount)
			{
				WeakenUnit();
			}
		}

		public void WeakenUnit()
		{
			Vector2[] allDrags = ((Component)((Component)this).transform.root).GetComponentInChildren<RigidbodyHolder>().AllDrags;
			for (int i = 0; i < allDrags.Length; i++)
			{
				allDrags[i].x *= dragMultiplier;
				allDrags[i].y *= dragMultiplier;
			}
			if (Object.op_Implicit((Object)(object)((Component)((Component)this).transform.root).GetComponentInChildren<DragHandler>()))
			{
				((Component)((Component)this).transform.root).GetComponentInChildren<DragHandler>().UpdateDrag();
			}
			if (Object.op_Implicit((Object)(object)((Component)((Compon