Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of HeimLifeTweaks v1.4.7
HeimLifeTweaks.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using TMPro; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace HeimLifeTweaks; [Flags] public enum KilnWoodTypes { None = 0, Wood = 1, CoreWood = 2, FineWood = 4, YggdrasilWood = 8 } [BepInPlugin("HeimLifeTweaks.Valheim", "HeimLifeTweaks", "1.5.2")] public class HeimLifeTweaksPlugin : BaseUnityPlugin { private sealed class CircletLightOriginal { internal bool Enabled; internal float Range; internal float Intensity; internal float SpotAngle; internal Color Color; } public const string PluginGuid = "HeimLifeTweaks.Valheim"; public const string PluginName = "HeimLifeTweaks"; public const string PluginVersion = "1.5.2"; internal static HeimLifeTweaksPlugin Instance; internal static ConfigEntry<bool> MasterEnabled; internal static ConfigEntry<bool> CircletEnabled; internal static ConfigEntry<float> CircletBrightness; internal static ConfigEntry<float> CircletRange; internal static ConfigEntry<int> CircletFocusSteps; internal static ConfigEntry<KeyboardShortcut> CircletNarrowKey; internal static ConfigEntry<KeyboardShortcut> CircletWidenKey; internal static ConfigEntry<KeyboardShortcut> CircletToggleKey; internal static ConfigEntry<bool> SkipIntroEnabled; internal static ConfigEntry<bool> WaterEquipmentEnabled; internal static ConfigEntry<bool> FermenterEnabled; internal static ConfigEntry<bool> FermenterShowProgress; internal static ConfigEntry<float> FermenterMinutes; internal static ConfigEntry<bool> FermenterNoCover; internal static ConfigEntry<bool> NoRainDamageEnabled; internal static ConfigEntry<bool> MapTeleportEnabled; internal static ConfigEntry<bool> BuildSpaceEnabled; internal static ConfigEntry<float> BuildRadiusMultiplier; internal static ConfigEntry<bool> FasterBoatsEnabled; internal static ConfigEntry<float> BoatWindMultiplier; internal static ConfigEntry<float> BoatRudderMultiplier; internal static ConfigEntry<bool> QuickCartEnabled; internal static ConfigEntry<KeyboardShortcut> QuickCartHotkey; internal static ConfigEntry<float> QuickCartDistance; internal static ConfigEntry<bool> QuickCartOutOfPlace; internal static ConfigEntry<bool> RegenerationEnabled; internal static ConfigEntry<float> StaminaCostMultiplier; internal static ConfigEntry<float> StaminaRegenMultiplier; internal static ConfigEntry<float> StaminaRegenDelayMultiplier; internal static ConfigEntry<float> EitrRegenRate; internal static ConfigEntry<float> HealthRegenMultiplier; internal static ConfigEntry<float> HealthRegenDelayMultiplier; internal static ConfigEntry<bool> AutoConsumeExtraSlotsFood; internal static ConfigEntry<bool> PathfinderEnabled; internal static ConfigEntry<bool> PathfinderDisableInDungeons; internal static ConfigEntry<float> LandExploreRadius; internal static ConfigEntry<float> SeaExploreRadius; internal static ConfigEntry<float> AltitudeExploreBonus; internal static ConfigEntry<bool> CarryWeightEnabled; internal static ConfigEntry<float> CarryWeightMultiplier; internal static ConfigEntry<bool> FastToolsEnabled; internal static ConfigEntry<float> PlaceDelay; internal static ConfigEntry<float> RemoveDelay; internal static ConfigEntry<float> BuildStaminaMultiplier; internal static ConfigEntry<bool> DigDeeperEnabled; internal static ConfigEntry<float> DigDepth; internal static ConfigEntry<float> RaiseHeight; internal static ConfigEntry<bool> BossPowersEnabled; internal static ConfigEntry<bool> BossPowersRequireDefeat; internal static ConfigEntry<bool> BossEikthyrEnabled; internal static ConfigEntry<float> EikthyrRunStaminaReduction; internal static ConfigEntry<float> EikthyrJumpStaminaReduction; internal static ConfigEntry<float> EikthyrSwimStaminaReduction; internal static ConfigEntry<bool> BossElderEnabled; internal static ConfigEntry<float> ElderChopDamage; internal static ConfigEntry<float> ElderPickaxeDamage; internal static ConfigEntry<float> ElderHealthRegen; internal static ConfigEntry<bool> BossBonemassEnabled; internal static ConfigEntry<float> BonemassBluntResistance; internal static ConfigEntry<float> BonemassSlashResistance; internal static ConfigEntry<float> BonemassPierceResistance; internal static ConfigEntry<float> BonemassBlockStaminaReduction; internal static ConfigEntry<float> BonemassStaminaReturn; internal static ConfigEntry<bool> BossModerEnabled; internal static ConfigEntry<bool> ModerTailwind; internal static ConfigEntry<float> ModerCarryWeight; internal static ConfigEntry<float> ModerMovementSpeed; internal static ConfigEntry<float> ModerFrostResistance; internal static ConfigEntry<bool> BossYagluthEnabled; internal static ConfigEntry<float> YagluthLightningResistance; internal static ConfigEntry<float> YagluthFarmingSkill; internal static ConfigEntry<float> YagluthDamage; internal static ConfigEntry<bool> BossQueenEnabled; internal static ConfigEntry<float> QueenEitrRegen; internal static ConfigEntry<float> QueenSneakStaminaReduction; internal static ConfigEntry<float> QueenPoisonResistance; internal static ConfigEntry<bool> BossFaderEnabled; internal static ConfigEntry<float> FaderAdrenalineGain; internal static ConfigEntry<float> FaderStaggerReduction; internal static ConfigEntry<float> FaderFireResistance; internal static ConfigEntry<bool> BeehiveEnabled; internal static ConfigEntry<float> HoneyProductionSeconds; internal static ConfigEntry<int> MaximumHoney; internal static ConfigEntry<bool> NearbyStorageEnabled; internal static ConfigEntry<bool> AutoSortEnabled; internal static ConfigEntry<KeyboardShortcut> AutoSortHotkey; internal static ConfigEntry<bool> CraftFromChestsEnabled; internal static ConfigEntry<bool> BuildFromChestsEnabled; internal static ConfigEntry<bool> UseItemsFromChestsEnabled; internal static ConfigEntry<bool> ShowHaveNeedCounts; internal static ConfigEntry<float> StorageRadius; internal static ConfigEntry<bool> RecyclingEnabled; internal static ConfigEntry<KeyboardShortcut> RecyclingHotkey; internal static ConfigEntry<bool> AutoCraftingEnabled; internal static ConfigEntry<bool> AutoCraftingAutoRefillLights; internal static ConfigEntry<float> AutoCraftingRange; internal static ConfigEntry<float> AutoCraftingInterval; internal static ConfigEntry<bool> AutoCraftingLeaveOneInput; internal static ConfigEntry<bool> AutoCraftingDepositOutputs; internal static ConfigEntry<bool> AutoCraftingWoodChests; internal static ConfigEntry<bool> AutoCraftingReinforcedChests; internal static ConfigEntry<bool> AutoCraftingBlackMetalChests; internal static ConfigEntry<bool> AutoCraftingPersonalChests; internal static ConfigEntry<bool> AutoCraftingCartContainers; internal static ConfigEntry<bool> AutoCraftingShipContainers; internal static ConfigEntry<bool> AutoCraftingOtherContainers; internal static ConfigEntry<int> AutoCraftingKilnCharcoalTarget; internal static ConfigEntry<KilnWoodTypes> AutoCraftingKilnWoodTypes; internal static ConfigEntry<int> AutoCraftingStationsPerTick; internal static ConfigEntry<float> AutoCraftingContainerCacheSeconds; internal static ConfigEntry<bool> AutoCraftingAutoPopCookingStations; internal static ConfigEntry<bool> HuntingGroundsEnabled; internal static ConfigEntry<float> HuntingSpawnRadius; internal static ConfigEntry<int> HuntingDeerCap; internal static ConfigEntry<int> HuntingBoarCap; internal static ConfigEntry<int> HuntingNeckCap; internal static ConfigEntry<int> HuntingOtherCap; internal static ConfigEntry<float> HuntingSpawnInterval; internal static ConfigEntry<float> HuntingPlayerRange; private readonly List<Harmony> _featureHarmonies = new List<Harmony>(); private float _nextUtilityUpdate; private float _nextExtraSlotsFoodUpdate; private int _circletStep; private bool _circletLightOn = true; private Player _circletCachedPlayer; private Light[] _circletCachedLights; private float _nextCircletRescan; private float _nextBossPowerUpdate; private Player _bossHealthTrackedPlayer; private float _bossBaselineMaxHealth; private static readonly string[] ManagedBossEffects = new string[7] { "GP_Eikthyr", "GP_TheElder", "GP_Bonemass", "GP_Moder", "GP_Yagluth", "GP_Queen", "GP_Fader" }; private readonly Dictionary<int, CircletLightOriginal> _circletOriginals = new Dictionary<int, CircletLightOriginal>(); private void Awake() { //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: 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_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_0b7f: Unknown result type (might be due to invalid IL or missing references) //IL_0b89: Expected O, but got Unknown //IL_0bd7: Unknown result type (might be due to invalid IL or missing references) //IL_0c78: Unknown result type (might be due to invalid IL or missing references) //IL_0c82: Expected O, but got Unknown //IL_0cb5: Unknown result type (might be due to invalid IL or missing references) Instance = this; MasterEnabled = Bind("00 - General", "Enabled", value: true, "Master switch for HeimLifeTweaks."); CircletEnabled = Bind("01 - Dverger Circlet", "Enabled", value: true, "Improve the Dverger Circlet light."); CircletBrightness = BindFloat("01 - Dverger Circlet", "Brightness", 2f, 0.25f, 5f, "Circlet light brightness."); CircletRange = BindFloat("01 - Dverger Circlet", "Range", 35f, 5f, 80f, "Maximum circlet beam range."); CircletFocusSteps = BindInt("01 - Dverger Circlet", "Focus Steps", 4, 2, 8, "Number of beam focus steps."); CircletNarrowKey = Bind<KeyboardShortcut>("01 - Dverger Circlet", "Narrow Beam Key", new KeyboardShortcut((KeyCode)91, (KeyCode[])(object)new KeyCode[0]), "Narrow the light beam."); CircletWidenKey = Bind<KeyboardShortcut>("01 - Dverger Circlet", "Widen Beam Key", new KeyboardShortcut((KeyCode)93, (KeyCode[])(object)new KeyCode[0]), "Widen the light beam."); CircletToggleKey = Bind<KeyboardShortcut>("01 - Dverger Circlet", "Toggle Light Key", new KeyboardShortcut((KeyCode)108, (KeyCode[])(object)new KeyCode[0]), "Toggle circlet light on or off."); SkipIntroEnabled = Bind("02 - Skip Intro", "Enabled", value: true, "Skip the startup intro video and logos."); WaterEquipmentEnabled = Bind("03 - Equipment In Water", "Enabled", value: true, "Allow equipment and tools to stay usable while swimming."); FermenterEnabled = Bind("04 - Fermenter", "Enabled", value: true, "Enable fermenter quality-of-life tweaks."); FermenterShowProgress = Bind("04 - Fermenter", "Show Progress", value: true, "Show fermentation progress while hovering."); FermenterMinutes = BindFloat("04 - Fermenter", "Fermentation Minutes", 40f, 1f, 120f, "Minutes required to finish fermenting."); FermenterNoCover = Bind("04 - Fermenter", "Work Without Cover", value: false, "Allow fermenters to work without cover."); NoRainDamageEnabled = Bind("05 - Rain Damage", "No Rain Damage", value: true, "Prevent uncovered structures from taking rain wear."); MapTeleportEnabled = Bind("06 - Map Teleport", "Enabled", value: true, "Hold Shift and press T while the large map is open to teleport to the cursor."); BuildSpaceEnabled = Bind("07 - Build Space", "Enabled", value: true, "Increase crafting-station build radius."); BuildRadiusMultiplier = BindFloat("07 - Build Space", "Build Radius Multiplier", 2f, 1f, 10f, "Multiplier for crafting-station build radius."); FasterBoatsEnabled = Bind("08 - Faster Boats", "Enabled", value: true, "Increase boat movement speed."); BoatWindMultiplier = BindFloat("08 - Faster Boats", "Wind Speed Multiplier", 2.5f, 1f, 5f, "Multiplier for wind-driven sail force."); BoatRudderMultiplier = BindFloat("08 - Faster Boats", "Rudder Speed Multiplier", 2.25f, 1f, 5f, "Multiplier for paddle/rudder force."); QuickCartEnabled = Bind("09 - Quick Cart", "Enabled", value: true, "Quickly attach or detach the nearest cart."); QuickCartHotkey = Bind<KeyboardShortcut>("09 - Quick Cart", "Hotkey", new KeyboardShortcut((KeyCode)118, (KeyCode[])(object)new KeyCode[0]), "Attach/detach the nearest cart."); QuickCartDistance = BindFloat("09 - Quick Cart", "Attach Distance", 5f, 1f, 12f, "Maximum distance to find a cart."); QuickCartOutOfPlace = Bind("09 - Quick Cart", "Allow Out Of Place Attach", value: true, "Allow attaching even if the cart is slightly out of its normal attach position."); RegenerationEnabled = Bind("10 - Regeneration", "Enabled", value: true, "Enable stamina, health, and eitr regeneration tweaks."); StaminaCostMultiplier = BindFloat("10 - Regeneration", "Stamina Cost Multiplier", 1f, 0f, 2f, "0 = no stamina cost, 1 = vanilla, 2 = double."); StaminaRegenMultiplier = BindFloat("10 - Regeneration", "Stamina Regen Multiplier", 1f, 0.1f, 5f, "Multiplier for stamina regeneration."); StaminaRegenDelayMultiplier = BindFloat("10 - Regeneration", "Stamina Regen Delay Multiplier", 1f, 0f, 2f, "Multiplier for stamina regeneration delay."); EitrRegenRate = BindFloat("10 - Regeneration", "Eitr Regen Rate", 5f, 0f, 20f, "Base eitr regeneration rate."); HealthRegenMultiplier = BindFloat("10 - Regeneration", "Health Regen Multiplier", 1f, 0.1f, 5f, "Multiplier for player health regeneration."); HealthRegenDelayMultiplier = BindFloat("10 - Regeneration", "Health Regen Delay Multiplier", 1f, 0.1f, 2f, "Multiplier for food health-regeneration delay."); AutoConsumeExtraSlotsFood = Bind("10 - Regeneration", "Auto Consume ExtraSlots Food", value: true, "Automatically consume food placed in ExtraSlots food slots whenever an active food slot is available."); PathfinderEnabled = Bind("11 - Pathfinder", "Enabled", value: true, "Increase map exploration radius."); PathfinderDisableInDungeons = Bind("11 - Pathfinder", "Disable In Dungeons", value: true, "Automatically suspend Pathfinder map revealing inside instanced dungeons and resume it in the overworld."); LandExploreRadius = BindFloat("11 - Pathfinder", "Land Explore Radius", 200f, 50f, 2000f, "Map reveal radius while travelling on land."); SeaExploreRadius = BindFloat("11 - Pathfinder", "Sea Explore Radius", 300f, 50f, 2000f, "Map reveal radius while attached to a ship."); AltitudeExploreBonus = BindFloat("11 - Pathfinder", "Altitude Bonus", 0.5f, 0f, 2f, "Additional land reveal radius per 100m of altitude, as a multiplier."); CarryWeightEnabled = Bind("12 - Carry Weight", "Enabled", value: true, "Modify maximum carry weight."); CarryWeightMultiplier = BindFloat("12 - Carry Weight", "Carry Weight Multiplier", 2f, 1f, 10f, "Multiplier for maximum carry weight."); FastToolsEnabled = Bind("13 - Fast Tools", "Enabled", value: true, "Speed up hammer/hoe/cultivator placement and removal."); PlaceDelay = BindFloat("13 - Fast Tools", "Place Delay", 0.1f, 0f, 1f, "Delay in seconds between placements. Vanilla is about 0.4."); RemoveDelay = BindFloat("13 - Fast Tools", "Remove Delay", 0.1f, 0f, 1f, "Delay in seconds between removals. Vanilla is about 0.25."); BuildStaminaMultiplier = BindFloat("13 - Fast Tools", "Build Stamina Multiplier", 1f, 0f, 2f, "Multiplier for placement-tool stamina cost."); DigDeeperEnabled = Bind("14 - Dig Deeper", "Enabled", value: true, "Increase terrain digging and raising limits."); DigDepth = BindFloat("14 - Dig Deeper", "Maximum Dig Depth", 16f, 8f, 128f, "Maximum terrain depth. Vanilla is 8."); RaiseHeight = BindFloat("14 - Dig Deeper", "Maximum Raise Height", 16f, 8f, 128f, "Maximum terrain raising height. Vanilla is 8."); BossPowersEnabled = Bind("15 - BossPowers", "Enabled", value: true, "Keep selected unlocked Forsaken powers active passively and permanently."); BossPowersRequireDefeat = Bind("15 - BossPowers", "Require Boss Defeated", value: true, "Only grant a power after its boss has been defeated in this world."); BossEikthyrEnabled = Bind("15 - BossPowers", "Enabled", value: true, "Enable Eikthyr's passive power."); EikthyrRunStaminaReduction = BindFloat("15 - BossPowers", "Run Stamina Reduction %", 60f, 0f, 100f, "Percent less stamina used while running."); EikthyrJumpStaminaReduction = BindFloat("15 - BossPowers", "Jump Stamina Reduction %", 60f, 0f, 100f, "Percent less stamina used while jumping."); EikthyrSwimStaminaReduction = BindFloat("15 - BossPowers", "Swim Stamina Reduction %", 60f, 0f, 100f, "Percent less stamina used while swimming."); BossElderEnabled = Bind("15 - BossPowers", "Enabled", value: true, "Enable The Elder's passive power."); ElderChopDamage = BindFloat("15 - BossPowers", "Chop Damage %", 60f, 0f, 500f, "Bonus chopping damage percent."); ElderPickaxeDamage = BindFloat("15 - BossPowers", "Pickaxe Damage %", 60f, 0f, 500f, "Bonus pickaxe/mining damage percent."); ElderHealthRegen = BindFloat("15 - BossPowers", "Health Regen %", 30f, 0f, 500f, "Bonus health regeneration percent."); BossBonemassEnabled = Bind("15 - BossPowers", "Enabled", value: true, "Enable Bonemass's passive power."); BonemassBluntResistance = BindFloat("15 - BossPowers", "Blunt Resistance %", 25f, 0f, 100f, "Physical resistance setting."); BonemassSlashResistance = BindFloat("15 - BossPowers", "Slash Resistance %", 25f, 0f, 100f, "Physical resistance setting."); BonemassPierceResistance = BindFloat("15 - BossPowers", "Pierce Resistance %", 25f, 0f, 100f, "Physical resistance setting."); BonemassBlockStaminaReduction = BindFloat("15 - BossPowers", "Block Stamina Reduction %", 100f, 0f, 100f, "Percent less stamina used when blocking."); BonemassStaminaReturn = BindFloat("15 - BossPowers", "Stamina Returned Per Block", 5f, 0f, 100f, "Flat stamina returned when blocking."); BossModerEnabled = Bind("15 - BossPowers", "Enabled", value: true, "Enable Moder's passive power."); ModerTailwind = Bind("15 - BossPowers", "Always Tailwind", value: true, "Keep Moder's sailing tailwind effect enabled."); ModerCarryWeight = BindFloat("15 - BossPowers", "Carry Weight Bonus", 300f, 0f, 5000f, "Flat carry weight bonus."); ModerMovementSpeed = BindFloat("15 - BossPowers", "Movement Speed %", 10f, 0f, 500f, "Bonus movement speed percent."); ModerFrostResistance = BindFloat("15 - BossPowers", "Frost Resistance %", 50f, 0f, 100f, "Frost resistance setting."); BossYagluthEnabled = Bind("15 - BossPowers", "Enabled", value: true, "Enable Yagluth's passive power."); YagluthLightningResistance = BindFloat("15 - BossPowers", "Lightning Resistance %", 50f, 0f, 100f, "Lightning resistance setting."); YagluthFarmingSkill = BindFloat("15 - BossPowers", "Farming Skill Bonus", 25f, 0f, 500f, "Flat Farming skill bonus."); YagluthDamage = BindFloat("15 - BossPowers", "Damage %", 10f, 0f, 500f, "Bonus outgoing damage percent."); BossQueenEnabled = Bind("15 - BossPowers", "Enabled", value: true, "Enable The Queen's passive power."); QueenEitrRegen = BindFloat("15 - BossPowers", "Eitr Regen %", 100f, 0f, 1000f, "Bonus Eitr regeneration percent."); QueenSneakStaminaReduction = BindFloat("15 - BossPowers", "Sneak Stamina Reduction %", 100f, 0f, 100f, "Percent less stamina used while sneaking."); QueenPoisonResistance = BindFloat("15 - BossPowers", "Poison Resistance %", 50f, 0f, 100f, "Poison resistance setting."); BossFaderEnabled = Bind("15 - BossPowers", "Enabled", value: true, "Enable Fader's passive power."); FaderAdrenalineGain = BindFloat("15 - BossPowers", "Adrenaline Gain %", 100f, 0f, 1000f, "Bonus Adrenaline gain percent."); FaderStaggerReduction = BindFloat("15 - BossPowers", "Stagger Meter Reduction %", 50f, 0f, 100f, "Percent reduction to the stagger meter modifier."); FaderFireResistance = BindFloat("15 - BossPowers", "Fire Resistance %", 50f, 0f, 100f, "Fire resistance setting."); BeehiveEnabled = Bind("16 - Beehives", "Enabled", value: true, "Enable configurable honey production."); HoneyProductionSeconds = BindFloat("16 - Beehives", "Honey Production Seconds", 600f, 1f, 1200f, "Seconds required to produce one honey. Vanilla is 1200. Minimum is 1 second."); MaximumHoney = ((BaseUnityPlugin)this).Config.Bind<int>("16 - Beehives", "Maximum Honey", 4, new ConfigDescription("Maximum honey stored in each hive. Type the number you want.", (AcceptableValueBase)null, new object[0])); NearbyStorageEnabled = Bind("17 - Nearby Storage", "Enabled", value: true, "Enable nearby storage quality-of-life features."); AutoSortEnabled = Bind("17 - Nearby Storage", "Auto Sort", value: true, "Press the hotkey to move normal backpack items into nearby chests that already contain the same item."); AutoSortHotkey = Bind<KeyboardShortcut>("17 - Nearby Storage", "Auto Sort Hotkey", new KeyboardShortcut((KeyCode)46, (KeyCode[])(object)new KeyCode[0]), "Hotkey for matching-chest auto sort. Default is period (.)."); CraftFromChestsEnabled = Bind("17 - Nearby Storage", "Craft From Chests", value: true, "Crafting can count and consume materials from nearby containers."); BuildFromChestsEnabled = Bind("17 - Nearby Storage", "Build From Chests", value: true, "Building pieces, ships, and other placeables can count and consume materials from nearby containers."); UseItemsFromChestsEnabled = Bind("17 - Nearby Storage", "Use Items From Chests", value: true, "Kilns, smelters, and fireplaces can use required items from nearby containers when you interact with them."); ShowHaveNeedCounts = Bind("17 - Nearby Storage", "Show Have Need Counts", value: true, "Show available / required material counts using inventory plus nearby containers."); StorageRadius = ((BaseUnityPlugin)this).Config.Bind<float>("17 - Nearby Storage", "Storage Radius", 20f, new ConfigDescription("Radius in meters used by nearby storage features. Type any positive value you want.", (AcceptableValueBase)null, new object[0])); RecyclingEnabled = Bind("18 - Recycling", "Enabled", value: true, "Recycle the inventory item under the mouse cursor back into its original recipe materials. Items without a recipe are deleted."); RecyclingHotkey = Bind<KeyboardShortcut>("18 - Recycling", "Recycle Hotkey", new KeyboardShortcut((KeyCode)127, (KeyCode[])(object)new KeyCode[0]), "Recycle or delete the hovered inventory item. Default: Delete."); AutoCraftingEnabled = Bind("19 - AutoCrafting", "Enabled", value: true, "Automatically feed loaded production stations from nearby allowed containers and route finished outputs into matching containers."); AutoCraftingAutoRefillLights = Bind("19 - AutoCrafting", "Auto Refill Lights", value: true, "Automatically refuel Fireplace-based lights and fires from nearby allowed storage."); AutoCraftingRange = BindFloat("19 - AutoCrafting", "Container Range", 20f, 1f, 50f, "Maximum distance in meters from a station to pull from or deposit into containers."); AutoCraftingInterval = BindFloat("19 - AutoCrafting", "Refill Interval Seconds", 1f, 0.25f, 10f, "How often loaded production stations check nearby containers for inputs."); AutoCraftingLeaveOneInput = Bind("19 - AutoCrafting", "Leave One Input In Chest", value: true, "Keep at least one of each station input in its source chest for sorting/reference."); AutoCraftingDepositOutputs = Bind("19 - AutoCrafting", "Deposit Outputs Into Matching Chests", value: true, "Move station outputs into a nearby allowed chest that already contains that item. If none exists or it is full, the output drops normally."); AutoCraftingWoodChests = Bind("19 - AutoCrafting", "Wood Chests", value: true, "Allow basic wooden chests."); AutoCraftingReinforcedChests = Bind("19 - AutoCrafting", "Reinforced Chests", value: true, "Allow reinforced/iron chests."); AutoCraftingBlackMetalChests = Bind("19 - AutoCrafting", "Black Metal Chests", value: true, "Allow black metal chests."); AutoCraftingPersonalChests = Bind("19 - AutoCrafting", "Personal Chests", value: false, "Allow personal/private chests."); AutoCraftingCartContainers = Bind("19 - AutoCrafting", "Cart Storage", value: false, "Allow cart storage."); AutoCraftingShipContainers = Bind("19 - AutoCrafting", "Ship Storage", value: false, "Allow ship storage."); AutoCraftingOtherContainers = Bind("19 - AutoCrafting", "Other Or Modded Containers", value: false, "Allow containers that do not match a known vanilla chest/storage category."); AutoCraftingKilnCharcoalTarget = BindInt("19 - AutoCrafting", "Kiln Charcoal Target", 50, 0, 5000, "Stop automatically feeding wood into charcoal kilns when nearby allowed containers already contain at least this much charcoal. 0 = unlimited."); AutoCraftingKilnWoodTypes = ((BaseUnityPlugin)this).Config.Bind<KilnWoodTypes>("19 - AutoCrafting", "Kiln Wood Types", KilnWoodTypes.Wood, "Select which wood types AutoCrafting may feed into charcoal kilns. Default is regular Wood only. This is a multi-select flags box in Configuration Manager."); AutoCraftingStationsPerTick = BindInt("19 - AutoCrafting", "Stations Processed Per Tick", 2, 1, 20, "Performance control. Lower values spread AutoCrafting work across frames and reduce spikes."); AutoCraftingContainerCacheSeconds = BindFloat("19 - AutoCrafting", "Container Cache Seconds", 3f, 0.5f, 30f, "How long each station reuses its nearby-container list before refreshing it."); AutoCraftingAutoPopCookingStations = Bind("19 - AutoCrafting", "Auto Pop Cooking Stations", value: true, "Automatically eject cooked food as soon as it reaches the finished state so it cannot burn."); HuntingGroundsEnabled = Bind("20 - Hunting Grounds", "Enabled", value: true, "Add placeable hunting-ground spawners for vanilla mobs, labeled and grouped by biome in the hammer Misc category."); HuntingSpawnRadius = BindFloat("20 - Hunting Grounds", "Spawn Radius", 30f, 5f, 50f, "Animals spawn randomly between 5 meters and this radius from their spawner."); HuntingDeerCap = BindInt("20 - Hunting Grounds", "Deer Population Cap", 10, 1, 50, "Maximum deer maintained inside a Deer Spawner's radius."); HuntingBoarCap = BindInt("20 - Hunting Grounds", "Boar Population Cap", 10, 1, 50, "Maximum boars maintained inside a Boar Spawner's radius."); HuntingNeckCap = BindInt("20 - Hunting Grounds", "Neck Population Cap", 10, 1, 50, "Maximum necks maintained inside a Neck Spawner's radius."); HuntingOtherCap = BindInt("20 - Hunting Grounds", "Other Mob Population Cap", 6, 1, 50, "Population cap used by the biome mob spawner variants."); HuntingSpawnInterval = BindFloat("20 - Hunting Grounds", "Spawn Interval Seconds", 15f, 5f, 120f, "When below the local population cap, spawn one animal this often."); HuntingPlayerRange = BindFloat("20 - Hunting Grounds", "Player Activation Range", 100f, 20f, 200f, "Spawner only operates while the local player is within this distance."); ((BaseUnityPlugin)this).Config.SettingChanged += OnAnySettingChanged; RefreshFeaturePatches(); if (AutoCraftingEnabled.Value) { AutoCrafting.RefreshExistingWorldObjects(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"HeimLifeTweaks v1.5.2 loaded."); } private ConfigEntry<T> Bind<T>(string section, string name, T value, string description) { return ((BaseUnityPlugin)this).Config.Bind<T>(section, name, value, description); } private ConfigEntry<float> BindFloat(string section, string name, float value, float min, float max, string description) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown return ((BaseUnityPlugin)this).Config.Bind<float>(section, name, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(min, max), new object[0])); } private ConfigEntry<int> BindInt(string section, string name, int value, int min, int max, string description) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown return ((BaseUnityPlugin)this).Config.Bind<int>(section, name, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<int>(min, max), new object[0])); } private void OnAnySettingChanged(object sender, SettingChangedEventArgs args) { try { if (args == null || args.ChangedSetting == null) { return; } string text = args.ChangedSetting.Definition.Section ?? ""; string text2 = args.ChangedSetting.Definition.Key ?? ""; if (text2 == "Enabled") { RefreshFeaturePatches(); } if (text.StartsWith("15", StringComparison.Ordinal)) { _nextBossPowerUpdate = 0f; } if (text == "19 - AutoCrafting") { AutoCrafting.InvalidateConfigCaches(); if (AutoCraftingEnabled.Value) { AutoCrafting.RefreshExistingWorldObjects(); } } if (text == "20 - Hunting Grounds" && HuntingGroundsEnabled.Value) { HuntingGrounds.EnsureRegistered(); } } catch { } } private void RefreshFeaturePatches() { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown for (int i = 0; i < _featureHarmonies.Count; i++) { try { _featureHarmonies[i].UnpatchSelf(); } catch { } } _featureHarmonies.Clear(); if (!MasterEnabled.Value) { return; } Type[] types = Assembly.GetExecutingAssembly().GetTypes(); foreach (Type type in types) { object[] customAttributes = type.GetCustomAttributes(typeof(HarmonyPatch), inherit: true); if (customAttributes != null && customAttributes.Length != 0 && ShouldPatchFeature(type)) { try { Harmony val = new Harmony("HeimLifeTweaks.Valheim." + type.Name); val.PatchAll(type); _featureHarmonies.Add(val); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Patch failed for " + type.Name + ": " + ex.Message)); } } } } private bool ShouldPatchFeature(Type t) { switch (t.Name) { case "SkipIntroCoroutinePatch": return SkipIntroEnabled.Value; case "EquipmentInWaterUpdatePatch": case "EquipmentInWaterEquipPatch": return WaterEquipmentEnabled.Value; case "FermenterAwakePatch": case "FermenterHoverPatch": case "FermenterCoverPatch": return FermenterEnabled.Value; case "NoRainDamagePatch": return NoRainDamageEnabled.Value; case "BuildSpacePatch": return BuildSpaceEnabled.Value; case "FasterBoatWindPatch": case "FasterBoatRudderPatch": return FasterBoatsEnabled.Value; case "QuickCartAttachPatch": return QuickCartEnabled.Value; case "StaminaUsePatch": case "RegenStatsPatch": case "HealthRegenDelayPatch": case "HealthRegenAmountPatch": return RegenerationEnabled.Value; case "CarryWeightPatch": return CarryWeightEnabled.Value; case "PathfinderPatch": return PathfinderEnabled.Value; case "BuildStaminaPatch": case "FastToolsPlacementPatch": return FastToolsEnabled.Value; case "DigDeeperHeightmapPatch": case "DigDeeperApplyToHeightmapPatch": case "DigDeeperTerrainLevelPatch": case "DigDeeperTerrainRaisePatch": return DigDeeperEnabled.Value; case "BeehiveUpdatePatch": case "BeehiveHoverPatch": return BeehiveEnabled.Value; case "DisableGuardianPowerActivationPatch": case "ElderResourceDamagePatch": return BossPowersEnabled.Value; case "NearbyStorageContainerRegistryPatch": if (!NearbyStorageEnabled.Value) { return AutoCraftingEnabled.Value; } return true; case "NearbyStorageBuildCheckContextPatch": if (NearbyStorageEnabled.Value) { return BuildFromChestsEnabled.Value; } return false; case "NearbyStorageCraftCheckContextPatch": if (NearbyStorageEnabled.Value) { return CraftFromChestsEnabled.Value; } return false; case "NearbyStorageBuildActionContextPatch": if (NearbyStorageEnabled.Value) { return BuildFromChestsEnabled.Value; } return false; case "NearbyStorageCraftActionContextPatch": if (NearbyStorageEnabled.Value) { return CraftFromChestsEnabled.Value; } return false; case "NearbyStorageCountItemsPatch": case "NearbyStorageHaveItemPatch": case "NearbyStorageConsumeResourcesPatch": if (NearbyStorageEnabled.Value) { if (!CraftFromChestsEnabled.Value) { return BuildFromChestsEnabled.Value; } return true; } return false; case "NearbyStorageRequirementUiPatch": if (NearbyStorageEnabled.Value && ShowHaveNeedCounts.Value) { if (!CraftFromChestsEnabled.Value) { return BuildFromChestsEnabled.Value; } return true; } return false; case "NearbyStorageSwitchInteractPatch": case "NearbyStorageFireplaceInteractPatch": if (NearbyStorageEnabled.Value) { return UseItemsFromChestsEnabled.Value; } return false; case "AutoCraftingEitrRefineryRegistryPatch": if (AutoCraftingEnabled.Value) { return AutoCrafting.GetEitrRefineryType() != null; } return false; case "AutoCraftingFireplaceRegistryPatch": case "AutoCraftingSmelterRegistryPatch": case "AutoCraftingCookingStationRegistryPatch": case "AutoCraftingFermenterRegistryPatch": case "AutoCraftingOutputRoutingPatch": case "AutoCraftingMessageSuppressPatch": case "AutoCraftingCookingAutoPopPatch": return AutoCraftingEnabled.Value; case "HuntingGroundsZNetScenePatch": case "HuntingGroundPlacementPatch": case "HuntingGroundMarkerRestorePatch": case "HuntingGroundContainerBlockInteractPatch": return HuntingGroundsEnabled.Value; case "NoRainDamageApplyDamagePatch": return NoRainDamageEnabled.Value; default: return false; } } internal static bool On(ConfigEntry<bool> feature) { if ((Object)(object)Instance != (Object)null && MasterEnabled.Value) { return feature.Value; } return false; } private void OnDestroy() { try { ((BaseUnityPlugin)this).Config.SettingChanged -= OnAnySettingChanged; } catch { } try { for (int i = 0; i < _featureHarmonies.Count; i++) { _featureHarmonies[i].UnpatchSelf(); } } catch { } _featureHarmonies.Clear(); try { RemoveManagedBossPowers(); } catch { } Instance = null; } private void Update() { //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) if (!MasterEnabled.Value) { RestoreCircletLights(); return; } if (!QuickCartEnabled.Value && !MapTeleportEnabled.Value && !CircletEnabled.Value && !BossPowersEnabled.Value && (!NearbyStorageEnabled.Value || !AutoSortEnabled.Value) && !RecyclingEnabled.Value && !AutoCraftingEnabled.Value && !HuntingGroundsEnabled.Value && (!RegenerationEnabled.Value || !AutoConsumeExtraSlotsFood.Value)) { return; } if (HuntingGroundsEnabled.Value) { HuntingGrounds.EnsureRegistered(); HuntingGrounds.Tick(); } if (RegenerationEnabled.Value && AutoConsumeExtraSlotsFood.Value && Time.unscaledTime >= _nextExtraSlotsFoodUpdate) { _nextExtraSlotsFoodUpdate = Time.unscaledTime + 0.75f; RegenerationFoodSlots.TryAutoConsume(Player.m_localPlayer); } if (AutoCraftingEnabled.Value) { AutoCrafting.Tick(); } if (RecyclingEnabled.Value) { KeyboardShortcut value = RecyclingHotkey.Value; if (!((KeyboardShortcut)(ref value)).IsDown()) { KeyboardShortcut value2 = RecyclingHotkey.Value; if (!Input.GetKeyDown(((KeyboardShortcut)(ref value2)).MainKey)) { goto IL_014a; } } Recycling.TryRecycleHoveredItem(Player.m_localPlayer); } goto IL_014a; IL_019a: if (QuickCartEnabled.Value) { KeyboardShortcut value3 = QuickCartHotkey.Value; if (!((KeyboardShortcut)(ref value3)).IsDown()) { KeyboardShortcut value4 = QuickCartHotkey.Value; if (!Input.GetKeyDown(((KeyboardShortcut)(ref value4)).MainKey)) { goto IL_01db; } } TryQuickCart(); } goto IL_01db; IL_01db: if (MapTeleportEnabled.Value && Minimap.IsOpen() && (Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303)) && Input.GetKeyDown((KeyCode)116)) { TryMapTeleport(); } if (CircletEnabled.Value) { KeyboardShortcut value5 = CircletToggleKey.Value; if (((KeyboardShortcut)(ref value5)).IsDown()) { _circletLightOn = !_circletLightOn; } KeyboardShortcut value6 = CircletNarrowKey.Value; if (((KeyboardShortcut)(ref value6)).IsDown()) { _circletStep = Mathf.Max(0, _circletStep - 1); } KeyboardShortcut value7 = CircletWidenKey.Value; if (((KeyboardShortcut)(ref value7)).IsDown()) { _circletStep = Mathf.Min(CircletFocusSteps.Value - 1, _circletStep + 1); } } if (CircletEnabled.Value && Time.time >= _nextUtilityUpdate) { _nextUtilityUpdate = Time.time + 0.5f; ApplyCircletLights(); } else if (!CircletEnabled.Value && _circletCachedLights != null) { RestoreCircletLights(); _circletCachedLights = null; } if (BossPowersEnabled.Value && Time.time >= _nextBossPowerUpdate) { _nextBossPowerUpdate = Time.time + 5f; MaintainBossPowers(); } return; IL_014a: if (NearbyStorageEnabled.Value && AutoSortEnabled.Value) { KeyboardShortcut value8 = AutoSortHotkey.Value; if (!((KeyboardShortcut)(ref value8)).IsDown()) { KeyboardShortcut value9 = AutoSortHotkey.Value; if (!Input.GetKeyDown(((KeyboardShortcut)(ref value9)).MainKey)) { goto IL_019a; } } NearbyStorage.AutoSort(Player.m_localPlayer); } goto IL_019a; } private void MaintainBossPowers() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)ObjectDB.instance == (Object)null) { return; } TrackBossHealthBaseline(localPlayer); try { FieldInfo fieldInfo = AccessTools.Field(typeof(Player), "m_guardianPowerCooldown"); if (fieldInfo != null) { fieldInfo.SetValue(localPlayer, 0f); } } catch { } EnsureBossPower(localPlayer, "GP_Eikthyr", "defeated_eikthyr", BossEikthyrEnabled.Value); EnsureBossPower(localPlayer, "GP_TheElder", "defeated_gdking", BossElderEnabled.Value); EnsureBossPower(localPlayer, "GP_Bonemass", "defeated_bonemass", BossBonemassEnabled.Value); EnsureBossPower(localPlayer, "GP_Moder", "defeated_dragon", BossModerEnabled.Value); EnsureBossPower(localPlayer, "GP_Yagluth", "defeated_goblinking", BossYagluthEnabled.Value); EnsureBossPower(localPlayer, "GP_Queen", "defeated_queen", BossQueenEnabled.Value); EnsureBossPower(localPlayer, "GP_Fader", "defeated_fader", BossFaderEnabled.Value); RestoreBossHealthIfCorrupted(localPlayer); } private void TrackBossHealthBaseline(Player player) { if ((Object)(object)player == (Object)null) { return; } if ((Object)(object)_bossHealthTrackedPlayer != (Object)(object)player) { _bossHealthTrackedPlayer = player; _bossBaselineMaxHealth = 0f; } try { float maxHealth = ((Character)player).GetMaxHealth(); if (maxHealth > _bossBaselineMaxHealth) { _bossBaselineMaxHealth = maxHealth; } } catch { } } private void RestoreBossHealthIfCorrupted(Player player) { if ((Object)(object)player == (Object)null || _bossBaselineMaxHealth <= 0f) { return; } float maxHealth; try { maxHealth = ((Character)player).GetMaxHealth(); } catch { return; } if (maxHealth >= _bossBaselineMaxHealth * 0.5f) { return; } TrySetMaxHealth((Character)(object)player, _bossBaselineMaxHealth); try { float health = ((Character)player).GetHealth(); if (health > _bossBaselineMaxHealth) { ((Character)player).SetHealth(_bossBaselineMaxHealth); } } catch { } ((BaseUnityPlugin)this).Logger.LogWarning((object)("Boss Power safety restored max health from " + maxHealth.ToString("0.##") + " to " + _bossBaselineMaxHealth.ToString("0.##") + ".")); } private static void TrySetMaxHealth(Character character, float value) { if ((Object)(object)character == (Object)null || value <= 0f) { return; } try { MethodInfo[] methods = ((object)character).GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name != "SetMaxHealth") { continue; } ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length < 1 || parameters[0].ParameterType != typeof(float)) { continue; } object[] array = new object[parameters.Length]; array[0] = value; bool flag = true; for (int j = 1; j < parameters.Length; j++) { Type parameterType = parameters[j].ParameterType; if (parameterType == typeof(bool)) { array[j] = false; continue; } if (parameterType == typeof(float)) { array[j] = 0f; continue; } if (parameterType == typeof(int)) { array[j] = 0; continue; } if (!parameterType.IsValueType) { array[j] = null; continue; } flag = false; break; } if (flag) { methodInfo.Invoke(character, array); break; } } } catch { } } private bool HasGlobalKey(string key) { if (!BossPowersRequireDefeat.Value) { return true; } if ((Object)(object)ZoneSystem.instance == (Object)null) { return false; } try { MethodInfo methodInfo = AccessTools.Method(typeof(ZoneSystem), "GetGlobalKey", new Type[1] { typeof(string) }, (Type[])null); if (methodInfo != null) { return Convert.ToBoolean(methodInfo.Invoke(ZoneSystem.instance, new object[1] { key })); } } catch { } return false; } private void EnsureBossPower(Player player, string effectName, string globalKey, bool enabled) { if (!enabled || !HasGlobalKey(globalKey)) { RemoveBossPower(player, effectName); return; } int stableHash = GetStableHash(effectName); try { MethodInfo methodInfo = AccessTools.Method(typeof(SEMan), "HaveStatusEffect", new Type[1] { typeof(int) }, (Type[])null); if (methodInfo != null && Convert.ToBoolean(methodInfo.Invoke(((Character)player).GetSEMan(), new object[1] { stableHash }))) { return; } } catch { } StatusEffect val = FindStatusEffect(effectName); if ((Object)(object)val == (Object)null) { return; } Dictionary<FieldInfo, object> dictionary = new Dictionary<FieldInfo, object>(); try { ApplyBossPowerSettings(val, effectName, dictionary); FieldInfo fieldInfo = AccessTools.Field(((object)val).GetType(), "m_ttl"); if (fieldInfo != null) { if (!dictionary.ContainsKey(fieldInfo)) { dictionary[fieldInfo] = fieldInfo.GetValue(val); } fieldInfo.SetValue(val, 0f); } FieldInfo fieldInfo2 = AccessTools.Field(((object)val).GetType(), "m_cooldown"); if (fieldInfo2 != null) { if (!dictionary.ContainsKey(fieldInfo2)) { dictionary[fieldInfo2] = fieldInfo2.GetValue(val); } fieldInfo2.SetValue(val, 0f); } ((Character)player).GetSEMan().AddStatusEffect(stableHash, false, 0, 0f, (short)(-1)); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Boss power " + effectName + " failed: " + ex.Message)); } finally { foreach (KeyValuePair<FieldInfo, object> item in dictionary) { try { item.Key.SetValue(val, item.Value); } catch { } } } } private void ApplyBossPowerSettings(StatusEffect effect, string effectName, Dictionary<FieldInfo, object> originals) { if ((Object)(object)effect == (Object)null) { return; } switch (effectName) { case "GP_Eikthyr": SetBossFloat(effect, originals, new string[2] { "m_runStaminaUseModifier", "m_runStaminaDrainModifier" }, (0f - EikthyrRunStaminaReduction.Value) / 100f); SetBossFloat(effect, originals, new string[1] { "m_jumpStaminaUseModifier" }, (0f - EikthyrJumpStaminaReduction.Value) / 100f); SetBossFloat(effect, originals, new string[1] { "m_swimStaminaUseModifier" }, (0f - EikthyrSwimStaminaReduction.Value) / 100f); break; case "GP_TheElder": SetBossFloat(effect, originals, new string[1] { "m_healthRegenMultiplier" }, 1f + ElderHealthRegen.Value / 100f); break; case "GP_Bonemass": SetBossFloat(effect, originals, new string[1] { "m_blockStaminaUseModifier" }, (0f - BonemassBlockStaminaReduction.Value) / 100f); SetKeywordFloat(effect, originals, new string[2] { "block", "stamina" }, new string[2] { "use", "modifier" }, BonemassStaminaReturn.Value); SetResistance(effect, "blunt", BonemassBluntResistance.Value); SetResistance(effect, "slash", BonemassSlashResistance.Value); SetResistance(effect, "pierce", BonemassPierceResistance.Value); break; case "GP_Moder": SetBossFloat(effect, originals, new string[1] { "m_addMaxCarryWeight" }, ModerCarryWeight.Value); SetBossFloat(effect, originals, new string[1] { "m_speedModifier" }, ModerMovementSpeed.Value / 100f); SetResistance(effect, "frost", ModerFrostResistance.Value); if (!ModerTailwind.Value) { ClearSailingPowerAttribute(effect, originals); } break; case "GP_Yagluth": SetResistance(effect, "lightning", YagluthLightningResistance.Value); SetKeywordFloat(effect, originals, new string[1] { "skill" }, null, YagluthFarmingSkill.Value); SetBossFloat(effect, originals, new string[1] { "m_damageModifier" }, 1f + YagluthDamage.Value / 100f); break; case "GP_Queen": SetBossFloat(effect, originals, new string[1] { "m_eitrRegenMultiplier" }, 1f + QueenEitrRegen.Value / 100f); SetBossFloat(effect, originals, new string[1] { "m_sneakStaminaUseModifier" }, (0f - QueenSneakStaminaReduction.Value) / 100f); SetResistance(effect, "poison", QueenPoisonResistance.Value); break; case "GP_Fader": SetKeywordFloat(effect, originals, new string[1] { "adrenaline" }, null, FaderAdrenalineGain.Value / 100f); SetBossFloat(effect, originals, new string[1] { "m_staggerModifier" }, (0f - FaderStaggerReduction.Value) / 100f); SetResistance(effect, "fire", FaderFireResistance.Value); break; } } private static FieldInfo FindFieldInHierarchy(Type type, string name) { while (type != null) { FieldInfo field = type.GetField(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return field; } type = type.BaseType; } return null; } private static void SetBossFloat(StatusEffect effect, Dictionary<FieldInfo, object> originals, string[] fieldNames, float value) { for (int i = 0; i < fieldNames.Length; i++) { FieldInfo fieldInfo = FindFieldInHierarchy(((object)effect).GetType(), fieldNames[i]); if (!(fieldInfo == null) && !(fieldInfo.FieldType != typeof(float))) { if (!originals.ContainsKey(fieldInfo)) { originals[fieldInfo] = fieldInfo.GetValue(effect); } fieldInfo.SetValue(effect, value); } } } private static void SetKeywordFloat(StatusEffect effect, Dictionary<FieldInfo, object> originals, string[] include, string[] exclude, float desiredPositiveValue) { Type type = ((object)effect).GetType(); while (type != null) { FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (fieldInfo.FieldType != typeof(float)) { continue; } string text = fieldInfo.Name.ToLowerInvariant(); bool flag = true; for (int j = 0; j < include.Length; j++) { if (!text.Contains(include[j])) { flag = false; break; } } if (!flag) { continue; } if (exclude != null) { for (int k = 0; k < exclude.Length; k++) { if (text.Contains(exclude[k])) { flag = false; break; } } } if (!flag) { continue; } float num = Convert.ToSingle(fieldInfo.GetValue(effect)); if (!(Math.Abs(num) < 0.0001f)) { if (!originals.ContainsKey(fieldInfo)) { originals[fieldInfo] = num; } fieldInfo.SetValue(effect, (num < 0f) ? (0f - Math.Abs(desiredPositiveValue)) : Math.Abs(desiredPositiveValue)); } } type = type.BaseType; } } private static void SetNamedNumericValue(object root, string token, float value) { if (root == null) { return; } Type type = root.GetType(); while (type != null) { FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); for (int i = 0; i < fields.Length; i++) { object value2; try { value2 = fields[i].GetValue(root); } catch { continue; } if (!(value2 is IEnumerable enumerable) || value2 is string) { continue; } foreach (object item in enumerable) { if (item == null) { continue; } FieldInfo[] fields2 = item.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); string text = item.ToString().ToLowerInvariant(); for (int j = 0; j < fields2.Length; j++) { if (!fields2[j].FieldType.IsEnum && !(fields2[j].FieldType == typeof(string))) { continue; } try { object value3 = fields2[j].GetValue(item); if (value3 != null) { text = text + " " + value3.ToString().ToLowerInvariant(); } } catch { } } if (!text.Contains(token.ToLowerInvariant())) { continue; } foreach (FieldInfo fieldInfo in fields2) { if (fieldInfo.FieldType != typeof(float)) { continue; } float num; try { num = Convert.ToSingle(fieldInfo.GetValue(item)); } catch { continue; } if (!(Math.Abs(num) < 0.0001f)) { try { fieldInfo.SetValue(item, (num < 0f) ? (0f - Math.Abs(value)) : Math.Abs(value)); } catch { } } } } } type = type.BaseType; } } private static void SetResistance(StatusEffect effect, string damageToken, float percent) { if ((Object)(object)effect == (Object)null) { return; } string b = ((percent <= 0.1f) ? "Normal" : ((percent < 37.5f) ? "SlightlyResistant" : ((percent < 62.5f) ? "Resistant" : ((percent < 87.5f) ? "VeryResistant" : "Immune")))); Type type = ((object)effect).GetType(); while (type != null) { FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); for (int i = 0; i < fields.Length; i++) { object value; try { value = fields[i].GetValue(effect); } catch { continue; } if (!(value is IEnumerable enumerable) || value is string) { continue; } foreach (object item in enumerable) { if (item == null) { continue; } FieldInfo[] fields2 = item.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); bool flag = false; for (int j = 0; j < fields2.Length; j++) { if (!fields2[j].FieldType.IsEnum && fields2[j].FieldType != typeof(string)) { continue; } try { object value2 = fields2[j].GetValue(item); if (value2 != null && value2.ToString().IndexOf(damageToken, StringComparison.OrdinalIgnoreCase) >= 0) { flag = true; } } catch { } } if (!flag) { continue; } foreach (FieldInfo fieldInfo in fields2) { if (!fieldInfo.FieldType.IsEnum) { continue; } Array values = Enum.GetValues(fieldInfo.FieldType); foreach (object item2 in values) { if (string.Equals(item2.ToString(), b, StringComparison.OrdinalIgnoreCase)) { try { fieldInfo.SetValue(item, item2); } catch { } break; } } } } } type = type.BaseType; } } private static void ClearSailingPowerAttribute(StatusEffect effect, Dictionary<FieldInfo, object> originals) { Type type = ((object)effect).GetType(); while (type != null) { FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (!fieldInfo.FieldType.IsEnum) { continue; } object value = fieldInfo.GetValue(effect); if (value != null && value.ToString().IndexOf("SailingPower", StringComparison.OrdinalIgnoreCase) >= 0) { if (!originals.ContainsKey(fieldInfo)) { originals[fieldInfo] = value; } fieldInfo.SetValue(effect, Enum.ToObject(fieldInfo.FieldType, 0)); } } type = type.BaseType; } } private static int GetStableHash(string text) { if (string.IsNullOrEmpty(text)) { return 0; } int num = 5381; int num2 = 5381; for (int i = 0; i < text.Length; i += 2) { num = ((num << 5) + num) ^ text[i]; if (i == text.Length - 1) { break; } num2 = ((num2 << 5) + num2) ^ text[i + 1]; } return num + num2 * 1566083941; } private StatusEffect FindStatusEffect(string effectName) { try { FieldInfo fieldInfo = AccessTools.Field(typeof(ObjectDB), "m_StatusEffects"); IList list = ((fieldInfo == null) ? null : (fieldInfo.GetValue(ObjectDB.instance) as IList)); if (list == null) { return null; } for (int i = 0; i < list.Count; i++) { object? obj = list[i]; StatusEffect val = (StatusEffect)((obj is StatusEffect) ? obj : null); if ((Object)(object)val != (Object)null && ((Object)val).name == effectName) { return val; } } } catch { } return null; } private void RemoveBossPower(Player player, string effectName) { if ((Object)(object)player == (Object)null) { return; } try { MethodInfo methodInfo = AccessTools.Method(typeof(SEMan), "RemoveStatusEffect", new Type[2] { typeof(int), typeof(bool) }, (Type[])null); if (methodInfo != null) { methodInfo.Invoke(((Character)player).GetSEMan(), new object[2] { GetStableHash(effectName), true }); } } catch { } } internal static bool IsBossPowerAvailable(ConfigEntry<bool> bossEnabled, string globalKey) { if ((Object)(object)Instance == (Object)null || MasterEnabled == null || !MasterEnabled.Value || BossPowersEnabled == null || !BossPowersEnabled.Value || bossEnabled == null || !bossEnabled.Value) { return false; } if (BossPowersRequireDefeat == null || !BossPowersRequireDefeat.Value) { return true; } if ((Object)(object)ZoneSystem.instance == (Object)null) { return false; } try { MethodInfo methodInfo = AccessTools.Method(typeof(ZoneSystem), "GetGlobalKey", new Type[1] { typeof(string) }, (Type[])null); if (methodInfo != null) { return Convert.ToBoolean(methodInfo.Invoke(ZoneSystem.instance, new object[1] { globalKey })); } } catch { } return false; } private void RemoveManagedBossPowers() { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { for (int i = 0; i < ManagedBossEffects.Length; i++) { RemoveBossPower(localPlayer, ManagedBossEffects[i]); } } } private void ApplyCircletLights() { //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } if (!IsDvergerCircletEquipped(localPlayer)) { RestoreCircletLights(); _circletCachedPlayer = localPlayer; _circletCachedLights = null; return; } if ((Object)(object)_circletCachedPlayer != (Object)(object)localPlayer || _circletCachedLights == null || Time.time >= _nextCircletRescan) { _circletCachedPlayer = localPlayer; _nextCircletRescan = Time.time + 2f; Light[] componentsInChildren = ((Component)localPlayer).GetComponentsInChildren<Light>(true); List<Light> list = new List<Light>(); foreach (Light val in componentsInChildren) { if ((Object)(object)val == (Object)null) { continue; } string text = GetTransformPath(((Component)val).transform).ToLowerInvariant(); bool flag = text.IndexOf("dverger") >= 0 || text.IndexOf("circlet") >= 0 || text.IndexOf("headlamp") >= 0; bool flag2 = (int)val.type == 0 && ((Component)val).transform.IsChildOf(((Component)localPlayer).transform); if (flag || flag2) { if (!list.Contains(val)) { list.Add(val); } RememberCircletOriginal(val); } } _circletCachedLights = list.ToArray(); } if (_circletCachedLights == null || _circletCachedLights.Length == 0) { return; } int num = Mathf.Max(2, CircletFocusSteps.Value); _circletStep = Mathf.Clamp(_circletStep, 0, num - 1); float num2 = Mathf.Clamp01((float)_circletStep / (float)(num - 1)); float range = Mathf.Lerp(CircletRange.Value * 0.55f, CircletRange.Value, num2); float spotAngle = Mathf.Lerp(28f, 80f, num2); float intensity = Mathf.Lerp(CircletBrightness.Value * 1.5f, CircletBrightness.Value * 0.7f, num2); for (int j = 0; j < _circletCachedLights.Length; j++) { Light val2 = _circletCachedLights[j]; if (!((Object)(object)val2 == (Object)null)) { ((Behaviour)val2).enabled = _circletLightOn; val2.range = range; val2.intensity = intensity; val2.color = new Color(0.95f, 0.98f, 1f, 1f); if ((int)val2.type == 0) { val2.spotAngle = spotAngle; } } } } private void RememberCircletOriginal(Light light) { //IL_005f: 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) if (!((Object)(object)light == (Object)null)) { int instanceID = ((Object)light).GetInstanceID(); if (!_circletOriginals.ContainsKey(instanceID)) { _circletOriginals[instanceID] = new CircletLightOriginal { Enabled = ((Behaviour)light).enabled, Range = light.range, Intensity = light.intensity, SpotAngle = light.spotAngle, Color = light.color }; } } } private void RestoreCircletLights() { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) if (_circletCachedLights == null) { return; } for (int i = 0; i < _circletCachedLights.Length; i++) { Light val = _circletCachedLights[i]; if (!((Object)(object)val == (Object)null) && _circletOriginals.TryGetValue(((Object)val).GetInstanceID(), out var value) && value != null) { ((Behaviour)val).enabled = value.Enabled; val.range = value.Range; val.intensity = value.Intensity; if ((int)val.type == 0) { val.spotAngle = value.SpotAngle; } val.color = value.Color; } } } private static bool IsDvergerCircletEquipped(Player player) { if ((Object)(object)player == (Object)null) { return false; } Type type = ((object)player).GetType(); while (type != null) { FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (typeof(ItemData).IsAssignableFrom(fieldInfo.FieldType)) { ItemData item = null; try { object? value = fieldInfo.GetValue(player); item = (ItemData)((value is ItemData) ? value : null); } catch { } if (IsDvergerCircletItem(item)) { return true; } } } type = type.BaseType; } try { Inventory inventory = ((Humanoid)player).GetInventory(); List<ItemData> list = ((inventory == null) ? null : inventory.GetAllItems()); if (list != null) { for (int j = 0; j < list.Count; j++) { ItemData val = list[j]; if (!IsDvergerCircletItem(val)) { continue; } bool flag = false; try { FieldInfo fieldInfo2 = AccessTools.Field(((object)val).GetType(), "m_equipped"); if (fieldInfo2 != null) { flag = Convert.ToBoolean(fieldInfo2.GetValue(val)); } } catch { } if (flag) { return true; } } } } catch { } return false; } private static bool IsDvergerCircletItem(ItemData item) { if (item == null || item.m_shared == null) { return false; } string text = (item.m_shared.m_name ?? "") + " " + (((Object)(object)item.m_dropPrefab == (Object)null) ? "" : (((Object)item.m_dropPrefab).name ?? "")); text = text.ToLowerInvariant(); if (text.IndexOf("dverger") >= 0) { if (text.IndexOf("circlet") < 0) { return text.IndexOf("helmet") >= 0; } return true; } return false; } private static string GetTransformPath(Transform t) { string text = (((Object)(object)t == (Object)null) ? "" : ((Object)t).name); while ((Object)(object)t != (Object)null && (Object)(object)t.parent != (Object)null) { t = t.parent; text = ((Object)t).name + "/" + text; } return text; } private void TryMapTeleport() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //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_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; Minimap instance = Minimap.instance; if ((Object)(object)localPlayer == (Object)null || (Object)(object)instance == (Object)null) { return; } try { MethodInfo methodInfo = AccessTools.Method(typeof(Minimap), "ScreenToWorldPoint", new Type[1] { typeof(Vector3) }, (Type[])null); if (methodInfo == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Map Teleport: Minimap.ScreenToWorldPoint was not found."); return; } Vector3 val = (Vector3)methodInfo.Invoke(instance, new object[1] { Input.mousePosition }); if (val == Vector3.zero) { return; } if (WorldGenerator.instance != null) { val.y = WorldGenerator.instance.GetHeight(val.x, val.z) + 1.5f; } else if ((Object)(object)ZoneSystem.instance != (Object)null) { val.y = ZoneSystem.instance.GetGroundHeight(val) + 1.5f; } ((Character)localPlayer).TeleportTo(val, ((Component)localPlayer).transform.rotation, true); try { MethodInfo methodInfo2 = AccessTools.Method(typeof(Minimap), "SetMapMode", (Type[])null, (Type[])null); if (methodInfo2 != null) { ParameterInfo[] parameters = methodInfo2.GetParameters(); if (parameters.Length == 1 && parameters[0].ParameterType.IsEnum) { object obj = Enum.ToObject(parameters[0].ParameterType, 1); methodInfo2.Invoke(instance, new object[1] { obj }); } } } catch { } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Map Teleport failed: " + ex.Message)); } } private void TryQuickCart() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } float num = QuickCartDistance.Value; Vagon val = null; Vector3 val2 = ((Component)localPlayer).transform.position + Vector3.up; Collider[] array = Physics.OverlapSphere(val2, QuickCartDistance.Value); foreach (Collider val3 in array) { if ((Object)(object)val3 == (Object)null || (Object)(object)val3.attachedRigidbody == (Object)null) { continue; } Vagon component = ((Component)val3).gameObject.GetComponent<Vagon>(); if ((Object)(object)component == (Object)null && (Object)(object)((Component)val3).transform.parent != (Object)null) { component = ((Component)((Component)val3).transform.parent).gameObject.GetComponent<Vagon>(); } if ((Object)(object)component == (Object)null) { continue; } float num2 = Vector3.Distance(val3.ClosestPoint(val2), val2); if (!(num2 >= num) && (component.IsAttached((Character)(object)localPlayer) || !component.InUse())) { num = num2; if ((Object)(object)((Component)val3).transform.parent != (Object)null) { Vagon component2 = ((Component)((Component)val3).transform.parent).gameObject.GetComponent<Vagon>(); val = (((Object)(object)component2 != (Object)null) ? component2 : component); } else { val = component; } } } if ((Object)(object)val != (Object)null) { val.Interact((Humanoid)(object)localPlayer, false, false); } } internal static float ComputeExploreRadius(Player player) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return LandExploreRadius.Value; } bool flag = false; try { flag = ((Character)player).IsAttachedToShip(); } catch { } float num = (flag ? SeaExploreRadius.Value : LandExploreRadius.Value); if (!flag) { float num2 = Mathf.Max(0f, ((Component)player).transform.position.y - 30f); num += LandExploreRadius.Value * AltitudeExploreBonus.Value * (num2 / 100f); } return Mathf.Clamp(num, 0f, 10000f); } } [HarmonyPatch] internal static class SkipIntroCoroutinePatch { private static MethodBase TargetMethod() { Type typeFromHandle = typeof(FejdStartup); Type[] nestedTypes = typeFromHandle.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic); for (int i = 0; i < nestedTypes.Length; i++) { string name = nestedTypes[i].Name; if (name.IndexOf("PlayIntroCinematic", StringComparison.OrdinalIgnoreCase) >= 0) { MethodInfo methodInfo = AccessTools.Method(nestedTypes[i], "MoveNext", (Type[])null, (Type[])null); if (methodInfo != null && methodInfo.ReturnType == typeof(bool)) { return methodInfo; } } } return null; } private static bool Prefix(ref bool __result) { if (HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.SkipIntroEnabled)) { __result = false; return false; } return true; } } internal static class EquipmentInWaterUtil { public static bool IsSwimmingForEquipment(Character character) { if (HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.WaterEquipmentEnabled)) { return false; } return character.IsSwimming(); } public static IEnumerable<CodeInstruction> ReplaceSwimmingCheck(IEnumerable<CodeInstruction> instructions) { MethodInfo swimming = AccessTools.Method(typeof(Character), "IsSwimming", (Type[])null, (Type[])null); MethodInfo replacement = AccessTools.Method(typeof(EquipmentInWaterUtil), "IsSwimmingForEquipment", (Type[])null, (Type[])null); foreach (CodeInstruction code in instructions) { if ((code.opcode == OpCodes.Call || code.opcode == OpCodes.Callvirt) && code.operand is MethodInfo && (MethodInfo)code.operand == swimming) { yield return new CodeInstruction(OpCodes.Call, (object)replacement); } else { yield return code; } } } } [HarmonyPatch(typeof(Humanoid), "UpdateEquipment")] internal static class EquipmentInWaterUpdatePatch { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { return EquipmentInWaterUtil.ReplaceSwimmingCheck(instructions); } } [HarmonyPatch(typeof(Humanoid), "EquipItem")] internal static class EquipmentInWaterEquipPatch { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { return EquipmentInWaterUtil.ReplaceSwimmingCheck(instructions); } } [HarmonyPatch(typeof(Fermenter), "Awake")] internal static class FermenterAwakePatch { private static void Postfix(Fermenter __instance) { if (HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.FermenterEnabled)) { FieldInfo fieldInfo = AccessTools.Field(typeof(Fermenter), "m_fermentationDuration"); if (fieldInfo != null) { fieldInfo.SetValue(__instance, HeimLifeTweaksPlugin.FermenterMinutes.Value * 60f); } } } } [HarmonyPatch(typeof(Fermenter), "GetHoverText")] internal static class FermenterHoverPatch { private static void Postfix(Fermenter __instance, ref string __result) { if (!HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.FermenterEnabled) || !HeimLifeTweaksPlugin.FermenterShowProgress.Value) { return; } try { MethodInfo methodInfo = AccessTools.Method(typeof(Fermenter), "GetStatus", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(Fermenter), "GetFermentationTime", (Type[])null, (Type[])null); if (!(methodInfo == null) && !(methodInfo2 == null)) { object obj = methodInfo.Invoke(__instance, null); if (obj != null && obj.ToString().IndexOf("Fermenting", StringComparison.OrdinalIgnoreCase) >= 0) { object value = methodInfo2.Invoke(__instance, null); float num = Convert.ToSingle(value); float num2 = Mathf.Max(1f, HeimLifeTweaksPlugin.FermenterMinutes.Value * 60f); float num3 = Mathf.Clamp01(num / num2) * 100f; __result = __result + "\n<color=#FFD36A>" + num3.ToString("0") + "%</color>"; } } } catch { } } } [HarmonyPatch(typeof(Fermenter), "GetStatus")] internal static class FermenterCoverPatch { private static void Postfix(ref object __result) { if (!HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.FermenterEnabled) || !HeimLifeTweaksPlugin.FermenterNoCover.Value || __result == null) { return; } Type type = __result.GetType(); if (!type.IsEnum) { return; } string text = __result.ToString(); if (text.IndexOf("Cover", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("Exposed", StringComparison.OrdinalIgnoreCase) < 0) { return; } try { object obj = Enum.Parse(type, "Fermenting"); __result = obj; } catch { } } } [HarmonyPatch(typeof(CraftingStation), "Start")] internal static class BuildSpacePatch { private static void Postfix(CraftingStation __instance) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) if (!HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.BuildSpaceEnabled)) { return; } try { FieldInfo fieldInfo = AccessTools.Field(typeof(CraftingStation), "m_rangeBuild"); if (!(fieldInfo == null)) { float num = Convert.ToSingle(fieldInfo.GetValue(__instance)); fieldInfo.SetValue(__instance, num * HeimLifeTweaksPlugin.BuildRadiusMultiplier.Value); FieldInfo fieldInfo2 = AccessTools.Field(typeof(CraftingStation), "m_areaMarker"); GameObject val = (GameObject)((fieldInfo2 == null) ? null : /*isinst with value type is only supported in some contexts*/); if ((Object)(object)val != (Object)null) { Transform transform = val.transform; transform.localScale *= HeimLifeTweaksPlugin.BuildRadiusMultiplier.Value; } } } catch { } } } [HarmonyPatch(typeof(Ship), "GetSailForce")] internal static class FasterBoatWindPatch { private static void Postfix(ref Vector3 __result) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //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) if (HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.FasterBoatsEnabled)) { __result *= HeimLifeTweaksPlugin.BoatWindMultiplier.Value; } } } [HarmonyPatch(typeof(Ship), "Awake")] internal static class FasterBoatRudderPatch { private static void Postfix(Ship __instance) { if (!HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.FasterBoatsEnabled)) { return; } FieldInfo fieldInfo = AccessTools.Field(typeof(Ship), "m_backwardForce"); if (fieldInfo == null) { return; } try { float num = Convert.ToSingle(fieldInfo.GetValue(__instance)); fieldInfo.SetValue(__instance, num * HeimLifeTweaksPlugin.BoatRudderMultiplier.Value); } catch { } } } [HarmonyPatch(typeof(Vagon), "CanAttach")] internal static class QuickCartAttachPatch { private static bool Prefix(Vagon __instance, GameObject go, ref bool __result) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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_0087: Unknown result type (might be due to invalid IL or missing references) if (!HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.QuickCartEnabled) || !HeimLifeTweaksPlugin.QuickCartOutOfPlace.Value || (Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)go != (Object)(object)((Component)Player.m_localPlayer).gameObject) { return true; } if (((Component)__instance).transform.up.y < 0.1f) { return true; } try { __result = !((Character)Player.m_localPlayer).IsTeleporting() && !((Character)Player.m_localPlayer).InDodge() && Vector3.Distance(go.transform.position + __instance.m_attachOffset, __instance.m_attachPoint.position) < HeimLifeTweaksPlugin.QuickCartDistance.Value; return false; } catch { return true; } } } [HarmonyPatch(typeof(Player), "UseStamina")] internal static class StaminaUsePatch { private static void Prefix(ref float v) { if (HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.RegenerationEnabled)) { v *= HeimLifeTweaksPlugin.StaminaCostMultiplier.Value; } } } [HarmonyPatch] internal static class RegenStatsPatch { private static IEnumerable<MethodBase> TargetMethods() { MethodInfo[] methods = typeof(Player).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo method in methods) { if (!(method == null) && !(method.Name != "UpdateStats") && !method.IsStatic && !(method.ReturnType != typeof(void))) { ParameterInfo[] p = method.GetParameters(); if (p.Length != 0 && !(p[0].ParameterType != typeof(float))) { yield return method; } } } } private static void Prefix(Player __instance, ref float __state) { __state = 0f; if (HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.RegenerationEnabled)) { FieldInfo fieldInfo = AccessTools.Field(typeof(Player), "m_stamina"); FieldInfo fieldInfo2 = AccessTools.Field(typeof(Player), "m_staminaRegenTimer"); FieldInfo fieldInfo3 = AccessTools.Field(typeof(Player), "m_eiterRegen"); if (fieldInfo != null) { __state = Convert.ToSingle(fieldInfo.GetValue(__instance)); } if (fieldInfo2 != null) { float num = Convert.ToSingle(fieldInfo2.GetValue(__instance)); fieldInfo2.SetValue(__instance, num * HeimLifeTweaksPlugin.StaminaRegenDelayMultiplier.Value); } if (fieldInfo3 != null) { fieldInfo3.SetValue(__instance, HeimLifeTweaksPlugin.EitrRegenRate.Value); } } } private static void Postfix(Player __instance, float __state) { if (!HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.RegenerationEnabled)) { return; } FieldInfo fieldInfo = AccessTools.Field(typeof(Player), "m_stamina"); if (!(fieldInfo == null)) { float num = Convert.ToSingle(fieldInfo.GetValue(__instance)); if (__state > 0f && num > __state) { fieldInfo.SetValue(__instance, __state + (num - __state) * HeimLifeTweaksPlugin.StaminaRegenMultiplier.Value); } } } } [HarmonyPatch(typeof(Player), "UpdateFood")] internal static class HealthRegenDelayPatch { private static void Prefix(float dt, bool forceUpdate, ref float ___m_foodRegenTimer) { if (HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.RegenerationEnabled) && !forceUpdate) { float num = Mathf.Max(0.1f, HeimLifeTweaksPlugin.HealthRegenDelayMultiplier.Value); ___m_foodRegenTimer += dt / num - dt; } } } [HarmonyPatch(typeof(Character), "Heal")] internal static class HealthRegenAmountPatch { private static void Prefix(Character __instance, ref float hp) { if (HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.RegenerationEnabled) && __instance is Player) { hp *= HeimLifeTweaksPlugin.HealthRegenMultiplier.Value; } } } internal static class RegenerationFoodSlots { private static bool _apiResolved; private static MethodInfo _getFoodSlotsItems; private static MethodInfo _useItemMethod; private static MethodInfo _consumeItemMethod; private static MethodInfo _canConsumeItemMethod; private static bool _canConsumeResolved; internal static void TryAutoConsume(Player player) { if ((Object)(object)player == (Object)null || !HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.RegenerationEnabled) || !HeimLifeTweaksPlugin.AutoConsumeExtraSlotsFood.Value) { return; } List<ItemData> extraSlotsFoodItems = GetExtraSlotsFoodItems(); if (extraSlotsFoodItems == null || extraSlotsFoodItems.Count == 0) { return; } int activeFoodCount = GetActiveFoodCount(player); for (int i = 0; i < extraSlotsFoodItems.Count; i++) { ItemData item = extraSlotsFoodItems[i]; if (!IsValidFoodItem(item)) { continue; } if (IsFoodActive(player, item)) { if (!IsFoodAtBlinkStage(player, item)) { continue; } } else if (activeFoodCount >= 3) { continue; } if (TryUseFood(player, item)) { break; } } } private static bool IsValidFoodItem(ItemData item) { if (item != null && item.m_stack > 0 && item.m_shared != null) { return item.m_shared.m_food > 0f; } return false; } private static bool ResolveCanConsumeMethod(Type playerType) { if (_canConsumeResolved) { return _canConsumeItemMethod != null; } _canConsumeResolved = true; if (playerType == null) { return false; } try { MethodInfo[] methods = playerType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name != "CanConsumeItem" || methodInfo.ReturnType != typeof(bool)) { continue; } ParameterInfo[] parameters = methodInfo.GetParameters(); bool flag = false; bool flag2 = true; for (int j = 0; j < parameters.Length; j++) { Type parameterType = parameters[j].ParameterType; if (parameterType == typeof(ItemData)) { flag = true; } else if (!(parameterType == typeof(bool)) && !(parameterType == typeof(Inventory))) { flag2 = false; break; } } if (flag2 && flag) { _canConsumeItemMethod = methodInfo; return true; } } } catch { } return false; } private static bool CanConsumeNow(Player player, ItemData item) { if ((Object)(object)player == (Object)null || item == null || _canConsumeItemMethod == null) { return false; } try { ParameterInfo[] parameters = _canConsumeItemMethod.GetParameters(); object[] array = new object[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { Type parameterType = parameters[i].ParameterType; if (parameterType == typeof(ItemData)) { array[i] = item; continue; } if (parameterType == typeof(bool)) { array[i] = false; continue; } if (parameterType == typeof(Inventory)) { array[i] = ((Humanoid)player).GetInventory(); continue; } return false; } object obj = _canConsumeItemMethod.Invoke(player, array); return obj is bool && (bool)obj; } catch { return false; } } private static List<ItemData> GetExtraSlotsFoodItems() { ResolveApi(); if (_getFoodSlotsItems == null) { return null; } try { object obj = _getFoodSlotsItems.Invoke(null, null); if (!(obj is IEnumerable enumerable)) { return null; } List<ItemData> list = new List<ItemData>(); foreach (object item in enumerable) { ItemData val = (ItemData)((item is ItemData) ? item : null); if (val != null) { list.Add(val); } } return list; } catch { return null; } } private static void ResolveApi() { if (_apiResolved) { return; } _apiResolved = true; try { Type type = Type.GetType("ExtraSlots.API, ExtraSlots", throwOnError: false); if (!(type == null)) { _getFoodSlotsItems = type.GetMethod("GetFoodSlotsItems", BindingFlags.Static | BindingFlags.Public); } } catch { } } private static int GetActiveFoodCount(Player player) { int num = 0; try { FieldInfo fieldInfo = AccessTools.Field(typeof(Player), "m_foods"); IEnumerable enumerable = ((fieldInfo == null) ? null : (fieldInfo.GetValue(player) as IEnumerable)); if (enumerable == null) { return 0; } foreach (object item in enumerable) { if (item != null) { num++; } } } catch { } return num; } private static bool IsFoodAtBlinkStage(Player player, ItemData item) { if ((Object)(object)player == (Object)null || item == null || item.m_shared == null) { return false; } string text = item.m_shared.m_name ?? ""; try { FieldInfo fieldInfo = AccessTools.Field(typeof(Player), "m_foods"); IEnumerable enumerable = ((fieldInfo == null) ? null : (fieldInfo.GetValue(player) as IEnumerable)); if (enumerable == null) { return false; } foreach (object item2 in enumerable) { if (item2 == null) { continue; } Type type = item2.GetType(); FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); ItemData val = null; foreach (FieldInfo fieldInfo2 in fields) { if (typeof(ItemData).IsAssignableFrom(fieldInfo2.FieldType)) { try { object? value = fieldInfo2.GetValue(item2); val = (ItemData)((value is ItemData) ? value : null); } catch { val = null; } if (val != null && val.m_shared != null) { break; } } } if (val != null && val.m_shared != null && !(val.m_shared.m_name != text)) { float foodBurnTime = val.m_shared.m_foodBurnTime; if (foodBurnTime <= 0f) { foodBurnTime = item.m_shared.m_foodBurnTime; } if (foodBurnTime <= 0f) { return false; } FieldInfo field = type.GetField("m_time", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null || field.FieldType != typeof(float)) { return false; } float num = Convert.ToSingle(field.GetValue(item2)); return num <= foodBurnTime * 0.5f; } } } catch { } return false; } private static bool IsFoodActive(Player player, ItemData item) { if ((Object)(object)player == (Object)null || item == null || item.m_shared == null) { return false; } string text = item.m_shared.m_name ?? ""; string text2 = ""; try { text2 = (((Object)(object)item.m_dropPrefab == (Object)null) ? "" : (((Object)item.m_dropPrefab).name ?? "")); } catch { } try { FieldInfo fieldInfo = AccessTools.Field(typeof(Player), "m_foods"); IEnumerable enumerable = ((fieldInfo == null) ? null : (fieldInfo.GetValue(player) as IEnumerable)); if (enumerable == null) { return false; } foreach (object item2 in enumerable) { if (item2 == null) { continue; } FieldInfo[] fields = item2.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo2 in fields) { if (typeof(ItemData).IsAssignableFrom(fieldInfo2.FieldType)) { ItemData val = null; try { object? value = fieldInfo2.GetValue(item2); val = (ItemData)((value is ItemData) ? value : null); } catch { } if (val != null && val.m_shared != null && val.m_shared.m_name == text) { return true; } } else if (fieldInfo2.FieldType == typeof(string)) { string text3 = null; try { text3 = fieldInfo2.GetValue(item2) as string; } catch { } if (!string.IsNullOrEmpty(text3) && (text3 == text || (!string.IsNullOrEmpty(text2) && text3 == text2))) { return true; } } } } } catch { } return false; } private static bool TryUseFood(Player player, ItemData item) { if ((Object)(object)player == (Object)null || item == null) { return false; } ResolveConsumeMethods(((object)player).GetType()); Inventory inventory = ((Humanoid)player).GetInventory(); if (_useItemMethod != null) { bool? flag = InvokeFoodMethod(_useItemMethod, player, inventory, item); if (flag.HasValue) { return flag.Value; } } if (_consumeItemMethod != null) { bool? flag2 = InvokeFoodMethod(_consumeItemMethod, player, inventory, item); if (flag2.HasValue) { return flag2.Value; } } return false; } private static void ResolveConsumeMethods(Type playerType) { if (_useItemMethod != null || _consumeItemMethod != null || playerType == null) { return; } try { MethodInfo[] methods = playerType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name != "UseItem" && methodInfo.Name != "ConsumeItem") { continue; } ParameterInfo[] parameters = methodInfo.GetParameters(); bool flag = false; bool flag2 = true; for (int j = 0; j < parameters.Length; j++) { Type parameterType = parameters[j].ParameterType; if (parameterType == typeof(ItemData)) { flag = true; } else if (!(parameterType == typeof(Inventory)) && !(parameterType == typeof(bool))) { flag2 = false; break; } } if (flag2 && flag) { if (methodInfo.Name == "UseItem" && _useItemMethod == null) { _useItemMethod = methodInfo; } if (methodInfo.Name == "ConsumeItem" && _consumeItemMethod == null) { _consumeItemMethod = methodInfo; } } } } catch { } } private static bool? InvokeFoodMethod(MethodInfo method, Player player, Inventory inventory, ItemData item) { if (method == null) { return null; } try { ParameterInfo[] parameters = method.GetParameters(); object[] array = new object[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { Type parameterType = parameters[i].ParameterType; if (parameterType == typeof(ItemData)) { array[i] = item; continue; } if (parameterType == typeof(Inventory)) { array[i] = inventory; continue; } if (parameterType == typeof(bool)) { array[i] = false; continue; } return null; } object value = method.Invoke(player, array); if (method.ReturnType == typeof(bool)) { return Convert.ToBoolean(value); } return true; } catch { return false; } } } [HarmonyPatch(typeof(Player), "GetMaxCarryWeight")] internal static class CarryWeightPatch { private static void Postfix(ref float __result) { if (HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.CarryWeightEnabled)) { __result *= HeimLifeTweaksPlugin.CarryWeightMultiplier.Value; } } } [HarmonyPatch(typeof(Minimap), "UpdateExplore")] internal static class PathfinderPatch { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { CodeInstruction previous = null; foreach (CodeInstruction code in instructions) { if (previous != null) { if (previous.opcode == OpCodes.Ldarg_0 && code.opcode == OpCodes.Ldfld && code.operand is FieldInfo && ((FieldInfo)code.operand).Name == "m_exploreRadius") { yield return new CodeInstruction(OpCodes.Ldarg_2, (object)null); yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(PathfinderPatch), "GetExploreRadius", (Type[])null, (Type[])null)); previous = null; continue; } yield return previous; previous = null; } if (code.opcode == OpCodes.Ldarg_0) { previous = code; } else { yield return code; } } if (previous != null) { yield return previous; } } public static float GetExploreRadius(Player player) { if (!HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.PathfinderEnabled)) { return 100f; } if (HeimLifeTweaksPlugin.PathfinderDisableInDungeons.Value && IsInsideInstancedDungeon(player)) { return 0f; } return HeimLifeTweaksPlugin.ComputeExploreRadius(player); } private static bool IsInsideInstancedDungeon(Player player) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)((Component)player).transform == (Object)null) { return false; } if (((Component)player).transform.position.y > 3000f) { return true; } try { if ((Object)(object)EnvMan.instance == (Object)null) { return false; } MethodInfo method = typeof(EnvMan).GetMethod("GetCurrentEnvironment", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); object obj = ((method == null) ? null : method.Invoke(EnvMan.instance, null)); if (obj == null) { return false; } Type type = obj.GetType(); string text = ""; FieldInfo field = type.GetField("m_name", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { object value = field.GetValue(obj); if (value != null) { text = value.ToString(); } } if (string.IsNullOrEmpty(text)) { return false; } string text2 = text.ToLowerInvariant(); return text2.Contains("crypt") || text2.Contains("dungeon") || text2.Contains("cave") || text2.Contains("burial") || text2.Contains("trollcave") || text2.Contains("sunken"); } catch { return false; } } } [HarmonyPatch(typeof(Player), "GetBuildStamina")] internal static class BuildStaminaPatch { private static void Postfix(ref float __result) { if (HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.FastToolsEnabled)) { __result *= HeimLifeTweaksPlugin.BuildStaminaMultiplier.Value; } } } [HarmonyPatch(typeof(Player), "UpdatePlacement")] internal static class FastToolsPlacementPatch { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { CodeInstruction previous = null; foreach (CodeInstruction code in instructions) { if (previous != null) { if (previous.opcode == OpCodes.Ldarg_0 && code.opcode == OpCodes.Ldfld && code.operand is FieldInfo) { string name = ((FieldInfo)code.operand).Name; if (name == "m_placeDelay") { yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(FastToolsPlacementPatch), "GetPlaceDelay", (Type[])null, (Type[])null)); previous = null; continue; } if (name == "m_removeDelay") { yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(FastToolsPlacementPatch), "GetRemoveDelay", (Type[])null, (Type[])null)); previous = null; continue; } } yield return previous; previous = null; } if (code.opcode == OpCodes.Ldarg_0) { previous = code; } else { yield return code; } } if (previous != null) { yield return previous; } } public static float GetPlaceDelay() { if (!HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.FastToolsEnabled)) { return 0.4f; } return HeimLifeTweaksPlugin.PlaceDelay.Value; } public static float GetRemoveDelay() { if (!HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.FastToolsEnabled)) { return 0.25f; } return HeimLifeTweaksPlugin.RemoveDelay.Value; } } internal static class DigDeeperTranspilerUtil { internal static IEnumerable<CodeInstruction> ReplaceEight(IEnumerable<CodeInstruction> instructions, bool depth) { foreach (CodeInstruction code in instructions) { if (code.opcode == OpCodes.Ldc_R4 && code.operand is float) { float value = (float)code.operand; if (Math.Abs(Math.Abs(value) - 8f) < 0.0001f) { yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(DigDeeperTranspilerUtil), depth ? "GetDepth" : "GetHeight", (Type[])null, (Type[])null)); if (value < 0f) { yield return new CodeInstruction(OpCodes.Neg, (object)null); } continue; } } yield return code; } } public static float GetDepth() { if (!HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.DigDeeperEnabled)) { return 8f; } return HeimLifeTweaksPlugin.DigDepth.Value; } public static float GetHeight() { if (!HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.DigDeeperEnabled)) { return 8f; } return HeimLifeTweaksPlugin.RaiseHeight.Value; } } [HarmonyPatch(typeof(Heightmap), "LevelTerrain")] internal static class DigDeeperHeightmapPatch { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { return DigDeeperTranspilerUtil.ReplaceEight(instructions, depth: true); } } [HarmonyPatch(typeof(TerrainComp), "ApplyToHeightmap")] internal static class DigDeeperApplyToHeightmapPatch { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { return DigDeeperTranspilerUtil.ReplaceEight(instructions, depth: true); } } [HarmonyPatch(typeof(TerrainComp), "LevelTerrain")] internal static class DigDeeperTerrainLevelPatch { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { return DigDeeperTranspilerUtil.ReplaceEight(instructions, depth: true); } } [HarmonyPatch(typeof(TerrainComp), "RaiseTerrain")] internal static class DigDeeperTerrainRaisePatch { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { return DigDeeperTranspilerUtil.ReplaceEight(instructions, depth: false); } } [HarmonyPatch] internal static class ElderResourceDamagePatch { private static IEnumerable<MethodBase> TargetMethods() { Type[] types = new Type[5] { typeof(TreeBase), typeof(TreeLog), typeof(MineRock), typeof(MineRock5), typeof(Destructible) }; HashSet<MethodBase> seen = new HashSet<MethodBase>(); foreach (Type type in types) { if (type == null) { continue; } MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo method in methods) { if (!(method.Name != "Damage")) { ParameterInfo[] p = method.GetParameters(); if (p.Length >= 1 && !(p[0].ParameterType != typeof(HitData)) && seen.Add(method)) { yield return method; } } } } } private static void Prefix(object __instance, HitData hit) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) if (hit == null) { return; } _ = hit.m_damage; if (!HeimLifeTweaksPlugin.IsBossPowerAvailable(HeimLifeTweaksPlugin.BossElderEnabled, "defeated_gdking")) { return; } float num = 1f + Mathf.Max(0f, HeimLifeTweaksPlugin.ElderChopDamage.Value) / 100f; float num2 = 1f + Mathf.Max(0f, HeimLifeTweaksPlugin.ElderPickaxeDamage.Value) / 100f; try { if (hit.m_damage.m_chop > 0f) { ref DamageTypes damage = ref hit.m_damage; damage.m_chop *= num; } if (hit.m_damage.m_pickaxe > 0f) { ref DamageTypes damage2 = ref hit.m_damage; damage2.m_pickaxe *= num2; } } catch { } } } [HarmonyPatch(typeof(Player), "ActivateGuardianPower")] internal static class DisableGuardianPowerActivationPatch { private static bool Prefix(Player __instance, ref bool __result) { if (!HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.BossPowersEnabled)) { return true; } try { FieldInfo fieldInfo = AccessTools.Field(typeof(Player), "m_guardianPowerCooldown"); if (fieldInfo != null) { fieldInfo.SetValue(__instance, 0f); } } catch { } __result = false; return false; } } [HarmonyPatch(typeof(Beehive), "UpdateBees")] internal static class BeehiveUpdatePatch { internal sealed class ProgressSnapshot { internal float Product; internal float UnityTime; internal int HoneyLevel; } internal static readonly Dictionary<int, ProgressSnapshot> Progress = new Dictionary<int, ProgressSnapshot>(); private static void Postfix(Beehive __instance) { if (!HeimLifeTweaksPlugin.On(HeimLifeTweaksPlugin.BeehiveEnabled)) { return; } try { __instance.m_secPerUnit = HeimLifeTweaksPlugin.HoneyProductionSeconds.Value; __instance.m_maxHoney = HeimLifeTweaksPlugin.MaximumHoney.Value; } catch { } int honeyLevel = GetHoneyLevel(__instance); ZNetView nView = GetNView(__instance); ZDO val = (((Object)(object)nView == (Object)null) ? null : nView.GetZDO()); float product = 0f; if (val != null) { try { product = val.GetFloat(ZDOVars.s_product, 0f); } catch { } } try { int instanceID = ((Object)__instance).GetInstanceID(); if (!Progress.TryGetValue(instanceID, out var value)) { value = new ProgressSnapshot(); Progress[instanceID] = value; } value.Product = product; value.UnityTime = Time.time; value.HoneyLevel = honeyLevel; } catch { } } internal static int GetHoneyLevel(Beehive hive) { if ((Object)(object)hive == (Object)null) { return 0; } try { MethodInfo methodInfo = AccessTools.Method(typeof(Beehive), "GetHoneyLevel", (Type[])null, (Type[])null); if (methodInfo != null) { return Convert.ToInt32(methodInfo.Invoke(hive, null)); } } catch { } try { ZNetView nView = GetNView(hive); ZDO val = (((Object)(object)nView == (Object)null) ? null : nView.GetZDO()); if (val != null) { return val.GetInt(ZDOVars.s_level, 0); } } catch { } return 0; } internal static ZNetView GetNView(Beehive hive) { if ((Object)(object)hive == (Object)null) { return null; } try { FieldInfo fieldInfo = AccessTools.Field(typeof(Beehive), "m_nview"); if (fieldInfo != null) { object? value = fieldInfo.GetValue(hive); return (ZNetView)((value is ZNetView) ? value : null); } } catch { } try { return ((Component)hive).GetComponent<ZNetView>(); } catch { return null; } } private static Container FindNearestContainer(Vector3 position, float range) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) Container result = null; float num = range; try { Container[] array = Object.FindObjectsOfType<Container>(); foreach (Container val in array) { if ((Object)(o