From 043e761eec6dd8952bbe9b8a3dc65e9b4bc164f4 Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Sun, 23 Oct 2016 06:06:59 -0400 Subject: [PATCH 1/4] - Implemented sv_singleplayerrespawn --- src/g_game.cpp | 3 ++- src/g_level.cpp | 4 +++- src/p_mobj.cpp | 5 +++-- src/p_user.cpp | 5 ++++- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/g_game.cpp b/src/g_game.cpp index 48bda24f5f..b0c8775fc5 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1655,9 +1655,10 @@ static void G_QueueBody (AActor *body) // // G_DoReborn // +EXTERN_CVAR(Bool, sv_singleplayerrespawn) void G_DoReborn (int playernum, bool freshbot) { - if (!multiplayer && !(level.flags2 & LEVEL2_ALLOWRESPAWN)) + if (!multiplayer && !(level.flags2 & LEVEL2_ALLOWRESPAWN) && !sv_singleplayerrespawn) { if (BackupSaveName.Len() > 0 && FileExists (BackupSaveName.GetChars())) { // Load game from the last point it was saved diff --git a/src/g_level.cpp b/src/g_level.cpp index 119cde378d..d3a8c4015a 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -526,6 +526,8 @@ static bool unloading; // //========================================================================== +EXTERN_CVAR(Bool, sv_singleplayerrespawn) + void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill) { level_info_t *nextinfo = NULL; @@ -634,7 +636,7 @@ void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill // If this is co-op, respawn any dead players now so they can // keep their inventory on the next map. - if ((multiplayer || level.flags2 & LEVEL2_ALLOWRESPAWN) && !deathmatch && player->playerstate == PST_DEAD) + if ((multiplayer || level.flags2 & LEVEL2_ALLOWRESPAWN || sv_singleplayerrespawn) && !deathmatch && player->playerstate == PST_DEAD) { // Copied from the end of P_DeathThink [[ player->cls = NULL; // Force a new class if the player is using a random class diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 8f926ea77f..3e20118784 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1,4 +1,4 @@ -// Emacs style mode select -*- C++ -*- +// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ @@ -4495,6 +4495,7 @@ void AActor::AdjustFloorClip () // Most of the player structure stays unchanged between levels. // EXTERN_CVAR (Bool, chasedemo) +EXTERN_CVAR(Bool, sv_singleplayerrespawn) extern bool demonew; @@ -4682,7 +4683,7 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags) { // Give all cards in death match mode. p->mo->GiveDeathmatchInventory (); } - else if ((multiplayer || (level.flags2 & LEVEL2_ALLOWRESPAWN)) && state == PST_REBORN && oldactor != NULL) + else if ((multiplayer || (level.flags2 & LEVEL2_ALLOWRESPAWN) || sv_singleplayerrespawn) && state == PST_REBORN && oldactor != NULL) { // Special inventory handling for respawning in coop p->mo->FilterCoopRespawnInventory (oldactor); } diff --git a/src/p_user.cpp b/src/p_user.cpp index e487120429..6ac39c2a5c 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -68,6 +68,7 @@ static FRandom pr_skullpop ("SkullPop"); // Variables for prediction CVAR (Bool, cl_noprediction, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(Bool, cl_predict_specials, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +CVAR(Bool, sv_singleplayerrespawn, false, CVAR_SERVERINFO | CVAR_LATCH) CUSTOM_CVAR(Float, cl_predict_lerpscale, 0.05f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) { @@ -2211,7 +2212,9 @@ void P_DeathThink (player_t *player) if (level.time >= player->respawn_time || ((player->cmd.ucmd.buttons & BT_USE) && player->Bot == NULL)) { player->cls = NULL; // Force a new class if the player is using a random class - player->playerstate = (multiplayer || (level.flags2 & LEVEL2_ALLOWRESPAWN)) ? PST_REBORN : PST_ENTER; + player->playerstate = + (multiplayer || (level.flags2 & LEVEL2_ALLOWRESPAWN) || sv_singleplayerrespawn) + ? PST_REBORN : PST_ENTER; if (player->mo->special1 > 2) { player->mo->special1 = 0; From 623910bd2ae0594479a9e3f1c05ca4c57d52ae5e Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Sun, 23 Oct 2016 08:14:54 -0400 Subject: [PATCH 2/4] - Putting the CVAR definition right in the middle of prediction stuff probably wasn't the best idea. --- src/p_user.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/p_user.cpp b/src/p_user.cpp index 6ac39c2a5c..b7bd4c2ec4 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -65,10 +65,12 @@ static FRandom pr_skullpop ("SkullPop"); // [RH] # of ticks to complete a turn180 #define TURN180_TICKS ((TICRATE / 4) + 1) +// [SP] Allows respawn in single player +CVAR(Bool, sv_singleplayerrespawn, false, CVAR_SERVERINFO | CVAR_LATCH) + // Variables for prediction CVAR (Bool, cl_noprediction, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(Bool, cl_predict_specials, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -CVAR(Bool, sv_singleplayerrespawn, false, CVAR_SERVERINFO | CVAR_LATCH) CUSTOM_CVAR(Float, cl_predict_lerpscale, 0.05f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) { From 81449728d7a6217460e9e451eca20232e86a3316 Mon Sep 17 00:00:00 2001 From: MaxED Date: Mon, 24 Oct 2016 14:13:40 +0300 Subject: [PATCH 3/4] Allows loading directories as IWADs using "-iwad" command line parameter. --- src/d_iwad.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/d_iwad.cpp b/src/d_iwad.cpp index 1fc63e03d3..6fa8604a0c 100644 --- a/src/d_iwad.cpp +++ b/src/d_iwad.cpp @@ -292,6 +292,7 @@ void FIWadManager::ParseIWadInfos(const char *fn) int FIWadManager::ScanIWAD (const char *iwad) { FResourceFile *iwadfile = FResourceFile::OpenResourceFile(iwad, NULL, true); + if (iwadfile == NULL) iwadfile = FResourceFile::OpenDirectory(iwad, true); //mxd. A directory can also work as an IWAD if (iwadfile != NULL) { @@ -344,7 +345,7 @@ int FIWadManager::CheckIWAD (const char *doomwaddir, WadStuff *wads) iwad.Format ("%s%s%s", doomwaddir, slash, mIWadNames[i].GetChars()); FixPathSeperator (iwad); - if (FileExists (iwad)) + if (DirEntryExists(iwad)) { wads[i].Type = ScanIWAD (iwad); if (wads[i].Type != -1) @@ -413,7 +414,7 @@ int FIWadManager::IdentifyVersion (TArray &wadfiles, const char *iwad, } else { - DefaultExtension (custwad, ".wad"); + if(FileExists(custwad)) DefaultExtension (custwad, ".wad"); //mxd. Don't treat folders as .wads iwadparm = custwad; mIWadNames[0] = custwad; CheckIWAD ("", &wads[0]); From fa8e05d56d908d0eb654770685eb9b904152a99c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 25 Oct 2016 22:40:58 +0200 Subject: [PATCH 4/4] - do not allow a multipatch texture to use itself as patch. Instead, look for an older texture with the same name. --- src/textures/multipatchtexture.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/textures/multipatchtexture.cpp b/src/textures/multipatchtexture.cpp index 340376a25b..cb2d5d803d 100644 --- a/src/textures/multipatchtexture.cpp +++ b/src/textures/multipatchtexture.cpp @@ -1323,6 +1323,24 @@ void FMultiPatchTexture::ResolvePatches() for (int i = 0; i < NumParts; i++) { FTextureID texno = TexMan.CheckForTexture(Inits[i].TexName, Inits[i].UseType); + if (texno == id) // we found ourselves. Try looking for another one with the same name which is not a multipatch texture itself. + { + TArray list; + TexMan.ListTextures(Inits[i].TexName, list); + for (int i = list.Size() - 1; i >= 0; i--) + { + if (list[i] != id && !TexMan[list[i]]->bMultiPatch) + { + texno = list[i]; + break; + } + } + if (texno == id) + { + if (Inits[i].HasLine) Inits[i].sc.Message(MSG_WARNING, "Texture '%s' references itself as patch\n", Inits[i].TexName.GetChars()); + else Printf(TEXTCOLOR_YELLOW "Texture '%s' references itself as patch\n", Inits[i].TexName.GetChars()); + } + } if (!texno.isValid()) {