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 MonsterModifiers v1.3.3
MonsterModifiers.dll
Decompiled 2 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using JetBrains.Annotations; using Jotunn; using Jotunn.Entities; using Jotunn.Extensions; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using MonsterModifiers.Custom_Components; using MonsterModifiers.Modifiers; using MonsterModifiers.StatusEffects; using MonsterModifiers.Visuals; using TMPro; using UnityEngine; using UnityEngine.UI; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("MonsterModifiers")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("KorCaptain")] [assembly: AssemblyProduct("MonsterModifiers")] [assembly: AssemblyCopyright("Copyright © 2022")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("E0E2F92E-557C-4A05-9D89-AA92A0BD75C4")] [assembly: AssemblyFileVersion("1.3.3")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.3.3.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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 MonsterModifiers { [BepInPlugin("KorCaptain.MonsterModifiers", "MonsterModifiers", "1.3.3")] public class MonsterModifiersPlugin : BaseUnityPlugin { public enum Toggle { On = 1, Off = 0 } internal const string ModName = "MonsterModifiers"; internal const string ModVersion = "1.3.3"; internal const string Author = "KorCaptain"; private const string ModGUID = "KorCaptain.MonsterModifiers"; private static string ConfigFileName = "KorCaptain.MonsterModifiers.cfg"; private static string ConfigFileFullPath; internal static string ConnectionError; private readonly Harmony _harmony = new Harmony("KorCaptain.MonsterModifiers"); public static readonly ManualLogSource MonsterModifiersLogger; public Texture2D tex = null; public static ConfigEntry<int> Configurations_Monster_Modifiers; public static ConfigEntry<int> Configurations_Boss_Modifiers; public static ConfigEntry<int> Cfg_PierceImmunity_DamageReduction; public static ConfigEntry<int> Cfg_SlashImmunity_DamageReduction; public static ConfigEntry<int> Cfg_BluntImmunity_DamageReduction; public static ConfigEntry<int> Cfg_ElementalImmunity_DamageReduction; public static ConfigEntry<int> Cfg_Knockback_StaggerForce; public static ConfigEntry<int> Cfg_Knockback_PushForce; public static ConfigEntry<float> Cfg_FastAttackSpeed_AnimatorMultiplier; public static ConfigEntry<float> Cfg_FastAttackSpeed_IntervalReduction; public static ConfigEntry<float> Cfg_SplitSpawn_Scale; public static ConfigEntry<float> Cfg_SplitSpawn_HP; public static ConfigEntry<Toggle> Cfg_SplitSpawn_RandomizeWeapon; public static ConfigEntry<float> Cfg_ShieldBreaker_DurabilityThreshold; public static ConfigEntry<float> Cfg_ShieldBreaker_DurabilityReduction; public static ConfigEntry<float> Cfg_IgnoreArmor_ArmorReduction; public static ConfigEntry<float> Cfg_FoodDrain_DurationReduction; public static ConfigEntry<float> Cfg_ElementalInfusion_DamageRatio; public static ConfigEntry<float> Cfg_Forceful_PushMultiplier; public static ConfigEntry<float> Cfg_Vampiric_HealRatio; public static ConfigEntry<int> Cfg_PersonalShield_Duration; public static ConfigEntry<float> Cfg_PersonalShield_Magnitude; public static ConfigEntry<float> Cfg_FastMovement_SpeedMultiplier; public static ConfigEntry<float> Cfg_DistantDetection_RangeMultiplier; public static ConfigEntry<float> Cfg_SoulEater_Radius; public static ConfigEntry<int> Cfg_SoulEater_MaxStacks; public static ConfigEntry<float> Cfg_SoulEater_GrowthMultiplier; public static ConfigEntry<float> Cfg_SoulEater_DmgStack1; public static ConfigEntry<float> Cfg_SoulEater_DmgStack2; public static ConfigEntry<float> Cfg_SoulEater_DmgStack3; public static ConfigEntry<int> Cfg_ResistanceNotification_MaxCount; public static ConfigEntry<int> Cfg_Boss_OffenseMultiplier; public static ConfigEntry<int> Cfg_Boss_HealMultiplier; public static ConfigEntry<int> Cfg_Offense_Probability; public static ConfigEntry<int> Cfg_Defense_Probability; public static ConfigEntry<int> Cfg_Utility_Probability; public static ConfigEntry<int> Cfg_SplitSpawn_Probability; public static ConfigEntry<Toggle> Cfg_EliteMonster_Enabled; public static ConfigEntry<int> Cfg_EliteMonster_Probability; public static ConfigEntry<int> Cfg_Elite_Size; public static ConfigEntry<int> Cfg_Elite_HP; public static ConfigEntry<int> Cfg_Elite_ATK; public static ConfigEntry<int> Cfg_Elite_DFS; public void Awake() { bool saveOnConfigSet = ((BaseUnityPlugin)this).Config.SaveOnConfigSet; ((BaseUnityPlugin)this).Config.SaveOnConfigSet = false; Assembly executingAssembly = Assembly.GetExecutingAssembly(); _harmony.PatchAll(executingAssembly); SetupWatcher(); if (saveOnConfigSet) { ((BaseUnityPlugin)this).Config.SaveOnConfigSet = saveOnConfigSet; ((BaseUnityPlugin)this).Config.Save(); } YamlUtils.ParseDefaultYamls(); TranslationUtils.AddLocalizations(); ModifierAssetUtils.Setup(); ModifierAssetUtils.LoadAllIcons(); int length = Enum.GetValues(typeof(MonsterModifierTypes)).Length; int num = length - ModifierUtils.BossExcludedModifiers.Count; ConfigFile config = ((BaseUnityPlugin)this).Config; AcceptableValueBase val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, num); Configurations_Boss_Modifiers = ConfigFileExtensions.BindConfig<int>(config, "General", "boss_Modifiers", 5, "Minimum modifiers for bosses (0 = disabled). Max is auto-calculated excluding death-spawn modifiers. N = always assign at least N modifiers.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); SetConfigOrder((ConfigEntryBase)(object)Configurations_Boss_Modifiers, 7); Cfg_EliteMonster_Enabled = ConfigFileExtensions.BindConfig<Toggle>(((BaseUnityPlugin)this).Config, "General", "Elite_Monster", Toggle.On, "Enable Elite Monster spawning. When Off, its 10% probability is automatically redistributed (+5% Offense, +5% Defense).", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); SetConfigOrder((ConfigEntryBase)(object)Cfg_EliteMonster_Enabled, 6); ConfigFile config2 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, length); Configurations_Monster_Modifiers = ConfigFileExtensions.BindConfig<int>(config2, "General", "Monster_Modifiers", 5, "Maximum modifiers for regular monsters. 0 = disabled.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); SetConfigOrder((ConfigEntryBase)(object)Configurations_Monster_Modifiers, 5); ConfigFile config3 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100); Cfg_EliteMonster_Probability = ConfigFileExtensions.BindConfig<int>(config3, "General", "Elite_Monster_Probability", 10, "Relative roll probability for Elite Monster (boss-excluded, biome-spawn only).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); SetConfigOrder((ConfigEntryBase)(object)Cfg_EliteMonster_Probability, 4); ConfigFile config4 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100); Cfg_SplitSpawn_Probability = ConfigFileExtensions.BindConfig<int>(config4, "General", "SplitSpawn_Probability", 10, "Relative roll probability for SplitSpawn modifier (boss-excluded). Set 0 to disable SplitSpawn from rolling.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); SetConfigOrder((ConfigEntryBase)(object)Cfg_SplitSpawn_Probability, 3); ConfigFile config5 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100); Cfg_Offense_Probability = ConfigFileExtensions.BindConfig<int>(config5, "General", "Offense_Probability", 35, "Relative roll probability for Offense modifiers (values are treated as ratio).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); SetConfigOrder((ConfigEntryBase)(object)Cfg_Offense_Probability, 2); ConfigFile config6 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100); Cfg_Defense_Probability = ConfigFileExtensions.BindConfig<int>(config6, "General", "Defense_Probability", 35, "Relative roll probability for Defense modifiers (values are treated as ratio).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); SetConfigOrder((ConfigEntryBase)(object)Cfg_Defense_Probability, 1); ConfigFile config7 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100); Cfg_Utility_Probability = ConfigFileExtensions.BindConfig<int>(config7, "General", "Utility_Probability", 10, "Relative roll probability for Utility modifiers.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); SetConfigOrder((ConfigEntryBase)(object)Cfg_Utility_Probability, 0); ConfigFile config8 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100); Cfg_PierceImmunity_DamageReduction = ConfigFileExtensions.BindConfig<int>(config8, "Modifier_Defense", "PierceImmunity Damage Reduction %", 70, "Percentage of pierce damage reduced when PierceImmunity modifier is active. 100 = full immunity.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config9 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100); Cfg_SlashImmunity_DamageReduction = ConfigFileExtensions.BindConfig<int>(config9, "Modifier_Defense", "SlashImmunity Damage Reduction %", 70, "Percentage of slash damage reduced when SlashImmunity modifier is active. 100 = full immunity.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config10 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100); Cfg_BluntImmunity_DamageReduction = ConfigFileExtensions.BindConfig<int>(config10, "Modifier_Defense", "BluntImmunity Damage Reduction %", 70, "Percentage of blunt damage reduced when BluntImmunity modifier is active. 100 = full immunity.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config11 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100); Cfg_ElementalImmunity_DamageReduction = ConfigFileExtensions.BindConfig<int>(config11, "Modifier_Defense", "ElementalImmunity Damage Reduction %", 70, "Percentage of elemental damage (fire/frost/lightning/poison/spirit) reduced when ElementalImmunity modifier is active. 100 = full immunity.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config12 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2000); Cfg_Knockback_StaggerForce = ConfigFileExtensions.BindConfig<int>(config12, "Modifier_Offense", "Knockback Stagger Force", 500, "Stagger force applied by the Knockback modifier.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config13 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 200); Cfg_Knockback_PushForce = ConfigFileExtensions.BindConfig<int>(config13, "Modifier_Offense", "Knockback Push Force", 45, "Push force applied by the Knockback modifier.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config14 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f); Cfg_FastAttackSpeed_AnimatorMultiplier = ConfigFileExtensions.BindConfig<float>(config14, "Modifier_Offense", "FastAttackSpeed Animator Speed Multiplier", 0.3f, "Animator speed bonus for FastAttackSpeed modifier (0.3 = +30% faster animation). Default: 0.3", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config15 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.95f); Cfg_FastAttackSpeed_IntervalReduction = ConfigFileExtensions.BindConfig<float>(config15, "Modifier_Offense", "FastAttackSpeed Attack Interval Reduction", 0.3f, "Attack cooldown reduction fraction for FastAttackSpeed modifier (0.3 = -30% cooldown). Default: 0.3", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config16 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f); Cfg_SplitSpawn_Scale = ConfigFileExtensions.BindConfig<float>(config16, "Modifier_Offense", "SplitSpawn Scale", 0.85f, "Size of SplitSpawn children relative to parent size (0.7 = 70%).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config17 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f); Cfg_SplitSpawn_HP = ConfigFileExtensions.BindConfig<float>(config17, "Modifier_Offense", "SplitSpawn Health", 0.7f, "HP of SplitSpawn children as a fraction of parent max HP (0.7 = 70%).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); Cfg_SplitSpawn_RandomizeWeapon = ConfigFileExtensions.BindConfig<Toggle>(((BaseUnityPlugin)this).Config, "Modifier_Offense", "SplitSpawn Randomize Weapon", Toggle.On, "When On, bow-wielding creatures may spawn melee-variant children instead of archer copies.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config18 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 0.5f); Cfg_ShieldBreaker_DurabilityThreshold = ConfigFileExtensions.BindConfig<float>(config18, "Modifier_Offense", "ShieldBreaker Durability Threshold", 0.1f, "Shield durability fraction below which reduction is skipped (0.1 = skip if below 10%).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config19 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f); Cfg_ShieldBreaker_DurabilityReduction = ConfigFileExtensions.BindConfig<float>(config19, "Modifier_Offense", "ShieldBreaker Durability Reduction", 0.5f, "Multiplier applied to shield durability on block (0.5 = halved).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config20 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f); Cfg_IgnoreArmor_ArmorReduction = ConfigFileExtensions.BindConfig<float>(config20, "Modifier_Offense", "IgnoreArmor Armor Reduction", 0.5f, "Multiplier applied to player armor value (0.5 = armor halved).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config21 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f); Cfg_FoodDrain_DurationReduction = ConfigFileExtensions.BindConfig<float>(config21, "Modifier_Offense", "FoodDrain Duration Reduction", 0.5f, "Multiplier applied to food duration on hit (0.5 = halved).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config22 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f); Cfg_ElementalInfusion_DamageRatio = ConfigFileExtensions.BindConfig<float>(config22, "Modifier_Offense", "ElementalInfusion Damage Ratio", 0.5f, "Ratio of total hit damage added as elemental bonus (0.5 = +50% as element).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config23 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f); Cfg_Forceful_PushMultiplier = ConfigFileExtensions.BindConfig<float>(config23, "Modifier_Offense", "Forceful Push Multiplier", 5f, "Multiplier applied to hit push force (5.0 = 5x knockback).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config24 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f); Cfg_Vampiric_HealRatio = ConfigFileExtensions.BindConfig<float>(config24, "Modifier_Offense", "Vampiric Heal Ratio", 0.5f, "Ratio of total hit damage healed by the attacker (0.5 = heal 50% of damage).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config25 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 60); Cfg_PersonalShield_Duration = ConfigFileExtensions.BindConfig<int>(config25, "Modifier_Defense", "PersonalShield Duration", 10, "Duration (seconds) of the GoblinShaman shield status effect.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config26 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 10f); Cfg_PersonalShield_Magnitude = ConfigFileExtensions.BindConfig<float>(config26, "Modifier_Defense", "PersonalShield Magnitude", 2f, "Magnitude of the GoblinShaman shield status effect.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config27 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f); Cfg_FastMovement_SpeedMultiplier = ConfigFileExtensions.BindConfig<float>(config27, "Modifier_Utility", "FastMovement Speed Multiplier", 1.5f, "Speed multiplier applied to m_speed/m_runSpeed/m_walkSpeed (1.5 = +50%).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config28 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f); Cfg_DistantDetection_RangeMultiplier = ConfigFileExtensions.BindConfig<float>(config28, "Modifier_Utility", "DistantDetection Range Multiplier", 2f, "Multiplier applied to hear and view range (2.0 = double range).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config29 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f); Cfg_SoulEater_Radius = ConfigFileExtensions.BindConfig<float>(config29, "Modifier_Utility", "SoulEater Absorb Radius", 5f, "Radius (units) in which SoulEater detects dying enemies.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config30 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10); Cfg_SoulEater_MaxStacks = ConfigFileExtensions.BindConfig<int>(config30, "Modifier_Utility", "SoulEater Max Stacks", 3, "Maximum number of soul stacks the SoulEater can accumulate.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config31 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 2f); Cfg_SoulEater_GrowthMultiplier = ConfigFileExtensions.BindConfig<float>(config31, "Modifier_Utility", "SoulEater Growth Multiplier", 1.1f, "Size and health growth multiplier per stack (1.1 = +10% per soul).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config32 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 3f); Cfg_SoulEater_DmgStack1 = ConfigFileExtensions.BindConfig<float>(config32, "Modifier_Utility", "SoulEater Damage Stack 1", 1.1f, "Damage multiplier at 1 soul stack.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config33 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 3f); Cfg_SoulEater_DmgStack2 = ConfigFileExtensions.BindConfig<float>(config33, "Modifier_Utility", "SoulEater Damage Stack 2", 1.2f, "Damage multiplier at 2 soul stacks.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config34 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 3f); Cfg_SoulEater_DmgStack3 = ConfigFileExtensions.BindConfig<float>(config34, "Modifier_Utility", "SoulEater Damage Stack 3", 1.3f, "Damage multiplier at 3 soul stacks.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config35 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10); Cfg_ResistanceNotification_MaxCount = ConfigFileExtensions.BindConfig<int>(config35, "Modifier_Utility", "ResistanceNotification Max Count", 2, "Max times to show a resistance notification per damage type per enemy.", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config36 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100); Cfg_Boss_OffenseMultiplier = ConfigFileExtensions.BindConfig<int>(config36, "Boss", "Boss_Offense_Multiplier", 20, "Scales offensive modifier effects when the modifier is on a boss (100 = full effect, 10 = 10% of normal).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config37 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100); Cfg_Boss_HealMultiplier = ConfigFileExtensions.BindConfig<int>(config37, "Boss", "Boss_Heal_Multiplier", 10, "Scales healing modifier effects when the modifier is on a boss (100 = full effect, 10 = 10% of normal).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config38 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 200); Cfg_Elite_Size = ConfigFileExtensions.BindConfig<int>(config38, "Modifier_Elite", "Elite_Monster_Size", 100, "Size increase % for Elite monsters (100 = +100% scale, i.e. 2x base size).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config39 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(100, 500); Cfg_Elite_HP = ConfigFileExtensions.BindConfig<int>(config39, "Modifier_Elite", "Elite_Monster_HP", 150, "Health multiplier % for Elite monsters (150 = 1.5x base HP).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config40 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 200); Cfg_Elite_ATK = ConfigFileExtensions.BindConfig<int>(config40, "Modifier_Elite", "Elite_Monster_ATK", 30, "Attack power increase % for Elite monsters (30 = +30% damage output).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ConfigFile config41 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 90); Cfg_Elite_DFS = ConfigFileExtensions.BindConfig<int>(config41, "Modifier_Elite", "Elite_Monster_DFS", 30, "Physical and elemental damage reduction % for Elite monsters (30 = -30% incoming damage).", true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); ShaderLogFilter.Install(); CompatibilityUtils.RunCompatibiltyChecks(); StatusEffectUtils.CreateCustomStatusEffects(); PrefabManager.OnVanillaPrefabsAvailable += PrefabUtils.CreateCustomPrefabs; } private static void SetConfigOrder(ConfigEntryBase entry, int order) { ConfigDescription description = entry.Description; if (((description != null) ? description.Tags : null) == null) { return; } object[] tags = entry.Description.Tags; foreach (object obj in tags) { if (obj == null) { continue; } PropertyInfo property = obj.GetType().GetProperty("Order"); if (!(property == null)) { try { property.SetValue(obj, (property.PropertyType == typeof(int?)) ? ((object)order) : ((object)order)); break; } catch { break; } } } } private void OnDestroy() { ((BaseUnityPlugin)this).Config.Save(); } private void SetupWatcher() { FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName); fileSystemWatcher.Changed += ReadConfigValues; fileSystemWatcher.Created += ReadConfigValues; fileSystemWatcher.Renamed += ReadConfigValues; fileSystemWatcher.IncludeSubdirectories = true; fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher.EnableRaisingEvents = true; } private void ReadConfigValues(object sender, FileSystemEventArgs e) { if (!File.Exists(ConfigFileFullPath)) { return; } try { MonsterModifiersLogger.LogDebug((object)"ReadConfigValues called"); ((BaseUnityPlugin)this).Config.Reload(); } catch { MonsterModifiersLogger.LogError((object)("There was an issue loading your " + ConfigFileName)); MonsterModifiersLogger.LogError((object)"Please check your config entries for spelling and format!"); } } static MonsterModifiersPlugin() { string configPath = Paths.ConfigPath; char directorySeparatorChar = Path.DirectorySeparatorChar; ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName; ConnectionError = ""; MonsterModifiersLogger = Logger.CreateLogSource("MonsterModifiers"); Configurations_Monster_Modifiers = null; Configurations_Boss_Modifiers = null; Cfg_PierceImmunity_DamageReduction = null; Cfg_SlashImmunity_DamageReduction = null; Cfg_BluntImmunity_DamageReduction = null; Cfg_ElementalImmunity_DamageReduction = null; Cfg_Knockback_StaggerForce = null; Cfg_Knockback_PushForce = null; Cfg_FastAttackSpeed_AnimatorMultiplier = null; Cfg_FastAttackSpeed_IntervalReduction = null; Cfg_SplitSpawn_Scale = null; Cfg_SplitSpawn_HP = null; Cfg_SplitSpawn_RandomizeWeapon = null; Cfg_ShieldBreaker_DurabilityThreshold = null; Cfg_ShieldBreaker_DurabilityReduction = null; Cfg_IgnoreArmor_ArmorReduction = null; Cfg_FoodDrain_DurationReduction = null; Cfg_ElementalInfusion_DamageRatio = null; Cfg_Forceful_PushMultiplier = null; Cfg_Vampiric_HealRatio = null; Cfg_PersonalShield_Duration = null; Cfg_PersonalShield_Magnitude = null; Cfg_FastMovement_SpeedMultiplier = null; Cfg_DistantDetection_RangeMultiplier = null; Cfg_SoulEater_Radius = null; Cfg_SoulEater_MaxStacks = null; Cfg_SoulEater_GrowthMultiplier = null; Cfg_SoulEater_DmgStack1 = null; Cfg_SoulEater_DmgStack2 = null; Cfg_SoulEater_DmgStack3 = null; Cfg_ResistanceNotification_MaxCount = null; Cfg_Boss_OffenseMultiplier = null; Cfg_Boss_HealMultiplier = null; Cfg_Offense_Probability = null; Cfg_Defense_Probability = null; Cfg_Utility_Probability = null; Cfg_SplitSpawn_Probability = null; Cfg_EliteMonster_Enabled = null; Cfg_EliteMonster_Probability = null; Cfg_Elite_Size = null; Cfg_Elite_HP = null; Cfg_Elite_ATK = null; Cfg_Elite_DFS = null; } } public static class KeyboardExtensions { public static bool IsKeyDown(this KeyboardShortcut shortcut) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) return (int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && Input.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey) && ((KeyboardShortcut)(ref shortcut)).Modifiers.All((Func<KeyCode, bool>)Input.GetKey); } public static bool IsKeyHeld(this KeyboardShortcut shortcut) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) return (int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && Input.GetKey(((KeyboardShortcut)(ref shortcut)).MainKey) && ((KeyboardShortcut)(ref shortcut)).Modifiers.All((Func<KeyCode, bool>)Input.GetKey); } } public class CompatibilityUtils { public static bool isStarLevelsExpandedInstalled; public static void RunCompatibiltyChecks() { if (Chainloader.PluginInfos.ContainsKey("CreatureLevelControl")) { MonsterModifiersPlugin.MonsterModifiersLogger.LogWarning((object)"CreatureLevelandLootControl plugin is installed. Please ensure special effects and infusions are disabled in CLLC configuration."); } if (Chainloader.PluginInfos.ContainsKey("MidnightsFX.StarLevelSystem")) { MonsterModifiersPlugin.MonsterModifiersLogger.LogWarning((object)"StarLevelSystem plugin is installed. Please ensure max modifiers config is set."); isStarLevelsExpandedInstalled = true; } } } public class DamageUtils { public static float TryCurrentWeapon(Humanoid humanoid) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) ItemData currentWeapon = humanoid.GetCurrentWeapon(); if (currentWeapon == null) { return 10f; } DamageTypes damage = currentWeapon.GetDamage(); if (((DamageTypes)(ref damage)).HaveDamage()) { return 10f; } float totalDamage = ((DamageTypes)(ref damage)).GetTotalDamage(); if (totalDamage == 0f) { return 10f; } DamageTypes damage2 = humanoid.GetCurrentWeapon().GetDamage(); return ((DamageTypes)(ref damage2)).GetTotalDamage(); } public static float TryWeaponList(GameObject[] weaponArray) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) float num = 10f; List<GameObject> list = weaponArray.ToList(); if (list.Count > 0) { foreach (GameObject item in list) { ItemData itemData = item.GetComponent<ItemDrop>().m_itemData; if (itemData != null) { DamageTypes damage = itemData.GetDamage(); float totalDamage = ((DamageTypes)(ref damage)).GetTotalDamage(); if (totalDamage > num) { num = totalDamage; } } } } if (num > 0f) { } return num; } public static float CalculateDamage(Character character, float percentTotal) { Humanoid val = (Humanoid)(object)((character is Humanoid) ? character : null); if ((Object)(object)val == (Object)null) { return 10f; } if (character.IsPlayer()) { return 10f; } float num = 10f; float num2 = TryCurrentWeapon(val); if (num2 > 0f && num2 > num) { num = num2; } float num3 = TryWeaponList(val.m_defaultItems); if (num3 > 0f && num3 > num) { num = num3; } float num4 = TryWeaponList(val.m_randomWeapon); if (num4 > 0f && num4 > num) { num = num4; } return num * percentTotal; } } public class ModifierAssetUtils { public static AssetBundle ashlandsAssetBundle; public static AssetBundle statusEffectBundle; public static AssetBundle modiferIconsBundle; public static Sprite swordIcon; public static Sprite shieldIcon; public static Sprite plusSquareIcon; public static Sprite circleIcon; public static Sprite soulIcon; public static Sprite skullIcon; public static Sprite appleIcon; public static Sprite shieldBrokenIcon; public static Sprite shieldSpearIcon; public static Sprite shieldMaceIcon; public static Sprite shieldSwordIcon; public static Sprite potionIcon; public static Sprite bloodIcon; public static Sprite bloodIconRed; public static Sprite heartIcon; public static Sprite earIcon; public static void Setup() { statusEffectBundle = AssetUtils.LoadAssetBundleFromResources("statusicon", Assembly.GetExecutingAssembly()); modiferIconsBundle = AssetUtils.LoadAssetBundleFromResources("modifiericons", Assembly.GetExecutingAssembly()); } public static void LoadAllIcons() { swordIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/Sword.png"); shieldIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/Shield.png"); plusSquareIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/PlusBox.png"); circleIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/Circle.png"); soulIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/SoulEater.png"); skullIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/Skull.png"); appleIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/Apple.png"); shieldBrokenIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/ShieldBroken.png"); shieldSpearIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/ShieldSpear.png"); shieldMaceIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/ShieldMace.png"); shieldSwordIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/ShieldSword.png"); potionIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/Potion.png"); heartIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/heartIcon.png"); bloodIcon = statusEffectBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/bloodIcon.png"); bloodIconRed = statusEffectBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/bloodIconRed.png"); earIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/Ear.png"); } } public enum MonsterModifierTypes { StaminaSiphon, EitrSiphon, ShieldBreaker, FoodDrain, IgnoreArmor, PoisonDeath, FrostDeath, FireDeath, HealDeath, StaggerDeath, TarDeath, PersonalShield, ShieldDome, SoulEater, RemoveStatusEffect, StaggerImmune, FireInfused, PoisonInfused, FrostInfused, LightningInfused, ElementalImmunity, PierceImmunity, BluntImmunity, SlashImmunity, FastMovement, FastAttackSpeed, DistantDetection, BloodLoss, Absorption, Vampiric, Forceful, Wet, Quiet, Knockback, ArmorCharge, FireTrail, ResistanceNotification, SplitSpawn, EliteMonster } public enum ModifierCategory { Offense, Defense, Utility, SplitSpawn, Elite } public class ModifierData { public int weight { get; set; } public List<float> color { get; set; } = null; } public class ModifierUtils { public static Dictionary<MonsterModifierTypes, ModifierData> modifiers = null; public static readonly Dictionary<MonsterModifierTypes, ModifierCategory> ModifierCategories = new Dictionary<MonsterModifierTypes, ModifierCategory> { { MonsterModifierTypes.StaminaSiphon, ModifierCategory.Offense }, { MonsterModifierTypes.EitrSiphon, ModifierCategory.Offense }, { MonsterModifierTypes.ShieldBreaker, ModifierCategory.Offense }, { MonsterModifierTypes.FoodDrain, ModifierCategory.Offense }, { MonsterModifierTypes.IgnoreArmor, ModifierCategory.Offense }, { MonsterModifierTypes.PoisonDeath, ModifierCategory.Offense }, { MonsterModifierTypes.FrostDeath, ModifierCategory.Offense }, { MonsterModifierTypes.FireDeath, ModifierCategory.Offense }, { MonsterModifierTypes.StaggerDeath, ModifierCategory.Offense }, { MonsterModifierTypes.TarDeath, ModifierCategory.Offense }, { MonsterModifierTypes.FireInfused, ModifierCategory.Offense }, { MonsterModifierTypes.PoisonInfused, ModifierCategory.Offense }, { MonsterModifierTypes.FrostInfused, ModifierCategory.Offense }, { MonsterModifierTypes.LightningInfused, ModifierCategory.Offense }, { MonsterModifierTypes.FastAttackSpeed, ModifierCategory.Offense }, { MonsterModifierTypes.BloodLoss, ModifierCategory.Offense }, { MonsterModifierTypes.Vampiric, ModifierCategory.Offense }, { MonsterModifierTypes.Forceful, ModifierCategory.Offense }, { MonsterModifierTypes.Wet, ModifierCategory.Offense }, { MonsterModifierTypes.Knockback, ModifierCategory.Offense }, { MonsterModifierTypes.RemoveStatusEffect, ModifierCategory.Offense }, { MonsterModifierTypes.PersonalShield, ModifierCategory.Defense }, { MonsterModifierTypes.ShieldDome, ModifierCategory.Defense }, { MonsterModifierTypes.ElementalImmunity, ModifierCategory.Defense }, { MonsterModifierTypes.PierceImmunity, ModifierCategory.Defense }, { MonsterModifierTypes.BluntImmunity, ModifierCategory.Defense }, { MonsterModifierTypes.SlashImmunity, ModifierCategory.Defense }, { MonsterModifierTypes.StaggerImmune, ModifierCategory.Defense }, { MonsterModifierTypes.Absorption, ModifierCategory.Defense }, { MonsterModifierTypes.FastMovement, ModifierCategory.Utility }, { MonsterModifierTypes.DistantDetection, ModifierCategory.Utility }, { MonsterModifierTypes.SoulEater, ModifierCategory.Utility }, { MonsterModifierTypes.HealDeath, ModifierCategory.Utility }, { MonsterModifierTypes.Quiet, ModifierCategory.Utility }, { MonsterModifierTypes.ResistanceNotification, ModifierCategory.Utility }, { MonsterModifierTypes.ArmorCharge, ModifierCategory.Utility }, { MonsterModifierTypes.FireTrail, ModifierCategory.Utility }, { MonsterModifierTypes.SplitSpawn, ModifierCategory.SplitSpawn }, { MonsterModifierTypes.EliteMonster, ModifierCategory.Elite } }; public static readonly HashSet<MonsterModifierTypes> BossExcludedModifiers = new HashSet<MonsterModifierTypes> { MonsterModifierTypes.PoisonDeath, MonsterModifierTypes.FireDeath, MonsterModifierTypes.FrostDeath, MonsterModifierTypes.StaggerDeath, MonsterModifierTypes.HealDeath, MonsterModifierTypes.TarDeath, MonsterModifierTypes.SplitSpawn, MonsterModifierTypes.EliteMonster, MonsterModifierTypes.Vampiric, MonsterModifierTypes.Absorption, MonsterModifierTypes.SoulEater }; public static Color GetModifierColor(MonsterModifierTypes modifier) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) List<float> color = modifiers[modifier].color; Color result = default(Color); ((Color)(ref result))..ctor(color[0], color[1], color[2], color[3]); return result; } public static Sprite GetModifierIcon(MonsterModifierTypes modifier) { if (modifier == MonsterModifierTypes.FireInfused || modifier == MonsterModifierTypes.FrostInfused || modifier == MonsterModifierTypes.PoisonInfused || modifier == MonsterModifierTypes.LightningInfused || modifier == MonsterModifierTypes.RemoveStatusEffect) { return ModifierAssetUtils.swordIcon; } if (modifier == MonsterModifierTypes.ShieldBreaker || modifier == MonsterModifierTypes.IgnoreArmor) { return ModifierAssetUtils.shieldBrokenIcon; } if (modifier == MonsterModifierTypes.StaminaSiphon || modifier == MonsterModifierTypes.EitrSiphon) { return ModifierAssetUtils.potionIcon; } switch (modifier) { case MonsterModifierTypes.FoodDrain: return ModifierAssetUtils.appleIcon; default: if (modifier != MonsterModifierTypes.TarDeath) { if (modifier == MonsterModifierTypes.ElementalImmunity || modifier == MonsterModifierTypes.StaggerImmune) { return ModifierAssetUtils.shieldIcon; } if (modifier == MonsterModifierTypes.PersonalShield || modifier == MonsterModifierTypes.ShieldDome) { return ModifierAssetUtils.circleIcon; } switch (modifier) { case MonsterModifierTypes.SoulEater: return ModifierAssetUtils.soulIcon; case MonsterModifierTypes.PierceImmunity: return ModifierAssetUtils.shieldSpearIcon; case MonsterModifierTypes.SlashImmunity: return ModifierAssetUtils.shieldSwordIcon; case MonsterModifierTypes.BluntImmunity: return ModifierAssetUtils.shieldMaceIcon; default: if (modifier != MonsterModifierTypes.Forceful) { if (modifier == MonsterModifierTypes.BloodLoss || modifier == MonsterModifierTypes.Wet) { return ModifierAssetUtils.bloodIcon; } if (modifier == MonsterModifierTypes.Absorption || modifier == MonsterModifierTypes.Vampiric) { return ModifierAssetUtils.heartIcon; } switch (modifier) { case MonsterModifierTypes.Quiet: return ModifierAssetUtils.earIcon; default: if (modifier != MonsterModifierTypes.FireTrail) { switch (modifier) { case MonsterModifierTypes.ResistanceNotification: return ModifierAssetUtils.potionIcon; case MonsterModifierTypes.SplitSpawn: return ModifierAssetUtils.skullIcon; case MonsterModifierTypes.EliteMonster: return ModifierAssetUtils.skullIcon; default: Debug.Log((object)"Could not find icon for modifier"); return ModifierAssetUtils.plusSquareIcon; } } goto case MonsterModifierTypes.Knockback; case MonsterModifierTypes.Knockback: case MonsterModifierTypes.ArmorCharge: return ModifierAssetUtils.plusSquareIcon; } } goto case MonsterModifierTypes.FastMovement; case MonsterModifierTypes.FastMovement: case MonsterModifierTypes.FastAttackSpeed: case MonsterModifierTypes.DistantDetection: return ModifierAssetUtils.plusSquareIcon; } } goto case MonsterModifierTypes.PoisonDeath; case MonsterModifierTypes.PoisonDeath: case MonsterModifierTypes.FrostDeath: case MonsterModifierTypes.FireDeath: case MonsterModifierTypes.HealDeath: case MonsterModifierTypes.StaggerDeath: return ModifierAssetUtils.skullIcon; } } public static float BossOffenseMult(Character attacker) { return ((Object)(object)attacker != (Object)null && attacker.IsBoss()) ? ((float)MonsterModifiersPlugin.Cfg_Boss_OffenseMultiplier.Value / 100f) : 1f; } public static float BossHealMult(Character monster) { return ((Object)(object)monster != (Object)null && monster.IsBoss()) ? ((float)MonsterModifiersPlugin.Cfg_Boss_HealMultiplier.Value / 100f) : 1f; } public static float ScaleReductionEffect(float configMult, float bossOffenseMult) { return 1f - (1f - configMult) * bossOffenseMult; } public static int GetModifierWeight(MonsterModifierTypes modifier) { return modifiers[modifier].weight; } public static int GetAvailableModifierCount(HashSet<MonsterModifierTypes>? excluded = null) { int num = 0; foreach (KeyValuePair<MonsterModifierTypes, ModifierData> modifier in modifiers) { if (modifier.Value.weight > 0 && (excluded == null || !excluded.Contains(modifier.Key))) { num++; } } return num; } public static List<MonsterModifierTypes> RollRandomModifiers(int numModifiers, HashSet<MonsterModifierTypes>? excluded = null, int splitGeneration = 0) { List<MonsterModifierTypes> list = new List<MonsterModifierTypes>(); Dictionary<MonsterModifierTypes, ModifierData> dictionary = new Dictionary<MonsterModifierTypes, ModifierData>(modifiers); if (excluded != null) { foreach (MonsterModifierTypes item in excluded) { dictionary.Remove(item); } } for (int i = 0; i < numModifiers; i++) { if (dictionary.Count == 0) { break; } Dictionary<ModifierCategory, List<MonsterModifierTypes>> dictionary2 = new Dictionary<ModifierCategory, List<MonsterModifierTypes>>(); foreach (KeyValuePair<MonsterModifierTypes, ModifierData> item2 in dictionary) { if (item2.Value.weight > 0) { ModifierCategory value; ModifierCategory key = (ModifierCategories.TryGetValue(item2.Key, out value) ? value : ModifierCategory.Utility); if (!dictionary2.ContainsKey(key)) { dictionary2[key] = new List<MonsterModifierTypes>(); } dictionary2[key].Add(item2.Key); } } int num = (dictionary2.ContainsKey(ModifierCategory.Offense) ? MonsterModifiersPlugin.Cfg_Offense_Probability.Value : 0); int num2 = (dictionary2.ContainsKey(ModifierCategory.Defense) ? MonsterModifiersPlugin.Cfg_Defense_Probability.Value : 0); int num3 = (dictionary2.ContainsKey(ModifierCategory.Utility) ? MonsterModifiersPlugin.Cfg_Utility_Probability.Value : 0); float num4 = (float)Math.Pow(0.5, splitGeneration); int num5 = (dictionary2.ContainsKey(ModifierCategory.SplitSpawn) ? Mathf.RoundToInt((float)MonsterModifiersPlugin.Cfg_SplitSpawn_Probability.Value * num4) : 0); int num6 = 0; if (MonsterModifiersPlugin.Cfg_EliteMonster_Enabled.Value == MonsterModifiersPlugin.Toggle.On && dictionary2.ContainsKey(ModifierCategory.Elite)) { num6 = MonsterModifiersPlugin.Cfg_EliteMonster_Probability.Value; } else if (MonsterModifiersPlugin.Cfg_EliteMonster_Enabled.Value == MonsterModifiersPlugin.Toggle.Off) { if (dictionary2.ContainsKey(ModifierCategory.Offense)) { num += 5; } if (dictionary2.ContainsKey(ModifierCategory.Defense)) { num2 += 5; } } int num7 = num + num2 + num3 + num5 + num6; MonsterModifierTypes monsterModifierTypes; if (num7 <= 0) { int num8 = 0; foreach (ModifierData value2 in dictionary.Values) { num8 += value2.weight; } if (num8 <= 0) { break; } int num9 = Random.Range(0, num8); int num10 = 0; monsterModifierTypes = MonsterModifierTypes.StaminaSiphon; foreach (KeyValuePair<MonsterModifierTypes, ModifierData> item3 in dictionary) { num10 += item3.Value.weight; if (num9 < num10) { monsterModifierTypes = item3.Key; break; } } } else { int num11 = Random.Range(0, num7); ModifierCategory key2 = ((num11 >= num) ? ((num11 < num + num2) ? ModifierCategory.Defense : ((num11 < num + num2 + num3) ? ModifierCategory.Utility : ((num11 >= num + num2 + num3 + num5) ? ModifierCategory.Elite : ModifierCategory.SplitSpawn))) : ModifierCategory.Offense); List<MonsterModifierTypes> list2 = dictionary2[key2]; monsterModifierTypes = list2[Random.Range(0, list2.Count)]; } list.Add(monsterModifierTypes); dictionary.Remove(monsterModifierTypes); if (monsterModifierTypes == MonsterModifierTypes.EliteMonster) { dictionary.Remove(MonsterModifierTypes.SplitSpawn); dictionary.Remove(MonsterModifierTypes.HealDeath); dictionary.Remove(MonsterModifierTypes.Vampiric); dictionary.Remove(MonsterModifierTypes.Absorption); } } return list; } public static void RunBiomeChecks() { } public static bool RunRPCDamageChecks(Character character, HitData hit) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Invalid comparison between Unknown and I4 if (hit == null || (Object)(object)character == (Object)null) { return false; } if (((DamageTypes)(ref hit.m_damage)).GetTotalDamage() == 0f) { return false; } if ((int)hit.m_hitType != 1) { return false; } return true; } public static bool RunRPCDamageChecks(Character character, HitData hit, bool isMonsterAttackingPlayer) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Invalid comparison between Unknown and I4 //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Invalid comparison between Unknown and I4 if (hit == null || (Object)(object)character == (Object)null) { Debug.Log((object)"Hit or character is null"); return true; } if (((DamageTypes)(ref hit.m_damage)).GetTotalDamage() == 0f) { Debug.Log((object)"Total damage is 0"); return true; } if (isMonsterAttackingPlayer) { if ((int)hit.m_hitType != 1) { Debug.Log((object)"hit type is not enemy hit"); return true; } } else if ((int)hit.m_hitType != 2) { Debug.Log((object)"hit type is not player hit"); return true; } return true; } public static bool RunHitChecks(HitData hit, bool isMonsterAttackingPlayer) { Character attacker = hit.GetAttacker(); if ((Object)(object)attacker == (Object)null) { return false; } if (isMonsterAttackingPlayer && attacker.IsPlayer()) { return false; } if (!isMonsterAttackingPlayer && attacker.IsPlayer()) { return true; } return true; } } public class PrefabUtils { public static GameObject leechDeathVFX; public static GameObject leechDeathSFX; public static void CreateCustomPrefabs() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Expected O, but got Unknown //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Expected O, but got Unknown //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Expected O, but got Unknown //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Expected O, but got Unknown //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Expected O, but got Unknown //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Expected O, but got Unknown //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Expected O, but got Unknown GameObject prefab = PrefabManager.Instance.GetPrefab("shaman_heal_aoe"); GameObject val = PrefabManager.Instance.CreateClonedPrefab("healCustomPrefab", prefab); CustomPrefab val2 = new CustomPrefab(val, false); Aoe component = val2.Prefab.GetComponent<Aoe>(); component.m_statusEffect = ""; GameObject prefab2 = PrefabManager.Instance.GetPrefab("Mistile"); GameObject val3 = PrefabManager.Instance.CreateClonedPrefab("mistleCustomPrefab", prefab2); CustomPrefab val4 = new CustomPrefab(val3, false); Character component2 = (Character)(object)val4.Prefab.GetComponent<Humanoid>(); component2.m_speed = 0f; component2.m_flyFastSpeed = 0f; component2.m_flySlowSpeed = 0f; component2.m_name = "$modifier_mistile"; val4.Prefab.GetComponent<CharacterTimedDestruction>().m_timeoutMin = 2f; val4.Prefab.GetComponent<CharacterTimedDestruction>().m_timeoutMax = 4f; GameObject prefab3 = PrefabManager.Instance.GetPrefab("fx_DvergerMage_Mistile_attack"); GameObject val5 = PrefabManager.Instance.CreateClonedPrefab("staggerDeathNovaCustomPrefab", prefab3); CustomPrefab val6 = new CustomPrefab(val5, false); GameObject gameObject = ((Component)ExposedGameObjectExtension.FindDeepChild(val6.Prefab, "shockwave (1)", (IterativeSearchType)1)).gameObject; ParticleSystem component3 = gameObject.GetComponent<ParticleSystem>(); MainModule main = component3.main; ((MainModule)(ref main)).startRotationX = new MinMaxCurve((float)Math.PI / 2f); ((MainModule)(ref main)).startRotationY = new MinMaxCurve(0f); ((MainModule)(ref main)).startRotationZ = new MinMaxCurve(0f); GameObject prefab4 = PrefabManager.Instance.GetPrefab("skeleton_bow"); GameObject val7 = PrefabManager.Instance.CreateClonedPrefab("skeletonBowCustomPrefab_Fire", prefab4); CustomItem val8 = new CustomItem(val7, false); ItemData itemData = val8.ItemPrefab.GetComponent<ItemDrop>().m_itemData; itemData.m_shared.m_attack.m_attackProjectile = PrefabManager.Instance.GetPrefab("bow_projectile_fire"); GameObject val9 = PrefabManager.Instance.CreateClonedPrefab("skeletonBowCustomPrefab_Frost", prefab4); CustomItem val10 = new CustomItem(val9, false); ItemData itemData2 = val10.ItemPrefab.GetComponent<ItemDrop>().m_itemData; itemData2.m_shared.m_attack.m_attackProjectile = PrefabManager.Instance.GetPrefab("bow_projectile_frost"); GameObject val11 = PrefabManager.Instance.CreateClonedPrefab("skeletonBowCustomPrefab_Poison", prefab4); CustomItem val12 = new CustomItem(val11, false); ItemData itemData3 = val12.ItemPrefab.GetComponent<ItemDrop>().m_itemData; itemData3.m_shared.m_attack.m_attackProjectile = PrefabManager.Instance.GetPrefab("bow_projectile_poison"); GameObject prefab5 = PrefabManager.Instance.GetPrefab("draugr_bow"); GameObject val13 = PrefabManager.Instance.CreateClonedPrefab("draugrBowCustomPrefab_Fire", prefab5); CustomItem val14 = new CustomItem(val13, false); ItemData itemData4 = val14.ItemPrefab.GetComponent<ItemDrop>().m_itemData; itemData4.m_shared.m_attack.m_attackProjectile = PrefabManager.Instance.GetPrefab("bow_projectile_fire"); GameObject val15 = PrefabManager.Instance.CreateClonedPrefab("draugrBowCustomPrefab_Frost", prefab5); CustomItem val16 = new CustomItem(val15, false); ItemData itemData5 = val16.ItemPrefab.GetComponent<ItemDrop>().m_itemData; itemData5.m_shared.m_attack.m_attackProjectile = PrefabManager.Instance.GetPrefab("bow_projectile_frost"); GameObject val17 = PrefabManager.Instance.CreateClonedPrefab("draugrBowCustomPrefab_Poison", prefab5); CustomItem val18 = new CustomItem(val17, false); ItemData itemData6 = val18.ItemPrefab.GetComponent<ItemDrop>().m_itemData; itemData6.m_shared.m_attack.m_attackProjectile = PrefabManager.Instance.GetPrefab("bow_projectile_poison"); PrefabManager.Instance.AddPrefab(val2); PrefabManager.Instance.AddPrefab(val4); PrefabManager.Instance.AddPrefab(val6); ItemManager.Instance.AddItem(val8); ItemManager.Instance.AddItem(val10); ItemManager.Instance.AddItem(val12); ItemManager.Instance.AddItem(val14); ItemManager.Instance.AddItem(val16); ItemManager.Instance.AddItem(val18); leechDeathVFX = PrefabManager.Instance.GetPrefab("vfx_leech_death"); leechDeathSFX = PrefabManager.Instance.GetPrefab("sfx_leech_death"); PrefabManager.OnVanillaPrefabsAvailable -= CreateCustomPrefabs; } } public static class SpawnCommands { [HarmonyPatch(typeof(Terminal), "InitTerminal")] private static class Patch_Terminal_InitTerminal { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__1_0; internal void <Postfix>b__1_0(ConsoleEventArgs args) { if (args.Length > 2) { string creatureName = args[1]; string modifierName = args[2]; SpawnModifier(creatureName, modifierName); } else { args.Context.AddString("Usage: modifier [creature] [modifier]"); } } } [HarmonyPriority(800)] private static void Prefix(out bool __state) { __state = Terminal.m_terminalInitialized; } private static void Postfix(bool __state) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown if (__state) { return; } MonsterModifiersPlugin.MonsterModifiersLogger.LogInfo((object)"Adding Terminal Commands for monster modifier spawning."); object obj = <>c.<>9__1_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { if (args.Length > 2) { string creatureName = args[1]; string modifierName = args[2]; SpawnModifier(creatureName, modifierName); } else { args.Context.AddString("Usage: modifier [creature] [modifier]"); } }; <>c.<>9__1_0 = val; obj = (object)val; } new ConsoleCommand("modifier", "[creature] [modifier]", (ConsoleEvent)obj, true, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } } public static void SpawnModifier(string creatureName, string modifierName) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) GameObject prefab = ZNetScene.instance.GetPrefab(creatureName); MonsterModifierTypes result; if ((Object)(object)prefab == (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)1, "Missing object " + creatureName, 0, (Sprite)null); } else if (Enum.TryParse<MonsterModifierTypes>(modifierName, ignoreCase: true, out result)) { Vector3 insideUnitSphere = Random.insideUnitSphere; GameObject val = Object.Instantiate<GameObject>(prefab, ((Component)Player.m_localPlayer).transform.position + ((Component)Player.m_localPlayer).transform.forward * 2f + Vector3.up + insideUnitSphere, Quaternion.identity); Character component = val.GetComponent<Character>(); if (component.m_nview.GetZDO().IsOwner()) { component.SetLevel(2); component.m_nview.GetZDO().Set("modifiers", modifierName); } } else { ((Character)Player.m_localPlayer).Message((MessageType)1, "Invalid modifier name: " + modifierName, 0, (Sprite)null); } } } public class StatusEffectUtils { public static void CreateCustomStatusEffects() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown BloodLoss_SE bloodLoss_SE = ScriptableObject.CreateInstance<BloodLoss_SE>(); ((Object)bloodLoss_SE).name = "BloodLossStatusEffect"; ((StatusEffect)bloodLoss_SE).m_name = "$se_bloodLoss"; ((StatusEffect)bloodLoss_SE).m_icon = ModifierAssetUtils.bloodIconRed; CustomStatusEffect val = new CustomStatusEffect((StatusEffect)(object)bloodLoss_SE, false); HealDeath_SE healDeath_SE = ScriptableObject.CreateInstance<HealDeath_SE>(); ((Object)healDeath_SE).name = "HealDeathStatusEffect"; ((StatusEffect)healDeath_SE).m_name = "$se_healDeath"; ((StatusEffect)healDeath_SE).m_ttl = 5f; ((SE_Stats)healDeath_SE).m_tickInterval = 1f; ((SE_Stats)healDeath_SE).m_healthOverTimeDuration = 5f; ((SE_Stats)healDeath_SE).m_healthOverTimeInterval = 0.5f; ((SE_Stats)healDeath_SE).m_healthOverTimeTicks = 10f; ((SE_Stats)healDeath_SE).m_healthOverTime = 0f; CustomStatusEffect val2 = new CustomStatusEffect((StatusEffect)(object)healDeath_SE, false); ItemManager.Instance.AddStatusEffect(val); ItemManager.Instance.AddStatusEffect(val2); } } public class TranslationUtils { public static CustomLocalization Localization; public static void AddLocalizations() { Localization = LocalizationManager.Instance.GetLocalization(); CustomLocalization localization = Localization; string text = "English"; localization.AddTranslation(ref text, new Dictionary<string, string> { { "$se_bloodLoss", "Blood Loss" }, { "$modifier_mistile", "Stagger Bomb" } }); } } public class ShaderLogFilter : ILogListener, IDisposable { private readonly ILogListener _inner; private ShaderLogFilter(ILogListener inner) { _inner = inner; } public static void Install() { ICollection<ILogListener> listeners = Logger.Listeners; foreach (ILogListener item in listeners) { if (item is ShaderLogFilter) { return; } } List<ILogListener> list = new List<ILogListener>(listeners); listeners.Clear(); foreach (ILogListener item2 in list) { listeners.Add((ILogListener)(object)new ShaderLogFilter(item2)); } } public void LogEvent(object sender, LogEventArgs eventArgs) { if (eventArgs == null || !(eventArgs.Data?.ToString()?.Contains("Failed to find expected binary shader data")).GetValueOrDefault()) { ILogListener inner = _inner; if (inner != null) { inner.LogEvent(sender, eventArgs); } } } public void Dispose() { ((IDisposable)_inner)?.Dispose(); } } public class WorldUtils { private static readonly Collider[] s_buffer = (Collider[])(object)new Collider[512]; public static List<Character> GetAllCharacter(Vector3 position, float range) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) int num = Physics.OverlapBoxNonAlloc(position, Vector3.one * range, s_buffer, Quaternion.identity); List<Character> list = new List<Character>(); for (int i = 0; i < num; i++) { Character component = ((Component)((Component)s_buffer[i]).transform.root).GetComponent<Character>(); if ((Object)(object)component != (Object)null && !list.Contains(component)) { list.Add(component); } } return list; } } public class YamlUtils { public static string defaultModifierValues; public static void ParseDefaultYamls() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown defaultModifierValues = AssetUtils.LoadTextFromResources("modifierValues.yml"); IDeserializer val = ((BuilderSkeleton<DeserializerBuilder>)new DeserializerBuilder()).WithNamingConvention(CamelCaseNamingConvention.Instance).Build(); ModifierUtils.modifiers = val.Deserialize<Dictionary<MonsterModifierTypes, ModifierData>>((TextReader)new StringReader(defaultModifierValues)); MonsterModifiersPlugin.MonsterModifiersLogger.LogInfo((object)($"[YamlUtils] Loaded {ModifierUtils.modifiers.Count} modifier entries. " + $"EliteMonster present: {ModifierUtils.modifiers.ContainsKey(MonsterModifierTypes.EliteMonster)}")); } } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] public static class RegisterAndCheckVersion { private static void Prefix(ZNetPeer peer, ref ZNet __instance) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown MonsterModifiersPlugin.MonsterModifiersLogger.LogDebug((object)"Registering version RPC handler"); peer.m_rpc.Register<ZPackage>("MonsterModifiers_VersionCheck", (Action<ZRpc, ZPackage>)RpcHandlers.RPC_MonsterModifiers_Version); MonsterModifiersPlugin.MonsterModifiersLogger.LogDebug((object)"Invoking version check"); ZPackage val = new ZPackage(); val.Write("1.3.3"); peer.m_rpc.Invoke("MonsterModifiers_VersionCheck", new object[1] { val }); } } [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] public static class VerifyClient { private static bool Prefix(ZRpc rpc, ZPackage pkg, ref ZNet __instance) { if (!__instance.IsServer() || RpcHandlers.ValidatedPeers.Contains(rpc)) { return true; } MonsterModifiersPlugin.MonsterModifiersLogger.LogWarning((object)("Peer (" + rpc.m_socket.GetHostName() + ") never sent version or couldn't due to previous disconnect, disconnecting")); rpc.Invoke("Error", new object[1] { 3 }); return false; } private static void Postfix(ZNet __instance) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), "MonsterModifiersRequestAdminSync", new object[1] { (object)new ZPackage() }); } } [HarmonyPatch(typeof(FejdStartup), "ShowConnectError")] public class ShowConnectionError { private static void Postfix(FejdStartup __instance) { if (__instance.m_connectionFailedPanel.activeSelf) { __instance.m_connectionFailedError.fontSizeMax = 25f; __instance.m_connectionFailedError.fontSizeMin = 15f; TMP_Text connectionFailedError = __instance.m_connectionFailedError; connectionFailedError.text = connectionFailedError.text + "\n" + MonsterModifiersPlugin.ConnectionError; } } } [HarmonyPatch(typeof(ZNet), "Disconnect")] public static class RemoveDisconnectedPeerFromVerified { private static void Prefix(ZNetPeer peer, ref ZNet __instance) { if (__instance.IsServer()) { MonsterModifiersPlugin.MonsterModifiersLogger.LogInfo((object)("Peer (" + peer.m_rpc.m_socket.GetHostName() + ") disconnected, removing from validated list")); RpcHandlers.ValidatedPeers.Remove(peer.m_rpc); } } } public static class RpcHandlers { public static readonly List<ZRpc> ValidatedPeers = new List<ZRpc>(); public static void RPC_MonsterModifiers_Version(ZRpc rpc, ZPackage pkg) { string text = pkg.ReadString(); MonsterModifiersPlugin.MonsterModifiersLogger.LogInfo((object)("Version check, local: 1.3.3, remote: " + text)); if (text != "1.3.3") { MonsterModifiersPlugin.ConnectionError = "MonsterModifiers Installed: 1.3.3\n Needed: " + text; if (ZNet.instance.IsServer()) { MonsterModifiersPlugin.MonsterModifiersLogger.LogWarning((object)("Peer (" + rpc.m_socket.GetHostName() + ") has incompatible version, disconnecting...")); rpc.Invoke("Error", new object[1] { 3 }); } } else if (!ZNet.instance.IsServer()) { MonsterModifiersPlugin.MonsterModifiersLogger.LogInfo((object)"Received same version from server!"); } else { MonsterModifiersPlugin.MonsterModifiersLogger.LogInfo((object)("Adding peer (" + rpc.m_socket.GetHostName() + ") to validated list")); ValidatedPeers.Add(rpc); } } } } namespace MonsterModifiers.Visuals { public class BowVisuals { public static GameObject? GetModifierVisual(string itemName, List<MonsterModifierTypes> modifiers) { if (!(itemName == "skeleton_bow")) { if (itemName == "draugr_bow") { return GetDraugrBowVisual(modifiers); } return null; } return GetSkeletonBowVisual(modifiers); } public static GameObject? GetSkeletonBowVisual(List<MonsterModifierTypes> modifiers) { if (modifiers.Contains(MonsterModifierTypes.FireInfused)) { return PrefabManager.Instance.GetPrefab("skeletonBowCustomPrefab_Fire"); } if (modifiers.Contains(MonsterModifierTypes.FrostInfused)) { return PrefabManager.Instance.GetPrefab("skeletonBowCustomPrefab_Frost"); } if (modifiers.Contains(MonsterModifierTypes.PoisonInfused)) { return PrefabManager.Instance.GetPrefab("skeletonBowCustomPrefab_Poison"); } return null; } public static GameObject? GetDraugrBowVisual(List<MonsterModifierTypes> modifiers) { if (modifiers.Contains(MonsterModifierTypes.FireInfused)) { return PrefabManager.Instance.GetPrefab("draugrBowCustomPrefab_Fire"); } if (modifiers.Contains(MonsterModifierTypes.FrostInfused)) { return PrefabManager.Instance.GetPrefab("draugrBowCustomPrefab_Frost"); } if (modifiers.Contains(MonsterModifierTypes.PoisonInfused)) { return PrefabManager.Instance.GetPrefab("draugrBowCustomPrefab_Poison"); } return null; } } } namespace MonsterModifiers.StatusEffects { public class BloodLoss_SE : StatusEffect { public int bloodLossAmount = 0; public int bloodLossCap; private float reductionTimer = 0f; private bool shouldRemove = false; public override void Setup(Character character) { ((StatusEffect)this).Setup(character); bloodLossCap = Mathf.FloorToInt(character.GetMaxHealth()); } public override void UpdateStatusEffect(float dt) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) reductionTimer += dt; if (reductionTimer >= 60f) { bloodLossAmount = Mathf.Max(0, bloodLossAmount - 10); shouldRemove = true; reductionTimer = 0f; } if (bloodLossAmount > bloodLossCap) { bloodLossAmount = 0; HitData val = new HitData { m_damage = { m_slash = base.m_character.GetMaxHealth() * 0.3f } }; base.m_character.Damage(val); Object.Instantiate<GameObject>(PrefabUtils.leechDeathSFX, ((Component)base.m_character).transform.position, ((Component)base.m_character).transform.rotation); Object.Instantiate<GameObject>(PrefabUtils.leechDeathVFX, ((Component)base.m_character).transform.position, ((Component)base.m_character).transform.rotation); shouldRemove = true; } } public override string GetIconText() { return bloodLossAmount.ToString(); } public override void OnDamaged(HitData hit, Character attacker) { if (ModifierUtils.RunRPCDamageChecks(attacker, hit) && ModifierUtils.RunHitChecks(hit, isMonsterAttackingPlayer: true)) { MonsterModifier component = ((Component)attacker).GetComponent<MonsterModifier>(); if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.BloodLoss)) { bloodLossAmount += Mathf.FloorToInt(hit.GetTotalDamage()); } } } public override bool IsDone() { return shouldRemove || ((StatusEffect)this).IsDone(); } } public class HealDeath_SE : SE_Stats { public override void SetLevel(int itemLevel, float skillLevel) { base.m_healthPerTick = skillLevel / 10f; } } } namespace MonsterModifiers.Patches { [HarmonyPatch(typeof(EnemyHud), "ShowHud")] public static class EnemyHud_ShowHud_Patch { private static void Postfix(EnemyHud __instance, Character c, bool isMount) { if (!(c.IsPlayer() || isMount)) { MonsterModifier component = ((Component)c).GetComponent<MonsterModifier>(); if (!((Object)(object)component == (Object)null)) { ChangeEnemyStars(c, component.Modifiers, component.IsBossCharacter, component.OverflowStars); } } } public static void ChangeEnemyStars(Character character, List<MonsterModifierTypes> modifiers, bool isBoss = false, int overflowStars = 0) { //IL_016a: Unknown result type (might be due to invalid IL or missing references) if ((character.GetLevel() <= 1 && !isBoss) || !EnemyHud.instance.m_huds.TryGetValue(character, out var value)) { return; } GameObject gui = value.m_gui; int num = 0; int num2 = 7; if (CompatibilityUtils.isStarLevelsExpandedInstalled && character.GetLevel() > num2) { num = 2; } int num3 = (isBoss ? MonsterModifiersPlugin.Configurations_Boss_Modifiers.Value : 0); int num4 = modifiers.Count - num3; for (int i = num; i < gui.transform.childCount; i++) { Transform child = gui.transform.GetChild(i); if (!((Object)child).name.StartsWith("level_" + (modifiers.Count - num3 + overflowStars + 1)) && (!((Object)child).name.StartsWith("level_n") || !((Component)child).gameObject.activeSelf)) { continue; } for (int j = 0; j < ((Component)child).transform.childCount; j++) { Transform child2 = ((Component)child).transform.GetChild(j); if (((Object)child2).name.StartsWith("star") && ((Component)child2).gameObject.activeSelf && j < num4) { int index = num3 + j; ((Component)child2).GetComponent<Image>().sprite = ModifierUtils.GetModifierIcon(modifiers[index]); ((Graphic)((Component)child2).GetComponent<Image>()).color = ModifierUtils.GetModifierColor(modifiers[index]); ((Component)child2.GetChild(0)).gameObject.SetActive(false); } } } } } } namespace MonsterModifiers.Modifiers { public class Absorption { [HarmonyPatch(typeof(Character), "RPC_Damage")] public class Absorption_Character_RPC_Damage_Patch { public static void Prefix(Character __instance, HitData hit) { if (hit == null || (Object)(object)__instance == (Object)null) { return; } MonsterModifier component = ((Component)__instance).GetComponent<MonsterModifier>(); if ((Object)(object)component == (Object)null || !component.Modifiers.Contains(MonsterModifierTypes.Absorption) || ((DamageTypes)(ref hit.m_damage)).GetTotalDamage() == 0f) { return; } List<MonsterModifierTypes> modifiers = component.Modifiers; float num = ModifierUtils.BossHealMult(__instance); if (modifiers.Contains(MonsterModifierTypes.BluntImmunity) && hit.m_damage.m_blunt > 0f) { float num2 = (float)MonsterModifiersPlugin.Cfg_BluntImmunity_DamageReduction.Value / 100f; __instance.Heal(hit.m_damage.m_blunt * num2 * num, true); } if (modifiers.Contains(MonsterModifierTypes.SlashImmunity) && hit.m_damage.m_slash > 0f) { float num3 = (float)MonsterModifiersPlugin.Cfg_SlashImmunity_DamageReduction.Value / 100f; __instance.Heal(hit.m_damage.m_slash * num3 * num, true); } if (modifiers.Contains(MonsterModifierTypes.PierceImmunity) && hit.m_damage.m_pierce > 0f) { float num4 = (float)MonsterModifiersPlugin.Cfg_PierceImmunity_DamageReduction.Value / 100f; __instance.Heal(hit.m_damage.m_pierce * num4 * num, true); } if (modifiers.Contains(MonsterModifierTypes.ElementalImmunity)) { float num5 = (float)MonsterModifiersPlugin.Cfg_ElementalImmunity_DamageReduction.Value / 100f * num; if (hit.m_damage.m_fire > 0f) { __instance.Heal(hit.m_damage.m_fire * num5, true); } if (hit.m_damage.m_frost > 0f) { __instance.Heal(hit.m_damage.m_frost * num5, true); } if (hit.m_damage.m_lightning > 0f) { __instance.Heal(hit.m_damage.m_lightning * num5, true); } if (hit.m_damage.m_poison > 0f) { __instance.Heal(hit.m_damage.m_poison * num5, true); } if (hit.m_damage.m_spirit > 0f) { __instance.Heal(hit.m_damage.m_spirit * num5, true); } } } } } public class BloodLoss { [HarmonyPatch(typeof(Character), "RPC_Damage")] public class RemoveMead_Character_RPC_Damage_Patch { public static void Postfix(Character __instance, HitData hit) { if (ModifierUtils.RunRPCDamageChecks(__instance, hit) && ModifierUtils.RunHitChecks(hit, isMonsterAttackingPlayer: true)) { Character attacker = hit.GetAttacker(); MonsterModifier component = ((Component)attacker).GetComponent<MonsterModifier>(); if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.BloodLoss) && !__instance.IsBlocking() && !__instance.GetSEMan().HaveStatusEffect(StringExtensionMethods.GetStableHashCode("BloodLossStatusEffect"))) { __instance.GetSEMan().AddStatusEffect(StringExtensionMethods.GetStableHashCode("BloodLossStatusEffect"), false, 0, 0f); } } } } } public class DistantDetection { public static void AddDistantDetection(Character character) { BaseAI baseAI = character.m_baseAI; if ((Object)(object)baseAI != (Object)null) { baseAI.m_hearRange *= MonsterModifiersPlugin.Cfg_DistantDetection_RangeMultiplier.Value; baseAI.m_viewRange *= MonsterModifiersPlugin.Cfg_DistantDetection_RangeMultiplier.Value; } } public static void RemoveDistantDetection(Character character) { BaseAI baseAI = character.m_baseAI; if ((Object)(object)baseAI != (Object)null) { baseAI.m_hearRange /= MonsterModifiersPlugin.Cfg_DistantDetection_RangeMultiplier.Value; baseAI.m_viewRange /= MonsterModifiersPlugin.Cfg_DistantDetection_RangeMultiplier.Value; } } } public class EitrSiphon { [HarmonyPatch(typeof(Character), "RPC_Damage")] public class EitrSiphon_Character_RPC_Damage_Patch { public static void Postfix(Character __instance, HitData hit) { if (ModifierUtils.RunRPCDamageChecks(__instance, hit) && ModifierUtils.RunHitChecks(hit, isMonsterAttackingPlayer: true) && !__instance.IsBlocking()) { Character attacker = hit.GetAttacker(); MonsterModifier component = ((Component)attacker).GetComponent<MonsterModifier>(); if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.EitrSiphon)) { __instance.UseEitr(hit.GetTotalDamage() * ModifierUtils.BossOffenseMult(attacker)); } } } } } public class FastAttackSpeed { [HarmonyPatch(typeof(CharacterAnimEvent), "CustomFixedUpdate")] public static class FastAttackSpeed_CharacterAnimEvent_CustomFixedUpdate_Patch { public static void Prefix(Character ___m_character, ref Animator ___m_animator) { if (!___m_character.InAttack() || ___m_character.IsPlayer()) { return; } MonsterModifier component = ((Component)___m_character).GetComponent<MonsterModifier>(); if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.FastAttackSpeed)) { double num = (double)___m_animator.speed * 10000000.0 % 100.0; float value = MonsterModifiersPlugin.Cfg_FastAttackSpeed_AnimatorMultiplier.Value; if ((!(num < 30.0) || !(num > 10.0)) && !(___m_animator.speed <= 0.001f)) { ___m_animator.speed = ___m_animator.speed * (1f + value) + 1.9E-06f; } } } } [HarmonyPatch(typeof(Attack), "Start")] public static class FastAttackSpeed_Attack_Start_Patch { private static void Postfix(Humanoid character, ItemData weapon, bool __result) { if (((Character)character).InAttack() && !((Character)character).IsPlayer()) { MonsterModifier component = ((Component)character).GetComponent<MonsterModifier>(); if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.FastAttackSpeed) && !((Character)character).IsPlayer() && __result && !((Character)character).IsBoss()) { float value = MonsterModifiersPlugin.Cfg_FastAttackSpeed_IntervalReduction.Value; weapon.m_lastAttackTime -= weapon.m_shared.m_aiAttackInterval * Mathf.Max(0f, value); } } } } } public class FastMovement { public static void AddFastMovement(Character character) { character.m_speed *= MonsterModifiersPlugin.Cfg_FastMovement_SpeedMultiplier.Value; character.m_runSpeed *= MonsterModifiersPlugin.Cfg_FastMovement_SpeedMultiplier.Value; character.m_walkSpeed *= MonsterModifiersPlugin.Cfg_FastMovement_SpeedMultiplier.Value; } public static void RemoveFastMovement(Character character) { character.m_speed /= MonsterModifiersPlugin.Cfg_FastMovement_SpeedMultiplier.Value; character.m_runSpeed /= MonsterModifiersPlugin.Cfg_FastMovement_SpeedMultiplier.Value; character.m_walkSpeed /= MonsterModifiersPlugin.Cfg_FastMovement_SpeedMultiplier.Value; } } public class FoodDrain { [HarmonyPatch(typeof(Character), "RPC_Damage")] public class FoodDrain_Character_RPC_Damage_Patch { public static void Postfix(Character __instance, HitData hit) { if (!ModifierUtils.RunRPCDamageChecks(__instance, hit) || !ModifierUtils.RunHitChecks(hit, isMonsterAttackingPlayer: true) || __instance.IsBlocking()) { return; } Character attacker = hit.GetAttacker(); MonsterModifier component = ((Component)attacker).GetComponent<MonsterModifier>(); if ((Object)(object)component == (Object)null || !component.Modifiers.Contains(MonsterModifierTypes.FoodDrain)) { return; } Player val = (Player)(object)((__instance is Player) ? __instance : null); if ((Object)(object)val != (Object)null) { List<Food> foods = val.GetFoods(); int count = foods.Count; if (count > 0) { int index = Random.Range(0, count); float num = ModifierUtils.ScaleReductionEffect(MonsterModifiersPlugin.Cfg_FoodDrain_DurationReduction.Value, ModifierUtils.BossOffenseMult(attacker)); Food obj = foods[index]; obj.m_time *= num; } } } } } public class ElementalInfusions { [HarmonyPatch(typeof(Character), "RPC_Damage")] public class ElementalInfusions_Character_RPC_Damage_Patch { public static void Prefix(Character __instance, HitData hit) { if (!ModifierUtils.RunRPCDamageChecks(__instance, hit) || !ModifierUtils.RunHitChecks(hit, isMonsterAttackingPlayer: true) || __instance.IsBlocking()) { return; } Character attacker = hit.GetAttacker(); MonsterModifier component = ((Component)attacker).GetComponent<MonsterModifier>(); if (!((Object)(object)component == (Object)null)) { float num = hit.GetTotalDamage() * MonsterModifiersPlugin.Cfg_ElementalInfusion_DamageRatio.Value; float num2 = hit.m_damage.m_chop + hit.m_damage.m_pickaxe + hit.m_damage.m_spirit; float num3 = (num - num2) * ModifierUtils.BossOffenseMult(attacker); if (component.Modifiers.Contains(MonsterModifierTypes.PoisonInfused)) { hit.m_damage.m_poison += num3; } if (component.Modifiers.Contains(MonsterModifierTypes.FireInfused)) { hit.m_damage.m_fire += num3; } if (component.Modifiers.Contains(MonsterModifierTypes.LightningInfused)) { hit.m_damage.m_lightning += num3; } if (component.Modifiers.Contains(MonsterModifierTypes.FrostInfused)) { hit.m_damage.m_frost += num3; } } } } } public class ArmorCharge { [HarmonyPatch(typeof(Character), "RPC_Damage")] public class ArmorCharge_Character_RPC_Damage_Patch { public static void Prefix(Character __instance, HitData hit) { if (hit == null || (Object)(object)__instance == (Object)null || !__instance.IsPlayer()) { return; } Character attacker = hit.GetAttacker(); if (!((Object)(object)attacker == (Object)null)) { MonsterModifier component = ((Component)attacker).GetComponent<MonsterModifier>(); if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.ArmorCharge)) { hit.m_damage.m_blunt *= 1.5f; hit.m_damage.m_slash *= 1.5f; hit.m_damage.m_pierce *= 1.5f; hit.m_damage.m_fire *= 1.5f; hit.m_damage.m_frost *= 1.5f; hit.m_damage.m_lightning *= 1.5f; hit.m_damage.m_poison *= 1.5f; hit.m_damage.m_spirit *= 1.5f; } } } } private const float SpeedMultiplier = 1.3f; private const float DamageMultiplier = 1.5f; public static void Apply(Character character) { character.m_walkSpeed *= 1.3f; character.m_runSpeed *= 1.3f; character.m_swimSpeed *= 1.3f; } } public class FireTrail : MonoBehaviour { private Character _character = null; private Vector3 _lastPosition; private float _timer; private readonly List<GameObject> _activeEffects = new List<GameObject>(); private const float SpawnInterval = 0.4f; private const float MinMoveDistance = 0.5f; private const float EffectLifetime = 1.5f; public void Init(Character character) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) _character = character; _lastPosition = ((Component)character).transform.position; } private void FixedUpdate() { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_character == (Object)null || _character.IsDead()) { return; } _timer += Time.fixedDeltaTime; if (_timer < 0.4f) { return; } _timer = 0f; Vector3 position = ((Component)_character).transform.position; if (Vector3.Distance(position, _lastPosition) < 0.5f) { return; } _lastPosition = position; ZNetScene instance = ZNetScene.instance; GameObject val = ((instance != null) ? instance.GetPrefab("fx_Hen_Egg_Heat") : null); if ((Object)(object)val == (Object)null) { ZNetScene instance2 = ZNetScene.instance; val = ((instance2 != null) ? instance2.GetPrefab("vfx_fire_shortlived") : null); } if (!((Object)(object)val == (Object)null)) { GameObject val2 = Object.Instantiate<GameObject>(val, position, Quaternion.identity); if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)val2, 1.5f); } } } } public class Forceful { [HarmonyPatch(typeof(Character), "RPC_Damage")] public class Forceful_Character_RPC_Damage_Patch { public static void Prefix(Character __instance, HitData hit) { if (ModifierUtils.RunRPCDamageChecks(__instance, hit) && ModifierUtils.RunHitChecks(hit, isMonsterAttackingPlayer: true) && !__instance.IsBlocking()) { Character attacker = hit.GetAttacker(); MonsterModifier component = ((Component)attacker).GetComponent<MonsterModifier>(); if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.Forceful)) { float value = MonsterModifiersPlugin.Cfg_Forceful_PushMultiplier.Value; float num = ModifierUtils.BossOffenseMult(attacker); hit.m_pushForce *= 1f + (value - 1f) * num; } } } } } public class ResistanceNotification { [HarmonyPatch(typeof(Character), "RPC_Damage")] public class ResistanceNotification_Character_RPC_Damage_Patch { public static void Prefix(Character __instance, HitData hit) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Invalid comparison between Unknown and I4 //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: 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) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) if (hit == null || (Object)(object)__instance == (Object)null || __instance.IsPlayer() || (int)hit.m_hitType != 2) { return; } MonsterModifier component = ((Component)__instance).GetComponent<MonsterModifier>(); if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.ResistanceNotification) && !((Object)(object)__instance.m_nview == (Object)null)) { ZDOID uid = __instance.m_nview.GetZDO().m_uid; if (!HitCounts.ContainsKey(uid)) { HitCounts[uid] = new Dictionary<DamageType, int>(); } CheckAndNotify(__instance, uid, (DamageType)1, hit.m_damage.m_blunt, component, MonsterModifierTypes.BluntImmunity, "$modifier_blunt_resistance"); CheckAndNotify(__instance, uid, (DamageType)2, hit.m_damage.m_slash, component, MonsterModifierTypes.SlashImmunity, "$modifier_slash_resistance"); CheckAndNotify(__instance, uid, (DamageType)4, hit.m_damage.m_pierce, component, MonsterModifierTypes.PierceImmunity, "$modifier_pierce_resistance"); CheckAndNotifyElemental(__instance, uid, hit.m_damage, component); } } private static void CheckAndNotify(Character character, ZDOID id, DamageType type, float damage, MonsterModifier modComp, MonsterModifierTypes immunity, string messageKey) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) if (damage <= 0f || !modComp.Modifiers.Contains(immunity)) { return; } Dictionary<DamageType, int> dictionary = HitCounts[id]; if (!dictionary.ContainsKey(type)) { dictionary[type] = 0; } if (dictionary[type] < MonsterModifiersPlugin.Cfg_ResistanceNotification_MaxCount.Value) { dictionary[type]++; Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, Localization.instance.Localize(messageKey), 0, (Sprite)null); } } } private static void CheckAndNotifyElemental(Character character, ZDOID id, DamageTypes dmg, MonsterModifier modComp) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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) if (!modComp.Modifiers.Contains(MonsterModifierTypes.ElementalImmunity)) { return; } float num = dmg.m_fire + dmg.m_frost + dmg.m_lightning + dmg.m_poison + dmg.m_spirit; if (num <= 0f) { return; } Dictionary<DamageType, int> dictionary = HitCounts[id]; DamageType key = (DamageType)32; if (!dictionary.ContainsKey(key)) { dictionary[key] = 0; } if (dictionary[key] < MonsterModifiersPlugin.Cfg_ResistanceNotification_MaxCount.Value) { dictionary[key]++; Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, Localization.instance.Localize("$modifier_elemental_resistance"), 0, (Sprite)null); } } } } [HarmonyPatch(typeof(Character), "OnDeath")] public class ResistanceNotification_Character_OnDeath_Patch { public static void Prefix(Character __instance) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.m_nview == (Object)null)) { ZDOID uid = __instance.m_nview.GetZDO().m_uid; HitCounts.Remove(uid); } } } private static readonly Dictionary<ZDOID, Dictionary<DamageType, int>> HitCounts = new Dictionary<ZDOID, Dictionary<DamageType, int>>(); } public class SplitSpawn { [HarmonyPatch(typeof(Character), "OnDeath")] public static class Character_OnDeath_SplitSpawn_Patch { public static void Prefix(Character __instance) { //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || __instance.IsPlayer() || (Object)(object)__instance.m_nview == (Object)null || !__instance.m_nview.IsOwner()) { return; } MonsterModifier component = ((Component)__instance).GetComponent<MonsterModifier>(); if ((Object)(object)component == (Object)null || !component.Modifiers.Contains(MonsterModifierTypes.SplitSpawn)) { return; } int level = __instance.GetLevel(); if (level <= 1) { return; } int num = level - 1; int level2 = level - 1; float value = MonsterModifiersPlugin.Cfg_SplitSpawn_Scale.Value; int num2 = ((Component)__instance).GetComponent<MonsterModifier>()?.SplitGeneration ?? 0; string text = ((Object)__instance).name.Replace("(Clone)", "").Trim(); string text2 = text; if (MonsterModifiersPlugin.Cfg_SplitSpawn_RandomizeWeapon.Value == MonsterModifiersPlugin.Toggle.On && _bowAliases.TryGetValue(text, out string[] value2) && value2.Length > 1) { text2 = value2[Random.Range(0, value2.Length)]; } GameObject prefab = ZNetScene.instance.GetPrefab(text2); if ((Object)(object)prefab == (Object)null) { prefab = ZNetScene.instance.GetPrefab(text); } if ((Object)(object)prefab == (Object)null) { return; } Vector3 position = ((Component)__instance).transform.position; for (int i = 0; i < num; i++) { Vector2 val = Random.insideUnitCircle * 2f; Vector3 val2 = position + new Vector3(val.x, 0f, val.y); float num3 = Random.Range(0f, 360f); GameObject val3 = Object.Instantiate<GameObject>(prefab, val2, Quaternion.Euler(0f, num3, 0f)); val3.transform.localScale = prefab.transform.localScale * value; MonsterModifier component2 = val3.GetComponent<MonsterModifier>(); if ((Object)(object)component2 != (Object)null) { component2.SplitGeneration = num2 + 1; ZNetView component3 = val3.GetComponent<ZNetView>(); if (((component3 != null) ? component3.GetZDO() : null) != null) { component3.GetZDO().Set("splitGeneration", num2 + 1); } } Character component4 = val3.GetComponent<Character>(); if ((Object)(object)component4 != (Object)null) { component4.SetLevel(level2); float num4 = __instance.GetMaxHealth() * MonsterModifiersPlugin.Cfg_SplitSpawn_HP.Value; component4.SetMaxHealth(num4); component4.SetHealth(num4); } } } } private static readonly Dictionary<string, string[]> _bowAliases = new Dictionary<string, string[]> { { "Skeleton", new string[2] { "Skeleton", "Skeleton_NoArcher" } }, { "Draugr", new string[2] { "Draugr", "DraugrE