Decompiled source of Red Alert v3.0.6

plugins/RA2Mod.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using Aetherium.Items;
using AncientScepter;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using BetterUI;
using EmotesAPI;
using EntityStates;
using EntityStates.AI.Walker;
using EntityStates.Commando;
using EntityStates.Commando.CommandoWeapon;
using EntityStates.Engi.Mine;
using EntityStates.Huntress;
using EntityStates.Toolbot;
using EntityStates.Treebot.Weapon;
using EntityStates.VagrantMonster;
using HG.BlendableTypes;
using IL.EntityStates;
using IL.RoR2;
using IL.RoR2.UI;
using JetBrains.Annotations;
using KinematicCharacterController;
using Mono.Cecil;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using On;
using On.EntityStates.Engi.Mine;
using On.RoR2;
using On.RoR2.CharacterAI;
using On.RoR2.Orbs;
using On.RoR2.UI;
using R2API;
using R2API.Utils;
using RA2Mod.General;
using RA2Mod.General.Components;
using RA2Mod.General.SkillDefs;
using RA2Mod.General.States;
using RA2Mod.Hooks.RoR2;
using RA2Mod.Minions.TeslaTower;
using RA2Mod.Minions.TeslaTower.Components;
using RA2Mod.Minions.TeslaTower.States;
using RA2Mod.Modules;
using RA2Mod.Modules.Achievements;
using RA2Mod.Modules.BaseStates;
using RA2Mod.Modules.Characters;
using RA2Mod.Survivors.Chrono;
using RA2Mod.Survivors.Chrono.Components;
using RA2Mod.Survivors.Chrono.SkillDefs;
using RA2Mod.Survivors.Chrono.States;
using RA2Mod.Survivors.Conscript;
using RA2Mod.Survivors.Conscript.SkillDefs;
using RA2Mod.Survivors.Conscript.States;
using RA2Mod.Survivors.Desolator;
using RA2Mod.Survivors.Desolator.Compat;
using RA2Mod.Survivors.Desolator.Components;
using RA2Mod.Survivors.Desolator.SkillDefs;
using RA2Mod.Survivors.Desolator.States;
using RA2Mod.Survivors.GI;
using RA2Mod.Survivors.GI.Components;
using RA2Mod.Survivors.GI.SkillDefs;
using RA2Mod.Survivors.GI.SkillStates;
using RA2Mod.Survivors.GI.SkillStates.Mine;
using RA2Mod.Survivors.MCV;
using RA2Mod.Survivors.MCV.Components;
using RA2Mod.Survivors.MCV.SkillDefs;
using RA2Mod.Survivors.MCV.States;
using RA2Mod.Survivors.Tesla;
using RA2Mod.Survivors.Tesla.Compat;
using RA2Mod.Survivors.Tesla.Components;
using RA2Mod.Survivors.Tesla.Orbs;
using RA2Mod.Survivors.Tesla.SkillDefs;
using RA2Mod.Survivors.Tesla.States;
using RTAutoSprintEx;
using Rewired;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using RoR2.Achievements;
using RoR2.Audio;
using RoR2.CharacterAI;
using RoR2.ContentManagement;
using RoR2.Orbs;
using RoR2.Projectile;
using RoR2.Skills;
using RoR2.UI;
using RobDriver;
using RobDriver.Modules.Components;
using ShaderSwapper;
using SkillsPlusPlus;
using SkillsPlusPlus.Modifiers;
using Slipstream;
using TILER2;
using ThinkInvisible.TinkersSatchel;
using ThreeEyedGames;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using VRAPI;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyProduct("RA2Mod")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+fc8c1763ebb60b2d1eff078739014e9e8c34b0c7")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("RA2Mod")]
[assembly: AssemblyTitle("RA2Mod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
public class TowerOwnerTrackerComponent : MonoBehaviour
{
	public TeslaTrackerComponentZap OwnerTrackerComponent;
}
public class TowerWeaponComponent : MonoBehaviour
{
	public bool hasTeslaCoil;

	public TeslaSkinDef towerSkinDef;

	private CharacterBody characterBody;

	private void Awake()
	{
		characterBody = ((Component)this).GetComponent<CharacterBody>();
		characterBody.onInventoryChanged += CharacterBody_onInventoryChanged;
	}

	private void Start()
	{
		try
		{
			towerSkinDef = Skins.GetCurrentSkinDef(characterBody) as TeslaSkinDef;
		}
		catch
		{
			Object.Destroy((Object)(object)this);
		}
	}

	private void CharacterBody_onInventoryChanged()
	{
		hasTeslaCoil = characterBody.inventory.GetItemCount(Items.ShockNearby) > 0;
	}
}
public interface IReflectionBarrier
{
	void StoreDamage(DamageInfo damageInfo, float damageStored);
}
public class TeslaTowerControllerController : MonoBehaviour
{
	public static float NearTowerRange = 60f;

	private List<GameObject> teslaTowers = new List<GameObject>();

	private List<GameObject> otherCommandables = new List<GameObject>();

	public bool coilReady
	{
		get
		{
			List<GameObject> nearbyTowers = GetNearbyTowers();
			for (int i = 0; i < nearbyTowers.Count; i++)
			{
				if (nearbyTowers[i].GetComponent<SkillLocator>().FindSkill("Secondary").IsReady())
				{
					return true;
				}
			}
			return false;
		}
	}

	public GameObject GetNearestTower()
	{
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		float num = NearTowerRange * 2f;
		GameObject result = null;
		for (int i = 0; i < teslaTowers.Count; i++)
		{
			GameObject val = teslaTowers[i];
			if (!((Object)(object)val == (Object)null))
			{
				float num2 = Vector3.Distance(val.transform.position, ((Component)this).transform.position);
				if (num2 < NearTowerRange && num2 < num)
				{
					num = num2;
					result = val;
				}
			}
		}
		return result;
	}

	public void commandPrismTowers(HurtBox target)
	{
	}

	public void commandTowers(HurtBox target)
	{
		if (!NetworkServer.active)
		{
			return;
		}
		List<GameObject> nearbyTowers = GetNearbyTowers();
		for (int i = 0; i < nearbyTowers.Count; i++)
		{
			GameObject val = nearbyTowers[i];
			if (!((Object)(object)val == (Object)null))
			{
				val.GetComponent<EntityStateMachine>().SetInterruptState((EntityState)(object)new TowerBigZap
				{
					lightningTarget = target
				}, (InterruptPriority)2);
			}
		}
		for (int j = 0; j < otherCommandables.Count; j++)
		{
			otherCommandables[j].GetComponent<EntityStateMachine>().SetInterruptState((EntityState)(object)new TowerZap
			{
				lightningTarget = target,
				zaps = 2
			}, (InterruptPriority)2);
		}
	}

	public void commandTowersGauntlet(HurtBox target)
	{
		if (!NetworkServer.active)
		{
			return;
		}
		List<GameObject> nearbyTowers = GetNearbyTowers();
		for (int i = 0; i < nearbyTowers.Count; i++)
		{
			GameObject val = nearbyTowers[i];
			if (!((Object)(object)val == (Object)null))
			{
				EntityStateMachine val2 = EntityStateMachine.FindByCustomName(val, "Weapon");
				if (!((Object)(object)val2 == (Object)null))
				{
					val2.SetInterruptState((EntityState)(object)new TowerBigZapGauntlet
					{
						lightningTarget = target
					}, (InterruptPriority)2);
				}
			}
		}
	}

	public int NearbyTowers()
	{
		return GetNearbyTowers().Count;
	}

	public List<GameObject> GetNearbyTowers(GameObject nearObject = null)
	{
		//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)
		if ((Object)(object)nearObject == (Object)null)
		{
			nearObject = ((Component)this).gameObject;
		}
		List<GameObject> list = new List<GameObject>();
		for (int i = 0; i < teslaTowers.Count; i++)
		{
			GameObject val = teslaTowers[i];
			if (!((Object)(object)val == (Object)null))
			{
				float num = Vector3.Distance(val.transform.position, nearObject.transform.position);
				if (num < NearTowerRange)
				{
					list.Add(val);
				}
			}
		}
		return list;
	}

	public void addTower(GameObject towerBodyObject)
	{
		teslaTowers.Add(towerBodyObject);
		towerBodyObject.GetComponent<TowerOwnerTrackerComponent>().OwnerTrackerComponent = ((Component)this).GetComponent<TeslaTrackerComponentZap>();
		SkinRecolorController component = ((Component)((Component)this).gameObject.GetComponent<CharacterBody>().modelLocator.modelTransform).GetComponent<SkinRecolorController>();
		if (Object.op_Implicit((Object)(object)component) && component.Recolors != null)
		{
			SkinRecolorController component2 = ((Component)towerBodyObject.GetComponent<CharacterBody>().modelLocator.modelTransform).GetComponent<SkinRecolorController>();
			if (Object.op_Implicit((Object)(object)component2))
			{
				component2.SetRecolor(component.currentColor);
			}
		}
	}

	public void removeTower(GameObject towerObject)
	{
		teslaTowers.Remove(towerObject);
	}

	public void addNotTower(GameObject notTowerBodyObject)
	{
		otherCommandables.Add(notTowerBodyObject);
	}

	public void removeNotTower(GameObject notTowerBodyObject)
	{
		otherCommandables.Remove(notTowerBodyObject);
	}
}
public class TeslaVRComponent : MonoBehaviour
{
	private CharacterBody body;

	private void Awake()
	{
		body = ((Component)this).GetComponent<CharacterBody>();
	}

	private void Start()
	{
		onHandPairSet();
	}

	private void onHandPairSet()
	{
		if (!(body.baseNameToken != "HABIBI_TESLA_BODY_NAME"))
		{
			SkillLocator skillLocator = body.skillLocator;
			object obj;
			if (skillLocator == null)
			{
				obj = null;
			}
			else
			{
				GenericSkill obj2 = skillLocator.FindSkill("Recolor");
				obj = ((obj2 != null) ? obj2.skillDef : null);
			}
			SkillDef val = (SkillDef)obj;
			if (Object.op_Implicit((Object)(object)val))
			{
				((Component)MotionControls.dominantHand.transform).GetComponentInChildren<SkinRecolorController>().SetRecolor(val.skillName.ToLowerInvariant());
				((Component)MotionControls.nonDominantHand.transform).GetComponentInChildren<SkinRecolorController>().SetRecolor(val.skillName.ToLowerInvariant());
			}
			ChildLocator componentInChildren = ((Component)MotionControls.dominantHand.transform).GetComponentInChildren<ChildLocator>();
			switch (body.skinIndex)
			{
			default:
				componentInChildren.FindChildGameObject("MeshEmission").SetActive(false);
				break;
			case 1u:
				componentInChildren.FindChildGameObject("MeshEmission").SetActive(true);
				break;
			case 2u:
				((Component)MotionControls.nonDominantHand.transform).GetComponentInChildren<ChildLocator>().FindChildGameObject("MeshArmorColor").SetActive(false);
				componentInChildren.FindChildGameObject("MeshEmission").SetActive(true);
				break;
			case 3u:
				componentInChildren.FindChildGameObject("MeshEmission").SetActive(false);
				break;
			}
		}
	}
}
public class TeslaWeaponComponent : MonoBehaviour
{
	public bool hasTeslaCoil;

	public TeslaSkinDef teslaSkinDef;

	private CharacterBody characterBody;

	private Animator animator;

	private void Awake()
	{
		characterBody = ((Component)this).GetComponent<CharacterBody>();
		animator = ((Component)characterBody.modelLocator.modelTransform).GetComponent<Animator>();
		characterBody.onInventoryChanged += CharacterBody_onInventoryChanged;
	}

	private void Start()
	{
		try
		{
			teslaSkinDef = Skins.GetCurrentSkinDef(characterBody) as TeslaSkinDef;
		}
		catch
		{
			Object.Destroy((Object)(object)this);
		}
	}

	private void CharacterBody_onInventoryChanged()
	{
		hasTeslaCoil = characterBody.inventory.GetItemCount(Items.ShockNearby) > 0;
		bool flag = characterBody.inventory.GetItemCount(Items.ChainLightning) > 0 || characterBody.inventory.GetItemCount(Items.ChainLightningVoid) > 0 || characterBody.inventory.GetItemCount(Items.MoveSpeedOnKill) > 0;
		animator.SetBool("LeftHandClosed", flag);
	}
}
public class TeslaZapBarrierController : NetworkBehaviour, IReflectionBarrier
{
	public delegate void StoredDamageEvent(float damageStored);

	private bool _recordingDamage;

	private float _recordedDamage;

	public StoredDamageEvent OnStoredDamage;

	private static int kRpcRpcPlaySoundToClients;

	public void StoreDamage(DamageInfo damageInfo, float damageStored)
	{
		if (_recordingDamage)
		{
			OnStoredDamage?.Invoke(damageStored);
			_recordedDamage += damageStored;
			PlaySound(Mathf.Max(ShieldZapReleaseDamage.MaxDamageCoefficient, _recordedDamage / 5f));
		}
	}

	public void PlaySound(float pitch)
	{
		CallRpcPlaySoundToClients(pitch);
		PlaySoundInternal(pitch);
	}

	[ClientRpc]
	public void RpcPlaySoundToClients(float pitch)
	{
		PlaySoundInternal(pitch);
	}

	private void PlaySoundInternal(float pitch)
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		uint num = Util.PlaySound("Play_Tesla_ShieldTakeDamage", ((Component)this).gameObject);
		AkSoundEngine.SetRTPCValueByPlayingID("Pitch_TeslaCharge", pitch, num);
	}

	public void StartRecordingDamage()
	{
		_recordingDamage = true;
	}

	public float GetReflectedDamage()
	{
		float recordedDamage = _recordedDamage;
		_recordingDamage = false;
		_recordedDamage = 0f;
		return recordedDamage;
	}

	private void UNetVersion()
	{
	}

	protected static void InvokeRpcRpcPlaySoundToClients(NetworkBehaviour obj, NetworkReader reader)
	{
		if (!NetworkClient.active)
		{
			Debug.LogError((object)"RPC RpcPlaySoundToClients called on server.");
		}
		else
		{
			((TeslaZapBarrierController)(object)obj).RpcPlaySoundToClients(reader.ReadSingle());
		}
	}

	public void CallRpcPlaySoundToClients(float pitch)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Expected O, but got Unknown
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		if (!NetworkServer.active)
		{
			Debug.LogError((object)"RPC Function RpcPlaySoundToClients called on client.");
			return;
		}
		NetworkWriter val = new NetworkWriter();
		val.Write((short)0);
		val.Write((short)2);
		val.WritePackedUInt32((uint)kRpcRpcPlaySoundToClients);
		val.Write(((Component)this).GetComponent<NetworkIdentity>().netId);
		val.Write(pitch);
		((NetworkBehaviour)this).SendRPCInternal(val, 0, "RpcPlaySoundToClients");
	}

	static TeslaZapBarrierController()
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Expected O, but got Unknown
		kRpcRpcPlaySoundToClients = -941864279;
		NetworkBehaviour.RegisterRpcDelegate(typeof(TeslaZapBarrierController), kRpcRpcPlaySoundToClients, new CmdDelegate(InvokeRpcRpcPlaySoundToClients));
		NetworkCRC.RegisterBehaviour("TeslaZapBarrierController", 0);
	}

	public override bool OnSerialize(NetworkWriter writer, bool forceAll)
	{
		bool result = default(bool);
		return result;
	}

	public override void OnDeserialize(NetworkReader reader, bool initialState)
	{
	}
}
public class TeslaIndicatorView : MonoBehaviour
{
	public static Color[] targetColors = (Color[])(object)new Color[3]
	{
		Color.cyan,
		Color.red,
		Color.green
	};

	public SpriteRenderer indicatorRenderer;

	public GameObject towerIndicator;

	public static Sprite[] rangeSprites => TeslaAssets.rangeSprites;

	public static Sprite allySprite => TeslaAssets.allySprite;

	public static Sprite towerSprite => TeslaAssets.towerSprite;

	public void SetColor(int currentTarget)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		indicatorRenderer.color = targetColors[currentTarget];
	}

	public void SetSpriteAlly()
	{
		indicatorRenderer.sprite = allySprite;
	}

	public void SetSpriteTower()
	{
		indicatorRenderer.sprite = towerSprite;
	}

	public void SetSpriteRange(int currentRange)
	{
		indicatorRenderer.sprite = rangeSprites[currentRange];
	}

	public void SetTowerIndicator(bool hasTower)
	{
		towerIndicator.SetActive(hasTower);
	}
}
[RequireComponent(typeof(InputBankTest))]
public class TeslaTrackerComponent : MonoBehaviour
{
	public delegate void OnSearchEvent();

	public OnSearchEvent SearchEvent;

	public static float maxTrackingDistance = 50f;

	public float trackingRadiusZap = 1f;

	public float trackingRadiusDash = 3f;

	public float trackerUpdateFrequency = 16f;

	public HurtBox trackingTargetZap;

	public HurtBox trackingTargetDash;

	public List<HealthComponent> dashCooldownTargets = new List<HealthComponent>();

	public List<float> dashCooldownTimers = new List<float>();

	private InputBankTest inputBank;

	private float trackerUpdateStopwatch;

	private void Start()
	{
		inputBank = ((Component)this).GetComponent<InputBankTest>();
	}

	private void FixedUpdate()
	{
		trackerUpdateStopwatch += Time.fixedDeltaTime;
		if (trackerUpdateStopwatch >= 1f / trackerUpdateFrequency)
		{
			OnSearch();
		}
		UpdateCooldownTimers();
	}

	private void UpdateCooldownTimers()
	{
		for (int num = dashCooldownTimers.Count - 1; num >= 0; num--)
		{
			if ((Object)(object)dashCooldownTargets[num] == (Object)null)
			{
				dashCooldownTargets.RemoveAt(num);
				dashCooldownTimers.RemoveAt(num);
			}
			else
			{
				dashCooldownTimers[num] -= Time.fixedDeltaTime;
				if (dashCooldownTimers[num] < 0f)
				{
					dashCooldownTargets.RemoveAt(num);
					dashCooldownTimers.RemoveAt(num);
				}
			}
		}
	}

	public void AddCooldownTarget(HealthComponent healthComponent)
	{
		if (!dashCooldownTargets.Contains(healthComponent))
		{
			dashCooldownTargets.Add(healthComponent);
			dashCooldownTimers.Add(4f);
		}
	}

	private void OnSearch()
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		trackerUpdateStopwatch -= 1f / trackerUpdateFrequency;
		Ray aimRay = default(Ray);
		((Ray)(ref aimRay))..ctor(inputBank.aimOrigin, inputBank.aimDirection);
		FindTrackingTarget(aimRay);
		ZappableTower zappableTower = default(ZappableTower);
		if (Object.op_Implicit((Object)(object)trackingTargetZap) && Object.op_Implicit((Object)(object)trackingTargetZap.hurtBoxGroup) && ((Component)trackingTargetZap.hurtBoxGroup).TryGetComponent<ZappableTower>(ref zappableTower))
		{
			trackingTargetZap = zappableTower.MainHurtbox;
		}
		SearchEvent?.Invoke();
	}

	private bool FindTrackingTarget(Ray aimRay)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		bool flag = SearchForTargetPoint(aimRay);
		if (!flag)
		{
			flag = SearchForTargetSphere(aimRay, trackingRadiusZap);
		}
		if (!Object.op_Implicit((Object)(object)trackingTargetDash))
		{
			SearchForDashTarget(aimRay, trackingRadiusDash);
		}
		return flag;
	}

	private bool SearchForTargetPoint(Ray aimRay)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		return CharacterRaycast(((Component)this).gameObject, aimRay, out trackingTargetZap, out trackingTargetDash, maxTrackingDistance, CommonMasks.bullet, (QueryTriggerInteraction)1);
	}

	private bool SearchForTargetSphere(Ray aimRay, float radius)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		return CharacterSpherecast(((Component)this).gameObject, aimRay, radius, out trackingTargetZap, out trackingTargetDash, maxTrackingDistance, CommonMasks.bullet, (QueryTriggerInteraction)1);
	}

	private bool SearchForDashTarget(Ray aimRay, float radius)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		HurtBox zapHit;
		return CharacterSpherecast(((Component)this).gameObject, aimRay, radius, out zapHit, out trackingTargetDash, maxTrackingDistance, CommonMasks.bullet, (QueryTriggerInteraction)1);
	}

	public bool CharacterRaycast(GameObject bodyObject, Ray ray, out HurtBox zapHit, out HurtBox dashHit, float maxDistance, LayerMask layerMask, QueryTriggerInteraction queryTriggerInteraction)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		RaycastHit[] hits = Physics.RaycastAll(ray, maxDistance, LayerMask.op_Implicit(layerMask), queryTriggerInteraction);
		return HandleCharacterPhysicsCastResults(bodyObject, ray, queryTriggerInteraction, hits, out zapHit, out dashHit);
	}

	public bool CharacterSpherecast(GameObject bodyObject, Ray ray, float radius, out HurtBox zapHit, out HurtBox dashHit, float maxDistance, LayerMask layerMask, QueryTriggerInteraction queryTriggerInteraction)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		RaycastHit[] hits = Physics.SphereCastAll(ray, radius, maxDistance, LayerMask.op_Implicit(layerMask), queryTriggerInteraction);
		return HandleCharacterPhysicsCastResults(bodyObject, ray, queryTriggerInteraction, hits, out zapHit, out dashHit);
	}

	private bool HandleCharacterPhysicsCastResults(GameObject bodyObject, Ray ray, QueryTriggerInteraction queryTriggerInteraction, RaycastHit[] hits, out HurtBox zapHit, out HurtBox dashHit)
	{
		//IL_00a2: 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_00b3: 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)
		zapHit = null;
		dashHit = null;
		float num = float.PositiveInfinity;
		float num2 = float.PositiveInfinity;
		for (int i = 0; i < hits.Length; i++)
		{
			if ((Object)(object)((RaycastHit)(ref hits[i])).collider == (Object)null)
			{
				continue;
			}
			HurtBox component = ((Component)((RaycastHit)(ref hits[i])).collider).GetComponent<HurtBox>();
			if ((Object)(object)component == (Object)null || (Object)(object)component.healthComponent == (Object)null || (Object)(object)component.hurtBoxGroup == (Object)null || ((!Object.op_Implicit((Object)(object)component.hurtBoxGroup) || !Object.op_Implicit((Object)(object)((Component)component.hurtBoxGroup).GetComponent<ZappableTower>())) && Physics.Linecast(((RaycastHit)(ref hits[i])).point, ((Ray)(ref ray)).origin, LayerMask.op_Implicit(((LayerIndex)(ref LayerIndex.world)).mask), queryTriggerInteraction)))
			{
				continue;
			}
			float distance = ((RaycastHit)(ref hits[i])).distance;
			if (!(distance < num) && !(distance < num2))
			{
				continue;
			}
			HealthComponent healthComponent = component.healthComponent;
			if (!Object.op_Implicit((Object)(object)healthComponent) || !((Object)(object)((Component)healthComponent).gameObject == (Object)(object)bodyObject))
			{
				if (distance < num2)
				{
					zapHit = component;
					num2 = distance;
				}
				if (distance < num && !dashCooldownTargets.Contains(component.healthComponent))
				{
					dashHit = component;
					num = distance;
				}
			}
		}
		if ((Object)(object)zapHit == (Object)null && (Object)(object)dashHit == (Object)null)
		{
			return false;
		}
		return true;
	}
}
[RequireComponent(typeof(TeamComponent))]
[RequireComponent(typeof(CharacterBody))]
[RequireComponent(typeof(TeslaTrackerComponent))]
public class TeslaTrackerComponentDash : MonoBehaviour
{
	public class TeslaDashIndicator : Indicator
	{
		public TeslaDashIndicator(GameObject owner, GameObject visualizerPrefab)
			: base(owner, visualizerPrefab)
		{
		}
	}

	private TeslaDashIndicator indicator;

	private TeslaTrackerComponent teslaTrackerComponent;

	private CharacterBody characterBody;

	private TeamComponent teamComponent;

	private HurtBox _trackingTarget;

	private bool _targetingAlly;

	private bool _isDashing;

	private bool _isReady;

	private void Awake()
	{
		indicator = new TeslaDashIndicator(((Component)this).gameObject, TeslaAssets.TeslaIndicatorPrefabDash);
	}

	private void Start()
	{
		teslaTrackerComponent = ((Component)this).GetComponent<TeslaTrackerComponent>();
		characterBody = ((Component)this).GetComponent<CharacterBody>();
		teamComponent = ((Component)this).GetComponent<TeamComponent>();
		TeslaTrackerComponent obj = teslaTrackerComponent;
		obj.SearchEvent = (TeslaTrackerComponent.OnSearchEvent)Delegate.Combine(obj.SearchEvent, new TeslaTrackerComponent.OnSearchEvent(OnSearch));
		characterBody.skillLocator.utility.onSkillChanged += Utility_onSkillChanged;
		Utility_onSkillChanged(characterBody.skillLocator.utility);
	}

	private void OnDestroy()
	{
		TeslaTrackerComponent obj = teslaTrackerComponent;
		obj.SearchEvent = (TeslaTrackerComponent.OnSearchEvent)Delegate.Remove(obj.SearchEvent, new TeslaTrackerComponent.OnSearchEvent(OnSearch));
	}

	private void Utility_onSkillChanged(GenericSkill genericSkill)
	{
		_isDashing = genericSkill.skillDef.skillNameToken == "HABIBI_TESLA_BODY_UTILITY_BLINK_NAME";
	}

	private void FixedUpdate()
	{
		((Indicator)indicator).active = _isDashing && _isReady;
	}

	public HurtBox GetTrackingTarget()
	{
		return _trackingTarget;
	}

	public bool GetIsTargetingTeammate()
	{
		return _targetingAlly;
	}

	public void SetIsReady(bool ready)
	{
		_isReady = ready;
	}

	private void OnSearch()
	{
		_trackingTarget = teslaTrackerComponent.trackingTargetDash;
		setIsTargetingTeammate();
		((Indicator)indicator).targetTransform = (Object.op_Implicit((Object)(object)_trackingTarget) ? ((Component)_trackingTarget).transform : null);
	}

	private void setIsTargetingTeammate()
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		bool targetingAlly = false;
		if (Object.op_Implicit((Object)(object)_trackingTarget))
		{
			targetingAlly = !FriendlyFireManager.ShouldDirectHitProceed(_trackingTarget.healthComponent, teamComponent.teamIndex);
		}
		_targetingAlly = targetingAlly;
	}
}
[RequireComponent(typeof(CharacterBody))]
[RequireComponent(typeof(TeamComponent))]
[RequireComponent(typeof(TeslaTrackerComponent))]
public class TeslaTrackerComponentZap : MonoBehaviour
{
	public enum RangeTier
	{
		CLOSEST,
		MIDDLE,
		FURTHEST
	}

	public enum TargetType
	{
		DEFAULT,
		EMPOWERED,
		ALLY
	}

	public class TeslaZapIndicator : Indicator
	{
		public RangeTier currentRange = RangeTier.FURTHEST;

		public bool empowered;

		public bool targetingAlly;

		public bool towerIsTargeting;

		public TeslaZapIndicator(GameObject owner, GameObject visualizerPrefab)
			: base(owner, visualizerPrefab)
		{
		}

		public override void UpdateVisualizer()
		{
			((Indicator)this).UpdateVisualizer();
			if (Object.op_Implicit((Object)(object)((Indicator)this).visualizerTransform))
			{
				TeslaIndicatorView component = ((Component)((Indicator)this).visualizerTransform).GetComponent<TeslaIndicatorView>();
				TargetType targetType = TargetType.DEFAULT;
				if (empowered)
				{
					targetType = TargetType.EMPOWERED;
				}
				else if (targetingAlly)
				{
					targetType = TargetType.ALLY;
				}
				component.SetColor((int)targetType);
				switch (targetType)
				{
				default:
					component.SetSpriteRange((int)currentRange);
					break;
				case TargetType.EMPOWERED:
					component.SetSpriteTower();
					break;
				case TargetType.ALLY:
					component.SetSpriteAlly();
					break;
				}
				component.SetTowerIndicator(!targetingAlly && towerIsTargeting);
			}
		}
	}

	public static float nearTrackingDistance = 16f;

	public static float mediumTrackingDistance = 28f;

	private TeslaTrackerComponent teslaTrackerComponent;

	private CharacterBody characterBody;

	private TeamComponent teamComponent;

	private TeslaTowerControllerController towerControllerComponent;

	private TeslaZapIndicator indicator;

	private HurtBox _trackingTarget;

	private HealthComponent _towerTargetHealthComponent;

	private bool _targetingAlly;

	private bool _hasTowerNear;

	private bool _empowered;

	private bool _isMelee;

	private void Awake()
	{
		indicator = new TeslaZapIndicator(((Component)this).gameObject, TeslaAssets.TeslaIndicatorPrefab);
		towerControllerComponent = ((Component)this).GetComponent<TeslaTowerControllerController>();
	}

	private void Start()
	{
		teslaTrackerComponent = ((Component)this).GetComponent<TeslaTrackerComponent>();
		characterBody = ((Component)this).GetComponent<CharacterBody>();
		teamComponent = ((Component)this).GetComponent<TeamComponent>();
		TeslaTrackerComponent obj = teslaTrackerComponent;
		obj.SearchEvent = (TeslaTrackerComponent.OnSearchEvent)Delegate.Combine(obj.SearchEvent, new TeslaTrackerComponent.OnSearchEvent(OnSearch));
		characterBody.skillLocator.primary.onSkillChanged += Primary_onSkillChanged;
		Primary_onSkillChanged(characterBody.skillLocator.primary);
	}

	private void OnDestroy()
	{
		TeslaTrackerComponent obj = teslaTrackerComponent;
		obj.SearchEvent = (TeslaTrackerComponent.OnSearchEvent)Delegate.Remove(obj.SearchEvent, new TeslaTrackerComponent.OnSearchEvent(OnSearch));
	}

	private void Primary_onSkillChanged(GenericSkill genericSkill)
	{
		_isMelee = genericSkill.skillDef.skillNameToken == "HABIBI_TESLA_BODY_PRIMARY_PUNCH_NAME";
	}

	public HurtBox GetTowerTrackingTarget()
	{
		if (_targetingAlly)
		{
			return null;
		}
		if (!_hasTowerNear)
		{
			return null;
		}
		if ((Object)(object)_trackingTarget == (Object)null)
		{
			return null;
		}
		if ((Object)(object)_trackingTarget.hurtBoxGroup == (Object)null)
		{
			return null;
		}
		return _trackingTarget.hurtBoxGroup.mainHurtBox;
	}

	public HurtBox GetTrackingTarget()
	{
		return _trackingTarget;
	}

	public bool GetIsTargetingTeammate()
	{
		return _targetingAlly;
	}

	public RangeTier GetTrackingTargetDistance()
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		RangeTier result = RangeTier.FURTHEST;
		float num = Vector3.Distance(((Component)_trackingTarget).transform.position, ((Component)this).transform.position);
		if (num > mediumTrackingDistance)
		{
			result = RangeTier.FURTHEST;
		}
		if (num < mediumTrackingDistance)
		{
			result = RangeTier.MIDDLE;
		}
		if (num < nearTrackingDistance)
		{
			result = RangeTier.CLOSEST;
		}
		return result;
	}

	public void SetTowerLockedTarget(HealthComponent healthComponent)
	{
		_towerTargetHealthComponent = healthComponent;
	}

	public void SetIndicatorEmpowered(bool empowered)
	{
		indicator.empowered = empowered;
		_empowered = empowered;
	}

	private void setIndicatorRange(RangeTier tier)
	{
		indicator.currentRange = tier;
	}

	private void setIndicatorAlly()
	{
		indicator.targetingAlly = _targetingAlly;
	}

	private void setIndicatorTower(bool hasTower)
	{
		indicator.towerIsTargeting = hasTower;
	}

	private void OnEnable()
	{
		((Indicator)indicator).active = true;
	}

	private void OnDisable()
	{
		((Indicator)indicator).active = false;
	}

	private void FixedUpdate()
	{
		((Indicator)indicator).active = !_isMelee || _empowered;
	}

	private void OnSearch()
	{
		_trackingTarget = teslaTrackerComponent.trackingTargetZap;
		setIsTargetingTeammate();
		if (Object.op_Implicit((Object)(object)_trackingTarget))
		{
			setIndicatorRange(GetTrackingTargetDistance());
		}
		((Indicator)indicator).targetTransform = (Object.op_Implicit((Object)(object)_trackingTarget) ? ((Component)_trackingTarget).transform : null);
		if (TeslaConfig.M4_Tower_Targeting.Value)
		{
			setIsTowerTargeting();
		}
	}

	private void setIsTowerTargeting()
	{
		bool indicatorTower = Object.op_Implicit((Object)(object)_towerTargetHealthComponent) && Object.op_Implicit((Object)(object)_trackingTarget) && (Object)(object)_towerTargetHealthComponent == (Object)(object)_trackingTarget.healthComponent;
		if (Object.op_Implicit((Object)(object)_towerTargetHealthComponent))
		{
			setIndicatorTower(indicatorTower);
			return;
		}
		_hasTowerNear = Object.op_Implicit((Object)(object)towerControllerComponent.GetNearestTower());
		setIndicatorTower(_hasTowerNear);
	}

	private void setIsTargetingTeammate()
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		bool targetingAlly = false;
		if (Object.op_Implicit((Object)(object)_trackingTarget))
		{
			targetingAlly = !FriendlyFireManager.ShouldDirectHitProceed(_trackingTarget.healthComponent, teamComponent.teamIndex);
		}
		_targetingAlly = targetingAlly;
		setIndicatorAlly();
	}
}
namespace Slipstream
{
	public static class ExtraHealthbarSegment
	{
		public abstract class BarData
		{
			public SlipHealthbarInfoTracker tracker;

			public HealthBar bar;

			public BarInfo info;

			public BarStyle? cachedStyle;

			private Image _imageReference;

			public virtual Image ImageReference
			{
				get
				{
					return _imageReference;
				}
				set
				{
					if (Object.op_Implicit((Object)(object)_imageReference) && (Object)(object)_imageReference != (Object)(object)value)
					{
						((Graphic)_imageReference).material = ((Graphic)bar.barAllocator.elementPrefab.GetComponent<Image>()).material;
					}
					_imageReference = value;
				}
			}

			public abstract BarStyle GetStyle();

			public virtual void UpdateInfo(ref BarInfo info, HealthBar healthBar)
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				//IL_0048: Unknown result type (might be due to invalid IL or missing references)
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0053: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				if (!cachedStyle.HasValue)
				{
					cachedStyle = GetStyle();
				}
				BarStyle value = cachedStyle.Value;
				info.enabled &= value.enabled;
				info.color = value.baseColor;
				info.imageType = value.imageType;
				info.sprite = value.sprite;
				info.sizeDelta = value.sizeDelta;
			}

			public virtual void CheckInventory(ref BarInfo info, CharacterBody body)
			{
			}

			public virtual void ApplyBar(ref BarInfo info, Image image, HealthComponent source, ref int i)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0086: Unknown result type (might be due to invalid IL or missing references)
				image.type = info.imageType;
				image.sprite = info.sprite;
				((Graphic)image).color = info.color;
				RectTransform val = (RectTransform)((Component)image).transform;
				val.anchorMin = new Vector2(info.normalizedXMin, 0f);
				val.anchorMax = new Vector2(info.normalizedXMax, 1f);
				val.anchoredPosition = Vector2.zero;
				val.sizeDelta = new Vector2(info.sizeDelta * 0.5f + 1f, info.sizeDelta + 1f);
				i++;
			}
		}

		public class SlipHealthbarInfoTracker : MonoBehaviour
		{
			public List<BarData> barInfos;

			public HealthBar healthBar;

			public void CheckInventory(CharacterBody body)
			{
				foreach (BarData barInfo in barInfos)
				{
					barInfo.CheckInventory(ref barInfo.info, body);
				}
			}

			public void UpdateInfo()
			{
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				if (!Object.op_Implicit((Object)(object)healthBar) || !Object.op_Implicit((Object)(object)healthBar.source))
				{
					return;
				}
				HealthBarValues healthBarValues = healthBar.source.GetHealthBarValues();
				foreach (BarData barInfo in barInfos)
				{
					if ((Object)(object)barInfo.tracker == (Object)null)
					{
						barInfo.tracker = this;
					}
					if ((Object)(object)barInfo.bar == (Object)null)
					{
						barInfo.bar = healthBar;
					}
					barInfo.UpdateInfo(ref barInfo.info, healthBar);
				}
			}

			public void ApplyBar(ref int i)
			{
				foreach (BarData barInfo in barInfos)
				{
					if (!barInfo.info.enabled)
					{
						barInfo.ImageReference = null;
					}
					else
					{
						barInfo.ApplyBar(image: barInfo.ImageReference = healthBar.barAllocator.elements[i], info: ref barInfo.info, source: healthBar.source, i: ref i);
					}
				}
			}

			public void Init(HealthBar healthBar)
			{
				this.healthBar = healthBar;
				barInfos = barDataTypes.Select((Type dataType) => (BarData)Activator.CreateInstance(dataType)).ToList();
			}
		}

		private static List<Type> barDataTypes = new List<Type>();

		public static Color defaultBaseColor = new Color(1f, 1f, 1f, 1f);

		public static void AddType<T>() where T : BarData, new()
		{
			barDataTypes.Add(typeof(T));
		}

		public static void Init()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			HealthBar.Awake += new hook_Awake(HealthBar_Awake);
			HealthBar.CheckInventory += new hook_CheckInventory(HealthBar_CheckInventory);
			HealthBar.UpdateBarInfos += new hook_UpdateBarInfos(HealthBar_UpdateBarInfos);
			HealthBar.ApplyBars += new Manipulator(HealthBar_ApplyBars);
		}

		private static void HealthBar_UpdateBarInfos(orig_UpdateBarInfos orig, HealthBar self)
		{
			orig.Invoke(self);
			SlipHealthbarInfoTracker component = ((Component)self).GetComponent<SlipHealthbarInfoTracker>();
			component.UpdateInfo();
		}

		private static void HealthBar_CheckInventory(orig_CheckInventory orig, HealthBar self)
		{
			orig.Invoke(self);
			HealthComponent source = self.source;
			if (!Object.op_Implicit((Object)(object)source))
			{
				return;
			}
			CharacterBody body = source.body;
			if (!Object.op_Implicit((Object)(object)body))
			{
				return;
			}
			Inventory inventory = body.inventory;
			if (Object.op_Implicit((Object)(object)inventory))
			{
				SlipHealthbarInfoTracker component = ((Component)self).GetComponent<SlipHealthbarInfoTracker>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.CheckInventory(body);
				}
			}
		}

		private static void HealthBar_Awake(orig_Awake orig, HealthBar self)
		{
			orig.Invoke(self);
			((Component)self).gameObject.AddComponent<SlipHealthbarInfoTracker>().Init(self);
		}

		private static void HealthBar_ApplyBars(ILContext il)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			int cls = -1;
			FieldReference fld = null;
			val.GotoNext(new Func<Instruction, bool>[3]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdloca(x, ref cls),
				(Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, 0),
				(Instruction x) => ILPatternMatchingExt.MatchStfld(x, ref fld)
			});
			val.GotoNext((MoveType)2, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<BarInfoCollection>(x, "GetActiveCount")
			});
			val.Emit(OpCodes.Ldarg_0);
			val.EmitDelegate<Func<int, HealthBar, int>>((Func<int, HealthBar, int>)delegate(int i, HealthBar bar)
			{
				SlipHealthbarInfoTracker component2 = ((Component)bar).GetComponent<SlipHealthbarInfoTracker>();
				i += component2.barInfos.Count((BarData x) => x.info.enabled);
				return i;
			});
			val.Index = il.Instrs.Count - 2;
			val.Emit(OpCodes.Ldloca, cls);
			val.Emit(OpCodes.Ldarg_0);
			val.Emit(OpCodes.Ldloca, cls);
			val.Emit(OpCodes.Ldfld, fld);
			val.EmitDelegate<Func<HealthBar, int, int>>((Func<HealthBar, int, int>)delegate(HealthBar bar, int i)
			{
				SlipHealthbarInfoTracker component = ((Component)bar).GetComponent<SlipHealthbarInfoTracker>();
				component.ApplyBar(ref i);
				return i;
			});
			val.Emit(OpCodes.Stfld, fld);
		}
	}
}
namespace RA2Mod
{
	internal static class Log
	{
		private static ManualLogSource _logSource;

		public static DateTime _startTime = default(DateTime);

		private static string timesLog = "";

		private static string funnyLog = "";

		internal static void Init(ManualLogSource logSource)
		{
			_logSource = logSource;
		}

		internal static void Debug(object data)
		{
			_logSource.LogDebug(data);
		}

		internal static void Error(object data)
		{
			_logSource.LogError(data);
		}

		internal static void ErrorAssetBundle(string assetName, string bundleName)
		{
			Error("failed to load asset, " + assetName + ", because it does not exist in asset bundle, " + bundleName);
		}

		internal static void Fatal(object data)
		{
			_logSource.LogFatal(data);
		}

		internal static void Info(object data)
		{
			_logSource.LogInfo(data);
		}

		internal static void Message(object data)
		{
			_logSource.LogMessage(data);
		}

		internal static void Warning(object data)
		{
			_logSource.LogWarning(data);
		}

		internal static void WarningNull(string name, object objecte)
		{
			Warning($"{name} is {objecte != null}");
		}

		internal static void WarningDebug(string format, params object[] data)
		{
			DebugWarning(format, data);
		}

		internal static void DebugWarning(string format, params object[] data)
		{
			if (GeneralConfig.Debug.Value)
			{
				_logSource.LogWarning((object)string.Format(format, data));
			}
		}

		internal static void CurrentTime(string funny)
		{
			if (GeneralConfig.Debug.Value)
			{
				funnyLog = funnyLog + "\n" + funny;
				string text = "\n" + (DateTime.Now - _startTime).TotalSeconds.ToString("0.0000");
				timesLog += text;
				_logSource.LogWarning((object)(funny + text));
			}
		}

		internal static void AllTimes()
		{
			if (!string.IsNullOrEmpty(timesLog))
			{
				Warning(timesLog);
				Warning(funnyLog);
			}
		}
	}
	[BepInPlugin("com.TheTimesweeper.RedAlert", "Red Alert", "3.0.5")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class RA2Plugin : BaseUnityPlugin
	{
		public const string MODUID = "com.TheTimesweeper.RedAlert";

		public const string MODNAME = "Red Alert";

		public const string MODVERSION = "3.0.5";

		public const string DEVELOPER_PREFIX = "HABIBI";

		public static RA2Plugin instance;

		public RA2Plugin()
		{
			if (Log._startTime == default(DateTime))
			{
				Log._startTime = DateTime.Now;
			}
		}

		private void Awake()
		{
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			instance = this;
			Log.Init(((BaseUnityPlugin)this).Logger);
			Materials.Init();
			GeneralConfig.Init();
			GeneralCompat.Init();
			GeneralStates.Init();
			GeneralHooks.Init();
			GeneralTokens.Init();
			Log.CurrentTime("START 3.0.5");
			Language.Init();
			new TeslaTrooperSurvivor().Initialize();
			new DesolatorSurvivor().Initialize();
			new ChronoSurvivor().Initialize();
			new GISurvivor().Initialize();
			new ConscriptSurvivor().Initialize();
			new MCVSurvivor().Initialize();
			new ContentPacks().Initialize();
			if (GeneralConfig.Debug.Value)
			{
				SceneManager.sceneLoaded += SceneManager_sceneLoaded;
			}
			LoadingScreenCanvas.Awake += new hook_Awake(LoadingScreenCanvas_Awake);
		}

		private void LoadingScreenCanvas_Awake(orig_Awake orig, LoadingScreenCanvas self)
		{
			PickRandomObjectOnAwake componentInChildren = ((Component)self).GetComponentInChildren<PickRandomObjectOnAwake>();
			AssetBundle val = Asset.LoadAssetBundle("ra2loading");
			Array.Resize(ref componentInChildren.ObjectsToSelect, componentInChildren.ObjectsToSelect.Length + 1);
			componentInChildren.ObjectsToSelect[componentInChildren.ObjectsToSelect.Length - 1] = Object.Instantiate<GameObject>(val.LoadAsset<GameObject>("TeslaTrooperSprite"), ((Component)componentInChildren).transform);
			orig.Invoke(self);
		}

		private void SceneManager_sceneLoaded(Scene arg0, LoadSceneMode arg1)
		{
			if (((Scene)(ref arg0)).name == "title")
			{
				Log.CurrentTime("TITLE SCREEN");
				Log.AllTimes();
			}
		}
	}
}
namespace RA2Mod.Modules
{
	internal static class Asset
	{
		internal static Dictionary<string, AssetBundle> loadedBundles = new Dictionary<string, AssetBundle>();

		internal static Dictionary<string, Action<AssetBundle>> loadingBundles = new Dictionary<string, Action<AssetBundle>>();

		internal static AssetBundle LoadAssetBundle(string bundleName)
		{
			AssetBundle result = null;
			try
			{
				result = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)RA2Plugin.instance).Info.Location), "AssetBundles", bundleName));
			}
			catch (Exception arg)
			{
				Log.Error($"Error loading asset bundle, {bundleName}. Your asset bundle must be in a folder next to your mod dll called 'AssetBundles'. Follow the guide to build and install your mod correctly!\n{arg}");
			}
			return result;
		}

		internal static void LoadAssetBundleAsync(string bundleName, Action<AssetBundle> onComplete)
		{
			if (bundleName == "myassetbundle")
			{
				Log.Error("AssetBundle name hasn't been changed. not loading any assets to avoid conflicts. Everything will now break.\nMake sure to rename your assetbundle filename and rename the AssetBundleName field in your character setup code.");
			}
			if (loadedBundles.ContainsKey(bundleName))
			{
				onComplete(loadedBundles[bundleName]);
				return;
			}
			if (loadingBundles.ContainsKey(bundleName))
			{
				Dictionary<string, Action<AssetBundle>> dictionary = loadingBundles;
				string key = bundleName;
				dictionary[key] = (Action<AssetBundle>)Delegate.Combine(dictionary[key], onComplete);
				return;
			}
			loadingBundles[bundleName] = onComplete;
			string path = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)RA2Plugin.instance).Info.Location), "AssetBundles", bundleName);
			Action<AssetBundle> onComplete2 = delegate(AssetBundle bundle)
			{
				loadedBundles[bundleName] = bundle;
				if (loadingBundles.ContainsKey(bundleName))
				{
					loadingBundles[bundleName]?.Invoke(bundle);
					loadingBundles.Remove(bundleName);
				}
			};
			ContentPacks.asyncLoadCoroutines.Add(LoadAssetBundleFromPathAsync(path, onComplete2));
		}

		internal static IEnumerator LoadAssetBundleFromPathAsync(string path, Action<AssetBundle> onComplete)
		{
			AssetBundleCreateRequest request = AssetBundle.LoadFromFileAsync(path);
			while (!((AsyncOperation)request).isDone)
			{
				yield return null;
			}
			ContentPacks.asyncLoadCoroutines.Add(ShaderSwapper.UpgradeStubbedShadersAsync(request.assetBundle));
			onComplete?.Invoke(request.assetBundle);
		}

		internal static void LoadAssetAsync<T>(this AssetBundle assetBundle, string name, Action<T> onComplete) where T : Object
		{
			ContentPacks.asyncLoadCoroutines.Add(assetBundle.LoadAssetCoroutine(name, onComplete));
		}

		internal static void LoadAssetAsync<T>(string Path, Action<T> onComplete) where T : Object
		{
			ContentPacks.asyncLoadCoroutines.Add(LoadAssetCoroutine(Path, onComplete));
		}

		internal static AsyncAsset<T> AddAsyncAsset<T>(this AssetBundle assetBundle, string name, Action<T> onComplete = null) where T : Object
		{
			return new AsyncAsset<T>(assetBundle, name, onComplete).AddCoroutine();
		}

		internal static AsyncAsset<T> AddAsyncAsset<T>(string path, Action<T> onComplete = null) where T : Object
		{
			return new AsyncAsset<T>(path, onComplete).AddCoroutine();
		}

		internal static IEnumerator LoadAssetCoroutine<T>(this AssetBundle assetBundle, string name, Action<T> onComplete) where T : Object
		{
			AssetBundleRequest request = assetBundle.LoadAssetAsync<T>(name);
			while (!((AsyncOperation)request).isDone)
			{
				yield return null;
			}
			onComplete?.Invoke((T)(object)/*isinst with value type is only supported in some contexts*/);
		}

		internal static IEnumerator LoadAssetCoroutine<T>(object key, Action<T> OnComplete) where T : Object
		{
			AsyncOperationHandle<T> loadAsset = Addressables.LoadAssetAsync<T>(key);
			while (!loadAsset.IsDone)
			{
				yield return null;
			}
			OnComplete?.Invoke(loadAsset.Result);
		}

		internal static void LoadAssetsAsync<T1>(AsyncAsset<T1> load1, Action<T1> onComplete) where T1 : Object
		{
			ContentPacks.asyncLoadCoroutines.Add(LoadAssetsAsyncCoroutine(load1, onComplete));
		}

		internal static IEnumerator LoadAssetsAsyncCoroutine<T1>(AsyncAsset<T1> load1, Action<T1> onComplete) where T1 : Object
		{
			while (!load1.coroutine.MoveNext())
			{
				yield return null;
			}
			onComplete(load1.result);
		}

		internal static void LoadAssetsAsync<T1, T2>(AsyncAsset<T1> load1, AsyncAsset<T2> load2, Action<T1, T2> onComplete) where T1 : Object where T2 : Object
		{
			ContentPacks.asyncLoadCoroutines.Add(LoadAssetsAsyncCoroutine(load1, load2, onComplete));
		}

		internal static IEnumerator LoadAssetsAsyncCoroutine<T1, T2>(AsyncAsset<T1> load1, AsyncAsset<T2> load2, Action<T1, T2> onComplete) where T1 : Object where T2 : Object
		{
			while (!load1.coroutine.MoveNext())
			{
				yield return null;
			}
			while (!load2.coroutine.MoveNext())
			{
				yield return null;
			}
			onComplete(load1.result, load2.result);
		}

		internal static void LoadAssetsAsync<T1, T2, T3>(AsyncAsset<T1> load1, AsyncAsset<T2> load2, AsyncAsset<T3> load3, Action<T1, T2, T3> onComplete) where T1 : Object where T2 : Object where T3 : Object
		{
			ContentPacks.asyncLoadCoroutines.Add(LoadAssetsAsyncCoroutine(load1, load2, load3, onComplete));
		}

		internal static IEnumerator LoadAssetsAsyncCoroutine<T1, T2, T3>(AsyncAsset<T1> load1, AsyncAsset<T2> load2, AsyncAsset<T3> load3, Action<T1, T2, T3> onComplete) where T1 : Object where T2 : Object where T3 : Object
		{
			while (!load1.coroutine.MoveNext())
			{
				yield return null;
			}
			while (!load2.coroutine.MoveNext())
			{
				yield return null;
			}
			while (!load3.coroutine.MoveNext())
			{
				yield return null;
			}
			onComplete(load1.result, load2.result, load3.result);
		}

		internal static void LoadAssetsAsync<T1, T2, T3, T4>(AsyncAsset<T1> load1, AsyncAsset<T2> load2, AsyncAsset<T3> load3, AsyncAsset<T4> load4, Action<T1, T2, T3, T4> onComplete) where T1 : Object where T2 : Object where T3 : Object where T4 : Object
		{
			ContentPacks.asyncLoadCoroutines.Add(LoadAssetsAsyncCoroutine(load1, load2, load3, load4, onComplete));
		}

		internal static IEnumerator LoadAssetsAsyncCoroutine<T1, T2, T3, T4>(AsyncAsset<T1> load1, AsyncAsset<T2> load2, AsyncAsset<T3> load3, AsyncAsset<T4> load4, Action<T1, T2, T3, T4> onComplete) where T1 : Object where T2 : Object where T3 : Object where T4 : Object
		{
			while (!load1.coroutine.MoveNext())
			{
				yield return null;
			}
			while (!load2.coroutine.MoveNext())
			{
				yield return null;
			}
			while (!load3.coroutine.MoveNext())
			{
				yield return null;
			}
			while (!load4.coroutine.MoveNext())
			{
				yield return null;
			}
			onComplete(load1.result, load2.result, load3.result, load4.result);
		}

		internal static IEnumerator LoadFromAddressableOrBundle<T>(AssetBundle assetBundle, string bundlePath, string addressablePath, Action<T> OnComplete) where T : Object
		{
			if (!string.IsNullOrEmpty(bundlePath))
			{
				return assetBundle.LoadAssetCoroutine(bundlePath, OnComplete);
			}
			if (!string.IsNullOrEmpty(addressablePath))
			{
				return LoadAssetCoroutine(addressablePath, OnComplete);
			}
			return null;
		}

		internal static IEnumerator PreLoadAssetsAsync<T>(AssetBundle assetBundle, params string[] paths) where T : Object
		{
			List<IEnumerator> coroutines = PreLoadAssetsAsyncCoroutines<T>(assetBundle, paths);
			for (int i = 0; i < coroutines.Count; i++)
			{
				while (coroutines[i].MoveNext())
				{
					yield return null;
				}
			}
		}

		internal static List<IEnumerator> PreLoadAssetsAsyncCoroutines<T>(AssetBundle assetBundle, params string[] paths) where T : Object
		{
			List<IEnumerator> list = new List<IEnumerator>();
			for (int i = 0; i < paths.Length; i++)
			{
				list.Add(assetBundle.LoadAssetCoroutine<T>(paths[i], null));
			}
			return list;
		}

		internal static IEnumerator LoadBuffIconAsync(BuffDef buffDef, AssetBundle assetBundle, string bundleLoadPath)
		{
			return assetBundle.LoadAssetCoroutine<Sprite>(bundleLoadPath, (Action<Sprite>)delegate(Sprite result)
			{
				buffDef.iconSprite = result;
			});
		}

		internal static IEnumerator LoadBuffIconAsync(BuffDef buffDef, string addressablePath)
		{
			return Asset.LoadAssetCoroutine<Sprite>((object)addressablePath, (Action<Sprite>)delegate(Sprite result)
			{
				buffDef.iconSprite = result;
			});
		}

		internal static GameObject CloneTracer(string originalTracerName, string newTracerName)
		{
			GameObject val = LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/Tracers/" + originalTracerName);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			GameObject val2 = PrefabAPI.InstantiateClone(val, newTracerName, true);
			if (!Object.op_Implicit((Object)(object)val2.GetComponent<EffectComponent>()))
			{
				val2.AddComponent<EffectComponent>();
			}
			if (!Object.op_Implicit((Object)(object)val2.GetComponent<VFXAttributes>()))
			{
				val2.AddComponent<VFXAttributes>();
			}
			if (!Object.op_Implicit((Object)(object)val2.GetComponent<NetworkIdentity>()))
			{
				val2.AddComponent<NetworkIdentity>();
			}
			val2.GetComponent<Tracer>().speed = 250f;
			val2.GetComponent<Tracer>().length = 50f;
			Content.CreateAndAddEffectDef(val2);
			return val2;
		}

		internal static void ConvertAllRenderersToHopooShader(GameObject objectToConvert)
		{
			if (Object.op_Implicit((Object)(object)objectToConvert))
			{
				MeshRenderer[] componentsInChildren = objectToConvert.GetComponentsInChildren<MeshRenderer>();
				foreach (MeshRenderer val in componentsInChildren)
				{
					((Renderer)val).sharedMaterial?.ConvertDefaultShaderToHopoo();
				}
				SkinnedMeshRenderer[] componentsInChildren2 = objectToConvert.GetComponentsInChildren<SkinnedMeshRenderer>();
				foreach (SkinnedMeshRenderer val2 in componentsInChildren2)
				{
					((Renderer)val2).sharedMaterial?.ConvertDefaultShaderToHopoo();
				}
			}
		}

		internal static GameObject LoadCrosshair(string crosshairName)
		{
			GameObject val = LegacyResourcesAPI.Load<GameObject>("Prefabs/Crosshair/" + crosshairName + "Crosshair");
			if ((Object)(object)val == (Object)null)
			{
				Log.Error("could not load crosshair with the name " + crosshairName + ". defaulting to Standard");
				return LegacyResourcesAPI.Load<GameObject>("Prefabs/Crosshair/StandardCrosshair");
			}
			return val;
		}

		internal static GameObject LoadEffect(this AssetBundle assetBundle, string resourceName, bool parentToTransform)
		{
			return assetBundle.LoadEffect(resourceName, "", parentToTransform);
		}

		internal static GameObject LoadEffect(this AssetBundle assetBundle, string resourceName, string soundName = "", bool parentToTransform = false)
		{
			GameObject val = assetBundle.LoadAsset<GameObject>(resourceName);
			if (!Object.op_Implicit((Object)(object)val))
			{
				Log.ErrorAssetBundle(resourceName, ((Object)assetBundle).name);
				return null;
			}
			CreateEffectFromObject(val, soundName, parentToTransform);
			return val;
		}

		internal static void CreateEffectFromObject(GameObject newEffect, string soundName, bool parentToTransform)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			newEffect.AddComponent<DestroyOnTimer>().duration = 6f;
			newEffect.AddComponent<NetworkIdentity>();
			if (!Object.op_Implicit((Object)(object)newEffect.GetComponent<VFXAttributes>()))
			{
				newEffect.AddComponent<VFXAttributes>().vfxPriority = (VFXPriority)2;
			}
			EffectComponent component = newEffect.GetComponent<EffectComponent>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				component = newEffect.AddComponent<EffectComponent>();
				component.applyScale = true;
				component.effectIndex = (EffectIndex)(-1);
				component.parentToReferencedTransform = parentToTransform;
				component.positionAtReferencedTransform = true;
				component.soundName = soundName;
			}
			Content.CreateAndAddEffectDef(newEffect);
		}

		internal static GameObject CreateProjectileGhostPrefab(this AssetBundle assetBundle, string ghostName)
		{
			GameObject val = assetBundle.LoadAsset<GameObject>(ghostName);
			if ((Object)(object)val == (Object)null)
			{
				Log.Error("Failed to load ghost prefab " + ghostName);
			}
			if (!Object.op_Implicit((Object)(object)val.GetComponent<NetworkIdentity>()))
			{
				val.AddComponent<NetworkIdentity>();
			}
			if (!Object.op_Implicit((Object)(object)val.GetComponent<ProjectileGhostController>()))
			{
				val.AddComponent<ProjectileGhostController>();
			}
			ConvertAllRenderersToHopooShader(val);
			return val;
		}

		internal static GameObject CloneProjectilePrefab(string prefabName, string newPrefabName)
		{
			return PrefabAPI.InstantiateClone(LegacyResourcesAPI.Load<GameObject>("Prefabs/Projectiles/" + prefabName), newPrefabName);
		}

		internal static GameObject LoadAndAddProjectilePrefab(this AssetBundle assetBundle, string newPrefabName)
		{
			GameObject val = assetBundle.LoadAsset<GameObject>(newPrefabName);
			if ((Object)(object)val == (Object)null)
			{
				Log.ErrorAssetBundle(newPrefabName, ((Object)assetBundle).name);
				return null;
			}
			Content.AddProjectilePrefab(val);
			return val;
		}
	}
	public class AsyncAsset<T> where T : Object
	{
		public T result;

		public bool isDone;

		public IEnumerator coroutine;

		public Action<T> onComplete;

		public static implicit operator T(AsyncAsset<T> asset)
		{
			return asset.result;
		}

		public AsyncAsset(string path_, Action<T> onComplete_ = null)
		{
			onComplete = onComplete_;
			coroutine = Asset.LoadAssetCoroutine<T>(path_, OnCoroutineComplete);
		}

		public AsyncAsset(AssetBundle bundle_, string name_, Action<T> onComplete_ = null)
		{
			onComplete = onComplete_;
			coroutine = bundle_.LoadAssetCoroutine<T>(name_, OnCoroutineComplete);
		}

		public AsyncAsset<T> AddCoroutine()
		{
			ContentPacks.asyncLoadCoroutines.Add(coroutine);
			return this;
		}

		public void OnCoroutineComplete(T loadResult)
		{
			result = loadResult;
			isDone = true;
			onComplete?.Invoke(result);
		}
	}
	internal static class CameraParams
	{
		internal static CharacterCameraParamsData CreateCameraParams(float pivotVerticalOffset, Vector3 idealPosition, float pitch = 70f, float wallCushion = 0.1f, float fov = 0f)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			CharacterCameraParamsData result = default(CharacterCameraParamsData);
			result.maxPitch = BlendableFloat.op_Implicit(pitch);
			result.minPitch = BlendableFloat.op_Implicit(0f - pitch);
			result.pivotVerticalOffset = BlendableFloat.op_Implicit(pivotVerticalOffset);
			result.idealLocalCameraPos = BlendableVector3.op_Implicit(idealPosition);
			result.wallCushion = BlendableFloat.op_Implicit(wallCushion);
			if (fov != 0f)
			{
				result.fov = new BlendableFloat
				{
					value = fov,
					alpha = 1f
				};
			}
			return result;
		}

		internal static CameraParamsOverrideHandle OverrideCameraParams(CameraTargetParams camParams, CharacterCameraParamsData paramsData, float transitionDuration = 0.5f)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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_001f: 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)
			CameraParamsOverrideRequest val = default(CameraParamsOverrideRequest);
			val.cameraParamsData = paramsData;
			val.priority = 1f;
			CameraParamsOverrideRequest val2 = val;
			return camParams.AddParamsOverride(val2, transitionDuration);
		}
	}
	public class ConfigEntry<T>
	{
		public ConfigEntry<T> ActualConfigEntry;

		public T DefaultValue;

		public T Value
		{
			get
			{
				if (ActualConfigEntry != null)
				{
					return ActualConfigEntry.Value;
				}
				return DefaultValue;
			}
		}

		public ConfigEntry(ConfigEntry<T> actualConfigEntry, T defaultValue)
		{
			ActualConfigEntry = actualConfigEntry;
			DefaultValue = defaultValue;
		}
	}
	public static class Config
	{
		public static ConfigFile MyConfig = ((BaseUnityPlugin)RA2Plugin.instance).Config;

		private static List<string> disabledSections = new List<string>();

		private static bool enableAll = true;

		private static bool loadedIcon;

		public static void DisableSection(string section)
		{
			disabledSections.Add(section);
		}

		private static bool SectionDisabled(string section)
		{
			return disabledSections.Contains(section);
		}

		public static void ConfigureBody(CharacterBody bodyComponent, string section, string bodyInfoTitle = "")
		{
			if (string.IsNullOrEmpty(bodyInfoTitle))
			{
				bodyInfoTitle = ((Object)bodyComponent).name;
			}
			bodyComponent.baseMaxHealth = BindAndOptions(section, bodyInfoTitle + " Base Max Health", bodyComponent.baseMaxHealth, 0f, 1000f, "levelMaxHealth will be adjusted accordingly (baseMaxHealth * 0.3)", restartRequired: true).Value;
			bodyComponent.levelMaxHealth = Mathf.Round(bodyComponent.baseMaxHealth * 0.3f);
			bodyComponent.baseRegen = BindAndOptions(section, bodyInfoTitle + " Base Regen", bodyComponent.baseRegen, "levelRegen will be adjusted accordingly (baseRegen * 0.2)", restartRequired: true).Value;
			bodyComponent.levelRegen = bodyComponent.baseRegen * 0.2f;
			bodyComponent.baseArmor = BindAndOptions(section, bodyInfoTitle + " Armor", bodyComponent.baseArmor, "", restartRequired: true).Value;
			bodyComponent.baseDamage = BindAndOptions(section, bodyInfoTitle + " Base Damage", bodyComponent.baseDamage, "pretty much all survivors are 12. If you want to change damage, change damage of the moves instead.\nlevelDamage will be adjusted accordingly (baseDamage * 0.2)", restartRequired: true).Value;
			bodyComponent.levelDamage = bodyComponent.baseDamage * 0.2f;
			bodyComponent.baseJumpCount = BindAndOptions(section, bodyInfoTitle + " Jump Count", bodyComponent.baseJumpCount, "", restartRequired: true).Value;
		}

		public static void ConfigureSkillDef(SkillDef skillDef, string section, string skillTitle, bool cooldown = true, bool maxStock = true, bool rechargeStock = false)
		{
			if (cooldown)
			{
				skillDef.baseRechargeInterval = BindAndOptions(section, skillTitle + " cooldown", skillDef.baseRechargeInterval, 0f, 20f, "", restartRequired: true).Value;
			}
			if (maxStock)
			{
				skillDef.baseMaxStock = BindAndOptions(section, skillTitle + " stocks", skillDef.baseMaxStock, 0f, 100f, "", restartRequired: true).Value;
			}
			if (rechargeStock)
			{
				skillDef.rechargeStock = BindAndOptions(section, skillTitle + " recharge stocks", skillDef.baseMaxStock, 0f, 100f, "", restartRequired: true).Value;
			}
		}

		public static ConfigEntry<bool> CharacterEnableConfig(string section, string characterName, string description = "", bool enabledByDefault = true)
		{
			if (string.IsNullOrEmpty(description))
			{
				description = "Set to false to disable this character and as much of its code and content as possible";
			}
			return BindAndOptions(section, "Enable " + characterName, enabledByDefault, description, restartRequired: true);
		}

		public static ConfigEntry<T> BindAndOptionsSlider<T>(string section, string name, T defaultValue, float min = 0f, float max = 20f, string description = "", bool restartRequired = false)
		{
			return BindAndOptions(section, name, defaultValue, min, max, description, restartRequired);
		}

		public static ConfigEntry<T> BindAndOptions<T>(string section, string name, T defaultValue, string description = "", bool restartRequired = false)
		{
			return BindAndOptions(section, name, defaultValue, 0f, 20f, description, restartRequired);
		}

		public static ConfigEntry<T> BindAndOptions<T>(string section, string name, T defaultValue, float min, float max, string description = "", bool restartRequired = false)
		{
			if (string.IsNullOrEmpty(description))
			{
				description = name;
			}
			description += $"\nDefault: {defaultValue}";
			if (restartRequired)
			{
				description += "\n(restart required)";
			}
			if (!enableAll && SectionDisabled(section))
			{
				return new ConfigEntry<T>(null, defaultValue);
			}
			ConfigEntry<T> val = MyConfig.Bind<T>(section, name, defaultValue, description);
			if (Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"))
			{
				TryRegisterOption<T>(val, min, max, restartRequired);
			}
			return new ConfigEntry<T>(val, defaultValue);
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private static void TryRegisterOption<T>(ConfigEntry<T> entry, float min, float max, bool restartRequired)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//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_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			if (entry is ConfigEntry<float>)
			{
				ModSettingsManager.AddOption((BaseOption)new SliderOption(entry as ConfigEntry<float>, new SliderConfig
				{
					min = min,
					max = max,
					formatString = "{0:0.00}",
					restartRequired = restartRequired
				}));
			}
			if (entry is ConfigEntry<int>)
			{
				ModSettingsManager.AddOption((BaseOption)new IntSliderOption(entry as ConfigEntry<int>, new IntSliderConfig
				{
					min = (int)min,
					max = (int)max,
					restartRequired = restartRequired
				}));
			}
			if (entry is ConfigEntry<bool>)
			{
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(entry as ConfigEntry<bool>, restartRequired));
			}
			if (entry is ConfigEntry<KeyboardShortcut>)
			{
				ModSettingsManager.AddOption((BaseOption)new KeyBindOption(entry as ConfigEntry<KeyboardShortcut>, restartRequired));
			}
			if (!loadedIcon)
			{
				loadedIcon = true;
				try
				{
					ModSettingsManager.SetModIcon(ImgHandler.LoadSpriteFromModFolder("icon.png"));
				}
				catch (Exception ex)
				{
					Log.Error("error adding ROO mod icon\n" + ex);
				}
			}
		}

		public static bool GetKeyPressed(KeyboardShortcut entry)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref entry)).Modifiers)
			{
				if (!Input.GetKey(modifier))
				{
					return false;
				}
			}
			return Input.GetKeyDown(((KeyboardShortcut)(ref entry)).MainKey);
		}
	}
	internal class Content
	{
		internal static void AddCharacterBodyPrefab(GameObject bprefab)
		{
			ContentPacks.bodyPrefabs.Add(bprefab);
		}

		internal static void AddMasterPrefab(GameObject prefab)
		{
			ContentPacks.masterPrefabs.Add(prefab);
		}

		internal static void AddProjectilePrefab(GameObject prefab)
		{
			ContentPacks.projectilePrefabs.Add(prefab);
		}

		internal static void NetworkAndAddProjectilePrefab(GameObject prefab)
		{
			PrefabAPI.RegisterNetworkPrefab(prefab);
			AddProjectilePrefab(prefab);
		}

		internal static void AddSurvivorDef(SurvivorDef survivorDef)
		{
			ContentPacks.survivorDefs.Add(survivorDef);
		}

		internal static void CreateSurvivor(GameObject bodyPrefab, GameObject displayPrefab, Color charColor, string tokenPrefix)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			CreateSurvivor(bodyPrefab, displayPrefab, charColor, tokenPrefix, null, 100f);
		}

		internal static void CreateSurvivor(GameObject bodyPrefab, GameObject displayPrefab, Color charColor, string tokenPrefix, float sortPosition)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			CreateSurvivor(bodyPrefab, displayPrefab, charColor, tokenPrefix, null, sortPosition);
		}

		internal static void CreateSurvivor(GameObject bodyPrefab, GameObject displayPrefab, Color charColor, string tokenPrefix, UnlockableDef unlockableDef)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			CreateSurvivor(bodyPrefab, displayPrefab, charColor, tokenPrefix, unlockableDef, 100f);
		}

		internal static void CreateSurvivor(GameObject bodyPrefab, GameObject displayPrefab, Color charColor, string tokenPrefix, UnlockableDef unlockableDef, float sortPosition)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			SurvivorDef val = ScriptableObject.CreateInstance<SurvivorDef>();
			val.bodyPrefab = bodyPrefab;
			val.displayPrefab = displayPrefab;
			val.primaryColor = charColor;
			val.cachedName = ((Object)bodyPrefab).name.Replace("Body", "");
			val.displayNameToken = tokenPrefix + "NAME";
			val.descriptionToken = tokenPrefix + "DESCRIPTION";
			val.outroFlavorToken = tokenPrefix + "OUTRO_FLAVOR";
			val.mainEndingEscapeFailureFlavorToken = tokenPrefix + "OUTRO_FAILURE";
			val.desiredSortPosition = sortPosition;
			val.unlockableDef = unlockableDef;
			AddSurvivorDef(val);
		}

		internal static void AddUnlockableDef(UnlockableDef unlockableDef)
		{
			ContentPacks.unlockableDefs.Add(unlockableDef);
		}

		internal static UnlockableDef CreateAndAddUnlockbleDef(string identifier, string nameToken, Sprite achievementIcon)
		{
			UnlockableDef val = ScriptableObject.CreateInstance<UnlockableDef>();
			val.cachedName = identifier;
			val.nameToken = nameToken;
			val.achievementIcon = achievementIcon;
			AddUnlockableDef(val);
			return val;
		}

		internal static void AddNetworkedObject(GameObject gameObject)
		{
			ContentPacks.networkedObjects.Add(gameObject);
		}

		internal static void AddSkillDef(SkillDef skillDef)
		{
			ContentPacks.skillDefs.Add(skillDef);
		}

		internal static void AddSkillFamily(SkillFamily skillFamily)
		{
			ContentPacks.skillFamilies.Add(skillFamily);
		}

		internal static void AddEntityState(Type entityState)
		{
			ContentPacks.entityStates.Add(entityState);
		}

		internal static void AddBuffDef(BuffDef buffDef)
		{
			ContentPacks.buffDefs.Add(buffDef);
		}

		internal static BuffDef CreateAndAddBuff(string buffName, Sprite buffIcon, Color buffColor, bool canStack, bool isDebuff)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			BuffDef val = ScriptableObject.CreateInstance<BuffDef>();
			((Object)val).name = buffName;
			val.buffColor = buffColor;
			val.canStack = canStack;
			val.isDebuff = isDebuff;
			val.eliteDef = null;
			val.iconSprite = buffIcon;
			AddBuffDef(val);
			return val;
		}

		internal static void AddItemDef(ItemDef itemDef)
		{
			ContentPacks.itemDefs.Add(itemDef);
		}

		internal static void AddEffectDef(EffectDef effectDef)
		{
			ContentPacks.effectDefs.Add(effectDef);
		}

		internal static EffectDef CreateAndAddEffectDef(GameObject effectPrefab)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			EffectDef val = new EffectDef(effectPrefab);
			AddEffectDef(val);
			return val;
		}

		internal static void AddNetworkSoundEventDef(NetworkSoundEventDef networkSoundEventDef)
		{
			ContentPacks.networkSoundEventDefs.Add(networkSoundEventDef);
		}

		internal static NetworkSoundEventDef CreateAndAddNetworkSoundEventDef(string eventName)
		{
			NetworkSoundEventDef val = ScriptableObject.CreateInstance<NetworkSoundEventDef>();
			val.akId = AkSoundEngine.GetIDFromString(eventName);
			val.eventName = eventName;
			AddNetworkSoundEventDef(val);
			return val;
		}
	}
	internal class ContentPacks : IContentPackProvider
	{
		internal ContentPack contentPack = new ContentPack();

		public static List<GameObject> bodyPrefabs = new List<GameObject>();

		public static List<GameObject> masterPrefabs = new List<GameObject>();

		public static List<GameObject> projectilePrefabs = new List<GameObject>();

		public static List<SurvivorDef> survivorDefs = new List<SurvivorDef>();

		public static List<UnlockableDef> unlockableDefs = new List<UnlockableDef>();

		public static List<SkillFamily> skillFamilies = new List<SkillFamily>();

		public static List<SkillDef> skillDefs = new List<SkillDef>();

		public static List<Type> entityStates = new List<Type>();

		public static List<EntityStateConfiguration> entityStateConfigurations = new List<EntityStateConfiguration>();

		public static List<BuffDef> buffDefs = new List<BuffDef>();

		public static List<EffectDef> effectDefs = new List<EffectDef>();

		public static List<ItemDef> itemDefs = new List<ItemDef>();

		public static List<NetworkSoundEventDef> networkSoundEventDefs = new List<NetworkSoundEventDef>();

		public static List<GameObject> networkedObjects = new List<GameObject>();

		public static List<IEnumerator> asyncLoadCoroutines = new List<IEnumerator>();

		public string identifier => "com.TheTimesweeper.RedAlert";

		public void Initialize()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			ContentManager.collectContentPackProviders += new CollectContentPackProvidersDelegate(ContentManager_collectContentPackProviders);
		}

		private void ContentManager_collectContentPackProviders(AddContentPackProviderDelegate addContentPackProvider)
		{
			addContentPackProvider.Invoke((IContentPackProvider)(object)this);
		}

		public IEnumerator LoadStaticContentAsync(LoadStaticContentAsyncArgs args)
		{
			contentPack.identifier = identifier;
			Log.CurrentTime("LoadStaticContentAsync start");
			for (int i = 0; i < asyncLoadCoroutines.Count; i++)
			{
				while (asyncLoadCoroutines[i].MoveNext())
				{
					yield return null;
				}
			}
			Log.CurrentTime("LoadStaticContentAsync done");
			contentPack.bodyPrefabs.Add(bodyPrefabs.ToArray());
			contentPack.masterPrefabs.Add(masterPrefabs.ToArray());
			contentPack.projectilePrefabs.Add(projectilePrefabs.ToArray());
			contentPack.survivorDefs.Add(survivorDefs.ToArray());
			contentPack.unlockableDefs.Add(unlockableDefs.ToArray());
			contentPack.skillDefs.Add(skillDefs.ToArray());
			contentPack.skillFamilies.Add(skillFamilies.ToArray());
			contentPack.entityStateTypes.Add(entityStates.ToArray());
			contentPack.entityStateConfigurations.Add(entityStateConfigurations.ToArray());
			contentPack.buffDefs.Add(buffDefs.ToArray());
			contentPack.effectDefs.Add(effectDefs.ToArray());
			contentPack.itemDefs.Add(itemDefs.ToArray());
			contentPack.networkSoundEventDefs.Add(networkSoundEventDefs.ToArray());
			contentPack.networkedObjectPrefabs.Add(networkedObjects.ToArray());
			args.ReportProgress(1f);
		}

		public IEnumerator GenerateContentPackAsync(GetContentPackAsyncArgs args)
		{
			ContentPack.Copy(contentPack, args.output);
			args.ReportProgress(1f);
			yield break;
		}

		public IEnumerator FinalizeAsync(FinalizeAsyncArgs args)
		{
			args.ReportProgress(1f);
			yield break;
		}
	}
	public static class ImgHandler
	{
		public static Sprite LoadSprite(string path, string name)
		{
			Texture2D texture2D = LoadTex2D(path, pointFilter: true);
			return CreateSprite(texture2D, name);
		}

		public static Texture2D LoadTex2D(string fullFilePath, bool pointFilter = false)
		{
			Texture2D val = LoadPNG(fullFilePath, pointFilter);
			if (pointFilter)
			{
				((Texture)val).filterMode = (FilterMode)0;
				val.Apply();
			}
			return val;
		}

		private static Sprite CreateSprite(Texture2D texture2D, string name)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			((Object)texture2D).name = name;
			((Texture)texture2D).filterMode = (FilterMode)0;
			texture2D.Apply();
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(0f, 0f, (float)((Texture)texture2D).width, (float)((Texture)texture2D).height);
			Sprite val2 = Sprite.Create(texture2D, val, new Vector2(0.5f, 0.5f), 16f);
			((Object)val2).name = name;
			return val2;
		}

		public static Texture2D LoadPNG(params string[] pathDirectories)
		{
			string text = pathDirectories[0];
			for (int i = 1; i < pathDirectories.Length; i++)
			{
				text = Path.Combine(text, pathDirectories[i]);
			}
			return LoadPNG(text);
		}

		public static Texture2D LoadPNG(string filePath, bool pointFilter = false)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			Texture2D val = new Texture2D(2, 2);
			byte[] array = File.ReadAllBytes(filePath);
			ImageConversion.LoadImage(val, array);
			((Texture)val).filterMode = (FilterMode)((!pointFilter) ? 1 : 0);
			val.Apply();
			return val;
		}

		internal static Sprite LoadSpriteFromModFolder(string fileName)
		{
			Texture2D texture2D = LoadTex2DFromPModFolder(fileName);
			return CreateSprite(texture2D, fileName);
		}

		internal static Texture2D LoadTex2DFromPModFolder(string fileName, bool pointFilter = false)
		{
			string fullFilePath = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)RA2Plugin.instance).Info.Location), fileName);
			return LoadTex2D(fullFilePath, pointFilter);
		}
	}
	internal static class ItemDisplayCheck
	{
		public static List<Object> allDisplayedItems;

		public static void PrintUnused(ItemDisplayRuleSet itemDisplayRuleSet, string bodyName = "")
		{
			PrintUnused((IEnumerable<KeyAssetRuleGroup>)itemDisplayRuleSet.keyAssetRuleGroups.ToList(), bodyName);
		}

		public static void PrintUnused(IEnumerable<KeyAssetRuleGroup> ruleSet = null, string bodyName = "")
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			string text = "generating item displays for " + bodyName;
			if (allDisplayedItems == null)
			{
				LazyGatherAllItems();
			}
			List<Object> list = new List<Object>(allDisplayedItems);
			string text2 = "";
			if (ruleSet != null)
			{
				foreach (KeyAssetRuleGroup item in ruleSet)
				{
					if (item.displayRuleGroup.rules.Length != 0)
					{
						list.Remove(item.keyAsset);
						if (string.IsNullOrEmpty(text2))
						{
							text2 = item.displayRuleGroup.rules[0].childName;
						}
					}
				}
			}
			if (string.IsNullOrEmpty(text2))
			{
				text2 = "Chest";
			}
			foreach (Object item2 in list)
			{
				string text3 = "";
				if (ItemDisplays.KeyAssetDisplayRules.ContainsKey(item2))
				{
					text3 += SpitOutNewRule(item2, text2, ItemDisplays.KeyAssetDisplayRules[item2]);
				}
				else
				{
					Log.Error($"COULD NOT FIND DISPLAY PREFABS FOR KEYASSET {item2}");
				}
				text += text3;
			}
			Log.Message(text);
		}

		private static void LazyGatherAllItems()
		{
			allDisplayedItems = new List<Object>(ItemDisplays.KeyAssetDisplayRules.Keys);
			allDisplayedItems.Sort(delegate(Object item1, Object item2)
			{
				if (item1 is ItemDef && item2 is ItemDef)
				{
					return item1.name.CompareTo(item2.name);
				}
				if (item1 is EquipmentDef && item2 is EquipmentDef)
				{
					return item1.name.CompareTo(item2.name);
				}
				if (item1 is ItemDef && item2 is EquipmentDef)
				{
					return -1;
				}
				return (item1 is EquipmentDef && item2 is ItemDef) ? 1 : 0;
			});
		}

		private static string SpitOutNewRule(Object asset, string firstCompatibleChild, ItemDisplayRule[] displayRules)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			if (displayRules.Length == 0)
			{
				return $"\n[NO DISPLAY RULES FOUND FOR THE KEYASSET {asset}";
			}
			string text = "\n            itemDisplayRules.Add(ItemDisplays.CreateDisplayRuleGroupWithRules(ItemDisplays.KeyAssets[\"" + asset.name + "\"]";
			for (int i = 0; i < displayRules.Length; i++)
			{
				text = (((int)displayRules[i].limbMask != 0) ? (text + ",\n" + $"                ItemDisplays.CreateLimbMaskDisplayRule(LimbFlags.{displayRules[i].limbMask})") : (text + ",\n                ItemDisplays.CreateDisplayRule(ItemDisplays.LoadDisplay(\"" + ((Object)displayRules[i].followerPrefab).name + "\"),\n                    \"" + firstCompatibleChild + "\",\n                    new Vector3(2, 2, 2),\n                    new Vector3(0, 0, 0),\n                    new Vector3(1, 1, 1)\n                    )"));
			}
			return text + "\n                ));";
		}
	}
	internal static class ItemDisplays
	{
		private static Dictionary<string, GameObject> itemDisplayPrefabs = new Dictionary<string, GameObject>();

		public static Dictionary<Object, ItemDisplayRule[]> KeyAssetDisplayRules = new Dictionary<Object, ItemDisplayRule[]>();

		public static Dictionary<string, Object> KeyAssets = new Dictionary<string, Object>();

		public static bool initialized = false;

		public static bool initializing = false;

		public static event Action OnDisplaysPopulated;

		public static void SetItemDisplaysWhenReady(Action onComplete)
		{
			if (initialized)
			{
				onComplete?.Invoke();
				return;
			}
			OnDisplaysPopulated += onComplete;
			if (!initializing)
			{
				initializing = true;
				ContentPacks.asyncLoadCoroutines.Add(PopulateDisplays());
				RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(DisposeWhenDone));
			}
		}

		internal static void DisposeWhenDone()
		{
			initialized = false;
			initializing = false;
			itemDisplayPrefabs = null;
			KeyAssetDisplayRules = null;
			KeyAssets = null;
		}

		internal static IEnumerator PopulateDisplays()
		{
			IEnumerator loadIDRS = Asset.LoadAssetCoroutine<GameObject>((object)"RoR2/Base/Loader/LoaderBody.prefab", (Action<GameObject>)delegate(GameObject result)
			{
				PopulateFromBody(result);
			});
			while (loadIDRS.MoveNext())
			{
				yield return null;
			}
			PopulateCustomLightningArm();
			initialized = true;
			ItemDisplays.OnDisplaysPopulated?.Invoke();
		}

		private static void PopulateFromBody(GameObject bodyPrefab)
		{
			ItemDisplayRuleSet itemDisplayRuleSet = ((Component)bodyPrefab.GetComponent<ModelLocator>().modelTransform).GetComponent<CharacterModel>().itemDisplayRuleSet;
			KeyAssetRuleGroup[] keyAssetRuleGroups = itemDisplayRuleSet.keyAssetRuleGroups;
			for (int i = 0; i < keyAssetRuleGroups.Length; i++)
			{
				ItemDisplayRule[] rules = keyAssetRuleGroups[i].displayRuleGroup.rules;
				KeyAssetDisplayRules[keyAssetRuleGroups[i].keyAsset] = rules;
				KeyAssets[keyAssetRuleGroups[i].keyAsset.name] = keyAssetRuleGroups[i].keyAsset;
				for (int j = 0; j < rules.Length; j++)
				{
					GameObject followerPrefab = rules[j].followerPrefab;
					if (Object.op_Implicit((Object)(object)followerPrefab))
					{
						string key = ((Object)followerPrefab).name?.ToLowerInvariant();
						if (!itemDisplayPrefabs.ContainsKey(key))
						{
							itemDisplayPrefabs[key] = followerPrefab;
						}
					}
				}
			}
		}

		private static void PopulateCustomLightningArm()
		{
			GameObject val = PrefabAPI.InstantiateClone(itemDisplayPrefabs["displaylightningarmright"], "DisplayLightningCustom", false);
			LimbMatcher component = val.GetComponent<LimbMatcher>();
			component.limbPairs[0].targetChildLimb = "LightningArm1";
			component.limbPairs[1].targetChildLimb = "LightningArm2";
			component.limbPairs[2].targetChildLimb = "LightningArmEnd";
			itemDisplayPrefabs["displaylightningarmcustom"] = val;
		}

		public static GameObject LoadDisplay(string name)
		{
			if (itemDisplayPrefabs.ContainsKey(name.ToLowerInvariant()) && Object.op_Implicit((Object)(object)itemDisplayPrefabs[name.ToLowerInvariant()]))
			{
				return itemDisplayPrefabs[name.ToLowerInvariant()];
			}
			Log.Error("item display " + name + " returned null");
			return null;
		}

		public static KeyAssetRuleGroup CreateGenericDisplayRule(Object itemDef, string prefabName, string childName, Vector3 position, Vector3 rotation, Vector3 scale)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			return CreateDisplayRuleGroupWithRules(itemDef, CreateDisplayRule(prefabName, childName, position, rotation, scale));
		}

		public static KeyAssetRuleGroup CreateGenericDisplayRule(Object itemDef, GameObject prefab, string childName, Vector3 position, Vector3 rotation, Vector3 scale)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			return CreateDisplayRuleGroupWithRules(itemDef, CreateDisplayRule(prefab, childName, position, rotation, scale));
		}

		public static KeyAssetRuleGroup CreateDisplayRuleGroupWithRules(string itemName, params ItemDisplayRule[] rules)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return CreateDisplayRuleGroupWithRules(GetKeyAssetFromString(itemName), rules);
		}

		public static KeyAssetRuleGroup CreateDisplayRuleGroupWithRules(Object keyAsset_, params ItemDisplayRule[] rules)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if (keyAsset_ == (Object)null)
			{
				Log.Error("could not find keyasset");
			}
			KeyAssetRuleGroup result = default(KeyAssetRuleGroup);
			result.keyAsset = keyAsset_;
			result.displayRuleGroup = new DisplayRuleGroup
			{
				rules = rules
			};
			return result;
		}

		public static ItemDisplayRule CreateDisplayRule(string prefabName, string childName, Vector3 position, Vector3 rotation, Vector3 scale)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			return CreateDisplayRule(LoadDisplay(prefabName), childName, position, rotation, scale);
		}

		public static ItemDisplayRule CreateDisplayRule(GameObject itemPrefab, string childName, Vector3 position, Vector3 rotation, Vector3 scale)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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_002b: 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_0033: 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_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)
			ItemDisplayRule result = default(ItemDisplayRule);
			result.ruleType = (ItemDisplayRuleType)0;
			result.childName = childName;
			result.followerPrefab = itemPrefab;
			result.limbMask = (LimbFlags)0;
			result.localPos = position;
			result.localAngles = rotation;
			result.localScale = scale;
			return result;
		}

		public static ItemDisplayRule CreateLimbMaskDisplayRule(LimbFlags limb)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			ItemDisplayRule result = default(ItemDisplayRule);
			result.ruleType = (ItemDisplayRuleType)1;
			result.limbMask = limb;
			result.childName = "";
			result.followerPrefab = null;
			return result;
		}

		private static Object GetKeyAssetFromString(string itemName)
		{
			Object val = KeyAssets[itemName];
			if (val == (Object)null)
			{
				Log.Error("Could not load keyasset for " + itemName);
			}
			return val;
		}
	}
	internal static class LanguageAPI
	{
		public static void Add(string token, string text)
		{
			Language.Add(token, text);
		}
	}
	internal static class Language
	{
		public static string TokensOutput = "";

		public static bool printingEnabled = false;

		public static void Init()
		{
			Language.collectLanguageRootFolders += Language_collectLanguageRootFolders;
		}

		private static void Language_collectLanguageRootFolders(List<string> obj)
		{
			string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)RA2Plugin.instance).Info.Location), "Language");
			if (Directory.Exists(text))
			{
				obj.Add(text);
			}
		}

		public static void Add(string token, string text)
		{
			LanguageAPI.Add(token, text, "en");
			if (printingEnabled)
			{
				TokensOutput = TokensOutput + "\n    \"" + token + "\" : \"" + text.Replace(Environment.NewLine, "\\n").Replace("\n", "\\n") + "\",";
			}
		}

		public static void PrintOutput(string fileName = "")
		{
			if (printingEnabled)
			{
				string text = "{\n    strings:\n    {" + TokensOutput + "\n    }\n}";
				Log.Message(fileName + ": \n" + text);
				if (!string.IsNullOrEmpty(fileName))
				{
					string path = Path.Combine(Directory.GetParent(((BaseUnityPlugin)RA2Plugin.instance).Info.Location).FullName, "Language", "en", fileName);
					File.WriteAllText(path, text);
				}
				TokensOutput = "";
			}
		}
	}
	internal static class Materials
	{
		private static List<Material> cachedMaterials = new List<Material>();

		internal static Shader _hotpoo;

		internal static Shader hotpoo
		{
			get
			{
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_hotpoo == (Object)null)
				{
					Log.Warning("Hotpoo was null. doing the big scary waitforcompletion");
					_hotpoo = Addressables.LoadAssetAsync<Shader>((object)"RoR2/Base/Shaders/HGStandard.shader").WaitForCompletion();
				}
				return _hotpoo;
			}
			set
			{
				_hotpoo = value;
			}
		}

		public static void Init()
		{
			ContentPacks.asyncLoadCoroutines.Add(Asset.LoadAssetCoroutine<Shader>((object)"RoR2/Base/Shaders/HGStandard.shader", (Action<Shader>)delegate(Shader result)
			{
				hotpoo = result;
			}));
		}

		[Obsolete("CreateHopooMaterialFromBundle is a bit more descriptive")]
		public static Material LoadMaterial(this AssetBundle assetBundle, string materialName)
		{
			return assetBundle.CreateHopooMaterialFromBundle(materialName);
		}

		public static Material CreateHopooMaterialFromBundle(this AssetBundle assetBundle, string materialName)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			Material val = cachedMaterials.Find(delegate(Material mat)
			{
				materialName.Replace(" (Instance)", "");
				return ((Object)mat).name.Contains(materialName);
			});
			if (Object.op_Implicit((Object)(object)val))
			{
				Log.Debug(((Object)val).name + " has already been loaded. returning cached");
				return val;
			}
			val = assetBundle.LoadAsset<Material>(materialName);
			if (!Object.op_Implicit((Object)(object)val))
			{
				Log.ErrorAssetBundle(materialName, ((Object)assetBundle).name);
				return new Material(hotpoo);
			}
			return val.ConvertDefaultShaderToHopoo();
		}

		public static Material SetHopooMaterial(this Material tempMat)
		{
			return tempMat.ConvertDefaultShaderToHopoo();
		}

		public static Material ConvertDefaultShaderToHopoo(this Material tempMat)
		{
			//IL_00aa: 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)
			if (cachedMaterials.Contains(tempMat))
			{
				Log.Debug(((Object)tempMat).name + " has already been loaded. returning cached");
				return tempMat;
			}
			string text = ((Object)tempMat.shader).name.ToLowerInvariant();
			if (!text.StartsWith("standard") && !text.StartsWith("autodesk"))
			{
				Log.Debug(((Object)tempMat).name + " is not unity standard shader. aborting material conversion");
				return tempMat;
			}
			float? num = null;
			Color? val = null;
			if (tempMat.IsKeywordEnabled("_NORMALMAP"))
			{
				num = tempMat.GetFloat("_BumpScale");
			}
			if (tempMat.IsKeywordEnabled("_EMISSION"))
			{
				val = tempMat.GetColor("_EmissionColor");
			}
			tempMat.shader = hotpoo;
			tempMat.SetTexture("_EmTex", tempMat.GetTexture("_EmissionMap"));
			tempMat.EnableKeyword("DITHER");
			if (num.HasValue)
			{
				tempMat.SetFloat("_NormalStrength", num.Value);
				tempMat.SetTexture("_NormalTex", tempMat.GetTexture("_BumpMap"));
			}
			if (val.HasValue)
			{
				tempMat.SetColor("_EmColor", val.Value);
				tempMat.SetFloat("_EmPower", 1f);
			}
			if (tempMat.IsKeywordEnabled("NOCULL"))
			{
				tempMat.SetInt("_Cull", 0);
			}
			if (tempMat.IsKeywordEnabled("LIMBREMOVAL"))
			{
				tempMat.SetInt("_LimbRemovalOn", 1);
			}
			cachedMaterials.Add(tempMat);
			return tempMat;
		}

		public static Material MakeUnique(this Material material)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			if (cachedMaterials.Contains(material))
			{
				return new Material(material);
			}
			return material;
		}

		public static Material SetColor(this Material material, Color color)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			material.SetColor("_Color", color);
			return material;
		}

		public static Material SetNormal(this Material material, float normalStrength = 1f)
		{
			material.SetFloat("_NormalStrength", normalStrength);
			return material;
		}

		public static Material SetEmission(this Material material)
		{
			return material.SetEmission(1f);
		}

		public static Material SetEmission(this Material material, float emission)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return material.SetEmission(emission, Color.white);
		}

		public static Material SetEmission(this Material material, float emission, Color emissionColor)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			material.SetFloat("_EmPower", emission);
			material.SetColor("_EmColor", emissionColor);
			return material;
		}

		publ