Fix Load File crash: VALUEPARM for literal field arg in CTCL_GetAutoSlotInt

Script calls callback(CTCL_GetAutoSlotInt, k, 0/1/2/3) where 0-3 are
integer literals. The script engine passes literals as (void*)N directly
(not as pointers), so INTPARM(1) = *((int*)data[1]) dereferences NULL
when field=0, producing the 'Attempt to read from NULL' STOP.

Fix: VALUEPARM(1) = (int)data[1] reads the value without dereferencing.
k (data[0]) remains INTPARM because it is a script variable (passed as
a pointer to the variable's storage, not a literal).

Also add exists(@ConLobbyMission@) guard before MAIL_SET_ROOKIE_MISSION
for defensive safety if the sub-script is not running.

Rebuild required: MW4.exe (Release + Profile).
This commit is contained in:
2026-07-24 09:31:51 -05:00
parent 76121f1c68
commit 7852269dc7
2 changed files with 5 additions and 2 deletions
+3 -1
View File
@@ -12930,10 +12930,12 @@ int __stdcall CTCL_GetAutoSlotMech(void* instance, int args, void* data[])
}
// Returns int field for slot k ? data[0]=int k, data[1]=int field (0=Type 1=Team 2=Skin 3=Decal)
// field is passed as a script literal (0/1/2/3), so use VALUEPARM not INTPARM (literals are passed
// as (void*)N directly, not as pointers; INTPARM would dereference NULL for field=0 and crash).
int __stdcall CTCL_GetAutoSlotInt(void* instance, int args, void* data[])
{
int k = INTPARM(0);
int field = INTPARM(1);
int field = VALUEPARM(1);
if (k < 0 || k >= 16) return 0;
switch (field) {
case 0: return g_aAutoSlots[k].nType;
@@ -1681,7 +1681,8 @@ main
if callback($$CTCL_LoadAutoFile$$)
{
// Apply mission + game options via existing Rookie Mission flow
mail(MAIL_SET_ROOKIE_MISSION, @ConLobbyMission@)
if exists(@ConLobbyMission@)
mail(MAIL_SET_ROOKIE_MISSION, @ConLobbyMission@)
// Clear all slots
o_cam_list.nselected = 0
for (k = 0; k < nRosterCount; k++)