Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of MyriadJewels v0.1.0
MyriadJewels.dll
Decompiled 11 hours agousing 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<SpiritWolf.Config>("Spirit Wolf", "Summons a combat wolf familiar.", "Spirit wolf familiar strength $1%."); API.AddGemEffect<CombatCrow.Config>("Combat Crow", "Summons an attacking crow familiar.", "Combat crow familiar strength $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)); } } [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<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 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<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, "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<MyriadFamiliar>(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<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) { return (Object)(object)((Component)character).GetComponent<MyriadFamiliar>() != (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<Character>(); if ((Object)(object)component == (Object)null) { familiar.transform.position = Vector3.Lerp(familiar.transform.position, val, Time.deltaTime * 2f); return; } MonsterAI component2 = ((Component)component).GetComponent<MonsterAI>(); 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<GameObject>(val, val2, Quaternion.identity); val3.AddComponent<MyriadFamiliar>().Kind = kind; Character component = val3.GetComponent<Character>(); 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<MonsterAI>(); if (component2 != null) { component2.SetFollowTarget(((Component)player).gameObject); ((BaseAI)component2).m_alerted = true; } } CharacterDrop component3 = val3.GetComponent<CharacterDrop>(); if (component3 != null) { component3.m_dropsEnabled = false; } DropOnDestroyed[] componentsInChildren = val3.GetComponentsInChildren<DropOnDestroyed>(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<MyriadFamiliar>(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<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) { } } }