Skip to content

Commit b2bb736

Browse files
committed
chore(release): merge dev into main for v0.0.64
2 parents ab851fc + 12811dd commit b2bb736

8 files changed

Lines changed: 161 additions & 91 deletions

Audio/FmodStudioServer.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using Godot;
22
using STS2RitsuLib.Audio.Internal;
3+
using FileAccess = Godot.FileAccess;
34

45
namespace STS2RitsuLib.Audio
56
{
@@ -22,7 +23,29 @@ public static class FmodStudioServer
2223
/// </summary>
2324
public static bool TryLoadBank(string resourcePath, FmodStudioLoadBankMode mode = FmodStudioLoadBankMode.Normal)
2425
{
25-
return FmodStudioGateway.TryCall(FmodStudioMethodNames.LoadBank, resourcePath, (int)mode);
26+
if (string.IsNullOrWhiteSpace(resourcePath))
27+
{
28+
RitsuLibFramework.Logger.Warn("[Audio] FMOD load_bank: empty path.");
29+
return false;
30+
}
31+
32+
if (!FileAccess.FileExists(resourcePath))
33+
{
34+
RitsuLibFramework.Logger.Warn($"[Audio] FMOD load_bank: file not found: {resourcePath}");
35+
return false;
36+
}
37+
38+
if (!FmodStudioGateway.TryCall(out var result, FmodStudioMethodNames.LoadBank, resourcePath, (int)mode))
39+
return false;
40+
41+
if (result.VariantType == Variant.Type.Bool)
42+
return result.AsBool();
43+
44+
if (result.VariantType == Variant.Type.Nil)
45+
return false;
46+
47+
var bank = result.AsGodotObject();
48+
return bank is not null && GodotObject.IsInstanceValid(bank);
2649
}
2750

2851
/// <summary>

Const.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public static class Const
1818
/// <summary>
1919
/// Assembly / manifest version string.
2020
/// </summary>
21-
public const string Version = "0.0.63";
21+
public const string Version = "0.0.64";
2222

2323
/// <summary>
2424
/// Root key for RitsuLib JSON settings under the mod’s user folder.

Interop/Patches/SavedAttachedStatePatch.cs

Lines changed: 0 additions & 79 deletions
This file was deleted.
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
using MegaCrit.Sts2.Core.Models;
2+
using MegaCrit.Sts2.Core.Saves.Runs;
3+
using STS2RitsuLib.Patching.Models;
4+
using STS2RitsuLib.Utils;
5+
6+
namespace STS2RitsuLib.Interop.Patches
7+
{
8+
/// <summary>
9+
/// Bridges <see cref="SavedAttachedState{TKey,TValue}" /> instances into <see cref="SavedProperties" />
10+
/// serialization and deserialization.
11+
/// </summary>
12+
public static class SavedAttachedStatePatches
13+
{
14+
// ReSharper disable once InconsistentNaming
15+
private static void ExportAttachedStates(ref SavedProperties? __result, object model)
16+
{
17+
var states = SavedAttachedStateRegistry.GetStatesForModel(model);
18+
if (states.Count == 0)
19+
return;
20+
21+
var props = __result ?? new SavedProperties();
22+
var added = false;
23+
foreach (var state in states)
24+
{
25+
state.Export(model, props);
26+
added = true;
27+
}
28+
29+
if (__result == null && added)
30+
__result = props;
31+
}
32+
33+
// ReSharper disable once InconsistentNaming
34+
private static void ImportAttachedStates(SavedProperties __instance, object model)
35+
{
36+
foreach (var state in SavedAttachedStateRegistry.GetStatesForModel(model))
37+
state.Import(model, __instance);
38+
}
39+
40+
/// <summary>
41+
/// Exports registered saved attached states after vanilla model properties are serialized.
42+
/// </summary>
43+
public sealed class SavedPropertiesFromInternalPatch : IPatchMethod
44+
{
45+
/// <inheritdoc />
46+
public static string PatchId => "ritsulib_saved_attached_state_SavedProperties_FromInternal";
47+
48+
/// <inheritdoc />
49+
public static string Description =>
50+
"Bridge SavedAttachedState through SavedProperties save -> SavedProperties.FromInternal(...)";
51+
52+
/// <inheritdoc />
53+
public static bool IsCritical => false;
54+
55+
/// <inheritdoc />
56+
public static ModPatchTarget[] GetTargets()
57+
{
58+
return
59+
[
60+
new(typeof(SavedProperties), nameof(SavedProperties.FromInternal),
61+
[typeof(object), typeof(ModelId)]),
62+
];
63+
}
64+
65+
/// <summary>
66+
/// Exports registered saved attached states after vanilla model properties are serialized.
67+
/// </summary>
68+
// ReSharper disable once InconsistentNaming
69+
// ReSharper disable once UnusedParameter
70+
public static void Postfix(ref SavedProperties? __result, object model, ModelId? id)
71+
{
72+
ExportAttachedStates(ref __result, model);
73+
}
74+
}
75+
76+
/// <summary>
77+
/// Imports registered saved attached states after vanilla model properties are deserialized.
78+
/// </summary>
79+
public sealed class SavedPropertiesFillInternalPatch : IPatchMethod
80+
{
81+
/// <inheritdoc />
82+
public static string PatchId => "ritsulib_saved_attached_state_SavedProperties_FillInternal";
83+
84+
/// <inheritdoc />
85+
public static string Description =>
86+
"Bridge SavedAttachedState through SavedProperties load -> SavedProperties.FillInternal(...)";
87+
88+
/// <inheritdoc />
89+
public static bool IsCritical => false;
90+
91+
/// <inheritdoc />
92+
public static ModPatchTarget[] GetTargets()
93+
{
94+
return
95+
[
96+
new(typeof(SavedProperties), nameof(SavedProperties.FillInternal), [typeof(object)]),
97+
];
98+
}
99+
100+
/// <summary>
101+
/// Imports registered saved attached states after vanilla model properties are deserialized.
102+
/// </summary>
103+
// ReSharper disable once InconsistentNaming
104+
public static void Postfix(SavedProperties __instance, object model)
105+
{
106+
ImportAttachedStates(__instance, model);
107+
}
108+
}
109+
}
110+
}

RitsuLibFramework.PatcherSetup.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ private static void RegisterLifecyclePatches()
5858
var patcher = CreatePatcher(Const.ModId, "framework-core", "framework core");
5959
patcher.RegisterPatch<ModTypeDiscoveryPatch>();
6060
patcher.RegisterPatch<SavedPropertiesTypeCacheInjectionPatch>();
61-
patcher.RegisterPatch<SavedAttachedStatePatch>();
61+
patcher.RegisterPatch<SavedAttachedStatePatches.SavedPropertiesFromInternalPatch>();
62+
patcher.RegisterPatch<SavedAttachedStatePatches.SavedPropertiesFillInternalPatch>();
6263
patcher.RegisterPatch<CoreInitializationLifecyclePatch>();
6364
patcher.RegisterPatch<NMainMenuContinueRunMissingCharacterPatch>();
6465
patcher.RegisterPatch<NMainMenuHarmonyPatchDumpPatch>();

STS2-RitsuLib.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<NoWarn>$(NoWarn);CS0436</NoWarn>
1212
<IsPackable>true</IsPackable>
1313
<PackageId>STS2.RitsuLib</PackageId>
14-
<Version>0.0.63</Version>
14+
<Version>0.0.64</Version>
1515
<Authors>OLC</Authors>
1616
<Description>Shared framework library for Slay the Spire 2 mods.</Description>
1717
<PackageReadmeFile>README.md</PackageReadmeFile>

Sts2PathDiscovery.props

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
<Project>
22
<!--
33
Fills Sts2Dir and Sts2DataDir when not set (e.g. no local.props).
4-
Override by creating local.props with <Sts2Dir>...</Sts2Dir> or env MSBuild property /p:Sts2Dir=...
4+
Override by creating local.props with <Sts2Dir>...</Sts2Dir> or MSBuild /p:Sts2Dir=...
5+
6+
Managed assemblies / refs live under platform data folders, typically:
7+
data_sts2_windows_x86_64
8+
data_sts2_linuxbsd_x86_64
9+
SlayTheSpire2.app/Contents/Resources/data_sts2_macos_arm64
10+
SlayTheSpire2.app/Contents/Resources/data_sts2_macos_x86_64
511
-->
612
<PropertyGroup>
713
<IsWindows>false</IsWindows>
@@ -12,25 +18,34 @@
1218
<IsOSX Condition="$([MSBuild]::IsOSPlatform('OSX'))">true</IsOSX>
1319
</PropertyGroup>
1420

15-
<!-- Windows: Steam uninstall registry, then default Steam library paths -->
21+
<!-- Windows: Steam library first, then uninstall registry InstallLocation when it contains data_sts2_windows_x86_64 -->
1622
<PropertyGroup Condition="'$(IsWindows)' == 'true'">
17-
<Sts2Dir Condition="'$(Sts2Dir)' == ''">$([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 2868840', 'InstallLocation', '', RegistryView.Registry64, RegistryView.Registry32))</Sts2Dir>
18-
<_RitsuAutoSteamApps>$(registry:HKEY_CURRENT_USER\Software\Valve\Steam@SteamPath)\steamapps</_RitsuAutoSteamApps>
19-
<SteamLibraryPath Condition="'$(SteamLibraryPath)' == '' and Exists('$(_RitsuAutoSteamApps)/common/Slay the Spire 2')">$(_RitsuAutoSteamApps)</SteamLibraryPath>
23+
<RegistrySts2Path>$([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 2868840', 'InstallLocation', '', RegistryView.Registry64, RegistryView.Registry32))</RegistrySts2Path>
24+
<AutoSteamPath>$(registry:HKEY_CURRENT_USER\Software\Valve\Steam@SteamPath)\steamapps</AutoSteamPath>
25+
<SteamLibraryPath Condition="'$(SteamLibraryPath)' == '' and Exists('$(AutoSteamPath)/common/Slay the Spire 2')">$(AutoSteamPath)</SteamLibraryPath>
2026
<SteamLibraryPath Condition="'$(SteamLibraryPath)' == ''">C:/Program Files (x86)/Steam/steamapps</SteamLibraryPath>
27+
28+
<Sts2Dir Condition="'$(Sts2Dir)' == '' and Exists('$(SteamLibraryPath)/common/Slay the Spire 2')">$(SteamLibraryPath)/common/Slay the Spire 2</Sts2Dir>
29+
<Sts2Dir Condition="'$(Sts2Dir)' == '' and Exists('$(RegistrySts2Path)/data_sts2_windows_x86_64')">$(RegistrySts2Path)</Sts2Dir>
2130
<Sts2Dir Condition="'$(Sts2Dir)' == ''">$(SteamLibraryPath)/common/Slay the Spire 2</Sts2Dir>
22-
<Sts2DataDir Condition="'$(Sts2DataDir)' == ''">$(Sts2Dir)\data_sts2_windows_x86_64</Sts2DataDir>
31+
32+
<Sts2DataDir Condition="'$(Sts2DataDir)' == ''">$(Sts2Dir)/data_sts2_windows_x86_64</Sts2DataDir>
2333
</PropertyGroup>
2434

2535
<PropertyGroup Condition="'$(IsLinux)' == 'true'">
2636
<SteamLibraryPath Condition="'$(SteamLibraryPath)' == ''">$(HOME)/.local/share/Steam/steamapps</SteamLibraryPath>
2737
<Sts2Dir Condition="'$(Sts2Dir)' == ''">$(SteamLibraryPath)/common/Slay the Spire 2</Sts2Dir>
38+
2839
<Sts2DataDir Condition="'$(Sts2DataDir)' == ''">$(Sts2Dir)/data_sts2_linuxbsd_x86_64</Sts2DataDir>
2940
</PropertyGroup>
3041

42+
<!-- macOS: managed assemblies live under .app/Contents/Resources; prefer arm64 when present, then x86_64 -->
3143
<PropertyGroup Condition="'$(IsOSX)' == 'true'">
3244
<SteamLibraryPath Condition="'$(SteamLibraryPath)' == ''">$(HOME)/Library/Application Support/Steam/steamapps</SteamLibraryPath>
3345
<Sts2Dir Condition="'$(Sts2Dir)' == ''">$(SteamLibraryPath)/common/Slay the Spire 2</Sts2Dir>
34-
<Sts2DataDir Condition="'$(Sts2DataDir)' == ''">$(Sts2Dir)/data_sts2_macos_x86_64</Sts2DataDir>
46+
47+
<Sts2DataDir Condition="'$(Sts2DataDir)' == '' and Exists('$(Sts2Dir)/SlayTheSpire2.app/Contents/Resources/data_sts2_macos_arm64')">$(Sts2Dir)/SlayTheSpire2.app/Contents/Resources/data_sts2_macos_arm64</Sts2DataDir>
48+
<Sts2DataDir Condition="'$(Sts2DataDir)' == '' and Exists('$(Sts2Dir)/SlayTheSpire2.app/Contents/Resources/data_sts2_macos_x86_64')">$(Sts2Dir)/SlayTheSpire2.app/Contents/Resources/data_sts2_macos_x86_64</Sts2DataDir>
49+
<Sts2DataDir Condition="'$(Sts2DataDir)' == ''">$(Sts2Dir)/SlayTheSpire2.app/Contents/Resources/data_sts2_macos_arm64</Sts2DataDir>
3550
</PropertyGroup>
3651
</Project>

mod_manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"name": "RitsuLib",
55
"author": "OLC",
66
"description": "A shared Slay the Spire 2 mod framework library providing reusable patching, persistence, lifecycle, localization, and utility APIs for other mods.",
7-
"version": "0.0.63",
7+
"version": "0.0.64",
88
"has_pck": false,
99
"has_dll": true,
1010
"affects_gameplay": false,

0 commit comments

Comments
 (0)