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 Configurations_Monster_Modifiers; public static ConfigEntry Configurations_Boss_Modifiers; public static ConfigEntry Cfg_PierceImmunity_DamageReduction; public static ConfigEntry Cfg_SlashImmunity_DamageReduction; public static ConfigEntry Cfg_BluntImmunity_DamageReduction; public static ConfigEntry Cfg_ElementalImmunity_DamageReduction; public static ConfigEntry Cfg_Knockback_StaggerForce; public static ConfigEntry Cfg_Knockback_PushForce; public static ConfigEntry Cfg_FastAttackSpeed_AnimatorMultiplier; public static ConfigEntry Cfg_FastAttackSpeed_IntervalReduction; public static ConfigEntry Cfg_SplitSpawn_Scale; public static ConfigEntry Cfg_SplitSpawn_HP; public static ConfigEntry Cfg_SplitSpawn_RandomizeWeapon; public static ConfigEntry Cfg_ShieldBreaker_DurabilityThreshold; public static ConfigEntry Cfg_ShieldBreaker_DurabilityReduction; public static ConfigEntry Cfg_IgnoreArmor_ArmorReduction; public static ConfigEntry Cfg_FoodDrain_DurationReduction; public static ConfigEntry Cfg_ElementalInfusion_DamageRatio; public static ConfigEntry Cfg_Forceful_PushMultiplier; public static ConfigEntry Cfg_Vampiric_HealRatio; public static ConfigEntry Cfg_PersonalShield_Duration; public static ConfigEntry Cfg_PersonalShield_Magnitude; public static ConfigEntry Cfg_FastMovement_SpeedMultiplier; public static ConfigEntry Cfg_DistantDetection_RangeMultiplier; public static ConfigEntry Cfg_SoulEater_Radius; public static ConfigEntry Cfg_SoulEater_MaxStacks; public static ConfigEntry Cfg_SoulEater_GrowthMultiplier; public static ConfigEntry Cfg_SoulEater_DmgStack1; public static ConfigEntry Cfg_SoulEater_DmgStack2; public static ConfigEntry Cfg_SoulEater_DmgStack3; public static ConfigEntry Cfg_ResistanceNotification_MaxCount; public static ConfigEntry Cfg_Boss_OffenseMultiplier; public static ConfigEntry Cfg_Boss_HealMultiplier; public static ConfigEntry Cfg_Offense_Probability; public static ConfigEntry Cfg_Defense_Probability; public static ConfigEntry Cfg_Utility_Probability; public static ConfigEntry Cfg_SplitSpawn_Probability; public static ConfigEntry Cfg_EliteMonster_Enabled; public static ConfigEntry Cfg_EliteMonster_Probability; public static ConfigEntry Cfg_Elite_Size; public static ConfigEntry Cfg_Elite_HP; public static ConfigEntry Cfg_Elite_ATK; public static ConfigEntry 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(0, num); Configurations_Boss_Modifiers = ConfigFileExtensions.BindConfig(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)null, (ConfigurationManagerAttributes)null); SetConfigOrder((ConfigEntryBase)(object)Configurations_Boss_Modifiers, 7); Cfg_EliteMonster_Enabled = ConfigFileExtensions.BindConfig(((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)null, (ConfigurationManagerAttributes)null); SetConfigOrder((ConfigEntryBase)(object)Cfg_EliteMonster_Enabled, 6); ConfigFile config2 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(0, length); Configurations_Monster_Modifiers = ConfigFileExtensions.BindConfig(config2, "General", "Monster_Modifiers", 5, "Maximum modifiers for regular monsters. 0 = disabled.", true, (int?)null, val, (Action)null, (ConfigurationManagerAttributes)null); SetConfigOrder((ConfigEntryBase)(object)Configurations_Monster_Modifiers, 5); ConfigFile config3 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(0, 100); Cfg_EliteMonster_Probability = ConfigFileExtensions.BindConfig(config3, "General", "Elite_Monster_Probability", 10, "Relative roll probability for Elite Monster (boss-excluded, biome-spawn only).", true, (int?)null, val, (Action)null, (ConfigurationManagerAttributes)null); SetConfigOrder((ConfigEntryBase)(object)Cfg_EliteMonster_Probability, 4); ConfigFile config4 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(0, 100); Cfg_SplitSpawn_Probability = ConfigFileExtensions.BindConfig(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)null, (ConfigurationManagerAttributes)null); SetConfigOrder((ConfigEntryBase)(object)Cfg_SplitSpawn_Probability, 3); ConfigFile config5 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(0, 100); Cfg_Offense_Probability = ConfigFileExtensions.BindConfig(config5, "General", "Offense_Probability", 35, "Relative roll probability for Offense modifiers (values are treated as ratio).", true, (int?)null, val, (Action)null, (ConfigurationManagerAttributes)null); SetConfigOrder((ConfigEntryBase)(object)Cfg_Offense_Probability, 2); ConfigFile config6 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(0, 100); Cfg_Defense_Probability = ConfigFileExtensions.BindConfig(config6, "General", "Defense_Probability", 35, "Relative roll probability for Defense modifiers (values are treated as ratio).", true, (int?)null, val, (Action)null, (ConfigurationManagerAttributes)null); SetConfigOrder((ConfigEntryBase)(object)Cfg_Defense_Probability, 1); ConfigFile config7 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(0, 100); Cfg_Utility_Probability = ConfigFileExtensions.BindConfig(config7, "General", "Utility_Probability", 10, "Relative roll probability for Utility modifiers.", true, (int?)null, val, (Action)null, (ConfigurationManagerAttributes)null); SetConfigOrder((ConfigEntryBase)(object)Cfg_Utility_Probability, 0); ConfigFile config8 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(0, 100); Cfg_PierceImmunity_DamageReduction = ConfigFileExtensions.BindConfig(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)null, (ConfigurationManagerAttributes)null); ConfigFile config9 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(0, 100); Cfg_SlashImmunity_DamageReduction = ConfigFileExtensions.BindConfig(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)null, (ConfigurationManagerAttributes)null); ConfigFile config10 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(0, 100); Cfg_BluntImmunity_DamageReduction = ConfigFileExtensions.BindConfig(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)null, (ConfigurationManagerAttributes)null); ConfigFile config11 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(0, 100); Cfg_ElementalImmunity_DamageReduction = ConfigFileExtensions.BindConfig(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)null, (ConfigurationManagerAttributes)null); ConfigFile config12 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(0, 2000); Cfg_Knockback_StaggerForce = ConfigFileExtensions.BindConfig(config12, "Modifier_Offense", "Knockback Stagger Force", 500, "Stagger force applied by the Knockback modifier.", true, (int?)null, val, (Action)null, (ConfigurationManagerAttributes)null); ConfigFile config13 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(0, 200); Cfg_Knockback_PushForce = ConfigFileExtensions.BindConfig(config13, "Modifier_Offense", "Knockback Push Force", 45, "Push force applied by the Knockback modifier.", true, (int?)null, val, (Action)null, (ConfigurationManagerAttributes)null); ConfigFile config14 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(0f, 2f); Cfg_FastAttackSpeed_AnimatorMultiplier = ConfigFileExtensions.BindConfig(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)null, (ConfigurationManagerAttributes)null); ConfigFile config15 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(0f, 0.95f); Cfg_FastAttackSpeed_IntervalReduction = ConfigFileExtensions.BindConfig(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)null, (ConfigurationManagerAttributes)null); ConfigFile config16 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 1f); Cfg_SplitSpawn_Scale = ConfigFileExtensions.BindConfig(config16, "Modifier_Offense", "SplitSpawn Scale", 0.85f, "Size of SplitSpawn children relative to parent size (0.7 = 70%).", true, (int?)null, val, (Action)null, (ConfigurationManagerAttributes)null); ConfigFile config17 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 1f); Cfg_SplitSpawn_HP = ConfigFileExtensions.BindConfig(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)null, (ConfigurationManagerAttributes)null); Cfg_SplitSpawn_RandomizeWeapon = ConfigFileExtensions.BindConfig(((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)null, (ConfigurationManagerAttributes)null); ConfigFile config18 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(0.01f, 0.5f); Cfg_ShieldBreaker_DurabilityThreshold = ConfigFileExtensions.BindConfig(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)null, (ConfigurationManagerAttributes)null); ConfigFile config19 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f); Cfg_ShieldBreaker_DurabilityReduction = ConfigFileExtensions.BindConfig(config19, "Modifier_Offense", "ShieldBreaker Durability Reduction", 0.5f, "Multiplier applied to shield durability on block (0.5 = halved).", true, (int?)null, val, (Action)null, (ConfigurationManagerAttributes)null); ConfigFile config20 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f); Cfg_IgnoreArmor_ArmorReduction = ConfigFileExtensions.BindConfig(config20, "Modifier_Offense", "IgnoreArmor Armor Reduction", 0.5f, "Multiplier applied to player armor value (0.5 = armor halved).", true, (int?)null, val, (Action)null, (ConfigurationManagerAttributes)null); ConfigFile config21 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f); Cfg_FoodDrain_DurationReduction = ConfigFileExtensions.BindConfig(config21, "Modifier_Offense", "FoodDrain Duration Reduction", 0.5f, "Multiplier applied to food duration on hit (0.5 = halved).", true, (int?)null, val, (Action)null, (ConfigurationManagerAttributes)null); ConfigFile config22 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(0f, 2f); Cfg_ElementalInfusion_DamageRatio = ConfigFileExtensions.BindConfig(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)null, (ConfigurationManagerAttributes)null); ConfigFile config23 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(1f, 20f); Cfg_Forceful_PushMultiplier = ConfigFileExtensions.BindConfig(config23, "Modifier_Offense", "Forceful Push Multiplier", 5f, "Multiplier applied to hit push force (5.0 = 5x knockback).", true, (int?)null, val, (Action)null, (ConfigurationManagerAttributes)null); ConfigFile config24 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f); Cfg_Vampiric_HealRatio = ConfigFileExtensions.BindConfig(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)null, (ConfigurationManagerAttributes)null); ConfigFile config25 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(1, 60); Cfg_PersonalShield_Duration = ConfigFileExtensions.BindConfig(config25, "Modifier_Defense", "PersonalShield Duration", 10, "Duration (seconds) of the GoblinShaman shield status effect.", true, (int?)null, val, (Action)null, (ConfigurationManagerAttributes)null); ConfigFile config26 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(0.5f, 10f); Cfg_PersonalShield_Magnitude = ConfigFileExtensions.BindConfig(config26, "Modifier_Defense", "PersonalShield Magnitude", 2f, "Magnitude of the GoblinShaman shield status effect.", true, (int?)null, val, (Action)null, (ConfigurationManagerAttributes)null); ConfigFile config27 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(1f, 5f); Cfg_FastMovement_SpeedMultiplier = ConfigFileExtensions.BindConfig(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)null, (ConfigurationManagerAttributes)null); ConfigFile config28 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(1f, 10f); Cfg_DistantDetection_RangeMultiplier = ConfigFileExtensions.BindConfig(config28, "Modifier_Utility", "DistantDetection Range Multiplier", 2f, "Multiplier applied to hear and view range (2.0 = double range).", true, (int?)null, val, (Action)null, (ConfigurationManagerAttributes)null); ConfigFile config29 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(1f, 20f); Cfg_SoulEater_Radius = ConfigFileExtensions.BindConfig(config29, "Modifier_Utility", "SoulEater Absorb Radius", 5f, "Radius (units) in which SoulEater detects dying enemies.", true, (int?)null, val, (Action)null, (ConfigurationManagerAttributes)null); ConfigFile config30 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(1, 10); Cfg_SoulEater_MaxStacks = ConfigFileExtensions.BindConfig(config30, "Modifier_Utility", "SoulEater Max Stacks", 3, "Maximum number of soul stacks the SoulEater can accumulate.", true, (int?)null, val, (Action)null, (ConfigurationManagerAttributes)null); ConfigFile config31 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(1f, 2f); Cfg_SoulEater_GrowthMultiplier = ConfigFileExtensions.BindConfig(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)null, (ConfigurationManagerAttributes)null); ConfigFile config32 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(1f, 3f); Cfg_SoulEater_DmgStack1 = ConfigFileExtensions.BindConfig(config32, "Modifier_Utility", "SoulEater Damage Stack 1", 1.1f, "Damage multiplier at 1 soul stack.", true, (int?)null, val, (Action)null, (ConfigurationManagerAttributes)null); ConfigFile config33 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(1f, 3f); Cfg_SoulEater_DmgStack2 = ConfigFileExtensions.BindConfig(config33, "Modifier_Utility", "SoulEater Damage Stack 2", 1.2f, "Damage multiplier at 2 soul stacks.", true, (int?)null, val, (Action)null, (ConfigurationManagerAttributes)null); ConfigFile config34 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(1f, 3f); Cfg_SoulEater_DmgStack3 = ConfigFileExtensions.BindConfig(config34, "Modifier_Utility", "SoulEater Damage Stack 3", 1.3f, "Damage multiplier at 3 soul stacks.", true, (int?)null, val, (Action)null, (ConfigurationManagerAttributes)null); ConfigFile config35 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(1, 10); Cfg_ResistanceNotification_MaxCount = ConfigFileExtensions.BindConfig(config35, "Modifier_Utility", "ResistanceNotification Max Count", 2, "Max times to show a resistance notification per damage type per enemy.", true, (int?)null, val, (Action)null, (ConfigurationManagerAttributes)null); ConfigFile config36 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(0, 100); Cfg_Boss_OffenseMultiplier = ConfigFileExtensions.BindConfig(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)null, (ConfigurationManagerAttributes)null); ConfigFile config37 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(0, 100); Cfg_Boss_HealMultiplier = ConfigFileExtensions.BindConfig(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)null, (ConfigurationManagerAttributes)null); ConfigFile config38 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(0, 200); Cfg_Elite_Size = ConfigFileExtensions.BindConfig(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)null, (ConfigurationManagerAttributes)null); ConfigFile config39 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(100, 500); Cfg_Elite_HP = ConfigFileExtensions.BindConfig(config39, "Modifier_Elite", "Elite_Monster_HP", 150, "Health multiplier % for Elite monsters (150 = 1.5x base HP).", true, (int?)null, val, (Action)null, (ConfigurationManagerAttributes)null); ConfigFile config40 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(0, 200); Cfg_Elite_ATK = ConfigFileExtensions.BindConfig(config40, "Modifier_Elite", "Elite_Monster_ATK", 30, "Attack power increase % for Elite monsters (30 = +30% damage output).", true, (int?)null, val, (Action)null, (ConfigurationManagerAttributes)null); ConfigFile config41 = ((BaseUnityPlugin)this).Config; val = (AcceptableValueBase)(object)new AcceptableValueRange(0, 90); Cfg_Elite_DFS = ConfigFileExtensions.BindConfig(config41, "Modifier_Elite", "Elite_Monster_DFS", 30, "Physical and elemental damage reduction % for Elite monsters (30 = -30% incoming damage).", true, (int?)null, val, (Action)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)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)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 list = weaponArray.ToList(); if (list.Count > 0) { foreach (GameObject item in list) { ItemData itemData = item.GetComponent().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("Assets/WarpProjects/Modifiers/NewModifierIcons/Sword.png"); shieldIcon = modiferIconsBundle.LoadAsset("Assets/WarpProjects/Modifiers/NewModifierIcons/Shield.png"); plusSquareIcon = modiferIconsBundle.LoadAsset("Assets/WarpProjects/Modifiers/NewModifierIcons/PlusBox.png"); circleIcon = modiferIconsBundle.LoadAsset("Assets/WarpProjects/Modifiers/NewModifierIcons/Circle.png"); soulIcon = modiferIconsBundle.LoadAsset("Assets/WarpProjects/Modifiers/NewModifierIcons/SoulEater.png"); skullIcon = modiferIconsBundle.LoadAsset("Assets/WarpProjects/Modifiers/NewModifierIcons/Skull.png"); appleIcon = modiferIconsBundle.LoadAsset("Assets/WarpProjects/Modifiers/NewModifierIcons/Apple.png"); shieldBrokenIcon = modiferIconsBundle.LoadAsset("Assets/WarpProjects/Modifiers/NewModifierIcons/ShieldBroken.png"); shieldSpearIcon = modiferIconsBundle.LoadAsset("Assets/WarpProjects/Modifiers/NewModifierIcons/ShieldSpear.png"); shieldMaceIcon = modiferIconsBundle.LoadAsset("Assets/WarpProjects/Modifiers/NewModifierIcons/ShieldMace.png"); shieldSwordIcon = modiferIconsBundle.LoadAsset("Assets/WarpProjects/Modifiers/NewModifierIcons/ShieldSword.png"); potionIcon = modiferIconsBundle.LoadAsset("Assets/WarpProjects/Modifiers/NewModifierIcons/Potion.png"); heartIcon = modiferIconsBundle.LoadAsset("Assets/WarpProjects/Modifiers/NewModifierIcons/heartIcon.png"); bloodIcon = statusEffectBundle.LoadAsset("Assets/WarpProjects/Modifiers/NewModifierIcons/bloodIcon.png"); bloodIconRed = statusEffectBundle.LoadAsset("Assets/WarpProjects/Modifiers/NewModifierIcons/bloodIconRed.png"); earIcon = modiferIconsBundle.LoadAsset("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 color { get; set; } = null; } public class ModifierUtils { public static Dictionary modifiers = null; public static readonly Dictionary ModifierCategories = new Dictionary { { 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 BossExcludedModifiers = new HashSet { 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 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? excluded = null) { int num = 0; foreach (KeyValuePair modifier in modifiers) { if (modifier.Value.weight > 0 && (excluded == null || !excluded.Contains(modifier.Key))) { num++; } } return num; } public static List RollRandomModifiers(int numModifiers, HashSet? excluded = null, int splitGeneration = 0) { List list = new List(); Dictionary dictionary = new Dictionary(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> dictionary2 = new Dictionary>(); foreach (KeyValuePair 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(); } 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 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 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(); 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(); component2.m_speed = 0f; component2.m_flyFastSpeed = 0f; component2.m_flySlowSpeed = 0f; component2.m_name = "$modifier_mistile"; val4.Prefab.GetComponent().m_timeoutMin = 2f; val4.Prefab.GetComponent().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(); 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().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().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().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().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().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().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 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(modifierName, ignoreCase: true, out result)) { Vector3 insideUnitSphere = Random.insideUnitSphere; GameObject val = Object.Instantiate(prefab, ((Component)Player.m_localPlayer).transform.position + ((Component)Player.m_localPlayer).transform.forward * 2f + Vector3.up + insideUnitSphere, Quaternion.identity); Character component = val.GetComponent(); 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(); ((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(); ((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 { { "$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 listeners = Logger.Listeners; foreach (ILogListener item in listeners) { if (item is ShaderLogFilter) { return; } } List list = new List(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 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 list = new List(); for (int i = 0; i < num; i++) { Character component = ((Component)((Component)s_buffer[i]).transform.root).GetComponent(); 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)new DeserializerBuilder()).WithNamingConvention(CamelCaseNamingConvention.Instance).Build(); ModifierUtils.modifiers = val.Deserialize>((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("MonsterModifiers_VersionCheck", (Action)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 ValidatedPeers = new List(); 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 modifiers) { if (!(itemName == "skeleton_bow")) { if (itemName == "draugr_bow") { return GetDraugrBowVisual(modifiers); } return null; } return GetSkeletonBowVisual(modifiers); } public static GameObject? GetSkeletonBowVisual(List 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 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(PrefabUtils.leechDeathSFX, ((Component)base.m_character).transform.position, ((Component)base.m_character).transform.rotation); Object.Instantiate(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(); 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(); if (!((Object)(object)component == (Object)null)) { ChangeEnemyStars(c, component.Modifiers, component.IsBossCharacter, component.OverflowStars); } } } public static void ChangeEnemyStars(Character character, List 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().sprite = ModifierUtils.GetModifierIcon(modifiers[index]); ((Graphic)((Component)child2).GetComponent()).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(); if ((Object)(object)component == (Object)null || !component.Modifiers.Contains(MonsterModifierTypes.Absorption) || ((DamageTypes)(ref hit.m_damage)).GetTotalDamage() == 0f) { return; } List 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(); 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(); 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(); 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(); 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(); 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 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(); 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(); 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 _activeEffects = new List(); 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(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(); 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(); 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(); } 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 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 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> HitCounts = new Dictionary>(); } 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(); 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()?.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(prefab, val2, Quaternion.Euler(0f, num3, 0f)); val3.transform.localScale = prefab.transform.localScale * value; MonsterModifier component2 = val3.GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.SplitGeneration = num2 + 1; ZNetView component3 = val3.GetComponent(); if (((component3 != null) ? component3.GetZDO() : null) != null) { component3.GetZDO().Set("splitGeneration", num2 + 1); } } Character component4 = val3.GetComponent(); 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 _bowAliases = new Dictionary { { "Skeleton", new string[2] { "Skeleton", "Skeleton_NoArcher" } }, { "Draugr", new string[2] { "Draugr", "DraugrElite" } }, { "Fuling", new string[2] { "Fuling", "FulingBerserker" } } }; } public class IgnoreArmor { [HarmonyPatch(typeof(Character), "RPC_Damage")] public class IgnoreArmor_Character_RPC_Damage_Patch { public static void Prefix(Character __instance, HitData hit) { if (ModifierUtils.RunRPCDamageChecks(__instance, hit) && ModifierUtils.RunHitChecks(hit, isMonsterAttackingPlayer: true)) { Character attacker = hit.GetAttacker(); MonsterModifier component = ((Component)attacker).GetComponent(); if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.IgnoreArmor)) { shouldIgnoreArmor = true; _bossOffenseMult = ModifierUtils.BossOffenseMult(attacker); } } } } [HarmonyPatch(typeof(Player), "GetBodyArmor")] public class IgnoreArmor_Player_GetBodyArmor_Patch { public static void Postfix(ref float __result) { if (shouldIgnoreArmor) { __result *= ModifierUtils.ScaleReductionEffect(MonsterModifiersPlugin.Cfg_IgnoreArmor_ArmorReduction.Value, _bossOffenseMult); shouldIgnoreArmor = false; _bossOffenseMult = 1f; } } } public static bool shouldIgnoreArmor = false; private static float _bossOffenseMult = 1f; } public class Quiet { public static void AddQuiet(Character character) { BaseAI baseAI = character.m_baseAI; if (!((Object)(object)baseAI != (Object)null)) { return; } if (baseAI.m_alertedEffects.HasEffects()) { EffectData[] effectPrefabs = baseAI.m_alertedEffects.m_effectPrefabs; foreach (EffectData val in effectPrefabs) { val.m_enabled = false; } } if (baseAI.m_idleSound.HasEffects()) { EffectData[] effectPrefabs2 = baseAI.m_idleSound.m_effectPrefabs; foreach (EffectData val2 in effectPrefabs2) { val2.m_enabled = false; } } } } public class StaggerDeath { [HarmonyPatch(typeof(Character), "OnDeath")] public class StaggerDeath_Character_OnDeath_Patch { public static void Prefix(Character __instance) { //IL_005b: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: 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) //IL_0144: 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 || !(((Object)((Component)__instance).gameObject).name == "mistleCustomPrefab(Clone)")) { return; } Vector3 position = ((Component)__instance).transform.position; GameObject prefab = PrefabManager.Instance.GetPrefab("staggerDeathNovaCustomPrefab"); if (!((Object)(object)prefab != (Object)null)) { return; } Object.Instantiate(prefab, new Vector3(((Component)__instance).transform.position.x, ((Component)__instance).transform.position.y - 1f, ((Component)__instance).transform.position.z), ((Component)__instance).transform.rotation); foreach (Character item in WorldUtils.GetAllCharacter(((Component)__instance).transform.position, 5f)) { if (!((Object)(object)item == (Object)null) && !((Object)(object)item == (Object)(object)__instance) && !((Object)(object)item.m_nview == (Object)null) && item.m_nview.m_zdo != null) { item.Stagger(position); } } } } } public class StaggerImmune { [HarmonyPatch(typeof(Character), "Stagger")] public class StaminaSiphon_Character_RPC_Damage_Patch { public static bool Prefix(Character __instance) { if ((Object)(object)__instance == (Object)null) { return true; } MonsterModifier component = ((Component)__instance).GetComponent(); if ((Object)(object)component == (Object)null) { return true; } if (component.Modifiers.Contains(MonsterModifierTypes.StaggerImmune)) { return false; } return true; } } public static void AddStaggerImmune(Character character) { character.m_staggerWhenBlocked = false; } public static void RemoveStaggerImmune(Character character) { character.m_staggerWhenBlocked = true; } } public class DamageModifiers { [HarmonyPatch(typeof(Character), "RPC_Damage")] public class ModiferDamageModifiers_Character_RPC_Damage_Patch { public static void Prefix(Character __instance, HitData hit) { if (hit == null || (Object)(object)__instance == (Object)null || ((DamageTypes)(ref hit.m_damage)).GetTotalDamage() == 0f) { return; } MonsterModifier component = ((Component)__instance).GetComponent(); if (!((Object)(object)component == (Object)null)) { if (component.Modifiers.Contains(MonsterModifierTypes.PierceImmunity)) { hit.m_damage.m_pierce *= 1f - (float)MonsterModifiersPlugin.Cfg_PierceImmunity_DamageReduction.Value / 100f; } if (component.Modifiers.Contains(MonsterModifierTypes.SlashImmunity)) { hit.m_damage.m_slash *= 1f - (float)MonsterModifiersPlugin.Cfg_SlashImmunity_DamageReduction.Value / 100f; } if (component.Modifiers.Contains(MonsterModifierTypes.BluntImmunity)) { hit.m_damage.m_blunt *= 1f - (float)MonsterModifiersPlugin.Cfg_BluntImmunity_DamageReduction.Value / 100f; } if (component.Modifiers.Contains(MonsterModifierTypes.ElementalImmunity)) { float num = 1f - (float)MonsterModifiersPlugin.Cfg_ElementalImmunity_DamageReduction.Value / 100f; hit.m_damage.m_fire *= num; hit.m_damage.m_frost *= num; hit.m_damage.m_lightning *= num; hit.m_damage.m_poison *= num; hit.m_damage.m_spirit *= num; } } } } } public class RemoveStatusEffect { [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) || __instance.IsBlocking()) { return; } Character attacker = hit.GetAttacker(); MonsterModifier component = ((Component)attacker).GetComponent(); if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.RemoveStatusEffect)) { List statusEffects = __instance.GetSEMan().GetStatusEffects(); if (statusEffects.Count > 1) { int index = Random.Range(0, statusEffects.Count); __instance.GetSEMan().RemoveStatusEffect(statusEffects[index], false); } } } } } public class ShieldBreaker { [HarmonyPatch(typeof(Humanoid), "BlockAttack")] public class ShieldBreaker_Humanoid_BlockAttack_Patch { public static void Postfix(Humanoid __instance, HitData hit, Character attacker) { if (hit == null || (Object)(object)__instance == (Object)null || (Object)(object)attacker == (Object)null || attacker.IsPlayer()) { return; } MonsterModifier component = ((Component)attacker).GetComponent(); if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.ShieldBreaker)) { ItemData currentBlocker = __instance.GetCurrentBlocker(); if (currentBlocker != null && currentBlocker.m_durability > currentBlocker.GetMaxDurability() * MonsterModifiersPlugin.Cfg_ShieldBreaker_DurabilityThreshold.Value) { float num = ModifierUtils.ScaleReductionEffect(MonsterModifiersPlugin.Cfg_ShieldBreaker_DurabilityReduction.Value, ModifierUtils.BossOffenseMult(attacker)); currentBlocker.m_durability *= num; } } } } } public class ShieldDome : MonoBehaviour { public static CustomPrefab ShieldGenereatorBubbleCustomPrefab; public static EffectData shieldDomeBubbleSFX; public GameObject shieldGenereatorBubble = null; public Character m_character = null; public ShieldGenerator m_shieldGenerator = null; public ShieldDomeImageEffect m_shieldDomeImageEffect = null; public ZNetView m_nview = null; public static void LoadShieldDome() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown ShieldGenereatorBubbleCustomPrefab = new CustomPrefab(ModifierAssetUtils.ashlandsAssetBundle, "ShieldDome_Bubble", true); PrefabManager.Instance.AddPrefab(ShieldGenereatorBubbleCustomPrefab); } public void AddShieldDome(Character character) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) ((Component)character).gameObject.AddComponent(); shieldGenereatorBubble = Object.Instantiate(ShieldGenereatorBubbleCustomPrefab.Prefab, ((Component)character).transform.position, ((Component)character).transform.rotation); m_character = character; m_shieldGenerator = shieldGenereatorBubble.GetComponent(); m_nview = shieldGenereatorBubble.GetComponent(); m_shieldGenerator.m_nview = m_nview; m_shieldGenerator.m_defaultFuel = 999; m_shieldGenerator.m_radius = 10f; m_shieldGenerator.m_maxShieldRadius = 10f; m_shieldGenerator.m_minShieldRadius = 10f; m_shieldDomeImageEffect = Object.FindFirstObjectByType(); if ((Object)(object)m_nview != (Object)null) { m_nview.Register("RPC_DestroyShieldDome", (Action)RPC_DestroyShieldDome); } } public void Update() { //IL_0041: 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_0089: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)m_character != (Object)null && (Object)(object)shieldGenereatorBubble != (Object)null) { m_shieldGenerator.m_shieldDome.transform.position = ((Component)m_character).transform.position; m_shieldGenerator.m_shieldDome.transform.rotation = ((Component)m_character).transform.rotation; m_shieldDomeImageEffect.SetShieldData(m_shieldGenerator, ((Component)m_character).transform.position, 10f, m_shieldGenerator.m_lastFuel, m_shieldGenerator.m_lastHitTime); } } public void OnDestroy() { if ((Object)(object)m_nview != (Object)null && m_nview.IsValid() && m_nview.IsOwner()) { m_nview.InvokeRPC(ZNetView.Everybody, "RPC_DestroyShieldDome", Array.Empty()); } } private void RPC_DestroyShieldDome(long sender) { DestroyShieldDome(); } private void DestroyShieldDome() { if ((Object)(object)m_shieldGenerator != (Object)null) { m_shieldDomeImageEffect.RemoveShield(m_shieldGenerator); } if ((Object)(object)shieldGenereatorBubble != (Object)null) { ZNetScene.instance.Destroy(shieldGenereatorBubble); } if ((Object)(object)m_shieldGenerator.m_shieldDome != (Object)null) { ZNetScene.instance.Destroy(m_shieldGenerator.m_shieldDome); } } } public class PersonalShield { public static void AddPersonalShield(Character character) { int stableHashCode = StringExtensionMethods.GetStableHashCode("GoblinShaman_shield"); character.GetSEMan().AddStatusEffect(stableHashCode, true, MonsterModifiersPlugin.Cfg_PersonalShield_Duration.Value, MonsterModifiersPlugin.Cfg_PersonalShield_Magnitude.Value); } public static void RemovePersonalShield(Character character) { int stableHashCode = StringExtensionMethods.GetStableHashCode("GoblinShaman_shield"); character.GetSEMan().RemoveStatusEffect(stableHashCode, false); } } public class DeathSpawns { [HarmonyPatch(typeof(Character), "OnDeath")] public class DeathSpawns_Character_OnDeath_Patch { public static void Prefix(Character __instance) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: 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_0402: Unknown result type (might be due to invalid IL or missing references) //IL_0412: Unknown result type (might be due to invalid IL or missing references) //IL_0428: Unknown result type (might be due to invalid IL or missing references) //IL_0432: Unknown result type (might be due to invalid IL or missing references) //IL_043d: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Expected O, but got Unknown //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_0559: Unknown result type (might be due to invalid IL or missing references) //IL_0569: Unknown result type (might be due to invalid IL or missing references) //IL_057f: Unknown result type (might be due to invalid IL or missing references) //IL_0589: Unknown result type (might be due to invalid IL or missing references) //IL_0594: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Expected O, but got Unknown //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_0474: Unknown result type (might be due to invalid IL or missing references) //IL_05cb: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || __instance.IsPlayer()) { return; } MonsterModifier component = ((Component)__instance).GetComponent(); if ((Object)(object)component == (Object)null) { return; } if (component.Modifiers.Contains(MonsterModifierTypes.PoisonDeath)) { float poison = DamageUtils.CalculateDamage(__instance, 0.5f); GameObject prefab = ZNetScene.instance.GetPrefab("blob_aoe"); if ((Object)(object)prefab != (Object)null) { Object.Instantiate(prefab, ((Component)__instance).transform.position, ((Component)__instance).transform.rotation); HitData hit = new HitData { m_damage = { m_poison = poison } }; ApplyDamageToNearbyPlayers(((Component)__instance).transform.position, hit); } } if (component.Modifiers.Contains(MonsterModifierTypes.FireDeath)) { float fire = DamageUtils.CalculateDamage(__instance, 0.5f); GameObject prefab2 = ZNetScene.instance.GetPrefab("fx_fireskeleton_nova"); if ((Object)(object)prefab2 != (Object)null) { GameObject val = Object.Instantiate(prefab2, new Vector3(((Component)__instance).transform.position.x, ((Component)__instance).transform.position.y + 1.25f, ((Component)__instance).transform.position.z), ((Component)__instance).transform.rotation); ParticleSystem[] componentsInChildren = val.GetComponentsInChildren(); foreach (ParticleSystem val2 in componentsInChildren) { MainModule main = val2.main; ((MainModule)(ref main)).startDelay = MinMaxCurve.op_Implicit(0f); } ZSFX componentInChildren = val.GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.m_delay = 0f; componentInChildren.m_minDelay = 0f; componentInChildren.m_maxDelay = 0f; } HitData hit2 = new HitData { m_damage = { m_fire = fire } }; ApplyDamageToNearbyPlayers(((Component)__instance).transform.position, hit2); } } if (component.Modifiers.Contains(MonsterModifierTypes.FrostDeath)) { float frost = DamageUtils.CalculateDamage(__instance, 0.5f); GameObject prefab3 = ZNetScene.instance.GetPrefab("fx_DvergerMage_Nova_ring"); if ((Object)(object)prefab3 != (Object)null) { GameObject val3 = Object.Instantiate(prefab3, new Vector3(((Component)__instance).transform.position.x, ((Component)__instance).transform.position.y + 1f, ((Component)__instance).transform.position.z), ((Component)__instance).transform.rotation); ParticleSystem[] componentsInChildren2 = val3.GetComponentsInChildren(); foreach (ParticleSystem val4 in componentsInChildren2) { MainModule main2 = val4.main; ((MainModule)(ref main2)).startDelay = MinMaxCurve.op_Implicit(0f); } ZSFX componentInChildren2 = val3.GetComponentInChildren(); if ((Object)(object)componentInChildren2 != (Object)null) { componentInChildren2.m_delay = 0f; componentInChildren2.m_minDelay = 0f; componentInChildren2.m_maxDelay = 0f; } HitData hit3 = new HitData { m_damage = { m_frost = frost } }; ApplyDamageToNearbyPlayers(((Component)__instance).transform.position, hit3); } } if (component.Modifiers.Contains(MonsterModifierTypes.StaggerDeath)) { GameObject prefab4 = PrefabManager.Instance.GetPrefab("mistleCustomPrefab"); if ((Object)(object)prefab4 != (Object)null) { Object.Instantiate(prefab4, new Vector3(((Component)__instance).transform.position.x, ((Component)__instance).transform.position.y + 1f, ((Component)__instance).transform.position.z), ((Component)__instance).transform.rotation); } } if (component.Modifiers.Contains(MonsterModifierTypes.HealDeath)) { GameObject prefab5 = PrefabManager.Instance.GetPrefab("healCustomPrefab"); float num = __instance.GetMaxHealth() * 0.75f; if ((Object)(object)prefab5 != (Object)null) { Object.Instantiate(prefab5, new Vector3(((Component)__instance).transform.position.x, ((Component)__instance).transform.position.y + 1f, ((Component)__instance).transform.position.z), ((Component)__instance).transform.rotation); } if ((Object)(object)Player.m_localPlayer != (Object)null && ((Character)Player.m_localPlayer).IsOwner()) { foreach (Character item in WorldUtils.GetAllCharacter(((Component)__instance).transform.position, 15f)) { if (!((Object)(object)item == (Object)null) && !((Object)(object)item == (Object)(object)__instance) && !((Object)(object)item.m_nview == (Object)null) && item.m_nview.IsValid()) { item.GetSEMan().AddStatusEffect(StringExtensionMethods.GetStableHashCode("HealDeathStatusEffect"), item.IsPlayer(), 0, num); } } } } if (!component.Modifiers.Contains(MonsterModifierTypes.TarDeath)) { return; } GameObject prefab6 = ZNetScene.instance.GetPrefab("blobtar_projectile_tarball"); if ((Object)(object)prefab6 != (Object)null) { Object.Instantiate(prefab6, new Vector3(((Component)__instance).transform.position.x, ((Component)__instance).transform.position.y + 1f, ((Component)__instance).transform.position.z), ((Component)__instance).transform.rotation); } if (!((Object)(object)Player.m_localPlayer != (Object)null) || !((Character)Player.m_localPlayer).IsOwner()) { return; } foreach (Character item2 in WorldUtils.GetAllCharacter(((Component)__instance).transform.position, 5f)) { if (!((Object)(object)item2 == (Object)null) && !((Object)(object)item2 == (Object)(object)__instance) && !((Object)(object)item2.m_nview == (Object)null) && item2.m_nview.IsValid()) { item2.GetSEMan().AddStatusEffect(StringExtensionMethods.GetStableHashCode("Tared"), false, 0, 0f); } } } } public static void ApplyDamageToNearbyPlayers(Vector3 position, HitData hit) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) List list = new List(); Player.GetPlayersInRange(position, 5f, list); foreach (Player item in list) { ((Character)item).Damage(hit); } } } public static class EliteMonster { [CompilerGenerated] private sealed class d__1 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Character character; public float logHp; private bool 5__1; private string 5__2; private bool 5__3; private float 5__4; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)character == (Object)null) { return false; } 5__1 = Location.IsInsideNoBuildLocation(((Component)character).transform.position); 5__2 = ((Object)character).name.Replace("(Clone)", "").Trim(); 5__3 = 5__1 || 5__2.StartsWith("Troll", StringComparison.OrdinalIgnoreCase); if (!5__3) { 5__4 = 1f + (float)MonsterModifiersPlugin.Cfg_Elite_Size.Value / 100f; Transform transform = ((Component)character).transform; transform.localScale *= 5__4; Physics.SyncTransforms(); } MonsterModifiersPlugin.MonsterModifiersLogger.LogInfo((object)("[EliteMonster] Applied to " + ((Object)character).name + " — " + $"scale={((Component)character).transform.localScale.x:F3}, HP {logHp:F0}, dungeon={5__1}")); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static void Apply(Character character) { float num = (float)MonsterModifiersPlugin.Cfg_Elite_HP.Value / 100f; float num2 = character.GetMaxHealth() * num; character.SetMaxHealth(num2); character.SetHealth(num2); MonsterModifier component = ((Component)character).GetComponent(); if (component != null) { ((MonoBehaviour)component).StartCoroutine(ApplyVisualDelayed(character, num2)); } } [IteratorStateMachine(typeof(d__1))] private static IEnumerator ApplyVisualDelayed(Character character, float logHp) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__1(0) { character = character, logHp = logHp }; } } [HarmonyPatch(typeof(Character), "RPC_Damage")] public static class EliteMonster_ATK_Patch { [HarmonyPrefix] public static void Prefix(Character __instance, long sender, HitData hit) { if (!ModifierUtils.RunRPCDamageChecks(__instance, hit) || !ModifierUtils.RunHitChecks(hit, isMonsterAttackingPlayer: true)) { return; } Character attacker = hit.GetAttacker(); if (!((Object)(object)attacker == (Object)null)) { MonsterModifier component = ((Component)attacker).GetComponent(); if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.EliteMonster)) { float num = (float)MonsterModifiersPlugin.Cfg_Elite_ATK.Value / 100f; hit.ApplyModifier(1f + num); } } } } [HarmonyPatch(typeof(Character), "RPC_Damage")] public static class EliteMonster_DFS_Patch { [HarmonyPrefix] public static void Prefix(Character __instance, long sender, HitData hit) { if (hit != null && !((Object)(object)__instance == (Object)null) && ((DamageTypes)(ref hit.m_damage)).GetTotalDamage() != 0f) { MonsterModifier component = ((Component)__instance).GetComponent(); if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.EliteMonster)) { float num = 1f - (float)MonsterModifiersPlugin.Cfg_Elite_DFS.Value / 100f; hit.m_damage.m_pierce *= num; hit.m_damage.m_slash *= num; hit.m_damage.m_blunt *= num; hit.m_damage.m_fire *= num; hit.m_damage.m_frost *= num; hit.m_damage.m_lightning *= num; hit.m_damage.m_poison *= num; hit.m_damage.m_spirit *= num; } } } } public class SoulEater : MonoBehaviour { [HarmonyPatch(typeof(Character), "OnDeath")] public class SoulEater_Character_OnDeath_Patch { public static void Prefix(Character __instance) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) MonsterModifier monsterModifier = default(MonsterModifier); if ((Object)(object)__instance == (Object)null || __instance.IsPlayer() || (((Component)__instance).TryGetComponent(ref monsterModifier) && monsterModifier.Modifiers.Contains(MonsterModifierTypes.SoulEater))) { return; } List allCharacter = WorldUtils.GetAllCharacter(((Component)__instance).transform.position, MonsterModifiersPlugin.Cfg_SoulEater_Radius.Value); foreach (Character item in allCharacter) { if (!((Object)(object)item == (Object)null) && !((Object)(object)item.m_nview == (Object)null) && item.m_nview.GetZDO() != null && item.m_nview.GetZDO().IsOwner()) { MonsterModifier component = ((Component)item).GetComponent(); if ((Object)(object)component != (Object)null && component.Modifiers.Contains(MonsterModifierTypes.SoulEater) && item.m_nview.GetZDO().GetInt("MM_soulEaterCount", 0) < MonsterModifiersPlugin.Cfg_SoulEater_MaxStacks.Value) { int num = item.m_nview.GetZDO().GetInt("MM_soulEaterCount", 0) + 1; item.m_nview.GetZDO().Set("MM_soulEaterCount", num); Transform transform = ((Component)item).transform; transform.localScale *= MonsterModifiersPlugin.Cfg_SoulEater_GrowthMultiplier.Value; Physics.SyncTransforms(); item.m_health *= MonsterModifiersPlugin.Cfg_SoulEater_GrowthMultiplier.Value; } } } } } [HarmonyPatch(typeof(Character), "RPC_Damage")] public class SoulEater_Character_RPC_Damage_Patch { public static void Prefix(Character __instance, HitData hit) { if (!ModifierUtils.RunRPCDamageChecks(__instance, hit) || !ModifierUtils.RunHitChecks(hit, isMonsterAttackingPlayer: true)) { return; } Character attacker = hit.GetAttacker(); MonsterModifier component = ((Component)attacker).GetComponent(); if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.SoulEater) && attacker.m_nview.GetZDO().GetInt("MM_soulEaterCount", 0) > 0) { int @int = attacker.m_nview.GetZDO().GetInt("MM_soulEaterCount", 0); float totalDamage = hit.GetTotalDamage(); float num = totalDamage; switch (@int) { case 1: hit.ApplyModifier(MonsterModifiersPlugin.Cfg_SoulEater_DmgStack1.Value); num = totalDamage * MonsterModifiersPlugin.Cfg_SoulEater_DmgStack1.Value; break; case 2: hit.ApplyModifier(MonsterModifiersPlugin.Cfg_SoulEater_DmgStack2.Value); num = totalDamage * MonsterModifiersPlugin.Cfg_SoulEater_DmgStack2.Value; break; case 3: hit.ApplyModifier(MonsterModifiersPlugin.Cfg_SoulEater_DmgStack3.Value); num = totalDamage * MonsterModifiersPlugin.Cfg_SoulEater_DmgStack3.Value; break; default: hit.ApplyModifier(1f); num = totalDamage * 1f; break; } } } } } public class StaminaSiphon { [HarmonyPatch(typeof(Character), "RPC_Damage")] public class StaminaSiphon_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(); if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.StaminaSiphon) && !__instance.IsBlocking()) { __instance.UseStamina(hit.GetTotalDamage() * ModifierUtils.BossOffenseMult(attacker)); } } } } } public class Vampiric { [HarmonyPatch(typeof(Character), "RPC_Damage")] public class Vampiric_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(); if (!((Object)(object)component == (Object)null)) { float num = hit.GetTotalDamage() * MonsterModifiersPlugin.Cfg_Vampiric_HealRatio.Value; float num2 = hit.m_damage.m_chop + hit.m_damage.m_pickaxe + hit.m_damage.m_spirit; float num3 = num - num2; if (component.Modifiers.Contains(MonsterModifierTypes.Vampiric)) { attacker.Heal(num3 * ModifierUtils.BossHealMult(attacker), true); } } } } } public class Wet { [HarmonyPatch(typeof(Character), "RPC_Damage")] public class Wet_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(); if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.Wet)) { __instance.GetSEMan().AddStatusEffect(StringExtensionMethods.GetStableHashCode("Wet"), false, 0, 0f); } } } } } } namespace MonsterModifiers.Custom_Components { public class MonsterModifier : MonoBehaviour { public List Modifiers = new List(); public Character character = null; public int level; public bool IsBossCharacter = false; public int OverflowStars = 0; public int SplitGeneration = 0; private void Start() { character = ((Component)this).GetComponent(); level = character.GetLevel(); if ((Object)(object)character.m_nview != (Object)null) { int @int = character.m_nview.GetZDO().GetInt("splitGeneration", 0); if (@int > SplitGeneration) { SplitGeneration = @int; } } if ((Object)(object)character.m_nview != (Object)null && character.m_nview.GetZDO().GetString("BountyID", "") != string.Empty) { Object.Destroy((Object)(object)this); } else { if (MonsterModifiersPlugin.Configurations_Monster_Modifiers.Value == 0) { return; } if (character.IsBoss()) { if (MonsterModifiersPlugin.Configurations_Boss_Modifiers.Value == 0) { return; } IsBossCharacter = true; int value = MonsterModifiersPlugin.Configurations_Boss_Modifiers.Value; int num = Mathf.Max(0, level - 1); int num2 = value + num; int availableModifierCount = ModifierUtils.GetAvailableModifierCount(ModifierUtils.BossExcludedModifiers); int numModifiers = Mathf.Min(num2, availableModifierCount); int num3 = Mathf.Min(num, availableModifierCount - value); OverflowStars = Mathf.Max(0, num - num3); string @string = character.m_nview.GetZDO().GetString("modifiers", string.Empty); if (string.IsNullOrEmpty(@string)) { foreach (MonsterModifierTypes item in ModifierUtils.RollRandomModifiers(numModifiers, ModifierUtils.BossExcludedModifiers, SplitGeneration)) { Modifiers.Add(item); } if (character.m_nview.GetZDO().IsOwner()) { character.m_nview.GetZDO().Set("modifiers", string.Join(",", Modifiers)); } } else { Modifiers = ParseModifiers(@string); int availableModifierCount2 = ModifierUtils.GetAvailableModifierCount(ModifierUtils.BossExcludedModifiers); int num4 = Mathf.Min(num, availableModifierCount2 - value); OverflowStars = Mathf.Max(0, num - num4); } ApplyStartModifiers(); } else { if (level <= 1) { return; } string string2 = character.m_nview.GetZDO().GetString("modifiers", string.Empty); if (string.IsNullOrEmpty(string2)) { int numModifiers2 = Mathf.Min(level - 1, MonsterModifiersPlugin.Configurations_Monster_Modifiers.Value); foreach (MonsterModifierTypes item2 in ModifierUtils.RollRandomModifiers(numModifiers2, null, SplitGeneration)) { Modifiers.Add(item2); } if (character.m_nview.GetZDO().IsOwner()) { string text = string.Join(",", Modifiers); character.m_nview.GetZDO().Set("modifiers", text); } } else { Modifiers = ParseModifiers(string2); } ApplyStartModifiers(); } } } private static List ParseModifiers(string modifiersString) { List list = new List(); string[] array = modifiersString.Split(new char[1] { ',' }); foreach (string text in array) { if (Enum.TryParse(text, out var result)) { list.Add(result); } else { MonsterModifiersPlugin.MonsterModifiersLogger.LogWarning((object)("Unknown modifier '" + text + "' in ZDO — skipped.")); } } return list; } public void ChangeModifiers(List modifierTypesList, int numModifiers) { if (level <= 1) { return; } foreach (MonsterModifierTypes modifierTypes in modifierTypesList) { Modifiers.Add(modifierTypes); Debug.Log((object)("Monster with name " + ((Object)character).name + " has has changed modifiers. New modifier: " + modifierTypes)); } if (character.m_nview.GetZDO().IsOwner()) { string text = string.Join(",", Modifiers); character.m_nview.GetZDO().Set("modifiers", text); } } public void ApplyStartModifiers() { if (Modifiers.Contains(MonsterModifierTypes.PersonalShield)) { PersonalShield.AddPersonalShield(character); } if (Modifiers.Contains(MonsterModifierTypes.ShieldDome)) { ShieldDome shieldDome = ((Component)character).gameObject.AddComponent(); shieldDome.AddShieldDome(character); } if (Modifiers.Contains(MonsterModifierTypes.StaggerImmune)) { StaggerImmune.AddStaggerImmune(character); } if (Modifiers.Contains(MonsterModifierTypes.FastMovement)) { FastMovement.AddFastMovement(character); } if (Modifiers.Contains(MonsterModifierTypes.DistantDetection)) { DistantDetection.AddDistantDetection(character); } if (Modifiers.Contains(MonsterModifierTypes.Quiet)) { Quiet.AddQuiet(character); } if (Modifiers.Contains(MonsterModifierTypes.PierceImmunity) && Modifiers.Contains(MonsterModifierTypes.SlashImmunity) && Modifiers.Contains(MonsterModifierTypes.BluntImmunity) && Modifiers.Contains(MonsterModifierTypes.FastMovement)) { Modifiers.Add(MonsterModifierTypes.ArmorCharge); ArmorCharge.Apply(character); } if (Modifiers.Contains(MonsterModifierTypes.FireInfused) && Modifiers.Contains(MonsterModifierTypes.FastAttackSpeed)) { Modifiers.Add(MonsterModifierTypes.FireTrail); FireTrail fireTrail = ((Component)character).gameObject.AddComponent(); fireTrail.Init(character); } if (Modifiers.Contains(MonsterModifierTypes.EliteMonster)) { EliteMonster.Apply(character); } } } public class AddMonsterModifiersToCharacter { [HarmonyPriority(800)] [HarmonyPatch(typeof(Character), "Awake")] public static class Character_Awake_Patch { private static void Postfix(Character __instance) { if (!__instance.IsPlayer()) { ((Component)__instance).gameObject.AddComponent(); } } } [HarmonyPatch(typeof(Character), "UpdateCachedAnimHashes")] public static class Character_UpdateCachedAnimHashes_Patch { private static bool Prefix(Character __instance) { if ((Object)(object)__instance.m_animator == (Object)null || !__instance.m_animator.isInitialized) { return false; } return true; } } } public class AddVisualsPatch { [HarmonyPatch(typeof(MonsterAI), "Start")] public static class MonsterAI_Start_Patch { private static void Postfix(MonsterAI __instance) { MonsterModifier component = ((Component)__instance).GetComponent(); if ((Object)(object)component == (Object)null || (!component.Modifiers.Contains(MonsterModifierTypes.FireInfused) && !component.Modifiers.Contains(MonsterModifierTypes.FrostInfused) && !component.Modifiers.Contains(MonsterModifierTypes.PoisonInfused))) { return; } List modifiers = component.Modifiers; if (modifiers.Count == 0) { return; } bool flag = false; bool flag2 = false; Humanoid component2 = ((Component)__instance).GetComponent(); if ((Object)(object)component2 == (Object)null || component2.m_inventory == null) { return; } List allItems = component2.m_inventory.GetAllItems(); if (allItems == null) { return; } foreach (ItemData item in allItems) { if (!((Object)(object)item?.m_dropPrefab == (Object)null)) { if (((Object)item.m_dropPrefab).name == "skeleton_bow") { flag = true; } if (((Object)item.m_dropPrefab).name == "draugr_bow") { flag2 = true; } } } if (flag) { GameObject modifierVisual = BowVisuals.GetModifierVisual("skeleton_bow", modifiers); if ((Object)(object)modifierVisual != (Object)null) { component2.m_inventory.RemoveAll(); component2.m_inventory.AddItem(modifierVisual, 1); } } if (flag2) { GameObject modifierVisual2 = BowVisuals.GetModifierVisual("draugr_bow", modifiers); if ((Object)(object)modifierVisual2 != (Object)null) { component2.m_inventory.RemoveAll(); component2.m_inventory.AddItem(modifierVisual2, 1); } } } } } } namespace LocalizationManager { [PublicAPI] public class Localizer { private static readonly Dictionary>> PlaceholderProcessors; private static readonly Dictionary> loadedTexts; private static readonly ConditionalWeakTable localizationLanguage; private static readonly List> localizationObjects; private static BaseUnityPlugin? _plugin; private static readonly List fileExtensions; private static BaseUnityPlugin plugin { get { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown if (_plugin == null) { IEnumerable source; try { source = Assembly.GetExecutingAssembly().DefinedTypes.ToList(); } catch (ReflectionTypeLoadException ex) { source = from t in ex.Types where t != null select t.GetTypeInfo(); } _plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); } return _plugin; } } private static void UpdatePlaceholderText(Localization localization, string key) { localizationLanguage.TryGetValue(localization, out string value); string text = loadedTexts[value][key]; if (PlaceholderProcessors.TryGetValue(key, out Dictionary> value2)) { text = value2.Aggregate(text, (string current, KeyValuePair> kv) => current.Replace("{" + kv.Key + "}", kv.Value())); } localization.AddWord(key, text); } public static void AddPlaceholder(string key, string placeholder, ConfigEntry config, Func? convertConfigValue = null) where T : notnull { string key2 = key; string placeholder2 = placeholder; Func convertConfigValue2 = convertConfigValue; ConfigEntry config2 = config; if (convertConfigValue2 == null) { convertConfigValue2 = (T val) => val.ToString(); } if (!PlaceholderProcessors.ContainsKey(key2)) { PlaceholderProcessors[key2] = new Dictionary>(); } config2.SettingChanged += delegate { UpdatePlaceholder(); }; if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage())) { UpdatePlaceholder(); } void UpdatePlaceholder() { PlaceholderProcessors[key2][placeholder2] = () => convertConfigValue2(config2.Value); UpdatePlaceholderText(Localization.instance, key2); } } public static void AddText(string key, string text) { List> list = new List>(); foreach (WeakReference localizationObject in localizationObjects) { if (localizationObject.TryGetTarget(out var target)) { Dictionary dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)]; if (!target.m_translations.ContainsKey(key)) { dictionary[key] = text; target.AddWord(key, text); } } else { list.Add(localizationObject); } } foreach (WeakReference item in list) { localizationObjects.Remove(item); } } public static void Load() { LoadLocalization(Localization.instance, Localization.instance.GetSelectedLanguage()); } private static void LoadLocalization(Localization __instance, string language) { //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Expected O, but got Unknown //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Expected O, but got Unknown if (!localizationLanguage.Remove(__instance)) { localizationObjects.Add(new WeakReference(__instance)); } localizationLanguage.Add(__instance, language); Dictionary dictionary = new Dictionary(); foreach (string item in from f in Directory.GetFiles(Path.GetDirectoryName(Paths.PluginPath), plugin.Info.Metadata.Name + ".*", SearchOption.AllDirectories) where fileExtensions.IndexOf(Path.GetExtension(f)) >= 0 select f) { string text = Path.GetFileNameWithoutExtension(item).Split(new char[1] { '.' })[1]; if (dictionary.ContainsKey(text)) { Debug.LogWarning((object)("Duplicate key " + text + " found for " + plugin.Info.Metadata.Name + ". The duplicate file found at " + item + " will be skipped.")); } else { dictionary[text] = item; } } byte[] array = LoadTranslationFromAssembly("English"); if (array == null) { throw new Exception("Found no English localizations in mod " + plugin.Info.Metadata.Name + ". Expected an embedded resource translations/English.json or translations/English.yml."); } Dictionary dictionary2 = ((BuilderSkeleton)new DeserializerBuilder()).IgnoreFields().Build().Deserialize>(Encoding.UTF8.GetString(array)); if (dictionary2 == null) { throw new Exception("Localization for mod " + plugin.Info.Metadata.Name + " failed: Localization file was empty."); } string text2 = null; if (language != "English") { if (dictionary.ContainsKey(language)) { text2 = File.ReadAllText(dictionary[language]); } else { byte[] array2 = LoadTranslationFromAssembly(language); if (array2 != null) { text2 = Encoding.UTF8.GetString(array2); } } } if (text2 == null && dictionary.ContainsKey("English")) { text2 = File.ReadAllText(dictionary["English"]); } if (text2 != null) { foreach (KeyValuePair item2 in ((BuilderSkeleton)new DeserializerBuilder()).IgnoreFields().Build().Deserialize>(text2) ?? new Dictionary()) { dictionary2[item2.Key] = item2.Value; } } loadedTexts[language] = dictionary2; foreach (KeyValuePair item3 in dictionary2) { UpdatePlaceholderText(__instance, item3.Key); } } static Localizer() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown PlaceholderProcessors = new Dictionary>>(); loadedTexts = new Dictionary>(); localizationLanguage = new ConditionalWeakTable(); localizationObjects = new List>(); fileExtensions = new List { ".json", ".yml" }; Harmony val = new Harmony("org.bepinex.helpers.LocalizationManager"); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static byte[]? LoadTranslationFromAssembly(string language) { foreach (string fileExtension in fileExtensions) { byte[] array = ReadEmbeddedFileBytes("translations." + language + fileExtension); if (array != null) { return array; } } return null; } public static byte[]? ReadEmbeddedFileBytes(string resourceFileName, Assembly? containingAssembly = null) { string resourceFileName2 = resourceFileName; using MemoryStream memoryStream = new MemoryStream(); if ((object)containingAssembly == null) { containingAssembly = Assembly.GetCallingAssembly(); } string text = containingAssembly.GetManifestResourceNames().FirstOrDefault((string str) => str.EndsWith(resourceFileName2, StringComparison.Ordinal)); if (text != null) { containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream); } return (memoryStream.Length == 0L) ? null : memoryStream.ToArray(); } } }