Convert some functions of Mission.cpp to std::fs::path

This commit is contained in:
Azamat H. Hackimov 2024-09-28 02:42:37 +03:00
parent 7ca92bd1bd
commit 1f1b0d2d88
9 changed files with 168 additions and 191 deletions

View File

@ -1,5 +1,5 @@
/*
* Descent 3
* Descent 3
* Copyright (C) 2024 Parallax Software
*
* This program is free software: you can redistribute it and/or modify
@ -649,7 +649,6 @@
#include "gamefont.h"
#include "grdefs.h"
#include "descent.h"
#include "ddio.h"
#include "d3movie.h"
#include "program.h"
#include "ObjScript.h"
@ -672,51 +671,45 @@
#include "terrain.h"
#include "multi.h"
#include "hud.h"
#include "localization.h"
#include "levelgoal.h"
// ---------------------------------------------------------------------------
// Data
// ---------------------------------------------------------------------------
// Info about the current level
level_info Level_info;
tMission Current_mission;
tLevelNode *Current_level = NULL;
char D3MissionsDir[_MAX_PATH];
tLevelNode *Current_level = nullptr;
std::filesystem::path D3MissionsDir;
extern int Times_game_restored;
extern msn_urls Net_msn_URLs;
// ---------------------------------------------------------------------------
// Function prototypes
// ---------------------------------------------------------------------------
bool InitMissionScript();
void DoEndMission();
void DoMissionMovie(const char *movie);
void FreeMission();
// used in load level callback
void LoadLevelCB(const char *chunk, int curlen, int filelen);
// MN3 based mission functions.
// loads the msn file from the mn3 file specified, specifies the hog and table file.
bool mn3_Open(const char *mn3file);
// returns mission information given the mn3 file.
bool mn3_GetInfo(const char *mn3file, tMissionInfo *msn);
// closes the current mn3 file
void mn3_Close();
static inline bool IS_MN3_FILE(const char *fname) {
char name[PSFILENAME_LEN + 1];
char ext[PSFILENAME_LEN + 1];
ddio_SplitPath(fname, NULL, name, ext);
return (stricmp(ext, ".mn3") == 0) ? true : false;
// MN3 based mission functions.
// returns mission information given the mn3 file.
bool mn3_GetInfo(const std::filesystem::path &mn3file, tMissionInfo *msn);
static inline bool IS_MN3_FILE(const std::filesystem::path &fname) {
std::filesystem::path ext = fname.extension();
return (stricmp(ext.u8string().c_str(), ".mn3") == 0);
}
static inline char *MN3_TO_MSN_NAME(const char *mn3name, char *msnname) {
char fname[PSFILENAME_LEN + 1];
ddio_SplitPath(mn3name, NULL, fname, NULL);
if (stricmp(fname, "d3_2") == 0) {
strcpy(fname, "d3");
static inline std::filesystem::path MN3_TO_MSN_NAME(const std::filesystem::path &mn3name) {
std::filesystem::path fname = std::filesystem::path(mn3name).stem();
if (stricmp(fname.u8string().c_str(), "d3_2") == 0) {
fname = "d3";
}
strcat(fname, ".msn");
strcpy(msnname, fname);
return msnname;
fname.replace_extension(".msn");
return fname;
}
// ---------------------------------------------------------------------------
@ -735,13 +728,13 @@ void InitMission() {
memset(Current_mission.author, 0, MSN_NAMELEN);
memset(Current_mission.email, 0, MSN_URLLEN);
memset(Current_mission.web, 0, MSN_URLLEN);
Current_mission.hog = NULL;
Current_mission.levels = NULL;
Current_mission.filename = NULL;
Current_mission.hog = nullptr;
Current_mission.levels = nullptr;
Current_mission.filename = nullptr;
Current_mission.game_state_flags = 0;
Current_mission.mn3_handle = 0;
// create add on mission directory
ddio_MakePath(D3MissionsDir, LocalD3Dir, "missions", NULL);
D3MissionsDir = std::filesystem::path(LocalD3Dir) / "missions";
std::error_code ec;
std::filesystem::create_directories(D3MissionsDir, ec);
if (ec) {
@ -760,16 +753,17 @@ void ResetMission() {
memset(Current_mission.author, 0, MSN_NAMELEN);
memset(Current_mission.email, 0, MSN_URLLEN);
memset(Current_mission.web, 0, MSN_URLLEN);
Current_mission.hog = NULL;
Current_mission.levels = NULL;
Current_mission.filename = NULL;
Current_mission.hog = nullptr;
Current_mission.levels = nullptr;
Current_mission.filename = nullptr;
Current_mission.game_state_flags = 0;
// clear out old URLs from memory
for (int a = 0; a < MAX_MISSION_URL_COUNT; a++) {
Net_msn_URLs.URL[a][0] = '\0';
for (auto & a : Net_msn_URLs.URL) {
a[0] = '\0';
}
}
#if (defined(OEM) || defined(DEMO))
bool DemoMission(int mode = 0) {
tMission *msn = &Current_mission;
@ -881,7 +875,6 @@ bool DemoMission(int mode = 0) {
bool LoadMission(const char *mssn) {
Times_game_restored = 0;
LOG_INFO << "In LoadMission()";
// ShowProgressScreen(TXT_LOADINGLEVEL);
#if (defined(OEM) || defined(DEMO))
#ifdef OEM
if (stricmp(mssn, "d3oem.mn3") == 0)
@ -902,31 +895,29 @@ bool LoadMission(const char *mssn) {
#endif
#else
// #endif
tLevelNode *lvls = NULL; // Temporary storage for level data.
tLevelNode *lvls = nullptr; // Temporary storage for level data.
tMission *msn;
CFILE *fp = NULL; // Mission file
CFILE *fp = nullptr; // Mission file
char errtext[80]; // Stores error if unable to read mission
char msnfname[_MAX_PATH];
char mission[_MAX_PATH];
std::filesystem::path msnfname;
std::filesystem::path mission;
int srclinenum = 0; // Current line of source.
int curlvlnum; // Current level number
int numlevels; // Number of levels required to read in.
int cur_objective; // current objective reading.
bool indesc; // are we in a multi-line block
bool res = false; // used to specify if no error has occurred.
char pathname[_MAX_PATH];
std::filesystem::path pathname;
ResetMission(); // Reset everything.
// open MN3 if filename passed was an mn3 file.
if (IS_MN3_FILE(mssn)) {
strcpy(mission, mssn);
ddio_MakePath(pathname, "missions", mission, NULL);
mission = mssn;
pathname = std::filesystem::path("missions") / mission;
} else {
strcpy(mission, mssn);
strcpy(pathname, mssn);
strcpy(msnfname, mssn);
// ddio_MakePath(pathname, D3MissionsDir, mission, NULL);
mission = mssn;
pathname = mssn;
msnfname = mssn;
}
if (IS_MN3_FILE(mission)) {
@ -934,7 +925,7 @@ bool LoadMission(const char *mssn) {
strcpy(errtext, TXT_MSN_OPENMN3FAILED);
goto msnfile_error;
}
MN3_TO_MSN_NAME(mission, msnfname);
msnfname = MN3_TO_MSN_NAME(mission);
}
// open mission file
fp = cfopen(msnfname, "rt");
@ -948,7 +939,7 @@ bool LoadMission(const char *mssn) {
srclinenum = 1;
numlevels = -1;
curlvlnum = 0;
indesc = 0;
indesc = false;
cur_objective = -1;
msn->multiplayable = true;
msn->singleplayable = true;
@ -968,7 +959,7 @@ bool LoadMission(const char *mssn) {
CleanupStr(command, srcline, sizeof(command));
CleanupStr(operand, srcline + strlen(command) + 1, sizeof(operand));
if (strlen(command) && indesc)
indesc = 0;
indesc = false;
if (!stricmp(command, "NAME")) {
strncpy(msn->name, operand, MSN_NAMELEN - 1);
} else if (!stricmp(command, "MULTI")) {
@ -994,16 +985,16 @@ bool LoadMission(const char *mssn) {
strcat(msn->desc, operand);
if (indesc)
strcat(msn->desc, "\n");
indesc = 1; // this is a multiline command
indesc = true; // this is a multiline command
} else if (!stricmp(command, "URL")) {
if (curlvlnum != 0) {
strcpy(errtext, TXT_MSN_LVLCOMMAND);
goto msnfile_error;
} else {
for (int a = 0; a < MAX_MISSION_URL_COUNT; a++) {
if (Net_msn_URLs.URL[a][0] == '\0') {
strncpy(Net_msn_URLs.URL[a], operand, MAX_MISSION_URL_LEN - 1);
Net_msn_URLs.URL[a][MAX_MISSION_URL_LEN - 1] = '\0';
for (auto & url : Net_msn_URLs.URL) {
if (url[0] == '\0') {
strncpy(url, operand, MAX_MISSION_URL_LEN - 1);
url[MAX_MISSION_URL_LEN - 1] = '\0';
LOG_INFO.printf("Found a Mission URL: %s", operand);
break;
}
@ -1173,11 +1164,12 @@ bool LoadMission(const char *mssn) {
msn->cur_level = 1;
msn->num_levels = numlevels;
msn->levels = lvls;
msn->filename = mem_strdup(mission);
msn->filename = mem_strdup(mission.u8string().c_str());
msn->game_state_flags = 0;
strcpy(Net_msn_URLs.msnname, mission);
res = true; // everthing is ok.
// if error, print it out, else end.
strcpy(Net_msn_URLs.msnname, mission.u8string().c_str());
res = true; // everything is ok.
// if error, print it out, else end.
msnfile_error:
if (!res) {
char str_text[128];
@ -1203,6 +1195,7 @@ fatal_error:
#endif
return false;
}
void FreeMission() {
// Free up mission script
int i; //,j;
@ -1229,33 +1222,27 @@ void FreeMission() {
mem_free(Current_mission.levels[i].progress);
}
mem_free(Current_mission.levels);
Current_mission.levels = NULL;
Current_mission.levels = nullptr;
}
//@@ if (Current_mission.d3xmod) {
//@@ D3XFreeProgram(Current_mission.d3xmod);
//@@ Current_mission.d3xmod = NULL;
//@@ }
if (Current_mission.hog)
mem_free(Current_mission.hog);
if (Current_mission.filename) {
// these DON't USE mem_free since we use _strdup, which doesn't use our memory routines.
mem_free(Current_mission.filename);
Current_mission.filename = NULL;
Current_mission.filename = nullptr;
}
Current_mission.hog = NULL;
Current_level = NULL;
Current_mission.hog = nullptr;
Current_level = nullptr;
}
#include "localization.h"
#include "levelgoal.h"
// Load the text (goal strings) for a level
void LoadLevelText(const char *level_filename) {
char pathname[_MAX_FNAME], filename[_MAX_FNAME];
void LoadLevelText(const std::filesystem::path &level_filename) {
int n_strings;
ddio_SplitPath(level_filename, pathname, filename, NULL);
strcat(pathname, filename);
strcat(pathname, ".str");
std::filesystem::path pathname = level_filename;
pathname.replace_extension(".str");
char **goal_strings;
if (CreateStringTable(pathname, &goal_strings, &n_strings)) {
if (CreateStringTable(pathname.u8string().c_str(), &goal_strings, &n_strings)) {
int n_goals = Level_goals.GetNumGoals();
ASSERT(n_strings == (n_goals * 3));
for (int i = 0; i < n_goals; i++) {
@ -1272,7 +1259,7 @@ void LoadLevelText(const char *level_filename) {
bool LoadMissionLevel(int level) {
Hud_show_controls = false;
LoadLevelProgress(LOAD_PROGRESS_START, 0);
if (!LoadLevel(Current_mission.levels[level - 1].filename, NULL)) {
if (!LoadLevel(Current_mission.levels[level - 1].filename, nullptr)) {
char buf[128];
snprintf(buf, sizeof(buf), TXT_MSNERROR, Current_mission.levels[level - 1].filename);
SetUICallback(DEFAULT_UICALLBACK);
@ -1307,7 +1294,7 @@ bool LoadMissionLevel(int level) {
#define LOADBAR_W (260 * (float)Max_window_w / (float)FIXED_SCREEN_WIDTH)
#define LOADBAR_H (22 * (float)Max_window_h / (float)FIXED_SCREEN_HEIGHT)
#define N_LOAD_MSGS 12
bool started_page = 0;
/*
$$TABLE_GAMEFILE "tunnelload.ogf"
*/
@ -1338,7 +1325,7 @@ void LoadLevelProgress(int step, float percent, const char *chunk) {
lvl_percent_loaded = 0.0f;
pag_percent_loaded = 0.0f;
dedicated_last_string_len = -1;
const char *p = NULL;
const char *p = nullptr;
if ((!(Game_mode & GM_MULTI)) && (!Current_mission.levels[Current_mission.cur_level - 1].progress)) {
p = "tunnelload.ogf";
} else {
@ -1352,12 +1339,6 @@ void LoadLevelProgress(int step, float percent, const char *chunk) {
n_text_msgs = 0;
}
}
/*
else
{
ShowProgressScreen (TXT_LOADINGLEVEL);
}
*/
Progress_screen_loaded = true;
return;
} break;
@ -1582,17 +1563,20 @@ void LoadLevelProgress(int step, float percent, const char *chunk) {
EndFrame();
rend_Flip();
}
/* this functions performs the end mission code
/**
* This function performs the end mission code
*/
void DoEndMission() {
if (Game_mode & GM_MULTI) // If multiplayer, just loop
{
// If multiplayer, just loop
if (Game_mode & GM_MULTI) {
if (Dedicated_server)
PrintDedicatedMessage(TXT_DS_MISSIONDONE);
SetCurrentLevel(1);
return;
}
}
// Shows some text on a background, useful for telling the player what is going on
// ie "Loading level...", "Receiving data...", etc
void ShowProgressScreen(const char *str, const char *str2, bool flip) {
@ -1615,6 +1599,7 @@ void ShowProgressScreen(const char *str, const char *str2, bool flip) {
if (flip)
rend_Flip();
}
/* does a mission briefing, returns if mission was canceled, a false, or 0 value.
first displays mission goals and some warnings or advice.
may allow for selection of player ships
@ -1678,49 +1663,41 @@ bool InitMissionScript() {
//@@ }
return true;
}
extern bool IsRestoredGame;
void InitLevelScript() {
if (Current_level->filename) {
char filename[_MAX_PATH], ext[_MAX_EXT];
ddio_SplitPath(Current_level->filename, NULL, filename, ext);
#if defined(WIN32)
strcat(filename, ".dll");
#elif defined(MACOSX)
strcat(filename, ".dylib");
#elif defined(__LINUX__)
strcat(filename, ".so");
#else
#error Unsupported platform!
#endif
std::filesystem::path filename = Current_level->filename;
filename.replace_extension(MODULE_EXT);
Osiris_LoadLevelModule(filename);
}
//@$-D3XExecScript(Current_level->d3xthread, Current_mission.cur_level, REF_LEVELTYPE, EVT_LEVELSTART, 0, 0);
tOSIRISEventInfo ei;
tOSIRISEventInfo ei{};
// This is a hack... we don't want the level start script to be called when restoring a save game
if (!IsRestoredGame)
Osiris_CallLevelEvent(EVT_LEVELSTART, &ei);
AssignScriptsForLevel(); // initialize all scripts for level.
}
void FreeLevelScript() {
Osiris_UnloadLevelModule();
if (Current_level) {
// free level's script and thread
//@$-D3XExecScript(Current_level->d3xthread, Current_mission.cur_level, REF_LEVELTYPE, EVT_LEVELEND, 0, 0);
tOSIRISEventInfo ei;
tOSIRISEventInfo ei{};
Osiris_CallLevelEvent(EVT_LEVELEND, &ei);
}
}
// return information about a mission
bool GetMissionInfo(const char *msnfile, tMissionInfo *msn) {
CFILE *fp;
bool GetMissionInfo(const std::filesystem::path &msnfile, tMissionInfo *msn) {
bool indesc = false; // are we in a multi-line block
// open mission file
if (IS_MN3_FILE(msnfile)) {
return mn3_GetInfo(msnfile, msn);
}
fp = cfopen(msnfile, "rt");
CFILE *fp = cfopen(msnfile, "rt");
if (!fp) {
LOG_WARNING.printf("Failed to open mission file %s in GetMissionInfo.", msnfile);
LOG_WARNING.printf("Failed to open mission file %s in GetMissionInfo.", msnfile.u8string().c_str());
return false;
}
msn->multi = true;
@ -1736,8 +1713,7 @@ bool GetMissionInfo(const char *msnfile, tMissionInfo *msn) {
int readcount; // read-in count
readcount = cf_ReadString(srcline, sizeof(srcline), fp);
if (readcount) {
// we have a line of source. parse out primary keyword
// then parse out remainder.
// We have a line of source. Parse out primary keyword then parse out remainder.
keyword = strtok(srcline, " \t");
CleanupStr(command, srcline, sizeof(command));
CleanupStr(operand, srcline + strlen(command) + 1, sizeof(operand));
@ -1756,14 +1732,13 @@ bool GetMissionInfo(const char *msnfile, tMissionInfo *msn) {
} else if (!stricmp(command, "AUTHOR")) {
strncpy(msn->author, operand, MSN_NAMELEN - 1);
} else if (!stricmp(command, "DESCRIPTION") || indesc) {
// multi-line descriptions require the strcat. the initial
// strings should be empty for this to work.
// Multi-line descriptions require the strcat. The initial strings should be empty for this to work.
strcat(msn->desc, operand);
if (indesc)
strcat(msn->desc, "\n");
indesc = true; // this is a multiline command
} else if (!stricmp(command, "NUMLEVELS")) {
// get number of levels
// Get number of levels
int value = atoi(operand);
msn->n_levels = value;
} else if (!stricmp(command, "LEVEL")) {
@ -1777,9 +1752,9 @@ bool GetMissionInfo(const char *msnfile, tMissionInfo *msn) {
cfclose(fp);
return true;
}
// ---------------------------------------------------------------------------
const char *GetMissionName(const char *mission) {
tMissionInfo msninfo;
tMissionInfo msninfo{};
static char msnname[MSN_NAMELEN];
msnname[0] = 0;
if (GetMissionInfo(mission, &msninfo)) {
@ -1789,38 +1764,23 @@ const char *GetMissionName(const char *mission) {
}
return msnname;
}
bool IsMissionMultiPlayable(const char *mission) {
tMissionInfo msninfo;
tMissionInfo msninfo{};
if (GetMissionInfo(mission, &msninfo)) {
return msninfo.multi;
}
return false;
}
bool IsMissionSinglePlayable(const char *mission) {
tMissionInfo msninfo;
if (GetMissionInfo(mission, &msninfo)) {
return msninfo.single;
}
return false;
}
int Mission_voice_hog_handle = 0;
// MN3 based mission functions.
// loads the msn file from the mn3 file specified, specifies the hog and table file.
bool mn3_Open(const char *mn3file) {
char pathname[_MAX_PATH];
char filename[PSFILENAME_LEN + 1];
char ext[PSFILENAME_LEN];
int mn3_handle;
// concatanate the mn3 extension if it isn't there.
char tempMn3File[_MAX_PATH];
if (!IS_MN3_FILE(mn3file)) {
strncpy(tempMn3File, mn3file, sizeof(tempMn3File) - 1);
tempMn3File[sizeof(tempMn3File) - 1] = 0;
strcat(tempMn3File, ".mn3");
mn3file = tempMn3File;
}
ddio_MakePath(pathname, D3MissionsDir, mn3file, NULL);
int Mission_voice_hog_handle = 0;
bool mn3_Open(const std::filesystem::path &mn3file) {
int mn3_handle;
// concatenate the mn3 extension if it isn't there.
std::filesystem::path tempMn3File = mn3file;
tempMn3File.replace_extension(".mn3");
// open MN3 HOG.
mn3_handle = cf_OpenLibrary(mn3file);
if (mn3_handle == 0) {
@ -1829,42 +1789,43 @@ bool mn3_Open(const char *mn3file) {
Osiris_ExtractScriptsFromHog(mn3_handle, true);
}
// do table file stuff.
ddio_SplitPath(mn3file, NULL, filename, ext);
std::filesystem::path filename = mn3file.stem();
char voice_hog[_MAX_PATH*2];
if ((stricmp(filename, "d3") == 0) || (stricmp(filename, "training") == 0)) {
std::filesystem::path voice_hog;
if ((stricmp(filename.u8string().c_str(), "d3") == 0) || (stricmp(filename.u8string().c_str(), "training") == 0)) {
// Open audio hog file
ddio_MakePath(voice_hog, "missions", "d3voice1.hog", nullptr); // Audio for levels 1-4
voice_hog = std::filesystem::path("missions") / "d3voice1.hog"; // Audio for levels 1-4
Mission_voice_hog_handle = cf_OpenLibrary(voice_hog);
} else if (stricmp(filename, "d3_2") == 0) {
} else if (stricmp(filename.u8string().c_str(), "d3_2") == 0) {
// Open audio hog file
ddio_MakePath(voice_hog, "missions", "d3voice2.hog", nullptr); // Audio for levels 5-17
voice_hog = std::filesystem::path("missions") / "d3voice2.hog"; // Audio for levels 5-17
Mission_voice_hog_handle = cf_OpenLibrary(voice_hog);
}
strcat(filename, ".gam");
mng_SetAddonTable(filename);
filename.replace_extension(".gam");
mng_SetAddonTable(filename.u8string().c_str());
Current_mission.mn3_handle = mn3_handle;
return true;
}
// returns mission information given the mn3 file.
bool mn3_GetInfo(const char *mn3file, tMissionInfo *msn) {
bool mn3_GetInfo(const std::filesystem::path &mn3file, tMissionInfo *msn) {
int handle;
bool retval;
char pathname[_MAX_PATH];
char filename[PSFILENAME_LEN + 1];
std::filesystem::path pathname;
std::filesystem::path filename;
ddio_MakePath(pathname, "missions", mn3file, nullptr);
pathname = std::filesystem::path(std::filesystem::path("missions")) / mn3file;
handle = cf_OpenLibrary(pathname);
if (handle == 0) {
LOG_ERROR << "MISSION: MN3 failed to open.";
return false;
}
MN3_TO_MSN_NAME(mn3file, filename);
filename = MN3_TO_MSN_NAME(mn3file);
retval = GetMissionInfo(filename, msn);
cf_CloseLibrary(handle);
return retval;
}
// closes the current mn3 file
void mn3_Close() {
if (Current_mission.mn3_handle) {
@ -1877,12 +1838,14 @@ void mn3_Close() {
}
Current_mission.mn3_handle = 0;
}
#define KEYWORD_LEN 16
#define NUM_KEYWORDS 16
#define GOALSTEXT "GOALS"
#define GOALSTEXTLEN strlen(GOALSTEXT)
#define MODMINGOALS "MINGOALS"
#define MODMINGOALSLEN strlen(MODMINGOALS)
// Returns the max number of teams this mission can support for this mod, or
//-1 if this level shouldn't be played with this mission
// Return values:
@ -1894,7 +1857,6 @@ int MissionGetKeywords(const char *mission, char *keywords) {
char msn_keywords[NUM_KEYWORDS][KEYWORD_LEN];
char mod_keywords[NUM_KEYWORDS][KEYWORD_LEN];
int i;
char *parse_keys = mem_strdup(keywords);
char seps[] = ",";
int teams = MAX_NET_PLAYERS;
@ -1903,7 +1865,7 @@ int MissionGetKeywords(const char *mission, char *keywords) {
int mod_key_count = 0;
int msn_key_count = 0;
bool goal_per_team = false;
tMissionInfo msn_info;
tMissionInfo msn_info{};
memset(msn_keywords, 0, sizeof(msn_keywords));
memset(mod_keywords, 0, sizeof(mod_keywords));
@ -1922,7 +1884,7 @@ int MissionGetKeywords(const char *mission, char *keywords) {
do {
strcpy(mod_keywords[mod_key_count], tokp);
mod_key_count++;
tokp = strtok(NULL, seps);
tokp = strtok(nullptr, seps);
} while ((tokp) && (mod_key_count < NUM_KEYWORDS));
}
// Break up the msn keywords into an array
@ -1931,38 +1893,38 @@ int MissionGetKeywords(const char *mission, char *keywords) {
do {
strcpy(msn_keywords[msn_key_count], tokp);
msn_key_count++;
tokp = strtok(NULL, seps);
tokp = strtok(nullptr, seps);
} while ((tokp) && (msn_key_count < NUM_KEYWORDS));
}
for (i = 0; i < NUM_KEYWORDS; i++) {
if (msn_keywords[i][0] == 0) {
for (auto & msn_keyword : msn_keywords) {
if (msn_keyword[0] == 0) {
continue;
}
if (strnicmp(GOALSTEXT, msn_keywords[i], GOALSTEXTLEN) == 0) {
if (strnicmp(GOALSTEXT, msn_keyword, GOALSTEXTLEN) == 0) {
// Get the number of goals this game has
goals = atoi(msn_keywords[i] + GOALSTEXTLEN);
goals = atoi(msn_keyword + GOALSTEXTLEN);
}
}
mem_free(parse_keys);
// Loop through looking for matches
for (i = 0; i < NUM_KEYWORDS; i++) {
if (mod_keywords[i][0] == 0) {
for (auto & mod_keyword : mod_keywords) {
if (mod_keyword[0] == 0) {
continue;
}
if (strnicmp(mod_keywords[i], MODMINGOALS, MODMINGOALSLEN) == 0) {
goalsneeded = atoi(mod_keywords[i] + MODMINGOALSLEN);
} else if (stricmp("GOALPERTEAM", mod_keywords[i]) == 0) {
if (strnicmp(mod_keyword, MODMINGOALS, MODMINGOALSLEN) == 0) {
goalsneeded = atoi(mod_keyword + MODMINGOALSLEN);
} else if (stricmp("GOALPERTEAM", mod_keyword) == 0) {
goal_per_team = true;
} else {
bool found_keyword = false;
// Loop through looking for matches
for (int a = 0; a < NUM_KEYWORDS; a++) {
if (msn_keywords[a][0] == 0) {
for (auto & msn_keyword : msn_keywords) {
if (msn_keyword[0] == 0) {
continue;
}
if (stricmp(msn_keywords[a], mod_keywords[i]) == 0) {
if (stricmp(msn_keyword, mod_keyword) == 0) {
// Woohoo! it's found
found_keyword = true;
break;
@ -1970,7 +1932,7 @@ int MissionGetKeywords(const char *mission, char *keywords) {
}
// We never found one we needed, so return -1;
if (!found_keyword) {
LOG_WARNING.printf("%s keyword needed in %s not found!", mod_keywords[i], mission);
LOG_WARNING.printf("%s keyword needed in %s not found!", mod_keyword, mission);
return -1;
}
}
@ -1988,6 +1950,7 @@ int MissionGetKeywords(const char *mission, char *keywords) {
}
return teams;
}
//////////////////////////////////////////////////////////////////////////////
#ifdef EDITOR
// Used by editor->game to load all necessary elements for level playing for systems

View File

@ -178,10 +178,10 @@
#define LOAD_PROGRESS_DONE 200
// Load level progress worker
void LoadLevelProgress(int step, float percent, const char *chunk = NULL);
void LoadLevelProgress(int step, float percent, const char *chunk = nullptr);
// array constants
const int MSN_FILENAMELEN = _MAX_PATH, MSN_URLLEN = 256;
// Array constants
const int MSN_URLLEN = 256;
#define MAX_KEYWORDLEN 300
@ -254,7 +254,7 @@ struct tMission {
tLevelNode *levels; // array of levels
};
// structyre used to get information about a mission
// structure used to get information about a mission
struct tMissionInfo {
char name[MSN_NAMELEN];
char author[MSN_NAMELEN];
@ -272,7 +272,19 @@ struct tMissionInfo {
extern tMission Current_mission;
extern tLevelNode *Current_level;
extern char D3MissionsDir[];
extern std::filesystem::path D3MissionsDir;
/**
* Loads the mn3 file, specifies the hog and table file.
* @param mn3file file for loading
* @return true on success
*/
bool mn3_Open(const std::filesystem::path &mn3file);
/**
* Closes the current mn3 file
*/
void mn3_Close();
// Get the name field out of the mission file
const char *GetMissionName(const char *mission);
@ -308,13 +320,18 @@ bool LoadMissionLevel(int level);
bool InitMissionScript();
// Shows text on a background
void ShowProgressScreen(const char *str, const char *str2 = NULL, bool flip = true);
void ShowProgressScreen(const char *str, const char *str2 = nullptr, bool flip = true);
// See if a mission file is multiplayer playable.
bool IsMissionMultiPlayable(const char *mission);
// return information about a mission
bool GetMissionInfo(const char *msnfile, tMissionInfo *msn);
/**
* Fill information about a mission.
* @param msnfile mission file
* @param msn mission info to be filled
* @return true on success
*/
bool GetMissionInfo(const std::filesystem::path &msnfile, tMissionInfo *msn);
// Returns the max number of teams this mission can support for this mod, or
//-1 if this level shouldn't be played with this mission

View File

@ -1138,9 +1138,6 @@ extern matrix editor_player_orient;
extern int editor_player_roomnum;
#endif
extern bool mn3_Open(const char *mn3file);
extern void mn3_Close();
extern bool Game_gauge_do_time_test;
extern char Game_gauge_usefile[_MAX_PATH];
@ -1455,7 +1452,7 @@ void DeleteAmbientObjects() {
void Localization_SetLanguage(int type);
int Localization_GetLanguage(void);
void LoadLevelText(const char *level_filename);
void LoadLevelText(const std::filesystem::path &level_filename);
// Starts the level, which has already been loaded
void StartLevel() {

View File

@ -602,8 +602,8 @@ int msn_CheckGetMission(network_address *net_addr, char *filename) {
return 1;
#else
// Don't download local missions
char pathname[_MAX_PATH];
ddio_MakePath(pathname, D3MissionsDir, filename, NULL);
std::filesystem::path pathname;
pathname = D3MissionsDir / filename;
if (cfexist(filename) || cfexist(pathname)) {
return 1;
}

View File

@ -826,7 +826,7 @@ void MultiStartServer(int playing, char *scriptname, int dedicated_server_num_te
//-1 Not compatible!
//>=0 Number of teams supported for this mod & level
#define SCRIPTBADFORMISSION -1
#define SCRIPTBADFORMISSION (-1)
int CheckMissionForScript(char *mission, char *script, int dedicated_server_num_teams) {
char mod_keys[MAX_KEYWORDLEN];

View File

@ -89,7 +89,7 @@ void mng_ClearAddonTables();
// Push the given table file as an addon table file
// returns true on success
bool mng_SetAddonTable(char *name);
bool mng_SetAddonTable(const char *name);
// Pushes an addon pack onto the stack so we can keep track of it
void mng_PushAddonPage(int pagetype, char *name, int overlay);

View File

@ -2729,7 +2729,7 @@ void mng_ClearAddonTables() {
}
// Push the given table file as an addon table file
// returns true on success
bool mng_SetAddonTable(char *name) {
bool mng_SetAddonTable(const char *name) {
ASSERT(Num_addon_tables < MAX_ADDON_TABLES);
if (Num_addon_tables >= MAX_ADDON_TABLES)
return false;

View File

@ -325,7 +325,7 @@ void (*DLLCheckBoxSetCheck)(void *cb, bool state);
bool (*DLLCheckBoxIsChecked)(void *cb);
uint32_t (*DLLnw_GetHostAddressFromNumbers)(char *str);
void (*TableFilesClear)(void);
bool (*TableFileAdd)(char *filename);
bool (*TableFileAdd)(const char *filename);
void (*DLLDebugBreak_callback_stop)(void);
void (*DLLDebugBreak_callback_resume)(void);
void (*DLLInt3MessageBox)(const char *file, const char *line);

View File

@ -928,7 +928,7 @@ typedef void (*TableFilesClear_fp)(void);
DMFCDLLOUT(TableFilesClear_fp TableFilesClear;)
// Adds a table file into the manage system for add-on data
typedef bool (*TableFileAdd_fp)(char *filename);
typedef bool (*TableFileAdd_fp)(const char *filename);
DMFCDLLOUT(TableFileAdd_fp TableFileAdd;)
// Debugger interaction