Decompiled source of MyriadJewels v0.1.4

MyriadJewels.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using JetBrains.Annotations;
using Jewelcrafting;
using Microsoft.CodeAnalysis;
using MyriadJewels.Effects.Bloodstone;
using MyriadJewels.Effects.Carnelian;
using MyriadJewels.Effects.Hematite;
using MyriadJewels.Effects.Howlite;
using MyriadJewels.Effects.MossAgate;
using MyriadJewels.Effects.Pyrite;
using MyriadJewels.Effects.Synergies;
using MyriadJewels.Effects.Tourmaline;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("MyriadJewels")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+b8c3d3c1b9840dfa998919a01d628943223572f0")]
[assembly: AssemblyProduct("MyriadJewels")]
[assembly: AssemblyTitle("MyriadJewels")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace MyriadJewels
{
	internal static class EffectRegistration
	{
		internal static void Register()
		{
			API.AddGemEffect<SpiritWolf.Config>("Spirit Wolf", "Summons a wolf cub that scales with your kit.", "Spirit wolf familiar; gem quality $1%.");
			API.AddGemEffect<CombatCrow.Config>("Combat Crow", "Summons a crow nestling that scales with your kit.", "Combat crow familiar; gem quality $1%.");
			API.AddGemEffect<SummonPotency.Config>("Summon Potency", "Familiar HP and damage up.", "Familiar power increased by $1%.");
			API.AddGemEffect<TrophyHunter.Config>("Trophy Hunter", "Trophy drops come easier.", "$1% trophy drop chance; $2% trophy weight reduction.");
			API.AddGemEffect<SecondWind.Config>("Second Wind", "Stamina recovers sooner after use.", "Stamina regen delay reduced by $1%.");
			API.AddGemEffect<CombatBreath.Config>("Combat Breath", "Attack and block cost less stamina.", "Attack and block stamina cost reduced by $1%.");
			API.AddGemEffect<EitrReservoir.Config>("Eitr Reservoir", "Increases maximum eitr.", "Maximum eitr increased by $1.");
			API.AddGemEffect<ClearHead.Config>("Clear Head", "Eitr returns faster after casting.", "Eitr regen delay reduced by $1%.");
			API.AddGemEffect<ManicCycle.Config>("Manic Cycle", "Faster adrenaline gain and decay.", "Adrenaline gain/decay rate +$1%.");
			API.AddGemEffect<SurgeDetonate.Config>("Surge Detonate", "Surge spends adrenaline for burst.", "On Surge, convert adrenaline into $1% burst.");
			API.AddGemEffect<OverchargeLean.Config>("Overcharge Lean", "Lean into Overcharge risk/reward.", "Overcharge effects amplified by $1%.");
			API.AddGemEffect<HighWaterAnchor.Config>("High-Water Anchor", "Resist decay while adrenaline is high.", "While high, adrenaline decay reduced by $1%.");
			API.AddGemEffect<CrestAmp.Config>("Crest Amp", "Power while adrenaline is high.", "While adrenaline ≥ threshold: +$1% combat power.");
			API.AddGemEffect<TrinketResonance.Config>("Trinket Resonance", "Battle Flow trinkets scale harder while high.", "BF trinket scaling +$1% while high.");
			API.AddGemEffect<LightningProc.Config>("Lightning Proc", "Chance on hit for lightning burst.", "$2% chance to deal $1% lightning damage.");
			API.AddGemEffect<SpiritHex.Config>("Spirit Hex", "Chance on hit for spirit damage.", "$2% chance to deal $1% spirit damage.");
			API.AddGemEffect<PhysicalBurst.Config>("Physical Burst", "Chance on hit for physical burst.", "$2% chance to deal $1% physical burst.");
			API.AddGemEffect<StaminaSiphon.Config>("Stamina Siphon", "Chance to restore stamina on block/hit.", "$2% chance to restore $1 stamina.");
			API.AddGemEffect<EitrSiphon.Config>("Eitr Siphon", "Chance to restore eitr on hit.", "$2% chance to restore $1 eitr.");
			API.AddGemEffect<AdrenalSpike.Config>("Adrenal Spike", "Chance on hit for adrenaline.", "$2% chance to gain $1 adrenaline.");
			API.AddGemEffect<AddSlash.Config>("Add Slash", "Chance to add slash damage.", "$2% chance to add $1% slash.");
			API.AddGemEffect<AddBlunt.Config>("Add Blunt", "Chance to add blunt damage.", "$2% chance to add $1% blunt.");
			API.AddGemEffect<AddPierce.Config>("Add Pierce", "Chance to add pierce damage.", "$2% chance to add $1% pierce.");
			API.AddGemEffect<AddLightning.Config>("Add Lightning", "Chance to add lightning damage.", "$2% chance to add $1% lightning.");
			API.AddGemEffect<AddSpirit.Config>("Add Spirit", "Chance to add spirit damage.", "$2% chance to add $1% spirit.");
			API.AddGemEffect<AddChopPick.Config>("Add Chop Pick", "Chance to add chop/pickaxe damage.", "$2% chance to add $1% tool damage.");
			API.AddGemEffect<ResistSlash.Config>("Resist Slash", "Reduces slash damage taken.", "Slash damage taken reduced by $1%.");
			API.AddGemEffect<ResistBlunt.Config>("Resist Blunt", "Reduces blunt damage taken.", "Blunt damage taken reduced by $1%.");
			API.AddGemEffect<ResistPierce.Config>("Resist Pierce", "Reduces pierce damage taken.", "Pierce damage taken reduced by $1%.");
			API.AddGemEffect<ResistFire.Config>("Resist Fire", "Reduces fire damage taken.", "Fire damage taken reduced by $1%.");
			API.AddGemEffect<ResistFrost.Config>("Resist Frost", "Reduces frost damage taken.", "Frost damage taken reduced by $1%.");
			API.AddGemEffect<ResistLightning.Config>("Resist Lightning", "Reduces lightning damage taken.", "Lightning damage taken reduced by $1%.");
			API.AddGemEffect<ResistPoison.Config>("Resist Poison", "Reduces poison damage taken.", "Poison damage taken reduced by $1%.");
			API.AddGemEffect<ResistSpirit.Config>("Resist Spirit", "Reduces spirit damage taken.", "Spirit damage taken reduced by $1%.");
			API.AddGemEffect<TwinBladeAptitude.Config>("Twin Blade Aptitude", "DualWield skill up.", "DualWield skill +$1%.");
			API.AddGemEffect<OffHandCatchUp.Config>("Off-Hand Catch-Up", "Softer off-hand penalty while dual.", "Off-hand penalty eased by $1%.");
			API.AddGemEffect<PairedRhythm.Config>("Paired Rhythm", "After dual hits, short attack speed.", "After dual hits: +$1% attack speed briefly.");
			API.AddGemEffect<ClawRake.Config>("Claw Rake", "Fist secondary assist.", "Fist secondary power +$1%.");
			API.AddGemEffect<KickThunder.Config>("Kick Thunder", "2H axe kick stagger.", "Kick stagger / blunt +$1%.");
			API.AddGemEffect<SledgeQuake.Config>("Sledge Quake", "Sledge special AOE/stagger.", "Sledge special power +$1%.");
			API.AddGemEffect<GreatWeaponPoise.Config>("Great Weapon Poise", "While 2H: stagger threshold up.", "2H stagger threshold +$1%.");
			API.AddGemEffect<GreatWeaponEconomy.Config>("Great Weapon Economy", "While 2H: attack stam cost down.", "2H attack stamina cost -$1%.");
			API.AddGemEffect<GreatWeaponSpecial.Config>("Great Weapon Special", "While 2H: secondary power up.", "2H secondary power +$1%.");
			API.AddGemEffect<GreatWeaponCommit.Config>("Great Weapon Commit", "While 2H: damage after heavy lands.", "After 2H secondary: +$1% damage briefly.");
			API.AddGemEffect<WellFedGrace.Config>("Well Fed Grace", "Bonus while Nature Well Fed.", "While Well Fed: +$1% to homestead bonuses.");
			API.AddGemEffect<Fieldcraft.Config>("Fieldcraft", "Farming, mining, lumber, foraging.", "Profession skills +$1%.");
			API.AddGemEffect<Outrider.Config>("Outrider", "Ranching, sailing, packhorse.", "Travel/ranch skills +$1%.");
			API.AddGemEffect<Craftmaster.Config>("Craftmaster", "Blacksmithing and building.", "Craft skills +$1%.");
			API.AddGemEffect<ExpertRuneforger.Config>("Expert Runeforger", "Runeforging skill.", "Runeforging +$1%.");
			API.AddGemEffect<ExpertAtgeir.Config>("Expert Atgeir", "Polearm skill.", "Polearms +$1%.");
			API.AddGemEffect<ExpertUnarmed.Config>("Expert Unarmed", "Fists skill.", "Unarmed +$1%.");
			API.AddGemEffect<ExpertSledge.Config>("Expert Sledge", "Sledge / 2H blunt skill.", "Clubs +$1%.");
			API.AddGemEffect<FamiliarBond.Config>("Familiar Bond", "Familiar duration and potency.", "Familiar duration/potency +$1%.");
			API.AddGemEffect<MoonHunt.Config>("Moon Hunt", "Night trophy hunt.", "At night: trophy chance +$1%.");
			API.AddGemEffect<ManicEngine.Config>("Manic Engine", "Overdrive Surge amp.", "Surge / detonate power +$1%.");
			API.AddGemEffect<CrestSovereign.Config>("Crest Sovereign", "Edge crest amp.", "Crest threshold/power +$1%.");
			API.AddGemEffect<FusedPulse.Config>("Fused Pulse", "High adren eitr return.", "While high adren: eitr return +$1%.");
			API.AddGemEffect<OpposedHearts.Config>("Opposed Hearts", "Surge AS / low DR.", "On Surge: AS +$1%; when low: DR +$2%.");
			API.AddGemEffect<TwinTempest.Config>("Twin Tempest", "DualWield cadence amp.", "Off-hand / rhythm ease +$1%.");
			API.AddGemEffect<GreatOath.Config>("Great Oath", "2H commit amp.", "2H special / commit +$1%.");
			API.AddGemEffect<Warpath.Config>("Warpath", "Stance hits feed adrenaline.", "Stance hits grant +$1 adrenaline.");
			API.AddGemEffect<SecondLung.Config>("Second Lung", "Economy sockets amp.", "Second Wind / Combat Breath +$1%.");
			API.AddGemEffect<OrangeReservoir.Config>("Orange Reservoir", "Eitr reservoir play.", "Eitr Reservoir / Clear Head +$1%.");
			API.AddGemEffect<Cascade.Config>("Cascade", "Pyrite proc chance up.", "Pyrite proc chances +$1%.");
			API.AddGemEffect<IronLattice.Config>("Iron Lattice", "Hematite resists amp.", "Hematite resists +$1%.");
			API.AddGemEffect<RootedCraft.Config>("Rooted Craft", "Profession sockets amp.", "Fieldcraft / Outrider / Craftmaster +$1%.");
			API.AddGemEffect<GreenThumb.Config>("Green Thumb", "Well Fed + green.", "Well Fed Grace +$1%.");
			API.AddGemEffect<FullLarder.Config>("Full Larder", "Food drain while Well Fed.", "Food drain -$1% while Well Fed.");
			API.AddGemEffect<RuneGrove.Config>("Rune Grove", "Runeforge gain.", "Runeforging gain +$1%.");
			API.AddGemEffect<PackAndPulse.Config>("Pack & Pulse", "Surge echoes to familiars.", "On Surge: familiars gain +$1% power briefly.");
		}
	}
	internal static class Gems
	{
		internal static void Register()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			API.AddGems("Howlite", "howlite", new Color(0.92f, 0.93f, 0.9f, 1f));
			API.AddGems("Carnelian", "carnelian", new Color(0.82f, 0.28f, 0.14f, 1f));
			API.AddGems("Bloodstone", "bloodstone", new Color(0.35f, 0.12f, 0.14f, 1f));
			API.AddGems("Pyrite", "pyrite", new Color(0.85f, 0.72f, 0.22f, 1f));
			API.AddGems("Hematite", "hematite", new Color(0.35f, 0.36f, 0.4f, 1f));
			API.AddGems("Tourmaline", "tourmaline", new Color(0.72f, 0.18f, 0.42f, 1f));
			API.AddGems("Moss Agate", "mossagate", new Color(0.35f, 0.55f, 0.28f, 1f));
		}
	}
	[HarmonyPatch(typeof(ZNetScene), "Awake")]
	internal static class HerbPlantableFix
	{
		private readonly struct HerbDef
		{
			public readonly string PickableName;

			public readonly string ItemName;

			public readonly string PieceName;

			public readonly string PieceDescription;

			public HerbDef(string pickableName, string itemName, string pieceName, string pieceDescription)
			{
				PickableName = pickableName;
				ItemName = itemName;
				PieceName = pieceName;
				PieceDescription = pieceDescription;
			}
		}

		private static readonly HerbDef[] Herbs = new HerbDef[2]
		{
			new HerbDef("Pickable_Sage_bal", "Sage_bal", "Sage", "Plant sage to grow more pickable sage."),
			new HerbDef("Pickable_Mint_bal", "Mint_bal", "Mint", "Plant mint to grow more pickable mint.")
		};

		[HarmonyPriority(0)]
		private static void Postfix(ZNetScene __instance)
		{
			((MonoBehaviour)__instance).StartCoroutine(CoFix());
		}

		private static IEnumerator CoFix()
		{
			for (int i = 0; i < 180; i++)
			{
				if (TryFix())
				{
					yield break;
				}
				yield return null;
			}
			Plugin.Log.LogWarning((object)"MyriadJewels: could not rebind sage/mint cultivator pickables.");
		}

		private static bool TryFix()
		{
			ZNetScene instance = ZNetScene.instance;
			ObjectDB instance2 = ObjectDB.instance;
			if (!Object.op_Implicit((Object)(object)instance) || !Object.op_Implicit((Object)(object)instance2))
			{
				return false;
			}
			List<PieceTable> cultivatorTables = GetCultivatorTables(instance2, instance);
			if (cultivatorTables.Count == 0)
			{
				return false;
			}
			bool result = true;
			HerbDef[] herbs = Herbs;
			foreach (HerbDef herb in herbs)
			{
				if (!FixHerb(instance, instance2, cultivatorTables, herb))
				{
					result = false;
				}
			}
			return result;
		}

		private static bool FixHerb(ZNetScene zns, ObjectDB odb, List<PieceTable> tables, HerbDef herb)
		{
			GameObject itemPrefab = odb.GetItemPrefab(herb.ItemName);
			GameObject val = FindPickablePrefab(zns, herb.PickableName, itemPrefab);
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)itemPrefab))
			{
				return false;
			}
			Pickable component = val.GetComponent<Pickable>();
			if (!Object.op_Implicit((Object)(object)component.m_itemPrefab))
			{
				component.m_itemPrefab = itemPrefab;
			}
			EnsureInZNetScene(zns, val);
			if (!Object.op_Implicit((Object)(object)val.GetComponent<Piece>()))
			{
				EnsurePiece(val, itemPrefab, zns, herb);
			}
			foreach (PieceTable table in tables)
			{
				SwapCultivatorPrefab(table, herb.ItemName, val);
			}
			return true;
		}

		private static GameObject? FindPickablePrefab(ZNetScene zns, string pickableName, GameObject item)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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)
			GameObject prefab = zns.GetPrefab(pickableName);
			if (IsWorldPickable(prefab, item))
			{
				return prefab;
			}
			GameObject[] array = Resources.FindObjectsOfTypeAll<GameObject>();
			foreach (GameObject val in array)
			{
				if (!Object.op_Implicit((Object)(object)val) || ((Object)val).name != pickableName)
				{
					continue;
				}
				Scene scene = val.scene;
				if (((Scene)(ref scene)).IsValid())
				{
					scene = val.scene;
					if (!string.IsNullOrEmpty(((Scene)(ref scene)).name))
					{
						continue;
					}
				}
				if (IsWorldPickable(val, item))
				{
					return val;
				}
			}
			return null;
		}

		private static bool IsWorldPickable(GameObject go, GameObject item)
		{
			if (!Object.op_Implicit((Object)(object)go) || (Object)(object)go == (Object)(object)item)
			{
				return false;
			}
			if (!Object.op_Implicit((Object)(object)go.GetComponent<Pickable>()))
			{
				return false;
			}
			return !Object.op_Implicit((Object)(object)go.GetComponent<ItemDrop>());
		}

		private static void EnsureInZNetScene(ZNetScene zns, GameObject pickable)
		{
			int key = StableHash(((Object)pickable).name);
			if (!zns.m_namedPrefabs.TryGetValue(key, out var value) || !((Object)(object)value == (Object)(object)pickable))
			{
				zns.m_namedPrefabs[key] = pickable;
				if (!zns.m_prefabs.Contains(pickable))
				{
					zns.m_prefabs.Add(pickable);
				}
			}
		}

		private static void EnsurePiece(GameObject pickable, GameObject item, ZNetScene zns, HerbDef herb)
		{
			//IL_0031: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			ItemDrop component = item.GetComponent<ItemDrop>();
			if (Object.op_Implicit((Object)(object)component))
			{
				Piece val = pickable.AddComponent<Piece>();
				val.m_name = herb.PieceName;
				val.m_description = herb.PieceDescription;
				val.m_category = (PieceCategory)0;
				val.m_cultivatedGroundOnly = false;
				val.m_groundOnly = true;
				val.m_groundPiece = true;
				val.m_canBeRemoved = true;
				val.m_targetNonPlayerBuilt = false;
				val.m_icon = component.m_itemData.GetIcon();
				val.m_resources = (Requirement[])(object)new Requirement[1]
				{
					new Requirement
					{
						m_resItem = component,
						m_amount = 1,
						m_recover = false
					}
				};
				GameObject prefab = zns.GetPrefab("RaspberryBush");
				Piece val2 = ((prefab != null) ? prefab.GetComponent<Piece>() : null);
				if (Object.op_Implicit((Object)(object)val2))
				{
					val.m_placeEffect = val2.m_placeEffect;
				}
			}
		}

		private static void SwapCultivatorPrefab(PieceTable table, string itemName, GameObject pickable)
		{
			string name = ((Object)pickable).name;
			bool flag = false;
			for (int num = table.m_pieces.Count - 1; num >= 0; num--)
			{
				GameObject val = table.m_pieces[num];
				if (Object.op_Implicit((Object)(object)val))
				{
					string text = ((Object)val).name.Replace("(Clone)", "").Trim();
					if (text == itemName || (Object.op_Implicit((Object)(object)val.GetComponent<ItemDrop>()) && !Object.op_Implicit((Object)(object)val.GetComponent<Pickable>()) && (text == itemName || text == name)))
					{
						if (flag)
						{
							table.m_pieces.RemoveAt(num);
						}
						else
						{
							table.m_pieces[num] = pickable;
							flag = true;
							Plugin.Log.LogInfo((object)("MyriadJewels: cultivator " + itemName + " rebound to " + name));
						}
					}
					else if (text == name)
					{
						if (flag)
						{
							table.m_pieces.RemoveAt(num);
						}
						else
						{
							table.m_pieces[num] = pickable;
							flag = true;
						}
					}
				}
			}
			if (!flag)
			{
				table.m_pieces.Add(pickable);
			}
		}

		private static List<PieceTable> GetCultivatorTables(ObjectDB odb, ZNetScene zns)
		{
			List<PieceTable> list = new List<PieceTable>();
			string[] array = new string[2] { "Cultivator", "BlackMetalCultivator_bal" };
			foreach (string text in array)
			{
				GameObject obj = odb.GetItemPrefab(text) ?? zns.GetPrefab(text);
				PieceTable val = ((obj == null) ? null : obj.GetComponent<ItemDrop>()?.m_itemData.m_shared.m_buildPieces);
				if (Object.op_Implicit((Object)(object)val) && !list.Contains(val))
				{
					list.Add(val);
				}
			}
			return list;
		}

		private static int StableHash(string str)
		{
			int num = 5381;
			int num2 = 5381;
			for (int i = 0; i < str.Length; i++)
			{
				if ((i & 1) == 0)
				{
					num = ((num << 5) + num) ^ str[i];
				}
				else
				{
					num2 = ((num2 << 5) + num2) ^ str[i];
				}
			}
			return num + num2 * 1566083941;
		}
	}
	[BepInPlugin("com.myriad.jewels", "MyriadJewels", "0.1.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.myriad.jewels";

		public const string PluginName = "MyriadJewels";

		public const string PluginVersion = "0.1.4";

		internal static ManualLogSource Log;

		internal static Harmony Harmony;

		private void Awake()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			if (!API.IsLoaded())
			{
				Log.LogError((object)"Jewelcrafting API not loaded; MyriadJewels aborted.");
				return;
			}
			EffectRegistration.Register();
			Gems.Register();
			API.AddGemConfig(LoadEmbeddedYaml());
			Harmony = new Harmony("com.myriad.jewels");
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			foreach (Type type in types)
			{
				try
				{
					Harmony.CreateClassProcessor(type).Patch();
				}
				catch (Exception ex)
				{
					Log.LogError((object)("Harmony patch failed for " + type.FullName + ": " + ex.Message));
				}
			}
			FamiliarController.HookRecalc();
			Log.LogInfo((object)("MyriadJewels 0.1.4 loaded (7 stones). SoftMods: " + SoftMods.DumpAsmHint()));
		}

		private static string LoadEmbeddedYaml()
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string text = executingAssembly.GetManifestResourceNames().FirstOrDefault((string n) => n.EndsWith("MyriadJewels.yaml", StringComparison.OrdinalIgnoreCase));
			if (text == null)
			{
				throw new InvalidOperationException("Embedded MyriadJewels.yaml not found.");
			}
			using Stream stream = executingAssembly.GetManifestResourceStream(text);
			using StreamReader streamReader = new StreamReader(stream);
			return streamReader.ReadToEnd();
		}
	}
	internal static class SoftMods
	{
		private static Assembly? _battleFlow;

		private static Assembly? _dualMastery;

		private static bool _bfTried;

		private static bool _dmTried;

		internal static Assembly? BattleFlow
		{
			get
			{
				if (_bfTried)
				{
					return _battleFlow;
				}
				_bfTried = true;
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				foreach (Assembly assembly in assemblies)
				{
					if (assembly.GetName().Name == "BalrondBattleFlow")
					{
						_battleFlow = assembly;
						break;
					}
				}
				return _battleFlow;
			}
		}

		internal static Assembly? DualMastery
		{
			get
			{
				if (_dmTried)
				{
					return _dualMastery;
				}
				_dmTried = true;
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				foreach (Assembly assembly in assemblies)
				{
					if (assembly.GetName().Name == "BalrondDualMastery")
					{
						_dualMastery = assembly;
						break;
					}
				}
				return _dualMastery;
			}
		}

		internal static float GetAdrenaline(Player player)
		{
			try
			{
				Assembly battleFlow = BattleFlow;
				if (battleFlow == null)
				{
					return 0f;
				}
				MethodInfo methodInfo = battleFlow.GetType("BalrondBattleFlow.AdrenalineRuntime")?.GetMethod("GetCurrentAdrenaline", BindingFlags.Static | BindingFlags.Public);
				if (methodInfo == null)
				{
					return 0f;
				}
				return (methodInfo.Invoke(null, new object[1] { player }) is float num) ? num : 0f;
			}
			catch
			{
				return 0f;
			}
		}

		internal static void AddAdrenaline(Player player, float amount)
		{
			try
			{
				Assembly battleFlow = BattleFlow;
				if (!(battleFlow == null))
				{
					(battleFlow.GetType("BalrondBattleFlow.AdrenalineRuntime")?.GetMethod("AddAdrenaline", BindingFlags.Static | BindingFlags.Public) ?? battleFlow.GetType("BalrondBattleFlow.AdrenalineRuntime")?.GetMethod("ModifyAdrenaline", BindingFlags.Static | BindingFlags.Public))?.Invoke(null, new object[2] { player, amount });
				}
			}
			catch
			{
			}
		}

		internal static bool IsDualWielding(Player player)
		{
			try
			{
				Assembly dualMastery = DualMastery;
				if (dualMastery == null)
				{
					return false;
				}
				MethodInfo methodInfo = dualMastery.GetType("BalrondDualWield.DualWieldMath")?.GetMethod("IsDualWieldingOneHandedWeapons", BindingFlags.Static | BindingFlags.Public);
				if (methodInfo == null)
				{
					return false;
				}
				object obj = methodInfo.Invoke(null, new object[1] { player });
				bool flag = default(bool);
				int num;
				if (obj is bool)
				{
					flag = (bool)obj;
					num = 1;
				}
				else
				{
					num = 0;
				}
				return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
			}
			catch
			{
				return false;
			}
		}

		internal static bool IsTwoHandedNoShield(Player player)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Invalid comparison between Unknown and I4
			ItemData rightItem = ((Humanoid)player).GetRightItem();
			if (rightItem == null)
			{
				return false;
			}
			if (((Humanoid)player).GetLeftItem() != null)
			{
				return false;
			}
			return (int)rightItem.m_shared.m_itemType == 14;
		}

		internal static string DumpAsmHint()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("BF=").Append(BattleFlow != null).Append(" DM=")
				.Append(DualMastery != null);
			return stringBuilder.ToString();
		}
	}
	[HarmonyPatch(typeof(BaseAI), "IsEnemy", new Type[]
	{
		typeof(Character),
		typeof(Character)
	})]
	internal static class TamedCombatIsEnemy
	{
		[HarmonyPriority(0)]
		private static void Postfix(Character a, Character b, ref bool __result)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Invalid comparison between Unknown and I4
			if (!Object.op_Implicit((Object)(object)a) || !Object.op_Implicit((Object)(object)b) || (Object)(object)a == (Object)(object)b)
			{
				return;
			}
			bool flag = a.IsTamed();
			bool flag2 = b.IsTamed();
			if (flag == flag2)
			{
				return;
			}
			Character val = (flag ? b : a);
			if (val is Player)
			{
				__result = false;
				return;
			}
			Faction faction = val.GetFaction();
			if (((int)faction == 0 || (int)faction == 11) ? true : false)
			{
				__result = false;
			}
			else
			{
				__result = true;
			}
		}
	}
}
namespace MyriadJewels.Effects.Tourmaline
{
	public static class TwinBladeAptitude
	{
		[PublicAPI]
		public struct Config
		{
			[InverseMultiplicativePercentagePower]
			public float Power;
		}
	}
	public static class OffHandCatchUp
	{
		[PublicAPI]
		public struct Config
		{
			[InverseMultiplicativePercentagePower]
			public float Power;
		}
	}
	public static class PairedRhythm
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}

		internal static int HitCount;

		internal static float Until;
	}
	public static class ClawRake
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class KickThunder
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class SledgeQuake
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class GreatWeaponPoise
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class GreatWeaponEconomy
	{
		[PublicAPI]
		public struct Config
		{
			[InverseMultiplicativePercentagePower]
			public float Power;
		}
	}
	public static class GreatWeaponSpecial
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class GreatWeaponCommit
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}

		internal static float Until;
	}
	[HarmonyPatch(typeof(Attack), "GetAttackStamina")]
	internal static class TourmalineStamina
	{
		private static void Postfix(Attack __instance, ref float __result)
		{
			Humanoid character = __instance.m_character;
			Player val = (Player)(object)((character is Player) ? character : null);
			if (val != null && SoftMods.IsTwoHandedNoShield(val))
			{
				float power = API.GetEffectPower<GreatWeaponEconomy.Config>(val, "Great Weapon Economy").Power;
				if (!(power <= 0f))
				{
					__result *= 100f / (100f + power);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Character), "Damage")]
	internal static class TourmalineDamage
	{
		[HarmonyPriority(0)]
		private static void Prefix(HitData hit)
		{
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Invalid comparison between Unknown and I4
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Invalid comparison between Unknown and I4
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Invalid comparison between Unknown and I4
			Character attacker = hit.GetAttacker();
			Player val = (Player)(object)((attacker is Player) ? attacker : null);
			if (val == null)
			{
				return;
			}
			float num = 1f;
			if (SoftMods.IsDualWielding(val))
			{
				PairedRhythm.HitCount++;
				float num2 = API.GetEffectPower<PairedRhythm.Config>(val, "Paired Rhythm").Power + API.GetEffectPower<TwinTempest.Config>(val, "Twin Tempest").Power;
				if (num2 > 0f && PairedRhythm.HitCount >= 4)
				{
					PairedRhythm.HitCount = 0;
					PairedRhythm.Until = Time.time + 3f;
				}
				if (Time.time < PairedRhythm.Until)
				{
					num += num2 / 100f;
				}
				float num3 = API.GetEffectPower<OffHandCatchUp.Config>(val, "Off-Hand Catch-Up").Power + API.GetEffectPower<TwinTempest.Config>(val, "Twin Tempest").Power;
				if (num3 > 0f)
				{
					num += num3 / 200f;
				}
			}
			if (SoftMods.IsTwoHandedNoShield(val))
			{
				float power = API.GetEffectPower<GreatOath.Config>(val, "Great Oath").Power;
				float num4 = API.GetEffectPower<GreatWeaponSpecial.Config>(val, "Great Weapon Special").Power + power;
				float num5 = API.GetEffectPower<GreatWeaponCommit.Config>(val, "Great Weapon Commit").Power + power;
				if ((int)hit.m_skill == 7)
				{
					num += API.GetEffectPower<KickThunder.Config>(val, "Kick Thunder").Power / 100f;
				}
				if ((int)hit.m_skill == 3)
				{
					num += API.GetEffectPower<SledgeQuake.Config>(val, "Sledge Quake").Power / 100f;
				}
				if ((int)hit.m_skill == 11)
				{
					num += API.GetEffectPower<ClawRake.Config>(val, "Claw Rake").Power / 100f;
				}
				if (num4 > 0f)
				{
					num += num4 / 200f;
				}
				if (Time.time < GreatWeaponCommit.Until)
				{
					num += num5 / 100f;
				}
				else if (num5 > 0f && hit.m_staggerMultiplier > 1f)
				{
					GreatWeaponCommit.Until = Time.time + 2.5f;
				}
			}
			if (num != 1f)
			{
				hit.ApplyModifier(num);
			}
		}
	}
	[HarmonyPatch(typeof(Character), "GetStaggerTreshold")]
	internal static class TourmalinePoise
	{
		private static void Postfix(Character __instance, ref float __result)
		{
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (val != null && SoftMods.IsTwoHandedNoShield(val))
			{
				float power = API.GetEffectPower<GreatWeaponPoise.Config>(val, "Great Weapon Poise").Power;
				if (!(power <= 0f))
				{
					__result *= 1f + power / 100f;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Skills), "GetSkillFactor")]
	internal static class TourmalineDualSkill
	{
		private static void Postfix(Skills __instance, SkillType skillType, ref float __result)
		{
			Player player = __instance.m_player;
			if (!((Object)(object)player == (Object)null))
			{
				float power = API.GetEffectPower<TwinBladeAptitude.Config>(player, "Twin Blade Aptitude").Power;
				if (power > 0f && SoftMods.DualMastery != null && SoftMods.IsDualWielding(player))
				{
					__result += power / 100f;
				}
			}
		}
	}
}
namespace MyriadJewels.Effects.Synergies
{
	public static class FamiliarBond
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class MoonHunt
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class ManicEngine
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class CrestSovereign
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class FusedPulse
	{
		[PublicAPI]
		public struct Config
		{
			[InverseMultiplicativePercentagePower]
			public float Power;
		}
	}
	public static class OpposedHearts
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class TwinTempest
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class GreatOath
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class Warpath
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class SecondLung
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class OrangeReservoir
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class Cascade
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class IronLattice
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class RootedCraft
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class GreenThumb
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class FullLarder
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class RuneGrove
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class PackAndPulse
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
}
namespace MyriadJewels.Effects.Pyrite
{
	public static class LightningProc
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;

			[AdditivePower]
			public float Chance;
		}
	}
	public static class SpiritHex
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;

			[AdditivePower]
			public float Chance;
		}
	}
	public static class PhysicalBurst
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;

			[AdditivePower]
			public float Chance;
		}
	}
	public static class StaminaSiphon
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;

			[AdditivePower]
			public float Chance;
		}
	}
	public static class EitrSiphon
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;

			[AdditivePower]
			public float Chance;
		}
	}
	public static class AdrenalSpike
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;

			[AdditivePower]
			public float Chance;
		}
	}
	[HarmonyPatch(typeof(Character), "Damage")]
	internal static class PyriteProcs
	{
		[HarmonyPriority(300)]
		private static void Prefix(HitData hit)
		{
			Character attacker = hit.GetAttacker();
			Player val = (Player)(object)((attacker is Player) ? attacker : null);
			if (val != null)
			{
				float power = API.GetEffectPower<Cascade.Config>(val, "Cascade").Power;
				float totalDamage = ((DamageTypes)(ref hit.m_damage)).GetTotalDamage();
				float value = Random.value;
				LightningProc.Config effectPower = API.GetEffectPower<LightningProc.Config>(val, "Lightning Proc");
				if (effectPower.Power > 0f && value <= (effectPower.Chance + power) / 100f)
				{
					hit.m_damage.m_lightning += totalDamage * effectPower.Power / 100f;
				}
				SpiritHex.Config effectPower2 = API.GetEffectPower<SpiritHex.Config>(val, "Spirit Hex");
				if (effectPower2.Power > 0f && Random.value <= (effectPower2.Chance + power) / 100f)
				{
					hit.m_damage.m_spirit += totalDamage * effectPower2.Power / 100f;
				}
				PhysicalBurst.Config effectPower3 = API.GetEffectPower<PhysicalBurst.Config>(val, "Physical Burst");
				if (effectPower3.Power > 0f && Random.value <= (effectPower3.Chance + power) / 100f)
				{
					float num = totalDamage * effectPower3.Power / 100f;
					hit.m_damage.m_slash += num * 0.34f;
					hit.m_damage.m_blunt += num * 0.33f;
					hit.m_damage.m_pierce += num * 0.33f;
				}
				EitrSiphon.Config effectPower4 = API.GetEffectPower<EitrSiphon.Config>(val, "Eitr Siphon");
				if (effectPower4.Power > 0f && Random.value <= (effectPower4.Chance + power) / 100f)
				{
					((Character)val).AddEitr(effectPower4.Power);
				}
				AdrenalSpike.Config effectPower5 = API.GetEffectPower<AdrenalSpike.Config>(val, "Adrenal Spike");
				if (effectPower5.Power > 0f && Random.value <= (effectPower5.Chance + power) / 100f)
				{
					SoftMods.AddAdrenaline(val, effectPower5.Power);
				}
				Warpath.Config effectPower6 = API.GetEffectPower<Warpath.Config>(val, "Warpath");
				if (effectPower6.Power > 0f && (SoftMods.IsDualWielding(val) || SoftMods.IsTwoHandedNoShield(val)))
				{
					SoftMods.AddAdrenaline(val, effectPower6.Power);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Humanoid), "BlockAttack")]
	internal static class PyriteStaminaSiphon
	{
		private static void Postfix(Humanoid __instance, bool __result)
		{
			if (!__result)
			{
				return;
			}
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (val != null)
			{
				StaminaSiphon.Config effectPower = API.GetEffectPower<StaminaSiphon.Config>(val, "Stamina Siphon");
				float power = API.GetEffectPower<Cascade.Config>(val, "Cascade").Power;
				if (!(effectPower.Power <= 0f) && !(Random.value > (effectPower.Chance + power) / 100f))
				{
					((Character)val).AddStamina(effectPower.Power);
				}
			}
		}
	}
}
namespace MyriadJewels.Effects.MossAgate
{
	public static class WellFedGrace
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class Fieldcraft
	{
		[PublicAPI]
		public struct Config
		{
			[InverseMultiplicativePercentagePower]
			public float Power;
		}
	}
	public static class Outrider
	{
		[PublicAPI]
		public struct Config
		{
			[InverseMultiplicativePercentagePower]
			public float Power;
		}
	}
	public static class Craftmaster
	{
		[PublicAPI]
		public struct Config
		{
			[InverseMultiplicativePercentagePower]
			public float Power;
		}
	}
	public static class ExpertRuneforger
	{
		[PublicAPI]
		public struct Config
		{
			[InverseMultiplicativePercentagePower]
			public float Power;
		}
	}
	public static class ExpertAtgeir
	{
		[PublicAPI]
		public struct Config
		{
			[InverseMultiplicativePercentagePower]
			public float Power;
		}
	}
	public static class ExpertUnarmed
	{
		[PublicAPI]
		public struct Config
		{
			[InverseMultiplicativePercentagePower]
			public float Power;
		}
	}
	public static class ExpertSledge
	{
		[PublicAPI]
		public struct Config
		{
			[InverseMultiplicativePercentagePower]
			public float Power;
		}
	}
	[HarmonyPatch(typeof(Skills), "GetSkillFactor")]
	internal static class MossSkillBoosts
	{
		private static void Postfix(Skills __instance, SkillType skillType, ref float __result)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Invalid comparison between Unknown and I4
			//IL_006c: 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_0071: Invalid comparison between Unknown and I4
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Invalid comparison between Unknown and I4
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Invalid comparison between Unknown and I4
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Invalid comparison between Unknown and I4
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Invalid comparison between Unknown and I4
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Invalid comparison between Unknown and I4
			Player player = __instance.m_player;
			if ((Object)(object)player == (Object)null)
			{
				return;
			}
			float power = API.GetEffectPower<RootedCraft.Config>(player, "Rooted Craft").Power;
			float num = 0f;
			if (IsWellFed(player))
			{
				num = API.GetEffectPower<WellFedGrace.Config>(player, "Well Fed Grace").Power + API.GetEffectPower<GreenThumb.Config>(player, "Green Thumb").Power;
			}
			float num2 = 0f;
			if ((int)skillType <= 11)
			{
				if ((int)skillType != 3)
				{
					if ((int)skillType != 4)
					{
						if ((int)skillType == 11)
						{
							num2 += API.GetEffectPower<ExpertUnarmed.Config>(player, "Expert Unarmed").Power;
						}
					}
					else
					{
						num2 += API.GetEffectPower<ExpertAtgeir.Config>(player, "Expert Atgeir").Power;
					}
				}
				else
				{
					num2 += API.GetEffectPower<ExpertSledge.Config>(player, "Expert Sledge").Power;
				}
			}
			else if (skillType - 12 > 1)
			{
				if ((int)skillType == 103 || (int)skillType == 110)
				{
					num2 += API.GetEffectPower<Outrider.Config>(player, "Outrider").Power + power;
				}
			}
			else
			{
				num2 += API.GetEffectPower<Fieldcraft.Config>(player, "Fieldcraft").Power + power;
			}
			num2 += API.GetEffectPower<Craftmaster.Config>(player, "Craftmaster").Power * 0.25f + power * 0.25f;
			num2 += API.GetEffectPower<ExpertRuneforger.Config>(player, "Expert Runeforger").Power * 0.25f + API.GetEffectPower<RuneGrove.Config>(player, "Rune Grove").Power * 0.25f;
			num2 += num * 0.25f;
			if (num2 > 0f)
			{
				__result += num2 / 100f;
			}
		}

		internal static bool IsWellFed(Player player)
		{
			foreach (Food food in player.m_foods)
			{
				if (food.m_item != null)
				{
					return true;
				}
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Player), "UpdateFood")]
	internal static class FullLarderFoodDrain
	{
		private static void Prefix(Player __instance)
		{
			float power = API.GetEffectPower<FullLarder.Config>(__instance, "Full Larder").Power;
			if (power <= 0f || !MossSkillBoosts.IsWellFed(__instance))
			{
				return;
			}
			foreach (Food food in __instance.m_foods)
			{
				food.m_time = Mathf.Min(food.m_item.m_shared.m_foodBurnTime, food.m_time + power * 0.02f * Time.fixedDeltaTime);
			}
		}
	}
}
namespace MyriadJewels.Effects.Howlite
{
	public static class SpiritWolf
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class CombatCrow
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class SummonPotency
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class TrophyHunter
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;

			[InverseMultiplicativePercentagePower]
			public float Chance;
		}
	}
	internal enum FamiliarKind
	{
		Wolf,
		Crow
	}
	internal sealed class MyriadFamiliar : MonoBehaviour
	{
		internal FamiliarKind Kind;

		internal long OwnerId;

		internal float TargetDamage;
	}
	internal static class FamiliarController
	{
		private const float WolfCooldownBase = 90f;

		private const float CrowCooldownBase = 75f;

		private const float MinCooldown = 20f;

		private const string ZdoFamiliarKey = "Myriad.Familiar";

		private const string ZdoOwnerKey = "Myriad.FamiliarOwner";

		private const string ZdoDamageKey = "Myriad.FamiliarDamage";

		private const string ZdoScaleKey = "Myriad.FamiliarScale";

		private const string WolfPrefab = "Wolf_cub";

		private const string WolfPrefabFallback = "Wolf";

		private const string CrowPrefab = "CrowNestling_bal";

		private const string CrowPrefabFallback = "GiantCrow_bal";

		private static GameObject? _wolf;

		private static GameObject? _crow;

		private static float _wolfCooldownUntil;

		private static float _crowCooldownUntil;

		private static float _pulseUntil;

		private static float _nextSweep;

		internal static float PulseMul
		{
			get
			{
				if (!(Time.time < _pulseUntil))
				{
					return 1f;
				}
				return 1.25f;
			}
		}

		internal static void HookRecalc()
		{
			API.OnEffectRecalc += delegate
			{
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer != (Object)null)
				{
					Ensure(localPlayer);
				}
			};
		}

		internal static void Ensure(Player player)
		{
			float power = API.GetEffectPower<SpiritWolf.Config>(player, "Spirit Wolf").Power;
			float power2 = API.GetEffectPower<CombatCrow.Config>(player, "Combat Crow").Power;
			float potency = API.GetEffectPower<SummonPotency.Config>(player, "Summon Potency").Power + API.GetEffectPower<FamiliarBond.Config>(player, "Familiar Bond").Power;
			if (power > 0f)
			{
				_wolf = Maintain(player, _wolf, FamiliarKind.Wolf, power, potency, ref _wolfCooldownUntil);
			}
			else
			{
				_wolf = Despawn(_wolf, applyCooldown: false);
				DestroyOwnedKind(player.GetPlayerID(), FamiliarKind.Wolf, null);
			}
			if (power2 > 0f)
			{
				_crow = Maintain(player, _crow, FamiliarKind.Crow, power2, potency, ref _crowCooldownUntil);
				return;
			}
			_crow = Despawn(_crow, applyCooldown: false);
			DestroyOwnedKind(player.GetPlayerID(), FamiliarKind.Crow, null);
		}

		internal static void DespawnAll(Player player)
		{
			if ((Object)(object)_wolf != (Object)null)
			{
				LoseFamiliar(FamiliarKind.Wolf, player, applyCooldown: true);
				_wolf = Despawn(_wolf, applyCooldown: false);
			}
			if ((Object)(object)_crow != (Object)null)
			{
				LoseFamiliar(FamiliarKind.Crow, player, applyCooldown: true);
				_crow = Despawn(_crow, applyCooldown: false);
			}
			DestroyOwnedKind(player.GetPlayerID(), FamiliarKind.Wolf, null);
			DestroyOwnedKind(player.GetPlayerID(), FamiliarKind.Crow, null);
		}

		internal static void OnFamiliarDeath(Character familiar)
		{
			if (!TryGetFamiliar(familiar, out var kind, out var ownerId))
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && ((Character)localPlayer).IsOwner() && (ownerId == 0L || ownerId == localPlayer.GetPlayerID()) && (ownerId != 0L || (kind == FamiliarKind.Wolf && Object.op_Implicit((Object)(object)_wolf) && (Object)(object)((Component)familiar).gameObject == (Object)(object)_wolf) || (kind == FamiliarKind.Crow && Object.op_Implicit((Object)(object)_crow) && (Object)(object)((Component)familiar).gameObject == (Object)(object)_crow)))
			{
				LoseFamiliar(kind, localPlayer, applyCooldown: true);
				if (kind == FamiliarKind.Wolf)
				{
					_wolf = null;
				}
				else
				{
					_crow = null;
				}
			}
		}

		private static void LoseFamiliar(FamiliarKind kind, Player player, bool applyCooldown)
		{
			if (applyCooldown)
			{
				float num = RespawnCooldown(player, (kind == FamiliarKind.Wolf) ? 90f : 75f);
				if (kind == FamiliarKind.Wolf)
				{
					_wolfCooldownUntil = Time.time + num;
				}
				else
				{
					_crowCooldownUntil = Time.time + num;
				}
			}
		}

		private static float RespawnCooldown(Player player, float baseSeconds)
		{
			float num = API.GetEffectPower<SummonPotency.Config>(player, "Summon Potency").Power + API.GetEffectPower<FamiliarBond.Config>(player, "Familiar Bond").Power;
			return Mathf.Max(20f, baseSeconds * 100f / (100f + num));
		}

		internal static bool IsFamiliar(Character character)
		{
			FamiliarKind kind;
			long ownerId;
			return TryGetFamiliar(character, out kind, out ownerId);
		}

		internal static bool TryGetFamiliar(Character character, out FamiliarKind kind, out long ownerId)
		{
			kind = FamiliarKind.Wolf;
			ownerId = 0L;
			if (!Object.op_Implicit((Object)(object)character))
			{
				return false;
			}
			bool flag = false;
			ZNetView nview = character.m_nview;
			if ((Object)(object)nview != (Object)null && nview.IsValid())
			{
				ZDO zDO = nview.GetZDO();
				int num = zDO.GetInt("Myriad.Familiar", 0);
				if (num > 0)
				{
					kind = ((num == 2) ? FamiliarKind.Crow : FamiliarKind.Wolf);
					ownerId = zDO.GetLong("Myriad.FamiliarOwner", 0L);
					flag = true;
				}
			}
			MyriadFamiliar myriadFamiliar = default(MyriadFamiliar);
			if (((Component)character).TryGetComponent<MyriadFamiliar>(ref myriadFamiliar))
			{
				if (flag)
				{
					myriadFamiliar.Kind = kind;
					if (ownerId != 0L)
					{
						myriadFamiliar.OwnerId = ownerId;
					}
				}
				else
				{
					kind = myriadFamiliar.Kind;
					ownerId = myriadFamiliar.OwnerId;
				}
				return true;
			}
			return flag;
		}

		internal static void TryBind(Character character)
		{
			if (Object.op_Implicit((Object)(object)character) && TryGetFamiliar(character, out var kind, out var ownerId))
			{
				Dress(character, kind, ownerId);
			}
		}

		internal static void Pulse(float seconds, float _)
		{
			_pulseUntil = Time.time + seconds;
		}

		internal static void TickFollow(Player player)
		{
			TickFollowOne(player, ref _wolf, FamiliarKind.Wolf, 2f, 0f);
			TickFollowOne(player, ref _crow, FamiliarKind.Crow, 3f, 1.5f);
			if (!(Time.time < _nextSweep))
			{
				_nextSweep = Time.time + 2f;
				SweepOrphans();
				RetuneAlive(player);
			}
		}

		private static void TickFollowOne(Player player, ref GameObject? familiar, FamiliarKind kind, float radius, float height)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)familiar))
			{
				familiar = null;
				return;
			}
			Vector3 val = ((Component)player).transform.position + ((Component)player).transform.forward * (0f - radius) + Vector3.up * height;
			Character component = familiar.GetComponent<Character>();
			if ((Object)(object)component == (Object)null)
			{
				familiar.transform.position = Vector3.Lerp(familiar.transform.position, val, Time.deltaTime * 2f);
				return;
			}
			Dress(component, kind, player.GetPlayerID());
			MonsterAI component2 = ((Component)component).GetComponent<MonsterAI>();
			if (component2 != null)
			{
				if ((Object)(object)component2.GetFollowTarget() != (Object)(object)((Component)player).gameObject)
				{
					component2.SetFollowTarget(((Component)player).gameObject);
				}
				((BaseAI)component2).m_alerted = true;
			}
			if (Vector3.Distance(((Component)component).transform.position, ((Component)player).transform.position) > 40f)
			{
				TeleportFamiliar(component, val);
			}
		}

		private static void TeleportFamiliar(Character ch, Vector3 target)
		{
			//IL_0006: 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)
			((Component)ch).transform.position = target;
			if ((Object)(object)ch.m_nview != (Object)null && ch.m_nview.IsValid() && ch.m_nview.IsOwner())
			{
				ch.m_nview.GetZDO().SetPosition(target);
			}
		}

		private static GameObject? Maintain(Player player, GameObject? existing, FamiliarKind kind, float power, float potency, ref float cooldownUntil)
		{
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: 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)
			//IL_0130: 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_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)existing != (Object)null && !Object.op_Implicit((Object)(object)existing))
			{
				existing = null;
			}
			if ((Object)(object)existing != (Object)null)
			{
				ApplyStats(existing, player, kind, power, potency, fillHealth: false);
				return existing;
			}
			if (Time.time < cooldownUntil)
			{
				return null;
			}
			if (player.GetPlayerID() == 0L || (Object)(object)ZNetScene.instance == (Object)null)
			{
				return null;
			}
			DestroyOwnedKind(player.GetPlayerID(), kind, null);
			string text = ((kind == FamiliarKind.Crow) ? "CrowNestling_bal" : "Wolf_cub");
			string text2 = ((kind == FamiliarKind.Crow) ? "GiantCrow_bal" : "Wolf");
			ZNetScene instance = ZNetScene.instance;
			object obj = ((instance != null) ? instance.GetPrefab(text) : null);
			if (obj == null)
			{
				ZNetScene instance2 = ZNetScene.instance;
				obj = ((instance2 != null) ? instance2.GetPrefab(text2) : null);
			}
			GameObject val = (GameObject)obj;
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)("MyriadJewels: familiar prefab '" + text + "' / '" + text2 + "' missing."));
				return null;
			}
			ComputeStats(player, kind, power, potency, out var hp, out var damage, out var visualScale);
			Vector3 val2 = ((Component)player).transform.position + ((Component)player).transform.forward * 2f + Vector3.up * ((kind == FamiliarKind.Crow) ? 1.2f : 0f);
			GameObject val3 = Object.Instantiate<GameObject>(val, val2, Quaternion.identity);
			StripRanchBehaviors(val3);
			long playerID = player.GetPlayerID();
			if (!MarkZdo(val3, kind, playerID, damage, visualScale))
			{
				Plugin.Log.LogWarning((object)("MyriadJewels: aborting " + ((Object)val).name + " spawn, ZDO mark failed."));
				DestroyNetworked(val3);
				return null;
			}
			ApplyStats(val3, player, kind, power, potency, fillHealth: true);
			MonsterAI component = val3.GetComponent<MonsterAI>();
			if (component != null)
			{
				component.SetFollowTarget(((Component)player).gameObject);
				((BaseAI)component).m_alerted = true;
			}
			DropOnDestroyed[] componentsInChildren = val3.GetComponentsInChildren<DropOnDestroyed>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
			Plugin.Log.LogInfo((object)$"Spawned familiar {((Object)val).name} hp={hp:0} dmg={damage:0.0} scale={visualScale:0.00} kit={KitPower(player):0} gem={power} pot={potency}.");
			return val3;
		}

		private static void RetuneAlive(Player player)
		{
			float power = API.GetEffectPower<SpiritWolf.Config>(player, "Spirit Wolf").Power;
			float power2 = API.GetEffectPower<CombatCrow.Config>(player, "Combat Crow").Power;
			float potency = API.GetEffectPower<SummonPotency.Config>(player, "Summon Potency").Power + API.GetEffectPower<FamiliarBond.Config>(player, "Familiar Bond").Power;
			if (power > 0f && Object.op_Implicit((Object)(object)_wolf))
			{
				ApplyStats(_wolf, player, FamiliarKind.Wolf, power, potency, fillHealth: false);
			}
			if (power2 > 0f && Object.op_Implicit((Object)(object)_crow))
			{
				ApplyStats(_crow, player, FamiliarKind.Crow, power2, potency, fillHealth: false);
			}
		}

		private static void ApplyStats(GameObject go, Player player, FamiliarKind kind, float power, float potency, bool fillHealth)
		{
			if (!Object.op_Implicit((Object)(object)go))
			{
				return;
			}
			ComputeStats(player, kind, power, potency, out var hp, out var damage, out var visualScale);
			if (!MarkZdo(go, kind, player.GetPlayerID(), damage, visualScale))
			{
				return;
			}
			Character component = go.GetComponent<Character>();
			if (component != null)
			{
				float maxHealth = component.GetMaxHealth();
				float health = component.GetHealth();
				component.SetMaxHealth(hp);
				if (fillHealth)
				{
					component.SetHealth(hp);
				}
				else if (hp > maxHealth)
				{
					component.SetHealth(health + (hp - maxHealth));
				}
				else
				{
					component.SetHealth(Mathf.Min(health, hp));
				}
				Dress(component, kind, player.GetPlayerID());
			}
		}

		private static float KitPower(Player player)
		{
			float bodyArmor = ((Character)player).GetBodyArmor();
			float maxEitr = ((Character)player).GetMaxEitr();
			return Mathf.Max(bodyArmor, maxEitr * 0.5f);
		}

		private static void ComputeStats(Player player, FamiliarKind kind, float power, float potency, out float hp, out float damage, out float visualScale)
		{
			float num = KitPower(player);
			float num2 = ((num <= 100f) ? (num / 100f) : ((100f + Mathf.Min((num - 100f) * 0.25f, 20f)) / 100f));
			float num3 = Mathf.Clamp(0.85f + (power - 15f) / 25f * 0.35f, 0.8f, 1.25f);
			float num4 = 1f + potency / 200f;
			float num5 = num3 * num4;
			hp = (26f + 74f * num2) * num5;
			damage = (8f + 34f * num2) * num5;
			visualScale = 0.72f + 0.4f * num2 + (num3 - 1f) * 0.15f;
			if (kind == FamiliarKind.Crow)
			{
				hp *= 0.85f;
				damage *= 0.85f;
				visualScale *= 0.9f;
			}
			hp = Mathf.Clamp(hp, 16f, 125f);
			damage = Mathf.Clamp(damage, 5f, 50f);
			visualScale = Mathf.Clamp(visualScale, 0.65f, 1.18f);
		}

		private static void StripRanchBehaviors(GameObject go)
		{
			Growup[] componentsInChildren = go.GetComponentsInChildren<Growup>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
			Procreation[] componentsInChildren2 = go.GetComponentsInChildren<Procreation>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren2[i]);
			}
			CharacterTimedDestruction[] componentsInChildren3 = go.GetComponentsInChildren<CharacterTimedDestruction>(true);
			for (int i = 0; i < componentsInChildren3.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren3[i]);
			}
		}

		private static bool MarkZdo(GameObject go, FamiliarKind kind, long ownerId, float damage, float visualScale)
		{
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			ZNetView component = go.GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return false;
			}
			if (!component.IsOwner())
			{
				component.ClaimOwnership();
			}
			if (!component.IsOwner())
			{
				return false;
			}
			ZDO zDO = component.GetZDO();
			zDO.Persistent = false;
			component.m_persistent = false;
			component.m_syncInitialScale = true;
			zDO.Set("Myriad.Familiar", (kind != FamiliarKind.Crow) ? 1 : 2);
			zDO.Set("Myriad.FamiliarOwner", ownerId);
			zDO.Set("Myriad.FamiliarDamage", damage);
			zDO.Set("Myriad.FamiliarScale", visualScale);
			zDO.Set(ZDOVars.s_scaleScalarHash, visualScale);
			zDO.Set(ZDOVars.s_tamed, true);
			go.transform.localScale = Vector3.one * visualScale;
			return true;
		}

		internal static void ScaleOutgoingHit(HitData hit)
		{
			if (hit == null)
			{
				return;
			}
			Character attacker = hit.GetAttacker();
			if ((Object)(object)attacker == (Object)null)
			{
				return;
			}
			TryBind(attacker);
			MyriadFamiliar myriadFamiliar = default(MyriadFamiliar);
			if (!((Component)attacker).TryGetComponent<MyriadFamiliar>(ref myriadFamiliar))
			{
				if (IsFamiliar(attacker))
				{
					hit.ApplyModifier(0.25f);
				}
				return;
			}
			float totalDamage = ((DamageTypes)(ref hit.m_damage)).GetTotalDamage();
			if (totalDamage <= 0.01f)
			{
				return;
			}
			if (myriadFamiliar.TargetDamage <= 0f)
			{
				hit.ApplyModifier(0.25f);
				return;
			}
			float num = myriadFamiliar.TargetDamage;
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer != (Object)null && myriadFamiliar.OwnerId == localPlayer.GetPlayerID())
			{
				num *= PulseMul;
			}
			float num2 = num / totalDamage;
			hit.ApplyModifier(num2);
			hit.m_pushForce *= Mathf.Clamp(num2, 0.25f, 1f);
			hit.m_staggerMultiplier *= Mathf.Clamp(num2, 0.35f, 1f);
		}

		private static void Dress(Character ch, FamiliarKind kind, long ownerId)
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			MyriadFamiliar myriadFamiliar = default(MyriadFamiliar);
			if (!((Component)ch).TryGetComponent<MyriadFamiliar>(ref myriadFamiliar))
			{
				myriadFamiliar = ((Component)ch).gameObject.AddComponent<MyriadFamiliar>();
			}
			myriadFamiliar.Kind = kind;
			myriadFamiliar.OwnerId = ownerId;
			ZNetView nview = ch.m_nview;
			if ((Object)(object)nview != (Object)null && nview.IsValid())
			{
				ZDO zDO = nview.GetZDO();
				float num = zDO.GetFloat("Myriad.FamiliarDamage", myriadFamiliar.TargetDamage);
				if (num > 0f)
				{
					myriadFamiliar.TargetDamage = num;
				}
				float num2 = zDO.GetFloat("Myriad.FamiliarScale", 0f);
				if (num2 > 0.1f)
				{
					((Component)ch).transform.localScale = Vector3.one * num2;
				}
			}
			ch.m_faction = (Faction)0;
			ch.m_tamed = true;
			if ((Object)(object)nview != (Object)null && nview.IsValid() && nview.IsOwner())
			{
				nview.GetZDO().Set(ZDOVars.s_tamed, true);
				if (!ch.IsTamed())
				{
					ch.SetTamed(true);
				}
			}
			CharacterDrop component = ((Component)ch).GetComponent<CharacterDrop>();
			if (component != null)
			{
				component.m_dropsEnabled = false;
			}
			Player val = FindOwner(ownerId);
			if ((Object)(object)val != (Object)null)
			{
				MonsterAI component2 = ((Component)ch).GetComponent<MonsterAI>();
				if (component2 != null && (Object)(object)component2.GetFollowTarget() != (Object)(object)((Component)val).gameObject)
				{
					component2.SetFollowTarget(((Component)val).gameObject);
				}
			}
		}

		private static Player? FindOwner(long ownerId)
		{
			if (ownerId == 0L)
			{
				return null;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer != (Object)null && localPlayer.GetPlayerID() == ownerId)
			{
				return localPlayer;
			}
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				if ((Object)(object)allPlayer != (Object)null && allPlayer.GetPlayerID() == ownerId)
				{
					return allPlayer;
				}
			}
			return null;
		}

		private static GameObject? Despawn(GameObject? go, bool applyCooldown)
		{
			if ((Object)(object)go != (Object)null)
			{
				if (applyCooldown)
				{
					Player localPlayer = Player.m_localPlayer;
					MyriadFamiliar myriadFamiliar = default(MyriadFamiliar);
					if (localPlayer != null && go.TryGetComponent<MyriadFamiliar>(ref myriadFamiliar))
					{
						LoseFamiliar(myriadFamiliar.Kind, localPlayer, applyCooldown: true);
					}
				}
				DestroyNetworked(go);
			}
			return null;
		}

		private static void DestroyOwnedKind(long ownerId, FamiliarKind kind, GameObject? except)
		{
			if (ownerId == 0L)
			{
				return;
			}
			List<GameObject> list = new List<GameObject>();
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				if (Object.op_Implicit((Object)(object)allCharacter) && !((Object)(object)((Component)allCharacter).gameObject == (Object)(object)except) && TryGetFamiliar(allCharacter, out var kind2, out var ownerId2) && kind2 == kind && ownerId2 == ownerId)
				{
					list.Add(((Component)allCharacter).gameObject);
				}
			}
			foreach (GameObject item in list)
			{
				DestroyNetworked(item);
			}
		}

		private static void SweepOrphans()
		{
			List<GameObject> list = new List<GameObject>();
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				if (!Object.op_Implicit((Object)(object)allCharacter))
				{
					continue;
				}
				TryBind(allCharacter);
				if (TryGetFamiliar(allCharacter, out var _, out var ownerId) && ownerId != 0L && !((Object)(object)FindOwner(ownerId) != (Object)null))
				{
					ZNetView nview = allCharacter.m_nview;
					if (!((Object)(object)nview == (Object)null) && nview.IsValid() && nview.IsOwner())
					{
						list.Add(((Component)allCharacter).gameObject);
					}
				}
			}
			foreach (GameObject item in list)
			{
				DestroyNetworked(item);
			}
		}

		private static void DestroyNetworked(GameObject go)
		{
			if (!Object.op_Implicit((Object)(object)go))
			{
				return;
			}
			try
			{
				ZNetView component = go.GetComponent<ZNetView>();
				if ((Object)(object)component != (Object)null && component.IsValid())
				{
					component.GetZDO().Persistent = false;
					component.m_persistent = false;
					if (!component.IsOwner())
					{
						component.ClaimOwnership();
					}
					if (component.IsOwner() && (Object)(object)ZNetScene.instance != (Object)null)
					{
						component.Destroy();
						return;
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("MyriadJewels: familiar despawn failed: " + ex.Message));
			}
			Object.Destroy((Object)(object)go);
		}
	}
	[HarmonyPatch(typeof(Character), "Awake")]
	internal static class FamiliarBindOnSpawn
	{
		private static void Postfix(Character __instance)
		{
			FamiliarController.TryBind(__instance);
		}
	}
	[HarmonyPatch(typeof(Character), "Damage")]
	internal static class FamiliarOutgoingDamage
	{
		private static void Prefix(HitData hit)
		{
			FamiliarController.ScaleOutgoingHit(hit);
		}
	}
	[HarmonyPatch(typeof(Player), "OnSpawned")]
	internal static class FamiliarBootstrap
	{
		private static void Postfix(Player __instance)
		{
			if (((Character)__instance).IsOwner())
			{
				FamiliarController.Ensure(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(Humanoid), "EquipItem", new Type[]
	{
		typeof(ItemData),
		typeof(bool)
	})]
	internal static class FamiliarOnEquip
	{
		private static void Postfix(Humanoid __instance)
		{
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (val != null && ((Character)val).IsOwner())
			{
				FamiliarController.Ensure(val);
			}
		}
	}
	[HarmonyPatch(typeof(Humanoid), "UnequipItem", new Type[]
	{
		typeof(ItemData),
		typeof(bool)
	})]
	internal static class FamiliarOnUnequip
	{
		private static void Postfix(Humanoid __instance)
		{
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (val != null && ((Character)val).IsOwner())
			{
				FamiliarController.Ensure(val);
			}
		}
	}
	[HarmonyPatch(typeof(Player), "OnDestroy")]
	internal static class FamiliarOnPlayerDestroy
	{
		private static void Prefix(Player __instance)
		{
			if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				FamiliarController.DespawnAll(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(Game), "Update")]
	internal static class FamiliarFollowTick
	{
		private static void Postfix()
		{
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && ((Character)localPlayer).IsOwner())
			{
				FamiliarController.TickFollow(localPlayer);
			}
		}
	}
	[HarmonyPatch(typeof(Character), "OnDeath")]
	internal static class FamiliarOnDeath
	{
		private static void Prefix(Character __instance)
		{
			if (FamiliarController.IsFamiliar(__instance))
			{
				CharacterDrop component = ((Component)__instance).GetComponent<CharacterDrop>();
				if (component != null)
				{
					component.m_dropsEnabled = false;
				}
				FamiliarController.OnFamiliarDeath(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(DropOnDestroyed), "OnDestroyed")]
	internal static class FamiliarNoDropOnDestroyed
	{
		private static bool Prefix(DropOnDestroyed __instance)
		{
			Character componentInParent = ((Component)__instance).GetComponentInParent<Character>();
			if (!((Object)(object)componentInParent == (Object)null))
			{
				return !FamiliarController.IsFamiliar(componentInParent);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(CharacterDrop), "GenerateDropList")]
	internal static class FamiliarNoCharacterDrop
	{
		private static bool Prefix(CharacterDrop __instance)
		{
			Character component = ((Component)__instance).GetComponent<Character>();
			if (!((Object)(object)component == (Object)null))
			{
				return !FamiliarController.IsFamiliar(component);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Character), "OnDeath")]
	internal static class TrophyHunterOnKill
	{
		private static void Prefix(Character __instance)
		{
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (val != null && ((Character)val).IsOwner())
			{
				FamiliarController.DespawnAll(val);
			}
			else
			{
				if (FamiliarController.IsFamiliar(__instance))
				{
					return;
				}
				Player localPlayer = Player.m_localPlayer;
				if (!((Object)(object)localPlayer == (Object)null))
				{
					TrophyHunter.Config effectPower = API.GetEffectPower<TrophyHunter.Config>(localPlayer, "Trophy Hunter");
					float power = API.GetEffectPower<MoonHunt.Config>(localPlayer, "Moon Hunt").Power;
					float num = effectPower.Power + (EnvMan.IsNight() ? power : 0f);
					if (!(num <= 0f) && !(Random.value > num / 100f))
					{
						((Character)localPlayer).AddStamina(Mathf.Clamp(num * 0.25f, 1f, 10f));
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(ItemData), "GetWeight")]
	internal static class TrophyWeightReduce
	{
		private static void Postfix(ItemData __instance, ref float __result)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Invalid comparison between Unknown and I4
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null))
			{
				float chance = API.GetEffectPower<TrophyHunter.Config>(localPlayer, "Trophy Hunter").Chance;
				if (!(chance <= 0f) && (int)__instance.m_shared.m_itemType == 1 && !(__instance.m_shared.m_weight < 5f))
				{
					__result *= (100f - Mathf.Clamp(chance, 0f, 50f)) / 100f;
				}
			}
		}
	}
}
namespace MyriadJewels.Effects.Hematite
{
	public static class AddSlash
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;

			[AdditivePower]
			public float Chance;
		}
	}
	public static class AddBlunt
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;

			[AdditivePower]
			public float Chance;
		}
	}
	public static class AddPierce
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;

			[AdditivePower]
			public float Chance;
		}
	}
	public static class AddLightning
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;

			[AdditivePower]
			public float Chance;
		}
	}
	public static class AddSpirit
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;

			[AdditivePower]
			public float Chance;
		}
	}
	public static class AddChopPick
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;

			[AdditivePower]
			public float Chance;
		}
	}
	public static class ResistSlash
	{
		[PublicAPI]
		public struct Config
		{
			[InverseMultiplicativePercentagePower]
			public float Power;
		}
	}
	public static class ResistBlunt
	{
		[PublicAPI]
		public struct Config
		{
			[InverseMultiplicativePercentagePower]
			public float Power;
		}
	}
	public static class ResistPierce
	{
		[PublicAPI]
		public struct Config
		{
			[InverseMultiplicativePercentagePower]
			public float Power;
		}
	}
	public static class ResistFire
	{
		[PublicAPI]
		public struct Config
		{
			[InverseMultiplicativePercentagePower]
			public float Power;
		}
	}
	public static class ResistFrost
	{
		[PublicAPI]
		public struct Config
		{
			[InverseMultiplicativePercentagePower]
			public float Power;
		}
	}
	public static class ResistLightning
	{
		[PublicAPI]
		public struct Config
		{
			[InverseMultiplicativePercentagePower]
			public float Power;
		}
	}
	public static class ResistPoison
	{
		[PublicAPI]
		public struct Config
		{
			[InverseMultiplicativePercentagePower]
			public float Power;
		}
	}
	public static class ResistSpirit
	{
		[PublicAPI]
		public struct Config
		{
			[InverseMultiplicativePercentagePower]
			public float Power;
		}
	}
	[HarmonyPatch(typeof(Character), "Damage")]
	internal static class HematiteTypedDamage
	{
		private static void Prefix(HitData hit)
		{
			Character attacker = hit.GetAttacker();
			Player val = (Player)(object)((attacker is Player) ? attacker : null);
			if (val != null)
			{
				float power = API.GetEffectPower<Cascade.Config>(val, "Cascade").Power;
				float totalDamage = ((DamageTypes)(ref hit.m_damage)).GetTotalDamage();
				float value = Random.value;
				float value2 = Random.value;
				AddSlash.Config effectPower = API.GetEffectPower<AddSlash.Config>(val, "Add Slash");
				if (effectPower.Power > 0f && value <= (effectPower.Chance + power) / 100f)
				{
					hit.m_damage.m_slash += totalDamage * effectPower.Power / 100f;
				}
				AddBlunt.Config effectPower2 = API.GetEffectPower<AddBlunt.Config>(val, "Add Blunt");
				if (effectPower2.Power > 0f && value <= (effectPower2.Chance + power) / 100f)
				{
					hit.m_damage.m_blunt += totalDamage * effectPower2.Power / 100f;
				}
				AddPierce.Config effectPower3 = API.GetEffectPower<AddPierce.Config>(val, "Add Pierce");
				if (effectPower3.Power > 0f && value <= (effectPower3.Chance + power) / 100f)
				{
					hit.m_damage.m_pierce += totalDamage * effectPower3.Power / 100f;
				}
				AddLightning.Config effectPower4 = API.GetEffectPower<AddLightning.Config>(val, "Add Lightning");
				if (effectPower4.Power > 0f && value2 <= (effectPower4.Chance + power) / 100f)
				{
					hit.m_damage.m_lightning += totalDamage * effectPower4.Power / 100f;
				}
				AddSpirit.Config effectPower5 = API.GetEffectPower<AddSpirit.Config>(val, "Add Spirit");
				if (effectPower5.Power > 0f && value2 <= (effectPower5.Chance + power) / 100f)
				{
					hit.m_damage.m_spirit += totalDamage * effectPower5.Power / 100f;
				}
				AddChopPick.Config effectPower6 = API.GetEffectPower<AddChopPick.Config>(val, "Add Chop Pick");
				if (effectPower6.Power > 0f && value <= (effectPower6.Chance + power) / 100f)
				{
					float num = totalDamage * effectPower6.Power / 100f;
					hit.m_damage.m_chop += num;
					hit.m_damage.m_pickaxe += num;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Character), "RPC_Damage")]
	internal static class HematiteResists
	{
		private static void Prefix(Character __instance, HitData hit)
		{
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (val != null)
			{
				Character attacker = hit.GetAttacker();
				if (attacker != null && !((Object)(object)attacker == (Object)(object)__instance))
				{
					float power = API.GetEffectPower<IronLattice.Config>(val, "Iron Lattice").Power;
					Scale(ref hit.m_damage.m_slash, API.GetEffectPower<ResistSlash.Config>(val, "Resist Slash").Power + power);
					Scale(ref hit.m_damage.m_blunt, API.GetEffectPower<ResistBlunt.Config>(val, "Resist Blunt").Power + power);
					Scale(ref hit.m_damage.m_pierce, API.GetEffectPower<ResistPierce.Config>(val, "Resist Pierce").Power + power);
					Scale(ref hit.m_damage.m_fire, API.GetEffectPower<ResistFire.Config>(val, "Resist Fire").Power + power);
					Scale(ref hit.m_damage.m_frost, API.GetEffectPower<ResistFrost.Config>(val, "Resist Frost").Power + power);
					Scale(ref hit.m_damage.m_lightning, API.GetEffectPower<ResistLightning.Config>(val, "Resist Lightning").Power + power);
					Scale(ref hit.m_damage.m_poison, API.GetEffectPower<ResistPoison.Config>(val, "Resist Poison").Power + power);
					Scale(ref hit.m_damage.m_spirit, API.GetEffectPower<ResistSpirit.Config>(val, "Resist Spirit").Power + power);
				}
			}
		}

		private static void Scale(ref float value, float resistPower)
		{
			if (!(value <= 0f) && !(resistPower <= 0f))
			{
				value *= (100f - Mathf.Clamp(resistPower, 0f, 90f)) / 100f;
			}
		}
	}
}
namespace MyriadJewels.Effects.Carnelian
{
	public static class SecondWind
	{
		[PublicAPI]
		public struct Config
		{
			[InverseMultiplicativePercentagePower]
			public float Power;
		}
	}
	public static class CombatBreath
	{
		[PublicAPI]
		public struct Config
		{
			[InverseMultiplicativePercentagePower]
			public float Power;
		}

		[HarmonyPatch(typeof(Attack), "GetAttackStamina")]
		private static class ReduceAttackStamina
		{
			private static void Postfix(Attack __instance, ref float __result)
			{
				Humanoid character = __instance.m_character;
				Player val = (Player)(object)((character is Player) ? character : null);
				if (val != null)
				{
					float num = API.GetEffectPower<Config>(val, "Combat Breath").Power + API.GetEffectPower<SecondLung.Config>(val, "Second Lung").Power;
					if (!(num <= 0f))
					{
						__result *= 100f / (100f + num);
					}
				}
			}
		}

		[HarmonyPatch(typeof(Humanoid), "BlockAttack")]
		private static class ReduceBlockStamina
		{
			private static void Prefix(Humanoid __instance)
			{
				Player val = (Player)(object)((__instance is Player) ? __instance : null);
				if (val != null)
				{
					float num = API.GetEffectPower<Config>(val, "Combat Breath").Power + API.GetEffectPower<SecondLung.Config>(val, "Second Lung").Power;
					if (!(num <= 0f))
					{
						__instance.m_blockStaminaDrain *= 100f / (100f + num);
					}
				}
			}
		}
	}
	public static class EitrReservoir
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}

		[HarmonyPatch(typeof(Player), "GetTotalFoodValue")]
		private static class IncreaseMaxEitr
		{
			private static void Postfix(Player __instance, ref float eitr)
			{
				float power = API.GetEffectPower<Config>(__instance, "Eitr Reservoir").Power;
				float power2 = API.GetEffectPower<OrangeReservoir.Config>(__instance, "Orange Reservoir").Power;
				eitr += power + power2;
			}
		}
	}
	public static class ClearHead
	{
		[PublicAPI]
		public struct Config
		{
			[InverseMultiplicativePercentagePower]
			public float Power;
		}
	}
	[HarmonyPatch(typeof(Player), "UpdateStats", new Type[] { })]
	internal static class CarnelianUpdateStats
	{
		private static void Prefix(Player __instance)
		{
			float num = API.GetEffectPower<SecondWind.Config>(__instance, "Second Wind").Power + API.GetEffectPower<SecondLung.Config>(__instance, "Second Lung").Power;
			if (num > 0f)
			{
				__instance.m_staminaRegenDelay = Mathf.Max(0.1f, __instance.m_staminaRegenDelay * (100f - num) / 100f);
			}
			float num2 = API.GetEffectPower<ClearHead.Config>(__instance, "Clear Head").Power + API.GetEffectPower<OrangeReservoir.Config>(__instance, "Orange Reservoir").Power;
			if (num2 > 0f)
			{
				__instance.m_eitrRegenDelay = Mathf.Max(0.1f, __instance.m_eitrRegenDelay * (100f - num2) / 100f);
			}
		}
	}
}
namespace MyriadJewels.Effects.Bloodstone
{
	public static class ManicCycle
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class SurgeDetonate
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class OverchargeLean
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class HighWaterAnchor
	{
		[PublicAPI]
		public struct Config
		{
			[InverseMultiplicativePercentagePower]
			public float Power;
		}
	}
	public static class CrestAmp
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	public static class TrinketResonance
	{
		[PublicAPI]
		public struct Config
		{
			[AdditivePower]
			public float Power;
		}
	}
	[HarmonyPatch(typeof(Character), "Damage")]
	internal static class BloodstoneCombat
	{
		[HarmonyPriority(100)]
		private static void Prefix(HitData hit)
		{
			Character attacker = hit.GetAttacker();
			Player val = (Player)(object)((attacker is Player) ? attacker : null);
			if (val != null)
			{
				float adrenaline = SoftMods.GetAdrenaline(val);
				float num = 1f;
				float num2 = API.GetEffectPower<ManicCycle.Config>(val, "Manic Cycle").Power + API.GetEffectPower<ManicEngine.Config>(val, "Manic Engine").Power;
				if (num2 > 0f)
				{
					SoftMods.AddAdrenaline(val, num2 * 0.05f);
				}
				float num3 = API.GetEffectPower<CrestAmp.Config>(val, "Crest Amp").Power + API.GetEffectPower<CrestSovereign.Config>(val, "Crest Sovereign").Power;
				float num4 = 60f;
				if (API.GetEffectPower<CrestSovereign.Config>(val, "Crest Sovereign").Power > 0f)
				{
					num4 = 45f;
				}
				if (num3 > 0f && adrenaline >= num4)
				{
					num += num3 / 100f;
				}
				float power = API.GetEffectPower<TrinketResonance.Config>(val, "Trinket Resonance").Power;
				if (power > 0f && adrenaline >= num4)
				{
					num += power / 200f;
				}
				float power2 = API.GetEffectPower<OverchargeLean.Config>(val, "Overcharge Lean").Power;
				if (power2 > 0f && adrenaline >= 90f)
				{
					num += power2 / 100f;
				}
				float num5 = API.GetEffectPower<SurgeDetonate.Config>(val, "Surge Detonate").Power + API.GetEffectPower<ManicEngine.Config>(val, "Manic Engine").Power;
				if (num5 > 0f && adrenaline >= 95f)
				{
					num += num5 / 100f;
					SoftMods.AddAdrenaline(val, 0f - Mathf.Min(adrenaline, 25f));
				}
				OpposedHearts.Config effectPower = API.GetEffectPower<OpposedHearts.Config>(val, "Opposed Hearts");
				if (effectPower.Power > 0f && adrenaline >= 90f)
				{
					num += effectPower.Power / 100f;
				}
				if (num != 1f)
				{
					hit.ApplyModifier(num);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Character), "RPC_Damage")]
	internal static class BloodstoneEdgeDefense
	{
		[HarmonyPriority(200)]
		private static void Prefix(Character __instance, HitData hit)
		{
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (val != null)
			{
				float adrenaline = SoftMods.GetAdrenaline(val);
				OpposedHearts.Config effectPower = API.GetEffectPower<OpposedHearts.Config>(val, "Opposed Hearts");
				if (effectPower.Power > 0f && adrenaline < 30f)
				{
					float num = (100f - Mathf.Clamp(effectPower.Power * 0.5f, 0f, 20f)) / 100f;
					hit.ApplyModifier(num);
				}
				float num2 = API.GetEffectPower<HighWaterAnchor.Config>(val, "High-Water Anchor").Power + API.GetEffectPower<CrestSovereign.Config>(val, "Crest Sovereign").Power;
				if (num2 > 0f && adrenaline >= 70f)
				{
					hit.ApplyModifier((100f - Mathf.Clamp(num2 * 0.25f, 0f, 20f)) / 100f);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Player), "FixedUpdate")]
	internal static class BloodstonePulseWatcher
	{
		private static float _lastAdren;

		private static bool _surged;

		private static void Postfix(Player __instance)
		{
			if (((Character)__instance).IsOwner())
			{
				float adrenaline = SoftMods.GetAdrenaline(__instance);
				float power = API.GetEffectPower<FusedPulse.Config>(__instance, "Fused Pulse").Power;
				if (power > 0f && adrenaline >= 70f)
				{
					__instance.m_eitrRegenDelay = Mathf.Max(0.1f, __instance.m_eitrRegenDelay * (100f - power) / 100f);
				}
				PackAndPulse.Config effectPower = API.GetEffectPower<PackAndPulse.Config>(__instance, "Pack & Pulse");
				if (effectPower.Power > 0f && adrenaline >= 90f && _lastAdren < 90f && !_surged)
				{
					_surged = true;
					FamiliarController.Pulse(6f, effectPower.Power);
					FamiliarController.Ensure(__instance);
				}
				if (adrenaline < 50f)
				{
					_surged = false;
				}
				_lastAdren = adrenaline;
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}