mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-15 08:51:24 +00:00
- WIP level transition refactored to a game independent event system.
This commit is contained in:
parent
1cf0ca3f75
commit
e5e8c02f1d
36 changed files with 536 additions and 368 deletions
|
@ -509,9 +509,7 @@ void GameInterface::Startup()
|
|||
if (!userConfig.nologo && gGameOptions.nGameType == 0) playlogos();
|
||||
else
|
||||
{
|
||||
gamestate = GS_MENUSCREEN;
|
||||
M_StartControlPanel(false);
|
||||
M_SetMenu(NAME_Mainmenu);
|
||||
startmainmenu();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -573,6 +571,13 @@ void GameInterface::FreeGameData()
|
|||
if (BloodINI) delete BloodINI;
|
||||
}
|
||||
|
||||
void GameInterface::FreeLevelData()
|
||||
{
|
||||
EndLevel();
|
||||
::GameInterface::FreeLevelData();
|
||||
}
|
||||
|
||||
|
||||
ReservedSpace GameInterface::GetReservedScreenSpace(int viewsize)
|
||||
{
|
||||
int top = 0;
|
||||
|
|
|
@ -79,6 +79,7 @@ struct GameInterface : ::GameInterface
|
|||
const char* Name() override { return "Blood"; }
|
||||
void app_init() override;
|
||||
bool GenerateSavePic() override;
|
||||
void FreeLevelData() override;
|
||||
void FreeGameData() override;
|
||||
FSavegameInfo GetSaveSig() override;
|
||||
void MenuOpened() override;
|
||||
|
|
|
@ -99,17 +99,6 @@ enum rendmode_t {
|
|||
Iter>=0 && (Next=nextspritestat[Iter], 1); Iter=Next
|
||||
|
||||
|
||||
////////// True Room over Room (YAX == rot -17 of "PRO") //////////
|
||||
#define YAX_ENABLE
|
||||
//#define YAX_DEBUG
|
||||
//#define ENGINE_SCREENSHOT_DEBUG
|
||||
|
||||
#ifdef YAX_ENABLE
|
||||
# if !defined NEW_MAP_FORMAT
|
||||
# define YAX_ENABLE__COMPAT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
////////// yax defs //////////
|
||||
#define SECTORFLD(Sect,Fld, Cf) (*((Cf) ? (§or[Sect].floor##Fld) : (§or[Sect].ceiling##Fld)))
|
||||
|
||||
|
@ -648,7 +637,6 @@ int32_t videoSetGameMode(char davidoption, int32_t daupscaledxdim, int32_t dau
|
|||
void videoSetCorrectedAspect();
|
||||
void videoSetViewableArea(int32_t x1, int32_t y1, int32_t x2, int32_t y2);
|
||||
void renderSetAspect(int32_t daxrange, int32_t daaspect);
|
||||
inline void renderFlushPerms(void) {}
|
||||
|
||||
void plotpixel(int32_t x, int32_t y, char col);
|
||||
FCanvasTexture *renderSetTarget(int16_t tilenume);
|
||||
|
|
|
@ -43,10 +43,18 @@
|
|||
#include "gamestate.h"
|
||||
#include "mmulti.h"
|
||||
#include "gstrings.h"
|
||||
#include "gamecontrol.h"
|
||||
#include "mapinfo.h"
|
||||
|
||||
CVAR(Bool, sv_cheats, true, CVAR_ARCHIVE|CVAR_SERVERINFO)
|
||||
CVAR(Bool, cl_blockcheats, false, 0)
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool CheckCheatmode (bool printmsg, bool sponly)
|
||||
{
|
||||
if ((sponly && netgame) || gamestate != GS_LEVEL)
|
||||
|
@ -76,6 +84,12 @@ bool CheckCheatmode (bool printmsg, bool sponly)
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void genericCheat(int player, uint8_t** stream, bool skip)
|
||||
{
|
||||
int cheat = ReadByte(stream);
|
||||
|
@ -94,6 +108,11 @@ void genericCheat(int player, uint8_t** stream, bool skip)
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
CCMD(god)
|
||||
{
|
||||
|
@ -140,6 +159,12 @@ CCMD(allmap)
|
|||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
CCMD(give)
|
||||
{
|
||||
static const char* type[] = { "ALL","AMMO","ARMOR","HEALTH","INVENTORY","ITEMS","KEYS","WEAPONS",nullptr };
|
||||
|
@ -166,4 +191,251 @@ CCMD(give)
|
|||
Net_WriteByte(DEM_GIVE);
|
||||
Net_WriteByte(found);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void CompleteLevel(MapRecord* map)
|
||||
{
|
||||
gameaction = ga_completed;
|
||||
g_nextmap = !currentLevel || !(currentLevel->flags & MI_FORCEEOG)? map : nullptr;
|
||||
g_nextskill = -1; // This does not change the skill
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void changeMap(int player, uint8_t** stream, bool skip)
|
||||
{
|
||||
int skill = (int8_t)ReadByte(stream);
|
||||
auto mapname = ReadStringConst(stream);
|
||||
if (skip) return;
|
||||
auto map = FindMapByName(mapname);
|
||||
if (map || *mapname == 0) // mapname = "" signals end of episode
|
||||
{
|
||||
gameaction = ga_completed;
|
||||
g_nextmap = map;
|
||||
g_nextskill = skill;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void ChangeLevel(MapRecord* map, int skill)
|
||||
{
|
||||
Net_WriteByte(DEM_CHANGEMAP);
|
||||
Net_WriteByte(skill);
|
||||
Net_WriteString(map->labelName);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void DeferedStartGame(MapRecord* map, int skill)
|
||||
{
|
||||
g_nextmap = map;
|
||||
g_nextskill = skill;
|
||||
gameaction = ga_newgame;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static MapRecord* levelwarp_common(FCommandLine& argv, const char *cmdname, const char *t2)
|
||||
{
|
||||
int numparm = g_gameType & (GAMEFLAG_SW | GAMEFLAG_PSEXHUMED) ? 1 : 2; // Handle games with episodic and non-episodic level order.
|
||||
if (argv.argc() <= numparm)
|
||||
{
|
||||
if (numparm == 2) Printf(PRINT_BOLD, "%s <e> <m>: %s episode 'e' and map 'm'\n", cmdname, t2);
|
||||
else Printf(PRINT_BOLD, "%s <m>: %s map 'm'\n", cmdname, t2);
|
||||
return nullptr;
|
||||
}
|
||||
// Values are one-based.
|
||||
int e = numparm == 2 ? atoi(argv[1]) : 0;
|
||||
int m = atoi(numparm == 2 ? argv[2] : argv[1]);
|
||||
if (e <= 0 || m <= 0)
|
||||
{
|
||||
Printf(PRINT_BOLD, "Invalid level! Numbers must be > 0\n");
|
||||
return nullptr;
|
||||
}
|
||||
auto map = FindMapByLevelNum(levelnum(e - 1, m - 1));
|
||||
if (!map)
|
||||
{
|
||||
if (numparm == 2) Printf(PRINT_BOLD, "Level E%s L%s not found!\n", argv[1], argv[2]);
|
||||
else Printf(PRINT_BOLD, "Level %s not found!\n", argv[1]);
|
||||
return nullptr;
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
CCMD(levelwarp)
|
||||
{
|
||||
if (gamestate != GS_LEVEL)
|
||||
{
|
||||
Printf("Use the startgame command when not in a game.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (/*!players[consoleplayer].settings_controller &&*/ netgame)
|
||||
{
|
||||
Printf("Only setting controllers can change the map.\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
auto map = levelwarp_common(argv, "levelwarp", "warp to");
|
||||
if (map)
|
||||
{
|
||||
ChangeLevel(map, -1);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
CCMD(startgame)
|
||||
{
|
||||
if (netgame)
|
||||
{
|
||||
Printf("Use " TEXTCOLOR_BOLD "levelwarp" TEXTCOLOR_NORMAL " instead. " TEXTCOLOR_BOLD "startgame"
|
||||
TEXTCOLOR_NORMAL " is for single-player only.\n");
|
||||
return;
|
||||
}
|
||||
auto map = levelwarp_common(argv, "start game", "start new game at");
|
||||
if (map)
|
||||
{
|
||||
DeferedStartGame(map, -1);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
CCMD(changemap)
|
||||
{
|
||||
if (argv.argc() < 2)
|
||||
{
|
||||
Printf(PRINT_BOLD, "changemap <mapname>: warp to the given map, identified by its name.\n");
|
||||
return;
|
||||
}
|
||||
if (gamestate != GS_LEVEL)
|
||||
{
|
||||
Printf("Use the map command when not in a game.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (/*!players[consoleplayer].settings_controller &&*/ netgame)
|
||||
{
|
||||
Printf("Only setting controllers can change the map.\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
FString mapname = argv[1];
|
||||
FString mapfilename = mapname;
|
||||
DefaultExtension(mapfilename, ".map");
|
||||
|
||||
auto map = FindMapByName(mapname);
|
||||
if (map == nullptr)
|
||||
{
|
||||
// got a user map
|
||||
Printf(PRINT_BOLD, "%s: Map not defined.\n", mapname.GetChars());
|
||||
return;
|
||||
}
|
||||
if (map->flags & MI_USERMAP)
|
||||
{
|
||||
// got a user map
|
||||
Printf(PRINT_BOLD, "%s: Cannot warp to user maps.\n", mapname.GetChars());
|
||||
return;
|
||||
}
|
||||
ChangeLevel(map, -1);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
CCMD(map)
|
||||
{
|
||||
if (argv.argc() < 2)
|
||||
{
|
||||
Printf(PRINT_BOLD, "map <mapname>: start new game at the given map, identified by its name.\n");
|
||||
return;
|
||||
}
|
||||
if (netgame)
|
||||
{
|
||||
Printf("Use " TEXTCOLOR_BOLD "changemap" TEXTCOLOR_NORMAL " instead. " TEXTCOLOR_BOLD "map"
|
||||
TEXTCOLOR_NORMAL " is for single-player only.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
FString mapname = argv[1];
|
||||
FString mapfilename = mapname;
|
||||
DefaultExtension(mapfilename, ".map");
|
||||
|
||||
// Check if the map is already defined.
|
||||
auto map = FindMapByName(mapname);
|
||||
if (map == nullptr)
|
||||
{
|
||||
// got a user map
|
||||
if (g_gameType & GAMEFLAG_SHAREWARE)
|
||||
{
|
||||
Printf(PRINT_BOLD, "Cannot use user maps in shareware.\n");
|
||||
return;
|
||||
}
|
||||
map = SetupUserMap(mapfilename, g_gameType & GAMEFLAG_DUKE? "dethtoll.mid" : nullptr);
|
||||
}
|
||||
if (map)
|
||||
{
|
||||
DeferedStartGame(map, -1);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
CCMD(restartmap)
|
||||
{
|
||||
if (gamestate != GS_LEVEL || currentLevel == nullptr)
|
||||
{
|
||||
Printf("Must be in a game to restart a level.\n");
|
||||
return;
|
||||
}
|
||||
ChangeLevel(currentLevel, -1);
|
||||
}
|
||||
|
|
|
@ -7,3 +7,4 @@
|
|||
EXTERN_CVAR(Bool, sv_cheats)
|
||||
|
||||
void genericCheat(int player, uint8_t** stream, bool skip);
|
||||
void changeMap(int player, uint8_t** stream, bool skip);
|
||||
|
|
|
@ -1664,6 +1664,7 @@ bool D_CheckNetGame (void)
|
|||
// First install the global net command handlers
|
||||
|
||||
Net_SetCommandHandler(DEM_GENERICCHEAT, genericCheat);
|
||||
Net_SetCommandHandler(DEM_CHANGEMAP, changeMap);
|
||||
|
||||
for (i = 0; i < MAXNETNODES; i++)
|
||||
{
|
||||
|
|
|
@ -122,6 +122,11 @@ CCMD(togglefollow)
|
|||
cycle_t thinktime, actortime, gameupdatetime, drawtime;
|
||||
|
||||
gamestate_t gamestate = GS_STARTUP;
|
||||
gameaction_t gameaction = ga_nothing;
|
||||
// gameaction state
|
||||
MapRecord* g_nextmap;
|
||||
int g_nextskill;
|
||||
|
||||
|
||||
FILE* hashfile;
|
||||
|
||||
|
@ -1182,3 +1187,11 @@ void startmainmenu()
|
|||
FX_StopAllSounds();
|
||||
}
|
||||
|
||||
|
||||
void GameInterface::FreeLevelData()
|
||||
{
|
||||
// Make sure that there is no more level to toy around with.
|
||||
initspritelists();
|
||||
numsectors = numwalls = 0;
|
||||
currentLevel = nullptr;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,12 @@ extern bool AppActive;
|
|||
extern cycle_t drawtime, actortime, thinktime, gameupdatetime;
|
||||
extern bool r_NoInterpolate;
|
||||
|
||||
struct MapRecord;
|
||||
struct FSaveGameNode;
|
||||
extern MapRecord* g_nextmap;
|
||||
extern int g_nextskill;
|
||||
extern FSaveGameNode* g_savenode;
|
||||
|
||||
extern FMemArena dump; // this is for memory blocks than cannot be deallocated without some huge effort. Put them in here so that they do not register on shutdown.
|
||||
|
||||
extern TMap<FName, int32_t> NameToTileIndex;
|
||||
|
@ -50,6 +56,9 @@ void CONFIG_ReadCombatMacros();
|
|||
int GameMain();
|
||||
void startmainmenu();
|
||||
void updatePauseStatus();
|
||||
void DeferedStartGame(MapRecord* map, int skill);
|
||||
void ChangeLevel(MapRecord* map, int skill);
|
||||
void CompleteLevel(MapRecord* map);
|
||||
|
||||
struct UserConfig
|
||||
{
|
||||
|
|
|
@ -21,4 +21,20 @@ enum gamestate_t : int
|
|||
GS_FORCEWIPEMELT = -4
|
||||
};
|
||||
|
||||
enum gameaction_t : int
|
||||
{
|
||||
ga_nothing,
|
||||
ga_startup, // go back to intro after uninitializing the game state
|
||||
ga_mainmenu, // go back to main menu after uninitializing the game state
|
||||
ga_newgame, // start a new game
|
||||
ga_recordgame, // start a new demo recording (later)
|
||||
ga_loadgame, // load a savegame and resume play.
|
||||
ga_loadgameplaydemo, // load a savegame and play a demo.
|
||||
ga_autoloadgame, // load last autosave and resume play.
|
||||
ga_savegame, // save the game
|
||||
ga_autosave, // autosave the game (for triggering a save from within the game.)
|
||||
ga_completed, // Level was exited.
|
||||
ga_nextlevel // Actually start the next level.
|
||||
};
|
||||
extern gamestate_t gamestate;
|
||||
extern gameaction_t gameaction;
|
||||
|
|
|
@ -23,8 +23,6 @@ struct FNewGameStartup
|
|||
int Episode;
|
||||
int Level;
|
||||
int Skill;
|
||||
int CustomLevel1;
|
||||
int CustomLevel2;
|
||||
};
|
||||
|
||||
struct FSavegameInfo
|
||||
|
@ -56,6 +54,7 @@ struct ReservedSpace
|
|||
};
|
||||
|
||||
enum EMenuSounds : int;
|
||||
struct MapRecord;
|
||||
|
||||
extern cycle_t drawtime, actortime, thinktime, gameupdatetime;
|
||||
|
||||
|
@ -67,6 +66,7 @@ struct GameInterface
|
|||
virtual void app_init() = 0;
|
||||
virtual void clearlocalinputstate() {}
|
||||
virtual void UpdateScreenSize() {}
|
||||
virtual void FreeLevelData();
|
||||
virtual void FreeGameData() {}
|
||||
virtual void PlayHudSound() {}
|
||||
virtual GameStats getStats() { return {}; }
|
||||
|
@ -86,7 +86,6 @@ struct GameInterface
|
|||
virtual bool SaveGame(FSaveGameNode*) { return true; }
|
||||
virtual bool LoadGame(FSaveGameNode*) { return true; }
|
||||
virtual void SerializeGameState(FSerializer& arc) {}
|
||||
virtual bool CleanupForLoad() { return true; }
|
||||
virtual void DrawPlayerSprite(const DVector2& origin, bool onteam) {}
|
||||
virtual void QuitToTitle() {}
|
||||
virtual void SetAmbience(bool on) {}
|
||||
|
@ -104,6 +103,9 @@ struct GameInterface
|
|||
virtual int GetPlayerChecksum(int pnum) { return 0x12345678 + pnum; }
|
||||
virtual const char *CheckCheatMode() { return nullptr; }
|
||||
virtual const char* GenericCheat(int player, int cheat) = 0;
|
||||
virtual void NextLevel(MapRecord* map, int skill) {}
|
||||
virtual void NewGame(MapRecord* map, int skill) {}
|
||||
virtual void LevelCompleted(MapRecord* map, int skill) {}
|
||||
|
||||
virtual FString statFPS()
|
||||
{
|
||||
|
|
|
@ -83,6 +83,7 @@
|
|||
#include "palette.h"
|
||||
#include "build.h"
|
||||
#include "g_input.h"
|
||||
#include "mapinfo.h"
|
||||
|
||||
CVAR(Bool, vid_activeinbackground, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
CVAR(Bool, r_ticstability, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
|
@ -125,16 +126,75 @@ static void GameTicker()
|
|||
|
||||
handleevents();
|
||||
|
||||
#if 0
|
||||
// Todo: Migrate state changes to here instead of doing them ad-hoc
|
||||
while (gameaction != ga_nothing)
|
||||
{
|
||||
switch (gameaction)
|
||||
auto ga = gameaction;
|
||||
gameaction = ga_nothing;
|
||||
switch (ga)
|
||||
{
|
||||
case ga_autoloadgame:
|
||||
// todo: for now just handle the restart case
|
||||
g_nextmap = currentLevel;
|
||||
g_nextskill = -1;
|
||||
FX_StopAllSounds();
|
||||
FX_SetReverb(0);
|
||||
gi->NextLevel(currentLevel, -1);
|
||||
break;
|
||||
|
||||
case ga_completed:
|
||||
FX_StopAllSounds();
|
||||
FX_SetReverb(0);
|
||||
if (g_nextmap == currentLevel)
|
||||
{
|
||||
// if the same level is restarted, skip any progression stuff like summary screens or cutscenes.
|
||||
gi->FreeLevelData();
|
||||
gi->NextLevel(currentLevel, g_nextskill);
|
||||
}
|
||||
else
|
||||
gi->LevelCompleted(g_nextmap, g_nextskill);
|
||||
break;
|
||||
|
||||
case ga_nextlevel:
|
||||
gi->FreeLevelData();
|
||||
gi->NextLevel(currentLevel, g_nextskill);
|
||||
break;
|
||||
|
||||
case ga_newgame:
|
||||
FX_StopAllSounds();
|
||||
FX_SetReverb(0);
|
||||
gi->FreeLevelData();
|
||||
gi->NewGame(g_nextmap, g_nextskill);
|
||||
break;
|
||||
|
||||
case ga_startup:
|
||||
gi->FreeLevelData();
|
||||
gamestate = GS_STARTUP;
|
||||
break;
|
||||
|
||||
case ga_mainmenu:
|
||||
gi->FreeLevelData();
|
||||
startmainmenu();
|
||||
break;
|
||||
|
||||
case ga_savegame:
|
||||
// We only need this for multiplayer saves that need to go through the network.
|
||||
// gi->SaveGame();
|
||||
break;
|
||||
|
||||
case ga_autosave:
|
||||
M_Autosave();
|
||||
break;
|
||||
|
||||
// for later
|
||||
// case ga_recordgame, // start a new demo recording (later)
|
||||
// case ga_loadgameplaydemo, // load a savegame and play a demo.
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
C_AdjustBottom();
|
||||
}
|
||||
#endif
|
||||
|
||||
// get commands, check consistancy, and build new consistancy check
|
||||
int buf = (gametic / ticdup) % BACKUPTICS;
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
|
||||
#include "mapinfo.h"
|
||||
#include "raze_music.h"
|
||||
#include "filesystem.h"
|
||||
#include "printf.h"
|
||||
|
||||
MapRecord mapList[512]; // Due to how this gets used it needs to be static. EDuke defines 7 episode plus one spare episode with 64 potential levels each and relies on the static array which is freely accessible by scripts.
|
||||
MapRecord *currentLevel; // level that is currently played. (The real level, not what script hacks modfifying the current level index can pretend.)
|
||||
|
@ -127,6 +129,13 @@ MapRecord* SetupUserMap(const char* boardfilename, const char *defaultmusic)
|
|||
return ↦
|
||||
}
|
||||
}
|
||||
|
||||
if (!fileSystem.FileExists(boardfilename))
|
||||
{
|
||||
Printf(TEXTCOLOR_RED "map: file \"%s\" not found.\n", boardfilename);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto map = AllocateMap();
|
||||
map->name = "";
|
||||
map->SetFileName(boardfilename);
|
||||
|
|
|
@ -61,6 +61,7 @@ struct MapRecord
|
|||
}
|
||||
void SetFileName(const char* n)
|
||||
{
|
||||
if (*n == '/' || *n == '\\') n++;
|
||||
fileName = n;
|
||||
FixPathSeperator(fileName);
|
||||
labelName = ExtractFileBase(n);
|
||||
|
|
|
@ -434,12 +434,10 @@ bool M_SetMenu(FName menu, int param, FName caller)
|
|||
switch (caller.GetIndex())
|
||||
{
|
||||
case NAME_Episodemenu:
|
||||
case NAME_HuntMenu:
|
||||
case NAME_TargetMenu:
|
||||
// sent from the episode menu
|
||||
NewGameStartupInfo.Episode = param;
|
||||
NewGameStartupInfo.Level = 0;
|
||||
NewGameStartupInfo.CustomLevel1 = NewGameStartupInfo.CustomLevel2 = -1;
|
||||
NewGameStartupInfo.Skill = gDefaultSkill;
|
||||
break;
|
||||
|
||||
|
@ -447,26 +445,6 @@ bool M_SetMenu(FName menu, int param, FName caller)
|
|||
NewGameStartupInfo.Skill = param;
|
||||
break;
|
||||
|
||||
case NAME_CustomGameMenu:
|
||||
NewGameStartupInfo.CustomLevel1 = param;
|
||||
NewGameStartupInfo.CustomLevel2 = -1;
|
||||
NewGameStartupInfo.Episode = 0; // Set start to E1L1 so that even if the script fails to set the starting level it is set to something valid.
|
||||
NewGameStartupInfo.Level = 0;
|
||||
NewGameStartupInfo.Skill = gDefaultSkill;
|
||||
gi->CustomMenuSelection(param, -1);
|
||||
break;
|
||||
|
||||
case NAME_CustomSubMenu1:
|
||||
case NAME_CustomSubMenu2:
|
||||
case NAME_CustomSubMenu3:
|
||||
case NAME_CustomSubMenu4:
|
||||
case NAME_CustomSubMenu5:
|
||||
case NAME_CustomSubMenu6:
|
||||
case NAME_CustomSubMenu7:
|
||||
NewGameStartupInfo.CustomLevel2 = param;
|
||||
gi->CustomMenuSelection(NewGameStartupInfo.CustomLevel1, param);
|
||||
break;
|
||||
|
||||
case NAME_Skillmenu:
|
||||
NewGameStartupInfo.Skill = param;
|
||||
break;
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include "serializer.h"
|
||||
#include "findfile.h"
|
||||
#include "inputstate.h"
|
||||
#include "gamestate.h"
|
||||
|
||||
|
||||
FSavegameManager savegameManager;
|
||||
|
@ -60,14 +61,12 @@ FSavegameManager savegameManager;
|
|||
void FSavegameManager::LoadGame(FSaveGameNode* node)
|
||||
{
|
||||
inputState.ClearAllInput();
|
||||
if (gi->CleanupForLoad())
|
||||
gi->FreeLevelData();
|
||||
if (OpenSaveGameForRead(node->Filename))
|
||||
{
|
||||
if (OpenSaveGameForRead(node->Filename))
|
||||
if (gi->LoadGame(node))
|
||||
{
|
||||
if (gi->LoadGame(node))
|
||||
{
|
||||
// do something here?
|
||||
}
|
||||
// do something here?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -576,6 +575,7 @@ static int nextquicksave = -1;
|
|||
|
||||
void M_Autosave()
|
||||
{
|
||||
if (disableautosave) return;
|
||||
if (!gi->CanSave()) return;
|
||||
FString description;
|
||||
FString file;
|
||||
|
@ -602,8 +602,7 @@ void M_Autosave()
|
|||
|
||||
CCMD(autosave)
|
||||
{
|
||||
if (disableautosave) return;
|
||||
M_Autosave();
|
||||
gameaction = ga_autosave;
|
||||
}
|
||||
|
||||
CCMD(rotatingquicksave)
|
||||
|
|
|
@ -267,7 +267,8 @@ void GameInterface::Startup()
|
|||
}
|
||||
else
|
||||
{
|
||||
DoTitle([](bool) { startmainmenu(); });
|
||||
if (!userConfig.nologo) DoTitle([](bool) { startmainmenu(); });
|
||||
else startmainmenu();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -968,7 +968,7 @@ public:
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void dobonus_d(bool bonusonly, const CompletionFunc& completion)
|
||||
void dobonus_d(int bonusonly, const CompletionFunc& completion)
|
||||
{
|
||||
JobDesc jobs[20];
|
||||
int job = 0;
|
||||
|
@ -976,7 +976,7 @@ void dobonus_d(bool bonusonly, const CompletionFunc& completion)
|
|||
FX_StopAllSounds();
|
||||
Mus_Stop();
|
||||
|
||||
if (!bonusonly && numplayers < 2 && ud.eog && ud.from_bonus == 0)
|
||||
if (bonusonly < 0 && numplayers < 2 && ud.from_bonus == 0)
|
||||
{
|
||||
bonussequence_d(volfromlevelnum(currentLevel->levelNumber), jobs, job);
|
||||
}
|
||||
|
@ -985,7 +985,7 @@ void dobonus_d(bool bonusonly, const CompletionFunc& completion)
|
|||
{
|
||||
jobs[job++] = { Create<DDukeMultiplayerBonusScreen>(playerswhenstarted) };
|
||||
}
|
||||
else if (!bonusonly && ud.multimode <= 1)
|
||||
else if (bonusonly <= 0 && ud.multimode <= 1)
|
||||
{
|
||||
jobs[job++] = { Create<DDukeLevelSummaryScreen>() };
|
||||
}
|
||||
|
@ -1081,68 +1081,4 @@ void PrintLevelName_d(double alpha)
|
|||
BigText(160, 114, currentLevel->DisplayName(), alpha);
|
||||
}
|
||||
|
||||
// Utility for testing the above screens
|
||||
CCMD(testscreen)
|
||||
{
|
||||
JobDesc jobs[10];
|
||||
int job = 0;
|
||||
C_HideConsole();
|
||||
FX_StopAllSounds();
|
||||
Mus_Stop();
|
||||
|
||||
auto gs = gamestate;
|
||||
auto completion = [=](bool)
|
||||
{
|
||||
if (gs == GS_LEVEL || gs == GS_MENUSCREEN) gamestate = gs;
|
||||
else gamestate = GS_STARTUP;
|
||||
};
|
||||
|
||||
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
int screen = strtol(argv[1], nullptr, 0);
|
||||
switch (screen)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
bonussequence_d(screen, jobs, job);
|
||||
RunScreenJob(jobs, job, completion);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
e4intro(nullptr);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
jobs[job++] = { Create<DDukeMultiplayerBonusScreen>(6) };
|
||||
RunScreenJob(jobs, job, completion);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
showtwoscreens(nullptr);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
doorders(nullptr);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
jobs[job++] = { Create<DDukeLevelSummaryScreen>() };
|
||||
RunScreenJob(jobs, job, completion);
|
||||
break;
|
||||
|
||||
case 10:
|
||||
ud.eog = true;
|
||||
jobs[job++] = { Create<DDukeLevelSummaryScreen>() };
|
||||
RunScreenJob(jobs, job, completion);
|
||||
ud.eog = false;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
END_DUKE_NS
|
||||
|
|
|
@ -556,7 +556,7 @@ public:
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void dobonus_r(bool bonusonly, const CompletionFunc& completion)
|
||||
void dobonus_r(int bonusonly, const CompletionFunc& completion)
|
||||
{
|
||||
JobDesc jobs[20];
|
||||
int job = 0;
|
||||
|
@ -564,7 +564,7 @@ void dobonus_r(bool bonusonly, const CompletionFunc& completion)
|
|||
FX_StopAllSounds();
|
||||
Mus_Stop();
|
||||
|
||||
if (!bonusonly && !isRRRA() && numplayers < 2 && ud.eog && ud.from_bonus == 0)
|
||||
if (bonusonly < 0 && !isRRRA() && numplayers < 2 && ud.from_bonus == 0)
|
||||
{
|
||||
int vol = volfromlevelnum(currentLevel->levelNumber);
|
||||
bonussequence_r(vol, jobs, job);
|
||||
|
@ -574,7 +574,7 @@ void dobonus_r(bool bonusonly, const CompletionFunc& completion)
|
|||
{
|
||||
jobs[job++] = { Create<DRRMultiplayerBonusScreen>(playerswhenstarted) };
|
||||
}
|
||||
else if (!bonusonly && ud.multimode <= 1)
|
||||
else if (bonusonly <= 0 && ud.multimode <= 1)
|
||||
{
|
||||
if (isRRRA() && !(currentLevel->flags & MI_USERMAP) && currentLevel->levelNumber < 106) // fixme: The logic here is awful. Shift more control to the map records.
|
||||
{
|
||||
|
@ -584,7 +584,7 @@ void dobonus_r(bool bonusonly, const CompletionFunc& completion)
|
|||
mysnprintf(fn, 20, "lvl%d.anm", levnum + 1);
|
||||
static const int framespeed[] = { 20, 20, 7200 }; // wait for one minute on the final frame so that the video doesn't stop before the user notices.
|
||||
jobs[job++] = { PlayVideo(fn, nullptr, framespeed) };
|
||||
if (ud.eog && currentLevel->levelNumber > 100)
|
||||
if (bonusonly < 0 && currentLevel->levelNumber > 100)
|
||||
{
|
||||
jobs[job++] = { Create<DRRRAEndOfGame>() };
|
||||
}
|
||||
|
|
|
@ -2133,9 +2133,7 @@ static void rrra_specialstats()
|
|||
ps[screenpeek].MamaEnd--;
|
||||
if (ps[screenpeek].MamaEnd == 0)
|
||||
{
|
||||
ps[screenpeek].gm = MODE_EOL;
|
||||
ud.eog = 1;
|
||||
ud.nextLevel = nullptr;
|
||||
CompleteLevel(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,90 +37,6 @@ Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au)
|
|||
|
||||
BEGIN_DUKE_NS
|
||||
|
||||
static void dowarp(MapRecord *map)
|
||||
{
|
||||
ud.m_monsters_off = ud.monsters_off = 0;
|
||||
|
||||
ud.m_respawn_items = 0;
|
||||
ud.m_respawn_inventory = 0;
|
||||
|
||||
ud.multimode = 1;
|
||||
|
||||
if (ps[myconnectindex].gm & MODE_GAME)
|
||||
{
|
||||
donewgame(map, ud.m_player_skill);
|
||||
ps[myconnectindex].gm = MODE_RESTART;
|
||||
}
|
||||
else startnewgame(map, ud.m_player_skill);
|
||||
}
|
||||
|
||||
static int ccmd_levelwarp(CCmdFuncPtr parm)
|
||||
{
|
||||
if (parm->numparms != 2)
|
||||
return CCMD_SHOWHELP;
|
||||
int e = atoi(parm->parms[0]);
|
||||
int m = atoi(parm->parms[1]);
|
||||
if (e == 0 || m == 0)
|
||||
{
|
||||
Printf(TEXTCOLOR_RED "Invalid level!: E%sL%s\n", parm->parms[0], parm->parms[1]);
|
||||
return CCMD_OK;
|
||||
}
|
||||
auto map = FindMapByLevelNum(levelnum(e - 1, m - 1));
|
||||
if (!map)
|
||||
{
|
||||
Printf(TEXTCOLOR_RED "Level not found!: E%sL%s\n", parm->parms[0], parm->parms[1]);
|
||||
return CCMD_OK;
|
||||
}
|
||||
dowarp(map);
|
||||
|
||||
return CCMD_OK;
|
||||
}
|
||||
|
||||
static int ccmd_map(CCmdFuncPtr parm)
|
||||
{
|
||||
if (parm->numparms != 1)
|
||||
{
|
||||
return CCMD_SHOWHELP;
|
||||
}
|
||||
FString mapname = parm->parms[0];
|
||||
FString mapfilename = mapname;
|
||||
DefaultExtension(mapfilename, ".map");
|
||||
|
||||
if (!fileSystem.FileExists(mapfilename))
|
||||
{
|
||||
Printf(TEXTCOLOR_RED "map: file \"%s\" not found.\n", mapname.GetChars());
|
||||
return CCMD_OK;
|
||||
}
|
||||
// Check if the map is already defined.
|
||||
auto map = FindMapByName(mapname);
|
||||
if (map == nullptr)
|
||||
{
|
||||
// got a user map
|
||||
if (VOLUMEONE)
|
||||
{
|
||||
Printf(TEXTCOLOR_RED "Cannot use user maps in shareware.\n");
|
||||
return CCMD_OK;
|
||||
}
|
||||
if (mapfilename[0] != '/') mapfilename.Insert(0, "/");
|
||||
map = SetupUserMap(mapfilename, !isRR() ? "dethtoll.mid" : nullptr);
|
||||
}
|
||||
if (numplayers > 1)
|
||||
{
|
||||
return CCMD_OK;
|
||||
}
|
||||
|
||||
dowarp(map);
|
||||
return CCMD_OK;
|
||||
}
|
||||
|
||||
static int ccmd_restartmap(CCmdFuncPtr)
|
||||
{
|
||||
if (ps[myconnectindex].gm & MODE_GAME && ud.multimode == 1)
|
||||
ps[myconnectindex].gm = MODE_RESTART;
|
||||
|
||||
return CCMD_OK;
|
||||
}
|
||||
|
||||
int getlabelvalue(const char* text);
|
||||
|
||||
static int ccmd_spawn(CCmdFuncPtr parm)
|
||||
|
@ -131,10 +47,12 @@ static int ccmd_spawn(CCmdFuncPtr parm)
|
|||
int ang = 0;
|
||||
int set = 0, idx;
|
||||
|
||||
if (numplayers > 1 || !(ps[myconnectindex].gm & MODE_GAME)) {
|
||||
#if 0 // fixme - route through the network and this limitation becomes irrelevant
|
||||
if (netgame || numplayers > 1 || !(ps[myconnectindex].gm & MODE_GAME)) {
|
||||
Printf("spawn: Can't spawn sprites in multiplayer games or demos\n");
|
||||
return CCMD_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (parm->numparms) {
|
||||
case 7: // x,y,z
|
||||
|
@ -252,9 +170,6 @@ static int osdcmd_show_weapon(CCmdFuncPtr parm)
|
|||
|
||||
int registerosdcommands(void)
|
||||
{
|
||||
C_RegisterFunction("map","map <mapname>: warp to the given map, identified by its name", ccmd_map);
|
||||
C_RegisterFunction("levelwarp","levelwarp <e> <m>: warp to episode 'e' and map 'm'", ccmd_levelwarp);
|
||||
C_RegisterFunction("restartmap", "restartmap: restarts the current map", ccmd_restartmap);
|
||||
C_RegisterFunction("spawn","spawn <picnum> [palnum] [cstat] [ang] [x y z]: spawns a sprite with the given properties",ccmd_spawn);
|
||||
C_RegisterFunction("warptocoords","warptocoords [x] [y] [z] [ang] (optional) [horiz] (optional): warps the player to the specified coordinates",osdcmd_warptocoords);
|
||||
C_RegisterFunction("third_person_view", "Switch to third person view", osdcmd_third_person_view);
|
||||
|
|
|
@ -295,21 +295,16 @@ static bool cheatLevel(cheatseq_t *s)
|
|||
auto map = FindMapByLevelNum(levelnum(volnume, levnume));
|
||||
if (map)
|
||||
{
|
||||
ud.nextLevel = map;
|
||||
FX_StopAllSounds();
|
||||
FX_SetReverb(0);
|
||||
ps[myconnectindex].gm |= MODE_RESTART;
|
||||
ChangeLevel(map, -1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cheatSkill(cheatseq_t *s)
|
||||
{
|
||||
lastlevel = 0;
|
||||
ud.m_player_skill = ud.player_skill = s->Args[0] - '1';
|
||||
ps[myconnectindex].gm |= MODE_RESTART;
|
||||
FX_StopAllSounds();
|
||||
FX_SetReverb(0);
|
||||
ChangeLevel(currentLevel, s->Args[0] - '1');
|
||||
//FX_StopAllSounds();
|
||||
//FX_SetReverb(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -416,10 +416,8 @@ enum EFlamethrowerState
|
|||
};
|
||||
|
||||
enum gamemode_t {
|
||||
MODE_DEMO = 0x00000002,
|
||||
MODE_GAME = 0x00000004,
|
||||
MODE_EOL = 0x00000008,
|
||||
MODE_RESTART = 0x00000020,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -273,7 +273,6 @@ void GameInterface::StartGame(FNewGameStartup& gs)
|
|||
static const short sounds_r[] = { 427, 428, 196, 195, 197 };
|
||||
if (gs.Skill >=0 && gs.Skill <= 5) skillsound = isRR()? sounds_r[gs.Skill] : sounds_d[gs.Skill];
|
||||
|
||||
ud.m_player_skill = gs.Skill + 1;
|
||||
if (menu_sounds && skillsound >= 0 && SoundEnabled() && !netgame)
|
||||
{
|
||||
S_PlaySound(skillsound, CHAN_AUTO, CHANF_UI);
|
||||
|
@ -286,16 +285,10 @@ void GameInterface::StartGame(FNewGameStartup& gs)
|
|||
}
|
||||
Net_ClearFifo();
|
||||
}
|
||||
ud.m_respawn_monsters = (gs.Skill == 3);
|
||||
|
||||
ud.m_monsters_off = ud.monsters_off = 0;
|
||||
ud.m_respawn_items = 0;
|
||||
ud.m_respawn_inventory = 0;
|
||||
ud.multimode = 1;
|
||||
auto map = FindMapByLevelNum(levelnum(gs.Episode, gs.Level));
|
||||
if (map)
|
||||
{
|
||||
startnewgame(map, ud.m_player_skill);
|
||||
DeferedStartGame(map, gs.Skill);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -58,7 +58,10 @@ struct GameInterface : public ::GameInterface
|
|||
void Render() override;
|
||||
void Ticker() override;
|
||||
const char* GenericCheat(int player, int cheat) override;
|
||||
const char* CheckCheatMode();
|
||||
const char* CheckCheatMode() override;
|
||||
void NextLevel(MapRecord* map, int skill) override;
|
||||
void NewGame(MapRecord* map, int skill) override;
|
||||
void LevelCompleted(MapRecord* map, int skill) override;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -208,8 +208,8 @@ void drawstatusbar_r(int snum);
|
|||
void drawoverheadmap(int cposx, int cposy, int czoom, int cang);
|
||||
void cameratext(int i);
|
||||
void dobonus(int bonusonly, const CompletionFunc& completion);
|
||||
void dobonus_d(bool bonusonly, const CompletionFunc& completion);
|
||||
void dobonus_r(bool bonusonly, const CompletionFunc& completion);
|
||||
void dobonus_d(int bonusonly, const CompletionFunc& completion);
|
||||
void dobonus_r(int bonusonly, const CompletionFunc& completion);
|
||||
|
||||
void drawoverlays(double smoothratio);
|
||||
void drawbackground(void);
|
||||
|
@ -221,7 +221,7 @@ bool setnextmap(bool checksecretexit);
|
|||
void prelevel_d(int g);
|
||||
void prelevel_r(int g);
|
||||
void e4intro(const CompletionFunc& completion);
|
||||
void exitlevel();
|
||||
void exitlevel(MapRecord *next);
|
||||
int enterlevel(MapRecord* mi, int gm);
|
||||
void donewgame(MapRecord* map, int sk);
|
||||
void startnewgame(MapRecord* map, int skill);
|
||||
|
|
|
@ -41,6 +41,7 @@ Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au)
|
|||
#include "prediction.h"
|
||||
#include "sbar.h"
|
||||
#include "glbackend/glbackend.h"
|
||||
#include "gamestate.h"
|
||||
|
||||
BEGIN_DUKE_NS
|
||||
|
||||
|
@ -84,7 +85,7 @@ template<class func>
|
|||
void runbonus(func completion)
|
||||
{
|
||||
// MP scoreboard
|
||||
if (playerswhenstarted > 1 && ps[myconnectindex].gm & MODE_GAME && !ud.coop)
|
||||
if (playerswhenstarted > 1 && !ud.coop)
|
||||
{
|
||||
dobonus(1, completion);
|
||||
}
|
||||
|
@ -127,7 +128,7 @@ void GameInterface::ExitFromMenu()
|
|||
|
||||
void FTA(int q, struct player_struct* p)
|
||||
{
|
||||
if (q < 0 || !(p->gm & MODE_GAME))
|
||||
if (q < 0 || gamestate != GS_LEVEL)
|
||||
return;
|
||||
|
||||
if (p->ftq != q || (ud.levelclock - p->ftt > TICRATE && q != QUOTE_DEAD))
|
||||
|
|
|
@ -36,6 +36,7 @@ source as it is released.
|
|||
#include "duke3d.h"
|
||||
#include "gamevar.h"
|
||||
#include "mapinfo.h"
|
||||
#include "gamestate.h"
|
||||
|
||||
BEGIN_DUKE_NS
|
||||
|
||||
|
@ -692,7 +693,7 @@ int ParseState::parse(void)
|
|||
insptr++;
|
||||
ps[g_p].timebeforeexit = *insptr;
|
||||
ps[g_p].customexitsound = -1;
|
||||
ud.eog = 1;
|
||||
ChangeLevel(nullptr, -1);
|
||||
insptr++;
|
||||
break;
|
||||
|
||||
|
@ -975,18 +976,9 @@ int ParseState::parse(void)
|
|||
case concmd_resetplayer:
|
||||
insptr++;
|
||||
|
||||
//AddLog("resetplayer");
|
||||
if(ud.multimode < 2)
|
||||
{
|
||||
#if 0
|
||||
if( lastsavedpos >= 0 && ud.recstat != 2 )
|
||||
{
|
||||
KB_ClearKeyDown(sc_Space);
|
||||
cmenu(15000);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
ps[g_p].gm = MODE_RESTART;
|
||||
gameaction = ga_autoloadgame;
|
||||
killit_flag = 2;
|
||||
}
|
||||
else
|
||||
|
@ -1737,8 +1729,7 @@ CCMD(endofgame)
|
|||
{
|
||||
ps[0].timebeforeexit = 120;
|
||||
ps[0].customexitsound = -1;
|
||||
ud.eog = 1;
|
||||
|
||||
ChangeLevel(nullptr, -1);
|
||||
}
|
||||
|
||||
END_DUKE_NS
|
||||
|
|
|
@ -103,11 +103,6 @@ void GameInterface::Ticker()
|
|||
|
||||
}
|
||||
else r_NoInterpolate = true;
|
||||
|
||||
if (ps[myconnectindex].gm & (MODE_EOL | MODE_RESTART))
|
||||
{
|
||||
exitlevel();
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -138,7 +133,8 @@ void GameInterface::Startup()
|
|||
}
|
||||
else
|
||||
{
|
||||
fi.ShowLogo([](bool) { startmainmenu(); });
|
||||
if (!userConfig.nologo) fi.ShowLogo([](bool) { startmainmenu(); });
|
||||
else startmainmenu();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,6 +156,44 @@ void GameInterface::Render()
|
|||
drawtime.Unclock();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void GameInterface::NextLevel(MapRecord* map, int skill)
|
||||
{
|
||||
ud.m_player_skill = skill + 1;
|
||||
int res = enterlevel(map, 0);
|
||||
if (!res) gameaction = ga_startup;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void GameInterface::NewGame(MapRecord* map, int skill)
|
||||
{
|
||||
// Hmm... What about the other players?
|
||||
ps[0].last_extra = max_player_health;
|
||||
resetweapons(0);
|
||||
resetinventory(0);
|
||||
NextLevel(map, skill);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void GameInterface::LevelCompleted(MapRecord* map, int skill)
|
||||
{
|
||||
exitlevel(map);
|
||||
}
|
||||
|
||||
END_DUKE_NS
|
||||
|
||||
|
|
|
@ -420,7 +420,6 @@ void resetprestat(int snum,int g)
|
|||
randomseed = 17L;
|
||||
paused = 0;
|
||||
ud.camerasprite =-1;
|
||||
ud.eog = 0;
|
||||
tempwallptr = 0;
|
||||
camsprite =-1;
|
||||
earthquaketime = 0;
|
||||
|
@ -435,12 +434,7 @@ void resetprestat(int snum,int g)
|
|||
numinterpolations = 0;
|
||||
//startofdynamicinterpolations = 0;
|
||||
|
||||
if( ( (g&MODE_EOL) != MODE_EOL && numplayers < 2) || (ud.coop != 1 && numplayers > 1) )
|
||||
{
|
||||
resetweapons(snum);
|
||||
resetinventory(snum);
|
||||
}
|
||||
else if(p->curr_weapon == HANDREMOTE_WEAPON)
|
||||
if(p->curr_weapon == HANDREMOTE_WEAPON)
|
||||
{
|
||||
p->ammo_amount[HANDBOMB_WEAPON]++;
|
||||
p->curr_weapon = HANDBOMB_WEAPON;
|
||||
|
@ -581,7 +575,7 @@ void resetpspritevars(int g)
|
|||
|
||||
which_palookup = 9;
|
||||
j = connecthead;
|
||||
i = headspritestat[10]; // 10 == players...
|
||||
i = headspritestat[STAT_PLAYER];
|
||||
while (i >= 0)
|
||||
{
|
||||
nexti = nextspritestat[i];
|
||||
|
@ -613,7 +607,7 @@ void resetpspritevars(int g)
|
|||
s->xoffset = 0;
|
||||
s->clipdist = 64;
|
||||
|
||||
if ((g & MODE_EOL) != MODE_EOL || ps[j].last_extra == 0)
|
||||
if (ps[j].last_extra == 0)
|
||||
{
|
||||
ps[j].last_extra = max_player_health;
|
||||
s->extra = max_player_health;
|
||||
|
@ -774,7 +768,7 @@ void donewgame(MapRecord* map, int sk)
|
|||
auto p = &ps[0];
|
||||
show_shareware = 26 * 34;
|
||||
|
||||
ud.nextLevel = map;
|
||||
//ud.nextLevel = map;
|
||||
ud.player_skill = sk;
|
||||
ud.secretlevel = 0;
|
||||
ud.from_bonus = 0;
|
||||
|
@ -782,7 +776,6 @@ void donewgame(MapRecord* map, int sk)
|
|||
ud.last_level = -1;
|
||||
|
||||
p->zoom = 768;
|
||||
p->gm = 0;
|
||||
M_ClearMenus();
|
||||
ResetGameVars();
|
||||
|
||||
|
@ -950,9 +943,6 @@ int enterlevel(MapRecord *mi, int gamemode)
|
|||
ud.coop = ud.m_coop;
|
||||
ud.ffire = ud.m_ffire;
|
||||
|
||||
if ((gamemode & MODE_DEMO) == 0 && ud.recstat == 2)
|
||||
ud.recstat = 0;
|
||||
|
||||
OnEvent(EVENT_ENTERLEVEL);
|
||||
|
||||
// Stop all sounds
|
||||
|
@ -970,7 +960,7 @@ int enterlevel(MapRecord *mi, int gamemode)
|
|||
if (res != 0) return res;
|
||||
|
||||
// Try this first so that it can disable the CD player if no tracks are found.
|
||||
if (isRR() && !(gamemode & MODE_DEMO))
|
||||
if (isRR())
|
||||
S_PlayRRMusic();
|
||||
|
||||
if (ud.recstat != 2)
|
||||
|
@ -978,17 +968,6 @@ int enterlevel(MapRecord *mi, int gamemode)
|
|||
S_PlayLevelMusic(mi);
|
||||
}
|
||||
|
||||
if (gamemode & (MODE_GAME|MODE_EOL))
|
||||
{
|
||||
ps[myconnectindex].gm = MODE_GAME;
|
||||
}
|
||||
else if (gamemode & MODE_RESTART)
|
||||
{
|
||||
if (ud.recstat == 2)
|
||||
ps[myconnectindex].gm = MODE_DEMO;
|
||||
else ps[myconnectindex].gm = MODE_GAME;
|
||||
}
|
||||
|
||||
if (VOLUMEONE && mi->levelNumber == 0 && ud.recstat != 2) FTA(QUOTE_F1HELP, &ps[myconnectindex]);
|
||||
|
||||
for (int i = connecthead; i >= 0; i = connectpoint2[i])
|
||||
|
@ -1027,11 +1006,17 @@ int enterlevel(MapRecord *mi, int gamemode)
|
|||
|
||||
void startnewgame(MapRecord* map, int skill)
|
||||
{
|
||||
ud.m_player_skill = skill;
|
||||
ud.m_respawn_monsters = (skill == 4);
|
||||
ud.m_monsters_off = ud.monsters_off = 0;
|
||||
ud.m_respawn_items = 0;
|
||||
ud.m_respawn_inventory = 0;
|
||||
ud.multimode = 1;
|
||||
|
||||
newgame(map, skill, [=](bool)
|
||||
{
|
||||
if (enterlevel(map, MODE_GAME))
|
||||
if (enterlevel(map, 0))
|
||||
{
|
||||
ps[myconnectindex].gm = 0;
|
||||
startmainmenu();
|
||||
}
|
||||
else
|
||||
|
@ -1077,16 +1062,11 @@ bool setnextmap(bool checksecretexit)
|
|||
map = FindNextMap(currentLevel);
|
||||
}
|
||||
|
||||
for (int i = connecthead; i >= 0; i = connectpoint2[i])
|
||||
ps[i].gm = MODE_EOL;
|
||||
|
||||
if (map)
|
||||
{
|
||||
ud.from_bonus = from_bonus;
|
||||
ud.nextLevel = map;
|
||||
return true;
|
||||
}
|
||||
ud.eog = true;
|
||||
CompleteLevel(map);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1096,61 +1076,42 @@ bool setnextmap(bool checksecretexit)
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
int exitlevelend()
|
||||
void exitlevel(MapRecord *nextlevel)
|
||||
{
|
||||
if (numplayers > 1)
|
||||
ps[myconnectindex].gm = MODE_GAME;
|
||||
|
||||
int res = enterlevel(ud.nextLevel, ps[myconnectindex].gm);
|
||||
ud.nextLevel = nullptr;
|
||||
return res;
|
||||
}
|
||||
|
||||
void exitlevel(void)
|
||||
{
|
||||
bool endofgame = ud.eog || (currentLevel->flags & MI_FORCEEOG) || ud.nextLevel == nullptr;
|
||||
bool endofgame = nextlevel == nullptr;
|
||||
STAT_Update(endofgame);
|
||||
setpal(&ps[myconnectindex]);
|
||||
|
||||
if (ps[myconnectindex].gm & MODE_RESTART)
|
||||
{
|
||||
// If no level was set, restart the current one.
|
||||
if (!ud.nextLevel) ud.nextLevel = currentLevel;
|
||||
}
|
||||
dobonus(endofgame? -1 : 0, [=](bool)
|
||||
{
|
||||
|
||||
if (ps[myconnectindex].gm & MODE_EOL)
|
||||
{
|
||||
dobonus(0, [=](bool)
|
||||
// Clear potentially loaded per-map ART only after the bonus screens.
|
||||
artClearMapArt();
|
||||
gamestate = GS_LEVEL;
|
||||
if (endofgame)
|
||||
{
|
||||
|
||||
// Clear potentially loaded per-map ART only after the bonus screens.
|
||||
artClearMapArt();
|
||||
gamestate = GS_LEVEL;
|
||||
if (endofgame)
|
||||
if (ud.multimode < 2)
|
||||
{
|
||||
ud.eog = 0;
|
||||
if (ud.multimode < 2)
|
||||
if (!VOLUMEALL)
|
||||
doorders([](bool) { gameaction = ga_startup; });
|
||||
else gameaction = ga_startup;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto nextlevel = FindMapByLevelNum(0);
|
||||
if (!nextlevel)
|
||||
{
|
||||
ps[myconnectindex].gm = 0;
|
||||
if (!VOLUMEALL)
|
||||
doorders([](bool) { gamestate = GS_STARTUP; });
|
||||
else gamestate = GS_STARTUP;
|
||||
gameaction = ga_startup;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
ud.nextLevel = FindMapByLevelNum(0);
|
||||
if (!ud.nextLevel || exitlevelend())
|
||||
gamestate = GS_STARTUP;
|
||||
}
|
||||
else gameaction = ga_nextlevel;
|
||||
}
|
||||
else if (exitlevelend())
|
||||
gamestate = GS_STARTUP;
|
||||
}
|
||||
else
|
||||
gameaction = ga_nextlevel;
|
||||
|
||||
});
|
||||
}
|
||||
else if (exitlevelend())
|
||||
gamestate = GS_STARTUP;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -207,7 +207,6 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, player_struct& w,
|
|||
("last_full_weapon", w.last_full_weapon)
|
||||
("footprintshade", w.footprintshade)
|
||||
("boot_amount", w.boot_amount)
|
||||
("gm", w.gm)
|
||||
("on_warping_sector", w.on_warping_sector)
|
||||
("footprintcount", w.footprintcount)
|
||||
("hbomb_on", w.hbomb_on)
|
||||
|
@ -400,7 +399,6 @@ void GameInterface::SerializeGameState(FSerializer& arc)
|
|||
//("auto_run", ud.auto_run)
|
||||
("monsters_off", ud.monsters_off)
|
||||
("last_level", ud.last_level)
|
||||
("eog", ud.eog)
|
||||
("coop", ud.coop)
|
||||
("marker", ud.marker)
|
||||
("ffire", ud.ffire)
|
||||
|
@ -488,7 +486,6 @@ void GameInterface::SerializeGameState(FSerializer& arc)
|
|||
if (arc.isReading())
|
||||
{
|
||||
screenpeek = myconnectindex;
|
||||
ps[myconnectindex].gm = MODE_GAME;
|
||||
gamestate = GS_LEVEL;
|
||||
ud.recstat = 0;
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ source as it is released.
|
|||
#include "raze_music.h"
|
||||
#include "mapinfo.h"
|
||||
#include "raze_sound.h"
|
||||
#include "gamestate.h"
|
||||
|
||||
BEGIN_DUKE_NS
|
||||
|
||||
|
@ -324,8 +325,7 @@ void GameInterface::UpdateSounds(void)
|
|||
vec3_t* c;
|
||||
int32_t ca, cs;
|
||||
|
||||
auto& gm = ps[myconnectindex].gm;
|
||||
if (isRR() && !Mus_IsPlaying() && (gm && gm & MODE_GAME))
|
||||
if (isRR() && !Mus_IsPlaying() && !paused && gamestate == GS_LEVEL)
|
||||
S_PlayRRMusic();
|
||||
|
||||
S_GetCamera(&c, &ca, &cs);
|
||||
|
|
|
@ -52,7 +52,7 @@ struct TileInfo
|
|||
struct user_defs
|
||||
{
|
||||
int levelclock;
|
||||
unsigned char god, cashman, eog;
|
||||
unsigned char god, cashman;
|
||||
unsigned char show_help, scrollmode, clipping;
|
||||
char user_name[MAXPLAYERS][32];
|
||||
unsigned char showweapons;
|
||||
|
@ -76,7 +76,7 @@ struct user_defs
|
|||
int m_respawn_items, m_respawn_monsters, m_respawn_inventory, m_recstat, m_monsters_off, detail;
|
||||
int m_ffire, ffire, m_player_skill, multimode;
|
||||
int player_skill, marker;
|
||||
MapRecord* nextLevel;
|
||||
//MapRecord* nextLevel;
|
||||
|
||||
};
|
||||
|
||||
|
@ -156,7 +156,6 @@ struct player_struct
|
|||
short holoduke_on, pycount, frag_ps;
|
||||
short transporter_hold, last_full_weapon, footprintshade, boot_amount;
|
||||
|
||||
unsigned char gm;
|
||||
unsigned char on_warping_sector, footprintcount;
|
||||
unsigned char hbomb_on, jumping_toggle, rapid_fire_hold, on_ground;
|
||||
char name[32];
|
||||
|
|
|
@ -205,16 +205,14 @@ void GameInterface::StartGame(FNewGameStartup& gs)
|
|||
|
||||
ready2send = 0;
|
||||
|
||||
MapRecord* map;
|
||||
if (gs.Episode >= 1)
|
||||
NextLevel = FindMapByLevelNum(5);
|
||||
map = FindMapByLevelNum(5);
|
||||
else
|
||||
NextLevel = FindMapByLevelNum(1);
|
||||
map = FindMapByLevelNum(1);
|
||||
|
||||
if (!NextLevel) return;
|
||||
ExitLevel = TRUE;
|
||||
NewGame = TRUE;
|
||||
if (!map) return;
|
||||
CameraTestMode = FALSE;
|
||||
Skill = gs.Skill;
|
||||
StopFX();
|
||||
|
||||
//InitNewGame();
|
||||
|
@ -238,6 +236,7 @@ void GameInterface::StartGame(FNewGameStartup& gs)
|
|||
}
|
||||
Net_ClearFifo();
|
||||
}
|
||||
DeferedStartGame(map, gs.Skill);
|
||||
}
|
||||
|
||||
FSavegameInfo GameInterface::GetSaveSig()
|
||||
|
|
|
@ -280,13 +280,6 @@ void GameInterface::DrawBackground(void)
|
|||
MNU_DrawString(160, 170, "Lo Wang is waiting for other players...", 1, 16, 0);
|
||||
MNU_DrawString(160, 180, "They are afraid!", 1, 16, 0);
|
||||
}
|
||||
// hack alert. This needs to go away.
|
||||
if (SavegameLoaded || NextLevel)
|
||||
{
|
||||
TerminateLevel();
|
||||
ExitLevel = false;
|
||||
gamestate = GS_LEVEL;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -663,7 +656,7 @@ void GameInterface::Ticker(void)
|
|||
StartAmbientSound();
|
||||
ExitLevel = false;
|
||||
}
|
||||
else if (NextLevel)
|
||||
else if (ShadowWarrior::NextLevel)
|
||||
{
|
||||
InitLevel();
|
||||
InitRunLevel();
|
||||
|
@ -731,7 +724,7 @@ void GameInterface::ErrorCleanup()
|
|||
{
|
||||
// Make sure we do not leave the game in an unstable state
|
||||
TerminateLevel();
|
||||
NextLevel = nullptr;
|
||||
ShadowWarrior::NextLevel = nullptr;
|
||||
SavegameLoaded = false;
|
||||
ExitLevel = false;
|
||||
FinishAnim = 0;
|
||||
|
@ -847,4 +840,10 @@ void GameInterface::FreeGameData()
|
|||
TerminateLevel();
|
||||
}
|
||||
|
||||
void GameInterface::FreeLevelData()
|
||||
{
|
||||
TerminateLevel();
|
||||
::GameInterface::FreeLevelData();
|
||||
}
|
||||
|
||||
END_SW_NS
|
||||
|
|
|
@ -2203,6 +2203,7 @@ struct GameInterface : ::GameInterface
|
|||
const char* Name() override { return "ShadowWarrior"; }
|
||||
void app_init() override;
|
||||
void FreeGameData() override;
|
||||
void FreeLevelData() override;
|
||||
bool GenerateSavePic() override;
|
||||
void DrawNativeMenuText(int fontnum, int state, double xpos, double ypos, float fontscale, const char* text, int flags) override;
|
||||
void MenuOpened() override;
|
||||
|
@ -2212,7 +2213,6 @@ struct GameInterface : ::GameInterface
|
|||
void StartGame(FNewGameStartup& gs) override;
|
||||
FSavegameInfo GetSaveSig() override;
|
||||
void DrawMenuCaption(const DVector2& origin, const char* text) override;
|
||||
bool CleanupForLoad() override;
|
||||
bool LoadGame(FSaveGameNode* sv) override;
|
||||
bool SaveGame(FSaveGameNode* sv) override;
|
||||
void SetAmbience(bool on) override { if (on) StartAmbientSound(); else StopAmbientSound(); }
|
||||
|
|
|
@ -650,13 +650,6 @@ bool GameInterface::SaveGame(FSaveGameNode *sv)
|
|||
|
||||
extern SWBOOL SavegameLoaded;
|
||||
|
||||
bool GameInterface::CleanupForLoad()
|
||||
{
|
||||
TerminateLevel();
|
||||
StopFX();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GameInterface::LoadGame(FSaveGameNode* sv)
|
||||
{
|
||||
MFILE_READ fil;
|
||||
|
@ -1089,7 +1082,7 @@ bool GameInterface::LoadGame(FSaveGameNode* sv)
|
|||
}
|
||||
|
||||
// this is not a new game
|
||||
NewGame = FALSE;
|
||||
ShadowWarrior::NewGame = FALSE;
|
||||
|
||||
|
||||
DoPlayerDivePalette(Player+myconnectindex);
|
||||
|
|
Loading…
Reference in a new issue