Decompiled source of Champions of Elatt v1.1.0

plugins/CustomGrip.dll

Decompiled 3 weeks ago
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using TinyHelper;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace CustomGrip;

[BepInPlugin("com.ehaugw.customgrip", "CustomGrip", "1.0.0")]
public class CustomGrip : BaseUnityPlugin
{
	public const string GUID = "com.ehaugw.customgrip";

	public const string VERSION = "1.0.0";

	public const string NAME = "CustomGrip";

	internal void Awake()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		Harmony val = new Harmony("com.ehaugw.customgrip");
		val.PatchAll();
	}

	public static void ChangeGrip(Character character, WeaponType toMoveset)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Expected I4, but got Unknown
		if (character != null)
		{
			Animator animator = character.Animator;
			if (animator != null)
			{
				animator.SetInteger("WeaponType", (int)toMoveset);
			}
		}
	}

	public static void ResetGrip(Character character)
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Expected I4, but got Unknown
		Weapon val = ((character != null) ? character.CurrentWeapon : null);
		if (val != null && character != null)
		{
			Animator animator = character.Animator;
			if (animator != null)
			{
				animator.SetInteger("WeaponType", (int)val.Type);
			}
		}
	}
}
[HarmonyPatch(typeof(Character), "HitEnded")]
public class Character_HitEnded
{
	[HarmonyPrefix]
	public static void Prefix(Character __instance, ref int _attackID)
	{
		if (_attackID != -2 && !__instance.IsCasting)
		{
			CustomGrip.ResetGrip(__instance);
		}
	}
}
[HarmonyPatch(typeof(Character), "StopLocomotionAction")]
public class Character_StopLocomotionAction
{
	[HarmonyPrefix]
	public static void Prefix(Character __instance)
	{
		CustomGrip.ResetGrip(__instance);
	}
}
public class WeaponSkillAnimationSelector : Effect
{
	public WeaponType WeaponType;

	protected override void ActivateLocally(Character character, object[] _infos)
	{
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		CustomGrip.ChangeGrip(character, WeaponType);
	}

	public static void SetCustomAttackAnimation(Skill skill, WeaponType weaponType)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		Transform transform = TinyGameObjectManager.MakeFreshObject("ActivationEffects", true, true, ((Component)skill).transform).transform;
		((Component)transform).gameObject.AddComponent<WeaponSkillAnimationSelector>().WeaponType = weaponType;
	}
}

plugins/Outward_Champions_of_Elatt.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Xml.Serialization;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Champions_of_Elatt.Cleric;
using Champions_of_Elatt.NPCs;
using Champions_of_Elatt.Paladin;
using Champions_of_Elatt.Quests;
using Champions_of_Elatt.Weapons;
using CustomGrip;
using HarmonyLib;
using NodeCanvas.DialogueTrees;
using NodeCanvas.Framework;
using NodeCanvas.Tasks.Actions;
using Photon;
using SideLoader;
using SideLoader.Managers;
using SideLoader.Model;
using TinyHelper;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Animations;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Playables;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Outward_Champions_of_Elatt")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Outward_Champions_of_Elatt")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("c5450fe0-edcf-483f-b9ea-4b1ef9d36da7")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Champions_of_Elatt
{
	public static class CustomSkillIcon
	{
		private struct Entry
		{
			public int Id;

			public Sprite SkillTree;

			public Sprite Item;
		}

		private static readonly List<Entry> s_entries = new List<Entry>();

		private static readonly HashSet<int> s_registered = new HashSet<int>();

		private static readonly Dictionary<int, Entry> s_byId = new Dictionary<int, Entry>();

		private static bool s_hooked;

		public static void ReapplyToInstance(Item item)
		{
			if ((Object)(object)item == (Object)null || !s_byId.TryGetValue(item.ItemID, out var value))
			{
				return;
			}
			if ((Object)(object)value.SkillTree != (Object)null)
			{
				Skill val = (Skill)(object)((item is Skill) ? item : null);
				if (val != null)
				{
					val.SkillTreeIcon = value.SkillTree;
				}
			}
			if ((Object)(object)value.Item != (Object)null)
			{
				At.SetField<Item>(item, "m_itemIcon", (object)value.Item);
			}
		}

		public static void Apply(int skillID, string subfolderName)
		{
			Item itemPrefab = ResourcesPrefabManager.Instance.GetItemPrefab(skillID);
			Skill val = (Skill)(object)((itemPrefab is Skill) ? itemPrefab : null);
			if (val != null)
			{
				Apply(val, subfolderName);
				return;
			}
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogMessage((object)("[SkillIcon] Apply(" + skillID + ", '" + subfolderName + "') ABORTED: " + (((Object)(object)itemPrefab == (Object)null) ? "GetItemPrefab returned NULL (skill not registered yet?)" : ("prefab found but is a " + ((object)itemPrefab).GetType().Name + ", not a Skill"))));
			}
		}

		public static void Apply(Skill skill, string subfolderName)
		{
			if ((Object)(object)skill == (Object)null || string.IsNullOrEmpty(subfolderName))
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogMessage((object)("[SkillIcon] Apply skipped: skill=" + (((Object)(object)skill == (Object)null) ? "NULL" : ((Item)skill).ItemID.ToString()) + " subfolder='" + subfolderName + "'"));
				}
				return;
			}
			if (!s_registered.Add(((Item)skill).ItemID))
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogMessage((object)("[SkillIcon] Skill " + ((Item)skill).ItemID + " already registered - skipping (dedup)."));
				}
				return;
			}
			string text = Path.Combine(Path.GetDirectoryName(typeof(Plugin).Assembly.Location), "SideLoader", "Items", subfolderName, "Textures");
			string path = Path.Combine(text, "skillicon.png");
			string path2 = Path.Combine(text, "icon.png");
			Entry entry = new Entry
			{
				Id = ((Item)skill).ItemID,
				SkillTree = LoadPersistentSprite(path, (SpriteBorderTypes)2),
				Item = LoadPersistentSprite(path2, (SpriteBorderTypes)1)
			};
			ManualLogSource log3 = Plugin.Log;
			if (log3 != null)
			{
				log3.LogMessage((object)("[SkillIcon] Apply skillID=" + ((Item)skill).ItemID + " subfolder='" + subfolderName + "' dir='" + text + "' -> skillTreeSprite=" + (((Object)(object)entry.SkillTree != (Object)null) ? "OK" : "NULL") + " (path exists=" + File.Exists(path) + "), itemSprite=" + (((Object)(object)entry.Item != (Object)null) ? "OK" : "NULL") + " (path exists=" + File.Exists(path2) + ")"));
			}
			s_entries.Add(entry);
			s_byId[entry.Id] = entry;
			Assign(entry);
			if (s_hooked)
			{
				return;
			}
			s_hooked = true;
			SceneManager.sceneLoaded += delegate
			{
				CoopGate.Guard("CustomSkillIcon.sceneLoaded", delegate
				{
					for (int i = 0; i < s_entries.Count; i++)
					{
						Assign(s_entries[i], silent: true);
					}
				});
			};
		}

		private static void Assign(Entry e, bool silent = false)
		{
			Item itemPrefab = ResourcesPrefabManager.Instance.GetItemPrefab(e.Id);
			Skill val = (Skill)(object)((itemPrefab is Skill) ? itemPrefab : null);
			if (val == null)
			{
				if (!silent)
				{
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogMessage((object)("[SkillIcon] Assign(" + e.Id + ") ABORTED: GetItemPrefab did not return a Skill."));
					}
				}
				return;
			}
			if ((Object)(object)e.SkillTree != (Object)null)
			{
				val.SkillTreeIcon = e.SkillTree;
			}
			if ((Object)(object)e.Item != (Object)null)
			{
				At.SetField<Item>((Item)(object)val, "m_itemIcon", (object)e.Item);
			}
			if (!silent)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogMessage((object)("[SkillIcon] Assign(" + e.Id + "): SkillTreeIcon set=" + ((Object)(object)e.SkillTree != (Object)null) + ", ItemIcon set=" + ((Object)(object)e.Item != (Object)null)));
				}
			}
		}

		private static Sprite LoadPersistentSprite(string path, SpriteBorderTypes border)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			if (!File.Exists(path))
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogMessage((object)("[SkillIcon] LoadPersistentSprite: file NOT FOUND at '" + path + "'"));
				}
				return null;
			}
			Texture2D val = CustomTextures.LoadTexture(path, false, false);
			if ((Object)(object)val == (Object)null)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogMessage((object)("[SkillIcon] LoadPersistentSprite: CustomTextures.LoadTexture returned NULL for '" + path + "'"));
				}
				return null;
			}
			Object.DontDestroyOnLoad((Object)(object)val);
			Sprite val2 = CustomTextures.CreateSprite(val, border);
			if ((Object)(object)val2 == (Object)null)
			{
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogMessage((object)("[SkillIcon] LoadPersistentSprite: CustomTextures.CreateSprite returned NULL for '" + path + "'"));
				}
				return null;
			}
			Object.DontDestroyOnLoad((Object)(object)val2);
			return val2;
		}
	}
	[HarmonyPatch(typeof(ResourcesPrefabManager), "GenerateItem", new Type[] { typeof(string) })]
	public static class SkillIconGenerateHook
	{
		private static void Postfix(Item __result)
		{
			CustomSkillIcon.ReapplyToInstance(__result);
		}
	}
	public static class CoopGate
	{
		public static bool BackgroundSceneLoad;

		public static bool IsConfirmedClient()
		{
			try
			{
				return PhotonNetwork.isNonMasterClientInRoom;
			}
			catch
			{
				return false;
			}
		}

		public static bool HasHostAuthority()
		{
			try
			{
				return !PhotonNetwork.isNonMasterClientInRoom;
			}
			catch
			{
				return true;
			}
		}

		public static bool IsLoadComplete()
		{
			NetworkLevelLoader instance = NetworkLevelLoader.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return true;
			}
			try
			{
				return instance.IsOverallLoadingDone && instance.AllPlayerReadyToContinue && !instance.IsGameplayPaused;
			}
			catch
			{
				return false;
			}
		}

		public static IEnumerator WaitForLoadComplete(float timeoutSeconds = 30f)
		{
			float start = Time.realtimeSinceStartup;
			while (!IsLoadComplete() && Time.realtimeSinceStartup - start < timeoutSeconds)
			{
				yield return null;
			}
		}

		public static void Guard(string label, Action action)
		{
			long started = Perf.Start();
			try
			{
				action();
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogError((object)("[CoopGate] '" + label + "' threw during a scene callback and was contained (this would otherwise have cancelled later sceneLoaded subscribers and hung the load): " + ex));
				}
			}
			finally
			{
				Perf.Stop(label, started);
			}
		}
	}
	public static class NpcPoses
	{
		public const SpellCastType Default = (SpellCastType)(-1);

		public const SpellCastType Sitting = (SpellCastType)41;

		public const SpellCastType ArmsCrossed = (SpellCastType)42;

		public const SpellCastType Meditating = (SpellCastType)55;

		public const SpellCastType Sleeping = (SpellCastType)32;

		public const SpellCastType InBed = (SpellCastType)22;

		public const SpellCastType Praying = (SpellCastType)58;

		public const SpellCastType Focusing = (SpellCastType)51;

		public const SpellCastType Bracing = (SpellCastType)48;

		public const SpellCastType Enraged = (SpellCastType)25;
	}
	[BepInPlugin("Elatt.Champions", "Champions of Elat", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency("com.ehaugw.customgrip", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(ResourcesPrefabManager), "Load")]
		public class ResourcesPrefabManager_Load
		{
			private static void Postfix()
			{
			}
		}

		public const string GUID = "Elatt.Champions";

		public const string NAME = "Champions of Elat";

		public const string VERSION = "1.0.0";

		public static readonly string SLPackName = ResolveSLPackName();

		public static string ModFolderName = SLPackName;

		public static readonly string PluginFolderName = Directory.GetParent(typeof(Plugin).Assembly.Location).Name.ToString();

		internal static ManualLogSource Log;

		public static ConfigEntry<bool> ExampleConfig;

		public static ConfigEntry<string> ExaltedBladeVfxFilter;

		public static ConfigEntry<bool> ProfileModWork;

		private static string ResolveSLPackName()
		{
			string result = Directory.GetParent(typeof(Plugin).Assembly.Location).Name.ToString();
			try
			{
				string path = Path.Combine(Path.GetDirectoryName(typeof(Plugin).Assembly.Location), Path.Combine("SideLoader", "manifest.txt"));
				if (File.Exists(path))
				{
					string text = File.ReadAllText(path).Trim();
					if (!string.IsNullOrEmpty(text))
					{
						return text;
					}
				}
			}
			catch
			{
			}
			return result;
		}

		internal void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogMessage((object)"Hello world from Champions of Elat 1.0.0!");
			Log.LogMessage((object)("[SLPack] folder='" + PluginFolderName + "' -> pack name '" + SLPackName + "'" + ((SLPackName == PluginFolderName) ? " (no SideLoader\\manifest.txt - falling back to the folder name)" : " (pinned by SideLoader\\manifest.txt)")));
			SL.OnPacksLoaded += OnPackLoaded;
			ExampleConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("ExampleCategory", "ExampleSetting", false, "This is an example setting.");
			ExaltedBladeVfxFilter = ((BaseUnityPlugin)this).Config.Bind<string>("ExaltedBlade", "VfxChildFilter", "FireParticlesEmber", "Substring (case-insensitive) of the Meteoric Sword particle system(s) to keep on The Exalted Blade. 'FireParticlesEmber' = just the floating orbs (default). Empty = all parts (orbs + the on-blade light bursts, 'FireParticlesLargeCore'). Any non-matching particle system is silenced.");
			ProfileModWork = ((BaseUnityPlugin)this).Config.Bind<bool>("Performance", "ProfileModWork", false, "Log a breakdown every 20 seconds of how much frame time this mod's periodic work is using, per subsystem. For diagnosing stutter - read the 'worst' column, not the average. Off for normal play.");
			ProfileModWork.SettingChanged += delegate
			{
				Perf.Enabled = ProfileModWork.Value;
			};
			Perf.Enabled = ProfileModWork.Value;
			Step("Harmony patches", delegate
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				new Harmony("Elatt.Champions").PatchAll();
			});
			Step("VFXTester", delegate
			{
				((Component)this).gameObject.AddComponent<VFXTester>();
			});
			Step("TrainerDebug", delegate
			{
				((Component)this).gameObject.AddComponent<TrainerDebug>();
			});
			Step("WatcherEyesTalisman", delegate
			{
				((Component)this).gameObject.AddComponent<WatcherEyesTalisman>();
			});
			Step("QuestDirector", delegate
			{
				QuestDirector.Ensure(((Component)this).gameObject);
			});
			Step("QuestDevSettings", delegate
			{
				QuestDevSettings.Init(((BaseUnityPlugin)this).Config);
			});
			Step("NpcSpawner", delegate
			{
				((Component)this).gameObject.AddComponent<NpcSpawner>();
			});
			Step("EnemyTemplateHarvester", delegate
			{
				((Component)this).gameObject.AddComponent<EnemyTemplateHarvester>();
			});
			Step("AmbushPrefetch", delegate
			{
				((Component)this).gameObject.AddComponent<AmbushPrefetch>();
			});
			Step("LurkerWatcher", delegate
			{
				((Component)this).gameObject.AddComponent<LurkerWatcher>();
			});
			Step("AmbushJoinRelay", delegate
			{
				((Component)this).gameObject.AddComponent<AmbushJoinRelay>();
			});
			Step("ConfluxConfrontationWatcher", delegate
			{
				((Component)this).gameObject.AddComponent<ConfluxConfrontationWatcher>();
			});
			Step("ConfluxBattleWatcher", delegate
			{
				((Component)this).gameObject.AddComponent<ConfluxBattleWatcher>();
			});
			Step("ConfluxAftermathWatcher", delegate
			{
				((Component)this).gameObject.AddComponent<ConfluxAftermathWatcher>();
			});
			Step("ConfluxStasisTicker", delegate
			{
				((Component)this).gameObject.AddComponent<ConfluxStasisTicker>();
			});
			Step("SacrificeSceneWatcher", delegate
			{
				((Component)this).gameObject.AddComponent<SacrificeSceneWatcher>();
			});
			Step("NpcHealthBarSuppressor", delegate
			{
				((Component)this).gameObject.AddComponent<NpcHealthBarSuppressor>();
			});
			Step("RelicRestorationWatcher", delegate
			{
				((Component)this).gameObject.AddComponent<RelicRestorationWatcher>();
			});
			Step("QuestJournalReconciler", delegate
			{
				((Component)this).gameObject.AddComponent<QuestJournalReconciler>();
			});
			Step("RelicHeraldPreloader", delegate
			{
				((Component)this).gameObject.AddComponent<RelicHeraldPreloader>();
			});
			Step("NpcEquipmentPreloader", delegate
			{
				((Component)this).gameObject.AddComponent<NpcEquipmentPreloader>();
			});
			Step("SkillVFXPreloader", delegate
			{
				((Component)this).gameObject.AddComponent<SkillVFXPreloader>();
			});
			Step("NpcBuildQueue", delegate
			{
				((Component)this).gameObject.AddComponent<NpcBuildQueue>();
			});
			Step("NpcCoopJoinGuard", delegate
			{
				((Component)this).gameObject.AddComponent<NpcCoopJoinGuard>();
			});
			Step("LastBoonWatch", delegate
			{
				((Component)this).gameObject.AddComponent<LastBoonWatch>();
			});
			Step("ShieldTicker", delegate
			{
				((Component)this).gameObject.AddComponent<ShieldTicker>();
			});
			Step("AmbientVFX", delegate
			{
				((Component)this).gameObject.AddComponent<AmbientVFX>();
			});
			Step("ManaPassiveRegen", delegate
			{
				((Component)this).gameObject.AddComponent<ManaPassiveRegen>();
			});
			Step("SpiritualWeaponPreloader", delegate
			{
				((Component)this).gameObject.AddComponent<SpiritualWeaponPreloader>();
			});
			Step("WeaponChargeDriver", delegate
			{
				((Component)this).gameObject.AddComponent<WeaponChargeDriver>();
			});
			Step("GraftedVisuals", delegate
			{
				((Component)this).gameObject.AddComponent<GraftedVisuals>();
			});
			Step("RigidVisualScaler", delegate
			{
				((Component)this).gameObject.AddComponent<RigidVisualScaler>();
			});
			Step("ItemMaterialGuard", delegate
			{
				((Component)this).gameObject.AddComponent<ItemMaterialGuard>();
			});
			Step("GraftLiveEditor", delegate
			{
				((Component)this).gameObject.AddComponent<GraftLiveEditor>();
			});
			Step("TextureHotReload", delegate
			{
				((Component)this).gameObject.AddComponent<TextureHotReload>();
			});
			Step("SharedGuidanceDriver", delegate
			{
				((Component)this).gameObject.AddComponent<SharedGuidanceDriver>();
			});
			Step("GuideOfWindsAuraWatcher", delegate
			{
				((Component)this).gameObject.AddComponent<GuideOfWindsAuraWatcher>();
			});
		}

		private void Step(string label, Action action)
		{
			try
			{
				action();
			}
			catch (Exception ex)
			{
				Log.LogError((object)("[Startup] '" + label + "' failed to initialise - the rest of the mod is still loading without it. " + ex));
			}
		}

		private void OnPackLoaded()
		{
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0340: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0390: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0412: Unknown result type (might be due to invalid IL or missing references)
			//IL_042b: Unknown result type (might be due to invalid IL or missing references)
			//IL_044f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0454: Unknown result type (might be due to invalid IL or missing references)
			//IL_0481: Unknown result type (might be due to invalid IL or missing references)
			//IL_0486: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0526: Unknown result type (might be due to invalid IL or missing references)
			//IL_052b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0567: Unknown result type (might be due to invalid IL or missing references)
			//IL_056c: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0606: Unknown result type (might be due to invalid IL or missing references)
			//IL_060c: Unknown result type (might be due to invalid IL or missing references)
			//IL_062d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0633: Unknown result type (might be due to invalid IL or missing references)
			//IL_0636: Unknown result type (might be due to invalid IL or missing references)
			//IL_063c: Unknown result type (might be due to invalid IL or missing references)
			//IL_065d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0663: Unknown result type (might be due to invalid IL or missing references)
			//IL_0666: Unknown result type (might be due to invalid IL or missing references)
			//IL_066c: Unknown result type (might be due to invalid IL or missing references)
			//IL_068d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0693: Unknown result type (might be due to invalid IL or missing references)
			//IL_0696: Unknown result type (might be due to invalid IL or missing references)
			//IL_069c: Unknown result type (might be due to invalid IL or missing references)
			//IL_06bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_06cc: Unknown result type (might be due to invalid IL or missing references)
			CoopVFX.Setup();
			ProtectionFromEvilAndGoodPassive.Init();
			WrathfulSmitePassive.Init();
			SearingSmitePassive.Init();
			SanctifiedHandsPassive.Init();
			AuraOfProtectionPassive.Init();
			DivineSmiteSkill.Init();
			VowOfEmnitySkill.Init();
			SacredWeaponSkill.Init();
			DivineSenseSkill.Init();
			LayOnHandsSkill.Init();
			RitesOfAscensionSkill.Init();
			AscendantsMarkPassive.Init();
			VFXTesterSkills.Init();
			ManaPassiveEffects.Init();
			BlessedConduitPassive.Init();
			AuraOfVitalityPassive.Init();
			DivineMomentumPassive.Init();
			ShieldOfFaithSkill.Init();
			ShieldVariants.MakeAll();
			PreserveLifeSkill.Init();
			RevitalizeSkill.Init();
			SharedGuidanceStatusEffect.MakeBuff();
			BlessedSkill.Init();
			SpiritualWeaponSkills.Init();
			SpiritualWeaponSkill.Init();
			SpiritualWeaponManager.Init();
			SpiritGuardiansSkill.Init();
			SanctuarySkill.Init();
			PaladinTrainer.Init();
			ClericTrainer.Init();
			LeftPriestNpc.Init();
			RightPriestNpc.Init();
			RelicHunterQuest.Init();
			WorldItemSpawner.Init();
			LurkerEncounters.Init();
			ConfluxAftermath.Init();
			RelicRestoration.Init();
			RelicHeralds.Init();
			RitualDirector.Hook();
			ConfluxConfrontation.Init();
			ConfluxBattle.Init();
			RitualPerformer.Init();
			ConfluxStasisStatusEffect.Make();
			RelicRestorationReactions.Hook();
			MerchantNpc.Init();
			CandleKnightNpc.Init();
			WanderingPaladinNpc.Init();
			WanderingClericNpc.Init();
			ItemVisualCleanup.RemoveParticles(-1961);
			ItemVisualCleanup.CopyParticles(2000265, -1961, ExaltedBladeVfxFilter.Value);
			ItemVisualCleanup.RemoveParticles(-1965);
			ItemVisualCleanup.CopyParticles(2120125, -1960, "FireParticlesEmber", ItemVisualCleanup.WhiteBlue);
			ItemVisualCleanup.CopyParticles(2020115, -1951, "FireParticlesEmber");
			ItemVisualCleanup.CopyParticles(2130265, -1946, "FireParticlesEmber", ItemVisualCleanup.WhiteBlue);
			ItemVisualCleanup.CopyParticles(2150095, -1947, "FireParticlesEmber", ItemVisualCleanup.WhiteBlue);
			ItemVisualCleanup.StripPhysics(-1950);
			SpectralGlowRecolour.ApplyAll();
			RecipeLinkFix.VerifyAndLink(-1952, "elatt.recipe.exaltedblade");
			RecipeLinkFix.VerifyAndLink(-1945, "elatt.recipe.devoteesmace");
			RecipeLinkFix.VerifyAndLink(-1944, "elatt.recipe.lightreaverhalberd");
			RecipeLinkFix.VerifyAndLink(-1943, "elatt.recipe.elattslightlance");
			RecipeLinkFix.VerifyAndLink(-1942, "elatt.recipe.mightygavel");
			RecipeLinkFix.VerifyAndLink(-1806, "elatt.recipe.resplendenthelm");
			RecipeLinkFix.VerifyAndLink(-1807, "elatt.recipe.resplendentarmor");
			RecipeLinkFix.VerifyAndLink(-1808, "elatt.recipe.resplendentboots");
			RecipeLinkFix.VerifyAndLink(-1809, "elatt.recipe.resplendentshield");
			RecipeLinkFix.VerifyAndLink(-1810, "elatt.recipe.resplendentsword");
			WeaponCharges.Init();
			GraftedVisuals.Register(-1908, -1957, "Oathbound Hood and Bevor", (EquipmentSlotIDs)0, "-1957_Oathbound Hood", new Vector3(0f, 0.02f, 0f), new Vector3(-5f, 0f, 0f));
			GraftedVisuals.Register(-1920, -1919, "Resplendent Bevor", (EquipmentSlotIDs)0, "-1919_Resplendent Hood", new Vector3(0f, 0.02f, 0f), new Vector3(-5f, 0f, 0f));
			GraftedVisuals.Register(-1925, -1926, "Blue Sand Bevor", (EquipmentSlotIDs)0, "-1926_Blue Sand Hood", new Vector3(0f, 0.02f, 0f), new Vector3(-5f, 0f, 0f));
			GraftedVisuals.Register(-1917, -1948, "Resplendent Helm", (EquipmentSlotIDs)0, "-1948_Resplendent Helm 2", Vector3.zero, Vector3.zero, 1.05f);
			GraftedVisuals.Register(-1917, -1920, "Resplendent Helm", (EquipmentSlotIDs)0, "-1920_Resplendent Bevor", new Vector3(0.015f, 0.03f, 0.024f), new Vector3(-10.1f, 0f, 0f), 1.18f, (Vector3?)new Vector3(0.08f, 1.63f, 0.02f));
			GraftedVisuals.Register(-1917, -1805, "Resplendent Helm", (EquipmentSlotIDs)0, "-1805_Resplendent Bevor 2", Vector3.zero, Vector3.zero);
			GraftedVisuals.Register(-1916, -1800, "Resplendent Blue Sand Armor", (EquipmentSlotIDs)1, "-1800_Resplendent Armor 2", Vector3.zero, Vector3.zero);
			GraftedVisuals.Register(-1803, -1800, "Resplendent Armor (Cape)", (EquipmentSlotIDs)1, "-1800_Resplendent Armor 2", Vector3.zero, Vector3.zero);
			GraftedVisuals.Register(-1803, -1804, "Resplendent Armor (Cape)", (EquipmentSlotIDs)1, "-1804_Resplendent Cape", Vector3.zero, Vector3.zero);
			GraftedVisuals.Register(-1921, -1802, "Resplendent Shield", (EquipmentSlotIDs)6, "-1802_Resplendent Shield 2", new Vector3(0f, 0.05f, 0.042f), Vector3.zero, 0.75f);
			GraftedVisuals.Register(-1923, -1927, "Blue Sand Shield", (EquipmentSlotIDs)6, "-1927_Blue Sand Shield 2", new Vector3(0f, 0.05f, 0.042f), Vector3.zero, 0.75f);
			GraftedVisuals.BuildTemplates();
			GraftLiveEditor.Watch(-1917, -1920);
			ItemMaterialGuard.Register(-1800, (EquipmentSlotIDs)1, "Resplendent Armor 2");
			TextureHotReload.Register(-1916, "-1916_Resplendent Blue Sand Armor", "mat_cha_blueSandArmor", (KeyCode)47, "Resplendent Blue Sand Armor");
			TextureHotReload.Register(-1800, "-1800_Resplendent Armor 2", "mat_cha_virginarmor", (KeyCode)289, "Resplendent Armor 2");
			ItemMaterialGuard.DumpFullShaderProperties(-1916, -1800);
			ItemVisualTransform.Apply(-1917, "Resplendent Helm", 0.95f, Vector3.zero, default(Vector3), (EquipmentSlotIDs)0);
			ItemVisualTransform.Apply(-1921, "Resplendent Shield", 0.85f, default(Vector3), default(Vector3), (EquipmentSlotIDs)6);
			ItemVisualTransform.Apply(-1922, "Resplendent Sword", 1.075f, default(Vector3), default(Vector3), (EquipmentSlotIDs)5);
			ItemVisualTransform.Apply(-1923, "Blue Sand Shield", 0.85f, default(Vector3), default(Vector3), (EquipmentSlotIDs)6);
			ItemVisualTransform.Apply(-1924, "Blue Sand Sword", 1.075f, default(Vector3), default(Vector3), (EquipmentSlotIDs)5);
			GhostMaterial.ApplyTo(-1900, -1901, -1902, -1903, -1904, -1905, -1906, -1907);
			ItemVisualReapply.ForceApplyAssetBundleVisual(-1953, SLPackName, "thermalspear", "ThermalSpear");
			ApplyAllSkillIcons();
			ImmaculateWards.Init();
			LanternSkillCompatibility.Init();
			Step("EnchantmentCompatibility", delegate
			{
				((Component)this).gameObject.AddComponent<EnchantmentCompatibilityWatcher>();
			});
		}

		private static void ApplyAllSkillIcons()
		{
			CustomSkillIcon.Apply(-1991, "-1991_Protection From Evil and Good");
			CustomSkillIcon.Apply(-1998, "-1998_Wrathful Smite");
			CustomSkillIcon.Apply(-1997, "-1997_Searing Smite");
			CustomSkillIcon.Apply(-1993, "-1993_Aura of Protection");
			CustomSkillIcon.Apply(-1999, "-1999_Divine Smite");
			CustomSkillIcon.Apply(-1996, "-1996_Vow of Emnity");
			CustomSkillIcon.Apply(-1995, "-1995_Sacred Weapon");
			CustomSkillIcon.Apply(-1994, "-1994_Divine Sense");
			CustomSkillIcon.Apply(-1992, "-1992_Lay on Hands");
			CustomSkillIcon.Apply(-1913, "-1913_Sanctified Hands");
			CustomSkillIcon.Apply(-1910, "-1910_Rites of Ascension");
			CustomSkillIcon.Apply(-1911, "-1911_Ascendants Mark");
			CustomSkillIcon.Apply(-1990, "-1990_Shield of Faith");
			CustomSkillIcon.Apply(-1989, "-1989_Preserve Life");
			CustomSkillIcon.Apply(-1988, "-1988_Revitalize");
			CustomSkillIcon.Apply(-1987, "-1987_Bless");
			CustomSkillIcon.Apply(-1986, "-1986_Spiritual Weapon");
			CustomSkillIcon.Apply(-1985, "-1985_Spirit Guardians");
			CustomSkillIcon.Apply(-1984, "-1984_Blessed Conduit");
			CustomSkillIcon.Apply(-1983, "-1983_Aura of Vitality");
			CustomSkillIcon.Apply(-1982, "-1982_Divine Momentum");
			CustomSkillIcon.Apply(-1981, "-1981_Sanctuary");
		}

		internal void Update()
		{
			Perf.Tick();
		}
	}
	public static class BaseGameSkills
	{
		private static readonly Dictionary<string, int> _cache = new Dictionary<string, int>();

		public static int IdOf(string displayName)
		{
			if (string.IsNullOrEmpty(displayName))
			{
				return 0;
			}
			if (_cache.TryGetValue(displayName, out var value))
			{
				return value;
			}
			int num = 0;
			Skill[] array = Resources.FindObjectsOfTypeAll<Skill>();
			foreach (Skill val in array)
			{
				if (!((Object)(object)val == (Object)null) && string.Equals(((Item)val).Name, displayName, StringComparison.OrdinalIgnoreCase))
				{
					num = ((Item)val).ItemID;
					break;
				}
			}
			_cache[displayName] = num;
			if (num != 0)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogMessage((object)("[Skills] '" + displayName + "' resolved to ID " + num + "."));
				}
			}
			else
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogMessage((object)("[Skills] '" + displayName + "' NOT FOUND - nobody will be taught it. (Is the DLC that adds it installed?)"));
				}
			}
			return num;
		}

		public static List<int> Build(IEnumerable<int> ids, IEnumerable<string> names)
		{
			List<int> list = new List<int>();
			if (ids != null)
			{
				foreach (int id in ids)
				{
					if (id != 0 && !list.Contains(id))
					{
						list.Add(id);
					}
				}
			}
			if (names != null)
			{
				foreach (string name in names)
				{
					int num = IdOf(name);
					if (num != 0 && !list.Contains(num))
					{
						list.Add(num);
					}
				}
			}
			return list;
		}
	}
	public static class CharacterFXLibrary
	{
		public class Alias
		{
			public string Name;

			public string BodyKey;

			public string Child;

			public Alias(string name, string bodyKey, string child)
			{
				Name = name;
				BodyKey = bodyKey;
				Child = child;
			}
		}

		public const string ImmaculateWard = "ElattImmaculateWard";

		public static readonly Alias[] Aliases = new Alias[1]
		{
			new Alias("ElattImmaculateWard", "EliteImmaculate", "BlockFX")
		};

		private static readonly Dictionary<string, GameObject> _found = new Dictionary<string, GameObject>(StringComparer.OrdinalIgnoreCase);

		private static readonly HashSet<string> _complained = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		public static GameObject Resolve(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return null;
			}
			if (_found.TryGetValue(name, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			Alias alias = null;
			for (int i = 0; i < Aliases.Length; i++)
			{
				if (string.Equals(Aliases[i].Name, name, StringComparison.OrdinalIgnoreCase))
				{
					alias = Aliases[i];
					break;
				}
			}
			if (alias == null)
			{
				return null;
			}
			GameObject val = Find(alias.BodyKey, alias.Child);
			if ((Object)(object)val == (Object)null)
			{
				if (_complained.Add(name))
				{
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogMessage((object)("[CharFX] '" + name + "' could not be resolved - '" + alias.BodyKey + "' is not harvested yet, or its FX set has no '" + alias.Child + "'. Anything asking for it plays nothing until the prefetch has run."));
					}
				}
				return null;
			}
			_found[name] = val;
			ManualLogSource log2 = Plugin.Log;
			if (log2 != null)
			{
				log2.LogMessage((object)("[CharFX] '" + name + "' resolved to " + alias.BodyKey + "'s '" + alias.Child + "' - cached for the session."));
			}
			return val;
		}

		public static GameObject Find(string bodyKey, string child)
		{
			if (string.IsNullOrEmpty(bodyKey) || string.IsNullOrEmpty(child))
			{
				return null;
			}
			try
			{
				GameObject val = EnemyTemplates.Get(bodyKey);
				if ((Object)(object)val == (Object)null)
				{
					return null;
				}
				Character component = val.GetComponent<Character>();
				if ((Object)(object)component == (Object)null || (Object)(object)component.CharacterFXs == (Object)null)
				{
					return null;
				}
				Transform val2 = component.CharacterFXs.Find(child);
				return ((Object)(object)val2 != (Object)null) ? ((Component)val2).gameObject : null;
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogMessage((object)("[CharFX] Could not read " + bodyKey + "'s FX set: " + ex.Message));
				}
				return null;
			}
		}
	}
	public class CharacterVisibility : MonoBehaviour
	{
		private const float NeverHiddenLongerThan = 6f;

		private readonly List<Renderer> _hidden = new List<Renderer>();

		private float _revealAt = -1f;

		private bool _sweeping;

		public static void Set(Character character, bool visible, bool keepSweeping = false)
		{
			if ((Object)(object)character == (Object)null)
			{
				return;
			}
			CharacterVisibility characterVisibility = ((Component)character).gameObject.GetComponent<CharacterVisibility>();
			if ((Object)(object)characterVisibility == (Object)null)
			{
				if (visible)
				{
					return;
				}
				characterVisibility = ((Component)character).gameObject.AddComponent<CharacterVisibility>();
			}
			if (visible)
			{
				characterVisibility.Show();
			}
			else
			{
				characterVisibility.Hide(keepSweeping);
			}
		}

		private void Hide(bool keepSweeping = false)
		{
			_revealAt = Time.time + 6f;
			_sweeping = keepSweeping;
			Sweep();
		}

		private void Sweep()
		{
			try
			{
				Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val in componentsInChildren)
				{
					if (!((Object)(object)val == (Object)null) && val.enabled)
					{
						val.enabled = false;
						_hidden.Add(val);
					}
				}
			}
			catch
			{
				Show();
			}
		}

		private void Show()
		{
			_revealAt = -1f;
			_sweeping = false;
			for (int i = 0; i < _hidden.Count; i++)
			{
				if (!((Object)(object)_hidden[i] == (Object)null))
				{
					try
					{
						_hidden[i].enabled = true;
					}
					catch
					{
					}
				}
			}
			_hidden.Clear();
		}

		private void Update()
		{
			if (_revealAt < 0f)
			{
				return;
			}
			if (_sweeping)
			{
				Sweep();
			}
			if (!(Time.time < _revealAt))
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogMessage((object)("[Visibility] '" + ((Object)this).name + "' was still hidden after " + 6f + "s - showing it anyway."));
				}
				Show();
			}
		}

		private void OnDisable()
		{
			Show();
		}
	}
	public static class CombatTargeting
	{
		public static bool IsValidHostileTarget(Character attacker, Character target)
		{
			if ((Object)(object)attacker == (Object)null || (Object)(object)target == (Object)null)
			{
				return false;
			}
			if ((Object)(object)target == (Object)(object)attacker)
			{
				return false;
			}
			if (!target.Alive)
			{
				return false;
			}
			if (SpiritualWeaponManager.IsSummon(target))
			{
				return false;
			}
			if (NpcSpawnManager.IsModNpc(target))
			{
				return false;
			}
			if (target.IsAlly(attacker))
			{
				return false;
			}
			TargetingSystem targetingSystem = attacker.TargetingSystem;
			if ((Object)(object)targetingSystem == (Object)null)
			{
				return true;
			}
			return targetingSystem.IsTargetable(target);
		}
	}
	public class CompanionDamageKeeper : MonoBehaviour
	{
		private const float CheckSeconds = 1f;

		public Character Owner;

		public string Label = "?";

		private float _nextCheck;

		private int _repairs;

		private int _lastStatsId;

		private void Update()
		{
			if ((Object)(object)Owner == (Object)null)
			{
				Owner = ((Component)this).GetComponent<Character>();
			}
			if (!((Object)(object)Owner == (Object)null) && !(Time.time < _nextCheck))
			{
				_nextCheck = Time.time + 1f;
				CoopGate.Guard("CompanionDamageKeeper", Check);
			}
		}

		private void Check()
		{
			CharacterStats stats = Owner.Stats;
			if ((Object)(object)stats == (Object)null)
			{
				return;
			}
			int instanceID = ((Object)stats).GetInstanceID();
			if (!FollowerStats.DamageOutputIsBroken(stats))
			{
				_lastStatsId = instanceID;
				return;
			}
			bool flag = _lastStatsId != 0 && _lastStatsId != instanceID;
			string text = FollowerStats.ForceDamageOutput(stats, Label);
			if (FollowerStats.DamageOutputIsBroken(stats))
			{
				if (_repairs == 0)
				{
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogError((object)("[Stats] " + Label + " damage multipliers are zero and COULD NOT be repaired (" + (text ?? "no route worked") + ") - it will hit for nothing and this is now the thing to chase."));
					}
				}
				_repairs++;
				_lastStatsId = instanceID;
				return;
			}
			_repairs++;
			if (_repairs == 1)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)("[Stats] '" + Label + "' had its damage multipliers back at ZERO after spawn - repaired by " + (text ?? "?") + ". CharacterStats instance " + instanceID + (flag ? (" is NOT the one normalised at spawn (" + _lastStatsId + ") - the component was REPLACED, so the spawn-time fix was applied to a corpse.") : " is the same one normalised at spawn - so nothing replaced it and something recomputed the values in place.") + " Without this repair every hit it lands is multiplied by zero."));
				}
			}
			else if (_repairs % 20 == 0)
			{
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogWarning((object)("[Stats] '" + Label + "' has needed its damage multipliers repaired " + _repairs + " times - something is actively resetting them, and the keeper is the only thing making it able to fight at all."));
				}
			}
			_lastStatsId = instanceID;
		}

		public static void Attach(Character character, string label)
		{
			if ((Object)(object)character == (Object)null)
			{
				return;
			}
			try
			{
				CompanionDamageKeeper companionDamageKeeper = ((Component)character).gameObject.GetComponent<CompanionDamageKeeper>();
				if ((Object)(object)companionDamageKeeper == (Object)null)
				{
					companionDamageKeeper = ((Component)character).gameObject.AddComponent<CompanionDamageKeeper>();
				}
				companionDamageKeeper.Owner = character;
				companionDamageKeeper.Label = label;
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("[Stats] Could not attach the damage keeper to '" + label + "': " + ex.Message));
				}
			}
		}
	}
	public class CoopVFX : MonoBehaviour
	{
		public const int ViewID = 896;

		private static CoopVFX _instance;

		private const float AttachTimeoutSeconds = 15f;

		private static bool CanSend
		{
			get
			{
				if ((Object)(object)_instance == (Object)null)
				{
					return false;
				}
				if (PhotonNetwork.room == null)
				{
					return false;
				}
				if (PhotonNetwork.playerList != null)
				{
					return PhotonNetwork.playerList.Length > 1;
				}
				return false;
			}
		}

		public static void Setup()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			if (!((Object)(object)_instance != (Object)null))
			{
				GameObject val = new GameObject("ChampionsOfElatt_CoopVFX");
				Object.DontDestroyOnLoad((Object)val);
				val.AddComponent<CoopVFX>();
			}
		}

		private void Awake()
		{
			_instance = this;
			PhotonView val = PhotonView.Find(896);
			if ((Object)(object)val != (Object)null)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogMessage((object)("[CoopVFX] WARNING: Photon view ID " + 896 + " is already taken by '" + ((Object)val).name + "' - co-op VFX may not arrive."));
				}
			}
			PhotonView val2 = ((Component)this).gameObject.GetComponent<PhotonView>();
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = ((Component)this).gameObject.AddComponent<PhotonView>();
			}
			val2.viewID = 896;
			ManualLogSource log2 = Plugin.Log;
			if (log2 != null)
			{
				log2.LogMessage((object)("[CoopVFX] Shared co-op VFX relay registered with view ID " + 896 + "."));
			}
		}

		private static float Red(Color? tint)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			if (!tint.HasValue)
			{
				return 0f;
			}
			return tint.Value.r;
		}

		private static float Green(Color? tint)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			if (!tint.HasValue)
			{
				return 0f;
			}
			return tint.Value.g;
		}

		private static float Blue(Color? tint)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			if (!tint.HasValue)
			{
				return 0f;
			}
			return tint.Value.b;
		}

		private static float Alpha(Color? tint)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			if (!tint.HasValue)
			{
				return 0f;
			}
			return tint.Value.a;
		}

		private static Color? Rebuild(bool hasTint, float r, float g, float b, float a)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (!hasTint)
			{
				return null;
			}
			return new Color(r, g, b, a);
		}

		private static void Send(string method, PhotonTargets targets, params object[] args)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (!CanSend)
			{
				return;
			}
			try
			{
				((MonoBehaviour)_instance).photonView.RPC(method, targets, args);
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogError((object)("[CoopVFX] " + method + " could not be sent and was contained (this would otherwise have thrown into the caller and abandoned whatever it was doing): " + ex));
				}
			}
		}

		public static void DeflectedProjectile(string prefabName, Vector3 start, Vector3 direction, float force, string targetUID, string blockerUID)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (!string.IsNullOrEmpty(prefabName))
			{
				Send("RPC_DeflectedProjectile", (PhotonTargets)1, prefabName, start, direction, force, targetUID ?? "", blockerUID ?? "");
			}
		}

		[PunRPC]
		private void RPC_DeflectedProjectile(string prefabName, Vector3 start, Vector3 direction, float force, string targetUID, string blockerUID)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Projectile val = SpellguardDeflect.FindProjectilePrefab(prefabName);
				if ((Object)(object)val == (Object)null)
				{
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogMessage((object)("[CoopVFX] '" + prefabName + "' is not a projectile this client can find - the deflection will be invisible here."));
					}
				}
				else
				{
					SpellguardDeflect.FireVisualOnly(val, start, direction, force, targetUID, Resolve(blockerUID));
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)("[CoopVFX] A deflected projectile could not be drawn here: " + ex));
				}
			}
		}

		public static void ImbueMany(IList<string> targetUIDs, int presetID, float lifespan)
		{
			if (targetUIDs != null && targetUIDs.Count != 0 && presetID != 0)
			{
				string[] array = new string[targetUIDs.Count];
				targetUIDs.CopyTo(array, 0);
				string[] array2 = array;
				for (int i = 0; i < array2.Length; i++)
				{
					SacredWeaponInfusion.ApplyTo(Resolve(array2[i]), presetID, lifespan);
				}
				Send("RPC_ImbueMany", (PhotonTargets)1, array, presetID, lifespan);
			}
		}

		[PunRPC]
		private void RPC_ImbueMany(string[] targetUIDs, int presetID, float lifespan)
		{
			if (targetUIDs == null)
			{
				return;
			}
			int num = 0;
			for (int i = 0; i < targetUIDs.Length; i++)
			{
				Character val = Resolve(targetUIDs[i]);
				if (!((Object)(object)val == (Object)null))
				{
					num++;
					SacredWeaponInfusion.ApplyTo(val, presetID, lifespan);
				}
			}
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogMessage((object)("[CoopVFX] received ImbueMany preset " + presetID + " for " + targetUIDs.Length + " uid(s), " + num + " resolved here."));
			}
		}

		public static void ImbueShieldMany(IList<string> targetUIDs, int presetID, float lifespan)
		{
			if (targetUIDs != null && targetUIDs.Count != 0 && presetID != 0)
			{
				string[] array = new string[targetUIDs.Count];
				targetUIDs.CopyTo(array, 0);
				string[] array2 = array;
				for (int i = 0; i < array2.Length; i++)
				{
					SacredWeaponAbsorb.ApplyToShield(Resolve(array2[i]), presetID, lifespan);
				}
				Send("RPC_ImbueShieldMany", (PhotonTargets)1, array, presetID, lifespan);
			}
		}

		[PunRPC]
		private void RPC_ImbueShieldMany(string[] targetUIDs, int presetID, float lifespan)
		{
			if (targetUIDs == null)
			{
				return;
			}
			int num = 0;
			for (int i = 0; i < targetUIDs.Length; i++)
			{
				Character val = Resolve(targetUIDs[i]);
				if (!((Object)(object)val == (Object)null))
				{
					num++;
					SacredWeaponAbsorb.ApplyToShield(val, presetID, lifespan);
				}
			}
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogMessage((object)("[CoopVFX] received ImbueShieldMany preset " + presetID + " for " + targetUIDs.Length + " uid(s), " + num + " resolved here."));
			}
		}

		public static void PlayBundleAudioOn(string bundleName, Character target, float volumeScale = 1f, string prefabName = null)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			EffectSourceTrace.Note("Bundle", bundleName, target);
			if (!((Object)(object)target == (Object)null) && !string.IsNullOrEmpty(bundleName))
			{
				ClericAudio.Play(bundleName, target, volumeScale, prefabName);
				Send("RPC_BundleAudio", (PhotonTargets)1, bundleName, ((object)target.UID/*cast due to .constrained prefix*/).ToString(), volumeScale, prefabName ?? "");
			}
		}

		[PunRPC]
		private void RPC_BundleAudio(string bundleName, string targetUID, float volumeScale, string prefabName)
		{
			Character val = Resolve(targetUID);
			if (!((Object)(object)val == (Object)null))
			{
				ClericAudio.Play(bundleName, val, volumeScale, string.IsNullOrEmpty(prefabName) ? null : prefabName);
			}
		}

		public static void PlayBundleAudioAt(string bundleName, Vector3 worldPos, float volumeScale = 1f, string prefabName = null)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			if (!string.IsNullOrEmpty(bundleName))
			{
				EffectSourceTrace.Note("Bundle", bundleName, worldPos);
				ClericAudio.PlayAt(bundleName, worldPos, volumeScale, prefabName);
				Send("RPC_BundleAudioAt", (PhotonTargets)1, bundleName, worldPos.x, worldPos.y, worldPos.z, volumeScale, prefabName ?? "");
			}
		}

		[PunRPC]
		private void RPC_BundleAudioAt(string bundleName, float x, float y, float z, float volumeScale, string prefabName)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			ClericAudio.PlayAt(bundleName, new Vector3(x, y, z), volumeScale, string.IsNullOrEmpty(prefabName) ? null : prefabName);
		}

		public static void CleanseStatusFromMany(IList<string> targetUIDs, string statusIdentifier)
		{
			if (targetUIDs != null && targetUIDs.Count != 0 && !string.IsNullOrEmpty(statusIdentifier))
			{
				string[] array = new string[targetUIDs.Count];
				targetUIDs.CopyTo(array, 0);
				ApplyCleanse(array, statusIdentifier);
				Send("RPC_CleanseStatusFromMany", (PhotonTargets)1, array, statusIdentifier);
			}
		}

		[PunRPC]
		private void RPC_CleanseStatusFromMany(string[] targetUIDs, string statusIdentifier)
		{
			ApplyCleanse(targetUIDs, statusIdentifier);
		}

		private static void ApplyCleanse(string[] targetUIDs, string statusIdentifier)
		{
			if (targetUIDs == null)
			{
				return;
			}
			for (int i = 0; i < targetUIDs.Length; i++)
			{
				Character val = Resolve(targetUIDs[i]);
				if ((Object)(object)val == (Object)null || (Object)(object)val.StatusEffectMngr == (Object)null)
				{
					continue;
				}
				try
				{
					val.StatusEffectMngr.RemoveStatusWithIdentifierName(statusIdentifier);
				}
				catch (Exception ex)
				{
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogMessage((object)("[CoopVFX] Could not remove '" + statusIdentifier + "' from " + val.Name + ": " + ex.Message));
					}
				}
			}
		}

		public static void BuildUpMany(IList<string> targetUIDs, string statusIdentifier, float amount, Character dealer)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			if (targetUIDs != null && targetUIDs.Count != 0 && !string.IsNullOrEmpty(statusIdentifier) && !(amount <= 0f))
			{
				string[] array = new string[targetUIDs.Count];
				targetUIDs.CopyTo(array, 0);
				string text = (((Object)(object)dealer != (Object)null) ? ((object)dealer.UID/*cast due to .constrained prefix*/).ToString() : "");
				ApplyBuildUp(array, statusIdentifier, amount, text);
				Send("RPC_BuildUpMany", (PhotonTargets)1, array, statusIdentifier, amount, text);
			}
		}

		[PunRPC]
		private void RPC_BuildUpMany(string[] targetUIDs, string statusIdentifier, float amount, string dealerUID)
		{
			ApplyBuildUp(targetUIDs, statusIdentifier, amount, dealerUID);
		}

		private static void ApplyBuildUp(string[] targetUIDs, string statusIdentifier, float amount, string dealerUID)
		{
			if (targetUIDs == null)
			{
				return;
			}
			Character val = Resolve(dealerUID);
			int num = 0;
			for (int i = 0; i < targetUIDs.Length; i++)
			{
				Character val2 = Resolve(targetUIDs[i]);
				if ((Object)(object)val2 == (Object)null || (Object)(object)val2.StatusEffectMngr == (Object)null)
				{
					continue;
				}
				try
				{
					val2.StatusEffectMngr.AddStatusEffectBuildUp(statusIdentifier, amount, val);
					num++;
				}
				catch (Exception ex)
				{
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogMessage((object)("[CoopVFX] Could not build up '" + statusIdentifier + "' on " + val2.Name + ": " + ex.Message));
					}
				}
			}
			if (num > 0)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogMessage((object)("[CoopVFX] build-up '" + statusIdentifier + "' x" + amount + " offered to " + num + " character(s) here."));
				}
			}
		}

		public static void DialogueBegin()
		{
			Send("RPC_DialogueBegin", (PhotonTargets)1);
		}

		public static void DialogueLine(string speaker, string text)
		{
			if (!string.IsNullOrEmpty(text))
			{
				Send("RPC_DialogueLine", (PhotonTargets)1, speaker ?? "", text);
			}
		}

		public static void DialogueVoice(string bundleName, float volume)
		{
			if (!string.IsNullOrEmpty(bundleName))
			{
				Send("RPC_DialogueVoice", (PhotonTargets)1, bundleName, volume);
			}
		}

		public static void DialogueEnd()
		{
			Send("RPC_DialogueEnd", (PhotonTargets)1);
		}

		[PunRPC]
		private void RPC_DialogueBegin()
		{
			CoopDialogueListener.Begin();
		}

		[PunRPC]
		private void RPC_DialogueLine(string speaker, string text)
		{
			CoopDialogueListener.Show(speaker, text);
		}

		[PunRPC]
		private void RPC_DialogueVoice(string bundleName, float volume)
		{
			try
			{
				AudioClip val = DialogueAudio.Load(bundleName);
				if (!((Object)(object)val == (Object)null))
				{
					if (volume >= 0f)
					{
						DialogueAudio.PlayLocal(val, volume);
					}
					else
					{
						DialogueAudio.PlayLocal(val);
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogMessage((object)("[CoopDialogue] '" + bundleName + "' would not play here: " + ex.Message));
				}
			}
		}

		[PunRPC]
		private void RPC_DialogueEnd()
		{
			CoopDialogueListener.Hide();
		}

		public static void HoldMusic(string trackName)
		{
			if (!string.IsNullOrEmpty(trackName))
			{
				Send("RPC_HoldMusic", (PhotonTargets)1, trackName);
			}
		}

		public static void ReleaseMusic()
		{
			Send("RPC_ReleaseMusic", (PhotonTargets)1);
		}

		[PunRPC]
		private void RPC_HoldMusic(string trackName)
		{
			ConfluxBossMusic.HoldFollower(trackName);
		}

		[PunRPC]
		private void RPC_ReleaseMusic()
		{
			ConfluxBossMusic.End();
		}

		public static void SetVisible(Character target, bool visible, bool keepSweeping = false)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)target == (Object)null))
			{
				CharacterVisibility.Set(target, visible, keepSweeping);
				Send("RPC_SetVisible", (PhotonTargets)1, ((object)target.UID/*cast due to .constrained prefix*/).ToString(), visible, keepSweeping);
			}
		}

		[PunRPC]
		private void RPC_SetVisible(string targetUID, bool visible, bool keepSweeping)
		{
			Character val = Resolve(targetUID);
			if (!((Object)(object)val == (Object)null))
			{
				CharacterVisibility.Set(val, visible, keepSweeping);
			}
		}

		public static void PlayOn(string vfxName, Character target, Color? tint = null, float lifetime = 6f, float height = 0f, bool forceEmission = false)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			EffectSourceTrace.Note("PlayOn", vfxName, target);
			if (!string.IsNullOrEmpty(vfxName) && !((Object)(object)target == (Object)null))
			{
				PlayOnLocal(vfxName, target, tint, lifetime, height, forceEmission);
				Send("RPC_PlayOn", (PhotonTargets)1, vfxName, ((object)target.UID/*cast due to .constrained prefix*/).ToString(), tint.HasValue, Red(tint), Green(tint), Blue(tint), Alpha(tint), lifetime, height, forceEmission);
			}
		}

		public static void PlayOnMany(string vfxName, IList<Character> targets, Color? tint = null, float lifetime = 6f, float height = 0f, bool forceEmission = false)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(vfxName) || targets == null || targets.Count == 0)
			{
				return;
			}
			List<string> list = new List<string>(targets.Count);
			foreach (Character target in targets)
			{
				if (!((Object)(object)target == (Object)null))
				{
					PlayOnLocal(vfxName, target, tint, lifetime, height, forceEmission);
					list.Add(((object)target.UID/*cast due to .constrained prefix*/).ToString());
				}
			}
			if (list.Count != 0)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogMessage((object)("[CoopVFX] PlayOnMany '" + vfxName + "' on " + list.Count + " target(s), relayed=" + CanSend + "."));
				}
				Send("RPC_PlayOnMany", (PhotonTargets)1, vfxName, list.ToArray(), tint.HasValue, Red(tint), Green(tint), Blue(tint), Alpha(tint), lifetime, height, forceEmission);
			}
		}

		public static void PlayOnCenter(string vfxName, Character target, Color? tint = null, float lifetime = 6f)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			EffectSourceTrace.Note("PlayOnCenter", vfxName, target);
			if (!((Object)(object)target == (Object)null))
			{
				PlayOn(vfxName, target, tint, lifetime, target.CenterPosition.y - ((Component)target).transform.position.y);
			}
		}

		[PunRPC]
		private void RPC_PlayOn(string vfxName, string targetUID, bool hasTint, float r, float g, float b, float a, float lifetime, float height, bool forceEmission)
		{
			Character val = Resolve(targetUID);
			if (!((Object)(object)val == (Object)null))
			{
				PlayOnLocal(vfxName, val, Rebuild(hasTint, r, g, b, a), lifetime, height, forceEmission);
			}
		}

		[PunRPC]
		private void RPC_PlayOnMany(string vfxName, string[] targetUIDs, bool hasTint, float r, float g, float b, float a, float lifetime, float height, bool forceEmission)
		{
			if (targetUIDs == null)
			{
				return;
			}
			int num = 0;
			for (int i = 0; i < targetUIDs.Length; i++)
			{
				Character val = Resolve(targetUIDs[i]);
				if (!((Object)(object)val == (Object)null))
				{
					num++;
					PlayOnLocal(vfxName, val, Rebuild(hasTint, r, g, b, a), lifetime, height, forceEmission);
				}
			}
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogMessage((object)("[CoopVFX] received PlayOnMany '" + vfxName + "' for " + targetUIDs.Length + " uid(s), " + num + " resolved here."));
			}
		}

		private static void PlayOnLocal(string vfxName, Character target, Color? tint, float lifetime, float height, bool forceEmission = false)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)target == (Object)null))
			{
				Vector3 position = ((Component)target).transform.position;
				position.y += height;
				Vector3 worldPos = position;
				bool forceEmission2 = forceEmission;
				VFXPlayer.Play(vfxName, worldPos, target, lifetime, tint, null, null, hideMeshParts: false, diagnose: false, forceEmission2);
			}
		}

		public static void ApplyStatusToMany(IList<Character> targets, string statusIdentifier)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(statusIdentifier) || targets == null || targets.Count == 0)
			{
				return;
			}
			List<string> list = new List<string>(targets.Count);
			foreach (Character target in targets)
			{
				if (!((Object)(object)target == (Object)null))
				{
					ApplyStatusLocal(target, statusIdentifier);
					list.Add(((object)target.UID/*cast due to .constrained prefix*/).ToString());
				}
			}
			if (!CanSend)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogMessage((object)("[CoopVFX] '" + statusIdentifier + "' applied to " + list.Count + " local target(s), NOT relayed - CanSend is false (instance=" + ((Object)(object)_instance != (Object)null) + ", room=" + (PhotonNetwork.room != null) + ", players=" + ((PhotonNetwork.playerList != null) ? PhotonNetwork.playerList.Length : 0) + ")."));
				}
			}
			else if (list.Count != 0)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogMessage((object)("[CoopVFX] relaying '" + statusIdentifier + "' to " + list.Count + " target(s)."));
				}
				Send("RPC_ApplyStatusToMany", (PhotonTargets)1, list.ToArray(), statusIdentifier);
			}
		}

		[PunRPC]
		private void RPC_ApplyStatusToMany(string[] targetUIDs, string statusIdentifier)
		{
			if (targetUIDs == null)
			{
				return;
			}
			int num = 0;
			int num2 = 0;
			for (int i = 0; i < targetUIDs.Length; i++)
			{
				Character val = Resolve(targetUIDs[i]);
				if (!((Object)(object)val == (Object)null))
				{
					num++;
					if (val.IsPhotonPlayerLocal)
					{
						num2++;
					}
					ApplyStatusLocal(val, statusIdentifier);
				}
			}
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogMessage((object)("[CoopVFX] received '" + statusIdentifier + "' for " + targetUIDs.Length + " uid(s): " + num + " resolved here, " + num2 + " local and applied."));
			}
		}

		private static void ApplyStatusLocal(Character target, string statusIdentifier)
		{
			if ((Object)(object)target == (Object)null || !target.Alive || (Object)(object)target.StatusEffectMngr == (Object)null || !target.IsPhotonPlayerLocal)
			{
				return;
			}
			try
			{
				target.StatusEffectMngr.AddStatusEffect(statusIdentifier);
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogMessage((object)("[CoopVFX] Could not give '" + statusIdentifier + "' to " + target.Name + ": " + ex.Message));
				}
			}
		}

		public static void AffectHealthMany(IList<Character> targets, float amount)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			if (targets == null || targets.Count == 0 || amount <= 0f)
			{
				return;
			}
			List<string> list = new List<string>(targets.Count);
			foreach (Character target in targets)
			{
				if (!((Object)(object)target == (Object)null))
				{
					AffectHealthLocal(target, amount);
					list.Add(((object)target.UID/*cast due to .constrained prefix*/).ToString());
				}
			}
			if (list.Count != 0)
			{
				Send("RPC_AffectHealthMany", (PhotonTargets)1, list.ToArray(), amount);
			}
		}

		[PunRPC]
		private void RPC_AffectHealthMany(string[] targetUIDs, float amount)
		{
			if (targetUIDs == null)
			{
				return;
			}
			for (int i = 0; i < targetUIDs.Length; i++)
			{
				Character val = Resolve(targetUIDs[i]);
				if ((Object)(object)val != (Object)null)
				{
					AffectHealthLocal(val, amount);
				}
			}
		}

		private static void AffectHealthLocal(Character target, float amount)
		{
			if ((Object)(object)target == (Object)null || !target.Alive || (Object)(object)target.Stats == (Object)null || !target.IsPhotonPlayerLocal)
			{
				return;
			}
			try
			{
				target.Stats.AffectHealth(amount);
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogMessage((object)("[CoopVFX] Could not heal " + target.Name + ": " + ex.Message));
				}
			}
		}

		public static void PlayAt(string vfxName, Vector3 worldPos, Color? tint = null, float lifetime = 6f, Quaternion? rotation = null, float fade = 1f)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			EffectSourceTrace.Note("PlayAt", vfxName, worldPos);
			if (!string.IsNullOrEmpty(vfxName))
			{
				VFXPlayer.Play(vfxName, worldPos, null, lifetime, tint, rotation, null, hideMeshParts: false, diagnose: false, forceEmission: false, fade);
				Send("RPC_PlayAt", (PhotonTargets)1, vfxName, worldPos, tint.HasValue, Red(tint), Green(tint), Blue(tint), Alpha(tint), lifetime, rotation.HasValue, (object)(Quaternion)(((??)rotation) ?? Quaternion.identity), fade);
			}
		}

		[PunRPC]
		private void RPC_PlayAt(string vfxName, Vector3 worldPos, bool hasTint, float r, float g, float b, float a, float lifetime, bool hasRot, Quaternion rotation, float fade)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			VFXPlayer.Play(vfxName, worldPos, null, lifetime, Rebuild(hasTint, r, g, b, a), hasRot ? new Quaternion?(rotation) : ((Quaternion?)null), null, hideMeshParts: false, diagnose: false, forceEmission: false, fade);
		}

		public static void AttachEndlessTo(string vfxName, Character target, float scale = 1f, float height = 0f, Color? tint = null, float lifetime = 0f, float fade = 1f)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if (!string.IsNullOrEmpty(vfxName) && !((Object)(object)target == (Object)null))
			{
				EndlessVFX.AttachTo(vfxName, target, scale, height, tint, lifetime, fade);
				Send("RPC_AttachEndless", (PhotonTargets)1, vfxName, ((object)target.UID/*cast due to .constrained prefix*/).ToString(), scale, height, tint.HasValue, Red(tint), Green(tint), Blue(tint), Alpha(tint), lifetime, fade);
			}
		}

		[PunRPC]
		private void RPC_AttachEndless(string vfxName, string targetUID, float scale, float height, bool hasTint, float r, float g, float b, float a, float lifetime, float fade)
		{
			((MonoBehaviour)this).StartCoroutine(AttachWhenPresent(vfxName, targetUID, scale, height, Rebuild(hasTint, r, g, b, a), lifetime, fade));
		}

		private IEnumerator AttachWhenPresent(string vfxName, string targetUID, float scale, float height, Color? tint, float lifetime, float fade)
		{
			float start = Time.realtimeSinceStartup;
			while (Time.realtimeSinceStartup - start < 15f)
			{
				Character val = Resolve(targetUID);
				if ((Object)(object)val != (Object)null)
				{
					EndlessVFX.AttachTo(vfxName, val, scale, height, tint, lifetime, fade);
					yield break;
				}
				yield return null;
			}
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogMessage((object)("[CoopVFX] Character '" + targetUID + "' never appeared here - '" + vfxName + "' aura not attached."));
			}
		}

		public static void PlaySoundAt(string soundName, Vector3 worldPos)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			EffectSourceTrace.Note("Sound", soundName, worldPos);
			if (!string.IsNullOrEmpty(soundName))
			{
				PlaySoundLocal(soundName, worldPos);
				Send("RPC_PlaySoundAt", (PhotonTargets)1, soundName, worldPos);
			}
		}

		[PunRPC]
		private void RPC_PlaySoundAt(string soundName, Vector3 worldPos)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			PlaySoundLocal(soundName, worldPos);
		}

		private static void PlaySoundLocal(string soundName, Vector3 worldPos)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if (!Enum.TryParse<Sounds>(soundName, out Sounds result))
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogMessage((object)("[CoopVFX] '" + soundName + "' is not a GlobalAudioManager.Sounds name - nothing played."));
				}
				return;
			}
			try
			{
				Global.AudioManager.PlaySoundAtPosition(result, worldPos, 0f, 1f, 1f, 1f, 1f);
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogMessage((object)("[CoopVFX] Error playing sound '" + soundName + "': " + ex.Message));
				}
			}
		}

		public static void BroadcastSpiritGuardians(Character caster)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)caster == (Object)null))
			{
				Send("RPC_SpiritGuardians", (PhotonTargets)1, ((object)caster.UID/*cast due to .constrained prefix*/).ToString());
			}
		}

		[PunRPC]
		private void RPC_SpiritGuardians(string casterUID)
		{
			Character val = Resolve(casterUID);
			if (!((Object)(object)val == (Object)null))
			{
				SpiritGuardiansController.StartFor(val, visualOnly: true);
			}
		}

		public static void SpawnAmbushEnemy(int spotIndex, string body, string uid, int[] viewIDs, Vector3 position, Vector3 rotation)
		{
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			if (!CanSend)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogMessage((object)("[Ambush] '" + body + "' not relayed - nobody else in the room (instance=" + ((Object)(object)_instance != (Object)null) + ", room=" + (PhotonNetwork.room != null) + ", players=" + ((PhotonNetwork.playerList != null) ? PhotonNetwork.playerList.Length : 0) + ")."));
				}
				return;
			}
			ManualLogSource log2 = Plugin.Log;
			if (log2 != null)
			{
				log2.LogMessage((object)("[Ambush] Relaying '" + body + "' to the other client(s): uid " + uid + ", view " + AmbushNetwork.Describe(viewIDs) + "."));
			}
			try
			{
				((MonoBehaviour)_instance).photonView.RPC("RPC_SpawnAmbushEnemy", (PhotonTargets)1, new object[6] { spotIndex, body, uid, viewIDs, position, rotation });
			}
			catch (Exception ex)
			{
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogError((object)("[Ambush] COULD NOT RELAY '" + body + "' - it will stand on this screen and nowhere else. The rest of the ambush is still being placed. " + ex));
				}
			}
		}

		public static void SpawnAmbushEnemyTo(PhotonPlayer player, int spotIndex, string body, string uid, int[] viewIDs, Vector3 position, Vector3 rotation)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_instance == (Object)null || player == null)
			{
				return;
			}
			try
			{
				((MonoBehaviour)_instance).photonView.RPC("RPC_SpawnAmbushEnemy", player, new object[6] { spotIndex, body, uid, viewIDs, position, rotation });
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogError((object)("[Ambush] Could not replay '" + body + "' to player " + player.ID + ": " + ex));
				}
			}
		}

		[PunRPC]
		private void RPC_SpawnAmbushEnemy(int spotIndex, string body, string uid, int[] viewIDs, Vector3 position, Vector3 rotation)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			((MonoBehaviour)this).StartCoroutine(AmbushNetwork.ReceiveRoutine(spotIndex, body, uid, viewIDs, position, rotation));
		}

		public static void DespawnAmbush()
		{
			Send("RPC_DespawnAmbush", (PhotonTargets)1);
		}

		[PunRPC]
		private void RPC_DespawnAmbush()
		{
			AmbushNetwork.ReceiveDespawn();
		}

		public static void SpawnLurker(string key, string body, string uid, int[] viewIDs, Vector3 position, Vector3 rotation)
		{
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			if (!CanSend)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogMessage((object)("[Lurker] '" + key + "' not relayed - nobody else in the room."));
				}
				return;
			}
			ManualLogSource log2 = Plugin.Log;
			if (log2 != null)
			{
				log2.LogMessage((object)("[Lurker] Relaying '" + key + "' to the other client(s): uid " + uid + ", view " + AmbushNetwork.Describe(viewIDs) + "."));
			}
			try
			{
				((MonoBehaviour)_instance).photonView.RPC("RPC_SpawnLurker", (PhotonTargets)1, new object[6] { key, body, uid, viewIDs, position, rotation });
			}
			catch (Exception ex)
			{
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogError((object)("[Lurker] COULD NOT RELAY '" + key + "' - it will stand on this screen and nowhere else. " + ex));
				}
			}
		}

		[PunRPC]
		private void RPC_SpawnLurker(string key, string body, string uid, int[] viewIDs, Vector3 position, Vector3 rotation)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			((MonoBehaviour)this).StartCoroutine(LurkerEncounters.ReceiveRoutine(key, body, uid, viewIDs, position, rotation));
		}

		public static void DespawnLurkers()
		{
			Send("RPC_DespawnLurkers", (PhotonTargets)1);
		}

		[PunRPC]
		private void RPC_DespawnLurkers()
		{
			LurkerEncounters.DespawnLocal();
		}

		public static void SetCombatBarrier(bool up)
		{
			Send("RPC_SetCombatBarrier", (PhotonTargets)1, up);
		}

		[PunRPC]
		private void RPC_SetCombatBarrier(bool up)
		{
			if (up)
			{
				ConfluxBattle.SpawnCombatBarrierLocal();
			}
			else
			{
				ConfluxBattle.DestroyCombatBarrierLocal();
			}
		}

		public static void Notify(string message)
		{
			if (!string.IsNullOrEmpty(message))
			{
				Send("RPC_Notify", (PhotonTargets)1, message);
				CoopDialogueRelay.Notify(message);
			}
		}

		[PunRPC]
		private void RPC_Notify(string message)
		{
			CoopDialogueRelay.Notify(message);
		}

		public static void SetWatcherEyes(string uid, bool on)
		{
			if (!string.IsNullOrEmpty(uid))
			{
				Send("RPC_SetWatcherEyes", (PhotonTargets)1, uid, on);
			}
		}

		[PunRPC]
		private void RPC_SetWatcherEyes(string uid, bool on)
		{
			if (!on)
			{
				WatcherEyesTalisman.CloseFor(uid);
				return;
			}
			Character val = Resolve(uid);
			if ((Object)(object)val != (Object)null)
			{
				WatcherEyesTalisman.SetLocal(val, on: true);
			}
		}

		public static void SceneFXShow(string group)
		{
			if (!string.IsNullOrEmpty(group))
			{
				Send("RPC_SceneFXShow", (PhotonTargets)1, group);
			}
		}

		[PunRPC]
		private void RPC_SceneFXShow(string group)
		{
			SceneFX.ShowLocal(group);
		}

		public static void SceneFXHide(string group, float fadeSeconds)
		{
			if (!string.IsNullOrEmpty(group))
			{
				Send("RPC_SceneFXHide", (PhotonTargets)1, group, fadeSeconds);
			}
		}

		[PunRPC]
		private void RPC_SceneFXHide(string group, float fadeSeconds)
		{
			SceneFX.HideLocal(group, fadeSeconds);
		}

		public static void AmbushRollCall(string[] bodies)
		{
			if (bodies != null)
			{
				Send("RPC_AmbushRollCall", (PhotonTargets)1, bodies);
			}
		}

		[PunRPC]
		private void RPC_AmbushRollCall(string[] bodies)
		{
			AmbushNetwork.ReportInventory(bodies, "this client");
		}

		private static Character Resolve(string uid)
		{
			if (string.IsNullOrEmpty(uid))
			{
				return null;
			}
			CharacterManager instance = CharacterManager.Instance;
			if (!((Object)(object)instance != (Object)null))
			{
				return null;
			}
			return instance.GetCharacter(uid);
		}
	}
	public static class EffectRepeatGuard
	{
		private static readonly Dictionary<string, float> _last = new Dictionary<string, float>();

		public static bool Allow(string label, Character character, float windowSeconds)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(label) || windowSeconds <= 0f)
			{
				return true;
			}
			string text = "?";
			try
			{
				if ((Object)(object)character != (Object)null)
				{
					text = ((object)character.UID/*cast due to .constrained prefix*/).ToString();
				}
			}
			catch
			{
			}
			string key = label + "|" + text;
			if (_last.TryGetValue(key, out var value) && Time.time - value < windowSeconds)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogMessage((object)("[RepeatGuard] '" + label + "' fired again " + (Time.time - value).ToString("0.00") + "s after the first - dropped as a replicated re-activation. See EffectRepeatGuard."));
				}
				return false;
			}
			_last[key] = Time.time;
			return true;
		}
	}
	public static class EffectSourceTrace
	{
		private class Record
		{
			public float First;

			public int Count;

			public string FirstCaller;
		}

		public static bool Enabled = false;

		public const float WindowSeconds = 3f;

		private static readonly Dictionary<string, Record> _seen = new Dictionary<string, Record>();

		public static void Note(string kind, string effect, object target)
		{
			if (!Enabled || string.IsNullOrEmpty(effect))
			{
				return;
			}
			try
			{
				string text = "?";
				try
				{
					if (target != null)
					{
						text = target.ToString();
					}
				}
				catch
				{
				}
				string key = kind + "|" + effect + "|" + text;
				string text2 = Caller();
				if (!_seen.TryGetValue(key, out var value) || Time.time - value.First > 3f)
				{
					_seen[key] = new Record
					{
						First = Time.time,
						Count = 1,
						FirstCaller = text2
					};
					return;
				}
				value.Count++;
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogMessage((object)("[SourceTrace] '" + effect + "' (" + kind + ") on " + text + " requested " + value.Count + " times in " + (Time.time - value.First).ToString("0.00") + "s.\n    first: " + value.FirstCaller + "\n    this : " + text2));
				}
			}
			catch
			{
			}
		}

		private static string Caller()
		{
			try
			{
				StackTrace stackTrace = new StackTrace(2, fNeedFileInfo: false);
				for (int i = 0; i < stackTrace.FrameCount; i++)
				{
					MethodBase method = stackTrace.GetFrame(i).GetMethod();
					if (!(method == null) && !(method.DeclaringType == null))
					{
						string name = method.DeclaringType.Name;
						if (!(name == "EffectSourceTrace") && !(name == "CoopVFX"))
						{
							return method.DeclaringType.FullName + "." + method.Name;
						}
					}
				}
			}
			catch
			{
			}
			return "?";
		}
	}
	public static class EnchantmentCompatibility
	{
		public class Pairing
		{
			public int RecipeID;

			public string RecipeName;

			public int[] ItemIDs;

			public Pairing(int recipeID, string recipeName, params int[] itemIDs)
			{
				RecipeID = recipeID;
				RecipeName = recipeName;
				ItemIDs = itemIDs;
			}
		}

		public static readonly Pairing[] Pairings = new Pairing[26]
		{
			new Pairing(49, "Elatt's Sanctity (helmet)", -1957, -1908, -1969, -1964),
			new Pairing(96, "Order and Discipline", -1957, -1908, -1969, -1964),
			new Pairing(75, "Formless Material (helmet)", -1917),
			new Pairing(94, "Stabilizing Forces (helmet)", -1917),
			new Pairing(66, "Cocoon (helmet)", -1917),
			new Pairing(71, "Economy (helmet)", -1917),
			new Pairing(48, "Elatt's Sanctity (armour)", -1967, -1968),
			new Pairing(29, "Spirit of Monsoon", -1967, -1968),
			new Pairing(74, "Formless Material (armour)", -1916),
			new Pairing(93, "Stabilizing Forces (armour)", -1916),
			new Pairing(65, "Cocoon (armour)", -1916),
			new Pairing(73, "Economy (armour)", -1916),
			new Pairing(50, "Elatt's Sanctity (boots)", -1966),
			new Pairing(45, "Unwavering Determination", -1966),
			new Pairing(76, "Formless Material (boots)", -1918),
			new Pairing(67, "Cocoon (boots)", -1918),
			new Pairing(72, "Economy (boots)", -1918),
			new Pairing(91, "Weightless", -1965),
			new Pairing(43, "Unsuspected Strength", -1963),
			new Pairing(47, "War Memento", -1947),
			new Pairing(38, "Isolated Rumination", -1951),
			new Pairing(90, "Redemption", -1961),
			new Pairing(88, "Rainbow Hex", -1922),
			new Pairing(13, "Foggy Memories", -1922),
			new Pairing(5, "Favorable Wind", -1922),
			new Pairing(12, "Winter's Cruelty", -1922)
		};

		private static readonly HashSet<string> _applied = new HashSet<string>();

		public static int Apply()
		{
			int num = 0;
			Pairing[] pairings = Pairings;
			foreach (Pairing pairing in pairings)
			{
				int[] itemIDs = pairing.ItemIDs;
				foreach (int itemID in itemIDs)
				{
					if (!Allow(pairing, itemID))
					{
						num++;
					}
				}
			}
			return num;
		}

		private static bool Allow(Pairing pairing, int itemID)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: 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_0183: Unknown result type (might be due to invalid IL or missing references)
			string item = pairing.RecipeID + ":" + itemID;
			if (_applied.Contains(item))
			{
				return true;
			}
			EnchantmentRecipe val = FindRecipe(pairing.RecipeID);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			Item val2 = ((ResourcesPrefabManager.Instance != null) ? ResourcesPrefabManager.Instance.GetItemPrefab(itemID) : null);
			if ((Object)(object)val2 == (Object)null)
			{
				return false;
			}
			_applied.Add(item);
			EquipmentData compatibleEquipments = val.CompatibleEquipments;
			IngredientData[] array = (IngredientData[])(((object)compatibleEquipments.CompatibleEquipments) ?? ((object)new IngredientData[0]));
			if (((EquipmentData)(ref compatibleEquipments)).Match(val2))
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogMessage((object)("[Enchant] " + val2.Name + " already accepts '" + pairing.RecipeName + "' - nothing to add."));
				}
				return true;
			}
			if (val2.IsNonEnchantable)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)("[Enchant] " + val2.Name + " is marked NON-ENCHANTABLE - it will still be refused '" + pairing.RecipeName + "' after this."));
				}
			}
			TagSourceSelector equipmentTag = compatibleEquipments.EquipmentTag;
			if (equipmentTag != null && equipmentTag.Tag != Tag.None && !val2.HasTag(equipmentTag.Tag))
			{
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogWarning((object)("[Enchant] " + val2.Name + " does not carry the '" + equipmentTag.Tag.TagName + "' tag that '" + pairing.RecipeName + "' requires - it will still be refused."));
				}
			}
			List<IngredientData> list = new List<IngredientData>(array)
			{
				new IngredientData
				{
					Type = (IngredientType)1,
					SpecificIngredient = val2
				}
			};
			compatibleEquipments.CompatibleEquipments = list.ToArray();
			val.CompatibleEquipments = compatibleEquipments;
			ManualLogSource log4 = Plugin.Log;
			if (log4 != null)
			{
				log4.LogMessage((object)("[Enchant] " + val2.Name + " can now take '" + pairing.RecipeName + "' (" + array.Length + " -> " + list.Count + " compatible item(s))."));
			}
			return true;
		}

		private static EnchantmentRecipe FindRecipe(int recipeID)
		{
			try
			{
				RecipeManager instance = RecipeManager.Instance;
				if (instance == null)
				{
					return null;
				}
				List<EnchantmentRecipe> enchantmentRecipes = instance.GetEnchantmentRecipes();
				if (enchantmentRecipes == null)
				{
					return null;
				}
				for (int i = 0; i < enchantmentRecipes.Count; i++)
				{
					if ((Object)(object)enchantmentRecipes[i] != (Object)null && enchantmentRecipes[i].RecipeID == recipeID)
					{
						return enchantmentRecipes[i];
					}
				}
			}
			catch
			{
			}
			return null;
		}
	}
	public class EnchantmentCompatibilityWatcher : MonoBehaviour
	{
		private const float RetryIntervalSeconds = 1f;

		private const float GiveUpSeconds = 90f;

		private float _nextTry;

		private float _giveUpAt;

		private bool _done;

		private void Start()
		{
			_giveUpAt = Time.realtimeSinceStartup + 90f;
			if (EnchantmentCompatibility.Apply() == 0)
			{
				_done = true;
			}
		}

		private void Update()
		{
			if (_done || Time.time < _nextTry)
			{
				return;
			}
			_nextTry = Time.time + 1f;
			CoopGate.Guard("EnchantmentCompatibility", delegate
			{
				int num = EnchantmentCompatibility.Apply();
				if (num == 0)
				{
					_done = true;
				}
				else if (!(Time.realtimeSinceStartup < _giveUpAt))
				{
					_done = true;
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogWarning((object)("[Enchant] Gave up after " + 90f + "s with " + num + " pairing(s) unapplied - either the enchantment recipe id is wrong or the item template never loaded. Those weapons will not be offered their enchantment."));
					}
				}
			});
		}
	}
	public static class EndlessVFX
	{
		public class Shaping
		{
			public string[] HideParts;

			public float RepeatSeconds;
		}

		public static readonly Dictionary<string, Shaping> Shapes = new Dictionary<string, Shaping>(StringComparer.OrdinalIgnoreCase)
		{
			{
				"VFXMultiStrikeWind",
				new Shaping
				{
					HideParts = new string[3] { "smoke", "cloud", "dust" },
					RepeatSeconds = 2.5f
				}
			},
			{
				"VFXBoonDecay",
				new Shaping
				{
					RepeatSeconds = 1f
				}
			}
		};

		private static Shaping ShapeFor(string vfxName)
		{
			if (string.IsNullOrEmpty(vfxName))
			{
				return null;
			}
			if (!Shapes.TryGetValue(vfxName, out var value))
			{
				return null;
			}
			return value;
		}

		private static void Shape(GameObject instance, string vfxName)
		{
			Shaping shaping = ShapeFor(vfxName);
			if (shaping != null && shaping.HideParts != null && shaping.HideParts.Length != 0)
			{
				VFXPlayer.FilterParts(instance, shaping.HideParts, hideMeshParts: false, vfxName);
			}
			if (shaping != null && shaping.RepeatSeconds > 0f)
			{
				MakeRepeating(instance, shaping.RepeatSeconds, vfxName);
			}
			else
			{
				MakeEndless(instance);
			}
		}

		public static GameObject SpawnAt(string vfxName, Vector3 position, Quaternion rotation, float scale = 1f, Color? tint = null)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = ResolvePrefab(vfxName);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			GameObject val2 = Object.Instantiate<GameObject>(val, position, rotation);
			((Object)val2).name = "ElattEndlessVFX_" + vfxName;
			if (scale != 1f)
			{
				val2.transform.localScale = Vector3.one * scale;
			}
			val2.SetActive(true);
			StripCharacterDependencies(val2);
			Tint(val2, tint);
			Shape(val2, vfxName);
			return val2;
		}

		public static GameObject AttachTo(string vfxName, Character target, float scale = 1f, float height = 0f, Color? tint = null, float lifetime = 0f, float fade = 1f)
		{
			//IL_008c: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)target == (Object)null)
			{
				return null;
			}
			GameObject val = ResolvePrefab(vfxName);
			if ((Object)(object)val == (Object)null)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogMessage((object)("[EndlessVFX] '" + vfxName + "' could not be resolved to a VFX, a blast, a loaded prefab or a status effect - nothing attached to " + target.Name + "."));
				}
				return null;
			}
			GameObject val2 = Object.Instantiate<GameObject>(val, ((Component)target).transform);
			((Object)val2).name = "ElattEndlessVFX_" + vfxName;
			val2.transform.localPosition = new Vector3(0f, height, 0f);
			val2.transform.localRotation = Quaternion.identity;
			val2.transform.localScale = Vector3.one * scale;
			val2.SetActive(true);
			Tint(val2, tint);
			if (fade < 1f)
			{
				ItemVisualCleanup.FadeHierarchy(val2, fade, vfxName);
			}
			BindToCharacter(val2, target);
			Shape(val2, vfxName);
			if (lifetime > 0f)
			{
				Object.Destroy((Object)(object)val2, lifetime);
			}
			return val2;
		}

		private static void BindToCharacter(GameObject instance, Character target)
		{
			if ((Object)(object)instance == (Object)null || (Object)(object)target == (Object)null)
			{
				return;
			}
			VFXSystem[] componentsInChildren = instance.GetComponentsInChildren<VFXSystem>(true);
			foreach (VFXSystem val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				try
				{
					val.Play(target, (Character)null);
				}
				catch (Exception ex)
				{
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogMessage((object)("[EndlessVFX] '" + ((Object)instance).name + "': VFXSystem.Play failed - " + ex.Message));
					}
				}
			}
		}

		private static void Tint(GameObject instance, Color? tint)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			if (tint.HasValue)
			{
				ItemVisualCleanup.TintHierarchy(instance, tint.Value, null, log: false);
			}
		}

		public static void MakeRepeating(GameObject root, float interval, string label)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)root == (Object)null))
			{
				ParticleSystem[] componentsInChildren = root.GetComponentsInChildren<ParticleSystem>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					MainModule main = componentsInChildren[i].main;
					((MainModule)(ref main)).loop = false;
					((MainModule)(ref main)).stopAction = (ParticleSystemStopAction)0;
					((MainModule)(ref main)).playOnAwake = true;
				}
				Transform[] componentsInChildren2 = root.GetComponentsInChildren<Transform>(true);
				for (int i = 0; i < componentsInChildren2.Length; i++)
				{
					((Component)componentsInChildren2[i]).gameObject.SetActive(true);
				}
				VFXRepeater vFXRepeater = root.GetComponent<VFXRepeater>();
				if ((Object)(object)vFXRepeater == (Object)null)
				{
					vFXRepeater = root.AddComponent<VFXRepeater>();
				}
				vFXRepeater.Interval = interval;
				vFXRepeater.Label = label;
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogMessage((object)("[EndlessVFX] '" + label + "' will re-play every " + interval + "s."));
				}
			}
		}

		public static void MakeEndless(GameObject root)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)root == (Object)null))
			{
				ParticleSystem[] componentsInChildren = root.GetComponentsInChildren<ParticleSystem>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					MainModule main = componentsInChildren[i].main;
					((MainModule)(ref main)).loop = true;
					((MainModule)(ref main)).stopAction = (ParticleSystemStopAction)0;
					((MainModule)(ref main)).playOnAwake = true;
				}
				Transform[] componentsInChildren2 = root.GetComponentsInChildren<Transform>(true);
				for (int i = 0; i < componentsInChildren2.Length; i++)
				{
					((Component)componentsInChildren2[i]).gameObject.SetActive(true);
				}
				componentsInChildren = root.GetComponentsInChildren<ParticleSystem>(true);
				foreach (ParticleSystem obj in componentsInChildren)
				{
					obj.Clear(true);
					obj.Play(true);
				}
			}
		}

		public static void Restart(GameObject root)
		{
			if ((Object)(object)root == (Object)null)
			{
				return;
			}
			ParticleSystem[] componentsInChildren = root.GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem val in componentsInChildren)
			{
				if ((!((Object)(object)((Component)val).transform.parent != (Object)null) || !((Object)(object)((Component)((Component)val).transform.parent).GetComponentInParent<ParticleSystem>() != (Object)null)) && !val.isPlaying)
				{
					val.Play(true);
				}
			}
		}

		public static void StripCharacterDependencies(GameObject root)
		{
			if ((Object)(object)root == (Object)null)
			{
				return;
			}
			List<Component> list = new List<Component>();
			VFXFollowCharBone[] componentsInChildren = root.GetComponentsInChildren<VFXFollowCharBone>(true);
			foreach (VFXFollowCharBone item in componentsInChildren)
			{
				list.Add((Component)(object)item);
			}
			foreach (Component item2 in list)
			{
				if ((Object)(object)item2 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)item2);
				}
			}
		}

		public static GameObject ResolvePrefab(string name)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(name))
			{
				return null;
			}
			if (Enum.TryParse<VFXPrefabs>(name, out VFXPrefabs result) && (int)result != 0)
			{
				try
				{
					GameObject vfxSystem = SL_PlayVFX.GetVfxSystem(result);
					if ((Object)(object)vfxSystem != (Object)null)
					{
						return vfxSystem;
					}
				}
				catch
				{
				}
			}
			if (Enum.TryParse<BlastPrefabs>(name, out BlastPrefabs result2) && (int)result2 != 0)
			{
				try
				{
					GameObject blastPrefab = SL_ShootBlast.GetBlastPrefab(result2);
					if ((Object)(object)blastPrefab != (Object)null)
					{
						return blastPrefab;
					}
				}
				catch
				{
				}
			}
			string text = Normalize(name);
			VFXSystem[] array = Resources.FindObjectsOfTypeAll<VFXSystem>();
			foreach (VFXSystem val in array)
			{
				if ((Object)(object)val != (Object)null && Normalize(((Object)val).name) == text)
				{
					return ((Component)val).gameObject;
				}
			}
			GameObject val2 = SceneFXLibrary.Resolve(name);
			if ((Object)(object)val2 != (Object)null)
			{
				return val2;
			}
			return VFXPlayer.StatusFXPrefab(name);
		}

		private static string Normalize(string s)
		{
			return s.Replace("(Clone)", "").Replace(" ", "").Replace("_", "")
				.Trim()
				.ToLowerInvariant();
		}
	}
	public static class FollowerStats
	{
		private const int ManaPointsToUnlockCasting = 1;

		public static void Apply(Character character, float health, float stamina, float mana, string label)
		{
			if ((Object)(object)character == (Object)null)
			{
				return;
			}
			CharacterStats stats = character.Stats;
			if ((Object)(object)stats == (Object)null)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("[Stats] '" + label + "' has no CharacterStats - nothing applied."));
				}
				return;
			}
			if (mana > 0f)
			{
				stats.SetManaPoint(1);
			}
			if (health > 0f)
			{
				Converge(stats, "m_maxHealthStat", health, () => stats.MaxHealth, label, "health");
			}
			if (mana > 0f)
			{
				Converge(stats, "m_maxManaStat", mana, () => stats.MaxMana, label, "mana");
			}
			if (stamina > 0f)
			{
				Converge(stats, "m_maxStamina", stamina, () => stats.MaxStamina, label, "stamina");
			}
			stats.FullHealth();
			stats.FullMana();
			stats.FullStamina();
			NormaliseDamageOutput(stats, label);
			CompanionDamageKeeper.Attach(character, label);
			ManualLogSource log2 = Plugin.Log;
			if (log2 != null)
			{
				log2.LogMessage((object)("[Stats] '" + label + "': health=" + stats.CurrentHealth.ToString("0") + "/" + stats.ActiveMaxHealth.ToString("0") + " stamina=" + stats.CurrentStamina.ToString("0") + "/" + stats.MaxStamina.ToString("0") + " mana=" + stats.CurrentMana.ToString("0") + "/" + stats.ActiveMaxMana.ToString("0")));
			}
			if (stats.ActiveMaxHealth <= 0f)
			{
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogError((object)("[Stats] '" + label + "' ended up with " + stats.ActiveMaxHealth + " max health - it will die instantly and cannot be revived. Check the modifiers."));
				}
			}
		}

		public static bool NormaliseDamageOutput(CharacterStats stats, string label)
		{
			try
			{
				if (!(At.GetField<CharacterStats>(stats, "m_damageTypesModifier") is Stat[] array))
				{
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogWarning((object)("[Stats] '" + label + "' has no m_damageTypesModifier - its damage multiplier cannot be checked, and if it is zero it will hit for nothing."));
					}
					return false;
				}
				int num = 0;
				foreach (Stat val in array)
				{
					if (val != null && !(val.CurrentValue > 0f))
					{
						val.BaseValue = 1f;
						val.Update();
						num++;
					}
				}
				if (num == 0)
				{
					return false;
				}
				stats.UpdateStats();
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogMessage((object)("[Stats] '" + label + "' had " + num + " of " + array.Length + " damage-type multiplier(s) at zero - set to 100%. Left alone, every hit it landed would have been multiplied by zero."));
				}
				return true;
			}
			catch (Exception ex)
			{
				ManualLogSource log3 = Plugin.Log;
				if (log3 != null)
				{
					log3.LogWarning((object)("[Stats] Could not normalise '" + label + "' damage output: " + ex.Message));
				}
				return false;
			}
		}

		public static string ForceDamageOutput(CharacterStats stats, string label)
		{
			if ((Object)(object)stats == (Object)null)
			{
				return null;
			}
			try
			{
				string text = null;
				if (NormaliseDamageOutput(stats, label))
				{
					text = "stats reset";
				}
				else
				{
					try
					{
						stats.UpdateStats();
						text = "recomputed";
					}
					catch
					{
					}
				}
				if (!DamageOutputIsBroken(stats))
				{
					return text;
				}
				if (!(At.GetField<CharacterStats>(stats, "m_totalDamageAttack") is float[] array))
				{
					return text;
				}
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = 1f;
				}
				At.SetField<CharacterStats>(stats, "m_totalDamageAttack", (object)array);
				return ((text == null) ? "" : (text + ", then ")) + "array written directly";
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("[Stats] Could not force damage output: " + ex.Message));
				}
				return null;
			}
		}

		public static bool DamageOutputIsBroken(CharacterStats stats)
		{
			if ((Object)(object)stats == (Object)null)
			{
				return false;
			}
			try
			{
				if (!(At.GetField<CharacterStats>(stats, "m_totalDamageAttack") is float[] array))
				{
					return false;
				}
				float[] array2 = array;
				for (int i = 0; i < array2.Length; i++)
				{
					if (array2[i] > 0f)
					{
						return false;
					}
				}
				return array.Length != 0;
			}
			catch
			{
				return false;
			}
		}

		private static void Converge(CharacterStats stats, string fieldName, float target, Func<float> read, string label, string what)
		{
			object field = At.GetField<CharacterStats>(stats, fieldName);
			Stat val = (Stat)((field is Stat) ? field : null);
			if (val == null)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("[Stats] '" + label + "' has no '" + fieldName + "' - " + what + " not set."));
				}
			}
			else
			{
				val.BaseValue = target;
				val.Update();
				float num = read();
				if (!(Mathf.Abs(num - target) <= 0.01f))
				{
					val.BaseValue = target + (target - num);
					val.Update();
				}
			}
		}
	}
	public static class GhostMaterial
	{
		public const int SourceItemID = 3200040;

		public const string SourceMaterialName = "mat_cha_beggarMaleArmorSummonedGhost";

		private static Material _ghost;

		private static bool _resolved;

		public static void ApplyTo(params int[] itemIDs)
		{
			Material val = Resolve();
			if ((Object)(object)val == (Object)null)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogMessage((object)("[Ghost] Could not find 'mat_cha_beggarMaleArmorSummonedGhost' on item " + 3200040 + " - no items were ghosted."));
				}
			}
			else
			{
				for (int i = 0; i < itemIDs.Length; i++)
				{
					Apply(itemIDs[i], val);
				}
			}
		}

		private static Material Resolve()
		{
			if (_resolved)
			{
				return _ghost;
			}
			_resolved = true;
			Item itemPrefab = ResourcesPrefabManager.Instance.GetItemPrefab(3200040);
			if ((Object)(object)itemPrefab == (Object)null)
			{
				return null;
			}
			Transform itemVisualPrefab = ResourcesPrefabManager.Instance.GetItemVisualPrefab(itemPrefab.SpecialVisualPrefabDefaultPath);
			if ((Object)(object)itemVisualPrefab == (Object)null)
			{
				return null;
			}
			Renderer[] componentsInChildren = ((Component)itemVisualPrefab).GetComp

plugins/TinyHelper.dll

Decompiled 3 weeks ago
#define DEBUG
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using CharacterQuestKnowledgeExtensions;
using HarmonyLib;
using Localizer;
using NodeCanvas.DialogueTrees;
using NodeCanvas.Framework;
using NodeCanvas.Tasks.Actions;
using NodeCanvas.Tasks.Conditions;
using Photon;
using TinyHelper;
using TinyHelper.Effects;
using TinyHelper.Interfaces;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.0.0.0")]
public static class TinyHelpers
{
	public static string OrConcat<T>(this ICollection<T> collection)
	{
		List<T> list = collection.ToList();
		string text = "";
		for (int i = 0; i < list.Count; i++)
		{
			text += list[i].ToString();
			if (i == list.Count - 2)
			{
				text += " or ";
			}
			else if (i < list.Count - 2)
			{
				text += ", ";
			}
		}
		return text;
	}

	public static void Shuffle<T>(this IList<T> list)
	{
		Random random = new Random();
		int count = list.Count;
		for (int num = list.Count - 1; num > 1; num--)
		{
			int index = random.Next(num + 1);
			T value = list[index];
			list[index] = list[num];
			list[num] = value;
		}
	}
}
namespace CharacterQuestKnowledgeExtensions
{
	public static class CharacterQuestKnowledgeExtensions
	{
		public static bool IsItemLearnedLocal(this CharacterQuestKnowledge questKnowledge, int _itemID)
		{
			return (from q in ((CharacterKnowledge)questKnowledge).GetLearnedItems()
				where q.ItemID == _itemID && Object.op_Implicit((Object)(object)((EffectSynchronizer)q).OwnerCharacter)
				select q).Count() > 0;
		}

		public static bool IsQuestCompletedLocal(this CharacterQuestKnowledge questKnowledge, int _itemID)
		{
			return ((CharacterKnowledge)questKnowledge).GetLearnedItems().Where(delegate(Item q)
			{
				int result;
				if (q.ItemID == _itemID && Object.op_Implicit((Object)(object)((EffectSynchronizer)q).OwnerCharacter))
				{
					Quest val = (Quest)(object)((q is Quest) ? q : null);
					if (val != null)
					{
						result = (val.IsCompleted ? 1 : 0);
						goto IL_002e;
					}
				}
				result = 0;
				goto IL_002e;
				IL_002e:
				return (byte)result != 0;
			}).Count() > 0;
		}
	}
}
namespace CharacterExtensions
{
	public static class CharacterExtensions
	{
		public static List<Item> EquippedOnBag(this Character character)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			object result;
			if (character == null)
			{
				result = null;
			}
			else
			{
				CharacterInventory inventory = character.Inventory;
				result = ((inventory == null) ? null : inventory.GetOwnedItems(TinyTagManager.GetOrMakeTag("Item"))?.Where((Item x) => x.DisplayedOnBag)?.ToList());
			}
			return (List<Item>)result;
		}
	}
}
namespace TinyHelper
{
	public static class At
	{
		public static BindingFlags flags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		public static object Call(object obj, string method, params object[] args)
		{
			MethodInfo method2 = obj.GetType().GetMethod(method, flags);
			if (method2 != null)
			{
				return method2.Invoke(obj, args);
			}
			return null;
		}

		public static void SetValue<T>(T value, Type type, object obj, string field)
		{
			FieldInfo field2 = type.GetField(field, flags);
			if (field2 != null)
			{
				field2.SetValue(obj, value);
			}
		}

		public static object GetValue(Type type, object obj, string value)
		{
			FieldInfo field = type.GetField(value, flags);
			if (field != null)
			{
				return field.GetValue(obj);
			}
			return null;
		}

		public static void InheritBaseValues(object _derived, object _base)
		{
			FieldInfo[] fields = _base.GetType().GetFields(flags);
			foreach (FieldInfo fieldInfo in fields)
			{
				try
				{
					_derived.GetType().GetField(fieldInfo.Name).SetValue(_derived, fieldInfo.GetValue(_base));
				}
				catch
				{
				}
			}
		}
	}
	public class ForbiddenWeaponTypeCondition : EffectCondition
	{
		public List<WeaponType> ForbiddenWeaponTypes = new List<WeaponType>();

		protected override bool CheckIsValid(Character _affectedCharacter)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			Equipment obj = ((_affectedCharacter != null) ? _affectedCharacter.LeftHandEquipment : null);
			Weapon val = (Weapon)(object)((obj is Weapon) ? obj : null);
			int result;
			if (val == null || !ForbiddenWeaponTypes.Contains(val.Type))
			{
				Weapon val2 = ((_affectedCharacter != null) ? _affectedCharacter.CurrentWeapon : null);
				result = ((val2 == null || !ForbiddenWeaponTypes.Contains(val2.Type)) ? 1 : 0);
			}
			else
			{
				result = 0;
			}
			return (byte)result != 0;
		}

		public static ActivationCondition AddToSkill(Skill skill, List<WeaponType> forbiddenWeaponTypes)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			GameObject val = new GameObject("ForbiddenWeaponTypeCondition");
			ActivationCondition val2 = new ActivationCondition();
			ForbiddenWeaponTypeCondition forbiddenWeaponTypeCondition = val.AddComponent<ForbiddenWeaponTypeCondition>();
			Object.DontDestroyOnLoad((Object)(object)forbiddenWeaponTypeCondition);
			val.SetActive(false);
			val2.Condition = (EffectCondition)(object)forbiddenWeaponTypeCondition;
			forbiddenWeaponTypeCondition.ForbiddenWeaponTypes = forbiddenWeaponTypes;
			At.SetValue("Can not be used with a " + forbiddenWeaponTypes.OrConcat() + ".", typeof(ActivationCondition), val2, "m_defaultMessage");
			List<ActivationCondition> list = (At.GetValue(typeof(Skill), skill, "m_additionalConditions") as ActivationCondition[])?.ToList() ?? new List<ActivationCondition>();
			list.Add(val2);
			At.SetValue(list.ToArray(), typeof(Skill), skill, "m_additionalConditions");
			return val2;
		}
	}
	public class QuestKnowledgeCondition : EffectCondition
	{
		public int[] Quests;

		public LogicType Logic = LogicType.Any;

		protected override bool CheckIsValid(Character _affectedCharacter)
		{
			return QuestRequirements.HasQuestKnowledge(_affectedCharacter, Quests, Logic);
		}
	}
	public class StatusEffectsCondition : EffectCondition
	{
		public enum LogicType
		{
			Any,
			All
		}

		public string[] StatusEffectNames;

		public LogicType Logic = LogicType.Any;

		protected override bool CheckIsValid(Character _affectedCharacter)
		{
			StatusEffectManager statusEffectManager = ((_affectedCharacter != null) ? _affectedCharacter.StatusEffectMngr : null);
			if (statusEffectManager != null)
			{
				IEnumerable<bool> source = StatusEffectNames.Select((string x) => (Object)(object)statusEffectManager.GetStatusEffectOfName(x) != (Object)null);
				return (Logic == LogicType.Any) ? source.Any((bool x) => x) : source.All((bool x) => x);
			}
			return false;
		}
	}
	public class AddNewStatusEffectRandom : AddStatusEffectRandom
	{
		protected override bool TryTriggerConditions()
		{
			List<StatusEffect> list = base.Statuses.ToList();
			list.Shuffle();
			base.ForceID = -1;
			for (int i = 0; i < list.Count; i++)
			{
				StatusEffect val = list[i];
				if (!((Object)(object)val == (Object)null) && !((Object)(object)((Effect)this).m_affectedCharacter == (Object)null) && !((Effect)this).m_affectedCharacter.StatusEffectMngr.HasStatusEffect(val.EffectFamily))
				{
					base.ForceID = UnityEngineExtensions.IndexOf<StatusEffect>(base.Statuses, val);
					break;
				}
			}
			return ((AddStatusEffectRandom)this).TryTriggerConditions();
		}
	}
	public class PunctualDamageSecondaryScaling : PunctualDamage
	{
		public Types ScalingToType;

		public DamageType[] BaseDamage;

		public DamageType[] ScaledDamage
		{
			get
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Expected O, but got Unknown
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Expected O, but got Unknown
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Expected O, but got Unknown
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_0042: Expected O, but got Unknown
				//IL_0077: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0083: Unknown result type (might be due to invalid IL or missing references)
				//IL_0085: Unknown result type (might be due to invalid IL or missing references)
				//IL_008a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0094: Expected O, but got Unknown
				DamageList val = DamageList.CreateEmptyCopy(new DamageList(BaseDamage)) + new DamageList(BaseDamage);
				DamageList val2 = DamageList.CreateEmptyCopy(new DamageList(BaseDamage)) + new DamageList(BaseDamage);
				Character sourceCharacter = ((Effect)this).SourceCharacter;
				if (sourceCharacter != null)
				{
					CharacterStats stats = sourceCharacter.Stats;
					if (stats != null)
					{
						stats.GetAmplifiedDamage((IList<Tag>)(object)new Tag[0], ref val2);
					}
				}
				float damage = val2.TotalDamage - val.TotalDamage;
				val.Add(new DamageType
				{
					Damage = damage,
					Type = ScalingToType
				});
				return val.List.ToArray();
			}
		}

		protected override void ActivateLocally(Character _affectedCharacter, object[] _infos)
		{
			base.Damages = ScaledDamage;
			((PunctualDamage)this).ActivateLocally(_affectedCharacter, _infos);
		}
	}
	public class EnableHitDetection : Effect
	{
		protected override void ActivateLocally(Character _affectedCharacter, object[] _infos)
		{
			Item parentItem = ((Effect)this).ParentItem;
			MeleeSkill val = (MeleeSkill)(object)((parentItem is MeleeSkill) ? parentItem : null);
			if (val != null && (Object)(object)val.MeleeHitDetector != (Object)null)
			{
				MeleeHitDetector val2 = ((_affectedCharacter != null) ? _affectedCharacter.SkillMeleeDetector : null);
				if (val2 != null)
				{
					val2.HitStarted(-1);
					return;
				}
			}
			Weapon obj = ((_affectedCharacter != null) ? _affectedCharacter.CurrentWeapon : null);
			MeleeWeapon val3 = (MeleeWeapon)(object)((obj is MeleeWeapon) ? obj : null);
			if (val3 != null)
			{
				((Weapon)val3).HitStarted(-1);
			}
		}
	}
	public class RemoveItemFromInventory : Effect
	{
		public int ItemID;

		public int Amount = 1;

		public bool AffectOwner = false;

		protected override void ActivateLocally(Character _affectedCharacter, object[] _infos)
		{
			if (AffectOwner)
			{
				_affectedCharacter = ((Effect)this).OwnerCharacter;
			}
			CharacterInventory inventory = _affectedCharacter.Inventory;
			if (inventory != null)
			{
				inventory.RemoveItem(ItemID, Amount);
			}
		}
	}
	public class CooldownChangeEffect : Effect
	{
		public float HitKnockbackCooldown = -1f;

		protected override void ActivateLocally(Character _affectedCharacter, object[] _infos)
		{
			Item parentItem = ((Effect)this).ParentItem;
			Skill val = (Skill)(object)((parentItem is Skill) ? parentItem : null);
			if (val != null && HitKnockbackCooldown != -1f && _affectedCharacter.IsInKnockback)
			{
				At.SetValue(HitKnockbackCooldown, typeof(Skill), val, "m_remainingCooldownTime");
			}
		}
	}
	public class EquipSkillDurabilityCondition : EquipDurabilityCondition
	{
		protected override bool CheckIsValid(Character _affectedCharacter)
		{
			Skill component = ((Component)((Component)this).transform.parent.parent).gameObject.GetComponent<Skill>();
			if (component != null)
			{
				base.DurabilityRequired = component.DurabilityCost;
			}
			return ((EquipDurabilityCondition)this).CheckIsValid(_affectedCharacter);
		}

		public static ActivationCondition AddToSkill(Skill skill, EquipmentSlotIDs slot)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			Transform orMake = TinyGameObjectManager.GetOrMake(((Component)skill).transform, "AdditionalActivationConditions", setActive: true, dontDestroyOnLoad: true);
			GameObject gameObject = ((Component)TinyGameObjectManager.GetOrMake(orMake, "EquipSkillDurabilityCondition", setActive: true, dontDestroyOnLoad: true)).gameObject;
			ActivationCondition val = new ActivationCondition();
			EquipSkillDurabilityCondition equipSkillDurabilityCondition = gameObject.AddComponent<EquipSkillDurabilityCondition>();
			((EquipDurabilityCondition)equipSkillDurabilityCondition).EquipmentSlot = slot;
			val.Condition = (EffectCondition)(object)equipSkillDurabilityCondition;
			At.SetValue("A required piece of equipment is missing or too damaged to be used this way.", typeof(ActivationCondition), val, "m_defaultMessage");
			List<ActivationCondition> list = (At.GetValue(typeof(Skill), skill, "m_additionalConditions") as ActivationCondition[])?.ToList() ?? new List<ActivationCondition>();
			list.Add(val);
			At.SetValue(list.ToArray(), typeof(Skill), skill, "m_additionalConditions");
			return val;
		}

		public static ActivationCondition AddToSkillNotBroken(Skill skill, EquipmentSlotIDs slot)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			Transform orMake = TinyGameObjectManager.GetOrMake(((Component)skill).transform, "AdditionalActivationConditions", setActive: true, dontDestroyOnLoad: true);
			GameObject gameObject = ((Component)TinyGameObjectManager.GetOrMake(orMake, "EquipDurabilityCondition", setActive: true, dontDestroyOnLoad: true)).gameObject;
			ActivationCondition val = new ActivationCondition();
			EquipDurabilityCondition val2 = gameObject.AddComponent<EquipDurabilityCondition>();
			val2.EquipmentSlot = slot;
			val2.DurabilityRequired = 0f;
			val.Condition = (EffectCondition)(object)val2;
			At.SetValue("A required piece of equipment is missing or broken.", typeof(ActivationCondition), val, "m_defaultMessage");
			List<ActivationCondition> list = (At.GetValue(typeof(Skill), skill, "m_additionalConditions") as ActivationCondition[])?.ToList() ?? new List<ActivationCondition>();
			list.Add(val);
			At.SetValue(list.ToArray(), typeof(Skill), skill, "m_additionalConditions");
			return val;
		}
	}
	public class AffectCorruption : Effect
	{
		public float AffectQuantity = 0f;

		public bool AffectOwner = false;

		public bool IsRaw = false;

		protected override KeyValuePair<string, Type>[] GenerateSignature()
		{
			return new KeyValuePair<string, Type>[1]
			{
				new KeyValuePair<string, Type>("Value", typeof(float))
			};
		}

		public override void SetValue(string[] _data)
		{
			if (_data == null || _data.Length >= 1)
			{
				float.TryParse(_data[0], out AffectQuantity);
			}
		}

		protected override void ActivateLocally(Character _affectedCharacter, object[] _infos)
		{
			if (AffectOwner)
			{
				_affectedCharacter = ((Effect)this).OwnerCharacter;
			}
			if ((Object)(object)_affectedCharacter != (Object)null && _affectedCharacter.Alive && Object.op_Implicit((Object)(object)_affectedCharacter.PlayerStats))
			{
				_affectedCharacter.PlayerStats.AffectCorruptionLevel(AffectQuantity, !IsRaw);
			}
		}
	}
	public class UseMana : Effect
	{
		public float UsedMana = 0f;

		protected override void ActivateLocally(Character _affectedCharacter, object[] _infos)
		{
			_affectedCharacter.Stats.UseMana((Tag[])null, UsedMana);
		}
	}
	public class SpecificImbueCondition : EffectCondition
	{
		public ImbueEffectPreset imbueEffectPreset;

		private bool inverse = false;

		protected override bool CheckIsValid(Character _affectedCharacter)
		{
			Weapon val = ((_affectedCharacter != null) ? _affectedCharacter.CurrentWeapon : null);
			return val != null && val.HasImbuePreset(imbueEffectPreset);
		}

		public static ActivationCondition AddToSkill(Skill skill, ImbueEffectPreset imbueEffectPreset, bool inverse = false)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			GameObject val = new GameObject("SpecificImbueCondition");
			ActivationCondition val2 = new ActivationCondition();
			SpecificImbueCondition specificImbueCondition = val.AddComponent<SpecificImbueCondition>();
			Object.DontDestroyOnLoad((Object)(object)specificImbueCondition);
			val.SetActive(false);
			val2.Condition = (EffectCondition)(object)specificImbueCondition;
			specificImbueCondition.inverse = inverse;
			specificImbueCondition.imbueEffectPreset = imbueEffectPreset;
			At.SetValue("You do not have the required imbue effect.", typeof(ActivationCondition), val2, "m_defaultMessage");
			List<ActivationCondition> list = (At.GetValue(typeof(Skill), skill, "m_additionalConditions") as ActivationCondition[])?.ToList() ?? new List<ActivationCondition>();
			list.Add(val2);
			At.SetValue(list.ToArray(), typeof(Skill), skill, "m_additionalConditions");
			return val2;
		}
	}
	public class ExtendedAddStatusEffect : AddStatusEffect
	{
		public bool ExtendDuration = false;

		protected override void ActivateLocally(Character _targetCharacter, object[] _infos)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			StatusEffect status = base.Status;
			if (ExtendDuration)
			{
				bool? obj;
				if (_targetCharacter == null)
				{
					obj = null;
				}
				else
				{
					StatusEffectManager statusEffectMngr = _targetCharacter.StatusEffectMngr;
					obj = ((statusEffectMngr != null) ? new bool?(statusEffectMngr.HasStatusEffect(status.IdentifierName)) : null);
				}
				bool? flag = obj;
				if (flag.GetValueOrDefault())
				{
					StatusData statusData = status.StatusData;
					status.StatusData = new StatusData(statusData);
					StatusEffect statusEffectOfName = _targetCharacter.StatusEffectMngr.GetStatusEffectOfName(status.IdentifierName);
					float num = ((statusEffectOfName != null) ? statusEffectOfName.RemainingLifespan : 0f);
					float num2 = ((status.RemainingLifespan > 0f) ? status.RemainingLifespan : status.StartLifespan);
					status.StatusData.LifeSpan = num2 + num;
					((AddStatusEffect)this).ActivateLocally(_targetCharacter, _infos);
					status.StatusData = statusData;
					return;
				}
			}
			((AddStatusEffect)this).ActivateLocally(_targetCharacter, _infos);
		}
	}
	public static class AnimatorExtension
	{
		public static bool HasParameter(this Animator animator, string paramName)
		{
			AnimatorControllerParameter[] parameters = animator.parameters;
			foreach (AnimatorControllerParameter val in parameters)
			{
				if (val.name == paramName)
				{
					return true;
				}
			}
			return false;
		}
	}
	public class TinyCharacterManager
	{
		public static Character SpawnCharacter(string uid, Vector3 position, Vector3 rotation)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			Character character = CharacterManager.Instance.GetCharacter(uid);
			if ((Object)(object)character != (Object)null)
			{
				return character;
			}
			object[] array = new object[4]
			{
				4,
				"NewPlayerPrefab",
				uid,
				string.Empty
			};
			GameObject val = PhotonNetwork.InstantiateSceneObject("_characters/NewPlayerPrefab", position, Quaternion.Euler(rotation), (byte)0, array);
			val.SetActive(false);
			Character component = val.GetComponent<Character>();
			component.SetUID(UID.op_Implicit(uid));
			At.SetValue<Character>(component, typeof(int), 1, "m_isAI");
			return component;
		}
	}
	public class TinyDialogueManager
	{
		public static GameObject AssignMerchantTemplate(Transform parentTransform)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(Resources.Load<GameObject>("editor/templates/MerchantTemplate"));
			val.transform.parent = parentTransform;
			val.transform.position = parentTransform.position;
			val.transform.rotation = parentTransform.rotation;
			return val;
		}

		public static GameObject AssignTrainerTemplate(Transform parentTransform)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(Resources.Load<GameObject>("editor/templates/TrainerTemplate"));
			val.transform.parent = parentTransform;
			val.transform.position = parentTransform.position;
			val.transform.rotation = parentTransform.rotation;
			return val;
		}

		public static DialogueActor SetDialogueActorName(GameObject dialogueGameObject, string name)
		{
			DialogueActor componentInChildren = dialogueGameObject.GetComponentInChildren<DialogueActor>();
			componentInChildren.SetName(name);
			return componentInChildren;
		}

		public static Merchant SetMerchant(GameObject merchantTemplate, UID merchantUID)
		{
			return merchantTemplate.GetComponentInChildren<Merchant>();
		}

		public static Trainer SetTrainerSkillTree(GameObject trainerTemplate, UID skillTreeUID)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			Trainer componentInChildren = trainerTemplate.GetComponentInChildren<Trainer>();
			At.SetValue<UID>(skillTreeUID, typeof(Trainer), componentInChildren, "m_skillTreeUID");
			return componentInChildren;
		}

		public static Graph GetDialogueGraph(GameObject trainerTemplate)
		{
			DialogueTreeController componentInChildren = trainerTemplate.GetComponentInChildren<DialogueTreeController>();
			return ((GraphOwner)componentInChildren).graph;
		}

		public static void SetActorReference(Graph graph, DialogueActor actor)
		{
			List<ActorParameter> list = At.GetValue(typeof(DialogueTree), (graph is DialogueTree) ? graph : null, "_actorParameters") as List<ActorParameter>;
			list[0].actor = (IDialogueActor)(object)actor;
			list[0].name = actor.name;
		}

		public static ActionNode MakeMerchantDialogueAction(Graph graph, Merchant merchant)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			ActionNode val = graph.AddNode<ActionNode>();
			ShopDialogueAction val2 = new ShopDialogueAction
			{
				Merchant = new BBParameter<Merchant>(merchant)
			};
			BBParameter<Character> obj = new BBParameter<Character>();
			((BBParameter)obj).name = "gInstigator";
			val2.PlayerCharacter = obj;
			ShopDialogueAction action = val2;
			val.action = (ActionTask)(object)action;
			return val;
		}

		public static ActionNode MakeTrainDialogueAction(Graph graph, Trainer trainer)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			ActionNode val = graph.AddNode<ActionNode>();
			TrainDialogueAction val2 = new TrainDialogueAction
			{
				Trainer = new BBParameter<Trainer>(trainer)
			};
			BBParameter<Character> obj = new BBParameter<Character>();
			((BBParameter)obj).name = "gInstigator";
			val2.PlayerCharacter = obj;
			TrainDialogueAction action = val2;
			val.action = (ActionTask)(object)action;
			return val;
		}

		public static ActionNode MakeStartQuest(Graph graph, int questID)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			ActionNode val = graph.AddNode<ActionNode>();
			GiveQuest val3 = (GiveQuest)(object)(val.action = (ActionTask)new GiveQuest());
			ref BBParameter<Quest> quest = ref val3.quest;
			Item itemPrefab = ResourcesPrefabManager.Instance.GetItemPrefab(questID);
			quest = new BBParameter<Quest>((Quest)(object)((itemPrefab is Quest) ? itemPrefab : null));
			return val;
		}

		public static ActionNode MakeQuestEvent(Graph graph, string EventUID)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			ActionNode val = graph.AddNode<ActionNode>();
			SendQuestEvent val3 = (SendQuestEvent)(object)(val.action = (ActionTask)new SendQuestEvent());
			val3.QuestEventRef = new QuestEventReference
			{
				EventUID = EventUID
			};
			return val;
		}

		public static ConditionNode MakeEventOccuredCondition(Graph graph, string EventUID, int MinStack)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			ConditionNode val = graph.AddNode<ConditionNode>();
			val.condition = (ConditionTask)new Condition_QuestEventOccured
			{
				QuestEventRef = new QuestEventReference
				{
					EventUID = EventUID
				},
				MinStack = MinStack
			};
			return val;
		}

		public static ConditionNode MakeHasItemCondition(Graph graph, int itemID, int MinStack)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			ConditionNode val = graph.AddNode<ConditionNode>();
			Condition_OwnsItem val2 = new Condition_OwnsItem();
			BBParameter<Character> obj = new BBParameter<Character>();
			((BBParameter)obj).name = "gInstigator";
			val2.character = obj;
			val2.item = new BBParameter<ItemReference>(new ItemReference
			{
				ItemID = itemID
			});
			val2.minAmount = new BBParameter<int>(MinStack);
			val2.itemMustBeEquiped = new BBParameter<bool>(false);
			val2.SaveMatchingContainerVariable = null;
			val.condition = (ConditionTask)val2;
			return val;
		}

		public static ConditionNode MakeHasItemConditionSimple(Graph graph, int itemID, int MinStack, int enchantment = 0)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			ConditionNode val = graph.AddNode<ConditionNode>();
			Condition_SimpleOwnsItem val2 = new Condition_SimpleOwnsItem();
			BBParameter<Character> obj = new BBParameter<Character>();
			((BBParameter)obj).name = "gInstigator";
			val2.character = obj;
			val2.item = new BBParameter<Item>(ResourcesPrefabManager.Instance.GetItemPrefab(itemID));
			val2.minAmount = new BBParameter<int>(MinStack);
			val.condition = (ConditionTask)val2;
			return val;
		}

		public static ActionNode MakeGiveItemReward(Graph graph, int itemID, Receiver receiver, int quantity = 1)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			ActionNode val = graph.AddNode<ActionNode>();
			GiveReward val3 = (GiveReward)(object)(val.action = (ActionTask)new GiveReward());
			val3.RewardReceiver = receiver;
			ItemQuantity val4 = new ItemQuantity();
			ItemReference val5 = new ItemReference();
			val5.ItemID = itemID;
			val4.Item = new BBParameter<ItemReference>(val5);
			val4.Quantity = BBParameter<int>.op_Implicit(quantity);
			val3.ItemReward = new List<ItemQuantity> { val4 };
			return val;
		}

		public static ActionNode MakeResignItem(Graph graph, int itemID, Receiver provider, int quantity = 1, int enchantment = 0)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			ActionNode val = graph.AddNode<ActionNode>();
			RemoveItem val2 = new RemoveItem();
			BBParameter<Character> obj = new BBParameter<Character>();
			((BBParameter)obj).name = "gInstigator";
			val2.fromCharacter = obj;
			val2.Items = new List<BBParameter<ItemReference>>
			{
				new BBParameter<ItemReference>(new ItemReference
				{
					ItemID = itemID
				})
			};
			val2.Amount = new List<BBParameter<int>>
			{
				new BBParameter<int>(quantity)
			};
			val.action = (ActionTask)val2;
			return val;
		}

		public static StatementNodeExt MakeStatementNode(Graph graph, string name, string statementText)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			StatementNodeExt val = graph.AddNode<StatementNodeExt>();
			val.statement = new Statement(statementText);
			val.SetActorName(name);
			return val;
		}

		public static MultipleChoiceNodeExt MakeMultipleChoiceNode(Graph graph, string[] statementTexts)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_0037: Expected O, but got Unknown
			MultipleChoiceNodeExt val = graph.AddNode<MultipleChoiceNodeExt>();
			foreach (string text in statementTexts)
			{
				val.availableChoices.Add(new Choice
				{
					statement = new Statement
					{
						text = text
					}
				});
			}
			return val;
		}

		public static void ChainNodes(Graph graph, Node[] nodes)
		{
			Node val = null;
			foreach (Node val2 in nodes)
			{
				if (val != null)
				{
					graph.ConnectNodes(val, val2, -1, -1);
				}
				val = val2;
			}
		}

		public static void ConnectMultipleChoices(Graph graph, Node baseNode, Node[] nodes)
		{
			for (int i = 0; i < nodes.Length; i++)
			{
				graph.ConnectNodes(baseNode, nodes[i], i, -1);
			}
		}
	}
	public class TinyGameObjectManager
	{
		public static Transform GetOrMake(Transform parent, string child, bool setActive, bool dontDestroyOnLoad)
		{
			return parent.Find(child) ?? MakeFreshObject(child, setActive, dontDestroyOnLoad, parent).transform;
		}

		public static GameObject InstantiateClone(GameObject sourceGameObject, bool setActive, bool dontDestroyOnLoad)
		{
			return InstantiateClone(sourceGameObject, ((Object)sourceGameObject).name + "(Clone)", setActive, dontDestroyOnLoad);
		}

		public static GameObject InstantiateClone(GameObject sourceGameObject, string newGameObjectName, bool setActive, bool dontDestroyOnLoad)
		{
			GameObject val = Object.Instantiate<GameObject>(sourceGameObject);
			val.SetActive(setActive);
			((Object)val).name = newGameObjectName;
			if (dontDestroyOnLoad)
			{
				Object.DontDestroyOnLoad((Object)(object)val);
			}
			return val;
		}

		public static Transform MakeFreshTransform(Transform parent, string child, bool setActive, bool dontDestroyOnLoad)
		{
			return MakeFreshObject(child, setActive, dontDestroyOnLoad, parent).transform;
		}

		public static GameObject MakeFreshObject(string newGameObjectName, bool setActive, bool dontDestroyOnLoad, Transform parent = null)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			GameObject val = new GameObject(newGameObjectName);
			val.SetActive(setActive);
			if ((Object)(object)parent != (Object)null)
			{
				val.transform.SetParent(parent);
			}
			if (dontDestroyOnLoad)
			{
				RecursiveDontDestroyOnLoad(val.transform);
			}
			return val;
		}

		public static void RecursiveDontDestroyOnLoad(Transform transform)
		{
			Transform val = transform;
			while ((Object)(object)val.parent != (Object)null)
			{
				val = val.parent;
			}
			Object.DontDestroyOnLoad((Object)(object)((Component)val).gameObject);
		}
	}
	public enum Behaviour
	{
		Add,
		Purge,
		Replace
	}
	public class TinyItemManager
	{
		private static Dictionary<int, ItemLocalization> m_ItemLocalizationDictionary;

		private static Dictionary<string, Item> m_ItemPrefabDictionary;

		private static Dictionary<int, ItemLocalization> ItemLocalizationDictionary
		{
			get
			{
				if (m_ItemLocalizationDictionary == null)
				{
					m_ItemLocalizationDictionary = At.GetValue(typeof(LocalizationManager), LocalizationManager.Instance, "m_itemLocalization") as Dictionary<int, ItemLocalization>;
				}
				return m_ItemLocalizationDictionary;
			}
		}

		private static Dictionary<string, Item> ItemPrefabDictionary
		{
			get
			{
				if (m_ItemPrefabDictionary == null)
				{
					m_ItemPrefabDictionary = At.GetValue(typeof(ResourcesPrefabManager), null, "ITEM_PREFABS") as Dictionary<string, Item>;
				}
				return m_ItemPrefabDictionary;
			}
		}

		public static bool SetLegacyResult(int itemID, int legacyOutcomeID)
		{
			Item itemPrefab = ResourcesPrefabManager.Instance.GetItemPrefab(itemID);
			if ((Object)(object)itemPrefab != (Object)null)
			{
				itemPrefab.LegacyItemID = legacyOutcomeID;
				return true;
			}
			return false;
		}

		public static bool AddEnchantingOption(int itemID, int enchantingRecipeID)
		{
			//IL_0045: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			Item itemPrefab = ResourcesPrefabManager.Instance.GetItemPrefab(itemID);
			EnchantmentRecipe enchantmentRecipeForID = RecipeManager.Instance.GetEnchantmentRecipeForID(enchantingRecipeID);
			if ((Object)(object)enchantmentRecipeForID != (Object)null && (Object)(object)itemPrefab != (Object)null)
			{
				List<IngredientData> list = enchantmentRecipeForID.CompatibleEquipments.CompatibleEquipments.ToList();
				list.Add(new IngredientData
				{
					Type = (IngredientType)1,
					SpecificIngredient = itemPrefab
				});
				enchantmentRecipeForID.CompatibleEquipments = new EquipmentData
				{
					EquipmentTag = enchantmentRecipeForID.CompatibleEquipments.EquipmentTag,
					CompatibleEquipments = list.ToArray()
				};
				return true;
			}
			return false;
		}

		public static Item MakeItem(int newID, int targetID, string name = null, string description = null, string identifierName = null)
		{
			Item val = TryCloneTargetItem(newID, targetID, newID + "_" + identifierName);
			ApplyNameAndDescription(val, name, description);
			return val;
		}

		public static Skill MakeSkill(int newID, int targetID, string name = null, string description = null, string identifierName = null, int? manaCost = 0, int? staminaCost = 0, int? healthCost = 0, bool? ignoreLearnNotification = null, bool? hideInUI = null)
		{
			Item obj = MakeItem(newID, targetID, name, description, identifierName);
			Skill val = (Skill)(object)((obj is Skill) ? obj : null);
			if (manaCost.HasValue)
			{
				val.ManaCost = manaCost.GetValueOrDefault();
			}
			if (healthCost.HasValue)
			{
				val.HealthCost = healthCost.GetValueOrDefault();
			}
			if (staminaCost.HasValue)
			{
				val.StaminaCost = staminaCost.GetValueOrDefault();
			}
			val.IgnoreLearnNotification = ignoreLearnNotification.GetValueOrDefault();
			return val;
		}

		public static Item TryCloneTargetItem(int newID, int targetID, string identifierName = null)
		{
			Dictionary<string, Item> itemPrefabDictionary = ItemPrefabDictionary;
			Item item = GetItem(targetID.ToString());
			if ((Object)(object)item == (Object)null)
			{
				TinyHelper.TinyHelperPrint("Could not find target item with ID " + targetID + ".");
				return null;
			}
			if ((Object)(object)((Component)item).gameObject.GetComponent<Item>() == (Object)null)
			{
				TinyHelper.TinyHelperPrint(((Object)item).name + " is does not have an Item component.");
				return null;
			}
			GameObject val = Object.Instantiate<GameObject>(((Component)item).gameObject);
			val.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)val);
			Item component = val.GetComponent<Item>();
			component.ItemID = newID;
			((Object)component).name = identifierName ?? (newID + "_" + component.Name.Replace(" ", ""));
			ItemPrefabDictionary.Add(component.ItemID.ToString(), component);
			return component;
		}

		public static void ApplyNameAndDescription(Item item, string name, string description)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			ItemLocalization value = new ItemLocalization(name, description);
			At.SetValue(name, typeof(Item), item, "m_name");
			if (ItemLocalizationDictionary.ContainsKey(item.ItemID))
			{
				ItemLocalizationDictionary[item.ItemID] = value;
			}
			else
			{
				ItemLocalizationDictionary.Add(item.ItemID, value);
			}
		}

		private static Item GetItem(int itemID)
		{
			return GetItem(itemID.ToString());
		}

		private static Item GetItem(string itemID)
		{
			return ItemPrefabDictionary[itemID];
		}
	}
	public class TinyHelperRPCManager : MonoBehaviour
	{
		public static TinyHelperRPCManager Instance;

		internal void Start()
		{
			Instance = this;
			PhotonView val = ((Component)this).gameObject.AddComponent<PhotonView>();
			val.viewID = 954;
			Debug.Log((object)("Registered TinyHelpertRPC with ViewID " + ((MonoBehaviour)this).photonView.viewID));
		}

		[PunRPC]
		public void ApplyAddImbueEffectRPC(string weaponGUID, int infusionID, float duration)
		{
			Item item = ItemManager.Instance.GetItem(weaponGUID);
			Weapon val = (Weapon)(object)((item is Weapon) ? item : null);
			? val2 = val;
			EffectPreset effectPreset = ResourcesPrefabManager.Instance.GetEffectPreset(infusionID);
			((Weapon)val2).AddImbueEffect((ImbueEffectPreset)(object)((effectPreset is ImbueEffectPreset) ? effectPreset : null), duration, (ImbueStack)null);
		}

		[PunRPC]
		public void CharacterForceCancelRPC(string characterGUID, bool bool1, bool bool2)
		{
			Character character = CharacterManager.Instance.GetCharacter(characterGUID);
			character.ForceCancel(bool1, bool2);
		}
	}
	public class QuestRequirements
	{
		public static bool HasQuestEvent(string questEventUID)
		{
			return QuestEventManager.Instance.GetEventCurrentStack(questEventUID) > 0;
		}

		public static bool HasQuestKnowledge(Character character, int[] questIDs, LogicType logicType, bool inverted = false, bool requireCompleted = false)
		{
			bool flag = false;
			object obj;
			if (character == null)
			{
				obj = null;
			}
			else
			{
				CharacterInventory inventory = character.Inventory;
				obj = ((inventory != null) ? inventory.QuestKnowledge : null);
			}
			CharacterQuestKnowledge q = (CharacterQuestKnowledge)obj;
			if (q != null)
			{
				IEnumerable<bool> source = questIDs.Select((int x) => ((CharacterKnowledge)q).IsItemLearned(x) && (q.IsQuestCompleted(x) || !requireCompleted));
				flag = flag || ((logicType == LogicType.Any) ? source.Any((bool x) => x) : source.All((bool x) => x));
			}
			return flag ^ inverted;
		}

		public static bool HasQuestKnowledgeLocal(Character character, int[] questIDs, LogicType logicType, bool inverted = false, bool requireCompleted = false)
		{
			bool flag = false;
			object obj;
			if (character == null)
			{
				obj = null;
			}
			else
			{
				CharacterInventory inventory = character.Inventory;
				obj = ((inventory != null) ? inventory.QuestKnowledge : null);
			}
			CharacterQuestKnowledge q = (CharacterQuestKnowledge)obj;
			if (q != null)
			{
				IEnumerable<bool> source = questIDs.Select((int x) => q.IsItemLearnedLocal(x) && (q.IsQuestCompletedLocal(x) || !requireCompleted));
				flag = flag || ((logicType == LogicType.Any) ? source.Any((bool x) => x) : source.All((bool x) => x));
			}
			return flag ^ inverted;
		}
	}
	public enum LogicType
	{
		Any,
		All
	}
	public class SkillRequirements
	{
		public static bool SafeHasSkillKnowledge(Character character, int skillID)
		{
			bool? obj;
			if (character == null)
			{
				obj = null;
			}
			else
			{
				CharacterInventory inventory = character.Inventory;
				if (inventory == null)
				{
					obj = null;
				}
				else
				{
					CharacterSkillKnowledge skillKnowledge = inventory.SkillKnowledge;
					obj = ((skillKnowledge != null) ? new bool?(((CharacterKnowledge)skillKnowledge).IsItemLearned(skillID)) : null);
				}
			}
			bool? flag = obj;
			return flag.GetValueOrDefault();
		}
	}
	public class CustomTexture
	{
		public enum SpriteBorderTypes
		{
			None,
			Item,
			TrainerSkill
		}

		public enum IconName
		{
			m_itemIcon,
			SkillTreeIcon
		}

		private static Dictionary<string, byte[]> m_loadedTextures;

		private static Dictionary<string, byte[]> LoadedTextures
		{
			get
			{
				if (m_loadedTextures == null)
				{
					m_loadedTextures = new Dictionary<string, byte[]>();
				}
				return m_loadedTextures;
			}
		}

		public static Texture2D LoadTexture(string filePath, int mipCount, bool linear, FilterMode filterMode, float? mipMapBias = null, string rootPath = null)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			filePath = (rootPath ?? TinyHelper.PLUGIN_ROOT_PATH) + filePath;
			if (!LoadedTextures.ContainsKey(filePath))
			{
				LoadedTextures[filePath] = File.ReadAllBytes(filePath);
			}
			Texture2D val = new Texture2D(4, 4, (TextureFormat)12, mipCount > 0, linear);
			((Texture)val).filterMode = filterMode;
			((Texture)val).mipMapBias = mipMapBias ?? ((Texture)val).mipMapBias;
			ImageConversion.LoadImage(val, LoadedTextures[filePath]);
			((Texture)val).filterMode = (FilterMode)1;
			return val;
		}

		public static Sprite MakeSprite(Texture2D texture, SpriteBorderTypes spriteBorderType)
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			float num;
			float num2;
			float num3;
			float num4;
			switch (spriteBorderType)
			{
			case SpriteBorderTypes.Item:
				num = 1f;
				num2 = 2f;
				num3 = 2f;
				num4 = 3f;
				break;
			case SpriteBorderTypes.TrainerSkill:
				num = 1f;
				num2 = 1f;
				num3 = 1f;
				num4 = 2f;
				break;
			default:
				num = 0f;
				num2 = 0f;
				num3 = 0f;
				num4 = 0f;
				break;
			}
			return Sprite.Create(texture, new Rect(num, num3, (float)((Texture)texture).width - num2, (float)((Texture)texture).height - num4), new Vector2(0f, 0f), 100f, 0u);
		}
	}
	public class CooldownChangeWeaponDamageTargetHealth : WeaponDamageTargetHealth
	{
		public float ExecuteSetCooldown = -1f;

		public float HitKnockbackCooldown = -1f;

		protected override void ActivateLocally(Character _affectedCharacter, object[] _infos)
		{
			Item parentItem = ((Effect)this).ParentItem;
			Skill val = (Skill)(object)((parentItem is Skill) ? parentItem : null);
			if (val != null)
			{
				if (HitKnockbackCooldown != -1f && _affectedCharacter.IsInKnockback)
				{
					At.SetValue(HitKnockbackCooldown, typeof(Skill), val, "m_remainingCooldownTime");
				}
				bool isDead = _affectedCharacter.IsDead;
				((WeaponDamage)this).ActivateLocally(_affectedCharacter, _infos);
				if (!isDead && _affectedCharacter.IsDead && ExecuteSetCooldown != -1f)
				{
					At.SetValue(ExecuteSetCooldown, typeof(Skill), val, "m_remainingCooldownTime");
				}
			}
		}
	}
	public class ToggleEffect : Effect
	{
		public StatusEffect StatusEffectInstance;

		protected override void ActivateLocally(Character _affectedCharacter, object[] _infos)
		{
			if (_affectedCharacter.StatusEffectMngr.HasStatusEffect(StatusEffectInstance.IdentifierName))
			{
				_affectedCharacter.StatusEffectMngr.CleanseStatusEffect(((Object)StatusEffectInstance).name);
			}
			else
			{
				_affectedCharacter.StatusEffectMngr.AddStatusEffect(StatusEffectInstance, ((Effect)this).SourceCharacter);
			}
		}
	}
	public class AddThenSpreadStatus : AddStatusEffect
	{
		public float Range;

		protected override void ActivateLocally(Character _affectedCharacter, object[] _infos)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			if (base.AffectController)
			{
				_affectedCharacter = ((Effect)this).OwnerCharacter;
			}
			if ((Object)(object)((_affectedCharacter != null) ? _affectedCharacter.StatusEffectMngr : null) == (Object)null || (Object)(object)base.Status == (Object)null)
			{
				return;
			}
			if (_affectedCharacter.StatusEffectMngr.HasStatusEffect(base.Status.IdentifierName))
			{
				List<Character> source = new List<Character>();
				CharacterManager.Instance.FindCharactersInRange(_affectedCharacter.CenterPosition, Range, ref source);
				foreach (Character item in source.Where((Character c) => !c.IsAlly(((Effect)this).SourceCharacter)))
				{
					((AddStatusEffect)this).ActivateLocally(item, _infos);
				}
			}
			((AddStatusEffect)this).ActivateLocally(_affectedCharacter, _infos);
		}
	}
	public class EmptyOffHandCondition : EffectCondition
	{
		public bool AllowDrawnTwoHandedInRight = false;

		public bool AllowSheathedTwoHandedInLeft = false;

		protected override bool CheckIsValid(Character _affectedCharacter)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_affectedCharacter == (Object)null)
			{
				goto IL_00dc;
			}
			bool? obj;
			if (_affectedCharacter == null)
			{
				obj = null;
			}
			else
			{
				Equipment leftHandEquipment = _affectedCharacter.LeftHandEquipment;
				obj = ((leftHandEquipment != null) ? new bool?(((Item)leftHandEquipment).HasTag(TinyTagManager.GetOrMakeTag("HandsFreeTag"))) : null);
			}
			if (obj ?? true)
			{
				bool? obj2;
				if (_affectedCharacter == null)
				{
					obj2 = null;
				}
				else
				{
					Weapon currentWeapon = _affectedCharacter.CurrentWeapon;
					obj2 = ((currentWeapon != null) ? new bool?(((Equipment)currentWeapon).TwoHanded) : null);
				}
				bool? flag = obj2;
				if (!flag.GetValueOrDefault())
				{
					goto IL_00dc;
				}
			}
			if (!_affectedCharacter.Sheathed && AllowDrawnTwoHandedInRight)
			{
				Weapon currentWeapon2 = _affectedCharacter.CurrentWeapon;
				if (currentWeapon2 == null || ((Equipment)currentWeapon2).TwoHandedRight)
				{
					goto IL_00dc;
				}
			}
			int result;
			if (_affectedCharacter.Sheathed && AllowSheathedTwoHandedInLeft)
			{
				Weapon currentWeapon3 = _affectedCharacter.CurrentWeapon;
				result = ((currentWeapon3 == null || ((Equipment)currentWeapon3).TwoHandedRight) ? 1 : 0);
			}
			else
			{
				result = 0;
			}
			goto IL_00dd;
			IL_00dc:
			result = 1;
			goto IL_00dd;
			IL_00dd:
			return (byte)result != 0;
		}

		public static ActivationCondition AddToSkill(Skill skill, bool allowDrawnTwoHandedInRight = false, bool allowSheathedTwoHandedInLeft = false)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			GameObject val = new GameObject("EmptyOffhandCondition");
			ActivationCondition val2 = new ActivationCondition();
			EmptyOffHandCondition emptyOffHandCondition = val.AddComponent<EmptyOffHandCondition>();
			Object.DontDestroyOnLoad((Object)(object)emptyOffHandCondition);
			val.SetActive(false);
			val2.Condition = (EffectCondition)(object)emptyOffHandCondition;
			emptyOffHandCondition.AllowDrawnTwoHandedInRight = allowDrawnTwoHandedInRight;
			emptyOffHandCondition.AllowSheathedTwoHandedInLeft = allowSheathedTwoHandedInLeft;
			At.SetValue("Requires an empty left hand.", typeof(ActivationCondition), val2, "m_defaultMessage");
			List<ActivationCondition> list = (At.GetValue(typeof(Skill), skill, "m_additionalConditions") as ActivationCondition[])?.ToList() ?? new List<ActivationCondition>();
			list.Add(val2);
			At.SetValue(list.ToArray(), typeof(Skill), skill, "m_additionalConditions");
			return val2;
		}
	}
	internal class InputEnablerEffect : Effect
	{
		protected override void ActivateLocally(Character _affectedCharacter, object[] _infos)
		{
			StatusEffect parentStatusEffect = base.m_parentStatusEffect;
			if (parentStatusEffect != null && (double)((_affectedCharacter != null) ? _affectedCharacter.AnimMoveSqMagnitude : 0f) > 0.1 && (double)parentStatusEffect.Age > 0.5)
			{
				StatusEffectManager statusEffectMngr = _affectedCharacter.StatusEffectMngr;
				if (statusEffectMngr != null)
				{
					statusEffectMngr.CleanseStatusEffect(parentStatusEffect.IdentifierName);
				}
				_affectedCharacter.ForceCancel(true, true);
			}
		}
	}
	internal class TinyUnofficialPatches
	{
	}
	[HarmonyPatch(typeof(Skill), "HasEnoughMana")]
	public class Skill_HasEnoughMana
	{
		[HarmonyPostfix]
		public static void Postfix(Skill __instance, ref bool _tryingToActivate, ref bool __result)
		{
			if (__instance.ManaCost <= 0f)
			{
				__result = true;
			}
		}
	}
	[HarmonyPatch(typeof(Skill), "HasEnoughStamina")]
	public class Skill_HasEnoughStamina
	{
		[HarmonyPostfix]
		public static void Postfix(Skill __instance, ref bool _tryingToActivate, ref bool __result)
		{
			if (__instance.StaminaCost <= 0f)
			{
				__result = true;
			}
		}
	}
	[HarmonyPatch(typeof(Skill), "HasEnoughHealth")]
	public class Skill_HasEnoughHealth
	{
		[HarmonyPostfix]
		public static void Postfix(Skill __instance, ref bool _tryingToActivate, ref bool __result)
		{
			if (__instance.HealthCost <= 0f)
			{
				__result = true;
			}
		}
	}
	public class WeaponManager
	{
		public static Dictionary<WeaponType, float> Speeds = new Dictionary<WeaponType, float>
		{
			{
				(WeaponType)0,
				1.251f
			},
			{
				(WeaponType)1,
				1.399f
			},
			{
				(WeaponType)2,
				1.629f
			},
			{
				(WeaponType)51,
				1.71f
			},
			{
				(WeaponType)52,
				1.667f
			},
			{
				(WeaponType)53,
				2.036f
			},
			{
				(WeaponType)54,
				1.499f
			},
			{
				(WeaponType)50,
				1.612f
			}
		};

		public static Dictionary<WeaponType, float> HeavyImpactModifiers = new Dictionary<WeaponType, float>
		{
			{
				(WeaponType)0,
				1.3f
			},
			{
				(WeaponType)1,
				1.3f
			},
			{
				(WeaponType)2,
				2.5f
			},
			{
				(WeaponType)51,
				1.5f
			},
			{
				(WeaponType)52,
				1.3f
			},
			{
				(WeaponType)53,
				2f
			},
			{
				(WeaponType)54,
				1.2f
			},
			{
				(WeaponType)50,
				1.3f
			}
		};
	}
	public class TinyTagManager
	{
		public static Tag GetOrMakeTag(string name)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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)
			Tag val = ((IEnumerable<Tag>)TagSourceManager.Instance.DbTags).FirstOrDefault((Func<Tag, bool>)((Tag x) => x.TagName == name));
			if (val == Tag.None)
			{
				((Tag)(ref val))..ctor(TagSourceManager.TagRoot, name);
				((Tag)(ref val)).SetTagType((TagTypes)0);
				TagSourceManager.Instance.DbTags.Add(val);
				TagSourceManager.Instance.RefreshTags(true);
				return val;
			}
			return val;
		}

		public static string[] GetOrMakeTags(string[] names)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			foreach (string name in names)
			{
				GetOrMakeTag(name);
			}
			return names;
		}

		public static string[] GetSafeTags(string[] tags)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			List<string> list = new List<string>();
			foreach (string tag in tags)
			{
				((IEnumerable<Tag>)TagSourceManager.Instance.DbTags).FirstOrDefault((Func<Tag, bool>)((Tag x) => x.TagName == tag || ((Tag)(ref x)).UID == UID.op_Implicit(tag)));
				if (true)
				{
					list.Add(tag);
				}
			}
			return list.ToArray();
		}
	}
	public class TinyUIDManager
	{
		public static UID MakeUID(string name, string modGUID, string category)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			if (modGUID == null || name == null || category == null)
			{
				Debug.LogError((object)$"TinyUIDManager.MakeUID({name}, {modGUID}, {category} returned a random UID. This will cause trouble in multiplayer!");
				return default(UID);
			}
			return new UID((modGUID + "." + category + "." + name).Replace(" ", "").ToLower());
		}
	}
	[BepInPlugin("com.ehaugw.tinyhelper", "Tiny Helper", "4.8.4")]
	public class TinyHelper : BaseUnityPlugin
	{
		public delegate void DescriptionModifier(Item item, ref string description);

		[HarmonyPatch(typeof(ResourcesPrefabManager), "Load")]
		public class ResourcesPrefabManager_Load
		{
			[HarmonyPostfix]
			public static void Postfix()
			{
				ResourcesPrefabManager instance = ResourcesPrefabManager.Instance;
				if (instance != null && instance.Loaded)
				{
					TinyHelper.OnPrefabLoaded();
				}
			}
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		public class Item_Description
		{
			[HarmonyPostfix]
			public static void Postfix(Item __instance, ref string __result)
			{
				OnDescriptionModified(__instance, ref __result);
			}
		}

		public const string GUID = "com.ehaugw.tinyhelper";

		public const string VERSION = "4.8.4";

		public const string NAME = "Tiny Helper";

		public static DescriptionModifier OnDescriptionModified;

		public static TinyHelper Instance;

		private static int tinyHelperPrintedMessages;

		public static string PLUGIN_ROOT_PATH => typeof(TinyHelper).Assembly.Location + "\\..\\..\\";

		public static event Action OnPrefabLoaded;

		internal void Awake()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			Instance = this;
			GameObject val = new GameObject("TinyHelperRPC");
			Object.DontDestroyOnLoad((Object)(object)val);
			val.AddComponent<TinyHelperRPCManager>();
			Harmony val2 = new Harmony("com.ehaugw.tinyhelper");
			val2.PatchAll();
		}

		public static void TinyHelperPrint(string str)
		{
			Debug.Log((object)("TinyHelper #" + tinyHelperPrintedMessages++ + ": " + str));
		}

		static TinyHelper()
		{
			TinyHelper.OnPrefabLoaded = delegate
			{
			};
			OnDescriptionModified = delegate
			{
			};
			tinyHelperPrintedMessages = 0;
		}
	}
	public class DelayedTask
	{
		public static Task GetTask(int milliseconds)
		{
			TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
			new Timer(delegate
			{
				tcs.SetResult(null);
			}).Change(milliseconds, -1);
			return tcs.Task;
		}
	}
	public class TinyEffectManager
	{
		public static StatusEffect MakeStatusEffectPrefab(string effectName, string familyName, string description, float lifespan, float refreshRate, StackBehaviors stackBehavior, string targetStatusName, bool isMalusEffect, string tagID = null, UID? uid = null, string modGUID = null, string iconFileName = null, string displayName = null, string rootPath = null)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: 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_0168: Expected O, but got Unknown
			//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_018f: Expected O, but got Unknown
			//IL_0194: Expected O, but got Unknown
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Expected O, but got Unknown
			Dictionary<string, StatusEffect> dictionary = At.GetValue(typeof(ResourcesPrefabManager), null, "STATUSEFFECT_PREFABS") as Dictionary<string, StatusEffect>;
			StatusEffectFamily val = MakeStatusEffectFamiliy(familyName, stackBehavior, -1, (LengthTypes)0);
			GameObject val2 = TinyGameObjectManager.InstantiateClone(((Component)dictionary[targetStatusName]).gameObject, effectName, setActive: false, dontDestroyOnLoad: true);
			StatusEffect obj = val2.GetComponent<StatusEffect>() ?? val2.AddComponent<StatusEffect>();
			StatusEffect val3 = obj;
			dictionary[effectName] = obj;
			StatusEffect val4 = val3;
			At.SetValue(effectName, typeof(StatusEffect), val4, "m_identifierName");
			At.SetValue<StatusEffectFamily>(val, typeof(StatusEffect), val4, "m_bindFamily");
			At.SetValue(displayName ?? effectName, typeof(StatusEffect), val4, "m_nameLocKey");
			At.SetValue(description, typeof(StatusEffect), val4, "m_descriptionLocKey");
			val4.RefreshRate = refreshRate;
			val4.IsMalusEffect = isMalusEffect;
			At.SetValue<EffectSignatureModes>((EffectSignatureModes)1, typeof(StatusEffect), val4, "m_effectSignatureMode");
			At.SetValue<FamilyModes>((FamilyModes)0, typeof(StatusEffect), val4, "m_familyMode");
			val4.RequiredStatus = null;
			val4.RemoveRequiredStatus = false;
			if (iconFileName != null)
			{
				val4.OverrideIcon = CustomTexture.MakeSprite(CustomTexture.LoadTexture(iconFileName, 0, linear: false, (FilterMode)0, null, rootPath), CustomTexture.SpriteBorderTypes.None);
			}
			TagSourceSelector value = ((tagID != null) ? new TagSourceSelector(TagSourceManager.Instance.GetTag(UID.op_Implicit(tagID))) : new TagSourceSelector());
			At.SetValue<TagSourceSelector>(value, typeof(StatusEffect), val4, "m_effectType");
			StatusData val5 = new StatusData(val4.StatusData);
			StatusData val6 = val5;
			val4.StatusData = val5;
			StatusData val7 = val6;
			val7.LifeSpan = lifespan;
			List<StatusData> list = At.GetValue(typeof(StatusEffect), val4, "m_statusStack") as List<StatusData>;
			list[0] = val7;
			Object.Destroy((Object)(object)((Component)val2.GetComponentInChildren<EffectSignature>()).gameObject);
			EffectSignature val8 = TinyGameObjectManager.MakeFreshObject("Signature", setActive: true, dontDestroyOnLoad: true).AddComponent<EffectSignature>();
			((Object)val8).name = "Signature";
			val8.SignatureUID = (UID)(((??)uid) ?? TinyUIDManager.MakeUID(effectName, modGUID, "Status Effect"));
			EffectSignature effectSignature = (val7.EffectSignature = val8);
			val.EffectSignature = effectSignature;
			StatusEffectFamilySelector val10 = new StatusEffectFamilySelector();
			((UidSelector<StatusEffectFamily>)(object)val10).Set(val);
			At.SetValue<StatusEffectFamilySelector>(val10, typeof(StatusEffect), val4, "m_stackingFamily");
			return val4;
		}

		public static StatusEffectFamily MakeStatusEffectFamiliy(string familyName, StackBehaviors stackBehavior, int maxStackCount, LengthTypes lengthType, UID? uid = null, string modGUID = null)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			StatusEffectFamily val = new StatusEffectFamily();
			uid = (UID)(((??)uid) ?? ((modGUID != null) ? TinyUIDManager.MakeUID(familyName, modGUID, "Status Effect Family") : UID.Generate()));
			At.SetValue<UID>(uid.Value, typeof(StatusEffectFamily), val, "m_uid");
			val.Name = familyName;
			val.StackBehavior = stackBehavior;
			val.MaxStackCount = maxStackCount;
			val.LengthType = lengthType;
			return val;
		}

		public static void SetNameAndDesc(EffectPreset imbueEffect, string name, string desc)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			ItemLocalization value = new ItemLocalization(name, desc);
			if (At.GetValue(typeof(LocalizationManager), LocalizationManager.Instance, "m_itemLocalization") is Dictionary<int, ItemLocalization> dictionary)
			{
				if (dictionary.ContainsKey(imbueEffect.PresetID))
				{
					dictionary[imbueEffect.PresetID] = value;
				}
				else
				{
					dictionary.Add(imbueEffect.PresetID, value);
				}
			}
		}

		public static AddStatusEffectBuildUp MakeStatusEffectBuildup(Transform effectTransform, string statusEffectName, float buildup)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			AddStatusEffectBuildUp val = ((Component)effectTransform).gameObject.AddComponent<AddStatusEffectBuildUp>();
			val.BuildUpValue = buildup;
			val.Status = ResourcesPrefabManager.Instance.GetStatusEffectPrefab(statusEffectName);
			((Effect)val).OverrideEffectCategory = (EffectCategories)4;
			return val;
		}

		public static AddStatusEffect MakeStatusEffectChance(Transform effectTransform, string statusEffectName, int chance)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			AddStatusEffect val = ((Component)effectTransform).gameObject.AddComponent<AddStatusEffect>();
			val.SetChanceToContract(chance);
			val.Status = ResourcesPrefabManager.Instance.GetStatusEffectPrefab(statusEffectName);
			((Effect)val).OverrideEffectCategory = (EffectCategories)4;
			return val;
		}

		public static WeaponDamage MakeWeaponDamage(Transform effectTransform, float baseDamage, float damageScaling, Types damageType, float knockback)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			WeaponDamage val = ((Component)effectTransform).gameObject.AddComponent<WeaponDamage>();
			val.WeaponDamageMult = 1f + damageScaling;
			val.OverrideDType = damageType;
			((PunctualDamage)val).Damages = (DamageType[])(object)new DamageType[1]
			{
				new DamageType(damageType, baseDamage)
			};
			((Effect)val).OverrideEffectCategory = (EffectCategories)4;
			((PunctualDamage)val).Knockback = knockback;
			return val;
		}

		public static WeaponDamage MakeDynamicWeaponDamage(Transform effectTransform, IDamageScaler damageScaler)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			DynamicWeaponDamage dynamicWeaponDamage = ((Component)effectTransform).gameObject.AddComponent<DynamicWeaponDamage>();
			((Effect)dynamicWeaponDamage).OverrideEffectCategory = (EffectCategories)4;
			dynamicWeaponDamage.DamageScaler = damageScaler;
			return (WeaponDamage)(object)dynamicWeaponDamage;
		}

		public static void MakeAbsorbHealth(Transform effectTransform, float absorbRatio)
		{
			AddAbsorbHealth obj = ((Component)effectTransform).gameObject.AddComponent<AddAbsorbHealth>();
			At.SetValue(absorbRatio, typeof(AddAbsorbHealth), obj, "m_healthRatio");
		}

		public static ImbueEffectPreset MakeImbuePreset(int imbueID, string name, string description, string iconFileName = null, int? visualEffectID = null, List<Skill> replaceOnSkills = null, string statusEffectName = null, int? chanceToContract = null, int? buildUp = null, float? scalingDamage = null, float? flatDamage = null, float? knockback = null, Types? damageType = null)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Expected O, but got I4
			//IL_023b->IL023b: Incompatible stack types: O vs I4
			//IL_0234->IL023b: Incompatible stack types: I4 vs O
			//IL_0234->IL023b: Incompatible stack types: O vs I4
			Dictionary<int, EffectPreset> dictionary = (Dictionary<int, EffectPreset>)At.GetValue(typeof(ResourcesPrefabManager), null, "EFFECTPRESET_PREFABS");
			if (!dictionary.ContainsKey(imbueID))
			{
				GameObject val = new GameObject(imbueID + "_" + name.Replace(" ", ""));
				val.SetActive(true);
				Object.DontDestroyOnLoad((Object)(object)val);
				ImbueEffectPreset val2 = val.AddComponent<ImbueEffectPreset>();
				((Object)val2).name = imbueID + "_" + name.Replace(" ", "");
				At.SetValue(imbueID, typeof(EffectPreset), val2, "m_StatusEffectID");
				At.SetValue(name, typeof(ImbueEffectPreset), val2, "m_imbueNameKey");
				At.SetValue(description, typeof(ImbueEffectPreset), val2, "m_imbueDescKey");
				if (visualEffectID.HasValue)
				{
					val2.ImbueStatusIcon = ((ImbueEffectPreset)dictionary[visualEffectID.Value]).ImbueStatusIcon;
					val2.ImbueFX = ((ImbueEffectPreset)dictionary[visualEffectID.Value]).ImbueFX;
				}
				if (iconFileName != null)
				{
					val2.ImbueStatusIcon = CustomTexture.MakeSprite(CustomTexture.LoadTexture(iconFileName, 0, linear: false, (FilterMode)0), CustomTexture.SpriteBorderTypes.None);
				}
				SetNameAndDesc((EffectPreset)(object)val2, name, description);
				dictionary.Add(imbueID, (EffectPreset)(object)val2);
				if (statusEffectName != null && chanceToContract.GetValueOrDefault() > 0)
				{
					MakeStatusEffectChance(TinyGameObjectManager.GetOrMake(((Component)val2).transform, "Effects", setActive: true, dontDestroyOnLoad: true), statusEffectName, chanceToContract.GetValueOrDefault());
				}
				if (statusEffectName != null && buildUp.GetValueOrDefault() > 0)
				{
					MakeStatusEffectBuildup(TinyGameObjectManager.GetOrMake(((Component)val2).transform, "Effects", setActive: true, dontDestroyOnLoad: true), statusEffectName, buildUp.GetValueOrDefault());
				}
				if (scalingDamage.GetValueOrDefault() > 0f || flatDamage.GetValueOrDefault() > 0f || knockback.GetValueOrDefault() > 0f)
				{
					object obj = TinyGameObjectManager.GetOrMake(((Component)val2).transform, "Effects", setActive: true, dontDestroyOnLoad: true);
					float valueOrDefault = flatDamage.GetValueOrDefault();
					valueOrDefault = scalingDamage.GetValueOrDefault();
					Types? val3 = damageType;
					int num;
					if (val3.HasValue)
					{
						obj = val3.GetValueOrDefault();
						num = (int)obj;
					}
					else
					{
						num = 9;
						obj = num;
						num = (int)obj;
					}
					MakeWeaponDamage((Transform)(object)num, valueOrDefault, valueOrDefault, (Types)obj, knockback.GetValueOrDefault());
				}
				foreach (Skill item in replaceOnSkills ?? new List<Skill>())
				{
					if ((Object)(object)item != (Object)null)
					{
						((ImbueObject)((Component)item).GetComponentInChildren<ImbueWeapon>()).ImbuedEffect = val2;
					}
				}
				return val2;
			}
			return null;
		}

		public static EffectPreset GetEffectPreset(int effectID)
		{
			Dictionary<int, EffectPreset> dictionary = (Dictionary<int, EffectPreset>)At.GetValue(typeof(ResourcesPrefabManager), null, "EFFECTPRESET_PREFABS");
			if (dictionary.ContainsKey(effectID))
			{
				EffectPreset val = dictionary[effectID];
				if (val != null)
				{
					return val;
				}
			}
			return null;
		}

		public static void AddStatusEffectForDuration(Character character, string _statusIdentifier, float duration, Character source = null, float chance = 1f)
		{
			StatusEffect statusEffectPrefab = ResourcesPrefabManager.Instance.GetStatusEffectPrefab(_statusIdentifier);
			AddStatusEffectForDuration(character, statusEffectPrefab, duration, source, chance);
		}

		public static void AddStatusEffectForDuration(Character character, StatusEffect statusEffect, float duration, Character source = null, float chance = 1f)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			StatusEffectManager statusEffectMngr = character.StatusEffectMngr;
			if (statusEffectMngr != null)
			{
				StatusData statusData = statusEffect.StatusData;
				statusEffect.StatusData = new StatusData(statusData);
				statusEffect.StatusData.LifeSpan = duration;
				statusEffectMngr.AddStatusEffect(statusEffect, source);
				statusEffect.StatusData = statusData;
			}
		}

		public static void ChangeEffectPresetDamageTypeData(EffectPreset effect, Types originalType, Types newType)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			PunctualDamage[] componentsInChildren = ((Component)effect).gameObject.GetComponentsInChildren<PunctualDamage>();
			foreach (PunctualDamage val in componentsInChildren)
			{
				WeaponDamage val2 = (WeaponDamage)(object)((val is WeaponDamage) ? val : null);
				if (val2 != null && val2.OverrideDType == originalType)
				{
					val2.OverrideDType = newType;
				}
				DamageType[] damages = val.Damages;
				foreach (DamageType val3 in damages)
				{
					if (val3.Type == originalType)
					{
						val3.Type = newType;
					}
				}
			}
		}
	}
	public class CasualStagger : Effect
	{
		protected override void ActivateLocally(Character _affectedCharacter, object[] _infos)
		{
			Stagger(_affectedCharacter);
		}

		public static void Stagger(Character character)
		{
			At.SetValue<HurtType>((HurtType)1, typeof(Character), character, "m_hurtType");
			character.Animator.SetTrigger("Knockback");
			character.ForceCancel(false, true);
			((MonoBehaviour)character).Invoke("DelayedForceCancel", 0.3f);
			if (Object.op_Implicit((Object)(object)character.CharacterUI))
			{
				character.CharacterUI.OnPlayerKnocked();
			}
		}
	}
	public class CooldownChangeWeaponDamage : WeaponDamage
	{
		public float ExecutionSetCooldown = -1f;

		public float HitKnockbackCooldown = -1f;

		protected override void ActivateLocally(Character _affectedCharacter, object[] _infos)
		{
			Item parentItem = ((Effect)this).ParentItem;
			Skill val = (Skill)(object)((parentItem is Skill) ? parentItem : null);
			if (val != null)
			{
				if (HitKnockbackCooldown != -1f && _affectedCharacter.IsInKnockback)
				{
					At.SetValue(HitKnockbackCooldown, typeof(Skill), val, "m_remainingCooldownTime");
				}
				bool isDead = _affectedCharacter.IsDead;
				((WeaponDamage)this).ActivateLocally(_affectedCharacter, _infos);
				if (!isDead && _affectedCharacter.IsDead && ExecutionSetCooldown != -1f)
				{
					At.SetValue(ExecutionSetCooldown, typeof(Skill), val, "m_remainingCooldownTime");
				}
			}
		}
	}
}
namespace TinyHelper.Interfaces
{
	public interface IDamageScaler
	{
		float GetWeaponDamageMult(WeaponDamage weaponDamage);

		Types GetOverrideDType(WeaponDamage weaponDamage);

		DamageType[] GetDamages(WeaponDamage weaponDamage);

		float GetKnockback(WeaponDamage weaponDamage);
	}
}
namespace TinyHelper.Effects
{
	public class DynamicWeaponDamage : WeaponDamage
	{
		public IDamageScaler DamageScaler = null;

		private void Recalculate()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			Console.WriteLine("recalculated");
			Debug.WriteLine("recalculated");
			base.WeaponDamageMult = DamageScaler.GetWeaponDamageMult((WeaponDamage)(object)this);
			base.OverrideDType = DamageScaler.GetOverrideDType((WeaponDamage)(object)this);
			((PunctualDamage)this).Damages = DamageScaler.GetDamages((WeaponDamage)(object)this);
			((PunctualDamage)this).Knockback = DamageScaler.GetKnockback((WeaponDamage)(object)this);
		}

		protected override void StartInit()
		{
			Recalculate();
			((WeaponDamage)this).StartInit();
		}

		public override Weapon BuildDamage(Character _targetCharacter, ref DamageList _list, ref float _knockback)
		{
			Recalculate();
			return ((WeaponDamage)this).BuildDamage(_targetCharacter, ref _list, ref _knockback);
		}

		protected override void BuildDamage(Weapon _weapon, Character _targetCharacter, bool _isSkillOrShield, ref DamageList _list, ref float _knockback)
		{
			Recalculate();
			((WeaponDamage)this).BuildDamage(_weapon, _targetCharacter, _isSkillOrShield, ref _list, ref _knockback);
		}

		protected override void ActivateLocally(Character _targetCharacter, object[] _infos)
		{
			Recalculate();
			((WeaponDamage)this).ActivateLocally(_targetCharacter, _infos);
		}

		protected override DamageList DealHit(Character _targetCharacter)
		{
			Recalculate();
			return ((WeaponDamage)this).DealHit(_targetCharacter);
		}

		public override float DamageMult(Character _targetCharacter, bool _isSkill)
		{
			Recalculate();
			return ((WeaponDamage)this).DamageMult(_targetCharacter, _isSkill);
		}

		public override float KnockbackMult(Character _targetCharacter, bool _isSkill)
		{
			Recalculate();
			return ((WeaponDamage)this).KnockbackMult(_targetCharacter, _isSkill);
		}
	}
	public class ShootBlastFromEffect : ShootBlast
	{
		public override void Setup(TargetingSystem _targetSystem, Transform _parent)
		{
			Character sourceCharacter = ((Effect)this).SourceCharacter;
			((Shooter)this).Setup(((sourceCharacter != null) ? sourceCharacter.TargetingSystem : null) ?? _targetSystem, _parent);
		}
	}
}