From 785cdf6a1be033894be31284ebb1bd3eff912410 Mon Sep 17 00:00:00 2001 From: Daniel Piers Date: Sun, 30 Nov 2025 16:53:30 -0800 Subject: [PATCH] [JK2] Fix crash/hang when loading saved games on 64-bit builds Add missing watchTarget pointer field to savefields_gNPC table. The watchTarget field (gentity_t*) in gNPC_t was being serialized as int32_t in sg_export() but was not included in the savefields_gNPC conversion table. This caused: - On save: 64-bit pointer truncated to 32-bit - On load: Truncated value used as invalid pointer - On use: Crash (Windows x64) or infinite loop (macOS ARM64) when NPC_BSCinematic() calls CalcEntitySpot(NPCInfo->watchTarget, ...) The Jedi Academy codebase (code/game/g_savegame.cpp) correctly includes watchTarget in its savefields_gNPC table, but the JK2 codebase was missing this entry. Fixes #1278 --- codeJK2/game/g_savegame.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/codeJK2/game/g_savegame.cpp b/codeJK2/game/g_savegame.cpp index 672f6de4ba..ee303c60dd 100644 --- a/codeJK2/game/g_savegame.cpp +++ b/codeJK2/game/g_savegame.cpp @@ -106,6 +106,7 @@ static const field_t savefields_gNPC[] = {strNPCOFS(defendEnt), F_GENTITY}, {strNPCOFS(greetEnt), F_GENTITY}, {strNPCOFS(group), F_GROUP}, + {strNPCOFS(watchTarget), F_GENTITY}, {NULL, 0, F_IGNORE} }; @@ -233,7 +234,7 @@ intptr_t GetGEntityNum(gentity_t* ent) gentity_t *GetGEntityPtr(intptr_t iEntNum) { - if (iEntNum == -1) + if (iEntNum < 0 || iEntNum >= MAX_GENTITIES) { return NULL; }