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 ComfortTweaks v3.3.10
ComfortTweaks.dll
Decompiled 2 months 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.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using ComfortTweaks.buffs; using ComfortTweaks.gems; using ComfortTweaks.gems.Jewelry; using ComfortTweaks.potions; using Groups; using HarmonyLib; using ItemManager; using JetBrains.Annotations; using Jewelcrafting; using LocalizationManager; using Microsoft.CodeAnalysis; using ServerSync; using TMPro; using UnityEngine; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Core.ObjectPool; using YamlDotNet.Core.Tokens; using YamlDotNet.Helpers; using YamlDotNet.Serialization; using YamlDotNet.Serialization.BufferedDeserialization; using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators; using YamlDotNet.Serialization.Callbacks; using YamlDotNet.Serialization.Converters; using YamlDotNet.Serialization.EventEmitters; using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NodeDeserializers; using YamlDotNet.Serialization.NodeTypeResolvers; using YamlDotNet.Serialization.ObjectFactories; using YamlDotNet.Serialization.ObjectGraphTraversalStrategies; using YamlDotNet.Serialization.ObjectGraphVisitors; using YamlDotNet.Serialization.Schemas; using YamlDotNet.Serialization.TypeInspectors; using YamlDotNet.Serialization.TypeResolvers; using YamlDotNet.Serialization.Utilities; using YamlDotNet.Serialization.ValueDeserializers; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("ComfortTweaks")] [assembly: AssemblyDescription("https://valheim.thunderstore.io/package/Smoothbrain/ComfortTweaks")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ComfortTweaks")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("ab196e42-67f0-4457-817e-a263453faf27")] [assembly: AssemblyFileVersion("3.3.10")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = "")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("3.3.10.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } internal sealed class <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { public bool? ShowRangeAsPercent; public Action<ConfigEntryBase> CustomDrawer; public bool? Browsable; public string Category; public object DefaultValue; public bool? HideDefaultButton; public bool? HideSettingName; public string Description; public string DispName; public int? Order; public bool? ReadOnly; public bool? IsAdvanced; public Func<object, string> ObjToStr; public Func<string, object> StrToObj; } namespace ComfortTweaks { [BepInPlugin("xyz.alcan.comfortcalc", "Comfort Tweaks", "3.3.10")] [BepInIncompatibility("org.bepinex.plugins.valheim_plus")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class ComfortTweaks : BaseUnityPlugin { [HarmonyPatch(typeof(SE_Rested), "GetNearbyComfortPieces")] private static class PatchPlayerGetNearbyComfortPieces { private static readonly MethodInfo RangeValueGetter = AccessTools.DeclaredMethod(typeof(PatchPlayerGetNearbyComfortPieces), "getRangeValue", (Type[])null, (Type[])null); private static float getRangeValue() { return Mathf.Max(10f, (float)comfortRadius.Value); } private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown if (!isEnabled.Value) { return instructions; } List<CodeInstruction> list = new List<CodeInstruction>(instructions); List<CodeInstruction> list2 = new List<CodeInstruction>(); foreach (CodeInstruction item in list) { CodeInstruction val = item; if (val.opcode == OpCodes.Ldc_R4 && CodeInstructionExtensions.OperandIs(val, (object)10)) { val = new CodeInstruction(OpCodes.Callvirt, (object)RangeValueGetter); } list2.Add(val); } return list2; } } [HarmonyPatch(typeof(SE_Rested), "CalculateComfortLevel", new Type[] { typeof(bool), typeof(Vector3) })] private class PatchPlayerCalculateComfortLevel { private static void Prefix(ref bool inShelter) { if (isEnabled.Value) { inShelter |= ignoreShelter.Value; } } private static void Postfix(bool inShelter, ref int __result) { if (isEnabled.Value && Object.op_Implicit((Object)(object)ZNetScene.instance) && Player.m_localPlayer != null) { __result -= ((!inShelter && ignoreShelter.Value) ? 1 : 0); } } } [HarmonyPatch(typeof(TeleportWorldTrigger), "OnTriggerEnter")] private class PlayerUsesPortal { private class CantTeleportBecauseNotRestedException : Exception { } private static void Prefix(TeleportWorldTrigger __instance, Collider colliderIn) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)((Component)colliderIn).GetComponent<Player>() != (Object)(object)Player.m_localPlayer) { return; } ZDO zDO = ZDOMan.instance.GetZDO(__instance.m_teleportWorld.m_nview.GetZDO().GetConnectionZDOID((ConnectionType)1)); if (zDO != null) { teleportDistance = Utils.DistanceXZ(((Component)Player.m_localPlayer).transform.position, zDO.GetPosition()); } if (blockTeleport.Value && (((Character)Player.m_localPlayer).m_seman.GetStatusEffect(restedHash) == null || teleportDistance / (float)teleportCostDistance.Value * (float)teleportCost.Value > ((Character)Player.m_localPlayer).m_seman.GetStatusEffect(restedHash).GetRemaningTime())) { if (!Player.m_debugMode) { ((Character)Player.m_localPlayer).Message((MessageType)2, "You're too tired to teleport that far.", 0, (Sprite)null); teleportDistance = 0f; throw new CantTeleportBecauseNotRestedException(); } logger.LogInfo((object)("Skipped Rested check on portal for debug player " + Player.m_localPlayer.GetPlayerName())); } else { playerUsedPortal = true; } } private static Exception Finalizer(Exception __exception) { if (!(__exception is CantTeleportBecauseNotRestedException)) { return __exception; } return null; } } [HarmonyPatch(typeof(Player), "UpdateTeleport")] private class Teleporting { private static void Prefix(Player __instance, ref bool __state) { if (isEnabled.Value && removeRestedOnTeleport.Value) { __state = __instance.m_teleporting; } } private static void Postfix(Player __instance, bool __state) { if (!isEnabled.Value || !removeRestedOnTeleport.Value || !playerUsedPortal || !__state || __instance.m_teleporting) { return; } playerUsedPortal = false; if (teleportCost.Value != 0) { StatusEffect statusEffect = ((Character)__instance).m_seman.GetStatusEffect(restedHash); if (!(((statusEffect != null) ? new float?(statusEffect.GetRemaningTime()) : ((float?)null)) - (float)teleportCost.Value * (teleportDistance / (float)teleportCostDistance.Value) < 1f)) { if (((Character)__instance).m_seman.HaveStatusEffect(restedHash)) { StatusEffect statusEffect2 = ((Character)__instance).m_seman.GetStatusEffect(restedHash); statusEffect2.m_ttl -= teleportDistance / (float)teleportCostDistance.Value * (float)teleportCost.Value; } goto IL_0126; } } ((Character)__instance).m_seman.RemoveStatusEffect(restedHash, false); goto IL_0126; IL_0126: teleportDistance = 0f; } } [HarmonyPatch(typeof(ZNetScene), "Awake")] private class FetchPieces { [HarmonyPriority(0)] private static void Postfix(ZNetScene __instance) { //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Expected O, but got Unknown //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Expected O, but got Unknown //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) if (!isEnabled.Value) { return; } comfortPieceSet.Clear(); allComfortPieces.Clear(); List<GameObject> source = __instance.m_prefabs.FindAll(delegate(GameObject p) { Piece component = p.GetComponent<Piece>(); if (component == null || component.m_comfort <= 0) { Piece component2 = p.GetComponent<Piece>(); return ((component2 != null) ? new bool?(((Object)component2).name.Contains("jackoturnip")) : ((bool?)null)) ?? false; } return true; }); foreach (Piece piece in source.Select((GameObject pieceObject) => pieceObject.GetComponent<Piece>())) { if (piece.m_name.Contains("maypole")) { piece.m_enabled = enableMaypole.Value; } if (piece.m_name.Contains("yuletree")) { piece.m_enabled = enableYuletree.Value; } if (piece.m_name.Contains("jackoturnip)")) { piece.m_enabled = enableJackoturnip.Value; } if (piece.m_name.Contains("armorstand_male") || !comfortPieceSet.Add(piece)) { continue; } ConfigEntry<int> comfortConfig = mod.config("09 - Comfort Piece Settings", regex.Replace(english.Localize(piece.m_name), "") + " Comfort", piece.m_comfort, new ConfigDescription("", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "09 - Comfort Groups", DispName = Localization.instance.Localize(piece.m_name), Order = order++ } })); comfortConfig.SettingChanged += delegate { if (isEnabled.Value) { (from p in Object.FindObjectsOfType<Piece>() where regex.Replace(english.Localize(p.m_name), "") == regex.Replace(english.Localize(piece.m_name), "") select p).ToList().ForEach(delegate(Piece c) { c.m_comfort = comfortConfig.Value; }); piece.m_comfort = comfortConfig.Value; } }; ConfigEntry<ComfortGroup> comfortGroupConfig = mod.config<ComfortGroup>("09 - Comfort Piece Settings", regex.Replace(english.Localize(piece.m_name), "") + " Comfort Group", piece.m_comfortGroup, new ConfigDescription("", (AcceptableValueBase)null, new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "09 - Comfort Groups", DispName = Localization.instance.Localize(piece.m_name), Order = order++ } })); comfortGroupConfig.SettingChanged += delegate { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) if (isEnabled.Value) { (from p in Object.FindObjectsOfType<Piece>() where regex.Replace(english.Localize(p.m_name), "") == regex.Replace(english.Localize(piece.m_name), "") select p).ToList().ForEach(delegate(Piece g) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) g.m_comfortGroup = comfortGroupConfig.Value; }); piece.m_comfortGroup = comfortGroupConfig.Value; } }; piece.m_comfort = comfortConfig.Value; piece.m_comfortGroup = comfortGroupConfig.Value; allComfortPieces.Add(((Object)piece).name, piece); } List<GameObject> prefabs = __instance.m_prefabs.FindAll((GameObject p) => Object.op_Implicit((Object)(object)p.GetComponent<Piece>())); if (prefabs != null) { ChangeWarmthPieces(ref prefabs); } } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] private class fetchFirePieces { [HarmonyPriority(0)] private static void Postfix(ObjectDB __instance) { GameObject itemPrefab = __instance.GetItemPrefab("Hammer"); PieceTable val = ((itemPrefab == null) ? null : itemPrefab.GetComponent<ItemDrop>()?.m_itemData.m_shared.m_buildPieces); if (val != null) { ChangeWarmthPieces(ref val.m_pieces); } } } [HarmonyPatch(typeof(SE_Cozy), "Setup")] private class PatchSECozy { private static void Prefix(SE_Cozy __instance) { if (isEnabled.Value) { __instance.m_delay = restedDelay.Value; ((SE_Stats)__instance).m_staminaRegenMultiplier = (float)cozyStaminaRegenMultiplierPercent.Value / 100f; ((SE_Stats)__instance).m_healthRegenMultiplier = (float)cozyHealthRegenMultiplierPercent.Value / 100f; ((SE_Stats)__instance).m_eitrRegenMultiplier = (float)cozyEitrRegenMultiplierPercent.Value / 100f; } } } [HarmonyPatch(typeof(SE_Rested), "Setup")] [HarmonyPriority(800)] private class PatchSERested { private static void Prefix(SE_Rested __instance) { //IL_00e1: Unknown result type (might be due to invalid IL or missing references) if (isEnabled.Value) { __instance.m_baseTTL = baseRestedTime.Value; __instance.m_TTLPerComfortLevel = restedPerComfort.Value; ((SE_Stats)__instance).m_raiseSkillModifier = raiseSkillModifier.Value; ((SE_Stats)__instance).m_staminaRegenMultiplier = (float)staminaRegenMultiplierPercent.Value / 100f; ((SE_Stats)__instance).m_runStaminaDrainModifier = 0f - (float)runStaminaDrainModifierPercent.Value / 100f; ((SE_Stats)__instance).m_jumpStaminaUseModifier = 0f - (float)jumpStaminaDrainModifierPercent.Value / 100f; ((SE_Stats)__instance).m_healthRegenMultiplier = (float)healthRegenMultipierPercent.Value / 100f; ((SE_Stats)__instance).m_eitrRegenMultiplier = (float)eitrRegenMultipierPercent.Value / 100f; ((SE_Stats)__instance).m_damageModifier = damageModifier.Value; if (((SE_Stats)__instance).m_damageModifier > 1f) { ((SE_Stats)__instance).m_modifyAttackSkill = (SkillType)999; } ((SE_Stats)__instance).m_addMaxCarryWeight = addMaxCarryWeight.Value; ((SE_Stats)__instance).m_speedModifier = speedModifier.Value; } } } [HarmonyPatch(typeof(Player), "SetLocalPlayer")] private class AddCoroutine { public static void Postfix(Player __instance) { ((MonoBehaviour)__instance).StartCoroutine(ReplaceFixedUpdate(__instance)); } } [HarmonyPatch(typeof(Player), "Load")] private class PatchPlayerLoad { private static void Postfix(Player __instance) { if (isEnabled.Value && !((Object)(object)ZNet.instance == (Object)null) && stayRested.Value && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { string value2; if (__instance.m_knownStations.TryGetValue("comfortTweaksRested_" + ZNet.m_world.m_uid, out var value) && value > 0) { logger.LogDebug((object)("Resting for " + value + "s")); ((Character)__instance).m_seman.AddStatusEffect(restedHash, true, 0, 0f).m_ttl = value; __instance.m_knownStations["comfortTweaksRested_" + ZNet.m_world.m_uid] = 0; } else if (__instance.m_customData.TryGetValue("comfortTweaksRested_" + ZNet.m_world.m_uid, out value2) && int.Parse(value2) > 0) { logger.LogDebug((object)("Resting for " + value2 + "s")); ((Character)__instance).m_seman.AddStatusEffect(restedHash, true, 0, 0f).m_ttl = int.Parse(value2); __instance.m_customData["comfortTweaksRested_" + ZNet.m_world.m_uid] = 0.ToString(); } } } } [HarmonyPatch(typeof(Player), "Save")] private class PatchPlayerSave { private static void Prefix(Player __instance) { if (isEnabled.Value && Object.op_Implicit((Object)(object)ZNet.instance)) { __instance.m_customData["comfortTweaksRested_" + ZNet.m_world.m_uid] = ((((Character)__instance).IsDead() || (Object)(object)((Character)__instance).m_seman.GetStatusEffect(restedHash) == (Object)null) ? 0.ToString() : ((int)((Character)__instance).m_seman.GetStatusEffect(restedHash).GetRemaningTime()).ToString()); } } } private const string guid = "xyz.alcan.comfortcalc"; private const string modname = "Comfort Tweaks"; public const string version = "3.3.10"; private readonly ConfigSync configSync = new ConfigSync("xyz.alcan.comfortcalc") { CurrentVersion = "3.3.10", MinimumRequiredVersion = "3.3.10", DisplayName = "Comfort Tweaks" }; private readonly Dictionary<string, int> _configOrderCount = new Dictionary<string, int>(); private static ComfortTweaks mod = null; public static ManualLogSource logger = null; public static ConfigEntry<bool> isEnabled = null; private static ConfigEntry<bool> isLocked = null; private static ConfigEntry<int> comfortRadius = null; private static ConfigEntry<bool> showPieces = null; private static ConfigEntry<int> showPiecesLocationX = null; private static ConfigEntry<int> showPiecesLocationY = null; private static ConfigEntry<bool> ignoreShelter = null; private static ConfigEntry<Color> showPiecesFontColor = null; private static ConfigEntry<int> showPiecesFontSize = null; private static ConfigEntry<KeyboardShortcut> showPiecesHotkey = null; private static ConfigEntry<int> updateInterval = null; private static ConfigEntry<bool> showOnlyInShelter = null; private static ConfigEntry<bool> showGainedComfortPieces = null; private static ConfigEntry<bool> showMissingComfortPieces = null; private static ConfigEntry<bool> showKnownComfortPieces = null; private static ConfigEntry<Color> missingPiecesFontColor = null; private static ConfigEntry<int> restedDelay = null; private static ConfigEntry<int> cozyStaminaRegenMultiplierPercent = null; private static ConfigEntry<int> cozyHealthRegenMultiplierPercent = null; private static ConfigEntry<int> cozyEitrRegenMultiplierPercent = null; public static ConfigEntry<int> baseRestedTime = null; public static ConfigEntry<int> restedPerComfort = null; public static ConfigEntry<float> raiseSkillModifier = null; public static ConfigEntry<int> staminaRegenMultiplierPercent = null; public static ConfigEntry<int> runStaminaDrainModifierPercent = null; private static ConfigEntry<int> jumpStaminaDrainModifierPercent = null; private static ConfigEntry<int> healthRegenMultipierPercent = null; private static ConfigEntry<int> eitrRegenMultipierPercent = null; private static ConfigEntry<float> damageModifier = null; private static ConfigEntry<int> addMaxCarryWeight = null; private static ConfigEntry<float> speedModifier = null; private static ConfigEntry<bool> stayRested = null; private static ConfigEntry<bool> removeRestedOnTeleport = null; private static ConfigEntry<int> teleportCost = null; private static ConfigEntry<int> teleportCostDistance = null; private static ConfigEntry<bool> blockTeleport = null; private static ConfigEntry<bool> enableMaypole = null; private static ConfigEntry<bool> enableYuletree = null; private static ConfigEntry<bool> enableJackoturnip = null; public static ConfigEntry<int> smallRestedPotionRestedTime = null; public static ConfigEntry<int> smallRestedPotionCooldown = null; public static ConfigEntry<int> mediumRestedPotionRestedTime = null; public static ConfigEntry<int> mediumRestedPotionCooldown = null; public static ConfigEntry<int> largeRestedPotionRestedTime = null; public static ConfigEntry<int> largeRestedPotionCooldown = null; public static ConfigEntry<bool> enableGroupBuff = null; public static ConfigEntry<int> nearbyGroupMembers = null; public static ConfigEntry<int> nearbyGroupRadius = null; public static ConfigEntry<int> nearbyGroupComfort = null; private static readonly Dictionary<string, ConfigEntry<float>> firePieces = new Dictionary<string, ConfigEntry<float>>(); private static ConfigEntry<bool> isVisible = null; public const bool IsDebug = false; private static List<Piece> gainedComfortPieces = new List<Piece>(); private static List<Piece> missingComfortPieces = new List<Piece>(); private static List<Piece> outputList = new List<Piece>(); private static readonly Dictionary<string, Piece> allComfortPieces = new Dictionary<string, Piece>(); private static readonly HashSet<Piece> comfortPieceSet = new HashSet<Piece>(); private static readonly Regex regex = new Regex("[=\\n\\t\\\\\"\\'\\[\\]]*"); private static Localization english = null; private static Font? fontCache; private static int longestWord; private static readonly Stopwatch guiTimer = new Stopwatch(); private static float teleportDistance; public static readonly int restedHash = StringExtensionMethods.GetStableHashCode("Rested"); public static readonly int restingHash = StringExtensionMethods.GetStableHashCode("Resting"); private static int order = 1; private static bool playerUsedPortal; private void Awake() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Expected O, but got Unknown //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Expected O, but got Unknown //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Expected O, but got Unknown //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Expected O, but got Unknown //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Expected O, but got Unknown //IL_0304: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Expected O, but got Unknown //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_0397: Expected O, but got Unknown //IL_0412: Unknown result type (might be due to invalid IL or missing references) //IL_041e: Expected O, but got Unknown //IL_0496: Unknown result type (might be due to invalid IL or missing references) //IL_04a2: Expected O, but got Unknown //IL_0521: Unknown result type (might be due to invalid IL or missing references) //IL_052d: Expected O, but got Unknown //IL_05a9: Unknown result type (might be due to invalid IL or missing references) //IL_05b5: Expected O, but got Unknown //IL_0629: Unknown result type (might be due to invalid IL or missing references) //IL_0635: Expected O, but got Unknown //IL_06a9: Unknown result type (might be due to invalid IL or missing references) //IL_06b5: Expected O, but got Unknown //IL_0731: Unknown result type (might be due to invalid IL or missing references) //IL_073d: Expected O, but got Unknown //IL_07b9: Unknown result type (might be due to invalid IL or missing references) //IL_07c5: Expected O, but got Unknown //IL_0844: Unknown result type (might be due to invalid IL or missing references) //IL_0850: Expected O, but got Unknown //IL_08c7: Unknown result type (might be due to invalid IL or missing references) //IL_08d3: Expected O, but got Unknown //IL_0952: Unknown result type (might be due to invalid IL or missing references) //IL_095e: Expected O, but got Unknown //IL_09cb: Unknown result type (might be due to invalid IL or missing references) //IL_09d7: Expected O, but got Unknown //IL_0a1f: Unknown result type (might be due to invalid IL or missing references) //IL_0a2b: Expected O, but got Unknown //IL_0a7d: Unknown result type (might be due to invalid IL or missing references) //IL_0a89: Expected O, but got Unknown //IL_0adc: Unknown result type (might be due to invalid IL or missing references) //IL_0ae8: Expected O, but got Unknown //IL_0b30: Unknown result type (might be due to invalid IL or missing references) //IL_0b3c: Expected O, but got Unknown //IL_0b84: Unknown result type (might be due to invalid IL or missing references) //IL_0b90: Expected O, but got Unknown //IL_0bd8: Unknown result type (might be due to invalid IL or missing references) //IL_0be4: Expected O, but got Unknown //IL_0c2c: Unknown result type (might be due to invalid IL or missing references) //IL_0c38: Expected O, but got Unknown //IL_0c87: Unknown result type (might be due to invalid IL or missing references) //IL_0c93: Expected O, but got Unknown //IL_0ce3: Unknown result type (might be due to invalid IL or missing references) //IL_0cef: Expected O, but got Unknown //IL_0cff: Unknown result type (might be due to invalid IL or missing references) //IL_0d3b: Unknown result type (might be due to invalid IL or missing references) //IL_0d47: Expected O, but got Unknown //IL_0d90: Unknown result type (might be due to invalid IL or missing references) //IL_0d9c: Expected O, but got Unknown //IL_0db6: Unknown result type (might be due to invalid IL or missing references) //IL_0df2: Unknown result type (might be due to invalid IL or missing references) //IL_0dfe: Expected O, but got Unknown //IL_0e4d: Unknown result type (might be due to invalid IL or missing references) //IL_0e59: Expected O, but got Unknown //IL_0ea1: Unknown result type (might be due to invalid IL or missing references) //IL_0ead: Expected O, but got Unknown //IL_0ef5: Unknown result type (might be due to invalid IL or missing references) //IL_0f01: Expected O, but got Unknown //IL_0f11: Unknown result type (might be due to invalid IL or missing references) //IL_0f4d: Unknown result type (might be due to invalid IL or missing references) //IL_0f59: Expected O, but got Unknown //IL_0fa1: Unknown result type (might be due to invalid IL or missing references) //IL_0fad: Expected O, but got Unknown //IL_101e: Unknown result type (might be due to invalid IL or missing references) //IL_102a: Expected O, but got Unknown //IL_109b: Unknown result type (might be due to invalid IL or missing references) //IL_10a7: Expected O, but got Unknown //IL_112b: Unknown result type (might be due to invalid IL or missing references) //IL_1137: Expected O, but got Unknown //IL_1189: Unknown result type (might be due to invalid IL or missing references) //IL_1195: Expected O, but got Unknown //IL_11fd: Unknown result type (might be due to invalid IL or missing references) //IL_1209: Expected O, but got Unknown //IL_125b: Unknown result type (might be due to invalid IL or missing references) //IL_1267: Expected O, but got Unknown //IL_12d0: Unknown result type (might be due to invalid IL or missing references) //IL_12dc: Expected O, but got Unknown //IL_132e: Unknown result type (might be due to invalid IL or missing references) //IL_133a: Expected O, but got Unknown //IL_1382: Unknown result type (might be due to invalid IL or missing references) //IL_138e: Expected O, but got Unknown //IL_13dd: Unknown result type (might be due to invalid IL or missing references) //IL_13e9: Expected O, but got Unknown //IL_1439: Unknown result type (might be due to invalid IL or missing references) //IL_1445: Expected O, but got Unknown //IL_1494: Unknown result type (might be due to invalid IL or missing references) //IL_14a0: Expected O, but got Unknown //IL_14f1: Unknown result type (might be due to invalid IL or missing references) //IL_14fb: Expected O, but got Unknown mod = this; logger = ((BaseUnityPlugin)this).Logger; ((BaseUnityPlugin)this).Config.SaveOnConfigSet = false; Localizer.Load(); Localization.Initialize(); english = new Localization(); english.SetupLanguage("English"); isEnabled = config("1. Mod Options", "Mod Enabled", value: true, new ConfigDescription("If the mod is enabled", (AcceptableValueBase)null, new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "01 - Mod options", Order = order++ } })); isLocked = config("1. Mod Options", "Config Locked", value: true, new ConfigDescription("The configuration is locked and may not be changed by clients. Only active for servers.", (AcceptableValueBase)null, new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "01 - Mod options", Order = order++ } })); configSync.AddLockingConfigEntry<bool>(isLocked); comfortRadius = config("2. Resting", "Comfort Range", 10, new ConfigDescription("Range of comfort detection", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 100), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "02 - Comfort Logic", Order = order++ } })); ignoreShelter = config("2. Resting", "Ignore Shelter", value: false, new ConfigDescription("Dont require shelter for comfort bonus pieces (You still need to sit)", (AcceptableValueBase)null, new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "02 - Comfort Logic", Order = order++ } })); restedDelay = config("2. Resting", "Rested Delay", 20, new ConfigDescription("Seconds resting before rested", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "03 - Rested Logic", Order = order++ } })); restedDelay.SettingChanged += SeCozySettingChanged; cozyStaminaRegenMultiplierPercent = config("2. Resting", "Stamina Regen Multiplier Percent", 400, new ConfigDescription("Stamina Regen Multiplier while Resting", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "03 - Rested Logic", Order = order++ } })); cozyStaminaRegenMultiplierPercent.SettingChanged += SeCozySettingChanged; cozyHealthRegenMultiplierPercent = config("2. Resting", "Health Regen Multiplier Percent", 300, new ConfigDescription("Health Regen Multiplier while Resting", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "03 - Rested Logic", Order = order++ } })); cozyHealthRegenMultiplierPercent.SettingChanged += SeCozySettingChanged; cozyEitrRegenMultiplierPercent = config("2. Resting", "Eitr Regen Multiplier Percent", 300, new ConfigDescription("Eitr Regen Multiplier while Resting", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "03 - Rested Logic", Order = order++ } })); cozyEitrRegenMultiplierPercent.SettingChanged += SeCozySettingChanged; baseRestedTime = config("3. Rested Buff", "Base Rested Time", 480, new ConfigDescription("Rested time at minimum comfort in seconds", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 3000), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "03 - Rested Logic", Order = order++ } })); baseRestedTime.SettingChanged += SeRestedSettingChanged; restedPerComfort = config("3. Rested Buff", "Rested per Comfort", 60, new ConfigDescription("Seconds Rested time per Comfort Level", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 3000), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "03 - Rested Logic", Order = order++ } })); restedPerComfort.SettingChanged += SeRestedSettingChanged; raiseSkillModifier = config("3. Rested Buff", "XP Multiplier", 0.5f, new ConfigDescription("How much extra experience you gain while rested. 0.5 is 1.5x", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "03 - Rested Logic", Order = order++ } })); raiseSkillModifier.SettingChanged += SeRestedSettingChanged; staminaRegenMultiplierPercent = config("3. Rested Buff", "Stamina Regen %", 200, new ConfigDescription("How fast your Stamina bar fills when regeneration starts. 100 is 1x, 200 is 2x etc", (AcceptableValueBase)(object)new AcceptableValueRange<int>(100, 1000), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "03 - Rested Logic", Order = order++ } })); staminaRegenMultiplierPercent.SettingChanged += SeRestedSettingChanged; runStaminaDrainModifierPercent = config("3. Rested Buff", "Run Stamina Drain Modifier %", 0, new ConfigDescription("Decreased Stamina Use for running", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "03 - Rested Logic", Order = order++ } })); runStaminaDrainModifierPercent.SettingChanged += SeRestedSettingChanged; jumpStaminaDrainModifierPercent = config("3. Rested Buff", "Jump Stamina Drain Modifier %", 0, new ConfigDescription("Decreased Stamina Use for jumping", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "03 - Rested Logic", Order = order++ } })); jumpStaminaDrainModifierPercent.SettingChanged += SeRestedSettingChanged; healthRegenMultipierPercent = config("3. Rested Buff", "Health Regen %", 150, new ConfigDescription("How much HP you regenerate. 100 is normal regeneration, 200 is 2x etc", (AcceptableValueBase)(object)new AcceptableValueRange<int>(100, 3000), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "03 - Rested Logic", Order = order++ } })); healthRegenMultipierPercent.SettingChanged += SeRestedSettingChanged; eitrRegenMultipierPercent = config("3. Rested Buff", "Eitr Regen %", 200, new ConfigDescription("How much Eitr you regenerate. 100 is normal regeneration, 200 is 2x etc", (AcceptableValueBase)(object)new AcceptableValueRange<int>(100, 3000), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "03 - Rested Logic", Order = order++ } })); eitrRegenMultipierPercent.SettingChanged += SeRestedSettingChanged; damageModifier = config("3. Rested Buff", "Damage Modifier", 1f, new ConfigDescription("How much Damage you do while rested. 1 is 1x, 2 is 2x etc", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 100f), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "03 - Rested Logic", Order = order++ } })); damageModifier.SettingChanged += SeRestedSettingChanged; addMaxCarryWeight = config("3. Rested Buff", "Added Max Carry Weight", 0, new ConfigDescription("Maximum Carry Weight added while rested", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "03 - Rested Logic", Order = order++ } })); addMaxCarryWeight.SettingChanged += SeRestedSettingChanged; speedModifier = config("3. Rested Buff", "Run Speed Modifier", 0f, new ConfigDescription("How fast you run while rested. 1 is 100% faster, 2 is 2x etc", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "03 - Rested Logic", Order = order++ } })); speedModifier.SettingChanged += SeRestedSettingChanged; stayRested = config("3. Rested Buff", "Stay Rested between Sessions", value: false, new ConfigDescription("Save Rested buff on Logout", (AcceptableValueBase)null, new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "03 - Rested Logic", Order = order++ } })); removeRestedOnTeleport = config("4. Teleport", "Lose Rested buff when teleporting", value: false, new ConfigDescription("Lose Rested buff time when teleporting", (AcceptableValueBase)null, new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "04 - Teleport", Order = order++ } })); teleportCost = config("4. Teleport", "Teleport Cost", 6, new ConfigDescription("Rested time in seconds that gets used to teleport set distance - 0 is all", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 6000), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "04 - Teleport", Order = order++ } })); teleportCostDistance = config("4. Teleport", "Teleport Distance for Cost", 10, new ConfigDescription("Distance in Meter that is used for Teleport Cost", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 1000), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "04 - Teleport", Order = order++ } })); blockTeleport = config("4. Teleport", "Block teleport if not rested enough", value: false, new ConfigDescription("Block the player from teleporting if rested time is not enough to pay tax (otherwise youll be able to teleport regardless if youre rested or not but you will arrive unrested if youre not rested for long enough", (AcceptableValueBase)null, new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "04 - Teleport", Order = order++ } })); showPieces = config("5. Comfort Pieces List", "Show Comfort Pieces List", value: false, new ConfigDescription("Show the comfort pieces List", (AcceptableValueBase)null, new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "05 - Comfort List", Order = order++ } })); showOnlyInShelter = config("5. Comfort Pieces List", "Show Comfort Pieces List only in Shelter", value: false, new ConfigDescription("Only Shows and the List while in shelter (should reduce lag)", (AcceptableValueBase)null, new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "05 - Comfort List", Order = order++ } })); showGainedComfortPieces = config("5. Comfort Pieces List", "Show Gained Comfort Pieces", value: true, new ConfigDescription("Show the comfort pieces that are currently providing comfort", (AcceptableValueBase)null, new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "05 - Comfort List", Order = order++ } })); showPiecesLocationX = config("5. Comfort Pieces List", "X Value", 2, new ConfigDescription("X value in % of the Screen from Top Left", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "05 - Comfort List", Order = order++ } }), synchronizedSetting: false, showAsPercent: true); showPiecesLocationY = config("5. Comfort Pieces List", "Y Value", 35, new ConfigDescription("Y value in % of the Screen from Top Left", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "05 - Comfort List", Order = order++ } }), synchronizedSetting: false, showAsPercent: true); showPiecesFontColor = config<Color>("5. Comfort Pieces List", "Font Color", Color.white, new ConfigDescription("Font color of the Comfort Pieces List", (AcceptableValueBase)null, new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "05 - Comfort List", Order = order++ } }), synchronizedSetting: false); showPiecesFontSize = config("5. Comfort Pieces List", "Font Size", 24, new ConfigDescription("Font size", (AcceptableValueBase)null, new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "05 - Comfort List", Order = order++ } }), synchronizedSetting: false); showPiecesHotkey = config<KeyboardShortcut>("5. Comfort Pieces List", "Toggle Visibility", new KeyboardShortcut((KeyCode)287, Array.Empty<KeyCode>()), new ConfigDescription("Show/Hide the list of comfort pieces", (AcceptableValueBase)null, new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "05 - Comfort List", Order = order++ } }), synchronizedSetting: false); updateInterval = config("5. Comfort Pieces List", "List update interval", 3, new ConfigDescription("List update interval in seconds", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "05 - Comfort List", Order = order++ } })); showMissingComfortPieces = config("6. Missing Comfort Pieces", "Show Missing Comfort Pieces", value: true, new ConfigDescription("Lists comfort pieces you dont have the comfort from", (AcceptableValueBase)null, new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "05 - Comfort List", Order = order++ } })); showKnownComfortPieces = config("6. Missing Comfort Pieces", "Show Only Known Missing Comfort Pieces", value: true, new ConfigDescription("Lists only unlocked comfort pieces you're able to build but dont have the comfort from", (AcceptableValueBase)null, new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "05 - Comfort List", Order = order++ } })); missingPiecesFontColor = config<Color>("6. Missing Comfort Pieces", "Missing Pieces Font Color", Color.red, new ConfigDescription("Font color of the Missing Pieces List", (AcceptableValueBase)null, new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "05 - Comfort List", Order = order++ } }), synchronizedSetting: false); enableMaypole = config("7. Enable Pieces", "Force enable Maypole", value: false, new ConfigDescription("Make Maypole buildable", (AcceptableValueBase)null, new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "06 - Enable Pieces", Order = order++ } })); enableMaypole.SettingChanged += delegate { allComfortPieces["piece_maypole"].m_enabled = enableMaypole.Value; }; enableYuletree = config("7. Enable Pieces", "Force enable Yule Tree", value: false, new ConfigDescription("Make Yule Tree buildable", (AcceptableValueBase)null, new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "06 - Enable Pieces", Order = order++ } })); enableYuletree.SettingChanged += delegate { allComfortPieces["piece_xmastree"].m_enabled = enableYuletree.Value; }; enableJackoturnip = config("7. Enable Pieces", "Force enable Jack o Turnip", value: false, new ConfigDescription("Make Jack o' Turnip buildable", (AcceptableValueBase)null, new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "06 - Enable Pieces", Order = order++ } })); enableJackoturnip.SettingChanged += delegate { allComfortPieces["piece_jackoturnip"].m_enabled = enableJackoturnip.Value; }; smallRestedPotionRestedTime = config("Campfire in a Bottle", "Rested time", baseRestedTime.Value, new ConfigDescription("Potion use rested Time in seconds", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 6000), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "07 - Potions", Order = order++ } })); smallRestedPotionCooldown = config("Campfire in a Bottle", "Potion cooldown", 1, new ConfigDescription("Potion use cooldown time in seconds", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 6000), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "07 - Potions", Order = order++ } })); mediumRestedPotionRestedTime = config("Bonfire in a Bottle", "Rested time", baseRestedTime.Value + restedPerComfort.Value * 5, new ConfigDescription("Potion use rested Time in seconds", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 6000), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "07 - Potions", Order = order++ } })); mediumRestedPotionCooldown = config("Bonfire in a Bottle", "Potion cooldown", 1, new ConfigDescription("Potion use cooldown time in seconds", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 6000), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "07 - Potions", Order = order++ } })); largeRestedPotionRestedTime = config("Livingroom in a Bottle", "Rested time", baseRestedTime.Value + restedPerComfort.Value * 10, new ConfigDescription("Potion use rested Time in seconds", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 6000), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "07 - Potions", Order = order++ } })); largeRestedPotionCooldown = config("Livingroom in a Bottle", "Potion cooldown", 1, new ConfigDescription("Potion use cooldown time in seconds", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 6000), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "07 - Potions", Order = order++ } })); enableGroupBuff = config("9. Buffs", "Enable Group Buff", value: false, new ConfigDescription("Gain Bonus Comfort when resting Together?", (AcceptableValueBase)null, new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "08 - Buffs", Order = order++ } })); nearbyGroupRadius = config("9. Buffs", "Rest Together Radius", 4, new ConfigDescription("Range at which group members count as resting together", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "08 - Buffs", Order = order++ } })); nearbyGroupMembers = config("9. Buffs", "Rest Together Group Percent", 50, new ConfigDescription("Percentage of Party (rounded down, minimum 2 people) that has to be resting together", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "08 - Buffs", Order = order++ } }), synchronizedSetting: true, showAsPercent: true); nearbyGroupComfort = config("9. Buffs", "Rest Together Group Comfort", 2, new ConfigDescription("Comfort provided by resting together", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "08 - Buffs", Order = order++ } })); isVisible = ((BaseUnityPlugin)this).Config.Bind<bool>("x. Advanced Options", "Value of Hotkey toggle (showing/not showing)", false, new ConfigDescription("Saves the Value of Hotkey Toggle", (AcceptableValueBase)null, new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Browsable = false, Category = "Hidden", Order = 9999 } })); if (Jewelcrafting.API.IsLoaded()) { AllGems.Initialize(); AllJewelry.Initialize(); } AllPotions.Initialize(); if (Groups.API.IsLoaded()) { AllBuffs.Initialize(); } ((BaseUnityPlugin)this).Config.SaveOnConfigSet = true; ((BaseUnityPlugin)this).Config.Save(); Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null); } private void Update() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (isEnabled.Value) { KeyboardShortcut value = showPiecesHotkey.Value; if (((KeyboardShortcut)(ref value)).IsDown() && (!Object.op_Implicit((Object)(object)Chat.instance) || !Chat.instance.HasFocus()) && !Console.IsVisible() && !TextInput.IsVisible() && !StoreGui.IsVisible() && !InventoryGui.IsVisible() && !Menu.IsVisible() && (!Object.op_Implicit((Object)(object)TextViewer.instance) || !TextViewer.instance.IsVisible()) && !Minimap.IsOpen() && !GameCamera.InFreeFly()) { isVisible.Value = !isVisible.Value; ((BaseUnityPlugin)this).Config.Save(); } } } private void OnGUI() { //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Expected O, but got Unknown //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_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Expected O, but got Unknown //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_031e: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_03da: Unknown result type (might be due to invalid IL or missing references) //IL_03e9: Unknown result type (might be due to invalid IL or missing references) //IL_03ee: Unknown result type (might be due to invalid IL or missing references) //IL_0476: Unknown result type (might be due to invalid IL or missing references) if (!isEnabled.Value || !showPieces.Value || !isVisible.Value || !Object.op_Implicit((Object)(object)EnvMan.instance) || Player.m_localPlayer == null || (showOnlyInShelter.Value && !Player.m_localPlayer.InShelter() && !ignoreShelter.Value) || (Object.op_Implicit((Object)(object)Chat.instance) && Chat.instance.HasFocus()) || Console.IsVisible() || TextInput.IsVisible() || StoreGui.IsVisible() || InventoryGui.IsVisible() || Menu.IsVisible() || (Object.op_Implicit((Object)(object)TextViewer.instance) && TextViewer.instance.IsVisible()) || Minimap.IsOpen() || GameCamera.InFreeFly()) { return; } if (!guiTimer.IsRunning) { guiTimer.Start(); } if (fontCache == null) { fontCache = ((IEnumerable<Font>)Resources.FindObjectsOfTypeAll<Font>()).FirstOrDefault((Func<Font, bool>)((Font val3) => ((Object)val3).name == "AveriaSerifLibre-Bold")); } if (longestWord == 0) { longestWord = allComfortPieces.Max<KeyValuePair<string, Piece>>((KeyValuePair<string, Piece> keyValuePair) => regex.Replace(english.Localize(keyValuePair.Key), "").Length); } GUIStyle val = new GUIStyle { richText = true, fontSize = showPiecesFontSize.Value, alignment = (TextAnchor)3, font = fontCache }; GUIStyle val2 = new GUIStyle { richText = true, fontSize = showPiecesFontSize.Value, alignment = (TextAnchor)3, font = fontCache }; val.normal.textColor = showPiecesFontColor.Value; val2.normal.textColor = missingPiecesFontColor.Value; if ((!Player.m_localPlayer.InShelter() || !showOnlyInShelter.Value) && showOnlyInShelter.Value) { return; } if (guiTimer.Elapsed.Seconds >= updateInterval.Value) { outputList.Clear(); if (showGainedComfortPieces.Value) { outputList.AddRange(gainedComfortPieces); } if (showMissingComfortPieces.Value) { outputList.AddRange(missingComfortPieces); } outputList = (from val3 in outputList orderby (int)val3.m_comfortGroup, val3.m_comfort, regex.Replace(english.Localize(val3.m_name), "") select val3).ToList(); guiTimer.Restart(); } GUI.Label(new Rect(new Vector2((float)showPiecesLocationX.Value / 100f * (float)Screen.width, (float)showPiecesLocationY.Value / 100f * (float)Screen.height), new Vector2(0f, 0f)), (gainedComfortPieces.Count > 0) ? string.Format("{0,-" + (longestWord + 3) + "}\t| {1} \t| {2}", "Piece Name".PadRight(longestWord), "Comfort", "Comfort Group") : "", val); int x; for (x = 0; x < outputList.Count; x++) { GUI.Label(new Rect(new Vector2((float)showPiecesLocationX.Value / 100f * (float)Screen.width, (float)showPiecesLocationY.Value / 100f * (float)Screen.height + (float)((x + 1) * showPiecesFontSize.Value + 2)), new Vector2(0f, 0f)), string.Format("{0,-" + (longestWord + 3) + "}\t| {1} Comfort \t| {2}", regex.Replace(english.Localize(outputList[x].m_name), "").PadRight(longestWord), outputList[x].m_comfort, outputList[x].m_comfortGroup), missingComfortPieces.Any((Piece g) => regex.Replace(english.Localize(g.m_name), "") == regex.Replace(english.Localize(outputList[x].m_name), "")) ? val2 : val); } } private static void SeCozySettingChanged(object sender, EventArgs e) { ConfigEntry<bool> val = isEnabled; if (val != null && !val.Value) { return; } Player[] array = Object.FindObjectsOfType<Player>(); foreach (Player val2 in array) { foreach (SE_Cozy item in from s in ((Character)val2).GetSEMan().GetStatusEffects() select (SE_Cozy)(object)((s is SE_Cozy) ? s : null) into s where (Object)(object)s != (Object)null select s) { if (!((Object)(object)item == (Object)null)) { item.m_delay = restedDelay.Value; ((SE_Stats)item).m_staminaRegenMultiplier = (float)cozyStaminaRegenMultiplierPercent.Value / 100f; ((SE_Stats)item).m_healthRegenMultiplier = (float)cozyHealthRegenMultiplierPercent.Value / 100f; ((SE_Stats)item).m_eitrRegenMultiplier = (float)cozyEitrRegenMultiplierPercent.Value / 100f; } } } } private static void SeRestedSettingChanged(object sender, EventArgs e) { //IL_01d8: Unknown result type (might be due to invalid IL or missing references) ConfigEntry<bool> val = isEnabled; if (val != null && !val.Value) { return; } Player[] array = Object.FindObjectsOfType<Player>(); foreach (Player val2 in array) { foreach (SE_Rested item in from s in ((Character)val2).GetSEMan().GetStatusEffects() select (SE_Rested)(object)((s is SE_Rested) ? s : null) into s where (Object)(object)s != (Object)null select s) { if ((Object)(object)item != (Object)null && ((StatusEffect)item).m_ttl > (float)(baseRestedTime.Value + 20 * restedPerComfort.Value)) { ManualLogSource obj = logger; if (obj != null) { obj.LogDebug((object)"over cap, limiting rested"); } ((StatusEffect)item).m_ttl = baseRestedTime.Value + 20 * restedPerComfort.Value; } if (!((Object)(object)item == (Object)null)) { item.m_baseTTL = baseRestedTime.Value; item.m_TTLPerComfortLevel = restedPerComfort.Value; ((SE_Stats)item).m_raiseSkillModifier = raiseSkillModifier.Value; ((SE_Stats)item).m_staminaRegenMultiplier = (float)staminaRegenMultiplierPercent.Value / 100f; ((SE_Stats)item).m_runStaminaDrainModifier = 0f - (float)runStaminaDrainModifierPercent.Value / 100f; ((SE_Stats)item).m_jumpStaminaUseModifier = 0f - (float)jumpStaminaDrainModifierPercent.Value / 100f; ((SE_Stats)item).m_healthRegenMultiplier = (float)healthRegenMultipierPercent.Value / 100f; ((SE_Stats)item).m_eitrRegenMultiplier = (float)eitrRegenMultipierPercent.Value / 100f; ((SE_Stats)item).m_damageModifier = damageModifier.Value; if (((SE_Stats)item).m_damageModifier > 1f) { ((SE_Stats)item).m_modifyAttackSkill = (SkillType)999; } ((SE_Stats)item).m_addMaxCarryWeight = addMaxCarryWeight.Value; ((SE_Stats)item).m_speedModifier = speedModifier.Value; } } } } private static void ChangeWarmthPieces(ref List<GameObject> prefabs) { //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Expected O, but got Unknown foreach (GameObject item in prefabs.Where((GameObject x) => x.GetComponentsInChildren<SphereCollider>(true).Count((SphereCollider y) => ((y != null) ? ((Object)y).name : null) == "FireWarmth") > 0)) { string name = item.GetComponent<Piece>().m_name; if (firePieces.ContainsKey(name)) { continue; } SphereCollider val = item.GetComponentsInChildren<SphereCollider>(true).First((SphereCollider x) => ((x != null) ? ((Object)x).name : null) == "FireWarmth"); if (val == null) { continue; } firePieces[name] = mod.config("10 - Fire", regex.Replace(english.Localize(name), ""), val.radius, new ConfigDescription("Set Radius of Fire Buff for " + regex.Replace(english.Localize(name), ""), (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 100f), new object[1] { new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Category = "10 - Fire", Order = 10 } })); firePieces[name].SettingChanged += FirePieceSettingChanged; foreach (SphereCollider item2 in from x in item.GetComponentsInChildren<SphereCollider>(true) where ((x != null) ? ((Object)x).name : null) == "FireWarmth" select x) { item2.radius = firePieces[name].Value; } } } private static void FirePieceSettingChanged(object o, EventArgs e) { foreach (EffectArea allArea in EffectArea.GetAllAreas()) { string name = ((Component)allArea).GetComponentInParent<Piece>().m_name; if (firePieces.TryGetValue(name, out ConfigEntry<float> value)) { Collider collider = allArea.m_collider; SphereCollider val = (SphereCollider)(object)((collider is SphereCollider) ? collider : null); if (val != null && ((Object)collider).name == "FireWarmth") { val.radius = value.Value; } } } } private static IEnumerator ReplaceFixedUpdate(Player player) { while (isEnabled.Value) { List<Piece> list = new List<Piece>(); HashSet<string> nearbyPieceNames = new HashSet<string>(); Dictionary<ComfortGroup, List<Piece>> dictionary = new Dictionary<ComfortGroup, List<Piece>>(); Piece.GetAllComfortPiecesInRadius(((Component)player).transform.localPosition, (float)comfortRadius.Value, list); list.ForEach(delegate(Piece pcs) { nearbyPieceNames.Add(regex.Replace(english.Localize(pcs.m_name), "")); }); foreach (Piece item in comfortPieceSet.Where((Piece piece) => !showKnownComfortPieces.Value || player.HaveRequirements(piece, (RequirementMode)1))) { if (!dictionary.TryGetValue(item.m_comfortGroup, out var value)) { value = new List<Piece>(); dictionary[item.m_comfortGroup] = value; } value.Add(item); } Dictionary<ComfortGroup, int> dictionary2 = (from g in list group g by g.m_comfortGroup).ToDictionary((IGrouping<ComfortGroup, Piece> g) => g.Key, (IGrouping<ComfortGroup, Piece> g) => g.Max((Piece c) => c.m_comfort)); foreach (KeyValuePair<ComfortGroup, List<Piece>> item2 in dictionary.Where((KeyValuePair<ComfortGroup, List<Piece>> keyValuePair) => (int)keyValuePair.Key > 0)) { if (!dictionary2.TryGetValue(item2.Key, out var highestComfort)) { highestComfort = 0; } highestComfort = Mathf.Max(item2.Value.Max((Piece c) => c.m_comfort), highestComfort); item2.Value.RemoveAll((Piece c) => c.m_comfort < highestComfort); } foreach (KeyValuePair<ComfortGroup, List<Piece>> pieceInfo in dictionary) { if ((int)pieceInfo.Key == 0) { pieceInfo.Value.RemoveAll((Piece pce) => nearbyPieceNames.Contains(regex.Replace(english.Localize(pce.m_name), ""))); } else if (pieceInfo.Value.Count == 0 || pieceInfo.Value.First().m_comfort == (from c in list where c.m_comfortGroup == pieceInfo.Key select c.m_comfort).DefaultIfEmpty(0).Max()) { pieceInfo.Value.Clear(); } } dictionary.TryGetValue((ComfortGroup)0, out var value2); missingComfortPieces.Clear(); if (value2 != null) { missingComfortPieces = value2.Where((Piece x) => x.m_enabled && ((Object)x).name != "ArmorStand_Female" && x.m_comfort > 0).ToList(); } missingComfortPieces.AddRange((from v in dictionary where (int)v.Key > 0 select v.Value).SelectMany((List<Piece> x) => x.Take(1))); gainedComfortPieces.Clear(); gainedComfortPieces = (from g in list where g.m_comfort > 0 group g by g.m_comfortGroup).SelectMany((IGrouping<ComfortGroup, Piece> g) => ((int)g.Key != 0) ? g.Where((Piece c) => c.m_comfort == g.Max((Piece g_p) => g_p.m_comfort)).Take(1) : (from n in g group n by regex.Replace(english.Localize(n.m_name), "") into f select f.First())).ToList(); yield return (object)new WaitForSeconds((float)updateInterval.Value); } } private ConfigEntry<T> config<T>(string group, string key, T value, ConfigDescription description, bool synchronizedSetting = true, bool showAsPercent = false) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown _configOrderCount.TryGetValue(group, out var value2); description = new ConfigDescription(description.Description, description.AcceptableValues, CollectionExtensions.AddItem<object>((IEnumerable<object>)description.Tags, (object)new <b0bea54f-bee4-4320-bc59-ec9a568b3945>ConfigurationManagerAttributes { Order = value2, ShowRangeAsPercent = showAsPercent }).ToArray()); value2 = (_configOrderCount[group] = value2 - 1); ConfigEntry<T> val = ((BaseUnityPlugin)this).Config.Bind<T>(group.Trim(), key.Trim(), value, description); SyncedConfigEntry<T> syncedConfigEntry = configSync.AddConfigEntry<T>(val); syncedConfigEntry.SynchronizedConfig = synchronizedSetting; return val; } private ConfigEntry<T> config<T>(string group, string key, T value, string description, bool synchronizedSetting = true, bool showAsPercent = false) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown return config(group, key, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting, showAsPercent); } } } namespace ComfortTweaks.potions { public static class AllPotions { public static void Initialize() { AssetBundle assets = PrefabManager.RegisterAssetBundle("ctweaks"); RestedPotionsSetup.initRestedPotions(assets); } } public static class Utils { private static void ItemValue<T>(Item item, Action<SharedData, T> setter, ConfigEntry<T> config) { string itemName = item.Prefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_name; config.SettingChanged += delegate { if (Object.op_Implicit((Object)(object)ObjectDB.instance)) { Inventory[] source = Player.s_players.Select((Player p) => ((Humanoid)p).GetInventory()).Concat(from c in Object.FindObjectsOfType<Container>() select c.GetInventory()).ToArray(); foreach (ItemData item2 in (from i in (from p in ObjectDB.instance.m_items select p.GetComponent<ItemDrop>() into c where Object.op_Implicit((Object)(object)c) && Object.op_Implicit((Object)(object)((Component)c).GetComponent<ZNetView>()) select c).Concat(ItemDrop.s_instances) select i.m_itemData).Concat(source.SelectMany((Inventory i) => i.GetAllItems()))) { if (itemName == item2.m_shared.m_name) { setter(item2.m_shared, config.Value); } } } set(); }; set(); void set() { setter(item.Prefab.GetComponent<ItemDrop>().m_itemData.m_shared, config.Value); } } public static void SEValue<T>(Item potion, Action<SE_Stats, T> setter, ConfigEntry<T> config) { ItemValue(potion, delegate(SharedData i, T c) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown setter((SE_Stats)i.m_consumeStatusEffect, c); }, config); } public static T ConvertConsumeSEStats<T>(GameObject item) where T : StatusEffect { SharedData shared = item.GetComponent<ItemDrop>().m_itemData.m_shared; StatusEffect consumeStatusEffect = shared.m_consumeStatusEffect; T val = ScriptableObject.CreateInstance<T>(); shared.m_consumeStatusEffect = (StatusEffect)(object)val; ((Object)(object)val).name = ((Object)consumeStatusEffect).name; FieldInfo[] fields = ((object)consumeStatusEffect).GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { fieldInfo.SetValue(val, fieldInfo.GetValue(consumeStatusEffect)); } return val; } } public static class RestedPotionsSetup { public static void initRestedPotions(AssetBundle assets) { if (ComfortTweaks.isEnabled.Value) { Item item = new Item(assets, "ct_campfireinabottle"); item.Crafting.Add(CraftingTable.Cauldron, 1); item.RequiredItems.Add("QueensJam", 1); ItemDrop component = item.Prefab.GetComponent<ItemDrop>(); component.m_itemData.m_shared.m_weight = 1f; component.m_itemData.m_shared.m_ammoType = "mead"; component.m_itemData.m_shared.m_consumeStatusEffect.m_tooltip = Localization.instance.Localize($"<color=#00FFEE>$ct_campfireinabottle_tooltip</color>{Environment.NewLine}$ct_rested: <color=#00FFEE>{ComfortTweaks.smallRestedPotionRestedTime.Value / 60}:{ComfortTweaks.smallRestedPotionRestedTime.Value % 60:D2}</color>"); component.m_itemData.m_shared.m_consumeStatusEffect.m_category = "restedPotion"; component.m_itemData.m_shared.m_consumeStatusEffect.m_icon = component.m_itemData.GetIcon(); component.m_itemData.m_shared.m_consumeStatusEffect.m_name = component.m_itemData.m_shared.m_name; component.m_itemData.m_shared.m_consumeStatusEffect.m_nameHash = StringExtensionMethods.GetStableHashCode(component.m_itemData.m_shared.m_name); Utils.ConvertConsumeSEStats<RestedPotion>(item.Prefab); Utils.SEValue(item, delegate(SE_Stats effect, int value) { ((StatusEffect)effect).m_ttl = value; }, ComfortTweaks.smallRestedPotionCooldown); Utils.SEValue(item, delegate(SE_Stats effect, int value) { ((StatusEffect)effect).m_cooldown = value; }, ComfortTweaks.smallRestedPotionCooldown); Utils.SEValue(item, delegate(SE_Stats effect, int value) { ((RestedPotion)(object)effect).restedTime = value; }, ComfortTweaks.smallRestedPotionRestedTime); Item item2 = new Item(assets, "ct_bonfireinabottle"); item2["mediumUpgrade"].Crafting.Add(CraftingTable.Cauldron, 2); item2["mediumUpgrade"].RequiredItems.Add("ct_campfireinabottle", 1); item2["mediumUpgrade"].RequiredItems.Add("OnionSoup", 1); item2["mediumScratch"].Crafting.Add(CraftingTable.Cauldron, 2); item2["mediumScratch"].RequiredItems.Add("QueensJam", 1); item2["mediumScratch"].RequiredItems.Add("OnionSoup", 1); ItemDrop component2 = item2.Prefab.GetComponent<ItemDrop>(); component2.m_itemData.m_shared.m_weight = 1f; component2.m_itemData.m_shared.m_ammoType = "mead"; component2.m_itemData.m_shared.m_consumeStatusEffect.m_tooltip = Localization.instance.Localize($"<color=#00FFEE>$ct_bonfireinabottle_tooltip</color>{Environment.NewLine}$ct_rested: <color=#00FFEE>{ComfortTweaks.mediumRestedPotionRestedTime.Value / 60}:{ComfortTweaks.mediumRestedPotionRestedTime.Value % 60:D2}</color>"); component2.m_itemData.m_shared.m_consumeStatusEffect.m_category = "restedPotion"; component2.m_itemData.m_shared.m_consumeStatusEffect.m_icon = component2.m_itemData.GetIcon(); component2.m_itemData.m_shared.m_consumeStatusEffect.m_name = component2.m_itemData.m_shared.m_name; Utils.ConvertConsumeSEStats<RestedPotion>(item2.Prefab); Utils.SEValue(item2, delegate(SE_Stats effect, int value) { ((StatusEffect)effect).m_ttl = value; }, ComfortTweaks.mediumRestedPotionCooldown); Utils.SEValue(item2, delegate(SE_Stats effect, int value) { ((StatusEffect)effect).m_cooldown = value; }, ComfortTweaks.mediumRestedPotionCooldown); Utils.SEValue(item2, delegate(SE_Stats effect, int value) { ((RestedPotion)(object)effect).restedTime = value; }, ComfortTweaks.mediumRestedPotionRestedTime); Item item3 = new Item(assets, "ct_livingroominabottle"); item3["largeUpgrade"].Crafting.Add(CraftingTable.Cauldron, 3); item3["largeUpgrade"].RequiredItems.Add("ct_bonfireinabottle", 1); item3["largeUpgrade"].RequiredItems.Add("BarleyWineBase", 1); item3["largeScratch"].Crafting.Add(CraftingTable.Cauldron, 3); item3["largeScratch"].RequiredItems.Add("QueensJam", 1); item3["largeScratch"].RequiredItems.Add("OnionSoup", 1); item3["largeScratch"].RequiredItems.Add("BarleyWineBase", 1); ItemDrop component3 = item3.Prefab.GetComponent<ItemDrop>(); component3.m_itemData.m_shared.m_weight = 1f; component3.m_itemData.m_shared.m_ammoType = "mead"; component3.m_itemData.m_shared.m_consumeStatusEffect.m_tooltip = Localization.instance.Localize($"<color=#00FFEE>$ct_livingroominabottle_tooltip</color>{Environment.NewLine}$ct_rested: <color=#00FFEE>{ComfortTweaks.largeRestedPotionRestedTime.Value / 60}:{ComfortTweaks.largeRestedPotionRestedTime.Value % 60:D2}</color>"); component3.m_itemData.m_shared.m_consumeStatusEffect.m_cooldownIcon = true; component3.m_itemData.m_shared.m_consumeStatusEffect.m_category = "restedPotion"; component3.m_itemData.m_shared.m_consumeStatusEffect.m_icon = component3.m_itemData.GetIcon(); component3.m_itemData.m_shared.m_consumeStatusEffect.m_name = component3.m_itemData.m_shared.m_name; Utils.ConvertConsumeSEStats<RestedPotion>(item3.Prefab); Utils.SEValue(item3, delegate(SE_Stats effect, int value) { ((StatusEffect)effect).m_ttl = value; }, ComfortTweaks.largeRestedPotionCooldown); Utils.SEValue(item3, delegate(SE_Stats effect, int value) { ((StatusEffect)effect).m_cooldown = value; }, ComfortTweaks.largeRestedPotionCooldown); Utils.SEValue(item3, delegate(SE_Stats effect, int value) { ((RestedPotion)(object)effect).restedTime = value; }, ComfortTweaks.largeRestedPotionRestedTime); } } } public class RestedPotion : SE_Stats { public int restedTime; public override void Setup(Character character) { if (!ComfortTweaks.isEnabled.Value) { return; } ((SE_Stats)this).Setup(character); Player val = (Player)(object)((character is Player) ? character : null); if (val != null) { Debug.Log((object)("statusEffect: " + (object)character.m_seman.GetStatusEffect(ComfortTweaks.restedHash))); if (((Character)val).m_seman.GetStatusEffect(ComfortTweaks.restedHash) == null) { val.m_comfortLevel = (restedTime - ComfortTweaks.baseRestedTime.Value) / ComfortTweaks.restedPerComfort.Value + 1; ((Character)val).m_seman.AddStatusEffect(ComfortTweaks.restedHash, true, 0, 0f).m_ttl = restedTime; return; } val.m_comfortLevel = (restedTime - ComfortTweaks.baseRestedTime.Value) / ComfortTweaks.restedPerComfort.Value + 1; ((Character)val).m_seman.GetStatusEffect(ComfortTweaks.restedHash).m_ttl = restedTime; ((Character)val).m_seman.GetStatusEffect(ComfortTweaks.restedHash).m_time = 0f; ((Character)val).Message((MessageType)2, $"$se_rested_start ($se_rested_comfort:{(restedTime - ComfortTweaks.baseRestedTime.Value) / ComfortTweaks.restedPerComfort.Value + 1})", 0, (Sprite)null); } } } [HarmonyPatch(typeof(Player), "CanConsumeItem")] public static class ConsumePotion { [UsedImplicitly] private static void Postfix(Player __instance, ItemData item, ref bool __result) { if (ComfortTweaks.isEnabled.Value && item.m_shared.m_consumeStatusEffect is RestedPotion restedPotion) { if ((Object)(object)((Character)__instance).m_seman.GetStatusEffect(ComfortTweaks.restedHash) != (Object)null && (float)restedPotion.restedTime <= ((Character)__instance).m_seman.GetStatusEffect(ComfortTweaks.restedHash).m_ttl - ((Character)__instance).m_seman.GetStatusEffect(ComfortTweaks.restedHash).m_time) { ((Character)__instance).Message((MessageType)2, "Theres no need to drink this potion!", 0, (Sprite)null); __result = false; } if ((Object)(object)((Character)__instance).m_seman.GetStatusEffect(ComfortTweaks.restingHash) != (Object)null) { ((Character)__instance).Message((MessageType)2, "You are already resting.", 0, (Sprite)null); __result = false; } } } } } namespace ComfortTweaks.gems { public static class Acceleration { [PublicAPI] public struct Config { [InverseMultiplicativePercentagePower] public float Power; } static Acceleration() { if (Jewelcrafting.API.IsLoaded() && ComfortTweaks.isEnabled.Value) { AnimationSpeedManager.Add(delegate(Character character, double speed) { Player val = (Player)(object)((character is Player) ? character : null); return (val == null || !((Character)val).InAttack() || ((Humanoid)val).m_currentAttack == null || Player.m_localPlayer == null || !((Character)val).m_seman.HaveStatusEffect(ComfortTweaks.restedHash)) ? speed : (speed * (double)(1f + Player.m_localPlayer.GetEffectPower<Config>("Acceleration").Power / 100f)); }); } } } public static class Nourishing { [PublicAPI] public struct Config { [MaxPower] public float Health; [MaxPower] public float ComfortRequirement; } [HarmonyPatch(typeof(Player), "EatFood")] public static class GetFoodHealth { [UsedImplicitly] private static void Postfix(Player __instance, ItemData item, bool __result) { if (Jewelcrafting.API.IsLoaded() && ComfortTweaks.isEnabled.Value && __result && ((Character)__instance).m_seman.HaveStatusEffect(ComfortTweaks.restingHash) && (float)__instance.m_comfortLevel >= Player.m_localPlayer.GetEffectPower<Config>("Nourishing").ComfortRequirement) { ((Character)__instance).Heal(item.m_shared.m_food * Player.m_localPlayer.GetEffectPower<Config>("Nourishing").Health / 100f, true); } } } } public static class Relaxed { [PublicAPI] public struct Config { [AdditivePower] public float Power; } [HarmonyPatch(typeof(SE_Rested), "UpdateTTL")] public static class IncreaseComfortTime { [UsedImplicitly] private static void Postfix(SE_Rested __instance) { if (Jewelcrafting.API.IsLoaded() && ComfortTweaks.isEnabled.Value) { __instance.m_TTLPerComfortLevel = (float)ComfortTweaks.restedPerComfort.Value + Player.m_localPlayer.GetEffectPower<Config>("Relaxed").Power; } } } } public static class AllGems { public static void Initialize() { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) if (!Jewelcrafting.API.IsLoaded() || !ComfortTweaks.isEnabled.Value) { return; } foreach (Type item in from t in typeof(AllGems).Assembly.GetTypes() where (t.Namespace ?? "").StartsWith(typeof(AllGems).Namespace, StringComparison.Ordinal) select t) { RuntimeHelpers.RunClassConstructor(item.TypeHandle); } StringBuilder stringBuilder = new StringBuilder(); Jewelcrafting.API.AddGems("Comfortite", "blueish", new Color(0.3f, 0.47f, 0.57f)); Jewelcrafting.API.AddGems("Comfordium", "redish", new Color(0.9f, 0.22f, 0.42f)); Jewelcrafting.API.AddGemEffect<Relaxed.Config>("Relaxed", "Increases the rested time per comfort", "Rested time is increased by $1s per comfort level."); stringBuilder.AppendLine("Relaxed:"); stringBuilder.AppendLine(" slot: utility"); stringBuilder.AppendLine(" gem: redish"); stringBuilder.AppendLine(" power: [6,12,30]"); Jewelcrafting.API.AddGemEffect<Refreshed_Mind.Config>("Refreshed Mind", "Increases XP gain while rested", "XP increased by $1% while rested."); stringBuilder.AppendLine("Refreshed Mind:"); stringBuilder.AppendLine(" slot: head"); stringBuilder.AppendLine(" gem: blueish"); stringBuilder.AppendLine(" power: [5,10,25]"); Jewelcrafting.API.AddGemEffect<Overexertion.Config>("Overexertion", "Overexert your attacks, increasing damage by using your vitality.", "Damage increased by $1%. While rested, you lose $2% of rested buff per hit, if you're not rested, you will take $2% damage instead."); stringBuilder.AppendLine("Overexertion:"); stringBuilder.AppendLine(" slot: weapon"); stringBuilder.AppendLine(" gem: blueish"); stringBuilder.AppendLine(" power:"); stringBuilder.AppendLine(" damage increase: [10,20,40]"); stringBuilder.AppendLine(" penalty: [1,2,4]"); Jewelcrafting.API.AddGemEffect<Restless_Legs.Config>("Restless Legs", "While rested, run stamina drain is reduced.", "Stamina drain is decreased by $1% while rested."); stringBuilder.AppendLine("Restless Legs:"); stringBuilder.AppendLine(" slot: legs"); stringBuilder.AppendLine(" gem: blueish"); stringBuilder.AppendLine(" power: [10,25,50]"); Jewelcrafting.API.AddGemEffect<Invigorated.Config>("Invigorated", "Increased stamina regeneration while rested", "Stamina regeneration is increased by $1% while rested."); stringBuilder.AppendLine("Invigorated:"); stringBuilder.AppendLine(" slot: chest"); stringBuilder.AppendLine(" gem: redish"); stringBuilder.AppendLine(" power: [10,25,50]"); Jewelcrafting.API.AddGemEffect<Acceleration.Config>("Acceleration", "Increased attack speed while rested", "Attack speed is increased by $1% while rested."); stringBuilder.AppendLine("Acceleration:"); stringBuilder.AppendLine(" slot: weapon"); stringBuilder.AppendLine(" gem: redish"); stringBuilder.AppendLine(" power: [2,4,6]"); Jewelcrafting.API.AddGemEffect<Secret_Pocket.Config>("Secret Pocket", "You relax your \"secret pocket\" and can fit a few items in there but its kind of uncomfortable", "Carry Weight is increased by $1 while rested."); stringBuilder.AppendLine("Secret Pocket:"); stringBuilder.AppendLine(" slot: legs"); stringBuilder.AppendLine(" gem: redish"); stringBuilder.AppendLine(" power:"); stringBuilder.AppendLine(" power: [50,100,150]"); stringBuilder.AppendLine(" uncomfort: [1,3,5]"); Jewelcrafting.API.AddGemEffect<Nourishing.Config>("Nourishing", "Food heals you for a percentage of the health it adds while resting", "Food heals you for $1% of the foods health while resting with at least $2% comfort."); stringBuilder.AppendLine("Nourishing:"); stringBuilder.AppendLine(" slot: cloak"); stringBuilder.AppendLine(" gem: blueish"); stringBuilder.AppendLine(" power:"); stringBuilder.AppendLine(" health: [25,50,100]"); stringBuilder.AppendLine(" comfort requirement: [3,5,10]"); stringBuilder.AppendLine("gems:"); stringBuilder.AppendLine(" Meadows:"); stringBuilder.AppendLine(" blueish: 0.001"); stringBuilder.AppendLine(" redish: 0.02"); stringBuilder.AppendLine(" Black Forest:"); stringBuilder.AppendLine(" blueish: 0.005"); stringBuilder.AppendLine(" redish: 0.015"); stringBuilder.AppendLine(" Swamp:"); stringBuilder.AppendLine(" blueish: 0.008"); stringBuilder.AppendLine(" redish: 0.01"); stringBuilder.AppendLine(" Mountain:"); stringBuilder.AppendLine(" blueish: 0.001"); stringBuilder.AppendLine(" redish: 0.08"); stringBuilder.AppendLine(" Plains:"); stringBuilder.AppendLine(" blueish: 0.015"); stringBuilder.AppendLine(" redish: 0.005"); stringBuilder.AppendLine(" Mistlands:"); stringBuilder.AppendLine(" blueish: 0.02"); stringBuilder.AppendLine(" redish: 0.003"); stringBuilder.AppendLine(" Ash Lands:"); stringBuilder.AppendLine(" blueish: 0.001"); stringBuilder.AppendLine(" redish: 0.001"); stringBuilder.AppendLine(" Deep North:"); stringBuilder.AppendLine(" blueish: 0.001"); stringBuilder.AppendLine(" redish: 0.001"); Jewelcrafting.API.AddGemConfig(stringBuilder.ToString()); } } public static class Invigorated { [PublicAPI] public struct Config { [InverseMultiplicativePercentagePower] public float Power; } [HarmonyPatch(typeof(SE_Rested), "UpdateTTL")] public static class IncreaseRestedStaminaRegeneration { [UsedImplicitly] private static void Postfix(SE_Rested __instance) { if (Jewelcrafting.API.IsLoaded() && ComfortTweaks.isEnabled.Value) { ((SE_Stats)__instance).m_staminaRegenMultiplier = (float)ComfortTweaks.staminaRegenMultiplierPercent.Value / 100f + Player.m_localPlayer.GetEffectPower<Config>("Invigorated").Power / 100f; } } } } public static class Overexertion { [PublicAPI] public struct Config { [AdditivePower] public float DamageIncrease; [AdditivePower] public float Penalty; } [HarmonyPatch(typeof(Character), "Damage")] [UsedImplicitly] private class AddOverexertionDamage { [UsedImplicitly] private static void Prefix(HitData hit) { //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Expected O, but got Unknown if (!Jewelcrafting.API.IsLoaded() || !ComfortTweaks.isEnabled.Value) { return; } Character attacker = hit.GetAttacker(); Player val = (Player)(object)((attacker is Player) ? attacker : null); if (val != null) { Config effectPower = val.GetEffectPower<Config>("Overexertion"); hit.ApplyModifier(1f + effectPower.DamageIncrease / 100f); StatusEffect statusEffect = ((Character)val).m_seman.GetStatusEffect(ComfortTweaks.restedHash); float? num = ((statusEffect != null) ? new float?(statusEffect.GetRemaningTime()) : ((float?)null)); StatusEffect statusEffect2 = ((Character)val).m_seman.GetStatusEffect(ComfortTweaks.restedHash); if (num >= ((statusEffect2 != null) ? new float?(statusEffect2.GetRemaningTime()) : ((float?)null)) * (effectPower.Penalty / 100f)) { StatusEffect statusEffect3 = ((Character)val).m_seman.GetStatusEffect(ComfortTweaks.restedHash); statusEffect3.m_ttl -= ((Character)val).m_seman.GetStatusEffect(ComfortTweaks.restedHash).GetRemaningTime() * (effectPower.Penalty / 100f); return; } ((Character)val).ApplyDamage(new HitData { m_damage = new DamageTypes { m_damage = ((Character)val).GetMaxHealth() * (effectPower.Penalty / 100f) }, m_point = ((Character)val).GetCenterPoint() }, true, true, (DamageModifier)0); } } } } public static class Refreshed_Mind { [PublicAPI] public struct Config { [InverseMultiplicativePercentagePower] public float Power; } [HarmonyPatch(typeof(SE_Rested), "UpdateTTL")] public static class IncreaseRestedXP { [UsedImplicitly] private static void Prefix(SE_Rested __instance) { if (Jewelcrafting.API.IsLoaded() && ComfortTweaks.isEnabled.Value) { ((SE_Stats)__instance).m_raiseSkillModifier = ComfortTweaks.raiseSkillModifier.Value + Player.m_localPlayer.GetEffectPower<Config>("Refreshed Mind").Power / 100f; } } } } public static class Restless_Legs { [PublicAPI] public struct Config { [InverseMultiplicativePercentagePower] public float Power; } [HarmonyPatch(typeof(SE_Rested), "UpdateTTL")] public static class DecreaseRestedRunStaminaDrain { [UsedImplicitly] private static void Postfix(SE_Rested __instance) { if (Jewelcrafting.API.IsLoaded() && ComfortTweaks.isEnabled.Value) { ((SE_Stats)__instance).m_runStaminaDrainModifier = 0f - ((float)ComfortTweaks.runStaminaDrainModifierPercent.Value / 100f + Player.m_localPlayer.GetEffectPower<Config>("Restless Legs").Power / 100f); } } } } public static class Secret_Pocket { [PublicAPI] public struct Config { [InverseMultiplicativePercentagePower] public float Power; [AdditivePower] public float Uncomfort; } [HarmonyPatch(typeof(Player), "GetMaxCarryWeight")] public static class IncreaseCarryWeight { [HarmonyPriority(500)] private static void Postfix(Player __instance, ref float __result) { if (Jewelcrafting.API.IsLoaded() && ComfortTweaks.isEnabled.Value && ((Character)__instance).m_seman.HaveStatusEffect(ComfortTweaks.restedHash)) { __result += __instance.GetEffectPower<Config>("Secret Pocket").Power; } } } [HarmonyPatch(typeof(SE_Rested), "CalculateComfortLevel", new Type[] { typeof(Player) })] public static class ReduceComfortLevel { [UsedImplicitly] private static void Postfix(Player player, ref int __result) { if (Jewelcrafting.API.IsLoaded() && ComfortTweaks.isEnabled.Value && player.m_maxCarryWeight - player.GetEffectPower<Config>("Secret Pocket").Power < ((Humanoid)player).m_inventory.m_totalWeight) { __result -= Mathf.RoundToInt(player.GetEffectPower<Config>("Secret Pocket").Uncomfort); } } } } } namespace ComfortTweaks.gems.Jewelry { public static class AllJewelry { public static class comfortableSatiation { [HarmonyPatch(typeof(Player), "UpdateFood")] public static class BypassFoodUpdate { [UsedImplicitly] private static void Prefix(Player __instance) { if (Jewelcrafting.API.IsLoaded() && ComfortTweaks.isEnabled.Value && ((Character)__instance).m_seman.HaveStatusEffect(comfortableSatiationHash) && __instance.m_foods.Count > 0) { __instance.m_foodUpdateTimer = 0f; } } } [HarmonyPatch(typeof(SEMan), "Internal_AddStatusEffect")] public static class AddStatusEffectToPlayer { [UsedImplicitly] private static void Postfix(int nameHash) { if (Jewelcrafting.API.IsLoaded() && ComfortTweaks.isEnabled.Value) { Player localPlayer = Player.m_localPlayer; if (localPlayer != null && ((Character)localPlayer).m_seman != null && ZNet.instance != null && Jewelcrafting.API.IsJewelryEquipped(localPlayer, "$jc_necklace_blueish") && nameHash == ComfortTweaks.restingHash) { ((Character)localPlayer).m_seman.AddStatusEffect(comfortableSatiationHash, false, 0, 0f); } } } } [HarmonyPatch(typeof(SEMan), "RemoveStatusEffect", new Type[] { typeof(int), typeof(bool) })] public static class RemoveStatusEffectsFromPlayer { [UsedImplicitly] private static void Postfix(int nameHash) { if (Jewelcrafting.API.IsLoaded() && ComfortTweaks.isEnabled.Value && nameHash == ComfortTweaks.restingHash) { ((Character)Player.m_localPlayer).m_seman.RemoveStatusEffect(comfortableSatiationHash, false); } } } public class NotHungry : StatusEffect { } private static Sprite blueishNecklaceIcon; static comfortableSatiation() { Jewelcrafting.API.OnEffectRecalc += delegate { if (!Jewelcrafting.API.IsJewelryEquipped(Player.m_localPlayer, "$jc_necklace_blueish")) { ((Character)Player.m_localPlayer).m_seman.RemoveStatusEffect(comfortableSatiationHash, false); } }; } public static void Init() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (Jewelcrafting.API.IsLoaded() && ComfortTweaks.isEnabled.Value) { Item item = new Item(Jewelcrafting.API.CreateNecklaceFromTemplate("blueish", new Color(0.3f, 0.47f, 0.57f))); item.Crafting.Add(((Object)Jewelcrafting.API.GetGemcuttersTable()).name, 3); item.MaximumRequiredStationLevel = 3; item.RequiredItems.Add("Chain", 1); item.RequiredItems.Add("Perfect_blueish_Socket", 1); item.RequiredUpgradeItems.Add("Coins", 500); blueishNecklaceIcon = item.Prefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_icons[0]; } } public static void blueishNecklaceEffect(ref List<StatusEffect> statusEffects) { StatusEffect val = (StatusEffect)(object)ScriptableObject.CreateInstance<NotHungry>(); ((Object)val).name = "comfortableSatiation"; val.m_name = "Comfortable Satiation"; val.m_nameHash = comfortableSatiationHash; val.m_icon = blueishNecklaceIcon; val.m_tooltip = "You're comfortably satiated. Your food timer wont decrease while resting."; statusEffects.Add(val); } } private static readonly int comfortableSatiationHash = StringExtensionMethods.GetStableHashCode("comfortableSatiation"); private static readonly int restedRadianceHash = StringExtensionMethods.GetStableHashCode("restedRadiance"); public static void Initialize() { comfortableSatiation.Init(); } } } namespace ComfortTweaks.buffs { public static class AllBuffs { public static void Initialize() { } } [HarmonyPatch(typeof(ObjectDB), "Awake")] public static class addBuffsToDB { private static List<StatusEffect> statusEffects = new List<StatusEffect>(); [UsedImplicitly] private static void Postfix(ObjectDB __instance) { if (!ComfortTweaks.isEnabled.Value) { return; } if (Groups.API.IsLoaded()) { RestTogetherEffects.restTogetherEffect(ref statusEffects); } if (Jewelcrafting.API.IsLoaded()) { AllJewelry.comfortableSatiation.blueishNecklaceEffect(ref statusEffects); } if (statusEffects.Count <= 0) { return; } foreach (StatusEffect statusEffect in statusEffects) { __instance.m_StatusEffects.Add(statusEffect); } } } public static class Utils { public static List<Player> GetNearbyGroupMembers(Player player, float range, bool includeSelf = false) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) if (!Groups.API.IsLoaded()) { return null; } List<PlayerReference> groupPlayers = Groups.API.GroupPlayers(); List<Player> list = new List<Player>(); Player.GetPlayersInRange(((Component)player).transform.position, range, list); list.RemoveAll((Player p) => !groupPlayers.Contains(PlayerReference.fromPlayer(p)) || (!includeSelf && (Object)(object)p == (Object)(object)player)); return list; } public static Sprite loadSprite(string name, int width, int height) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) return Sprite.Create(loadTexture(name), new Rect(0f, 0f, (float)width, (float)height), Vector2.zero); } private static Texture2D loadTexture(string name) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown Texture2D val = new Texture2D(0, 0); ImageConversion.LoadImage(val, ReadEmbeddedFileBytes("icons." + name), false); return val; } private static byte[] ReadEmbeddedFileBytes(string name) { using MemoryStream memoryStream = new MemoryStream(); Assembly.GetExecutingAssembly().GetManifestResourceStream("ComfortTweaks." + name)?.CopyTo(memoryStream); return memoryStream.ToArray(); } } [HarmonyPatch(typeof(SEMan), "Internal_AddStatusEffect")] public static class AddStatusEffectsToPlayer { private static void Postfix(int nameHash) { if (Groups.API.IsLoaded() && ComfortTweaks.isEnabled.Value) { Player localPlayer = Player.m_localPlayer; if (ComfortTweaks.isEnabled.Value && ComfortTweaks.enableGroupBuff.Value && localPlayer != null && ((Character)localPlayer).m_seman != null && ZNet.instance != null && Groups.API.GroupPlayers().Count >= 1 && nameHash == ComfortTweaks.restingHash && (double)Utils.GetNearbyGroupMembers(localPlayer, ComfortTweaks.nearbyGroupRadius.Value).Count >= Math.Max(1.0, Math.Floor((float)Groups.API.GroupPlayers().Count * ((float)ComfortTweaks.nearbyGroupMembers.Value / 100f))) && localPlayer.m_nearFireTimer > 0f && localPlayer.IsSafeInHome()) { ((Character)Player.m_localPlayer).m_seman.AddStatusEffect(StringExtensionMethods.GetStableHashCode("restTogether"), false, 0, 0f); } } } } [HarmonyPatch(typeof(SEMan), "RemoveStatusEffect", new Type[] { typeof(int), typeof(bool) })] public static class RemoveStatusEffectsFromPlayer { private static void Postfix(int nameHash) { if (Groups.API.IsLoaded() && ComfortTweaks.isEnabled.Value && nameHash == ComfortTweaks.restingHash) { ((Character)Player.m_localPlayer).m_seman.RemoveStatusEffect(StringExtensionMethods.GetStableHashCode("restTogether"), false); } } } [HarmonyPatch(typeof(SE_Rested), "CalculateComfortLevel", new Type[] { typeof(Player) })] public static class RaiseComfortIfRestingTogether { private static void Postfix(Player player, ref int __result) { if (ComfortTweaks.isEnabled.Value && ComfortTweaks.enableGroupBuff.Value && Groups.API.IsLoaded() && ((Character)player).m_seman.HaveStatusEffect(StringExtensionMethods.GetStableHashCode("restTogether"))) { __result += ComfortTweaks.nearbyGroupComfort.Value; } } } public class RestTogether : StatusEffect { } public static class RestTogetherEffects { public static void restTogetherEffect([NotNull] ref List<StatusEffect> statusEffects) { if (Groups.API.IsLoaded() && ComfortTweaks.isEnabled.Value) { StatusEffect val = (StatusEffect)(object)ScriptableObject.CreateInstance<RestTogether>(); val.m_name = "Resting Together"; ((Object)val).name = "restTogether"; val.m_nameHash = StringExtensionMethods.GetStableHashCode("restTogether"); val.m_icon = Utils.loadSprite("restTogether.png", 64, 64); val.m_tooltip = $"Resting with group members gives you {ComfortTweaks.nearbyGroupComfort.Value} bonus comfort!"; statusEffects.Add(val); } } } } namespace ServerSync { [PublicAPI] internal abstract class OwnConfigEntryBase { public object? LocalBaseValue; public bool SynchronizedConfig = true; public abstract ConfigEntryBase BaseConfig { get; } } [PublicAPI] internal class SyncedConfigEntry<T>(ConfigEntry<T> sourceConfig) : OwnConfigEntryBase() { public readonly ConfigEntry<T> SourceConfig = sourceConfig; public override ConfigEntryBase BaseConfig => (ConfigEntryBase)(object)SourceConfig; public T Value { get { return SourceConfig.Value; } set { SourceConfig.Value = value; } } public void AssignLocalValue(T value) { if (LocalBaseValue == null) { Value = value; } else { LocalBaseValue = value; } } } internal abstract class CustomSyncedValueBase { public object? LocalBaseValue; public readonly string Identifier; public readonly Type Type; private object? boxedValue; protected bool localIsOwner; public readonly int Priority; public object? BoxedValue { get { return boxedValue; } set { boxedValue = value; this.ValueChanged?.Invoke(); } } public event Action? ValueChanged; protected CustomSyncedValueBase(ConfigSync configSync, string identifier, Type type, int priority) { Priority = priority; Identifier = identifier; Type = type; configSync.AddCustomValue(this); localIsOwner = configSync.IsSourceOfTruth; configSync.SourceOfTruthChanged += delegate(bool truth) { localIsOwner = truth; }; } } [PublicAPI] internal sealed class CustomSyncedValue<T> : CustomSyncedValueBase { public T Value { get { return (T)base.BoxedValue; } set { base.BoxedValue = value; } } public CustomSyncedValue(ConfigSync configSync, string identifier, T value = default(T), int priority = 0) : base(configSync, identifier, typeof(T), priority) { Value = value; } public void AssignLocalValue(T value) { if (localIsOwner) { Value = value; } else { LocalBaseValue = value; } } } internal class ConfigurationManagerAttributes { [UsedImplicitly] public bool? ReadOnly = false; } [PublicAPI] internal class ConfigSync { [HarmonyPatch(typeof(ZRpc), "HandlePackage")] private static class SnatchCurrentlyHandlingRPC { public static ZRpc? currentRpc; [HarmonyPrefix] private static void Prefix(ZRpc __instance) { currentRpc = __instance; } } [HarmonyPatch(typeof(ZNet), "Awake")] internal static class RegisterRPCPatch { [HarmonyPostfix] private static void Postfix(ZNet __instance) { isServer = __instance.IsServer(); foreach (ConfigSync configSync2 in configSyncs) { ZRoutedRpc.instance.Register<ZPackage>(configSync2.Name + " ConfigSync", (Action<long, ZPackage>)configSync2.RPC_FromOtherClientConfigSync); if (isServer) { configSync2.InitialSyncDone = true; Debug.Log((object)("Registered '" + configSync2.Name + " ConfigSync' RPC - waiting for incoming connections")); } } if (isServer) { ((MonoBehaviour)__instance).StartCoroutine(Watch