Fix '-mission' and '-loadlevel' arguments

This commit is contained in:
Louis Gombert
2025-05-11 15:21:54 +02:00
parent ae7d8fbc17
commit 8d39908d88
6 changed files with 56 additions and 47 deletions

View File

@@ -641,6 +641,9 @@
#include <cstdlib>
#include <filesystem>
#include "args.h"
#include "ddio.h"
#include "crossplat.h"
#include "Mission.h"
#include "3d.h"
#include "LoadLevel.h"
@@ -742,6 +745,26 @@ void InitMission() {
}
atexit(ResetMission);
}
void InitDefaultMissionFromCLI() {
// Load mission on startup
int mission_arg = FindArg("-mission");
if (mission_arg > 0) {
std::filesystem::path filename = std::filesystem::path(GameArgs[mission_arg + 1]).filename().replace_extension(".mn3");
LoadMission((const char*)filename.u8string().c_str());
int level_arg = FindArg("-loadlevel");
if (level_arg > 0) {
int level{std::atoi(GameArgs[level_arg + 1])};
if (level <= 0 || level > Current_mission.num_levels) {
LOG_WARNING << "Invalid level selection, resetting to 1";
level = 1;
}
Current_mission.cur_level = level;
}
}
}
// reset all states for a mission
void ResetMission() {
LOG_INFO << "In ResetMission()";
@@ -1784,14 +1807,16 @@ bool mn3_Open(const std::filesystem::path &mn3file) {
/* Disabled loading scripts from .mn3 files on purpose:
all 64-bit first-party level scripts have already been loaded from `PRIMARY_HOG`.
Mission files contain only Win32 scripts by default, which cannot not be loaded on 64-bit builds.
Reactivate this when we have a proper sandbox system to safely run third-party scripts contained in user-made levels. */
Reactivate this when we have a proper sandbox system to safely run third-party scripts contained in user-made
levels. */
// Osiris_ExtractScriptsFromHog(mn3_handle, true);
}
// do table file stuff.
std::filesystem::path filename = mn3file.stem();
std::filesystem::path voice_hog;
if ((stricmp((const char*)filename.u8string().c_str(), "d3") == 0) || (stricmp((const char*)filename.u8string().c_str(), "training") == 0)) {
if ((stricmp((const char *)filename.u8string().c_str(), "d3") == 0) ||
(stricmp((const char *)filename.u8string().c_str(), "training") == 0)) {
// Open audio hog file
voice_hog = std::filesystem::path("missions") / "d3voice1.hog"; // Audio for levels 1-4
Mission_voice_hog_handle = cf_OpenLibrary(voice_hog);

View File

@@ -294,6 +294,9 @@ const char *GetMissionName(const char *mission);
// initializes mission system.
void InitMission();
// Load the mission and level from CLI arguments
void InitDefaultMissionFromCLI();
// reset all states for a mission
void ResetMission();

View File

@@ -1161,7 +1161,7 @@ bool GameSequencer() {
break;
case RESTORE_GAME_MODE:
case LOADDEMO_MODE:
SetFunctionMode(GAME_MODE); // need to do so sequencer thiks we're in game.
SetFunctionMode(GAME_MODE); // need to do so sequencer thinks we're in game.
break;
}
@@ -1241,14 +1241,6 @@ bool GameSequencer() {
SuspendControls();
EndLevel(1);
SetGameState(GAMESTATE_LVLNEXT);
// This is for HEAT.NET and their tournement mode stuff
// if(FindArg("-doonelevel"))
// SetGameState(GAMESTATE_LVLSTART);
if (FindArg("-doonelevel")) {
SetFunctionMode(QUIT_MODE);
}
break;
case GAMESTATE_LVLNEXT:

View File

@@ -1544,28 +1544,6 @@ void InitIOSystems(bool editor) {
// this one at the end to find our newly build script libraries first
sys_hid = cf_OpenLibrary(PRIMARY_HOG);
// Check to see if there is a -mission command line option
// if there is, attempt to open that hog/mn3 so it can override such
// things as the mainmenu movie, or loading screen
int mission_arg = FindArg("-mission");
if (mission_arg > 0) {
char path_to_mission[_MAX_PATH];
char filename[256];
// get the true filename
ddio_SplitPath(GameArgs[mission_arg + 1], NULL, filename, NULL);
strcat(filename, ".mn3");
// make the full path (it is forced to be on the harddrive since it contains
// textures and stuff).
ddio_MakePath(path_to_mission, LocalD3Dir, "missions", filename, NULL);
if (cfexist(path_to_mission)) {
cf_OpenLibrary(path_to_mission);
} else {
Int3(); // mission not found
}
}
// Initialize debug graph early incase any system uses it in its init
INIT_MESSAGE(("Initializing debug graph."));
DebugGraph_Initialize();
@@ -1864,6 +1842,7 @@ void InitD3Systems1(bool editor) {
// Initialize missions
InitMission();
InitDefaultMissionFromCLI();
// Initializes the ship structure
InitShips();

View File

@@ -1010,13 +1010,13 @@ bool ProcessCommandLine() {
exit_menu = 1;
#endif
}
#ifndef RELEASE
int t = FindArg("-loadlevel");
if (t) {
SimpleStartLevel(GameArgs[t + 1]);
// On first load, enter mission directly if the argument is specified
int missionArg = FindArg("-mission");
static bool missionEntered = false;
if (missionArg && !missionEntered) {
missionEntered = true;
exit_menu = 1;
}
#endif
// at some point the code above sets exit_menu, so we're going to game mode.
if (exit_menu) {
SetFunctionMode(GAME_MODE);

View File

@@ -525,6 +525,16 @@ The following command-line options are available in Descent 3. You can set comma
### Other Options
- `-loadlevel`
**Type:** int
**Default:** Off
**Platform:** all
**Description:** Load a specific level from the mission selected with `-mission`. Only has an effect when `-mission` is specified.
- `-logfile`
**Type:** boolean
@@ -563,7 +573,7 @@ The following command-line options are available in Descent 3. You can set comma
**Platform:** all
**Description:** Loads the specified mission file at startup.
**Description:** Loads the specified mission file at startup. Example: `-mission d3` to load the main campaign. Combine this option with `-loadlevel` to load a specific level from the mission.
- `-pilot <name>`