using System;
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("warpalicious")]
[assembly: AssemblyProduct("MonsterModifiers")]
[assembly: AssemblyCopyright("Copyright © 2022")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("E0E2F92E-557C-4A05-9D89-AA92A0BD75C4")]
[assembly: AssemblyFileVersion("1.2.6")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.6.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("warpalicious.MonsterModifiers", "MonsterModifiers", "1.2.6")]
public class MonsterModifiersPlugin : BaseUnityPlugin
{
public enum Toggle
{
On = 1,
Off = 0
}
internal const string ModName = "MonsterModifiers";
internal const string ModVersion = "1.2.6";
internal const string Author = "warpalicious";
private const string ModGUID = "warpalicious.MonsterModifiers";
private static string ConfigFileName = "warpalicious.MonsterModifiers.cfg";
private static string ConfigFileFullPath;
internal static string ConnectionError;
private readonly Harmony _harmony = new Harmony("warpalicious.MonsterModifiers");
public static readonly ManualLogSource MonsterModifiersLogger;
public Texture2D tex = null;
public static ConfigEntry<int> Configurations_Monster_Modifiers;
public static ConfigEntry<int> Configurations_Boss_Modifiers;
public static ConfigEntry<int> Cfg_PierceImmunity_DamageReduction;
public static ConfigEntry<int> Cfg_SlashImmunity_DamageReduction;
public static ConfigEntry<int> Cfg_BluntImmunity_DamageReduction;
public static ConfigEntry<int> Cfg_ElementalImmunity_DamageReduction;
public static ConfigEntry<int> Cfg_Knockback_StaggerForce;
public static ConfigEntry<int> Cfg_Knockback_PushForce;
public static ConfigEntry<float> Cfg_FastAttackSpeed_AnimatorMultiplier;
public static ConfigEntry<float> Cfg_FastAttackSpeed_IntervalReduction;
public static ConfigEntry<float> Cfg_SplitSpawn_Scale;
public static ConfigEntry<Toggle> Cfg_SplitSpawn_RandomizeWeapon;
public static ConfigEntry<float> Cfg_ShieldBreaker_DurabilityThreshold;
public static ConfigEntry<float> Cfg_ShieldBreaker_DurabilityReduction;
public static ConfigEntry<float> Cfg_IgnoreArmor_ArmorReduction;
public static ConfigEntry<float> Cfg_FoodDrain_DurationReduction;
public static ConfigEntry<float> Cfg_ElementalInfusion_DamageRatio;
public static ConfigEntry<float> Cfg_Forceful_PushMultiplier;
public static ConfigEntry<float> Cfg_Vampiric_HealRatio;
public static ConfigEntry<int> Cfg_PersonalShield_Duration;
public static ConfigEntry<float> Cfg_PersonalShield_Magnitude;
public static ConfigEntry<float> Cfg_FastMovement_SpeedMultiplier;
public static ConfigEntry<float> Cfg_DistantDetection_RangeMultiplier;
public static ConfigEntry<float> Cfg_SoulEater_Radius;
public static ConfigEntry<int> Cfg_SoulEater_MaxStacks;
public static ConfigEntry<float> Cfg_SoulEater_GrowthMultiplier;
public static ConfigEntry<float> Cfg_SoulEater_DmgStack1;
public static ConfigEntry<float> Cfg_SoulEater_DmgStack2;
public static ConfigEntry<float> Cfg_SoulEater_DmgStack3;
public static ConfigEntry<int> Cfg_ResistanceNotification_MaxCount;
public static ConfigEntry<int> Cfg_Category_Offense_Weight;
public static ConfigEntry<int> Cfg_Category_Defense_Weight;
public static ConfigEntry<int> Cfg_Category_Utility_Weight;
public static ConfigEntry<int> Cfg_Category_SplitSpawn_Weight;
public void Awake()
{
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Expected O, but got Unknown
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Expected O, but got Unknown
//IL_0116: Unknown result type (might be due to invalid IL or missing references)
//IL_0120: Expected O, but got Unknown
//IL_0149: Unknown result type (might be due to invalid IL or missing references)
//IL_0153: Expected O, but got Unknown
//IL_017c: Unknown result type (might be due to invalid IL or missing references)
//IL_0186: Expected O, but got Unknown
//IL_01af: Unknown result type (might be due to invalid IL or missing references)
//IL_01b9: Expected O, but got Unknown
//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
//IL_01ec: Expected O, but got Unknown
//IL_0215: Unknown result type (might be due to invalid IL or missing references)
//IL_021f: Expected O, but got Unknown
//IL_0248: Unknown result type (might be due to invalid IL or missing references)
//IL_0252: Expected O, but got Unknown
//IL_027b: Unknown result type (might be due to invalid IL or missing references)
//IL_0285: Expected O, but got Unknown
//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
//IL_02be: Expected O, but got Unknown
//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
//IL_02f4: Expected O, but got Unknown
//IL_0327: Unknown result type (might be due to invalid IL or missing references)
//IL_0331: Expected O, but got Unknown
//IL_0364: Unknown result type (might be due to invalid IL or missing references)
//IL_036e: Expected O, but got Unknown
//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
//IL_03ab: Expected O, but got Unknown
//IL_040c: Unknown result type (might be due to invalid IL or missing references)
//IL_0416: Expected O, but got Unknown
//IL_0449: Unknown result type (might be due to invalid IL or missing references)
//IL_0453: Expected O, but got Unknown
//IL_0486: Unknown result type (might be due to invalid IL or missing references)
//IL_0490: Expected O, but got Unknown
//IL_04c3: Unknown result type (might be due to invalid IL or missing references)
//IL_04cd: Expected O, but got Unknown
//IL_0500: Unknown result type (might be due to invalid IL or missing references)
//IL_050a: Expected O, but got Unknown
//IL_053d: Unknown result type (might be due to invalid IL or missing references)
//IL_0547: Expected O, but got Unknown
//IL_057a: Unknown result type (might be due to invalid IL or missing references)
//IL_0584: Expected O, but got Unknown
//IL_05ad: Unknown result type (might be due to invalid IL or missing references)
//IL_05b7: Expected O, but got Unknown
//IL_05ea: Unknown result type (might be due to invalid IL or missing references)
//IL_05f4: Expected O, but got Unknown
//IL_0627: Unknown result type (might be due to invalid IL or missing references)
//IL_0631: Expected O, but got Unknown
//IL_0664: Unknown result type (might be due to invalid IL or missing references)
//IL_066e: Expected O, but got Unknown
//IL_06a1: Unknown result type (might be due to invalid IL or missing references)
//IL_06ab: Expected O, but got Unknown
//IL_06d3: Unknown result type (might be due to invalid IL or missing references)
//IL_06dd: Expected O, but got Unknown
//IL_0710: Unknown result type (might be due to invalid IL or missing references)
//IL_071a: Expected O, but got Unknown
//IL_074d: Unknown result type (might be due to invalid IL or missing references)
//IL_0757: Expected O, but got Unknown
//IL_078a: Unknown result type (might be due to invalid IL or missing references)
//IL_0794: Expected O, but got Unknown
//IL_07c7: Unknown result type (might be due to invalid IL or missing references)
//IL_07d1: Expected O, but got Unknown
//IL_07f9: Unknown result type (might be due to invalid IL or missing references)
//IL_0803: Expected O, but got Unknown
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;
Configurations_Monster_Modifiers = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Monster_Modifiers", 5, new ConfigDescription("Maximum modifiers for regular monsters. 0 = disabled.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, length), Array.Empty<object>()));
Configurations_Boss_Modifiers = ((BaseUnityPlugin)this).Config.Bind<int>("General", "boss_Modifiers", 5, new ConfigDescription("Minimum modifiers for bosses (0 = disabled). Max is auto-calculated excluding death-spawn modifiers. N = always assign at least N modifiers.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, num), Array.Empty<object>()));
Cfg_Category_Offense_Weight = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Category_Offense_Weight", 35, new ConfigDescription("Relative roll weight for Offense modifiers (default 35/35/15/15, values are treated as ratio).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
Cfg_Category_Defense_Weight = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Category_Defense_Weight", 35, new ConfigDescription("Relative roll weight for Defense modifiers.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
Cfg_Category_Utility_Weight = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Category_Utility_Weight", 15, new ConfigDescription("Relative roll weight for Utility modifiers.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
Cfg_Category_SplitSpawn_Weight = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Category_SplitSpawn_Weight", 15, new ConfigDescription("Relative roll weight for SplitSpawn modifier (boss-excluded). Set 0 to disable SplitSpawn from rolling.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
Cfg_PierceImmunity_DamageReduction = ((BaseUnityPlugin)this).Config.Bind<int>("Modifier_Defense", "PierceImmunity Damage Reduction %", 70, new ConfigDescription("Percentage of pierce damage reduced when PierceImmunity modifier is active. 100 = full immunity.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
Cfg_SlashImmunity_DamageReduction = ((BaseUnityPlugin)this).Config.Bind<int>("Modifier_Defense", "SlashImmunity Damage Reduction %", 70, new ConfigDescription("Percentage of slash damage reduced when SlashImmunity modifier is active. 100 = full immunity.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
Cfg_BluntImmunity_DamageReduction = ((BaseUnityPlugin)this).Config.Bind<int>("Modifier_Defense", "BluntImmunity Damage Reduction %", 70, new ConfigDescription("Percentage of blunt damage reduced when BluntImmunity modifier is active. 100 = full immunity.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
Cfg_ElementalImmunity_DamageReduction = ((BaseUnityPlugin)this).Config.Bind<int>("Modifier_Defense", "ElementalImmunity Damage Reduction %", 70, new ConfigDescription("Percentage of elemental damage (fire/frost/lightning/poison/spirit) reduced when ElementalImmunity modifier is active. 100 = full immunity.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
Cfg_Knockback_StaggerForce = ((BaseUnityPlugin)this).Config.Bind<int>("Modifier_Offense", "Knockback Stagger Force", 500, new ConfigDescription("Stagger force applied by the Knockback modifier.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2000), Array.Empty<object>()));
Cfg_Knockback_PushForce = ((BaseUnityPlugin)this).Config.Bind<int>("Modifier_Offense", "Knockback Push Force", 45, new ConfigDescription("Push force applied by the Knockback modifier.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 200), Array.Empty<object>()));
Cfg_FastAttackSpeed_AnimatorMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Modifier_Offense", "FastAttackSpeed Animator Speed Multiplier", 0.3f, new ConfigDescription("Animator speed bonus for FastAttackSpeed modifier (0.3 = +30% faster animation). Default: 0.3", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
Cfg_FastAttackSpeed_IntervalReduction = ((BaseUnityPlugin)this).Config.Bind<float>("Modifier_Offense", "FastAttackSpeed Attack Interval Reduction", 0.3f, new ConfigDescription("Attack cooldown reduction fraction for FastAttackSpeed modifier (0.3 = -30% cooldown). Default: 0.3", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.95f), Array.Empty<object>()));
Cfg_SplitSpawn_Scale = ((BaseUnityPlugin)this).Config.Bind<float>("Modifier_Offense", "SplitSpawn Scale", 0.7f, new ConfigDescription("Size of SplitSpawn children relative to parent size (0.7 = 70%).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f), Array.Empty<object>()));
Cfg_SplitSpawn_RandomizeWeapon = ConfigFileExtensions.BindConfig<Toggle>(((BaseUnityPlugin)this).Config, "Modifier_Offense", "SplitSpawn Randomize Weapon", Toggle.On, "When On, bow-wielding creatures may spawn melee-variant children instead of archer copies.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
Cfg_ShieldBreaker_DurabilityThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("Modifier_Offense", "ShieldBreaker Durability Threshold", 0.1f, new ConfigDescription("Shield durability fraction below which reduction is skipped (0.1 = skip if below 10%).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 0.5f), Array.Empty<object>()));
Cfg_ShieldBreaker_DurabilityReduction = ((BaseUnityPlugin)this).Config.Bind<float>("Modifier_Offense", "ShieldBreaker Durability Reduction", 0.5f, new ConfigDescription("Multiplier applied to shield durability on block (0.5 = halved).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
Cfg_IgnoreArmor_ArmorReduction = ((BaseUnityPlugin)this).Config.Bind<float>("Modifier_Offense", "IgnoreArmor Armor Reduction", 0.5f, new ConfigDescription("Multiplier applied to player armor value (0.5 = armor halved).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
Cfg_FoodDrain_DurationReduction = ((BaseUnityPlugin)this).Config.Bind<float>("Modifier_Offense", "FoodDrain Duration Reduction", 0.5f, new ConfigDescription("Multiplier applied to food duration on hit (0.5 = halved).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
Cfg_ElementalInfusion_DamageRatio = ((BaseUnityPlugin)this).Config.Bind<float>("Modifier_Offense", "ElementalInfusion Damage Ratio", 0.5f, new ConfigDescription("Ratio of total hit damage added as elemental bonus (0.5 = +50% as element).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
Cfg_Forceful_PushMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Modifier_Offense", "Forceful Push Multiplier", 5f, new ConfigDescription("Multiplier applied to hit push force (5.0 = 5x knockback).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f), Array.Empty<object>()));
Cfg_Vampiric_HealRatio = ((BaseUnityPlugin)this).Config.Bind<float>("Modifier_Offense", "Vampiric Heal Ratio", 0.5f, new ConfigDescription("Ratio of total hit damage healed by the attacker (0.5 = heal 50% of damage).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
Cfg_PersonalShield_Duration = ((BaseUnityPlugin)this).Config.Bind<int>("Modifier_Defense", "PersonalShield Duration", 10, new ConfigDescription("Duration (seconds) of the GoblinShaman shield status effect.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 60), Array.Empty<object>()));
Cfg_PersonalShield_Magnitude = ((BaseUnityPlugin)this).Config.Bind<float>("Modifier_Defense", "PersonalShield Magnitude", 2f, new ConfigDescription("Magnitude of the GoblinShaman shield status effect.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 10f), Array.Empty<object>()));
Cfg_FastMovement_SpeedMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Modifier_Utility", "FastMovement Speed Multiplier", 1.5f, new ConfigDescription("Speed multiplier applied to m_speed/m_runSpeed/m_walkSpeed (1.5 = +50%).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), Array.Empty<object>()));
Cfg_DistantDetection_RangeMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Modifier_Utility", "DistantDetection Range Multiplier", 2f, new ConfigDescription("Multiplier applied to hear and view range (2.0 = double range).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>()));
Cfg_SoulEater_Radius = ((BaseUnityPlugin)this).Config.Bind<float>("Modifier_Utility", "SoulEater Absorb Radius", 5f, new ConfigDescription("Radius (units) in which SoulEater detects dying enemies.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f), Array.Empty<object>()));
Cfg_SoulEater_MaxStacks = ((BaseUnityPlugin)this).Config.Bind<int>("Modifier_Utility", "SoulEater Max Stacks", 3, new ConfigDescription("Maximum number of soul stacks the SoulEater can accumulate.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), Array.Empty<object>()));
Cfg_SoulEater_GrowthMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Modifier_Utility", "SoulEater Growth Multiplier", 1.1f, new ConfigDescription("Size and health growth multiplier per stack (1.1 = +10% per soul).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 2f), Array.Empty<object>()));
Cfg_SoulEater_DmgStack1 = ((BaseUnityPlugin)this).Config.Bind<float>("Modifier_Utility", "SoulEater Damage Stack 1", 1.1f, new ConfigDescription("Damage multiplier at 1 soul stack.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 3f), Array.Empty<object>()));
Cfg_SoulEater_DmgStack2 = ((BaseUnityPlugin)this).Config.Bind<float>("Modifier_Utility", "SoulEater Damage Stack 2", 1.2f, new ConfigDescription("Damage multiplier at 2 soul stacks.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 3f), Array.Empty<object>()));
Cfg_SoulEater_DmgStack3 = ((BaseUnityPlugin)this).Config.Bind<float>("Modifier_Utility", "SoulEater Damage Stack 3", 1.3f, new ConfigDescription("Damage multiplier at 3 soul stacks.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 3f), Array.Empty<object>()));
Cfg_ResistanceNotification_MaxCount = ((BaseUnityPlugin)this).Config.Bind<int>("Modifier_Utility", "ResistanceNotification Max Count", 2, new ConfigDescription("Max times to show a resistance notification per damage type per enemy.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), Array.Empty<object>()));
ShaderLogFilter.Install();
CompatibilityUtils.RunCompatibiltyChecks();
StatusEffectUtils.CreateCustomStatusEffects();
PrefabManager.OnVanillaPrefabsAvailable += PrefabUtils.CreateCustomPrefabs;
}
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");
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_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_Category_Offense_Weight = null;
Cfg_Category_Defense_Weight = null;
Cfg_Category_Utility_Weight = null;
Cfg_Category_SplitSpawn_Weight = null;
}
}
public static class KeyboardExtensions
{
public static bool IsKeyDown(this KeyboardShortcut shortcut)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
return (int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && Input.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey) && ((KeyboardShortcut)(ref shortcut)).Modifiers.All((Func<KeyCode, bool>)Input.GetKey);
}
public static bool IsKeyHeld(this KeyboardShortcut shortcut)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
return (int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && Input.GetKey(((KeyboardShortcut)(ref shortcut)).MainKey) && ((KeyboardShortcut)(ref shortcut)).Modifiers.All((Func<KeyCode, bool>)Input.GetKey);
}
}
public class CompatibilityUtils
{
public static bool isStarLevelsExpandedInstalled;
public static void RunCompatibiltyChecks()
{
if (Chainloader.PluginInfos.ContainsKey("CreatureLevelControl"))
{
MonsterModifiersPlugin.MonsterModifiersLogger.LogWarning((object)"CreatureLevelandLootControl plugin is installed. Please ensure special effects and infusions are disabled in CLLC configuration.");
}
if (Chainloader.PluginInfos.ContainsKey("MidnightsFX.StarLevelSystem"))
{
MonsterModifiersPlugin.MonsterModifiersLogger.LogWarning((object)"StarLevelSystem plugin is installed. Please ensure max modifiers config is set.");
isStarLevelsExpandedInstalled = true;
}
}
}
public class DamageUtils
{
public static float TryCurrentWeapon(Humanoid humanoid)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
ItemData currentWeapon = humanoid.GetCurrentWeapon();
if (currentWeapon == null)
{
return 10f;
}
DamageTypes damage = currentWeapon.GetDamage();
if (((DamageTypes)(ref damage)).HaveDamage())
{
return 10f;
}
float totalDamage = ((DamageTypes)(ref damage)).GetTotalDamage();
if (totalDamage == 0f)
{
return 10f;
}
DamageTypes damage2 = humanoid.GetCurrentWeapon().GetDamage();
return ((DamageTypes)(ref damage2)).GetTotalDamage();
}
public static float TryWeaponList(GameObject[] weaponArray)
{
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
float num = 10f;
List<GameObject> list = weaponArray.ToList();
if (list.Count > 0)
{
foreach (GameObject item in list)
{
ItemData itemData = item.GetComponent<ItemDrop>().m_itemData;
if (itemData != null)
{
DamageTypes damage = itemData.GetDamage();
float totalDamage = ((DamageTypes)(ref damage)).GetTotalDamage();
if (totalDamage > num)
{
num = totalDamage;
}
}
}
}
if (num > 0f)
{
}
return num;
}
public static float CalculateDamage(Character character, float percentTotal)
{
Humanoid val = (Humanoid)(object)((character is Humanoid) ? character : null);
if ((Object)(object)val == (Object)null)
{
return 10f;
}
if (character.IsPlayer())
{
return 10f;
}
float num = 10f;
float num2 = TryCurrentWeapon(val);
if (num2 > 0f && num2 > num)
{
num = num2;
}
float num3 = TryWeaponList(val.m_defaultItems);
if (num3 > 0f && num3 > num)
{
num = num3;
}
float num4 = TryWeaponList(val.m_randomWeapon);
if (num4 > 0f && num4 > num)
{
num = num4;
}
return num * percentTotal;
}
}
public class ModifierAssetUtils
{
public static AssetBundle ashlandsAssetBundle;
public static AssetBundle statusEffectBundle;
public static AssetBundle modiferIconsBundle;
public static Sprite swordIcon;
public static Sprite shieldIcon;
public static Sprite plusSquareIcon;
public static Sprite circleIcon;
public static Sprite soulIcon;
public static Sprite skullIcon;
public static Sprite appleIcon;
public static Sprite shieldBrokenIcon;
public static Sprite shieldSpearIcon;
public static Sprite shieldMaceIcon;
public static Sprite shieldSwordIcon;
public static Sprite potionIcon;
public static Sprite bloodIcon;
public static Sprite bloodIconRed;
public static Sprite heartIcon;
public static Sprite earIcon;
public static void Setup()
{
statusEffectBundle = AssetUtils.LoadAssetBundleFromResources("statusicon", Assembly.GetExecutingAssembly());
modiferIconsBundle = AssetUtils.LoadAssetBundleFromResources("modifiericons", Assembly.GetExecutingAssembly());
}
public static void LoadAllIcons()
{
swordIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/Sword.png");
shieldIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/Shield.png");
plusSquareIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/PlusBox.png");
circleIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/Circle.png");
soulIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/SoulEater.png");
skullIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/Skull.png");
appleIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/Apple.png");
shieldBrokenIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/ShieldBroken.png");
shieldSpearIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/ShieldSpear.png");
shieldMaceIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/ShieldMace.png");
shieldSwordIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/ShieldSword.png");
potionIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/Potion.png");
heartIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/heartIcon.png");
bloodIcon = statusEffectBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/bloodIcon.png");
bloodIconRed = statusEffectBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/bloodIconRed.png");
earIcon = modiferIconsBundle.LoadAsset<Sprite>("Assets/WarpProjects/Modifiers/NewModifierIcons/Ear.png");
}
}
public enum MonsterModifierTypes
{
StaminaSiphon,
EitrSiphon,
ShieldBreaker,
FoodDrain,
IgnoreArmor,
PoisonDeath,
FrostDeath,
FireDeath,
HealDeath,
StaggerDeath,
TarDeath,
PersonalShield,
ShieldDome,
SoulEater,
RemoveStatusEffect,
StaggerImmune,
FireInfused,
PoisonInfused,
FrostInfused,
LightningInfused,
ElementalImmunity,
PierceImmunity,
BluntImmunity,
SlashImmunity,
FastMovement,
FastAttackSpeed,
DistantDetection,
BloodLoss,
Absorption,
Vampiric,
Forceful,
Wet,
Quiet,
Knockback,
ArmorCharge,
FireTrail,
ResistanceNotification,
SplitSpawn
}
public enum ModifierCategory
{
Offense,
Defense,
Utility,
SplitSpawn
}
public class ModifierData
{
public int weight { get; set; }
public List<float> color { get; set; }
}
public class ModifierUtils
{
public static Dictionary<MonsterModifierTypes, ModifierData> modifiers;
public static readonly Dictionary<MonsterModifierTypes, ModifierCategory> ModifierCategories = new Dictionary<MonsterModifierTypes, ModifierCategory>
{
{
MonsterModifierTypes.StaminaSiphon,
ModifierCategory.Offense
},
{
MonsterModifierTypes.EitrSiphon,
ModifierCategory.Offense
},
{
MonsterModifierTypes.ShieldBreaker,
ModifierCategory.Offense
},
{
MonsterModifierTypes.FoodDrain,
ModifierCategory.Offense
},
{
MonsterModifierTypes.IgnoreArmor,
ModifierCategory.Offense
},
{
MonsterModifierTypes.PoisonDeath,
ModifierCategory.Offense
},
{
MonsterModifierTypes.FrostDeath,
ModifierCategory.Offense
},
{
MonsterModifierTypes.FireDeath,
ModifierCategory.Offense
},
{
MonsterModifierTypes.StaggerDeath,
ModifierCategory.Offense
},
{
MonsterModifierTypes.TarDeath,
ModifierCategory.Offense
},
{
MonsterModifierTypes.FireInfused,
ModifierCategory.Offense
},
{
MonsterModifierTypes.PoisonInfused,
ModifierCategory.Offense
},
{
MonsterModifierTypes.FrostInfused,
ModifierCategory.Offense
},
{
MonsterModifierTypes.LightningInfused,
ModifierCategory.Offense
},
{
MonsterModifierTypes.FastAttackSpeed,
ModifierCategory.Offense
},
{
MonsterModifierTypes.BloodLoss,
ModifierCategory.Offense
},
{
MonsterModifierTypes.Vampiric,
ModifierCategory.Offense
},
{
MonsterModifierTypes.Forceful,
ModifierCategory.Offense
},
{
MonsterModifierTypes.Wet,
ModifierCategory.Offense
},
{
MonsterModifierTypes.Knockback,
ModifierCategory.Offense
},
{
MonsterModifierTypes.RemoveStatusEffect,
ModifierCategory.Offense
},
{
MonsterModifierTypes.PersonalShield,
ModifierCategory.Defense
},
{
MonsterModifierTypes.ShieldDome,
ModifierCategory.Defense
},
{
MonsterModifierTypes.ElementalImmunity,
ModifierCategory.Defense
},
{
MonsterModifierTypes.PierceImmunity,
ModifierCategory.Defense
},
{
MonsterModifierTypes.BluntImmunity,
ModifierCategory.Defense
},
{
MonsterModifierTypes.SlashImmunity,
ModifierCategory.Defense
},
{
MonsterModifierTypes.StaggerImmune,
ModifierCategory.Defense
},
{
MonsterModifierTypes.Absorption,
ModifierCategory.Defense
},
{
MonsterModifierTypes.FastMovement,
ModifierCategory.Utility
},
{
MonsterModifierTypes.DistantDetection,
ModifierCategory.Utility
},
{
MonsterModifierTypes.SoulEater,
ModifierCategory.Utility
},
{
MonsterModifierTypes.HealDeath,
ModifierCategory.Utility
},
{
MonsterModifierTypes.Quiet,
ModifierCategory.Utility
},
{
MonsterModifierTypes.ResistanceNotification,
ModifierCategory.Utility
},
{
MonsterModifierTypes.ArmorCharge,
ModifierCategory.Utility
},
{
MonsterModifierTypes.FireTrail,
ModifierCategory.Utility
},
{
MonsterModifierTypes.SplitSpawn,
ModifierCategory.SplitSpawn
}
};
public static readonly HashSet<MonsterModifierTypes> BossExcludedModifiers = new HashSet<MonsterModifierTypes>
{
MonsterModifierTypes.PoisonDeath,
MonsterModifierTypes.FireDeath,
MonsterModifierTypes.FrostDeath,
MonsterModifierTypes.StaggerDeath,
MonsterModifierTypes.HealDeath,
MonsterModifierTypes.TarDeath,
MonsterModifierTypes.SplitSpawn
};
public static Color GetModifierColor(MonsterModifierTypes modifier)
{
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
List<float> color = modifiers[modifier].color;
Color result = default(Color);
((Color)(ref result))..ctor(color[0], color[1], color[2], color[3]);
return result;
}
public static Sprite GetModifierIcon(MonsterModifierTypes modifier)
{
if (modifier == MonsterModifierTypes.FireInfused || modifier == MonsterModifierTypes.FrostInfused || modifier == MonsterModifierTypes.PoisonInfused || modifier == MonsterModifierTypes.LightningInfused || modifier == MonsterModifierTypes.RemoveStatusEffect)
{
return ModifierAssetUtils.swordIcon;
}
if (modifier == MonsterModifierTypes.ShieldBreaker || modifier == MonsterModifierTypes.IgnoreArmor)
{
return ModifierAssetUtils.shieldBrokenIcon;
}
if (modifier == MonsterModifierTypes.StaminaSiphon || modifier == MonsterModifierTypes.EitrSiphon)
{
return ModifierAssetUtils.potionIcon;
}
switch (modifier)
{
case MonsterModifierTypes.FoodDrain:
return ModifierAssetUtils.appleIcon;
default:
if (modifier != MonsterModifierTypes.TarDeath)
{
if (modifier == MonsterModifierTypes.ElementalImmunity || modifier == MonsterModifierTypes.StaggerImmune)
{
return ModifierAssetUtils.shieldIcon;
}
if (modifier == MonsterModifierTypes.PersonalShield || modifier == MonsterModifierTypes.ShieldDome)
{
return ModifierAssetUtils.circleIcon;
}
switch (modifier)
{
case MonsterModifierTypes.SoulEater:
return ModifierAssetUtils.soulIcon;
case MonsterModifierTypes.PierceImmunity:
return ModifierAssetUtils.shieldSpearIcon;
case MonsterModifierTypes.SlashImmunity:
return ModifierAssetUtils.shieldSwordIcon;
case MonsterModifierTypes.BluntImmunity:
return ModifierAssetUtils.shieldMaceIcon;
default:
if (modifier != MonsterModifierTypes.Forceful)
{
if (modifier == MonsterModifierTypes.BloodLoss || modifier == MonsterModifierTypes.Wet)
{
return ModifierAssetUtils.bloodIcon;
}
if (modifier == MonsterModifierTypes.Absorption || modifier == MonsterModifierTypes.Vampiric)
{
return ModifierAssetUtils.heartIcon;
}
switch (modifier)
{
case MonsterModifierTypes.Quiet:
return ModifierAssetUtils.earIcon;
default:
if (modifier != MonsterModifierTypes.FireTrail)
{
switch (modifier)
{
case MonsterModifierTypes.ResistanceNotification:
return ModifierAssetUtils.potionIcon;
case MonsterModifierTypes.SplitSpawn:
return ModifierAssetUtils.skullIcon;
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 int GetModifierWeight(MonsterModifierTypes modifier)
{
return modifiers[modifier].weight;
}
public static int GetAvailableModifierCount(HashSet<MonsterModifierTypes> excluded = null)
{
int num = 0;
foreach (KeyValuePair<MonsterModifierTypes, ModifierData> modifier in modifiers)
{
if (modifier.Value.weight > 0 && (excluded == null || !excluded.Contains(modifier.Key)))
{
num++;
}
}
return num;
}
public static List<MonsterModifierTypes> RollRandomModifiers(int numModifiers, HashSet<MonsterModifierTypes> excluded = null)
{
List<MonsterModifierTypes> list = new List<MonsterModifierTypes>();
Dictionary<MonsterModifierTypes, ModifierData> dictionary = new Dictionary<MonsterModifierTypes, ModifierData>(modifiers);
if (excluded != null)
{
foreach (MonsterModifierTypes item in excluded)
{
dictionary.Remove(item);
}
}
for (int i = 0; i < numModifiers; i++)
{
if (dictionary.Count == 0)
{
break;
}
Dictionary<ModifierCategory, List<MonsterModifierTypes>> dictionary2 = new Dictionary<ModifierCategory, List<MonsterModifierTypes>>();
foreach (KeyValuePair<MonsterModifierTypes, ModifierData> item2 in dictionary)
{
if (item2.Value.weight > 0)
{
ModifierCategory value;
ModifierCategory key = (ModifierCategories.TryGetValue(item2.Key, out value) ? value : ModifierCategory.Utility);
if (!dictionary2.ContainsKey(key))
{
dictionary2[key] = new List<MonsterModifierTypes>();
}
dictionary2[key].Add(item2.Key);
}
}
int num = (dictionary2.ContainsKey(ModifierCategory.Offense) ? MonsterModifiersPlugin.Cfg_Category_Offense_Weight.Value : 0);
int num2 = (dictionary2.ContainsKey(ModifierCategory.Defense) ? MonsterModifiersPlugin.Cfg_Category_Defense_Weight.Value : 0);
int num3 = (dictionary2.ContainsKey(ModifierCategory.Utility) ? MonsterModifiersPlugin.Cfg_Category_Utility_Weight.Value : 0);
int num4 = (dictionary2.ContainsKey(ModifierCategory.SplitSpawn) ? MonsterModifiersPlugin.Cfg_Category_SplitSpawn_Weight.Value : 0);
int num5 = num + num2 + num3 + num4;
MonsterModifierTypes monsterModifierTypes;
if (num5 <= 0)
{
int num6 = 0;
foreach (ModifierData value2 in dictionary.Values)
{
num6 += value2.weight;
}
if (num6 <= 0)
{
break;
}
int num7 = Random.Range(0, num6);
int num8 = 0;
monsterModifierTypes = MonsterModifierTypes.StaminaSiphon;
foreach (KeyValuePair<MonsterModifierTypes, ModifierData> item3 in dictionary)
{
num8 += item3.Value.weight;
if (num7 < num8)
{
monsterModifierTypes = item3.Key;
break;
}
}
}
else
{
int num9 = Random.Range(0, num5);
ModifierCategory key2 = ((num9 >= num) ? ((num9 < num + num2) ? ModifierCategory.Defense : ((num9 >= num + num2 + num3) ? ModifierCategory.SplitSpawn : ModifierCategory.Utility)) : ModifierCategory.Offense);
List<MonsterModifierTypes> list2 = dictionary2[key2];
monsterModifierTypes = list2[Random.Range(0, list2.Count)];
}
list.Add(monsterModifierTypes);
dictionary.Remove(monsterModifierTypes);
}
return list;
}
public static void RunBiomeChecks()
{
}
public static bool RunRPCDamageChecks(Character character, HitData hit)
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Invalid comparison between Unknown and I4
if (hit == null || (Object)(object)character == (Object)null)
{
return false;
}
if (((DamageTypes)(ref hit.m_damage)).GetTotalDamage() == 0f)
{
return false;
}
if ((int)hit.m_hitType != 1)
{
return false;
}
return true;
}
public static bool RunRPCDamageChecks(Character character, HitData hit, bool isMonsterAttackingPlayer)
{
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Invalid comparison between Unknown and I4
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Invalid comparison between Unknown and I4
if (hit == null || (Object)(object)character == (Object)null)
{
Debug.Log((object)"Hit or character is null");
return true;
}
if (((DamageTypes)(ref hit.m_damage)).GetTotalDamage() == 0f)
{
Debug.Log((object)"Total damage is 0");
return true;
}
if (isMonsterAttackingPlayer)
{
if ((int)hit.m_hitType != 1)
{
Debug.Log((object)"hit type is not enemy hit");
return true;
}
}
else if ((int)hit.m_hitType != 2)
{
Debug.Log((object)"hit type is not player hit");
return true;
}
return true;
}
public static bool RunHitChecks(HitData hit, bool isMonsterAttackingPlayer)
{
Character attacker = hit.GetAttacker();
if ((Object)(object)attacker == (Object)null)
{
return false;
}
if (isMonsterAttackingPlayer && attacker.IsPlayer())
{
return false;
}
if (!isMonsterAttackingPlayer && attacker.IsPlayer())
{
return true;
}
return true;
}
}
public class PrefabUtils
{
public static GameObject leechDeathVFX;
public static GameObject leechDeathSFX;
public static void CreateCustomPrefabs()
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Expected O, but got Unknown
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Expected O, but got Unknown
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_0107: Expected O, but got Unknown
//IL_012b: Unknown result type (might be due to invalid IL or missing references)
//IL_0130: Unknown result type (might be due to invalid IL or missing references)
//IL_0139: Unknown result type (might be due to invalid IL or missing references)
//IL_014b: Unknown result type (might be due to invalid IL or missing references)
//IL_015d: Unknown result type (might be due to invalid IL or missing references)
//IL_018f: Unknown result type (might be due to invalid IL or missing references)
//IL_0196: Expected O, but got Unknown
//IL_01df: Unknown result type (might be due to invalid IL or missing references)
//IL_01e6: Expected O, but got Unknown
//IL_022f: Unknown result type (might be due to invalid IL or missing references)
//IL_0236: Expected O, but got Unknown
//IL_0290: Unknown result type (might be due to invalid IL or missing references)
//IL_0297: Expected O, but got Unknown
//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
//IL_02e7: Expected O, but got Unknown
//IL_0330: Unknown result type (might be due to invalid IL or missing references)
//IL_0337: Expected O, but got Unknown
GameObject prefab = PrefabManager.Instance.GetPrefab("shaman_heal_aoe");
GameObject val = PrefabManager.Instance.CreateClonedPrefab("healCustomPrefab", prefab);
CustomPrefab val2 = new CustomPrefab(val, false);
Aoe component = val2.Prefab.GetComponent<Aoe>();
component.m_statusEffect = "";
GameObject prefab2 = PrefabManager.Instance.GetPrefab("Mistile");
GameObject val3 = PrefabManager.Instance.CreateClonedPrefab("mistleCustomPrefab", prefab2);
CustomPrefab val4 = new CustomPrefab(val3, false);
Character component2 = (Character)(object)val4.Prefab.GetComponent<Humanoid>();
component2.m_speed = 0f;
component2.m_flyFastSpeed = 0f;
component2.m_flySlowSpeed = 0f;
component2.m_name = "$modifier_mistile";
val4.Prefab.GetComponent<CharacterTimedDestruction>().m_timeoutMin = 2f;
val4.Prefab.GetComponent<CharacterTimedDestruction>().m_timeoutMax = 4f;
GameObject prefab3 = PrefabManager.Instance.GetPrefab("fx_DvergerMage_Mistile_attack");
GameObject val5 = PrefabManager.Instance.CreateClonedPrefab("staggerDeathNovaCustomPrefab", prefab3);
CustomPrefab val6 = new CustomPrefab(val5, false);
GameObject gameObject = ((Component)ExposedGameObjectExtension.FindDeepChild(val6.Prefab, "shockwave (1)", (IterativeSearchType)1)).gameObject;
ParticleSystem component3 = gameObject.GetComponent<ParticleSystem>();
MainModule main = component3.main;
((MainModule)(ref main)).startRotationX = new MinMaxCurve((float)Math.PI / 2f);
((MainModule)(ref main)).startRotationY = new MinMaxCurve(0f);
((MainModule)(ref main)).startRotationZ = new MinMaxCurve(0f);
GameObject prefab4 = PrefabManager.Instance.GetPrefab("skeleton_bow");
GameObject val7 = PrefabManager.Instance.CreateClonedPrefab("skeletonBowCustomPrefab_Fire", prefab4);
CustomItem val8 = new CustomItem(val7, false);
ItemData itemData = val8.ItemPrefab.GetComponent<ItemDrop>().m_itemData;
itemData.m_shared.m_attack.m_attackProjectile = PrefabManager.Instance.GetPrefab("bow_projectile_fire");
GameObject val9 = PrefabManager.Instance.CreateClonedPrefab("skeletonBowCustomPrefab_Frost", prefab4);
CustomItem val10 = new CustomItem(val9, false);
ItemData itemData2 = val10.ItemPrefab.GetComponent<ItemDrop>().m_itemData;
itemData2.m_shared.m_attack.m_attackProjectile = PrefabManager.Instance.GetPrefab("bow_projectile_frost");
GameObject val11 = PrefabManager.Instance.CreateClonedPrefab("skeletonBowCustomPrefab_Poison", prefab4);
CustomItem val12 = new CustomItem(val11, false);
ItemData itemData3 = val12.ItemPrefab.GetComponent<ItemDrop>().m_itemData;
itemData3.m_shared.m_attack.m_attackProjectile = PrefabManager.Instance.GetPrefab("bow_projectile_poison");
GameObject prefab5 = PrefabManager.Instance.GetPrefab("draugr_bow");
GameObject val13 = PrefabManager.Instance.CreateClonedPrefab("draugrBowCustomPrefab_Fire", prefab5);
CustomItem val14 = new CustomItem(val13, false);
ItemData itemData4 = val14.ItemPrefab.GetComponent<ItemDrop>().m_itemData;
itemData4.m_shared.m_attack.m_attackProjectile = PrefabManager.Instance.GetPrefab("bow_projectile_fire");
GameObject val15 = PrefabManager.Instance.CreateClonedPrefab("draugrBowCustomPrefab_Frost", prefab5);
CustomItem val16 = new CustomItem(val15, false);
ItemData itemData5 = val16.ItemPrefab.GetComponent<ItemDrop>().m_itemData;
itemData5.m_shared.m_attack.m_attackProjectile = PrefabManager.Instance.GetPrefab("bow_projectile_frost");
GameObject val17 = PrefabManager.Instance.CreateClonedPrefab("draugrBowCustomPrefab_Poison", prefab5);
CustomItem val18 = new CustomItem(val17, false);
ItemData itemData6 = val18.ItemPrefab.GetComponent<ItemDrop>().m_itemData;
itemData6.m_shared.m_attack.m_attackProjectile = PrefabManager.Instance.GetPrefab("bow_projectile_poison");
PrefabManager.Instance.AddPrefab(val2);
PrefabManager.Instance.AddPrefab(val4);
PrefabManager.Instance.AddPrefab(val6);
ItemManager.Instance.AddItem(val8);
ItemManager.Instance.AddItem(val10);
ItemManager.Instance.AddItem(val12);
ItemManager.Instance.AddItem(val14);
ItemManager.Instance.AddItem(val16);
ItemManager.Instance.AddItem(val18);
leechDeathVFX = PrefabManager.Instance.GetPrefab("vfx_leech_death");
leechDeathSFX = PrefabManager.Instance.GetPrefab("sfx_leech_death");
PrefabManager.OnVanillaPrefabsAvailable -= CreateCustomPrefabs;
}
}
public static class SpawnCommands
{
[HarmonyPatch(typeof(Terminal), "InitTerminal")]
private static class Patch_Terminal_InitTerminal
{
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static ConsoleEvent <>9__1_0;
internal void <Postfix>b__1_0(ConsoleEventArgs args)
{
if (args.Length > 2)
{
string creatureName = args[1];
string modifierName = args[2];
SpawnModifier(creatureName, modifierName);
}
else
{
args.Context.AddString("Usage: modifier [creature] [modifier]");
}
}
}
[HarmonyPriority(800)]
private static void Prefix(out bool __state)
{
__state = Terminal.m_terminalInitialized;
}
private static void Postfix(bool __state)
{
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Expected O, but got Unknown
if (__state)
{
return;
}
MonsterModifiersPlugin.MonsterModifiersLogger.LogInfo((object)"Adding Terminal Commands for monster modifier spawning.");
object obj = <>c.<>9__1_0;
if (obj == null)
{
ConsoleEvent val = delegate(ConsoleEventArgs args)
{
if (args.Length > 2)
{
string creatureName = args[1];
string modifierName = args[2];
SpawnModifier(creatureName, modifierName);
}
else
{
args.Context.AddString("Usage: modifier [creature] [modifier]");
}
};
<>c.<>9__1_0 = val;
obj = (object)val;
}
new ConsoleCommand("modifier", "[creature] [modifier]", (ConsoleEvent)obj, true, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
}
}
public static void SpawnModifier(string creatureName, string modifierName)
{
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
GameObject prefab = ZNetScene.instance.GetPrefab(creatureName);
MonsterModifierTypes result;
if ((Object)(object)prefab == (Object)null)
{
((Character)Player.m_localPlayer).Message((MessageType)1, "Missing object " + creatureName, 0, (Sprite)null);
}
else if (Enum.TryParse<MonsterModifierTypes>(modifierName, ignoreCase: true, out result))
{
Vector3 insideUnitSphere = Random.insideUnitSphere;
GameObject val = Object.Instantiate<GameObject>(prefab, ((Component)Player.m_localPlayer).transform.position + ((Component)Player.m_localPlayer).transform.forward * 2f + Vector3.up + insideUnitSphere, Quaternion.identity);
Character component = val.GetComponent<Character>();
if (component.m_nview.GetZDO().IsOwner())
{
component.SetLevel(2);
component.m_nview.GetZDO().Set("modifiers", modifierName);
}
}
else
{
((Character)Player.m_localPlayer).Message((MessageType)1, "Invalid modifier name: " + modifierName, 0, (Sprite)null);
}
}
}
public class StatusEffectUtils
{
public static void CreateCustomStatusEffects()
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Expected O, but got Unknown
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Expected O, but got Unknown
BloodLoss_SE bloodLoss_SE = ScriptableObject.CreateInstance<BloodLoss_SE>();
((Object)bloodLoss_SE).name = "BloodLossStatusEffect";
((StatusEffect)bloodLoss_SE).m_name = "$se_bloodLoss";
((StatusEffect)bloodLoss_SE).m_icon = ModifierAssetUtils.bloodIconRed;
CustomStatusEffect val = new CustomStatusEffect((StatusEffect)(object)bloodLoss_SE, false);
HealDeath_SE healDeath_SE = ScriptableObject.CreateInstance<HealDeath_SE>();
((Object)healDeath_SE).name = "HealDeathStatusEffect";
((StatusEffect)healDeath_SE).m_name = "$se_healDeath";
((StatusEffect)healDeath_SE).m_ttl = 5f;
((SE_Stats)healDeath_SE).m_tickInterval = 1f;
((SE_Stats)healDeath_SE).m_healthOverTimeDuration = 5f;
((SE_Stats)healDeath_SE).m_healthOverTimeInterval = 0.5f;
((SE_Stats)healDeath_SE).m_healthOverTimeTicks = 10f;
((SE_Stats)healDeath_SE).m_healthOverTime = 0f;
CustomStatusEffect val2 = new CustomStatusEffect((StatusEffect)(object)healDeath_SE, false);
ItemManager.Instance.AddStatusEffect(val);
ItemManager.Instance.AddStatusEffect(val2);
}
}
public class TranslationUtils
{
public static CustomLocalization Localization;
public static void AddLocalizations()
{
Localization = LocalizationManager.Instance.GetLocalization();
CustomLocalization localization = Localization;
string text = "English";
localization.AddTranslation(ref text, new Dictionary<string, string>
{
{ "$se_bloodLoss", "Blood Loss" },
{ "$modifier_mistile", "Stagger Bomb" }
});
}
}
public class ShaderLogFilter : ILogListener, IDisposable
{
private readonly ILogListener _inner;
private ShaderLogFilter(ILogListener inner)
{
_inner = inner;
}
public static void Install()
{
ICollection<ILogListener> listeners = Logger.Listeners;
foreach (ILogListener item in listeners)
{
if (item is ShaderLogFilter)
{
return;
}
}
List<ILogListener> list = new List<ILogListener>(listeners);
listeners.Clear();
foreach (ILogListener item2 in list)
{
listeners.Add((ILogListener)(object)new ShaderLogFilter(item2));
}
}
public void LogEvent(object sender, LogEventArgs eventArgs)
{
if (eventArgs == null || !(eventArgs.Data?.ToString()?.Contains("Failed to find expected binary shader data")).GetValueOrDefault())
{
ILogListener inner = _inner;
if (inner != null)
{
inner.LogEvent(sender, eventArgs);
}
}
}
public void Dispose()
{
((IDisposable)_inner)?.Dispose();
}
}
public class WorldUtils
{
public static List<Character> GetAllCharacter(Vector3 position, float range)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
Collider[] array = Physics.OverlapBox(position, Vector3.one * range, Quaternion.identity);
List<Character> list = new List<Character>();
Collider[] array2 = array;
foreach (Collider val in array2)
{
Character componentInChildren = ((Component)((Component)val).transform.root).gameObject.GetComponentInChildren<Character>();
if ((Object)(object)componentInChildren != (Object)null)
{
list.Add(componentInChildren);
}
}
return list;
}
}
public class YamlUtils
{
public static string defaultModifierValues;
public static void ParseDefaultYamls()
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Expected O, but got Unknown
defaultModifierValues = AssetUtils.LoadTextFromResources("modifierValues.yml");
IDeserializer val = ((BuilderSkeleton<DeserializerBuilder>)new DeserializerBuilder()).WithNamingConvention(CamelCaseNamingConvention.Instance).Build();
ModifierUtils.modifiers = val.Deserialize<Dictionary<MonsterModifierTypes, ModifierData>>((TextReader)new StringReader(defaultModifierValues));
}
}
[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
public static class RegisterAndCheckVersion
{
private static void Prefix(ZNetPeer peer, ref ZNet __instance)
{
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Expected O, but got Unknown
MonsterModifiersPlugin.MonsterModifiersLogger.LogDebug((object)"Registering version RPC handler");
peer.m_rpc.Register<ZPackage>("MonsterModifiers_VersionCheck", (Action<ZRpc, ZPackage>)RpcHandlers.RPC_MonsterModifiers_Version);
MonsterModifiersPlugin.MonsterModifiersLogger.LogDebug((object)"Invoking version check");
ZPackage val = new ZPackage();
val.Write("1.2.6");
peer.m_rpc.Invoke("MonsterModifiers_VersionCheck", new object[1] { val });
}
}
[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
public static class VerifyClient
{
private static bool Prefix(ZRpc rpc, ZPackage pkg, ref ZNet __instance)
{
if (!__instance.IsServer() || RpcHandlers.ValidatedPeers.Contains(rpc))
{
return true;
}
MonsterModifiersPlugin.MonsterModifiersLogger.LogWarning((object)("Peer (" + rpc.m_socket.GetHostName() + ") never sent version or couldn't due to previous disconnect, disconnecting"));
rpc.Invoke("Error", new object[1] { 3 });
return false;
}
private static void Postfix(ZNet __instance)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Expected O, but got Unknown
ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), "MonsterModifiersRequestAdminSync", new object[1] { (object)new ZPackage() });
}
}
[HarmonyPatch(typeof(FejdStartup), "ShowConnectError")]
public class ShowConnectionError
{
private static void Postfix(FejdStartup __instance)
{
if (__instance.m_connectionFailedPanel.activeSelf)
{
__instance.m_connectionFailedError.fontSizeMax = 25f;
__instance.m_connectionFailedError.fontSizeMin = 15f;
TMP_Text connectionFailedError = __instance.m_connectionFailedError;
connectionFailedError.text = connectionFailedError.text + "\n" + MonsterModifiersPlugin.ConnectionError;
}
}
}
[HarmonyPatch(typeof(ZNet), "Disconnect")]
public static class RemoveDisconnectedPeerFromVerified
{
private static void Prefix(ZNetPeer peer, ref ZNet __instance)
{
if (__instance.IsServer())
{
MonsterModifiersPlugin.MonsterModifiersLogger.LogInfo((object)("Peer (" + peer.m_rpc.m_socket.GetHostName() + ") disconnected, removing from validated list"));
RpcHandlers.ValidatedPeers.Remove(peer.m_rpc);
}
}
}
public static class RpcHandlers
{
public static readonly List<ZRpc> ValidatedPeers = new List<ZRpc>();
public static void RPC_MonsterModifiers_Version(ZRpc rpc, ZPackage pkg)
{
string text = pkg.ReadString();
MonsterModifiersPlugin.MonsterModifiersLogger.LogInfo((object)("Version check, local: 1.2.6, remote: " + text));
if (text != "1.2.6")
{
MonsterModifiersPlugin.ConnectionError = "MonsterModifiers Installed: 1.2.6\n Needed: " + text;
if (ZNet.instance.IsServer())
{
MonsterModifiersPlugin.MonsterModifiersLogger.LogWarning((object)("Peer (" + rpc.m_socket.GetHostName() + ") has incompatible version, disconnecting..."));
rpc.Invoke("Error", new object[1] { 3 });
}
}
else if (!ZNet.instance.IsServer())
{
MonsterModifiersPlugin.MonsterModifiersLogger.LogInfo((object)"Received same version from server!");
}
else
{
MonsterModifiersPlugin.MonsterModifiersLogger.LogInfo((object)("Adding peer (" + rpc.m_socket.GetHostName() + ") to validated list"));
ValidatedPeers.Add(rpc);
}
}
}
}
namespace MonsterModifiers.Visuals
{
public class BowVisuals
{
public static GameObject GetModifierVisual(string itemName, List<MonsterModifierTypes> modifiers)
{
if (!(itemName == "skeleton_bow"))
{
if (itemName == "draugr_bow")
{
return GetDraugrBowVisual(modifiers);
}
return null;
}
return GetSkeletonBowVisual(modifiers);
}
public static GameObject GetSkeletonBowVisual(List<MonsterModifierTypes> modifiers)
{
if (modifiers.Contains(MonsterModifierTypes.FireInfused))
{
return PrefabManager.Instance.GetPrefab("skeletonBowCustomPrefab_Fire");
}
if (modifiers.Contains(MonsterModifierTypes.FrostInfused))
{
return PrefabManager.Instance.GetPrefab("skeletonBowCustomPrefab_Frost");
}
if (modifiers.Contains(MonsterModifierTypes.PoisonInfused))
{
return PrefabManager.Instance.GetPrefab("skeletonBowCustomPrefab_Poison");
}
return null;
}
public static GameObject GetDraugrBowVisual(List<MonsterModifierTypes> modifiers)
{
if (modifiers.Contains(MonsterModifierTypes.FireInfused))
{
return PrefabManager.Instance.GetPrefab("draugrBowCustomPrefab_Fire");
}
if (modifiers.Contains(MonsterModifierTypes.FrostInfused))
{
return PrefabManager.Instance.GetPrefab("draugrBowCustomPrefab_Frost");
}
if (modifiers.Contains(MonsterModifierTypes.PoisonInfused))
{
return PrefabManager.Instance.GetPrefab("draugrBowCustomPrefab_Poison");
}
return null;
}
}
}
namespace MonsterModifiers.StatusEffects
{
public class BloodLoss_SE : StatusEffect
{
public int bloodLossAmount = 0;
public int bloodLossCap;
private float reductionTimer = 0f;
private bool shouldRemove = false;
public override void Setup(Character character)
{
((StatusEffect)this).Setup(character);
bloodLossCap = Mathf.FloorToInt(character.GetMaxHealth());
}
public override void UpdateStatusEffect(float dt)
{
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Expected O, but got Unknown
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
reductionTimer += dt;
if (reductionTimer >= 60f)
{
bloodLossAmount = Mathf.Max(0, bloodLossAmount - 10);
shouldRemove = true;
reductionTimer = 0f;
}
if (bloodLossAmount > bloodLossCap)
{
bloodLossAmount = 0;
HitData val = new HitData
{
m_damage =
{
m_slash = base.m_character.GetMaxHealth() * 0.3f
}
};
base.m_character.Damage(val);
Object.Instantiate<GameObject>(PrefabUtils.leechDeathSFX, ((Component)base.m_character).transform.position, ((Component)base.m_character).transform.rotation);
Object.Instantiate<GameObject>(PrefabUtils.leechDeathVFX, ((Component)base.m_character).transform.position, ((Component)base.m_character).transform.rotation);
shouldRemove = true;
}
}
public override string GetIconText()
{
return bloodLossAmount.ToString();
}
public override void OnDamaged(HitData hit, Character attacker)
{
if (ModifierUtils.RunRPCDamageChecks(attacker, hit) && ModifierUtils.RunHitChecks(hit, isMonsterAttackingPlayer: true))
{
MonsterModifier component = ((Component)attacker).GetComponent<MonsterModifier>();
if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.BloodLoss))
{
bloodLossAmount += Mathf.FloorToInt(hit.GetTotalDamage());
}
}
}
public override bool IsDone()
{
return shouldRemove || ((StatusEffect)this).IsDone();
}
}
public class HealDeath_SE : SE_Stats
{
public override void SetLevel(int itemLevel, float skillLevel)
{
base.m_healthPerTick = skillLevel / 10f;
}
}
}
namespace MonsterModifiers.Patches
{
[HarmonyPatch(typeof(EnemyHud), "ShowHud")]
public static class EnemyHud_ShowHud_Patch
{
private static void Postfix(EnemyHud __instance, Character c, bool isMount)
{
if (!(c.IsPlayer() || isMount))
{
MonsterModifier component = ((Component)c).GetComponent<MonsterModifier>();
if (!((Object)(object)component == (Object)null))
{
ChangeEnemyStars(c, component.Modifiers, component.IsBossCharacter, component.OverflowStars);
}
}
}
public static void ChangeEnemyStars(Character character, List<MonsterModifierTypes> modifiers, bool isBoss = false, int overflowStars = 0)
{
//IL_016a: Unknown result type (might be due to invalid IL or missing references)
if ((character.GetLevel() <= 1 && !isBoss) || !EnemyHud.instance.m_huds.TryGetValue(character, out var value))
{
return;
}
GameObject gui = value.m_gui;
int num = 0;
int num2 = 7;
if (CompatibilityUtils.isStarLevelsExpandedInstalled && character.GetLevel() > num2)
{
num = 2;
}
int num3 = (isBoss ? MonsterModifiersPlugin.Configurations_Boss_Modifiers.Value : 0);
int num4 = modifiers.Count - num3;
for (int i = num; i < gui.transform.childCount; i++)
{
Transform child = gui.transform.GetChild(i);
if (!((Object)child).name.StartsWith("level_" + (modifiers.Count - num3 + overflowStars + 1)) && (!((Object)child).name.StartsWith("level_n") || !((Component)child).gameObject.activeSelf))
{
continue;
}
for (int j = 0; j < ((Component)child).transform.childCount; j++)
{
Transform child2 = ((Component)child).transform.GetChild(j);
if (((Object)child2).name.StartsWith("star") && ((Component)child2).gameObject.activeSelf && j < num4)
{
int index = num3 + j;
((Component)child2).GetComponent<Image>().sprite = ModifierUtils.GetModifierIcon(modifiers[index]);
((Graphic)((Component)child2).GetComponent<Image>()).color = ModifierUtils.GetModifierColor(modifiers[index]);
((Component)child2.GetChild(0)).gameObject.SetActive(false);
}
}
}
}
}
}
namespace MonsterModifiers.Modifiers
{
public class Absorption
{
[HarmonyPatch(typeof(Character), "RPC_Damage")]
public class Absorption_Character_RPC_Damage_Patch
{
public static void Prefix(Character __instance, HitData hit)
{
if (hit == null || (Object)(object)__instance == (Object)null)
{
return;
}
MonsterModifier component = ((Component)__instance).GetComponent<MonsterModifier>();
if ((Object)(object)component == (Object)null || !component.Modifiers.Contains(MonsterModifierTypes.Absorption) || ((DamageTypes)(ref hit.m_damage)).GetTotalDamage() == 0f)
{
return;
}
List<MonsterModifierTypes> modifiers = component.Modifiers;
if (modifiers.Contains(MonsterModifierTypes.BluntImmunity) && hit.m_damage.m_blunt > 0f)
{
float num = (float)MonsterModifiersPlugin.Cfg_BluntImmunity_DamageReduction.Value / 100f;
__instance.Heal(hit.m_damage.m_blunt * num, true);
}
if (modifiers.Contains(MonsterModifierTypes.SlashImmunity) && hit.m_damage.m_slash > 0f)
{
float num2 = (float)MonsterModifiersPlugin.Cfg_SlashImmunity_DamageReduction.Value / 100f;
__instance.Heal(hit.m_damage.m_slash * num2, true);
}
if (modifiers.Contains(MonsterModifierTypes.PierceImmunity) && hit.m_damage.m_pierce > 0f)
{
float num3 = (float)MonsterModifiersPlugin.Cfg_PierceImmunity_DamageReduction.Value / 100f;
__instance.Heal(hit.m_damage.m_pierce * num3, true);
}
if (modifiers.Contains(MonsterModifierTypes.ElementalImmunity))
{
float num4 = (float)MonsterModifiersPlugin.Cfg_ElementalImmunity_DamageReduction.Value / 100f;
if (hit.m_damage.m_fire > 0f)
{
__instance.Heal(hit.m_damage.m_fire * num4, true);
}
if (hit.m_damage.m_frost > 0f)
{
__instance.Heal(hit.m_damage.m_frost * num4, true);
}
if (hit.m_damage.m_lightning > 0f)
{
__instance.Heal(hit.m_damage.m_lightning * num4, true);
}
if (hit.m_damage.m_poison > 0f)
{
__instance.Heal(hit.m_damage.m_poison * num4, true);
}
if (hit.m_damage.m_spirit > 0f)
{
__instance.Heal(hit.m_damage.m_spirit * num4, true);
}
}
}
}
}
public class BloodLoss
{
[HarmonyPatch(typeof(Character), "RPC_Damage")]
public class RemoveMead_Character_RPC_Damage_Patch
{
public static void Postfix(Character __instance, HitData hit)
{
if (ModifierUtils.RunRPCDamageChecks(__instance, hit) && ModifierUtils.RunHitChecks(hit, isMonsterAttackingPlayer: true))
{
Character attacker = hit.GetAttacker();
MonsterModifier component = ((Component)attacker).GetComponent<MonsterModifier>();
if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.BloodLoss) && !__instance.IsBlocking() && !__instance.GetSEMan().HaveStatusEffect(StringExtensionMethods.GetStableHashCode("BloodLossStatusEffect")))
{
__instance.GetSEMan().AddStatusEffect(StringExtensionMethods.GetStableHashCode("BloodLossStatusEffect"), false, 0, 0f);
}
}
}
}
}
public class DistantDetection
{
public static void AddDistantDetection(Character character)
{
BaseAI baseAI = character.m_baseAI;
if ((Object)(object)baseAI != (Object)null)
{
baseAI.m_hearRange *= MonsterModifiersPlugin.Cfg_DistantDetection_RangeMultiplier.Value;
baseAI.m_viewRange *= MonsterModifiersPlugin.Cfg_DistantDetection_RangeMultiplier.Value;
}
}
public static void RemoveDistantDetection(Character character)
{
BaseAI baseAI = character.m_baseAI;
if ((Object)(object)baseAI != (Object)null)
{
baseAI.m_hearRange /= MonsterModifiersPlugin.Cfg_DistantDetection_RangeMultiplier.Value;
baseAI.m_viewRange /= MonsterModifiersPlugin.Cfg_DistantDetection_RangeMultiplier.Value;
}
}
}
public class EitrSiphon
{
[HarmonyPatch(typeof(Character), "RPC_Damage")]
public class EitrSiphon_Character_RPC_Damage_Patch
{
public static void Postfix(Character __instance, HitData hit)
{
if (ModifierUtils.RunRPCDamageChecks(__instance, hit) && ModifierUtils.RunHitChecks(hit, isMonsterAttackingPlayer: true) && !__instance.IsBlocking())
{
Character attacker = hit.GetAttacker();
MonsterModifier component = ((Component)attacker).GetComponent<MonsterModifier>();
if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.EitrSiphon))
{
__instance.UseEitr(hit.GetTotalDamage());
}
}
}
}
}
public class FastAttackSpeed
{
[HarmonyPatch(typeof(CharacterAnimEvent), "CustomFixedUpdate")]
public static class FastAttackSpeed_CharacterAnimEvent_CustomFixedUpdate_Patch
{
public static void Prefix(Character ___m_character, ref Animator ___m_animator)
{
if (!___m_character.InAttack() || ___m_character.IsPlayer())
{
return;
}
MonsterModifier component = ((Component)___m_character).GetComponent<MonsterModifier>();
if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.FastAttackSpeed))
{
double num = (double)___m_animator.speed * 10000000.0 % 100.0;
float value = MonsterModifiersPlugin.Cfg_FastAttackSpeed_AnimatorMultiplier.Value;
if ((!(num < 30.0) || !(num > 10.0)) && !(___m_animator.speed <= 0.001f))
{
___m_animator.speed = ___m_animator.speed * (1f + value) + 1.9E-06f;
}
}
}
}
[HarmonyPatch(typeof(Attack), "Start")]
public static class FastAttackSpeed_Attack_Start_Patch
{
private static void Postfix(Humanoid character, ItemData weapon, bool __result)
{
if (((Character)character).InAttack() && !((Character)character).IsPlayer())
{
MonsterModifier component = ((Component)character).GetComponent<MonsterModifier>();
if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.FastAttackSpeed) && !((Character)character).IsPlayer() && __result && !((Character)character).IsBoss())
{
float value = MonsterModifiersPlugin.Cfg_FastAttackSpeed_IntervalReduction.Value;
weapon.m_lastAttackTime -= weapon.m_shared.m_aiAttackInterval * Mathf.Max(0f, value);
}
}
}
}
}
public class FastMovement
{
public static void AddFastMovement(Character character)
{
character.m_speed *= MonsterModifiersPlugin.Cfg_FastMovement_SpeedMultiplier.Value;
character.m_runSpeed *= MonsterModifiersPlugin.Cfg_FastMovement_SpeedMultiplier.Value;
character.m_walkSpeed *= MonsterModifiersPlugin.Cfg_FastMovement_SpeedMultiplier.Value;
}
public static void RemoveFastMovement(Character character)
{
character.m_speed /= MonsterModifiersPlugin.Cfg_FastMovement_SpeedMultiplier.Value;
character.m_runSpeed /= MonsterModifiersPlugin.Cfg_FastMovement_SpeedMultiplier.Value;
character.m_walkSpeed /= MonsterModifiersPlugin.Cfg_FastMovement_SpeedMultiplier.Value;
}
}
public class FoodDrain
{
[HarmonyPatch(typeof(Character), "RPC_Damage")]
public class FoodDrain_Character_RPC_Damage_Patch
{
public static void Postfix(Character __instance, HitData hit)
{
if (!ModifierUtils.RunRPCDamageChecks(__instance, hit) || !ModifierUtils.RunHitChecks(hit, isMonsterAttackingPlayer: true) || __instance.IsBlocking())
{
return;
}
Character attacker = hit.GetAttacker();
MonsterModifier component = ((Component)attacker).GetComponent<MonsterModifier>();
if ((Object)(object)component == (Object)null || !component.Modifiers.Contains(MonsterModifierTypes.FoodDrain))
{
return;
}
Player val = (Player)(object)((__instance is Player) ? __instance : null);
if ((Object)(object)val != (Object)null)
{
List<Food> foods = val.GetFoods();
int count = foods.Count;
if (count > 0)
{
int index = Random.Range(0, count);
Food obj = foods[index];
obj.m_time *= MonsterModifiersPlugin.Cfg_FoodDrain_DurationReduction.Value;
}
}
}
}
}
public class ElementalInfusions
{
[HarmonyPatch(typeof(Character), "RPC_Damage")]
public class ElementalInfusions_Character_RPC_Damage_Patch
{
public static void Prefix(Character __instance, HitData hit)
{
if (!ModifierUtils.RunRPCDamageChecks(__instance, hit) || !ModifierUtils.RunHitChecks(hit, isMonsterAttackingPlayer: true) || __instance.IsBlocking())
{
return;
}
Character attacker = hit.GetAttacker();
MonsterModifier component = ((Component)attacker).GetComponent<MonsterModifier>();
if (!((Object)(object)component == (Object)null))
{
float num = hit.GetTotalDamage() * MonsterModifiersPlugin.Cfg_ElementalInfusion_DamageRatio.Value;
float num2 = hit.m_damage.m_chop + hit.m_damage.m_pickaxe + hit.m_damage.m_spirit;
float num3 = num - num2;
if (component.Modifiers.Contains(MonsterModifierTypes.PoisonInfused))
{
hit.m_damage.m_poison += num3;
}
if (component.Modifiers.Contains(MonsterModifierTypes.FireInfused))
{
hit.m_damage.m_fire += num3;
}
if (component.Modifiers.Contains(MonsterModifierTypes.LightningInfused))
{
hit.m_damage.m_lightning += num3;
}
if (component.Modifiers.Contains(MonsterModifierTypes.FrostInfused))
{
hit.m_damage.m_frost += num3;
}
}
}
}
}
public class ArmorCharge
{
[HarmonyPatch(typeof(Character), "RPC_Damage")]
public class ArmorCharge_Character_RPC_Damage_Patch
{
public static void Prefix(Character __instance, HitData hit)
{
if (hit == null || (Object)(object)__instance == (Object)null || !__instance.IsPlayer())
{
return;
}
Character attacker = hit.GetAttacker();
if (!((Object)(object)attacker == (Object)null))
{
MonsterModifier component = ((Component)attacker).GetComponent<MonsterModifier>();
if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.ArmorCharge))
{
hit.m_damage.m_blunt *= 1.5f;
hit.m_damage.m_slash *= 1.5f;
hit.m_damage.m_pierce *= 1.5f;
hit.m_damage.m_fire *= 1.5f;
hit.m_damage.m_frost *= 1.5f;
hit.m_damage.m_lightning *= 1.5f;
hit.m_damage.m_poison *= 1.5f;
hit.m_damage.m_spirit *= 1.5f;
}
}
}
}
private const float SpeedMultiplier = 1.3f;
private const float DamageMultiplier = 1.5f;
public static void Apply(Character character)
{
character.m_walkSpeed *= 1.3f;
character.m_runSpeed *= 1.3f;
character.m_swimSpeed *= 1.3f;
}
}
public class FireTrail : MonoBehaviour
{
private Character _character;
private Vector3 _lastPosition;
private float _timer;
private readonly List<GameObject> _activeEffects = new List<GameObject>();
private const float SpawnInterval = 0.4f;
private const float MinMoveDistance = 0.5f;
private const float EffectLifetime = 1.5f;
public void Init(Character character)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
_character = character;
_lastPosition = ((Component)character).transform.position;
}
private void FixedUpdate()
{
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_character == (Object)null || _character.IsDead())
{
return;
}
_timer += Time.fixedDeltaTime;
if (_timer < 0.4f)
{
return;
}
_timer = 0f;
Vector3 position = ((Component)_character).transform.position;
if (Vector3.Distance(position, _lastPosition) < 0.5f)
{
return;
}
_lastPosition = position;
ZNetScene instance = ZNetScene.instance;
GameObject val = ((instance != null) ? instance.GetPrefab("fx_Hen_Egg_Heat") : null);
if ((Object)(object)val == (Object)null)
{
ZNetScene instance2 = ZNetScene.instance;
val = ((instance2 != null) ? instance2.GetPrefab("vfx_fire_shortlived") : null);
}
if (!((Object)(object)val == (Object)null))
{
GameObject val2 = Object.Instantiate<GameObject>(val, position, Quaternion.identity);
if ((Object)(object)val2 != (Object)null)
{
Object.Destroy((Object)(object)val2, 1.5f);
}
}
}
}
public class Forceful
{
[HarmonyPatch(typeof(Character), "RPC_Damage")]
public class Forceful_Character_RPC_Damage_Patch
{
public static void Prefix(Character __instance, HitData hit)
{
if (ModifierUtils.RunRPCDamageChecks(__instance, hit) && ModifierUtils.RunHitChecks(hit, isMonsterAttackingPlayer: true) && !__instance.IsBlocking())
{
Character attacker = hit.GetAttacker();
MonsterModifier component = ((Component)attacker).GetComponent<MonsterModifier>();
if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.Forceful))
{
hit.m_pushForce *= MonsterModifiersPlugin.Cfg_Forceful_PushMultiplier.Value;
}
}
}
}
}
public class ResistanceNotification
{
[HarmonyPatch(typeof(Character), "RPC_Damage")]
public class ResistanceNotification_Character_RPC_Damage_Patch
{
public static void Prefix(Character __instance, HitData hit)
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Invalid comparison between Unknown and I4
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
//IL_010a: Unknown result type (might be due to invalid IL or missing references)
//IL_010c: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
if (hit == null || (Object)(object)__instance == (Object)null || __instance.IsPlayer() || (int)hit.m_hitType != 2)
{
return;
}
MonsterModifier component = ((Component)__instance).GetComponent<MonsterModifier>();
if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.ResistanceNotification) && !((Object)(object)__instance.m_nview == (Object)null))
{
ZDOID uid = __instance.m_nview.GetZDO().m_uid;
if (!HitCounts.ContainsKey(uid))
{
HitCounts[uid] = new Dictionary<DamageType, int>();
}
CheckAndNotify(__instance, uid, (DamageType)1, hit.m_damage.m_blunt, component, MonsterModifierTypes.BluntImmunity, "$modifier_blunt_resistance");
CheckAndNotify(__instance, uid, (DamageType)2, hit.m_damage.m_slash, component, MonsterModifierTypes.SlashImmunity, "$modifier_slash_resistance");
CheckAndNotify(__instance, uid, (DamageType)4, hit.m_damage.m_pierce, component, MonsterModifierTypes.PierceImmunity, "$modifier_pierce_resistance");
CheckAndNotifyElemental(__instance, uid, hit.m_damage, component);
}
}
private static void CheckAndNotify(Character character, ZDOID id, DamageType type, float damage, MonsterModifier modComp, MonsterModifierTypes immunity, string messageKey)
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
if (damage <= 0f || !modComp.Modifiers.Contains(immunity))
{
return;
}
Dictionary<DamageType, int> dictionary = HitCounts[id];
if (!dictionary.ContainsKey(type))
{
dictionary[type] = 0;
}
if (dictionary[type] < MonsterModifiersPlugin.Cfg_ResistanceNotification_MaxCount.Value)
{
dictionary[type]++;
Player localPlayer = Player.m_localPlayer;
if (localPlayer != null)
{
((Character)localPlayer).Message((MessageType)2, Localization.instance.Localize(messageKey), 0, (Sprite)null);
}
}
}
private static void CheckAndNotifyElemental(Character character, ZDOID id, DamageTypes dmg, MonsterModifier modComp)
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
if (!modComp.Modifiers.Contains(MonsterModifierTypes.ElementalImmunity))
{
return;
}
float num = dmg.m_fire + dmg.m_frost + dmg.m_lightning + dmg.m_poison + dmg.m_spirit;
if (num <= 0f)
{
return;
}
Dictionary<DamageType, int> dictionary = HitCounts[id];
DamageType key = (DamageType)32;
if (!dictionary.ContainsKey(key))
{
dictionary[key] = 0;
}
if (dictionary[key] < MonsterModifiersPlugin.Cfg_ResistanceNotification_MaxCount.Value)
{
dictionary[key]++;
Player localPlayer = Player.m_localPlayer;
if (localPlayer != null)
{
((Character)localPlayer).Message((MessageType)2, Localization.instance.Localize("$modifier_elemental_resistance"), 0, (Sprite)null);
}
}
}
}
[HarmonyPatch(typeof(Character), "OnDeath")]
public class ResistanceNotification_Character_OnDeath_Patch
{
public static void Prefix(Character __instance)
{
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.m_nview == (Object)null))
{
ZDOID uid = __instance.m_nview.GetZDO().m_uid;
HitCounts.Remove(uid);
}
}
}
private static readonly Dictionary<ZDOID, Dictionary<DamageType, int>> HitCounts = new Dictionary<ZDOID, Dictionary<DamageType, int>>();
}
public class SplitSpawn
{
[HarmonyPatch(typeof(Character), "OnDeath")]
public static class Character_OnDeath_SplitSpawn_Patch
{
public static void Prefix(Character __instance)
{
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_0151: Unknown result type (might be due to invalid IL or missing references)
//IL_0156: 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_016b: Unknown result type (might be due to invalid IL or missing references)
//IL_0170: Unknown result type (might be due to invalid IL or missing references)
//IL_0172: Unknown result type (might be due to invalid IL or missing references)
//IL_0174: Unknown result type (might be due to invalid IL or missing references)
//IL_0180: Unknown result type (might be due to invalid IL or missing references)
//IL_0187: Unknown result type (might be due to invalid IL or missing references)
//IL_018c: Unknown result type (might be due to invalid IL or missing references)
//IL_0191: Unknown result type (might be due to invalid IL or missing references)
//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)__instance == (Object)null || __instance.IsPlayer() || (Object)(object)__instance.m_nview == (Object)null || !__instance.m_nview.IsOwner())
{
return;
}
MonsterModifier component = ((Component)__instance).GetComponent<MonsterModifier>();
if ((Object)(object)component == (Object)null || !component.Modifiers.Contains(MonsterModifierTypes.SplitSpawn))
{
return;
}
int level = __instance.GetLevel();
if (level <= 1)
{
return;
}
int num = level - 1;
int level2 = level - 1;
float value = MonsterModifiersPlugin.Cfg_SplitSpawn_Scale.Value;
Vector3 localScale = ((Component)__instance).transform.localScale;
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 num2 = Random.Range(0f, 360f);
GameObject val3 = Object.Instantiate<GameObject>(prefab, val2, Quaternion.Euler(0f, num2, 0f));
val3.transform.localScale = localScale * value;
Character component2 = val3.GetComponent<Character>();
if ((Object)(object)component2 != (Object)null)
{
component2.SetLevel(level2);
}
}
}
}
private static readonly Dictionary<string, string[]> _bowAliases = new Dictionary<string, string[]>
{
{
"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<MonsterModifier>();
if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.IgnoreArmor))
{
shouldIgnoreArmor = true;
}
}
}
}
[HarmonyPatch(typeof(Player), "GetBodyArmor")]
public class IgnoreArmor_Player_GetBodyArmor_Patch
{
public static void Postfix(ref float __result)
{
if (shouldIgnoreArmor)
{
__result *= MonsterModifiersPlugin.Cfg_IgnoreArmor_ArmorReduction.Value;
shouldIgnoreArmor = false;
}
}
}
public static bool shouldIgnoreArmor;
}
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_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_0180: Unknown result type (might be due to invalid IL or missing references)
//IL_0150: Unknown result type (might be due to invalid IL or missing references)
//IL_01de: 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<GameObject>(prefab, new Vector3(((Component)__instance).transform.position.x, ((Component)__instance).transform.position.y - 1f, ((Component)__instance).transform.position.z), ((Component)__instance).transform.rotation);
List<Character> allCharacter = WorldUtils.GetAllCharacter(((Component)__instance).transform.position, 5f);
foreach (Character item in allCharacter)
{
if (!((Object)(object)item == (Object)(object)__instance) && !((Object)(object)item == (Object)null) && !((Object)(object)item.m_nview == (Object)null) && item.m_nview.m_zdo != null && !item.IsPlayer())
{
item.Stagger(position);
}
}
List<Player> list = new List<Player>();
Player.GetPlayersInRange(((Component)__instance).transform.position, 5f, list);
foreach (Player item2 in list)
{
if (!((Object)(object)item2 == (Object)null) && !((Object)(object)((Character)item2).m_nview == (Object)null) && ((Character)item2).m_nview.m_zdo != null)
{
((Character)item2).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<MonsterModifier>();
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<MonsterModifier>();
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<MonsterModifier>();
if (!((Object)(object)component == (Object)null) && component.Modifiers.Contains(MonsterModifierTypes.RemoveStatusEffect))
{
List<StatusEffect> 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<MonsterModifier>();
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)
{
currentBlocker.m_durability *= MonsterModifiersPlugin.Cfg_ShieldBreaker_DurabilityReduction.Value;
}