using System; 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; [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+3d232cbe17db55d84f9cdcb3003fe87d78eb190a")] [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("Spirit Wolf", "Summons a combat wolf familiar.", "Spirit wolf familiar strength $1%."); API.AddGemEffect("Combat Crow", "Summons an attacking crow familiar.", "Combat crow familiar strength $1%."); API.AddGemEffect("Summon Potency", "Familiar HP and damage up.", "Familiar power increased by $1%."); API.AddGemEffect("Trophy Hunter", "Trophy drops come easier.", "$1% trophy drop chance; $2% trophy weight reduction."); API.AddGemEffect("Second Wind", "Stamina recovers sooner after use.", "Stamina regen delay reduced by $1%."); API.AddGemEffect("Combat Breath", "Attack and block cost less stamina.", "Attack and block stamina cost reduced by $1%."); API.AddGemEffect("Eitr Reservoir", "Increases maximum eitr.", "Maximum eitr increased by $1."); API.AddGemEffect("Clear Head", "Eitr returns faster after casting.", "Eitr regen delay reduced by $1%."); API.AddGemEffect("Manic Cycle", "Faster adrenaline gain and decay.", "Adrenaline gain/decay rate +$1%."); API.AddGemEffect("Surge Detonate", "Surge spends adrenaline for burst.", "On Surge, convert adrenaline into $1% burst."); API.AddGemEffect("Overcharge Lean", "Lean into Overcharge risk/reward.", "Overcharge effects amplified by $1%."); API.AddGemEffect("High-Water Anchor", "Resist decay while adrenaline is high.", "While high, adrenaline decay reduced by $1%."); API.AddGemEffect("Crest Amp", "Power while adrenaline is high.", "While adrenaline ≥ threshold: +$1% combat power."); API.AddGemEffect("Trinket Resonance", "Battle Flow trinkets scale harder while high.", "BF trinket scaling +$1% while high."); API.AddGemEffect("Lightning Proc", "Chance on hit for lightning burst.", "$2% chance to deal $1% lightning damage."); API.AddGemEffect("Spirit Hex", "Chance on hit for spirit damage.", "$2% chance to deal $1% spirit damage."); API.AddGemEffect("Physical Burst", "Chance on hit for physical burst.", "$2% chance to deal $1% physical burst."); API.AddGemEffect("Stamina Siphon", "Chance to restore stamina on block/hit.", "$2% chance to restore $1 stamina."); API.AddGemEffect("Eitr Siphon", "Chance to restore eitr on hit.", "$2% chance to restore $1 eitr."); API.AddGemEffect("Adrenal Spike", "Chance on hit for adrenaline.", "$2% chance to gain $1 adrenaline."); API.AddGemEffect("Add Slash", "Chance to add slash damage.", "$2% chance to add $1% slash."); API.AddGemEffect("Add Blunt", "Chance to add blunt damage.", "$2% chance to add $1% blunt."); API.AddGemEffect("Add Pierce", "Chance to add pierce damage.", "$2% chance to add $1% pierce."); API.AddGemEffect("Add Lightning", "Chance to add lightning damage.", "$2% chance to add $1% lightning."); API.AddGemEffect("Add Spirit", "Chance to add spirit damage.", "$2% chance to add $1% spirit."); API.AddGemEffect("Add Chop Pick", "Chance to add chop/pickaxe damage.", "$2% chance to add $1% tool damage."); API.AddGemEffect("Resist Slash", "Reduces slash damage taken.", "Slash damage taken reduced by $1%."); API.AddGemEffect("Resist Blunt", "Reduces blunt damage taken.", "Blunt damage taken reduced by $1%."); API.AddGemEffect("Resist Pierce", "Reduces pierce damage taken.", "Pierce damage taken reduced by $1%."); API.AddGemEffect("Resist Fire", "Reduces fire damage taken.", "Fire damage taken reduced by $1%."); API.AddGemEffect("Resist Frost", "Reduces frost damage taken.", "Frost damage taken reduced by $1%."); API.AddGemEffect("Resist Lightning", "Reduces lightning damage taken.", "Lightning damage taken reduced by $1%."); API.AddGemEffect("Resist Poison", "Reduces poison damage taken.", "Poison damage taken reduced by $1%."); API.AddGemEffect("Resist Spirit", "Reduces spirit damage taken.", "Spirit damage taken reduced by $1%."); API.AddGemEffect("Twin Blade Aptitude", "DualWield skill up.", "DualWield skill +$1%."); API.AddGemEffect("Off-Hand Catch-Up", "Softer off-hand penalty while dual.", "Off-hand penalty eased by $1%."); API.AddGemEffect("Paired Rhythm", "After dual hits, short attack speed.", "After dual hits: +$1% attack speed briefly."); API.AddGemEffect("Claw Rake", "Fist secondary assist.", "Fist secondary power +$1%."); API.AddGemEffect("Kick Thunder", "2H axe kick stagger.", "Kick stagger / blunt +$1%."); API.AddGemEffect("Sledge Quake", "Sledge special AOE/stagger.", "Sledge special power +$1%."); API.AddGemEffect("Great Weapon Poise", "While 2H: stagger threshold up.", "2H stagger threshold +$1%."); API.AddGemEffect("Great Weapon Economy", "While 2H: attack stam cost down.", "2H attack stamina cost -$1%."); API.AddGemEffect("Great Weapon Special", "While 2H: secondary power up.", "2H secondary power +$1%."); API.AddGemEffect("Great Weapon Commit", "While 2H: damage after heavy lands.", "After 2H secondary: +$1% damage briefly."); API.AddGemEffect("Well Fed Grace", "Bonus while Nature Well Fed.", "While Well Fed: +$1% to homestead bonuses."); API.AddGemEffect("Fieldcraft", "Farming, mining, lumber, foraging.", "Profession skills +$1%."); API.AddGemEffect("Outrider", "Ranching, sailing, packhorse.", "Travel/ranch skills +$1%."); API.AddGemEffect("Craftmaster", "Blacksmithing and building.", "Craft skills +$1%."); API.AddGemEffect("Expert Runeforger", "Runeforging skill.", "Runeforging +$1%."); API.AddGemEffect("Expert Atgeir", "Polearm skill.", "Polearms +$1%."); API.AddGemEffect("Expert Unarmed", "Fists skill.", "Unarmed +$1%."); API.AddGemEffect("Expert Sledge", "Sledge / 2H blunt skill.", "Clubs +$1%."); API.AddGemEffect("Familiar Bond", "Familiar duration and potency.", "Familiar duration/potency +$1%."); API.AddGemEffect("Moon Hunt", "Night trophy hunt.", "At night: trophy chance +$1%."); API.AddGemEffect("Manic Engine", "Overdrive Surge amp.", "Surge / detonate power +$1%."); API.AddGemEffect("Crest Sovereign", "Edge crest amp.", "Crest threshold/power +$1%."); API.AddGemEffect("Fused Pulse", "High adren eitr return.", "While high adren: eitr return +$1%."); API.AddGemEffect("Opposed Hearts", "Surge AS / low DR.", "On Surge: AS +$1%; when low: DR +$2%."); API.AddGemEffect("Twin Tempest", "DualWield cadence amp.", "Off-hand / rhythm ease +$1%."); API.AddGemEffect("Great Oath", "2H commit amp.", "2H special / commit +$1%."); API.AddGemEffect("Warpath", "Stance hits feed adrenaline.", "Stance hits grant +$1 adrenaline."); API.AddGemEffect("Second Lung", "Economy sockets amp.", "Second Wind / Combat Breath +$1%."); API.AddGemEffect("Orange Reservoir", "Eitr reservoir play.", "Eitr Reservoir / Clear Head +$1%."); API.AddGemEffect("Cascade", "Pyrite proc chance up.", "Pyrite proc chances +$1%."); API.AddGemEffect("Iron Lattice", "Hematite resists amp.", "Hematite resists +$1%."); API.AddGemEffect("Rooted Craft", "Profession sockets amp.", "Fieldcraft / Outrider / Craftmaster +$1%."); API.AddGemEffect("Green Thumb", "Well Fed + green.", "Well Fed Grace +$1%."); API.AddGemEffect("Full Larder", "Food drain while Well Fed.", "Food drain -$1% while Well Fed."); API.AddGemEffect("Rune Grove", "Runeforge gain.", "Runeforging gain +$1%."); API.AddGemEffect("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)); } } [BepInPlugin("com.myriad.jewels", "MyriadJewels", "0.1.0")] [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.0"; 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.0 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(); } } } 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(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(val, "Paired Rhythm").Power + API.GetEffectPower(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(val, "Off-Hand Catch-Up").Power + API.GetEffectPower(val, "Twin Tempest").Power; if (num3 > 0f) { num += num3 / 200f; } } if (SoftMods.IsTwoHandedNoShield(val)) { float power = API.GetEffectPower(val, "Great Oath").Power; float num4 = API.GetEffectPower(val, "Great Weapon Special").Power + power; float num5 = API.GetEffectPower(val, "Great Weapon Commit").Power + power; if ((int)hit.m_skill == 7) { num += API.GetEffectPower(val, "Kick Thunder").Power / 100f; } if ((int)hit.m_skill == 3) { num += API.GetEffectPower(val, "Sledge Quake").Power / 100f; } if ((int)hit.m_skill == 11) { num += API.GetEffectPower(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(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(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(val, "Cascade").Power; float totalDamage = ((DamageTypes)(ref hit.m_damage)).GetTotalDamage(); float value = Random.value; LightningProc.Config effectPower = API.GetEffectPower(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(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(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(val, "Eitr Siphon"); if (effectPower4.Power > 0f && Random.value <= (effectPower4.Chance + power) / 100f) { ((Character)val).AddEitr(effectPower4.Power); } AdrenalSpike.Config effectPower5 = API.GetEffectPower(val, "Adrenal Spike"); if (effectPower5.Power > 0f && Random.value <= (effectPower5.Chance + power) / 100f) { SoftMods.AddAdrenaline(val, effectPower5.Power); } Warpath.Config effectPower6 = API.GetEffectPower(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(val, "Stamina Siphon"); float power = API.GetEffectPower(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(player, "Rooted Craft").Power; float num = 0f; if (IsWellFed(player)) { num = API.GetEffectPower(player, "Well Fed Grace").Power + API.GetEffectPower(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(player, "Expert Unarmed").Power; } } else { num2 += API.GetEffectPower(player, "Expert Atgeir").Power; } } else { num2 += API.GetEffectPower(player, "Expert Sledge").Power; } } else if (skillType - 12 > 1) { if ((int)skillType == 103 || (int)skillType == 110) { num2 += API.GetEffectPower(player, "Outrider").Power + power; } } else { num2 += API.GetEffectPower(player, "Fieldcraft").Power + power; } num2 += API.GetEffectPower(player, "Craftmaster").Power * 0.25f + power * 0.25f; num2 += API.GetEffectPower(player, "Expert Runeforger").Power * 0.25f + API.GetEffectPower(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(__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 static class FamiliarController { private const float WolfCooldownBase = 90f; private const float CrowCooldownBase = 75f; private const float MinCooldown = 20f; private static GameObject? _wolf; private static GameObject? _crow; private static float _wolfCooldownUntil; private static float _crowCooldownUntil; private static float _pulseUntil; 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(player, "Spirit Wolf").Power; float power2 = API.GetEffectPower(player, "Combat Crow").Power; float potency = API.GetEffectPower(player, "Summon Potency").Power + API.GetEffectPower(player, "Familiar Bond").Power; if (power > 0f) { _wolf = Maintain(player, _wolf, FamiliarKind.Wolf, "Wolf", power, potency, 1f, ref _wolfCooldownUntil); } else if ((Object)(object)_wolf != (Object)null) { _wolf = Despawn(_wolf, applyCooldown: false); } if (power2 > 0f) { _crow = Maintain(player, _crow, FamiliarKind.Crow, "GiantCrow_bal", power2, potency, 0.5f, ref _crowCooldownUntil); } else if ((Object)(object)_crow != (Object)null) { _crow = Despawn(_crow, applyCooldown: false); } } 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); } } internal static void OnFamiliarDeath(Character familiar) { MyriadFamiliar myriadFamiliar = default(MyriadFamiliar); if (!((Component)familiar).TryGetComponent(ref myriadFamiliar)) { return; } Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && ((Character)localPlayer).IsOwner()) { LoseFamiliar(myriadFamiliar.Kind, localPlayer, applyCooldown: true); if (myriadFamiliar.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(player, "Summon Potency").Power + API.GetEffectPower(player, "Familiar Bond").Power; return Mathf.Max(20f, baseSeconds * 100f / (100f + num)); } internal static bool IsFamiliar(Character character) { return (Object)(object)((Component)character).GetComponent() != (Object)null; } 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); } private static void TickFollowOne(Player player, ref GameObject? familiar, FamiliarKind kind, float radius, float height) { //IL_0026: 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_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_0042: 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) //IL_0053: 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_0084: 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_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)familiar == (Object)null) { return; } if (!Object.op_Implicit((Object)(object)familiar)) { LoseFamiliar(kind, player, applyCooldown: true); familiar = null; return; } Vector3 val = ((Component)player).transform.position + ((Component)player).transform.forward * (0f - radius) + Vector3.up * height; Character component = familiar.GetComponent(); if ((Object)(object)component == (Object)null) { familiar.transform.position = Vector3.Lerp(familiar.transform.position, val, Time.deltaTime * 2f); return; } MonsterAI component2 = ((Component)component).GetComponent(); if (component2 != null && (Object)(object)component2.GetFollowTarget() != (Object)(object)((Component)player).gameObject) { component2.SetFollowTarget(((Component)player).gameObject); } if (Vector3.Distance(((Component)component).transform.position, ((Component)player).transform.position) > 40f) { ((Component)component).transform.position = val; } } private static GameObject? Maintain(Player player, GameObject? existing, FamiliarKind kind, string prefab, float power, float potency, float sizeScale, ref float cooldownUntil) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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) { return existing; } if (Time.time < cooldownUntil) { return null; } ZNetScene instance = ZNetScene.instance; GameObject val = ((instance != null) ? instance.GetPrefab(prefab) : null); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)("MyriadJewels: familiar prefab '" + prefab + "' missing.")); return null; } Vector3 val2 = ((Component)player).transform.position + ((Component)player).transform.forward * 2f + Vector3.up * ((sizeScale < 1f) ? 1.5f : 0f); GameObject val3 = Object.Instantiate(val, val2, Quaternion.identity); val3.AddComponent().Kind = kind; Character component = val3.GetComponent(); if (component != null) { component.m_faction = (Faction)0; float num = sizeScale * (1f + (power + potency) / 200f * PulseMul); component.SetMaxHealth(component.GetMaxHealth() * Mathf.Max(num, 0.25f)); component.SetHealth(component.GetMaxHealth()); MonsterAI component2 = val3.GetComponent(); if (component2 != null) { component2.SetFollowTarget(((Component)player).gameObject); ((BaseAI)component2).m_alerted = true; } } CharacterDrop component3 = val3.GetComponent(); if (component3 != null) { component3.m_dropsEnabled = false; } DropOnDestroyed[] componentsInChildren = val3.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.Destroy((Object)(object)componentsInChildren[i]); } Plugin.Log.LogInfo((object)$"Spawned familiar {prefab} (power={power}, potency={potency})."); return val3; } 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(ref myriadFamiliar)) { LoseFamiliar(myriadFamiliar.Kind, localPlayer, applyCooldown: true); } } Object.Destroy((Object)(object)go); } return null; } } [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(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(); 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(); 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(); 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(localPlayer, "Trophy Hunter"); float power = API.GetEffectPower(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(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(val, "Cascade").Power; float totalDamage = ((DamageTypes)(ref hit.m_damage)).GetTotalDamage(); float value = Random.value; float value2 = Random.value; AddSlash.Config effectPower = API.GetEffectPower(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(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(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(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(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(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(val, "Iron Lattice").Power; Scale(ref hit.m_damage.m_slash, API.GetEffectPower(val, "Resist Slash").Power + power); Scale(ref hit.m_damage.m_blunt, API.GetEffectPower(val, "Resist Blunt").Power + power); Scale(ref hit.m_damage.m_pierce, API.GetEffectPower(val, "Resist Pierce").Power + power); Scale(ref hit.m_damage.m_fire, API.GetEffectPower(val, "Resist Fire").Power + power); Scale(ref hit.m_damage.m_frost, API.GetEffectPower(val, "Resist Frost").Power + power); Scale(ref hit.m_damage.m_lightning, API.GetEffectPower(val, "Resist Lightning").Power + power); Scale(ref hit.m_damage.m_poison, API.GetEffectPower(val, "Resist Poison").Power + power); Scale(ref hit.m_damage.m_spirit, API.GetEffectPower(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(val, "Combat Breath").Power + API.GetEffectPower(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(val, "Combat Breath").Power + API.GetEffectPower(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(__instance, "Eitr Reservoir").Power; float power2 = API.GetEffectPower(__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(__instance, "Second Wind").Power + API.GetEffectPower(__instance, "Second Lung").Power; if (num > 0f) { __instance.m_staminaRegenDelay = Mathf.Max(0.1f, __instance.m_staminaRegenDelay * (100f - num) / 100f); } float num2 = API.GetEffectPower(__instance, "Clear Head").Power + API.GetEffectPower(__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(val, "Manic Cycle").Power + API.GetEffectPower(val, "Manic Engine").Power; if (num2 > 0f) { SoftMods.AddAdrenaline(val, num2 * 0.05f); } float num3 = API.GetEffectPower(val, "Crest Amp").Power + API.GetEffectPower(val, "Crest Sovereign").Power; float num4 = 60f; if (API.GetEffectPower(val, "Crest Sovereign").Power > 0f) { num4 = 45f; } if (num3 > 0f && adrenaline >= num4) { num += num3 / 100f; } float power = API.GetEffectPower(val, "Trinket Resonance").Power; if (power > 0f && adrenaline >= num4) { num += power / 200f; } float power2 = API.GetEffectPower(val, "Overcharge Lean").Power; if (power2 > 0f && adrenaline >= 90f) { num += power2 / 100f; } float num5 = API.GetEffectPower(val, "Surge Detonate").Power + API.GetEffectPower(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(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(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(val, "High-Water Anchor").Power + API.GetEffectPower(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(__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(__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) { } } }