Skip to content

Commit 86256ff

Browse files
committed
refactor(character): replace direct child manipulation with RitsuGodotTreeCompat methods
- Updated NFakeMerchantProceduralCharacterInstantiationPatch and NMerchantRoomProceduralCharacterInstantiationPatch to use RitsuGodotTreeCompat for adding and moving child nodes, ensuring compatibility across game versions. - Introduced RitsuGodotTreeCompat class to provide safe methods for tree mutations, addressing issues with multi-version builds.
1 parent f9deb98 commit 86256ff

3 files changed

Lines changed: 53 additions & 5 deletions

File tree

Scaffolding/Characters/Patches/NFakeMerchantProceduralCharacterInstantiationPatch.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ private static void RunAfterRoomIsLoaded(NFakeMerchant screen)
8787
?? RitsuGodotNodeFactories.CreateFromScenePath<NMerchantCharacter>(
8888
player.Character.MerchantAnimPath, PackedScene.GenEditState.Disabled);
8989

90-
characterContainer.AddChildSafely(nMerchantCharacter);
91-
characterContainer.MoveChildSafely(nMerchantCharacter, 0);
90+
RitsuGodotTreeCompat.AddChildSafely(characterContainer, nMerchantCharacter);
91+
RitsuGodotTreeCompat.MoveChildSafely(characterContainer, nMerchantCharacter, 0);
9292
nMerchantCharacter.Position = new(num2, -50f * i);
9393
if (i > 0)
9494
nMerchantCharacter.Modulate = new(0.5f, 0.5f, 0.5f);

Scaffolding/Characters/Patches/NMerchantRoomProceduralCharacterInstantiationPatch.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using HarmonyLib;
33
using MegaCrit.Sts2.Core.Context;
44
using MegaCrit.Sts2.Core.Entities.Players;
5-
using MegaCrit.Sts2.Core.Helpers;
65
using MegaCrit.Sts2.Core.Nodes.Rooms;
76
using MegaCrit.Sts2.Core.Nodes.Screens.Shops;
87
using STS2RitsuLib.Patching.Models;
@@ -79,8 +78,8 @@ private static void RunAfterRoomIsLoaded(NMerchantRoom room)
7978
ModWorldSceneVisualNodeFactory.TryInstantiateMerchantCharacter(player.Character)
8079
?? RitsuGodotNodeFactories.CreateFromScenePath<NMerchantCharacter>(
8180
player.Character.MerchantAnimPath, PackedScene.GenEditState.Disabled);
82-
characterContainer.AddChildSafely(nMerchantCharacter);
83-
characterContainer.MoveChild(nMerchantCharacter, 0);
81+
RitsuGodotTreeCompat.AddChildSafely(characterContainer, nMerchantCharacter);
82+
RitsuGodotTreeCompat.MoveChildSafely(characterContainer, nMerchantCharacter, 0);
8483
nMerchantCharacter.Position = new(num2, -50f * i);
8584
if (i > 0)
8685
nMerchantCharacter.Modulate = new(0.5f, 0.5f, 0.5f);
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using Godot;
2+
using MegaCrit.Sts2.Core.Nodes;
3+
4+
namespace STS2RitsuLib.Scaffolding.Godot
5+
{
6+
/// <summary>
7+
/// Tree mutations aligned with vanilla <c>GodotTreeExtensions</c> (0.104.x). Game 0.103.2 omits
8+
/// <c>MoveChildSafely</c>; referencing it from mods breaks multi-version builds. Use these helpers instead of
9+
/// calling game extension methods for merchant-booth style layout.
10+
/// </summary>
11+
public static class RitsuGodotTreeCompat
12+
{
13+
/// <summary>
14+
/// Same branching as <c>MegaCrit.Sts2.Core.Helpers.GodotTreeExtensions.AddChildSafely</c> on current game
15+
/// branches that ship it.
16+
/// </summary>
17+
public static void AddChildSafely(Node parent, Node? child)
18+
{
19+
if (child == null || !GodotObject.IsInstanceValid(parent))
20+
return;
21+
22+
if (NGame.IsMainThread() && (parent.IsNodeReady() || !parent.IsInsideTree()))
23+
{
24+
parent.AddChild(child);
25+
return;
26+
}
27+
28+
parent.CallDeferred(Node.MethodName.AddChild, child);
29+
}
30+
31+
/// <summary>
32+
/// Same branching as <c>MegaCrit.Sts2.Core.Helpers.GodotTreeExtensions.MoveChildSafely</c> where the game
33+
/// provides it (0.104+); self-contained for 0.103.2 reference assemblies.
34+
/// </summary>
35+
public static void MoveChildSafely(Node parent, Node? child, int index)
36+
{
37+
if (child == null || !GodotObject.IsInstanceValid(parent))
38+
return;
39+
40+
if (NGame.IsMainThread() && (parent.IsNodeReady() || !parent.IsInsideTree()))
41+
{
42+
parent.MoveChild(child, index);
43+
return;
44+
}
45+
46+
parent.CallDeferred(Node.MethodName.MoveChild, child, index);
47+
}
48+
}
49+
}

0 commit comments

Comments
 (0)