]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - com_game.c
NudgeOutOfSolid: fix moving entities out of the world in complex cases
[xonotic/darkplaces.git] / com_game.c
index 29446b9cf6384a1ae1209317806a4ccc7ff216c9..0dcde1ea082ec5a55cadd84310df9d0e8d1a95ef 100644 (file)
@@ -1,8 +1,5 @@
 /*
-Copyright (C) 1996-1997 Id Software, Inc.
-Copyright (C) 2000-2020 Ashley Rose "LadyHavoc" Hale
-Copyright (C) 2020 David "Cloudwalk" Knapp
-Copyright (C) 2020 Kristus <kristustf@gmail.com>
+Copyright (C) 2000-2021 DarkPlaces contributors
 
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
@@ -21,7 +18,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 */
 
-#include "quakedef.h"
+#include "darkplaces.h"
+#include "com_game.h"
 
 // Game mods
 
@@ -87,6 +85,7 @@ static const gamemode_info_t gamemode_info [GAME_COUNT] =
 { GAME_MOONHELM,                               GAME_MOONHELM,                          "moonhelm",                             "-moonhelm",                            "MoonHelm",                                     "MoonHelm",                                     "data",         NULL,                   "mh",                           "moonhelm"                              }, // COMMANDLINEOPTION: Game: -moonhelm runs the game MoonHelm
 { GAME_VORETOURNAMENT,                 GAME_VORETOURNAMENT,            "voretournament",               "-voretournament",                      "Vore Tournament",                      "Vore_Tournament",                      "data",         NULL,                   "voretournament",       "voretournament"                }, // COMMANDLINEOPTION: Game: -voretournament runs the multiplayer game Vore Tournament
 { GAME_DOOMBRINGER,                            GAME_DOOMBRINGER,                       "doombringer",                  "-doombringer",                         "DOOMBRINGER",                          "DOOMBRINGER",                          "dbdata",       NULL,                   "doombringer",          "doombringer"                   }, // COMMANDLINEOPTION: Game: -doombringer runs the game DOOMBRINGER
+{ GAME_BATTLEMETAL,                            GAME_NORMAL,                            "battlemetal",                  "-battlemetal",                         "battlemetal",                          "battlemetal",                          "metaldata",    NULL,           "battlemetal",          "battlemetal"                   }, // COMMANDLINEOPTION: Game: -battlemetal runs the game battleMETAL
 };
 
 static void COM_SetGameType(int index);
@@ -119,11 +118,12 @@ void COM_InitGameType (void)
 
 void COM_ChangeGameTypeForGameDirs(void)
 {
-       int i;
+       unsigned i, gamemode_count = sizeof(gamemode_info) / sizeof(gamemode_info[0]);
        int index = -1;
        // this will not not change the gamegroup
+
        // first check if a base game (single gamedir) matches
-       for (i = 0;i < (int)(sizeof (gamemode_info) / sizeof (gamemode_info[0]));i++)
+       for (i = 0; i < gamemode_count; i++)
        {
                if (gamemode_info[i].group == com_startupgamegroup && !(gamemode_info[i].gamedirname2 && gamemode_info[i].gamedirname2[0]))
                {
@@ -131,10 +131,21 @@ void COM_ChangeGameTypeForGameDirs(void)
                        break;
                }
        }
-       // now that we have a base game, see if there is a matching derivative game (two gamedirs)
+       // now that we have a base game, see if there is a derivative game matching the startup one (two gamedirs)
+       // bones_was_here: this prevents a Quake expansion (eg Rogue) getting switched to Quake,
+       // and its gamedirname2 (eg "rogue") being lost from the search path, when adding a miscellaneous gamedir.
+       for (i = 0; i < gamemode_count; i++)
+       {
+               if (gamemode_info[i].group == com_startupgamegroup && (gamemode_info[i].gamedirname2 && gamemode_info[i].gamedirname2[0]) && gamemode_info[i].mode == com_startupgamemode)
+               {
+                       index = i;
+                       break;
+               }
+       }
+       // also see if the first gamedir (from -game parm or gamedir command) matches a derivative game (two/three gamedirs)
        if (fs_numgamedirs)
        {
-               for (i = 0;i < (int)(sizeof (gamemode_info) / sizeof (gamemode_info[0]));i++)
+               for (i = 0; i < gamemode_count; i++)
                {
                        if (gamemode_info[i].group == com_startupgamegroup && (gamemode_info[i].gamedirname2 && gamemode_info[i].gamedirname2[0]) && !strcasecmp(fs_gamedirs[0], gamemode_info[i].gamedirname2))
                        {
@@ -196,7 +207,7 @@ static void COM_SetGameType(int index)
                // if there are spaces in the game's network filter name it would
                // cause parse errors in getservers in dpmaster, so we need to replace
                // them with _ characters
-               strlcpy(gamenetworkfilternamebuffer, gamenetworkfiltername, sizeof(gamenetworkfilternamebuffer));
+               dp_strlcpy(gamenetworkfilternamebuffer, gamenetworkfiltername, sizeof(gamenetworkfilternamebuffer));
                while ((s = strchr(gamenetworkfilternamebuffer, ' ')) != NULL)
                        *s = '_';
                gamenetworkfiltername = gamenetworkfilternamebuffer;