Decompiled source of FeverishTempoDelta v1.0.25

BepInEx/plugins/Local-FeverishTempoDelta/FeverishTempoDelta.dll

Decompiled 17 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using EntityStates;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using On.EntityStates;
using On.RoR2;
using On.RoR2.UI;
using RoR2;
using RoR2.ContentManagement;
using RoR2.Skills;
using RoR2.UI;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace FeverishTempo;

public sealed class DeltaContent : IContentPackProvider
{
	private readonly ContentPack pack = new ContentPack();

	private GameObject holder;

	public static GameObject BodyPrefab;

	public static GameObject MasterPrefab;

	public static GameObject DisplayPrefab;

	public static SurvivorDef Survivor;

	internal static BuffDef BlueMeterBuff;

	internal static BuffDef PinkMeterBuff;

	internal static BuffDef SpMeterBuff;

	internal static BuffDef FrenzyMeterBuff;

	public static BuffDef FractureBuff;

	public static BuffDef ImmobilizeBuff;

	public string identifier => "local.FeverishTempoDelta";

	public DeltaContent()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		typeof(ContentPack).GetProperty("identifier").GetSetMethod(nonPublic: true).Invoke(pack, new object[1] { identifier });
	}

	public IEnumerator LoadStaticContentAsync(LoadStaticContentAsyncArgs args)
	{
		AsyncOperationHandle<GameObject> bodyLoad = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Merc/MercBody.prefab");
		AsyncOperationHandle<GameObject> masterLoad = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Merc/MercMonsterMaster.prefab");
		AsyncOperationHandle<GameObject> displayLoad = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Merc/MercDisplay.prefab");
		yield return bodyLoad;
		yield return masterLoad;
		yield return displayLoad;
		if (!Object.op_Implicit((Object)(object)bodyLoad.Result) || !Object.op_Implicit((Object)(object)masterLoad.Result) || !Object.op_Implicit((Object)(object)displayLoad.Result))
		{
			throw new InvalidOperationException("Required movement skeleton prefab unavailable.");
		}
		holder = new GameObject("FeverishTempoDelta_PrefabHolder");
		holder.SetActive(false);
		Object.DontDestroyOnLoad((Object)(object)holder);
		BodyPrefab = Object.Instantiate<GameObject>(bodyLoad.Result, holder.transform, false);
		((Object)BodyPrefab).name = "FeverishTempoDeltaBody";
		BodyPrefab.SetActive(true);
		AssignNetworkId(BodyPrefab, "fde14cf47bba4b329048cde5a3245a81");
		Component mercController = BodyPrefab.GetComponent("MercController");
		if (Object.op_Implicit((Object)(object)mercController))
		{
			Object.DestroyImmediate((Object)(object)mercController);
		}
		CharacterBody body = BodyPrefab.GetComponent<CharacterBody>();
		body.baseNameToken = "DELTA_NAME";
		body.subtitleNameToken = "DELTA_SUBTITLE";
		body.baseMaxHealth = 155f;
		body.levelMaxHealth = 46.5f;
		body.baseRegen = 1f;
		body.levelRegen = 0.2f;
		body.baseDamage = 13f;
		body.levelDamage = 2.6f;
		body.baseArmor = 20f;
		body.levelArmor = 0f;
		body.baseMoveSpeed = 7f;
		body.baseJumpCount = 2;
		body.baseCrit = CorePlugin.Positive(CorePlugin.DreamCrit, 0f);
		body.levelCrit = 0f;
		body.bodyFlags = (BodyFlags)0;
		body.portraitIcon = (Texture)(object)DeltaAssets.GetPortrait();
		BlueMeterBuff = MeterBuff("DeltaBlueEnergy", new Color(0.2f, 0.65f, 1f));
		PinkMeterBuff = MeterBuff("DeltaPinkEnergy", new Color(1f, 0.35f, 0.65f));
		SpMeterBuff = MeterBuff("DeltaSP", new Color(0.9f, 0.8f, 0.25f));
		FrenzyMeterBuff = MeterBuff("DeltaFrenzyEnergy", new Color(0.72f, 0.4f, 0.95f));
		FractureBuff = MeterBuff("DeltaSourceTimeFracture", new Color(0.8f, 0.6f, 1f));
		FractureBuff.canStack = false;
		FractureBuff.isDebuff = true;
		ImmobilizeBuff = MeterBuff("DeltaSourceImmobilize", new Color(0.8f, 0.2f, 0.7f));
		ImmobilizeBuff.canStack = false;
		ImmobilizeBuff.isDebuff = true;
		pack.buffDefs.Add((BuffDef[])(object)new BuffDef[6] { BlueMeterBuff, PinkMeterBuff, SpMeterBuff, FrenzyMeterBuff, FractureBuff, ImmobilizeBuff });
		DeltaFracture.Install(FractureBuff, ImmobilizeBuff);
		BodyPrefab.AddComponent<DeltaPassives>();
		BodyPrefab.AddComponent<DeltaController>();
		BodyPrefab.AddComponent<DeltaAirbornePresentation>();
		DeltaVoice.LoadOriginalVoices();
		BodyPrefab.AddComponent<DeltaVoice>();
		DeltaCombatAudio.LoadOriginalSfx();
		BodyPrefab.AddComponent<DeltaCombatAudio>();
		SfxLocator voiceLocator = BodyPrefab.GetComponent<SfxLocator>();
		if (Object.op_Implicit((Object)(object)voiceLocator))
		{
			voiceLocator.barkSound = "";
			voiceLocator.deathSound = "";
		}
		EntityStateMachine[] components = BodyPrefab.GetComponents<EntityStateMachine>();
		foreach (EntityStateMachine val in components)
		{
			if (val.customName == "Body")
			{
				val.initialStateType = new SerializableEntityStateType(typeof(DeltaSpawn));
				val.mainStateType = new SerializableEntityStateType(typeof(GenericCharacterMain));
			}
			else
			{
				val.initialStateType = new SerializableEntityStateType(typeof(Idle));
				val.mainStateType = new SerializableEntityStateType(typeof(Idle));
			}
		}
		BuildSkills(BodyPrefab);
		DeltaAssets.SetupBody(BodyPrefab);
		DeltaFrenzyWeapon.Install(BodyPrefab);
		DeltaSelectionPortrait.Apply(BodyPrefab);
		DeltaModelAnchor.Align(((Component)BodyPrefab.GetComponent<ModelLocator>().modelTransform).gameObject);
		ModelLocator deltaLocator = BodyPrefab.GetComponent<ModelLocator>();
		CharacterDirection deltaDirection = BodyPrefab.GetComponent<CharacterDirection>();
		if (!Object.op_Implicit((Object)(object)deltaLocator) || !Object.op_Implicit((Object)(object)deltaLocator.modelTransform) || !Object.op_Implicit((Object)(object)deltaLocator.modelTransform.parent) || !Object.op_Implicit((Object)(object)deltaDirection))
		{
			throw new InvalidOperationException("Native Delta facing frame unavailable.");
		}
		deltaDirection.targetTransform = deltaLocator.modelTransform.parent;
		pack.effectDefs.Add((EffectDef[])(object)new EffectDef[1] { DeltaEffects.CreateDreamBonusDefinition() });
		pack.effectDefs.Add(DeltaImpactEffects.CreateDefinitions());
		DisplayPrefab = DeltaAssets.BuildDisplay(displayLoad.Result);
		if (!Object.op_Implicit((Object)(object)DisplayPrefab))
		{
			throw new InvalidOperationException("Delta display adapter did not provide its real model.");
		}
		DeltaSelectionPortrait.Apply(DisplayPrefab);
		DeltaModelAnchor.Align(((Component)DisplayPrefab.GetComponentInChildren<DeltaRig>(true)).gameObject);
		((Object)DisplayPrefab).name = "FeverishTempoDeltaDisplay";
		DisplayPrefab.transform.SetParent(holder.transform, false);
		DeltaDisplayIdlePresentation.Init(DisplayPrefab);
		DisplayPrefab.SetActive(true);
		MasterPrefab = Object.Instantiate<GameObject>(masterLoad.Result, holder.transform, false);
		((Object)MasterPrefab).name = "FeverishTempoDeltaMaster";
		MasterPrefab.SetActive(true);
		CharacterMaster master = MasterPrefab.GetComponent<CharacterMaster>();
		master.bodyPrefab = BodyPrefab;
		master.originalBodyPrefab = BodyPrefab;
		AssignNetworkId(MasterPrefab, "f52c3e119ff34ae6a17710fd6c4b9103");
		Survivor = ScriptableObject.CreateInstance<SurvivorDef>();
		((Object)Survivor).name = "FeverishTempoDelta";
		Survivor.bodyPrefab = BodyPrefab;
		Survivor.displayPrefab = DisplayPrefab;
		Survivor.displayNameToken = "DELTA_NAME";
		Survivor.descriptionToken = "DELTA_DESC";
		Survivor.outroFlavorToken = "DELTA_OUTRO";
		Survivor.mainEndingEscapeFailureFlavorToken = "DELTA_FAIL";
		Survivor.primaryColor = new Color(0.79f, 0.34f, 0.65f);
		Survivor.desiredSortPosition = 18f;
		Survivor.hidden = false;
		Survivor.unlockableDef = null;
		Survivor.unlockableName = "";
		pack.bodyPrefabs.Add((GameObject[])(object)new GameObject[1] { BodyPrefab });
		pack.masterPrefabs.Add((GameObject[])(object)new GameObject[1] { MasterPrefab });
		pack.survivorDefs.Add((SurvivorDef[])(object)new SurvivorDef[1] { Survivor });
		pack.entityStateTypes.Add(new Type[7]
		{
			typeof(DeltaSpawn),
			typeof(DeltaPrimary),
			typeof(DeltaCharge),
			typeof(DeltaDodge),
			typeof(DeltaDreamWeapon),
			typeof(DeltaParry),
			typeof(DeltaCounter)
		});
		CorePlugin.LogInfo("Delta content built: independent Body/Master/Survivor, primary six-hit combo with passive charge, secondary dodge, utility Dream weapon, special parry.");
		args.ReportProgress(1f);
	}

	private static BuffDef MeterBuff(string name, Color color)
	{
		//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 = name;
		val.buffColor = color;
		val.canStack = true;
		val.isDebuff = false;
		val.iconSprite = DeltaAssets.GetSkillIcon("PASSIVE");
		return val;
	}

	private void BuildSkills(GameObject body)
	{
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0196: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: Unknown result type (might be due to invalid IL or missing references)
		SkillLocator component = body.GetComponent<SkillLocator>();
		GenericSkill[] components = body.GetComponents<GenericSkill>();
		GenericSkill[] array = components;
		foreach (GenericSkill val in array)
		{
			Object.DestroyImmediate((Object)(object)val);
		}
		SkillDef val2 = MakeSkill<DeltaPrimarySkillDef>("PRIMARY", typeof(DeltaPrimary), "Weapon", 0f, 1);
		val2.stockToConsume = 0;
		val2.mustKeyPress = true;
		val2.cancelSprintingOnActivation = true;
		val2.interruptPriority = (InterruptPriority)0;
		SkillDef val3 = MakeSkill<SkillDef>("SECONDARY", typeof(DeltaDodge), "Body", CorePlugin.Positive(CorePlugin.DodgeCooldown, 0.1f), 2);
		val3.interruptPriority = (InterruptPriority)2;
		val3.isCombatSkill = false;
		val3.cancelSprintingOnActivation = false;
		SkillDef val4 = MakeSkill<DeltaDreamWeaponSkillDef>("UTILITY", typeof(DeltaDreamWeapon), "Body", CorePlugin.Positive(CorePlugin.DreamCooldown, 0.1f), 1);
		val4.interruptPriority = (InterruptPriority)2;
		val4.cancelSprintingOnActivation = false;
		SkillDef val5 = MakeSkill<DeltaSpecialSkillDef>("SPECIAL", typeof(DeltaParry), "Weapon", CorePlugin.Positive(CorePlugin.SpecialCooldown, 0.1f), 1);
		val5.interruptPriority = (InterruptPriority)2;
		component.primary = AddSlot(body, val2);
		component.secondary = AddSlot(body, val3);
		component.utility = AddSlot(body, val4);
		component.special = AddSlot(body, val5);
		component.passiveSkill = new PassiveSkill
		{
			enabled = true,
			skillNameToken = "DELTA_PASSIVE_NAME",
			skillDescriptionToken = "DELTA_PASSIVE_DESC",
			icon = DeltaAssets.GetSkillIcon("PASSIVE")
		};
		pack.skillDefs.Add((SkillDef[])(object)new SkillDef[4] { val2, val3, val4, val5 });
	}

	private SkillDef MakeSkill<T>(string slot, Type state, string machine, float cooldown, int stocks) where T : SkillDef
	{
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		T val = ScriptableObject.CreateInstance<T>();
		((Object)(object)val).name = "FeverishTempoDelta" + slot;
		((SkillDef)val).skillName = "FeverishTempoDelta" + slot;
		((SkillDef)val).skillNameToken = "DELTA_" + slot + "_NAME";
		((SkillDef)val).skillDescriptionToken = "DELTA_" + slot + "_DESC";
		((SkillDef)val).activationState = new SerializableEntityStateType(state);
		((SkillDef)val).activationStateMachineName = machine;
		((SkillDef)val).baseRechargeInterval = cooldown;
		((SkillDef)val).baseMaxStock = stocks;
		((SkillDef)val).rechargeStock = 1;
		((SkillDef)val).requiredStock = 1;
		((SkillDef)val).stockToConsume = 1;
		((SkillDef)val).fullRestockOnAssign = true;
		((SkillDef)val).resetCooldownTimerOnUse = false;
		((SkillDef)val).beginSkillCooldownOnSkillEnd = false;
		((SkillDef)val).cancelSprintingOnActivation = true;
		((SkillDef)val).interruptPriority = (InterruptPriority)1;
		((SkillDef)val).isCombatSkill = true;
		((SkillDef)val).mustKeyPress = true;
		((SkillDef)val).keywordTokens = new string[0];
		((SkillDef)val).icon = DeltaAssets.GetSkillIcon(slot);
		return (SkillDef)(object)val;
	}

	private GenericSkill AddSlot(GameObject body, SkillDef skill)
	{
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		GenericSkill val = body.AddComponent<GenericSkill>();
		val.skillName = skill.skillName;
		SkillFamily val2 = ScriptableObject.CreateInstance<SkillFamily>();
		((Object)val2).name = skill.skillName + "Family";
		val2.variants = (Variant[])(object)new Variant[1]
		{
			new Variant
			{
				skillDef = skill,
				unlockableDef = null
			}
		};
		typeof(GenericSkill).GetField("_skillFamily", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(val, val2);
		pack.skillFamilies.Add((SkillFamily[])(object)new SkillFamily[1] { val2 });
		return val;
	}

	private static void AssignNetworkId(GameObject prefab, string stableId)
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		NetworkIdentity component = prefab.GetComponent<NetworkIdentity>();
		if (!Object.op_Implicit((Object)(object)component))
		{
			throw new InvalidOperationException("Custom network prefab missing NetworkIdentity.");
		}
		typeof(NetworkIdentity).GetField("m_AssetId", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(component, NetworkHash128.Parse(stableId));
	}

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

	public IEnumerator FinalizeAsync(FinalizeAsyncArgs args)
	{
		args.ReportProgress(1f);
		yield break;
	}
}
public sealed class DeltaDreamWeaponSkillDef : SkillDef
{
	public override bool IsReady(GenericSkill slot)
	{
		if (((SkillDef)this).IsReady(slot))
		{
			return DeltaSkillReadiness.BodyReady(slot);
		}
		return false;
	}

	public override bool CanExecute(GenericSkill slot)
	{
		if (((SkillDef)this).CanExecute(slot))
		{
			return ((SkillDef)this).IsReady(slot);
		}
		return false;
	}
}
public sealed class DeltaSpecialSkillDef : SkillDef
{
	public override bool IsReady(GenericSkill slot)
	{
		DeltaController component = ((Component)slot).GetComponent<DeltaController>();
		if (((SkillDef)this).IsReady(slot) && DeltaSkillReadiness.BodyReady(slot) && Object.op_Implicit((Object)(object)component))
		{
			return component.Meters.Sp >= CorePlugin.Positive(CorePlugin.SpecialSp, 0f);
		}
		return false;
	}

	public override bool CanExecute(GenericSkill slot)
	{
		if (((SkillDef)this).CanExecute(slot))
		{
			return ((SkillDef)this).IsReady(slot);
		}
		return false;
	}
}
public sealed class DeltaPrimarySkillDef : SkillDef
{
	public override bool IsReady(GenericSkill slot)
	{
		if (((SkillDef)this).IsReady(slot))
		{
			return DeltaSkillReadiness.BodyReady(slot);
		}
		return false;
	}

	public override bool CanExecute(GenericSkill slot)
	{
		if (((SkillDef)this).CanExecute(slot))
		{
			return ((SkillDef)this).IsReady(slot);
		}
		return false;
	}
}
internal static class DeltaSkillReadiness
{
	internal static bool BodyReady(GenericSkill slot)
	{
		EntityStateMachine val = EntityStateMachine.FindByCustomName(((Component)slot).gameObject, "Body");
		return (Object.op_Implicit((Object)(object)val) ? (val.state as DeltaDodge) : null)?.CanCancelForSkill ?? true;
	}
}
[BepInPlugin("local.FeverishTempoDelta", "Feverish Tempo Delta", "1.0.25")]
public sealed class CorePlugin : BaseUnityPlugin
{
	public const string PluginGuid = "local.FeverishTempoDelta";

	internal static CorePlugin Instance;

	internal static ConfigEntry<float> NormalBlue;

	internal static ConfigEntry<float> DodgePink;

	internal static ConfigEntry<float> PerfectPink;

	internal static ConfigEntry<float> MeterMax;

	internal static ConfigEntry<float> InitialSp;

	internal static ConfigEntry<float> SpRegen;

	internal static ConfigEntry<float> SpecialSp;

	internal static ConfigEntry<float> SpecialCooldown;

	internal static ConfigEntry<float> FrenzyInitial;

	internal static ConfigEntry<float> FrenzyMax;

	internal static ConfigEntry<float> FrenzyDrain;

	internal static ConfigEntry<float> FrenzyInterval;

	internal static ConfigEntry<float> FrenzyBonus;

	internal static ConfigEntry<float> DodgeCooldown;

	internal static ConfigEntry<float> DodgeDuration;

	internal static ConfigEntry<float> DodgePerfectWindow;

	internal static ConfigEntry<float> DodgeSpeed;

	internal static ConfigEntry<float> PerfectCooldown;

	internal static ConfigEntry<float> FractureDuration;

	internal static ConfigEntry<float> FractureRadius;

	internal static ConfigEntry<float> BarrierFraction;

	internal static ConfigEntry<float> BarrierDuration;

	internal static ConfigEntry<float> ParryDuration;

	internal static ConfigEntry<float> ParryPerfectWindow;

	internal static ConfigEntry<float> PerfectParryFracture;

	internal static ConfigEntry<float> ChargeDamage;

	internal static ConfigEntry<float> ChargeExtraDamage;

	internal static ConfigEntry<float> CounterDamage;

	internal static ConfigEntry<float> PerfectCounterDamage;

	internal static ConfigEntry<float> MeleeRange;

	internal static ConfigEntry<float> MeleeAngle;

	internal static ConfigEntry<float> ComboTimeout;

	internal static ConfigEntry<float> ChargeHold;

	internal static ConfigEntry<float> DreamCooldown;

	internal static ConfigEntry<float> DreamDelay;

	internal static ConfigEntry<float> DreamSelfDamage;

	internal static ConfigEntry<float> DreamDamage;

	internal static ConfigEntry<float> DreamDuration;

	internal static ConfigEntry<float> DreamBonus;

	internal static ConfigEntry<float> DreamInterval;

	internal static ConfigEntry<float> DreamRange;

	internal static ConfigEntry<float> DreamExplosionRange;

	internal static ConfigEntry<float> DreamCrit;

	internal static ConfigEntry<float> DreamFrenzySp;

	internal static ConfigEntry<float> DreamFrenzySpCooldown;

	internal static ConfigEntry<float> DreamFrenzyReduction;

	internal static ConfigEntry<string> NormalDamage;

	internal static ConfigEntry<string> FrenzyDamage;

	internal static ConfigEntry<bool> VoicesEnabled;

	internal static ConfigEntry<float> VoiceVolume;

	internal static ConfigEntry<bool> CombatAudioEnabled;

	internal static ConfigEntry<float> CombatAudioVolume;

	private readonly DeltaContent content = new DeltaContent();

	private static readonly PropertyInfo critProperty = typeof(CharacterBody).GetProperty("crit");

	private static readonly PropertyInfo critMultiplierProperty = typeof(CharacterBody).GetProperty("critMultiplier");

	private static readonly PropertyInfo moveSpeedProperty = typeof(CharacterBody).GetProperty("moveSpeed");

	internal static readonly Dictionary<string, string> Tokens = new Dictionary<string, string>
	{
		{ "DELTA_NAME", "狂热蓝调Δ" },
		{ "DELTA_SUBTITLE", "二重印痕" },
		{ "DELTA_DESC", "物理近战生存者。<style=cIsUtility>普攻</style>积蓝色动能,<style=cIsUtility>闪避</style>积粉色动能;双条充满后长按普攻蓄力进入双剑狂热。<style=cIsDamage>睡美人之梦</style>主动可触发招架反击或极限闪避。" },
		{ "DELTA_OUTRO", "她走了,留下的色彩仍在跳动。" },
		{ "DELTA_FAIL", "她留在了这片星球,继续那首未完成的蓝调。" },
		{ "DELTA_PRIMARY_NAME", "异色随想" },
		{ "DELTA_PRIMARY_DESC", "点击左键逐次接续六招大剑连击;长按只用于双条满后的蓄力,不会自动连攻。每招获得<style=cIsUtility>150蓝色动能</style>,未命中也获得。第四至第六招命中回复1SP;狂热时切换双剑三招。伤害倍率可配置。" },
		{ "DELTA_SECONDARY_NAME", "即兴速写·闪避" },
		{ "DELTA_SECONDARY_DESC", "拥有2个闪避存量,每次获得200粉色动能。开始短时间内躲过攻击触发极限闪避:额外400粉色、3秒时空、4秒敌人禁锢及最大生命15%的屏障,屏障最多持续6秒并提高25%暴击率。睡美人之梦自伤也可触发。狂热期间不获得粉蓝,时空期间暂停动能流失。" },
		{ "DELTA_UTILITY_NAME", "睡美人之梦·荆棘摇篮" },
		{ "DELTA_UTILITY_DESC", "<style=cIsUtility>0SP,18秒冷却</style>。0.5秒后自伤1并对周围敌人造成<style=cIsDamage>800%伤害</style>;之后5秒攻击命中产生100%伤害爆炸,每秒最多一次。自伤可触发招架反击或极限闪避,在RoR2中不会致命。范围为适配值。" },
		{ "DELTA_SPECIAL_NAME", "旧日残像·招架反击" },
		{ "DELTA_SPECIAL_DESC", "<style=cIsUtility>50SP,9秒冷却</style>。进入0.7秒招架态势,受击或时间结束后释放400%+400%反击;摆出态势时立即受击改为100%+400%+1000%强化反击并触发1.6秒时空。进入狂热并补充2400动能,动能上限4800;狂热结束后恢复之前的粉蓝。发动后9秒内暴击率与物理伤害各提高15%。" },
		{ "DELTA_PASSIVE_NAME", "二重印痕·双剑狂热" },
		{ "DELTA_PASSIVE_DESC", "粉蓝动能各1200,双满后长按普攻蓄力,清空双条、提高蓄力400%伤害并进入双剑狂热。普通前三招闪避接下一招,第四至第六招闪避接第四招。狂热期间停止积粉蓝,每0.2秒消耗75狂热动能。必杀入狂热保留粉蓝,结束恢复。状态图标的蓝、粉、紫数字表示动能百分比,黄色数字表示SP。" },
		{ "DELTA_DEFAULT_SKIN", "狂热蓝调Δ" }
	};

	private void Awake()
	{
		//IL_0738: Unknown result type (might be due to invalid IL or missing references)
		//IL_0742: Expected O, but got Unknown
		//IL_0749: Unknown result type (might be due to invalid IL or missing references)
		//IL_0753: Expected O, but got Unknown
		//IL_075a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0764: Expected O, but got Unknown
		//IL_076b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0775: Expected O, but got Unknown
		//IL_077c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0786: Expected O, but got Unknown
		Instance = this;
		string text = "已核对的原作机制数值;在 RoR2 中运行。";
		string text2 = "RoR2 本地适配默认值,尚未核对为原作技能表数值。联机玩家应使用相同配置。";
		string text3 = "历史客户端原始技能表数值,已与较新表描述交叉核对;尚未解出本机9.1表。伤害登记时刻仍从原动作推定。";
		NormalBlue = ((BaseUnityPlugin)this).Config.Bind<float>("原作动能", "普通每招蓝色", 150f, text);
		DodgePink = ((BaseUnityPlugin)this).Config.Bind<float>("原作动能", "每次闪避粉色", 200f, text);
		PerfectPink = ((BaseUnityPlugin)this).Config.Bind<float>("原作动能", "极限闪避额外粉色", 400f, text);
		MeterMax = ((BaseUnityPlugin)this).Config.Bind<float>("原作动能", "粉蓝各自上限", 1200f, text);
		FrenzyDrain = ((BaseUnityPlugin)this).Config.Bind<float>("原作动能", "狂热每次流失", 75f, text);
		FrenzyInterval = ((BaseUnityPlugin)this).Config.Bind<float>("原作动能", "狂热流失间隔秒", 0.2f, text);
		ChargeExtraDamage = ((BaseUnityPlugin)this).Config.Bind<float>("原作动能", "灵感迸发蓄力倍率增量", 4f, "原作技能截图:蓄力攻击造成的物理伤害提高攻击力的400%,并入原蓄力伤害。");
		InitialSp = ((BaseUnityPlugin)this).Config.Bind<float>("原作武器被动", "初始额外SP", 35f, "睡美人之梦65级:二重梦境在战斗开始时额外35SP。");
		SpRegen = ((BaseUnityPlugin)this).Config.Bind<float>("可选适配", "每秒SP回复", 0f, "默认关闭。尚未获得原作基础命中SP表;此选项仅用于额外自定义回复。");
		SpecialSp = ((BaseUnityPlugin)this).Config.Bind<float>("原作技能表", "必杀SP消耗", 50f, text3);
		SpecialCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("原作技能表", "必杀冷却秒", 9f, text3);
		FrenzyInitial = ((BaseUnityPlugin)this).Config.Bind<float>("原作技能表", "首次狂热动能及必杀补充", 2400f, text3);
		FrenzyMax = ((BaseUnityPlugin)this).Config.Bind<float>("原作技能表", "狂热动能上限", 4800f, text3);
		FrenzyBonus = ((BaseUnityPlugin)this).Config.Bind<float>("原作武器被动", "狂热普攻物理伤害倍率", 1.35f, "睡美人之梦65级:狂热普通攻击物理伤害提高35%。");
		DreamCrit = ((BaseUnityPlugin)this).Config.Bind<float>("原作武器被动", "常驻暴击率百分比", 15f, "睡美人之梦65级:噩梦原点常驻暴击率提高15%。");
		DreamFrenzySp = ((BaseUnityPlugin)this).Config.Bind<float>("原作武器被动", "入狂热回复SP", 6f, "睡美人之梦65级:樱桃炸弹进入狂热回复6SP。");
		DreamFrenzySpCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("原作武器被动", "入狂热回复SP冷却秒", 20f, text);
		DreamFrenzyReduction = ((BaseUnityPlugin)this).Config.Bind<float>("原作武器被动", "狂热所受伤害降低比例", 0.2f, "睡美人之梦65级:狂热所受全部伤害降低20%。");
		DodgeCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("RoR2适配", "闪避每个存量回复秒", 4f, text2);
		DodgeDuration = ((BaseUnityPlugin)this).Config.Bind<float>("原作控制器", "闪避持续秒", 0.429f, "闪避保护及最早取消窗口;收尾动作另按原控制器播放,未延长保护时间。水平根位移按入招时moveSpeed/baseMoveSpeed缩放,无敌起止事件尚未解出。");
		DodgePerfectWindow = ((BaseUnityPlugin)this).Config.Bind<float>("RoR2适配", "闪避开始后极限窗口秒", 0.18f, text2);
		DodgeSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("RoR2适配", "闪避移动速度倍率", 3.2f, text2);
		PerfectCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("原作技能表", "极限闪避效果冷却秒", 15f, text3);
		FractureDuration = ((BaseUnityPlugin)this).Config.Bind<float>("原作动能", "极限闪避时空秒", 3f, "暂停自身狂热流失,局部减慢敌人动作、攻击状态、技能回复与移动;额外4秒禁锢,不改变全局时间。");
		FractureRadius = ((BaseUnityPlugin)this).Config.Bind<float>("RoR2适配", "时空敌人减速范围", 35f, text2);
		BarrierFraction = ((BaseUnityPlugin)this).Config.Bind<float>("原作技能表", "极闪屏障最大生命比例", 0.15f, text3);
		BarrierDuration = ((BaseUnityPlugin)this).Config.Bind<float>("原作技能表", "极闪屏障最长秒", 6f, text3);
		ParryDuration = ((BaseUnityPlugin)this).Config.Bind<float>("原作技能表", "招架窗口秒", 0.7f, text3);
		ParryPerfectWindow = ((BaseUnityPlugin)this).Config.Bind<float>("RoR2适配", "完美弹反开始窗口秒", 0.2f, text2);
		PerfectParryFracture = ((BaseUnityPlugin)this).Config.Bind<float>("原作动能", "完美弹反时空秒", 1.6f, "原作攻略描述的1.6秒时空;敌人减速范围为RoR2适配。");
		ChargeDamage = ((BaseUnityPlugin)this).Config.Bind<float>("原作技能表", "蓄力主攻击倍率", 4f, text3);
		CounterDamage = ((BaseUnityPlugin)this).Config.Bind<float>("原作技能表", "普通反击倍率", 8f, text3 + " 原描述400%+400%,按两段登记。");
		PerfectCounterDamage = ((BaseUnityPlugin)this).Config.Bind<float>("原作技能表", "完美弹反倍率", 15f, text3 + " 原描述100%+400%+1000%,按三段登记。");
		NormalDamage = ((BaseUnityPlugin)this).Config.Bind<string>("原作技能表", "普通六招总倍率", "1.2,1.4,1.6,1.8,2.8,3.0", text3 + " 逐段分配遵照原120%;70%+70%;40%+120%;180%;140%+140%;300%。");
		FrenzyDamage = ((BaseUnityPlugin)this).Config.Bind<string>("原作技能表", "狂热三招总倍率", "2.4,2.4,5.6", text3 + " 每段拆分未解出,当前按动作候选分摊总倍率。");
		MeleeRange = ((BaseUnityPlugin)this).Config.Bind<float>("RoR2适配", "大剑攻击范围米", 7f, text2 + " 按敌人有效受击碰撞体的最近表面判定,适用于大型敌人。");
		MeleeAngle = ((BaseUnityPlugin)this).Config.Bind<float>("RoR2适配", "大剑攻击半角度", 75f, text2);
		ComboTimeout = ((BaseUnityPlugin)this).Config.Bind<float>("RoR2适配", "普攻断连秒", 1.3f, text2);
		ChargeHold = ((BaseUnityPlugin)this).Config.Bind<float>("RoR2适配", "双满长按普攻蓄力秒", 19f / 30f, "基础攻速下长按进入蓄力的秒数;按用户原作录像先完成一次普攻再蓄力,随攻速等比换算。该阈值由录像校准,原输入脚本尚未恢复。");
		if (Math.Abs(ChargeHold.Value - 0.35f) < 1E-05f)
		{
			ChargeHold.Value = 19f / 30f;
		}
		DreamCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("原作武器主动", "荆棘摇篮冷却秒", 18f, "睡美人之梦65级官方武器指南数值;不消耗SP。");
		DreamDelay = ((BaseUnityPlugin)this).Config.Bind<float>("原作武器主动", "荆棘摇篮延迟秒", 0.5f, text);
		DreamSelfDamage = ((BaseUnityPlugin)this).Config.Bind<float>("原作武器主动", "荆棘摇篮自伤", 1f, "可以触发招架反击或极限闪避;RoR2中设为不致命。");
		DreamDamage = ((BaseUnityPlugin)this).Config.Bind<float>("原作武器主动", "荆棘摇篮敌人伤害倍率", 8f, text);
		DreamDuration = ((BaseUnityPlugin)this).Config.Bind<float>("原作武器主动", "命中附加爆炸持续秒", 5f, text);
		DreamBonus = ((BaseUnityPlugin)this).Config.Bind<float>("原作武器主动", "命中附加爆炸倍率", 1f, text);
		DreamInterval = ((BaseUnityPlugin)this).Config.Bind<float>("原作武器主动", "命中附加爆炸最小间隔秒", 1f, text);
		DreamRange = ((BaseUnityPlugin)this).Config.Bind<float>("RoR2适配", "武器主动范围米", 8f, text2);
		DreamExplosionRange = ((BaseUnityPlugin)this).Config.Bind<float>("RoR2适配", "命中附加爆炸范围米", 3f, text2);
		VoicesEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("角色语音", "启用原作语音", true, "使用本机提取的Δ中文原声;死亡语音已按用户要求关闭,受击语音保留。音量同时跟随游戏主音量和音效音量。");
		VoiceVolume = ((BaseUnityPlugin)this).Config.Bind<float>("角色语音", "语音相对音量", 1f, "0至1,仅调整本角色原作语音。");
		CombatAudioEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("角色音效", "启用原作攻击音效", true, "使用本机提取的Δ战斗音效,跟随游戏主音量和音效音量。");
		CombatAudioVolume = ((BaseUnityPlugin)this).Config.Bind<float>("角色音效", "攻击音效相对音量", 1f, "0至1,仅调整本角色原作攻击音效,与人物语音分开。");
		ContentManager.collectContentPackProviders += new CollectContentPackProvidersDelegate(RegisterContent);
		Language.LoadStrings += new hook_LoadStrings(AddLanguage);
		HealthComponent.TakeDamageProcess += new hook_TakeDamageProcess(InterceptDamage);
		CharacterBody.RecalculateStats += new hook_RecalculateStats(ApplySourceStats);
		HealthComponent.GetBarrierDecayRate += new hook_GetBarrierDecayRate(ApplyOwnedBarrierDecay);
		GlobalEventManager.onClientDamageNotified += DeltaVoice.NotifyDamage;
		DeltaImpactEffects.Init();
		DeltaKineticHud.Init();
		DeltaBodyRendering.Init();
		((BaseUnityPlugin)this).Logger.LogInfo((object)("Feverish Tempo Delta: native independent survivor provider registered. " + DeltaMeters.CheckInvariants()));
	}

	private void RegisterContent(AddContentPackProviderDelegate add)
	{
		add.Invoke((IContentPackProvider)(object)content);
	}

	private static void InterceptDamage(orig_TakeDamageProcess orig, HealthComponent self, DamageInfo info)
	{
		//IL_0287: Unknown result type (might be due to invalid IL or missing references)
		DeltaController deltaController = ((info != null && Object.op_Implicit((Object)(object)info.attacker)) ? info.attacker.GetComponent<DeltaController>() : null);
		DeltaPassives deltaPassives = (Object.op_Implicit((Object)(object)deltaController) ? ((Component)deltaController).GetComponent<DeltaPassives>() : null);
		DeltaSourceKind deltaSourceKind = (Object.op_Implicit((Object)(object)deltaController) ? deltaController.CurrentSourceKind : DeltaSourceKind.Normal);
		if (NetworkServer.active && Object.op_Implicit((Object)(object)self) && Object.op_Implicit((Object)(object)self.body) && info != null)
		{
			DeltaController component = ((Component)self.body).GetComponent<DeltaController>();
			if (Object.op_Implicit((Object)(object)component))
			{
				if ((Object)(object)info.attacker != (Object)(object)((Component)self).gameObject && !info.rejected)
				{
					if (component.IsFrenzy)
					{
						info.damage *= 1f - Mathf.Clamp(DreamFrenzyReduction.Value, 0f, 1f);
					}
					DeltaPassives component2 = ((Component)component).GetComponent<DeltaPassives>();
					if (Object.op_Implicit((Object)(object)component2))
					{
						info.damage *= component2.IncomingMultiplier(component.Normal4To6Active);
					}
				}
				component.TryBlockDamage(info);
			}
			if (Object.op_Implicit((Object)(object)deltaPassives) && !info.rejected && info.damage > 0f)
			{
				float num = deltaPassives.SourceDamageMultiplier(self.body, deltaSourceKind);
				if (deltaSourceKind == DeltaSourceKind.Frenzy && (Object)(object)self.body != (Object)(object)deltaPassives.Body)
				{
					float num2 = (deltaPassives.UltimateBuffActive ? 0.15f : 0f);
					num *= (Positive(FrenzyBonus, 0.1f) + num2) / (1f + num2);
				}
				info.damage *= num;
				if (info.crit && deltaSourceKind == DeltaSourceKind.PerfectCounter && (Object)(object)self.body != (Object)(object)((Component)deltaController).GetComponent<CharacterBody>())
				{
					CharacterBody body = deltaPassives.Body;
					float num3 = deltaPassives.CriticalDamageBonus(deltaSourceKind) - deltaPassives.CriticalDamageBonus(DeltaSourceKind.Normal);
					float num4 = (Object.op_Implicit((Object)(object)body) ? Mathf.Max(0.01f, body.critMultiplier) : 2f);
					info.damage *= (num4 + num3) / num4;
				}
			}
		}
		orig.Invoke(self, info);
		if (NetworkServer.active && info != null && !info.rejected && info.damage > 0f && info.procCoefficient > 0f && Object.op_Implicit((Object)(object)info.attacker) && Object.op_Implicit((Object)(object)self) && Object.op_Implicit((Object)(object)self.body))
		{
			if (Object.op_Implicit((Object)(object)deltaPassives))
			{
				deltaPassives.TryRegisterHit(self.body, info, deltaSourceKind == DeltaSourceKind.Frenzy);
			}
			if (Object.op_Implicit((Object)(object)deltaController))
			{
				deltaController.TryDreamBonus(self.body.corePosition);
			}
		}
	}

	private static void ApplySourceStats(orig_RecalculateStats orig, CharacterBody body)
	{
		orig.Invoke(body);
		if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)Run.instance))
		{
			return;
		}
		if (DeltaFracture.IsImmobilized(body))
		{
			moveSpeedProperty.SetValue(body, 0f, null);
		}
		else if (DeltaFracture.IsAffected(body))
		{
			moveSpeedProperty.SetValue(body, body.moveSpeed * 0.2f, null);
		}
		DeltaPassives component = ((Component)body).GetComponent<DeltaPassives>();
		DeltaController component2 = ((Component)body).GetComponent<DeltaController>();
		if (Object.op_Implicit((Object)(object)component2))
		{
			float num = (Object.op_Implicit((Object)(object)component) ? component.CriticalChanceBonus(DeltaSourceKind.Normal) : 0f);
			if (component2.OwnBarrierActive)
			{
				num += 25f;
			}
			critProperty.SetValue(body, body.crit + num, null);
			if (Object.op_Implicit((Object)(object)component))
			{
				critMultiplierProperty.SetValue(body, body.critMultiplier + component.CriticalDamageBonus(DeltaSourceKind.Normal), null);
			}
		}
	}

	private static float ApplyOwnedBarrierDecay(orig_GetBarrierDecayRate orig, HealthComponent health)
	{
		DeltaController deltaController = ((Object.op_Implicit((Object)(object)health) && Object.op_Implicit((Object)(object)health.body)) ? ((Component)health.body).GetComponent<DeltaController>() : null);
		if (!Object.op_Implicit((Object)(object)deltaController) || !deltaController.OwnBarrierActive)
		{
			return orig.Invoke(health);
		}
		return 0f;
	}

	private static void AddLanguage(orig_LoadStrings orig, Language language)
	{
		orig.Invoke(language);
		foreach (KeyValuePair<string, string> token in Tokens)
		{
			language.SetStringByToken(token.Key, token.Value);
		}
	}

	internal static float Positive(ConfigEntry<float> entry, float minimum)
	{
		return Math.Max(minimum, entry.Value);
	}

	internal static void LogInfo(string message)
	{
		if (Object.op_Implicit((Object)(object)Instance))
		{
			((BaseUnityPlugin)Instance).Logger.LogInfo((object)message);
		}
	}

	internal static float Sequence(ConfigEntry<string> entry, int index, float fallback)
	{
		string[] array = entry.Value.Split(',');
		if (index < array.Length && float.TryParse(array[index], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && result > 0f)
		{
			return result;
		}
		return fallback;
	}

	private void OnDestroy()
	{
		//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
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Expected O, but got Unknown
		ContentManager.collectContentPackProviders -= new CollectContentPackProvidersDelegate(RegisterContent);
		Language.LoadStrings -= new hook_LoadStrings(AddLanguage);
		HealthComponent.TakeDamageProcess -= new hook_TakeDamageProcess(InterceptDamage);
		CharacterBody.RecalculateStats -= new hook_RecalculateStats(ApplySourceStats);
		HealthComponent.GetBarrierDecayRate -= new hook_GetBarrierDecayRate(ApplyOwnedBarrierDecay);
		GlobalEventManager.onClientDamageNotified -= DeltaVoice.NotifyDamage;
		DeltaVoice.Shutdown();
		DeltaCombatAudio.Shutdown();
		DeltaImpactEffects.Shutdown();
		DeltaImpactAudio.Shutdown();
		DeltaKineticHud.Shutdown();
		DeltaBodyRendering.Shutdown();
		DeltaSceneDepth.Shutdown();
		DeltaFracture.Uninstall();
		DeltaRenderBridge.Shutdown();
	}
}
public sealed class DeltaAirbornePresentation : MonoBehaviour
{
	private sealed class SourceClip
	{
		internal string Key;

		internal string State;

		internal bool Loop;

		internal float Rate;

		internal DeltaAnimationData Animation;

		internal DeltaHumanClip Human;

		internal JObject Phase;
	}

	private static readonly BindingFlags privateInstance = BindingFlags.Instance | BindingFlags.NonPublic;

	private static readonly FieldInfo RigClips = Field("clips");

	private static readonly FieldInfo RigHumanoid = Field("humanoid");

	private static readonly FieldInfo Nodes = Field("nodes");

	private static readonly FieldInfo FromPositions = Field("fromPositions");

	private static readonly FieldInfo FromRotations = Field("fromRotations");

	private static readonly FieldInfo FromScales = Field("fromScales");

	private static readonly FieldInfo Current = Field("current");

	private static readonly FieldInfo CurrentKey = Field("currentKey");

	private static readonly FieldInfo ClipTime = Field("clipTime");

	private static readonly FieldInfo StartOffset = Field("startClipOffset");

	private static readonly FieldInfo PlayRate = Field("playRate");

	private static readonly FieldInfo BlendTime = Field("blendTime");

	private static readonly FieldInfo BlendDuration = Field("blendDuration");

	private static readonly FieldInfo Looping = Field("looping");

	private static readonly FieldInfo LastFrenzy = Field("lastFrenzy");

	private static readonly FieldInfo HumanClips = typeof(DeltaHumanoid).GetField("clips", privateInstance);

	private static readonly MethodInfo Sample = typeof(DeltaRig).GetMethod("Sample", privateInstance);

	private static Dictionary<string, SourceClip> sourceClips;

	private static Dictionary<string, SourceClip> sourceStates;

	private CharacterBody body;

	private CharacterMotor motor;

	private DeltaRig rig;

	private SourceClip stage;

	private bool subscribed;

	private bool pendingJump;

	private bool pendingMoving;

	private bool hasGroundExit;

	private float groundExitBlend;

	private static FieldInfo Field(string name)
	{
		FieldInfo field = typeof(DeltaRig).GetField(name, privateInstance);
		if (field == null)
		{
			throw new MissingFieldException(typeof(DeltaRig).FullName, name);
		}
		return field;
	}

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

	private void OnEnable()
	{
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Expected O, but got Unknown
		if (!Object.op_Implicit((Object)(object)body))
		{
			body = ((Component)this).GetComponent<CharacterBody>();
		}
		if (!Object.op_Implicit((Object)(object)motor))
		{
			motor = ((Component)this).GetComponent<CharacterMotor>();
		}
		if (Object.op_Implicit((Object)(object)body) && !subscribed)
		{
			body.OnJump += new JumpDelegate(OnNativeJump);
			subscribed = true;
		}
	}

	private void OnDisable()
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Expected O, but got Unknown
		if (Object.op_Implicit((Object)(object)body) && subscribed)
		{
			body.OnJump -= new JumpDelegate(OnNativeJump);
		}
		subscribed = false;
		ResetPresentation();
	}

	private static DeltaAirbornePresentation Get(CharacterBody target)
	{
		if (!Object.op_Implicit((Object)(object)target))
		{
			return null;
		}
		DeltaAirbornePresentation component = ((Component)target).GetComponent<DeltaAirbornePresentation>();
		if (!Object.op_Implicit((Object)(object)component))
		{
			return ((Component)target).gameObject.AddComponent<DeltaAirbornePresentation>();
		}
		return component;
	}

	public static bool TryUpdate(CharacterBody target)
	{
		DeltaAirbornePresentation deltaAirbornePresentation = Get(target);
		if (Object.op_Implicit((Object)(object)deltaAirbornePresentation))
		{
			return deltaAirbornePresentation.UpdatePresentation();
		}
		return false;
	}

	public static void Interrupt(CharacterBody target)
	{
		if (Object.op_Implicit((Object)(object)target))
		{
			DeltaAirbornePresentation component = ((Component)target).GetComponent<DeltaAirbornePresentation>();
			if (Object.op_Implicit((Object)(object)component))
			{
				component.ResetPresentation();
			}
		}
	}

	public static void ApplyGroundExit(CharacterBody target)
	{
		if (!Object.op_Implicit((Object)(object)target))
		{
			return;
		}
		DeltaAirbornePresentation component = ((Component)target).GetComponent<DeltaAirbornePresentation>();
		if (Object.op_Implicit((Object)(object)component) && component.hasGroundExit)
		{
			component.hasGroundExit = false;
			if (Object.op_Implicit((Object)(object)component.rig))
			{
				BlendDuration.SetValue(component.rig, component.groundExitBlend);
				BlendTime.SetValue(component.rig, 0f);
				Sample.Invoke(component.rig, new object[2]
				{
					component.rig.CurrentClipTime,
					(component.groundExitBlend > 0f) ? 0f : 1f
				});
			}
		}
	}

	private void ResetPresentation()
	{
		stage = null;
		pendingJump = false;
		hasGroundExit = false;
	}

	private bool SkillOwnsAnimation()
	{
		if (!Object.op_Implicit((Object)(object)body))
		{
			return false;
		}
		EntityStateMachine[] components = ((Component)body).GetComponents<EntityStateMachine>();
		foreach (EntityStateMachine val in components)
		{
			if (val.state is DeltaSkillState)
			{
				return true;
			}
		}
		return false;
	}

	private bool Moving()
	{
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.inputBank))
		{
			return ((Vector3)(ref body.inputBank.moveVector)).sqrMagnitude > 0.01f;
		}
		if (Object.op_Implicit((Object)(object)motor))
		{
			Vector3 moveDirection = motor.moveDirection;
			return ((Vector3)(ref moveDirection)).sqrMagnitude > 0.01f;
		}
		return false;
	}

	private void OnNativeJump()
	{
		if (SkillOwnsAnimation())
		{
			ResetPresentation();
			return;
		}
		pendingJump = true;
		pendingMoving = Moving();
		hasGroundExit = false;
	}

	private bool EnsureRig()
	{
		DeltaRig bodyRig = DeltaEffects.GetBodyRig(body);
		if (!Object.op_Implicit((Object)(object)bodyRig))
		{
			return false;
		}
		if ((Object)(object)rig == (Object)(object)bodyRig)
		{
			return true;
		}
		bodyRig.GetSourceAttachment("RootNode");
		Load();
		Dictionary<string, DeltaAnimationData> dictionary = (Dictionary<string, DeltaAnimationData>)RigClips.GetValue(bodyRig);
		DeltaHumanoid deltaHumanoid = (DeltaHumanoid)RigHumanoid.GetValue(bodyRig);
		if (deltaHumanoid == null || HumanClips == null || Sample == null)
		{
			throw new InvalidDataException("Original airborne sampler is unavailable.");
		}
		Dictionary<string, DeltaHumanClip> dictionary2 = (Dictionary<string, DeltaHumanClip>)HumanClips.GetValue(deltaHumanoid);
		foreach (SourceClip value in sourceClips.Values)
		{
			dictionary[value.Animation.name] = value.Animation;
			dictionary2[value.Human.name] = value.Human;
		}
		rig = bodyRig;
		stage = null;
		return true;
	}

	private static void Load()
	{
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Expected O, but got Unknown
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Expected O, but got Unknown
		if (sourceClips != null)
		{
			return;
		}
		string path = Path.Combine(Path.GetDirectoryName(typeof(CorePlugin).Assembly.Location), "Assets", "Locomotion", "Jump");
		JObject val = JObject.Parse(File.ReadAllText(Path.Combine(path, "jump.json")));
		JObject val2 = JObject.Parse(File.ReadAllText(Path.Combine(path, "phases.json")));
		if ((int)val["schemaVersion"] != 1 || (string)val["status"] != "ORIGINAL_TWINS_CONTROLLER_JUMP_CLIPS_RECOVERED")
		{
			throw new InvalidDataException("Original Twins jump clip evidence is missing.");
		}
		Dictionary<string, JObject> dictionary = new Dictionary<string, JObject>(StringComparer.Ordinal);
		foreach (JObject item in (IEnumerable<JToken>)val2["states"])
		{
			JObject val3 = item;
			dictionary[(string)val3["name"]] = val3;
		}
		Dictionary<string, SourceClip> dictionary2 = new Dictionary<string, SourceClip>(StringComparer.Ordinal);
		Dictionary<string, SourceClip> dictionary3 = new Dictionary<string, SourceClip>(StringComparer.Ordinal);
		foreach (JObject item2 in (IEnumerable<JToken>)val["clips"])
		{
			JObject val4 = item2;
			SourceClip sourceClip = new SourceClip();
			sourceClip.Key = (string)val4["key"];
			sourceClip.Animation = val4["animation"].ToObject<DeltaAnimationData>();
			sourceClip.Human = val4["human"].ToObject<DeltaHumanClip>();
			sourceClip.Loop = (bool)val4["loop"];
			sourceClip.Rate = (float)val4["sourceRate"];
			string text = (string)val4["source"][(object)"state"];
			sourceClip.State = text.Substring(text.LastIndexOf('.') + 1);
			if (!dictionary.TryGetValue(sourceClip.State, out sourceClip.Phase) || sourceClip.Rate <= 0f || sourceClip.Animation == null || sourceClip.Human == null || sourceClip.Animation.name != sourceClip.Human.name || sourceClip.Animation.duration <= 0f || !sourceClip.Human.enabled || sourceClip.Human.times == null || sourceClip.Human.muscles == null || sourceClip.Human.muscles.Length != sourceClip.Human.times.Length * 95 || sourceClip.Human.motionPositions == null || sourceClip.Human.motionPositions.Length != sourceClip.Human.times.Length * 3 || sourceClip.Human.motionRotations == null || sourceClip.Human.motionRotations.Length != sourceClip.Human.times.Length * 4)
			{
				throw new InvalidDataException("Incomplete original airborne clip: " + sourceClip.Key);
			}
			dictionary2.Add(sourceClip.Key, sourceClip);
			dictionary3.Add(sourceClip.State, sourceClip);
		}
		string[] array = new string[5] { "jumpLocal", "jumpMove", "fall", "landIdle", "landMove" };
		foreach (string text2 in array)
		{
			if (!dictionary2.ContainsKey(text2))
			{
				throw new InvalidDataException("Missing original airborne stage: " + text2);
			}
		}
		sourceStates = dictionary3;
		sourceClips = dictionary2;
	}

	private bool UpdatePresentation()
	{
		//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b7: Expected O, but got Unknown
		if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)motor) || !Object.op_Implicit((Object)(object)body.healthComponent) || !body.healthComponent.alive)
		{
			ResetPresentation();
			return false;
		}
		if (SkillOwnsAnimation())
		{
			ResetPresentation();
			return true;
		}
		bool isGrounded = motor.isGrounded;
		bool moving = Moving();
		if (stage == null && !pendingJump && isGrounded)
		{
			return false;
		}
		if (!EnsureRig())
		{
			return false;
		}
		DeltaController component = ((Component)body).GetComponent<DeltaController>();
		LastFrenzy.SetValue(rig, Object.op_Implicit((Object)(object)component) && component.IsFrenzy);
		if (pendingJump)
		{
			pendingJump = false;
			SourceClip sourceClip = sourceClips[pendingMoving ? "jumpMove" : "jumpLocal"];
			JObject transition = FindJumpEntrance(sourceClip.State);
			Enter(sourceClip, transition);
			return true;
		}
		if (stage == null)
		{
			Enter(sourceClips["fall"], null);
			return true;
		}
		if (!isGrounded && (stage.Key == "landIdle" || stage.Key == "landMove"))
		{
			Enter(sourceClips["fall"], null);
			return true;
		}
		float normalized = rig.CurrentClipTime / stage.Animation.duration;
		foreach (JObject item in (IEnumerable<JToken>)stage.Phase["transitions"])
		{
			JObject val = item;
			string text = (string)val["destination"];
			string text2 = (string)val["user"];
			SourceClip value;
			bool flag = sourceStates.TryGetValue(text, out value);
			int num;
			switch (text)
			{
			default:
				if (!(text2 == "To-StandBy"))
				{
					num = ((text2 == "To-Run") ? 1 : 0);
					break;
				}
				goto case "StandBy";
			case "StandBy":
			case "Run":
			case "RunAS":
				num = 1;
				break;
			}
			bool flag2 = (byte)num != 0;
			if ((flag || flag2) && (!flag || (!(value.Key == "jumpLocal") && !(value.Key == "jumpMove"))) && Conditions(val, normalized, isGrounded, moving, jump: false))
			{
				if (flag)
				{
					Enter(value, val);
					return true;
				}
				groundExitBlend = TransitionBlend(val, stage);
				hasGroundExit = true;
				stage = null;
				return false;
			}
		}
		return true;
	}

	private JObject FindJumpEntrance(string destination)
	{
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Expected O, but got Unknown
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Expected O, but got Unknown
		if (stage != null)
		{
			foreach (JObject item in (IEnumerable<JToken>)stage.Phase["transitions"])
			{
				JObject val = item;
				if ((string)val["destination"] == destination && Conditions(val, rig.CurrentClipTime / stage.Animation.duration, motor.isGrounded, pendingMoving, jump: true))
				{
					return val;
				}
			}
		}
		foreach (JObject item2 in (IEnumerable<JToken>)sourceClips["landIdle"].Phase["transitions"])
		{
			JObject val2 = item2;
			if ((string)val2["destination"] == destination && Conditions(val2, 0f, motor.isGrounded, pendingMoving, jump: true))
			{
				return val2;
			}
		}
		return null;
	}

	private static bool Conditions(JObject transition, float normalized, bool grounded, bool moving, bool jump)
	{
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Expected O, but got Unknown
		if ((bool)transition["hasExitTime"] && normalized < (float)transition["exitTime"])
		{
			return false;
		}
		foreach (JObject item in (IEnumerable<JToken>)transition["conditions"])
		{
			JObject val = item;
			string text = (string)val["name"];
			int num = (int)val["mode"];
			float num2 = (float)val["threshold"];
			bool flag;
			switch (text)
			{
			case "NormalizedTime":
				if (num == 3 && !(normalized > num2))
				{
					return false;
				}
				if (num == 4 && !(normalized < num2))
				{
					return false;
				}
				if (num == 3 || num == 4)
				{
					continue;
				}
				return false;
			case "IsOnGround":
				flag = grounded;
				break;
			case "IsMove":
				flag = moving;
				break;
			case "JumpNewTrigger":
				flag = jump;
				break;
			case "JumpNewBS":
			case "IsDead":
				flag = false;
				break;
			default:
				return false;
			}
			if ((num == 1 && !flag) || (num == 2 && flag) || (num != 1 && num != 2))
			{
				return false;
			}
		}
		return true;
	}

	private static float TransitionBlend(JObject transition, SourceClip previous)
	{
		if (transition == null)
		{
			return 0f;
		}
		float num = (float)transition["duration"];
		if (!(bool)transition["hasFixedDuration"] && previous != null)
		{
			return num * previous.Animation.duration / previous.Rate;
		}
		return num;
	}

	private void Enter(SourceClip next, JObject transition)
	{
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		Transform[] array = (Transform[])Nodes.GetValue(rig);
		Vector3[] array2 = (Vector3[])FromPositions.GetValue(rig);
		Vector3[] array3 = (Vector3[])FromScales.GetValue(rig);
		Quaternion[] array4 = (Quaternion[])FromRotations.GetValue(rig);
		for (int i = 0; i < array.Length; i++)
		{
			ref Vector3 reference = ref array2[i];
			reference = array[i].localPosition;
			ref Quaternion reference2 = ref array4[i];
			reference2 = array[i].localRotation;
			ref Vector3 reference3 = ref array3[i];
			reference3 = array[i].localScale;
		}
		float num = TransitionBlend(transition, stage);
		float num2 = ((transition == null) ? 0f : ((float)transition["offset"] * next.Animation.duration));
		Current.SetValue(rig, next.Animation);
		CurrentKey.SetValue(rig, "run");
		ClipTime.SetValue(rig, num2);
		StartOffset.SetValue(rig, num2);
		PlayRate.SetValue(rig, next.Rate);
		BlendTime.SetValue(rig, 0f);
		BlendDuration.SetValue(rig, num);
		Looping.SetValue(rig, next.Loop);
		DeltaController component = ((Component)body).GetComponent<DeltaController>();
		LastFrenzy.SetValue(rig, Object.op_Implicit((Object)(object)component) && component.IsFrenzy);
		stage = next;
		hasGroundExit = false;
		Sample.Invoke(rig, new object[2]
		{
			num2,
			(num > 0f) ? 0f : 1f
		});
	}
}
internal static class DeltaAssets
{
	private static DeltaModelDocument document;

	private static DeltaAnimationAliases aliases;

	private static readonly Dictionary<string, DeltaActionData> actions = new Dictionary<string, DeltaActionData>(StringComparer.Ordinal);

	private static readonly Dictionary<string, Sprite> skillIcons = new Dictionary<string, Sprite>(StringComparer.Ordinal);

	private static Texture2D portrait;

	private static Mesh[][] meshes;

	private static Material[][] materials;

	private static string assetDirectory;

	internal static DeltaModelDocument Document
	{
		get
		{
			EnsureLoaded();
			return document;
		}
	}

	internal static DeltaAnimationAliases Aliases
	{
		get
		{
			EnsureLoaded();
			return aliases;
		}
	}

	public static Texture2D GetPortrait()
	{
		EnsureLoaded();
		return portrait;
	}

	internal static DeltaActionData Action(string key)
	{
		EnsureLoaded();
		if (!actions.TryGetValue(key, out var value))
		{
			throw new InvalidDataException("Original controller action missing: " + key);
		}
		return value;
	}

	internal static Sprite GetSkillIcon(string slot)
	{
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		EnsureLoaded();
		if (skillIcons.TryGetValue(slot, out var value))
		{
			return value;
		}
		string text = slot switch
		{
			"PASSIVE" => "005", 
			"SPECIAL" => "004", 
			"SECONDARY" => "003", 
			_ => "001", 
		};
		Texture2D val = LoadTexture((slot == "UTILITY") ? "Icons/SleepDreamWeapon.png" : ("Icons/Skill_Twins_BS_AF01_" + text + ".png"), "DeltaSkill" + slot);
		value = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
		skillIcons[slot] = value;
		return value;
	}

	private static void EnsureLoaded()
	{
		//IL_032f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0334: Unknown result type (might be due to invalid IL or missing references)
		//IL_021f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0226: Expected O, but got Unknown
		//IL_0242: Unknown result type (might be due to invalid IL or missing references)
		//IL_0249: Expected O, but got Unknown
		//IL_0259: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ca: Expected O, but got Unknown
		//IL_04fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0529: Unknown result type (might be due to invalid IL or missing references)
		//IL_06c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_06c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_06dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_06e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0739: Unknown result type (might be due to invalid IL or missing references)
		//IL_073e: Unknown result type (might be due to invalid IL or missing references)
		//IL_075f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0764: Unknown result type (might be due to invalid IL or missing references)
		//IL_09c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_09cd: Expected O, but got Unknown
		//IL_0aea: Unknown result type (might be due to invalid IL or missing references)
		//IL_0afd: Expected O, but got Unknown
		//IL_0c47: Unknown result type (might be due to invalid IL or missing references)
		//IL_0e25: Unknown result type (might be due to invalid IL or missing references)
		//IL_0e5b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0e5d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0d43: Unknown result type (might be due to invalid IL or missing references)
		//IL_0d45: Unknown result type (might be due to invalid IL or missing references)
		if (document != null)
		{
			return;
		}
		assetDirectory = Path.Combine(Path.GetDirectoryName(typeof(DeltaAssets).Assembly.Location), "Assets");
		string path = Path.Combine(assetDirectory, "model.json");
		string path2 = Path.Combine(assetDirectory, "aliases.json");
		if (!File.Exists(path) || !File.Exists(path2))
		{
			throw new FileNotFoundException("Delta requires its real extracted Assets/model.json and Assets/aliases.json.");
		}
		DeltaModelDocument deltaModelDocument = JsonConvert.DeserializeObject<DeltaModelDocument>(File.ReadAllText(path));
		if (deltaModelDocument == null || deltaModelDocument.version != 1 || deltaModelDocument.coordinates != "Unity" || deltaModelDocument.nodes == null || deltaModelDocument.meshes == null || deltaModelDocument.meshes.Length == 0)
		{
			throw new InvalidDataException("Unsupported or empty Delta model document.");
		}
		DeltaAnimationAliases deltaAnimationAliases = JsonConvert.DeserializeObject<DeltaAnimationAliases>(File.ReadAllText(path2));
		if (deltaAnimationAliases == null)
		{
			throw new InvalidDataException("Delta animation aliases are missing.");
		}
		ValidateAliases(deltaModelDocument, deltaAnimationAliases);
		DeltaActionDocument deltaActionDocument = JsonConvert.DeserializeObject<DeltaActionDocument>(File.ReadAllText(Path.Combine(assetDirectory, "actions.json")));
		if (deltaActionDocument == null || deltaActionDocument.version != 1 || deltaActionDocument.actions == null)
		{
			throw new InvalidDataException("Original BattleY controller actions are required.");
		}
		DeltaActionData[] array = deltaActionDocument.actions;
		foreach (DeltaActionData deltaActionData in array)
		{
			if (deltaActionData.rawDuration <= 0f || deltaActionData.speed <= 0f || deltaAnimationAliases.Get(deltaActionData.key) != deltaActionData.clip)
			{
				throw new InvalidDataException("Invalid source controller action: " + deltaActionData.key);
			}
			actions[deltaActionData.key] = deltaActionData;
		}
		portrait = LoadTexture("portrait.png", "FeverishTempoDeltaPortrait");
		Dictionary<string, Texture2D> dictionary = new Dictionary<string, Texture2D>(StringComparer.Ordinal);
		JObject val = JObject.Parse(File.ReadAllText(Path.Combine(assetDirectory, "BodyShaders", "source-materials.json")));
		DeltaTextureData[] array2 = deltaModelDocument.textures ?? new DeltaTextureData[0];
		foreach (DeltaTextureData deltaTextureData in array2)
		{
			JObject metadata = null;
			foreach (JObject item in (IEnumerable<JToken>)val["materials"])
			{
				JObject val2 = item;
				foreach (JObject item2 in (IEnumerable<JToken>)val2["textures"])
				{
					JObject val3 = item2;
					foreach (JToken item3 in (IEnumerable<JToken>)(((object)val3["modelTextureFiles"]) ?? ((object)new JArray())))
					{
						if ((string)item3 == deltaTextureData.file)
						{
							metadata = val3;
						}
					}
				}
			}
			Texture2D value = LoadTexture(deltaTextureData.file, deltaTextureData.name, metadata);
			dictionary[deltaTextureData.name] = value;
			dictionary[deltaTextureData.file] = value;
		}
		DeltaSourceMaterials.Configure(assetDirectory);
		LoadOriginalMaterialTextures(dictionary);
		Shader val4 = Addressables.LoadAssetAsync<Shader>((object)"RoR2/Base/Shaders/HGStandard.shader").WaitForCompletion();
		if (!Object.op_Implicit((Object)(object)val4))
		{
			throw new InvalidDataException("Current game HGStandard shader unavailable.");
		}
		Material[] array3 = (Material[])(object)new Material[(deltaModelDocument.materials ?? new DeltaMaterialData[0]).Length];
		Dictionary<string, int> dictionary2 = new Dictionary<string, int>(StringComparer.Ordinal);
		HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
		DeltaMeshData[] array4 = deltaModelDocument.meshes;
		foreach (DeltaMeshData deltaMeshData in array4)
		{
			if (IsHiddenMesh(deltaMeshData.name, deltaAnimationAliases))
			{
				continue;
			}
			DeltaSubmeshData[] array5 = deltaMeshData.submeshes ?? new DeltaSubmeshData[0];
			foreach (DeltaSubmeshData deltaSubmeshData in array5)
			{
				if (deltaSubmeshData.material is string)
				{
					hashSet.Add((string)deltaSubmeshData.material);
				}
				else if (deltaSubmeshData.material is int || deltaSubmeshData.material is long)
				{
					int num = Convert.ToInt32(deltaSubmeshData.material);
					if (num >= 0 && num < deltaModelDocument.materials.Length)
					{
						hashSet.Add(deltaModelDocument.materials[num].name);
					}
				}
			}
		}
		for (int l = 0; l < array3.Length; l++)
		{
			DeltaMaterialData deltaMaterialData = deltaModelDocument.materials[l];
			dictionary2[deltaMaterialData.name] = l;
			if (!hashSet.Contains(deltaMaterialData.name))
			{
				continue;
			}
			Material val5 = DeltaSourceMaterials.TryBuild(deltaMaterialData.name, dictionary);
			if (Object.op_Implicit((Object)(object)val5))
			{
				array3[l] = val5;
				continue;
			}
			Material val6 = new Material(val4);
			((Object)val6).name = "Delta_" + deltaMaterialData.name;
			val6.SetColor("_Color", (Color)((deltaMaterialData.diffuse != null && deltaMaterialData.diffuse.Length >= 4) ? new Color(deltaMaterialData.diffuse[0], deltaMaterialData.diffuse[1], deltaMaterialData.diffuse[2], deltaMaterialData.diffuse[3]) : Color.white));
			val6.SetFloat("_Smoothness", 0f);
			val6.SetFloat("_SpecularStrength", 0f);
			val6.SetFloat("_NormalStrength", 0f);
			val6.SetFloat("_EmPower", 0f);
			val6.SetFloat("_Cull", 0f);
			val6.SetFloat("_DitherOn", 1f);
			val6.EnableKeyword("DITHER");
			DeltaMaterialTexture deltaMaterialTexture = null;
			DeltaMaterialTexture[] array6 = deltaMaterialData.textures ?? new DeltaMaterialTexture[0];
			foreach (DeltaMaterialTexture deltaMaterialTexture2 in array6)
			{
				if (deltaMaterialTexture2.dest == 0 && dictionary.ContainsKey(deltaMaterialTexture2.name))
				{
					deltaMaterialTexture = deltaMaterialTexture2;
					break;
				}
			}
			if (deltaMaterialTexture == null)
			{
				array6 = deltaMaterialData.textures ?? new DeltaMaterialTexture[0];
				foreach (DeltaMaterialTexture deltaMaterialTexture3 in array6)
				{
					if (dictionary.ContainsKey(deltaMaterialTexture3.name) && (deltaMaterialTexture3.name.IndexOf("_D", StringComparison.OrdinalIgnoreCase) >= 0 || deltaMaterialTexture3.name.IndexOf("diffuse", StringComparison.OrdinalIgnoreCase) >= 0 || deltaMaterialTexture3.name.IndexOf("color", StringComparison.OrdinalIgnoreCase) >= 0))
					{
						deltaMaterialTexture = deltaMaterialTexture3;
						break;
					}
				}
			}
			if (deltaMaterialTexture == null)
			{
				throw new InvalidDataException("No extracted color texture for material " + deltaMaterialData.name);
			}
			val6.SetTexture("_MainTex", (Texture)(object)dictionary[deltaMaterialTexture.name]);
			val6.SetTextureOffset("_MainTex", V2(deltaMaterialTexture.offset, Vector2.zero));
			val6.SetTextureScale("_MainTex", V2(deltaMaterialTexture.scale, Vector2.one));
			DeltaMaterialOverride[] array7 = deltaAnimationAliases.materialOverrides ?? new DeltaMaterialOverride[0];
			foreach (DeltaMaterialOverride deltaMaterialOverride in array7)
			{
				if (!(deltaMaterialOverride.material != deltaMaterialData.name))
				{
					if (deltaMaterialOverride.scale != null)
					{
						val6.SetTextureScale("_MainTex", V2(deltaMaterialOverride.scale, Vector2.one));
					}
					if (deltaMaterialOverride.offset != null)
					{
						val6.SetTextureOffset("_MainTex", V2(deltaMaterialOverride.offset, Vector2.zero));
					}
					if (deltaMaterialOverride.cutout)
					{
						val6.SetFloat("_EnableCutout", 1f);
						val6.EnableKeyword("CUTOUT");
					}
				}
			}
			array3[l] = val6;
		}
		Mesh[][] array8 = new Mesh[deltaModelDocument.meshes.Length][];
		Material[][] array9 = new Material[deltaModelDocument.meshes.Length][];
		JObject val7 = JObject.Parse(File.ReadAllText(Path.Combine(assetDirectory, "body-vertex-channels.json")));
		if ((int)val7["version"] != 1 || (string)val7["coordinates"] != "Unity")
		{
			throw new InvalidDataException("Invalid original vertex-channel mapping.");
		}
		for (int m = 0; m < deltaModelDocument.meshes.Length; m++)
		{
			DeltaMeshData deltaMeshData2 = deltaModelDocument.meshes[m];
			if (IsHiddenMesh(deltaMeshData2.name, deltaAnimationAliases))
			{
				array8[m] = (Mesh[])(object)new Mesh[0];
				array9[m] = (Material[])(object)new Material[0];
				continue;
			}
			if (deltaMeshData2.node < 0 || deltaMeshData2.node >= deltaModelDocument.nodes.Length || deltaMeshData2.positions == null || deltaMeshData2.positions.Length % 3 != 0 || deltaMeshData2.submeshes == null)
			{
				throw new InvalidDataException("Invalid extracted mesh " + deltaMeshData2.name);
			}
			array8[m] = (Mesh[])(object)new Mesh[deltaMeshData2.submeshes.Length];
			array9[m] = (Material[])(object)new Material[deltaMeshData2.submeshes.Length];
			for (int n = 0; n < deltaMeshData2.submeshes.Length; n++)
			{
				DeltaSubmeshData deltaSubmeshData2 = deltaMeshData2.submeshes[n];
				int value2;
				if (deltaSubmeshData2.material is string)
				{
					if (!dictionary2.TryGetValue((string)deltaSubmeshData2.material, out value2))
					{
						throw new InvalidDataException(string.Concat("Unresolved original material ", deltaSubmeshData2.material, " on ", deltaMeshData2.name));
					}
				}
				else
				{
					if (!(deltaSubmeshData2.material is long) && !(deltaSubmeshData2.material is int))
					{
						throw new InvalidDataException("Unresolved material reference on " + deltaMeshData2.name);
					}
					value2 = Convert.ToInt32(deltaSubmeshData2.material);
				}
				if (value2 < 0 || value2 >= array3.Length)
				{
					throw new InvalidDataException("Unresolved material on " + deltaMeshData2.name);
				}
				Mesh val8 = new Mesh();
				((Object)val8).name = "Delta_" + deltaMeshData2.name + "_" + n;
				if (deltaMeshData2.positions.Length / 3 > 65535)
				{
					val8.indexFormat = (IndexFormat)1;
				}
				val8.vertices = Vectors3(deltaMeshData2.positions);
				if (deltaMeshData2.normals != null && deltaMeshData2.normals.Length == deltaMeshData2.positions.Length)
				{
					val8.normals = Vectors3(deltaMeshData2.normals);
				}
				if (deltaMeshData2.uvs != null && deltaMeshData2.uvs.Length == deltaMeshData2.positions.Length / 3 * 2)
				{
					val8.uv = Vectors2(deltaMeshData2.uvs);
				}
				if (deltaMeshData2.tangents != null && deltaMeshData2.tangents.Length == deltaMeshData2.positions.Length / 3 * 4)
				{
					val8.tangents = Vectors4(deltaMeshData2.tangents);
				}
				ApplyOriginalVertexChannels(val8, (JObject)val7["meshes"][(object)m], m, deltaMeshData2.name);
				val8.triangles = deltaSubmeshData2.indices;
				if (deltaMeshData2.bones != null && deltaMeshData2.bones.Length > 0)
				{
					int num2 = deltaMeshData2.positions.Length / 3;
					if (deltaMeshData2.weights == null || deltaMeshData2.weights.Length != num2 * 4 || deltaMeshData2.boneIndices == null || deltaMeshData2.boneIndices.Length != num2 * 4 || deltaMeshData2.bindposes == null || deltaMeshData2.bindposes.Length != deltaMeshData2.bones.Length)
					{
						throw new InvalidDataException("Incomplete skin weights on " + deltaMeshData2.name);
					}
					BoneWeight[] array10 = (BoneWeight[])(object)new BoneWeight[num2];
					for (int num3 = 0; num3 < num2; num3++)
					{
						int num4 = num3 * 4;
						float num5 = 0f;
						for (int num6 = 0; num6 < 4; num6++)
						{
							int num7 = deltaMeshData2.boneIndices[num4 + num6];
							float num8 = deltaMeshData2.weights[num4 + num6];
							if (num8 > 0f && (num7 < 0 || num7 >= deltaMeshData2.bones.Length))
							{
								throw new InvalidDataException("Invalid skin bone index on " + deltaMeshData2.name);
							}
							num5 += num8;
						}
						if (num5 < 1E-05f)
						{
							throw new InvalidDataException("Unweighted vertex on " + deltaMeshData2.name);
						}
						ref BoneWeight reference = ref array10[num3];
						BoneWeight val9 = default(BoneWeight);
						((BoneWeight)(ref val9)).boneIndex0 = ((deltaMeshData2.weights[num4] > 0f) ? deltaMeshData2.boneIndices[num4] : 0);
						((BoneWeight)(ref val9)).boneIndex1 = ((deltaMeshData2.weights[num4 + 1] > 0f) ? deltaMeshData2.boneIndices[num4 + 1] : 0);
						((BoneWeight)(ref val9)).boneIndex2 = ((deltaMeshData2.weights[num4 + 2] > 0f) ? deltaMeshData2.boneIndices[num4 + 2] : 0);
						((BoneWeight)(ref val9)).boneIndex3 = ((deltaMeshData2.weights[num4 + 3] > 0f) ? deltaMeshData2.boneIndices[num4 + 3] : 0);
						((BoneWeight)(ref val9)).weight0 = deltaMeshData2.weights[num4] / num5;
						((BoneWeight)(ref val9)).weight1 = deltaMeshData2.weights[num4 + 1] / num5;
						((BoneWeight)(ref val9)).weight2 = deltaMeshData2.weights[num4 + 2] / num5;
						((BoneWeight)(ref val9)).weight3 = deltaMeshData2.weights[num4 + 3] / num5;
						reference = val9;
					}
					Matrix4x4[] array11 = (Matrix4x4[])(object)new Matrix4x4[deltaMeshData2.bindposes.Length];
					for (int num9 = 0; num9 < array11.Length; num9++)
					{
						if (deltaMeshData2.bindposes[num9] == null || deltaMeshData2.bindposes[num9].Length != 16)
						{
							throw new InvalidDataException("Invalid bind pose on " + deltaMeshData2.name);
						}
						if (Math.Abs(deltaMeshData2.bindposes[num9][3]) > 0.001f || Math.Abs(deltaMeshData2.bindposes[num9][7]) > 0.001f || Math.Abs(deltaMeshData2.bindposes[num9][11]) > 0.001f || Math.Abs(deltaMeshData2.bindposes[num9][15] - 1f) > 0.001f)
						{
							throw new InvalidDataException("Bind poses must be original Unity affine column-major matrices: " + deltaMeshData2.name);
						}
						Matrix4x4 val10 = default(Matrix4x4);
						for (int num10 = 0; num10 < 16; num10++)
						{
							((Matrix4x4)(ref val10))[num10] = deltaMeshData2.bindposes[num9][num10];
						}
						array11[num9] = val10;
					}
					val8.boneWeights = array10;
					val8.bindposes = array11;
				}
				AddMorphs(val8, deltaMeshData2, deltaModelDocument.morphs);
				if (deltaMeshData2.normals == null || deltaMeshData2.normals.Length != deltaMeshData2.positions.Length)
				{
					val8.RecalculateNormals();
				}
				val8.RecalculateBounds();
				array8[m][n] = val8;
				array9[m][n] = array3[value2];
			}
		}
		document = deltaModelDocument;
		aliases = deltaAnimationAliases;
		meshes = array8;
		materials = array9;
		CorePlugin.LogInfo("Real Delta assets loaded: " + deltaModelDocument.nodes.Length + " nodes, " + deltaModelDocument.meshes.Length + " meshes, " + deltaModelDocument.animations.Length + " source clips.");
	}

	private static void LoadOriginalMaterialTextures(Dictionary<string, Texture2D> textures)
	{
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Expected O, but got Unknown
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Expected O, but got Unknown
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Expected O, but got Unknown
		//IL_015f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cc: Expected O, but got Unknown
		string path = Path.Combine(assetDirectory, "BodyShaders", "source-materials.json");
		if (!File.Exists(path))
		{
			return;
		}
		JObject val = JObject.Parse(File.ReadAllText(path));
		foreach (JObject item in (IEnumerable<JToken>)(((object)val["sourceTextureFiles"]) ?? ((object)new JArray())))
		{
			JObject val2 = item;
			textures[(string)val2["id"]] = LoadTexture("BodyShaders/" + (string)val2["file"], (string)val2["name"], val2);
		}
		JObject val3 = JObject.Parse(File.ReadAllText(Path.Combine(assetDirectory, "Effects", "effects.json")));
		foreach (JObject item2 in (IEnumerable<JToken>)val["materials"])
		{
			JObject val4 = item2;
			foreach (JObject item3 in (IEnumerable<JToken>)val4["textures"])
			{
				JObject val5 = item3;
				string text = (string)val5["id"];
				if (text == "0" || textures.ContainsKey(text))
				{
					continue;
				}
				Texture2D value = null;
				foreach (JToken item4 in (IEnumerable<JToken>)(((object)val5["modelTextureFiles"]) ?? ((object)new JArray())))
				{
					if (textures.TryGetValue((string)item4, out value))
					{
						break;
					}
				}
				if (!Object.op_Implicit((Object)(object)value))
				{
					foreach (JObject item5 in (IEnumerable<JToken>)val3["textures"])
					{
						JObject val6 = item5;
						if (!((string)val6["id"] != text))
						{
							value = LoadTexture("Effects/" + (string)val6["file"], (string)val6["name"], val6);
							break;
						}
					}
				}
				if (Object.op_Implicit((Object)(object)value))
				{
					textures[text] = value;
				}
			}
		}
	}

	private static void ApplyOriginalVertexChannels(Mesh mesh, JObject source, int index, string name)
	{
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Expected O, but got Unknown
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Expected O, but got Unknown
		//IL_0177: Unknown result type (might be due to invalid IL or missing references)
		//IL_017e: Expected O, but got Unknown
		//IL_0205: Unknown result type (might be due to invalid IL or missing references)
		//IL_020a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		if ((int)source["modelMeshIndex"] != index || (string)source["modelMeshName"] != name || (int)source["vertexCount"] != mesh.vertexCount)
		{
			throw new InvalidDataException("Original vertex-channel identity mismatch: " + name);
		}
		foreach (JObject item in (IEnumerable<JToken>)source["uvChannels"])
		{
			JObject val = item;
			int num = (int)val["dimension"];
			if (num == 0)
			{
				continue;
			}
			JArray val2 = (JArray)val["values"];
			if (num < 1 || num > 4 || ((JContainer)val2).Count != mesh.vertexCount * num)
			{
				throw new InvalidDataException("Invalid original UV channel: " + name);
			}
			List<Vector4> list = new List<Vector4>(mesh.vertexCount);
			for (int i = 0; i < mesh.vertexCount; i++)
			{
				Vector4 zero = Vector4.zero;
				for (int j = 0; j < num; j++)
				{
					((Vector4)(ref zero))[j] = (float)val2[i * num + j];
				}
				list.Add(zero);
			}
			mesh.SetUVs((int)val["channel"], list);
		}
		if ((int)source["colorDimension"] == 4)
		{
			JArray val3 = (JArray)source["colors"];
			if (((JContainer)val3).Count != mesh.vertexCount * 4)
			{
				throw new InvalidDataException("Invalid original vertex colors: " + name);
			}
			Color[] array = (Color[])(object)new Color[mesh.vertexCount];
			for (int k = 0; k < array.Length; k++)
			{
				ref Color reference = ref array[k];
				reference = new Color((float)val3[k * 4], (float)val3[k * 4 + 1], (float)val3[k * 4 + 2], (float)val3[k * 4 + 3]);
			}
			mesh.colors = array;
		}
	}

	private static void ValidateAliases(DeltaModelDocument model, DeltaAnimationAliases map)
	{
		HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
		DeltaAnimationData[] array = model.animations ?? new DeltaAnimationData[0];
		foreach (DeltaAnimationData deltaAnimationData in array)
		{
			if (deltaAnimationData.tracks != null && deltaAnimationData.tracks.Length > 0 && deltaAnimationData.duration > 0f)
			{
				hashSet.Add(deltaAnimationData.name);
			}
		}
		string[] array2 = new string[18]
		{
			"idle", "run", "attack1", "attack2", "attack3", "attack4", "attack5", "attack6", "frenzy1", "frenzy2",
			"frenzy3", "charge", "chargeRelease", "dodge", "dodgeBackward", "parryStart", "parry", "counter"
		};
		foreach (string text in array2)
		{
			string text2 = map.Get(text);
			if (string.IsNullOrEmpty(text2) || !hashSet.Contains(text2))
			{
				throw new InvalidDataException("Real source animation missing: " + text + " -> " + text2);
			}
		}
		string[] array3 = new string[2] { "frenzyIdle", "frenzyRun" };
		foreach (string text3 in array3)
		{
			string text4 = map.Get(text3);
			if (!string.IsNullOrEmpty(text4) && !hashSet.Contains(text4))
			{
				throw new InvalidDataException("Original frenzy stance clip missing: " + text3 + " -> " + text4);
			}
		}
	}

	private static Texture2D LoadTexture(string relative, string name)
	{
		return LoadTexture(relative, name, null);
	}

	private static Texture2D LoadTexture(string relative, string name, JObject metadata)
	{
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Expected O, but got Unknown
		string fullPath = Path.GetFullPath(Path.Combine(assetDirectory, relative));
		if (!fullPath.StartsWith(Path.GetFullPath(assetDirectory) + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase))
		{
			throw new InvalidDataException("Asset texture path escapes Assets.");
		}
		if (!File.Exists(fullPath))
		{
			throw new FileNotFoundException("Extracted texture missing", fullPath);
		}
		int num = ((metadata == null) ? 2 : (((int?)(metadata["sourceMipCount"] ?? metadata["mipCount"])) ?? 1));
		int num3;
		if (metadata != null)
		{
			int? num2 = (int?)metadata["colorSpace"];
			num3 = ((num2.GetValueOrDefault() == 0 && num2.HasValue) ? 1 : 0);
		}
		else
		{
			num3 = 0;
		}
		bool flag = (byte)num3 != 0;
		Texture2D val = new Texture2D(2, 2, (TextureFormat)4, num > 1, flag);
		((Object)val).name = name;
		if (!ImageConversion.LoadImage(val, File.ReadAllBytes(fullPath), false))
		{
			throw new InvalidDataException("Invalid PNG texture: " + relative);
		}
		((Texture)val).wrapMode = (TextureWrapMode)0;
		((Texture)val).filterMode = (FilterMode)2;
		((Texture)val).anisoLevel = 4;
		JObject val2 = (JObject)((metadata == null) ? null : /*isinst with value type is only supported in some contexts*/);
		if (val2 != null)
		{
			((Texture)val).wrapModeU = (TextureWrapMode)(int)val2["m_WrapU"];
			((Texture)val).wrapModeV = (TextureWrapMode)(int)val2["m_WrapV"];
			((Texture)val).wrapModeW = (TextureWrapMode)(int)val2["m_WrapW"];
			((Texture)val).filterMode = (FilterMode)(int)val2["m_FilterMode"];
			((Texture)val).anisoLevel = (int)val2["m_Aniso"];
			((Texture)val).mipMapBias = (float)val2["m_MipBias"];
		}
		return val;
	}

	private static void AddMorphs(Mesh mesh, DeltaMeshData data, DeltaMorphData[] morphs)
	{
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Unknown result type (might be due to invalid IL or missing references)
		//IL_0168: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0191: Unknown result type (might be due to invalid IL or missing references)
		DeltaMorphData[] array = morphs ?? new DeltaMorphData[0];
		foreach (DeltaMorphData deltaMorphData in array)
		{
			if (deltaMorphData.node != data.node || deltaMorphData.path != data.path)
			{
				continue;
			}
			DeltaMorphChannel[] array2 = deltaMorphData.channels ?? new DeltaMorphChannel[0];
			foreach (DeltaMorphChannel deltaMorphChannel in array2)
			{
				DeltaMorphFrame[] array3 = deltaMorphChannel.frames ?? new DeltaMorphFrame[0];
				foreach (DeltaMorphFrame deltaMorphFrame in array3)
				{
					Vector3[] array4 = (Vector3[])(object)new Vector3[mesh.vertexCount];
					Vector3[] array5 = (Vector3[])(object)new Vector3[mesh.vertexCount];
					Vector3[] array6 = (Vector3[])(object)new Vector3[mesh.vertexCount];
					DeltaMorphVertex[] array7 = deltaMorphFrame.vertices ?? new DeltaMorphVertex[0];
					foreach (DeltaMorphVertex deltaMorphVertex in array7)
					{
						if (deltaMorphVertex.index < 0 || deltaMorphVertex.index >= mesh.vertexCount)
						{
							throw new InvalidDataException("Invalid morph vertex index.");
						}
						ref Vector3 reference = ref array4[deltaMorphVertex.index];
						reference = V3(deltaMorphVertex.position, Vector3.zero) - new Vector3(data.positions[deltaMorphVertex.index * 3], data.positions[deltaMorphVertex.index * 3 + 1], data.positions[deltaMorphVertex.index * 3 + 2]);
						ref Vector3 reference2 = ref array5[deltaMorphVertex.index];
						reference2 = V3(deltaMorphVertex.normal, Vector3.zero);
						ref Vector3 reference3 = ref array6[deltaMorphVertex.index];
						reference3 = V3(deltaMorphVertex.tangent, Vector3.zero);
					}
					mesh.AddBlendShapeFrame(deltaMorphChannel.name, deltaMorphFrame.weight, array4, array5, array6);
				}
			}
		}
	}

	public static void SetupBody(GameObject bodyObject)
	{
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		EnsureLoaded();
		ModelLocator component = bodyObject.GetComponent<ModelLocator>();
		if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component.modelTransform))
		{
			throw new InvalidOperationException("Body movement prefab has no model locator.");
		}
		Transform modelTransform = component.modelTransform;
		Transform parent = modelTransform.parent;
		CharacterModel component2 = ((Component)modelTransform).GetComponent<CharacterModel>();
		GameObject val = BuildModel(parent, component2, bodyObject.GetComponent<CharacterBody>());
		val.transform.localPosition = modelTransform.localPosition;
		val.transform.localRotation = modelTransform.localRotation;
		val.transform.localScale = Vector3.one;
		component.modelTransform = val.transform;
		component.forcedAnimatorAtStart = null;
		component.SetAnimator((Animator)null);
		component.modelVisibility = val.GetComponent<CharacterModel>().visibilityChecker;
		component.compensateForInitialScale = false;
		component.desiredModelScale = 1f;
		CharacterDirection component3 = bodyObject.GetComponent<CharacterDirection>();
		if (Object.op_Implicit((Object)(object)component3))
		{
			component3.targetTransform = val.transform;
			component3.modelAnimator = null;
			component3.rootMotionAccumulator = null;
			component3.driveFromRootRotation = false;
			component3.overrideAnimatorForwardTransform = null;
		}
		CharacterBody component4 = bodyObject.GetComponent<CharacterBody>();
		Transform cameraPivotTransform = (component4.aimOriginTransform = (component4.overrideCoreTransform = val.GetComponent<ChildLocator>().FindChild("Chest")));
		CameraTargetParams component5 = bodyObject.GetComponent<CameraTargetParams>();
		if (Object.op_Implicit((Object)(object)component5) && Object.op_Implicit((Object)(object)component5.cameraPivotTransform) && ((Object)(object)component5.cameraPivotTransform == (Object)(object)modelTransform || component5.cameraPivotTransform.IsChildOf(modelTransform)))
		{
			component5.cameraPivotTransform = cameraPivotTransform;
		}
		Object.DestroyImmediate((Object)(object)((Component)modelTransform).gameObject);
		val.SetActive(true);
	}

	public static GameObject BuildDisplay(GameObject originalDisplay)
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Expected O, but got Unknown
		EnsureLoaded();
		GameObject val = new GameObject("FeverishTempoDeltaDisplay");
		val.SetActive(false);
		CharacterModel componentInChildren = originalDisplay.GetComponentInChildren<CharacterModel>(true);
		GameObject val2 = BuildModel(val.transform, componentInChildren, null);
		val2.SetActive(true);
		val.SetActive(true);
		return val;
	}

	public static void PlayAnimation(GameObject body, string key, float speed)
	{
		PlayAnimation(body, key, speed, 0f);
	}

	public static void PlayAnimation(GameObject body, string key, float speed, float desiredDuration)
	{
		ModelLocator component = body.GetComponent<ModelLocator>();
		DeltaRig deltaRig = ((Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.modelTransform)) ? ((Component)component.modelTransform).GetComponent<DeltaRig>() : body.GetComponentInChildren<DeltaRig>());
		if (Object.op_Implicit((Object)(object)deltaRig))
		{
			deltaRig.Play(key, speed, desiredDuration);
		}
	}

	private static GameObject BuildModel(Transform parent, CharacterModel original, CharacterBody body)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Expected O, but got Unknown
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Expected O, but got Unknown
		//IL_040c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0432: Unknown result type (might be due to invalid IL or missing references)
		//IL_0449: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0196: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Expected O, but got Unknown
		//IL_0340: Unknown result type (might be due to invalid IL or missing references)
		//IL_0364: Unknown result type (might be due to invalid IL or missing references)
		//IL_0379: Unknown result type (might be due to invalid IL or missing references)
		//IL_0390: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0290: Unknown result type (might be due to invalid IL or missing references)
		//IL_0295: Unknown result type (might be due to invalid IL or missing references)
		//IL_0299: Unknown result type (might be due to invalid IL or missing references)
		//IL_029e: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02da: Unknown result type (might be due to invalid IL or missing references)
		//IL_0592: Unknown result type (might be due to invalid IL or missing references)
		//IL_0599: Expected O, but got Unknown
		//IL_05c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_05ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_0638: Unknown result type (might be due to invalid IL or missing references)
		//IL_0882: Unknown result type (might be due to invalid IL or missing references)
		//IL_0891: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("mdlFeverishTempoDelta");
		val.SetActive(false);
		val.transform.SetParent(parent, false);
		GameObject val2 = new GameObject("SourceRig");
		val2.transform.SetParent(val.transform, false);
		Transform[] array = (Transform[])(object)new Transform[document.nodes.Length];
		for (int i = 0; i < array.Length; i++)
		{
			DeltaNodeData deltaNodeData = document.nodes[i];
			if (deltaNodeData.parent >= i || deltaNodeData.parent < -1)
			{
				throw new InvalidDataException("Model nodes must use preorder parents.");
			}
			GameObject val3 = new GameObject(deltaNodeData.name);
			array[i] = val3.transform;
			val3.transform.SetParent((deltaNodeData.parent < 0) ? val2.transform : array[deltaNodeData.parent], false);
			val3.transform.localPosition = V3(deltaNodeData.position, Vector3.zero);
			val3.transform.localRotation = Q4(deltaNodeData.rotation);
			val3.transform.localScale = V3(deltaNodeData.scale, Vector3.one);
		}
		List<RendererInfo> list = new List<RendererInfo>();
		List<Renderer> list2 = new List<Renderer>();
		List<GameObjectActivation> list3 = new List<GameObjectActivation>();
		for (int j = 0; j < document.meshes.Length; j++)
		{
			DeltaMeshData deltaMeshData = document.meshes[j];
			if (IsHiddenMesh(deltaMeshData.name, aliases))
			{
				continue;
			}
			bool flag = IsInitiallyInactiveMesh(deltaMeshData.name, aliases);
			for (int k = 0; k < meshes[j].Length; k++)
			{
				GameObject val4 = new GameObject(deltaMeshData.name + "_Part" + k);
				val4.transform.SetParent(array[deltaMeshData.node], false);
				Renderer val6;
				if (deltaMeshData.bones != null && deltaMeshData.bones.Length > 0)
				{
					SkinnedMeshRenderer val5 = val4.AddComponent<SkinnedMeshRenderer>();
					val5.sharedMesh = meshes[j][k];
					Transform[] array2 = (Transform[])(object)new Transform[deltaMeshData.bones.Length];
					for (int l = 0; l < array2.Length; l++)
					{
						if (deltaMeshData.bones[l] < 0 || deltaMeshData.bones[l] >= array.Length)
						{
							throw new InvalidDataException("Unresolved source bone: " + deltaMeshData.name);
						}
						array2[l] = array[deltaMeshData.bones[l]];
					}
					val5.bones = array2;
					val5.rootBone = FindNode(array, "Bip001") ?? array2[0];
					val5.updateWhenOffscreen = true;
					val5.quality = (SkinQuality)4;
					Bounds bounds = meshes[j][k].bounds;
					Vector3 center = ((Bounds)(ref bounds)).center;
					Vector3 one = Vector3.one;
					Bounds bounds2 = meshes[j][k].bounds;
					Vector3 size = ((Bounds)(ref bounds2)).size;
					((Renderer)val5).localBounds = new Bounds(center, one * Mathf.Max(5f, ((Vector3)(ref size)).magnitude * 2f));
					val6 = (Renderer)(object)val5;
				}
				else
				{
					val4.AddComponent<MeshFilter>().sharedMesh = meshes[j][k];
					val6 = (Renderer)(object)val4.AddComponent<MeshRenderer>();
				}
				val6.sharedMaterial = materials[j][k];
				val6.shadowCastingMode = (ShadowCastingMode)1;
				val6.receiveShadows = true;
				DeltaRenderBridge.Register(val6);
				list2.Add(val6);
				list.Add(new RendererInfo
				{
					renderer = val6,
					defaultMaterial = materials[j][k],
					defaultShadowCastingMode = (ShadowCastingMode)1,
					ignoreOverlays = false,
					hideOnDeath = false
				});
				if (flag)
				{
					val4.SetActive(false);
					list3.Add(new GameObjectActivation
					{
						gameObject = val4,
						shouldActivate = false
					});
				}
			}
		}
		NormaliseVisual(val2.transform, array);
		ChildLocator val7 = val.AddComponent<ChildLocator>();
		Transform val8 = Anchor(val.transform, "DeltaChest", new Vector3(0f, 1.05f, 0f));
		Transform val9 = Anchor(val.transform, "DeltaHead", new Vector3(0f, 1.65f, 0f));
		Transform val10 = Anchor(val.transform, "DeltaFeet", Vector3.zero);
		val7.AddChild("Chest", val8);
		val7.AddChild("Head", FindNode(array, "Bip001 Head") ?? val9);
		val7.AddChild("Base", val10);
		val7.AddChild("FootL", FindNode(array, "Bip001 L Foot") ?? val10);
		val7.AddChild("FootR", FindNode(array, "Bip001 R Foot") ?? val10);
		val7.AddChild("HandL", FindNode(array, "Bip001 L Hand") ?? val8);
		val7.AddChild("HandR", FindNode(array, "Bip001 R Hand") ?? val8);
		val7.AddChild("Muzzle", val7.FindChild("HandR"));
		val7.AddChild("Pelvis", FindNode(array, "Bip001 Pelvis") ?? val8);
		Transform[] array3 = array;
		foreach (Transform val11 in array3)
		{
			if ((Object)(object)val7.FindChild(((Object)val11).name) == (Object)null)
			{
				val7.AddChild(((Object)val11).name, val11);
			}
		}
		if (Object.op_Implicit((Object)(object)body))
		{
			HurtBoxGroup val12 = val.AddComponent<HurtBoxGroup>();
			GameObject val13 = new GameObject("DeltaMainHurtBox");
			val13.transform.SetParent(val.transform, false);
			val13.transform.localPosition = new Vector3(0f, 0.95f, 0f);
			val13.layer = LayerIndex.entityPrecise.intVal;
			CapsuleCollider val14 = val13.AddComponent<CapsuleCollider>();
			val14.radius = 0.32f;
			val14.height = 1.75f;
			((Collider)val14).isTrigger = false;
			HurtBox val15 = val13.AddComponent<HurtBox>();
			val15.healthComponent = ((Component)body).GetComponent<HealthComponent>();
			val15.hurtBoxGroup = val12;
			val15.indexInGroup = 0;
			val15.isBullseye = true;
			val15.damageModifier = (DamageModifier)0;
			val12.hurtBoxes = (HurtBox[])(object)new HurtBox[1] { val15 };
			val12.mainHurtBox = val15;
			val12.bullseyeCount = 1;
		}
		CharacterModel val16 = val.AddComponent<CharacterModel>();
		if (Object.op_Implicit((Object)(object)original))
		{
			FieldInfo[] fields = typeof(CharacterModel).GetFields(BindingFlags.Instance | BindingFlags.Public);
			foreach (FieldInfo fieldInfo in fields)
			{
				if (fieldInfo.FieldType == typeof(Material))
				{
					fieldInfo.SetValue(val16, fieldInfo.GetValue(original));
				}
			}
		}
		val16.body = body;
		val16.baseRendererInfos = list.ToArray();
		val16.baseLightInfos = (LightInfo[])(object)new LightInfo[0];
		val16.autoPopulateLightInfos = false;
		val16.itemDisplayRuleSet = null;
		val16.fullBodyPing = true;
		val16.CharacterOnScreen = true;
		Renderer val17 = null;
		int num = -1;
		foreach (Renderer item in list2)
		{
			if (((Object)item).name.IndexOf("claymore", StringComparison.OrdinalIgnoreCase) < 0 && ((Object)item).name.IndexOf("weapon", StringComparison.OrdinalIgnoreCase) < 0 && ((Object)item).name.IndexOf("sword", StringComparison.OrdinalIgnoreCase) < 0)
			{
				SkinnedMeshRenderer val18 = (SkinnedMeshRenderer)(object)((item is SkinnedMeshRenderer) ? item : null);
				MeshFilter component = ((Component)item).GetComponent<MeshFilter>();
				Mesh val19 = (Object.op_Implicit((Object)(object)val18) ? val18.sharedMesh : (Object.op_Implicit((Object)(object)component) ? component.sharedMesh : null));
				if (Object.op_Implicit((Object)(object)val19) && val19.vertexCount > num)
				{
					val17 = item;
					num = val19.vertexCount;
				}
			}
		}
		if (Object.op_Implicit((Object)(object)val17))
		{
			RendererVisiblity val20 = ((Component)val17).gameObject.AddComponent<RendererVisiblity>();
			val20.parentModel = val16;
			val20.isVisible = true;
			val20.shouldUpdateVisuals = true;
			val16.visibilityChecker = val20;
		}
		val16.gameObjectActivationTransforms = new List<Transform>();
		val16.customGameObjectActivationTransforms = new List<Transform>();
		SkinDef val21 = ScriptableObject.CreateInstance<SkinDef>();
		((Object)val21).name = "skinFeverishTempoDelta";
		val21.nameToken = "DELTA_NAME";
		val21.rootObject = val;
		val21.icon = Sprite.Create(portrait, new Rect(0f, 0f, (float)((Texture)portrait).width, (float)((Texture)portrait).height), new Vector2(0.5f, 0.5f));
		val21.baseSkins = (SkinDef[])(object)new SkinDef[0];
		SkinDefParams val22 = ScriptableObject.CreateInstance<SkinDefParams>();
		((Object)val22).name = "skinFeverishTempoDeltaParams";
		val22.rendererInfos = list.ToArray();
		val22.gameObjectActivations = list3.ToArray();
		val22.meshReplacements = (MeshReplacement[])(object)new MeshReplacement[0];
		val22.projectileGhostReplacements = (ProjectileGhostReplacement[])(object)new ProjectileGhostReplacement[0];
		val22.minionSkinReplacements = (MinionSkinReplacement[])(object)new MinionSkinReplacement[0];
		val22.lightReplacements = (LightInfo[])(object)new LightInfo[0];
		val21.skinDefParams = val22;
		ModelSkinController val23 = val.AddComponent<ModelSkinController>();
		val23.skins = (SkinDef[])(object)new SkinDef[1] { val21 };
		val23.prefabInstantiationDatas = (AsyncPrefabInstantiationData[])(object)new AsyncPrefabInstantiationData[0];
		DeltaRig deltaRig = val.AddComponent<DeltaRig>();
		deltaRig.Configure(array, list2.ToArray());
		return val;
	}

	private static void NormaliseVisual(Transform visual, Transform[] nodes)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0321: Unknown result type (might be due to invalid IL or missing references)
		//IL_033b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0342: Unknown result type (might be due to invalid IL or missing references)
		//IL_0361: Unknown result type (might be due to invalid IL or missing references)
		//IL_036f: Unknown result type (might be due to invalid IL or missing references)
		//IL_037b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0387: Unknown result type (might be due to invalid IL or missing references)
		//IL_0398: Unknown result type (might be due to invalid IL or missing references)
		//IL_039d: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e1: Unknown result type (might be due to invalid IL or missing references)