// Baker: begin "game2" modification
i = COM_CheckParm ("-game2");
if (i && i < com_argc-1)
{
com_modified = true;
COM_AddGameDirectory (va("%s/%s", basedir, com_argv[i+1]));
}
// Baker: end "game2" modification
Commentary on the functionality:
If you modify, say, FitzQuake using the above, start the engine with this command as an example:
// Note: you need to have maps or models or such in both gamedirs for this to be interesting c:\quake\fitzquake085.exe -game mymod -game2 mymod2
Now here is how multiple gamedir works.
Folder priority is this:
Content chain of priority: game2 > game > id1
Quake's file system will first search for data in -game2 (mymod2 folder) and then fall back to -game (mymod folder) and then to id1 folder.
It will not run multiple progs.dat at the same time like some newcomers would hope. Like "-game ctf -game2 slide" would not suddenly give you Capture The Flag with hoverboards (it would run the progs.dat in -game2, in this case "Slide" and you'd be playing the Slide mod with the CTF folder models and maps available where not superceded by anything with the same filename in the Slide folder).
Anyway, as far as file priority goes -game2 has priority over -game.
So the progs.dat in -game2 would be used over a progs.dat in -game, which in turn has priority over a progs.dat in id1.
One thing this can be used for is doing an additive mod where you are extending some other mod while keeping the content separate. The Quoth mod uses this philosophy where a mapper can make their own stuff and put in "my_mapmod_folder" while falling back to the extended Quoth content.
The night is young. How else can I annoy the world before sunsrise? Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
two notes: first, you may need to increase MAX_HANDLES (a handle is needed for each pak file and another one for the lose files in a gamedir) -- with this feature added i think you will need 33 handles. (might have to check the math on that)
second, i think the right way to do this would be to add darkplaces style multi-gamedir support, where a single "gamedir" command (equivalent to "game" in fitzquake) takes multiple arguments:
metlslime wrote:second, i think the right way to do this would be to add darkplaces style multi-gamedir support, where a single "gamedir" command (equivalent to "game" in fitzquake) takes multiple arguments:
// -game <gamedir>
// Adds basedir/gamedir as an override game
// LordHavoc: now supports multiple -game directories
for (i = 1;i < com_argc;i++)
{
if (!com_argv[i])
continue;
if (!strcmp (com_argv[i], "-game") && i < com_argc-1)
{
i++;
com_modified = true;
COM_AddGameDirectory (va("%s/%s", basedir, com_argv[i]));
}
}
I don't recall how FitzQuake stores the game name in a variable somewhere when, for instance, the "game" command is used with no arguments. But that'd need to happen.
DarkPlaces from the code above obviously, the final gamedir when multiple gamedirs are used has top priority
So "-game quoth warp mymod" ... mymod is priority #1, warp #2 and quoth #3
Modifying the existing Host_Game_f in FitzQuake would be a fair bit more work.
The night is young. How else can I annoy the world before sunsrise? Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
/*
==================
Host_Game_f
==================
*/
void Host_Game_f (void)
{
int i;
searchpath_t *search = com_searchpaths;
pack_t *pak;
char pakfile[MAX_OSPATH]; //FIXME: it's confusing to use this string for two different things
if (Cmd_Argc() > 1)
{
if (!registered.value) //disable command for shareware quake
{
Con_Printf("You must have the registered version to use modified games\n");
return;
}
if (strstr(Cmd_Argv(1), ".."))
{
Con_Printf ("Relative pathnames are not allowed.\n");
return;
}
strcpy (pakfile, va("%s/%s", host_parms.basedir, Cmd_Argv(1)));
if (!Q_strcasecmp(pakfile, com_gamedir)) //no change
{
Con_Printf("\"game\" is already \"%s\"\n", COM_SkipPath(com_gamedir));
return;
}
com_modified = true;
//Kill the server
CL_Disconnect ();
Host_ShutdownServer(true);
//Write config file
Host_WriteConfiguration ();
//Kill the extra game if it is loaded
if (NumGames(com_searchpaths) > 1 + com_nummissionpacks)
KillGameDir(com_searchpaths);
strcpy (com_gamedir, pakfile);
if (Q_strcasecmp(Cmd_Argv(1), GAMENAME)) //game is not id1
{
search = Z_Malloc(sizeof(searchpath_t));
strcpy (search->filename, pakfile);
search->next = com_searchpaths;
com_searchpaths = search;
//Load the paks if any are found:
for (i = 0; ; i++)
{
sprintf (pakfile, "%s/pak%i.pak", com_gamedir, i);
pak = COM_LoadPackFile (pakfile);
if (!pak)
break;
search = Z_Malloc(sizeof(searchpath_t));
search->pack = pak;
search->next = com_searchpaths;
com_searchpaths = search;
}
}
//clear out and reload appropriate data
Cache_Flush ();
if (!isDedicated)
{
TexMgr_NewGame ();
Draw_NewGame ();
R_NewGame ();
}
ExtraMaps_NewGame ();
//Cbuf_InsertText ("exec quake.rc\n");
Con_Printf("\"game\" changed to \"%s\"\n", COM_SkipPath(com_gamedir));
}
else //Diplay the current gamedir
Con_Printf("\"game\" is \"%s\"\n", COM_SkipPath(com_gamedir));
}
The night is young. How else can I annoy the world before sunsrise? Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
With not to use a cvar, allowing one to set a DOS/Unix-like search path via console (or even thru a nice menu option) and then parse its contents at the game start/restart ?
Any good system should be able to utilize both the command line and the "command" or cvar method of setting a gamedir.
A little bit of sweat and planning to make something "right" is the way to go.
The night is young. How else can I annoy the world before sunsrise? Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..