Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions S1API/Entities/NPC.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
using S1Registry = Il2CppScheduleOne.Registry;
using S1Money = Il2CppScheduleOne.Money;
using ConversationCategoryList = Il2CppSystem.Collections.Generic.List<Il2CppScheduleOne.Messaging.EConversationCategory>;
using S1MessageConversationData = Il2CppScheduleOne.Persistence.Datas.MSGConversationData;
#elif MONOMELON
using NativeVehicleLifecycleAction = System.Action<ScheduleOne.Vehicles.LandVehicle>;
using S1DevUtilities = ScheduleOne.DevUtilities;
Expand Down Expand Up @@ -58,6 +59,7 @@
using S1Registry = ScheduleOne.Registry;
using S1Money = ScheduleOne.Money;
using ConversationCategoryList = System.Collections.Generic.List<ScheduleOne.Messaging.EConversationCategory>;
using S1MessageConversationData = ScheduleOne.Persistence.Datas.MSGConversationData;
#endif

#if IL2CPPMELON
Expand Down Expand Up @@ -4308,6 +4310,7 @@ internal static bool TrySetRequiresRegionUnlocked(object npc, bool value) =>
private NPCSupplier? _supplier;
private NPCRelationship? _relationship;
private NPCMessaging? _messaging;
private S1MessageConversationData? _conversationBeforeNetworkSpawn;
private ManagedEventRegistrationTracker<AwarenessEventRegistration<S1PlayerScripts.Player>>?
_noticedDrugDealingRegistrations;
private ManagedEventRegistrationTracker<AwarenessEventRegistration<S1PlayerScripts.Player>>?
Expand Down Expand Up @@ -4360,6 +4363,7 @@ private void TrySpawnNetworkInstance()

internal bool PrepareForNetworkSpawn()
{
_conversationBeforeNetworkSpawn = null;
try
{
if (!TryValidateNativeAwakeReferences(out string diagnostic))
Expand All @@ -4369,6 +4373,8 @@ internal bool PrepareForNetworkSpawn()
return false;
}

PreserveConversationBeforeNativeAwake();

NPCDataAccess.PrepareForRuntime(S1NPC);
RestoreLoadedRelationship();

Expand Down Expand Up @@ -4397,6 +4403,22 @@ internal bool PrepareForNetworkSpawn()
}
}

internal void PreserveConversationBeforeNativeAwake()
{
var conversation = S1NPC.MSGConversation;
if (_conversationBeforeNetworkSpawn != null || conversation == null)
return;

try
{
_conversationBeforeNetworkSpawn = conversation.GetSaveData();
}
catch (Exception ex)
{
Logger.Warning($"[NPC] Could not preserve conversation before spawning '{GetSafeNpcId()}': {ex.Message}");
}
}

private bool TryValidateNativeAwakeReferences(out string diagnostic)
{
var missing = new System.Collections.Generic.List<string>();
Expand Down Expand Up @@ -4463,6 +4485,19 @@ internal void FinalizeNetworkSpawn()
S1NPC.SetVisible(ShouldBeVisibleAfterSpawn(), networked: false);

EnsureMessageConversationReady(resetDefaults: false);
var savedConversation = _conversationBeforeNetworkSpawn;
_conversationBeforeNetworkSpawn = null;
if (savedConversation != null && S1NPC.MSGConversation != null && S1NPC.MSGConversation.MessageHistoryCount == 0)
{
try
{
S1NPC.MSGConversation.Load(savedConversation);
}
catch (Exception ex)
{
Logger.Warning($"[NPC] Could not restore conversation after spawning '{GetSafeNpcId()}': {ex.Message}");
}
}

// If we're the server, also broadcast to clients via RPC after a delay
// This ensures the NPC is fully spawned before the RPC is sent
Expand Down
3 changes: 3 additions & 0 deletions S1API/Internal/Patches/NPCPatches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1160,7 +1160,10 @@ private static bool NPC_Awake_Prefix(S1NPCs.NPC __instance)
}

if (isCustomNpc)
{
FindWrapperForS1Npc(__instance)?.PreserveConversationBeforeNativeAwake();
NPCDataAccess.PrepareForNativeAwake(__instance!);
}
}
catch (Exception ex)
{
Expand Down
Loading