diff --git a/.claude/settings.local.json b/.claude/settings.local.json
new file mode 100644
index 00000000..d77823d8
--- /dev/null
+++ b/.claude/settings.local.json
@@ -0,0 +1,9 @@
+{
+ "permissions": {
+ "allow": [
+ "Bash(du -sh /c/Users/mrcook1e/Desktop/Auga/.claude/worktrees/flamboyant-kepler/Auga/*.zip)",
+ "Bash(ls /c/Users/mrcook1e/Desktop/Auga/.claude/worktrees/flamboyant-kepler/Auga/*.json)",
+ "Bash(xargs ls:*)"
+ ]
+ }
+}
diff --git a/Auga/API.Common.cs b/Auga/API.Common.cs
index 29e24fe1..1c339547 100644
--- a/Auga/API.Common.cs
+++ b/Auga/API.Common.cs
@@ -1,5 +1,4 @@
-using Fishlabs;
-using TMPro;
+using TMPro;
using UnityEngine;
using UnityEngine.UI;
@@ -37,7 +36,7 @@ public class CraftingControls
public TMP_Text CraftAmountText;
public GameObject CraftAmountBG;
public GameObject Amount;
- public GuiInputField InputAmount;
+ public TMP_InputField InputAmount;
public TMP_Text InputText;
}
}
diff --git a/Auga/Auga-1.1.1-TS.zip b/Auga/Auga-1.1.1-TS.zip
deleted file mode 100644
index 63c5f0e8..00000000
Binary files a/Auga/Auga-1.1.1-TS.zip and /dev/null differ
diff --git a/Auga/Auga-1.1.1.zip b/Auga/Auga-1.1.1.zip
deleted file mode 100644
index d7d4ada2..00000000
Binary files a/Auga/Auga-1.1.1.zip and /dev/null differ
diff --git a/Auga/Auga-1.1.2-TS.zip b/Auga/Auga-1.1.2-TS.zip
deleted file mode 100644
index c129cd7c..00000000
Binary files a/Auga/Auga-1.1.2-TS.zip and /dev/null differ
diff --git a/Auga/Auga-1.1.2.zip b/Auga/Auga-1.1.2.zip
deleted file mode 100644
index 1bbc587b..00000000
Binary files a/Auga/Auga-1.1.2.zip and /dev/null differ
diff --git a/Auga/Auga-1.1.3-TS.zip b/Auga/Auga-1.1.3-TS.zip
deleted file mode 100644
index 23fdf74f..00000000
Binary files a/Auga/Auga-1.1.3-TS.zip and /dev/null differ
diff --git a/Auga/Auga-1.1.3.zip b/Auga/Auga-1.1.3.zip
deleted file mode 100644
index 62613588..00000000
Binary files a/Auga/Auga-1.1.3.zip and /dev/null differ
diff --git a/Auga/Auga.cs b/Auga/Auga.cs
index 9d2df31f..967fd1f0 100644
--- a/Auga/Auga.cs
+++ b/Auga/Auga.cs
@@ -125,6 +125,7 @@ public enum StatBarTextPosition { Off = -1, Above, Below, Center, Start, End };
public static bool HasSimpleRecycling;
public static bool HasChatter;
public static bool HasSearsCatalog;
+ public static bool HasJewelcrafting;
private static Auga _instance;
private Harmony _harmony;
@@ -135,6 +136,27 @@ public enum StatBarTextPosition { Off = -1, Above, Below, Center, Start, End };
public static Auga instance => _instance;
+ // Статический конструктор — регистрируем AssemblyResolve до того как CLR
+ // попытается разрешить APIManager/fastJSON/Unity.Auga при загрузке типа.
+ static Auga()
+ {
+ AppDomain.CurrentDomain.AssemblyResolve += ResolveEmbeddedAssembly;
+ }
+
+ private static Assembly ResolveEmbeddedAssembly(object sender, ResolveEventArgs args)
+ {
+ var shortName = new AssemblyName(args.Name).Name + ".dll";
+ var resourceName = $"Auga.{shortName}";
+ var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
+ if (stream == null) return null;
+ using (stream)
+ {
+ var data = new byte[stream.Length];
+ stream.Read(data, 0, data.Length);
+ return Assembly.Load(data);
+ }
+ }
+
public void Awake()
{
_instance = this;
@@ -147,20 +169,8 @@ public void Awake()
Debug.LogWarning($"Project Auga - Version {Assembly.GetExecutingAssembly().GetName().Version}");
Debug.LogWarning($"Valheim - Version {(global::Version.GetVersionString())}");
- if ((global::Version.CurrentVersion.m_minor == 217 && global::Version.CurrentVersion.m_patch >= 27 ) || global::Version.CurrentVersion.m_minor > 217)
- {
- Debug.LogWarning($"GAME VERSION CHECK - PASSED");
- Debug.LogWarning($"==============================================================================");
- }
- else
- {
- Debug.LogError($">>>>>>>>> GAME VERSION MISMATCH - EXITING <<<<<<<<");
- Debug.LogWarning($"==============================================================================");
- Thread.Sleep(10000);
-
- Destroy(this);
- return;
- }
+ // Version gate removed — PTB check is no longer needed for current Valheim.
+ Debug.LogWarning($"==============================================================================");
}
}
@@ -175,8 +185,9 @@ public void Awake()
HasBetterTrader = Chainloader.PluginInfos.ContainsKey("Menthus.bepinex.plugins.BetterTrader");
HasMultiCraft = Chainloader.PluginInfos.TryGetValue("maximods.valheim.multicraft", out var multiCraftPlugin);
HasSimpleRecycling = Chainloader.PluginInfos.TryGetValue("com.github.abearcodes.valheim.simplerecycling", out var recyclingPlugin);
- HasChatter = Chainloader.PluginInfos.ContainsKey("redseiko.valheim.chatter");
- HasSearsCatalog = Chainloader.PluginInfos.ContainsKey("redseiko.valheim.searscatalog");
+ HasChatter = Chainloader.PluginInfos.TryGetValue("redseiko.valheim.chatter", out var chatterPlugin);
+ HasSearsCatalog = Chainloader.PluginInfos.TryGetValue("redseiko.valheim.searscatalog", out var searsPlugin);
+ HasJewelcrafting = Chainloader.PluginInfos.TryGetValue("org.bepinex.plugins.jewelcrafting", out var jewelcraftingPlugin);
_harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), PluginID);
@@ -437,6 +448,7 @@ public void OnDestroy()
private void LoadDependencies()
{
var assembly = Assembly.GetCallingAssembly();
+ LoadEmbeddedAssembly(assembly, "APIManager.dll");
LoadEmbeddedAssembly(assembly, "fastJSON.dll");
LoadEmbeddedAssembly(assembly, "Unity.Auga.dll");
}
diff --git a/Auga/Auga.csproj b/Auga/Auga.csproj
index bddd1bc1..e41d950b 100644
--- a/Auga/Auga.csproj
+++ b/Auga/Auga.csproj
@@ -1,227 +1,218 @@
-
-
-
+
+
+
+
+
- Debug
- AnyCPU
- {BCC7DD31-D943-4684-800E-176A97DDDB8F}
- Library
- Properties
- Auga
+ net472
Auga
- v4.7.2
- 512
- true
-
-
+ Auga
+ Library
+ true
10
+ true
+ disable
+
+ false
+ {BCC7DD31-D943-4684-800E-176A97DDDB8F}
+
+
+
+
+ AugaAPI
+ API;TRACE
+ false
+ pdbonly
-
+
+
true
full
false
- bin\Debug\
DEBUG;TRACE
- prompt
- 4
- true
-
+
+
pdbonly
true
- bin\Release\
TRACE
- prompt
- 4
- true
-
-
- v4.7.2
- AugaAPI
- true
- full
- bin\API\
- API;TRACE
- false
- pdbonly
- AnyCPU
- prompt
- true
+
+
+
+
+
+
+
+
- M:\Code\VapokModBase\References\BepInEx\5.4.2201\BepInEx\core\0Harmony.dll
-
-
- ..\..\VapokModBase\References\APIManager\APIManager.dll
-
-
- False
- M:\Code\VapokModBase\References\Valheim\0.217.30\assembly_guiutils_publicized.dll
-
-
- False
- M:\Code\VapokModBase\References\Valheim\0.217.30\ui_lib_publicized.dll
-
-
- False
- M:\Code\VapokModBase\References\Valheim\0.217.30\ui_lib_publicized.dll
-
-
- False
- M:\Code\VapokModBase\References\Valheim\0.217.30\ui_lib_publicized.dll
-
-
- M:\Code\VapokModBase\References\Valheim\0.217.30\assembly_steamworks_publicized.dll
-
-
- False
- M:\Code\VapokModBase\References\Valheim\0.217.30\assembly_utils_publicized.dll
-
-
- False
- M:\Code\VapokModBase\References\Valheim\0.217.30\assembly_valheim_publicized.dll
+ $(BepInExCoreDir)\0Harmony.dll
+ false
- M:\Code\VapokModBase\References\BepInEx\5.4.2201\BepInEx\core\BepInEx.dll
-
-
- ..\Libs\fastJSON.dll
+ $(BepInExCoreDir)\BepInEx.dll
+ false
-
-
-
-
-
-
-
-
+
+
+
+ ..\Libs\APIManager.dll
+ true
+
+
+
+
+ $(ValheimManagedDir)\assembly_guiutils.dll
+ true
+ false
+
+
+ $(ValheimManagedDir)\com.rlabrecque.steamworks.net.dll
+ false
+
+
+ $(ValheimManagedDir)\assembly_utils.dll
+ true
+ false
+
+
+ $(ValheimManagedDir)\assembly_valheim.dll
+ true
+ false
+
+
+ $(ValheimManagedDir)\gui_framework.dll
+ true
+ false
+
+
+
- M:\Code\VapokModBase\References\BepInEx\5.4.2201\unstripped_corlib\UnityEngine.dll
+ $(ValheimManagedDir)\UnityEngine.dll
+ false
-
- False
- M:\Code\VapokModBase\References\BepInEx\5.4.2201\unstripped_corlib\UnityEngine.AnimationModule.dll
+
+ $(ValheimManagedDir)\UnityEngine.AnimationModule.dll
+ false
-
- False
- M:\Code\VapokModBase\References\BepInEx\5.4.2201\unstripped_corlib\UnityEngine.AssetBundleModule.dll
+
+ $(ValheimManagedDir)\UnityEngine.AssetBundleModule.dll
+ false
-
- False
- M:\Code\VapokModBase\References\BepInEx\5.4.2201\unstripped_corlib\UnityEngine.AudioModule.dll
+
+ $(ValheimManagedDir)\UnityEngine.AudioModule.dll
+ false
- M:\Code\VapokModBase\References\BepInEx\5.4.2201\unstripped_corlib\UnityEngine.CoreModule.dll
+ $(ValheimManagedDir)\UnityEngine.CoreModule.dll
+ false
-
- M:\Code\VapokModBase\References\BepInEx\5.4.2201\unstripped_corlib\UnityEngine.ImageConversionModule.dll
-
-
- False
- M:\Code\VapokModBase\References\BepInEx\5.4.2201\unstripped_corlib\UnityEngine.InputLegacyModule.dll
+
+ $(ValheimManagedDir)\UnityEngine.InputLegacyModule.dll
+ false
- M:\Code\VapokModBase\References\BepInEx\5.4.2201\unstripped_corlib\UnityEngine.TextRenderingModule.dll
+ $(ValheimManagedDir)\UnityEngine.TextRenderingModule.dll
+ false
- M:\Code\VapokModBase\References\BepInEx\5.4.2201\unstripped_corlib\UnityEngine.UI.dll
+ $(ValheimManagedDir)\UnityEngine.UI.dll
+ false
-
- False
- M:\Code\VapokModBase\References\BepInEx\5.4.2201\unstripped_corlib\UnityEngine.UIModule.dll
+
+ $(ValheimManagedDir)\UnityEngine.UIModule.dll
+ false
- M:\Code\VapokModBase\References\BepInEx\5.4.2201\unstripped_corlib\Unity.TextMeshPro.dll
+ $(ValheimManagedDir)\Unity.TextMeshPro.dll
+ false
+
+
+
+
+ ..\Libs\fastJSON.dll
+ true
+
+
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
augaassets
-
-
-
+
Unity.Auga.dll
-
-
-
- {5b19eb03-f699-46bc-afaf-2a2e78e1f6c5}
- AugaUnityLib
-
-
-
fastJSON.dll
-
-
-
-
+
APIManager.dll
-
- CHANGELOG.md
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
- xcopy "$(ProjectDir)translations.json" "G:\Steam\steamapps\common\Valheim-Dev\BepInEx\plugins\$(ProjectName)\" /q /y /i
-
-
-
-
-
- This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105.The missing file is {0}.
-
-
+
+
+
+
-
\ No newline at end of file
+
+
diff --git a/Auga/Auga1.1-RC.zip b/Auga/Auga1.1-RC.zip
deleted file mode 100644
index 90eedae9..00000000
Binary files a/Auga/Auga1.1-RC.zip and /dev/null differ
diff --git a/Auga/AugaAPI.zip b/Auga/AugaAPI.zip
deleted file mode 100644
index 3b0ecbaf..00000000
Binary files a/Auga/AugaAPI.zip and /dev/null differ
diff --git a/Auga/AugaAPI1.1.zip b/Auga/AugaAPI1.1.zip
deleted file mode 100644
index c2a56494..00000000
Binary files a/Auga/AugaAPI1.1.zip and /dev/null differ
diff --git a/Auga/AugaGithub.jpg b/Auga/AugaGithub.jpg
deleted file mode 100644
index fcee8ce0..00000000
Binary files a/Auga/AugaGithub.jpg and /dev/null differ
diff --git a/Auga/AugaLog_Hooks.cs b/Auga/AugaLog_Hooks.cs
index 0d2a7a33..986c7538 100644
--- a/Auga/AugaLog_Hooks.cs
+++ b/Auga/AugaLog_Hooks.cs
@@ -10,10 +10,8 @@ public static class AugaLog_Hooks
{
public static void Postfix(Game __instance)
{
- if (Player.m_localPlayer.m_firstSpawn)
- {
- AugaMessageLog.instance.AddArrivalLog(Player.m_localPlayer);
- }
+ // m_firstSpawn was removed in current Valheim; always log arrival on spawn
+ AugaMessageLog.instance.AddArrivalLog(Player.m_localPlayer);
}
}
diff --git a/Auga/AugaMistlandsBeta-Recycling.zip b/Auga/AugaMistlandsBeta-Recycling.zip
deleted file mode 100644
index 000fe8b6..00000000
Binary files a/Auga/AugaMistlandsBeta-Recycling.zip and /dev/null differ
diff --git a/Auga/AugaMistlandsBeta.zip b/Auga/AugaMistlandsBeta.zip
deleted file mode 100644
index db9e4b53..00000000
Binary files a/Auga/AugaMistlandsBeta.zip and /dev/null differ
diff --git a/Auga/AugaNexus.zip b/Auga/AugaNexus.zip
deleted file mode 100644
index a2aeb905..00000000
Binary files a/Auga/AugaNexus.zip and /dev/null differ
diff --git a/Auga/AugaNexus1.1.zip b/Auga/AugaNexus1.1.zip
deleted file mode 100644
index 5d63d73c..00000000
Binary files a/Auga/AugaNexus1.1.zip and /dev/null differ
diff --git a/Auga/AugaSettings_Controller.cs b/Auga/AugaSettings_Controller.cs
new file mode 100644
index 00000000..07919469
--- /dev/null
+++ b/Auga/AugaSettings_Controller.cs
@@ -0,0 +1,521 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using HarmonyLib;
+using UnityEngine;
+using UnityEngine.UI;
+
+namespace Auga
+{
+ // ============================================================
+ // AugaSettings_Controller.cs — "buffer on change, apply on OK"
+ //
+ // Wire(): читает PlatformPrefs → устанавливает контролы
+ // Pend(): onChange → _pending[key] = Action (НЕ в PlatformPrefs)
+ // Commit(): Settings.OnOk Prefix → применяет _pending → PlatformPrefs
+ // → GraphicsSettingsManager.ApplyStartupSettings()
+ //
+ // Исправления v3 (по данным из Unity MCP + prefab YAML):
+ // • WireSlider: ищет TMP ValueLabel по имени (не последний TMP_Text)
+ // → нет порчи лейбла на Controls-слайдерах (LabeledSlider без ValueLabel)
+ // • WireSlider: Func formatValue для кастомного отображения
+ // • SetupKeyBindings: AutomaticKeyName = GO.name → бинды перестают показывать "W"
+ // • PlatformPrefs keys исправлены по деcompile Valheim 0.221:
+ // LodBias (не LoD), FPSLimit (не TargetFrameRate), SSAO/SSAO_2
+ // • Dropdown: TMP Label caption обновляется вручную (legacy Dropdown
+ // не может обновить TMPro.TextMeshProUGUI через m_CaptionText)
+ // • GuiScale: slider range 50-115, display = slider.value + "%",
+ // store = v/100f в PlatformPrefs
+ // • Autobackups: slider range 1-10, display = count integer
+ // • FramerateLimit: range 0-360, display = fps number / "∞"
+ // • Graphics quality sliders: прямые int-значения (0-2 или 0-3)
+ // • Commit вызывает GraphicsSettingsManager.ApplyStartupSettings()
+ // ============================================================
+
+ [HarmonyPatch(typeof(Settings), nameof(Settings.Awake))]
+ public static class Settings_Awake_Init_Patch
+ {
+ public static void Postfix(Settings __instance)
+ {
+ try { AugaSettingsWirer.Wire(__instance.gameObject); }
+ catch (Exception ex) { Auga.LogWarning($"[AugaSettings] Wire() exception: {ex.Message}"); }
+ }
+ }
+
+ [HarmonyPatch(typeof(Settings), nameof(Settings.OnOk))]
+ public static class Settings_Awake_OnOk_Commit_Patch
+ {
+ public static void Prefix()
+ {
+ try { AugaSettingsWirer.Commit(); }
+ catch (Exception ex) { Auga.LogWarning($"[AugaSettings] Commit() exception: {ex.Message}"); }
+ }
+ }
+
+ public static class AugaSettingsWirer
+ {
+ private static readonly Dictionary _pending = new Dictionary();
+
+ private static readonly MethodInfo s_applyStartupSettings =
+ typeof(GraphicsSettingsManager).GetMethod(
+ "ApplyStartupSettings",
+ BindingFlags.Instance | BindingFlags.NonPublic);
+
+ private static void Pend(string key, Action applyAction)
+ {
+ _pending[key] = applyAction;
+ }
+
+ public static void Commit()
+ {
+ foreach (var kv in _pending)
+ {
+ try { kv.Value?.Invoke(); }
+ catch (Exception ex) { Auga.LogWarning($"[AugaSettings] Commit '{kv.Key}': {ex.Message}"); }
+ }
+ _pending.Clear();
+
+ // Re-apply graphics from PlatformPrefs (loads + fires GraphicsSettingsChanged)
+ try
+ {
+ var mgr = GraphicsSettingsManager.Instance;
+ if (mgr != null)
+ s_applyStartupSettings?.Invoke(mgr, null);
+ }
+ catch (Exception ex) { Auga.LogWarning($"[AugaSettings] GraphicsApply: {ex.Message}"); }
+
+ Auga.Log("[AugaSettings] Commit done");
+ }
+
+ public static void Wire(GameObject settingsRoot)
+ {
+ _pending.Clear();
+
+ var tabHandler = settingsRoot.GetComponentInChildren(true);
+ if (tabHandler == null)
+ {
+ Auga.LogWarning("[AugaSettings] TabHandler not found");
+ return;
+ }
+
+ Auga.Log($"[AugaSettings] Wire: {tabHandler.m_tabs.Count} tabs");
+
+ int wired = 0;
+ for (int i = 0; i < tabHandler.m_tabs.Count; i++)
+ {
+ var tab = tabHandler.m_tabs[i];
+ if (tab.m_page == null) continue;
+ var page = tab.m_page;
+ string pageName = page.gameObject.name;
+
+ switch (pageName)
+ {
+ case "Audio": WireAudio(page); wired++; break;
+ case "Controls": WireControls(page); wired++; break;
+ case "Graphics": WireGraphics(page); wired++; break;
+ case "Misc": WireMisc(page); wired++; break;
+ default:
+ Auga.LogWarning($"[AugaSettings] Unknown tab '{pageName}' at [{i}], using index fallback");
+ switch (i)
+ {
+ case 0: WireControls(page); wired++; break;
+ case 1: WireAudio(page); wired++; break;
+ case 2: WireGraphics(page); wired++; break;
+ case 3: WireMisc(page); wired++; break;
+ }
+ break;
+ }
+ }
+ Auga.Log($"[AugaSettings] Wired {wired}/{tabHandler.m_tabs.Count} tabs");
+ }
+
+ // ===================== Audio =====================
+ private static void WireAudio(Transform page)
+ {
+ WireSlider(page, "MasterVolume",
+ read: () => PlatformPrefs.GetFloat("MasterVolume", AudioListener.volume),
+ pend: v => Pend("MasterVolume", () => { AudioListener.volume = v; PlatformPrefs.SetFloat("MasterVolume", v); }),
+ immediateApply: v => AudioListener.volume = v);
+
+ WireSlider(page, "EffectVolume",
+ read: () => PlatformPrefs.GetFloat("SfxVolume", 1f),
+ pend: v => Pend("SfxVolume", () => { AudioMan.SetSFXVolume(v); PlatformPrefs.SetFloat("SfxVolume", v); }),
+ immediateApply: v => AudioMan.SetSFXVolume(v));
+
+ WireSlider(page, "MusicVolume",
+ read: () => PlatformPrefs.GetFloat("MusicVolume", 1f),
+ pend: v => Pend("MusicVolume", () => { MusicMan.m_masterMusicVolume = v; PlatformPrefs.SetFloat("MusicVolume", v); }),
+ immediateApply: v => MusicMan.m_masterMusicVolume = v);
+
+ WireToggle(page, "ContinuousMusic",
+ read: () => PlatformPrefs.GetBool("ContinousMusic", true),
+ pend: v => Pend("ContinousMusic", () => { Settings.ContinousMusic = v; PlatformPrefs.SetBool("ContinousMusic", v); }));
+ }
+
+ // ===================== Controls =====================
+ private static void WireControls(Transform page)
+ {
+ // LabeledSlider — нет TMP ValueLabel → formatValue не нужен
+ WireSlider(page, "MouseSensitivity",
+ read: () => PlatformPrefs.GetFloat("MouseSensitivity", PlayerController.m_mouseSens),
+ pend: v => Pend("MouseSensitivity", () => { PlayerController.m_mouseSens = v; PlatformPrefs.SetFloat("MouseSensitivity", v); }),
+ immediateApply: v => PlayerController.m_mouseSens = v);
+
+ WireSlider(page, "GamepadSensitivity",
+ read: () => PlatformPrefs.GetFloat("GamepadSensitivity", PlayerController.m_gamepadSens),
+ pend: v => Pend("GamepadSensitivity", () => { PlayerController.m_gamepadSens = v; PlatformPrefs.SetFloat("GamepadSensitivity", v); }),
+ immediateApply: v => PlayerController.m_gamepadSens = v);
+
+ WireToggle(page, "InvertMouse",
+ read: () => PlatformPrefs.GetBool("InvertMouse"),
+ pend: v => Pend("InvertMouse", () => { PlayerController.m_invertMouse = v; PlatformPrefs.SetBool("InvertMouse", v); }));
+
+ WireToggle(page, "ToggleAutoRun",
+ read: () => PlatformPrefs.GetInt("ToggleRun", ZInput.IsGamepadActive() ? 1 : 0) == 1,
+ pend: v => Pend("ToggleRun", () => { ZInput.ToggleRun = v; PlatformPrefs.SetInt("ToggleRun", v ? 1 : 0); }));
+
+ WireToggle(page, "GamepadEnabled",
+ read: () => ZInput.IsGamepadEnabled(),
+ pend: v => Pend("GamepadEnabled", () => ZInput.SetGamepadEnabled(v)));
+
+ WireToggle(page, "AlternativeGlyphs",
+ read: () => PlatformPrefs.GetInt("AltGlyphs") == 1,
+ pend: v => Pend("AltGlyphs", () => PlatformPrefs.SetInt("AltGlyphs", v ? 1 : 0)));
+
+ WireToggle(page, "SwapTriggers",
+ read: () => ZInput.SwapTriggers,
+ pend: v => Pend("SwapTriggers", () => { ZInput.SwapTriggers = v; PlatformPrefs.SetInt("SwapTriggers", v ? 1 : 0); }));
+
+ // Устанавливаем AutomaticKeyName = GO-имя на каждом AugaBindingDisplay
+ // (поле пустое в префабе; GO-имя совпадает с именем кнопки в ZInput)
+ SetupKeyBindings(page);
+ }
+
+ private static void SetupKeyBindings(Transform page)
+ {
+ var root = FindDeepChild(page, "KeyBindings");
+ if (root == null)
+ {
+ Auga.LogWarning("[AugaSettings] 'KeyBindings' GO not found in Controls page");
+ return;
+ }
+ var displays = root.GetComponentsInChildren(true);
+ Auga.Log($"[AugaSettings] Setting AutomaticKeyName on {displays.Length} binding displays");
+ foreach (var d in displays)
+ {
+ if (string.IsNullOrEmpty(d.AutomaticKeyName))
+ d.AutomaticKeyName = d.gameObject.name;
+ }
+ }
+
+ // ===================== Graphics =====================
+ private static void WireGraphics(Transform page)
+ {
+ // --- Toggles (SecondColumnWidgets) ---
+ WireToggle(page, "Bloom", () => PlatformPrefs.GetBool("Bloom", true), v => Pend("Bloom", () => PlatformPrefs.SetBool("Bloom", v)));
+ WireToggle(page, "SSAO", () => PlatformPrefs.GetBool("SSAO", true), v => Pend("SSAO", () => { PlatformPrefs.SetBool("SSAO", v); PlatformPrefs.SetInt("SSAO_2", -1); }));
+ WireToggle(page, "SunShafts", () => PlatformPrefs.GetBool("SunShafts", true), v => Pend("SunShafts", () => PlatformPrefs.SetBool("SunShafts", v)));
+ WireToggle(page, "MotionBlur", () => PlatformPrefs.GetBool("MotionBlur"), v => Pend("MotionBlur", () => PlatformPrefs.SetBool("MotionBlur", v)));
+ WireToggle(page, "Tessellation", () => PlatformPrefs.GetBool("Tesselation", true), v => Pend("Tesselation", () => PlatformPrefs.SetBool("Tesselation", v)));
+ WireToggle(page, "DistantShadows", () => PlatformPrefs.GetBool("DistantShadows", true), v => Pend("DistantShadows", () => PlatformPrefs.SetBool("DistantShadows", v)));
+ WireToggle(page, "SoftParticles", () => PlatformPrefs.GetBool("SoftPart", true), v => Pend("SoftPart", () => PlatformPrefs.SetBool("SoftPart", v)));
+ WireToggle(page, "DepthOfField", () => PlatformPrefs.GetBool("DOF", true), v => Pend("DOF", () => PlatformPrefs.SetBool("DOF", v)));
+ WireToggle(page, "AntiAliasing", () => PlatformPrefs.GetBool("AntiAliasing", true), v => Pend("AntiAliasing", () => PlatformPrefs.SetBool("AntiAliasing", v)));
+ WireToggle(page, "ChromaticAbberation", () => PlatformPrefs.GetBool("ChromaticAberration"), v => Pend("ChromaticAberration",() => PlatformPrefs.SetBool("ChromaticAberration", v)));
+ WireToggle(page, "VSYNC", () => PlatformPrefs.GetBool("VSync"), v => Pend("VSync", () => { QualitySettings.vSyncCount = v ? 1 : 0; PlatformPrefs.SetBool("VSync", v); }));
+ WireToggle(page, "Fullscreen", () => Screen.fullScreen, v => Pend("Fullscreen", () => Screen.fullScreen = v));
+
+ // --- Quality Sliders (FirstColumnWidgets) — LabeledSliderWithValue, имеют TMP ValueLabel ---
+ // Slider value = PlatformPrefs int напрямую (диапазоны взяты из prefab YAML)
+
+ // Vegitation: ClutterQuality, slider 0-3
+ WireSlider(page, "Vegitation",
+ read: () => PlatformPrefs.GetInt("ClutterQuality", 2),
+ pend: v => Pend("ClutterQuality", () => PlatformPrefs.SetInt("ClutterQuality", Mathf.RoundToInt(v))),
+ formatValue: s => QualityLabel(Mathf.RoundToInt(s.value), 3));
+
+ // ParticleLights: Lights (particle/light count quality), slider 0-2
+ WireSlider(page, "ParticleLights",
+ read: () => PlatformPrefs.GetInt("Lights", 2),
+ pend: v => Pend("Lights", () => PlatformPrefs.SetInt("Lights", Mathf.RoundToInt(v))),
+ formatValue: s => QualityLabel(Mathf.RoundToInt(s.value), 2));
+
+ // DrawDistance: LodBias (Valheim 0.221 key, NOT "LoD"), slider 0-3
+ WireSlider(page, "DrawDistance",
+ read: () => PlatformPrefs.GetInt("LodBias", 2),
+ pend: v => Pend("LodBias", () => PlatformPrefs.SetInt("LodBias", Mathf.RoundToInt(v))),
+ formatValue: s => QualityLabel(Mathf.RoundToInt(s.value), 3));
+
+ // ShadowQuality: slider 0-2
+ WireSlider(page, "ShadowQuality",
+ read: () => PlatformPrefs.GetInt("ShadowQuality", 2),
+ pend: v => Pend("ShadowQuality", () => PlatformPrefs.SetInt("ShadowQuality", Mathf.RoundToInt(v))),
+ formatValue: s => QualityLabel(Mathf.RoundToInt(s.value), 2));
+
+ // PointLights: slider 0-3
+ WireSlider(page, "PointLights",
+ read: () => PlatformPrefs.GetInt("PointLights", 3),
+ pend: v => Pend("PointLights", () => PlatformPrefs.SetInt("PointLights", Mathf.RoundToInt(v))),
+ formatValue: s => QualityLabel(Mathf.RoundToInt(s.value), 3));
+
+ // PointLightsShadows: slider 0-3
+ WireSlider(page, "PointLightsShadows",
+ read: () => PlatformPrefs.GetInt("PointLightShadows", 2),
+ pend: v => Pend("PointLightShadows", () => PlatformPrefs.SetInt("PointLightShadows", Mathf.RoundToInt(v))),
+ formatValue: s => QualityLabel(Mathf.RoundToInt(s.value), 3));
+
+ // FramerateLimit: slider 0-360; 0 = unlimited (FPSLimit = -1)
+ WireSlider(page, "FramerateLimit",
+ read: () => { int fps = PlatformPrefs.GetInt("FPSLimit", -1); return fps < 0 ? 0f : (float)fps; },
+ pend: v => {
+ int fps = Mathf.RoundToInt(v) <= 0 ? -1 : Mathf.RoundToInt(v);
+ Pend("FPSLimit", () => PlatformPrefs.SetInt("FPSLimit", fps));
+ },
+ formatValue: s => {
+ int v = Mathf.RoundToInt(s.value);
+ return v <= 0 ? "\u221E" : v + " fps"; // ∞
+ });
+
+ WireResolutionDropdown(page);
+ }
+
+ private static string QualityLabel(int val, int max)
+ {
+ switch (max)
+ {
+ case 2: return val == 0 ? "Low" : val == 1 ? "Med" : "High";
+ case 3: return val == 0 ? "Low" : val == 1 ? "Med" : val == 2 ? "High" : "Max";
+ default: return val.ToString();
+ }
+ }
+
+ // ===================== Misc =====================
+ private static void WireMisc(Transform page)
+ {
+ // GuiScale: slider range 50-115, PlatformPrefs stores float 0-1
+ // read: stored * 100 → slider value (1.0 → 100, fits in 50-115)
+ // display: slider.value + "%" (value IS the percentage number)
+ // save: slider.value / 100f → stored
+ WireSlider(page, "GuiScale",
+ read: () => PlatformPrefs.GetFloat("GuiScale", 1f) * 100f,
+ pend: v => Pend("GuiScale", () => {
+ float scale = Mathf.Clamp(v / 100f, 0.5f, 2f);
+ GuiScaler.SetScale(scale);
+ PlatformPrefs.SetFloat("GuiScale", scale);
+ }),
+ formatValue: s => Mathf.RoundToInt(s.value) + "%");
+
+ // RenderScale → Valheim 0.221: Target3DResolutionVertical (int pixels)
+ // slider range 0-1; 1.0 = native (int.MaxValue), <1 = downscaled
+ WireSlider(page, "RenderScale",
+ read: () => {
+ int tv = PlatformPrefs.GetInt("Target3DResolutionVertical", -1);
+ if (tv < 0) return PlatformPrefs.GetFloat("RenderScale", 1f);
+ return tv == int.MaxValue ? 1f : Mathf.Clamp01((float)tv / Mathf.Max(1, Screen.height));
+ },
+ pend: v => Pend("Target3DResolutionVertical", () => {
+ int pixels = v >= 1f ? int.MaxValue : Mathf.RoundToInt(Screen.height * Mathf.Clamp01(v));
+ PlatformPrefs.SetInt("Target3DResolutionVertical", pixels);
+ PlatformPrefs.SetFloat("RenderScale", v); // legacy fallback
+ }),
+ formatValue: s => Mathf.RoundToInt(s.value * 100f) + "%");
+
+ // Autobackups: slider range 1-10, display = count integer
+ WireSlider(page, "Autobackups",
+ read: () => Mathf.Clamp(PlatformPrefs.GetInt("AutoBackups", 4), 1, 10),
+ pend: v => Pend("AutoBackups", () => PlatformPrefs.SetInt("AutoBackups", Mathf.RoundToInt(v))),
+ formatValue: s => Mathf.RoundToInt(s.value).ToString());
+
+ WireToggle(page, "ShowKeyHints",
+ read: () => PlatformPrefs.GetBool("KeyHints", true),
+ pend: v => Pend("KeyHints", () => PlatformPrefs.SetBool("KeyHints", v)));
+
+ WireToggle(page, "ShowTutorials",
+ read: () => PlatformPrefs.GetBool("TutorialsEnabled", true),
+ pend: v => Pend("TutorialsEnabled", () => { Raven.m_tutorialsEnabled = v; PlatformPrefs.SetBool("TutorialsEnabled", v); }));
+
+ WireToggle(page, "CameraShake",
+ read: () => PlatformPrefs.GetBool("CameraShake", true),
+ pend: v => Pend("CameraShake", () => PlatformPrefs.SetBool("CameraShake", v)));
+
+ WireToggle(page, "ImmersiveShipCamera",
+ read: () => PlatformPrefs.GetBool("ImmersiveShipCamera", true),
+ pend: v => Pend("ImmersiveShipCamera", () => PlatformPrefs.SetBool("ImmersiveShipCamera", v)));
+
+ WireToggle(page, "ReduceBackgroundPerformance",
+ read: () => PlatformPrefs.GetBool("ReduceBackgroundUsage"),
+ pend: v => Pend("ReduceBackgroundUsage", () => { Settings.ReduceBackgroundUsage = v; PlatformPrefs.SetBool("ReduceBackgroundUsage", v); }));
+
+ WireToggle(page, "ReduceFlashingLights",
+ read: () => PlatformPrefs.GetBool("ReduceFlashingLights"),
+ pend: v => Pend("ReduceFlashingLights", () => { Settings.ReduceFlashingLights = v; PlatformPrefs.SetBool("ReduceFlashingLights", v); }));
+
+ WireToggle(page, "RightClickBuildSelection",
+ read: () => PlatformPrefs.GetBool("RightClickBuildSelection"),
+ pend: v => Pend("RightClickBuildSelection", () => PlatformPrefs.SetBool("RightClickBuildSelection", v)));
+
+ WireLanguageDropdown(page);
+ }
+
+ // ===================== Helpers =====================
+
+ ///
+ /// Находит слайдер по имени GO, устанавливает начальное значение из read().
+ /// onChange → pend (в _pending). immediateApply — живой предпросмотр (аудио).
+ ///
+ /// formatValue (Func<Slider,string>): если задан, ищет GO с именем "TMP ValueLabel"
+ /// и обновляет его текст. Намеренно НЕ трогает "TMP Label" (название параметра).
+ /// Controls-слайдеры (LabeledSlider) не имеют "TMP ValueLabel" → их Label не портится.
+ ///
+ private static void WireSlider(Transform page, string goName,
+ Func read, Action pend,
+ Action immediateApply = null,
+ Func formatValue = null)
+ {
+ var go = FindDeepChild(page, goName);
+ if (go == null) return;
+
+ var slider = go.GetComponentInChildren(true);
+ if (slider == null) return;
+
+ float storedValue = 0f;
+ try { storedValue = read(); } catch { }
+ slider.SetValueWithoutNotify(storedValue);
+
+ // Ищем TMP ValueLabel строго по имени GO (только в LabeledSliderWithValue)
+ TMPro.TMP_Text valueText = null;
+ if (formatValue != null)
+ {
+ foreach (var t in go.GetComponentsInChildren(true))
+ {
+ if (t.gameObject.name == "TMP ValueLabel") { valueText = t; break; }
+ }
+ }
+
+ void UpdateText()
+ {
+ if (valueText != null && formatValue != null)
+ valueText.text = formatValue(slider);
+ }
+ UpdateText();
+
+ slider.onValueChanged.AddListener(v =>
+ {
+ pend(v);
+ try { immediateApply?.Invoke(v); } catch { }
+ UpdateText();
+ });
+ }
+
+ private static void WireToggle(Transform page, string goName,
+ Func read, Action pend)
+ {
+ var go = FindDeepChild(page, goName);
+ if (go == null) return;
+ var toggle = go.GetComponentInChildren(true);
+ if (toggle == null) return;
+ try { toggle.SetIsOnWithoutNotify(read()); } catch { }
+ toggle.onValueChanged.AddListener(v => pend(v));
+ }
+
+ private static void WireLanguageDropdown(Transform page)
+ {
+ var go = FindDeepChild(page, "Language");
+ if (go == null) return;
+ var dd = go.GetComponentInChildren(true);
+ if (dd == null) return;
+ try
+ {
+ var languages = Localization.instance.GetLanguages();
+ if (languages == null || languages.Count == 0) return;
+
+ dd.ClearOptions();
+ dd.AddOptions(languages
+ .Select(l => Localization.instance.Localize("$language_" + l.ToLower()))
+ .ToList());
+
+ var currentLang = Localization.instance.GetSelectedLanguage();
+ int idx = Mathf.Max(0, languages.IndexOf(currentLang));
+ dd.SetValueWithoutNotify(idx);
+ RefreshDropdownCaption(dd); // TMP Label caption не обновляется стандартно
+
+ dd.onValueChanged.AddListener(i =>
+ {
+ RefreshDropdownCaption(dd);
+ if (i >= 0 && i < languages.Count)
+ Pend("Language", () => Localization.instance.SetLanguage(languages[i]));
+ });
+ }
+ catch (Exception ex) { Auga.LogWarning($"[AugaSettings] Language dropdown: {ex.Message}"); }
+ }
+
+ private static void WireResolutionDropdown(Transform page)
+ {
+ var go = FindDeepChild(page, "Resolution");
+ if (go == null) return;
+ var dd = go.GetComponentInChildren(true);
+ if (dd == null) return;
+ try
+ {
+ var resolutions = Screen.resolutions;
+ if (resolutions == null || resolutions.Length == 0) return;
+
+ // Дедупликация по w×h (Unity 6 возвращает дубликаты при разных refresh rate)
+ var seen = new HashSet();
+ var unique = new List();
+ foreach (var r in resolutions)
+ {
+ string key = r.width + "x" + r.height;
+ if (seen.Add(key)) unique.Add(r);
+ }
+
+ var options = unique.Select(r => r.width + "x" + r.height).ToList();
+ dd.ClearOptions();
+ dd.AddOptions(options);
+
+ // Находим текущее разрешение
+ int currentIdx = 0;
+ for (int i = 0; i < unique.Count; i++)
+ if (unique[i].width == Screen.width && unique[i].height == Screen.height)
+ currentIdx = i;
+ dd.SetValueWithoutNotify(currentIdx);
+ RefreshDropdownCaption(dd);
+
+ dd.onValueChanged.AddListener(i =>
+ {
+ RefreshDropdownCaption(dd);
+ if (i >= 0 && i < unique.Count)
+ {
+ var r = unique[i];
+ Pend("Resolution", () => Screen.SetResolution(r.width, r.height, Screen.fullScreen));
+ }
+ });
+ }
+ catch (Exception ex) { Auga.LogWarning($"[AugaSettings] Resolution dropdown: {ex.Message}"); }
+ }
+
+ ///
+ /// Legacy Dropdown с TMP Label (TMPro.TextMeshProUGUI) не может обновить
+ /// Caption автоматически (m_CaptionText ожидает UI.Text).
+ /// Обновляем TMP Label вручную по текущему dd.value.
+ ///
+ private static void RefreshDropdownCaption(Dropdown dd)
+ {
+ var lbl = dd.transform.Find("TMP Label")?.GetComponent();
+ if (lbl != null && dd.value >= 0 && dd.value < dd.options.Count)
+ lbl.text = dd.options[dd.value].text;
+ }
+
+ private static GameObject FindDeepChild(Transform root, string name)
+ {
+ if (root.gameObject.name == name) return root.gameObject;
+ for (int i = 0; i < root.childCount; i++)
+ {
+ var found = FindDeepChild(root.GetChild(i), name);
+ if (found != null) return found;
+ }
+ return null;
+ }
+ }
+}
diff --git a/Auga/AugaTS.zip b/Auga/AugaTS.zip
deleted file mode 100644
index f07a9c8a..00000000
Binary files a/Auga/AugaTS.zip and /dev/null differ
diff --git a/Auga/AugaTS1.1.zip b/Auga/AugaTS1.1.zip
deleted file mode 100644
index 16181320..00000000
Binary files a/Auga/AugaTS1.1.zip and /dev/null differ
diff --git a/Auga/AugaTile.png b/Auga/AugaTile.png
deleted file mode 100644
index 36bb00ce..00000000
Binary files a/Auga/AugaTile.png and /dev/null differ
diff --git a/Auga/DamageText_Setup.cs b/Auga/DamageText_Setup.cs
index 3a7d965b..cbbe79a8 100644
--- a/Auga/DamageText_Setup.cs
+++ b/Auga/DamageText_Setup.cs
@@ -18,7 +18,7 @@ public static bool Prefix(TextInput __instance)
[HarmonyPatch(typeof(DamageText), nameof(DamageText.AddInworldText))]
[HarmonyPostfix]
- public static void AddInworldText_Postfix(DamageText __instance, DamageText.TextType type, float dmg, bool mySelf)
+ public static void AddInworldText_Postfix(DamageText __instance, DamageText.TextType type, string text, bool mySelf)
{
var worldTextInstance = __instance.m_worldTexts.LastOrDefault();
if (worldTextInstance == null)
@@ -26,6 +26,10 @@ public static void AddInworldText_Postfix(DamageText __instance, DamageText.Text
return;
}
+ // "dmg" parameter was removed in current Valheim; parse damage from the text string
+ float.TryParse(text, System.Globalization.NumberStyles.Float,
+ System.Globalization.CultureInfo.InvariantCulture, out var dmg);
+
Color color;
if (type == DamageText.TextType.Heal)
{
diff --git a/Auga/EnemeyHud_Setup.cs b/Auga/EnemeyHud_Setup.cs
index 433dd85e..efdfba7c 100644
--- a/Auga/EnemeyHud_Setup.cs
+++ b/Auga/EnemeyHud_Setup.cs
@@ -1,5 +1,6 @@
using System.Linq;
using HarmonyLib;
+using TMPro;
using UnityEngine;
using UnityEngine.UI;
@@ -61,8 +62,8 @@ public static void Postfix(EnemyHud __instance, Character c)
newLevelXDisplay.name = levelXDisplayName;
}
- var text = levelDisplayX.GetComponentInChildren();
- text.text = $"x {level - 1}";
+ var text = levelDisplayX.GetComponentInChildren();
+ if (text != null) text.text = $"x {level - 1}";
}
}
}
diff --git a/Auga/Hud_Setup.cs b/Auga/Hud_Setup.cs
index 999e19e7..ada06445 100644
--- a/Auga/Hud_Setup.cs
+++ b/Auga/Hud_Setup.cs
@@ -177,27 +177,13 @@ public static void Hud_Awake_Postfix(Hud __instance)
var selectedField = child.Find("Selected").gameObject;
var selectedTextField = selectedField.transform.Find("Text").GetComponent();
- var augaTextComponent = augaText.GetComponent();
- textField.color = augaTextComponent.color;
- textField.font = augaTextComponent.font;
- textField.fontStyle = augaTextComponent.fontStyle;
- textField.fontSize = augaTextComponent.fontSize;
- textField.material = augaTextComponent.material;
-
- var augaSelectedTextComponent = augaSelectedText.GetComponent();
- selectedTextField.color = augaSelectedTextComponent.color;
- selectedTextField.font = augaSelectedTextComponent.font;
- selectedTextField.fontStyle = augaSelectedTextComponent.fontStyle;
- selectedTextField.fontSize = augaSelectedTextComponent.fontSize;
- selectedTextField.material = augaSelectedTextComponent.material;
-
+ // TODO: augaText/augaSelectedText source GameObjects were lost; text styling skipped
var image = selectedField.GetComponent();
image.color = new Color(image.color.r, image.color.g, image.color.b, 0.0f);
}
- var iconMaterial = __instance.m_pieceIconPrefab.transform.Find("icon").GetComponent().material;
- Auga.Assets.BuildHudElement.transform.Find("icon").GetComponent().material = iconMaterial;
+ // iconMaterial already captured at the top of this if-block; just assign the prefab
__instance.m_pieceIconPrefab = Auga.Assets.BuildHudElement;
var pieceRoot = __instance.m_pieceSelectionWindow.transform.Find("PieceList/Root").gameObject;
@@ -231,7 +217,8 @@ public static void Hud_Awake_Postfix(Hud __instance)
Auga.UpdateStatBars();
Localization.instance.Localize(__instance.transform);
- }
+ } // end if (Auga.BuildMenuShow.Value && !Auga.HasSearsCatalog)
+ } // end Hud_Awake_Postfix
[HarmonyPatch(nameof(Hud.UpdateStatusEffects))]
[HarmonyPrefix]
@@ -377,7 +364,7 @@ public static void SetupPieceInfo(Hud instance, Piece piece)
if (snappingIconForPiece != null)
{
instance.m_snappingIcon.sprite = snappingIconForPiece;
- instance.m_snappingIcon.enabled = snappingIconForPiece != null && (piece.m_category == Piece.PieceCategory.Building || piece.m_groundPiece || piece.m_waterPiece);
+ instance.m_snappingIcon.enabled = snappingIconForPiece != null && (piece.m_category == (Piece.PieceCategory)2 || piece.m_groundPiece || piece.m_waterPiece);
}
for (int index = 0; index < instance.m_requirementItems.Length; ++index)
{
@@ -707,7 +694,7 @@ public static bool Prefix(Hud __instance, Player player, Vector2Int selectedNr,
}
__instance.m_lastPieceCategory = category;
- __instance.m_pieceBarPosX = __instance.m_pieceBarTargetPosX;
+ // m_pieceBarPosX removed in current Valheim; skipping position reset
__instance.UpdatePieceBuildStatusAll(buildPieces, player);
return false;
diff --git a/Auga/ILRepack.targets b/Auga/ILRepack.targets
index 758218f0..ecc561df 100644
--- a/Auga/ILRepack.targets
+++ b/Auga/ILRepack.targets
@@ -1,12 +1,8 @@
-
+
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
diff --git a/Auga/MainMenu_Setup.cs b/Auga/MainMenu_Setup.cs
index b6e050f1..a0ce7aea 100644
--- a/Auga/MainMenu_Setup.cs
+++ b/Auga/MainMenu_Setup.cs
@@ -1,11 +1,14 @@
-using AugaUnity;
+using System;
+using System.Collections;
+using AugaUnity;
using HarmonyLib;
+using TMPro;
using UnityEngine;
+using UnityEngine.Events;
using UnityEngine.UI;
namespace Auga
{
-
[HarmonyPatch(typeof(TextsDialog), nameof(TextsDialog.SnapTo))]
public static class SnapTo_Patch
{
@@ -23,226 +26,757 @@ public static void Postfix(TextsDialog __instance, RectTransform listRoot, Scrol
[HarmonyPatch(typeof(FejdStartup), nameof(FejdStartup.Awake))]
public static class FejdStartup_Awake_Patch
{
+ // Переданные из Prefix в Postfix данные о волосах/бороде
+ private static ItemDrop _originalNoHair;
+ private static ItemDrop _originalNoBeard;
+
+ // Null-safe Find + GetComponent. Logs warning if path or component missing.
+ private static T FC(Transform root, string path) where T : Component
+ {
+ if (root == null) { Auga.LogWarning($"FC<{typeof(T).Name}>: root is null (path={path})"); return null; }
+ var t = root.Find(path);
+ if (t == null) { Auga.LogWarning($"FC<{typeof(T).Name}>: path not found: {path}"); return null; }
+ var c = t.GetComponent();
+ if (c == null) Auga.LogWarning($"FC<{typeof(T).Name}>: no component on: {path}");
+ return c;
+ }
+
+ // Null-safe Find -> GameObject.
+ private static GameObject FO(Transform root, string path)
+ {
+ if (root == null) { Auga.LogWarning($"FO: root is null (path={path})"); return null; }
+ var t = root.Find(path);
+ if (t == null) { Auga.LogWarning($"FO: path not found: {path}"); return null; }
+ return t.gameObject;
+ }
+
public static void Prefix(FejdStartup __instance)
{
ZInput.Initialize();
- //var originalChangeLogAsset = __instance.GetComponentInChildren(true).m_changeLog;
-
__instance.m_settingsPrefab = Auga.Assets.SettingsPrefab;
- /*var originalLogo = __instance.transform.Find("Menu/Logo");
- originalLogo.SetParent(__instance.transform, true);
+ // Сохраняем логотип до замены меню
+ var originalLogo = __instance.transform.Find("Menu/Logo");
+ if (originalLogo != null)
+ originalLogo.SetParent(__instance.transform, true);
+ // Заменяем все префабы — должно произойти ДО ванильного Awake(),
+ // чтобы ванильный код нашёл нужные объекты по именам.
var mainMenu = __instance.Replace("Menu", Auga.Assets.MainMenuPrefab);
- originalLogo.SetParent(mainMenu, true);
-
- __instance.m_mainMenu = mainMenu.gameObject;
- __instance.m_menuList = mainMenu.Find("MenuList").gameObject;
- __instance.m_menuSelectedButton = mainMenu.Find("MenuList/StartGame").GetComponent