diff --git a/code/network/multi.cpp b/code/network/multi.cpp index d30f7017cce..258e8e377a2 100644 --- a/code/network/multi.cpp +++ b/code/network/multi.cpp @@ -1671,8 +1671,13 @@ void multi_standalone_reset_all() // NETLOG ml_string(NOX("Standalone resetting")); - // shut all game stuff down - game_level_close(); + // shut all game stuff down -- but only if a mission was actually in progress, + // otherwise scripting hooks in game_level_close() may fire into uninitialized + // subsystems (e.g. SEXP nodes never allocated because no mission was loaded) + if (Game_mode & GM_IN_MISSION) { + game_level_close(); + Game_mode &= ~GM_IN_MISSION; + } // reinitialize the gui std_reset_standalone_gui(); diff --git a/code/scripting/api/libs/mission.cpp b/code/scripting/api/libs/mission.cpp index 395c254fda6..2a2ac722bc7 100644 --- a/code/scripting/api/libs/mission.cpp +++ b/code/scripting/api/libs/mission.cpp @@ -201,6 +201,11 @@ ADE_FUNC(evaluateSEXP, l_Mission, "string", "Runs the defined SEXP script, and r if(!ade_get_args(L, "s", &s)) return ADE_RETURN_FALSE; + if (Sexp_nodes == nullptr) { + Warning(LOCATION, "evaluateSEXP called before SEXP system initialized; returning false"); + return ADE_RETURN_FALSE; + } + r_val = run_sexp(s); if (r_val == SEXP_TRUE) @@ -218,6 +223,11 @@ ADE_FUNC(evaluateNumericSEXP, l_Mission, "string", "Runs the defined SEXP script if (!ade_get_args(L, "s", &s)) return ade_set_args(L, "i", 0); + if (Sexp_nodes == nullptr) { + Warning(LOCATION, "evaluateNumericSEXP called before SEXP system initialized; returning NaN"); + return ade_set_args(L, "f", std::numeric_limits::quiet_NaN()); + } + r_val = run_sexp(s, true, &got_nan); if (got_nan) @@ -235,6 +245,11 @@ ADE_FUNC(runSEXP, l_Mission, "string", "Runs the defined SEXP script within a `w if(!ade_get_args(L, "s", &s)) return ADE_RETURN_FALSE; + if (Sexp_nodes == nullptr) { + Warning(LOCATION, "runSEXP called before SEXP system initialized; returning false"); + return ADE_RETURN_FALSE; + } + while (is_white_space(*s)) s++; if (*s != '(')