using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("NowYouFloat")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("NowYouFloat")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("1dac10d4-b657-4e10-a8bf-d3ac5b0e47f0")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace NowYouFloat; [BepInPlugin("hex.nowyoufloat", "Now You Float", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "hex.nowyoufloat"; public const string PluginName = "Now You Float"; public const string PluginVersion = "1.0.0"; private static ConfigEntry _allowedExactPrefabsConfig; private static ConfigEntry _allowedNameContainsConfig; internal static HashSet AllowedExactPrefabs { get; private set; } internal static HashSet AllowedNameContains { get; private set; } internal static Plugin Instance { get; private set; } internal static Harmony HarmonyInstance { get; private set; } internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; _allowedExactPrefabsConfig = ((BaseUnityPlugin)this).Config.Bind("Prefabs", "AllowedExactPrefabs", "Copper,CopperOre,IronNails,BronzeNails,IronScrap,Iron,IronOre,BlackMetal,BlackMetalScrap,Silver,SilverOre,Tin,TinOre,SurtlingCore,DeerHide,CeramicPlate", "Comma-separated exact prefab names that should float."); _allowedNameContainsConfig = ((BaseUnityPlugin)this).Config.Bind("Prefabs", "AllowedNameContains", "Trophy", "Comma-separated text fragments. Any prefab name containing one of these values will float. Example: Trophy,Ore"); ReloadPrefabConfig(); _allowedExactPrefabsConfig.SettingChanged += delegate { ReloadPrefabConfig(); }; _allowedNameContainsConfig.SettingChanged += delegate { ReloadPrefabConfig(); }; HarmonyInstance = new Harmony("hex.nowyoufloat"); HarmonyInstance.PatchAll(); Log.LogInfo((object)"loaded (v1.0.0)."); } private void OnDestroy() { Instance = null; Harmony harmonyInstance = HarmonyInstance; if (harmonyInstance != null) { harmonyInstance.UnpatchSelf(); } Log.LogInfo((object)"[Now You Float] unloaded."); } private static void ReloadPrefabConfig() { AllowedExactPrefabs = ParseConfigList(_allowedExactPrefabsConfig.Value); AllowedNameContains = ParseConfigList(_allowedNameContainsConfig.Value); ManualLogSource log = Log; if (log != null) { log.LogInfo((object)$"Reloaded prefab config. Exact: {AllowedExactPrefabs.Count}, Contains: {AllowedNameContains.Count}"); } } private static HashSet ParseConfigList(string value) { HashSet hashSet = new HashSet(); if (string.IsNullOrWhiteSpace(value)) { return hashSet; } string[] array = value.Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (!string.IsNullOrWhiteSpace(text)) { hashSet.Add(text); } } return hashSet; } } [HarmonyPatch(typeof(ItemDrop), "Awake")] public static class ItemDropPatchAwake { private static readonly FieldInfo FloatingField = AccessTools.Field(typeof(ItemDrop), "m_floating"); private static Floating _referenceFloating; [HarmonyPostfix] private static void Postfix(ItemDrop __instance) { if (!((Object)(object)__instance == (Object)null) && __instance.m_itemData != null && !((Object)(object)__instance.m_itemData.m_dropPrefab == (Object)null) && !(FloatingField == null) && !((Object)/*isinst with value type is only supported in some contexts*/ != (Object)null) && ShouldFloat(((Object)__instance.m_itemData.m_dropPrefab).name)) { Floating val = ((Component)__instance).GetComponent(); if ((Object)(object)val == (Object)null) { val = ((Component)__instance).gameObject.AddComponent(); } Floating woodFLoatingReference = GetWoodFLoatingReference(); if ((Object)(object)woodFLoatingReference != (Object)null) { val.m_waterLevelOffset = woodFLoatingReference.m_waterLevelOffset; val.m_force = woodFLoatingReference.m_force; val.m_forceDistance = woodFLoatingReference.m_forceDistance; val.m_balanceForceFraction = woodFLoatingReference.m_balanceForceFraction; val.m_damping = woodFLoatingReference.m_damping; } FloatingField.SetValue(__instance, val); } } private static bool ShouldFloat(string prefabName) { if (string.IsNullOrWhiteSpace(prefabName)) { return false; } if (Plugin.AllowedExactPrefabs != null && Plugin.AllowedExactPrefabs.Contains(prefabName)) { return true; } if (Plugin.AllowedNameContains != null) { foreach (string allowedNameContain in Plugin.AllowedNameContains) { if (prefabName.Contains(allowedNameContain)) { return true; } } } return false; } private static Floating GetWoodFLoatingReference() { if ((Object)(object)_referenceFloating != (Object)null) { return _referenceFloating; } if ((Object)(object)ObjectDB.instance == (Object)null) { return null; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("Wood"); if ((Object)(object)itemPrefab == (Object)null) { return null; } ItemDrop component = itemPrefab.GetComponent(); if ((Object)(object)component == (Object)null) { return null; } _referenceFloating = ((Component)component).GetComponent(); return _referenceFloating; } }