From 099563eda1003c037722a6a1d9718dae939dc181 Mon Sep 17 00:00:00 2001 From: DaWrecka <61927940+DaWrecka@users.noreply.github.com> Date: Sun, 31 Jan 2021 16:07:46 +0000 Subject: [PATCH 01/11] 2021-01-31 commit *) Updated projects to use MrPurple's approach for setting variable paths, instead of hard paths like "D:\Steam\bluhbluh" *) AutosortLockers: Can be compiled into a DLL for BelowZero which is loaded, but lockers fail to instantiate properly --- .../AutosortLockers/AutosortLocker.cs | 61 +- ...ckers.csproj => AutosortLockersSML.csproj} | 84 +- .../AutosortLockers/AutosortTarget.cs | 54 +- .../AutosortLockers/AutosorterCategories.cs | 7 +- .../AutosortLockers/ColorPickerButton.cs | 11 +- SubnauticaModSystem/AutosortLockers/Config.cs | 6 +- .../AutosortLockers/LabelController.cs | 4 + SubnauticaModSystem/AutosortLockers/Mod.cs | 10 +- .../Patches/Initializer_Patch.cs | 2 +- .../AutosortLockers/{mod.json => mod_BZ.json} | 1 + .../AutosortLockers/mod_SN1.json | 10 + .../AutosortLockersSML/BZ/0Harmony.dll | Bin 0 -> 178176 bytes .../AutosortLockersSML/BZ/0Harmony.xml | 4006 +++++++++++++++++ .../BZ/AutosortLockersSML.dll | Bin 0 -> 75264 bytes .../BaseTeleporters/BaseTeleporters.csproj | 56 +- .../BetterPowerInfo/BetterPowerInfo.csproj | 63 +- .../BetterScannerBlips.csproj | 60 +- .../BlueprintTracker/BlueprintTracker.csproj | 58 +- SubnauticaModSystem/Common/Mod/ModUtils.cs | 11 +- .../Common/Mod/ProtoBufSerializerPatcher.cs | 4 +- .../CustomPings/CustomBeacons.csproj | 60 +- .../CustomizedStorage.csproj | 58 +- .../DockedVehicleStorageAccess.csproj | 65 +- SubnauticaModSystem/GameDir.targets | 7 + .../HabitatControlPanel.csproj | 64 +- .../HudConfig/HudConfig.csproj | 58 +- .../LongLockerNames/LongLockerNames.csproj | 58 +- .../ModInjector_MoreQuickSlots.csproj | 26 +- .../MoreQuickSlots/MoreQuickSlots.csproj | 60 +- .../PrawnsuitLightswitch.csproj | 58 +- .../QuitToDesktop/QuitToDesktop.csproj | 52 +- .../SeaglideMapMod/SeaglideMapControls.csproj | 58 +- SubnauticaModSystem/SubnauticaModSystem.sln | 80 +- .../TorpedoImprovements.csproj | 61 +- .../WhiteLights/WhiteLights.csproj | 58 +- .../zzzEnableConsole/zzzEnableConsole.csproj | 36 +- 36 files changed, 5013 insertions(+), 354 deletions(-) rename SubnauticaModSystem/AutosortLockers/{AutosortLockers.csproj => AutosortLockersSML.csproj} (65%) rename SubnauticaModSystem/AutosortLockers/{mod.json => mod_BZ.json} (90%) create mode 100644 SubnauticaModSystem/AutosortLockers/mod_SN1.json create mode 100644 SubnauticaModSystem/AutosortLockersSML/BZ/0Harmony.dll create mode 100644 SubnauticaModSystem/AutosortLockersSML/BZ/0Harmony.xml create mode 100644 SubnauticaModSystem/AutosortLockersSML/BZ/AutosortLockersSML.dll create mode 100644 SubnauticaModSystem/GameDir.targets diff --git a/SubnauticaModSystem/AutosortLockers/AutosortLocker.cs b/SubnauticaModSystem/AutosortLockers/AutosortLocker.cs index c454801..2eab9f3 100644 --- a/SubnauticaModSystem/AutosortLockers/AutosortLocker.cs +++ b/SubnauticaModSystem/AutosortLockers/AutosortLocker.cs @@ -7,6 +7,12 @@ using SMLHelper.V2.Crafting; using UnityEngine; using UnityEngine.UI; +using UWE; +#if SUBNAUTICA + using RecipeData = SMLHelper.V2.Crafting.TechData; + using Sprite = Atlas.Sprite; +#endif + namespace AutosortLockers { @@ -302,6 +308,7 @@ public AutosortLockerBuildable() public override TechCategory CategoryForPDA => TechCategory.InteriorModule; +#if SUBNAUTICA public override GameObject GetGameObject() { GameObject originalPrefab = CraftData.GetPrefabForTechType(TechType.SmallLocker); @@ -339,10 +346,58 @@ public override GameObject GetGameObject() return prefab; } +#endif + + public override IEnumerator GetGameObjectAsync(IOut gameObject) + { + CoroutineTask task = CraftData.GetPrefabForTechTypeAsync(TechType.SmallLocker); + yield return task; + + //GameObject originalPrefab = CraftData.GetPrefabForTechType(TechType.SmallLocker); + //GameObject prefab = GameObject.Instantiate(originalPrefab); + GameObject prefab = task.GetResult(); + + if (prefab == null) + QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"AutosortLockerBuildable.GetGameObjectAsync(): prefab == null"); + + var container = prefab.GetComponent(); + container.width = Mod.config.AutosorterWidth; + container.height = Mod.config.AutosorterHeight; + container.container.Resize(Mod.config.AutosorterWidth, Mod.config.AutosorterHeight); + + var meshRenderers = prefab.GetComponentsInChildren(); + foreach (var meshRenderer in meshRenderers) + { + meshRenderer.material.color = new Color(1, 0, 0); + } + + var prefabText = prefab.GetComponentInChildren(); + var label = prefab.FindChild("Label"); + DestroyImmediate(label); + + var autoSorter = prefab.AddComponent(); + + var canvas = LockerPrefabShared.CreateCanvas(prefab.transform); + autoSorter.background = LockerPrefabShared.CreateBackground(canvas.transform); + autoSorter.icon = LockerPrefabShared.CreateIcon(autoSorter.background.transform, MainColor, 40); + autoSorter.text = LockerPrefabShared.CreateText(autoSorter.background.transform, prefabText, MainColor, 0, 14, "Autosorter"); + + autoSorter.sortingText = LockerPrefabShared.CreateText(autoSorter.background.transform, prefabText, MainColor, -120, 12, "Sorting..."); + autoSorter.sortingText.alignment = TextAnchor.UpperCenter; + + autoSorter.background.gameObject.SetActive(false); + autoSorter.icon.gameObject.SetActive(false); + autoSorter.text.gameObject.SetActive(false); + autoSorter.sortingText.gameObject.SetActive(false); + + //return prefab; + gameObject.Set(prefab); + yield break; + } - protected override TechData GetBlueprintRecipe() + protected override RecipeData GetBlueprintRecipe() { - return new TechData + return new RecipeData() { craftAmount = 1, Ingredients = Mod.config.EasyBuild @@ -359,7 +414,7 @@ protected override TechData GetBlueprintRecipe() }; } - protected override Atlas.Sprite GetItemSprite() + protected override Sprite GetItemSprite() { return SMLHelper.V2.Utility.ImageUtils.LoadSpriteFromFile(Mod.GetAssetPath("AutosortLocker.png")); } diff --git a/SubnauticaModSystem/AutosortLockers/AutosortLockers.csproj b/SubnauticaModSystem/AutosortLockers/AutosortLockersSML.csproj similarity index 65% rename from SubnauticaModSystem/AutosortLockers/AutosortLockers.csproj rename to SubnauticaModSystem/AutosortLockers/AutosortLockersSML.csproj index 8c1c9af..d1d093a 100644 --- a/SubnauticaModSystem/AutosortLockers/AutosortLockers.csproj +++ b/SubnauticaModSystem/AutosortLockers/AutosortLockersSML.csproj @@ -1,6 +1,7 @@  + Debug AnyCPU @@ -9,7 +10,8 @@ Properties AutosortLockers AutosortLockersSML - v4.0 + $(SolutionDir)$(AssemblyName)\$(Configuration)\ + v4.7.2 512 @@ -35,77 +37,100 @@ Always + + BZ;BELOWZERO + true + true + $(CommonDir)SubnauticaZero.Stable + SubnauticaZero_Data + SMLHelper_BZ + AnyCPU + 7.1 + prompt + false + + + SN1;SUBNAUTICA_STABLE + true + true + $(CommonDir)Subnautica.Stable + Subnautica_Data + Modding Helper + AnyCPU + 7.1 + prompt + false + - - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\0Harmony-1.2.0.1.dll - False + + $(GameDir)\BepInEx\core\0Harmony.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp.dll False False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp-firstpass.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp-firstpass.dll False False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Newtonsoft.Json.dll + $(GameDir)\$(DataFolder)\Managed\NewtonSoft.Json.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\QModInstaller.dll + $(GameDir)\BepInEx\plugins\QModManager\QModInstaller.dll False - D:\SteamLibrary\steamapps\common\Subnautica\QMods\Modding Helper\SMLHelper.dll + $(GameDir)\QMods\$(SMLHelperFolder)\SMLHelper.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.CoreModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.CoreModule.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.InputLegacyModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.InputLegacyModule.dll False False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.Physics2DModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.Physics2DModule.dll False False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.PhysicsModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.PhysicsModule.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.TextCoreModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.TextCoreModule.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.TextRenderingModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.TextRenderingModule.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UI.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UI.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIElementsModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIElementsModule.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIModule.dll False @@ -139,27 +164,22 @@ - - - PreserveNewest - - ResXFileCodeGenerator Resources.Designer.cs - + + + + - xcopy $(TargetPath) D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)mod.json D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)Assets D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\Assets\ /q /y /i - -xcopy $(TargetPath) D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)mod.json D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)Assets D:\EpicGames\Subnautica\QMods\$(ProjectName)\Assets\ /q /y /i + xcopy $(TargetPath) $(GameDir)\QMods\$(ProjectName)\ /q /y +copy $(ProjectDir)mod_$(ConfigurationName).json $(GameDir)\QMods\$(ProjectName)\mod.json /y +xcopy $(ProjectDir)Assets $(GameDir)\QMods\$(ProjectName)\Assets\ /q /y /i + \ No newline at end of file diff --git a/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs b/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs index c311362..6a566b3 100644 --- a/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs +++ b/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs @@ -7,6 +7,10 @@ using SMLHelper.V2.Crafting; using UnityEngine; using UnityEngine.UI; +#if SUBNAUTICA + using RecipeData = SMLHelper.V2.Crafting.TechData; + using Sprite = Atlas.Sprite; +#endif namespace AutosortLockers { @@ -534,21 +538,26 @@ public AutosortTargetBuildable() public override TechCategory CategoryForPDA => TechCategory.InteriorModule; - public override GameObject GetGameObject() + public override IEnumerator GetGameObjectAsync(IOut gameObject) { - GameObject prefab = GetPrefab(TechType.SmallLocker); + //var prefab = GetPrefab(TechType.Locker); + TaskResult result = new TaskResult(); + yield return GetPrefabAsync(TechType.Locker, result); + GameObject prefab = result.Get(); StorageContainer container = prefab.GetComponent(); container.width = Mod.config.ReceptacleWidth; container.height = Mod.config.ReceptacleHeight; container.container.Resize(Mod.config.ReceptacleWidth, Mod.config.ReceptacleHeight); - return prefab; + gameObject.Set(prefab); + yield break; + //return prefab; } - protected override TechData GetBlueprintRecipe() + protected override RecipeData GetBlueprintRecipe() { - return new TechData + return new RecipeData { craftAmount = 1, Ingredients = Mod.config.EasyBuild @@ -564,7 +573,7 @@ protected override TechData GetBlueprintRecipe() }; } - protected override Atlas.Sprite GetItemSprite() + protected override Sprite GetItemSprite() { return SMLHelper.V2.Utility.ImageUtils.LoadSpriteFromFile(Mod.GetAssetPath("AutosortTarget.png")); } @@ -583,21 +592,26 @@ public AutosortStandingTargetBuildable() public override TechCategory CategoryForPDA => TechCategory.InteriorModule; - public override GameObject GetGameObject() + public override IEnumerator GetGameObjectAsync(IOut gameObject) { - var prefab = GetPrefab(TechType.Locker); + //var prefab = GetPrefab(TechType.Locker); + TaskResult result = new TaskResult(); + yield return GetPrefabAsync(TechType.Locker, result); + GameObject prefab = result.Get(); var container = prefab.GetComponent(); container.width = Mod.config.StandingReceptacleWidth; container.height = Mod.config.StandingReceptacleHeight; container.container.Resize(Mod.config.StandingReceptacleWidth, Mod.config.StandingReceptacleHeight); - return prefab; + gameObject.Set(prefab); + yield break; + //return prefab; } - protected override TechData GetBlueprintRecipe() + protected override RecipeData GetBlueprintRecipe() { - return new TechData + return new RecipeData { craftAmount = 1, Ingredients = Mod.config.EasyBuild @@ -615,7 +629,7 @@ protected override TechData GetBlueprintRecipe() }; } - protected override Atlas.Sprite GetItemSprite() + protected override Sprite GetItemSprite() { return SMLHelper.V2.Utility.ImageUtils.LoadSpriteFromFile(Mod.GetAssetPath("AutosortTargetStanding.png")); } @@ -631,9 +645,12 @@ public static void AddBuildable() sorterStandingTarget.Patch(); } - public static GameObject GetPrefab(TechType basePrefab) + public static IEnumerator GetPrefabAsync(TechType basePrefab, IOut gameObject) { - GameObject originalPrefab = CraftData.GetPrefabForTechType(basePrefab); + CoroutineTask task = CraftData.GetPrefabForTechTypeAsync(basePrefab); + yield return task; + + GameObject originalPrefab = task.GetResult();//CraftData.GetPrefabForTechType(basePrefab); GameObject prefab = GameObject.Instantiate(originalPrefab); var meshRenderers = prefab.GetComponentsInChildren(); @@ -644,7 +661,10 @@ public static GameObject GetPrefab(TechType basePrefab) var autosortTarget = prefab.AddComponent(); - var smallLockerPrefab = CraftData.GetPrefabForTechType(TechType.SmallLocker); + task = CraftData.GetPrefabForTechTypeAsync(TechType.SmallLocker); + yield return task; + //var smallLockerPrefab = CraftData.GetPrefabForTechType(TechType.SmallLocker); + var smallLockerPrefab = task.GetResult(); autosortTarget.textPrefab = GameObject.Instantiate(smallLockerPrefab.GetComponentInChildren()); var label = prefab.FindChild("Label"); DestroyImmediate(label); @@ -677,7 +697,9 @@ public static GameObject GetPrefab(TechType basePrefab) autosortTarget.customizeButton = ConfigureButton.Create(autosortTarget.background.transform, autosortTarget.textPrefab.color, 20); autosortTarget.customizeButtonImage = autosortTarget.customizeButton.GetComponent(); - return prefab; + //return prefab; + originalPrefab.SetActive(false); + gameObject.Set(prefab); } } } diff --git a/SubnauticaModSystem/AutosortLockers/AutosorterCategories.cs b/SubnauticaModSystem/AutosortLockers/AutosorterCategories.cs index 2873056..ad56125 100644 --- a/SubnauticaModSystem/AutosortLockers/AutosorterCategories.cs +++ b/SubnauticaModSystem/AutosortLockers/AutosorterCategories.cs @@ -1,4 +1,8 @@ -using Oculus.Newtonsoft.Json; +#if SUBNAUTICA +using Oculus.Newtonsoft.Json; +#elif BELOWZERO +using Newtonsoft.Json; +#endif using System; using System.Collections; using System.Collections.Generic; @@ -6,6 +10,7 @@ using System.IO; using System.Linq; using UnityEngine; +using static HandReticle; namespace AutosortLockers { diff --git a/SubnauticaModSystem/AutosortLockers/ColorPickerButton.cs b/SubnauticaModSystem/AutosortLockers/ColorPickerButton.cs index 1c97187..baf4ac1 100644 --- a/SubnauticaModSystem/AutosortLockers/ColorPickerButton.cs +++ b/SubnauticaModSystem/AutosortLockers/ColorPickerButton.cs @@ -4,6 +4,9 @@ using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; +#if SUBNAUTICA + using Sprite = Atlas.Sprite; +#endif namespace AutosortLockers { @@ -31,13 +34,13 @@ public void OnPointerClick(PointerEventData eventData) onClick(id); } - public void Initialize(int id, Color color, bool toggled, Sprite imageSprite) + /*public void Initialize(int id, Color color, bool toggled, Sprite imageSprite) { - var sprite = new Atlas.Sprite(imageSprite); + Sprite sprite = new Sprite(imageSprite); Initialize(id, color, toggled, sprite); - } + }*/ - public void Initialize(int id, Color color, bool toggled, Atlas.Sprite imageSprite) + public void Initialize(int id, Color color, bool toggled, Sprite imageSprite) { this.id = id; this.toggled = toggled; diff --git a/SubnauticaModSystem/AutosortLockers/Config.cs b/SubnauticaModSystem/AutosortLockers/Config.cs index 4cc282a..5b44924 100644 --- a/SubnauticaModSystem/AutosortLockers/Config.cs +++ b/SubnauticaModSystem/AutosortLockers/Config.cs @@ -1,4 +1,8 @@ -using Oculus.Newtonsoft.Json; +#if SUBNAUTICA +using Oculus.Newtonsoft.Json; +#elif BELOWZERO +using Newtonsoft.Json; +#endif namespace AutosortLockers { diff --git a/SubnauticaModSystem/AutosortLockers/LabelController.cs b/SubnauticaModSystem/AutosortLockers/LabelController.cs index 9f1d516..b91cb02 100644 --- a/SubnauticaModSystem/AutosortLockers/LabelController.cs +++ b/SubnauticaModSystem/AutosortLockers/LabelController.cs @@ -65,7 +65,11 @@ private void Update() if (hover) { HandReticle.main.SetIcon(HandReticle.IconType.Rename); +#if SUBNAUTICA HandReticle.main.SetInteractTextRaw("Set Locker Label", ""); +#elif BELOWZERO + HandReticle.main.SetTextRaw(HandReticle.TextType.Hand, "Set Locker Label"); +#endif } } diff --git a/SubnauticaModSystem/AutosortLockers/Mod.cs b/SubnauticaModSystem/AutosortLockers/Mod.cs index f617fa2..7ef0a03 100644 --- a/SubnauticaModSystem/AutosortLockers/Mod.cs +++ b/SubnauticaModSystem/AutosortLockers/Mod.cs @@ -4,8 +4,12 @@ using System.IO; using System.Reflection; using Common.Mod; -using Harmony; +using HarmonyLib; +#if SUBNAUTICA using Oculus.Newtonsoft.Json; +#elif BELOWZERO +using Newtonsoft.Json; +#endif using UnityEngine; namespace AutosortLockers @@ -31,7 +35,7 @@ public static void Patch(string modDirectory = null) AddBuildables(); - HarmonyInstance harmony = HarmonyInstance.Create("com.AutosortLockersSML.mod"); + Harmony harmony = new Harmony("com.AutosortLockersSML.mod"); harmony.PatchAll(Assembly.GetExecutingAssembly()); Logger.Log("Patched"); @@ -58,7 +62,7 @@ private static void LoadConfig() config = ModUtils.LoadConfig(GetModPath() + "/config.json"); ValidateConfig(); - var serializedColors = JsonConvert.DeserializeObject>(File.ReadAllText(GetAssetPath("colors.json"))); + List serializedColors = JsonConvert.DeserializeObject< List >(File.ReadAllText(GetAssetPath("colors.json"))); foreach (var sColor in serializedColors) { colors.Add(sColor.ToColor()); diff --git a/SubnauticaModSystem/AutosortLockers/Patches/Initializer_Patch.cs b/SubnauticaModSystem/AutosortLockers/Patches/Initializer_Patch.cs index 70f33e5..3f60dd3 100644 --- a/SubnauticaModSystem/AutosortLockers/Patches/Initializer_Patch.cs +++ b/SubnauticaModSystem/AutosortLockers/Patches/Initializer_Patch.cs @@ -1,5 +1,5 @@  -using Harmony; +using HarmonyLib; namespace AutosortLockers.Patches { diff --git a/SubnauticaModSystem/AutosortLockers/mod.json b/SubnauticaModSystem/AutosortLockers/mod_BZ.json similarity index 90% rename from SubnauticaModSystem/AutosortLockers/mod.json rename to SubnauticaModSystem/AutosortLockers/mod_BZ.json index 0a7eed4..d55260d 100644 --- a/SubnauticaModSystem/AutosortLockers/mod.json +++ b/SubnauticaModSystem/AutosortLockers/mod_BZ.json @@ -1,4 +1,5 @@ { + "Game": "BelowZero", "Id": "AutosortLockersSML", "DisplayName": "Autosort Lockers SML", "Author": "RandyKnapp w/PrimeSonic", diff --git a/SubnauticaModSystem/AutosortLockers/mod_SN1.json b/SubnauticaModSystem/AutosortLockers/mod_SN1.json new file mode 100644 index 0000000..f59a68e --- /dev/null +++ b/SubnauticaModSystem/AutosortLockers/mod_SN1.json @@ -0,0 +1,10 @@ +{ + "Game": "Subnautica", + "Id": "AutosortLockersSML", + "DisplayName": "Autosort Lockers SML", + "Author": "RandyKnapp w/PrimeSonic", + "Version": "2.0.0", + "Requires": [ "SMLHelper" ], + "Enable": true, + "AssemblyName": "AutosortLockersSML.dll" +} \ No newline at end of file diff --git a/SubnauticaModSystem/AutosortLockersSML/BZ/0Harmony.dll b/SubnauticaModSystem/AutosortLockersSML/BZ/0Harmony.dll new file mode 100644 index 0000000000000000000000000000000000000000..eec61353d103716141feee83922ebd3d3c683a87 GIT binary patch literal 178176 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 I|33=+Z>L;|!2kdN literal 0 HcmV?d00001 diff --git a/SubnauticaModSystem/AutosortLockersSML/BZ/0Harmony.xml b/SubnauticaModSystem/AutosortLockersSML/BZ/0Harmony.xml new file mode 100644 index 0000000..6660e87 --- /dev/null +++ b/SubnauticaModSystem/AutosortLockersSML/BZ/0Harmony.xml @@ -0,0 +1,4006 @@ + + + + 0Harmony + + + + A factory to create delegate types + + + + Instance for the delegate type factory + + + Exists for API compatibility with Harmony + + + + + Creates a delegate type for a method + + Type of the return value + Types of the arguments + The new delegate type for the given type info + + + + Creates a delegate type for a method + + Type of the return value + Types of the arguments + Calling convention. If specified, adds to the delegate type + The new delegate type for the given type info + + + Creates a delegate type for a method + The method + The new delegate type + + + Creates a delegate type for a method + The method + Calling convention. If specified, adds to the delegate type. + The new delegate type + + + A getter delegate type + Type that getter gets field/property value from + Type of the value that getter gets + The instance get getter uses + An delegate + + + + A setter delegate type + Type that setter sets field/property value for + Type of the value that setter sets + The instance the setter uses + The value the setter uses + An delegate + + + + A constructor delegate type + Type that constructor creates + An delegate + + + + A helper class for fast access to getters and setters + + + Creates an instantiation delegate + Type that constructor creates + The new instantiation delegate + + + + Creates an getter delegate for a property + Type that getter reads property from + Type of the property that gets accessed + The property + The new getter delegate + + + + Creates an getter delegate for a field + Type that getter reads field from + Type of the field that gets accessed + The field + The new getter delegate + + + + Creates an getter delegate for a field (with a list of possible field names) + Type that getter reads field/property from + Type of the field/property that gets accessed + A list of possible field names + The new getter delegate + + + + Creates an setter delegate + Type that setter assigns property value to + Type of the property that gets assigned + The property + The new setter delegate + + + + Creates an setter delegate for a field + Type that setter assigns field value to + Type of the field that gets assigned + The field + The new getter delegate + + + + A delegate to invoke a method + The instance + The method parameters + The method result + + + A helper class to invoke method with delegates + + + Creates a fast invocation handler from a method + The method to invoke + Controls if boxed value object is accessed/updated directly + The + + + The directBoxValueAccess option controls how value types passed by reference (e.g. ref int, out my_struct) are handled in the arguments array + passed to the fast invocation handler. + Since the arguments array is an object array, any value types contained within it are actually references to a boxed value object. + Like any other object, there can be other references to such boxed value objects, other than the reference within the arguments array. + For example, + + var val = 5; + var box = (object)val; + var arr = new object[] { box }; + handler(arr); // for a method with parameter signature: ref/out/in int + + + + + If directBoxValueAccess is true, the boxed value object is accessed (and potentially updated) directly when the handler is called, + such that all references to the boxed object reflect the potentially updated value. + In the above example, if the method associated with the handler updates the passed (boxed) value to 10, both box and arr[0] + now reflect the value 10. Note that the original val is not updated, since boxing always copies the value into the new boxed value object. + + + If directBoxValueAccess is false (default), the boxed value object in the arguments array is replaced with a "reboxed" value object, + such that potential updates to the value are reflected only in the arguments array. + In the above example, if the method associated with the handler updates the passed (boxed) value to 10, only arr[0] now reflects the value 10. + + + + + Patch function helpers + + + Sorts patch methods by their priority rules + The original method + Patches to sort + Use debug mode. Present for source parity with Harmony 2, don't use. + The sorted patch methods + + + + Sorts patch methods by their priority rules + The original method + Patches to sort + The sorted patch methods + + + + Creates new replacement method with the latest patches and detours the original method + The original method + Information describing the patches + The newly created replacement method + + + + + High-level IL code manipulator for MonoMod that allows to manipulate a method as a stream of CodeInstructions. + + + + + Initialize IL transpiler + + Body of the method to transpile + + + + Adds a transpiler method that edits the IL of the given method + + Transpiler method + Currently not implemented + + + + Processes and writes IL to the provided method body. + Note that this cleans the existing method body (removes insturctions and exception handlers). + + Method body to write to. + Original method that transpiler can optionally call into + + One of IL opcodes contains a CallSide (e.g. calli), which is currently not + fully supported. + + One of IL opcodes with an operand contains a null operand. + + + + Converts all branches to long types. This exists to mimic the behaviour of Harmony 2 + + Enumerable of instructions + Enumerable of fixed instructions + + + + Helper wrapper around ILProcessor to allow emitting code at certain positions + + + + + Write method body to a ILDasm -like representation + + Method body to write + String representation of the method body (locals and instruction) + Unexpected exception block type + + + + Patching methods potentially messes up the stack. + Especially calls to GetExecutingAssembly won't turn in correct methods + + + + Creates a patch sorter + Array of patches that will be sorted + Use debugging + + + Sorts internal PatchSortingWrapper collection and caches the results. + After first run the result is provided from the cache. + The original method + The sorted patch methods + + + Sorts internal PatchSortingWrapper collection and caches the results. + After first run the result is provided from the cache. + The original method + The sorted patch methods as instance + + + Checks if the sorter was created with the same patch list and as a result can be reused to + get the sorted order of the patches. + List of patches to check against + true if equal + + + Removes one unresolved dependency from the least important patch. + + + Outputs all unblocked patches from the waiting list to results list + + + Adds patch to both results list and handled patches set + Patch to add + + + Wrapper used over the Patch object to allow faster dependency access and + dependency removal in case of cyclic dependencies + + + Create patch wrapper object used for sorting + Patch to wrap + + + Determines how patches sort + The other patch + integer to define sort order (-1, 0, 1) + + + Determines whether patches are equal + The other patch + true if equal + + + Hash function + A hash code + + + Bidirectionally registers Patches as after dependencies + List of dependencies to register + + + Bidirectionally registers Patches as before dependencies + List of dependencies to register + + + Bidirectionally removes Patch from after dependencies + Patch to remove + + + Bidirectionally removes Patch from before dependencies + Patch to remove + + + Specifies the type of method + + + + This is a normal method + + + This is a getter + + + This is a setter + + + This is a constructor + + + This is a static constructor + + + Specifies the type of argument + + + + This is a normal argument + + + This is a reference argument (ref) + + + This is an out argument (out) + + + This is a pointer argument (&) + + + Specifies the type of patch + + + + Any patch + + + A prefix patch + + + A postfix patch + + + A transpiler + + + A finalizer + + + A reverse patch + + + Specifies the type of reverse patch + + + + Use the unmodified original method (directly from IL) + + + Use the original as it is right now including previous patches but excluding future ones + + + Specifies the type of method call dispatching mechanics + + + + Call the method using dynamic dispatching if method is virtual (including overriden) + + + This is the built-in form of late binding (a.k.a. dynamic binding) and is the default dispatching mechanic in C#. + This directly corresponds with the instruction. + + + For virtual (including overriden) methods, the instance type's most-derived/overriden implementation of the method is called. + For non-virtual (including static) methods, same behavior as : the exact specified method implementation is called. + + + Note: This is not a fully dynamic dispatch, since non-virtual (including static) methods are still called non-virtually. + A fully dynamic dispatch in C# involves using + the dynamic type + (actually a fully dynamic binding, since even the name and overload resolution happens at runtime), which does not support. + + + + + Call the method using static dispatching, regardless of whether method is virtual (including overriden) or non-virtual (including static) + + + a.k.a. non-virtual dispatching, early binding, or static binding. + This directly corresponds with the instruction. + + + For both virtual (including overriden) and non-virtual (including static) methods, the exact specified method implementation is called, without virtual/override mechanics. + + + + + The base class for all Harmony annotations (not meant to be used directly) + + + + The common information for all attributes + + + Annotation to define your Harmony patch methods + + + + An empty annotation can be used together with TargetMethod(s) + + + + An annotation that specifies a class to patch + The declaring class/type + + + + An annotation that specifies a method, property or constructor to patch + The declaring class/type + The argument types of the method or constructor to patch + + + + An annotation that specifies a method, property or constructor to patch + The declaring class/type + The name of the method, property or constructor to patch + + + + An annotation that specifies a method, property or constructor to patch + The declaring class/type + The name of the method, property or constructor to patch + An array of argument types to target overloads + + + + An annotation that specifies a method, property or constructor to patch + The declaring class/type + The name of the method, property or constructor to patch + An array of argument types to target overloads + Array of + + + + An annotation that specifies a method, property or constructor to patch + Assembly-qualified name of the declaring class/type + The name of the method, property or constructor to patch + The + An array of argument types to target overloads + Array of + + + + An annotation that specifies a method, property or constructor to patch + The declaring class/type + The + + + + An annotation that specifies a method, property or constructor to patch + The declaring class/type + The + An array of argument types to target overloads + + + + An annotation that specifies a method, property or constructor to patch + The declaring class/type + The + An array of argument types to target overloads + Array of + + + + An annotation that specifies a method, property or constructor to patch + The declaring class/type + The name of the method, property or constructor to patch + The + + + + An annotation that specifies a method, property or constructor to patch + The name of the method, property or constructor to patch + + + + An annotation that specifies a method, property or constructor to patch + The name of the method, property or constructor to patch + An array of argument types to target overloads + + + + An annotation that specifies a method, property or constructor to patch + The name of the method, property or constructor to patch + An array of argument types to target overloads + An array of + + + + An annotation that specifies a method, property or constructor to patch + The name of the method, property or constructor to patch + The + + + + An annotation that specifies a method, property or constructor to patch + The + + + + An annotation that specifies a method, property or constructor to patch + The + An array of argument types to target overloads + + + + An annotation that specifies a method, property or constructor to patch + The + An array of argument types to target overloads + An array of + + + + An annotation that specifies a method, property or constructor to patch + An array of argument types to target overloads + + + + An annotation that specifies a method, property or constructor to patch + An array of argument types to target overloads + An array of + + + + Annotation to define the original method for delegate injection + + + + An annotation that specifies a class to patch + The declaring class/type + + + + An annotation that specifies a method, property or constructor to patch + The declaring class/type + The argument types of the method or constructor to patch + + + + An annotation that specifies a method, property or constructor to patch + The declaring class/type + The name of the method, property or constructor to patch + + + + An annotation that specifies a method, property or constructor to patch + The declaring class/type + The name of the method, property or constructor to patch + An array of argument types to target overloads + + + + An annotation that specifies a method, property or constructor to patch + The declaring class/type + The name of the method, property or constructor to patch + An array of argument types to target overloads + Array of + + + + An annotation that specifies a method, property or constructor to patch + The declaring class/type + The + + + + An annotation that specifies a method, property or constructor to patch + The declaring class/type + The + An array of argument types to target overloads + + + + An annotation that specifies a method, property or constructor to patch + The declaring class/type + The + An array of argument types to target overloads + Array of + + + + An annotation that specifies a method, property or constructor to patch + The declaring class/type + The name of the method, property or constructor to patch + The + + + + An annotation that specifies a method, property or constructor to patch + The name of the method, property or constructor to patch + + + + An annotation that specifies a method, property or constructor to patch + The name of the method, property or constructor to patch + An array of argument types to target overloads + + + + An annotation that specifies a method, property or constructor to patch + The name of the method, property or constructor to patch + An array of argument types to target overloads + An array of + + + + An annotation that specifies a method, property or constructor to patch + The name of the method, property or constructor to patch + The + + + + An annotation that specifies call dispatching mechanics for the delegate + The + + + + An annotation that specifies a method, property or constructor to patch + The + An array of argument types to target overloads + + + + An annotation that specifies a method, property or constructor to patch + The + An array of argument types to target overloads + An array of + + + + An annotation that specifies a method, property or constructor to patch + An array of argument types to target overloads + + + + An annotation that specifies a method, property or constructor to patch + An array of argument types to target overloads + An array of + + + + Annotation to define your standin methods for reverse patching + + + + An annotation that specifies the type of reverse patching + The of the reverse patch + + + + A Harmony annotation to define that all methods in a class are to be patched + + + + A Harmony annotation + + + + A Harmony annotation to define patch priority + The priority + + + + A Harmony annotation + + + + A Harmony annotation to define that a patch comes before another patch + The array of harmony IDs of the other patches + + + + A Harmony annotation + + + A Harmony annotation to define that a patch comes after another patch + The array of harmony IDs of the other patches + + + + A Harmony annotation + + + A Harmony annotation to debug a patch (output uses to log to your Desktop) + + + + A Harmony attribute + + + If specified on a prefix, postfix or a finalizer, the method will be automatically wrapped into try/catch. + + + + Specifies the Prepare function in a patch class + + + + Specifies the Cleanup function in a patch class + + + + Specifies the TargetMethod function in a patch class + + + + Specifies the TargetMethods function in a patch class + + + + Specifies the Prefix function in a patch class + + + + Specifies the Postfix function in a patch class + + + + Specifies the Transpiler function in a patch class + + + + Specifies the Finalizer function in a patch class + + + + A Harmony annotation + + + + The name of the original argument + + + + The index of the original argument + + + + The new name of the original argument + + + + An annotation to declare injected arguments by name + + + + An annotation to declare injected arguments by index + Zero-based index + + + + An annotation to declare injected arguments by renaming them + Name of the original argument + New name + + + + An annotation to declare injected arguments by index and renaming them + Zero-based index + New name + + + + An abstract wrapper around OpCode and their operands. Used by transpilers + + + + The opcode + + + + The operand + + + + All labels defined on this instruction + + + + All exception block boundaries defined on this instruction + + + + Creates a new CodeInstruction with a given opcode and optional operand + The opcode + The operand + + + + Create a full copy (including labels and exception blocks) of a CodeInstruction + The to copy + + + + Clones a CodeInstruction and resets its labels and exception blocks + A lightweight copy of this code instruction + + + + Clones a CodeInstruction, resets labels and exception blocks and sets its opcode + The opcode + A copy of this CodeInstruction with a new opcode + + + + Clones a CodeInstruction, resets labels and exception blocks and sets its operand + The operand + A copy of this CodeInstruction with a new operand + + + + Creates a CodeInstruction calling a method (CALL) + The class/type where the method is declared + The name of the method (case sensitive) + Optional parameters to target a specific overload of the method + Optional list of types that define the generic version of the method + A code instruction that calls the method matching the arguments + + + + Creates a CodeInstruction calling a method (CALL) + The target method in the form TypeFullName:MethodName, where the type name matches a form recognized by Type.GetType like Some.Namespace.Type. + Optional parameters to target a specific overload of the method + Optional list of types that define the generic version of the method + A code instruction that calls the method matching the arguments + + + + Creates a CodeInstruction calling a method (CALL) + The lambda expression using the method + + + + + Creates a CodeInstruction calling a method (CALL) + The lambda expression using the method + + + + + Creates a CodeInstruction calling a method (CALL) + The lambda expression using the method + + + + + Creates a CodeInstruction calling a method (CALL) + The lambda expression using the method + + + + + Creates a CodeInstruction loading a field (LD[S]FLD[A]) + The class/type where the field is defined + The name of the field (case sensitive) + Use address of field + + + + Creates a CodeInstruction storing to a field (ST[S]FLD) + The class/type where the field is defined + The name of the field (case sensitive) + + + + Returns a string representation of the code instruction + A string representation of the code instruction + + + + Exception block types + + + + The beginning of an exception block + + + + The beginning of a catch block + + + + The beginning of an except filter block + + + + The beginning of a fault block + + + + The beginning of a finally block + + + + The end of an exception block + + + + An exception block + + + + Block type + + + + Catch type + + + + Creates an exception block + The + The catch type + + + + + An exception thrown when a patch argument in a Harmony patch is invalid. + + + + + Original method to be patched. + + + + + Patch that was attempted to be applied. + + + + + + + + Constructs a new exception instance. + + Message of the exception. + Original method to be patched. + Patch that was attempted to be applied. + + + + An exception thrown when a reflection member is not found. + + + + + + + The Harmony instance is the main entry to Harmony. After creating one with an unique identifier, it is used to patch and query the current application domain + + + + Set to true before instantiating Harmony to debug Harmony or use an environment variable to set HARMONY_DEBUG to '1' like this: cmd /C "set HARMONY_DEBUG=1 && game.exe" + This is for full debugging. To debug only specific patches, use the attribute + + + + Creates a new Harmony instance + A unique identifier (you choose your own) + A Harmony instance + + + + The unique identifier + + + + Searches the current assembly for Harmony annotations and uses them to create patches + + + + Creates a empty patch processor for an original method + The original method/constructor + A new instance + + + + Creates a patch class processor from an annotated class + The class/type + A new instance + + + + Creates a patch class processor from an annotated class + The class/type + If true, the type doesn't need to have any attributes present for processing + A new instance + + + + Creates a reverse patcher for one of your stub methods + The original method/constructor + The stand-in stub method as + A new instance + + + + Searches an assembly for Harmony annotations and uses them to create patches + The assembly + + + + Searches the given type for Harmony annotation and uses them to create patches + The type to search + + + + Creates patches by manually specifying the methods + The original method/constructor + An optional prefix method wrapped in a object + An optional postfix method wrapped in a object + An optional transpiler method wrapped in a object + An optional finalizer method wrapped in a object + The replacement method that was created to patch the original method + + + + Patches a foreign method onto a stub method of yours and optionally applies transpilers during the process + The original method/constructor you want to duplicate + Your stub method as that will become the original. Needs to have the correct signature (either original or whatever your transpilers generates) + An optional transpiler as method that will be applied during the process + The replacement method that was created to patch the stub method + + + + Unpatches methods by patching them with zero patches. Fully unpatching is not supported. Be careful, unpatching is global + The optional Harmony ID to restrict unpatching to a specific Harmony instance + This method could be static if it wasn't for the fact that unpatching creates a new replacement method that contains your harmony ID + + + + Unpatches all methods that were patched by this Harmony instance's ID. Unpatching is done by repatching methods without patches of this instance. + + + + Unpatches a method by patching it with zero patches. Fully unpatching is not supported. Be careful, unpatching is global + The original method/constructor + The + The optional Harmony ID to restrict unpatching to a specific Harmony instance + + + + Unpatches a method by patching it with zero patches. Fully unpatching is not supported. Be careful, unpatching is global + The original method/constructor + The patch method as method to remove + + + + Test for patches from a specific Harmony ID + The Harmony ID + True if patches for this ID exist + + + + Gets patch information for a given original method + The original method/constructor + The patch information as + + + + Gets the methods this instance has patched + An enumeration of original methods/constructors + + + + Gets all patched original methods in the appdomain + An enumeration of patched original methods/constructors + + + + Gets Harmony version for all active Harmony instances + [out] The current Harmony version + A dictionary containing assembly versions keyed by Harmony IDs + + + + Creates a new Harmony instance and applies all patches specified in the type + The type to scan for patches. + The ID for the Harmony instance to create, which will be used. + + + + Applies all patches specified in the assembly + The assembly to scan. + The ID for the Harmony instance to create, which will be used. + + + + Under Mono, HarmonyException wraps IL compile errors with detailed information about the failure + + + + Default serialization constructor (not implemented) + The info + The context + + + + Get a list of IL instructions in pairs of offset+code + A list of key/value pairs which represent an offset and the code at that offset + + + + Get a list of IL instructions without offsets + A list of + + + + Get the error offset of the errornous IL instruction + The offset + + + + Get the index of the errornous IL instruction + The index into the list of instructions or -1 if not found + + + + A wrapper around a method to use it as a patch (for example a Prefix) + + + + The original method + + + + Class/type declaring this patch + + + + Patch method name + + + + Optional patch + + + + Array of argument types of the patch method + + + + of the patch + + + + Install this patch before patches with these Harmony IDs + + + + Install this patch after patches with these Harmony IDs + + + + Reverse patch type, see + + + + Create debug output for this patch + + + + Whether to use (true) or (false) mechanics + for -attributed delegate + + + + Whether to wrap the patch itself into a try/catch. + + + + Default constructor + + + + Creates a patch from a given method + The original method + + + + Creates a patch from a given method + The original method + The patch + A list of harmony IDs that should come after this patch + A list of harmony IDs that should come before this patch + Set to true to generate debug output + + + + Creates a patch from a given method + The patch class/type + The patch method name + The optional argument types of the patch method (for overloaded methods) + + + + Gets the names of all internal patch info fields + A list of field names + + + + Merges annotations + The list of to merge + The merged + + + + Returns a string that represents the annotation + A string representation + + + + Annotation extensions + + + + Copies annotation information + The source + The destination + + + + Clones an annotation + The to clone + A copied + + + + Merges annotations + The master + The detail + A new, merged + + + + Gets all annotations on a class/type + The class/type + A list of all + + + + Gets merged annotations on a class/type + The class/type + The merged + + + + Gets all annotations on a method + The method/constructor + A list of + + + + Gets merged annotations on a method + The method/constructor + The merged + + + + + A mutable representation of an inline signature, similar to Mono.Cecil's CallSite. + Used by the calli instruction, can be used by transpilers + + + + + See + + + + See + + + + See + + + + The list of all parameter types or function pointer signatures received by the call site + + + + The return type or function pointer signature returned by the call site + + + + Returns a string representation of the inline signature + A string representation of the inline signature + + + + + A mutable representation of a parameter type with an attached type modifier, + similar to Mono.Cecil's OptionalModifierType / RequiredModifierType and C#'s modopt / modreq + + + + + Whether this is a modopt (optional modifier type) or a modreq (required modifier type) + + + + The modifier type attached to the parameter type + + + + The modified parameter type + + + + Returns a string representation of the modifier type + A string representation of the modifier type + + + + Patch serialization + + + + Control the binding of a serialized object to a type + Specifies the assembly name of the serialized object + Specifies the type name of the serialized object + The type of the object the formatter creates a new instance of + + + + Serializes a patch info + The + The serialized data + + + + Deserialize a patch info + The serialized data + A + + + + Compare function to sort patch priorities + The patch + Zero-based index + The priority + A standard sort integer (-1, 0, 1) + + + + Serializable patch information + + + + Prefixes as an array of + + + + Postfixes as an array of + + + + Transpilers as an array of + + + + Finalizers as an array of + + + + Returns if any of the patches wants debugging turned on + + + + Adds prefixes + An owner (Harmony ID) + The patch methods + + + + Adds a prefix + + + Removes prefixes + The owner of the prefixes, or * for all + + + + Adds postfixes + An owner (Harmony ID) + The patch methods + + + + Adds a postfix + + + Removes postfixes + The owner of the postfixes, or * for all + + + + Adds transpilers + An owner (Harmony ID) + The patch methods + + + + Adds a transpiler + + + Removes transpilers + The owner of the transpilers, or * for all + + + + Adds finalizers + An owner (Harmony ID) + The patch methods + + + + Adds a finalizer + + + Removes finalizers + The owner of the finalizers, or * for all + + + + Removes a patch using its method + The method of the patch to remove + + + + Gets a concatenated list of patches + The Harmony instance ID adding the new patches + The patches to add + The current patches + + + + Gets a list of patches with any from the given owner removed + The owner of the methods, or * for all + The current patches + + + + A serializable patch + + + + Zero-based index + + + + The owner (Harmony ID) + + + + The priority, see + + + + Keep this patch before the patches indicated in the list of Harmony IDs + + + + Keep this patch after the patches indicated in the list of Harmony IDs + + + + A flag that will log the replacement method via every time this patch is used to build the replacement, even in the future + + + + Whether to wrap the patch into a general try/catch that logs the error + + + + The method of the static patch method + + + + Creates a patch + The method of the patch + Zero-based index + An owner (Harmony ID) + The priority, see + A list of Harmony IDs for patches that should run after this patch + A list of Harmony IDs for patches that should run before this patch + A flag that will log the replacement method via every time this patch is used to build the replacement, even in the future + + + + Creates a patch + The method of the patch + Zero-based index + An owner (Harmony ID) + The priority, see + A list of Harmony IDs for patches that should run after this patch + A list of Harmony IDs for patches that should run before this patch + A flag that will log the replacement method via every time this patch is used to build the replacement, even in the future + Whether to wrap the patch into a general try/catch that logs the error + + + + Creates a patch + The method of the patch + Zero-based index + An owner (Harmony ID) + + + Get the patch method or a DynamicMethod if original patch method is a patch factory + The original method/constructor + The method of the patch + + + + Determines whether patches are equal + The other patch + true if equal + + + + Determines how patches sort + The other patch + integer to define sort order (-1, 0, 1) + + + + Hash function + A hash code + + + + A PatchClassProcessor used to turn on a class/type into patches + + + + Creates a patch class processor by pointing out a class. Similar to PatchAll() but without searching through all classes. + The Harmony instance + The class to process (need to have at least a [HarmonyPatch] attribute if allowUnannotatedType is set to false) + + + + Creates a patch class processor by pointing out a class. Similar to PatchAll() but without searching through all classes. + The Harmony instance + The class to process (need to have at least a [HarmonyPatch] attribute if allowUnannotatedType is set to false) + If true, the type doesn't need to have any attributes present for processing + + + + Applies the patches + A list of all created replacement methods or null if patch class is not annotated + + + + A group of patches + + + + A collection of prefix + + + + A collection of postfix + + + + A collection of transpiler + + + + A collection of finalizer + + + + Gets all owners (Harmony IDs) or all known patches + The patch owners + + + + Creates a group of patches + An array of prefixes as + An array of postfixes as + An array of transpileres as + An array of finalizeres as + + + + + IL manipulator to create Harmony-style patches + + + + + + Manipulates a by applying Harmony patches to it. + + Reference to the method that should be considered as original. Used to reference parameter and return types. + Collection of Harmony patches to apply. + Method body to manipulate as instance. Should contain instructions to patch. + + In most cases you will want to use to create or obtain global + patch info for the method that contains aggregated info of all Harmony instances. + + + + + + Method patcher for normal managed methods that have IL body attached to them. + Uses in order to apply hooks in a way compatible with MonoMod's own + hooking system. + + + + + + + + + + + + + + + + + + A handler for that checks if a method is a normal Managed method. + + Not used + Patch resolver arguments + + + + + A general method patcher for implementing custom Harmony patcher backends. + + + + + + Constructs a method patcher + + Original method to patch + + + + + Original method to patch. + + + + + + Prepares method body for the unpatched that simply calls + function. + + + A that contains a call to + the original method to pass to the IL manipulator. + If null, Harmony patches must be manually applied to the original via . + + + + + + Detours to the provided replacement function. If called multiple times, + is re-detoured to the new method. + + + Result of + if returned non-null. + Otherwise, this will be null, in which case you must manually generate Harmony-patched method + with . + + of the hook, if it's different from `replacement`. + + + + + Creates a copy of the original method. If not possible, creates a method that calls into the original method. + + Copy of the original method that is transpileable. If not possible, returns null. + + This method creates a pure copy of the original method that is usable with transpilers. Currently, this + method is used to generate reverse patchers. + If a purse IL copy is not possible, a best approximation should be generated + (e.g. a wrapper that calls original method). + If no best approximation is possible, this method should return null, in which case generating reverse + patchers for the method will fail. + + + + + + A method patcher that uses to patch internal calls, + methods marked with and any other managed method that CLR managed-to-native + trampolines for and which has no IL body defined. + + + + + Constructs a new instance of method patcher. + + + + + + + + + + + + + + + A handler for that checks if a method doesn't have a body + (e.g. it's icall or marked with ) and thus can be patched with + . + + Not used + Patch resolver arguments + + + + + A global manager for handling Harmony patch state. Contains information about all patched methods and all + actual instances that handle patching implementation. + + + + + + Method patcher resolve event. + + + When a method is to be patched, this resolver event is called once on the method to determine which + backend to use in order to patch the method. + To make Harmony use the specified backend, set to an + instance of the method patcher backend to use. + + + + + + Creates or gets an existing instance of that handles patching the method. + + Method to patch. + Instance of that handles patching the method. + No suitable patcher found for the method. + + + + + Gets patch info for the given target method. + + Method to get patch info for. + Current patch info of the method. + + + + + Gets or creates patch info for the given method. + + Method to get info from. + An existing or new patch info for the method containing information about the applied patches. + + + + + Gets all methods that have been patched. + + List of methods that have been patched. + + + + + Removes all method resolvers. Use with care, this removes the default ones too! + + + + + Patcher resolve event arguments. + + + + + + Original method that is to be patched. + + + + + + Method patcher to use to patch . + Set this value to specify which one to use. + + + + + A PatchProcessor handles patches on a method/constructor + + + + Creates an empty patch processor + The Harmony instance + The original method/constructor + + + + Adds a prefix + The prefix as a + A for chaining calls + + + + Adds a prefix + The prefix method + A for chaining calls + + + + Adds a postfix + The postfix as a + A for chaining calls + + + + Adds a postfix + The postfix method + A for chaining calls + + + + Adds a transpiler + The transpiler as a + A for chaining calls + + + + Adds a transpiler + The transpiler method + A for chaining calls + + + + Adds a finalizer + The finalizer as a + A for chaining calls + + + + Adds a finalizer + The finalizer method + A for chaining calls + + + + Gets all patched original methods in the appdomain + An enumeration of patched method/constructor + + + + Applies all registered patches + The generated replacement method + + + + Unpatches patches of a given type and/or Harmony ID + The patch type + Harmony ID or * for any + A for chaining calls + + + + Unpatches a specific patch + The method of the patch + A for chaining calls + + + + Gets patch information on an original + The original method/constructor + The patch information as + + + + Sort patch methods by their priority rules + The original method + Patches to sort + The sorted patch methods + + + + Gets Harmony version for all active Harmony instances + [out] The current Harmony version + A dictionary containing assembly version keyed by Harmony ID + + + + Creates a new empty generator to use when reading method bodies + A new + + + + Creates a new generator matching the method/constructor to use when reading method bodies + The original method/constructor to copy method information from + A new + + + + Returns the methods unmodified list of code instructions + The original method/constructor + Optionally an existing generator that will be used to create all local variables and labels contained in the result (if not specified, an internal generator is used) + A list containing all the original + + + + Returns the methods unmodified list of code instructions + The original method/constructor + A new generator that now contains all local variables and labels contained in the result + A list containing all the original + + + + Returns the methods current list of code instructions after all existing transpilers have been applied + The original method/constructor + Apply only the first count of transpilers + Optionally an existing generator that will be used to create all local variables and labels contained in the result (if not specified, an internal generator is used) + A list of + + + + Returns the methods current list of code instructions after all existing transpilers have been applied + The original method/constructor + A new generator that now contains all local variables and labels contained in the result + Apply only the first count of transpilers + A list of + + + + A low level way to read the body of a method. Used for quick searching in methods + The original method + All instructions as opcode/operand pairs + + + + A low level way to read the body of a method. Used for quick searching in methods + The original method + An existing generator that will be used to create all local variables and labels contained in the result + All instructions as opcode/operand pairs + + + + A patch priority + + + + Patch last + + + + Patch with very low priority + + + + Patch with low priority + + + + Patch with lower than normal priority + + + + Patch with normal priority + + + + Patch with higher than normal priority + + + + Patch with high priority + + + + Patch with very high priority + + + + Patch first + + + + A reverse patcher + + + + Creates a reverse patcher + The Harmony instance + The original method/constructor + Your stand-in stub method as + + + + Applies the patch + The type of patch, see + The generated replacement method + + + + A collection of commonly used transpilers + + + + Returns an instruction to call the specified delegate + The delegate type to emit + The delegate to emit + The instruction to call the specified action + + + + A transpiler that replaces all occurrences of a given method with another one using the same signature + The enumeration of to act on + Method or constructor to search for + Method or constructor to replace with + Modified enumeration of + + + + A transpiler that alters instructions that match a predicate by calling an action + The enumeration of to act on + A predicate selecting the instructions to change + An action to apply to matching instructions + Modified enumeration of + + + + A transpiler that logs a text at the beginning of the method + The instructions to act on + The log text + Modified enumeration of + + + + A transpiler that replaces the entire body of the method with another one + The replacement method. It's up to the caller of this transpiler to make sure that the signatures match. + of the patch. This is passed via transpiler. + A collection of that contains instructions of replacement method. + The replacement method is not a managed method that contains any IL. + This transpiler has a side effect of clearing up all previous locals and previous transpilers. + Use to run this transpiler as early as possible. + + + A helper class for reflection related functions + + + + Shortcut for to simplify the use of reflections and make it work for any access level + + + + Shortcut for to simplify the use of reflections and make it work for any access level but only within the current type + + + + Gets a type by name. Prefers a full name with namespace but falls back to the first type matching the name otherwise + The name + A type or null if not found + + + + Gets all successfully loaded types from a given assembly + The assembly + An array of types + + This calls and returns , while catching any thrown . + If such an exception is thrown, returns the successfully loaded types (, + filtered for non-null values). + + + + + Applies a function going up the type hierarchy and stops at the first non-null result + Result type of func() + The class/type to start with + The evaluation function returning T + The first non-null result, or null if no match + + The type hierarchy of a class or value type (including struct) does NOT include implemented interfaces, + and the type hierarchy of an interface is only itself (regardless of whether that interface implements other interfaces). + The top-most type in the type hierarchy of all non-interface types (including value types) is . + + + + + Applies a function going into inner types and stops at the first non-null result + Generic type parameter + The class/type to start with + The evaluation function returning T + The first non-null result, or null if no match + + + + Gets the reflection information for a directly declared field + The class/type where the field is defined + The name of the field + A field or null when type/name is null or when the field cannot be found + + + + Gets the reflection information for a field by searching the type and all its super types + The class/type where the field is defined + The name of the field (case sensitive) + A field or null when type/name is null or when the field cannot be found + + + + Gets the reflection information for a field + The class/type where the field is declared + The zero-based index of the field inside the class definition + A field or null when type is null or when the field cannot be found + + + + Gets the reflection information for a directly declared property + The class/type where the property is declared + The name of the property (case sensitive) + A property or null when type/name is null or when the property cannot be found + + + + Gets the reflection information for the getter method of a directly declared property + The class/type where the property is declared + The name of the property (case sensitive) + A method or null when type/name is null or when the property cannot be found + + + + Gets the reflection information for the setter method of a directly declared property + The class/type where the property is declared + The name of the property (case sensitive) + A method or null when type/name is null or when the property cannot be found + + + + Gets the reflection information for a property by searching the type and all its super types + The class/type + The name + A property or null when type/name is null or when the property cannot be found + + + + Gets the reflection information for the getter method of a property by searching the type and all its super types + The class/type + The name + A method or null when type/name is null or when the property cannot be found + + + + Gets the reflection information for the setter method of a property by searching the type and all its super types + The class/type + The name + A method or null when type/name is null or when the property cannot be found + + + + Gets the reflection information for a directly declared method + The class/type where the method is declared + The name of the method (case sensitive) + Optional parameters to target a specific overload of the method + Optional list of types that define the generic version of the method + A method or null when type/name is null or when the method cannot be found + + + + Gets the reflection information for a method by searching the type and all its super types + The class/type where the method is declared + The name of the method (case sensitive) + Optional parameters to target a specific overload of the method + Optional list of types that define the generic version of the method + A method or null when type/name is null or when the method cannot be found + + + + Gets the reflection information for a method by searching the type and all its super types + The target method in the form TypeFullName:MethodName, where the type name matches a form recognized by Type.GetType like Some.Namespace.Type. + Optional parameters to target a specific overload of the method + Optional list of types that define the generic version of the method + A method or null when type/name is null or when the method cannot be found + + + + Gets the names of all method that are declared in a type + The declaring class/type + A list of method names + + + + Gets the names of all method that are declared in the type of the instance + An instance of the type to search in + A list of method names + + + + Gets the names of all fields that are declared in a type + The declaring class/type + A list of field names + + + + Gets the names of all fields that are declared in the type of the instance + An instance of the type to search in + A list of field names + + + + Gets the names of all properties that are declared in a type + The declaring class/type + A list of property names + + + + Gets the names of all properties that are declared in the type of the instance + An instance of the type to search in + A list of property names + + + + Gets the type of any class member of + A member + The class/type of this member + + + + Test if a class member is actually an concrete implementation + A member + True if the member is a declared + + + + Gets the real implementation of a class member + A member + The member itself if its declared. Otherwise the member that is actually implemented in some base type + + + + Gets the reflection information for a directly declared constructor + The class/type where the constructor is declared + Optional parameters to target a specific overload of the constructor + Optional parameters to only consider static constructors + A constructor info or null when type is null or when the constructor cannot be found + + + + Gets the reflection information for a constructor by searching the type and all its super types + The class/type where the constructor is declared + Optional parameters to target a specific overload of the method + Optional parameters to only consider static constructors + A constructor info or null when type is null or when the method cannot be found + + + + Gets reflection information for all declared constructors + The class/type where the constructors are declared + Optional parameters to only consider static constructors + A list of constructor infos + + + + Gets reflection information for all declared methods + The class/type where the methods are declared + A list of methods + + + + Gets reflection information for all declared properties + The class/type where the properties are declared + A list of properties + + + + Gets reflection information for all declared fields + The class/type where the fields are declared + A list of fields + + + + Gets the return type of a method or constructor + The method/constructor + The return type + + + + Given a type, returns the first inner type matching a recursive search by name + The class/type to start searching at + The name of the inner type (case sensitive) + The inner type or null if type/name is null or if a type with that name cannot be found + + + + Given a type, returns the first inner type matching a recursive search with a predicate + The class/type to start searching at + The predicate to search with + The inner type or null if type/predicate is null or if a type with that name cannot be found + + + + Given a type, returns the first method matching a predicate + The class/type to start searching at + The predicate to search with + The method or null if type/predicate is null or if a type with that name cannot be found + + + + Given a type, returns the first constructor matching a predicate + The class/type to start searching at + The predicate to search with + The constructor info or null if type/predicate is null or if a type with that name cannot be found + + + + Given a type, returns the first property matching a predicate + The class/type to start searching at + The predicate to search with + The property or null if type/predicate is null or if a type with that name cannot be found + + + + Returns an array containing the type of each object in the given array + An array of objects + An array of types or an empty array if parameters is null (if an object is null, the type for it will be object) + + + + Creates an array of input parameters for a given method and a given set of potential inputs + The method/constructor you are planing to call + The possible input parameters in any order + An object array matching the method signature + + + + A readable/assignable reference delegate to an instance field of a class or static field (NOT an instance field of a struct) + + An arbitrary type if the field is static; otherwise the class that defines the field, or a parent class (including ), + implemented interface, or derived class of this type + + + The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), + a type that is assignable from that type; or if the field's type is an enum type, + either that type or the underlying integral type of that enum type + + The runtime instance to access the field (ignored and can be omitted for static fields) + A readable/assignable reference to the field + Null instance passed to a non-static field ref delegate + + Instance of invalid type passed to a non-static field ref delegate + (this can happen if is a parent class or interface of the field's declaring type) + + + + This delegate cannot be used for instance fields of structs, since a struct instance passed to the delegate would be passed by + value and thus would be a copy that only exists within the delegate's invocation. This is fine for a readonly reference, + but makes assignment futile. Use instead. + + + Note that is not required to be the field's declaring type. It can be a parent class (including ), + implemented interface, or a derived class of the field's declaring type ("instanceOfT is FieldDeclaringType" must be possible). + Specifically, must be assignable from OR to the field's declaring type. + Technically, this allows Nullable, although Nullable is only relevant for structs, and since only static fields of structs + are allowed for this delegate, and the instance passed to such a delegate is ignored, this hardly matters. + + + Similarly, is not required to be the field's field type, unless that type is a non-enum value type. + It can be a parent class (including object) or implemented interface of the field's field type. It cannot be a derived class. + This variance is not allowed for value types, since that would require boxing/unboxing, which is not allowed for ref values. + Special case for enum types: can also be the underlying integral type of the enum type. + Specifically, for reference types, must be assignable from + the field's field type; for non-enum value types, must be exactly the field's field type; for enum types, + must be either the field's field type or the underyling integral type of that field type. + + + This delegate supports static fields, even those defined in structs, for legacy reasons. + For such static fields, is effectively ignored. + Consider using (and StaticFieldRefAccess methods that return it) instead for static fields. + + + + + + Creates a field reference delegate for an instance field of a class + The class that defines the instance field, or derived class of this type + + The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), + a type that is assignable from that type; or if the field's type is an enum type, + either that type or the underlying integral type of that enum type + + The name of the field + A readable/assignable delegate + + + For backwards compatibility, there is no class constraint on . + Instead, the non-value-type check is done at runtime within the method. + + + + + + Creates an instance field reference for a specific instance of a class + The class that defines the instance field, or derived class of this type + + The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), + a type that is assignable from that type; or if the field's type is an enum type, + either that type or the underlying integral type of that enum type + + The instance + The name of the field + A readable/assignable reference to the field + + + This method is meant for one-off access to a field's value for a single instance. + If you need to access a field's value for potentially multiple instances, use instead. + FieldRefAccess<T, F>(instance, fieldName) is functionally equivalent to FieldRefAccess<T, F>(fieldName)(instance). + + + For backwards compatibility, there is no class constraint on . + Instead, the non-value-type check is done at runtime within the method. + + + + + + Creates a field reference delegate for an instance field of a class or static field (NOT an instance field of a struct) + + The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), + a type that is assignable from that type; or if the field's type is an enum type, + either that type or the underlying integral type of that enum type + + + The type that defines the field, or derived class of this type; must not be a struct type unless the field is static + + The name of the field + + A readable/assignable delegate with T=object + (for static fields, the instance delegate parameter is ignored) + + + + This method is meant for cases where the given type is only known at runtime and thus can't be used as a type parameter T + in e.g. . + + + This method supports static fields, even those defined in structs, for legacy reasons. + Consider using (and other overloads) instead for static fields. + + + + + + Creates a field reference delegate for an instance field of a class or static field (NOT an instance field of a struct) + + An arbitrary type if the field is static; otherwise the class that defines the field, or a parent class (including ), + implemented interface, or derived class of this type ("instanceOfT is FieldDeclaringType" must be possible) + + + The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), + a type that is assignable from that type; or if the field's type is an enum type, + either that type or the underlying integral type of that enum type + + The field + A readable/assignable delegate + + + This method is meant for cases where the field has already been obtained, avoiding the field searching cost in + e.g. . + + + This method supports static fields, even those defined in structs, for legacy reasons. + For such static fields, is effectively ignored. + Consider using (and other overloads) instead for static fields. + + + For backwards compatibility, there is no class constraint on . + Instead, the non-value-type check is done at runtime within the method. + + + + + + Creates a field reference for an instance field of a class + + The type that defines the field; or a parent class (including ), implemented interface, or derived class of this type + ("instanceOfT is FieldDeclaringType" must be possible) + + + The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), + a type that is assignable from that type; or if the field's type is an enum type, + either that type or the underlying integral type of that enum type + + The instance + The field + A readable/assignable reference to the field + + + This method is meant for one-off access to a field's value for a single instance and where the field has already been obtained. + If you need to access a field's value for potentially multiple instances, use instead. + FieldRefAccess<T, F>(instance, fieldInfo) is functionally equivalent to FieldRefAccess<T, F>(fieldInfo)(instance). + + + For backwards compatibility, there is no class constraint on . + Instead, the non-value-type check is done at runtime within the method. + + + + + + A readable/assignable reference delegate to an instance field of a struct + The struct that defines the instance field + + The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), + a type that is assignable from that type; or if the field's type is an enum type, + either that type or the underlying integral type of that enum type + + A reference to the runtime instance to access the field + A readable/assignable reference to the field + + + + Creates a field reference delegate for an instance field of a struct + The struct that defines the instance field + + The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), + a type that is assignable from that type; or if the field's type is an enum type, + either that type or the underlying integral type of that enum type + + The name of the field + A readable/assignable delegate + + + + Creates an instance field reference for a specific instance of a struct + The struct that defines the instance field + + The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), + a type that is assignable from that type; or if the field's type is an enum type, + either that type or the underlying integral type of that enum type + + The instance + The name of the field + A readable/assignable reference to the field + + + This method is meant for one-off access to a field's value for a single instance. + If you need to access a field's value for potentially multiple instances, use instead. + StructFieldRefAccess<T, F>(ref instance, fieldName) is functionally equivalent to StructFieldRefAccess<T, F>(fieldName)(ref instance). + + + + + + Creates a field reference delegate for an instance field of a struct + The struct that defines the instance field + + The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), + a type that is assignable from that type; or if the field's type is an enum type, + either that type or the underlying integral type of that enum type + + The field + A readable/assignable delegate + + + This method is meant for cases where the field has already been obtained, avoiding the field searching cost in + e.g. . + + + + + + Creates a field reference for an instance field of a struct + The struct that defines the instance field + + The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), + a type that is assignable from that type; or if the field's type is an enum type, + either that type or the underlying integral type of that enum type + + The instance + The field + A readable/assignable reference to the field + + + This method is meant for one-off access to a field's value for a single instance and where the field has already been obtained. + If you need to access a field's value for potentially multiple instances, use instead. + StructFieldRefAccess<T, F>(ref instance, fieldInfo) is functionally equivalent to StructFieldRefAccess<T, F>(fieldInfo)(ref instance). + + + + + + A readable/assignable reference delegate to a static field + + The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), + a type that is assignable from that type; or if the field's type is an enum type, + either that type or the underlying integral type of that enum type + + A readable/assignable reference to the field + + + + Creates a static field reference + The type (can be class or struct) the field is defined in + + The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), + a type that is assignable from that type; or if the field's type is an enum type, + either that type or the underlying integral type of that enum type + + The name of the field + A readable/assignable reference to the field + + + + Creates a static field reference + + The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), + a type that is assignable from that type; or if the field's type is an enum type, + either that type or the underlying integral type of that enum type + + The type (can be class or struct) the field is defined in + The name of the field + A readable/assignable reference to the field + + + + Creates a static field reference + An arbitrary type (by convention, the type the field is defined in) + + The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), + a type that is assignable from that type; or if the field's type is an enum type, + either that type or the underlying integral type of that enum type + + The field + A readable/assignable reference to the field + + The type parameter is only used in exception messaging and to distinguish between this method overload + and the overload (which returns a rather than a reference). + + + + + Creates a static field reference delegate + + The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), + a type that is assignable from that type; or if the field's type is an enum type, + either that type or the underlying integral type of that enum type + + The field + A readable/assignable delegate + + + + Creates a delegate to a given method + The delegate Type + The method to create a delegate from. + + Only applies for instance methods. If null (default), returned delegate is an open (a.k.a. unbound) instance delegate + where an instance is supplied as the first argument to the delegate invocation; else, delegate is a closed (a.k.a. bound) + instance delegate where the delegate invocation always applies to the given . + + + Only applies for instance methods. If true (default) and is virtual, invocation of the delegate + calls the instance method virtually (the instance type's most-derived/overriden implementation of the method is called); + else, invocation of the delegate calls the exact specified (this is useful for calling base class methods) + Note: if false and is an interface method, an ArgumentException is thrown. + + A delegate of given to given + + + Delegate invocation is more performant and more convenient to use than + at a one-time setup cost. + + + Works for both type of static and instance methods, both open and closed (a.k.a. unbound and bound) instance methods, + and both class and struct methods. + + + + + + Creates a delegate for a given delegate definition, attributed with [] + The delegate Type, attributed with [] + + Only applies for instance methods. If null (default), returned delegate is an open (a.k.a. unbound) instance delegate + where an instance is supplied as the first argument to the delegate invocation; else, delegate is a closed (a.k.a. bound) + instance delegate where the delegate invocation always applies to the given . + + A delegate of given to the method specified via [] + attributes on + + This calls with the method and virtualCall arguments + determined from the [] attributes on , + and the given (for closed instance delegates). + + + + + Returns who called the current method + The calling method/constructor (excluding the caller) + + + + Rethrows an exception while preserving its stack trace (throw statement typically clobbers existing stack traces) + The exception to rethrow + + + + True if the current runtime is based on Mono, false otherwise (.NET) + + + + True if the current runtime is .NET Framework, false otherwise (.NET Core or Mono, although latter isn't guaranteed) + + + + True if the current runtime is .NET Core, false otherwise (Mono or .NET Framework) + + + + Throws a missing member runtime exception + The type that is involved + A list of names + + + + Gets default value for a specific type + The class/type + The default value + + + + Creates an (possibly uninitialized) instance of a given type + The class/type + The new instance + + + + Creates an (possibly uninitialized) instance of a given type + The class/type + The new instance + + + + + A cache for the or similar Add methods for different types. + + + + Makes a deep copy of any object + The type of the instance that should be created; for legacy reasons, this must be a class or interface + The original object + A copy of the original object but of type T + + + + Makes a deep copy of any object + The type of the instance that should be created + The original object + [out] The copy of the original object + Optional value transformation function (taking a field name and src/dst instances) + The optional path root to start with + + + + Makes a deep copy of any object + The original object + The type of the instance that should be created + Optional value transformation function (taking a field name and src/dst instances) + The optional path root to start with + The copy of the original object + + + + Tests if a type is a struct + The type + True if the type is a struct + + + + Tests if a type is a class + The type + True if the type is a class + + + + Tests if a type is a value type + The type + True if the type is a value type + + + + Tests if a type is an integer type + The type + True if the type represents some integer + + + + Tests if a type is a floating point type + The type + True if the type represents some floating point + + + + Tests if a type is a numerical type + The type + True if the type represents some number + + + + Tests if a type is void + The type + True if the type is void + + + + Test whether an instance is of a nullable type + Type of instance + An instance to test + True if instance is of nullable type, false if not + + + + Tests whether a type or member is static, as defined in C# + The type or member + True if the type or member is static + + + + Tests whether a type is static, as defined in C# + The type + True if the type is static + + + + Tests whether a property is static, as defined in C# + The property + True if the property is static + + + + Tests whether an event is static, as defined in C# + The event + True if the event is static + + + + Calculates a combined hash code for an enumeration of objects + The objects + The hash code + + + + A CodeInstruction match + + + The name of the match + + + The matched opcodes + + + The matched operands + + + The matched labels + + + The matched blocks + + + The jumps from the match + + + The jumps to the match + + + The match predicate + + + Creates a code match + The optional opcode + The optional operand + The optional name + + + + Creates a code match + The CodeInstruction + An optional name + + + + Creates a code match + The predicate + An optional name + + + + Returns a string that represents the match + A string representation + + + + A CodeInstruction matcher + + + The current position + The index or -1 if out of bounds + + + + Gets the number of code instructions in this matcher + The count + + + + Checks whether the position of this CodeMatcher is within bounds + True if this CodeMatcher is valid + + + + Checks whether the position of this CodeMatcher is outside its bounds + True if this CodeMatcher is invalid + + + + Gets the remaining code instructions + The remaining count + + + + Gets the opcode at the current position + The opcode + + + + Gets the operand at the current position + The operand + + + + Gets the labels at the current position + The labels + + + + Gets the exception blocks at the current position + The blocks + + + + Creates an empty code matcher + + + Creates a code matcher from an enumeration of instructions + The instructions (transpiler argument) + An optional IL generator + + + + Makes a clone of this instruction matcher + A copy of this matcher + + + + Gets instructions at the current position + The instruction + + + + Gets instructions at the current position with offset + The offset + The instruction + + + + Gets all instructions + A list of instructions + + + + Gets all instructions as an enumeration + A list of instructions + + + + Gets some instructions counting from current position + Number of instructions + A list of instructions + + + + Gets all instructions within a range + The start index + The end index + A list of instructions + + + + Gets all instructions within a range (relative to current position) + The start offset + The end offset + A list of instructions + + + + Gets a list of all distinct labels + The instructions (transpiler argument) + A list of Labels + + + + Reports a failure + The method involved + The logger + True if current position is invalid and error was logged + + + + Sets an instruction at current position + The instruction to set + The same code matcher + + + + Sets instruction at current position and advances + The instruction + The same code matcher + + + + Sets opcode and operand at current position + The opcode + The operand + The same code matcher + + + + Sets opcode and operand at current position and advances + The opcode + The operand + The same code matcher + + + + Sets opcode at current position and advances + The opcode + The same code matcher + + + + Sets operand at current position and advances + The operand + The same code matcher + + + + Creates a label at current position + [out] The label + The same code matcher + + + + Creates a label at a position + The position + [out] The new label + The same code matcher + + + + Adds an enumeration of labels to current position + The labels + The same code matcher + + + + Adds an enumeration of labels at a position + The position + The labels + The same code matcher + + + + Sets jump to + Branch instruction + Destination for the jump + [out] The created label + The same code matcher + + + + Inserts some instructions + The instructions + The same code matcher + + + + Inserts an enumeration of instructions + The instructions + The same code matcher + + + + Inserts a branch + The branch opcode + Branch destination + The same code matcher + + + + Inserts some instructions and advances the position + The instructions + The same code matcher + + + + Inserts an enumeration of instructions and advances the position + The instructions + The same code matcher + + + + Inserts a branch and advances the position + The branch opcode + Branch destination + The same code matcher + + + + Removes current instruction + The same code matcher + + + + Removes some instruction fro current position by count + Number of instructions + The same code matcher + + + + Removes the instructions in a range + The start + The end + The same code matcher + + + + Removes the instructions in a offset range + The start offset + The end offset + The same code matcher + + + + Advances the current position + The offset + The same code matcher + + + + Moves the current position to the start + The same code matcher + + + + Moves the current position to the end + The same code matcher + + + + Searches forward with a predicate and advances position + The predicate + The same code matcher + + + + Searches backwards with a predicate and reverses position + The predicate + The same code matcher + + + + Matches forward and advances position + True to set position to end of match, false to set it to the beginning of the match + Some code matches + The same code matcher + + + + Matches backwards and reverses position + True to set position to end of match, false to set it to the beginning of the match + Some code matches + The same code matcher + + + + Repeats a match action until boundaries are met + The match action + An optional action that is executed when no match is found + The same code matcher + + + + Gets a match by its name + The match name + An instruction + + + + General extensions for common cases + + + + Joins an enumeration with a value converter and a delimiter to a string + The inner type of the enumeration + The enumeration + An optional value converter (from T to string) + An optional delimiter + The values joined into a string + + + + Converts an array of types (for example methods arguments) into a human readable form + The array of types + A human readable description including brackets + + + + A full description of a type + The type + A human readable description + + + + A a full description of a method or a constructor without assembly details but with generics + The method/constructor + A human readable description + + + + A helper converting parameter infos to types + The array of parameter infos + An array of types + + + + A helper to access a value via key from a dictionary + The key type + The value type + The dictionary + The key + The value for the key or the default value (of T) if that key does not exist + + + + A helper to access a value via key from a dictionary with extra casting + The value type + The dictionary + The key + The value for the key or the default value (of T) if that key does not exist or cannot be cast to T + + + + Escapes Unicode and ASCII non printable characters + The string to convert + The string to convert + A string literal surrounded by + + + + Extensions for + + + + Shortcut for testing whether the operand is equal to a non-null value + The + The value + True if the operand has the same type and is equal to the value + + + + Shortcut for testing whether the operand is equal to a non-null value + The + The value + True if the operand is equal to the value + This is an optimized version of for + + + + Shortcut for code.opcode == opcode && code.OperandIs(operand) + The + The + The operand value + True if the opcode is equal to the given opcode and the operand has the same type and is equal to the given operand + + + + Shortcut for code.opcode == opcode && code.OperandIs(operand) + The + The + The operand value + True if the opcode is equal to the given opcode and the operand is equal to the given operand + This is an optimized version of for + + + + Tests for any form of Ldarg* + The + The (optional) index + True if it matches one of the variations + + + + Tests for Ldarga/Ldarga_S + The + The (optional) index + True if it matches one of the variations + + + + Tests for Starg/Starg_S + The + The (optional) index + True if it matches one of the variations + + + + Tests for any form of Ldloc* + The + The optional local variable + True if it matches one of the variations + + + + Tests for any form of Stloc* + The + The optional local variable + True if it matches one of the variations + + + + Tests if the code instruction branches + The + The label if the instruction is a branch operation or if not + True if the instruction branches + + + + Tests if the code instruction calls the method/constructor + The + The method + True if the instruction calls the method or constructor + + + + Tests if the code instruction loads a constant + The + True if the instruction loads a constant + + + + Tests if the code instruction loads an integer constant + The + The integer constant + True if the instruction loads the constant + + + + Tests if the code instruction loads a floating point constant + The + The floating point constant + True if the instruction loads the constant + + + + Tests if the code instruction loads an enum constant + The + The enum + True if the instruction loads the constant + + + + Tests if the code instruction loads a field + The + The field + Set to true if the address of the field is loaded + True if the instruction loads the field + + + + Tests if the code instruction stores a field + The + The field + True if the instruction stores this field + + + + Adds labels to the code instruction and return it + The + One or several to add + The same code instruction + + + Adds labels to the code instruction and return it + The + An enumeration of + The same code instruction + + + Extracts all labels from the code instruction and returns them + The + A list of + + + Moves all labels from the code instruction to a different one + The to move the labels from + The to move the labels to + The code instruction labels were moved from (now empty) + + + Moves all labels from a different code instruction to the current one + The to move the labels from + The to move the labels to + The code instruction that received the labels + + + Adds ExceptionBlocks to the code instruction and return it + The + One or several to add + The same code instruction + + + Adds ExceptionBlocks to the code instruction and return it + The + An enumeration of + The same code instruction + + + Extracts all ExceptionBlocks from the code instruction and returns them + The + A list of + + + Moves all ExceptionBlocks from the code instruction to a different one + The to move the ExceptionBlocks from + The to move the ExceptionBlocks to + The code instruction blocks were moved from (now empty) + + + Moves all ExceptionBlocks from a different code instruction to the current one + The to move the ExceptionBlocks from + The to move the ExceptionBlocks to + The code instruction that received the blocks + + + General extensions for collections + + + + A simple way to execute code for every element in a collection + The inner type of the collection + The collection + The action to execute + + + + A simple way to execute code for elements in a collection matching a condition + The inner type of the collection + The collection + The predicate + The action to execute + + + + A helper to add an item to a collection + The inner type of the collection + The collection + The item to add + The collection containing the item + + + + A helper to add an item to an array + The inner type of the collection + The array + The item to add + The array containing the item + + + + A helper to add items to an array + The inner type of the collection + The array + The items to add + The array containing the items + + + + General extensions for collections + + + + Tests a class member if it has an IL method body (external methods for example don't have a body) + The member to test + Returns true if the member has an IL body or false if not + + + A file log for debugging + + + + Full pathname of the log file, defaults to a file called harmony.log.txt on your Desktop + + + + The indent character. The default is tab + + + + The current indent level + + + + Changes the indentation level + The value to add to the indentation level + + + + Log a string in a buffered way. Use this method only if you are sure that FlushBuffer will be called + or else logging information is incomplete in case of a crash + The string to log + + + + Logs a list of string in a buffered way. Use this method only if you are sure that FlushBuffer will be called + or else logging information is incomplete in case of a crash + A list of strings to log (they will not be re-indented) + + + + Returns the log buffer and optionally empties it + True to empty the buffer + The buffer. + + + + Replaces the buffer with new lines + The lines to store + + + + Flushes the log buffer to disk (use in combination with LogBuffered) + + + + Log a string directly to disk. Slower method that prevents missing information in case of a crash + The string to log. + + + + Resets and deletes the log + + + + Logs some bytes as hex values + The pointer to some memory + The length of bytes to log + + + + + Default Harmony logger that writes to a file + + + + + Whether or not to enable writing the log. + + + + + Text writer to write the logs to. If not set, defaults to a file log. + + + + + File path of the log. + + + + + Main logger class that exposes log events. + + + + + A single log event that represents a single log message. + + + + + Log channel of the message. + + + + + The log message. + + + + + Log channel for the messages. + + + + + No channels (or an empty channel). + + + + + Basic information. + + + + + Full IL dumps of the generated dynamic methods. + + + + + Channel for warnings. + + + + + Channel for errors. + + + + + Additional debug information that is related to patching + + + + + All channels. + + + + + Filter for which channels should be listened to. + If the channel is in the filter, all log messages from that channel get propagated into event. + + + + + Event fired on any incoming message that passes the channel filter. + + + + A helper class to retrieve reflection info for non-private methods + + + + Given a lambda expression that calls a method, returns the method info + The lambda expression using the method + The method in the lambda expression + + + + Given a lambda expression that calls a method, returns the method info + The generic type + The lambda expression using the method + The method in the lambda expression + + + + Given a lambda expression that calls a method, returns the method info + The generic type + The generic result type + The lambda expression using the method + The method in the lambda expression + + + + Given a lambda expression that calls a method, returns the method info + The lambda expression using the method + The method in the lambda expression + + + + A reflection helper to read and write private elements + The result type defined by GetValue() + + + + Creates a traverse instance from an existing instance + The existing instance + + + + Gets/Sets the current value + The value to read or write + + + + A reflection helper to read and write private elements + + + + Creates a new traverse instance from a class/type + The class/type + A instance + + + + Creates a new traverse instance from a class T + The class + A instance + + + + Creates a new traverse instance from an instance + The object + A instance + + + + Creates a new traverse instance from a named type + The type name, for format see + A instance + + + + Creates a new and empty traverse instance + + + + Creates a new traverse instance from a class/type + The class/type + + + + Creates a new traverse instance from an instance + The object + + + + Gets the current value + The value + + + + Gets the current value + The type of the value + The value + + + + Invokes the current method with arguments and returns the result + The method arguments + The value returned by the method + + + + Invokes the current method with arguments and returns the result + The type of the value + The method arguments + The value returned by the method + + + + Sets a value of the current field or property + The value + The same traverse instance + + + + Gets the type of the current field or property + The type + + + + Moves the current traverse instance to a inner type + The type name + A traverse instance + + + + Moves the current traverse instance to a field + The type name + A traverse instance + + + + Moves the current traverse instance to a field + The type of the field + The type name + A traverse instance + + + + Gets all fields of the current type + A list of field names + + + + Moves the current traverse instance to a property + The type name + Optional property index + A traverse instance + + + + Moves the current traverse instance to a field + The type of the property + The type name + Optional property index + A traverse instance + + + + Gets all properties of the current type + A list of property names + + + + Moves the current traverse instance to a method + The name of the method + The arguments defining the argument types of the method overload + A traverse instance + + + + Moves the current traverse instance to a method + The name of the method + The argument types of the method + The arguments for the method + A traverse instance + + + + Gets all methods of the current type + A list of method names + + + + Checks if the current traverse instance is for a field + True if its a field + + + + Checks if the current traverse instance is for a property + True if its a property + + + + Checks if the current traverse instance is for a method + True if its a method + + + + Checks if the current traverse instance is for a type + True if its a type + + + + Iterates over all fields of the current type and executes a traverse action + Original object + The action receiving a instance for each field + + + + Iterates over all fields of the current type and executes a traverse action + Original object + Target object + The action receiving a pair of instances for each field pair + + + + Iterates over all fields of the current type and executes a traverse action + Original object + Target object + The action receiving a dot path representing the field pair and the instances + + + + Iterates over all properties of the current type and executes a traverse action + Original object + The action receiving a instance for each property + + + + Iterates over all properties of the current type and executes a traverse action + Original object + Target object + The action receiving a pair of instances for each property pair + + + + Iterates over all properties of the current type and executes a traverse action + Original object + Target object + The action receiving a dot path representing the property pair and the instances + + + + A default field action that copies fields to fields + + + + Returns a string that represents the current traverse + A string representation + + + + + Indicates that the marked symbol is used implicitly (e.g. via reflection, in external library), + so this symbol will not be reported as unused (as well as by other usage inspections). + + + + + Can be applied to attributes, type parameters, and parameters of a type assignable from . + When applied to an attribute, the decorated attribute behaves the same as . + When applied to a type parameter or to a parameter of type , indicates that the corresponding type + is used implicitly. + + + + + Specify the details of implicitly used symbol when it is marked + with or . + + + + Only entity marked with attribute considered used. + + + Indicates implicit assignment to a member. + + + + Indicates implicit instantiation of a type with fixed constructor signature. + That means any unused constructor parameters won't be reported as such. + + + + Indicates implicit instantiation of a type. + + + + Specify what is considered to be used implicitly when marked + with or . + + + + Members of entity marked with attribute are considered used. + + + Inherited entities are considered used. + + + Entity marked with attribute and all its members considered used. + + + diff --git a/SubnauticaModSystem/AutosortLockersSML/BZ/AutosortLockersSML.dll b/SubnauticaModSystem/AutosortLockersSML/BZ/AutosortLockersSML.dll new file mode 100644 index 0000000000000000000000000000000000000000..692b0b16f6abd04e6e347d4aaa488d37876f5e1f GIT binary patch literal 75264 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⪚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 + Debug AnyCPU @@ -9,6 +10,7 @@ Properties BaseTeleporters BaseTeleporters + $(SolutionDir)$(AssemblyName)\$(Configuration)\ v3.5 512 @@ -33,27 +35,49 @@ Always + + BZ;BELOWZERO + true + true + $(CommonDir)SubnauticaZero.Stable + SubnauticaZero_Data + SMLHelper_BZ + AnyCPU + 7.1 + prompt + + + SN1;SUBNAUTICA_STABLE + true + true + $(CommonDir)Subnautica.Stable + Subnautica_Data + Modding Helper + AnyCPU + 7.1 + prompt + - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\0Harmony.dll + $(GameDir)\$(DataFolder)\Managed\0Harmony.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp-firstpass.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp-firstpass.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-UnityScript.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-UnityScript.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-UnityScript-firstpass.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-UnityScript-firstpass.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Newtonsoft.Json.dll + $(GameDir)\$(DataFolder)\Managed\NewtonSoft.Json.dll @@ -62,25 +86,25 @@ - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.Analytics.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.Analytics.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.Networking.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.Networking.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.PerformanceTesting.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.PerformanceTesting.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UI.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UI.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.VR.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.VR.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityScript.Lang.dll + $(GameDir)\$(DataFolder)\Managed\UnityScript.Lang.dll @@ -100,8 +124,8 @@ - xcopy $(TargetPath) D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(TargetName)\ /q /y -xcopy $(ProjectDir)mod.json D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(TargetName)\ /q /y -xcopy $(ProjectDir)Assets D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(TargetName)\Assets\ /q /y /i /s + xcopy $(TargetPath) $(GameDir)\QMods\$(TargetName)\ /q /y +xcopy $(ProjectDir)mod.json $(GameDir)\QMods\$(TargetName)\ /q /y +xcopy $(ProjectDir)Assets $(GameDir)\QMods\$(TargetName)\Assets\ /q /y /i /s \ No newline at end of file diff --git a/SubnauticaModSystem/BetterPowerInfo/BetterPowerInfo.csproj b/SubnauticaModSystem/BetterPowerInfo/BetterPowerInfo.csproj index 73566c1..cbcc503 100644 --- a/SubnauticaModSystem/BetterPowerInfo/BetterPowerInfo.csproj +++ b/SubnauticaModSystem/BetterPowerInfo/BetterPowerInfo.csproj @@ -1,6 +1,7 @@  + Debug AnyCPU @@ -9,6 +10,7 @@ Properties BetterPowerInfo BetterPowerInfo + $(SolutionDir)$(AssemblyName)\$(Configuration)\ v4.7.1 512 @@ -35,20 +37,42 @@ Always + + BZ;BELOWZERO + true + true + $(CommonDir)SubnauticaZero.Stable + SubnauticaZero_Data + SMLHelper_BZ + AnyCPU + 7.1 + prompt + + + SN1;SUBNAUTICA_STABLE + true + true + $(CommonDir)Subnautica.Stable + Subnautica_Data + Modding Helper + AnyCPU + 7.1 + prompt + - - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\0Harmony-1.2.0.1.dll + + $(GameDir)\BepInEx\core\0Harmony.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp-firstpass.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp-firstpass.dll - D:\SteamLibrary\steamapps\common\Subnautica\QMods\Modding Helper\SMLHelper.dll + $(GameDir)\QMods\$(SMLHelperFolder)\SMLHelper.dll @@ -57,31 +81,31 @@ - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.CoreModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.CoreModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.ImageConversionModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.ImageConversionModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.InputLegacyModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.InputLegacyModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.JSONSerializeModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.JSONSerializeModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.TextRenderingModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.TextRenderingModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UI.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UI.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIElementsModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIElementsModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIModule.dll @@ -103,7 +127,8 @@ - + @@ -128,10 +153,10 @@ - xcopy $(TargetPath) D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)mod.json D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y + xcopy $(TargetPath) $(GameDir)\QMods\$(ProjectName)\ /q /y +xcopy $(ProjectDir)mod.json $(GameDir)\QMods\$(ProjectName)\ /q /y -xcopy $(TargetPath) D:\SteamLibrary\steamapps\common\SubnauticaZero\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)mod.json D:\SteamLibrary\steamapps\common\SubnauticaZero\QMods\$(ProjectName)\ /q /y +xcopy $(TargetPath) $(GameDir)Zero\QMods\$(ProjectName)\ /q /y +xcopy $(ProjectDir)mod.json $(GameDir)Zero\QMods\$(ProjectName)\ /q /y \ No newline at end of file diff --git a/SubnauticaModSystem/BetterScannerBlips/BetterScannerBlips.csproj b/SubnauticaModSystem/BetterScannerBlips/BetterScannerBlips.csproj index dfda4e5..c0a2046 100644 --- a/SubnauticaModSystem/BetterScannerBlips/BetterScannerBlips.csproj +++ b/SubnauticaModSystem/BetterScannerBlips/BetterScannerBlips.csproj @@ -1,6 +1,7 @@  + Debug AnyCPU @@ -9,6 +10,7 @@ Properties BetterScannerBlips BetterScannerBlips + $(SolutionDir)$(AssemblyName)\$(Configuration)\ v4.7.1 512 @@ -35,24 +37,46 @@ Always + + BZ;BELOWZERO + true + true + $(CommonDir)SubnauticaZero.Stable + SubnauticaZero_Data + SMLHelper_BZ + AnyCPU + 7.1 + prompt + + + SN1;SUBNAUTICA_STABLE + true + true + $(CommonDir)Subnautica.Stable + Subnautica_Data + Modding Helper + AnyCPU + 7.1 + prompt + - - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\0Harmony-1.2.0.1.dll + + $(GameDir)\BepInEx\core\0Harmony.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp-firstpass.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp-firstpass.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Newtonsoft.Json.dll + $(GameDir)\$(DataFolder)\Managed\NewtonSoft.Json.dll - D:\SteamLibrary\steamapps\common\Subnautica\QMods\Modding Helper\SMLHelper.dll + $(GameDir)\QMods\$(SMLHelperFolder)\SMLHelper.dll @@ -61,31 +85,31 @@ - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.CoreModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.CoreModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.ImageConversionModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.ImageConversionModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.InputLegacyModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.InputLegacyModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.JSONSerializeModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.JSONSerializeModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.TextRenderingModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.TextRenderingModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UI.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UI.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIElementsModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIElementsModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIModule.dll @@ -116,9 +140,9 @@ - xcopy $(TargetPath) D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)mod.json D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)Assets D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\Assets\ /q /y /i + xcopy $(TargetPath) $(GameDir)\QMods\$(ProjectName)\ /q /y +xcopy $(ProjectDir)mod.json $(GameDir)\QMods\$(ProjectName)\ /q /y +xcopy $(ProjectDir)Assets $(GameDir)\QMods\$(ProjectName)\Assets\ /q /y /i xcopy $(TargetPath) D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y xcopy $(ProjectDir)mod.json D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y diff --git a/SubnauticaModSystem/BlueprintTracker/BlueprintTracker.csproj b/SubnauticaModSystem/BlueprintTracker/BlueprintTracker.csproj index cb7edf1..7599d45 100644 --- a/SubnauticaModSystem/BlueprintTracker/BlueprintTracker.csproj +++ b/SubnauticaModSystem/BlueprintTracker/BlueprintTracker.csproj @@ -1,6 +1,7 @@  + Debug AnyCPU @@ -9,6 +10,7 @@ Properties BlueprintTracker BlueprintTracker + $(SolutionDir)$(AssemblyName)\$(Configuration)\ v4.7.1 512 @@ -35,23 +37,45 @@ Always + + BZ;BELOWZERO + true + true + $(CommonDir)SubnauticaZero.Stable + SubnauticaZero_Data + SMLHelper_BZ + AnyCPU + 7.1 + prompt + + + SN1;SUBNAUTICA_STABLE + true + true + $(CommonDir)Subnautica.Stable + Subnautica_Data + Modding Helper + AnyCPU + 7.1 + prompt + - - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\0Harmony-1.2.0.1.dll + + $(GameDir)\BepInEx\core\0Harmony.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp-firstpass.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp-firstpass.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Newtonsoft.Json.dll + $(GameDir)\$(DataFolder)\Managed\NewtonSoft.Json.dll - D:\SteamLibrary\steamapps\common\Subnautica\QMods\Modding Helper\SMLHelper.dll + $(GameDir)\QMods\$(SMLHelperFolder)\SMLHelper.dll @@ -60,28 +84,28 @@ - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.CoreModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.CoreModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.ImageConversionModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.ImageConversionModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.JSONSerializeModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.JSONSerializeModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.TextRenderingModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.TextRenderingModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UI.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UI.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIElementsModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIElementsModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIModule.dll @@ -118,9 +142,9 @@ - xcopy $(TargetPath) D:\SteamLibrary\steamapps\common\Subnautica\QMods\BlueprintTracker\ /q /y -xcopy $(ProjectDir)mod.json D:\SteamLibrary\steamapps\common\Subnautica\QMods\BlueprintTracker\ /q /y -xcopy $(ProjectDir)Assets D:\SteamLibrary\steamapps\common\Subnautica\QMods\BlueprintTracker\Assets\ /q /y + xcopy $(TargetPath) $(GameDir)\QMods\BlueprintTracker\ /q /y +xcopy $(ProjectDir)mod.json $(GameDir)\QMods\BlueprintTracker\ /q /y +xcopy $(ProjectDir)Assets $(GameDir)\QMods\BlueprintTracker\Assets\ /q /y xcopy $(TargetPath) D:\EpicGames\Subnautica\QMods\BlueprintTracker\ /q /y xcopy $(ProjectDir)mod.json D:\EpicGames\Subnautica\QMods\BlueprintTracker\ /q /y diff --git a/SubnauticaModSystem/Common/Mod/ModUtils.cs b/SubnauticaModSystem/Common/Mod/ModUtils.cs index ad851b2..3c3a12c 100644 --- a/SubnauticaModSystem/Common/Mod/ModUtils.cs +++ b/SubnauticaModSystem/Common/Mod/ModUtils.cs @@ -5,7 +5,11 @@ using System.Linq; using System.Reflection; using System.Text; +#if SUBNAUTICA using Oculus.Newtonsoft.Json; +#elif BELOWZERO +using Newtonsoft.Json; +#endif using UnityEngine; using UnityEngine.UI; @@ -216,7 +220,12 @@ public static void PrintObjectFields(object obj, string indent = "") public static Text GetTextPrefab() { - Text prefab = GameObject.FindObjectOfType().interactPrimaryText; + Text prefab = null; +#if SUBNAUTICA + prefab = GameObject.FindObjectOfType().interactPrimaryText; +#elif BELOWZERO + //prefab = GameObject.FindObjectOfType(). +#endif if (prefab == null) { return null; diff --git a/SubnauticaModSystem/Common/Mod/ProtoBufSerializerPatcher.cs b/SubnauticaModSystem/Common/Mod/ProtoBufSerializerPatcher.cs index c7979c2..d413534 100644 --- a/SubnauticaModSystem/Common/Mod/ProtoBufSerializerPatcher.cs +++ b/SubnauticaModSystem/Common/Mod/ProtoBufSerializerPatcher.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Reflection; -using Harmony; +using HarmonyLib; using ProtoBuf; public class ProtobufSerializerPatcher @@ -28,7 +28,7 @@ public static bool Prefix_GetKeyImpl(Type key, ref int __result) return true; } - public static void Patch(HarmonyInstance instance) + public static void Patch(Harmony instance) { Type type = typeof(ProtobufSerializerPrecompiled); instance.Patch(type.GetMethod("Serialize", BindingFlags.NonPublic | BindingFlags.Instance), new HarmonyMethod(typeof(ProtobufSerializerPatcher).GetMethod("Prefix_Serialize")), null); diff --git a/SubnauticaModSystem/CustomPings/CustomBeacons.csproj b/SubnauticaModSystem/CustomPings/CustomBeacons.csproj index b34d4bb..d5e5c46 100644 --- a/SubnauticaModSystem/CustomPings/CustomBeacons.csproj +++ b/SubnauticaModSystem/CustomPings/CustomBeacons.csproj @@ -1,6 +1,7 @@  + Debug AnyCPU @@ -9,6 +10,7 @@ Properties CustomBeacons CustomBeacons + $(SolutionDir)$(AssemblyName)\$(Configuration)\ v4.7.1 512 @@ -35,24 +37,46 @@ Always + + BZ;BELOWZERO + true + true + $(CommonDir)SubnauticaZero.Stable + SubnauticaZero_Data + SMLHelper_BZ + AnyCPU + 7.1 + prompt + + + SN1;SUBNAUTICA_STABLE + true + true + $(CommonDir)Subnautica.Stable + Subnautica_Data + Modding Helper + AnyCPU + 7.1 + prompt + - - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\0Harmony-1.2.0.1.dll + + $(GameDir)\BepInEx\core\0Harmony.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp-firstpass.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp-firstpass.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Newtonsoft.Json.dll + $(GameDir)\$(DataFolder)\Managed\NewtonSoft.Json.dll - D:\SteamLibrary\steamapps\common\Subnautica\QMods\Modding Helper\SMLHelper.dll + $(GameDir)\QMods\$(SMLHelperFolder)\SMLHelper.dll @@ -61,31 +85,31 @@ - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.CoreModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.CoreModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.ImageConversionModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.ImageConversionModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.JSONSerializeModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.JSONSerializeModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.Physics2DModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.Physics2DModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.TextRenderingModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.TextRenderingModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UI.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UI.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIElementsModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIElementsModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIModule.dll @@ -113,9 +137,9 @@ - xcopy $(TargetPath) D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)mod.json D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)Assets D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\Assets\ /q /y /i /s + xcopy $(TargetPath) $(GameDir)\QMods\$(ProjectName)\ /q /y +xcopy $(ProjectDir)mod.json $(GameDir)\QMods\$(ProjectName)\ /q /y +xcopy $(ProjectDir)Assets $(GameDir)\QMods\$(ProjectName)\Assets\ /q /y /i /s xcopy $(TargetPath) D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y xcopy $(ProjectDir)mod.json D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y diff --git a/SubnauticaModSystem/CustomizedStorage/CustomizedStorage.csproj b/SubnauticaModSystem/CustomizedStorage/CustomizedStorage.csproj index 02cd599..1e14b9e 100644 --- a/SubnauticaModSystem/CustomizedStorage/CustomizedStorage.csproj +++ b/SubnauticaModSystem/CustomizedStorage/CustomizedStorage.csproj @@ -1,6 +1,7 @@  + Debug AnyCPU @@ -9,6 +10,7 @@ Properties CustomizedStorage CustomizedStorage + $(SolutionDir)$(AssemblyName)\$(Configuration)\ v4.7.1 512 @@ -35,25 +37,47 @@ Always + + BZ;BELOWZERO + true + true + $(CommonDir)SubnauticaZero.Stable + SubnauticaZero_Data + SMLHelper_BZ + AnyCPU + 7.1 + prompt + + + SN1;SUBNAUTICA_STABLE + true + true + $(CommonDir)Subnautica.Stable + Subnautica_Data + Modding Helper + AnyCPU + 7.1 + prompt + - - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\0Harmony-1.2.0.1.dll + + $(GameDir)\BepInEx\core\0Harmony.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp-firstpass.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp-firstpass.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Newtonsoft.Json.dll + $(GameDir)\$(DataFolder)\Managed\NewtonSoft.Json.dll False - D:\SteamLibrary\steamapps\common\Subnautica\QMods\Modding Helper\SMLHelper.dll + $(GameDir)\QMods\$(SMLHelperFolder)\SMLHelper.dll @@ -62,28 +86,28 @@ - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.CoreModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.CoreModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.ImageConversionModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.ImageConversionModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.JSONSerializeModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.JSONSerializeModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.TextRenderingModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.TextRenderingModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UI.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UI.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIElementsModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIElementsModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIModule.dll @@ -114,9 +138,9 @@ - xcopy $(TargetPath) D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)mod.json D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)config.json D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y /i + xcopy $(TargetPath) $(GameDir)\QMods\$(ProjectName)\ /q /y +xcopy $(ProjectDir)mod.json $(GameDir)\QMods\$(ProjectName)\ /q /y +xcopy $(ProjectDir)config.json $(GameDir)\QMods\$(ProjectName)\ /q /y /i xcopy $(TargetPath) D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y xcopy $(ProjectDir)mod.json D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y diff --git a/SubnauticaModSystem/DockedVehicleStorageAccess/DockedVehicleStorageAccess.csproj b/SubnauticaModSystem/DockedVehicleStorageAccess/DockedVehicleStorageAccess.csproj index 3b85e69..5366738 100644 --- a/SubnauticaModSystem/DockedVehicleStorageAccess/DockedVehicleStorageAccess.csproj +++ b/SubnauticaModSystem/DockedVehicleStorageAccess/DockedVehicleStorageAccess.csproj @@ -1,6 +1,7 @@  + Debug AnyCPU @@ -9,6 +10,7 @@ Properties DockedVehicleStorageAccess DockedVehicleStorageAccessSML + $(SolutionDir)$(AssemblyName)\$(Configuration)\ v4.0 512 @@ -35,73 +37,94 @@ Always + + BZ;BELOWZERO + true + true + $(CommonDir)SubnauticaZero.Stable + SubnauticaZero_Data + SMLHelper_BZ + AnyCPU + 7.1 + prompt + + + SN1;SUBNAUTICA_STABLE + true + true + $(CommonDir)Subnautica.Stable + Subnautica_Data + Modding Helper + AnyCPU + 7.1 + prompt + - - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\0Harmony-1.2.0.1.dll - False + + $(GameDir)\BepInEx\core\0Harmony.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp.dll False False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp-firstpass.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp-firstpass.dll False False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Newtonsoft.Json.dll + $(GameDir)\$(DataFolder)\Managed\NewtonSoft.Json.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\QModInstaller.dll + $(GameDir)\BepInEx\plugins\QModManager\QModInstaller.dll False - D:\SteamLibrary\steamapps\common\Subnautica\QMods\Modding Helper\SMLHelper.dll + $(GameDir)\QMods\$(SMLHelperFolder)\SMLHelper.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.CoreModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.CoreModule.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.InputLegacyModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.InputLegacyModule.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.Physics2DModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.Physics2DModule.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.PhysicsModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.PhysicsModule.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.TextCoreModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.TextCoreModule.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.TextRenderingModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.TextRenderingModule.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UI.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UI.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIElementsModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIElementsModule.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIModule.dll False @@ -136,9 +159,9 @@ - xcopy $(TargetPath) D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)mod.json D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)Assets D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\Assets\ /q /y /i + xcopy $(TargetPath) $(GameDir)\QMods\$(ProjectName)\ /q /y +xcopy $(ProjectDir)mod.json $(GameDir)\QMods\$(ProjectName)\ /q /y +xcopy $(ProjectDir)Assets $(GameDir)\QMods\$(ProjectName)\Assets\ /q /y /i xcopy $(TargetPath) D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y xcopy $(ProjectDir)mod.json D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y diff --git a/SubnauticaModSystem/GameDir.targets b/SubnauticaModSystem/GameDir.targets new file mode 100644 index 0000000..820a418 --- /dev/null +++ b/SubnauticaModSystem/GameDir.targets @@ -0,0 +1,7 @@ + + + + + S:\Steam\steamapps\common\ + + \ No newline at end of file diff --git a/SubnauticaModSystem/HabitatControlPanel/HabitatControlPanel.csproj b/SubnauticaModSystem/HabitatControlPanel/HabitatControlPanel.csproj index e203823..2b103af 100644 --- a/SubnauticaModSystem/HabitatControlPanel/HabitatControlPanel.csproj +++ b/SubnauticaModSystem/HabitatControlPanel/HabitatControlPanel.csproj @@ -1,6 +1,7 @@  + Debug AnyCPU @@ -9,6 +10,7 @@ Properties HabitatControlPanel HabitatControlPanelSML + $(SolutionDir)$(AssemblyName)\$(Configuration)\ v4.7.1 512 @@ -35,27 +37,49 @@ Always + + BZ;BELOWZERO + true + true + $(CommonDir)SubnauticaZero.Stable + SubnauticaZero_Data + SMLHelper_BZ + AnyCPU + 7.1 + prompt + + + SN1;SUBNAUTICA_STABLE + true + true + $(CommonDir)Subnautica.Stable + Subnautica_Data + Modding Helper + AnyCPU + 7.1 + prompt + - - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\0Harmony-1.2.0.1.dll + + $(GameDir)\BepInEx\core\0Harmony.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp-firstpass.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp-firstpass.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Newtonsoft.Json.dll + $(GameDir)\$(DataFolder)\Managed\NewtonSoft.Json.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\QModInstaller.dll + $(GameDir)\BepInEx\plugins\QModManager\QModInstaller.dll - D:\SteamLibrary\steamapps\common\Subnautica\QMods\Modding Helper\SMLHelper.dll + $(GameDir)\QMods\$(SMLHelperFolder)\SMLHelper.dll @@ -64,34 +88,34 @@ - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.AnimationModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.AnimationModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.AssetBundleModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.AssetBundleModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.CoreModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.CoreModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.ImageConversionModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.ImageConversionModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.Physics2DModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.Physics2DModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.PhysicsModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.PhysicsModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.TextRenderingModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.TextRenderingModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UI.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UI.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIModule.dll @@ -140,9 +164,9 @@ - xcopy $(TargetPath) D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)mod.json D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)Assets D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\Assets\ /q /y /i + xcopy $(TargetPath) $(GameDir)\QMods\$(ProjectName)\ /q /y +xcopy $(ProjectDir)mod.json $(GameDir)\QMods\$(ProjectName)\ /q /y +xcopy $(ProjectDir)Assets $(GameDir)\QMods\$(ProjectName)\Assets\ /q /y /i xcopy $(TargetPath) D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y xcopy $(ProjectDir)mod.json D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y diff --git a/SubnauticaModSystem/HudConfig/HudConfig.csproj b/SubnauticaModSystem/HudConfig/HudConfig.csproj index b37c0e6..8a0f8c0 100644 --- a/SubnauticaModSystem/HudConfig/HudConfig.csproj +++ b/SubnauticaModSystem/HudConfig/HudConfig.csproj @@ -1,6 +1,7 @@  + Debug AnyCPU @@ -9,6 +10,7 @@ Properties HudConfig HudConfig + $(SolutionDir)$(AssemblyName)\$(Configuration)\ v4.7.1 512 @@ -35,24 +37,46 @@ Always + + BZ;BELOWZERO + true + true + $(CommonDir)SubnauticaZero.Stable + SubnauticaZero_Data + SMLHelper_BZ + AnyCPU + 7.1 + prompt + + + SN1;SUBNAUTICA_STABLE + true + true + $(CommonDir)Subnautica.Stable + Subnautica_Data + Modding Helper + AnyCPU + 7.1 + prompt + - - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\0Harmony-1.2.0.1.dll + + $(GameDir)\BepInEx\core\0Harmony.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp-firstpass.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp-firstpass.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Newtonsoft.Json.dll + $(GameDir)\$(DataFolder)\Managed\NewtonSoft.Json.dll - D:\SteamLibrary\steamapps\common\Subnautica\QMods\Modding Helper\SMLHelper.dll + $(GameDir)\QMods\$(SMLHelperFolder)\SMLHelper.dll @@ -61,28 +85,28 @@ - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.CoreModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.CoreModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.ImageConversionModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.ImageConversionModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.JSONSerializeModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.JSONSerializeModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.TextRenderingModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.TextRenderingModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UI.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UI.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIElementsModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIElementsModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIModule.dll @@ -101,9 +125,9 @@ - xcopy $(TargetPath) D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)mod.json D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)Assets D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\Assets\ /q /y /i + xcopy $(TargetPath) $(GameDir)\QMods\$(ProjectName)\ /q /y +xcopy $(ProjectDir)mod.json $(GameDir)\QMods\$(ProjectName)\ /q /y +xcopy $(ProjectDir)Assets $(GameDir)\QMods\$(ProjectName)\Assets\ /q /y /i xcopy $(TargetPath) D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y xcopy $(ProjectDir)mod.json D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y diff --git a/SubnauticaModSystem/LongLockerNames/LongLockerNames.csproj b/SubnauticaModSystem/LongLockerNames/LongLockerNames.csproj index 5b8d995..8dc332f 100644 --- a/SubnauticaModSystem/LongLockerNames/LongLockerNames.csproj +++ b/SubnauticaModSystem/LongLockerNames/LongLockerNames.csproj @@ -1,6 +1,7 @@  + Debug AnyCPU @@ -9,6 +10,7 @@ Properties LongLockerNames LongLockerNames + $(SolutionDir)$(AssemblyName)\$(Configuration)\ v4.7.1 512 @@ -35,23 +37,45 @@ Always + + BZ;BELOWZERO + true + true + $(CommonDir)SubnauticaZero.Stable + SubnauticaZero_Data + SMLHelper_BZ + AnyCPU + 7.1 + prompt + + + SN1;SUBNAUTICA_STABLE + true + true + $(CommonDir)Subnautica.Stable + Subnautica_Data + Modding Helper + AnyCPU + 7.1 + prompt + - - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\0Harmony-1.2.0.1.dll + + $(GameDir)\BepInEx\core\0Harmony.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp-firstpass.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp-firstpass.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Newtonsoft.Json.dll + $(GameDir)\$(DataFolder)\Managed\NewtonSoft.Json.dll - D:\SteamLibrary\steamapps\common\Subnautica\QMods\Modding Helper\SMLHelper.dll + $(GameDir)\QMods\$(SMLHelperFolder)\SMLHelper.dll @@ -60,28 +84,28 @@ - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.CoreModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.CoreModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.ImageConversionModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.ImageConversionModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.JSONSerializeModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.JSONSerializeModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.TextRenderingModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.TextRenderingModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UI.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UI.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIElementsModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIElementsModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIModule.dll @@ -110,9 +134,9 @@ - xcopy $(TargetPath) D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)mod.json D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)Assets D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\Assets\ /q /y /i + xcopy $(TargetPath) $(GameDir)\QMods\$(ProjectName)\ /q /y +xcopy $(ProjectDir)mod.json $(GameDir)\QMods\$(ProjectName)\ /q /y +xcopy $(ProjectDir)Assets $(GameDir)\QMods\$(ProjectName)\Assets\ /q /y /i xcopy $(TargetPath) D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y xcopy $(ProjectDir)mod.json D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y diff --git a/SubnauticaModSystem/ModInjector_MoreQuickSlots/ModInjector_MoreQuickSlots.csproj b/SubnauticaModSystem/ModInjector_MoreQuickSlots/ModInjector_MoreQuickSlots.csproj index 33eaf30..2b536d2 100644 --- a/SubnauticaModSystem/ModInjector_MoreQuickSlots/ModInjector_MoreQuickSlots.csproj +++ b/SubnauticaModSystem/ModInjector_MoreQuickSlots/ModInjector_MoreQuickSlots.csproj @@ -1,6 +1,7 @@  + Debug AnyCPU @@ -8,6 +9,7 @@ WinExe ModInjector_MoreQuickSlots ModInjector_MoreQuickSlots + $(SolutionDir)$(AssemblyName)\$(Configuration)\ v4.6.1 512 true @@ -17,7 +19,7 @@ true full false - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\ + $(GameDir)\$(DataFolder)\Managed\ DEBUG;TRACE prompt 4 @@ -34,6 +36,28 @@ inject128.ico + + BZ;BELOWZERO + true + true + $(CommonDir)SubnauticaZero.Stable + SubnauticaZero_Data + SMLHelper_BZ + AnyCPU + 7.1 + prompt + + + SN1;SUBNAUTICA_STABLE + true + true + $(CommonDir)Subnautica.Stable + Subnautica_Data + Modding Helper + AnyCPU + 7.1 + prompt + ..\Packages\Mono.Cecil.dll diff --git a/SubnauticaModSystem/MoreQuickSlots/MoreQuickSlots.csproj b/SubnauticaModSystem/MoreQuickSlots/MoreQuickSlots.csproj index 705c497..57a9050 100644 --- a/SubnauticaModSystem/MoreQuickSlots/MoreQuickSlots.csproj +++ b/SubnauticaModSystem/MoreQuickSlots/MoreQuickSlots.csproj @@ -1,6 +1,7 @@  + Debug AnyCPU @@ -9,6 +10,7 @@ Properties MoreQuickSlots MoreQuickSlots + $(SolutionDir)$(AssemblyName)\$(Configuration)\ v4.7.1 512 @@ -35,26 +37,48 @@ OnBuildSuccess + + BZ;BELOWZERO + true + true + $(CommonDir)SubnauticaZero.Stable + SubnauticaZero_Data + SMLHelper_BZ + AnyCPU + 7.1 + prompt + + + SN1;SUBNAUTICA_STABLE + true + true + $(CommonDir)Subnautica.Stable + Subnautica_Data + Modding Helper + AnyCPU + 7.1 + prompt + - - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\0Harmony-1.2.0.1.dll + + $(GameDir)\BepInEx\core\0Harmony.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp-firstpass.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp-firstpass.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\LitJson.dll + $(GameDir)\$(DataFolder)\Managed\LitJson.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Newtonsoft.Json.dll + $(GameDir)\$(DataFolder)\Managed\NewtonSoft.Json.dll - D:\SteamLibrary\steamapps\common\Subnautica\QMods\Modding Helper\SMLHelper.dll + $(GameDir)\QMods\$(SMLHelperFolder)\SMLHelper.dll @@ -63,38 +87,38 @@ - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.CoreModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.CoreModule.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.ImageConversionModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.ImageConversionModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.InputLegacyModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.InputLegacyModule.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.JSONSerializeModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.JSONSerializeModule.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.TextRenderingModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.TextRenderingModule.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UI.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UI.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIElementsModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIElementsModule.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIModule.dll @@ -124,8 +148,8 @@ - xcopy $(TargetPath) D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)mod.json D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y + xcopy $(TargetPath) $(GameDir)\QMods\$(ProjectName)\ /q /y +xcopy $(ProjectDir)mod.json $(GameDir)\QMods\$(ProjectName)\ /q /y xcopy $(TargetPath) D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y xcopy $(ProjectDir)mod.json D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y diff --git a/SubnauticaModSystem/PrawnsuitLightswitch/PrawnsuitLightswitch.csproj b/SubnauticaModSystem/PrawnsuitLightswitch/PrawnsuitLightswitch.csproj index 572de39..27d5adb 100644 --- a/SubnauticaModSystem/PrawnsuitLightswitch/PrawnsuitLightswitch.csproj +++ b/SubnauticaModSystem/PrawnsuitLightswitch/PrawnsuitLightswitch.csproj @@ -1,6 +1,7 @@  + Debug AnyCPU @@ -9,6 +10,7 @@ Properties PrawnsuitLightswitch PrawnsuitLightswitch + $(SolutionDir)$(AssemblyName)\$(Configuration)\ v4.7.1 512 @@ -35,24 +37,46 @@ Always + + BZ;BELOWZERO + true + true + $(CommonDir)SubnauticaZero.Stable + SubnauticaZero_Data + SMLHelper_BZ + AnyCPU + 7.1 + prompt + + + SN1;SUBNAUTICA_STABLE + true + true + $(CommonDir)Subnautica.Stable + Subnautica_Data + Modding Helper + AnyCPU + 7.1 + prompt + - - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\0Harmony-1.2.0.1.dll + + $(GameDir)\BepInEx\core\0Harmony.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp-firstpass.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp-firstpass.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Newtonsoft.Json.dll + $(GameDir)\$(DataFolder)\Managed\NewtonSoft.Json.dll - D:\SteamLibrary\steamapps\common\Subnautica\QMods\Modding Helper\SMLHelper.dll + $(GameDir)\QMods\$(SMLHelperFolder)\SMLHelper.dll @@ -61,28 +85,28 @@ - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.CoreModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.CoreModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.ImageConversionModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.ImageConversionModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.JSONSerializeModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.JSONSerializeModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.TextRenderingModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.TextRenderingModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UI.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UI.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIElementsModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIElementsModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIModule.dll @@ -112,9 +136,9 @@ - xcopy $(TargetPath) D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)mod.json D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)Assets D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\Assets\ /q /y /i + xcopy $(TargetPath) $(GameDir)\QMods\$(ProjectName)\ /q /y +xcopy $(ProjectDir)mod.json $(GameDir)\QMods\$(ProjectName)\ /q /y +xcopy $(ProjectDir)Assets $(GameDir)\QMods\$(ProjectName)\Assets\ /q /y /i xcopy $(TargetPath) D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y xcopy $(ProjectDir)mod.json D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y diff --git a/SubnauticaModSystem/QuitToDesktop/QuitToDesktop.csproj b/SubnauticaModSystem/QuitToDesktop/QuitToDesktop.csproj index 9f1fa62..c6787c4 100644 --- a/SubnauticaModSystem/QuitToDesktop/QuitToDesktop.csproj +++ b/SubnauticaModSystem/QuitToDesktop/QuitToDesktop.csproj @@ -1,6 +1,7 @@  + Debug AnyCPU @@ -9,6 +10,7 @@ Properties QuitToDesktop QuitToDesktop + $(SolutionDir)$(AssemblyName)\$(Configuration)\ v4.7.2 512 @@ -36,21 +38,43 @@ Always + + BZ;BELOWZERO + true + true + $(CommonDir)SubnauticaZero.Stable + SubnauticaZero_Data + SMLHelper_BZ + AnyCPU + 7.1 + prompt + + + SN1;SUBNAUTICA_STABLE + true + true + $(CommonDir)Subnautica.Stable + Subnautica_Data + Modding Helper + AnyCPU + 7.1 + prompt + - D:\SteamLibrary\steamapps\common\Subnautica\BepInEx\core\0Harmony.dll + $(GameDir)\BepInEx\core\0Harmony.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\publicized_assemblies\Assembly-CSharp-firstpass_publicized.dll + $(GameDir)\$(DataFolder)\Managed\publicized_assemblies\Assembly-CSharp-firstpass_publicized.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\publicized_assemblies\Assembly-CSharp_publicized.dll + $(GameDir)\$(DataFolder)\Managed\publicized_assemblies\Assembly-CSharp_publicized.dll - D:\SteamLibrary\steamapps\common\Subnautica\BepInEx\plugins\QModManager\QModInstaller.dll + $(GameDir)\BepInEx\plugins\QModManager\QModInstaller.dll - D:\SteamLibrary\steamapps\common\Subnautica\QMods\Modding Helper\SMLHelper.dll + $(GameDir)\QMods\$(SMLHelperFolder)\SMLHelper.dll @@ -59,27 +83,27 @@ - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.CoreModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.CoreModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.ImageConversionModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.ImageConversionModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.JSONSerializeModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.JSONSerializeModule.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.TextRenderingModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.TextRenderingModule.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UI.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UI.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIModule.dll @@ -105,8 +129,8 @@ - xcopy $(TargetPath) D:\SteamLibrary\steamapps\common\Subnautica\QMods\QuitToDesktop\ /q /y -xcopy $(ProjectDir)mod.json D:\SteamLibrary\steamapps\common\Subnautica\QMods\QuitToDesktop\ /q /y + xcopy $(TargetPath) $(GameDir)\QMods\QuitToDesktop\ /q /y +xcopy $(ProjectDir)mod.json $(GameDir)\QMods\QuitToDesktop\ /q /y xcopy $(TargetPath) D:\EpicGames\Subnautica\QMods\QuitToDesktop\ /q /y xcopy $(ProjectDir)mod.json D:\EpicGames\Subnautica\QMods\QuitToDesktop\ /q /y diff --git a/SubnauticaModSystem/SeaglideMapMod/SeaglideMapControls.csproj b/SubnauticaModSystem/SeaglideMapMod/SeaglideMapControls.csproj index 06126b6..567d29e 100644 --- a/SubnauticaModSystem/SeaglideMapMod/SeaglideMapControls.csproj +++ b/SubnauticaModSystem/SeaglideMapMod/SeaglideMapControls.csproj @@ -1,6 +1,7 @@  + Debug AnyCPU @@ -9,6 +10,7 @@ Properties SeaglideMapControls SeaglideMapControls + $(SolutionDir)$(AssemblyName)\$(Configuration)\ v4.7.1 512 @@ -35,24 +37,46 @@ Always + + BZ;BELOWZERO + true + true + $(CommonDir)SubnauticaZero.Stable + SubnauticaZero_Data + SMLHelper_BZ + AnyCPU + 7.1 + prompt + + + SN1;SUBNAUTICA_STABLE + true + true + $(CommonDir)Subnautica.Stable + Subnautica_Data + Modding Helper + AnyCPU + 7.1 + prompt + - - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\0Harmony-1.2.0.1.dll + + $(GameDir)\BepInEx\core\0Harmony.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp-firstpass.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp-firstpass.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Newtonsoft.Json.dll + $(GameDir)\$(DataFolder)\Managed\NewtonSoft.Json.dll - D:\SteamLibrary\steamapps\common\Subnautica\QMods\Modding Helper\SMLHelper.dll + $(GameDir)\QMods\$(SMLHelperFolder)\SMLHelper.dll @@ -61,28 +85,28 @@ - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.CoreModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.CoreModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.ImageConversionModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.ImageConversionModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.JSONSerializeModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.JSONSerializeModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.TextRenderingModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.TextRenderingModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UI.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UI.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIElementsModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIElementsModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIModule.dll @@ -113,9 +137,9 @@ - xcopy $(TargetPath) D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)mod.json D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)Assets D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\Assets\ /q /y /i + xcopy $(TargetPath) $(GameDir)\QMods\$(ProjectName)\ /q /y +xcopy $(ProjectDir)mod.json $(GameDir)\QMods\$(ProjectName)\ /q /y +xcopy $(ProjectDir)Assets $(GameDir)\QMods\$(ProjectName)\Assets\ /q /y /i xcopy $(TargetPath) D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y xcopy $(ProjectDir)mod.json D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y diff --git a/SubnauticaModSystem/SubnauticaModSystem.sln b/SubnauticaModSystem/SubnauticaModSystem.sln index eae8059..ca20a4e 100644 --- a/SubnauticaModSystem/SubnauticaModSystem.sln +++ b/SubnauticaModSystem/SubnauticaModSystem.sln @@ -17,7 +17,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LongLockerNames", "LongLock EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Common", "Common\Common.shproj", "{DD1D2DC7-3BDC-4DC1-99C8-2D0CCBF2B171}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutosortLockers", "AutosortLockers\AutosortLockers.csproj", "{6C883B28-31E6-4C26-B32B-BF5BE0D70190}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutosortLockersSML", "AutosortLockers\AutosortLockersSML.csproj", "{6C883B28-31E6-4C26-B32B-BF5BE0D70190}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BetterScannerBlips", "BetterScannerBlips\BetterScannerBlips.csproj", "{B7752C03-C7BB-494F-BA52-9CD5EC649AA7}" EndProject @@ -64,125 +64,203 @@ Global Common\Common.projitems*{fd7b0bb5-6bcf-45b6-9145-10a8f0fef277}*SharedItemsImports = 4 EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution + BZ|Any CPU = BZ|Any CPU Debug_Autosort|Any CPU = Debug_Autosort|Any CPU Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU + SN1|Any CPU = SN1|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2B390DAA-56B9-42D9-BAD4-8A47736C0563}.BZ|Any CPU.ActiveCfg = BZ|Any CPU + {2B390DAA-56B9-42D9-BAD4-8A47736C0563}.BZ|Any CPU.Build.0 = BZ|Any CPU {2B390DAA-56B9-42D9-BAD4-8A47736C0563}.Debug_Autosort|Any CPU.ActiveCfg = Debug|Any CPU {2B390DAA-56B9-42D9-BAD4-8A47736C0563}.Debug_Autosort|Any CPU.Build.0 = Debug|Any CPU {2B390DAA-56B9-42D9-BAD4-8A47736C0563}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2B390DAA-56B9-42D9-BAD4-8A47736C0563}.Debug|Any CPU.Build.0 = Debug|Any CPU {2B390DAA-56B9-42D9-BAD4-8A47736C0563}.Release|Any CPU.ActiveCfg = Release|Any CPU {2B390DAA-56B9-42D9-BAD4-8A47736C0563}.Release|Any CPU.Build.0 = Release|Any CPU + {2B390DAA-56B9-42D9-BAD4-8A47736C0563}.SN1|Any CPU.ActiveCfg = SN1|Any CPU + {2B390DAA-56B9-42D9-BAD4-8A47736C0563}.SN1|Any CPU.Build.0 = SN1|Any CPU + {09868E2D-416A-441C-9D9A-19D791E8FC42}.BZ|Any CPU.ActiveCfg = BZ|Any CPU + {09868E2D-416A-441C-9D9A-19D791E8FC42}.BZ|Any CPU.Build.0 = BZ|Any CPU {09868E2D-416A-441C-9D9A-19D791E8FC42}.Debug_Autosort|Any CPU.ActiveCfg = Debug|Any CPU {09868E2D-416A-441C-9D9A-19D791E8FC42}.Debug_Autosort|Any CPU.Build.0 = Debug|Any CPU {09868E2D-416A-441C-9D9A-19D791E8FC42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {09868E2D-416A-441C-9D9A-19D791E8FC42}.Debug|Any CPU.Build.0 = Debug|Any CPU {09868E2D-416A-441C-9D9A-19D791E8FC42}.Release|Any CPU.ActiveCfg = Release|Any CPU {09868E2D-416A-441C-9D9A-19D791E8FC42}.Release|Any CPU.Build.0 = Release|Any CPU + {09868E2D-416A-441C-9D9A-19D791E8FC42}.SN1|Any CPU.ActiveCfg = SN1|Any CPU + {09868E2D-416A-441C-9D9A-19D791E8FC42}.SN1|Any CPU.Build.0 = SN1|Any CPU + {0D86304E-0A53-422A-99E6-0C687D9DBBC6}.BZ|Any CPU.ActiveCfg = BZ|Any CPU + {0D86304E-0A53-422A-99E6-0C687D9DBBC6}.BZ|Any CPU.Build.0 = BZ|Any CPU {0D86304E-0A53-422A-99E6-0C687D9DBBC6}.Debug_Autosort|Any CPU.ActiveCfg = Debug|Any CPU {0D86304E-0A53-422A-99E6-0C687D9DBBC6}.Debug_Autosort|Any CPU.Build.0 = Debug|Any CPU {0D86304E-0A53-422A-99E6-0C687D9DBBC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0D86304E-0A53-422A-99E6-0C687D9DBBC6}.Debug|Any CPU.Build.0 = Debug|Any CPU {0D86304E-0A53-422A-99E6-0C687D9DBBC6}.Release|Any CPU.ActiveCfg = Release|Any CPU {0D86304E-0A53-422A-99E6-0C687D9DBBC6}.Release|Any CPU.Build.0 = Release|Any CPU + {0D86304E-0A53-422A-99E6-0C687D9DBBC6}.SN1|Any CPU.ActiveCfg = SN1|Any CPU + {0D86304E-0A53-422A-99E6-0C687D9DBBC6}.SN1|Any CPU.Build.0 = SN1|Any CPU + {CF7E5EA0-EE32-4330-AF9C-E720E9A64681}.BZ|Any CPU.ActiveCfg = BZ|Any CPU + {CF7E5EA0-EE32-4330-AF9C-E720E9A64681}.BZ|Any CPU.Build.0 = BZ|Any CPU {CF7E5EA0-EE32-4330-AF9C-E720E9A64681}.Debug_Autosort|Any CPU.ActiveCfg = Debug|Any CPU {CF7E5EA0-EE32-4330-AF9C-E720E9A64681}.Debug_Autosort|Any CPU.Build.0 = Debug|Any CPU {CF7E5EA0-EE32-4330-AF9C-E720E9A64681}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CF7E5EA0-EE32-4330-AF9C-E720E9A64681}.Debug|Any CPU.Build.0 = Debug|Any CPU {CF7E5EA0-EE32-4330-AF9C-E720E9A64681}.Release|Any CPU.ActiveCfg = Release|Any CPU {CF7E5EA0-EE32-4330-AF9C-E720E9A64681}.Release|Any CPU.Build.0 = Release|Any CPU + {CF7E5EA0-EE32-4330-AF9C-E720E9A64681}.SN1|Any CPU.ActiveCfg = SN1|Any CPU + {CF7E5EA0-EE32-4330-AF9C-E720E9A64681}.SN1|Any CPU.Build.0 = SN1|Any CPU + {BFFEC1AE-67D2-4CBA-B76B-76DF2BA9C053}.BZ|Any CPU.ActiveCfg = BZ|Any CPU + {BFFEC1AE-67D2-4CBA-B76B-76DF2BA9C053}.BZ|Any CPU.Build.0 = BZ|Any CPU {BFFEC1AE-67D2-4CBA-B76B-76DF2BA9C053}.Debug_Autosort|Any CPU.ActiveCfg = Debug|Any CPU {BFFEC1AE-67D2-4CBA-B76B-76DF2BA9C053}.Debug_Autosort|Any CPU.Build.0 = Debug|Any CPU {BFFEC1AE-67D2-4CBA-B76B-76DF2BA9C053}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BFFEC1AE-67D2-4CBA-B76B-76DF2BA9C053}.Debug|Any CPU.Build.0 = Debug|Any CPU {BFFEC1AE-67D2-4CBA-B76B-76DF2BA9C053}.Release|Any CPU.ActiveCfg = Release|Any CPU {BFFEC1AE-67D2-4CBA-B76B-76DF2BA9C053}.Release|Any CPU.Build.0 = Release|Any CPU + {BFFEC1AE-67D2-4CBA-B76B-76DF2BA9C053}.SN1|Any CPU.ActiveCfg = SN1|Any CPU + {BFFEC1AE-67D2-4CBA-B76B-76DF2BA9C053}.SN1|Any CPU.Build.0 = SN1|Any CPU + {7B7CDBE9-9FAC-4E28-A42C-80A21066D7AB}.BZ|Any CPU.ActiveCfg = BZ|Any CPU + {7B7CDBE9-9FAC-4E28-A42C-80A21066D7AB}.BZ|Any CPU.Build.0 = BZ|Any CPU {7B7CDBE9-9FAC-4E28-A42C-80A21066D7AB}.Debug_Autosort|Any CPU.ActiveCfg = Debug|Any CPU {7B7CDBE9-9FAC-4E28-A42C-80A21066D7AB}.Debug_Autosort|Any CPU.Build.0 = Debug|Any CPU {7B7CDBE9-9FAC-4E28-A42C-80A21066D7AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7B7CDBE9-9FAC-4E28-A42C-80A21066D7AB}.Debug|Any CPU.Build.0 = Debug|Any CPU {7B7CDBE9-9FAC-4E28-A42C-80A21066D7AB}.Release|Any CPU.ActiveCfg = Release|Any CPU {7B7CDBE9-9FAC-4E28-A42C-80A21066D7AB}.Release|Any CPU.Build.0 = Release|Any CPU + {7B7CDBE9-9FAC-4E28-A42C-80A21066D7AB}.SN1|Any CPU.ActiveCfg = SN1|Any CPU + {7B7CDBE9-9FAC-4E28-A42C-80A21066D7AB}.SN1|Any CPU.Build.0 = SN1|Any CPU + {6C883B28-31E6-4C26-B32B-BF5BE0D70190}.BZ|Any CPU.ActiveCfg = BZ|Any CPU + {6C883B28-31E6-4C26-B32B-BF5BE0D70190}.BZ|Any CPU.Build.0 = BZ|Any CPU {6C883B28-31E6-4C26-B32B-BF5BE0D70190}.Debug_Autosort|Any CPU.ActiveCfg = Release|Any CPU {6C883B28-31E6-4C26-B32B-BF5BE0D70190}.Debug_Autosort|Any CPU.Build.0 = Release|Any CPU {6C883B28-31E6-4C26-B32B-BF5BE0D70190}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6C883B28-31E6-4C26-B32B-BF5BE0D70190}.Debug|Any CPU.Build.0 = Debug|Any CPU {6C883B28-31E6-4C26-B32B-BF5BE0D70190}.Release|Any CPU.ActiveCfg = Release|Any CPU {6C883B28-31E6-4C26-B32B-BF5BE0D70190}.Release|Any CPU.Build.0 = Release|Any CPU + {6C883B28-31E6-4C26-B32B-BF5BE0D70190}.SN1|Any CPU.ActiveCfg = SN1|Any CPU + {6C883B28-31E6-4C26-B32B-BF5BE0D70190}.SN1|Any CPU.Build.0 = SN1|Any CPU + {B7752C03-C7BB-494F-BA52-9CD5EC649AA7}.BZ|Any CPU.ActiveCfg = BZ|Any CPU + {B7752C03-C7BB-494F-BA52-9CD5EC649AA7}.BZ|Any CPU.Build.0 = BZ|Any CPU {B7752C03-C7BB-494F-BA52-9CD5EC649AA7}.Debug_Autosort|Any CPU.ActiveCfg = Debug|Any CPU {B7752C03-C7BB-494F-BA52-9CD5EC649AA7}.Debug_Autosort|Any CPU.Build.0 = Debug|Any CPU {B7752C03-C7BB-494F-BA52-9CD5EC649AA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B7752C03-C7BB-494F-BA52-9CD5EC649AA7}.Debug|Any CPU.Build.0 = Debug|Any CPU {B7752C03-C7BB-494F-BA52-9CD5EC649AA7}.Release|Any CPU.ActiveCfg = Release|Any CPU {B7752C03-C7BB-494F-BA52-9CD5EC649AA7}.Release|Any CPU.Build.0 = Release|Any CPU + {B7752C03-C7BB-494F-BA52-9CD5EC649AA7}.SN1|Any CPU.ActiveCfg = SN1|Any CPU + {B7752C03-C7BB-494F-BA52-9CD5EC649AA7}.SN1|Any CPU.Build.0 = SN1|Any CPU + {829B1A80-D3B3-431A-A4B8-284C6B9DE226}.BZ|Any CPU.ActiveCfg = BZ|Any CPU + {829B1A80-D3B3-431A-A4B8-284C6B9DE226}.BZ|Any CPU.Build.0 = BZ|Any CPU {829B1A80-D3B3-431A-A4B8-284C6B9DE226}.Debug_Autosort|Any CPU.ActiveCfg = Debug|Any CPU {829B1A80-D3B3-431A-A4B8-284C6B9DE226}.Debug_Autosort|Any CPU.Build.0 = Debug|Any CPU {829B1A80-D3B3-431A-A4B8-284C6B9DE226}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {829B1A80-D3B3-431A-A4B8-284C6B9DE226}.Debug|Any CPU.Build.0 = Debug|Any CPU {829B1A80-D3B3-431A-A4B8-284C6B9DE226}.Release|Any CPU.ActiveCfg = Release|Any CPU {829B1A80-D3B3-431A-A4B8-284C6B9DE226}.Release|Any CPU.Build.0 = Release|Any CPU + {829B1A80-D3B3-431A-A4B8-284C6B9DE226}.SN1|Any CPU.ActiveCfg = SN1|Any CPU + {829B1A80-D3B3-431A-A4B8-284C6B9DE226}.SN1|Any CPU.Build.0 = SN1|Any CPU + {D9A802D6-AD51-4543-9903-0B90B1FA65AC}.BZ|Any CPU.ActiveCfg = BZ|Any CPU + {D9A802D6-AD51-4543-9903-0B90B1FA65AC}.BZ|Any CPU.Build.0 = BZ|Any CPU {D9A802D6-AD51-4543-9903-0B90B1FA65AC}.Debug_Autosort|Any CPU.ActiveCfg = Debug|Any CPU {D9A802D6-AD51-4543-9903-0B90B1FA65AC}.Debug_Autosort|Any CPU.Build.0 = Debug|Any CPU {D9A802D6-AD51-4543-9903-0B90B1FA65AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D9A802D6-AD51-4543-9903-0B90B1FA65AC}.Debug|Any CPU.Build.0 = Debug|Any CPU {D9A802D6-AD51-4543-9903-0B90B1FA65AC}.Release|Any CPU.ActiveCfg = Release|Any CPU {D9A802D6-AD51-4543-9903-0B90B1FA65AC}.Release|Any CPU.Build.0 = Release|Any CPU + {D9A802D6-AD51-4543-9903-0B90B1FA65AC}.SN1|Any CPU.ActiveCfg = SN1|Any CPU + {D9A802D6-AD51-4543-9903-0B90B1FA65AC}.SN1|Any CPU.Build.0 = SN1|Any CPU + {7E1DE3EC-3325-4F95-B306-616E1FA23B40}.BZ|Any CPU.ActiveCfg = BZ|Any CPU + {7E1DE3EC-3325-4F95-B306-616E1FA23B40}.BZ|Any CPU.Build.0 = BZ|Any CPU {7E1DE3EC-3325-4F95-B306-616E1FA23B40}.Debug_Autosort|Any CPU.ActiveCfg = Debug|Any CPU {7E1DE3EC-3325-4F95-B306-616E1FA23B40}.Debug_Autosort|Any CPU.Build.0 = Debug|Any CPU {7E1DE3EC-3325-4F95-B306-616E1FA23B40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7E1DE3EC-3325-4F95-B306-616E1FA23B40}.Debug|Any CPU.Build.0 = Debug|Any CPU {7E1DE3EC-3325-4F95-B306-616E1FA23B40}.Release|Any CPU.ActiveCfg = Release|Any CPU {7E1DE3EC-3325-4F95-B306-616E1FA23B40}.Release|Any CPU.Build.0 = Release|Any CPU + {7E1DE3EC-3325-4F95-B306-616E1FA23B40}.SN1|Any CPU.ActiveCfg = SN1|Any CPU + {7E1DE3EC-3325-4F95-B306-616E1FA23B40}.SN1|Any CPU.Build.0 = SN1|Any CPU + {F8A529A2-4CF8-4651-B0E8-B43B26C66753}.BZ|Any CPU.ActiveCfg = BZ|Any CPU + {F8A529A2-4CF8-4651-B0E8-B43B26C66753}.BZ|Any CPU.Build.0 = BZ|Any CPU {F8A529A2-4CF8-4651-B0E8-B43B26C66753}.Debug_Autosort|Any CPU.ActiveCfg = Debug|Any CPU {F8A529A2-4CF8-4651-B0E8-B43B26C66753}.Debug_Autosort|Any CPU.Build.0 = Debug|Any CPU {F8A529A2-4CF8-4651-B0E8-B43B26C66753}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F8A529A2-4CF8-4651-B0E8-B43B26C66753}.Debug|Any CPU.Build.0 = Debug|Any CPU {F8A529A2-4CF8-4651-B0E8-B43B26C66753}.Release|Any CPU.ActiveCfg = Release|Any CPU {F8A529A2-4CF8-4651-B0E8-B43B26C66753}.Release|Any CPU.Build.0 = Release|Any CPU + {F8A529A2-4CF8-4651-B0E8-B43B26C66753}.SN1|Any CPU.ActiveCfg = SN1|Any CPU + {F8A529A2-4CF8-4651-B0E8-B43B26C66753}.SN1|Any CPU.Build.0 = SN1|Any CPU + {1CC2A3A8-342F-4C3F-83C7-249882920D71}.BZ|Any CPU.ActiveCfg = BZ|Any CPU + {1CC2A3A8-342F-4C3F-83C7-249882920D71}.BZ|Any CPU.Build.0 = BZ|Any CPU {1CC2A3A8-342F-4C3F-83C7-249882920D71}.Debug_Autosort|Any CPU.ActiveCfg = Debug|Any CPU {1CC2A3A8-342F-4C3F-83C7-249882920D71}.Debug_Autosort|Any CPU.Build.0 = Debug|Any CPU {1CC2A3A8-342F-4C3F-83C7-249882920D71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1CC2A3A8-342F-4C3F-83C7-249882920D71}.Debug|Any CPU.Build.0 = Debug|Any CPU {1CC2A3A8-342F-4C3F-83C7-249882920D71}.Release|Any CPU.ActiveCfg = Release|Any CPU {1CC2A3A8-342F-4C3F-83C7-249882920D71}.Release|Any CPU.Build.0 = Release|Any CPU + {1CC2A3A8-342F-4C3F-83C7-249882920D71}.SN1|Any CPU.ActiveCfg = SN1|Any CPU + {1CC2A3A8-342F-4C3F-83C7-249882920D71}.SN1|Any CPU.Build.0 = SN1|Any CPU + {683A1124-D419-49F6-B602-60A803658315}.BZ|Any CPU.ActiveCfg = BZ|Any CPU + {683A1124-D419-49F6-B602-60A803658315}.BZ|Any CPU.Build.0 = BZ|Any CPU {683A1124-D419-49F6-B602-60A803658315}.Debug_Autosort|Any CPU.ActiveCfg = Debug|Any CPU {683A1124-D419-49F6-B602-60A803658315}.Debug_Autosort|Any CPU.Build.0 = Debug|Any CPU {683A1124-D419-49F6-B602-60A803658315}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {683A1124-D419-49F6-B602-60A803658315}.Debug|Any CPU.Build.0 = Debug|Any CPU {683A1124-D419-49F6-B602-60A803658315}.Release|Any CPU.ActiveCfg = Release|Any CPU {683A1124-D419-49F6-B602-60A803658315}.Release|Any CPU.Build.0 = Release|Any CPU + {683A1124-D419-49F6-B602-60A803658315}.SN1|Any CPU.ActiveCfg = SN1|Any CPU + {683A1124-D419-49F6-B602-60A803658315}.SN1|Any CPU.Build.0 = SN1|Any CPU + {667BF0BB-F5AB-446C-A6B3-3FAABB2F49D5}.BZ|Any CPU.ActiveCfg = BZ|Any CPU + {667BF0BB-F5AB-446C-A6B3-3FAABB2F49D5}.BZ|Any CPU.Build.0 = BZ|Any CPU {667BF0BB-F5AB-446C-A6B3-3FAABB2F49D5}.Debug_Autosort|Any CPU.ActiveCfg = Debug|Any CPU {667BF0BB-F5AB-446C-A6B3-3FAABB2F49D5}.Debug_Autosort|Any CPU.Build.0 = Debug|Any CPU {667BF0BB-F5AB-446C-A6B3-3FAABB2F49D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {667BF0BB-F5AB-446C-A6B3-3FAABB2F49D5}.Debug|Any CPU.Build.0 = Debug|Any CPU {667BF0BB-F5AB-446C-A6B3-3FAABB2F49D5}.Release|Any CPU.ActiveCfg = Release|Any CPU {667BF0BB-F5AB-446C-A6B3-3FAABB2F49D5}.Release|Any CPU.Build.0 = Release|Any CPU + {667BF0BB-F5AB-446C-A6B3-3FAABB2F49D5}.SN1|Any CPU.ActiveCfg = SN1|Any CPU + {667BF0BB-F5AB-446C-A6B3-3FAABB2F49D5}.SN1|Any CPU.Build.0 = SN1|Any CPU + {FD7B0BB5-6BCF-45B6-9145-10A8F0FEF277}.BZ|Any CPU.ActiveCfg = BZ|Any CPU + {FD7B0BB5-6BCF-45B6-9145-10A8F0FEF277}.BZ|Any CPU.Build.0 = BZ|Any CPU {FD7B0BB5-6BCF-45B6-9145-10A8F0FEF277}.Debug_Autosort|Any CPU.ActiveCfg = Debug|Any CPU {FD7B0BB5-6BCF-45B6-9145-10A8F0FEF277}.Debug_Autosort|Any CPU.Build.0 = Debug|Any CPU {FD7B0BB5-6BCF-45B6-9145-10A8F0FEF277}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {FD7B0BB5-6BCF-45B6-9145-10A8F0FEF277}.Debug|Any CPU.Build.0 = Debug|Any CPU {FD7B0BB5-6BCF-45B6-9145-10A8F0FEF277}.Release|Any CPU.ActiveCfg = Release|Any CPU {FD7B0BB5-6BCF-45B6-9145-10A8F0FEF277}.Release|Any CPU.Build.0 = Release|Any CPU + {FD7B0BB5-6BCF-45B6-9145-10A8F0FEF277}.SN1|Any CPU.ActiveCfg = SN1|Any CPU + {FD7B0BB5-6BCF-45B6-9145-10A8F0FEF277}.SN1|Any CPU.Build.0 = SN1|Any CPU + {03B89974-4EA6-4CD4-8C9F-C039EB81DE5F}.BZ|Any CPU.ActiveCfg = BZ|Any CPU + {03B89974-4EA6-4CD4-8C9F-C039EB81DE5F}.BZ|Any CPU.Build.0 = BZ|Any CPU {03B89974-4EA6-4CD4-8C9F-C039EB81DE5F}.Debug_Autosort|Any CPU.ActiveCfg = Debug|Any CPU {03B89974-4EA6-4CD4-8C9F-C039EB81DE5F}.Debug_Autosort|Any CPU.Build.0 = Debug|Any CPU {03B89974-4EA6-4CD4-8C9F-C039EB81DE5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {03B89974-4EA6-4CD4-8C9F-C039EB81DE5F}.Debug|Any CPU.Build.0 = Debug|Any CPU {03B89974-4EA6-4CD4-8C9F-C039EB81DE5F}.Release|Any CPU.ActiveCfg = Release|Any CPU {03B89974-4EA6-4CD4-8C9F-C039EB81DE5F}.Release|Any CPU.Build.0 = Release|Any CPU + {03B89974-4EA6-4CD4-8C9F-C039EB81DE5F}.SN1|Any CPU.ActiveCfg = SN1|Any CPU + {03B89974-4EA6-4CD4-8C9F-C039EB81DE5F}.SN1|Any CPU.Build.0 = SN1|Any CPU + {B4A7744B-F777-426C-94CD-1470B680B5B7}.BZ|Any CPU.ActiveCfg = BZ|Any CPU + {B4A7744B-F777-426C-94CD-1470B680B5B7}.BZ|Any CPU.Build.0 = BZ|Any CPU {B4A7744B-F777-426C-94CD-1470B680B5B7}.Debug_Autosort|Any CPU.ActiveCfg = Debug|Any CPU {B4A7744B-F777-426C-94CD-1470B680B5B7}.Debug_Autosort|Any CPU.Build.0 = Debug|Any CPU {B4A7744B-F777-426C-94CD-1470B680B5B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B4A7744B-F777-426C-94CD-1470B680B5B7}.Debug|Any CPU.Build.0 = Debug|Any CPU {B4A7744B-F777-426C-94CD-1470B680B5B7}.Release|Any CPU.ActiveCfg = Release|Any CPU {B4A7744B-F777-426C-94CD-1470B680B5B7}.Release|Any CPU.Build.0 = Release|Any CPU + {B4A7744B-F777-426C-94CD-1470B680B5B7}.SN1|Any CPU.ActiveCfg = SN1|Any CPU + {B4A7744B-F777-426C-94CD-1470B680B5B7}.SN1|Any CPU.Build.0 = SN1|Any CPU + {2EBF18DB-437E-4A9A-A03C-06770A3F9CB6}.BZ|Any CPU.ActiveCfg = BZ|Any CPU + {2EBF18DB-437E-4A9A-A03C-06770A3F9CB6}.BZ|Any CPU.Build.0 = BZ|Any CPU {2EBF18DB-437E-4A9A-A03C-06770A3F9CB6}.Debug_Autosort|Any CPU.ActiveCfg = Debug|Any CPU {2EBF18DB-437E-4A9A-A03C-06770A3F9CB6}.Debug_Autosort|Any CPU.Build.0 = Debug|Any CPU {2EBF18DB-437E-4A9A-A03C-06770A3F9CB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2EBF18DB-437E-4A9A-A03C-06770A3F9CB6}.Debug|Any CPU.Build.0 = Debug|Any CPU {2EBF18DB-437E-4A9A-A03C-06770A3F9CB6}.Release|Any CPU.ActiveCfg = Release|Any CPU {2EBF18DB-437E-4A9A-A03C-06770A3F9CB6}.Release|Any CPU.Build.0 = Release|Any CPU + {2EBF18DB-437E-4A9A-A03C-06770A3F9CB6}.SN1|Any CPU.ActiveCfg = SN1|Any CPU + {2EBF18DB-437E-4A9A-A03C-06770A3F9CB6}.SN1|Any CPU.Build.0 = SN1|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/SubnauticaModSystem/TorpedoImprovements/TorpedoImprovements.csproj b/SubnauticaModSystem/TorpedoImprovements/TorpedoImprovements.csproj index 46100b3..0ce7654 100644 --- a/SubnauticaModSystem/TorpedoImprovements/TorpedoImprovements.csproj +++ b/SubnauticaModSystem/TorpedoImprovements/TorpedoImprovements.csproj @@ -1,6 +1,7 @@  + Debug AnyCPU @@ -9,6 +10,7 @@ Properties TorpedoImprovements TorpedoImprovements + $(SolutionDir)$(AssemblyName)\$(Configuration)\ v4.7.1 512 @@ -35,25 +37,46 @@ Always + + BZ;BELOWZERO + true + true + $(CommonDir)SubnauticaZero.Stable + SubnauticaZero_Data + SMLHelper_BZ + AnyCPU + 7.1 + prompt + + + SN1;SUBNAUTICA_STABLE + true + true + $(CommonDir)Subnautica.Stable + Subnautica_Data + Modding Helper + AnyCPU + 7.1 + prompt + - - False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\0Harmony-1.2.0.1.dll + + $(GameDir)\BepInEx\core\0Harmony.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp-firstpass.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp-firstpass.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Newtonsoft.Json.dll + $(GameDir)\$(DataFolder)\Managed\NewtonSoft.Json.dll - D:\SteamLibrary\steamapps\common\Subnautica\QMods\Modding Helper\SMLHelper.dll + $(GameDir)\QMods\$(SMLHelperFolder)\SMLHelper.dll @@ -62,31 +85,31 @@ - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.CoreModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.CoreModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.ImageConversionModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.ImageConversionModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.JSONSerializeModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.JSONSerializeModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.PhysicsModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.PhysicsModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.TextRenderingModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.TextRenderingModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UI.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UI.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIElementsModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIElementsModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIModule.dll @@ -110,9 +133,9 @@ - xcopy $(TargetPath) D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)mod.json D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)Assets D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\Assets\ /q /y /i + xcopy $(TargetPath) $(GameDir)\QMods\$(ProjectName)\ /q /y +xcopy $(ProjectDir)mod.json $(GameDir)\QMods\$(ProjectName)\ /q /y +xcopy $(ProjectDir)Assets $(GameDir)\QMods\$(ProjectName)\Assets\ /q /y /i xcopy $(TargetPath) D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y xcopy $(ProjectDir)mod.json D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y diff --git a/SubnauticaModSystem/WhiteLights/WhiteLights.csproj b/SubnauticaModSystem/WhiteLights/WhiteLights.csproj index 1f3a272..98f3ec7 100644 --- a/SubnauticaModSystem/WhiteLights/WhiteLights.csproj +++ b/SubnauticaModSystem/WhiteLights/WhiteLights.csproj @@ -1,6 +1,7 @@  + Debug AnyCPU @@ -9,6 +10,7 @@ Properties WhiteLights WhiteLights + $(SolutionDir)$(AssemblyName)\$(Configuration)\ v4.7.1 512 @@ -35,24 +37,46 @@ Always + + BZ;BELOWZERO + true + true + $(CommonDir)SubnauticaZero.Stable + SubnauticaZero_Data + SMLHelper_BZ + AnyCPU + 7.1 + prompt + + + SN1;SUBNAUTICA_STABLE + true + true + $(CommonDir)Subnautica.Stable + Subnautica_Data + Modding Helper + AnyCPU + 7.1 + prompt + - - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\0Harmony-1.2.0.1.dll + + $(GameDir)\BepInEx\core\0Harmony.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp-firstpass.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp-firstpass.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Newtonsoft.Json.dll + $(GameDir)\$(DataFolder)\Managed\NewtonSoft.Json.dll - D:\SteamLibrary\steamapps\common\Subnautica\QMods\Modding Helper\SMLHelper.dll + $(GameDir)\QMods\$(SMLHelperFolder)\SMLHelper.dll @@ -61,28 +85,28 @@ - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.CoreModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.CoreModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.ImageConversionModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.ImageConversionModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.JSONSerializeModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.JSONSerializeModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.TextRenderingModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.TextRenderingModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UI.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UI.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIElementsModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIElementsModule.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UIModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIModule.dll @@ -103,9 +127,9 @@ - xcopy $(TargetPath) D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)mod.json D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)Assets D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\Assets\ /q /y /i + xcopy $(TargetPath) $(GameDir)\QMods\$(ProjectName)\ /q /y +xcopy $(ProjectDir)mod.json $(GameDir)\QMods\$(ProjectName)\ /q /y +xcopy $(ProjectDir)Assets $(GameDir)\QMods\$(ProjectName)\Assets\ /q /y /i xcopy $(TargetPath) D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y xcopy $(ProjectDir)mod.json D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y diff --git a/SubnauticaModSystem/zzzEnableConsole/zzzEnableConsole.csproj b/SubnauticaModSystem/zzzEnableConsole/zzzEnableConsole.csproj index 87262bb..0038d87 100644 --- a/SubnauticaModSystem/zzzEnableConsole/zzzEnableConsole.csproj +++ b/SubnauticaModSystem/zzzEnableConsole/zzzEnableConsole.csproj @@ -1,6 +1,7 @@  + Debug AnyCPU @@ -9,6 +10,7 @@ Properties zzzEnableConsole zzzEnableConsole + $(SolutionDir)$(AssemblyName)\$(Configuration)\ v4.7.1 512 @@ -35,13 +37,35 @@ Always + + BZ;BELOWZERO + true + true + $(CommonDir)SubnauticaZero.Stable + SubnauticaZero_Data + SMLHelper_BZ + AnyCPU + 7.1 + prompt + + + SN1;SUBNAUTICA_STABLE + true + true + $(CommonDir)Subnautica.Stable + Subnautica_Data + Modding Helper + AnyCPU + 7.1 + prompt + - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\0Harmony.dll + $(GameDir)\$(DataFolder)\Managed\0Harmony.dll False - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\Assembly-CSharp.dll + $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp.dll @@ -50,10 +74,10 @@ - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.dll - D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UI.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.UI.dll @@ -77,8 +101,8 @@ - xcopy $(TargetPath) D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)mod.json D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\ /q /y + xcopy $(TargetPath) $(GameDir)\QMods\$(ProjectName)\ /q /y +xcopy $(ProjectDir)mod.json $(GameDir)\QMods\$(ProjectName)\ /q /y xcopy $(TargetPath) D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y xcopy $(ProjectDir)mod.json D:\\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y From 3da41265b13ca09cbc85e6b3fa887c166129ae93 Mon Sep 17 00:00:00 2001 From: DaWrecka <61927940+DaWrecka@users.noreply.github.com> Date: Sun, 31 Jan 2021 20:12:06 +0000 Subject: [PATCH 02/11] Now instantiating GameObjects, oops --- .../AutosortLockers/AutosortLocker.cs | 33 ++++++- .../AutosortLockers/AutosortLockersSML.csproj | 4 + .../AutosortLockers/AutosortTarget.cs | 81 ++++++++++++++---- .../AutosortLockers/AutosortTypePicker.cs | 24 +++++- .../AutosortLockers/ColorPicker.cs | 5 +- .../AutosortLockers/ColorSetting.cs | 18 +++- .../AutosortLockers/ColoredIconButton.cs | 24 +++++- .../AutosortLockers/CustomizeScreen.cs | 48 +++++++++-- .../AutosortLockers/LabelController.cs | 20 ++++- SubnauticaModSystem/AutosortLockers/Mod.cs | 2 + SubnauticaModSystem/AutosortLockers/Picker.cs | 16 +++- .../AutosortLockers/PickerButton.cs | 22 ++++- .../BZ/AutosortLockersSML.dll | Bin 75264 -> 79872 bytes .../Common/Mod/LockerPrefabShared.cs | 14 ++- 14 files changed, 267 insertions(+), 44 deletions(-) diff --git a/SubnauticaModSystem/AutosortLockers/AutosortLocker.cs b/SubnauticaModSystem/AutosortLockers/AutosortLocker.cs index 2eab9f3..5563f6e 100644 --- a/SubnauticaModSystem/AutosortLockers/AutosortLocker.cs +++ b/SubnauticaModSystem/AutosortLockers/AutosortLocker.cs @@ -11,6 +11,8 @@ #if SUBNAUTICA using RecipeData = SMLHelper.V2.Crafting.TechData; using Sprite = Atlas.Sprite; +#elif BELOWZERO + using TMPro; #endif @@ -34,10 +36,17 @@ public class AutosortLocker : MonoBehaviour private Image background; [SerializeField] private Image icon; +#if SUBNAUTICA [SerializeField] private Text text; [SerializeField] private Text sortingText; +#elif BELOWZERO + [SerializeField] + private TextMeshProUGUI text; + [SerializeField] + private TextMeshProUGUI sortingText; +#endif [SerializeField] private bool isSorting; [SerializeField] @@ -350,46 +359,64 @@ public override GameObject GetGameObject() public override IEnumerator GetGameObjectAsync(IOut gameObject) { + Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 1"); CoroutineTask task = CraftData.GetPrefabForTechTypeAsync(TechType.SmallLocker); yield return task; //GameObject originalPrefab = CraftData.GetPrefabForTechType(TechType.SmallLocker); - //GameObject prefab = GameObject.Instantiate(originalPrefab); - GameObject prefab = task.GetResult(); + Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 2"); + GameObject originalPrefab = task.GetResult(); + GameObject prefab = GameObject.Instantiate(originalPrefab); + Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 3"); if (prefab == null) QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"AutosortLockerBuildable.GetGameObjectAsync(): prefab == null"); + Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 4"); var container = prefab.GetComponent(); container.width = Mod.config.AutosorterWidth; container.height = Mod.config.AutosorterHeight; container.container.Resize(Mod.config.AutosorterWidth, Mod.config.AutosorterHeight); + Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 5"); var meshRenderers = prefab.GetComponentsInChildren(); foreach (var meshRenderer in meshRenderers) { meshRenderer.material.color = new Color(1, 0, 0); } - var prefabText = prefab.GetComponentInChildren(); + Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 6"); + var prefabText = prefab.GetComponentInChildren(); var label = prefab.FindChild("Label"); DestroyImmediate(label); + Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 7"); var autoSorter = prefab.AddComponent(); + Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 8"); var canvas = LockerPrefabShared.CreateCanvas(prefab.transform); + Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 8.1"); autoSorter.background = LockerPrefabShared.CreateBackground(canvas.transform); + Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 8.2"); autoSorter.icon = LockerPrefabShared.CreateIcon(autoSorter.background.transform, MainColor, 40); + Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 8.3: prefabText " + (prefabText == null ? "is" : "is not") + " null"); autoSorter.text = LockerPrefabShared.CreateText(autoSorter.background.transform, prefabText, MainColor, 0, 14, "Autosorter"); + Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 9"); autoSorter.sortingText = LockerPrefabShared.CreateText(autoSorter.background.transform, prefabText, MainColor, -120, 12, "Sorting..."); +#if SUBNAUTICA autoSorter.sortingText.alignment = TextAnchor.UpperCenter; +#elif BELOWZERO + autoSorter.sortingText.alignment = TextAlignmentOptions.Top; +#endif + Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 10"); autoSorter.background.gameObject.SetActive(false); autoSorter.icon.gameObject.SetActive(false); autoSorter.text.gameObject.SetActive(false); autoSorter.sortingText.gameObject.SetActive(false); + Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 11"); //return prefab; gameObject.Set(prefab); yield break; diff --git a/SubnauticaModSystem/AutosortLockers/AutosortLockersSML.csproj b/SubnauticaModSystem/AutosortLockers/AutosortLockersSML.csproj index d1d093a..4755ee8 100644 --- a/SubnauticaModSystem/AutosortLockers/AutosortLockersSML.csproj +++ b/SubnauticaModSystem/AutosortLockers/AutosortLockersSML.csproj @@ -133,6 +133,10 @@ $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIModule.dll False + + $(GameDir)\$(DataFolder)\Managed\Unity.TextMeshPro.dll + False + diff --git a/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs b/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs index 6a566b3..750b445 100644 --- a/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs +++ b/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs @@ -7,9 +7,12 @@ using SMLHelper.V2.Crafting; using UnityEngine; using UnityEngine.UI; +using UWE; #if SUBNAUTICA using RecipeData = SMLHelper.V2.Crafting.TechData; using Sprite = Atlas.Sprite; +#elif BELOWZERO +using TMPro; #endif namespace AutosortLockers @@ -27,8 +30,29 @@ public class AutosortTarget : MonoBehaviour private Coroutine plusCoroutine; private SaveDataEntry saveData; +#if SUBNAUTICA [SerializeField] private Text textPrefab; + [SerializeField] + private Text text; + [SerializeField] + private Text label; + [SerializeField] + private Text plus; + [SerializeField] + private Text quantityText; +#elif BELOWZERO + [SerializeField] + private TextMeshProUGUI textPrefab; + [SerializeField] + private TextMeshProUGUI text; + [SerializeField] + private TextMeshProUGUI label; + [SerializeField] + private TextMeshProUGUI plus; + [SerializeField] + private TextMeshProUGUI quantityText; +#endif [SerializeField] private Image background; [SerializeField] @@ -42,14 +66,6 @@ public class AutosortTarget : MonoBehaviour [SerializeField] private Image customizeButtonImage; [SerializeField] - private Text text; - [SerializeField] - private Text label; - [SerializeField] - private Text plus; - [SerializeField] - private Text quantityText; - [SerializeField] private List currentFilters = new List(); private void Awake() @@ -374,10 +390,28 @@ private void Initialize() UpdateText(); + // Moved to FinalSetup + //CreatePicker(); + //CreateCustomizeScreen(); + StartCoroutine("FinalSetup"); + initialized = true; + } + + internal bool bPrefabsLoaded = false; + internal GameObject lockerPrefab; + + private IEnumerator FinalSetup() + { + IPrefabRequest request = PrefabDatabase.GetPrefabForFilenameAsync("Submarine/Build/SmallLocker.prefab"); + yield return request; + request.TryGetPrefab(out GameObject prefab); + lockerPrefab = prefab; + bPrefabsLoaded = true; + CreatePicker(); CreateCustomizeScreen(); - initialized = true; + yield break; } private void InitializeFromSaveData() @@ -476,7 +510,7 @@ private void CreatePicker() private void CreateCustomizeScreen() { - customizeScreen = CustomizeScreen.Create(background.transform, saveData); + customizeScreen = CustomizeScreen.Create(background.transform, saveData, lockerPrefab); customizeScreen.onModified += InitializeFromSaveData; customizeScreen.Initialize(saveData); customizeScreen.gameObject.SetActive(false); @@ -540,19 +574,26 @@ public AutosortTargetBuildable() public override IEnumerator GetGameObjectAsync(IOut gameObject) { + Logger.Log("AutosortTargetBuildable.GetGameObjectAsync: 1"); //var prefab = GetPrefab(TechType.Locker); TaskResult result = new TaskResult(); yield return GetPrefabAsync(TechType.Locker, result); - GameObject prefab = result.Get(); + Logger.Log("AutosortTargetBuildable.GetGameObjectAsync: 2"); + GameObject basePrefab = result.Get(); + GameObject prefab = GameObject.Instantiate(basePrefab); + + + Logger.Log("AutosortTargetBuildable.GetGameObjectAsync: 3"); StorageContainer container = prefab.GetComponent(); container.width = Mod.config.ReceptacleWidth; container.height = Mod.config.ReceptacleHeight; container.container.Resize(Mod.config.ReceptacleWidth, Mod.config.ReceptacleHeight); + Logger.Log("AutosortTargetBuildable.GetGameObjectAsync: 4"); gameObject.Set(prefab); + prefab.SetActive(false); yield break; - //return prefab; } protected override RecipeData GetBlueprintRecipe() @@ -597,7 +638,8 @@ public override IEnumerator GetGameObjectAsync(IOut gameObject) //var prefab = GetPrefab(TechType.Locker); TaskResult result = new TaskResult(); yield return GetPrefabAsync(TechType.Locker, result); - GameObject prefab = result.Get(); + GameObject basePrefab = result.Get(); + GameObject prefab = GameObject.Instantiate(basePrefab); var container = prefab.GetComponent(); container.width = Mod.config.StandingReceptacleWidth; @@ -606,7 +648,6 @@ public override IEnumerator GetGameObjectAsync(IOut gameObject) gameObject.Set(prefab); yield break; - //return prefab; } protected override RecipeData GetBlueprintRecipe() @@ -647,10 +688,11 @@ public static void AddBuildable() public static IEnumerator GetPrefabAsync(TechType basePrefab, IOut gameObject) { + Logger.Log($"GetPrefabAsync() executing for basePrefab TechType.{basePrefab.AsString()}"); CoroutineTask task = CraftData.GetPrefabForTechTypeAsync(basePrefab); yield return task; - GameObject originalPrefab = task.GetResult();//CraftData.GetPrefabForTechType(basePrefab); + GameObject originalPrefab = task.GetResult(); GameObject prefab = GameObject.Instantiate(originalPrefab); var meshRenderers = prefab.GetComponentsInChildren(); @@ -664,8 +706,15 @@ public static IEnumerator GetPrefabAsync(TechType basePrefab, IOut g task = CraftData.GetPrefabForTechTypeAsync(TechType.SmallLocker); yield return task; //var smallLockerPrefab = CraftData.GetPrefabForTechType(TechType.SmallLocker); - var smallLockerPrefab = task.GetResult(); + + Logger.Log($"GetPrefabAsync() attempting to instantiate smallLockerPrefab"); + var smallLockerPrefab = GameObject.Instantiate(task.GetResult()); + Logger.Log($"GetPrefabAsync() attempting to instantiate autosortTarget; smallLockerPrefab " + (smallLockerPrefab == null ? "is" : "is not") + " null"); +#if SUBNAUTICA autosortTarget.textPrefab = GameObject.Instantiate(smallLockerPrefab.GetComponentInChildren()); +#elif BELOWZERO + autosortTarget.textPrefab = GameObject.Instantiate(smallLockerPrefab.GetComponentInChildren()); +#endif var label = prefab.FindChild("Label"); DestroyImmediate(label); diff --git a/SubnauticaModSystem/AutosortLockers/AutosortTypePicker.cs b/SubnauticaModSystem/AutosortLockers/AutosortTypePicker.cs index 6c70d0d..3290a73 100644 --- a/SubnauticaModSystem/AutosortLockers/AutosortTypePicker.cs +++ b/SubnauticaModSystem/AutosortLockers/AutosortTypePicker.cs @@ -3,6 +3,9 @@ using System.Linq; using Common.Mod; using Common.Utility; +#if BELOWZERO + using TMPro; +#endif using UnityEngine; using UnityEngine.UI; @@ -29,8 +32,13 @@ private enum Mode { Categories, Items } private Image[] underlines = new Image[2]; [SerializeField] private PickerCloseButton closeButton; +#if SUBNAUTICA [SerializeField] private Text pageText; +#elif BELOWZERO + [SerializeField] + private TextMeshProUGUI pageText; +#endif [SerializeField] private PickerPageButton prevPageButton; [SerializeField] @@ -167,7 +175,13 @@ private void SetCurrentPage(int page) - public static AutosortTypePicker Create(Transform parent, Text textPrefab) + public static AutosortTypePicker Create(Transform parent, +#if SUBNAUTICA + Text textPrefab +#elif BELOWZERO + TextMeshProUGUI textPrefab +#endif + ) { var picker = LockerPrefabShared.CreateCanvas(parent).gameObject.AddComponent(); picker.GetComponent().sortingLayerID = 0; @@ -253,7 +267,13 @@ public static PickerCloseButton AddCloseButton(Transform parent) return closeButton; } - public static PickerButton CreatePickerButton(Transform parent, int x, int y, Text textPrefab, Action action, int width = 100) + public static PickerButton CreatePickerButton(Transform parent, int x, int y, +#if SUBNAUTICA + Text textPrefab, +#elif BELOWZERO + TextMeshProUGUI textPrefab, +#endif + Action action, int width = 100) { var button = PickerButton.Create(parent, textPrefab, action, width); diff --git a/SubnauticaModSystem/AutosortLockers/ColorPicker.cs b/SubnauticaModSystem/AutosortLockers/ColorPicker.cs index 2889211..ae86d78 100644 --- a/SubnauticaModSystem/AutosortLockers/ColorPicker.cs +++ b/SubnauticaModSystem/AutosortLockers/ColorPicker.cs @@ -54,7 +54,7 @@ public override void Open() /////////////////////////////////////////////////////////////////////////////////////////////////////////////// - public static ColorPicker Create(Transform parent) + public static ColorPicker Create(Transform parent, GameObject lockerPrefab = null) { var beaconColorPicker = new GameObject("ColorPicker", typeof(RectTransform)).AddComponent(); @@ -63,8 +63,7 @@ public static ColorPicker Create(Transform parent) beaconColorPicker.ButtonsPerPage = 72; beaconColorPicker.ButtonsPerRow = 8; - Picker.Create(parent, beaconColorPicker, Mod.colors.Count); - + Picker.Create(parent, beaconColorPicker, Mod.colors.Count, lockerPrefab); return beaconColorPicker; } } diff --git a/SubnauticaModSystem/AutosortLockers/ColorSetting.cs b/SubnauticaModSystem/AutosortLockers/ColorSetting.cs index bf727f2..3085754 100644 --- a/SubnauticaModSystem/AutosortLockers/ColorSetting.cs +++ b/SubnauticaModSystem/AutosortLockers/ColorSetting.cs @@ -5,6 +5,9 @@ using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; +#if BELOWZERO +using TMPro; +#endif namespace AutosortLockers { @@ -21,11 +24,18 @@ private void Awake() rectTransform = transform as RectTransform; } +#if SUBNAUTICA private void Initialize(Text textPrefab, string label) { activeButton = ColoredIconButton.Create(transform, CustomizeScreen.ScreenContentColor, textPrefab, label, 100, 15); activeButton.text.supportRichText = true; } +#elif BELOWZERO + private void Initialize(TextMeshProUGUI textPrefab, string label) + { + activeButton = ColoredIconButton.Create(transform, CustomizeScreen.ScreenContentColor, textPrefab, label, 100, 15); + } +#endif internal void SetInitialValue(Color initialColor) { @@ -45,10 +55,14 @@ private void OnClick() /////////////////////////////////////////////////////////////////////////////////////////// - public static ColorSetting Create(Transform parent, string label) + public static ColorSetting Create(Transform parent, string label, GameObject lockerPrefab = null) { - var lockerPrefab = Resources.Load("Submarine/Build/SmallLocker"); +#if SUBNAUTICA + lockerPrefab = Resources.Load("Submarine/Build/SmallLocker"); var textPrefab = Instantiate(lockerPrefab.GetComponentInChildren()); +#elif BELOWZERO + var textPrefab = Instantiate(lockerPrefab.GetComponentInChildren()); +#endif textPrefab.fontSize = 12; textPrefab.color = new Color32(66, 134, 244, 255); diff --git a/SubnauticaModSystem/AutosortLockers/ColoredIconButton.cs b/SubnauticaModSystem/AutosortLockers/ColoredIconButton.cs index a453539..9028604 100644 --- a/SubnauticaModSystem/AutosortLockers/ColoredIconButton.cs +++ b/SubnauticaModSystem/AutosortLockers/ColoredIconButton.cs @@ -8,6 +8,10 @@ using UnityEngine.EventSystems; using UnityEngine.UI; +#if BELOWZERO +using TMPro; +#endif + namespace AutosortLockers { public class ColoredIconButton : MonoBehaviour, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler @@ -23,7 +27,11 @@ public class ColoredIconButton : MonoBehaviour, IPointerClickHandler, IPointerEn public Color imageColor; public Image image; +#if SUBNAUTICA public Text text; +#elif BELOWZERO + public TextMeshProUGUI text; +#endif public Action onClick = delegate { }; private Color imageDisabledColor; @@ -89,7 +97,13 @@ public void OnPointerUp(PointerEventData eventData) ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - public static ColoredIconButton Create(Transform parent, Color color, Text textPrefab = null, string label = "", float width = 100, float iconWidth = 20) + public static ColoredIconButton Create(Transform parent, Color color, +#if SUBNAUTICA + Text textPrefab = null, +#elif BELOWZERO + TextMeshProUGUI textPrefab = null, +#endif + string label = "", float width = 100, float iconWidth = 20) { var checkboxButton = new GameObject("Checkbox", typeof(RectTransform)); var rt = checkboxButton.transform as RectTransform; @@ -101,14 +115,22 @@ public static ColoredIconButton Create(Transform parent, Color color, Text textP RectTransformExtensions.SetSize(checkbox.rectTransform, iconWidth, iconWidth); checkbox.rectTransform.anchoredPosition = new Vector2(textPrefab != null ? - width / 2 + 10 : 0, 0); +#if SUBNAUTICA Text text = null; +#elif BELOWZERO + TextMeshProUGUI text = null; +#endif if (textPrefab != null) { var spacing = 5; text = LockerPrefabShared.CreateText(rt, textPrefab, color, 0, 10, label); RectTransformExtensions.SetSize(text.rectTransform, width - 20 - spacing, 20); text.rectTransform.anchoredPosition = new Vector2(10 + spacing, 0); +#if SUBNAUTICA text.alignment = TextAnchor.MiddleLeft; +#elif BELOWZERO + text.alignment = TextAlignmentOptions.MidlineLeft; +#endif } checkboxButton.AddComponent(); diff --git a/SubnauticaModSystem/AutosortLockers/CustomizeScreen.cs b/SubnauticaModSystem/AutosortLockers/CustomizeScreen.cs index 09debf6..414d4c0 100644 --- a/SubnauticaModSystem/AutosortLockers/CustomizeScreen.cs +++ b/SubnauticaModSystem/AutosortLockers/CustomizeScreen.cs @@ -6,6 +6,11 @@ using System.Text; using UnityEngine; using UnityEngine.UI; +using UWE; +using System.Collections; +#if BELOWZERO +using TMPro; +#endif namespace AutosortLockers { @@ -20,7 +25,11 @@ class CustomizeScreen : MonoBehaviour [SerializeField] private Image background; [SerializeField] +#if SUBNAUTICA private Text labelLabel; +#elif BELOWZERO + private TextMeshProUGUI labelLabel; +#endif [SerializeField] private LabelController label; [SerializeField] @@ -174,49 +183,70 @@ private void OnLockerColorPicked(int index) ////////////////////////////////////////////////////////////////////////////////////////////////////////////// - public static CustomizeScreen Create(Transform parent, SaveDataEntry data) + public static CustomizeScreen Create(Transform parent, SaveDataEntry data, GameObject lockerPrefab = null) { - var lockerPrefab = Resources.Load("Submarine/Build/SmallLocker"); + Logger.Log("CustomiseScreen.Create: 1"); +#if SUBNAUTICA + lockerPrefab = Resources.Load("Submarine/Build/SmallLocker"); var textPrefab = Instantiate(lockerPrefab.GetComponentInChildren()); +#elif BELOWZERO + var textPrefab = Instantiate(lockerPrefab.GetComponentInChildren()); +#endif + Logger.Log("CustomiseScreen.Create: 2"); textPrefab.fontSize = 12; textPrefab.color = CustomizeScreen.ScreenContentColor; + Logger.Log("CustomiseScreen.Create: 3"); var screen = new GameObject("CustomizeScreen", typeof(RectTransform)).AddComponent(); RectTransformExtensions.SetParams(screen.rectTransform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), parent); RectTransformExtensions.SetSize(screen.rectTransform, 114, 241); + Logger.Log("CustomiseScreen.Create: 4"); screen.background = new GameObject("Background").AddComponent(); screen.background.sprite = ImageUtils.LoadSprite(Mod.GetAssetPath("CustomizeScreen.png")); RectTransformExtensions.SetParams(screen.background.rectTransform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), screen.transform); RectTransformExtensions.SetSize(screen.background.rectTransform, 114, 241); + Logger.Log("CustomiseScreen.Create: 5"); screen.labelLabel = LockerPrefabShared.CreateText(screen.background.transform, textPrefab, ScreenContentColor, 100, 9, "Label:"); RectTransformExtensions.SetSize(screen.labelLabel.rectTransform, 90, 40); +#if SUBNAUTICA screen.labelLabel.alignment = TextAnchor.MiddleLeft; +#elif BELOWZERO + screen.labelLabel.alignment = TextAlignmentOptions.MidlineLeft; +#endif - screen.label = LabelController.Create(data, screen.background.transform); + Logger.Log("CustomiseScreen.Create: 6"); + screen.label = LabelController.Create(data, screen.background.transform, lockerPrefab); screen.label.rectTransform.anchoredPosition = new Vector2(0, 80); + Logger.Log("CustomiseScreen.Create: 7"); screen.exitButton = ConfigureButton.Create(screen.background.transform, Color.white, 40); var startX = 0; var startY = 30; - screen.labelColorSetting = ColorSetting.Create(screen.background.transform, "Label Color"); + Logger.Log("CustomiseScreen.Create: 8"); + screen.labelColorSetting = ColorSetting.Create(screen.background.transform, "Label Color", lockerPrefab); screen.labelColorSetting.rectTransform.anchoredPosition = new Vector2(startX, startY); - screen.iconColorSetting = ColorSetting.Create(screen.background.transform, "Icon Color"); + Logger.Log("CustomiseScreen.Create: 9"); + screen.iconColorSetting = ColorSetting.Create(screen.background.transform, "Icon Color", lockerPrefab); screen.iconColorSetting.rectTransform.anchoredPosition = new Vector2(startX, startY - 19); - screen.textColorSetting = ColorSetting.Create(screen.background.transform, "Filters Color"); + Logger.Log("CustomiseScreen.Create: 10"); + screen.textColorSetting = ColorSetting.Create(screen.background.transform, "Filters Color", lockerPrefab); screen.textColorSetting.rectTransform.anchoredPosition = new Vector2(startX, startY - (19 * 2)); - screen.buttonsColorSetting = ColorSetting.Create(screen.background.transform, "Misc Color"); + Logger.Log("CustomiseScreen.Create: 11"); + screen.buttonsColorSetting = ColorSetting.Create(screen.background.transform, "Misc Color", lockerPrefab); screen.buttonsColorSetting.rectTransform.anchoredPosition = new Vector2(startX, startY - (19 * 3)); - screen.lockerColorSetting = ColorSetting.Create(screen.background.transform, "Locker Color"); + Logger.Log("CustomiseScreen.Create: 12"); + screen.lockerColorSetting = ColorSetting.Create(screen.background.transform, "Locker Color", lockerPrefab); screen.lockerColorSetting.rectTransform.anchoredPosition = new Vector2(startX, startY - (19 * 4)); - screen.colorPicker = ColorPicker.Create(screen.background.transform); + Logger.Log("CustomiseScreen.Create: 13"); + screen.colorPicker = ColorPicker.Create(screen.background.transform, lockerPrefab); screen.colorPicker.gameObject.SetActive(false); screen.colorPicker.rectTransform.anchoredPosition = new Vector2(0, 30); diff --git a/SubnauticaModSystem/AutosortLockers/LabelController.cs b/SubnauticaModSystem/AutosortLockers/LabelController.cs index b91cb02..5426f78 100644 --- a/SubnauticaModSystem/AutosortLockers/LabelController.cs +++ b/SubnauticaModSystem/AutosortLockers/LabelController.cs @@ -5,6 +5,9 @@ using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; +#if BELOWZERO +using TMPro; +#endif namespace AutosortLockers { @@ -14,7 +17,11 @@ class LabelController : MonoBehaviour, IPointerClickHandler, IPointerEnterHandle public RectTransform rectTransform; public Action onModified = delegate { }; +#if SUBNAUTICA public Text text; +#elif BELOWZERO + public TextMeshProUGUI text; +#endif [SerializeField] private SaveDataEntry target; @@ -24,7 +31,11 @@ private void Awake() rectTransform = transform as RectTransform; } +#if SUBNAUTICA private void Initialize(SaveDataEntry data, Text textPrefab) +#elif BELOWZERO + private void Initialize(SaveDataEntry data, TextMeshProUGUI textPrefab) +#endif { target = data; @@ -76,10 +87,13 @@ private void Update() /////////////////////////////////////////////////////////////////////////////////////////// - public static LabelController Create(SaveDataEntry data, Transform parent) + public static LabelController Create(SaveDataEntry data, Transform parent, GameObject lockerPrefab = null) { - var lockerPrefab = Resources.Load("Submarine/Build/SmallLocker"); - var textPrefab = Instantiate(lockerPrefab.GetComponentInChildren()); +#if SUBNAUTICA + lockerPrefab = Resources.Load("Submarine/Build/SmallLocker"); +#elif BELOWZERO + var textPrefab = Instantiate(lockerPrefab.GetComponentInChildren()); +#endif textPrefab.fontSize = 12; textPrefab.color = CustomizeScreen.ScreenContentColor; diff --git a/SubnauticaModSystem/AutosortLockers/Mod.cs b/SubnauticaModSystem/AutosortLockers/Mod.cs index 7ef0a03..a3efabc 100644 --- a/SubnauticaModSystem/AutosortLockers/Mod.cs +++ b/SubnauticaModSystem/AutosortLockers/Mod.cs @@ -11,6 +11,7 @@ using Newtonsoft.Json; #endif using UnityEngine; +using UWE; namespace AutosortLockers { @@ -26,6 +27,7 @@ internal static class Mod public static event Action OnDataLoaded; + internal static GameObject lockerPrefab; public static void Patch(string modDirectory = null) { Logger.Log("Starting patching"); diff --git a/SubnauticaModSystem/AutosortLockers/Picker.cs b/SubnauticaModSystem/AutosortLockers/Picker.cs index 7e75d8b..6e73b24 100644 --- a/SubnauticaModSystem/AutosortLockers/Picker.cs +++ b/SubnauticaModSystem/AutosortLockers/Picker.cs @@ -6,6 +6,9 @@ using System.Text; using UnityEngine; using UnityEngine.UI; +#if BELOWZERO + using TMPro; +#endif namespace AutosortLockers { @@ -32,7 +35,11 @@ class Picker : MonoBehaviour [SerializeField] private ColorPickerPageButton nextPageButton; [SerializeField] +#if SUBNAUTICA private Text pageText; +#elif BELOWZERO + private TextMeshProUGUI pageText; +#endif [SerializeField] protected List buttons = new List(); @@ -171,10 +178,15 @@ public void Close() /////////////////////////////////////////////////////////////////////////////////////////////////////// - protected static void Create(Transform parent, Picker instance, int buttonCount) + + protected static void Create(Transform parent, Picker instance, int buttonCount, GameObject lockerPrefab = null) { - var lockerPrefab = Resources.Load("Submarine/Build/SmallLocker"); +#if SUBNAUTICA + lockerPrefab = Resources.Load("Submarine/Build/SmallLocker"); var textPrefab = Instantiate(lockerPrefab.GetComponentInChildren()); +#elif BELOWZERO + var textPrefab = Instantiate(lockerPrefab.GetComponentInChildren()); +#endif textPrefab.fontSize = 16; textPrefab.color = ScreenContentColor; diff --git a/SubnauticaModSystem/AutosortLockers/PickerButton.cs b/SubnauticaModSystem/AutosortLockers/PickerButton.cs index 5c9f294..88ea9e5 100644 --- a/SubnauticaModSystem/AutosortLockers/PickerButton.cs +++ b/SubnauticaModSystem/AutosortLockers/PickerButton.cs @@ -6,6 +6,9 @@ using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; +#if BELOWZERO + using TMPro; +#endif namespace AutosortLockers { @@ -26,7 +29,11 @@ public class PickerButton : MonoBehaviour, IPointerClickHandler, IPointerEnterHa [SerializeField] private Image background; [SerializeField] +#if SUBNAUTICA private Text text; +#elif BELOWZERO + private TextMeshProUGUI text; +#endif public AutosorterFilter GetTechType() { @@ -99,7 +106,13 @@ public void SetTabActive(bool active) - public static PickerButton Create(Transform parent, Text textPrefab, Action action, int width = 100, int height = 18) + public static PickerButton Create(Transform parent, +#if SUBNAUTICA + Text textPrefab, +#elif BELOWZERO + TextMeshProUGUI textPrefab, +#endif + Action action, int width = 100, int height = 18) { var button = new GameObject("PickerButton", typeof(RectTransform)).AddComponent(); button.transform.SetParent(parent, false); @@ -112,13 +125,18 @@ public static PickerButton Create(Transform parent, Text textPrefab, Action(); + button.text.alignment = TextAnchor.MiddleCenter; +#elif BELOWZERO + button.text = new GameObject("TextMeshProUGUI", typeof(RectTransform)).AddComponent(); + button.text.alignment = TextAlignmentOptions.Center; +#endif RectTransformExtensions.SetParams(button.text.rectTransform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), button.transform); RectTransformExtensions.SetSize(button.text.rectTransform, width, height); button.text.color = new Color(1, 1, 1); button.text.font = textPrefab.font; button.text.fontSize = 10; - button.text.alignment = TextAnchor.MiddleCenter; button.onClick += action; diff --git a/SubnauticaModSystem/AutosortLockersSML/BZ/AutosortLockersSML.dll b/SubnauticaModSystem/AutosortLockersSML/BZ/AutosortLockersSML.dll index 692b0b16f6abd04e6e347d4aaa488d37876f5e1f..b1fabb40c5dd78e15103124ec120eb56a0b4d9af 100644 GIT binary patch literal 79872 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 TvynNl=ld?<-!lF`%z^&{WqE0p literal 75264 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⪚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 + var text = new GameObject("TextMeshProUGUI", typeof(RectTransform)).AddComponent(); var rt = text.rectTransform; RectTransformExtensions.SetParams(rt, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), parent); RectTransformExtensions.SetSize(rt, 120, 200); @@ -70,7 +78,11 @@ internal static Text CreateText(Transform parent, Text prefab, Color color, int text.font = prefab.font; text.fontSize = size; text.color = color; +#if SUBNAUTICA text.alignment = TextAnchor.MiddleCenter; +#elif BELOWZERO + text.alignment = TextAlignmentOptions.Center; +#endif text.text = initial; return text; From f304255d684316d1396616b50e07031c5d0d6b1d Mon Sep 17 00:00:00 2001 From: DaWrecka <61927940+DaWrecka@users.noreply.github.com> Date: Sun, 31 Jan 2021 20:57:11 +0000 Subject: [PATCH 03/11] Further efforts --- .gitignore | 1 + SubnauticaModSystem/AutosortLockers/AutosortTarget.cs | 8 ++++++++ SubnauticaModSystem/AutosortLockers/LabelController.cs | 1 + 3 files changed, 10 insertions(+) diff --git a/.gitignore b/.gitignore index 3e62424..42b36f4 100644 --- a/.gitignore +++ b/.gitignore @@ -274,3 +274,4 @@ paket-files/ # JetBrains Rider .idea/ *.sln.iml +SubnauticaModSystem/AutosortLockersSML/BZ/AutosortLockersSML.dll diff --git a/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs b/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs index 750b445..749408f 100644 --- a/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs +++ b/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs @@ -635,17 +635,25 @@ public AutosortStandingTargetBuildable() public override IEnumerator GetGameObjectAsync(IOut gameObject) { + Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 1"); //var prefab = GetPrefab(TechType.Locker); TaskResult result = new TaskResult(); yield return GetPrefabAsync(TechType.Locker, result); + Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 2"); + GameObject basePrefab = result.Get(); GameObject prefab = GameObject.Instantiate(basePrefab); + Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 3"); var container = prefab.GetComponent(); + Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 3.1"); container.width = Mod.config.StandingReceptacleWidth; + Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 3.2"); container.height = Mod.config.StandingReceptacleHeight; + Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 3.3"); container.container.Resize(Mod.config.StandingReceptacleWidth, Mod.config.StandingReceptacleHeight); + Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 4"); gameObject.Set(prefab); yield break; } diff --git a/SubnauticaModSystem/AutosortLockers/LabelController.cs b/SubnauticaModSystem/AutosortLockers/LabelController.cs index 5426f78..a602598 100644 --- a/SubnauticaModSystem/AutosortLockers/LabelController.cs +++ b/SubnauticaModSystem/AutosortLockers/LabelController.cs @@ -91,6 +91,7 @@ public static LabelController Create(SaveDataEntry data, Transform parent, GameO { #if SUBNAUTICA lockerPrefab = Resources.Load("Submarine/Build/SmallLocker"); + var textPrefab = Instantiate(lockerPrefab.GetComponentInChildren()); #elif BELOWZERO var textPrefab = Instantiate(lockerPrefab.GetComponentInChildren()); #endif From 7fbf006f96b02e14f07212d4b756d734a3dd58b1 Mon Sep 17 00:00:00 2001 From: DaWrecka <61927940+DaWrecka@users.noreply.github.com> Date: Sun, 31 Jan 2021 22:49:08 +0000 Subject: [PATCH 04/11] 2021-01-31 22:47 UTC Still not functioning; selecting floor locker first after game load can be crafted and a ghost will appear after, but cannot be crafted. Selecting wall locker after game load turns into floor locker ghost and fails to build at all. --- .gitignore | 2 + .../AutosortLockers/AutosortLocker.cs | 14 +- .../AutosortLockers/AutosortTarget.cs | 11 +- SubnauticaModSystem/AutosortLockers/Mod.cs | 1 - .../AutosortLockersSML/BZ/0Harmony.dll | Bin 178176 -> 0 bytes .../AutosortLockersSML/BZ/0Harmony.xml | 4006 ----------------- .../BZ/AutosortLockersSML.dll | Bin 79872 -> 0 bytes 7 files changed, 18 insertions(+), 4016 deletions(-) delete mode 100644 SubnauticaModSystem/AutosortLockersSML/BZ/0Harmony.dll delete mode 100644 SubnauticaModSystem/AutosortLockersSML/BZ/0Harmony.xml delete mode 100644 SubnauticaModSystem/AutosortLockersSML/BZ/AutosortLockersSML.dll diff --git a/.gitignore b/.gitignore index 42b36f4..1202c5b 100644 --- a/.gitignore +++ b/.gitignore @@ -275,3 +275,5 @@ paket-files/ .idea/ *.sln.iml SubnauticaModSystem/AutosortLockersSML/BZ/AutosortLockersSML.dll +SubnauticaModSystem/AutosortLockersSML/BZ/AutosortLockersSML.dll +*.dll diff --git a/SubnauticaModSystem/AutosortLockers/AutosortLocker.cs b/SubnauticaModSystem/AutosortLockers/AutosortLocker.cs index 5563f6e..be068e4 100644 --- a/SubnauticaModSystem/AutosortLockers/AutosortLocker.cs +++ b/SubnauticaModSystem/AutosortLockers/AutosortLocker.cs @@ -368,15 +368,18 @@ public override IEnumerator GetGameObjectAsync(IOut gameObject) GameObject originalPrefab = task.GetResult(); GameObject prefab = GameObject.Instantiate(originalPrefab); - Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 3"); - if (prefab == null) - QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"AutosortLockerBuildable.GetGameObjectAsync(): prefab == null"); + Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 3, prefab " + (prefab == null ? "is" : "is not") + " null"); Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 4"); - var container = prefab.GetComponent(); + // TEST + //StorageContainer container = prefab.GetComponent(); + StorageContainer container = prefab.GetComponent(); + Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 4.1, container.container is " + (container.container == null ? "is" : "is not") + " null"); container.width = Mod.config.AutosorterWidth; + Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 4.2"); container.height = Mod.config.AutosorterHeight; - container.container.Resize(Mod.config.AutosorterWidth, Mod.config.AutosorterHeight); + Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 4.3"); + container.Resize(Mod.config.AutosorterWidth, Mod.config.AutosorterHeight); Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 5"); var meshRenderers = prefab.GetComponentsInChildren(); @@ -387,6 +390,7 @@ public override IEnumerator GetGameObjectAsync(IOut gameObject) Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 6"); var prefabText = prefab.GetComponentInChildren(); + Logger.Log($"AutosortLockerBuildable.GetGameObjectAsync: 6.1, prefabText == {prefabText.ToString()}"); var label = prefab.FindChild("Label"); DestroyImmediate(label); diff --git a/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs b/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs index 749408f..39bef70 100644 --- a/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs +++ b/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs @@ -586,9 +586,12 @@ public override IEnumerator GetGameObjectAsync(IOut gameObject) Logger.Log("AutosortTargetBuildable.GetGameObjectAsync: 3"); StorageContainer container = prefab.GetComponent(); + Logger.Log("AutosortTargetBuildable.GetGameObjectAsync: 3.1"); container.width = Mod.config.ReceptacleWidth; + Logger.Log("AutosortTargetBuildable.GetGameObjectAsync: 3.2"); container.height = Mod.config.ReceptacleHeight; - container.container.Resize(Mod.config.ReceptacleWidth, Mod.config.ReceptacleHeight); + Logger.Log("AutosortTargetBuildable.GetGameObjectAsync: 3.3, container.container " + (container.container == null ? "is" : "is not") + " null"); + container.Resize(Mod.config.ReceptacleWidth, Mod.config.ReceptacleHeight); Logger.Log("AutosortTargetBuildable.GetGameObjectAsync: 4"); gameObject.Set(prefab); @@ -645,13 +648,13 @@ public override IEnumerator GetGameObjectAsync(IOut gameObject) GameObject prefab = GameObject.Instantiate(basePrefab); Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 3"); - var container = prefab.GetComponent(); + StorageContainer container = prefab.GetComponent(); Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 3.1"); container.width = Mod.config.StandingReceptacleWidth; Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 3.2"); container.height = Mod.config.StandingReceptacleHeight; - Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 3.3"); - container.container.Resize(Mod.config.StandingReceptacleWidth, Mod.config.StandingReceptacleHeight); + Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 3.3, container.container " + (container.container == null ? "is" : "is not") + " null"); + container.Resize(Mod.config.StandingReceptacleWidth, Mod.config.StandingReceptacleHeight); Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 4"); gameObject.Set(prefab); diff --git a/SubnauticaModSystem/AutosortLockers/Mod.cs b/SubnauticaModSystem/AutosortLockers/Mod.cs index a3efabc..aea5bb9 100644 --- a/SubnauticaModSystem/AutosortLockers/Mod.cs +++ b/SubnauticaModSystem/AutosortLockers/Mod.cs @@ -27,7 +27,6 @@ internal static class Mod public static event Action OnDataLoaded; - internal static GameObject lockerPrefab; public static void Patch(string modDirectory = null) { Logger.Log("Starting patching"); diff --git a/SubnauticaModSystem/AutosortLockersSML/BZ/0Harmony.dll b/SubnauticaModSystem/AutosortLockersSML/BZ/0Harmony.dll deleted file mode 100644 index eec61353d103716141feee83922ebd3d3c683a87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 178176 zcmc${37i~NwZL6dRbAD~%p^TC=}Bg?k2^SI zV^I-Y0wP3lLlO5K6%{wYh`YiFxNpy=&*ixd-~XIj)m1&2D8AqK{l5OqRNdv=bI(2Z z+;i_ecd4UKdyVB-mgVyQ)KixAG2Zf9ug`z|m?U~|$tMP_59J=(i6NthwsODRj#(ep^c^je=N|YyGtX zDu2m4@=6fD`QSZP9N^uni$ntApJVmo{Kwa9YhfJpblyw5q$_k5|1(qRR&2W9g`4nS z{+_5@Qr3v>7>p!muV^$I=MkW^N!dL-_x1v=x2*Lm8W%h-1W;&|k}Ix{>;QL=MyDP} z319gMZMK!MZri=jI(u86)u*BV`D4OfG#bE1uQFjfUDqPVgq>^$%PcEzJ8kg0w%aCi zx3bu7iC5n0R~-2+j>rWLbtO0`rQjepO)Fl(q5k2Ot~CVtATHXDJ7i7IgLC6vFerE} zYj~w+Jw+rL7Mq{4Eid0Gl74jKq`Vr$T&@AvzZM+9a)=%+HFxFJEc0m8cZ@Fu6T}oe zKirLXds@&u8?eSHJHjsQBZFoDT-j?0(kA4#s5|z(}eG2<0w4C`r4Dxa%dfxf)lv7msYXH&4>-!>iGP(xoq> zwL}=+*n^?DFEHf=;Tm28xo|D7`8PmqU%3>)kM+W@17cfwG>UxFERg|hsAj|c0nCNZ z;MsV&knjK%XHq%Jj&#n$Zqe1eU2od^G!@r8fOG-%SWRIAM$nnM2-XYcS*ju2Ktu&u za4c#)l9fbMgb|caW##p}5wK$OK9LpAZKEsQ4ie@%Lw0x&cxsEXQ1lt0=wQ47(A9FG z=KHOG0#(V@hYWZVjh8R?hllZMeiHDq?SzNpaY7nlKKOB;xV}G9U)(A2S?(o{JD7)uSp?m`p*G>^w$4o{G0=R}@fcoNSJjU^wREDx$Gza8!y0)mZrH;I?Z5E_9-Q_-$R!&8aM z+u>=v0)nbB+UF3UxXPW=aeCnyJZI)W$U|?d zRx=hf#r!!J_?SQ0+4*xGApe$CNK~3t;+1xjv8XEjMZEg=d7Mvnv$JisJRWX5fI!(P zIYMR)C0()ZO6oS1ETPM@)<<+Tre>t?>a_WBvq;jHN4Iy;N5}-%Qj`n4E;jz$#nl+J zt;?Od-x%Uu%`|r96`AkxXd^1v|WuSAEp)h~x&Se9w^=oS65Y9*&W?02N9 z4Q`}oPswA)Ah0Yh`t>otb1BeCaRNFZZ;hx2zw^8pPtjldQbI`MIQ7f@&hv>VW)zgL z=lPw>k^sLG#>uj^ky5{(;4X!i6E)#?u81N0P9t$P6XzzJQ3llkzmxJ7>AR(643&d5yH4?s1oF_Y>)JU!0RyH}xrF5w9Dhd@n=UCs4WZ0Q^ z>Y;huh@myeKLTY<@V|j&(v0EUqsxP!VF9Mk%#_nuMx#{A&;a8>H?UcKd za=$p`o=mx~PPwn?x}Bvje(I^G_AEI|fwlG+v^y^$&bcT=O7a!EbFKKomx+h?amq-S zCqsO6q8GfJaN8N`3txewKG=LEuY&FP;j3`?F8%Cv5-}$eUeCMVceCLQII;s%z8Bnx z>(N}LkAA`i>E|0-L|@W$tUR%pK~-_>p*3o}9Qp8=|Un&gX+7Mov) z^39rjb0*)s<~v`JX-rEaroAr;GMY$U2H&ZC$9DvMU#+846^d&($WL=x2*7XanE16PuD%V zbY1M8ERhP4&~|;SQUM*EBE>7$M<+USaZGy;3Ds{AG?Nk&z_@B>s2Ap8fw@CrBqkUD zM#hNM$`N)c+(tyO7L66mk)TWLTGrl7tLv-TBNgJ`7ROii>G46AZ5;?*pex$JIxsNM zBaIi*5WL_n($#(AA&fTQl~#=yhjZh_d*mGB-dbT4BD(8ha6whE`E}^cdro^8V(q$9 zsygBTIvOov9Mzu9OE(^96+hRL-@x)v04G?GYrzK z2AOR!I#PO&vGvws z%Fs8?T)D)cf^rp`-_Wd`_6YUm+3itzwd7eZG*&UnX}$+cTTD=EBT`NHK}mS?y+pUc z7Nu%YD0g6V*d20$dx$E!(|tJKhx4r3O0Ol^1Ydxz;f&WZ$t0+lX-$$a7=qQMU<2{t zy(DpKOo|1{4d0K~8)?r=auQ+?sYfV4^8>^VdDHW#iM}CkwEaQ+MX&iGUIjn=Fs~^v zNn*nkKX`l0K*FWCTDGh(*UM5tqRTDo$5!^&R=@B}>VYdbRx{S z8fU{8MtyehB;Cih^8Cj28nD0%KLQEC6B;_!_<)24A0?>yF&8_Jb1hW4Yj`s3mWDIcdCUbE_kA4b@Ls@*8Ad|b0^B_c#SER(Cx}?}!>nV6A0(Et zh-~i(?ZeRSNQ<*up9IDkvcgaCu8%c8&8zIR@8gw^BE9f4_`J$@j6eJ=zRu?aPW0FP zIHtYN^K4R?=r4&0$efX8)PJ?&wIpab zGd}DMWr7EZDS8NKMuE<%FOSCM`oS zhsggxARhrTKm!;U847zX0SLcI1Y+~)d9EUf2j7P07)W>XR3THK+8{IgN%Q9L1xR0gK*i0T7zd=xyOQW}! zN9W&Op1>o}&p|B<3UPE>hPVgj&N#YS3f^APLiZt`l0Cwv01eD##( zf03r(4_U#J1hi`;^IP&XVE(lCJ3;zmBE>RO4S$Yz2E>2&Li_?R_i${Q`R~=Ki0YD+l#$j{Z2k!}($}vPV!W2Tg5zNmqC^Yznm-egc9jyA zc~pcyz*sbpqTQOHh&A85D|Ykez_uZuVb?FjNeb7FNcklJ&0k3<$f9C5e~mxChN%O6 z#cyyIs?Qqg3x12MKik5p?b_4c$wV5)kXyC3(55dXDBG$KAN~&5+K3&TL{PQgZb_Ee z@V^NK(eHWH?}0ac)1?Cv-UKHCY(NbK#vT3va4-BHp6i~^lnBa&)XpB{qpHHx{vU-a ze*~yJDKP<+UDZCXE!?n2363&ED3!|sz z*W5?23G%`}6Q;}#|AMQq<{IK)-v8o(p;DdM@UM94&r7GshQB0ByCt$-JFfXxJT%i* z6+%O11D@*L_A0!&bh4QMs{vTDG&k-2O$zWgvI&mIHMJWQ{2kxA1~p-7a6`8SJ&NF! z_TP^vDW{pURjgY+lkoK%!qL0wa*GA;C_{^{g^p!R%UGWFrI0<67D>}T2%m_=PO=7% zYfN~n?q#^HQsSu08Fo40KP3gjb;ax`_bOXD)QnrtH>Zi56t@Ooe|U-jDTnm&C-A02 zC^r8N7o=V81%qs3XvEl^r>g%Uoa)0ZwhS46FZWskrD{}{FG8Exemk;HI(P~`83_In z@Y69A?Iu&zJO)^v-e|}iHm~Dnn5;iLIG;)!nf8v5=I0X~fT7yimyEPA?1N+4!@lk{ znRe0`BqpdzV?YCIpCh{B5Of88>ft$*IFG_&+L~Vr`3%E?0`7u;Xof81pRUY0lmA!o z{}%q&(4QctqNnTrNdIG05dDWJaT92_PA6(4cs8W=KSsZj24-N;0~{O+l(9bdKgL)# z4SUDzu;)@S{g1sQ6)E|Zf^#Ilsmly0L(cTPXCiF5;5>pmYkC>PGO5?3J-{G|5pz^k ztVq@VsTEU|VYl%b8Ki_$l&SHZc#uNR&s3W6mNQXwWyIob8L4C|8xV~6$ADVL|5S>s zh4wM*`VMey>W`T&T~A&*OUU&q$C$U>k~pV*D$h!1$1oG`wxx*wDqd=%a?j4wOT59A zF}Sw<8`#XC8(blT{;U`9{4OH5okl8xH0ajy_MkhMF)45AO({i;iqphck#9?q%Kc9R zsE6>6Je>qx>UWMlO?`@<8TF!kol!4Iv7>sqtd}H>cV}lpDs3v$b9)e^B6?YvMD&Qo zH9JXd$280+lgiQoQ6eX*X7rG4y%M=yf?jZIu6tvBz~tf>fx$Q-mV&vBAJ8BgC%McM zuqoxYG_knkMf>jOunyz;HxJ|vb-^>lza9M-cvt6ULu@hm{;Ho1F}TQ-BE*)FSEUX1 zRi82Wc_H)GyvY8|-wkookoe;Q6yeTu4MFxNMdfAs{5&5OBG;W{46K^L!g_$$I{*iU&&EnaT)` z?+^y>-CpFQP1Ie!4gY5VkG9W~Ffxoa-v9C4I!N$P$hJDzk#KMvpbi2Ki38NZa=}P& zYs8R|;5KnJ;++z~&3Ns3!RzJa25(G9j+jWNC-O?WiTxtqKAb%4CW}S+HeE_=vb^VC z#X|C-0_wI869T1eokAOs-@i`Ql4K^W(~`7`z;;?fge<*O4LMFrND20k0C80y_AQjC zoRC~jNUp52gF7VFkd^W(d9?kE+H~peWsgTDIGIipv*pUh7TWpP4P$DAu`$3n*k0V= zaiX`C7i5ehSO9Cx6yB^6H*Xi-QdY6;NVy}t!6^pqfeT}^P9|f_I%3h;L){CU2>V#$ zNDUZ|vNKj4y50PibS{TQt5PKye`&sP2$QL5Z^)iIge>T$(s7uK`Eu&j6dEq$Ty5FIth;>~mx^NMIvUO3j8r-Q$X1{Ee~mLzD# zsV632)-KT4TuL}LB@v8p7u*BYD)vCEFsy5PjXNP*Cilltbs^@Ie6s&0#F&x?6nja& z{vgA6XS#GucNlN0WQ7;;-b zCcp-fuYZ~xGSel-Ly<+q3n@dsw9?m9)g_HD35JJwcp=lrd{E_)jJpc9HiVJjJxEo5 zHe`aHFYVdi_$CRmnjI4&X*R>YSYGy#0yFB&W3YONm&jq?Lg|Z!tTjiNxrl9DU>*LR zcwUmRE`X=#C~VzcpqnZFQ&zdb3CUimL33A(39?Pnc%~&og-gc=pT@zist5&3amxK&R zMa@#5CV^QDUwug9=b&u-iHE%j;PKA7caM@z*Hgnhpo6ztxlg;aHfy!yLQKqeVRIa47 zGi^;MJ){Iz#)6m9))5A=d(s71%cTuvV1~@+_Jb3KEUzVQU8boO8jHxqXf~^HqLhXy z9dn~v)sMt*nXiQ^_>EAaAElIa1aEJ^s(quA7(m=9XJX3gh^yv}28Tk$eCCUuRKwo@ z*O@go9?79^A15rN@AD=q z_rc4L;w`(P9lVKhCZvJ$W(k*eD~^n?#hVa0Aq$6YmVVj8K9#W`*D4F$zVh5|?@xhY z{WIj%l4pHrF^tLfFeZ3_^ugYc69SJNg!z=!%mdS(_1e(yX0b_-I^RA(JS}+!d6*nI zzd-tda_zWW>&5Uk+ma;HUQROk6Wq^Edj)ZmEFYjcs<~EYCvg2U;3jthH_!uD3v#Wi zcLF)s14%g`F28PZ*S3PpL@G0q37cICzue8(iubYY;KRb4&j^PPit5JAgtSR2i^|i= zaz#GzYyZYbLH0Won{&uH&!W_N;g+zta}X{yA#6|v4GU?+q9r6I*caANIddf#hEXk&~%3vu; zeGYG$E%;n(J#QTYr;EWjdn6ucFK)aDN(j-FXfv)3Hd1)g`Jm91xSwsOqmFh#m|&@J{s2?C@meJ`6`KnI%&TpxVApNG;`zZYNNF2+X1!tB zTO^21CI66Y@?xe`{qZc`@SU-zr1x|z)JCdV-!|zHZ8xB+mxYR51jlm($LTy8c9!v7 zOMsK1UCf`af)^VcvLHsH`l#JPGhkh8EG1EO*m$c91SMJ*j~Mu#hFhAI0u}75o`YZQ zm~pzXDC`WfH!EEu@t~CvMc#j}&W$X&Kw%k1P3buaK4tToP7_jq<& zd12#nbuY?oD=%(Lid*L?mA6Ml88fukhFG_dGK~gjLXDdH41~@N8N*u)sEcmB4+BDo zbbEQH@lw#45ygPh*cy9k^S!VRKyVg_+`C>YD)eleb8XKJYeYo49tCVMUo1A4NnJT$ zjw=bxL&s|>3&z$)OdjEvV-3d z-J$iH!k`Oa@Sakb?aU4 zsk+!^(g?PJ>OSl<{WBR3RN1N(*2!j|x~%aags`QSJxm2B_y~YXpP9~|hh(seN9F{s zbq)EUU5kz>Rq#hpHO~j4YzM!@9bRDEzZUm}#{FB|kBpxBNO%!`HdaV^!{_2IRF^QE zyBHUJ`X#*BYorM2Zu8-#1Q7i^UiI&pWi)z=cy|{%D zTZAd@zI6_^8|9%si_J|!RdX{>8tawv3SYppFh&2(5MTiudlao;^7E{DKSbDp1V_nX=T(xbu0RhZ6j_UCj zTyI5w4jQiomJ2F#`h0a!KO&zW5+eB7txG6c2eodboZbd0-$$hUPmo@ol$hWk@UMG` zf?q1&DDO1*z6rR*D0ux8TX!gR(C%s2H3_W57}%=adcNRA@14yBEoC&Q z#YG?Ybn!mb#j7Y3uc9z`pV!4JuKxh94S|MUMWJ{Vg~2PlGxUn1u;u*6*NE8r4JrD=X0wGaA z2pvEiI17X!QE6n{YB5$QHrE3ub3*i->)cqk-HOM8Pa75Jx=x2)G%Z-`1gYr)B}Tg> z^4cK5SJ7N#-d_z4jf;hFNt==OhXyP*4~p_ak23j}XJaF6&y05FJ779kFi8VScvC6e z05k2%lx-X;wy|5e5`}B|Be#^at9OKkS3v{w9mblQiK@4Bu|0e-GIVR3ThS!p!EorGxNfW+|fbiu!Shk-oF{U)u&h`t41eNmn#k}Qb z3htO)x8se|VXTy?8Q_J~1Cpq-7iP1zjJ~{6f$mUoYb2>gYJ1srR#|+Y7IwNHXIw zWx>PF~Sx zVWi)t@CyjFgGD?!gM2e2l~(2@e4LPK&d%W+!&#Ve@>3Q_V_Bs4H;A)}SSD;THnXe^ z){4+_Xcz2*cdVBZvL0GX`RWyhfgEfgmxA9~3RC*W2gu+-+Ch$O!nWBaTszqDm8Aib zdGC0;C9>ljXToIrH5J);1!1yNRZlq;-BP$7DkrA0gutKtqu%I7x-nB_uP4J*S4VsN z&a?^_bD)WzjHf%u@CN8>z5y8aFRWQefXf-FH{w6ubB_z(gaboCx9$hle4n%|oN4X5 zjSwk^5LYP{X%Kny5Corte;HlXD*9$Rq??GClSTF%Bm&`b6ENd9hLJQ_V$`VBSbBpi zZXo82+TzCIf^5$PlLTImx*1QcQ4)N*WUxG@!}!&}F*6r7y@y-DNx?)g*Nq$dGiyzW zY??h9DkTSgk28T@cq^dcZ9Imv)v=+h9P7#t=iFkhbvv%(?P4x~p&l`B!C!w2Y0plV zP)hMMC%l93uFO}h-;5eLx2=QvcDp#1dE5FFJZJPA)l;fE3f05W5K$@@%`yw}Xdl47TdIY22LQ%cvN&ZAN?@{v+HNh#sm z4yBCOA5Xe4Zr796ZtsZac3JBWl#wA|(X{5cp*fn#Hf`1;g|&AAq{82yRna%m!PU%U z2H4FhO-0UQcuwn1coJ@t$3O7*#=W&0_tXw?Z|la{6skAfUEMet@|wJJGB)$_Q_R); ztZ97qP~ZHx&obnfNBu})_z}gTjvTN3b}&ZuFV?T?K4x@>jr+z=Cg=R#PqSn&iOv(H zYz`%Km_eIS*d;jF4k@FsuhYEBlM)jgh2mRFcg5svi?Bu7jpx!3WIh}PV861cWIPv!b}2k0V8G`%wbZr!W!|91Bc>T#z!oPbWA!K`Jo@DbxNm%rOa4iJ5`4Vvmfl ziF6rcH}59rsJl3hoSAcT1axm)6=g&L&<=KkH1gvF`FoUNiHTAlPa2lLeRg-fm$^) z(l54T!H_g;6DQ5v+al|Y6I4GVcH~An{p9>VYYg{5-`XtkgA_|fuw(RDajP>eX^yR70*cyxtqA~UNF}WiFW`rj)P7yAS;z(MLt^t79{CZ z1jVMD*pAJJ+#Q&i-Rc2vB&)-~31^@>7<=v-MyC#BYL!ebq^+1s4HjwE(Ng*SWXiz} z?N@ZPKQ%C%v5Of``|l|$S8=2rY9Ib_>-2ej1EvqpShP5cGVhFswX^;+{zc@+C6io~ zk*l*#ZnOA~hcegZ#7smPWJPoxW|c3slrEXWG5*k>?maATU*2ud!!V${eb*WO@(lk( zkAJd_d{my4y&vv??EUCqH%rU=u_BNM3+73Qky8!Tn%5W<;1O&E8Ebn?&j$p`)+OW) zMl6E`n-)6iWWn-5#Ue3sT%sC&$iTlC3OX3B((tDw@DkGlKPm8-xYF<&6L^W~fxlYd zv4y4KPfg$@CV|%lqwvE}M%iqY0V!TIm#k;a#CmR@+jZKRuG8T#bqpc%z>}qv9|2dp z0}bp4NCKqLHe1cQ5K=0po~aO_yTUa^)Hf%7+L&l%Ch-ypWfiy05Yx3;9CXB<>_uLQ zxVAUKcqQUxy%EMM5ijqJFy67?8ah{mP{!WUM>B1sElB?L@y0sp-);#_p>(@ubn!7L z-C{uG#3NIZ#h3#Q5KY@vY1)a$r}Pz@cH#w&>~yikwl}*ah1{kc`RwshxNUM;fqO1y zOD|>I7D|Ucd%P5NTPU5nA=}qZy}x?^KR&Z*TgOZ7Yu-vafyk#9_W{tPN6?Ahq(x1N1YLdV*FLx=B#sQRA5%|sj7miw(; zSH|NG*Am@xgw(g57>yR3jOET)=ZpnTt!&L*$w5TYoF=8+a1R^lk=tVPG#Xmo-o9s7 z>8ztUgddg1$9Np?H9s!x10ypVJi$X3_#A1QpCDB3#Hf1BPYS?Q0C+6{1LACf_>@4L zDiAG+tlZZ)9hsc5wIZ>>o6CpvY8SmL#n@+%FN^U~(N^OEt1JCUiYj+-q5oMl&`VP~ zFCiCQE5qW2N;_YO_%uY6CnZKE%vG7WapcR`ItH>Ob3Q!052(gf(qeR{n>H5qe~%EH zBIsP39U}gO9qa=iN@70r%*KH;S?`dr<89}-bojZleJoDk>?DDk3K#oWpX}q1wM**u z#We8navt%D;=3qrcsCC{FC1{7SnXJxuY0;_%Fc+M51t4$@rtHsuSuD;A{Va3kV1d) z9@tc)WvI}2Jv?Hh5UCI*an)$>u%L0)phU5vED9(J9dEoyLd~LcqpK-z0s>9>I(cQ< zH=Dd2>C4SNgqFl~b(lc!sKX?cnLKTP^DMYafUPM#v#m?*dk2D(ac!}Afyg;aI1FI( z?Q4;T=-Qq0MW(kqGC`G5Q~RYvA;A}l@W{AVLfL&XywbPMuq`<^Q?#$2BNN5X5UYYz zTONgcmXLbMZ23)K%r4(_A`~@essUDMy&nf>s(D7zDltY{UGmPSQwsHIzlgu5BFb@h z#)Mb|OvXY=_z?mIQUSGEF8l%!oiFl8<^2HO=9eUFQetHPf3@0Is!+qL z32MFUE@FZfFq_;^ro!TfbjEojCs!_+Zaxp;E8A_12QGW!Z~K5D>T??pfv{1YLq=Gi^IOcOjm9$wFw2%_gR}JwqQXby@lAPr ziw7gGeW{(wisrZRO^Q^RJRIv=|u88#e^?kFQJ9`0NCxG8kK#2*?flfGbg9Lw=?*@(6l4tlmvMx*=&&i`U^H*24o8I1o z!fQ!*_Ee9iElF=4U!PNmOjGm{hEe?(p_c?v0`#T1(bLITf7 z2P*uu_b#F3N5cDy63)DPM*>fPg*ym#BM z-qTaGkxHhP^)ulU3ZeStSJ2KFx7d8I((bewrwh>x#)ZuchoN1bLgwK^DK-nB1imsA zXozn!z$cZUs6X4JhLn4RlqZGt&xQ4csS_!qqM!EO*Bj;67d5^H)+oLuIq7OZw)tby zZ<(6kO?mIklv?WdOK4Y-&M0+kgE`e2Yg+p;Kti`=)CR-wlru9FsXW{*r#-4$qsyfw z>)ssxgxvFV+4EP-ZCndXqi-bc%e>Oo;F;3yMz^vb``OZ4Asdd^di7`5i;Ek(1Fot` zPdio2`S;G-C|*i4zg~#{DLIuVB}NWnM!R0GQ6#MyNOaUDyK7}?zhj=?o&m1fp>tPn zo^Oymf2Mg#On_GC$+JAKmvEEkX*dCSgnz5(y7oaKlV=MFi{1ruiY{hu>V1Mz7<^GbnD{9p>_9oVT`@&xWl&|h> zZ({D+r>B|n)!l5}zhI_?)dlt@=0$zsuN1P-*t10SVuIyfD^A;*fiev}9viL&j0I|V zZVMf9tw2217by1a1+?XAjeVq1;%fzQ3X$moe@&=#f%EACS-cb=Z?&JhOS;iYw-bDl zU0+ha8EXS?hF?ZjzW|L#)xB@Xvlm~&ytCZ zg3CG^e9aF~C9jX7q6!`}(Vro9hKe*KbPO=RgZ$@FDfj_)OCZKFjk0V^jEtLAr08bSQGK!gdzO*=sR zULY6??FA(3W@Qdl9DtkQuvNRK=y?en;(hz&P2}e{qzN0YP^<&3U6*p z0%bh@Q7P>ogoG=E1aJvX^qIw2uGsuog!BFw=c7q-uO*>^b7HKUQFH-_jK{$Kalzgl z+ZtUaxEY`oo1chqe?G>&B|+o0Bvf!ekOZcf4(?A1?mnSBo+}%=Y0uob9^q!*X?U@4 zyi20jl2F0jNCG3=kqmrVaH|Y7lq)e$7zlAkcZBpF07&Q-2gwILvpQH%PpUr|$MfVR- zuhKTrDTT&WFu+U&tz=SKHn-Fk8n2O9Rf^b~(8i_UN>Jseb}Ka8Md?evlVu@W4}bX0 zKa(-4)U3_Sv1Ev$6NPj{^vIR#r=bpJa+}w1J$yzG0Hkj3O`{rWx>O@wr5m&pI zQ|r%m{tAq*H&SOii*Osbl(|U_P1|pX&2#2bYw=1Q%DyA)N@Anfx!y2JB6v}(BiP!K z`b0odmYwK``MV`L0<*)>;9kgJ7ET1y}3PnDR z8ZOV!!U2}&YWQ~*mBod|D=9(>lhLu=ZotR@=hb&jbnIc^*M5smDpfyr&=$o1P{j0% zPxT<)snjQWad1&A1CE^Wuoz~})Z?}ipPyP(Xl&l4hi;uLcggP7XKuc=$mpMpg`rx1 zk+Lr|o&ZJMt#_bZtJo-`=&oR`Wj&%O8w(nRWxdrc%}19+R4b)c=i+Z~EQT4gf8pWP zaZ;mS#LMkpv)5R8N98Vc9or`v3$sVlc2+Fmrum3J$Bhvhs-2KaOn919>c5%2cAd-dTxNkx*lrYrg%rTo`pCWrR ziHtfGKjhvJIt4NA|EP=FS%;OBLvAle%ECSXbak|RV|`(Q)*zc`>^%_^6m9YDk8oC^ zF~TxFKx2brI9trNI0~NU&@~q zwjyi+a=xQzuFwg@WS87Zl#fEisFs8lx*PuF+8swP(vh|N10jN0l3bP5xLDm|?1lX( zrD+a9_m=zB2y!bikv%GPU~;wGCT?aCz8wq$u6xZqJ-gyY`Yf44*?e4Tf$2g~TqKE$F zmmEzs}~e=;Ub*HEQ|TW+2MhqfnW?^ly6H4YOV`f=@#?VArqn-H&DzE34#I(+b!Wl zv7o#|$8l^V-jZ7E-)01tOpxMy{idmT#oT7BA$_7(YJPDrx@(-1MB%vb<4z&lIN4c% z6Jlxm_9i0w!i7TFT&IhFu3ipil)>f^YHXP8K>8jk4G&k385%Z)Va24UFeAN%88L;K zS1cBXi$lfXt;IP}spe^^wiSnA&M=X4SG}iLgjQ+3{n^IvqzODKC7YYA&B-?YDgH&o zNwqtPZe8IxRZiiGybjoMU;7uOG8Y3F9LV}*cb;tX#h=FEee)=})reXVXG~rv5<$24 z2Hxl(4oXE$Ogx9#Drj|1k;`a=Q?h1^R0IceG3K31$S3cOpSoyod(_ zi@ESvFWE#I^aDmLwyI+A7OyB(kMpqNulANKU9rwvI!VlmRn`6NO^c=GWvGK;6$Q{2 z+$Kat#(kOl;ud3maH|OyyLhlw+>LQ)Fu7mP^ewuw=V76#Bj&G^8VZ+6t-(VMSm$BV zl@fn+QiRcP84(PHl#t6L_M&v`a$-%KtmR(<@ytz%OEdE_^YR`he>>b2h=Jaah4uD{Vw2Nq;$AZkLNnabyCUe2@|&tH1M zbsNt(Z6kFqa~7K~cpQ3ie9qjpehVG)Te|=LmNoeXItw-8&p&(ejkveV6hQ~_jTU8z z_MylERVwDzBxaJH*X_u|=$px{I2&ICAef*`NWrA^PK_TCVzy++6=^yMK~Sqp8wc+W z=xzc!67s#qyk5P~cs`+_G@422)Ou386Q!LdyRMr|I>F}dg5Y*sumXF9BX^BiS5XHY z35<5Fs+;LT1z^s8MBj|^qjOgM)|~Npf2LzCBYk@(>8qsgChzjT-x?f?_hH(Sx5e~| zyRo_4B;URRDxxa}P-QqrsqQunCcdKct?J~4lzjVbiSsUT>ONwYMOF~0>mz&MU}Kx$ z^khSgd=|xS30|(v!pq*dx8RYBWA%o?<|+csy_{}vr!)3_nZoxG?3@YJxxL*t>KG)n%`VxVAX%|ka zBivu%R@yD`p~1f-8vGdq2GgFu%2mLzBi=R!J+e6XGepLzI-5V1i5n9^0@reu~2ULh2{l82Pj^amO1 zQtE+0O|kJ78V{3(LI5yNEG$F=FmKc@>Dw)m|4E_*9hu z|4D_Hun2zrO!!p&0RMG`m#_%_x|#5)dIJ7O3NK+1{Pi>8Q}qS>?-X9bBKR9-!l!Bo zc)r_4c_nOT@G83fUIWfvuJe07ACS6M?K^VuI@VIT!maf#@aV-h>Nv(O*#T?dUT~09 z8Vg3AY=|kXbmmo=#xt(-OyDZJ^-fZ1W%E%0O;cJm$2bh&w5#1z6vZe(@WxRxFp%pq z6lFTkQ!8g0)CN907&@*xREV4<{IH#bV-B4a{+SYflifT7q-~*}d&s2RcJojPdAB%K zm!W>p4X*4*(cjZZf=+pdq<1=BrxoZfiidGbdk;z*z{$8+V$7aJdbX-kVAeB_iStpe z+AYB(XIj`xscZ|SCOH2h6e^jx?-sW_a5Ic?+w#EuUUAEVj}sYm28D1Ej;Dg0jmlmT z17QXy+4XHURQ{m{GCYjbo$b9PdnhTH#3Uut{Zdq#;hiFN+&w+Vo!d8;8&aH8M>iUT z-{?j7aDq@`QV7rFQbv&J_K?23v49SZb=cm6dYs+1@mpJYUA<#cf_=)Li&1@QJvlnHL^GV08bD3>PP*FLi?Z zKsaHDWS7I}Mr|)P*Qf^Awmj$ReHhbl-zskR_-G%6Bj4_b(!0TDXGfrY)#4bg2bnM? zotKo+(Qj}nO`4f={Ejrep4$vW(!wJt$<=5C2)h?t$2nJsCp=0E_z6108Bk1c1fX1U z74U8130N<}o|1YK%F`rR=tV zX<1yI%#5Py?0(Vs8`Pkz84C_NW$t^RhS=J}RdQ4*-}s6#VVwr&wM<62NO8V z*x0vrt;S>HUYYn>LPffwk4Xz;c-(9pI$i^>OqyR*9i|bQ*b8@TTr@wa%uYAPh_N;o z=3P$kE&yy!=9D7&J_tzZ9!5`%0;tr{;CqC~@tt|brE+-$ypo?Cu!X>@4n|qfqD9Hs zrbP~7EoAqkrvtCrqrkiepWZgsxRi$JsPRkHpUq^`9d&{q0wB(LkyGlH@vZ)%ybfjD zDO!?YpeV?=aKRKwYh#&Oy&Lixbj9eYhNNm~HWKR}Oc7OTTqi_D9WtxkRqbFS`b>M2 zspKRw!kU2U==$!ByGYbzgD@M=?eIjYDWl2_K=6IYnvh!;3{&bq;B!ktw^yITc$#J@ zDob^fEnnY}&cO*!0*&h5E6MMrB9o;(M873noGXHUiU>MPmO9&GEE@@uQPtX1L$>_! zea%uOYer&=Oa{i6Zqp&(ddxec8|U_Qo5fqrn9kMjiC+s1&69zVZ_=N_n{8bi<<*jB zz3g>P<*gm&X*f8f#j|<3giT6}0^4dGV_3^cmVEO}9>GmUog-7OoblJ69p5uy~^Pjtev;cq}}JfO@}g2tetv>mr-mYHrX|Z}&5B z5BZJ0YK$p5`<=0#fWDXa&=*`pb>*Aqf|v|11Z55U8Ip$Q5jJ6m=kt=Vd8x1qqOje& zVaz$70FxO%3n_8((*)&03=rZlFmlJb7BPlle3kDYwP~JzPk4SI`IILm#uWKxcrKr> zK9&SpRoUc{LW9iLxi@QXogeh#`@Y~a+leG5Ic-GOu5~xc`xU|)`C8;fQb6tjlCuEA z%)9k0fSG&0GKP7sz|4uvw7xN~Y63B_`m`m-y1Gw4)5QMH8pDD48=DuC20@Mrj{RiK z;efDSbO{jyxh2c?erE2_K`1$j|ND3He+J=~@y~c&Z_oM=Z<&>2`>;Te_8Z zKDXrb6}zortV-4F*R8BI4{N}NB;eB;aCj1cx+BTaNdOiQ0!~ZW*SIwCo!~XDNPLHQjTa=oeR4~du9}lu(pj0u8gwaanW!>*X?G#KoZKDT zcnJZ)^N2RQG@DG7%?G|$E<}lV>=}80RR31VLoS(+R8SEJr7-C|a2z zsJq~)%@7F=UXOfp!IQ=X&nIU`pUg-+wI}WXbD6@(6Bv_@&%@xYTs9j4QQW!a;|Wf1 zIgsqYb%URiF>|6FBiJ-75vFWUQ8xKuPq{);=5RD{a4o3X8g#YGAjMo7L**l=(bX~7 zdD2cb?^(d+cfp#V-YM9EF4(3tSVV}dADW~~VlrfNtPmSF7x0kklS!d2ahecnJtkt_jzs8m)9`l&&KK^0^F`f|r-5^8=N{-V)P!3| zsp3}~U}!C}XT)T*vbFQRrvvtI=iXkh+WZKS8e5tzGPs(#+W2UN@34uZq-%W}B0h;Y zCTsB#k4_gs=;0d6f>8)1>=Ee0I`8i#z|@1R0x_22jJ|L^@65Yo^&GE*^*#|Dr%uS0 zo{&+6YW0N8*D$nPD&+zV!VORHrE!Hr``AJ$& zk8v8#Ec7~z-y^0_kgL)%5LKnB3IvHS1*`0}yD+gdcDf;5z6Pp1NVN}xX2B4!Z8tg} zVQjG1M|$j*t{yYH2IH^bWc281-mNoDmwY|bR04v7CO#{HPHuiXxS+uu;_`DM;fohI*iWnoM?tO!;1yyaG;x<4F`=l!%3W# z0~m+?4Xy-i0+d;Yu&V19oQx|N*pgJ7-!e7efpXiF6Dfer;?nzN75yqRkq24rf`|TRfDbKGyUg$^14y-%In8BG_9lH21?epUIWal zfoZ-^NMX+#uR?X)58scY-@_RE0UW$O$SeF158oI@9-GShH7>_k052YO21>(j^&sw* z+!|q6XfO?}5?RM^*^hg@Bg zlhHb~cj^8xlohJWxDM|lxcWUOqCEU4-kAK4iMvm}Mv||8+uU?V+l;T{i`MQ2tUdO( z1|=UE*X+-mIVST745!R}`zN?_cHY}bHR%(zLDp{zmXn zTSapf#s`pyCAmqa5pHSn!y?>E!9MvBT#Y+rn7tR?cn<4(lOH6aQVLLn`Eqa{&xyw8 z1?)38P2@oxLDo@RpCwe}P3kw`&HTIAku1T;Tr^)&Fngme9ccE+3Z$`b^;;uLll9B$ zEI2wsYtYY@1KUh2cZK2vO=KtQw?>!8cx-Ezo#C;=&p~o3HCD>GQvdzdz=9;blnEO^ zPg#@>yOvKFm|l%d@XXsK#?vR?G2VeEwlY5})Koc+}~$ln)m4fwh6i@fnZz^nd?srhp4D(WE;!K6W%mJb_L zw)UQdkBuKAmqt=MUk2~>bfZ0WBK z6}_=D>ZF&C=$SNP6(ik7*`w*~`3C0(!O4esz6#;Fk`sK5ckrNi!iRVcyK2N4&d6OI zyRb3TE&8vPB#qr5DR>wVGgB^tST61;a+&z5?>6eha;KuwDg>o!IN`|?zcoDJ+fCS{ z^aD~o?}zR1>twL`>m*@sL}LR;%}(HOJK^PevGE{5wq|3t0m^rvj)XzqPA2X&KgE5MUG2at=9Sc_sDsh}+M zeNu2_+8A5h%C_Ewt{&ix0Y8-j>^Zy85)}Gn!x|su5s#h)wp&7;ep!WinZm53Dr!Ll zBOU{z`(&7R2o1qEh0)&nzf=cKzhL;@sdG(j@^<{v!6)cQLxPQ`gAQy zZDT_=;#{{go+<>?MspZp!u;Ww(*&6k3ksE%3wdN(Entu+D_jA}lb} z&kCT`EXTf6=*<{pEqsQ-I_JAxsu5G6T(Ku9>RxlXG%e%fW6TIYk`RS@rm2x$)>xPv zip6p!9@z{eo14?onP?WepO`UGM()g#GbR5Adgysl^cXsP*W}E&*$r0Dp0#XRmbT;Reu1q|FK<3c zO|n9oB|bda2O9YPPEYBxdNY9A+)Y@Z`J6-3^i@-8QRt-Sj^ack~Ia$J4kT-zl!!1=kZ1 zF4jJ}xVRyti;LSn61tw86_=EYJxj&rj}@2G{z(egPc{7+rd&UnHNBMU4oUyhh?bwF z(qlUA(t@=ZS|VIO+bOO)1=r6bT)#}=`c(?ouhY1G(Tl5Ls?gj6D1CvshQ=7;$2y;( zdg*&71(Tk!+6yf z1kdCZ{D73f4|y~n71!Z}akui3yqb?mz_GY0Jt4@lG_F6aJDC$(VyJmA}Sm zHgm|pRDqPZ%8JIPfHgFYb?%Qy)VIppZcw-lUUoiD6nkaabvy-zO)f*3{ufIi-=#&M zxh=|H{kXJGNAIVak>>G#k>;y*a5S`^RSPr|*{5F_Y5o?9Ir{u7c{$+|qz`|CJA4vX zboBX3(wh^2Q?&C9@##YCmYiA=@#?Bd6yx$>jt=ivwH$Zgf zbD`sHBD24zkaE8m)VF7LmFoy=%{8%&#kVMp^$yC#$Bq98obZ`#COt*?-iL({4=liA7GK~hHrv%na-E+uonCm$*u0_N_oMA`pK;*D{{6U zVi@(ReIw=m@P7f$GCu3KJAcLLh1ey%LAT@dQuE zD7bxFt5NR|_4y4Gyw$XR7ynoow6>!w*_PII$jZD3f6h+045|1ACw=z}!g@{{nF z;Lq`YJ)SsxoVg2qm-Wt+T(bl;zmw^$ioYjUyBWWklhe`?%3VB&!&69Dc&mt~Hi)b? z2zF$-Yz$V>9-u*spq7p@G7vB{YzqZ`exgpo?Sk5e^=r*%hPN02^jMuG^FScOx;UHN2y+m2w?M2xK z%3OFGrDMAkOWiZ|(oFx3dMalWLaGtV{wdQZ*nMCBMqfYtWL%N4xJ1ul6G(B0FD$eR zRNs(gw=tLUcG?5_&a?-4do77I3RVR%i#OFtOecaUG0_(xBxUC-NP^cAq{%58l`NI1 zD5h6Xxc*Au&2vWgl#*r>-?8I5i2R~oeIrggM>8w#9aw3gjNbQJS{$SNubKmWrUy9O zYYC^c8yLhRdk+px3!0oLh zBccXbwv-Z#o0B}WpZpgng~lBUFdXr*lOaP?n6#tOh!Z9|0;L-_p8sQ^IY(lO?Zw5a zu8czd9q0ZPBf{4yVLi2K@Ts^7|3~$V?ppeWchhd0eXbeX&J_W2+C`Nk@nB2)9LmfX zTV>#B1DPJtCZO^q2QZsqYDNdE8waCzeRPbpPEXp$?xVNzT7n?-DSz`dq~;@er|{}; zW(gT!Bley21B2#e)ObdBpCSID#`T+QI=Vd##kiJXj+NtESltl)+)9`O*Sc#|`J1R` z0^G@waZ2?(C8{S6WO-6zf^9NnD&WW7y$UVfFV5_a*ip_pN(f#B-HAdXh3M+~7g5wc ziaJ_5gl<*g`x_OWAtqzSuq93e3&*oLH#ikkXLtRXU?cvn7jB%U@n+ORxUz5n`clrc z4hpvdKg`}-J}&foxTfQ4sSvlPLZ((WGXxBCt%TPeh7<-vxnjOOgmcN?eAM@*@(-&m7CG zd7VKDR@Sb4}1!Q$a-&^zBs8kO}%uDrndQeK!>}VuHSx3Yuqv zzMl#znV{FEf+A9XkP1>W9lm{bbj25;UJtC-7Gml>3nr{P6F9rGRPf30bImdMWAHD;;A^jg!=`k# zxoPO7K${EK*pp}WF29zV;u`_rxQHx6><-)$P%ai$7wis~+L&z0wWY-Z-+W9$?9MVG z4G!f$Y%CVeT6l4xkg#K*dYD^J>PI)eNka_8_| zqcV3r`^dEajNhFW}6i3TbR7k44ILlYEslvDYlU!F7ub;x~d&FBcXJe zWK}2O@L|FSqG*^K7E~Z=L&dr3sOJc|SVV*Q1eyU#QYJuE+MPhk_bAb z(~8ix+JFxa*~K9auu>}`{YmQ8Lw09{RNY(^?lqXNb_CK3wbnmKR1ffA z#!e7v*L=L0B@Skeif`4R;z+p<}3Q8Ra|q#CYu9KLv9)`5Kv#Q?no_k zyYeB_^^Bxs(S6=}R!U?3=siBeBgGND$!EAUR5IV!9Vm{Z?(!*)B$xRN&nwPbi^7gE zJgqB=hDVE|YgtK*^x5$I;yknDH;__z)fK50TAXiWWz6UIoIs|yd! zU02%5RPAHi1J}V6bF1groxO#Iyz1TRnqsy#T+Fe! zt=c#a-lYf1?q(dEj!x4qgiu>B|sXRg@z9GOH{ zY)r}ssG{X_bj)}UlG^+o19!2@|1U;KuO&|>IEePZ`1ZeLOuq(dg15_ffreOR-s4*2 zZ@rJSc5Lc(ThpX#{FJ;*n6|R$l_>$t#a~F_>!c!4-JvFkwl;20 zAE^}Djs0YmwbzBQ?b)+_M)cY~Z3sC>r@JLKBc6>gnJ6{o=CsMAVT*hVU1o)9*v+ZgGwGIAEQ`|0(9s}OJ4~Xx zIW<_%W{st4&;YY9QmvY10<>;Fndziz4y3S^Y8>Vf&8c+1w8V9L{%ieWWdEBVsgK zKNjZ%&lU_FC-fPn>fXs((J{W}1w@5;!YiNHegJrlRR0sX2~J`xG|8SOworvcq zn%(%M6d<*6iK&mQPqy@ZGM57|!CMGHU@1IFXA^JkSGm4Vyx9MlH<_f?z(;PSQ-vr5RW=i4VBJux)lr(v%v-)eI^)V#rP*iOyv=`nl*bK?4$n&@}Vg^mL(o&gK!j!}O3k zlnhMDaDWPHGgjevY)fA0Z$PylB>)ZuFEqT6`^Vk|FAxl5=rJPAvTtyJNQ0?Aj^Rzu zdub#=2NLcz*Yj)(bcdOxiz(veP-VA-+oe@S4K%)R1CSFC@!VzumqY`n9CTendT4NmE zrdibU)iQWKH>+1E=JX~-<*i{Q4Caekr&Bibb+FWJ#?d*%wd6@_DY~1lg($sR&Iu2J z%8KJgQZPEvSWW)s6q^~2916e|y}Gvg+Ho6au}GkN4Y} zF{)uU-XS#{i5<>Vcgcoufji>DXKGRr=VE4S_$++I41GNVMI*tm^P9e2`Z$o&qdO)a z!*ykI2jhaPmsXb8(>a_oH(Yw=hRbLRX18jd$eBwnjo_RC4Y}m@N9xD$X`Z!Ug;}Fc zYn^&m>s%qSrdsEI^GPs~XtNz#n7IAeZvXlYm=yP~LTBZ&#^*(_jCy0U30KG9*KuiO zs(A$EpL|@AiR%em%n>gkyXH{@1Z`Xdyr?HY{*}+ zX6{*-k>+uFqfI+YBmH}a{5~%E2zjyGiJQ-rhetzZ&GiSS&S(};%WP%H^6FQbR89DN zxA+)*MbRDT?r)XL>0+6_cyqkx*R%;b z_F_kv7}F+h4!u+If72#hi$26+yVES`DcfQO0(mnN(=b7XqGrMXRbTQI2SDmzqQS$R}P8jCW^4Er&x^^FYFd+74VtPPLv}} zc2Js7cy#wTsKW6@wB?OQVWB!4Hshp*dpy_~2G)cEP^wgq5vab~=p>@@WST!3O)t*c z`R-JCX{z156k&2tge_ep*GMsN*8m}340d6c8(X-u9_T#0-<+%dDRYfhLL|pR>CL{?p&yh2HE)$mjQI z8lx}_J%_^#XiBERi36j1rvt-uXVbTE+$vx90|J_m?4E*5Xgb-Jr5Clbz5}a~obqVr z`r4-N$>KN&ilYOQeH&c@c?q=81%|cwP2+o0{Ka*;5Id1Zbx}~)IvnoE7bK@d?Oo;# zIz5n4*a~7=mmB1@z)j>Ed&wOHI^01tvbQzX#mkH*P=lgSAvZWOc&%O!M4Ur;DmLyhR;z8yT)kmTB=Op4wS+gibzTmaUAFi zobH(rY*%b(Sde#L3NxNrqA?=%ws_9Vbpknt-2<%l%2ipZDTFk=z?z8Ddg%dQB7J*n z(zwvHVNoIa_HY}%qM8N$|CSQ7VUP8c%i*uBaf45?Sg8f>OmJ~|cjIjQdWG>j2X4dt zZH?GO!kUTOOD||)f!#GY&}B9)_`Y%mtnn%rEyGClZc(4(S#ijRFVc@Dcu0nVksnKFa zdz@ZmcWmz;prY0UA$p>n^LG$_=})h3hIIpq1@4Tynv6e^(fi@cDFWx60^t3@41BFk zOu3P?7!K18>7LWDNy*4aJ>SXs*msLDt*|}=acEjZ0JHi(q%(8GW*d5O_=yoRQ(*+Q2HdnzJUU0M(1Hwg-repDWGXykV*hy zrg7^8{9*+y)bx;UyDd7?W{b(};KZWjQfPC~29UF}-nh&Hq5llOiVKBa_fS?zpWMsg z2p&;=CI4Q9KQgEW2ep0$_?W9u;9Fn)wYgWq8fTm9!;ubYBl#yKn$Kb)6XGcF6ATX> z%|vIXd#F4Z?rWu2y#ICpb#yoTMLhQ^uz2ZL%DS&3UyE->fN<*JdVnB*K7{GM0p@nj zu{cS3BTVQfR^w-W6AEy8V4%UrHR-lqw#D2mj(U)E2TiHs=)BNR zT`)y4^t?vpMv0j+a`$?L?IxEK8z0v7)vMIJ>}%&$BJHpe2QBXVy{e?Y|L;1W+V9@n z)`ymV3zF%6;D03bU|XsG8rp}*^M~6y_z#{x(pHMv2b;jelmC3CQmqS#KcQ&X9i;&) z4cvKnXbl)KX;cG7`8)@YM%%n5M9V=wYJa01x*C&59vY=IPHM|;oxoX>27ZFRbqK|; zR5+eMFFyYeN@vs02whr>&XXMqDXt)teW`(c6xBbj#7GkNZ1im;Vcq>Gl7J@~JfHl- z6ykN1yD-5YqBe9#oxmOC=&~_ydJ_J$3y5-WffN5|2WqxFTaNvFns4B&*0&H0;8uyo zrt?=JLFn)hZlA|_p~vA&wp^9qVR9Eo8$szg0eEC2ooj1!YNHc|bG8^7p*#WklqTXh zw!tg|vYDhzr>-1tV7Y-kQ_jK-&>|)0;i(a8A(fOVG&>;6tXbNvv zmk4pZ4@2WX_e&t5L9J_gN{#oS8tK&iGNf{!wsen|-ZlkT-qybYiT3{PUHA!aUyS7} zfd?I4C4>+EC|^Q@=^+n16>dwdkD(b)V+L&bgo-Q}9jRdKhKrOY;<#Uf(VYs(@X+F` z(btBBI=T@G3k~DZIK7L&<8jIwS{PV@e=O_>^g{x7+Kb}8Aa(hzX;W9(YWBt@My69B z%eh~NpT#sWsOw2-6efr9v{=ClS1NJ-tDfO-DD}LJaMaCh_42R6@26C^p?d?hXXlKT1V5m;IPnhQNygVh!-_z z#1h^iw1aFLa6ALw0R)GJ_%sexU~=PtJ@xclFe4f>+ZKY@*4BYI=d}*-1S2B4EQ5+V zpB5N(x+`K`3Jl;!=sK?0NmS%D-(DA*>TL^1L zxWck7*xh?zX-HAL@#TIS&_C^JgF~N?XmFjb--*cbB>}qJBE`JG6u4*A+}ook#JGQ?b|p9}yo1w8h3fVQUcb8+?YtHq(nv`f z7UI|k_c%oJA^mi~{sl^UXfXCJ-rigGf350jQWe@rd4hKABhnG-{`eoN@M0X57JI|* z5Y+4UL!jXgGJ0pCe-gmXnJS6pk<{X2MI?(nI|vEKv+&0K8B9{leF(-NIf>C6 zp98cDXdmE?gFIhM@Av{%G}cMS5vGKo%-*0K@)kT_U2;*j= zBM|paVzhHn-$AMRoKL1u>p;lAxDl-c4o&eu2umU7r4x=|)5wTRf=_(#3E@8lX~=Y* zAU znZfV8I7{(+4dw{v~!NC&x7;!fmpNo4i*hPD6mGLhkpG{ z$K&uX+>F6z1Nr0&`T=6OV&YO!2v^GTG0poOZ9Ky6 zz<+Q2d)p#3O9Cq$q6ZRvJ^t-5(;uBD!k((YW=v>(G13R;?P=`c{tIC?+}u%}g%Qom zIsDZBO;PEM5@Yiab>r&=Z2CzvKDELkhd)*45@=FIlf+OoiP>76`PGJY#V8FZ0&xgV z`#_Gl&C`d(Ro7ceT68$XDTD@Mpl0DqE4%D|Y@WV8vSlQTuYMrw*FX#`PT-p#d!SDt z!m3DICRRlf0y86>on@#4`F2$|zW=d1U3C$dX4Owe<-IbH^9V;I?toR@Lp1$zbVWex zaS+aarLS8l=~#sd;tg0opMaJ728#{&>axA(N63g%fS(Y_A~N^`9YgQ|t|7Z==Hv z&a{EJ@R_yV3awI=H(u~H0D`&)pPzeuMUE(6r?RgUKj|+T9{4LA1VPH{?`!1m=h9!Y zw>f5b{bjxEFDvu<`=IV=2SMG_9#q9P7)FjQ?jY*`bA%h$?bzu;pjJ`Eag0GOr)Adf zfyYfDkhPNWYJ=})m(KuvhC;1goTUd#cT%9D47xSQ8;*g78-YWc84e}nWryzj;7kbUZ<}^0nEgVSi{eV6^u0*h8XV>K;7wXL`m_Y1@uq;xsMX%g+~iqf$cyu8R$# z;xpNN>*6=jIZEzl&|caVNc&H?E+s+-^|o&!CDJc}0nP~^ zzIuz-J2+MiOZT!j+F)-S+e2UcFzPvD?J3Y zISJ|O7z$e~z|);s^@Cxi4O|G|y{;}`HzdN0D)JdJpb2Y|tyN@>sv_7$l&7H@lOQS! z|0Kz)dmihnyvuLMn*%!=jw-4>xymgqcy0fTZ{E#J%S$h`>obXJq{~8hvX{|=g zC(N{GjrnMia6z!#jAKa;QO_I%L6^q46dJVDwD+uY-hN7Dfn8!<0aw$J3pW}C%*QPw zCq!Q#9zQOchB~bCni$pu@RkyGTrspuvbnM2O(Q!BAl@oQSX2Ey6hwTwNWi?B!+&PU zz4$ds))V!(k*+3F`9a$XvgKryiJ9jyI2&YU{B)%FhTrpRY*!%YVk)p>ymy+;_99nd9cydWO#7s&4(rK3xUhfF;tMs^1lmvAzu zt{Q0=r?wb%PZ`3Gvw8vOJp<8mh62Qf`fYS{B#%qbv7|b#K~B+*pc@UOJ-t>L+!R85 z02Uy_r92D+{)dmp;3HPO_{6lmj7Gv}rj&MDT^HCm5)igkUm^TFNS62IsuyIuC3Q~S z6iDixa>}G_Xu#^OD~C(0Cfd_*^IZk3u`0?nP$HR=(N>D%BF`!au>##w38So^RDo=G zpZWhQt~UZ04WXyNXvhVx-F=XJC`4gYh%l>aEkx)Hc2R&b>m!NR%a_*$52Yj`snXgQ zlE@~rK92O~iBCVUQ_ zZDZK_%2oq$y|!;4yU}{!J856fsYk6X?838)n~Y>Z($LD{*t=W6c6tz(B#qELV9K0)H34(pzA5W=%%M}VDv zb>FgeM}D#kHCy-K0HV_2r`*QzOI~t(j4^@1^M08(q$|BM(wtoJinHO3W;=uCoQB-jlhMPZkn?03e!qaMb=Vk# zQu!$)9X8f*5wbk_n-a6P*y7OBc`@{Ko*BT6JU0q-X3~25?#sHLkVyD6G8Q$`k*eD0 zWLc*QDAX7Dh8i7OJvu?^*#7nRA2T2tN$DOe3Yh0K8c?Dc_`hf6P0KL`#&Q=z-#FcK z5q|1J;DeQ_1HDb)#bC*rpIP6BqA>#&me@$coq{OV`BkVPCIt>NThlbH3;Nyh)ELVYAc!3ELbBA-GL3ZlKFe$`=BDM=<-u=*_oJ;~Q9TGl zpLiJgj2`nf6th(MMxK9N1;lkvJp$!fh#a7=7Eu8x*JMZKUv~>j%!7m)19P84Cll&E z_FnJqm3^{R8zw|1R|XD?6wp2Mp{8BH{9Ht}ePBB7?8jspE9bIXw9 z$G#99fx(c-8#P%UGU@9JThju_S}BHdNMkiBkN^IwCQwv|{CNN1OR8`Dd1i`dCYw2x64~1vuOdJxe5bvsmXNC{{r^7^*{=*iTZBr0F`fh4Ep|6HF6@ms z%!0&0?l!}4&NiJQgM9?#E^!>#bHL|Ybk+MJK)A#rI!^o3=+2!9Bf9WuaMDDst?Wf> zkp*7eVU#j?FA3FBEC98(t-B5W=2Z7AfkS%f-H_`u^m3){!RXDDFH+J-NzNwG8bfCj z_EK84c(uYc2BmngL`xeZ@0__l!){$egPFvY)>L#QRO=3Gz1ZE@@31$lqJY!7j^6q{ zvWJB1wuG~prY$TS(EB}1C>F8h_b}w{7o_VEq^r*Euq_?zA6v}-LwWKWnPWwmq|-6h;Lvu2CKM45 z`G=FvjTon2>4m80x)=o=7;UI@OgNW^*I+4oT5}7R=S0c0v^)Ky>SrMc7zcW8f=~mc z70lO@nGzc28_7&5!97hqq^%-~!S~Hz81m^~oF>185q6z$(zdm8_D>i|ZF;!N`U66ktN;rS~qsbO%*u;bQN4eRHA0#9D&mXAhp4;Gn zUzTpT6(-~uF{ACD-Rmn#dA%0}LS47e52Z^!T!b;FRrN{EK@Xby4k%+|CXuB@{5ABHUs%roGjA%DFi zZ1#hiOY+P59b=^X%XPN2){oM#+Q#EfI#goP*KK$-g6uC#3|L8yXw1=<-w){?pdkTeNQr!-A@)$cIW?PkY zb-i4q@^R)r0or=j)5qVBSm;R>+WHSAnR8oZVx_#IOZV)A0F8!~J%#@zSjq5X z*Ss}faYW-~a11v#%G=n!!nW8DZDYHOZLzu8#`aaV#b#xzE$XGg-!mUWy{yL}UDP+D z0XHNdp1VOYF@FV?_1LwvyRk!vrJ|_ZK;82ic>cHJdoU7ppm*@Cg*4$MdxOt)_>^AM ze;ONJfZwmV9e4v$d?iyttR7I+3fUC!OEmEIWby$zNxzaI}N_rTU&N$HeXkF%Dx zrgvarIm3$MdYWJV^Ov`VExG$}|42HGaI*dRIVmTCi95*>q=l585T%zzlK&j3}+ExmoihL2SavB2k+fbKzk^a`VcY>h~Z?m0{>-Sed-p?i*4 zW;b?&Tct17J($42@2^N8g1UN}yN&0!>z-pQ@pY?&?m6BH+-=hmQlOV~~II4*;28=P){Jg+x5oPh}+z|BK( zYWS73c!g;#_9K-4<0${$?^cxN3od3X}IYeyT z{p6O~vjIq7`ty~>9<2QQCNo=EV>DuKv>_NicUKkWv2|}yK>8{-ucHXau?TA7{l4A6gt}9lKq2H4>V~}9BJJh6j6RfZ zp|ExjK(g=`7Ih<9EopPsfy2#wF2Mf3ci_#TrFG+3X*hi1i*Gp;x+jbRq=prq2mr1W zY(S-m^jfe1y0}tg)?-`L))Yldul`i;7={vq$2Zr)KPxe2_$EeAOj8FUvO0f0jD%b% z?^gABN1}cZ_zm&!LG_njf4sk$_0bdt`WVCt16C^@$D}2#P<%^}pDnXZ70lg5IFwjptjeZndB}kb69QzGT%W zB!QxM-yM=2%ofY+Ie!PVe&grnG z(fYB!bUsO6MCUpUH+Ir&{E;2KO4~a8!$_4*(ix5$$kvP86Oeiqa$M)jb6iiTb^hKT z&VA?a1A)(*zmv#$YdsiK{rmjgptrZgw>;h?cUbGe$&<`!n6NJg19MsS5c^1A%GvY~ zm}oXl3}+AQ1Q7>C+1{@4S2X7VT))B$_e4Z0-9I3ZS7Kl5^}wE*K;^|>JNz%m&CJd$$S%sI13qXXFe?)DPI_;v@WWu7XW2bJu2*IU;Xe1y+}G zh(4W5G?MA9Y_pZ=dba7v=4BOSqiy2T9HRGS8yDI{(D?c?o7kC6bYvdUhHUb8ZZ4V6 zmJ$7C0@0kPA@PvuNxs;^$sC?V=7db*>S07zR9!VBSZp1Bb7`;$96|I|Hm6sS`PWLK z4>7IDA@jRzjse#u2Ii24eOW~7YKT5sMD!f{Sk;UCN@eqLge^>Ls(i27Chi@m)!4)j zZ2v_HnXeeRuEH+<46QG-i^GxiWx=A)v{~>gZ0M}gF!AE#De$YVM}1k87*@P(P?T7h zzip6Bv=18+A1tm9yCmLUn>Ub76F*-$tMqa~X1n+c+*r{MG>*B^O!2N*HwxjGu(yeK zn9kso+|-*w64{-?Jl#d~yArL&E~bTR>S`o6>MV3emk8l!h5)pTr^!dy^}> zgLGDQCOu2TelI~7IBl=vF#j^33EJj$BRVTb3`Y5>BKcqX5dDhNvt~G%)10Isv4G4^ zvfEzW#bCP#>PYqvrPPYyYZJ4;ZWD0C*`;xXhSpV!alAN7JHrI!f@52hn$1k|-<#wTTdkygl z77?71-_(#zA*b7wgQ%qaKI*+{ySTdBfnH%EyC0Rhp}AE14)>-sxyMC1YX_~(w}}U* zlKDE={3N~^Ky@}7X192$g3Mh}>TF^X=kinIsDxa?>HHa&_7t|CnM`@HuZko~dQ;lI zF(rOU)i%O^mpO%Ikyv~)wdkxJ0#_@bPeZD zCWrQ7)_Et}7s>D=Ji%fH^2jZ)#e^$OmX}dU=!eh-i)56UVByC(I2P0qxr-DD z%IaIgfBz{c9SSqG{N1;QG`0-vuQ$WMoZL#C4Ybq#6vd-cdkN0odudS zpxgTs>ViIs+?}Z={ukjNUAjlGiXgf%GJIOBvN8EQFRZdZV92 z%Nf01Akhj&8L1MjWRwPXYyx|Ik^oWT61!s;PWnPSn z&?wvo3}>Pzm#k5^5m!qL5tp*$7m8LY>X^VY`S05@H(4U@h)r>CBRA3%;tZ z#jT3H89Dn9dRYu%^yPpz@@vH|QO#Ov`@E4~ti3BP(wm|44xn0mRWyrvjm+C8E`vKE zIxz1Gu}G(sZy9mlh+6CeE&;;#lcUy`)?yWJ1qO{FB6`-M?hAZf|ber1FR0p)7HGpgYjeyu3i z{24tOOsEnM+>m5N03nyw!DvmT9vZGjv(l`W7U6^XX&u>JA9NwLVt^LU=*13%25Oys zbPm=M8DT#SyrEhbMl!93Yso%3tF=@^N6Pm?-lFzv={~%PS{9D|hG3K;#0u>KE!T&4 zftJrYWmu+bWj?-NsJR$XFHtKl)_VH5o1yjgK{K`fELqNZTd$4u;VsZcF%N6E(Bjc1 z`0$#wsmzn5b%}Nn^G=77s#dJjW-*eb=Vom_qZOFH)`}MGa)YYz_mQ+{ zbeGn|=(s{l7!3=Pyyfgp=IveDD)vv7>-E}=%#*46khYFdFqgVVwDpW+IoqP$&FBrz zzsI#rjAW^MQo~ja%7m;(+qBJ$Wa-(iJ;Z1l*Ue|OM;J|HEjzR)7_H{Av{T#42%FZ3 z-%Hw4j4tLf__FpiqqVH%742C@n>n1jwC5RJ#yVfsb}(AP`L|o!$tVazm0Iz-_A;YK zS<4&RE=IB~cuU*OXeCST(O&mSrFXP9nfEN`(FfXI=Do-0L+yPZ$&a-Ueb52zQ+6lA zc~JX|kqqY{?Q=#4IPQnF!;EC8k7`F4HE`)UrhUZ-%f*PpH`>=+=3m3X+_TzA?Hhwi zK@W`JE)w5s-y75teLI;X&j3-b$oA|v?Gz(fT7TDmWOM=Q^b6WK?I%Vu$NnZ{)ncLl z!aS<)FK9u!W|B@>J32WM6%V4hFh0&*+ zM|pa(kGldrm3cB<%Job}mvUKh={byK%g{s5Vf0rqm>Hcj6MzRQX`cR};nrjl)rz{U`n*^B*hM6cmTV4l+JIA}`dchGRDqc&0#?+!has)@^n{tbF( z4VimQJ_DJBQvt^G) zXyS#=6pPfPr;WeOtOedM<%&9Pc)Q{*d&Wk`lESLkjHLJqUCVoXa8={JHWJh9!pC&$L z+9h!Te6c5aKx+~xMn8-Q1Wg%9wEtM5r$AH1D^r%Iri!$FwUMdpV=DWY%08xYKBlrS z&0<8?KG0TGPAN7dwl*>ebQ8DS2YdK@~dm>T`aJZ!-6R9phy*NJovnN0PfH^MolsXx=(i^+Ts z(-lnD7Lv`)Os7HKSAUYYvivy8?dPcvbqf^>Q9BBSz3eW~cRNvym{QOOp`BK+4YVSm z0%bmm>Cc_X{9WoZNUO^3lsmnLz5?_7!5&bb5+e4L?SV~jPond(K0xgD4mMfQBI8>dImnm4*d(X8`CpG$b6XTt3^(foHK>Bkx?SA_r1|k zVpQq!)KC%7$L2^9mu4M{&Ji8DwTC%5lhS|GBqw|v-zyY0Ny$|9;zmU|qQuO>v5ru2 zcPFZk5&gTtd_zKQWT?0>F&$=m=Nw0l*pA%H5qC4)&Gb*EN0@#m?c+%1F{bUqDa9(I z`XD`5qg3RGANmuW(5cL!i3!vCf{rO3gpg1z$Puq{%FA}?9mFd~eA9)>(yPO!f|jDR zYvO0*qb5R2h`!I<{ey->&kv|gn)o8EIy^@#A2S-EeR0ebgnWOWOF?HKUOA$^*L;{q zkGl%=$*wCvUoX4`bb0JL&vrqMqbba8r)o ze=N~cprrF%zbNswz7w>?XlIk{Cx!Vt)F4;vB>2^0OeY#V3$$;qs72Ug{ zCHXtGD_Rwz^9pZ*?{TTOb|<%YLgu*N-Jr|-ABDXP=et9xb#jGMjT;k1w29lsl91`_ z>N&`_7&}21nZI=)J#WH%$p2kvaB)kXUVSw*)S}#ab!LZu3NG1@{O2rxl(qc;^D_Tm zKz|G%8WV!eHOO>KixORJE8wbd%CTr@W||$|In9Rtjx$^24BGN0^t z4QO1%4WOmLw?Th;^+r&cFN=EI&w3sPcaixx=&oR*lOl+oiFzE8_F>P1-dVF7^n-}K zpmotiACDp0qvKxI@G0ascKjT4q_L#~`nV!*4@e<@u0xb?>RUi}wEqC~Z1`^-G|@eq zT879;C(_V9#FP0z8I|gfKs7P57nv^t)kL2$r{I?hR1+!Tzr##zvQ4y97|wsw^V4KX zw{4*R=9X#@g{r-iLPhDhqkS06cSI452<{4c+Li$tEs8)7Xgxvi4;TVEMG*bE9mT~F z?LkP6P8;jAi9J(lKz(bytf$gO(u+Ay|GSKIb>~HD6|ze^z1eDeky5(IXir* zlTzkd#BpK3jYR#3Hrt5aAFvKG2f0k%*nbwMVI%so+l4f5fy^3hE9lqy4$u~q1k&~f zT(wlZ11h*4wN%6+B+{I&Z1!7Rug(8PUK4L5q@!oqL~Vs?lRxjC?ikZFsu$6_Vu{}0 zgXru5MBgnSdbl(lA(3M?8h3f?g{&PPj5vl+*+vqL8cXyYrhVg2!Avp~yPpx$u71B0 zwc%NMaY2W6pf^SkJxL`1`U7uz55Cz+Zkvgu*&fSyxhyQHJ6mZpPBf18Hoz^zfu_YYruz3;FBS~a4q53jVnF4Rt z(74ML+YI0D3ttNAiCP1Cam-SL@T&x>*VlG-VkDp^QW&OlZ}o2f1IZMNkCMslI>>Km zPi{XC-w3LiRI|GJZGri;?PbvZ(J#Zt^y+s(rG`FZ_Q6~d@)_v1(nBb{Mn7sZr8zF2 zTFz~y$64k(&<`Sh1+9zz6`}fPn=^DAwJifcy={y1g;INXA||6~RgVs&y^;y7C_}?& z%ggi6(8U}Jwa+lb5{UvzM@DA&iB$?M9T^LBvn8ovU*)b=1m0!~`DfU~6BcTp;V)j7 zh;;^vy$X@eK(SvU@oQQF&~Fy%o)IL>t^$8c!7Iza?vaIhW^@p{CF1ynigy^TjyW-K zL{Al_~*q1)&TI?5zbWVfjqbRMA9U5rBHE=}i6C*`g- z152nZxm%0uc6mmkLX_5bX-Nu^yFUEAu-CuF3=Sk~iR`vKBSo}JCgB#*x9^P^sp2t( zuIzg|P)Lg8UD@}6jBer*gD5#ecul=(!_d3tHqcuM>Cva zpF*>N(n-up7c53HqHvyWmt~=ZZr^3(SSYgF9~lKAu^U;mh>d-<%tA4^JE1iqye2TS zSd6w%cxI`XtkBuggv<&tlhJBX-pQHi!YG2=trqD(J;hojc~4D#W^b`5P4aRlmS^_G z_}YucXATszXhTgb#yOD2%wgiFLgl@#&8!wR9I3^kwCCE)vEn!*S>|g*1xHbqi5f9i zBJuwC`!j3ATMB)U`&i}$;*dfUM?8}`N&If1moq1efJ_;d_Z@F#P7$Llv@dg-*khs3 zGcOV`oQP}06H|_7ULs~FfnM7K65%R-NIS|xf}Xj|5GV!DNPWZfVZTjX`kY_|rm3*$<0o ztQ|@p(zCaSatq~UKQ2aFs3iLdaixWNW^WaDSZHYWcCp1mqqCnDI~g^LRpUozKPyI8 zd3|`K)AM4Ig|=nAATF`cj;t3&orPY_dPy``=-sScVx@&9XTL7)vCxd{H^mDUs>^;` zd}5)d?Dxb^7K#-6#9tQbnEj!!xx67u%Klh{T4+V~ry|WlH)bCcJuK9c{h63xq4n9H zi+L6rn*F6{u+Zr2BVw6_9?JeoY_O0fj)~0{@&kI_LXT&EE%y4Li(s`Hkq<1|_vY-P@p?HmIZx>d^)bXoE&b6mUJBmi$JHXVe_9-VuqAO;fy?Q|9=c z5Hl5T-V{Hap{rNC6L9yf@F?CHxcgQtkvy~okvMgDy@mY5cVexD!UDe++bpy_`v>tp zBWgo5aa#Of@m|P2E#iB6)8*CdpT$)YiKE^3Wd9=8S?GPBhb?p<`;2&=QH#*ZzRdnr zMD!vpgnrEaQ(SJLbJ^#_3JbN%`CHs!AuOh7k60)_N7HsH)T?tvj;<7oUn;b;a7|8( z7B+x8AaqBp)68R*pl97$p6>ZSaRcaSCng`8iNmg`O_`KBv1j&_ciF zIJL_dHH&2Jkxm&}lR|?vEjLqJ%Se{UENz2@B1M+=fQ3fev$ZD~EkWM;=jLiVEnaAD zzIKoi^{`2~McR#nW!#61&&Vy&b}3{VQvsAbMDn&xoa0xbr7N@v^$*7lCF0sqqRnE| zEPm+P5AN=Quqwbv~)B)3e98Ol20?$s=pb|Iq{Q8Rc_ZZBDs8)x~0@c85Z7)geHe6dGIgW^T3iutKw|_5y8F zX!6*Pb4O_}C^Tp6=Rms^dOv-j7_Ggd(BbsUI*!)%Gm>dGMjKpBaabezrX0^5qdm{) zuvV6xg}wZmQN(K&)%{QBj>jT8A=%DP(9#*L5q|l9=1$P&D%2t0$eXBbQ0TgTL3uUW zN$D=&IlMtKS$lX4X;~~@8xfW_S=+^EsrYtET;5deCxw2Q5-DbA{$r)&?~uGii)XY{ zL{E*&o2d;_sLRwyF;|l&RHb*yFOiyR;38_iD-|OA#db8s6|{PQ9+OQfmSK>K-U9#4{Libmb?eLp2~YnyJQ9-*#|tKy~t>dIMx1- zyeG8Z7%dGLHP$cxNp0UHBuQ}y1{z=MMP2f@YxLME<)e*RAF14b=^+Uu9JgNnBl z{ohO4$(b@Ns|w5WU()7X>P7kauV{N1wFv41c4_)7;6s5w3s=hQ|7}*S~8<%kzt#yf21vDL@EDP{zuvdiBMiX&i_RFnb8`tukWG!Pc@fY zhU~ShuksIQ4_qeE!rtHKAJkq~=$iq41)poFb&{9br+dMdnoFUvMHK}{wObg;upHAi zDW1K1MZ_^}NxgLU?zABVUuz-rBH=Lqxll^RCf`_K(|cbb(Nn|jEC|$Zw$ObAcKvCE zHiH+W2V5y7HxIk7pq-ws&^O?<*B4pnzJg$VgF;)JTM9bpp&se3viJ6a5ItR?VZC=0 zgz9S*G6wA~2-A-%Gy*76AGJuj^B?zqL5%*oLOTZ^Er``mC=@yDR6(5Hu0cwM5B{?t zUe8p>Oj{k-NuQ!nazFpV&iYn`68d#0Ow>afrMt6TI~R7*XDKvzP)1?0{<=by7giRg z>Rqprl1;;h6*}}9g&M|=E$ptJROtS3Qwp8>tR^XW|F}7Y>3U+b7cDHz)OT8FSz)$5 z_i8Wi*1{aUW-+1FVrt1fg*cDRUDobodJ@n?~ zN+(KkPyI24A}2=__12FlG&3o_sIMNgLQ0NJOD^iC-^{2*T$7bv)L-AVO8R#!tFUO0 zo`0Q0!Tl>R&<`jyaC#xoSqn`p8mY(MAhisfURN|mU%OhO?h}_4P0+U~ zG9#aHN;TfAbRtqLto?NxlG?sq5a6vM~&Dqf^_Qs}wrVa1L5aD|p-0qmolQPnyk5W4>uyqF@do`qh5Wk^+OAOd zWUXX_{*pqs6=@}R>w6esHdqi+vQh7{LHb^loLI6+&roPnQDVt`dNHGBe0}CD*{ttU zytNaGN*>Zv@0RY&!a*gE==qGA#mbbCC6DS)Gini6mrpEtOi$cMk}a4U&MkRTpR3T) z9+#JF)kE%)yrn%FO19}|6?$;^;*zKI^i7hNn0j5wc73=)O?m4|p3$2WT3B+K{+u3i zpOpM+(1Rr}=yzJ^iINxfrxiLm==qYD^!F_ETFEZ`q(b)>>??Uq|LuOM<=41Hs|q~?^satVp}|AHEqPB*d_cPUy!y|Q5A@jzZK*L!Kh&En z6jb_=zWPBaxuqt&bie+Zh2ly-)%Pn@os?X9P@nRUl$?~5RrEYwhXQtzzL;Ogs3 zzt;;DItneP^u7u`3N1hCqZr9{_a{AZi`4mik2^|#(uXRPnEz<$FZu-vT~PK$>2LZX zg;q@ctn?3kl|na9{igIU{V_&s#EYqCO3&$+JVrX#h>;T#%7n3(QH#i*R$itXF^>~Z z`feDDBoYG(dg4g?jf`5v3pIU#_9=9r)8=T?h<}3IwTJ_q29^04H46RQdsLat*rd?8 z-h;~gje`mu?>!orE%a(xN8@!VDelV~DB_J-+bJwdf$oowH`Z9_rSN#;Sqr^W*2y@o z(3ZT9$~qejPfK^*u!fXiJkO|Ee4qDOS%NX@8Ock?JOXs5Ld{7>$`Xxs&q`i%(uuMp zBUYg~gU^(8G13+4b>TUnr55rpPd08*XvVNJWvRwyg<_M>0fjs#b;c$~mOG5O3b}`z zDRUZEE2K{-7Ea?%g;E(krBE=VmlTR)w1-iP=sh^8+-bCXo_rvbS)O5xvrtuewy{Z} zk;9V8^Ngbw$}BH1vR{zyMh>egFE*}VB*!RaMvLSHtmrhLsLWWW&@G)tl$RL~Ds-&h znDTPtafN>DR|E8hLa9YP%PNe$3Y8RXj;=8FGg>X4FBp+gX=Lpn-&c$Asng3VjVTiG zUb)Md#i%79q5q}jE~8$doc@;qEmG)Ir-kJ`jK>r*Ixj5mX&hm+M%+`dq`a3A^&1_U4+nvSOBTy+VVgPO5MlI~6+HWp+iqQU0!!ysO`WiuuN!A2H%o@)(OgCbULu z*RQYe7*8uyAADCugVBG#Vn-bVaiuJ zkSmOS{m8#oME1^u)XR-K6(TLmjSCM-9%)%& z>}S+0?#+4|DDgAmtrqWf|G45>V+x~Yu?JyUWh_5LJQ<@^#%4w`M%NpkFlrWS^x69L z#xHGn*t{cm0XzB}s<_^`P@(sLZZOtLB-ZvhQE{V@{{>584e4~nYGa;4tAK7Y_A2x! z)}_`M5r?JZ{bNUDtTEyhvXv3S_8|UNi+88|QL)BYuF%0LdgaZ=R)sz+oNwH0IF7I+ zmylbGe4s?tvfpC7%DfiQ$2lwL7GuAZ6!ozqGFprqk4fLdYXT};j13A6$_%f(%`m@~ zyl4A`SKeX7DC92gRJqP*I!-()S$B6?Z+y(CIiT0XzY{hX9ll|n_^YUU1+J-ft{bXlu#X%FV`g3XLCd0nkQ;-Y&Vg z@&V&{h0gVuUHPD~=cLpUUNf`fL&nb*T2T40QT&~k*HrnaQEQ=TWC$?6UJK> zy0dbt@uP({RX$}zfA7`uaOKlRe+xZT`K&RQkt|Ek8~LY5vPFbU-&y&*F+rhm6W^@d zVa!q}r{Mj{7mfWtljIt4SbS2s)9Ct(M19+TQ~9#dn~~J{iV^uM@hIg_SH5EOlPDm3 z+F5g#F`QAe7&`Iy%3a3I3dN7ts&*SOzmdCU5kJjd^}5mjPu3!~_3fAYhB1y&v)DL3 zrs_>2`7g=K7?WQ0jxk&z>>mMbVAPBgA%m;-8cWVf$tOpQT4HLC%)IElDw>7Q`INN!;D&lZOrznPmLJ*91C%;4tTZdfYF5!#ZMET8EI`$ zE~CZbc;KF@&x}4kyhFxti?^@pkg>{#_qlPi;%%}YsQTP^TA`Oh2%S=>Eb=fAKK?{l zr0-uCc1DZEXZCNZzA&;C`XhwU427mdo&vhk$K7G$YQ@`b-ye9`ctoLnA%tFIBy;ny z@j)AR2bAPv;@7If#$O7hwLe$&rJS}dZC{eH)cbqeh>;%#3W_xea4Hy%;E z12KNCMz`o=iHNcwQXIOF5)gmF$ut~aKIpD<$mWjNOd-w^bzk*m2VU6Z50-i9)pZa@sg4-HFGh zc5|IJ`UgngPXPU7Y*Og#)T^?7Hg+ns3+NZ)Afsd2yy`sH8RM2fa(7I7HKoG!o3W0O zEIq#)_qIWgFj_1^LYHR!ZoI3|g2<&=e;7Y9lBx8kan{G(pN5}ZhU`bb-mX85_6ptT zKg9Ky5y?pUch>0Sl?)o=I%_z6c;}2f#rq^^lIxt&*N6AFF;wyX3Yx9|ZCu)hH&5|y z4ZO(pxACw-^FyYE3v(AE8EVbk>*G!{_bbUqjZ0mcc}Ss+rV*l>$9&uw=4l^yhWVG0 zObNKmWtg3VDDE)lD`&Rz~%@{_DMS18#SD@)+BvZm}7Wqip z%_=4Ni~m(FyV=i2GRUm3l;h!V416(Ia{HmkeglY%>|64f5GO} zjASYWn=6%Mx$T$mVDnZVUI%l7;_V2$$JN0+=)(&!k1F2EkVp|?#ss&blFf09Wa_4vQxwk?@~kVxT;Rj&W;QBb7<}kvu4W|T=P=j# zNIJ}Wm1K~%%jGbiRp_$zZ@IdgFZ;MlGvD!Xmu7yXBt81H@HF#RgIDW}HGP5rlJ1m4{Dz{nDKh6Pv>mNYvAI^E-_hEXn9nJ6Ia-@i z^9zNJhkWlUGfVLOjW^WgW*fkcpP{gogD=ggkT zm5?h*NCJce5#%CwkZ_q?fIzq=h)6I@W+utVBok&PU@QuVN-3bFh?j~Ag0(1WZK2gx z5ev3zt(B+r!c%Rb&{|vCN=vP@THpU#d!Lyz3HE(HydPfpoi%H%z4m?Wwb#C!lNA)U zPKW(*27>uj;V!q35&l6;(|Q9D4i6IF&bavik;^%%xT>xLjs3wOL%weKBLXEYsAR1utgY zC?{%aPGP&bLe61IY0nDTz?4d5g>2N4OeoYd!^i@sgjHr zGj5VwH1&yVfxAiGtEq9K!M#d8psC*(E8HIWn5LdjZgw}zBbvGy_es6-`v9# z%iTJxGA-m@Ex%z43(6OC*!R*LnL+uwEv#L>qr;NY*16l|Ia^qV{F4sLNqaG)LteIp zg``nJb$~sC#~G4+nNnrxl=(WW0r_>xA-1qJa-##TSU(ATegSN1!JgmdMowv;$l_dk>t-DSRVQRD3kaoX&ot$h7yG72_VZ~Vw zyKj+Rrqo#J#^+w+sdUSATJnzMKJIS0!J?df+_%atn%d^-pcw#tueVOwR%pm;xgNe*EOZ-gM; zm*jjEmOSdZ*WBCWQWcgw?YbXeAr;1Z7dzy-1ZqP9wME4f z!?XU!y+ao5Zz%RTb`(s()Vk&iO9S+roh-y@GOrCR%gRPabyPC%?m#(uv*j6&*Gdb=WO`uBo}OpSxvJnacft zVTpFj$xK=CX6mpP3Mi~uh4EhVZh5l`OMYeY>Z08;qQh!xK6KwNzo4mQH6MYxQ&HSU z56JCIsTO=dK9~@;m#NJn+3~6S0r`}s?vnnQ56YJ`_2Y~aeIJr1Z1KJ--_l|Asj~8` z@;zJF!xERkVck@X9+t@oR3=lZEDy`#gs^g^HjC$Saw;E|BQ$kqzv9Y0@;Xh03UVqR zm6a-9GTq5|OwQHR=;^P4s@GK7;JIS2T%oD_!D|ZlN}r}KPy1}(J{ik$&$K^3w*a7*v4m*>dn|46{i78dTC*(hEl26FbwB%ELaw?yY zNkfzte2~*V{cAE+Q)%)<-zR0Zre-;(ReoI#*VHvhb(II@SWPX-ud94YUdNPb>!)S4 z4!b>lY30+>F;wMnXVz7d56ON^DamK#03G&3+D(#(hj3<8P49AkN@&3nCrne0U?tDE_`76iUz(FHItUnnLM&O9XpLn&S0wae2ZW97}#~ zEK1W%2(7E46t1l#_^*Wo?VKT_h@+rA_rMBDXU{SUjpJ9!ePv}P{wl}18%XlVbrdW2 zszjW=GS!o_lFOsy?V)yD)xC&ILVW!7rD6D_ym-HcQtQqC{c`$Rx(X$E6Y`mv4pB5R zGgAtOmty_D@hO+zFDH45<QVNPgk}6b{+`zXz z;+*TIQfkAe5a%ZgsGL8WVCTf~C%CO{tsqH~cZlE4qR;`OiSy1}ihDKplqwtLV&Lmj z6#56&(!n`|*Y_hn>eb-pf z#Fwt(IF&(#np_@7uTaI2V%buXT!VB-l4^A4aO#Dvi>Mb=DCJ^;A5W9;#5Cg^D@_%P zNxzR_%zRa7$jLL(tSI*zy0b+DFyJjlQs2mGHzCh;y#g z0xItRy#vq6Mw^Wg38V)j(uG3Sw@=kPu9%QumEJoNTU?zU5q0`^oI5n&apMKI3z!4 zC8d*GO!(RngqL$KcrjkAQK`lqaSVL5h#-wts~uEoxvYU|)YFJI@co#$%vFz1j#CM( zGOJps+8J)*{}fip6#v^qIB`sTm4|fi1njec@81x|%XN93`$*ZM!R3_xzr0koO~_Z` z+fh^_W$V;9QsZ5XAZ2N1#`@hMzRYd-D_Bbt-vo-6@N093vjZ~@zK6%Nq$fXhce>cynq>T>Lh0DN}f8Bh-l~o@OjtZ5iDa}Nr?euLw zOCD|e|NB@+7Sk>ck+#%E`ldL&6*OQ(oT)|4#{PnEEYJ`T7FUH3N($Wo$ zR2Sv>C>e!+L-~6=%MXEl zwZGC{WhH)sKO=bm%dtI8k^Y4q=!1JKKkoXhTz+;8KxCWVdprc$C{;)!L3LNyWG0 zEf{yIRMuS3TgEQ`f5WLw>@$UxW>0?a8H6Mad@0i^)s=8hHHF%tvbt&}+N4{6`l~m` z3XP|)a?Ix$%_^rAYT_$j|5sdTvg-W_yzUszwodB+<0^f{SE~jUs&InPRh}Pv$Gx&V z#_#8(98c5gUnO}jW=T_fm3A35o7{;x#UUC-61sbPT3Tlm`T1-J}%|&BjPb0;B zvzBI}d2HF#TI>S6{Y1V!h5wGLGN`^*l4^xjz_ZoI+*TLxjVP=KXHhvXjHKE6GzG5+Bjqk@r7yBdO>bU)#j?* zRNQNWRzf>IV0>I=ODVO(Us#`2I$O96 z6|VZdC$4fqo3o~=P&@8rZBhI<{`s*U9764^W*miYn;xHo6vvNw$`HNrvIgR3@mLVc z2~TGH49lzD%wWsBg)QwXyd#v(EtAaUSNu%~#cH~OQs}*oP@L6llT}|UZCT2rGCnuq zLkG+uXyOajR15NX6kqKZIrN?b?QGynIt*2sDxE|~8lqC5eUCU!>8rRTZ;HiOQ`0U7 zrKzl+YEOmJZjUvme;()mF0V>!hu=qgn)sF>BtaA3uq53+ z!E1BHQFE?p=TU3{)SRVova!}|rTA)YDuL!${O4@=7i_cJ3%puU@^<`go4hLRN-o<~ zm?I29xS?B*%3uoB4$5=(Hd81;Q?zpr_QVaW{Ygf(4B-yUq2$jzrCW@~zUnU}LpZ+T zk5I|qic@h7=9rq}<$VAZYrzdx84U5INmP=X*jH5LR3lg63aUN8=eRX~#${Hzq}DQO zwWXk1wNaXeP_Yyo%&`=%Y?_K|U-A8dXLAMrhFQQ6?=z&mN>eoYh@<3*gLeL}P?aQ` zb$B7`@Daub@m!$R{+|cQR$FUQrA2nA+Dh$6tYuy84OLB5I(A&`Jg7Dt%(l9jJ!i$~ z4b?o}o3B$SrZ|1a=eTCU8UT+ zcZOX{t*X3GgO_u1^V`#juk?Nw@OEZ9?4`1e@T)TxK!*yF0wsuokBpK`s_c%+s$ z#cbOMwZ~OBeXR^9DRZcml+LTT3Rh_=+zwS~6=yt;Rt4=Gm5$0?!C}`<5MB5qHbV?Q zo)*lu+e8MQCyZ_Q8>-vHBlz8C>;P{Ecssz`0p1Sq-Ujb&@ZJXRZSdX(FGbKhBUyk> zQOI~HU@HFL_xZV*_-lvswLmw+T84`mE@$Xr7+|=DVK>7~40i(d7Y_j%_&O%uG!QQ` z{wl-e2Bo|c5IYqn!4J$ve35I4V=?YQx*c>Pn=4XossVm4&RpG&l$-FDt5`F4nW%NF z!P)9!2gQ0GuoZuqitwHCu^SJH=aJfT;vso{?h*X8vt!LK1DaRAiN9HPe(pQsvN%2T zH2yBwtwYX&^V8uU08d@?Av(VtFNBO2_m7**p{a%&^4WkdE-wV1-UWUUX_gz+EIGy) zuy}$|$M_UT)*4fcj}|o;&&#G|D~!e9e1Ln|tFLM?#uz*5HW&>o*@$vJYMhq;yzzi> zRt_xrp>fbWKk^;JC-#rKWCV5SipC@}$~E$dhN;8Nv*Le7j5RNcdzMWyPs=@?=?JCL zp42i__se41yc^BSC}ExmI12Fn$DMNLjcd$@P?B|kkI&s?y5(0UZ87&5IgQ(aPhFw# z`w^OU?IY$%`NZgh_ zdk7w_qFkCMk8rqU2bW<1%d{}Qlx04;i6o13*(Nyl8J}J^9r8z6W`~19cVrNpmP_z- zKZ0K`AUL^@;5mjF{RyAM&{d>rHy7zlgCw=p5{KcOKc~xai2LX;xA`INm&43?Nziwq z4>QMbmNa%bPB8y1mOR1yx0rK^Id3uNl;%+Xz6<`N#(9Pp7+zw@PZ&z{pn<;=s9<@? za5ES9qed~q({jqFt@5BTZt+2RTCQk(P6ix=@02;d?}Kv{bm^c$`jFxrGX9i&$k;vo zLwOc)Kax`ndIK)YNjg)`>5nibHr9v{291JpWA#;Io#h5;S|MZ}H7*zHWAw>U8E!Z9}ZFH+4A28}v7yDh$%?YEHk}ps&nV7*y*DW830G&N_qs z7D$~ze;1_Ap!cR4AW36nVbj0Cx!;lQsx#;fsz&Bla5_FN;b~dqyT#?>GE*78=o-Ui z2(o09;d+L5GThE}*>0?vd(w5ELAK>SgY3*64n4r|5W~ZOW1T1Yd!ak!JKo_*hmBzk z*CzSEm&RrBGTQScmOR0!y~U}WV$NHf<_Y7oo3KJ>&UrvXoY0V3hH$62065lp0Vy0y zy2L4*mS?Z~Y0`Oay%Sv8OFA`IHTLe9{|RC}YDieQM~xE(wf1?WFd#YIq#B*)a^`Yq zx=FP=VSF_1TBKQCa&1yETiRli+W)ecJ%3ShIZN)84duvWw&XS7mxlaCZv9`jo8(Sr50|1$*L_f56yu%fB-GDmX!w zZ#1blqg?lsg5FXKaxPJ>yN^THbLe{J1WjuHAeUjMyrW__@}h49Z8d6#k2SX=%}0$| z=NIv9&syh3SlylS!KwHLuR%8#KR}uD#A4@+p+87j?ra?Wed$3>F@HH13_F>!)A3r_ zFH-`JVMyn)c%=Egl>0cfJzRzZT!ur;Ilv`3%=k+TPs_31pC+APywovuz?{^#Owu>X z5i=v;($oOwwNt)a8cOYU=1lBL-Q@hm4U@$w#4^NbbJz8Er*3u5o4P%9r!zRN-P|f0 zNAH4UL-`k7r?}Sd>b#mfPp6(|{FF&!^MW~Kd~O=Gd3o9;=5IHCHDP+%CyWP8!YfRg z0WV{`H>DkPK8LrW-w#yUmJIC+Ved6E+W?= z^G7fouVtE>lFUL!ZrLm80msOS4rjpe&!Im`FLYckKAB$4+Ky3h)0y;(u=#&W-_GN) z0&xw|z`b0}wX1N@_^Rf5)p4yGnBTyhJ=_;{4jQ?24${U(PGOHpoJI$IDc)R9`pz_ zM5Z+@15Q?bJ=gb6hT9qL;ZalJAbmJ3w^S@ohYnADG2=c5{nZ7shqx!kl7|iNq_G%5 zA2pA71_h;VaxaYZ5PdVuC_ndO5H)#&J$tK*O zXYJI?3oLnBZX7x?^P;G1o{>34(%<5$l{C|xG{OrPWnOZSEj?>>MmsM}-6{XQ zVt&>L=8R`p!7$)RAGsszMMoDb;U*(z6j_PG*FTn3&7sw7QLFVR8+gMTS(k-x;ZFgV z)V-Hg$1)8J8yWf-lBHdm8boQEvd;p~PI1fj8@8BHaNf*b4|qQNPKNNircM@b2pYL# z98Zj%m~&ZFmyqCo2q8zY;r80zX0%3-GZF6!ZqU&c!me?H+$T&fUWMq30u%> zPmEp$`SI5@15TUQnsZS+KD0AutHVEMZO#YIuJT)R$SP*SDvCu9L8h_1-Mk16zFm&c zCpgyAIo)`#=hYm;b>v3k{0g(lW%0LR1aDcsFLSG;FLhrQ2RxHSij(Z~PPul{KXSHn ztuKqO59yP8S$qxOceyOqmrTZAF+9ClJs|#K9Tenl|GR( z``->oZ#+o!-J`}ON$*LdGk#irH2TTBT*i0G_DQGnUgR>rXkIh;k9illUoMI}rc4&a zEK}~J)*iu-B%N5PJ$n7%ek4D%ANBR9ex{-10Is^LgW4NV?^>p`UKK3Y-cj^++{xmxf#Bvu{5i zvD|Vf@J5tjth3Q1JK*DX^D)QAoC?G;M1_<5CAWN>S2S;MzAjGT30||D zSn?!GX0YTlEIEurA7(g>;cSMx8IEDNm*FIaUt@SH!#0MS8LnZto#FdfAGzhk(FETf zNAMTSnTEePignEjg4YZsIJl8uW(7f$VLrnYh64cWoHSkUB&pj zm9?(%*M2?!4f+0xm-CmqmUzFP?{VEe`bYTz*LNnK%wOyxUD{{nH2*Tc+eNd?eNOt@ zmIqLhM~zLck4OD0pX`7r*lIjCF0)`0;6T9d<4e|uATzh%1IM56hnn54^hrNRsYS{= z3r=E=c(96df*cuVw#$&jxupjZtINA)NC^>l)d|H-ZhWl2rt2T75>5z zE^5yaE~?`Q7um59$nm6Wysl9Z*Jv%Lvwaf9x?JQhq?zJ$-cEV_gb(|#asGY9Kl)d2 zX~`dU6`eMAajpLfNwfpwe_;G9!`U8x;a0hPbQ&a&a{GVNO_GNgeg(N4G}=hRje`^X zh2veM?KFpG7gcjEFPi&?{V}i3RgS+oMSCx+i)deE4d6W^b`}*%+TALZw2m%>{(r6L zJhbTAq(XUg*z*XbHT5vazgcveE%teMiLYmzl-~Xqi*ngxJnJgOU-M`{C~h7y9Ko8| z=wchodf4cq5!%3<294L=xTAOsa(oQ%=&&b?DfhZK8X)yemx_|v35e|u^;H5 zRZJB88nGS_D?8b|0)K&3_Qzj@4RXpsF2kLGG`k%f|8(kU+1&J;q@9zQC2o1wJiVg= zykXTA%;~e|FDcp1nsXob<38iZQ`!)^qDk%fgi0vxx{^J}@sW~?u1_YVP)9)yQrB+=hXp%scD zXzceNaDdDI5~py2A-qI<|LC;wGid%vDVr(=oHnZFQ1Ab_*0yu>03`2f8uEUuQ z4t69^{tE+hlgPpZoY&QY0RMFq~A}JMsdZHQ#tWLq z)3M|9dd6AfpF`i|ee(Wg)dsCVs|{LvRvWbTtTt%vxt-UHbquQwT8CcZa(=?)JkPsQ zr{P5}EhFeHJ7~UN(QYnwK3wro*<$C8ipR%7WUp3 zWS5sSznD{di9^?L+!5d#Vni~nOx;O+O2(ACla3a5I4_E8=D{OPCVO~UOdZ}(E_q#0 z4o?96!mxok6`XQ|dHbqhc{Sv}RNlzDI(5n9Z`UQ0zuf@->luxlS0nPeJv!3j1vzdonf|I}Fq!_sWiXlE9gK4B>zTiv z`FC<&+rh^d!sN*zWkbfZwq(h`@L@y9T8eIm4mnIqo0CJ>Y!El9yQW6UK!>rM=pqd`B>TtwALp zZ&0Zw8&v)ZgW}de#)Mu|%1aqv&Uk?FcHpKs!kqV*^C{!yCZ&9}xeIWF`5@r6<|BaP z&Bp;Jn@<8(n1=von$H7Po8KOiEdq#@EwE1qxQ0{M?I8Te41dS)1BMqF{sS;sNJ%hR zQjO9jwL_MC6R}Fc&xY?n(9aOI7I-_uH4JZKxQXEoh6fow511@2%C{i@59VBE_$k8_ zC#CbEi_=dc$tg)E!I{Q*E%0RFXZ$6G$C9XRPb5*RzMe!{@mA9J0N+VE26!szHN-WN zDK#g}Gh7;m!==Oz2B+8bc4mlB}&mO2xy_%%M1^U5&&1G=@1MrD~KY64`)dVhrFl;yS=_ zVkW~SfK$b-fK}oE;5_j>V7)jBxI(-K=oNLdYB%Rqg|7tOG0Vfa z7x=bW0i6G?9s2yhw-#XnZ3%Ol5b>q+@O+sO@d{P z>j0}9yTr!XUcj%;-VAtn_I|*(XCDXr#q4tog?w6UtaeD^3<7?#x{UFez+E*}jIRRz zRE-z-nb{jzW;5ga86IbNj-lcF9`bcKNm4q$MI~XpilGjQjXqp9 zhNTS47*;X#GTh8?Kf~h;&oOjlaM>7EG4wLr%y2)$;|$L+bo6C;hE)u`4EHlU$Iy|< zG7PI2dKqqJxS!#1hUXYMvRIyB6+%?$T5EXyXDDu$~VdKvn%Ne4DEzM0`(hWi;F zV|bk58HVQ=iX2MK!LW>B6+;h0FT+g?H#6MFa6iN249_ui3aqefA7Gj#iuo55W!Upk1^aknA0yOcx))aRaaB2jSTlP zJa!Fn&M*`s2$v(MY~>>fR*xd+8%^-cwUmMwLvRqond8!o#j{p1+{p0EIF=bt@EF50 z49`#CG$(R8Qz;iwL2wYmnG9Dk+{kb*!($B3Fci}`)-=j-5aTl~NM&GrBg0M8DEGaL z?_>NJ<7XI(>6|aanG9Dk+{kb*!($B3FcdRbp5aV}s~B!%xR>EEhG!UxnJmw66~m1T z_cA=j@C-xYW=V!K8E&eilJ8@9wuW$H7Qs@6qL%PM4EHiT#_&Wfw<_aeF3HTSBe;s; zMuvOmGiM>ey$p{rJhPC>AQo{+7|vWw_(q0%86IPJhGF#*%IgHfy$vLJpn*8Y7(c`C zJafcS%4-nAjSOclBTjWA$@^9kJl{m{PA|a&4A1)r-`MVeC%l)T=pcL$!H!|GIFc~-D&J5Wo?h`*Z7MtHP&zc#I8yyci{_Jqd68Vz+ zp?pXFRyv$@&aiWi>z}TPNw+3FnDj|fdh+Dt*~x2?Ur&}P^HXk2*^}~0%8ye1l+rJC zWvVN!f7*z&+O+G_TGDP!+n9ED+I?vcr9GK;GVRxCe^2X^UX)&%9!|d{{k8O8q+d>- z*~il-+UMgwB^eVl4rDx)@so_tGLrjd_buq#)c5Yb+xvc{Z+50Hb9d&GnJ;9%nfXrU z+01`r{yQ^0Yh2cxth=&yWgX0VF6&s<`&s|Y`ZUXtosxZZ_O$G}?AGj!+4p5Xp8b6G zPqY7){aLmnCq3tmoO^Tj=KL_{Cpk&EdAWmg>vNlOZ_eG4o0M0QSC%(AuP$#{-aC0` z^ZuQe)~}%7xPIY&U+DKpzbE_k&A%bPE5AGcj{HaSpUJfqg6@J1 z1$Px}D|oEncLo10Fbc0Kyr=MDVNU`#kW)GM@pnkxc0~Qag7*spxnL*zk^z%XU zN_Uigz4Tn^;K8>J{_fx(4gU4uKMnqPa9P>tvI%9kl-*JGy|P!!-YNTC*{5Zb%4d`> zC|_B=uKYXYC(3h%Ode7-WFBr-F2Ws4AyNlq1OBq6A1K^M$Ny{aUc+dSj5~{IVuDB) zlW?DLGFAcCi5xKlw+P)LU(6AuVy+kr-+72wAg+SGv(U70{0FzncEe@yn|=1OAKg(kWYj-#u|V;EJm#G_{1FS-%r- zAj7RQb_3tJ>|wy)jo1(P%6JN`DWh07EPE1g*RXE@b~E%byz_d>Wzi&p0|t=%aEARR z5U0;ohXIQQe-H3@{V~AC`X2#CrvDu9`{UjPe5i!dESPf^aN4Bz0VmA)6QC+{^NNeW zZ)*N0;INexE4q@(X2;#veF~1Mmx}dpjRW^-RW3z?Nj`Hrr4x^pEEbyhmVj6UNN>kD z&^x!85}exs=?xJlU>e@iHql=xfV)5$7`th}cZ)v2?*}x+1EMeR2LVm-Ec(?H&!JaM z@ePp&cmzFb;%{OXLgtTvruY-qQP}MQH1T(>OMw3c5buDAfxtfmG{r^ef+79}Xo`Ph z#f35$L%`_+h<6T+p@3VAVSryWt^wR?j0F6eF&Z*Y0-E9}V+`Qa#yG%3#st7;j7fmc z8dCtDGo}K5!19^k2frYMqL;KhKZD3N~P0{~4iP__ae1Zd*qH2_#8S7Utr5p~}t{?|1Q z@Lksgz%#B%fWLK30X*-T3ix~1G{8T&W?*c62+1AdZ;;#}K7!;9@i8QKh<`zHhxi1N zJH&q=`Lo} zWb872Z+vPDHkX-?n{S(@Bh4`k-l4mAkPa^r1k5C1Y2{D;e)*{4-;C-*J7X_O0$4?E7Tj-}U`#--65)nbFMcna^h88_HSJvl_Cz zS<$Q`S%1#zn_ZYaDtl@6vFvxV|Cs%+oYA=xbLZxE=H8Nfd+r0d&*Z+Adph^exm9_d zytR2d@*c_iVcx|&vtL%fhJLI11^V69Z%4n~{eIi;Vn2~TIe$U^1Npzs|5N^7@+%AS z3QG#B3hN6S3)dDNE_}K02ZcW={7vB>3cdZ?`>*Z)oBr?j|5yLgB2UpLMXuuC6#udK z@5QMlStU1=tSb3($pzJ|c z585>7OM`X|dVJ8EgVIWKO0O=RRC--$W2vt+Sh}n9vC|-+?FYKHTj~{bb3!YXy zZFmBBZpO13PY_nH9Z!cCAwrn5I`OQ*6UGz46BT1cml!A3;#r617ChaU*KWo01w899 zl5fLvyO=08V8+~t2Y;bL+<|8^X3slu_x~%i=&m(vq#q$`Ry?FNFc^uDv zJO}VRA!drN;dv4>_}4`x-Xf?JPvLo5)MEd*Ry>2}Sv=3-`39cn@q80A{I~EN7Il~% z>hK4;>cn^OynyFLJm1ChJv=Yrc^MwXQL#k4g69}Kf>-f;AJ1|88SoQ$UW14513W*( z^E#e4@VtrVM|j@C^J6@3iGp@cUE|(V0xsFVO~i?GSzi_RZDr4E^h7 zIe}V|oWL$0r9;1p#$6<)YcxGu)3Y^=*5L43P0!QxJWbEn^n6YGK~p}h`uEHF_xt+y zg#OJnlw2`>sXWETm;1w)5Cb$lfN9i6|IXL)3w8KH{a3vgY5o%ZdyoE|VLrv_&M;Lz zZqQV&yO@?@xBh)VhrgnKU)8_(3w<2_Hzt(}U-i@USxukQzrWM`-)Z`NO~0?{4>bJ& z(*@#Bn*Nif|E%dhYx=L6{;Q@hYWkw4|E}r3GcCkFH2n`v|5N{7*8Izw{32n)8SO#6#ZKSIeNdcgn!|2>fbT?_Z9v7hC{XY8=C%+{!Nmq{ZsUB zn*QyhfBWj+EcqaR{W(iM%l(w2=^Rau)^cO;OZqZK-rPv#bZdUS{#~Yjz4|wxe`hBj zDq4rXV821UVr+%CvhSo)XAYmpmn~wX+#qg|RR--0@0YXjJ0H(t zD%S(XW>=N*fNO);kLR1wdM>w~NT}fHy3&~ZS-p9$ajgOPJ852^r8B=o>q)e70P>!LgcbQXCt3V$#e~`M(_-X0}oHA@PMA|mwTkLqzb=2{I zYl+NGzsscZk8u9mT$KJPDMxA*Kyu0w%OE!q|%*Pxe zZHcVO%rfuH+=_OuLiqjW9Nc05%<;10GyFB6e0iU_3vIG8YlCRVb9>fN4yXFllP|X! zBv)r{6(1*WMIUVtgR{~8*?%yPntw2F&6bWs*?$9WI*ytjnTN7JLHtkfD;;xE7Nh(w z{6^%2lrB6GITgQCQ#ObrxwnC?GP2VnXqzrPM;$-TJ?fZ{a?~*uPd3`-Ke;<0ljE3{ zcNEVn@>TrSnMcu9RmPkY7y9J^{C8=WTB9SrIHeCzul%}S! zj5UPnqv1eD>-1)eGut1X74Qdr3q0-qNSxg>Ar+kx8qW#2z0odDaFHjBXiuUCmRZxiWKXtPdHZf`vn!{&2KA-f2pvNAHilB6oZ| zJxaKtyVGCEDRJ);tEN2=t@a1~t)8eq#_UyTt5jpg5r$G#b_G}4+Dh?jI|5N|YL@Dm zh?1!fg>_p;rlU)VT(3fU%8ym4piLQ>)fEi(XjkTs@_M78FlEam$~HID%pIuW_h_dp zGRKU!Dma$0s<0o;QCm0L-{B8?bn+^wXDP=~ggT$MsWz5|EeR?Xla_|r+Kl$m2T;f?* z+YyO|ySy}BIY||%XPTOeM8|R5p0O0SXRIr8C&!9a?e}+9g*v-wG&F>}QJ^`V4j(#l zy^1g5%j6qPAm+r=yj7RR#8pthtEHaZz9D^|*pCw`U~9r0Pu83a=u>jH2SJ3WWXf z^0T+|2@_u0!#ia9$RTDM*av4g>di7Dh*CVQr-xuhi=j?`n;PI2J9L<1e(D33{QGsW+j zlI9{ME1`t)L9MS?0A|w2SM9~khz4b?r=|d2?e_*fVZYDLi>o38xMgFiquqlZkrN`I zmYiJzb5b?4;FGq}MtZH5XY^v}GL;ZN8@?(AgE#^EMbu{OzH& zRy4c!$6;%s7^)?7!b+SAt2ro0UC8TU^N2W0J37g!(*6@C(g`K6xy9>`xi;XcCJI@_ zg(+*W2qefYTielMW2uI)@vcYFV0vvFYDMk$BywY2!81N`ukFA*p!4QtwliW)q#Oi@ z$8;8W6|6m*{a7d`(3@S0=?%>sHvwRgjjqsFjgb8FVyMp@cBEu-SOVz@kQp;9f|ncn}b%6)s|Y)%De}gYoExg z^TFT7K&g+a-#VWs+)4vyiQnU^4EcE0BHUKX^{R#qkR&q)>#@Wi=?X@{uk!^ud`-1u zEQe`6VZ>TGruTXV%MjvX)MHrz>~oeOSBR9^__4~+`D2j) z47It!D&q>-D{-ED$5KRex78Rl12d1UCZk*exE7%bbzF;K%qZxMpjLp{7j&9!@rV9}&t_q*y7oGu7(=S`v_vO4ti ziL?X@=z_$pJ99aK$?*gdeG-b_!=;Dk0qzx?2&)XX=^c&F#fq`Wd5_TitP92n3T7LX zY(-)MkhA;>)f(Kue&uP{rbx)eD+U5-vSb1?HkU!5$D{&|wFv;!HdCmy5+(=5N}L?P z>oGYfDa%S(lLNRh%MRRToIz2es`_ywfYaNJ;;Plcp7wNpXvCtiuH-@5te}#zN<~^v zgMw`47;QU=CfkX`dUic_GgfJK3`yA7fyJ-{#sZnu)#1g@0!#v)=Aa*FZA}MuRKgau zFzoZgsYzgB;$#m1(u)ul@M1y(zPQWZMZeq=OZ+WB>!Tj;YW&vR(i!$gXkrEd3$8!`zh)iI)-+H_J=)4H&ybBw5}FRz$Bxv2?# z;t57@#^wn}NuV8ulpN<^Hz=FOgE3ZHUDf8tZW98?U{qp>O;dhd2uo2P*3M(a(%O#b zxUmA02>{{^KjXe znHa0h1oaJ>iLq*w6Pq?BV#9N+H4?{?($lt!+ALTF$sY7PfA{sCU>6+8Kp4T*0UorT za5o6V?Kxn^iuSQQDo{$&TDV{1diMo0l~N=0N=gkjN2l05x{6p71|0;3GW6EXah7gE zK&vE1Vm+2a>&IKsClJ!wTQ4=&u9sj@hS*5~*0b#umkTsS7wB{P6Emw$iIRyaBZwaJ z9XN@)2Zl}eK=n{GaIT~&V550#!yXKkuihUFlLey2qB&-qRvw~BdB!Q_8E5IrI5t!h z$16jHUp4;mL%w&dqLHUYU(SL<+eC$KAar>=HPv-~otHmr)T~oPq zHg0RQVr16ViG@pQXV)%p*EP+rX_&LHx@nPniF>}NT~OcPUQkt|$t6n{G{pp!M16N8 z>Te%ayHG%~p{D72_YzTaLsiY9hT4S-m|9X(zqGD_Q9Y5>qn@0D zdxZa%XxJk_L_P3}_`-cUG5NHhGskQa`e$A>awdn3ndj7wPpwjPg->YmF+!tLh4e;Zv%ZqAuj|2`q7h z2M;+(m7!Z|TNe2JKEI-ub~M{KHlsxIXl;ZX{s2UqJQ{(A=MSSctHIP&^?QPvsOccr z+b1F@n}z!|PYEvyV4un-TAJ#}|E%l^1mU7L1tLwIDgX|swJU?Nw^nwww2%wW!z+qk zRHJD=IuR|l#P9V7)`A!2{k~pol_947fK}4k4k#6<+Q{`G{4DUVo85(9Y9n?mgq5|T zW~+rGyj`{Bg&`CQYqX-)H+^+eQze!NIFV8E6$^3j12?31fG%Zc(bXeW|}s&?RsB=cb-p%iouXbIwQ&=S&URB7L}b^p?n|IuDZL!(;o0@3B`tCOk|VQ)boTEL`)c6O(@3~Mc{*Ji)+~$ zEfj6@Yb?;QHniH0eTw$Z5cJk!BgtMoGU(QTs`NxGQS60=f@>{`nuRr6r%$bGr;)Io z?2KO^q3*Sk*O9^DZ7v_}FvNK_3d5L_iye<>DHs`zHHB~*&I!>i70M)mK=W!rJ&&sa zqr9Mh<<_pcwBDMh*LlKF0;(k@Z6;dLBDE2o*;;VtKO#Au{T58Xb_xn2%!g4>vn_F!>WMhbO?ZICaKC+ysCeX{tt>{cy(p3yAA!fe~g* ziBi*2@-T4=JDCWnpAH=W!`0=l_q6ye$8Z^T!kC6HtVcb26r7=+tHna7tKvcd$loA0 zY6+d`LqF(%(T>}C4SJ+PP$Y$@?oznk*Tdj|RYOudm_&SFS9!3tCa5nIW}SB`3f_;l zi;9LH2LD~*ZZA2v3Wt4!uLCP0D*d=IV&Or*<>6QwLG4!4u{ID6bDvX{0K<(C)^ScvNvMg_02!-^mp9 zn8cADc^E2DUacwA6X;NOU9aJoOJkS&lo6hy7*iI3QQQ~g1H#3$?FtE>GRw$`GG~#f zg=in#9mRFR=B}s;^(0VKSIc5@WL9B)`G*-~`)Hq)2@Ti+0j32To~ zRZ4k>qC@{ufz=5bIz`or<5^W?f+~YmOi0_}4r(DbZ0swNIw+(X6MX|bOK!)W?q;0X z)5FvuHm6e0x^$2zcp_v>TL9$87t3t39Tg!y9K?bU;#Hx%=*X^Ss-n(9&$rA$6y>R6 z6-5&8_d@HIcEFbmVNIr)t!Qf)E84Ty97J2-$0A!rqHwmOoP_1<#5okMjXO&y^<`A) z6Qi^mr7MJF5Xky7lcHKfiy5_%g)P>xMNEPwa3)A+Vnj6N2UwE(z5=PH6{ViGOYE(gsU~doqwLI~^RVW5pRbsO?&ar`FCOYP zGR(L4Sg;ZUrXr9?ZEa@TVV3&kpL zXOfWpBh+zyAWWC(V-oiBJ24*>!oh4Lb|Ks9 zyO_AUwKdFk7M*6@{)$Z|qQ)1%PE955>ai<=`7P?lw%VAcCiDVON(MhPOF{QXEsX|( zkx{jDd7vH_KlPjx3Xf_CSv;Y((-Y#6k?Ox;$w+HzAy>|*2LM?&TF5F7HV(zwk^6|L5&O?R~-DC}+c-Yd8cC{PZ z!wkhGcpoQDDh=T5m-vI8TNsPP!>x9}-m?$qm%Rh%$}?QTHd_#En`O`9@@zHT;jpJW z&O`V4tgZ~&_*SM=I1k=4iFKg1TychW#aS>KXb#ZTgLtSX7O}pv8v}++2zwDcDJcwv zB^&Egly*5-5-U2zge8HL!s{&roN9lI2P0httR+_kM+S5Zp$;LmqlfEN*yX@RFIgnL zv!PdD!XI)X2wRCbd} zVi$@yltb)Ffo0-wXfbLL)=dHLD0W~-P?ZK1ixN){_rOut0Mb~WZ> z2cH;;2bdtSpQi*drlXpu?`n=Hc02C3`8%;wLW^G9Qf|c=3wIk%5kj~F%U73MVTKbg zhFE2$@sAxLJ_Er)5}l$E0Yi%41{@X!(QL4Emb@Z-%tEF$SPs+V8QUyDSJQEepvx@K z2X+vo0ccC@>bBBt$1B&PC;R4aXj(;>aW=%|9Ww~?Pt zQW08B1WZ}?9E@qT5TQ*f9=(e^kw~;H9O^;{jW{eJY1ad70>GPMP(k=OZPEb0PxR*)cS*Cv9z$=1dy#NH!1M zFHNe=#K-1^LRwf$z^Mx1K*JwKl~${*3+`Zc$^`ES8#}Eo zJSk2yx%8rzhqVX^M=0%|z}Ek<#vi4}sjQV6`pNEk?>M z`D5DQKC>41+zTA5H4$s#=J;Jd@-6f)?);=17bK$E-@mccOEeOEYF{o z{%~k`kqcE*TS%6PL7@H0O^?8aP#t`wu&xj6zH;bbVuNTzev<($*8(qC;jkJp+-gyJ z1xdS*N{Bpg3rl!W39f(ar6rsrP`oRg)h=wl8LNA^boOBE7k8ks6qhwTcFx4DA3t^y zv?qt-C+z2vDXhaHGZ=Fcs{#riRps{vf}<=l?mrU8=f|qYE@#$g<@dQ(Gejxk&9>D z%1~wHtw+Alu(U%|^1TF6$+r@~q^k&Es-F-%TTcha!s^K5^F%!j*dFcB3nYct`J&7V zg0IR=n^)B#no2pUUTkscaNF zb-7mH`ksyQVHZQCP1>4x^2>VLgT*=>Zz84IHk$keTN7%>($0a$Y9|xllH{Ww-TcBE zfWGJ6$q-tnE2U}?4^!$4?=#L~ zXEaXgbQ2~MeTonlQkzwAT1Tpa9}#C_(~(LNXXrHJ41cU=dc2fQt^;ch9U0LDc(KeA z?!bi95+z7e7-7{R_JiTtG=$XQ0Ddvv=3*WIrq)wH;iWyGIG*0kT%OdRz z^)$eEf{A4gRy(|cWsPBuQUgX~7U7|sL}#a{?&`Gso+_H5L9+da^S{QLJ?a7-Yp^k(T|k~L&<~WH^7n|K z$YJ4SxTY%<^<(uEj@P!H{AUmL1evYeJ4S0G+84#G3_9?p+VtSGs{ovVb+H5{RuWWN zqL)cwt?>FjoA4%FZ;KtrS;6(4@F6|HS-d`jQKbVBwym_I4>Um~G>;d5>N*@1Qezk_ z8f)g8a_aREwSEZ0{i2@1eOwGBtg&IQ2*=uyeqt+S;H{XiRE1b)!HM+Z=tW7Qn0@0T zF$85yWT-u0``R1X;6R(+ilo~rR?cBQT<^(k@x#|Zgb?n@gi%Yn*@npt(m%>jUth!f^ia#&s?2SBMau z!XPut7gHaq5KBAZ4P#>f+d~NEUZ5AnV7@ILtum~=7K_JnFwj`;&_M>-d5Rql&~hO5 z_7dMXrIN%tOf5C2>#!@Jk6YYyp~Er*ir_mQbeos<{t(y-byRy7teF~B3mHu`;0CZp zqj8iXVx-fuPHhKp{6r4a1RD^PO$}{6U|Xuk?k^3vo-CA&4a| z^Ou?8OqS`v>x`vXTL)vK-swmBx{P*~?UgudmWZzrVt2MjSz=gy;#EiMPB?CHC;0r+ zamO2%V7lnVK}-=>O3;>24`FRM;)`Fw`vbPsuxhT@;usfcFdh=lnXuaw4{o(SwZkv1 ztmP8%%T_{t;0H4e`~t6S;GcBbstVdmB~fYt_JQek4Q-LfHdXZMQ*-T;iJ;}J zwWY4M9&o2ALP^ofkEjcbS-=~ydaF9%Y3+caBo<_>!NWrfe>}$id5Z`J872|f6?N-7 zf-QaOdi`Akims!@Mh9HR2>X;eAf#@TB6qg83tK8_Sxlv}=20$%oA+WdZ|OUq%w*M1 z;8=xK^JToW79A_D#fbY`?4NS7WV8KhGszM|ML08y?xgj)MIg}j))`gW3emN;-@1$l zPuDF0d?BRU5^C2u_t-|@l7%|qz^o0xJXpPB?K03rfe9lV3y+z?7zbO&Sm4K2Xc01~ zJS)=@k+loEAEFsko|o?qB9A3C>XIP3i1y|zB8Uj^4QaGT1P(I8{ussX5PeFCb_F9s z-4~3&$)r@lpbgcyf23$${2@%u;i{!UqTzZseeC-;g2ECh)&CLNK8t_CM(w2_IqoC; z`uzH<7Wjq+NTpI*dkzK!yzOJ6#`QYzS7C~K6s)+n&CVyb21>Cs^0Ab%Ux3MEHN z@>zC-j?^>;De5D>WP&}62<{G&r(7THCIX>6cxWGkDWyq@#9JxCV5IQBkgr)``rNXJlFLp)X1JQLzZ?KE>hqg(Sl+F~ot%s>%!;|sw?VJdFe5!zA zCnUlSRV=Sqa+pHYeH1b=INs3#dgv$$$2mxsEk>zVB%xSw-la#l}M+ZBzt( zKwBg>mP)h-llrR1DLyw(FCIpjy0BwQ5nX0&i`clHc(JjdpmSjiM~0LcFV8S0>D_s_ zsPyIxKA~mJ;R)N|+9)UicqusLXklSE6=cdRlAXF3)oHOQhV_Xqp`*lT6(>fL3$4;d z_v5^SUesV?jT7|Pn;XJ9N>5;R*(IzIM6deOx(xahPfHn0Mcb0HvvF#MMp7azTnNmY zNF+kwo0_5&k7U(8 zydXW(DDH8f%hU;31aH)7b~7!mU?uhWQAF@Z3SgOoDj~J|LXM`!$aJArnxYIesx#0O zZW>{kVSV;W9qV9l*l*>qPm!QL4cN-pEu>I&E~W6qb$1gFWsF6fUeNT-8XikbjTe+i zU0tz8CE17GOnl*odMGZe&IxS{<-uXsFP2_?cYAZl&WO9HHmM%Ys4YZ0@HP(H1#3v! z_<9nijgnFErBlS+XGOwg8kt^M!(!Qw5z6qco$2dw9ypd zVW#F2J^RtrVksR*CbC`cXQ-I5?DYNt+ygbTdIwr-w;HTFYjIAm;jJQ(QKl85;TG#R5><^EGNvV*K4c14JYCY+XHO$N^m zi-QQSQ*q568y)Zqu_^{vokQVeTAuJ!IrP$u-5mI9F=p>m^qxC{T9h`aG)e`l@8VZF z=w&&y66qf%S_@NtGORLfh|xDK(3IB9tfm~UyoIWnCvt@`MJ=K~#YnAaA1^(E^kyf2 zl9fc+#0dUZM$eZ z#Oot0Jn2N0*5GtA9vIEeqy~5o4m*B~;f`(;d*Eu4g&xIy&lMSdF#jSPIB_>U@U<1_p_#CMLy_ePy(t%+Wfy$%ypQHS)x!Quk zMzf%O$W}j1h9KZi(oZ=4;bZJa;;2l$nk9O;?AF-O8utIRcQ!C`Rac(BRsB)bZFjk= z+6J6dI|Z1*UW{WK2qp)(`cH8cu-R=G`&@4!8^Uoe)_A=HyStCO0S&R0=Y&+MWqisS|A zIU4OAk#yOL#-O5lZRcknXdSx_a#0 zo-rdbM$g7KNmPe_Y{%l>KWAfnh`a5;qrq+e8(sN)7(4#FQ$T*JF@kxpX=p)tntt0O z_JUNo`@;jNx@$j0X^nLS00*5bRefOsi|8SZ@672D^@6ox9h+M5^dXh_^a;AChU)sF zH V(s)XT^R>F8QZLJ&1D}23CCuikEfP}%HDmuI1bJG0Xl>pSKM|4$TH}Wlk_q9 zh!k6VJ_&8uw}@r_;>_+C;hIY^T$0TOJ1>Z&aj-cJ$u@^_S*dZ>{!uPh-RZ*y!1a%_ zTEfX{`K*|8PYf;hgc9Jas#@#trzMW+NkDN3+RI3#pW$C>e%gzu`=;m4%ub$UJMEM= ziZe)<9_Mv5Jqy&%^$mpfBgj~sNT=o6nIq}zoZ8Sd2Y4K6%xH89M6~02_MlxgbME2W z37m6JkI3EUkQ(25IYQJibswlP*FG{x{p@3)aab{MOL#UrlCZTMwVm1OJ6d=y@;F#4 z5hBJnZYOuAyJQ;E{dhi{JV+g>_DKZj;yY=3CeV3i=+kc?D!q4tH`myanw^U=q`1e( z83NyIjJU=rKyT^%&BN1sPM@J!ToyzZP^{cen{I1Aok`C>q*b1u)9;Ji_8`Au#tt68 zNH)Q*jqMJH_{P&Nevga@3Aso4)v`H$eQX=QJQi+UuI_$X^2H14jmCO~aPx9C4*}^+ zR%_K(el-o(hu*`$UV49)^fQ!)r0)cv zAn!Dts9l3n4NA4AX%#zb@Drl5Dg2dcoCca895pP?(0&Z`Mrb$6kGC~=ny~aV_YrVV zo@z~6u6h~;zvXk6Z!Izi##tlz7}#zO{IcCGB8*0$(P5lY93H0D@6v~QIugS5yTMkN zoTkRH@Bk&t$h4Q_$i# z>~)`EK4Fw;7|drW=L7~wLM|Xy(Fwo4Fq|sJGJAXZeiHmS{M} zPoxPi&B|hEM-8XBP`LX*uHVic9dg9i=YPW3dz{~GUAbNOSe`e%ol{1$#xEJ((kT-A z$UVvocjksYyP&{P8^u|$6|W0!Mx_(viV~ge_UCB+JIv!#{3fl$`XmrEKJm_@KoNZe zYYZsjt0*JlFHy~VQxBS*Q4{LeUS*nBm$Svtqj1kK(#2)V^&FaCdI%&IPmzXq7DSFy z5{DXa9clSV@+K@_6Eb6M?~q>Ge65&- zkFMNLxL##T`v~_s^b-(R1dStGJWAKGuEtcy#}%sk7?Id%JRN-~?ctXx5!6+mCyzsb z=*-a5;1?=Gk1z;b{Ofy&-$LBS|DorT{2F8!$e=JmU0XsJiv4X$d)iF?P5eW|N}Fi| zl)J_Z+bfAg0}RBDnc58>eGvQcNZ219<`-X|0Mp%J55E9;7_}6-w(~Q_Vxi39+|JWk z=4+B)b9S5xH|_=V2EU~^$y}a+Zn7;6pm0jg`U^)MAxA1qY%E;&a+iYU?FPfyAxOQ; zOt{M3%5O${-F;xSiQn@)PLFrO0Y2VMh~sUfH-_-Q)i97M(hNSsze#?rQ>MpfBNHzu zx=Qo71MY;&2AnTb#n}8eotjZ#q|L-8&i?u8ONAk`h>}M!OcaU8IvFcT%PtlSM+~%v zuc%3eoJ~hlykynFnoTgB?5>=Id(nzwyF9iL6Ux@8EE8aVcKu*&yCBlKeA}o;!i~~F znXSk)Z@WgHC?zE!_J?gxALe<6Y2oZ8xtyT{f+(YUVhjm?gBr3C!f}?muIZLiD8pJT zvy8A*-78Q(V>ZID%4cqrA8rj@{MzH;&Kb^IQ8`s^4NriRaF~Fm!tQv7CGVtbBOsv7 zKe>r&>T0nO*hP9*gfou(_H zh|6LQM05%?sL&S~AT{MrnQ_9Q@S7J7)Ghpl0+kv$)JZ_ozQ$foLbUd!rUnkwSoGUmKXCo(pKaZr^B&=VlJT(8C z5R0PHNfMFJ)kmJ8#z6ZF`Le_A?l~dy(=!u3&Lq0y*SRFpz?_^T2nGk?jrd~>ScDR} zq+6UVBt(&YI+tLYuzY_^&ibW#W)eoEqzg^)(cQon&L>SY_{0ZyEe6mTRTusvSawa^ zX@pSq1SM@8Z9fFFJU?R$Cl-WY{IP2@^32K(3ZWN_D80=Ss7me={c%NMfziY(j8r!ef z|KXMTUre6^rYIz|GU0P3q$^VC*Mhntt}MfrpUV%0+lPX(A}(K8375rm+YiMgneutB z$XUNK#1(PewGxikjMFtkSP_ROuC{bu&S%Pp7&4>j?%pR;qaTiZ*wJa_qSe4ehx4)` z=D(k(l5|lFam6q~X2PX8q@Uav-O38f*Sj+FBc^?}whj4qbWb$uJK%_XFR@+W)+kw5 z#yPCWGcs_UPFjRLb7d}MzLuA5wyhca4}nc4bUgf_GIsSJYjO z=VD!Rjo3bQWo)ku^{O~GzbZD8uP*hxlv&-pN2b!EU28bSpZ0QnCe?8$^+((}B zSAo2uGF%?}PIi;}x(fWO2-{-JGfuh++^H*5U9MwXkx0cx#i^M*ZDnp)ABO9fpZg_h zXhnxfT;gkjEAq)Twx38%z>@y=t~6rNOc8jO$!ox5MJZSb(iz})y6Q`?`|Yb^m*>hW zQffs-n&Gz?)-_;w4N#Zoge&5@qWomIt_<}WuwK#lW$-&?@+uDYie~!C@U8*Vp%d+e zP&92}<`D9>DQ6!fmnR4)XRd-cX|V$k?Tz+^GWRLQRI_EChlsVL%@$r^Oe68o{L2JCJHpc#`QhwAW+gfzS%3eBS?~{jlfC{5?0EeVGdywJ zoz(E)>#-b)IwqPI@V@G!zA*dAKDmT_ovC9@z-ChaEq zSUmPzXf9j}sHK2>nAa+SS2lEEF2iA|lynBgGh??Drx?rSr5JN`V{9RVo>>K7h~>># zEV~r~HHcgI)(EfD=QbNODT>yfWa@pxBARQNdXKfpa7Ux6<)V%)WLVFHLi4K`LjPF9 zjR-C0HLyF>eC0QT((>CInV@97L~3WWnl|gwxrG?13yOzj14a93s5@fuA#p$!C)BJh zW_Lx`wZ-Aij5f*?hxM&8&1<+#Q1iR($Ell-<7YD$ZhP34>=U;9pE14XTb)uR`8HU@ z;e9N;PEdz$CoL^~Y;j(;Evpj+8i_2r9}GKTs=!Aeu3h<9Q23NK^pzoA}svHaCBYXYHBj_>A@);^vh4cbC$arD6L@HRUL0VU28o99CR(WeaW1sc&RG zN@|?+=#^t`0|%Kujm36U*5seqkFgU9F|-r5i!S-|4dR6?$kYEVg zaIABLouyk1KbH>8fR4vaGnd+5@;$H4`r>+534S0e-E{)bc(~#@8wuZ3wf4uz=i{-4 zjqnS@TZz~1F@vb-xRJv{T4yhShL$03@)8rV3+v)>3C(0& zHieIAcQ03K5T8VX!Fl)?2$yKb}Vh+U7`^@LrS zed=)1mFuispS9~*uFrD@DXhwjOjwm^k8tDS(^UNADx1njm_KbF?_oAN&r@x+89#|E z%pxiDb(_=I7q3^TTe_LCGPX5p^GVK`>Fk`ws#F*fE(bY!n3MVDmn0T>V;}+bsdAr5 ztgr3k7Lo@ie@$d}<*UOi`S^`bsvl8NeHkUx*Ke=HKzW0gnNC;vVu%dS zHZ$(;WSf)J5+dX3bx6RyX5QGNr{{SNkI6Jo8ok|AJDoBSUJP4d3qckHk5~G3 zT~xQOy2J1Rpo(8&Px*rpIvN9I-2I@#(>%HRAYOintseb|j>s3!aXd|)pB4}*K4FW|6I=~m7D|V_b>K(djqF0FcM~3VZ7FQs z196tur2EdH$gV@uzA@vg3|SRTl56aIq$hmV;prrZAJoo6Ry#e*gA(**+CR`KmQj>6 zqIe8P7{+B`oR&@zf_?7mgp>E07uQ{B7DAt<)s77fWD^W*&Z$Iae~}2T)2WwEhNJ#x zmt$pDURqH*6{NQEicz^v=SWjA>SEZ!qjRpZc2QWv^~+&}9lBl1S9wC3<2)qCXz|z- zpHhk2KljVSjmlljRr{GOS8wp#M?J13EFWIXebpHAigO#*D93vc&nnJvg!|$HWuZs; zp`WY)|&^`YG`h=mq;I)gI zI@=>@VQidLl&WOybbTD#V>U;sCFu)yAEtLV9{vJ`bABgnqbkc;%1T3Us`bAnwZ!B8KEIC6dyia#^Qw=N(zs zcN&E2(9A-|=T4D|5Oj<*vR90aM8Z2{<;vQ5G(1`fq3Q@LC99))u8rNDla+ECC^3=% zO9?4=lRf!4*(koJz?(N(8QCW})b?>xXPP*@J)_r(69RdNVDnDw+!ybY3(QZ zJ|1@B+Yy#9X+G3US2hPyILS z(8h9%;ObMN;)inaY0{SmBurBJ*#a}e#CysMdsJm%&3%l+0|4dSXb9Tq;j^Na#2Z-lL#W7|4rS;MBH!1<^8Hz70t}jsRJhYQ9kd zx9v%d?8D@1RyCiGSu1|MggnvQl~A}t&cP%?twWQJZ?+V1lj{-~PmbP*Cv*sUixXC= zsaf-Kaicg}PvU~bXWOHqnF+vMcO>_gkB1_3irH!1K?k-W?gK7!#-h}hhzcM`&P4~& z$7t9-0sSa6O8w40EiI;*htT!=&{xtPWx^LDQ8~NxX62mqAJ7cx0CK4P_=_`cRGud&b2LTp<<9PgHJ!{6w(kYOyg%WZK6}9{^I_cH zg^$TnW^dZ;BAtIBEUf7)5BGfDupPlnh>%j#Vrj9vNF!p(vbyr-#d^{zLCAQ|#Ys)N z`PG|){$Kohf(Ck=;DRG3S6GHne!WX#{#CBXkx@$XuW_l%XHB2WKBz?dp@Qc}bhQqU z1yN|jU+)PwM~n`_c_NAUPg*^5JN@;o#r-mzdt=*Ov~maRlW>>+e>>~a{k*uOQ~6p1 zoWlB?=KrmXY6h$d$!+o$GG)EXW<6Uk$P79SB_`qsM=awnF>yABd+{9Z1)_6LgRb>L zgnKN`m4e~Xf4$S|i=ADl_# zEORB`5}??ZM_GJ4M17P1MJ(oR z%5B+-r?2s&%uB*#io4{Acu49EieXZPcKd!{&zWZ}ACHvbO)2x=WaI3VK8ZtI*hje01C44;hAm^}1K<`FZ?~+ z63@UNV*UmF^W5bJ%Uc$va!}NZ#3$2@8m~KD@x>4+ZM9KuDDC3T%s#VHZ*K5npINMP zvAZD*WHHq1t?* z9209xy|v`&TJvkQ=GSY@m+kMBo=~h*>OGBOp zU9I`EVr`yc4Yz*7M+S>UZzULNY&AB74TVy_S1dEyDpp;83B@drF=xt_8t1YAN)hP)wdIrL9DTp)drq1W_{#*P53G z1`CDZcDrus&-auV*Bbzt?5w%ovis8AUwb=Q)eHm$!9-@tA!n~XPK zwukrDmrAvyS!@0h0WnqdWcA5f^WAFm@0kL`XR4HD8&NLzqb&^4p-}8CiUVNE){9hM zC%t7oC6CvdZ+qi%PbgG|rA>!I838Ewq48?T7kLEy=eSjTrsvXJ=Zp9R>8);8Z*7jC z%eq?YYsl_ULHU1}Hbz^dwTfk6Sw2|COaSI;^!3N?2ce~KY}0cMjkB6V1bOHnh0HW} z6!k~wLjkTB3b!IT$(M)g)PrQri}7XzeZ2bkx@uBYeoD*7`v(gGt=SY;?d}a-k}`4H z&x-XT6IV~u^=??D-sYT(&N&xtGA>5`xmcvObu7!HzMyvOGgYX~i?!X-m%3jk@k-Ve zDn7N34_6;AS09hvSJY+tP${N0QCwIc<`Mc2l!^{Kd8wBC@hU?a>sU)(Dyst}gkSQK zV?}nXo+6yQR226ne-?4O44Zk=DbZtUU8xHM*9!(shjr%<`2^`SVTC^2;dHoGZwU6! zL=t3!t=(ovs&`1L%%VFZUy3zcM6qKsjJM4zr^Ed zrl%}}bFMa3!9f_VO}Sd7YjiX=jER-*oRYe=PVeanq1JkNl@#h-wd9^^>lJ4(*(jKz zw)FQFs^|fs>!aD$6jY{c`^=sy;pw8FiZ+3n?kx^tX!|(R06rP zfP%;1M;h?wY|wnY)_fgX(PI^yHz z2f~_SsKcnXTJnRkOy``2mmCJ`WIto6NfCb6F_^0*-$TdwDADgGopWL@YBnz$sPCt| z2?FnmH+7E$eAfy1Zc6{TA`@Coz6!kLYcPjMSZjU&L)DVgW`ytwF|FT6d@93Tr2y8a zVTxEJL|Yexdh2|d(lQR+57*e-g4$G(rsvA;2DRSG6qZ$x1F#x()ULM*4HqA(oiG4X z$yMdiCh?q2+_`jm&w*rlD43o$m0~VHT}%$zKSF;*I$ca{!F~k9NOoBS*k8aL^+=ml z55OI`V=n6(dxK_Sp1gW(zHAMCYCT^x$nOFf&%0iigEKF)g$wxCwd8McDOXFrU~3qu zUN`Tk^%LWsI-IRcp(JPan^rSPYnlOnVYo*VQfvLJ4p$8KSjR7z2~57kSPR2FJk%-g zE)~mVR4?3vm#um&8&|6vccS$k&h|xS;_^qAkxfeFj1)}&U8K?t%h+>M_XgHS|Dw5( z$>Ef%lEdzD9v*b5P7X6DltJ>MsjR~!V$B!5=8K?Tn-egY&$yi&F`@`MB_D1TMozSm zp|QEX)Z0K`4cC9m#gieWdc#Pj`H>p{No%|LUmm5rFmnQwIqxE~I~AGTLrhci15*}L z=p8AIIq9b6mt8`>QY-bAYrDM<>|m|=etky?$@&~hUWk2B%0Bjo&|Ji|(qk<08uY3L zSY*o|LbxT?YOEQo?dEukI!{Yc_i4H|wK@;3?A3~XN=q8W zP$J!YB*P^Z3qpuH%qU%Beg4q;+_<(>W;Nl<5C(|$hf%<{wFzRbVisiZ)K)V>rmtLS z0B37acA-Dkxln{E)V&Z1aY0LVRuU|v+Lhi&E4?8dflcZ)EVf0T=A1OIkX53Z&1yQi zB2DXWBv`HC?%rDKmiB@+8K5tzq+~#=(bjHph)MHdSL{&7GmIE4Uen2BeYHvr_K6C~ zU(f@I-jbGRAsxuPmNMuY3d-hi%%_e;>wsZ@D5W$+xnLQO!;b(+k#^1Yq?J6KRXuOr z9*2Kes@57XlKhoy^{N2D6kYZUyHf~8a&N?^Higa}784F*-Wa&KK9wE_H&tm<-`Vg& zJL9}(oX44hm8;3O87o($4h~3OW13#;lRK5X=EIAF9M5omLyE3-h7zl3>upb+Z|7Zz z?PlBP+A6*Eyiwp^+qG%eFGgI?i&Gc`hKfPxDjEF4bY$~&jcgtl89%eN(^k*O8@LRz zhBm=VbD-%5QY%gd0^$?45WD}FcTrB@-6vTI2Y>k)3Hww zP9I;mR_ejO|s11iOZ`D1#k$y=qMt4%h1C~n4o zN2Qj_lI6{EJxqk`#v^#q74=y7yE6w#wyY9?&1h~ZD!iAb)kX8irg)?43s{f+{df)h z(R!)Y`lGsaP>y_ft|$W@S2Hw*C(Bw9mh1h&vq3J+m&Fxm{71uB+PQhIzd^mT@L;)| z`W4M{)(QTzYc>+_0Rd2?Zx?Hl)L}5StejFe3?cXRTv-dhH0a5r^j^X`)4b-S8^yqs z1!(QgW9v_0GO?ZR#okJvD`r;w%KS4jO@;p%xG{?rtynd_4MYUAX2J!f+IwBZjw+#+Q!Rismq2b!KXY3eCS zAi)v3)%%b^YL~m@3wD(?$H`M&q*)qCTfyt0&|l{=02>swLgxzg`SZnAnX<|;rIxXfsVK}FqLs6KsF5EDTjIso)Eo^6|R1P!O7VZ&26~w_bCmX>KtDgJ~s>?)P)pxCF^wjGZ z2${J$&y_|GV(u9{4mNt*k5&%aQsjgRNdTvL!TW%52B6+?U*$R&Et`CuupsULT3`S7TZGH% z%Dt)+!y*QZ|Cj$4UA!O3fo~D8Nh4IPH*2jo84~_l>&Dj!=!3iz9IPbCjExux?7Dw+8@&!)Ok+6s>_t zXR>)o8ccFi?4k%|+oe#Wq^peRp)m(>DCM-lx5kfu9UbAzBBFpQ(KZ7%Zi0!aRj|i6 zQ?w^2%;+U@&0i7-W9)Nf?3rAHIV}@nQ9t~}CJBU*zF=5$^iXXPy-2-vk224Z1*fpu znoE~v@<-gAU00$&E{Eaf&3GOpxJ}@OdM{J8UM}~C-U=(OO0if3HOw@nZ^u-!GZVP? z!A?TdzGrgv{`FctT3h1X{I%ZKHQ8y-Sqc-dY1HWLwdq!fy2}1iH$jng9H-BEz!qf|@liWOWx_ z$kNGxh-eJRu2E}!)DcQQL1bt_vnUO%Ka}@%dMfH2#32DzP~_fdKme^tf>+0q;} zQ6;BM8Y%vknrIW*xGG!7YRPRx+n%C8EeMF3vIM=t2SPzg@O6*o_sJEG-J6Cka0Lkj zK$yld1y!@QP`-7KfOyE0w1O?>S(C}%-KCm)f7fzFf-aO*vDIf{somc+(dskqbttTp zdQ)Z=o6EPbfenZYZxB($FcyAjQ$Pf~v$VRlu+d4lu(oD@^=j*0n=?7`ar~MA4{fwI zr!2lUk`e}9YoxS91ZK3lw>X?GQ3MP{q1&K*m9qt{V32s!L#hMpt{j&|paN@3PH>%I zbpBB+ys#!_v5#MPIw zxszMiknxkPJLFt@qS)6Dh1Y6Wcb8Ju6hf(6VgzLp&p}hmJZm_rcW_m{?`FW_9tT3Z z1I;P3u-4X7zl9oGxD(atxi$+V_Y0EUVJg5&@{vWgwIWYY2DxhspB9G;OKe3AcJ$@s z3-P{M3kVs2c^EGLaQ;TLIuV?mGL7c@8LBRZs4ld;R1DfJnb&$YZeyB;d#P>y+naLW z=(}^wbMlg+O_8)40%t3_vM0uIdtBOpS)H9LT$!gZM~Wm?u+7zEgeQ6P$rI+&drW(T zbamltzF^Ui4VSkG5U}==7Bpm8?qQnP$P$e&dl2EpHCoI)pli@Mmw4Gm=y@7G;&*pt_43tz%x zGXl`SF6tuFLmz*+P@r#?tkDvUH+g@ z=+>dX;!UCXAGa2oUtIjFZn>Yv-Wq>rEX!;E@a~qz>6v4b)8k`Dw>0=s!5MxK?cN<* zx9R^a4SvpU_U!cNy%VEn`4!mlEsXx9O+GU^aqrQ)?;g49*j=C4e$O3u zj&9p|&$_~);^4t&#?Am~?8F#9Dhs$mS8sKYe`|}qIN)ZkrcBQzPZCDELC1oAqIrx5 zNOVL2lSa7Ef;$%$J)a-Sm#Y$yG=g%~$KePzuRJorUO&}PrpZeR$t3HP>LGO3yzF6y zdL5Jw@b3`+9_Js(RG%*P*1esSn*(URE)2f~s#AjGswnnyK+(YYu3nBGrTsn$cxjTN zTD{O~FzUkWd)^u~H6;u{ZFhQ~Hw?dKBAWJ)e4YNbv|DURks|J5P0Q`j{yF;5`oJM_ zD9->WCZ@p>q~e*u!@}OO0^B=klDr1e_0=l<8$3J(3zYkTma!MDku9#(Pr9^GKkw=C zOD?Sel`u>4?Ays?XS?P5j);75rQ8{hI~(%oHFo6ONb|!1J+%E}b@GNT7t&$jMp6Na zEd*gKWp6&2_aVn3rdoX|Cs~k6xmt8AaN5w?PkAXO08fL`)Rd^NZ!q%YRK!rWB$qx< zjpX^1=xipvnkGq!{>fK_pK1D-sArYMl2#}lQKDjVc3BNy(&bOvgCa)pQhc!E8!G;m zhM_UQlv-n#)pcdT1QYpXvht)mk^iKD3=j z9~SmF+)h2Alv^~_Zp7M{F@Z1<(5$B^taX}_5!9Gl52nPy5;}vJ1d7D-ZS1Bh5iaN7 z+R5`Vz)RR2NXcPc{sK`WN}p9KO3mfWo>*&_I@WZz{y5ICJEbWRvw*eg{COnTeAf3R zk*W1+9DTAem73JJin$Px)|=Eyo>JAHMvMqsNdR=Fr=9g?F(#XrY|tKVQsaGXQV-}+ zm*y`7@aKBmsnq|By%l&`DC=SYNQlBJBh}dLMTv?Bgu3f*V+<(u(}qbS{>A7tyYD2^62qu z!*+>CMa_U`DurFKDrxYk`2vQSMJPulUc;?ue!I?!e+b@sZJ@yp7-*IuQnXm14>cg z{uKwJS2Bdy7ObFNi}r9neIO2veVA7qPG$IAnCDm7y}|)&zN$!>=isNOiFxqD zwp|*ou=z&2=BpgLER!T)Q&Aoc|F9~o3ARqd$5+Vha&dJ~$nmm2K?W6IxfnVr;)-*% zsX;Yyy`i$V%Buo%qYRFS&^}!sa1M<2OeqIoF5(3X=gURhUNF%;NWldpLfn0s?J&`addy@58S?4=Kgq&Sh&3L2)V;p!pwu-Q>?+zvoU zvMio9Up;`cO}(meVa%AMg3iwas(L^*MSa!Ooig=CiOI?V4bR%c?4Gb1oF?+!y4l+5+_v;%+IfIn@(Rl|U%RjuerU40*=%(g2y;ISJO@oI=)VayOq7N9sa zmZ(<(f_Kiz14Mgg;GB&JTp*|^*FBJWF9DYJBeSa=sI?|KT66DV7O(=^5HcP-S4+Oo z2a6bJ_>);zCrn|buG5Z+*Rc>2^~6C;c&+(!TpQhgssb8thdW5TZ_{eSU>&HV2bSTC z#MOCGQ?GR?Gc>2es&rzYHHdfdrR;PILzwFee$;_Dub9VdT z4z#K*u#(YgGPXwGb)qSCW)%(7s*%6<)~E*#7AbrorD{E5S44XHof?GUK#(&K&UGA~ zw+5BfLh+(W0o)ttA=$_tW01-*S+Q~(D7`6%Kk?Z!XQ#VMjUD zQs>PVN{*@a-A#Jbmlnv)Zz!vlB&2A_J{nPK0ezc8aHt3ZC5MvJPgrK+}V@QLsX2HH25MNR1n5m91d#I8Om7E&n3 z1$#rdF4N;abVF+H=B3#t>@c=EGT)HX{;^5CS8ObKvmjGM$mlRf>(LZu=HxiCb0H~` zp^J&KCC-yGfPP~0E7eFQ>1n#pH9zmkpm9Xt3bq05%mS@fry|%W=cX-BwbHH^y%(#I zz&xAoFGdSOFKxl0=XM&rWOL?0g2~d|M?YWGBdz>#syL`o2&^qRc+1B!0F`E(N8m*P znQ7jafg9@Xr=+KWcr&A@BSJVg6$@skhkJAA}P09LoH-qK*f_xfdXYQ9&)>C|VZmj&H^;GskL* zBL9ZK=?BhX!ef#*{60pH=*?rDaN=M#+@nIBuHcs}%vD(%y6Za4(~;SuNERo9r50YZ zTl2g>{RA#he2raWh)Siw+7|Dpwq*d0PrXrM$z~5Y;5>i=NGIf6QBQ68BUH^%C`=>1 z?H~cSFet9V9ga!Ds<^XKDH;<&)wg6*lWvIik@peUX?fS3Mh$5eB71 z0(jD~Xuu@0#(fRO*)7xUS*f*7x`||}%Anz-I%OpXEYl$JB!`=V_y`dkmR0rk=&y6R zM)@B7C`-4_#|TQflET&s4{={(*=_PMWK~1gC%g`$j+81Fhtg`&4GC`#Xmm~_*?!(W zqL$*mu3^Oj<~!K=4oNrjjab_iYi%+k&lG-@w)O)k8v@4~5OOo%Os{6Yc}|v0cle|~ zbSWh=;?<-{@^MJ@V4P8ISAPd>rR+iH7-Co{peg6Kb7=?t>3txUkEZ<~30frx21z=x z#5tC?yG##|>zfl~VDMAcBGX(5mGYN0QwTr8u(>27ZAMD989h*7MH3;pV;_N}S(cI1 z6*LD4O`*ifsahnD_rUB`FwxS}TsN6YNzeJTEs1=)Ve8NgiyrG86=MVU1A__e9D=X+ zFE}vIMT17i`<<5}iiQ3%gOd5igT%+w5!&>LERAUhEz{0%$OWl+b|=1|d$JM5fI=a` zL~*VA&Afh22fd~j6T8?m}YgP-=h++Tj%@4N=|1DmVE$T&l?BM8X2k_e#$H+e^CcJW}T1)T@7 zJ{P*-5oHk3@%5e+qE+dHb2&n9Ay^x2zjzyaZUMUhqDHI*KG5l@<{R*$<;ksdO4{;{ z9pdy3!>4sG#8ff>vWoX|yhh`LQ+~?Y66G)A;v<@3&N4^|z>ykwYXRRj0ycc;!X3$JdDN~s1lFSF=KabVA+AscX+KMEPiWwYV-W}%>7 zCXk_Sh@Gf{sn7oJ!o}zG`URi*vS8CIZ&z^5|%GbZj-6 zu=yIN#}zTdmGKkiWLXVzsgV+9o=&YZo%Nx!3w{#F ziAv+OkiM>ix5aWC6eI&RgRjPlV@U{5)BG{F(yR=Qn+Cx-w3PTJdu)=vNh$QYBsNHP zs;b|Zzc-+_zdk2ncS)C&Zl?o^b-3d?%)_vITy0+l(V}5n77&}1e4apx*meaMgGq;+ z_*rZHvT3$S@l`HsyEcUi|H?eDH0CnJQ?Z94*6^FmNY%-ymzCBEwX4iY>P_y%a;x`q zkvfJxF$ul^fLg%gWOZ4lh-MX1kVi!v8BvAz)Q{&RJIe(YY5H$Nfvwa-#p@oM9y#;S zkA7nG z?%VJD#GN~C-??q)_S^5cXUEQ?ckH;f&J$CZcY~#OvvyoP7?AW%0FVjyH!q~0`+qcsr({qgzlhcheBeTa&jZK`~(wH7S zGd^;RWMgFFc;ome`@HPP^0@V(J%=n$gJ_%{ojo;qe5P^y?6eA}&rZyaogQtRnS5?^ zdh~eX=v*U?)lu8A^$u+hhtOXLJ@&viAR%o^qsRSeTlyHnfkOE0!!x6eUB`}%&deN| zoP=KctLJ8|sOhqg2he&#cqpxv3#>Djrx6DKCOJ}^4VpV!_rJAHO^ z^X3rlEQF6Q26+G2==kwRMo)Mr4r|j1WeN_Bn*XT~ntyyv%_c@pk8UComa4ePNnhJ$8>adI}^KIUkJN7$03a~ zuxosL^11ySs~9^oK3bq8tXQ%eGA+|aBoqZjOI5MN=PaR)P;kpMvf_B5$BzF#chR+- zGXJI0jgI2>!@gX-5RTk8IlX&)eE-PUM6e?yqoZ4okB?jJf4Bu0i@RyV`RBwx1qu{w zf^I-Dc4FhQy=|F%)syf(ez_Qa#F9Av_oFU;>m)oH4)QtSN5dXIH+?Yd<&(+}@w}Jo z{iOBZ8{Pl?e~CN0QtKM;pS4nsIC0N7(KE&21)%CXarg7JD}76KFWmoaMTyJ7lpa`w%@?2BODn~rJe3ts*y+hZvX4chq^G4(y(WAxx(AoDg2 zzE&E4S18ttzlgN-Gw#Rv8dw~g`qGzNMFnB3Z_Q2GcYTF}zP0J!ZH>@$KTdCf@v@3e z$Eq<*Wk%&&AfkR+CTUlzd9;-oqcR&O!{iB{(Cg6r|mxaILWBSZG>kSn=sYS zn(+PDW%3%~o6xFr%nk6`X8#2D^M=#n@43b?#SeR48MhrqL;paeW>MdC%SI)66L;yW zx0(%HEB@OSdKph=o5d8&=ok1DzUFoDcT$&pF?I>ft+Ri={J%qi?-s*qMl;S))PMf( I|33=+Z>L;|!2kdN diff --git a/SubnauticaModSystem/AutosortLockersSML/BZ/0Harmony.xml b/SubnauticaModSystem/AutosortLockersSML/BZ/0Harmony.xml deleted file mode 100644 index 6660e87..0000000 --- a/SubnauticaModSystem/AutosortLockersSML/BZ/0Harmony.xml +++ /dev/null @@ -1,4006 +0,0 @@ - - - - 0Harmony - - - - A factory to create delegate types - - - - Instance for the delegate type factory - - - Exists for API compatibility with Harmony - - - - - Creates a delegate type for a method - - Type of the return value - Types of the arguments - The new delegate type for the given type info - - - - Creates a delegate type for a method - - Type of the return value - Types of the arguments - Calling convention. If specified, adds to the delegate type - The new delegate type for the given type info - - - Creates a delegate type for a method - The method - The new delegate type - - - Creates a delegate type for a method - The method - Calling convention. If specified, adds to the delegate type. - The new delegate type - - - A getter delegate type - Type that getter gets field/property value from - Type of the value that getter gets - The instance get getter uses - An delegate - - - - A setter delegate type - Type that setter sets field/property value for - Type of the value that setter sets - The instance the setter uses - The value the setter uses - An delegate - - - - A constructor delegate type - Type that constructor creates - An delegate - - - - A helper class for fast access to getters and setters - - - Creates an instantiation delegate - Type that constructor creates - The new instantiation delegate - - - - Creates an getter delegate for a property - Type that getter reads property from - Type of the property that gets accessed - The property - The new getter delegate - - - - Creates an getter delegate for a field - Type that getter reads field from - Type of the field that gets accessed - The field - The new getter delegate - - - - Creates an getter delegate for a field (with a list of possible field names) - Type that getter reads field/property from - Type of the field/property that gets accessed - A list of possible field names - The new getter delegate - - - - Creates an setter delegate - Type that setter assigns property value to - Type of the property that gets assigned - The property - The new setter delegate - - - - Creates an setter delegate for a field - Type that setter assigns field value to - Type of the field that gets assigned - The field - The new getter delegate - - - - A delegate to invoke a method - The instance - The method parameters - The method result - - - A helper class to invoke method with delegates - - - Creates a fast invocation handler from a method - The method to invoke - Controls if boxed value object is accessed/updated directly - The - - - The directBoxValueAccess option controls how value types passed by reference (e.g. ref int, out my_struct) are handled in the arguments array - passed to the fast invocation handler. - Since the arguments array is an object array, any value types contained within it are actually references to a boxed value object. - Like any other object, there can be other references to such boxed value objects, other than the reference within the arguments array. - For example, - - var val = 5; - var box = (object)val; - var arr = new object[] { box }; - handler(arr); // for a method with parameter signature: ref/out/in int - - - - - If directBoxValueAccess is true, the boxed value object is accessed (and potentially updated) directly when the handler is called, - such that all references to the boxed object reflect the potentially updated value. - In the above example, if the method associated with the handler updates the passed (boxed) value to 10, both box and arr[0] - now reflect the value 10. Note that the original val is not updated, since boxing always copies the value into the new boxed value object. - - - If directBoxValueAccess is false (default), the boxed value object in the arguments array is replaced with a "reboxed" value object, - such that potential updates to the value are reflected only in the arguments array. - In the above example, if the method associated with the handler updates the passed (boxed) value to 10, only arr[0] now reflects the value 10. - - - - - Patch function helpers - - - Sorts patch methods by their priority rules - The original method - Patches to sort - Use debug mode. Present for source parity with Harmony 2, don't use. - The sorted patch methods - - - - Sorts patch methods by their priority rules - The original method - Patches to sort - The sorted patch methods - - - - Creates new replacement method with the latest patches and detours the original method - The original method - Information describing the patches - The newly created replacement method - - - - - High-level IL code manipulator for MonoMod that allows to manipulate a method as a stream of CodeInstructions. - - - - - Initialize IL transpiler - - Body of the method to transpile - - - - Adds a transpiler method that edits the IL of the given method - - Transpiler method - Currently not implemented - - - - Processes and writes IL to the provided method body. - Note that this cleans the existing method body (removes insturctions and exception handlers). - - Method body to write to. - Original method that transpiler can optionally call into - - One of IL opcodes contains a CallSide (e.g. calli), which is currently not - fully supported. - - One of IL opcodes with an operand contains a null operand. - - - - Converts all branches to long types. This exists to mimic the behaviour of Harmony 2 - - Enumerable of instructions - Enumerable of fixed instructions - - - - Helper wrapper around ILProcessor to allow emitting code at certain positions - - - - - Write method body to a ILDasm -like representation - - Method body to write - String representation of the method body (locals and instruction) - Unexpected exception block type - - - - Patching methods potentially messes up the stack. - Especially calls to GetExecutingAssembly won't turn in correct methods - - - - Creates a patch sorter - Array of patches that will be sorted - Use debugging - - - Sorts internal PatchSortingWrapper collection and caches the results. - After first run the result is provided from the cache. - The original method - The sorted patch methods - - - Sorts internal PatchSortingWrapper collection and caches the results. - After first run the result is provided from the cache. - The original method - The sorted patch methods as instance - - - Checks if the sorter was created with the same patch list and as a result can be reused to - get the sorted order of the patches. - List of patches to check against - true if equal - - - Removes one unresolved dependency from the least important patch. - - - Outputs all unblocked patches from the waiting list to results list - - - Adds patch to both results list and handled patches set - Patch to add - - - Wrapper used over the Patch object to allow faster dependency access and - dependency removal in case of cyclic dependencies - - - Create patch wrapper object used for sorting - Patch to wrap - - - Determines how patches sort - The other patch - integer to define sort order (-1, 0, 1) - - - Determines whether patches are equal - The other patch - true if equal - - - Hash function - A hash code - - - Bidirectionally registers Patches as after dependencies - List of dependencies to register - - - Bidirectionally registers Patches as before dependencies - List of dependencies to register - - - Bidirectionally removes Patch from after dependencies - Patch to remove - - - Bidirectionally removes Patch from before dependencies - Patch to remove - - - Specifies the type of method - - - - This is a normal method - - - This is a getter - - - This is a setter - - - This is a constructor - - - This is a static constructor - - - Specifies the type of argument - - - - This is a normal argument - - - This is a reference argument (ref) - - - This is an out argument (out) - - - This is a pointer argument (&) - - - Specifies the type of patch - - - - Any patch - - - A prefix patch - - - A postfix patch - - - A transpiler - - - A finalizer - - - A reverse patch - - - Specifies the type of reverse patch - - - - Use the unmodified original method (directly from IL) - - - Use the original as it is right now including previous patches but excluding future ones - - - Specifies the type of method call dispatching mechanics - - - - Call the method using dynamic dispatching if method is virtual (including overriden) - - - This is the built-in form of late binding (a.k.a. dynamic binding) and is the default dispatching mechanic in C#. - This directly corresponds with the instruction. - - - For virtual (including overriden) methods, the instance type's most-derived/overriden implementation of the method is called. - For non-virtual (including static) methods, same behavior as : the exact specified method implementation is called. - - - Note: This is not a fully dynamic dispatch, since non-virtual (including static) methods are still called non-virtually. - A fully dynamic dispatch in C# involves using - the dynamic type - (actually a fully dynamic binding, since even the name and overload resolution happens at runtime), which does not support. - - - - - Call the method using static dispatching, regardless of whether method is virtual (including overriden) or non-virtual (including static) - - - a.k.a. non-virtual dispatching, early binding, or static binding. - This directly corresponds with the instruction. - - - For both virtual (including overriden) and non-virtual (including static) methods, the exact specified method implementation is called, without virtual/override mechanics. - - - - - The base class for all Harmony annotations (not meant to be used directly) - - - - The common information for all attributes - - - Annotation to define your Harmony patch methods - - - - An empty annotation can be used together with TargetMethod(s) - - - - An annotation that specifies a class to patch - The declaring class/type - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The argument types of the method or constructor to patch - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The name of the method, property or constructor to patch - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The name of the method, property or constructor to patch - An array of argument types to target overloads - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The name of the method, property or constructor to patch - An array of argument types to target overloads - Array of - - - - An annotation that specifies a method, property or constructor to patch - Assembly-qualified name of the declaring class/type - The name of the method, property or constructor to patch - The - An array of argument types to target overloads - Array of - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The - An array of argument types to target overloads - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The - An array of argument types to target overloads - Array of - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The name of the method, property or constructor to patch - The - - - - An annotation that specifies a method, property or constructor to patch - The name of the method, property or constructor to patch - - - - An annotation that specifies a method, property or constructor to patch - The name of the method, property or constructor to patch - An array of argument types to target overloads - - - - An annotation that specifies a method, property or constructor to patch - The name of the method, property or constructor to patch - An array of argument types to target overloads - An array of - - - - An annotation that specifies a method, property or constructor to patch - The name of the method, property or constructor to patch - The - - - - An annotation that specifies a method, property or constructor to patch - The - - - - An annotation that specifies a method, property or constructor to patch - The - An array of argument types to target overloads - - - - An annotation that specifies a method, property or constructor to patch - The - An array of argument types to target overloads - An array of - - - - An annotation that specifies a method, property or constructor to patch - An array of argument types to target overloads - - - - An annotation that specifies a method, property or constructor to patch - An array of argument types to target overloads - An array of - - - - Annotation to define the original method for delegate injection - - - - An annotation that specifies a class to patch - The declaring class/type - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The argument types of the method or constructor to patch - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The name of the method, property or constructor to patch - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The name of the method, property or constructor to patch - An array of argument types to target overloads - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The name of the method, property or constructor to patch - An array of argument types to target overloads - Array of - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The - An array of argument types to target overloads - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The - An array of argument types to target overloads - Array of - - - - An annotation that specifies a method, property or constructor to patch - The declaring class/type - The name of the method, property or constructor to patch - The - - - - An annotation that specifies a method, property or constructor to patch - The name of the method, property or constructor to patch - - - - An annotation that specifies a method, property or constructor to patch - The name of the method, property or constructor to patch - An array of argument types to target overloads - - - - An annotation that specifies a method, property or constructor to patch - The name of the method, property or constructor to patch - An array of argument types to target overloads - An array of - - - - An annotation that specifies a method, property or constructor to patch - The name of the method, property or constructor to patch - The - - - - An annotation that specifies call dispatching mechanics for the delegate - The - - - - An annotation that specifies a method, property or constructor to patch - The - An array of argument types to target overloads - - - - An annotation that specifies a method, property or constructor to patch - The - An array of argument types to target overloads - An array of - - - - An annotation that specifies a method, property or constructor to patch - An array of argument types to target overloads - - - - An annotation that specifies a method, property or constructor to patch - An array of argument types to target overloads - An array of - - - - Annotation to define your standin methods for reverse patching - - - - An annotation that specifies the type of reverse patching - The of the reverse patch - - - - A Harmony annotation to define that all methods in a class are to be patched - - - - A Harmony annotation - - - - A Harmony annotation to define patch priority - The priority - - - - A Harmony annotation - - - - A Harmony annotation to define that a patch comes before another patch - The array of harmony IDs of the other patches - - - - A Harmony annotation - - - A Harmony annotation to define that a patch comes after another patch - The array of harmony IDs of the other patches - - - - A Harmony annotation - - - A Harmony annotation to debug a patch (output uses to log to your Desktop) - - - - A Harmony attribute - - - If specified on a prefix, postfix or a finalizer, the method will be automatically wrapped into try/catch. - - - - Specifies the Prepare function in a patch class - - - - Specifies the Cleanup function in a patch class - - - - Specifies the TargetMethod function in a patch class - - - - Specifies the TargetMethods function in a patch class - - - - Specifies the Prefix function in a patch class - - - - Specifies the Postfix function in a patch class - - - - Specifies the Transpiler function in a patch class - - - - Specifies the Finalizer function in a patch class - - - - A Harmony annotation - - - - The name of the original argument - - - - The index of the original argument - - - - The new name of the original argument - - - - An annotation to declare injected arguments by name - - - - An annotation to declare injected arguments by index - Zero-based index - - - - An annotation to declare injected arguments by renaming them - Name of the original argument - New name - - - - An annotation to declare injected arguments by index and renaming them - Zero-based index - New name - - - - An abstract wrapper around OpCode and their operands. Used by transpilers - - - - The opcode - - - - The operand - - - - All labels defined on this instruction - - - - All exception block boundaries defined on this instruction - - - - Creates a new CodeInstruction with a given opcode and optional operand - The opcode - The operand - - - - Create a full copy (including labels and exception blocks) of a CodeInstruction - The to copy - - - - Clones a CodeInstruction and resets its labels and exception blocks - A lightweight copy of this code instruction - - - - Clones a CodeInstruction, resets labels and exception blocks and sets its opcode - The opcode - A copy of this CodeInstruction with a new opcode - - - - Clones a CodeInstruction, resets labels and exception blocks and sets its operand - The operand - A copy of this CodeInstruction with a new operand - - - - Creates a CodeInstruction calling a method (CALL) - The class/type where the method is declared - The name of the method (case sensitive) - Optional parameters to target a specific overload of the method - Optional list of types that define the generic version of the method - A code instruction that calls the method matching the arguments - - - - Creates a CodeInstruction calling a method (CALL) - The target method in the form TypeFullName:MethodName, where the type name matches a form recognized by Type.GetType like Some.Namespace.Type. - Optional parameters to target a specific overload of the method - Optional list of types that define the generic version of the method - A code instruction that calls the method matching the arguments - - - - Creates a CodeInstruction calling a method (CALL) - The lambda expression using the method - - - - - Creates a CodeInstruction calling a method (CALL) - The lambda expression using the method - - - - - Creates a CodeInstruction calling a method (CALL) - The lambda expression using the method - - - - - Creates a CodeInstruction calling a method (CALL) - The lambda expression using the method - - - - - Creates a CodeInstruction loading a field (LD[S]FLD[A]) - The class/type where the field is defined - The name of the field (case sensitive) - Use address of field - - - - Creates a CodeInstruction storing to a field (ST[S]FLD) - The class/type where the field is defined - The name of the field (case sensitive) - - - - Returns a string representation of the code instruction - A string representation of the code instruction - - - - Exception block types - - - - The beginning of an exception block - - - - The beginning of a catch block - - - - The beginning of an except filter block - - - - The beginning of a fault block - - - - The beginning of a finally block - - - - The end of an exception block - - - - An exception block - - - - Block type - - - - Catch type - - - - Creates an exception block - The - The catch type - - - - - An exception thrown when a patch argument in a Harmony patch is invalid. - - - - - Original method to be patched. - - - - - Patch that was attempted to be applied. - - - - - - - - Constructs a new exception instance. - - Message of the exception. - Original method to be patched. - Patch that was attempted to be applied. - - - - An exception thrown when a reflection member is not found. - - - - - - - The Harmony instance is the main entry to Harmony. After creating one with an unique identifier, it is used to patch and query the current application domain - - - - Set to true before instantiating Harmony to debug Harmony or use an environment variable to set HARMONY_DEBUG to '1' like this: cmd /C "set HARMONY_DEBUG=1 && game.exe" - This is for full debugging. To debug only specific patches, use the attribute - - - - Creates a new Harmony instance - A unique identifier (you choose your own) - A Harmony instance - - - - The unique identifier - - - - Searches the current assembly for Harmony annotations and uses them to create patches - - - - Creates a empty patch processor for an original method - The original method/constructor - A new instance - - - - Creates a patch class processor from an annotated class - The class/type - A new instance - - - - Creates a patch class processor from an annotated class - The class/type - If true, the type doesn't need to have any attributes present for processing - A new instance - - - - Creates a reverse patcher for one of your stub methods - The original method/constructor - The stand-in stub method as - A new instance - - - - Searches an assembly for Harmony annotations and uses them to create patches - The assembly - - - - Searches the given type for Harmony annotation and uses them to create patches - The type to search - - - - Creates patches by manually specifying the methods - The original method/constructor - An optional prefix method wrapped in a object - An optional postfix method wrapped in a object - An optional transpiler method wrapped in a object - An optional finalizer method wrapped in a object - The replacement method that was created to patch the original method - - - - Patches a foreign method onto a stub method of yours and optionally applies transpilers during the process - The original method/constructor you want to duplicate - Your stub method as that will become the original. Needs to have the correct signature (either original or whatever your transpilers generates) - An optional transpiler as method that will be applied during the process - The replacement method that was created to patch the stub method - - - - Unpatches methods by patching them with zero patches. Fully unpatching is not supported. Be careful, unpatching is global - The optional Harmony ID to restrict unpatching to a specific Harmony instance - This method could be static if it wasn't for the fact that unpatching creates a new replacement method that contains your harmony ID - - - - Unpatches all methods that were patched by this Harmony instance's ID. Unpatching is done by repatching methods without patches of this instance. - - - - Unpatches a method by patching it with zero patches. Fully unpatching is not supported. Be careful, unpatching is global - The original method/constructor - The - The optional Harmony ID to restrict unpatching to a specific Harmony instance - - - - Unpatches a method by patching it with zero patches. Fully unpatching is not supported. Be careful, unpatching is global - The original method/constructor - The patch method as method to remove - - - - Test for patches from a specific Harmony ID - The Harmony ID - True if patches for this ID exist - - - - Gets patch information for a given original method - The original method/constructor - The patch information as - - - - Gets the methods this instance has patched - An enumeration of original methods/constructors - - - - Gets all patched original methods in the appdomain - An enumeration of patched original methods/constructors - - - - Gets Harmony version for all active Harmony instances - [out] The current Harmony version - A dictionary containing assembly versions keyed by Harmony IDs - - - - Creates a new Harmony instance and applies all patches specified in the type - The type to scan for patches. - The ID for the Harmony instance to create, which will be used. - - - - Applies all patches specified in the assembly - The assembly to scan. - The ID for the Harmony instance to create, which will be used. - - - - Under Mono, HarmonyException wraps IL compile errors with detailed information about the failure - - - - Default serialization constructor (not implemented) - The info - The context - - - - Get a list of IL instructions in pairs of offset+code - A list of key/value pairs which represent an offset and the code at that offset - - - - Get a list of IL instructions without offsets - A list of - - - - Get the error offset of the errornous IL instruction - The offset - - - - Get the index of the errornous IL instruction - The index into the list of instructions or -1 if not found - - - - A wrapper around a method to use it as a patch (for example a Prefix) - - - - The original method - - - - Class/type declaring this patch - - - - Patch method name - - - - Optional patch - - - - Array of argument types of the patch method - - - - of the patch - - - - Install this patch before patches with these Harmony IDs - - - - Install this patch after patches with these Harmony IDs - - - - Reverse patch type, see - - - - Create debug output for this patch - - - - Whether to use (true) or (false) mechanics - for -attributed delegate - - - - Whether to wrap the patch itself into a try/catch. - - - - Default constructor - - - - Creates a patch from a given method - The original method - - - - Creates a patch from a given method - The original method - The patch - A list of harmony IDs that should come after this patch - A list of harmony IDs that should come before this patch - Set to true to generate debug output - - - - Creates a patch from a given method - The patch class/type - The patch method name - The optional argument types of the patch method (for overloaded methods) - - - - Gets the names of all internal patch info fields - A list of field names - - - - Merges annotations - The list of to merge - The merged - - - - Returns a string that represents the annotation - A string representation - - - - Annotation extensions - - - - Copies annotation information - The source - The destination - - - - Clones an annotation - The to clone - A copied - - - - Merges annotations - The master - The detail - A new, merged - - - - Gets all annotations on a class/type - The class/type - A list of all - - - - Gets merged annotations on a class/type - The class/type - The merged - - - - Gets all annotations on a method - The method/constructor - A list of - - - - Gets merged annotations on a method - The method/constructor - The merged - - - - - A mutable representation of an inline signature, similar to Mono.Cecil's CallSite. - Used by the calli instruction, can be used by transpilers - - - - - See - - - - See - - - - See - - - - The list of all parameter types or function pointer signatures received by the call site - - - - The return type or function pointer signature returned by the call site - - - - Returns a string representation of the inline signature - A string representation of the inline signature - - - - - A mutable representation of a parameter type with an attached type modifier, - similar to Mono.Cecil's OptionalModifierType / RequiredModifierType and C#'s modopt / modreq - - - - - Whether this is a modopt (optional modifier type) or a modreq (required modifier type) - - - - The modifier type attached to the parameter type - - - - The modified parameter type - - - - Returns a string representation of the modifier type - A string representation of the modifier type - - - - Patch serialization - - - - Control the binding of a serialized object to a type - Specifies the assembly name of the serialized object - Specifies the type name of the serialized object - The type of the object the formatter creates a new instance of - - - - Serializes a patch info - The - The serialized data - - - - Deserialize a patch info - The serialized data - A - - - - Compare function to sort patch priorities - The patch - Zero-based index - The priority - A standard sort integer (-1, 0, 1) - - - - Serializable patch information - - - - Prefixes as an array of - - - - Postfixes as an array of - - - - Transpilers as an array of - - - - Finalizers as an array of - - - - Returns if any of the patches wants debugging turned on - - - - Adds prefixes - An owner (Harmony ID) - The patch methods - - - - Adds a prefix - - - Removes prefixes - The owner of the prefixes, or * for all - - - - Adds postfixes - An owner (Harmony ID) - The patch methods - - - - Adds a postfix - - - Removes postfixes - The owner of the postfixes, or * for all - - - - Adds transpilers - An owner (Harmony ID) - The patch methods - - - - Adds a transpiler - - - Removes transpilers - The owner of the transpilers, or * for all - - - - Adds finalizers - An owner (Harmony ID) - The patch methods - - - - Adds a finalizer - - - Removes finalizers - The owner of the finalizers, or * for all - - - - Removes a patch using its method - The method of the patch to remove - - - - Gets a concatenated list of patches - The Harmony instance ID adding the new patches - The patches to add - The current patches - - - - Gets a list of patches with any from the given owner removed - The owner of the methods, or * for all - The current patches - - - - A serializable patch - - - - Zero-based index - - - - The owner (Harmony ID) - - - - The priority, see - - - - Keep this patch before the patches indicated in the list of Harmony IDs - - - - Keep this patch after the patches indicated in the list of Harmony IDs - - - - A flag that will log the replacement method via every time this patch is used to build the replacement, even in the future - - - - Whether to wrap the patch into a general try/catch that logs the error - - - - The method of the static patch method - - - - Creates a patch - The method of the patch - Zero-based index - An owner (Harmony ID) - The priority, see - A list of Harmony IDs for patches that should run after this patch - A list of Harmony IDs for patches that should run before this patch - A flag that will log the replacement method via every time this patch is used to build the replacement, even in the future - - - - Creates a patch - The method of the patch - Zero-based index - An owner (Harmony ID) - The priority, see - A list of Harmony IDs for patches that should run after this patch - A list of Harmony IDs for patches that should run before this patch - A flag that will log the replacement method via every time this patch is used to build the replacement, even in the future - Whether to wrap the patch into a general try/catch that logs the error - - - - Creates a patch - The method of the patch - Zero-based index - An owner (Harmony ID) - - - Get the patch method or a DynamicMethod if original patch method is a patch factory - The original method/constructor - The method of the patch - - - - Determines whether patches are equal - The other patch - true if equal - - - - Determines how patches sort - The other patch - integer to define sort order (-1, 0, 1) - - - - Hash function - A hash code - - - - A PatchClassProcessor used to turn on a class/type into patches - - - - Creates a patch class processor by pointing out a class. Similar to PatchAll() but without searching through all classes. - The Harmony instance - The class to process (need to have at least a [HarmonyPatch] attribute if allowUnannotatedType is set to false) - - - - Creates a patch class processor by pointing out a class. Similar to PatchAll() but without searching through all classes. - The Harmony instance - The class to process (need to have at least a [HarmonyPatch] attribute if allowUnannotatedType is set to false) - If true, the type doesn't need to have any attributes present for processing - - - - Applies the patches - A list of all created replacement methods or null if patch class is not annotated - - - - A group of patches - - - - A collection of prefix - - - - A collection of postfix - - - - A collection of transpiler - - - - A collection of finalizer - - - - Gets all owners (Harmony IDs) or all known patches - The patch owners - - - - Creates a group of patches - An array of prefixes as - An array of postfixes as - An array of transpileres as - An array of finalizeres as - - - - - IL manipulator to create Harmony-style patches - - - - - - Manipulates a by applying Harmony patches to it. - - Reference to the method that should be considered as original. Used to reference parameter and return types. - Collection of Harmony patches to apply. - Method body to manipulate as instance. Should contain instructions to patch. - - In most cases you will want to use to create or obtain global - patch info for the method that contains aggregated info of all Harmony instances. - - - - - - Method patcher for normal managed methods that have IL body attached to them. - Uses in order to apply hooks in a way compatible with MonoMod's own - hooking system. - - - - - - - - - - - - - - - - - - A handler for that checks if a method is a normal Managed method. - - Not used - Patch resolver arguments - - - - - A general method patcher for implementing custom Harmony patcher backends. - - - - - - Constructs a method patcher - - Original method to patch - - - - - Original method to patch. - - - - - - Prepares method body for the unpatched that simply calls - function. - - - A that contains a call to - the original method to pass to the IL manipulator. - If null, Harmony patches must be manually applied to the original via . - - - - - - Detours to the provided replacement function. If called multiple times, - is re-detoured to the new method. - - - Result of - if returned non-null. - Otherwise, this will be null, in which case you must manually generate Harmony-patched method - with . - - of the hook, if it's different from `replacement`. - - - - - Creates a copy of the original method. If not possible, creates a method that calls into the original method. - - Copy of the original method that is transpileable. If not possible, returns null. - - This method creates a pure copy of the original method that is usable with transpilers. Currently, this - method is used to generate reverse patchers. - If a purse IL copy is not possible, a best approximation should be generated - (e.g. a wrapper that calls original method). - If no best approximation is possible, this method should return null, in which case generating reverse - patchers for the method will fail. - - - - - - A method patcher that uses to patch internal calls, - methods marked with and any other managed method that CLR managed-to-native - trampolines for and which has no IL body defined. - - - - - Constructs a new instance of method patcher. - - - - - - - - - - - - - - - A handler for that checks if a method doesn't have a body - (e.g. it's icall or marked with ) and thus can be patched with - . - - Not used - Patch resolver arguments - - - - - A global manager for handling Harmony patch state. Contains information about all patched methods and all - actual instances that handle patching implementation. - - - - - - Method patcher resolve event. - - - When a method is to be patched, this resolver event is called once on the method to determine which - backend to use in order to patch the method. - To make Harmony use the specified backend, set to an - instance of the method patcher backend to use. - - - - - - Creates or gets an existing instance of that handles patching the method. - - Method to patch. - Instance of that handles patching the method. - No suitable patcher found for the method. - - - - - Gets patch info for the given target method. - - Method to get patch info for. - Current patch info of the method. - - - - - Gets or creates patch info for the given method. - - Method to get info from. - An existing or new patch info for the method containing information about the applied patches. - - - - - Gets all methods that have been patched. - - List of methods that have been patched. - - - - - Removes all method resolvers. Use with care, this removes the default ones too! - - - - - Patcher resolve event arguments. - - - - - - Original method that is to be patched. - - - - - - Method patcher to use to patch . - Set this value to specify which one to use. - - - - - A PatchProcessor handles patches on a method/constructor - - - - Creates an empty patch processor - The Harmony instance - The original method/constructor - - - - Adds a prefix - The prefix as a - A for chaining calls - - - - Adds a prefix - The prefix method - A for chaining calls - - - - Adds a postfix - The postfix as a - A for chaining calls - - - - Adds a postfix - The postfix method - A for chaining calls - - - - Adds a transpiler - The transpiler as a - A for chaining calls - - - - Adds a transpiler - The transpiler method - A for chaining calls - - - - Adds a finalizer - The finalizer as a - A for chaining calls - - - - Adds a finalizer - The finalizer method - A for chaining calls - - - - Gets all patched original methods in the appdomain - An enumeration of patched method/constructor - - - - Applies all registered patches - The generated replacement method - - - - Unpatches patches of a given type and/or Harmony ID - The patch type - Harmony ID or * for any - A for chaining calls - - - - Unpatches a specific patch - The method of the patch - A for chaining calls - - - - Gets patch information on an original - The original method/constructor - The patch information as - - - - Sort patch methods by their priority rules - The original method - Patches to sort - The sorted patch methods - - - - Gets Harmony version for all active Harmony instances - [out] The current Harmony version - A dictionary containing assembly version keyed by Harmony ID - - - - Creates a new empty generator to use when reading method bodies - A new - - - - Creates a new generator matching the method/constructor to use when reading method bodies - The original method/constructor to copy method information from - A new - - - - Returns the methods unmodified list of code instructions - The original method/constructor - Optionally an existing generator that will be used to create all local variables and labels contained in the result (if not specified, an internal generator is used) - A list containing all the original - - - - Returns the methods unmodified list of code instructions - The original method/constructor - A new generator that now contains all local variables and labels contained in the result - A list containing all the original - - - - Returns the methods current list of code instructions after all existing transpilers have been applied - The original method/constructor - Apply only the first count of transpilers - Optionally an existing generator that will be used to create all local variables and labels contained in the result (if not specified, an internal generator is used) - A list of - - - - Returns the methods current list of code instructions after all existing transpilers have been applied - The original method/constructor - A new generator that now contains all local variables and labels contained in the result - Apply only the first count of transpilers - A list of - - - - A low level way to read the body of a method. Used for quick searching in methods - The original method - All instructions as opcode/operand pairs - - - - A low level way to read the body of a method. Used for quick searching in methods - The original method - An existing generator that will be used to create all local variables and labels contained in the result - All instructions as opcode/operand pairs - - - - A patch priority - - - - Patch last - - - - Patch with very low priority - - - - Patch with low priority - - - - Patch with lower than normal priority - - - - Patch with normal priority - - - - Patch with higher than normal priority - - - - Patch with high priority - - - - Patch with very high priority - - - - Patch first - - - - A reverse patcher - - - - Creates a reverse patcher - The Harmony instance - The original method/constructor - Your stand-in stub method as - - - - Applies the patch - The type of patch, see - The generated replacement method - - - - A collection of commonly used transpilers - - - - Returns an instruction to call the specified delegate - The delegate type to emit - The delegate to emit - The instruction to call the specified action - - - - A transpiler that replaces all occurrences of a given method with another one using the same signature - The enumeration of to act on - Method or constructor to search for - Method or constructor to replace with - Modified enumeration of - - - - A transpiler that alters instructions that match a predicate by calling an action - The enumeration of to act on - A predicate selecting the instructions to change - An action to apply to matching instructions - Modified enumeration of - - - - A transpiler that logs a text at the beginning of the method - The instructions to act on - The log text - Modified enumeration of - - - - A transpiler that replaces the entire body of the method with another one - The replacement method. It's up to the caller of this transpiler to make sure that the signatures match. - of the patch. This is passed via transpiler. - A collection of that contains instructions of replacement method. - The replacement method is not a managed method that contains any IL. - This transpiler has a side effect of clearing up all previous locals and previous transpilers. - Use to run this transpiler as early as possible. - - - A helper class for reflection related functions - - - - Shortcut for to simplify the use of reflections and make it work for any access level - - - - Shortcut for to simplify the use of reflections and make it work for any access level but only within the current type - - - - Gets a type by name. Prefers a full name with namespace but falls back to the first type matching the name otherwise - The name - A type or null if not found - - - - Gets all successfully loaded types from a given assembly - The assembly - An array of types - - This calls and returns , while catching any thrown . - If such an exception is thrown, returns the successfully loaded types (, - filtered for non-null values). - - - - - Applies a function going up the type hierarchy and stops at the first non-null result - Result type of func() - The class/type to start with - The evaluation function returning T - The first non-null result, or null if no match - - The type hierarchy of a class or value type (including struct) does NOT include implemented interfaces, - and the type hierarchy of an interface is only itself (regardless of whether that interface implements other interfaces). - The top-most type in the type hierarchy of all non-interface types (including value types) is . - - - - - Applies a function going into inner types and stops at the first non-null result - Generic type parameter - The class/type to start with - The evaluation function returning T - The first non-null result, or null if no match - - - - Gets the reflection information for a directly declared field - The class/type where the field is defined - The name of the field - A field or null when type/name is null or when the field cannot be found - - - - Gets the reflection information for a field by searching the type and all its super types - The class/type where the field is defined - The name of the field (case sensitive) - A field or null when type/name is null or when the field cannot be found - - - - Gets the reflection information for a field - The class/type where the field is declared - The zero-based index of the field inside the class definition - A field or null when type is null or when the field cannot be found - - - - Gets the reflection information for a directly declared property - The class/type where the property is declared - The name of the property (case sensitive) - A property or null when type/name is null or when the property cannot be found - - - - Gets the reflection information for the getter method of a directly declared property - The class/type where the property is declared - The name of the property (case sensitive) - A method or null when type/name is null or when the property cannot be found - - - - Gets the reflection information for the setter method of a directly declared property - The class/type where the property is declared - The name of the property (case sensitive) - A method or null when type/name is null or when the property cannot be found - - - - Gets the reflection information for a property by searching the type and all its super types - The class/type - The name - A property or null when type/name is null or when the property cannot be found - - - - Gets the reflection information for the getter method of a property by searching the type and all its super types - The class/type - The name - A method or null when type/name is null or when the property cannot be found - - - - Gets the reflection information for the setter method of a property by searching the type and all its super types - The class/type - The name - A method or null when type/name is null or when the property cannot be found - - - - Gets the reflection information for a directly declared method - The class/type where the method is declared - The name of the method (case sensitive) - Optional parameters to target a specific overload of the method - Optional list of types that define the generic version of the method - A method or null when type/name is null or when the method cannot be found - - - - Gets the reflection information for a method by searching the type and all its super types - The class/type where the method is declared - The name of the method (case sensitive) - Optional parameters to target a specific overload of the method - Optional list of types that define the generic version of the method - A method or null when type/name is null or when the method cannot be found - - - - Gets the reflection information for a method by searching the type and all its super types - The target method in the form TypeFullName:MethodName, where the type name matches a form recognized by Type.GetType like Some.Namespace.Type. - Optional parameters to target a specific overload of the method - Optional list of types that define the generic version of the method - A method or null when type/name is null or when the method cannot be found - - - - Gets the names of all method that are declared in a type - The declaring class/type - A list of method names - - - - Gets the names of all method that are declared in the type of the instance - An instance of the type to search in - A list of method names - - - - Gets the names of all fields that are declared in a type - The declaring class/type - A list of field names - - - - Gets the names of all fields that are declared in the type of the instance - An instance of the type to search in - A list of field names - - - - Gets the names of all properties that are declared in a type - The declaring class/type - A list of property names - - - - Gets the names of all properties that are declared in the type of the instance - An instance of the type to search in - A list of property names - - - - Gets the type of any class member of - A member - The class/type of this member - - - - Test if a class member is actually an concrete implementation - A member - True if the member is a declared - - - - Gets the real implementation of a class member - A member - The member itself if its declared. Otherwise the member that is actually implemented in some base type - - - - Gets the reflection information for a directly declared constructor - The class/type where the constructor is declared - Optional parameters to target a specific overload of the constructor - Optional parameters to only consider static constructors - A constructor info or null when type is null or when the constructor cannot be found - - - - Gets the reflection information for a constructor by searching the type and all its super types - The class/type where the constructor is declared - Optional parameters to target a specific overload of the method - Optional parameters to only consider static constructors - A constructor info or null when type is null or when the method cannot be found - - - - Gets reflection information for all declared constructors - The class/type where the constructors are declared - Optional parameters to only consider static constructors - A list of constructor infos - - - - Gets reflection information for all declared methods - The class/type where the methods are declared - A list of methods - - - - Gets reflection information for all declared properties - The class/type where the properties are declared - A list of properties - - - - Gets reflection information for all declared fields - The class/type where the fields are declared - A list of fields - - - - Gets the return type of a method or constructor - The method/constructor - The return type - - - - Given a type, returns the first inner type matching a recursive search by name - The class/type to start searching at - The name of the inner type (case sensitive) - The inner type or null if type/name is null or if a type with that name cannot be found - - - - Given a type, returns the first inner type matching a recursive search with a predicate - The class/type to start searching at - The predicate to search with - The inner type or null if type/predicate is null or if a type with that name cannot be found - - - - Given a type, returns the first method matching a predicate - The class/type to start searching at - The predicate to search with - The method or null if type/predicate is null or if a type with that name cannot be found - - - - Given a type, returns the first constructor matching a predicate - The class/type to start searching at - The predicate to search with - The constructor info or null if type/predicate is null or if a type with that name cannot be found - - - - Given a type, returns the first property matching a predicate - The class/type to start searching at - The predicate to search with - The property or null if type/predicate is null or if a type with that name cannot be found - - - - Returns an array containing the type of each object in the given array - An array of objects - An array of types or an empty array if parameters is null (if an object is null, the type for it will be object) - - - - Creates an array of input parameters for a given method and a given set of potential inputs - The method/constructor you are planing to call - The possible input parameters in any order - An object array matching the method signature - - - - A readable/assignable reference delegate to an instance field of a class or static field (NOT an instance field of a struct) - - An arbitrary type if the field is static; otherwise the class that defines the field, or a parent class (including ), - implemented interface, or derived class of this type - - - The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), - a type that is assignable from that type; or if the field's type is an enum type, - either that type or the underlying integral type of that enum type - - The runtime instance to access the field (ignored and can be omitted for static fields) - A readable/assignable reference to the field - Null instance passed to a non-static field ref delegate - - Instance of invalid type passed to a non-static field ref delegate - (this can happen if is a parent class or interface of the field's declaring type) - - - - This delegate cannot be used for instance fields of structs, since a struct instance passed to the delegate would be passed by - value and thus would be a copy that only exists within the delegate's invocation. This is fine for a readonly reference, - but makes assignment futile. Use instead. - - - Note that is not required to be the field's declaring type. It can be a parent class (including ), - implemented interface, or a derived class of the field's declaring type ("instanceOfT is FieldDeclaringType" must be possible). - Specifically, must be assignable from OR to the field's declaring type. - Technically, this allows Nullable, although Nullable is only relevant for structs, and since only static fields of structs - are allowed for this delegate, and the instance passed to such a delegate is ignored, this hardly matters. - - - Similarly, is not required to be the field's field type, unless that type is a non-enum value type. - It can be a parent class (including object) or implemented interface of the field's field type. It cannot be a derived class. - This variance is not allowed for value types, since that would require boxing/unboxing, which is not allowed for ref values. - Special case for enum types: can also be the underlying integral type of the enum type. - Specifically, for reference types, must be assignable from - the field's field type; for non-enum value types, must be exactly the field's field type; for enum types, - must be either the field's field type or the underyling integral type of that field type. - - - This delegate supports static fields, even those defined in structs, for legacy reasons. - For such static fields, is effectively ignored. - Consider using (and StaticFieldRefAccess methods that return it) instead for static fields. - - - - - - Creates a field reference delegate for an instance field of a class - The class that defines the instance field, or derived class of this type - - The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), - a type that is assignable from that type; or if the field's type is an enum type, - either that type or the underlying integral type of that enum type - - The name of the field - A readable/assignable delegate - - - For backwards compatibility, there is no class constraint on . - Instead, the non-value-type check is done at runtime within the method. - - - - - - Creates an instance field reference for a specific instance of a class - The class that defines the instance field, or derived class of this type - - The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), - a type that is assignable from that type; or if the field's type is an enum type, - either that type or the underlying integral type of that enum type - - The instance - The name of the field - A readable/assignable reference to the field - - - This method is meant for one-off access to a field's value for a single instance. - If you need to access a field's value for potentially multiple instances, use instead. - FieldRefAccess<T, F>(instance, fieldName) is functionally equivalent to FieldRefAccess<T, F>(fieldName)(instance). - - - For backwards compatibility, there is no class constraint on . - Instead, the non-value-type check is done at runtime within the method. - - - - - - Creates a field reference delegate for an instance field of a class or static field (NOT an instance field of a struct) - - The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), - a type that is assignable from that type; or if the field's type is an enum type, - either that type or the underlying integral type of that enum type - - - The type that defines the field, or derived class of this type; must not be a struct type unless the field is static - - The name of the field - - A readable/assignable delegate with T=object - (for static fields, the instance delegate parameter is ignored) - - - - This method is meant for cases where the given type is only known at runtime and thus can't be used as a type parameter T - in e.g. . - - - This method supports static fields, even those defined in structs, for legacy reasons. - Consider using (and other overloads) instead for static fields. - - - - - - Creates a field reference delegate for an instance field of a class or static field (NOT an instance field of a struct) - - An arbitrary type if the field is static; otherwise the class that defines the field, or a parent class (including ), - implemented interface, or derived class of this type ("instanceOfT is FieldDeclaringType" must be possible) - - - The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), - a type that is assignable from that type; or if the field's type is an enum type, - either that type or the underlying integral type of that enum type - - The field - A readable/assignable delegate - - - This method is meant for cases where the field has already been obtained, avoiding the field searching cost in - e.g. . - - - This method supports static fields, even those defined in structs, for legacy reasons. - For such static fields, is effectively ignored. - Consider using (and other overloads) instead for static fields. - - - For backwards compatibility, there is no class constraint on . - Instead, the non-value-type check is done at runtime within the method. - - - - - - Creates a field reference for an instance field of a class - - The type that defines the field; or a parent class (including ), implemented interface, or derived class of this type - ("instanceOfT is FieldDeclaringType" must be possible) - - - The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), - a type that is assignable from that type; or if the field's type is an enum type, - either that type or the underlying integral type of that enum type - - The instance - The field - A readable/assignable reference to the field - - - This method is meant for one-off access to a field's value for a single instance and where the field has already been obtained. - If you need to access a field's value for potentially multiple instances, use instead. - FieldRefAccess<T, F>(instance, fieldInfo) is functionally equivalent to FieldRefAccess<T, F>(fieldInfo)(instance). - - - For backwards compatibility, there is no class constraint on . - Instead, the non-value-type check is done at runtime within the method. - - - - - - A readable/assignable reference delegate to an instance field of a struct - The struct that defines the instance field - - The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), - a type that is assignable from that type; or if the field's type is an enum type, - either that type or the underlying integral type of that enum type - - A reference to the runtime instance to access the field - A readable/assignable reference to the field - - - - Creates a field reference delegate for an instance field of a struct - The struct that defines the instance field - - The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), - a type that is assignable from that type; or if the field's type is an enum type, - either that type or the underlying integral type of that enum type - - The name of the field - A readable/assignable delegate - - - - Creates an instance field reference for a specific instance of a struct - The struct that defines the instance field - - The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), - a type that is assignable from that type; or if the field's type is an enum type, - either that type or the underlying integral type of that enum type - - The instance - The name of the field - A readable/assignable reference to the field - - - This method is meant for one-off access to a field's value for a single instance. - If you need to access a field's value for potentially multiple instances, use instead. - StructFieldRefAccess<T, F>(ref instance, fieldName) is functionally equivalent to StructFieldRefAccess<T, F>(fieldName)(ref instance). - - - - - - Creates a field reference delegate for an instance field of a struct - The struct that defines the instance field - - The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), - a type that is assignable from that type; or if the field's type is an enum type, - either that type or the underlying integral type of that enum type - - The field - A readable/assignable delegate - - - This method is meant for cases where the field has already been obtained, avoiding the field searching cost in - e.g. . - - - - - - Creates a field reference for an instance field of a struct - The struct that defines the instance field - - The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), - a type that is assignable from that type; or if the field's type is an enum type, - either that type or the underlying integral type of that enum type - - The instance - The field - A readable/assignable reference to the field - - - This method is meant for one-off access to a field's value for a single instance and where the field has already been obtained. - If you need to access a field's value for potentially multiple instances, use instead. - StructFieldRefAccess<T, F>(ref instance, fieldInfo) is functionally equivalent to StructFieldRefAccess<T, F>(fieldInfo)(ref instance). - - - - - - A readable/assignable reference delegate to a static field - - The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), - a type that is assignable from that type; or if the field's type is an enum type, - either that type or the underlying integral type of that enum type - - A readable/assignable reference to the field - - - - Creates a static field reference - The type (can be class or struct) the field is defined in - - The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), - a type that is assignable from that type; or if the field's type is an enum type, - either that type or the underlying integral type of that enum type - - The name of the field - A readable/assignable reference to the field - - - - Creates a static field reference - - The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), - a type that is assignable from that type; or if the field's type is an enum type, - either that type or the underlying integral type of that enum type - - The type (can be class or struct) the field is defined in - The name of the field - A readable/assignable reference to the field - - - - Creates a static field reference - An arbitrary type (by convention, the type the field is defined in) - - The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), - a type that is assignable from that type; or if the field's type is an enum type, - either that type or the underlying integral type of that enum type - - The field - A readable/assignable reference to the field - - The type parameter is only used in exception messaging and to distinguish between this method overload - and the overload (which returns a rather than a reference). - - - - - Creates a static field reference delegate - - The type of the field; or if the field's type is a reference type (a class or interface, NOT a struct or other value type), - a type that is assignable from that type; or if the field's type is an enum type, - either that type or the underlying integral type of that enum type - - The field - A readable/assignable delegate - - - - Creates a delegate to a given method - The delegate Type - The method to create a delegate from. - - Only applies for instance methods. If null (default), returned delegate is an open (a.k.a. unbound) instance delegate - where an instance is supplied as the first argument to the delegate invocation; else, delegate is a closed (a.k.a. bound) - instance delegate where the delegate invocation always applies to the given . - - - Only applies for instance methods. If true (default) and is virtual, invocation of the delegate - calls the instance method virtually (the instance type's most-derived/overriden implementation of the method is called); - else, invocation of the delegate calls the exact specified (this is useful for calling base class methods) - Note: if false and is an interface method, an ArgumentException is thrown. - - A delegate of given to given - - - Delegate invocation is more performant and more convenient to use than - at a one-time setup cost. - - - Works for both type of static and instance methods, both open and closed (a.k.a. unbound and bound) instance methods, - and both class and struct methods. - - - - - - Creates a delegate for a given delegate definition, attributed with [] - The delegate Type, attributed with [] - - Only applies for instance methods. If null (default), returned delegate is an open (a.k.a. unbound) instance delegate - where an instance is supplied as the first argument to the delegate invocation; else, delegate is a closed (a.k.a. bound) - instance delegate where the delegate invocation always applies to the given . - - A delegate of given to the method specified via [] - attributes on - - This calls with the method and virtualCall arguments - determined from the [] attributes on , - and the given (for closed instance delegates). - - - - - Returns who called the current method - The calling method/constructor (excluding the caller) - - - - Rethrows an exception while preserving its stack trace (throw statement typically clobbers existing stack traces) - The exception to rethrow - - - - True if the current runtime is based on Mono, false otherwise (.NET) - - - - True if the current runtime is .NET Framework, false otherwise (.NET Core or Mono, although latter isn't guaranteed) - - - - True if the current runtime is .NET Core, false otherwise (Mono or .NET Framework) - - - - Throws a missing member runtime exception - The type that is involved - A list of names - - - - Gets default value for a specific type - The class/type - The default value - - - - Creates an (possibly uninitialized) instance of a given type - The class/type - The new instance - - - - Creates an (possibly uninitialized) instance of a given type - The class/type - The new instance - - - - - A cache for the or similar Add methods for different types. - - - - Makes a deep copy of any object - The type of the instance that should be created; for legacy reasons, this must be a class or interface - The original object - A copy of the original object but of type T - - - - Makes a deep copy of any object - The type of the instance that should be created - The original object - [out] The copy of the original object - Optional value transformation function (taking a field name and src/dst instances) - The optional path root to start with - - - - Makes a deep copy of any object - The original object - The type of the instance that should be created - Optional value transformation function (taking a field name and src/dst instances) - The optional path root to start with - The copy of the original object - - - - Tests if a type is a struct - The type - True if the type is a struct - - - - Tests if a type is a class - The type - True if the type is a class - - - - Tests if a type is a value type - The type - True if the type is a value type - - - - Tests if a type is an integer type - The type - True if the type represents some integer - - - - Tests if a type is a floating point type - The type - True if the type represents some floating point - - - - Tests if a type is a numerical type - The type - True if the type represents some number - - - - Tests if a type is void - The type - True if the type is void - - - - Test whether an instance is of a nullable type - Type of instance - An instance to test - True if instance is of nullable type, false if not - - - - Tests whether a type or member is static, as defined in C# - The type or member - True if the type or member is static - - - - Tests whether a type is static, as defined in C# - The type - True if the type is static - - - - Tests whether a property is static, as defined in C# - The property - True if the property is static - - - - Tests whether an event is static, as defined in C# - The event - True if the event is static - - - - Calculates a combined hash code for an enumeration of objects - The objects - The hash code - - - - A CodeInstruction match - - - The name of the match - - - The matched opcodes - - - The matched operands - - - The matched labels - - - The matched blocks - - - The jumps from the match - - - The jumps to the match - - - The match predicate - - - Creates a code match - The optional opcode - The optional operand - The optional name - - - - Creates a code match - The CodeInstruction - An optional name - - - - Creates a code match - The predicate - An optional name - - - - Returns a string that represents the match - A string representation - - - - A CodeInstruction matcher - - - The current position - The index or -1 if out of bounds - - - - Gets the number of code instructions in this matcher - The count - - - - Checks whether the position of this CodeMatcher is within bounds - True if this CodeMatcher is valid - - - - Checks whether the position of this CodeMatcher is outside its bounds - True if this CodeMatcher is invalid - - - - Gets the remaining code instructions - The remaining count - - - - Gets the opcode at the current position - The opcode - - - - Gets the operand at the current position - The operand - - - - Gets the labels at the current position - The labels - - - - Gets the exception blocks at the current position - The blocks - - - - Creates an empty code matcher - - - Creates a code matcher from an enumeration of instructions - The instructions (transpiler argument) - An optional IL generator - - - - Makes a clone of this instruction matcher - A copy of this matcher - - - - Gets instructions at the current position - The instruction - - - - Gets instructions at the current position with offset - The offset - The instruction - - - - Gets all instructions - A list of instructions - - - - Gets all instructions as an enumeration - A list of instructions - - - - Gets some instructions counting from current position - Number of instructions - A list of instructions - - - - Gets all instructions within a range - The start index - The end index - A list of instructions - - - - Gets all instructions within a range (relative to current position) - The start offset - The end offset - A list of instructions - - - - Gets a list of all distinct labels - The instructions (transpiler argument) - A list of Labels - - - - Reports a failure - The method involved - The logger - True if current position is invalid and error was logged - - - - Sets an instruction at current position - The instruction to set - The same code matcher - - - - Sets instruction at current position and advances - The instruction - The same code matcher - - - - Sets opcode and operand at current position - The opcode - The operand - The same code matcher - - - - Sets opcode and operand at current position and advances - The opcode - The operand - The same code matcher - - - - Sets opcode at current position and advances - The opcode - The same code matcher - - - - Sets operand at current position and advances - The operand - The same code matcher - - - - Creates a label at current position - [out] The label - The same code matcher - - - - Creates a label at a position - The position - [out] The new label - The same code matcher - - - - Adds an enumeration of labels to current position - The labels - The same code matcher - - - - Adds an enumeration of labels at a position - The position - The labels - The same code matcher - - - - Sets jump to - Branch instruction - Destination for the jump - [out] The created label - The same code matcher - - - - Inserts some instructions - The instructions - The same code matcher - - - - Inserts an enumeration of instructions - The instructions - The same code matcher - - - - Inserts a branch - The branch opcode - Branch destination - The same code matcher - - - - Inserts some instructions and advances the position - The instructions - The same code matcher - - - - Inserts an enumeration of instructions and advances the position - The instructions - The same code matcher - - - - Inserts a branch and advances the position - The branch opcode - Branch destination - The same code matcher - - - - Removes current instruction - The same code matcher - - - - Removes some instruction fro current position by count - Number of instructions - The same code matcher - - - - Removes the instructions in a range - The start - The end - The same code matcher - - - - Removes the instructions in a offset range - The start offset - The end offset - The same code matcher - - - - Advances the current position - The offset - The same code matcher - - - - Moves the current position to the start - The same code matcher - - - - Moves the current position to the end - The same code matcher - - - - Searches forward with a predicate and advances position - The predicate - The same code matcher - - - - Searches backwards with a predicate and reverses position - The predicate - The same code matcher - - - - Matches forward and advances position - True to set position to end of match, false to set it to the beginning of the match - Some code matches - The same code matcher - - - - Matches backwards and reverses position - True to set position to end of match, false to set it to the beginning of the match - Some code matches - The same code matcher - - - - Repeats a match action until boundaries are met - The match action - An optional action that is executed when no match is found - The same code matcher - - - - Gets a match by its name - The match name - An instruction - - - - General extensions for common cases - - - - Joins an enumeration with a value converter and a delimiter to a string - The inner type of the enumeration - The enumeration - An optional value converter (from T to string) - An optional delimiter - The values joined into a string - - - - Converts an array of types (for example methods arguments) into a human readable form - The array of types - A human readable description including brackets - - - - A full description of a type - The type - A human readable description - - - - A a full description of a method or a constructor without assembly details but with generics - The method/constructor - A human readable description - - - - A helper converting parameter infos to types - The array of parameter infos - An array of types - - - - A helper to access a value via key from a dictionary - The key type - The value type - The dictionary - The key - The value for the key or the default value (of T) if that key does not exist - - - - A helper to access a value via key from a dictionary with extra casting - The value type - The dictionary - The key - The value for the key or the default value (of T) if that key does not exist or cannot be cast to T - - - - Escapes Unicode and ASCII non printable characters - The string to convert - The string to convert - A string literal surrounded by - - - - Extensions for - - - - Shortcut for testing whether the operand is equal to a non-null value - The - The value - True if the operand has the same type and is equal to the value - - - - Shortcut for testing whether the operand is equal to a non-null value - The - The value - True if the operand is equal to the value - This is an optimized version of for - - - - Shortcut for code.opcode == opcode && code.OperandIs(operand) - The - The - The operand value - True if the opcode is equal to the given opcode and the operand has the same type and is equal to the given operand - - - - Shortcut for code.opcode == opcode && code.OperandIs(operand) - The - The - The operand value - True if the opcode is equal to the given opcode and the operand is equal to the given operand - This is an optimized version of for - - - - Tests for any form of Ldarg* - The - The (optional) index - True if it matches one of the variations - - - - Tests for Ldarga/Ldarga_S - The - The (optional) index - True if it matches one of the variations - - - - Tests for Starg/Starg_S - The - The (optional) index - True if it matches one of the variations - - - - Tests for any form of Ldloc* - The - The optional local variable - True if it matches one of the variations - - - - Tests for any form of Stloc* - The - The optional local variable - True if it matches one of the variations - - - - Tests if the code instruction branches - The - The label if the instruction is a branch operation or if not - True if the instruction branches - - - - Tests if the code instruction calls the method/constructor - The - The method - True if the instruction calls the method or constructor - - - - Tests if the code instruction loads a constant - The - True if the instruction loads a constant - - - - Tests if the code instruction loads an integer constant - The - The integer constant - True if the instruction loads the constant - - - - Tests if the code instruction loads a floating point constant - The - The floating point constant - True if the instruction loads the constant - - - - Tests if the code instruction loads an enum constant - The - The enum - True if the instruction loads the constant - - - - Tests if the code instruction loads a field - The - The field - Set to true if the address of the field is loaded - True if the instruction loads the field - - - - Tests if the code instruction stores a field - The - The field - True if the instruction stores this field - - - - Adds labels to the code instruction and return it - The - One or several to add - The same code instruction - - - Adds labels to the code instruction and return it - The - An enumeration of - The same code instruction - - - Extracts all labels from the code instruction and returns them - The - A list of - - - Moves all labels from the code instruction to a different one - The to move the labels from - The to move the labels to - The code instruction labels were moved from (now empty) - - - Moves all labels from a different code instruction to the current one - The to move the labels from - The to move the labels to - The code instruction that received the labels - - - Adds ExceptionBlocks to the code instruction and return it - The - One or several to add - The same code instruction - - - Adds ExceptionBlocks to the code instruction and return it - The - An enumeration of - The same code instruction - - - Extracts all ExceptionBlocks from the code instruction and returns them - The - A list of - - - Moves all ExceptionBlocks from the code instruction to a different one - The to move the ExceptionBlocks from - The to move the ExceptionBlocks to - The code instruction blocks were moved from (now empty) - - - Moves all ExceptionBlocks from a different code instruction to the current one - The to move the ExceptionBlocks from - The to move the ExceptionBlocks to - The code instruction that received the blocks - - - General extensions for collections - - - - A simple way to execute code for every element in a collection - The inner type of the collection - The collection - The action to execute - - - - A simple way to execute code for elements in a collection matching a condition - The inner type of the collection - The collection - The predicate - The action to execute - - - - A helper to add an item to a collection - The inner type of the collection - The collection - The item to add - The collection containing the item - - - - A helper to add an item to an array - The inner type of the collection - The array - The item to add - The array containing the item - - - - A helper to add items to an array - The inner type of the collection - The array - The items to add - The array containing the items - - - - General extensions for collections - - - - Tests a class member if it has an IL method body (external methods for example don't have a body) - The member to test - Returns true if the member has an IL body or false if not - - - A file log for debugging - - - - Full pathname of the log file, defaults to a file called harmony.log.txt on your Desktop - - - - The indent character. The default is tab - - - - The current indent level - - - - Changes the indentation level - The value to add to the indentation level - - - - Log a string in a buffered way. Use this method only if you are sure that FlushBuffer will be called - or else logging information is incomplete in case of a crash - The string to log - - - - Logs a list of string in a buffered way. Use this method only if you are sure that FlushBuffer will be called - or else logging information is incomplete in case of a crash - A list of strings to log (they will not be re-indented) - - - - Returns the log buffer and optionally empties it - True to empty the buffer - The buffer. - - - - Replaces the buffer with new lines - The lines to store - - - - Flushes the log buffer to disk (use in combination with LogBuffered) - - - - Log a string directly to disk. Slower method that prevents missing information in case of a crash - The string to log. - - - - Resets and deletes the log - - - - Logs some bytes as hex values - The pointer to some memory - The length of bytes to log - - - - - Default Harmony logger that writes to a file - - - - - Whether or not to enable writing the log. - - - - - Text writer to write the logs to. If not set, defaults to a file log. - - - - - File path of the log. - - - - - Main logger class that exposes log events. - - - - - A single log event that represents a single log message. - - - - - Log channel of the message. - - - - - The log message. - - - - - Log channel for the messages. - - - - - No channels (or an empty channel). - - - - - Basic information. - - - - - Full IL dumps of the generated dynamic methods. - - - - - Channel for warnings. - - - - - Channel for errors. - - - - - Additional debug information that is related to patching - - - - - All channels. - - - - - Filter for which channels should be listened to. - If the channel is in the filter, all log messages from that channel get propagated into event. - - - - - Event fired on any incoming message that passes the channel filter. - - - - A helper class to retrieve reflection info for non-private methods - - - - Given a lambda expression that calls a method, returns the method info - The lambda expression using the method - The method in the lambda expression - - - - Given a lambda expression that calls a method, returns the method info - The generic type - The lambda expression using the method - The method in the lambda expression - - - - Given a lambda expression that calls a method, returns the method info - The generic type - The generic result type - The lambda expression using the method - The method in the lambda expression - - - - Given a lambda expression that calls a method, returns the method info - The lambda expression using the method - The method in the lambda expression - - - - A reflection helper to read and write private elements - The result type defined by GetValue() - - - - Creates a traverse instance from an existing instance - The existing instance - - - - Gets/Sets the current value - The value to read or write - - - - A reflection helper to read and write private elements - - - - Creates a new traverse instance from a class/type - The class/type - A instance - - - - Creates a new traverse instance from a class T - The class - A instance - - - - Creates a new traverse instance from an instance - The object - A instance - - - - Creates a new traverse instance from a named type - The type name, for format see - A instance - - - - Creates a new and empty traverse instance - - - - Creates a new traverse instance from a class/type - The class/type - - - - Creates a new traverse instance from an instance - The object - - - - Gets the current value - The value - - - - Gets the current value - The type of the value - The value - - - - Invokes the current method with arguments and returns the result - The method arguments - The value returned by the method - - - - Invokes the current method with arguments and returns the result - The type of the value - The method arguments - The value returned by the method - - - - Sets a value of the current field or property - The value - The same traverse instance - - - - Gets the type of the current field or property - The type - - - - Moves the current traverse instance to a inner type - The type name - A traverse instance - - - - Moves the current traverse instance to a field - The type name - A traverse instance - - - - Moves the current traverse instance to a field - The type of the field - The type name - A traverse instance - - - - Gets all fields of the current type - A list of field names - - - - Moves the current traverse instance to a property - The type name - Optional property index - A traverse instance - - - - Moves the current traverse instance to a field - The type of the property - The type name - Optional property index - A traverse instance - - - - Gets all properties of the current type - A list of property names - - - - Moves the current traverse instance to a method - The name of the method - The arguments defining the argument types of the method overload - A traverse instance - - - - Moves the current traverse instance to a method - The name of the method - The argument types of the method - The arguments for the method - A traverse instance - - - - Gets all methods of the current type - A list of method names - - - - Checks if the current traverse instance is for a field - True if its a field - - - - Checks if the current traverse instance is for a property - True if its a property - - - - Checks if the current traverse instance is for a method - True if its a method - - - - Checks if the current traverse instance is for a type - True if its a type - - - - Iterates over all fields of the current type and executes a traverse action - Original object - The action receiving a instance for each field - - - - Iterates over all fields of the current type and executes a traverse action - Original object - Target object - The action receiving a pair of instances for each field pair - - - - Iterates over all fields of the current type and executes a traverse action - Original object - Target object - The action receiving a dot path representing the field pair and the instances - - - - Iterates over all properties of the current type and executes a traverse action - Original object - The action receiving a instance for each property - - - - Iterates over all properties of the current type and executes a traverse action - Original object - Target object - The action receiving a pair of instances for each property pair - - - - Iterates over all properties of the current type and executes a traverse action - Original object - Target object - The action receiving a dot path representing the property pair and the instances - - - - A default field action that copies fields to fields - - - - Returns a string that represents the current traverse - A string representation - - - - - Indicates that the marked symbol is used implicitly (e.g. via reflection, in external library), - so this symbol will not be reported as unused (as well as by other usage inspections). - - - - - Can be applied to attributes, type parameters, and parameters of a type assignable from . - When applied to an attribute, the decorated attribute behaves the same as . - When applied to a type parameter or to a parameter of type , indicates that the corresponding type - is used implicitly. - - - - - Specify the details of implicitly used symbol when it is marked - with or . - - - - Only entity marked with attribute considered used. - - - Indicates implicit assignment to a member. - - - - Indicates implicit instantiation of a type with fixed constructor signature. - That means any unused constructor parameters won't be reported as such. - - - - Indicates implicit instantiation of a type. - - - - Specify what is considered to be used implicitly when marked - with or . - - - - Members of entity marked with attribute are considered used. - - - Inherited entities are considered used. - - - Entity marked with attribute and all its members considered used. - - - diff --git a/SubnauticaModSystem/AutosortLockersSML/BZ/AutosortLockersSML.dll b/SubnauticaModSystem/AutosortLockersSML/BZ/AutosortLockersSML.dll deleted file mode 100644 index b1fabb40c5dd78e15103124ec120eb56a0b4d9af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 79872 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 TvynNl=ld?<-!lF`%z^&{WqE0p From 5631e08625be9e7912d1dad58e80a244818f6ab1 Mon Sep 17 00:00:00 2001 From: DaWrecka <61927940+DaWrecka@users.noreply.github.com> Date: Sun, 31 Jan 2021 23:21:00 +0000 Subject: [PATCH 05/11] 2021-01-31 23:20 --- .gitignore | 1 + SubnauticaModSystem/AutosortLockers/AutosortLocker.cs | 2 -- SubnauticaModSystem/AutosortLockers/AutosortTarget.cs | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 1202c5b..ecb55c4 100644 --- a/.gitignore +++ b/.gitignore @@ -277,3 +277,4 @@ paket-files/ SubnauticaModSystem/AutosortLockersSML/BZ/AutosortLockersSML.dll SubnauticaModSystem/AutosortLockersSML/BZ/AutosortLockersSML.dll *.dll +*.xml diff --git a/SubnauticaModSystem/AutosortLockers/AutosortLocker.cs b/SubnauticaModSystem/AutosortLockers/AutosortLocker.cs index be068e4..1d3cd64 100644 --- a/SubnauticaModSystem/AutosortLockers/AutosortLocker.cs +++ b/SubnauticaModSystem/AutosortLockers/AutosortLocker.cs @@ -363,7 +363,6 @@ public override IEnumerator GetGameObjectAsync(IOut gameObject) CoroutineTask task = CraftData.GetPrefabForTechTypeAsync(TechType.SmallLocker); yield return task; - //GameObject originalPrefab = CraftData.GetPrefabForTechType(TechType.SmallLocker); Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 2"); GameObject originalPrefab = task.GetResult(); GameObject prefab = GameObject.Instantiate(originalPrefab); @@ -372,7 +371,6 @@ public override IEnumerator GetGameObjectAsync(IOut gameObject) Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 4"); // TEST - //StorageContainer container = prefab.GetComponent(); StorageContainer container = prefab.GetComponent(); Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 4.1, container.container is " + (container.container == null ? "is" : "is not") + " null"); container.width = Mod.config.AutosorterWidth; diff --git a/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs b/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs index 39bef70..de37fcb 100644 --- a/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs +++ b/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs @@ -577,7 +577,7 @@ public override IEnumerator GetGameObjectAsync(IOut gameObject) Logger.Log("AutosortTargetBuildable.GetGameObjectAsync: 1"); //var prefab = GetPrefab(TechType.Locker); TaskResult result = new TaskResult(); - yield return GetPrefabAsync(TechType.Locker, result); + yield return GetPrefabAsync(TechType.SmallLocker, result); Logger.Log("AutosortTargetBuildable.GetGameObjectAsync: 2"); GameObject basePrefab = result.Get(); @@ -594,8 +594,8 @@ public override IEnumerator GetGameObjectAsync(IOut gameObject) container.Resize(Mod.config.ReceptacleWidth, Mod.config.ReceptacleHeight); Logger.Log("AutosortTargetBuildable.GetGameObjectAsync: 4"); + gameObject.Set(prefab); - prefab.SetActive(false); yield break; } From 6c4ebd3c1e6a19746b91b35a3a7347f005d42245 Mon Sep 17 00:00:00 2001 From: DaWrecka <61927940+DaWrecka@users.noreply.github.com> Date: Mon, 1 Feb 2021 02:23:09 +0000 Subject: [PATCH 06/11] Now working but only lightly-tested --- .../AutosortLockers/AutosortLocker.cs | 16 ++-- .../AutosortLockers/AutosortTarget.cs | 6 +- .../AutosortLockers/AutosorterCategories.cs | 88 ++++++++++++++++++- 3 files changed, 98 insertions(+), 12 deletions(-) diff --git a/SubnauticaModSystem/AutosortLockers/AutosortLocker.cs b/SubnauticaModSystem/AutosortLockers/AutosortLocker.cs index 1d3cd64..f63b72a 100644 --- a/SubnauticaModSystem/AutosortLockers/AutosortLocker.cs +++ b/SubnauticaModSystem/AutosortLockers/AutosortLocker.cs @@ -431,15 +431,15 @@ protected override RecipeData GetBlueprintRecipe() craftAmount = 1, Ingredients = Mod.config.EasyBuild ? new List - { - new Ingredient(TechType.Titanium, 2) - } + { + new Ingredient(TechType.Titanium, 2) + } : new List - { - new Ingredient(TechType.Titanium, 2), - new Ingredient(TechType.ComputerChip, 1), - new Ingredient(TechType.AluminumOxide, 2) - } + { + new Ingredient(TechType.Titanium, 2), + new Ingredient(TechType.ComputerChip, 1), + new Ingredient(TechType.AluminumOxide, 2) + } }; } diff --git a/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs b/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs index de37fcb..0222681 100644 --- a/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs +++ b/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs @@ -575,7 +575,7 @@ public AutosortTargetBuildable() public override IEnumerator GetGameObjectAsync(IOut gameObject) { Logger.Log("AutosortTargetBuildable.GetGameObjectAsync: 1"); - //var prefab = GetPrefab(TechType.Locker); + TaskResult result = new TaskResult(); yield return GetPrefabAsync(TechType.SmallLocker, result); @@ -639,7 +639,7 @@ public AutosortStandingTargetBuildable() public override IEnumerator GetGameObjectAsync(IOut gameObject) { Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 1"); - //var prefab = GetPrefab(TechType.Locker); + TaskResult result = new TaskResult(); yield return GetPrefabAsync(TechType.Locker, result); Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 2"); @@ -758,7 +758,7 @@ public static IEnumerator GetPrefabAsync(TechType basePrefab, IOut g autosortTarget.customizeButtonImage = autosortTarget.customizeButton.GetComponent(); //return prefab; - originalPrefab.SetActive(false); + //originalPrefab.SetActive(false); gameObject.Set(prefab); } } diff --git a/SubnauticaModSystem/AutosortLockers/AutosorterCategories.cs b/SubnauticaModSystem/AutosortLockers/AutosorterCategories.cs index ad56125..e5ba63e 100644 --- a/SubnauticaModSystem/AutosortLockers/AutosorterCategories.cs +++ b/SubnauticaModSystem/AutosortLockers/AutosorterCategories.cs @@ -130,7 +130,36 @@ public static class AutosorterCategoryData TechType.LavaLizardEgg, TechType.LavaLizardEggUndiscovered, TechType.CrabsnakeEggUndiscovered, - TechType.SpadefishEggUndiscovered + TechType.SpadefishEggUndiscovered, + TechType.SeaMonkeyEgg, + TechType.ArcticRayEgg, + TechType.ArcticRayEggUndiscovered, + TechType.BruteSharkEgg, + TechType.BruteSharkEggUndiscovered, + TechType.LilyPaddlerEgg, + TechType.LilyPaddlerEggUndiscovered, + TechType.PinnacaridEgg, + TechType.PinnacaridEggUndiscovered, + TechType.SquidSharkEgg, + TechType.SquidSharkEggUndiscovered, + TechType.TitanHolefishEgg, + TechType.TitanHolefishEggUndiscovered, + TechType.TrivalveBlueEgg, + TechType.TrivalveYellowEgg, + TechType.TrivalveBlueEggUndiscovered, + TechType.TrivalveYellowEggUndiscovered, + TechType.BrinewingEgg, + TechType.BrinewingEggUndiscovered, + TechType.CryptosuchusEgg, + TechType.CryptosuchusEggUndiscovered, + TechType.GlowWhaleEgg, + TechType.GlowWhaleEggUndiscovered, + TechType.JellyfishEgg, + TechType.JellyfishEggUndiscovered, + TechType.PenguinEgg, + TechType.PenguinEggUndiscovered, + TechType.RockPuncherEgg, + TechType.RockPuncherEggUndiscovered }; public static List Food = new List { @@ -170,6 +199,29 @@ public static class AutosorterCategoryData TechType.HangingFruit, TechType.Melon, TechType.PurpleVegetable, + TechType.CookedSpinnerfish, + TechType.CookedSymbiote, + TechType.CookedArcticPeeper, + TechType.CookedArrowRay, + TechType.CookedNootFish, + TechType.CookedTriops, + TechType.CookedFeatherFish, + TechType.CookedFeatherFishRed, + TechType.CookedDiscusFish, + TechType.WaterPurificationTablet, + TechType.SpicyFruitSalad, + TechType.CuredSpinnerfish, + TechType.CuredSymbiote, + TechType.CuredArcticPeeper, + TechType.CuredArrowRay, + TechType.CuredNootFish, + TechType.CuredTriops, + TechType.CuredFeatherFish, + TechType.CuredFeatherFishRed, + TechType.CuredDiscusFish, + TechType.HeatFruit, + TechType.LeafyFruit, + TechType.IceFruit, }; public static List Water = new List { @@ -178,6 +230,7 @@ public static class AutosorterCategoryData TechType.DisinfectedWater, TechType.FilteredWater, TechType.StillsuitWater, + TechType.WaterPurificationTablet, }; public static List ScannerRoomUpgrades = new List { @@ -226,6 +279,16 @@ public static class AutosorterCategoryData TechType.VehicleHullModule3, TechType.VehiclePowerUpgradeModule, TechType.VehicleStorageModule, + TechType.SeaTruckUpgradeAfterburner, + TechType.SeaTruckUpgradeThruster, + TechType.SeaTruckUpgradeEnergyEfficiency, + TechType.SeaTruckUpgradePerimeterDefense, + TechType.SeaTruckUpgradeHorsePower, + TechType.SeaTruckUpgradeHull1, + TechType.SeaTruckUpgradeHull2, + TechType.SeaTruckUpgradeHull3, + TechType.HoverbikeJumpModule, + TechType.HoverbikeIceWormReductionModule }; public static List Equipment = new List { @@ -244,6 +307,12 @@ public static class AutosorterCategoryData TechType.SwimChargeFins, TechType.Tank, TechType.UltraGlideFins, + TechType.ColdSuit, + TechType.ColdSuitGloves, + TechType.ColdSuitHelmet, + TechType.SuitBoosterTank, + TechType.Constructor, + TechType.Hoverbike, }; public static List Tools = new List { @@ -272,6 +341,14 @@ public static class AutosorterCategoryData TechType.StasisRifle, TechType.Welder, TechType.LuggageBag, + TechType.Thumper, + TechType.TeleportationTool, + TechType.MetalDetector, + TechType.FlashlightHelmet, + TechType.QuantumLocker, + TechType.SnowBall, + TechType.SpyPenguin, + TechType.SpyPenguinRemote, }; public static List Torpedoes = new List { @@ -319,6 +396,13 @@ public static class AutosorterCategoryData TechType.SpikePlantSeed, TechType.SpottedLeavesPlantSeed, TechType.WhiteMushroomSpore, + TechType.KelpRootPustule, + TechType.KelpRootPustuleSeed, + TechType.GenericRibbonSeed, + TechType.FrozenRiverPlant2Seeds, + TechType.GenericSpiralChunk, + TechType.DeepLilyShroomSeed, + TechType.SmallMaroonPlantSeed, }; public static List Metals = new List { @@ -347,6 +431,7 @@ public static class AutosorterCategoryData TechType.SeaTreaderPoop, TechType.StalkerTooth, TechType.JellyPlant, + TechType.SnowStalkerFur, }; public static List Electronics = new List { @@ -372,6 +457,7 @@ public static class AutosorterCategoryData TechType.Polyaniline, TechType.PrecursorIonCrystal, TechType.Silicone, + TechType.HydraulicFluid, }; public static List CrystalMaterials = new List { From c9418f346c31f64fce4ccc6aeb20fdd7ca450128 Mon Sep 17 00:00:00 2001 From: DaWrecka <61927940+DaWrecka@users.noreply.github.com> Date: Mon, 1 Feb 2021 21:04:11 +0000 Subject: [PATCH 07/11] Public beta release disabled most log outputs, and added what I believe to be most of the new (post-SN1) inventory TechTypes to the Autosort categories --- .../AutosortLockers/AutosortLocker.cs | 36 +++++++++---------- .../AutosortLockers/AutosortTarget.cs | 32 ++++++++--------- .../AutosortLockers/AutosorterCategories.cs | 9 +++++ 3 files changed, 43 insertions(+), 34 deletions(-) diff --git a/SubnauticaModSystem/AutosortLockers/AutosortLocker.cs b/SubnauticaModSystem/AutosortLockers/AutosortLocker.cs index f63b72a..17848c2 100644 --- a/SubnauticaModSystem/AutosortLockers/AutosortLocker.cs +++ b/SubnauticaModSystem/AutosortLockers/AutosortLocker.cs @@ -359,52 +359,52 @@ public override GameObject GetGameObject() public override IEnumerator GetGameObjectAsync(IOut gameObject) { - Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 1"); + //Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 1"); CoroutineTask task = CraftData.GetPrefabForTechTypeAsync(TechType.SmallLocker); yield return task; - Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 2"); + //Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 2"); GameObject originalPrefab = task.GetResult(); GameObject prefab = GameObject.Instantiate(originalPrefab); - Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 3, prefab " + (prefab == null ? "is" : "is not") + " null"); + //Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 3, prefab " + (prefab == null ? "is" : "is not") + " null"); - Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 4"); + //Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 4"); // TEST StorageContainer container = prefab.GetComponent(); - Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 4.1, container.container is " + (container.container == null ? "is" : "is not") + " null"); + //Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 4.1, container.container is " + (container.container == null ? "is" : "is not") + " null"); container.width = Mod.config.AutosorterWidth; - Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 4.2"); + //Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 4.2"); container.height = Mod.config.AutosorterHeight; - Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 4.3"); + //Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 4.3"); container.Resize(Mod.config.AutosorterWidth, Mod.config.AutosorterHeight); - Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 5"); + //Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 5"); var meshRenderers = prefab.GetComponentsInChildren(); foreach (var meshRenderer in meshRenderers) { meshRenderer.material.color = new Color(1, 0, 0); } - Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 6"); + //Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 6"); var prefabText = prefab.GetComponentInChildren(); - Logger.Log($"AutosortLockerBuildable.GetGameObjectAsync: 6.1, prefabText == {prefabText.ToString()}"); + //Logger.Log($"AutosortLockerBuildable.GetGameObjectAsync: 6.1, prefabText == {prefabText.ToString()}"); var label = prefab.FindChild("Label"); DestroyImmediate(label); - Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 7"); + //Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 7"); var autoSorter = prefab.AddComponent(); - Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 8"); + //Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 8"); var canvas = LockerPrefabShared.CreateCanvas(prefab.transform); - Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 8.1"); + //Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 8.1"); autoSorter.background = LockerPrefabShared.CreateBackground(canvas.transform); - Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 8.2"); + //Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 8.2"); autoSorter.icon = LockerPrefabShared.CreateIcon(autoSorter.background.transform, MainColor, 40); - Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 8.3: prefabText " + (prefabText == null ? "is" : "is not") + " null"); + //Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 8.3: prefabText " + (prefabText == null ? "is" : "is not") + " null"); autoSorter.text = LockerPrefabShared.CreateText(autoSorter.background.transform, prefabText, MainColor, 0, 14, "Autosorter"); - Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 9"); + //Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 9"); autoSorter.sortingText = LockerPrefabShared.CreateText(autoSorter.background.transform, prefabText, MainColor, -120, 12, "Sorting..."); #if SUBNAUTICA autoSorter.sortingText.alignment = TextAnchor.UpperCenter; @@ -412,13 +412,13 @@ public override IEnumerator GetGameObjectAsync(IOut gameObject) autoSorter.sortingText.alignment = TextAlignmentOptions.Top; #endif - Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 10"); + //Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 10"); autoSorter.background.gameObject.SetActive(false); autoSorter.icon.gameObject.SetActive(false); autoSorter.text.gameObject.SetActive(false); autoSorter.sortingText.gameObject.SetActive(false); - Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 11"); + //Logger.Log("AutosortLockerBuildable.GetGameObjectAsync: 11"); //return prefab; gameObject.Set(prefab); yield break; diff --git a/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs b/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs index 0222681..27c8dfb 100644 --- a/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs +++ b/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs @@ -574,26 +574,26 @@ public AutosortTargetBuildable() public override IEnumerator GetGameObjectAsync(IOut gameObject) { - Logger.Log("AutosortTargetBuildable.GetGameObjectAsync: 1"); + //Logger.Log("AutosortTargetBuildable.GetGameObjectAsync: 1"); TaskResult result = new TaskResult(); yield return GetPrefabAsync(TechType.SmallLocker, result); - Logger.Log("AutosortTargetBuildable.GetGameObjectAsync: 2"); + //Logger.Log("AutosortTargetBuildable.GetGameObjectAsync: 2"); GameObject basePrefab = result.Get(); GameObject prefab = GameObject.Instantiate(basePrefab); - Logger.Log("AutosortTargetBuildable.GetGameObjectAsync: 3"); + //Logger.Log("AutosortTargetBuildable.GetGameObjectAsync: 3"); StorageContainer container = prefab.GetComponent(); - Logger.Log("AutosortTargetBuildable.GetGameObjectAsync: 3.1"); + //Logger.Log("AutosortTargetBuildable.GetGameObjectAsync: 3.1"); container.width = Mod.config.ReceptacleWidth; - Logger.Log("AutosortTargetBuildable.GetGameObjectAsync: 3.2"); + //Logger.Log("AutosortTargetBuildable.GetGameObjectAsync: 3.2"); container.height = Mod.config.ReceptacleHeight; - Logger.Log("AutosortTargetBuildable.GetGameObjectAsync: 3.3, container.container " + (container.container == null ? "is" : "is not") + " null"); + //Logger.Log("AutosortTargetBuildable.GetGameObjectAsync: 3.3, container.container " + (container.container == null ? "is" : "is not") + " null"); container.Resize(Mod.config.ReceptacleWidth, Mod.config.ReceptacleHeight); - Logger.Log("AutosortTargetBuildable.GetGameObjectAsync: 4"); + //Logger.Log("AutosortTargetBuildable.GetGameObjectAsync: 4"); gameObject.Set(prefab); yield break; @@ -638,25 +638,25 @@ public AutosortStandingTargetBuildable() public override IEnumerator GetGameObjectAsync(IOut gameObject) { - Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 1"); + //Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 1"); TaskResult result = new TaskResult(); yield return GetPrefabAsync(TechType.Locker, result); - Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 2"); + //Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 2"); GameObject basePrefab = result.Get(); GameObject prefab = GameObject.Instantiate(basePrefab); - Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 3"); + //Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 3"); StorageContainer container = prefab.GetComponent(); - Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 3.1"); + //Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 3.1"); container.width = Mod.config.StandingReceptacleWidth; - Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 3.2"); + //Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 3.2"); container.height = Mod.config.StandingReceptacleHeight; - Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 3.3, container.container " + (container.container == null ? "is" : "is not") + " null"); + //Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 3.3, container.container " + (container.container == null ? "is" : "is not") + " null"); container.Resize(Mod.config.StandingReceptacleWidth, Mod.config.StandingReceptacleHeight); - Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 4"); + //Logger.Log("AutosortStandingTargetBuildable.GetGameObjectAsync: 4"); gameObject.Set(prefab); yield break; } @@ -718,9 +718,9 @@ public static IEnumerator GetPrefabAsync(TechType basePrefab, IOut g yield return task; //var smallLockerPrefab = CraftData.GetPrefabForTechType(TechType.SmallLocker); - Logger.Log($"GetPrefabAsync() attempting to instantiate smallLockerPrefab"); + //Logger.Log($"GetPrefabAsync() attempting to instantiate smallLockerPrefab"); var smallLockerPrefab = GameObject.Instantiate(task.GetResult()); - Logger.Log($"GetPrefabAsync() attempting to instantiate autosortTarget; smallLockerPrefab " + (smallLockerPrefab == null ? "is" : "is not") + " null"); + //Logger.Log($"GetPrefabAsync() attempting to instantiate autosortTarget; smallLockerPrefab " + (smallLockerPrefab == null ? "is" : "is not") + " null"); #if SUBNAUTICA autosortTarget.textPrefab = GameObject.Instantiate(smallLockerPrefab.GetComponentInChildren()); #elif BELOWZERO diff --git a/SubnauticaModSystem/AutosortLockers/AutosorterCategories.cs b/SubnauticaModSystem/AutosortLockers/AutosorterCategories.cs index e5ba63e..7bb7116 100644 --- a/SubnauticaModSystem/AutosortLockers/AutosorterCategories.cs +++ b/SubnauticaModSystem/AutosortLockers/AutosorterCategories.cs @@ -58,6 +58,15 @@ public static class AutosorterCategoryData TechType.Peeper, TechType.Reginald, TechType.Spadefish, + TechType.SpinnerFish, + TechType.Symbiote, + TechType.ArcticPeeper, + TechType.ArrowRay, + TechType.NootFish, + TechType.Triops, + TechType.FeatherFish, + TechType.FeatherFishRed, + TechType.DiscusFish, }; public static List AlterraArtifacts = new List { From f0edf9a45f8edae1567f9ed3de9b65e5e7562457 Mon Sep 17 00:00:00 2001 From: DaWrecka <61927940+DaWrecka@users.noreply.github.com> Date: Sun, 28 Mar 2021 19:36:12 +0100 Subject: [PATCH 08/11] 2021-03-28 multiple updates Changed all projects to target .NET Framework v4.7.2 Changed all projects to use programmatic paths, (e.g. "$(GameDir)" ) instead of a static game path Updated all projects to use new Harmony references (e.g. "new Harmony()" instead of "HarmonyInstance.Create") AutosortLockers: *) Added a patch to CanvasLink to prevent NullReferenceExceptions caused by UWE code not sanity-checking canvases *) Added config options for standing receptacle capacity *) Modified config validation to use named constants Better Scanner Blips: *) Added a bit of code which is, as yet, inert, intended to allow for blip distances to be considered from the crosshair, rather than world; for example, to allow blips to have their size on-screen varied based on how close they are to the crosshair, not how close they are to the player. *) Added code, including patching the ResourceTracker class, so that scanner blips on fragments will show the fragment's name, e.g. "Mobile Vehicle Bay fragment", rather than just "Fragment"; code is currently not functional. (Some fragments get the right name, some just get "Fragment", and some get the name for a completely different fragment) *) Used compiler directives to allow the code to be compiled for SN1 or BZ; not currently tested with SN1 --- .../AutosortLockers/AutosortLockersSML.csproj | 7 +- .../AutosortLockers/AutosorterCategories.cs | 26 +++++ .../AutosortLockers/CanvasLink_Patch.cs | 59 ++++++++++ .../AutosortLockers/CustomizeScreen.cs | 13 --- SubnauticaModSystem/AutosortLockers/Mod.cs | 14 ++- .../BaseTeleporters/BaseTeleporters.csproj | 2 +- SubnauticaModSystem/BaseTeleporters/Mod.cs | 2 +- .../Patches/BuilderUtils_Patches.cs | 2 +- .../Patches/Teleporter_Patches.cs | 2 +- .../BetterPowerInfo/BetterPowerInfo.csproj | 14 +-- SubnauticaModSystem/BetterPowerInfo/Mod.cs | 2 +- .../BetterPowerInfo/ModLoaderIntegration.cs | 2 +- .../uGUI_PowerIndicator_Initialize_Patch.cs | 2 +- .../BetterScannerBlips.csproj | 23 ++-- .../BetterScannerBlips/BlipIdentifier.cs | 21 ++++ .../BetterScannerBlips/Config.cs | 12 +++ .../BetterScannerBlips/CustomBlip.cs | 59 +++++++++- SubnauticaModSystem/BetterScannerBlips/Mod.cs | 8 +- .../uGUI_ResourceTracker_UpdateBlips_Patch.cs | 38 ++++++- .../Properties/Resources.Designer.cs | 2 +- .../BetterScannerBlips/ResourceTracker.cs | 101 ++++++++++++++++++ .../BlueprintTracker/BlueprintTracker.csproj | 4 +- SubnauticaModSystem/BlueprintTracker/Mod.cs | 2 +- .../uGUI_BlueprintEntry_SetIcon_Patch.cs | 2 +- .../uGUI_PowerIndicator_Initialize_Patch.cs | 2 +- .../Common/Mod/LockerPrefabShared.cs | 2 +- SubnauticaModSystem/Common/Mod/ModUtils.cs | 17 +-- .../CustomPings/CustomBeacons.csproj | 2 +- SubnauticaModSystem/CustomPings/Mod.cs | 2 +- .../CustomPings/Patches/PingTab_Patches.cs | 2 +- .../CustomPings/Patches/Ping_Patches.cs | 2 +- .../CustomizedStorage.csproj | 2 +- SubnauticaModSystem/CustomizedStorage/Mod.cs | 2 +- .../CustomizedStorage/Patches/Patches.cs | 2 +- .../DockedVehicleStorageAccess/Config.cs | 13 ++- .../DockedVehicleStorageAccess.csproj | 6 +- .../DockedVehicleStorageAccess/Mod.cs | 11 +- .../MoonpoolTerminalController.cs | 4 + .../Patches/DockingBay_Patches.cs | 2 +- .../HabitatControlPanel.csproj | 2 +- .../HabitatControlPanel/Mod.cs | 2 +- .../Patches/Ping_Patches.cs | 2 +- .../HudConfig/HudConfig.csproj | 2 +- SubnauticaModSystem/HudConfig/Mod.cs | 2 +- .../HudConfig/Patches/HUD_Patches.cs | 2 +- .../LongLockerNames/LongLockerNames.csproj | 2 +- SubnauticaModSystem/LongLockerNames/Mod.cs | 2 +- .../Patches/uGUI_SignInput_Awake_Patch.cs | 2 +- .../ModInjector_MoreQuickSlots.csproj | 2 +- SubnauticaModSystem/MoreQuickSlots/Mod.cs | 2 +- .../MoreQuickSlots/MoreQuickSlots.csproj | 2 +- .../Patches/QuickSlots_Ctor_Patch.cs | 2 +- .../Patches/uGUI_QuickSlots_Init_Patch.cs | 2 +- .../PrawnsuitLightswitch/Mod.cs | 2 +- .../Patches/Exosuit_Patches.cs | 2 +- .../PrawnsuitLightswitch.csproj | 2 +- SubnauticaModSystem/SeaglideMapMod/Mod.cs | 2 +- .../Patches/ScannerTool_Patches.cs | 2 +- .../Patches/Seaglide_Patches.cs | 2 +- .../SeaglideMapMod/SeaglideMapControls.csproj | 2 +- .../TorpedoImprovements/Mod.cs | 2 +- .../Patches/Exosuit_Patches.cs | 2 +- .../Patches/Seamoth_Patches.cs | 2 +- .../TorpedoImprovements.csproj | 2 +- SubnauticaModSystem/WhiteLights/Mod.cs | 2 +- .../WhiteLights/Patches/Exosuit_Patches.cs | 2 +- .../WhiteLights/Patches/Seaglide_Patches.cs | 2 +- .../WhiteLights/Patches/Seamoth_Patches.cs | 2 +- .../WhiteLights/WhiteLights.csproj | 2 +- .../zzzEnableConsole/zzzEnableConsole.csproj | 2 +- 70 files changed, 444 insertions(+), 108 deletions(-) create mode 100644 SubnauticaModSystem/AutosortLockers/CanvasLink_Patch.cs create mode 100644 SubnauticaModSystem/BetterScannerBlips/BlipIdentifier.cs create mode 100644 SubnauticaModSystem/BetterScannerBlips/ResourceTracker.cs diff --git a/SubnauticaModSystem/AutosortLockers/AutosortLockersSML.csproj b/SubnauticaModSystem/AutosortLockers/AutosortLockersSML.csproj index 4755ee8..9d4456b 100644 --- a/SubnauticaModSystem/AutosortLockers/AutosortLockersSML.csproj +++ b/SubnauticaModSystem/AutosortLockers/AutosortLockersSML.csproj @@ -134,15 +134,16 @@ False - $(GameDir)\$(DataFolder)\Managed\Unity.TextMeshPro.dll - False - + $(GameDir)\$(DataFolder)\Managed\Unity.TextMeshPro.dll + False + + diff --git a/SubnauticaModSystem/AutosortLockers/AutosorterCategories.cs b/SubnauticaModSystem/AutosortLockers/AutosorterCategories.cs index 7bb7116..85af185 100644 --- a/SubnauticaModSystem/AutosortLockers/AutosorterCategories.cs +++ b/SubnauticaModSystem/AutosortLockers/AutosorterCategories.cs @@ -58,6 +58,7 @@ public static class AutosorterCategoryData TechType.Peeper, TechType.Reginald, TechType.Spadefish, +#if BELOWZERO TechType.SpinnerFish, TechType.Symbiote, TechType.ArcticPeeper, @@ -67,6 +68,9 @@ public static class AutosorterCategoryData TechType.FeatherFish, TechType.FeatherFishRed, TechType.DiscusFish, + TechType.Penguin, + TechType.PenguinBaby +#endif }; public static List AlterraArtifacts = new List { @@ -140,6 +144,7 @@ public static class AutosorterCategoryData TechType.LavaLizardEggUndiscovered, TechType.CrabsnakeEggUndiscovered, TechType.SpadefishEggUndiscovered, +#if BELOWZERO TechType.SeaMonkeyEgg, TechType.ArcticRayEgg, TechType.ArcticRayEggUndiscovered, @@ -169,6 +174,7 @@ public static class AutosorterCategoryData TechType.PenguinEggUndiscovered, TechType.RockPuncherEgg, TechType.RockPuncherEggUndiscovered +#endif }; public static List Food = new List { @@ -208,6 +214,7 @@ public static class AutosorterCategoryData TechType.HangingFruit, TechType.Melon, TechType.PurpleVegetable, +#if BELOWZERO TechType.CookedSpinnerfish, TechType.CookedSymbiote, TechType.CookedArcticPeeper, @@ -231,6 +238,7 @@ public static class AutosorterCategoryData TechType.HeatFruit, TechType.LeafyFruit, TechType.IceFruit, +#endif }; public static List Water = new List { @@ -239,7 +247,9 @@ public static class AutosorterCategoryData TechType.DisinfectedWater, TechType.FilteredWater, TechType.StillsuitWater, +#if BELOWZERO TechType.WaterPurificationTablet, +#endif }; public static List ScannerRoomUpgrades = new List { @@ -288,6 +298,7 @@ public static class AutosorterCategoryData TechType.VehicleHullModule3, TechType.VehiclePowerUpgradeModule, TechType.VehicleStorageModule, +#if BELOWZERO TechType.SeaTruckUpgradeAfterburner, TechType.SeaTruckUpgradeThruster, TechType.SeaTruckUpgradeEnergyEfficiency, @@ -298,6 +309,7 @@ public static class AutosorterCategoryData TechType.SeaTruckUpgradeHull3, TechType.HoverbikeJumpModule, TechType.HoverbikeIceWormReductionModule +#endif }; public static List Equipment = new List { @@ -315,6 +327,7 @@ public static class AutosorterCategoryData TechType.Stillsuit, TechType.SwimChargeFins, TechType.Tank, +#if BELOWZERO TechType.UltraGlideFins, TechType.ColdSuit, TechType.ColdSuitGloves, @@ -322,6 +335,7 @@ public static class AutosorterCategoryData TechType.SuitBoosterTank, TechType.Constructor, TechType.Hoverbike, +#endif }; public static List Tools = new List { @@ -349,6 +363,7 @@ public static class AutosorterCategoryData TechType.SmallStorage, TechType.StasisRifle, TechType.Welder, +#if BELOWZERO TechType.LuggageBag, TechType.Thumper, TechType.TeleportationTool, @@ -358,6 +373,7 @@ public static class AutosorterCategoryData TechType.SnowBall, TechType.SpyPenguin, TechType.SpyPenguinRemote, +#endif }; public static List Torpedoes = new List { @@ -375,6 +391,7 @@ public static class AutosorterCategoryData TechType.FernPalmSeed, TechType.GabeSFeatherSeed, TechType.HangingFruit, + TechType.JellyPlant, TechType.JellyPlantSeed, TechType.KooshChunk, TechType.Melon, @@ -405,13 +422,18 @@ public static class AutosorterCategoryData TechType.SpikePlantSeed, TechType.SpottedLeavesPlantSeed, TechType.WhiteMushroomSpore, +#if BELOWZERO TechType.KelpRootPustule, TechType.KelpRootPustuleSeed, TechType.GenericRibbonSeed, + TechType.FrozenRiverPlant2, TechType.FrozenRiverPlant2Seeds, TechType.GenericSpiralChunk, + TechType.DeepLilyShroom, TechType.DeepLilyShroomSeed, TechType.SmallMaroonPlantSeed, + TechType.LilyPadResource, +#endif }; public static List Metals = new List { @@ -440,7 +462,9 @@ public static class AutosorterCategoryData TechType.SeaTreaderPoop, TechType.StalkerTooth, TechType.JellyPlant, +#if BELOWZERO TechType.SnowStalkerFur, +#endif }; public static List Electronics = new List { @@ -466,7 +490,9 @@ public static class AutosorterCategoryData TechType.Polyaniline, TechType.PrecursorIonCrystal, TechType.Silicone, +#if BELOWZERO TechType.HydraulicFluid, +#endif }; public static List CrystalMaterials = new List { diff --git a/SubnauticaModSystem/AutosortLockers/CanvasLink_Patch.cs b/SubnauticaModSystem/AutosortLockers/CanvasLink_Patch.cs new file mode 100644 index 0000000..aea3859 --- /dev/null +++ b/SubnauticaModSystem/AutosortLockers/CanvasLink_Patch.cs @@ -0,0 +1,59 @@ +using HarmonyLib; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace AutosortLockers +{ + [HarmonyPatch(typeof(CanvasLink))] + public class CanvasLink_Patch + { + private static FieldInfo canvasesInfo = typeof(CanvasLink).GetField("canvases", BindingFlags.NonPublic | BindingFlags.Instance); + /* + private void SetCanvasesEnabled(bool enabled) + { + Canvas[] array = this.canvases; + for (int i = 0; i < array.Length; i++) + { + array[i].enabled = enabled; + } + } + */ + [HarmonyPatch("SetCanvasesEnabled")] + [HarmonyPrefix] + public static bool PrefixSetCanvasesEnabled(ref CanvasLink __instance) + { + if (__instance == null) + return false; + + //QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"PrefixSetCanvasesEnabled(): begin"); + Canvas[] array = (Canvas[])(canvasesInfo.GetValue(__instance)); + //QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"PrefixSetCanvasesEnabled(): canvases array " + ((array == null || array.Length < 1) ? "not " : "") + "successfully retrieved"); + List list = new List(); + if (array != null && array.Length > 0) + { + for (int i = 0; i < array.Length; i++) + { + //QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"PrefixSetCanvasesEnabled(): checking canvas array index {i}"); + if (array[i] != null) + { + list.Add(array[i]); + } + else + { + //QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"PrefixSetCanvasesEnabled(): Found null entry in canvas array at index {i}"); + } + + } + canvasesInfo.SetValue(__instance, list.ToArray()); + } + + //QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"PrefixSetCanvasesEnabled(): end"); + return true; + } + } +} diff --git a/SubnauticaModSystem/AutosortLockers/CustomizeScreen.cs b/SubnauticaModSystem/AutosortLockers/CustomizeScreen.cs index 414d4c0..c56708e 100644 --- a/SubnauticaModSystem/AutosortLockers/CustomizeScreen.cs +++ b/SubnauticaModSystem/AutosortLockers/CustomizeScreen.cs @@ -185,29 +185,24 @@ private void OnLockerColorPicked(int index) ////////////////////////////////////////////////////////////////////////////////////////////////////////////// public static CustomizeScreen Create(Transform parent, SaveDataEntry data, GameObject lockerPrefab = null) { - Logger.Log("CustomiseScreen.Create: 1"); #if SUBNAUTICA lockerPrefab = Resources.Load("Submarine/Build/SmallLocker"); var textPrefab = Instantiate(lockerPrefab.GetComponentInChildren()); #elif BELOWZERO var textPrefab = Instantiate(lockerPrefab.GetComponentInChildren()); #endif - Logger.Log("CustomiseScreen.Create: 2"); textPrefab.fontSize = 12; textPrefab.color = CustomizeScreen.ScreenContentColor; - Logger.Log("CustomiseScreen.Create: 3"); var screen = new GameObject("CustomizeScreen", typeof(RectTransform)).AddComponent(); RectTransformExtensions.SetParams(screen.rectTransform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), parent); RectTransformExtensions.SetSize(screen.rectTransform, 114, 241); - Logger.Log("CustomiseScreen.Create: 4"); screen.background = new GameObject("Background").AddComponent(); screen.background.sprite = ImageUtils.LoadSprite(Mod.GetAssetPath("CustomizeScreen.png")); RectTransformExtensions.SetParams(screen.background.rectTransform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), screen.transform); RectTransformExtensions.SetSize(screen.background.rectTransform, 114, 241); - Logger.Log("CustomiseScreen.Create: 5"); screen.labelLabel = LockerPrefabShared.CreateText(screen.background.transform, textPrefab, ScreenContentColor, 100, 9, "Label:"); RectTransformExtensions.SetSize(screen.labelLabel.rectTransform, 90, 40); #if SUBNAUTICA @@ -216,36 +211,28 @@ public static CustomizeScreen Create(Transform parent, SaveDataEntry data, GameO screen.labelLabel.alignment = TextAlignmentOptions.MidlineLeft; #endif - Logger.Log("CustomiseScreen.Create: 6"); screen.label = LabelController.Create(data, screen.background.transform, lockerPrefab); screen.label.rectTransform.anchoredPosition = new Vector2(0, 80); - Logger.Log("CustomiseScreen.Create: 7"); screen.exitButton = ConfigureButton.Create(screen.background.transform, Color.white, 40); var startX = 0; var startY = 30; - Logger.Log("CustomiseScreen.Create: 8"); screen.labelColorSetting = ColorSetting.Create(screen.background.transform, "Label Color", lockerPrefab); screen.labelColorSetting.rectTransform.anchoredPosition = new Vector2(startX, startY); - Logger.Log("CustomiseScreen.Create: 9"); screen.iconColorSetting = ColorSetting.Create(screen.background.transform, "Icon Color", lockerPrefab); screen.iconColorSetting.rectTransform.anchoredPosition = new Vector2(startX, startY - 19); - Logger.Log("CustomiseScreen.Create: 10"); screen.textColorSetting = ColorSetting.Create(screen.background.transform, "Filters Color", lockerPrefab); screen.textColorSetting.rectTransform.anchoredPosition = new Vector2(startX, startY - (19 * 2)); - Logger.Log("CustomiseScreen.Create: 11"); screen.buttonsColorSetting = ColorSetting.Create(screen.background.transform, "Misc Color", lockerPrefab); screen.buttonsColorSetting.rectTransform.anchoredPosition = new Vector2(startX, startY - (19 * 3)); - Logger.Log("CustomiseScreen.Create: 12"); screen.lockerColorSetting = ColorSetting.Create(screen.background.transform, "Locker Color", lockerPrefab); screen.lockerColorSetting.rectTransform.anchoredPosition = new Vector2(startX, startY - (19 * 4)); - Logger.Log("CustomiseScreen.Create: 13"); screen.colorPicker = ColorPicker.Create(screen.background.transform, lockerPrefab); screen.colorPicker.gameObject.SetActive(false); screen.colorPicker.rectTransform.anchoredPosition = new Vector2(0, 30); diff --git a/SubnauticaModSystem/AutosortLockers/Mod.cs b/SubnauticaModSystem/AutosortLockers/Mod.cs index aea5bb9..282cb5f 100644 --- a/SubnauticaModSystem/AutosortLockers/Mod.cs +++ b/SubnauticaModSystem/AutosortLockers/Mod.cs @@ -9,6 +9,7 @@ using Oculus.Newtonsoft.Json; #elif BELOWZERO using Newtonsoft.Json; +using SMLHelper.V2.Handlers; #endif using UnityEngine; using UWE; @@ -18,6 +19,9 @@ namespace AutosortLockers internal static class Mod { public const string SaveDataFilename = "AutosortLockerSMLSaveData.json"; + + private const int MAX_LOCKER_WIDTH = 8; + private const int MAX_LOCKER_HEIGHT = 10; public static Config config; public static SaveData saveData; public static List colors = new List(); @@ -75,10 +79,12 @@ private static void ValidateConfig() Config defaultConfig = new Config(); ModUtils.ValidateConfigValue("SortInterval", 0.1f, 10.0f, ref config, ref defaultConfig); - ModUtils.ValidateConfigValue("AutosorterWidth", 1, 8, ref config, ref defaultConfig); - ModUtils.ValidateConfigValue("AutosorterHeight", 1, 10, ref config, ref defaultConfig); - ModUtils.ValidateConfigValue("ReceptacleWidth", 1, 8, ref config, ref defaultConfig); - ModUtils.ValidateConfigValue("ReceptacleHeight", 1, 10, ref config, ref defaultConfig); + ModUtils.ValidateConfigValue("AutosorterWidth", 1, MAX_LOCKER_WIDTH, ref config, ref defaultConfig); + ModUtils.ValidateConfigValue("AutosorterHeight", 1, MAX_LOCKER_HEIGHT, ref config, ref defaultConfig); + ModUtils.ValidateConfigValue("ReceptacleWidth", 1, MAX_LOCKER_WIDTH, ref config, ref defaultConfig); + ModUtils.ValidateConfigValue("ReceptacleHeight", 1, MAX_LOCKER_HEIGHT, ref config, ref defaultConfig); + ModUtils.ValidateConfigValue("StandingReceptacleWidth", 1, MAX_LOCKER_WIDTH, ref config, ref defaultConfig); + ModUtils.ValidateConfigValue("StandingReceptacleHeight", 1, MAX_LOCKER_HEIGHT, ref config, ref defaultConfig); } public static SaveData GetSaveData() diff --git a/SubnauticaModSystem/BaseTeleporters/BaseTeleporters.csproj b/SubnauticaModSystem/BaseTeleporters/BaseTeleporters.csproj index add4567..46906f2 100644 --- a/SubnauticaModSystem/BaseTeleporters/BaseTeleporters.csproj +++ b/SubnauticaModSystem/BaseTeleporters/BaseTeleporters.csproj @@ -11,7 +11,7 @@ BaseTeleporters BaseTeleporters $(SolutionDir)$(AssemblyName)\$(Configuration)\ - v3.5 + v4.7.2 512 diff --git a/SubnauticaModSystem/BaseTeleporters/Mod.cs b/SubnauticaModSystem/BaseTeleporters/Mod.cs index 82433fd..e9f9291 100644 --- a/SubnauticaModSystem/BaseTeleporters/Mod.cs +++ b/SubnauticaModSystem/BaseTeleporters/Mod.cs @@ -1,6 +1,6 @@ using Common.Mod; using Common.Utility; -using Harmony; +using HarmonyLib; using System; using System.Collections; using System.Collections.Generic; diff --git a/SubnauticaModSystem/BaseTeleporters/Patches/BuilderUtils_Patches.cs b/SubnauticaModSystem/BaseTeleporters/Patches/BuilderUtils_Patches.cs index 1d35500..66293de 100644 --- a/SubnauticaModSystem/BaseTeleporters/Patches/BuilderUtils_Patches.cs +++ b/SubnauticaModSystem/BaseTeleporters/Patches/BuilderUtils_Patches.cs @@ -1,5 +1,5 @@ using Common.Mod; -using Harmony; +using HarmonyLib; using System; using UnityEngine; using UWE; diff --git a/SubnauticaModSystem/BaseTeleporters/Patches/Teleporter_Patches.cs b/SubnauticaModSystem/BaseTeleporters/Patches/Teleporter_Patches.cs index f819305..1b1aaa3 100644 --- a/SubnauticaModSystem/BaseTeleporters/Patches/Teleporter_Patches.cs +++ b/SubnauticaModSystem/BaseTeleporters/Patches/Teleporter_Patches.cs @@ -1,5 +1,5 @@ using Common.Mod; -using Harmony; +using HarmonyLib; using System; using System.Collections.Generic; using System.Linq; diff --git a/SubnauticaModSystem/BetterPowerInfo/BetterPowerInfo.csproj b/SubnauticaModSystem/BetterPowerInfo/BetterPowerInfo.csproj index cbcc503..593ea0b 100644 --- a/SubnauticaModSystem/BetterPowerInfo/BetterPowerInfo.csproj +++ b/SubnauticaModSystem/BetterPowerInfo/BetterPowerInfo.csproj @@ -11,7 +11,7 @@ BetterPowerInfo BetterPowerInfo $(SolutionDir)$(AssemblyName)\$(Configuration)\ - v4.7.1 + v4.7.2 512 @@ -45,7 +45,7 @@ SubnauticaZero_Data SMLHelper_BZ AnyCPU - 7.1 + 8.0 prompt @@ -56,7 +56,7 @@ Subnautica_Data Modding Helper AnyCPU - 7.1 + 8.0 prompt @@ -71,6 +71,9 @@ False $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp-firstpass.dll + + $(GameDir)\$(DataFolder)\Managed\NewtonSoft.Json.dll + $(GameDir)\QMods\$(SMLHelperFolder)\SMLHelper.dll @@ -127,8 +130,7 @@ - + @@ -159,4 +161,4 @@ xcopy $(ProjectDir)mod.json $(GameDir)\QMods\$(ProjectName)\ /q /y xcopy $(TargetPath) $(GameDir)Zero\QMods\$(ProjectName)\ /q /y xcopy $(ProjectDir)mod.json $(GameDir)Zero\QMods\$(ProjectName)\ /q /y - \ No newline at end of file + diff --git a/SubnauticaModSystem/BetterPowerInfo/Mod.cs b/SubnauticaModSystem/BetterPowerInfo/Mod.cs index 899e58a..3983f41 100644 --- a/SubnauticaModSystem/BetterPowerInfo/Mod.cs +++ b/SubnauticaModSystem/BetterPowerInfo/Mod.cs @@ -1,5 +1,5 @@ using Common.Utility; -using Harmony; +using HarmonyLib; using System; using System.IO; using System.Reflection; diff --git a/SubnauticaModSystem/BetterPowerInfo/ModLoaderIntegration.cs b/SubnauticaModSystem/BetterPowerInfo/ModLoaderIntegration.cs index 9f56606..83319ee 100644 --- a/SubnauticaModSystem/BetterPowerInfo/ModLoaderIntegration.cs +++ b/SubnauticaModSystem/BetterPowerInfo/ModLoaderIntegration.cs @@ -1,4 +1,4 @@ -using Harmony; +using HarmonyLib; using System; using System.Reflection; using UnityEngine; diff --git a/SubnauticaModSystem/BetterPowerInfo/Patches/uGUI_PowerIndicator_Initialize_Patch.cs b/SubnauticaModSystem/BetterPowerInfo/Patches/uGUI_PowerIndicator_Initialize_Patch.cs index 1a863ae..720c043 100644 --- a/SubnauticaModSystem/BetterPowerInfo/Patches/uGUI_PowerIndicator_Initialize_Patch.cs +++ b/SubnauticaModSystem/BetterPowerInfo/Patches/uGUI_PowerIndicator_Initialize_Patch.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using Harmony; +using HarmonyLib; using System.Reflection; namespace BetterPowerInfo.Patches diff --git a/SubnauticaModSystem/BetterScannerBlips/BetterScannerBlips.csproj b/SubnauticaModSystem/BetterScannerBlips/BetterScannerBlips.csproj index c0a2046..a70f27c 100644 --- a/SubnauticaModSystem/BetterScannerBlips/BetterScannerBlips.csproj +++ b/SubnauticaModSystem/BetterScannerBlips/BetterScannerBlips.csproj @@ -11,7 +11,7 @@ BetterScannerBlips BetterScannerBlips $(SolutionDir)$(AssemblyName)\$(Configuration)\ - v4.7.1 + v4.7.2 512 @@ -71,6 +71,9 @@ False $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp-firstpass.dll + + $(GameDir)\BepInEx\plugins\QModManager\QModInstaller.dll + False $(GameDir)\$(DataFolder)\Managed\NewtonSoft.Json.dll @@ -111,8 +114,13 @@ $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIModule.dll + + $(GameDir)\$(DataFolder)\Managed\Unity.TextMeshPro.dll + False + + @@ -125,6 +133,7 @@ True Resources.resx + @@ -140,12 +149,12 @@ - xcopy $(TargetPath) $(GameDir)\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)mod.json $(GameDir)\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)Assets $(GameDir)\QMods\$(ProjectName)\Assets\ /q /y /i + rem xcopy $(TargetPath) $(GameDir)\QMods\$(ProjectName)\ /q /y +rem xcopy $(ProjectDir)mod.json $(GameDir)\QMods\$(ProjectName)\ /q /y +rem xcopy $(ProjectDir)Assets $(GameDir)\QMods\$(ProjectName)\Assets\ /q /y /i -xcopy $(TargetPath) D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)mod.json D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)Assets D:\EpicGames\Subnautica\QMods\$(ProjectName)\Assets\ /q /y /i +rem xcopy $(TargetPath) D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y +rem xcopy $(ProjectDir)mod.json D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y +rem xcopy $(ProjectDir)Assets D:\EpicGames\Subnautica\QMods\$(ProjectName)\Assets\ /q /y /i \ No newline at end of file diff --git a/SubnauticaModSystem/BetterScannerBlips/BlipIdentifier.cs b/SubnauticaModSystem/BetterScannerBlips/BlipIdentifier.cs new file mode 100644 index 0000000..68d5ca6 --- /dev/null +++ b/SubnauticaModSystem/BetterScannerBlips/BlipIdentifier.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace BetterScannerBlips +{ + internal class BlipIdentifier : MonoBehaviour + { + // A component added to a GUI scanner blip that stores information about the actual TechType of a fragment, allowing the code to identify exactly what type of Fragment the object is + + internal string uniqueId; + internal TechType actualTechType { get + { + return ResourceTrackerPatches.GetTechTypeForId(this.uniqueId); + } + } + } +} diff --git a/SubnauticaModSystem/BetterScannerBlips/Config.cs b/SubnauticaModSystem/BetterScannerBlips/Config.cs index 0f4fca7..b9acd66 100644 --- a/SubnauticaModSystem/BetterScannerBlips/Config.cs +++ b/SubnauticaModSystem/BetterScannerBlips/Config.cs @@ -21,5 +21,17 @@ class Config public bool ShowDistance = true; public bool NoText = false; public string ToggleKey = "l"; + + // Added by DaWrecka; if bUseScreenDistance, then distance is counted as distance on screen from the crosshair, expressed as a fraction of total screen real estate. + // The maximum such distance is 0.5, because the crosshair is always dead-centre of the screen. + public bool bUseScreenDistance = false; + public float MaxScreenRange = 0.5f; + public float MaxScreenRangeScale = 0.2f; + public float CloseScreenRange = 0.15f; + public float CloseScreenRangeScale = 1.0f; + public float MinScreenRange = 0.1f; + public float MinScreenRangeScale = 10.0f; + public float TextScreenRange = 0.2f; + public float AlphaOutScreenRange = 0.2f; } } diff --git a/SubnauticaModSystem/BetterScannerBlips/CustomBlip.cs b/SubnauticaModSystem/BetterScannerBlips/CustomBlip.cs index f28585c..d7563e3 100644 --- a/SubnauticaModSystem/BetterScannerBlips/CustomBlip.cs +++ b/SubnauticaModSystem/BetterScannerBlips/CustomBlip.cs @@ -3,21 +3,34 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using TMPro; using UnityEngine; using UnityEngine.UI; namespace BetterScannerBlips { - class CustomBlip : MonoBehaviour + public class CustomBlip : MonoBehaviour { private static Color circleColor; private static Color textColor; private Image image; +#if SUBNAUTICA private Text text; +#elif BELOWZERO + private TextMeshProUGUI text; +#endif private TechType techType; private string resourceName; + private BlipIdentifier blipId; + + public void ResetCustomBlip() + { + this.techType = TechType.None; + this.resourceName = ""; + } + public static void InitializeColors() { if (Mod.config.CustomColors) @@ -36,20 +49,56 @@ public static void InitializeColors() private void Awake() { image = gameObject.GetComponent(); +#if SUBNAUTICA text = gameObject.GetComponentInChildren(); +#elif BELOWZERO + text = gameObject.GetComponentInChildren(); +#endif } - public void Refresh(ResourceTracker.ResourceInfo target) + public void Refresh(ResourceTrackerDatabase.ResourceInfo target) { if (target != null) { var vectorToPlayer = Player.main.transform.position - target.position; var distance = vectorToPlayer.magnitude; - if (resourceName == string.Empty || techType != target.techType) + if (techType == TechType.None) { - techType = target.techType; - resourceName = Language.main.Get(techType); + TechType thisTechType = target.techType; + QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, + $"CustomBlip.Refresh(): Attempting to establish resourceName for ResourceInfo with unique ID {target.uniqueId}, which includes TechType {thisTechType}"); + if (thisTechType == TechType.Fragment) + { + blipId = gameObject.GetComponent(); + if (blipId == null) + { + blipId = gameObject.AddComponent(); + blipId.uniqueId = target.uniqueId; + } + if (blipId != null) + { + thisTechType = blipId.actualTechType; + if (thisTechType == TechType.None) + { + QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, + $"CustomBlip.Refresh(): Could not get TechType from BlipIdentifier, attempting to use ResourceTrackerPatches.GetTechTypeForId"); + thisTechType = ResourceTrackerPatches.GetTechTypeForId(target.uniqueId); + QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, + $"CustomBlip.Refresh(): Got TechType of {techType.AsString()}"); + } + } + } + + if (thisTechType != TechType.None && thisTechType != TechType.Fragment) + { + techType = thisTechType; + resourceName = Language.main.Get(techType); + QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, + $"For unique ID {target.uniqueId}, got TechType {thisTechType.AsString()} and resourceName '{resourceName}'"); + } + else + resourceName = "(*)" + Language.main.Get(target.techType); } RefreshColor(distance); diff --git a/SubnauticaModSystem/BetterScannerBlips/Mod.cs b/SubnauticaModSystem/BetterScannerBlips/Mod.cs index 8c6ca73..49fd60b 100644 --- a/SubnauticaModSystem/BetterScannerBlips/Mod.cs +++ b/SubnauticaModSystem/BetterScannerBlips/Mod.cs @@ -1,13 +1,17 @@ using Common.Mod; using Common.Utility; -using Harmony; using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Reflection; using UnityEngine; +using HarmonyLib; +#if SUBNAUTICA using Oculus.Newtonsoft.Json; +#elif BELOWZERO +using Newtonsoft.Json; +#endif using System.Threading; using System.Globalization; @@ -24,7 +28,7 @@ public static void Patch(string modDirectory = null) Mod.modDirectory = modDirectory ?? "Subnautica_Data/Managed"; LoadConfig(); - HarmonyInstance harmony = HarmonyInstance.Create("com.BetterScannerBlips.mod"); + var harmony = new Harmony("com.BetterScannerBlips.mod"); harmony.PatchAll(Assembly.GetExecutingAssembly()); CustomBlip.InitializeColors(); diff --git a/SubnauticaModSystem/BetterScannerBlips/Patches/uGUI_ResourceTracker_UpdateBlips_Patch.cs b/SubnauticaModSystem/BetterScannerBlips/Patches/uGUI_ResourceTracker_UpdateBlips_Patch.cs index 2627f82..11027df 100644 --- a/SubnauticaModSystem/BetterScannerBlips/Patches/uGUI_ResourceTracker_UpdateBlips_Patch.cs +++ b/SubnauticaModSystem/BetterScannerBlips/Patches/uGUI_ResourceTracker_UpdateBlips_Patch.cs @@ -1,17 +1,23 @@ using Common.Mod; -using Harmony; +using HarmonyLib; +#if SUBNAUTICA +using Oculus.Newtonsoft.Json; +#elif BELOWZERO +using Newtonsoft.Json; +#endif using System; using System.Collections; using System.Collections.Generic; +using System.Linq; using System.Reflection; +using System.Reflection.Emit; using UnityEngine; using UnityEngine.UI; namespace BetterScannerBlips.Patches { [HarmonyPatch(typeof(uGUI_ResourceTracker))] - [HarmonyPatch("UpdateBlips")] - class uGUI_ResourceTracker_UpdateBlips_Patch + internal class uGUI_ResourceTracker_UpdateBlips_Patch { private static readonly FieldInfo uGUI_ResourceTracker_blips = typeof(uGUI_ResourceTracker).GetField("blips", BindingFlags.NonPublic | BindingFlags.Instance); private static readonly FieldInfo uGUI_ResourceTracker_nodes = typeof(uGUI_ResourceTracker).GetField("nodes", BindingFlags.NonPublic | BindingFlags.Instance); @@ -19,6 +25,19 @@ class uGUI_ResourceTracker_UpdateBlips_Patch private static bool hide = false; + private static void CustomiseBlip(GameObject blipObject, ResourceTrackerDatabase.ResourceInfo node) + { + if(node.techType == TechType.Fragment && blipObject.GetComponent() == null) + { + QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"CustomiseBlip: Customising blip for ResourceInfo node (position=({node.position.ToString()}), techType={node.techType.AsString()}, uniqueId={node.uniqueId}"); + BlipIdentifier blipId = blipObject.EnsureComponent(); + blipId.uniqueId = node.uniqueId; + QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"CustomiseBlip: got actual techType of {blipId.actualTechType}"); + } + } + + [HarmonyPrefix] + [HarmonyPatch("UpdateBlips")] private static bool Prefix(uGUI_ResourceTracker __instance) { if (__instance != null && __instance.blip != null) @@ -33,6 +52,8 @@ private static bool Prefix(uGUI_ResourceTracker __instance) return true; } + [HarmonyPostfix] + [HarmonyPatch("UpdateBlips")] private static void Postfix(uGUI_ResourceTracker __instance) { if (Blip_gameObject == null) @@ -47,20 +68,29 @@ private static void Postfix(uGUI_ResourceTracker __instance) ErrorMessage.AddDebug(string.Format("Scanner Blips Toggled: {0}", hide ? $"OFF (Press {Mod.config.ToggleKey} to show)" : "ON")); } - HashSet nodes = (HashSet)uGUI_ResourceTracker_nodes.GetValue(__instance); +#if SUBNAUTICA + HashSet nodes = (HashSet)uGUI_ResourceTracker_nodes.GetValue(__instance); +#elif BELOWZERO + HashSet nodes = (HashSet)uGUI_ResourceTracker_nodes.GetValue(__instance); +#endif IList blips = (IList)uGUI_ResourceTracker_blips.GetValue(__instance); Camera camera = MainCamera.camera; Vector3 position = camera.transform.position; Vector3 forward = camera.transform.forward; int i = 0; +#if SUBNAUTICA foreach (ResourceTracker.ResourceInfo resourceInfo in nodes) +#elif BELOWZERO + foreach (ResourceTrackerDatabase.ResourceInfo resourceInfo in nodes) +#endif { Vector3 lhs = resourceInfo.position - position; if (Vector3.Dot(lhs, forward) > 0f) { var blipObject = (GameObject)Blip_gameObject.GetValue(blips[i]); var customBlip = blipObject.GetComponent(); + CustomiseBlip(blipObject, resourceInfo); customBlip.Refresh(resourceInfo); diff --git a/SubnauticaModSystem/BetterScannerBlips/Properties/Resources.Designer.cs b/SubnauticaModSystem/BetterScannerBlips/Properties/Resources.Designer.cs index b1e2a3d..987dcd1 100644 --- a/SubnauticaModSystem/BetterScannerBlips/Properties/Resources.Designer.cs +++ b/SubnauticaModSystem/BetterScannerBlips/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace BetterScannerBlips.Properties { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { diff --git a/SubnauticaModSystem/BetterScannerBlips/ResourceTracker.cs b/SubnauticaModSystem/BetterScannerBlips/ResourceTracker.cs new file mode 100644 index 0000000..dc25e57 --- /dev/null +++ b/SubnauticaModSystem/BetterScannerBlips/ResourceTracker.cs @@ -0,0 +1,101 @@ +using HarmonyLib; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using UWE; + +namespace BetterScannerBlips +{ + [HarmonyPatch(typeof(ResourceTracker))] + public class ResourceTrackerPatches + { + internal static Dictionary IdToGameObjectDict = new Dictionary(); + internal static Dictionary IdToTechTypeDict = new Dictionary(); + internal static readonly FieldInfo uniqueIdInfo = typeof(ResourceTracker).GetField("uniqueId", BindingFlags.Instance | BindingFlags.NonPublic); + internal static readonly FieldInfo TechTypeInfo = typeof(ResourceTracker).GetField("techType", BindingFlags.Instance | BindingFlags.NonPublic); + + [HarmonyPatch("Register")] + [HarmonyPrefix] + public static void PreRegister(ref ResourceTracker __instance) + { + TechType tt = (TechType)TechTypeInfo.GetValue(__instance); + if (tt == TechType.Fragment || __instance.overrideTechType == TechType.Fragment) + { + string uniqueId = __instance.prefabIdentifier.Id; + GameObject go = __instance.gameObject; + TechType resourceType = (go == null ? TechType.None : CraftData.GetTechType(go)); + QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"ResourceTrackerPatches.PreRegister() running on ResourceTracker with unique ID {uniqueId}, overrideTechType {__instance.overrideTechType} and techType {resourceType}"); + + if (!string.IsNullOrEmpty(uniqueId)) + { + IdToGameObjectDict[uniqueId] = __instance.gameObject; + IdToTechTypeDict[uniqueId] = resourceType; + } + + //__instance.overrideTechType = TechType.None; + } + } + + [HarmonyPatch("Register")] + [HarmonyPostfix] + public static void PostRegister(ref ResourceTracker __instance) + { + TechType tt = (TechType)TechTypeInfo.GetValue(__instance); + if (tt == TechType.Fragment || __instance.overrideTechType == TechType.Fragment) // We only need to concern ourselves with fragments + { + string uniqueId = __instance.prefabIdentifier.Id; + GameObject go = __instance.gameObject; + TechType resourceType = (go == null ? TechType.None : CraftData.GetTechType(go)); + QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"ResourceTrackerPatches.PostRegister() running on ResourceTracker with unique ID {uniqueId}, overrideTechType {__instance.overrideTechType} and techType {resourceType}"); + + //TechType actualTechType = CraftData.GetTechType(__instance.gameObject); + if (!string.IsNullOrEmpty(uniqueId)) + { + if (__instance.gameObject != null) + { + IdToGameObjectDict[uniqueId] = __instance.gameObject; + } + IdToTechTypeDict[uniqueId] = resourceType; + } + } + + //if((TechType)TechTypeInfo.GetValue(__instance) == TechType.Fragment) + //CoroutineHost.StartCoroutine(RegisterResourceTrackerCoroutine(__instance)); + } + + [HarmonyPatch("Unregister")] + [HarmonyPostfix] + public static void PostUnregister(ref ResourceTracker __instance) + { + string uniqueId = (string)uniqueIdInfo.GetValue(__instance); + if (!string.IsNullOrEmpty(uniqueId)) + { + IdToGameObjectDict.Remove(uniqueId); + IdToTechTypeDict.Remove(uniqueId); + } + } + + public static TechType GetTechTypeForId(string uniqueId) + { + if (!string.IsNullOrEmpty(uniqueId)) + { + if (IdToTechTypeDict.TryGetValue(uniqueId, out TechType tt)) + { + return tt; + } + else if (IdToGameObjectDict.TryGetValue(uniqueId, out GameObject go)) + { + if(go != null) + return CraftData.GetTechType(go); + } + } + + return TechType.None; + } + } +} diff --git a/SubnauticaModSystem/BlueprintTracker/BlueprintTracker.csproj b/SubnauticaModSystem/BlueprintTracker/BlueprintTracker.csproj index 7599d45..17f5b12 100644 --- a/SubnauticaModSystem/BlueprintTracker/BlueprintTracker.csproj +++ b/SubnauticaModSystem/BlueprintTracker/BlueprintTracker.csproj @@ -11,7 +11,7 @@ BlueprintTracker BlueprintTracker $(SolutionDir)$(AssemblyName)\$(Configuration)\ - v4.7.1 + v4.7.2 512 @@ -150,4 +150,4 @@ xcopy $(TargetPath) D:\EpicGames\Subnautica\QMods\BlueprintTracker\ /q /y xcopy $(ProjectDir)mod.json D:\EpicGames\Subnautica\QMods\BlueprintTracker\ /q /y xcopy $(ProjectDir)Assets D:\EpicGames\Subnautica\QMods\BlueprintTracker\Assets\ /q /y - \ No newline at end of file + diff --git a/SubnauticaModSystem/BlueprintTracker/Mod.cs b/SubnauticaModSystem/BlueprintTracker/Mod.cs index e8b8761..ac6d8f6 100644 --- a/SubnauticaModSystem/BlueprintTracker/Mod.cs +++ b/SubnauticaModSystem/BlueprintTracker/Mod.cs @@ -1,6 +1,6 @@ using Common.Mod; using Common.Utility; -using Harmony; +using HarmonyLib; using System; using System.IO; using System.Linq; diff --git a/SubnauticaModSystem/BlueprintTracker/Patches/uGUI_BlueprintEntry_SetIcon_Patch.cs b/SubnauticaModSystem/BlueprintTracker/Patches/uGUI_BlueprintEntry_SetIcon_Patch.cs index d3836d7..43ea6e1 100644 --- a/SubnauticaModSystem/BlueprintTracker/Patches/uGUI_BlueprintEntry_SetIcon_Patch.cs +++ b/SubnauticaModSystem/BlueprintTracker/Patches/uGUI_BlueprintEntry_SetIcon_Patch.cs @@ -1,4 +1,4 @@ -using Harmony; +using HarmonyLib; namespace BlueprintTracker.Patches { diff --git a/SubnauticaModSystem/BlueprintTracker/Patches/uGUI_PowerIndicator_Initialize_Patch.cs b/SubnauticaModSystem/BlueprintTracker/Patches/uGUI_PowerIndicator_Initialize_Patch.cs index ecc4833..225b071 100644 --- a/SubnauticaModSystem/BlueprintTracker/Patches/uGUI_PowerIndicator_Initialize_Patch.cs +++ b/SubnauticaModSystem/BlueprintTracker/Patches/uGUI_PowerIndicator_Initialize_Patch.cs @@ -1,4 +1,4 @@ -using Harmony; +using HarmonyLib; using System.Reflection; using UnityEngine; diff --git a/SubnauticaModSystem/Common/Mod/LockerPrefabShared.cs b/SubnauticaModSystem/Common/Mod/LockerPrefabShared.cs index 3d314d9..7368039 100644 --- a/SubnauticaModSystem/Common/Mod/LockerPrefabShared.cs +++ b/SubnauticaModSystem/Common/Mod/LockerPrefabShared.cs @@ -8,7 +8,7 @@ namespace Common.Mod { public static class LockerPrefabShared { - internal static Canvas CreateCanvas(Transform parent) + internal static Canvas CreateCanvas(Transform parent) { var canvas = new GameObject("Canvas", typeof(RectTransform)).AddComponent(); var t = canvas.transform; diff --git a/SubnauticaModSystem/Common/Mod/ModUtils.cs b/SubnauticaModSystem/Common/Mod/ModUtils.cs index 3c3a12c..54d8c3e 100644 --- a/SubnauticaModSystem/Common/Mod/ModUtils.cs +++ b/SubnauticaModSystem/Common/Mod/ModUtils.cs @@ -68,13 +68,16 @@ public static void ValidateConfigValue(string field, T min, T max, r var value = (T)fieldInfo.GetValue(config, null); if (value.CompareTo(min) < 0 || value.CompareTo(max) > 0) { - Console.WriteLine("Config value for '{0}' ({1}) was not valid. Must be between {2} and {3}", - field, - value, - min, - max - ); - fieldInfo.SetValue(config, fieldInfo.GetValue(defaultConfig, null), null); + string errorString = $"Config value for '{field}' ({value}) was not valid. Must be between {min} and {max}"; + //Console.WriteLine(string); + QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Error, errorString, null, true); + var newValue = value; + if (value.CompareTo(min) < 0) + newValue = min; + else if (value.CompareTo(max) > 0) + newValue = max; + //fieldInfo.SetValue(config, fieldInfo.GetValue(defaultConfig, null), null); + fieldInfo.SetValue(config, newValue, null); } } diff --git a/SubnauticaModSystem/CustomPings/CustomBeacons.csproj b/SubnauticaModSystem/CustomPings/CustomBeacons.csproj index d5e5c46..e1a6472 100644 --- a/SubnauticaModSystem/CustomPings/CustomBeacons.csproj +++ b/SubnauticaModSystem/CustomPings/CustomBeacons.csproj @@ -11,7 +11,7 @@ CustomBeacons CustomBeacons $(SolutionDir)$(AssemblyName)\$(Configuration)\ - v4.7.1 + v4.7.2 512 diff --git a/SubnauticaModSystem/CustomPings/Mod.cs b/SubnauticaModSystem/CustomPings/Mod.cs index 34f1cba..6e252b2 100644 --- a/SubnauticaModSystem/CustomPings/Mod.cs +++ b/SubnauticaModSystem/CustomPings/Mod.cs @@ -1,6 +1,6 @@ using Common.Mod; using Common.Utility; -using Harmony; +using HarmonyLib; using System; using System.Collections; using System.Collections.Generic; diff --git a/SubnauticaModSystem/CustomPings/Patches/PingTab_Patches.cs b/SubnauticaModSystem/CustomPings/Patches/PingTab_Patches.cs index c69f7a3..5c6931d 100644 --- a/SubnauticaModSystem/CustomPings/Patches/PingTab_Patches.cs +++ b/SubnauticaModSystem/CustomPings/Patches/PingTab_Patches.cs @@ -1,4 +1,4 @@ -using Harmony; +using HarmonyLib; using System; using System.Collections.Generic; using System.Linq; diff --git a/SubnauticaModSystem/CustomPings/Patches/Ping_Patches.cs b/SubnauticaModSystem/CustomPings/Patches/Ping_Patches.cs index e277fe2..2017687 100644 --- a/SubnauticaModSystem/CustomPings/Patches/Ping_Patches.cs +++ b/SubnauticaModSystem/CustomPings/Patches/Ping_Patches.cs @@ -1,6 +1,6 @@ using Common.Mod; using Common.Utility; -using Harmony; +using HarmonyLib; using System; using System.Collections.Generic; using System.IO; diff --git a/SubnauticaModSystem/CustomizedStorage/CustomizedStorage.csproj b/SubnauticaModSystem/CustomizedStorage/CustomizedStorage.csproj index 1e14b9e..e8911c3 100644 --- a/SubnauticaModSystem/CustomizedStorage/CustomizedStorage.csproj +++ b/SubnauticaModSystem/CustomizedStorage/CustomizedStorage.csproj @@ -11,7 +11,7 @@ CustomizedStorage CustomizedStorage $(SolutionDir)$(AssemblyName)\$(Configuration)\ - v4.7.1 + v4.7.2 512 diff --git a/SubnauticaModSystem/CustomizedStorage/Mod.cs b/SubnauticaModSystem/CustomizedStorage/Mod.cs index 0bdfe4f..959f588 100644 --- a/SubnauticaModSystem/CustomizedStorage/Mod.cs +++ b/SubnauticaModSystem/CustomizedStorage/Mod.cs @@ -1,5 +1,5 @@ using Common.Mod; -using Harmony; +using HarmonyLib; using Oculus.Newtonsoft.Json; using System; using System.IO; diff --git a/SubnauticaModSystem/CustomizedStorage/Patches/Patches.cs b/SubnauticaModSystem/CustomizedStorage/Patches/Patches.cs index 40b41d9..13fdcf9 100644 --- a/SubnauticaModSystem/CustomizedStorage/Patches/Patches.cs +++ b/SubnauticaModSystem/CustomizedStorage/Patches/Patches.cs @@ -1,5 +1,5 @@ using Common.Mod; -using Harmony; +using HarmonyLib; using System; using System.Collections; using System.Collections.Generic; diff --git a/SubnauticaModSystem/DockedVehicleStorageAccess/Config.cs b/SubnauticaModSystem/DockedVehicleStorageAccess/Config.cs index e13174c..c62fdce 100644 --- a/SubnauticaModSystem/DockedVehicleStorageAccess/Config.cs +++ b/SubnauticaModSystem/DockedVehicleStorageAccess/Config.cs @@ -1,9 +1,18 @@ -using Oculus.Newtonsoft.Json; +#if SUBNAUTICA +using Oculus.Newtonsoft.Json; +#elif BELOWZERO +using Newtonsoft.Json; +using SMLHelper.V2.Json; +#endif namespace DockedVehicleStorageAccess { +#if !BELOWZERO [JsonObject] internal class Config +#else + internal class Config : ConfigFile +#endif { public int LockerWidth { get; set; } = 6; public int LockerHeight { get; set; } = 8; @@ -11,7 +20,9 @@ internal class Config public float ExtractInterval { get; set; } = 0.25f; public float AutosortTransferInterval { get; set; } = 0.25f; +#if !BELOWZERO [JsonIgnore] +#endif internal bool UseAutosortMod { get; set; } } } diff --git a/SubnauticaModSystem/DockedVehicleStorageAccess/DockedVehicleStorageAccess.csproj b/SubnauticaModSystem/DockedVehicleStorageAccess/DockedVehicleStorageAccess.csproj index 5366738..ac57980 100644 --- a/SubnauticaModSystem/DockedVehicleStorageAccess/DockedVehicleStorageAccess.csproj +++ b/SubnauticaModSystem/DockedVehicleStorageAccess/DockedVehicleStorageAccess.csproj @@ -11,7 +11,7 @@ DockedVehicleStorageAccess DockedVehicleStorageAccessSML $(SolutionDir)$(AssemblyName)\$(Configuration)\ - v4.0 + v4.7.2 512 @@ -87,6 +87,10 @@ False + + $(GameDir)\$(DataFolder)\Managed\Unity.TextMeshPro.dll + False + $(GameDir)\$(DataFolder)\Managed\UnityEngine.dll False diff --git a/SubnauticaModSystem/DockedVehicleStorageAccess/Mod.cs b/SubnauticaModSystem/DockedVehicleStorageAccess/Mod.cs index 13ffebe..4e67397 100644 --- a/SubnauticaModSystem/DockedVehicleStorageAccess/Mod.cs +++ b/SubnauticaModSystem/DockedVehicleStorageAccess/Mod.cs @@ -1,14 +1,19 @@ using System; using System.Reflection; using Common.Mod; -using Harmony; +using HarmonyLib; using QModManager.API; +using SMLHelper.V2.Handlers; namespace DockedVehicleStorageAccess { internal static class Mod { +#if !BELOWZERO public static Config config; +#else + public static Config config { get; } = OptionsPanelHandler.RegisterModOptions(); +#endif private static string modDirectory; @@ -21,7 +26,7 @@ public static void Patch(string modDirectory = null) AddBuildables(); - HarmonyInstance harmony = HarmonyInstance.Create("com.DockedVehicleStorageAccessSML.mod"); + var harmony = new Harmony("com.DockedVehicleStorageAccessSML.mod"); harmony.PatchAll(Assembly.GetExecutingAssembly()); Logger.Log("Patched"); @@ -44,7 +49,9 @@ public static string GetAssetPath(string filename) private static void LoadConfig() { +#if !BELOWZERO config = ModUtils.LoadConfig(GetModPath() + "/config.json"); +#endif config.UseAutosortMod = QModServices.Main.ModPresent("AutosortLockersSML"); if (config.UseAutosortMod) diff --git a/SubnauticaModSystem/DockedVehicleStorageAccess/MoonpoolTerminalController.cs b/SubnauticaModSystem/DockedVehicleStorageAccess/MoonpoolTerminalController.cs index 3f16274..745984b 100644 --- a/SubnauticaModSystem/DockedVehicleStorageAccess/MoonpoolTerminalController.cs +++ b/SubnauticaModSystem/DockedVehicleStorageAccess/MoonpoolTerminalController.cs @@ -1,5 +1,9 @@ using Common.Mod; +#if SUBNAUTICA using Oculus.Newtonsoft.Json; +#elif BELOWZERO +using Newtonsoft.Json; +#endif using System; using System.Collections.Generic; using System.IO; diff --git a/SubnauticaModSystem/DockedVehicleStorageAccess/Patches/DockingBay_Patches.cs b/SubnauticaModSystem/DockedVehicleStorageAccess/Patches/DockingBay_Patches.cs index 83e57e7..d2b9b76 100644 --- a/SubnauticaModSystem/DockedVehicleStorageAccess/Patches/DockingBay_Patches.cs +++ b/SubnauticaModSystem/DockedVehicleStorageAccess/Patches/DockingBay_Patches.cs @@ -1,5 +1,5 @@ using Common.Mod; -using Harmony; +using HarmonyLib; using System; using System.Collections; using System.Collections.Generic; diff --git a/SubnauticaModSystem/HabitatControlPanel/HabitatControlPanel.csproj b/SubnauticaModSystem/HabitatControlPanel/HabitatControlPanel.csproj index 2b103af..f04df1c 100644 --- a/SubnauticaModSystem/HabitatControlPanel/HabitatControlPanel.csproj +++ b/SubnauticaModSystem/HabitatControlPanel/HabitatControlPanel.csproj @@ -11,7 +11,7 @@ HabitatControlPanel HabitatControlPanelSML $(SolutionDir)$(AssemblyName)\$(Configuration)\ - v4.7.1 + v4.7.2 512 diff --git a/SubnauticaModSystem/HabitatControlPanel/Mod.cs b/SubnauticaModSystem/HabitatControlPanel/Mod.cs index 43580d9..c75d7b7 100644 --- a/SubnauticaModSystem/HabitatControlPanel/Mod.cs +++ b/SubnauticaModSystem/HabitatControlPanel/Mod.cs @@ -1,5 +1,5 @@ using Common.Mod; -using Harmony; +using HarmonyLib; using System; using System.Reflection; diff --git a/SubnauticaModSystem/HabitatControlPanel/Patches/Ping_Patches.cs b/SubnauticaModSystem/HabitatControlPanel/Patches/Ping_Patches.cs index eb7d9ef..95a9437 100644 --- a/SubnauticaModSystem/HabitatControlPanel/Patches/Ping_Patches.cs +++ b/SubnauticaModSystem/HabitatControlPanel/Patches/Ping_Patches.cs @@ -1,4 +1,4 @@ -using Harmony; +using HarmonyLib; using System; using System.Collections.Generic; using System.Reflection; diff --git a/SubnauticaModSystem/HudConfig/HudConfig.csproj b/SubnauticaModSystem/HudConfig/HudConfig.csproj index 8a0f8c0..e8d0baa 100644 --- a/SubnauticaModSystem/HudConfig/HudConfig.csproj +++ b/SubnauticaModSystem/HudConfig/HudConfig.csproj @@ -11,7 +11,7 @@ HudConfig HudConfig $(SolutionDir)$(AssemblyName)\$(Configuration)\ - v4.7.1 + v4.7.2 512 diff --git a/SubnauticaModSystem/HudConfig/Mod.cs b/SubnauticaModSystem/HudConfig/Mod.cs index f5868b9..1b36203 100644 --- a/SubnauticaModSystem/HudConfig/Mod.cs +++ b/SubnauticaModSystem/HudConfig/Mod.cs @@ -1,5 +1,5 @@ using Common.Mod; -using Harmony; +using HarmonyLib; using Oculus.Newtonsoft.Json; using System; using System.IO; diff --git a/SubnauticaModSystem/HudConfig/Patches/HUD_Patches.cs b/SubnauticaModSystem/HudConfig/Patches/HUD_Patches.cs index a874602..9654e3b 100644 --- a/SubnauticaModSystem/HudConfig/Patches/HUD_Patches.cs +++ b/SubnauticaModSystem/HudConfig/Patches/HUD_Patches.cs @@ -1,4 +1,4 @@ -using Harmony; +using HarmonyLib; using System; using System.Collections.Generic; using System.Linq; diff --git a/SubnauticaModSystem/LongLockerNames/LongLockerNames.csproj b/SubnauticaModSystem/LongLockerNames/LongLockerNames.csproj index 8dc332f..2607a7c 100644 --- a/SubnauticaModSystem/LongLockerNames/LongLockerNames.csproj +++ b/SubnauticaModSystem/LongLockerNames/LongLockerNames.csproj @@ -11,7 +11,7 @@ LongLockerNames LongLockerNames $(SolutionDir)$(AssemblyName)\$(Configuration)\ - v4.7.1 + v4.7.2 512 diff --git a/SubnauticaModSystem/LongLockerNames/Mod.cs b/SubnauticaModSystem/LongLockerNames/Mod.cs index 12dd3e5..d901dae 100644 --- a/SubnauticaModSystem/LongLockerNames/Mod.cs +++ b/SubnauticaModSystem/LongLockerNames/Mod.cs @@ -1,5 +1,5 @@ using Common.Utility; -using Harmony; +using HarmonyLib; using System; using System.IO; using System.Linq; diff --git a/SubnauticaModSystem/LongLockerNames/Patches/uGUI_SignInput_Awake_Patch.cs b/SubnauticaModSystem/LongLockerNames/Patches/uGUI_SignInput_Awake_Patch.cs index 146d24b..1970a49 100644 --- a/SubnauticaModSystem/LongLockerNames/Patches/uGUI_SignInput_Awake_Patch.cs +++ b/SubnauticaModSystem/LongLockerNames/Patches/uGUI_SignInput_Awake_Patch.cs @@ -1,4 +1,4 @@ -using Harmony; +using HarmonyLib; using System.Linq; using UnityEngine; using UnityEngine.UI; diff --git a/SubnauticaModSystem/ModInjector_MoreQuickSlots/ModInjector_MoreQuickSlots.csproj b/SubnauticaModSystem/ModInjector_MoreQuickSlots/ModInjector_MoreQuickSlots.csproj index 2b536d2..db635f0 100644 --- a/SubnauticaModSystem/ModInjector_MoreQuickSlots/ModInjector_MoreQuickSlots.csproj +++ b/SubnauticaModSystem/ModInjector_MoreQuickSlots/ModInjector_MoreQuickSlots.csproj @@ -10,7 +10,7 @@ ModInjector_MoreQuickSlots ModInjector_MoreQuickSlots $(SolutionDir)$(AssemblyName)\$(Configuration)\ - v4.6.1 + v4.7.2 512 true diff --git a/SubnauticaModSystem/MoreQuickSlots/Mod.cs b/SubnauticaModSystem/MoreQuickSlots/Mod.cs index 9b669af..1a57abb 100644 --- a/SubnauticaModSystem/MoreQuickSlots/Mod.cs +++ b/SubnauticaModSystem/MoreQuickSlots/Mod.cs @@ -1,5 +1,5 @@ using Common.Utility; -using Harmony; +using HarmonyLib; using System; using System.IO; using System.Reflection; diff --git a/SubnauticaModSystem/MoreQuickSlots/MoreQuickSlots.csproj b/SubnauticaModSystem/MoreQuickSlots/MoreQuickSlots.csproj index 57a9050..d8165e0 100644 --- a/SubnauticaModSystem/MoreQuickSlots/MoreQuickSlots.csproj +++ b/SubnauticaModSystem/MoreQuickSlots/MoreQuickSlots.csproj @@ -11,7 +11,7 @@ MoreQuickSlots MoreQuickSlots $(SolutionDir)$(AssemblyName)\$(Configuration)\ - v4.7.1 + v4.7.2 512 diff --git a/SubnauticaModSystem/MoreQuickSlots/Patches/QuickSlots_Ctor_Patch.cs b/SubnauticaModSystem/MoreQuickSlots/Patches/QuickSlots_Ctor_Patch.cs index 218df48..b26e32d 100644 --- a/SubnauticaModSystem/MoreQuickSlots/Patches/QuickSlots_Ctor_Patch.cs +++ b/SubnauticaModSystem/MoreQuickSlots/Patches/QuickSlots_Ctor_Patch.cs @@ -1,4 +1,4 @@ -using Harmony; +using HarmonyLib; using System; using System.Reflection; using UnityEngine; diff --git a/SubnauticaModSystem/MoreQuickSlots/Patches/uGUI_QuickSlots_Init_Patch.cs b/SubnauticaModSystem/MoreQuickSlots/Patches/uGUI_QuickSlots_Init_Patch.cs index d71a552..a99e45a 100644 --- a/SubnauticaModSystem/MoreQuickSlots/Patches/uGUI_QuickSlots_Init_Patch.cs +++ b/SubnauticaModSystem/MoreQuickSlots/Patches/uGUI_QuickSlots_Init_Patch.cs @@ -1,4 +1,4 @@ -using Harmony; +using HarmonyLib; namespace MoreQuickSlots.Patches { diff --git a/SubnauticaModSystem/PrawnsuitLightswitch/Mod.cs b/SubnauticaModSystem/PrawnsuitLightswitch/Mod.cs index f4d62f3..47130dc 100644 --- a/SubnauticaModSystem/PrawnsuitLightswitch/Mod.cs +++ b/SubnauticaModSystem/PrawnsuitLightswitch/Mod.cs @@ -1,5 +1,5 @@ using Common.Mod; -using Harmony; +using HarmonyLib; using System; using System.Reflection; diff --git a/SubnauticaModSystem/PrawnsuitLightswitch/Patches/Exosuit_Patches.cs b/SubnauticaModSystem/PrawnsuitLightswitch/Patches/Exosuit_Patches.cs index 3373d54..03ef4e0 100644 --- a/SubnauticaModSystem/PrawnsuitLightswitch/Patches/Exosuit_Patches.cs +++ b/SubnauticaModSystem/PrawnsuitLightswitch/Patches/Exosuit_Patches.cs @@ -1,5 +1,5 @@ using Common.Mod; -using Harmony; +using HarmonyLib; using System; using System.Collections; using System.Collections.Generic; diff --git a/SubnauticaModSystem/PrawnsuitLightswitch/PrawnsuitLightswitch.csproj b/SubnauticaModSystem/PrawnsuitLightswitch/PrawnsuitLightswitch.csproj index 27d5adb..1964e13 100644 --- a/SubnauticaModSystem/PrawnsuitLightswitch/PrawnsuitLightswitch.csproj +++ b/SubnauticaModSystem/PrawnsuitLightswitch/PrawnsuitLightswitch.csproj @@ -11,7 +11,7 @@ PrawnsuitLightswitch PrawnsuitLightswitch $(SolutionDir)$(AssemblyName)\$(Configuration)\ - v4.7.1 + v4.7.2 512 diff --git a/SubnauticaModSystem/SeaglideMapMod/Mod.cs b/SubnauticaModSystem/SeaglideMapMod/Mod.cs index b9ac501..f4111d6 100644 --- a/SubnauticaModSystem/SeaglideMapMod/Mod.cs +++ b/SubnauticaModSystem/SeaglideMapMod/Mod.cs @@ -1,5 +1,5 @@ using Common.Mod; -using Harmony; +using HarmonyLib; using System; using System.Reflection; diff --git a/SubnauticaModSystem/SeaglideMapMod/Patches/ScannerTool_Patches.cs b/SubnauticaModSystem/SeaglideMapMod/Patches/ScannerTool_Patches.cs index 1a64849..8c2c322 100644 --- a/SubnauticaModSystem/SeaglideMapMod/Patches/ScannerTool_Patches.cs +++ b/SubnauticaModSystem/SeaglideMapMod/Patches/ScannerTool_Patches.cs @@ -1,4 +1,4 @@ -using Harmony; +using HarmonyLib; using System; using System.Collections.Generic; using System.Linq; diff --git a/SubnauticaModSystem/SeaglideMapMod/Patches/Seaglide_Patches.cs b/SubnauticaModSystem/SeaglideMapMod/Patches/Seaglide_Patches.cs index 2f0f4f9..601efdf 100644 --- a/SubnauticaModSystem/SeaglideMapMod/Patches/Seaglide_Patches.cs +++ b/SubnauticaModSystem/SeaglideMapMod/Patches/Seaglide_Patches.cs @@ -1,5 +1,5 @@ using Common.Mod; -using Harmony; +using HarmonyLib; using System; using System.Collections; using System.Collections.Generic; diff --git a/SubnauticaModSystem/SeaglideMapMod/SeaglideMapControls.csproj b/SubnauticaModSystem/SeaglideMapMod/SeaglideMapControls.csproj index 567d29e..a2a5d6d 100644 --- a/SubnauticaModSystem/SeaglideMapMod/SeaglideMapControls.csproj +++ b/SubnauticaModSystem/SeaglideMapMod/SeaglideMapControls.csproj @@ -11,7 +11,7 @@ SeaglideMapControls SeaglideMapControls $(SolutionDir)$(AssemblyName)\$(Configuration)\ - v4.7.1 + v4.7.2 512 diff --git a/SubnauticaModSystem/TorpedoImprovements/Mod.cs b/SubnauticaModSystem/TorpedoImprovements/Mod.cs index b1575f2..9785392 100644 --- a/SubnauticaModSystem/TorpedoImprovements/Mod.cs +++ b/SubnauticaModSystem/TorpedoImprovements/Mod.cs @@ -1,5 +1,5 @@ using Common.Mod; -using Harmony; +using HarmonyLib; using Oculus.Newtonsoft.Json; using System; using System.IO; diff --git a/SubnauticaModSystem/TorpedoImprovements/Patches/Exosuit_Patches.cs b/SubnauticaModSystem/TorpedoImprovements/Patches/Exosuit_Patches.cs index 53ce9e1..f0953e2 100644 --- a/SubnauticaModSystem/TorpedoImprovements/Patches/Exosuit_Patches.cs +++ b/SubnauticaModSystem/TorpedoImprovements/Patches/Exosuit_Patches.cs @@ -1,4 +1,4 @@ -using Harmony; +using HarmonyLib; using System; using System.Collections.Generic; using System.Linq; diff --git a/SubnauticaModSystem/TorpedoImprovements/Patches/Seamoth_Patches.cs b/SubnauticaModSystem/TorpedoImprovements/Patches/Seamoth_Patches.cs index 35a2287..c610009 100644 --- a/SubnauticaModSystem/TorpedoImprovements/Patches/Seamoth_Patches.cs +++ b/SubnauticaModSystem/TorpedoImprovements/Patches/Seamoth_Patches.cs @@ -1,5 +1,5 @@ using Common.Mod; -using Harmony; +using HarmonyLib; using System; using System.Collections.Generic; using System.Linq; diff --git a/SubnauticaModSystem/TorpedoImprovements/TorpedoImprovements.csproj b/SubnauticaModSystem/TorpedoImprovements/TorpedoImprovements.csproj index 0ce7654..1067f26 100644 --- a/SubnauticaModSystem/TorpedoImprovements/TorpedoImprovements.csproj +++ b/SubnauticaModSystem/TorpedoImprovements/TorpedoImprovements.csproj @@ -11,7 +11,7 @@ TorpedoImprovements TorpedoImprovements $(SolutionDir)$(AssemblyName)\$(Configuration)\ - v4.7.1 + v4.7.2 512 diff --git a/SubnauticaModSystem/WhiteLights/Mod.cs b/SubnauticaModSystem/WhiteLights/Mod.cs index b489ea7..9b9ea8b 100644 --- a/SubnauticaModSystem/WhiteLights/Mod.cs +++ b/SubnauticaModSystem/WhiteLights/Mod.cs @@ -1,5 +1,5 @@ using Common.Mod; -using Harmony; +using HarmonyLib; using Oculus.Newtonsoft.Json; using System; using System.IO; diff --git a/SubnauticaModSystem/WhiteLights/Patches/Exosuit_Patches.cs b/SubnauticaModSystem/WhiteLights/Patches/Exosuit_Patches.cs index 8f13adb..38ae034 100644 --- a/SubnauticaModSystem/WhiteLights/Patches/Exosuit_Patches.cs +++ b/SubnauticaModSystem/WhiteLights/Patches/Exosuit_Patches.cs @@ -1,4 +1,4 @@ -using Harmony; +using HarmonyLib; using System; using System.Collections.Generic; using System.Linq; diff --git a/SubnauticaModSystem/WhiteLights/Patches/Seaglide_Patches.cs b/SubnauticaModSystem/WhiteLights/Patches/Seaglide_Patches.cs index 46d529d..044e4d8 100644 --- a/SubnauticaModSystem/WhiteLights/Patches/Seaglide_Patches.cs +++ b/SubnauticaModSystem/WhiteLights/Patches/Seaglide_Patches.cs @@ -1,4 +1,4 @@ -using Harmony; +using HarmonyLib; using UnityEngine; namespace WhiteLights.Patches diff --git a/SubnauticaModSystem/WhiteLights/Patches/Seamoth_Patches.cs b/SubnauticaModSystem/WhiteLights/Patches/Seamoth_Patches.cs index a8623c3..80a8758 100644 --- a/SubnauticaModSystem/WhiteLights/Patches/Seamoth_Patches.cs +++ b/SubnauticaModSystem/WhiteLights/Patches/Seamoth_Patches.cs @@ -1,4 +1,4 @@ -using Harmony; +using HarmonyLib; using UnityEngine; namespace WhiteLights.Patches diff --git a/SubnauticaModSystem/WhiteLights/WhiteLights.csproj b/SubnauticaModSystem/WhiteLights/WhiteLights.csproj index 98f3ec7..0a31afa 100644 --- a/SubnauticaModSystem/WhiteLights/WhiteLights.csproj +++ b/SubnauticaModSystem/WhiteLights/WhiteLights.csproj @@ -11,7 +11,7 @@ WhiteLights WhiteLights $(SolutionDir)$(AssemblyName)\$(Configuration)\ - v4.7.1 + v4.7.2 512 diff --git a/SubnauticaModSystem/zzzEnableConsole/zzzEnableConsole.csproj b/SubnauticaModSystem/zzzEnableConsole/zzzEnableConsole.csproj index 0038d87..f326d34 100644 --- a/SubnauticaModSystem/zzzEnableConsole/zzzEnableConsole.csproj +++ b/SubnauticaModSystem/zzzEnableConsole/zzzEnableConsole.csproj @@ -11,7 +11,7 @@ zzzEnableConsole zzzEnableConsole $(SolutionDir)$(AssemblyName)\$(Configuration)\ - v4.7.1 + v4.7.2 512 From 9105c21494b40de0b03381b2761645837f97e883 Mon Sep 17 00:00:00 2001 From: DaWrecka <61927940+DaWrecka@users.noreply.github.com> Date: Mon, 17 May 2021 17:57:18 +0100 Subject: [PATCH 09/11] BZ updates for Autosort Lockers, BetterScannerBlips, and DockedVehicleStorageAccess --- .../AutosortLockers/AutosortTarget.cs | 2 +- .../BetterScannerBlips/BlipIdentifier.cs | 4 +- .../BetterScannerBlips/CustomBlip.cs | 69 +++++--- .../uGUI_ResourceTracker_UpdateBlips_Patch.cs | 18 +- .../BetterScannerBlips/ResourceTracker.cs | 20 ++- .../Common/Mod/LockerPrefabShared.cs | 8 +- SubnauticaModSystem/Common/Mod/ModUtils.cs | 25 ++- .../CheckboxButton.cs | 19 ++- .../DockedVehicleStorageAccess.csproj | 16 +- .../DockedVehicleStorageAccess/Mod.cs | 3 +- .../MoonpoolTerminalController.cs | 27 ++- .../Patches/DockingBay_Patches.cs | 20 ++- .../VehicleStorageAccess.cs | 161 ++++++++++++++++-- .../DockedVehicleStorageAccess/mod_BZ.json | 10 ++ .../{mod.json => mod_SN1.json} | 0 .../BZ/mod_BZ.json | 10 ++ .../BZ/mod_SN1.json | 9 + SubnauticaModSystem/GameDir.targets | 2 + 18 files changed, 331 insertions(+), 92 deletions(-) create mode 100644 SubnauticaModSystem/DockedVehicleStorageAccess/mod_BZ.json rename SubnauticaModSystem/DockedVehicleStorageAccess/{mod.json => mod_SN1.json} (100%) create mode 100644 SubnauticaModSystem/DockedVehicleStorageAccessSML/BZ/mod_BZ.json create mode 100644 SubnauticaModSystem/DockedVehicleStorageAccessSML/BZ/mod_SN1.json diff --git a/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs b/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs index 27c8dfb..110810f 100644 --- a/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs +++ b/SubnauticaModSystem/AutosortLockers/AutosortTarget.cs @@ -699,7 +699,7 @@ public static void AddBuildable() public static IEnumerator GetPrefabAsync(TechType basePrefab, IOut gameObject) { - Logger.Log($"GetPrefabAsync() executing for basePrefab TechType.{basePrefab.AsString()}"); + //Logger.Log($"GetPrefabAsync() executing for basePrefab TechType.{basePrefab.AsString()}"); CoroutineTask task = CraftData.GetPrefabForTechTypeAsync(basePrefab); yield return task; diff --git a/SubnauticaModSystem/BetterScannerBlips/BlipIdentifier.cs b/SubnauticaModSystem/BetterScannerBlips/BlipIdentifier.cs index 68d5ca6..da24146 100644 --- a/SubnauticaModSystem/BetterScannerBlips/BlipIdentifier.cs +++ b/SubnauticaModSystem/BetterScannerBlips/BlipIdentifier.cs @@ -7,7 +7,7 @@ namespace BetterScannerBlips { - internal class BlipIdentifier : MonoBehaviour + /*internal class BlipIdentifier : MonoBehaviour { // A component added to a GUI scanner blip that stores information about the actual TechType of a fragment, allowing the code to identify exactly what type of Fragment the object is @@ -17,5 +17,5 @@ internal TechType actualTechType { get return ResourceTrackerPatches.GetTechTypeForId(this.uniqueId); } } - } + }*/ } diff --git a/SubnauticaModSystem/BetterScannerBlips/CustomBlip.cs b/SubnauticaModSystem/BetterScannerBlips/CustomBlip.cs index d7563e3..102228e 100644 --- a/SubnauticaModSystem/BetterScannerBlips/CustomBlip.cs +++ b/SubnauticaModSystem/BetterScannerBlips/CustomBlip.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; using System.Linq; using System.Text; +#if BELOWZERO using TMPro; +#endif using UnityEngine; using UnityEngine.UI; @@ -15,15 +17,19 @@ public class CustomBlip : MonoBehaviour private static Color textColor; private Image image; -#if SUBNAUTICA +#if SN1 private Text text; #elif BELOWZERO private TextMeshProUGUI text; #endif private TechType techType; private string resourceName; - - private BlipIdentifier blipId; + private string lastID = ""; // Last unique identifier we were attached to. As long as the current ID matches this, we shouldn't need to retrieve the string. + // Randy's original code didn't take this into account; and in fairness, he may not have needed to take it into account at all. + // This code was originally based on Subnautica 1, and this behaviour may not have happened there. + // However, in BZ, a given blip might be moved around - for example, a blip may initially be highlighting a Seaglide fragment, but later on - be it frames, seconds, whatever - + // it might instead be highlighting a Seatruck fragment. Wouldn't be a problem under normal circumstances, but since we want proper text for these blips... + // Not only that, but since every blip from a given map room would've been showing the exact same text anyway, blips moving around didn't matter, until we wanted blips with different text. public void ResetCustomBlip() { @@ -49,56 +55,67 @@ public static void InitializeColors() private void Awake() { image = gameObject.GetComponent(); -#if SUBNAUTICA +#if SN1 text = gameObject.GetComponentInChildren(); #elif BELOWZERO text = gameObject.GetComponentInChildren(); #endif } +#if SN1 + public void Refresh(ResourceTracker.ResourceInfo target) +#elif BELOWZERO public void Refresh(ResourceTrackerDatabase.ResourceInfo target) +#endif { if (target != null) { var vectorToPlayer = Player.main.transform.position - target.position; var distance = vectorToPlayer.magnitude; - if (techType == TechType.None) + if(this.techType == TechType.None) + this.techType = target.techType; + if (this.techType == TechType.Fragment || string.IsNullOrEmpty(resourceName)) { - TechType thisTechType = target.techType; - QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, - $"CustomBlip.Refresh(): Attempting to establish resourceName for ResourceInfo with unique ID {target.uniqueId}, which includes TechType {thisTechType}"); - if (thisTechType == TechType.Fragment) + /*blipId = gameObject.EnsureComponent(); + blipId.uniqueId = target.uniqueId;*/ + if (this.techType == TechType.Fragment) { - blipId = gameObject.GetComponent(); - if (blipId == null) + /*thisTechType = blipId.actualTechType; + if (thisTechType == TechType.None || thisTechType == TechType.Fragment) { - blipId = gameObject.AddComponent(); - blipId.uniqueId = target.uniqueId; - } - if (blipId != null) + QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, + $"CustomBlip.Refresh(): Could not get TechType from BlipIdentifier, attempting to use ResourceTrackerPatches.GetTechTypeForId"); + thisTechType = ResourceTrackerPatches.GetTechTypeForId(target.uniqueId); + QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, + $"CustomBlip.Refresh(): Got TechType of {techType.AsString()}"); + }*/ + if (lastID != target.uniqueId) { - thisTechType = blipId.actualTechType; - if (thisTechType == TechType.None) + /*QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, + $"CustomBlip.Refresh(): Last unique ID {lastID} does not match current unique ID {target.uniqueId}; Attempting to establish resourceName for ResourceInfo, which includes TechType {thisTechType}"); + */ + if (!ResourceTrackerPatches.TryGetResourceName(target.uniqueId, out resourceName)) { - QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, - $"CustomBlip.Refresh(): Could not get TechType from BlipIdentifier, attempting to use ResourceTrackerPatches.GetTechTypeForId"); - thisTechType = ResourceTrackerPatches.GetTechTypeForId(target.uniqueId); - QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, - $"CustomBlip.Refresh(): Got TechType of {techType.AsString()}"); + resourceName = Language.main.Get(this.techType); + lastID = target.uniqueId; + /*QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, + $"For unique ID {target.uniqueId}, got TechType {thisTechType.AsString()} and resourceName '{resourceName}'");*/ } } } - if (thisTechType != TechType.None && thisTechType != TechType.Fragment) + /*if (thisTechType != TechType.None && thisTechType != TechType.Fragment) { + techType = thisTechType; - resourceName = Language.main.Get(techType); + resourceName = Language.main.Get(thisTechType); + lastID = target.uniqueId; QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"For unique ID {target.uniqueId}, got TechType {thisTechType.AsString()} and resourceName '{resourceName}'"); - } + }*/ else - resourceName = "(*)" + Language.main.Get(target.techType); + resourceName = Language.main.Get(target.techType); } RefreshColor(distance); diff --git a/SubnauticaModSystem/BetterScannerBlips/Patches/uGUI_ResourceTracker_UpdateBlips_Patch.cs b/SubnauticaModSystem/BetterScannerBlips/Patches/uGUI_ResourceTracker_UpdateBlips_Patch.cs index 11027df..10ad2e1 100644 --- a/SubnauticaModSystem/BetterScannerBlips/Patches/uGUI_ResourceTracker_UpdateBlips_Patch.cs +++ b/SubnauticaModSystem/BetterScannerBlips/Patches/uGUI_ResourceTracker_UpdateBlips_Patch.cs @@ -1,6 +1,6 @@ using Common.Mod; using HarmonyLib; -#if SUBNAUTICA +#if SN1 using Oculus.Newtonsoft.Json; #elif BELOWZERO using Newtonsoft.Json; @@ -25,17 +25,6 @@ internal class uGUI_ResourceTracker_UpdateBlips_Patch private static bool hide = false; - private static void CustomiseBlip(GameObject blipObject, ResourceTrackerDatabase.ResourceInfo node) - { - if(node.techType == TechType.Fragment && blipObject.GetComponent() == null) - { - QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"CustomiseBlip: Customising blip for ResourceInfo node (position=({node.position.ToString()}), techType={node.techType.AsString()}, uniqueId={node.uniqueId}"); - BlipIdentifier blipId = blipObject.EnsureComponent(); - blipId.uniqueId = node.uniqueId; - QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"CustomiseBlip: got actual techType of {blipId.actualTechType}"); - } - } - [HarmonyPrefix] [HarmonyPatch("UpdateBlips")] private static bool Prefix(uGUI_ResourceTracker __instance) @@ -68,7 +57,7 @@ private static void Postfix(uGUI_ResourceTracker __instance) ErrorMessage.AddDebug(string.Format("Scanner Blips Toggled: {0}", hide ? $"OFF (Press {Mod.config.ToggleKey} to show)" : "ON")); } -#if SUBNAUTICA +#if SN1 HashSet nodes = (HashSet)uGUI_ResourceTracker_nodes.GetValue(__instance); #elif BELOWZERO HashSet nodes = (HashSet)uGUI_ResourceTracker_nodes.GetValue(__instance); @@ -79,7 +68,7 @@ private static void Postfix(uGUI_ResourceTracker __instance) Vector3 position = camera.transform.position; Vector3 forward = camera.transform.forward; int i = 0; -#if SUBNAUTICA +#if SN1 foreach (ResourceTracker.ResourceInfo resourceInfo in nodes) #elif BELOWZERO foreach (ResourceTrackerDatabase.ResourceInfo resourceInfo in nodes) @@ -90,7 +79,6 @@ private static void Postfix(uGUI_ResourceTracker __instance) { var blipObject = (GameObject)Blip_gameObject.GetValue(blips[i]); var customBlip = blipObject.GetComponent(); - CustomiseBlip(blipObject, resourceInfo); customBlip.Refresh(resourceInfo); diff --git a/SubnauticaModSystem/BetterScannerBlips/ResourceTracker.cs b/SubnauticaModSystem/BetterScannerBlips/ResourceTracker.cs index dc25e57..327c80a 100644 --- a/SubnauticaModSystem/BetterScannerBlips/ResourceTracker.cs +++ b/SubnauticaModSystem/BetterScannerBlips/ResourceTracker.cs @@ -16,6 +16,7 @@ public class ResourceTrackerPatches { internal static Dictionary IdToGameObjectDict = new Dictionary(); internal static Dictionary IdToTechTypeDict = new Dictionary(); + internal static Dictionary IdToResourceNameDict = new Dictionary(); internal static readonly FieldInfo uniqueIdInfo = typeof(ResourceTracker).GetField("uniqueId", BindingFlags.Instance | BindingFlags.NonPublic); internal static readonly FieldInfo TechTypeInfo = typeof(ResourceTracker).GetField("techType", BindingFlags.Instance | BindingFlags.NonPublic); @@ -24,17 +25,18 @@ public class ResourceTrackerPatches public static void PreRegister(ref ResourceTracker __instance) { TechType tt = (TechType)TechTypeInfo.GetValue(__instance); - if (tt == TechType.Fragment || __instance.overrideTechType == TechType.Fragment) + if (tt == TechType.Fragment || __instance.overrideTechType == TechType.Fragment) // We only need to concern ourselves with fragments { string uniqueId = __instance.prefabIdentifier.Id; GameObject go = __instance.gameObject; TechType resourceType = (go == null ? TechType.None : CraftData.GetTechType(go)); - QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"ResourceTrackerPatches.PreRegister() running on ResourceTracker with unique ID {uniqueId}, overrideTechType {__instance.overrideTechType} and techType {resourceType}"); + //QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"ResourceTrackerPatches.PreRegister() running on ResourceTracker with unique ID {uniqueId}, overrideTechType {__instance.overrideTechType} and techType {resourceType}"); if (!string.IsNullOrEmpty(uniqueId)) { IdToGameObjectDict[uniqueId] = __instance.gameObject; IdToTechTypeDict[uniqueId] = resourceType; + IdToResourceNameDict[uniqueId] = Language.main.Get(resourceType); } //__instance.overrideTechType = TechType.None; @@ -46,12 +48,12 @@ public static void PreRegister(ref ResourceTracker __instance) public static void PostRegister(ref ResourceTracker __instance) { TechType tt = (TechType)TechTypeInfo.GetValue(__instance); - if (tt == TechType.Fragment || __instance.overrideTechType == TechType.Fragment) // We only need to concern ourselves with fragments + if (tt == TechType.Fragment || __instance.overrideTechType == TechType.Fragment) { string uniqueId = __instance.prefabIdentifier.Id; GameObject go = __instance.gameObject; TechType resourceType = (go == null ? TechType.None : CraftData.GetTechType(go)); - QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"ResourceTrackerPatches.PostRegister() running on ResourceTracker with unique ID {uniqueId}, overrideTechType {__instance.overrideTechType} and techType {resourceType}"); + //QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"ResourceTrackerPatches.PostRegister() running on ResourceTracker with unique ID {uniqueId}, overrideTechType {__instance.overrideTechType} and techType {resourceType}"); //TechType actualTechType = CraftData.GetTechType(__instance.gameObject); if (!string.IsNullOrEmpty(uniqueId)) @@ -61,6 +63,7 @@ public static void PostRegister(ref ResourceTracker __instance) IdToGameObjectDict[uniqueId] = __instance.gameObject; } IdToTechTypeDict[uniqueId] = resourceType; + IdToResourceNameDict[uniqueId] = Language.main.Get(resourceType); } } @@ -77,6 +80,7 @@ public static void PostUnregister(ref ResourceTracker __instance) { IdToGameObjectDict.Remove(uniqueId); IdToTechTypeDict.Remove(uniqueId); + IdToResourceNameDict.Remove(uniqueId); } } @@ -86,7 +90,8 @@ public static TechType GetTechTypeForId(string uniqueId) { if (IdToTechTypeDict.TryGetValue(uniqueId, out TechType tt)) { - return tt; + if(tt != TechType.Fragment) + return tt; } else if (IdToGameObjectDict.TryGetValue(uniqueId, out GameObject go)) { @@ -97,5 +102,10 @@ public static TechType GetTechTypeForId(string uniqueId) return TechType.None; } + + public static bool TryGetResourceName(string uniqueId, out string resourceName) + { + return IdToResourceNameDict.TryGetValue(uniqueId, out resourceName); + } } } diff --git a/SubnauticaModSystem/Common/Mod/LockerPrefabShared.cs b/SubnauticaModSystem/Common/Mod/LockerPrefabShared.cs index 7368039..4b0e249 100644 --- a/SubnauticaModSystem/Common/Mod/LockerPrefabShared.cs +++ b/SubnauticaModSystem/Common/Mod/LockerPrefabShared.cs @@ -62,14 +62,16 @@ internal static Image CreateIcon(Transform parent, Color color, int y) return icon; } -#if SUBNAUTICA +#if SN1 internal static Text CreateText(Transform parent, Text prefab, Color color, int y, int size, string initial) + { + var text = new GameObject("Text", typeof(RectTransform)).AddComponent(); #elif BELOWZERO internal static TextMeshProUGUI CreateText(Transform parent, TextMeshProUGUI prefab, Color color, int y, int size, string initial) -#endif - { var text = new GameObject("TextMeshProUGUI", typeof(RectTransform)).AddComponent(); +#endif + var rt = text.rectTransform; RectTransformExtensions.SetParams(rt, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), parent); RectTransformExtensions.SetSize(rt, 120, 200); diff --git a/SubnauticaModSystem/Common/Mod/ModUtils.cs b/SubnauticaModSystem/Common/Mod/ModUtils.cs index 54d8c3e..7379b58 100644 --- a/SubnauticaModSystem/Common/Mod/ModUtils.cs +++ b/SubnauticaModSystem/Common/Mod/ModUtils.cs @@ -5,10 +5,11 @@ using System.Linq; using System.Reflection; using System.Text; -#if SUBNAUTICA +#if SN1 using Oculus.Newtonsoft.Json; #elif BELOWZERO using Newtonsoft.Json; +using TMPro; #endif using UnityEngine; using UnityEngine.UI; @@ -26,6 +27,7 @@ internal static class ModUtils { if (!File.Exists(configFilePath)) { + QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Error, $"Could not find config file {configFilePath}", null, true); return WriteDefaultConfig(configFilePath); } @@ -35,6 +37,7 @@ internal static class ModUtils if (string.IsNullOrEmpty(serialilzedConfig)) { + QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Error, $"Config file {configFilePath} empty; creating default config", null, true); return new ConfigT(); } @@ -42,13 +45,15 @@ internal static class ModUtils if (config == null) { + QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Error, $"Failed to deserialise configuration object from file {configFilePath}", null, true); config = new ConfigT(); } return config; } - catch + catch (Exception e) { + QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Error, $"Exception caught while parsing config file {configFilePath}", e, true); return WriteDefaultConfig(configFilePath); } } @@ -221,25 +226,33 @@ public static void PrintObjectFields(object obj, string indent = "") } } +#if SN1 public static Text GetTextPrefab() { Text prefab = null; -#if SUBNAUTICA prefab = GameObject.FindObjectOfType().interactPrimaryText; #elif BELOWZERO - //prefab = GameObject.FindObjectOfType(). + public static TextMeshProUGUI GetTextPrefab() + { + TextMeshProUGUI prefab = GameObject.FindObjectOfType().progressText; #endif - if (prefab == null) + /*if (prefab == null) { return null; - } + }*/ return prefab; } +#if SN1 public static Text InstantiateNewText(string name, Transform parent) { Text text = GameObject.Instantiate(GetTextPrefab()); +#elif BZ + public static TextMeshProUGUI InstantiateNewText(string name, Transform parent) + { + TextMeshProUGUI text = GameObject.Instantiate(GetTextPrefab()); +#endif text.gameObject.layer = parent.gameObject.layer; text.gameObject.name = name; text.transform.SetParent(parent, false); diff --git a/SubnauticaModSystem/DockedVehicleStorageAccess/CheckboxButton.cs b/SubnauticaModSystem/DockedVehicleStorageAccess/CheckboxButton.cs index 4a37564..21ff8e5 100644 --- a/SubnauticaModSystem/DockedVehicleStorageAccess/CheckboxButton.cs +++ b/SubnauticaModSystem/DockedVehicleStorageAccess/CheckboxButton.cs @@ -4,6 +4,9 @@ using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; +#if BZ +using TMPro; +#endif namespace DockedVehicleStorageAccess { @@ -21,7 +24,11 @@ public class CheckboxButton : MonoBehaviour, IPointerClickHandler, IPointerEnter public RectTransform rectTransform; public Image image; +#if SN1 public Text text; +#elif BZ + public TextMeshProUGUI text; +#endif public Action onToggled = delegate { }; private Sprite checkedSprite = null; @@ -94,9 +101,14 @@ public void OnPointerUp(PointerEventData eventData) ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#if SN1 public static CheckboxButton CreateCheckbox(Transform parent, Color color, Text textPrefab, string label, float width = 100) { - var checkboxButton = new GameObject("Checkbox", typeof(RectTransform)); +#elif BZ + public static CheckboxButton CreateCheckbox(Transform parent, Color color, TextMeshProUGUI textPrefab, string label, float width = 100) + { +#endif + var checkboxButton = new GameObject("Checkbox", typeof(RectTransform)); var rt = checkboxButton.transform as RectTransform; RectTransformExtensions.SetParams(rt, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), parent); RectTransformExtensions.SetSize(rt, width, 20); @@ -111,8 +123,11 @@ public static CheckboxButton CreateCheckbox(Transform parent, Color color, Text var text = LockerPrefabShared.CreateText(rt, textPrefab, color, 0, 10, label); RectTransformExtensions.SetSize(text.rectTransform, width - iconWidth - spacing, iconWidth); text.rectTransform.anchoredPosition = new Vector2(iconWidth / 2 + spacing, 0); +#if SN1 text.alignment = TextAnchor.MiddleLeft; - +#elif BZ + text.alignment = TextAlignmentOptions.MidlineLeft; +#endif checkboxButton.AddComponent(); var button = checkboxButton.AddComponent(); diff --git a/SubnauticaModSystem/DockedVehicleStorageAccess/DockedVehicleStorageAccess.csproj b/SubnauticaModSystem/DockedVehicleStorageAccess/DockedVehicleStorageAccess.csproj index ac57980..67eb5de 100644 --- a/SubnauticaModSystem/DockedVehicleStorageAccess/DockedVehicleStorageAccess.csproj +++ b/SubnauticaModSystem/DockedVehicleStorageAccess/DockedVehicleStorageAccess.csproj @@ -150,7 +150,10 @@ - + + PreserveNewest + + PreserveNewest @@ -163,12 +166,9 @@ - xcopy $(TargetPath) $(GameDir)\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)mod.json $(GameDir)\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)Assets $(GameDir)\QMods\$(ProjectName)\Assets\ /q /y /i - -xcopy $(TargetPath) D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)mod.json D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)Assets D:\EpicGames\Subnautica\QMods\$(ProjectName)\Assets\ /q /y /i + xcopy $(TargetPath) $(GameDir)\QMods\$(AssemblyName)\ /q /y +copy $(ProjectDir)mod_$(Configuration).json "$(GameDir)\QMods\$(AssemblyName)\mod.json" /y +xcopy $(ProjectDir)Assets $(GameDir)\QMods\$(AssemblyName)\Assets\ /q /y /i + \ No newline at end of file diff --git a/SubnauticaModSystem/DockedVehicleStorageAccess/Mod.cs b/SubnauticaModSystem/DockedVehicleStorageAccess/Mod.cs index 4e67397..5da36f5 100644 --- a/SubnauticaModSystem/DockedVehicleStorageAccess/Mod.cs +++ b/SubnauticaModSystem/DockedVehicleStorageAccess/Mod.cs @@ -26,8 +26,7 @@ public static void Patch(string modDirectory = null) AddBuildables(); - var harmony = new Harmony("com.DockedVehicleStorageAccessSML.mod"); - harmony.PatchAll(Assembly.GetExecutingAssembly()); + new Harmony("com.DockedVehicleStorageAccessSML.mod").PatchAll(Assembly.GetExecutingAssembly()); Logger.Log("Patched"); } diff --git a/SubnauticaModSystem/DockedVehicleStorageAccess/MoonpoolTerminalController.cs b/SubnauticaModSystem/DockedVehicleStorageAccess/MoonpoolTerminalController.cs index 745984b..6e0df65 100644 --- a/SubnauticaModSystem/DockedVehicleStorageAccess/MoonpoolTerminalController.cs +++ b/SubnauticaModSystem/DockedVehicleStorageAccess/MoonpoolTerminalController.cs @@ -3,6 +3,7 @@ using Oculus.Newtonsoft.Json; #elif BELOWZERO using Newtonsoft.Json; +using TMPro; #endif using System; using System.Collections.Generic; @@ -41,13 +42,14 @@ class MoonpoolTerminalController : MonoBehaviour, IProtoEventListener private void Awake() { - var buttonPositionCenter = new Vector2(0, 0); - var buttonSpacing = 104; + Vector2 buttonPositionCenter = new Vector2(0, 0); + int buttonSpacing = 104; - var parent = GetComponentInChildren().transform; - var color = new Color32(189, 255, 255, 255); + Transform parent = GetComponentInChildren().transform; + Color32 color = new Color32(189, 255, 255, 255); - var text = new GameObject("label", typeof(RectTransform)).AddComponent(); +#if SN1 + Text text = new GameObject("label", typeof(RectTransform)).AddComponent(); RectTransformExtensions.SetParams(text.rectTransform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), parent); RectTransformExtensions.SetSize(text.rectTransform, 500, 140); text.rectTransform.anchoredPosition = buttonPositionCenter + new Vector2(0, 80); @@ -56,11 +58,22 @@ private void Awake() text.fontSize = Mathf.FloorToInt(GetComponentInChildren().fontSize * 1.8f); text.font = GetComponentInChildren().font; text.alignment = TextAnchor.MiddleCenter; +#elif BZ + TextMeshProUGUI text = new GameObject("label", typeof(RectTransform)).AddComponent(); + RectTransformExtensions.SetParams(text.rectTransform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), parent); + RectTransformExtensions.SetSize(text.rectTransform, 500, 140); + text.rectTransform.anchoredPosition = buttonPositionCenter + new Vector2(0, 80); + text.color = GetComponentInChildren().color; + text.text = "Position"; + text.fontSize = Mathf.FloorToInt(GetComponentInChildren().fontSize * 1.8f); + text.font = GetComponentInChildren().font; + text.alignment = TextAlignmentOptions.Midline; +#endif text.raycastTarget = false; - for (int i = 0; i < 4; ++i) + for (int i = 0; i < 4; i++) { - var button = CheckboxButton.CreateCheckboxNoText(parent, color, 100); + CheckboxButton button = CheckboxButton.CreateCheckboxNoText(parent, color, 100); button.Initialize(); button.toggled = false; button.rectTransform.anchoredPosition = buttonPositionCenter + new Vector2((-1.5f + i) * buttonSpacing, 0); diff --git a/SubnauticaModSystem/DockedVehicleStorageAccess/Patches/DockingBay_Patches.cs b/SubnauticaModSystem/DockedVehicleStorageAccess/Patches/DockingBay_Patches.cs index d2b9b76..64f7478 100644 --- a/SubnauticaModSystem/DockedVehicleStorageAccess/Patches/DockingBay_Patches.cs +++ b/SubnauticaModSystem/DockedVehicleStorageAccess/Patches/DockingBay_Patches.cs @@ -11,7 +11,6 @@ namespace DockedVehicleStorageAccess.Patches { [HarmonyPatch(typeof(VehicleDockingBay))] - [HarmonyPatch("Start")] class VehicleDockingBay_Start_Patch { private static readonly MethodInfo CyclopsVehicleStorageTerminalManager_OnDockedChanged = typeof(CyclopsVehicleStorageTerminalManager).GetMethod("OnDockedChanged", BindingFlags.NonPublic | BindingFlags.Instance); @@ -19,18 +18,36 @@ class VehicleDockingBay_Start_Patch private static GameObject prefab; private static bool requestingPrefab; + [HarmonyPatch("Start")] private static void Postfix(VehicleDockingBay __instance) { + // in SN1, VehicleDockingBay.subRoot will either be of type BaseRoot, if the docking bay in question is in a habitat, or of SubRoot, if it's in a Cyclops. + // But subRoot always seems to be Null in BZ, so something else needs to be done + + // Of course, this assumes we can figure out an alternative to the Cyclops terminal used by default. +#if SN1 + //QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"VehicleDockingBay.Start.Postfix: running on VehicleDockingBay {__instance.ToString()}"); + //QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"VehicleDockingBay is of type {__instance.GetType().ToString()}"); if (__instance.subRoot is BaseRoot) { + //QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"VehicleDockingBay is BaseRoot, creating console"); __instance.StartCoroutine(CreateConsole(__instance)); } +#elif BZ + QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"Cyclops prefab not available in BZ, not attempting to add moonpool console"); + /*QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"VehicleDockingBay type is {__instance.dockType.ToString()}"); + if (__instance.dockType == Vehicle.DockType.Base) + { + QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"VehicleDockingBay type is correct, creating console"); + }*/ +#endif } private static IEnumerator CreateConsole(VehicleDockingBay __instance) { if (prefab == null) { + QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"CreateConsole: attempting to create prefab"); yield return CreatePrefab(); } @@ -39,6 +56,7 @@ private static IEnumerator CreateConsole(VehicleDockingBay __instance) console.transform.localPosition = new Vector3(4.96f, 1.4f, 3.23f); console.transform.localEulerAngles = new Vector3(0, 42.5f, 0); + QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"Adding MoonpoolTerminalController component"); console.AddComponent(); var terminalManager = console.GetComponent(); diff --git a/SubnauticaModSystem/DockedVehicleStorageAccess/VehicleStorageAccess.cs b/SubnauticaModSystem/DockedVehicleStorageAccess/VehicleStorageAccess.cs index 8bdcf36..57e4363 100644 --- a/SubnauticaModSystem/DockedVehicleStorageAccess/VehicleStorageAccess.cs +++ b/SubnauticaModSystem/DockedVehicleStorageAccess/VehicleStorageAccess.cs @@ -10,6 +10,12 @@ using SMLHelper.V2.Crafting; using UnityEngine; using UnityEngine.UI; +#if SUBNAUTICA + using RecipeData = SMLHelper.V2.Crafting.TechData; + using Sprite = Atlas.Sprite; +#elif BELOWZERO +using TMPro; +#endif namespace DockedVehicleStorageAccess { @@ -34,11 +40,16 @@ public class VehicleStorageAccess : MonoBehaviour, IProtoEventListener private StorageContainer container; private SubRoot subRoot; private VehicleDockingBay[] dockingBays = new VehicleDockingBay[0]; +#if SN1 private List vehicles = new List(); +#elif BZ + private List vehicles = new List(); +#endif private bool transferringToAutosorter; private List autosorters = new List(); +#if SN1 [SerializeField] private Text textPrefab; [SerializeField] @@ -55,6 +66,24 @@ public class VehicleStorageAccess : MonoBehaviour, IProtoEventListener private Image exosuitIcon; [SerializeField] private Text exosuitCountText; +#elif BZ + [SerializeField] + private TextMeshProUGUI textPrefab; + [SerializeField] + private Image background; + [SerializeField] + private Image icon; + [SerializeField] + private TextMeshProUGUI text; + [SerializeField] + private Image seamothIcon; + [SerializeField] + private TextMeshProUGUI seamothCountText; + [SerializeField] + private Image exosuitIcon; + [SerializeField] + private TextMeshProUGUI exosuitCountText; +#endif [SerializeField] private CheckboxButton enableCheckbox; @@ -132,7 +161,11 @@ private void UpdateDockedVehicles() vehicles.Clear(); foreach (var dockingBay in dockingBays) { +#if SN1 var vehicle = dockingBay.GetDockedVehicle(); +#elif BZ + var vehicle = dockingBay.GetDockedObject(); +#endif if (vehicle != null) { vehicles.Add(vehicle); @@ -160,6 +193,7 @@ private IEnumerator TryExtractItems() bool extractedAnything = false; Dictionary extractionResults = new Dictionary(); +#if SN1 List localVehicles = vehicles.ToList(); foreach (var vehicle in localVehicles) { @@ -167,6 +201,31 @@ private IEnumerator TryExtractItems() extractionResults[vehicleName] = 0; var vehicleContainers = vehicle.gameObject.GetComponentsInChildren().Select((x) => x.container).ToList(); vehicleContainers.AddRange(GetSeamothStorage(vehicle)); +#elif BZ + foreach (Dockable dockable in vehicles) + { + if (dockable.gameObject == null) + continue; + + string vehicleName = ""; + NamePlate namePlate = dockable.gameObject.GetComponent(); + if (namePlate != null) + { + vehicleName = namePlate.namePlateText; + } + else + { + vehicleName = dockable.gameObject.name; + } + + extractionResults[vehicleName] = 0; + List vehicleContainers = new List(); + vehicleContainers.AddRange(dockable.gameObject.GetComponentsInChildren().Select((x) => x.container).ToList()); + List dockableContainers = GetSeamothStorage(dockable); + if (dockableContainers != null) + vehicleContainers.AddRange(dockableContainers); + +#endif bool couldNotAdd = false; foreach (var vehicleContainer in vehicleContainers) { @@ -218,10 +277,11 @@ private IEnumerator TryExtractItems() extractingItems = false; } +#if SN1 private List GetSeamothStorage(Vehicle seamoth) { var results = new List(); - if (seamoth is SeaMoth && seamoth.modules != null) + if ((seamoth is SeaMoth && seamoth.modules != null) { using (var e = seamoth.modules.GetEquipment()) { @@ -244,6 +304,55 @@ private List GetSeamothStorage(Vehicle seamoth) return results; } +#elif BZ + // This method appears to be flawless as-is; no exceptions seem to be getting thrown here. + private List GetSeamothStorage(Dockable dockable) + { + if (dockable == null) + { + //QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Error, $"GetSeamothStorage invoked with null dockable"); + return null; + } + + //QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"GetSeamothStorage: running on dockable {dockable.name}; dockable.truckMotor = " + (dockable.truckMotor != null ? dockable.truckMotor.ToString() : "null")); + Equipment modules = null; + if (dockable.vehicle is SeaMoth) + modules = dockable.vehicle.modules; + else if (dockable.truckMotor != null) + modules = dockable.truckMotor.upgrades.modules; + + if (modules != null) + { + var results = new List(); + int i = 0; + using (var e = modules.GetEquipment()) + { + //QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"GetSeamothStorage: start enumerator"); + while (e.MoveNext()) + { + //QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"GetSeamothStorage: For dockable {dockable.name}, using module {i}"); + var module = e.Current.Value; + if (module != null && module.item != null) + { + var container = module.item.GetComponent(); + if (container != null && !container.gameObject.name.Contains("Torpedo")) + { + //QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"GetSeamothStorage: For dockable {dockable.name}, found SeamothStorageContainer at index {i}"); + results.Add(container.container); + } + } + i++; + } + } + //QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"GetSeamothStorage: got {results.Count} storage containers"); + return results; + } + + //QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"GetSeamothStorage: could not get Equipment instance"); + return null; + } +#endif + private void NotifyExtraction(Dictionary extractionResults) { List messageEntries = new List(); @@ -346,10 +455,16 @@ private void UpdateText() int seamothCount = 0; int exosuitCount = 0; - foreach (var vehicle in vehicles) - { - seamothCount += (vehicle is SeaMoth ? 1 : 0); + foreach (var dockable in vehicles) + { +#if SN1 + seamothCount += (dockable is SeaMoth ? 1 : 0); + exosuitCount += (dockable is Exosuit ? 1 : 0); +#elif BZ + var vehicle = dockable.vehicle; + seamothCount += ((vehicle is SeaMoth || dockable.truckMotor != null) ? 1 : 0); exosuitCount += (vehicle is Exosuit ? 1 : 0); +#endif } seamothCountText.text = seamothCount > 1 ? "x" + seamothCount : ""; @@ -364,15 +479,15 @@ private void UpdateText() } else if (extractingItems) { - text.text += "\n\nEXTRACTING..."; + text.text += "\n\nEXTRACTING..."; // The original code here was , but that apparently isn't valid for a TextMeshProUGUI. } else if (Mod.config.UseAutosortMod && autosorters.Count == 0 && transferringToAutosorter) { - text.text += "\n\nTRANSFERRING..."; + text.text += "\n\nTRANSFERRING..."; } else { - text.text += "\n\nREADY"; + text.text += "\n\nREADY"; } } @@ -406,7 +521,9 @@ private void Initialize() background.gameObject.SetActive(true); icon.gameObject.SetActive(true); text.gameObject.SetActive(true); +#if !BZ text.supportRichText = true; +#endif background.sprite = ImageUtils.LoadSprite(Mod.GetAssetPath("LockerScreen.png")); icon.sprite = ImageUtils.LoadSprite(Mod.GetAssetPath("Receptacle.png")); @@ -461,6 +578,7 @@ public void OnProtoDeserialize(ProtobufSerializer serializer) saveData = data; initialized = false; }); + StopAllCoroutines(); } public string GetSaveDataPath() @@ -485,12 +603,26 @@ public VehicleStorageAccessBuildable() public override TechCategory CategoryForPDA => TechCategory.InteriorModule; +#if SN1 public override GameObject GetGameObject() { GameObject originalPrefab = CraftData.GetPrefabForTechType(TechType.SmallLocker); GameObject prefab = GameObject.Instantiate(originalPrefab); + var storageAccess = prefab.AddComponent(); + storageAccess.textPrefab = GameObject.Instantiate(prefab.GetComponentInChildren()); + +#elif BZ + public override IEnumerator GetGameObjectAsync(IOut gameObject) + { + CoroutineTask task = CraftData.GetPrefabForTechTypeAsync(TechType.SmallLocker); + yield return task; + var smallLockerPrefab = task.GetResult(); + GameObject prefab = GameObject.Instantiate(smallLockerPrefab); + var storageAccess = prefab.EnsureComponent(); + storageAccess.textPrefab = GameObject.Instantiate(smallLockerPrefab.GetComponentInChildren()); +#endif - var container = prefab.GetComponent(); + var container = prefab.EnsureComponent(); container.width = Mod.config.LockerWidth; container.height = Mod.config.LockerHeight; container.container.Resize(Mod.config.LockerWidth, Mod.config.LockerHeight); @@ -501,9 +633,6 @@ public override GameObject GetGameObject() meshRenderer.material.color = new Color(0, 0, 1); } - var storageAccess = prefab.AddComponent(); - - storageAccess.textPrefab = GameObject.Instantiate(prefab.GetComponentInChildren()); var label = prefab.FindChild("Label"); DestroyImmediate(label); @@ -532,12 +661,16 @@ public override GameObject GetGameObject() storageAccess.background.gameObject.SetActive(false); +#if SN1 return prefab; +#elif BZ + gameObject.Set(prefab); +#endif } - protected override TechData GetBlueprintRecipe() + protected override RecipeData GetBlueprintRecipe() { - return new TechData + return new RecipeData { craftAmount = 1, Ingredients = @@ -548,7 +681,7 @@ protected override TechData GetBlueprintRecipe() }; } - protected override Atlas.Sprite GetItemSprite() + protected override Sprite GetItemSprite() { return SMLHelper.V2.Utility.ImageUtils.LoadSpriteFromFile(Mod.GetAssetPath("StorageAccess.png")); } diff --git a/SubnauticaModSystem/DockedVehicleStorageAccess/mod_BZ.json b/SubnauticaModSystem/DockedVehicleStorageAccess/mod_BZ.json new file mode 100644 index 0000000..14c39b1 --- /dev/null +++ b/SubnauticaModSystem/DockedVehicleStorageAccess/mod_BZ.json @@ -0,0 +1,10 @@ +{ + "Id": "DockedVehicleStorageAccessSML", + "DisplayName": "Docked Vehicle Storage Access", + "Author": "RandyKnapp w/PrimeSonic", + "Version": "2.0.0", + "Requires": [ "SMLHelper" ], + "Enable": true, + "Game": "BelowZero", + "AssemblyName": "DockedVehicleStorageAccessSML.dll" +} \ No newline at end of file diff --git a/SubnauticaModSystem/DockedVehicleStorageAccess/mod.json b/SubnauticaModSystem/DockedVehicleStorageAccess/mod_SN1.json similarity index 100% rename from SubnauticaModSystem/DockedVehicleStorageAccess/mod.json rename to SubnauticaModSystem/DockedVehicleStorageAccess/mod_SN1.json diff --git a/SubnauticaModSystem/DockedVehicleStorageAccessSML/BZ/mod_BZ.json b/SubnauticaModSystem/DockedVehicleStorageAccessSML/BZ/mod_BZ.json new file mode 100644 index 0000000..14c39b1 --- /dev/null +++ b/SubnauticaModSystem/DockedVehicleStorageAccessSML/BZ/mod_BZ.json @@ -0,0 +1,10 @@ +{ + "Id": "DockedVehicleStorageAccessSML", + "DisplayName": "Docked Vehicle Storage Access", + "Author": "RandyKnapp w/PrimeSonic", + "Version": "2.0.0", + "Requires": [ "SMLHelper" ], + "Enable": true, + "Game": "BelowZero", + "AssemblyName": "DockedVehicleStorageAccessSML.dll" +} \ No newline at end of file diff --git a/SubnauticaModSystem/DockedVehicleStorageAccessSML/BZ/mod_SN1.json b/SubnauticaModSystem/DockedVehicleStorageAccessSML/BZ/mod_SN1.json new file mode 100644 index 0000000..1e01245 --- /dev/null +++ b/SubnauticaModSystem/DockedVehicleStorageAccessSML/BZ/mod_SN1.json @@ -0,0 +1,9 @@ +{ + "Id": "DockedVehicleStorageAccessSML", + "DisplayName": "Docked Vehicle Storage Access", + "Author": "RandyKnapp w/PrimeSonic", + "Version": "2.0.0", + "Requires": [ "SMLHelper" ], + "Enable": true, + "AssemblyName": "DockedVehicleStorageAccessSML.dll" +} \ No newline at end of file diff --git a/SubnauticaModSystem/GameDir.targets b/SubnauticaModSystem/GameDir.targets index 820a418..112228b 100644 --- a/SubnauticaModSystem/GameDir.targets +++ b/SubnauticaModSystem/GameDir.targets @@ -3,5 +3,7 @@ S:\Steam\steamapps\common\ + $(CommonDir)\Subnautica\ + $(CommonDir)\SubnauticaZero\ \ No newline at end of file From 70d52d057192b3c293a12dcac8c399ea25056363 Mon Sep 17 00:00:00 2001 From: DaWrecka <61927940+DaWrecka@users.noreply.github.com> Date: Mon, 17 May 2021 19:28:42 +0100 Subject: [PATCH 10/11] Manual resolve MoreQuickSlots conflict --- SubnauticaModSystem/MoreQuickSlots/Config.cs | 5 +- SubnauticaModSystem/MoreQuickSlots/Mod.cs | 62 +++------ .../MoreQuickSlots/MoreQuickSlots.csproj | 127 +++++------------- .../Patches/QuickSlots_Ctor_Patch.cs | 8 +- .../MoreQuickSlots/Properties/AssemblyInfo.cs | 4 +- SubnauticaModSystem/MoreQuickSlots/mod.json | 17 +-- 6 files changed, 60 insertions(+), 163 deletions(-) diff --git a/SubnauticaModSystem/MoreQuickSlots/Config.cs b/SubnauticaModSystem/MoreQuickSlots/Config.cs index 1ec219d..fe2e623 100644 --- a/SubnauticaModSystem/MoreQuickSlots/Config.cs +++ b/SubnauticaModSystem/MoreQuickSlots/Config.cs @@ -1,9 +1,8 @@ -using System; +using SMLHelper.V2.Json; namespace MoreQuickSlots { - [Serializable] - public class Config + public class Config: ConfigFile { public int SlotCount = 12; public bool ShowInputText = true; diff --git a/SubnauticaModSystem/MoreQuickSlots/Mod.cs b/SubnauticaModSystem/MoreQuickSlots/Mod.cs index 1a57abb..b1303b9 100644 --- a/SubnauticaModSystem/MoreQuickSlots/Mod.cs +++ b/SubnauticaModSystem/MoreQuickSlots/Mod.cs @@ -1,27 +1,23 @@ -using Common.Utility; -using HarmonyLib; -using System; -using System.IO; +using HarmonyLib; +using QModManager.API.ModLoading; using System.Reflection; using UnityEngine; namespace MoreQuickSlots { + [QModCore] public static class Mod { public const int MaxSlots = 12; public const int MinSlots = 1; - public static Config config; + public static Config config = new Config(); - private static string modDirectory; - private static string[] keys = new string[MaxSlots]; - - public static void Patch(string modDirectory = null) + private static readonly string[] keys = new string[MaxSlots]; + + [QModPatch] + public static void Patch() { - Mod.modDirectory = modDirectory ?? "Subnautica_Data/Managed"; - LoadConfig(); - keys[5] = config.Slot6Key; keys[6] = config.Slot7Key; keys[7] = config.Slot8Key; @@ -30,45 +26,24 @@ public static void Patch(string modDirectory = null) keys[10] = config.Slot11Key; keys[11] = config.Slot12Key; - HarmonyInstance harmony = HarmonyInstance.Create("com.morequickslots.mod"); + Harmony harmony = new Harmony("com.morequickslots.mod"); harmony.PatchAll(Assembly.GetExecutingAssembly()); Logger.Log("Patched"); } - private static string GetModInfoPath() - { - return Environment.CurrentDirectory + "/" + modDirectory + "/mod.json"; - } - - private static void LoadConfig() + [QModPrePatch] + public static void LoadConfig() { - string modInfoPath = GetModInfoPath(); - - if (!File.Exists(modInfoPath)) - { - config = new Config(); - return; - } - - var modInfoObject = JSON.Parse(File.ReadAllText(modInfoPath)); - string configJson = modInfoObject["Config"].ToString(); - config = JsonUtility.FromJson(configJson); + config.Load(true); ValidateConfig(); } private static void ValidateConfig() { - Config defaultConfig = new Config(); - if (config == null) - { - config = defaultConfig; - return; - } - if (config.SlotCount < MinSlots || config.SlotCount > MaxSlots) { - config.SlotCount = defaultConfig.SlotCount; + config.SlotCount = 12; } } @@ -80,15 +55,10 @@ public static string GetInputForSlot(int slotID) string input = LanguageCache.GetButtonFormat("{0}", GameInput.Button.Slot1 + slotID); return string.IsNullOrEmpty(inputName) ? "" : input; } - if (slotID < 0 || slotID >= MaxSlots) - { - return "???"; - } - - return keys[slotID]; - } + return slotID < 0 || slotID >= MaxSlots ? "???" : keys[slotID]; + } - public static bool GetKeyDownForSlot(int slotID) + public static bool GetKeyDownForSlot(int slotID) { return slotID >= Player.quickSlotButtonsCount && slotID < Mod.MaxSlots && Input.GetKeyDown(Mod.GetInputForSlot(slotID)); } diff --git a/SubnauticaModSystem/MoreQuickSlots/MoreQuickSlots.csproj b/SubnauticaModSystem/MoreQuickSlots/MoreQuickSlots.csproj index d8165e0..efd6a72 100644 --- a/SubnauticaModSystem/MoreQuickSlots/MoreQuickSlots.csproj +++ b/SubnauticaModSystem/MoreQuickSlots/MoreQuickSlots.csproj @@ -1,7 +1,6 @@  - Debug AnyCPU @@ -10,7 +9,6 @@ Properties MoreQuickSlots MoreQuickSlots - $(SolutionDir)$(AssemblyName)\$(Configuration)\ v4.7.2 512 @@ -24,101 +22,58 @@ prompt 4 false + true - pdbonly + none true bin\Release\ TRACE - prompt + none 4 false + true OnBuildSuccess - - BZ;BELOWZERO - true - true - $(CommonDir)SubnauticaZero.Stable - SubnauticaZero_Data - SMLHelper_BZ - AnyCPU - 7.1 - prompt - - - SN1;SUBNAUTICA_STABLE - true - true - $(CommonDir)Subnautica.Stable - Subnautica_Data - Modding Helper - AnyCPU - 7.1 - prompt - - $(GameDir)\BepInEx\core\0Harmony.dll - - - False - $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp.dll + D:\SteamLibrary\steamapps\common\Subnautica\BepInEx\core\0Harmony.dll + False - - False - $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp-firstpass.dll + + D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\publicized_assemblies\Assembly-CSharp.dll + False - - $(GameDir)\$(DataFolder)\Managed\LitJson.dll + + D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\publicized_assemblies\Assembly-CSharp-firstpass.dll + False - - $(GameDir)\$(DataFolder)\Managed\NewtonSoft.Json.dll + + D:\SteamLibrary\steamapps\common\Subnautica\BepInEx\plugins\QModManager\QModInstaller.dll + False - $(GameDir)\QMods\$(SMLHelperFolder)\SMLHelper.dll + D:\SteamLibrary\steamapps\common\Subnautica\QMods\Modding Helper\SMLHelper.dll + False - - - - - - - $(GameDir)\$(DataFolder)\Managed\UnityEngine.dll - - - False - $(GameDir)\$(DataFolder)\Managed\UnityEngine.CoreModule.dll - - - False - $(GameDir)\$(DataFolder)\Managed\UnityEngine.ImageConversionModule.dll + + D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.CoreModule.dll + False - $(GameDir)\$(DataFolder)\Managed\UnityEngine.InputLegacyModule.dll - - - False - $(GameDir)\$(DataFolder)\Managed\UnityEngine.JSONSerializeModule.dll + D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.InputLegacyModule.dll + False - - False - $(GameDir)\$(DataFolder)\Managed\UnityEngine.TextRenderingModule.dll + + D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.TextRenderingModule.dll + False - - False - $(GameDir)\$(DataFolder)\Managed\UnityEngine.UI.dll - - - False - $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIElementsModule.dll - - - False - $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIModule.dll + + D:\SteamLibrary\steamapps\common\Subnautica\Subnautica_Data\Managed\UnityEngine.UI.dll + False @@ -126,32 +81,20 @@ - - - True - True - Resources.resx - - - - - - ResXFileCodeGenerator - Resources.Designer.cs - + + PreserveNewest + - - xcopy $(TargetPath) $(GameDir)\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)mod.json $(GameDir)\QMods\$(ProjectName)\ /q /y - -xcopy $(TargetPath) D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y -xcopy $(ProjectDir)mod.json D:\EpicGames\Subnautica\QMods\$(ProjectName)\ /q /y + + xcopy "$(TargetDir)" "D:\SteamLibrary\steamapps\common\Subnautica\QMods\$(ProjectName)\" /q /y /i + xcopy "$(TargetDir)" "D:\EpicGames\Subnautica\QMods\$(ProjectName)\" /q /y /i + \ No newline at end of file diff --git a/SubnauticaModSystem/MoreQuickSlots/Patches/QuickSlots_Ctor_Patch.cs b/SubnauticaModSystem/MoreQuickSlots/Patches/QuickSlots_Ctor_Patch.cs index b26e32d..ce10bde 100644 --- a/SubnauticaModSystem/MoreQuickSlots/Patches/QuickSlots_Ctor_Patch.cs +++ b/SubnauticaModSystem/MoreQuickSlots/Patches/QuickSlots_Ctor_Patch.cs @@ -1,6 +1,5 @@ using HarmonyLib; using System; -using System.Reflection; using UnityEngine; namespace MoreQuickSlots.Patches @@ -9,7 +8,8 @@ namespace MoreQuickSlots.Patches [HarmonyPatch(new Type[] { typeof(GameObject), typeof(Transform), typeof(Transform), typeof(Inventory), typeof(Transform), typeof(int) })] class QuickSlots_Ctor_Patch { - static bool Prefix(ref int slotCount) + [HarmonyPrefix] + static void Prefix(ref int slotCount, ref string[] ___slotNames) { slotCount = Mod.config.SlotCount; @@ -18,9 +18,7 @@ static bool Prefix(ref int slotCount) { newSlotNames[i] = "QuickSlot" + i; } - typeof(QuickSlots).GetField("slotNames", BindingFlags.Static | BindingFlags.NonPublic).SetValue(null, newSlotNames); - - return true; + ___slotNames = newSlotNames; } } } diff --git a/SubnauticaModSystem/MoreQuickSlots/Properties/AssemblyInfo.cs b/SubnauticaModSystem/MoreQuickSlots/Properties/AssemblyInfo.cs index 9876665..e574fd9 100644 --- a/SubnauticaModSystem/MoreQuickSlots/Properties/AssemblyInfo.cs +++ b/SubnauticaModSystem/MoreQuickSlots/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyVersion("1.1.8.0")] +[assembly: AssemblyFileVersion("1.1.8.0")] diff --git a/SubnauticaModSystem/MoreQuickSlots/mod.json b/SubnauticaModSystem/MoreQuickSlots/mod.json index c948070..f16c620 100644 --- a/SubnauticaModSystem/MoreQuickSlots/mod.json +++ b/SubnauticaModSystem/MoreQuickSlots/mod.json @@ -2,20 +2,7 @@ "Id": "MoreQuickSlots", "DisplayName": "More Quick Slots", "Author": "RandyKnapp", - "Version": "1.1.7", - "Requires": [ "0Harmony-1.2.0.1.dll" ], + "Version": "1.1.8", "Enable": true, - "AssemblyName": "MoreQuickSlots.dll", - "EntryMethod": "MoreQuickSlots.QPatch.Patch", - "Config": { - "SlotCount": 12, - "ShowInputText": true, - "Slot6Key": "6", - "Slot7Key": "7", - "Slot8Key": "8", - "Slot9Key": "9", - "Slot10Key": "0", - "Slot11Key": "-", - "Slot12Key": "=" - } + "AssemblyName": "MoreQuickSlots.dll" } \ No newline at end of file From cf87332b5dd8801da28cc232fe88160f5266a09f Mon Sep 17 00:00:00 2001 From: DaWrecka <61927940+DaWrecka@users.noreply.github.com> Date: Thu, 18 Nov 2021 23:57:49 +0000 Subject: [PATCH 11/11] 2021-11-18 BetterScannerBlips: Fragments now show their names instead of just "Fragment". BlueprintTracker: Currently broken. --- .../BetterScannerBlips.csproj | 14 ++--- .../BetterScannerBlips/Config.cs | 2 +- .../BetterScannerBlips/CustomBlip.cs | 49 ++-------------- SubnauticaModSystem/BetterScannerBlips/Mod.cs | 2 +- .../ResourceTrackerPatches.cs} | 44 ++++++++++---- .../BlueprintTracker/BlueprintTracker.csproj | 58 ++++++++----------- SubnauticaModSystem/BlueprintTracker/Mod.cs | 2 +- .../Properties/Resources.Designer.cs | 2 +- SubnauticaModSystem/Common/Mod/ModUtils.cs | 47 ++++----------- SubnauticaModSystem/GameDir.targets | 2 +- 10 files changed, 88 insertions(+), 134 deletions(-) rename SubnauticaModSystem/BetterScannerBlips/{ResourceTracker.cs => Patches/ResourceTrackerPatches.cs} (67%) diff --git a/SubnauticaModSystem/BetterScannerBlips/BetterScannerBlips.csproj b/SubnauticaModSystem/BetterScannerBlips/BetterScannerBlips.csproj index a70f27c..a9ad289 100644 --- a/SubnauticaModSystem/BetterScannerBlips/BetterScannerBlips.csproj +++ b/SubnauticaModSystem/BetterScannerBlips/BetterScannerBlips.csproj @@ -63,13 +63,13 @@ $(GameDir)\BepInEx\core\0Harmony.dll - - False - $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp.dll + + $(GameDir)\$(DataFolder)\Managed\publicized_assemblies\Assembly-CSharp-firstpass_publicized.dll + False - - False - $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp-firstpass.dll + + $(GameDir)\$(DataFolder)\Managed\publicized_assemblies\Assembly-CSharp_publicized.dll + False $(GameDir)\BepInEx\plugins\QModManager\QModInstaller.dll @@ -133,7 +133,7 @@ True Resources.resx - + diff --git a/SubnauticaModSystem/BetterScannerBlips/Config.cs b/SubnauticaModSystem/BetterScannerBlips/Config.cs index b9acd66..e5ffdd9 100644 --- a/SubnauticaModSystem/BetterScannerBlips/Config.cs +++ b/SubnauticaModSystem/BetterScannerBlips/Config.cs @@ -3,7 +3,7 @@ namespace BetterScannerBlips { [Serializable] - class Config + public class Config { public float MaxRange = 200.0f; public float MaxRangeScale = 0.2f; diff --git a/SubnauticaModSystem/BetterScannerBlips/CustomBlip.cs b/SubnauticaModSystem/BetterScannerBlips/CustomBlip.cs index 102228e..dbc48b5 100644 --- a/SubnauticaModSystem/BetterScannerBlips/CustomBlip.cs +++ b/SubnauticaModSystem/BetterScannerBlips/CustomBlip.cs @@ -1,4 +1,5 @@ -using Common.Utility; +using BetterScannerBlips.Patches; +using Common.Utility; using System; using System.Collections.Generic; using System.Linq; @@ -73,49 +74,11 @@ public void Refresh(ResourceTrackerDatabase.ResourceInfo target) var vectorToPlayer = Player.main.transform.position - target.position; var distance = vectorToPlayer.magnitude; - if(this.techType == TechType.None) - this.techType = target.techType; - if (this.techType == TechType.Fragment || string.IsNullOrEmpty(resourceName)) + if (techType != target.techType || target.techType == TechType.Fragment) { - /*blipId = gameObject.EnsureComponent(); - blipId.uniqueId = target.uniqueId;*/ - if (this.techType == TechType.Fragment) - { - /*thisTechType = blipId.actualTechType; - if (thisTechType == TechType.None || thisTechType == TechType.Fragment) - { - QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, - $"CustomBlip.Refresh(): Could not get TechType from BlipIdentifier, attempting to use ResourceTrackerPatches.GetTechTypeForId"); - thisTechType = ResourceTrackerPatches.GetTechTypeForId(target.uniqueId); - QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, - $"CustomBlip.Refresh(): Got TechType of {techType.AsString()}"); - }*/ - if (lastID != target.uniqueId) - { - /*QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, - $"CustomBlip.Refresh(): Last unique ID {lastID} does not match current unique ID {target.uniqueId}; Attempting to establish resourceName for ResourceInfo, which includes TechType {thisTechType}"); - */ - if (!ResourceTrackerPatches.TryGetResourceName(target.uniqueId, out resourceName)) - { - resourceName = Language.main.Get(this.techType); - lastID = target.uniqueId; - /*QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, - $"For unique ID {target.uniqueId}, got TechType {thisTechType.AsString()} and resourceName '{resourceName}'");*/ - } - } - } - - /*if (thisTechType != TechType.None && thisTechType != TechType.Fragment) - { - - techType = thisTechType; - resourceName = Language.main.Get(thisTechType); - lastID = target.uniqueId; - QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, - $"For unique ID {target.uniqueId}, got TechType {thisTechType.AsString()} and resourceName '{resourceName}'"); - }*/ - else - resourceName = Language.main.Get(target.techType); + techType = target.techType; + if(!ResourceTrackerPatches.TryGetResourceName(target.uniqueId, out resourceName)) + resourceName = Language.main.Get(techType); } RefreshColor(distance); diff --git a/SubnauticaModSystem/BetterScannerBlips/Mod.cs b/SubnauticaModSystem/BetterScannerBlips/Mod.cs index 49fd60b..94bc249 100644 --- a/SubnauticaModSystem/BetterScannerBlips/Mod.cs +++ b/SubnauticaModSystem/BetterScannerBlips/Mod.cs @@ -17,7 +17,7 @@ namespace BetterScannerBlips { - static class Mod + public static class Mod { public static Config config; diff --git a/SubnauticaModSystem/BetterScannerBlips/ResourceTracker.cs b/SubnauticaModSystem/BetterScannerBlips/Patches/ResourceTrackerPatches.cs similarity index 67% rename from SubnauticaModSystem/BetterScannerBlips/ResourceTracker.cs rename to SubnauticaModSystem/BetterScannerBlips/Patches/ResourceTrackerPatches.cs index 327c80a..c777950 100644 --- a/SubnauticaModSystem/BetterScannerBlips/ResourceTracker.cs +++ b/SubnauticaModSystem/BetterScannerBlips/Patches/ResourceTrackerPatches.cs @@ -1,4 +1,5 @@ -using HarmonyLib; +using QLogger = QModManager.Utility.Logger; +using HarmonyLib; using System; using System.Collections; using System.Collections.Generic; @@ -9,7 +10,8 @@ using UnityEngine; using UWE; -namespace BetterScannerBlips + +namespace BetterScannerBlips.Patches { [HarmonyPatch(typeof(ResourceTracker))] public class ResourceTrackerPatches @@ -20,29 +22,46 @@ public class ResourceTrackerPatches internal static readonly FieldInfo uniqueIdInfo = typeof(ResourceTracker).GetField("uniqueId", BindingFlags.Instance | BindingFlags.NonPublic); internal static readonly FieldInfo TechTypeInfo = typeof(ResourceTracker).GetField("techType", BindingFlags.Instance | BindingFlags.NonPublic); +/* + [HarmonyPatch(nameof(ResourceTracker.Start))] + [HarmonyPrefix] + public static bool PreStart(ref ResourceTracker __instance) + { + if (__instance.overrideTechType == TechType.Fragment) + { + __instance.overrideTechType = TechType.None; + } + + return true; + } +*/ + [HarmonyPatch("Register")] [HarmonyPrefix] public static void PreRegister(ref ResourceTracker __instance) { - TechType tt = (TechType)TechTypeInfo.GetValue(__instance); - if (tt == TechType.Fragment || __instance.overrideTechType == TechType.Fragment) // We only need to concern ourselves with fragments + GameObject go = __instance.gameObject; + TechType gameTechType = (go != null ? CraftData.GetTechType(go) : TechType.None); + //TechType tt = ((__instance.overrideTechType == TechType.None) ? gameTechType : __instance.overrideTechType); + if (gameTechType == TechType.Fragment || __instance.overrideTechType == TechType.Fragment) // We only need to concern ourselves with fragments { string uniqueId = __instance.prefabIdentifier.Id; - GameObject go = __instance.gameObject; - TechType resourceType = (go == null ? TechType.None : CraftData.GetTechType(go)); - //QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"ResourceTrackerPatches.PreRegister() running on ResourceTracker with unique ID {uniqueId}, overrideTechType {__instance.overrideTechType} and techType {resourceType}"); + QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Debug, $"ResourceTrackerPatches.PreRegister() running on ResourceTracker with unique ID {uniqueId}, overrideTechType {__instance.overrideTechType} and techType {gameTechType}"); if (!string.IsNullOrEmpty(uniqueId)) { + string resourceName = Language.main.Get(gameTechType); + QLogger.Log(QLogger.Level.Debug, $"Registering resource names for fragment:\nUnique ID: {uniqueId}\nTechType: {gameTechType.AsString()}\nResource name: {resourceName}"); IdToGameObjectDict[uniqueId] = __instance.gameObject; - IdToTechTypeDict[uniqueId] = resourceType; - IdToResourceNameDict[uniqueId] = Language.main.Get(resourceType); + IdToTechTypeDict[uniqueId] = gameTechType; + IdToResourceNameDict[uniqueId] = resourceName; } //__instance.overrideTechType = TechType.None; } } + /* [HarmonyPatch("Register")] [HarmonyPostfix] public static void PostRegister(ref ResourceTracker __instance) @@ -70,6 +89,7 @@ public static void PostRegister(ref ResourceTracker __instance) //if((TechType)TechTypeInfo.GetValue(__instance) == TechType.Fragment) //CoroutineHost.StartCoroutine(RegisterResourceTrackerCoroutine(__instance)); } + */ [HarmonyPatch("Unregister")] [HarmonyPostfix] @@ -105,7 +125,11 @@ public static TechType GetTechTypeForId(string uniqueId) public static bool TryGetResourceName(string uniqueId, out string resourceName) { - return IdToResourceNameDict.TryGetValue(uniqueId, out resourceName); + bool result = IdToResourceNameDict.TryGetValue(uniqueId, out resourceName); + + QLogger.Log(QLogger.Level.Debug, $"Attempting to retrieve resource name for unique ID '{uniqueId}': Result is {result}" + (result ? $", retrieved string '{resourceName}'" : "")); + + return result; } } } diff --git a/SubnauticaModSystem/BlueprintTracker/BlueprintTracker.csproj b/SubnauticaModSystem/BlueprintTracker/BlueprintTracker.csproj index 17f5b12..401e6d0 100644 --- a/SubnauticaModSystem/BlueprintTracker/BlueprintTracker.csproj +++ b/SubnauticaModSystem/BlueprintTracker/BlueprintTracker.csproj @@ -15,28 +15,6 @@ 512 - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - - - Always - BZ;BELOWZERO true @@ -59,19 +37,26 @@ 7.1 prompt + + Always + $(GameDir)\BepInEx\core\0Harmony.dll - - False - $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp.dll + + $(GameDir)\$(DataFolder)\Managed\publicized_assemblies\Assembly-CSharp-firstpass_publicized.dll + False - - False - $(GameDir)\$(DataFolder)\Managed\Assembly-CSharp-firstpass.dll + + $(GameDir)\$(DataFolder)\Managed\publicized_assemblies\Assembly-CSharp_publicized.dll + False - + + $(GameDir)\BepInEx\plugins\QModManager\QModInstaller.dll + + + False $(GameDir)\$(DataFolder)\Managed\NewtonSoft.Json.dll @@ -92,6 +77,9 @@ $(GameDir)\$(DataFolder)\Managed\UnityEngine.ImageConversionModule.dll + + $(GameDir)\$(DataFolder)\Managed\UnityEngine.InputLegacyModule.dll + $(GameDir)\$(DataFolder)\Managed\UnityEngine.JSONSerializeModule.dll @@ -107,6 +95,10 @@ $(GameDir)\$(DataFolder)\Managed\UnityEngine.UIModule.dll + + $(GameDir)\$(DataFolder)\Managed\Unity.TextMeshPro.dll + False + @@ -142,12 +134,12 @@ - xcopy $(TargetPath) $(GameDir)\QMods\BlueprintTracker\ /q /y -xcopy $(ProjectDir)mod.json $(GameDir)\QMods\BlueprintTracker\ /q /y -xcopy $(ProjectDir)Assets $(GameDir)\QMods\BlueprintTracker\Assets\ /q /y + xcopy $(TargetPath) D:\SteamLibrary\steamapps\common\Subnautica\QMods\BlueprintTracker\ /q /y +xcopy $(ProjectDir)mod.json D:\SteamLibrary\steamapps\common\Subnautica\QMods\BlueprintTracker\ /q /y +xcopy $(ProjectDir)Assets D:\SteamLibrary\steamapps\common\Subnautica\QMods\BlueprintTracker\Assets\ /q /y xcopy $(TargetPath) D:\EpicGames\Subnautica\QMods\BlueprintTracker\ /q /y xcopy $(ProjectDir)mod.json D:\EpicGames\Subnautica\QMods\BlueprintTracker\ /q /y xcopy $(ProjectDir)Assets D:\EpicGames\Subnautica\QMods\BlueprintTracker\Assets\ /q /y - + \ No newline at end of file diff --git a/SubnauticaModSystem/BlueprintTracker/Mod.cs b/SubnauticaModSystem/BlueprintTracker/Mod.cs index ac6d8f6..1c61ab4 100644 --- a/SubnauticaModSystem/BlueprintTracker/Mod.cs +++ b/SubnauticaModSystem/BlueprintTracker/Mod.cs @@ -27,7 +27,7 @@ public static void Patch(string modDirectory = null) Mod.modDirectory = modDirectory ?? "Subnautica_Data/Managed"; LoadConfig(); - HarmonyInstance harmony = HarmonyInstance.Create("com.blueprinttracker.mod"); + var harmony = new Harmony("com.blueprinttracker.mod"); harmony.PatchAll(Assembly.GetExecutingAssembly()); Logger.Log("Patched"); diff --git a/SubnauticaModSystem/BlueprintTracker/Properties/Resources.Designer.cs b/SubnauticaModSystem/BlueprintTracker/Properties/Resources.Designer.cs index eb50062..6dfc5d6 100644 --- a/SubnauticaModSystem/BlueprintTracker/Properties/Resources.Designer.cs +++ b/SubnauticaModSystem/BlueprintTracker/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace BlueprintTracker.Properties { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { diff --git a/SubnauticaModSystem/Common/Mod/ModUtils.cs b/SubnauticaModSystem/Common/Mod/ModUtils.cs index 7379b58..ad851b2 100644 --- a/SubnauticaModSystem/Common/Mod/ModUtils.cs +++ b/SubnauticaModSystem/Common/Mod/ModUtils.cs @@ -5,12 +5,7 @@ using System.Linq; using System.Reflection; using System.Text; -#if SN1 using Oculus.Newtonsoft.Json; -#elif BELOWZERO -using Newtonsoft.Json; -using TMPro; -#endif using UnityEngine; using UnityEngine.UI; @@ -27,7 +22,6 @@ internal static class ModUtils { if (!File.Exists(configFilePath)) { - QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Error, $"Could not find config file {configFilePath}", null, true); return WriteDefaultConfig(configFilePath); } @@ -37,7 +31,6 @@ internal static class ModUtils if (string.IsNullOrEmpty(serialilzedConfig)) { - QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Error, $"Config file {configFilePath} empty; creating default config", null, true); return new ConfigT(); } @@ -45,15 +38,13 @@ internal static class ModUtils if (config == null) { - QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Error, $"Failed to deserialise configuration object from file {configFilePath}", null, true); config = new ConfigT(); } return config; } - catch (Exception e) + catch { - QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Error, $"Exception caught while parsing config file {configFilePath}", e, true); return WriteDefaultConfig(configFilePath); } } @@ -73,16 +64,13 @@ public static void ValidateConfigValue(string field, T min, T max, r var value = (T)fieldInfo.GetValue(config, null); if (value.CompareTo(min) < 0 || value.CompareTo(max) > 0) { - string errorString = $"Config value for '{field}' ({value}) was not valid. Must be between {min} and {max}"; - //Console.WriteLine(string); - QModManager.Utility.Logger.Log(QModManager.Utility.Logger.Level.Error, errorString, null, true); - var newValue = value; - if (value.CompareTo(min) < 0) - newValue = min; - else if (value.CompareTo(max) > 0) - newValue = max; - //fieldInfo.SetValue(config, fieldInfo.GetValue(defaultConfig, null), null); - fieldInfo.SetValue(config, newValue, null); + Console.WriteLine("Config value for '{0}' ({1}) was not valid. Must be between {2} and {3}", + field, + value, + min, + max + ); + fieldInfo.SetValue(config, fieldInfo.GetValue(defaultConfig, null), null); } } @@ -226,33 +214,20 @@ public static void PrintObjectFields(object obj, string indent = "") } } -#if SN1 public static Text GetTextPrefab() { - Text prefab = null; - prefab = GameObject.FindObjectOfType().interactPrimaryText; -#elif BELOWZERO - public static TextMeshProUGUI GetTextPrefab() - { - TextMeshProUGUI prefab = GameObject.FindObjectOfType().progressText; -#endif - /*if (prefab == null) + Text prefab = GameObject.FindObjectOfType().interactPrimaryText; + if (prefab == null) { return null; - }*/ + } return prefab; } -#if SN1 public static Text InstantiateNewText(string name, Transform parent) { Text text = GameObject.Instantiate(GetTextPrefab()); -#elif BZ - public static TextMeshProUGUI InstantiateNewText(string name, Transform parent) - { - TextMeshProUGUI text = GameObject.Instantiate(GetTextPrefab()); -#endif text.gameObject.layer = parent.gameObject.layer; text.gameObject.name = name; text.transform.SetParent(parent, false); diff --git a/SubnauticaModSystem/GameDir.targets b/SubnauticaModSystem/GameDir.targets index 112228b..abcff26 100644 --- a/SubnauticaModSystem/GameDir.targets +++ b/SubnauticaModSystem/GameDir.targets @@ -2,7 +2,7 @@ - S:\Steam\steamapps\common\ + C:\Steam\steamapps\common\ $(CommonDir)\Subnautica\ $(CommonDir)\SubnauticaZero\