mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 06:53:58 +00:00
- moved a few parts from g_level.cpp to better fitting places.
This commit is contained in:
parent
6be073f528
commit
ef3e5ef01e
6 changed files with 309 additions and 274 deletions
|
@ -349,3 +349,58 @@ CCMD(targetinv)
|
|||
"the NOBLOCKMAP flag or have height/radius of 0.\n");
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Lists all currently defined maps
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
CCMD(listmaps)
|
||||
{
|
||||
for (unsigned i = 0; i < wadlevelinfos.Size(); i++)
|
||||
{
|
||||
level_info_t *info = &wadlevelinfos[i];
|
||||
MapData *map = P_OpenMapData(info->MapName, true);
|
||||
|
||||
if (map != NULL)
|
||||
{
|
||||
Printf("%s: '%s' (%s)\n", info->MapName.GetChars(), info->LookupLevelName().GetChars(),
|
||||
Wads.GetWadName(Wads.GetLumpFile(map->lumpnum)));
|
||||
delete map;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// For testing sky fog sheets
|
||||
//
|
||||
//==========================================================================
|
||||
CCMD(skyfog)
|
||||
{
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
// Do this only on the primary level.
|
||||
primaryLevel->skyfog = MAX(0, (int)strtoull(argv[1], NULL, 0));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
CCMD(listsnapshots)
|
||||
{
|
||||
for (unsigned i = 0; i < wadlevelinfos.Size(); ++i)
|
||||
{
|
||||
FCompressedBuffer *snapshot = &wadlevelinfos[i].Snapshot;
|
||||
if (snapshot->mBuffer != nullptr)
|
||||
{
|
||||
Printf("%s (%u -> %u bytes)\n", wadlevelinfos[i].MapName.GetChars(), snapshot->mCompressedSize, snapshot->mSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
223
src/g_level.cpp
223
src/g_level.cpp
|
@ -1634,68 +1634,6 @@ void FLevelLocals::Init()
|
|||
notexturefill = info->notexturefill < 0 ? gl_notexturefill : !!info->notexturefill;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FLevelLocals::IsJumpingAllowed() const
|
||||
{
|
||||
if (dmflags & DF_NO_JUMP)
|
||||
return false;
|
||||
if (dmflags & DF_YES_JUMP)
|
||||
return true;
|
||||
return !(flags & LEVEL_JUMP_NO);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FLevelLocals, IsJumpingAllowed)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
|
||||
ACTION_RETURN_BOOL(self->IsJumpingAllowed());
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FLevelLocals::IsCrouchingAllowed() const
|
||||
{
|
||||
if (dmflags & DF_NO_CROUCH)
|
||||
return false;
|
||||
if (dmflags & DF_YES_CROUCH)
|
||||
return true;
|
||||
return !(flags & LEVEL_CROUCH_NO);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FLevelLocals, IsCrouchingAllowed)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
|
||||
ACTION_RETURN_BOOL(self->IsCrouchingAllowed());
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FLevelLocals::IsFreelookAllowed() const
|
||||
{
|
||||
if (dmflags & DF_NO_FREELOOK)
|
||||
return false;
|
||||
if (dmflags & DF_YES_FREELOOK)
|
||||
return true;
|
||||
return !(flags & LEVEL_FREELOOK_NO);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FLevelLocals, IsFreelookAllowed)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
|
||||
ACTION_RETURN_BOOL(self->IsFreelookAllowed());
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
@ -1735,89 +1673,6 @@ void FLevelLocals::AirControlChanged ()
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Archives the current level
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FLevelLocals::SnapshotLevel ()
|
||||
{
|
||||
info->Snapshot.Clean();
|
||||
|
||||
if (info->isValid())
|
||||
{
|
||||
FSerializer arc(this);
|
||||
|
||||
if (arc.OpenWriter(save_formatted))
|
||||
{
|
||||
SaveVersion = SAVEVER;
|
||||
Serialize(arc, false);
|
||||
info->Snapshot = arc.GetCompressedOutput();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Unarchives the current level based on its snapshot
|
||||
// The level should have already been loaded and setup.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FLevelLocals::UnSnapshotLevel (bool hubLoad)
|
||||
{
|
||||
if (info->Snapshot.mBuffer == nullptr)
|
||||
return;
|
||||
|
||||
if (info->isValid())
|
||||
{
|
||||
FSerializer arc(this);
|
||||
if (!arc.OpenReader(&info->Snapshot))
|
||||
{
|
||||
I_Error("Failed to load savegame");
|
||||
return;
|
||||
}
|
||||
|
||||
Serialize (arc, hubLoad);
|
||||
FromSnapshot = true;
|
||||
|
||||
auto it = GetThinkerIterator<AActor>(NAME_PlayerPawn);
|
||||
AActor *pawn, *next;
|
||||
|
||||
next = it.Next();
|
||||
while ((pawn = next) != 0)
|
||||
{
|
||||
next = it.Next();
|
||||
if (pawn->player == nullptr || pawn->player->mo == nullptr || !PlayerInGame(pawn->player))
|
||||
{
|
||||
int i;
|
||||
|
||||
// If this isn't the unmorphed original copy of a player, destroy it, because it's extra.
|
||||
for (i = 0; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
if (PlayerInGame(i) && Players[i]->morphTics && Players[i]->mo->alternative == pawn)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == MAXPLAYERS)
|
||||
{
|
||||
pawn->Destroy ();
|
||||
}
|
||||
}
|
||||
}
|
||||
arc.Close();
|
||||
}
|
||||
// No reason to keep the snapshot around once the level's been entered.
|
||||
info->Snapshot.Clean();
|
||||
if (hubLoad)
|
||||
{
|
||||
// Unlock ACS global strings that were locked when the snapshot was made.
|
||||
Behaviors.UnlockLevelVarStrings(levelnum);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
@ -1968,23 +1823,6 @@ void G_ReadVisited(FSerializer &arc)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
CCMD(listsnapshots)
|
||||
{
|
||||
for (unsigned i = 0; i < wadlevelinfos.Size(); ++i)
|
||||
{
|
||||
FCompressedBuffer *snapshot = &wadlevelinfos[i].Snapshot;
|
||||
if (snapshot->mBuffer != nullptr)
|
||||
{
|
||||
Printf("%s (%u -> %u bytes)\n", wadlevelinfos[i].MapName.GetChars(), snapshot->mCompressedSize, snapshot->mSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void P_WriteACSDefereds (FSerializer &arc)
|
||||
{
|
||||
bool found = false;
|
||||
|
@ -2322,64 +2160,3 @@ int IsPointInMap(FLevelLocals *Level, double x, double y, double z)
|
|||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Lists all currently defined maps
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
CCMD(listmaps)
|
||||
{
|
||||
for(unsigned i = 0; i < wadlevelinfos.Size(); i++)
|
||||
{
|
||||
level_info_t *info = &wadlevelinfos[i];
|
||||
MapData *map = P_OpenMapData(info->MapName, true);
|
||||
|
||||
if (map != NULL)
|
||||
{
|
||||
Printf("%s: '%s' (%s)\n", info->MapName.GetChars(), info->LookupLevelName().GetChars(),
|
||||
Wads.GetWadName(Wads.GetLumpFile(map->lumpnum)));
|
||||
delete map;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// For testing sky fog sheets
|
||||
//
|
||||
//==========================================================================
|
||||
CCMD(skyfog)
|
||||
{
|
||||
if (argv.argc()>1)
|
||||
{
|
||||
// Do this only on the primary level.
|
||||
primaryLevel->skyfog = MAX(0, (int)strtoull(argv[1], NULL, 0));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ZScript counterpart to ACS ChangeSky, uses TextureIDs
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_ACTION_FUNCTION(FLevelLocals, ChangeSky)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
|
||||
PARAM_INT(sky1);
|
||||
PARAM_INT(sky2);
|
||||
self->skytexture1 = FSetTextureID(sky1);
|
||||
self->skytexture2 = FSetTextureID(sky2);
|
||||
InitSkyMap(self);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FLevelLocals, StartIntermission)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
|
||||
PARAM_NAME(seq);
|
||||
PARAM_INT(state);
|
||||
F_StartIntermission(seq, (uint8_t)state);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -143,6 +143,13 @@ private:
|
|||
void AddDisplacementForPortal(FSectorPortal *portal);
|
||||
void AddDisplacementForPortal(FLinePortal *portal);
|
||||
bool ConnectPortalGroups();
|
||||
|
||||
void SerializePlayers(FSerializer &arc, bool skipload);
|
||||
void CopyPlayer(player_t *dst, player_t *src, const char *name);
|
||||
void ReadOnePlayer(FSerializer &arc, bool skipload);
|
||||
void ReadMultiplePlayers(FSerializer &arc, int numPlayers, int numPlayersNow, bool skipload);
|
||||
void SerializeSounds(FSerializer &arc);
|
||||
|
||||
public:
|
||||
void SnapshotLevel();
|
||||
void UnSnapshotLevel(bool hubLoad);
|
||||
|
@ -646,9 +653,47 @@ public:
|
|||
|
||||
TObjPtr<DSpotState *> SpotState = nullptr;
|
||||
|
||||
bool IsJumpingAllowed() const;
|
||||
bool IsCrouchingAllowed() const;
|
||||
bool IsFreelookAllowed() const;
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool IsJumpingAllowed() const
|
||||
{
|
||||
if (dmflags & DF_NO_JUMP)
|
||||
return false;
|
||||
if (dmflags & DF_YES_JUMP)
|
||||
return true;
|
||||
return !(flags & LEVEL_JUMP_NO);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool IsCrouchingAllowed() const
|
||||
{
|
||||
if (dmflags & DF_NO_CROUCH)
|
||||
return false;
|
||||
if (dmflags & DF_YES_CROUCH)
|
||||
return true;
|
||||
return !(flags & LEVEL_CROUCH_NO);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool IsFreelookAllowed() const
|
||||
{
|
||||
if (dmflags & DF_NO_FREELOOK)
|
||||
return false;
|
||||
if (dmflags & DF_YES_FREELOOK)
|
||||
return true;
|
||||
return !(flags & LEVEL_FREELOOK_NO);
|
||||
}
|
||||
|
||||
node_t *HeadNode() const
|
||||
{
|
||||
|
|
178
src/p_saveg.cpp
178
src/p_saveg.cpp
|
@ -58,8 +58,11 @@
|
|||
#include "events.h"
|
||||
#include "p_destructible.h"
|
||||
#include "r_sky.h"
|
||||
#include "version.h"
|
||||
#include "fragglescript/t_script.h"
|
||||
|
||||
EXTERN_CVAR(Bool, save_formatted)
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
@ -486,6 +489,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FPolyObj &poly, FPolyO
|
|||
("blocked", poly.bBlocked)
|
||||
("hasportals", poly.bHasPortals)
|
||||
("specialdata", poly.specialdata)
|
||||
("level", poly.Level)
|
||||
.EndObject();
|
||||
|
||||
if (arc.isReading())
|
||||
|
@ -526,46 +530,39 @@ FSerializer &Serialize(FSerializer &arc, const char *key, zone_t &z, zone_t *def
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void P_SerializeSounds(FLevelLocals *Level, FSerializer &arc)
|
||||
void FLevelLocals::SerializeSounds(FSerializer &arc)
|
||||
{
|
||||
S_SerializeSounds(arc);
|
||||
const char *name = NULL;
|
||||
uint8_t order;
|
||||
float musvol = Level->MusicVolume;
|
||||
|
||||
if (arc.isWriting())
|
||||
if (isPrimaryLevel())
|
||||
{
|
||||
order = S_GetMusic(&name);
|
||||
}
|
||||
arc.StringPtr("musicname", name)
|
||||
("musicorder", order)
|
||||
("musicvolume", musvol);
|
||||
S_SerializeSounds(arc);
|
||||
const char *name = NULL;
|
||||
uint8_t order;
|
||||
float musvol = MusicVolume;
|
||||
|
||||
if (arc.isReading())
|
||||
{
|
||||
if (!S_ChangeMusic(name, order))
|
||||
Level->SetMusic();
|
||||
Level->SetMusicVolume(musvol);
|
||||
if (arc.isWriting())
|
||||
{
|
||||
order = S_GetMusic(&name);
|
||||
}
|
||||
arc.StringPtr("musicname", name)
|
||||
("musicorder", order)
|
||||
("musicvolume", musvol);
|
||||
|
||||
if (arc.isReading())
|
||||
{
|
||||
if (!S_ChangeMusic(name, order))
|
||||
SetMusic();
|
||||
SetMusicVolume(musvol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void CopyPlayer(player_t *dst, player_t *src, const char *name);
|
||||
static void ReadOnePlayer(FSerializer &arc, bool skipload);
|
||||
static void ReadMultiplePlayers(FSerializer &arc, int numPlayers, int numPlayersNow, bool skipload);
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// P_ArchivePlayers
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void P_SerializePlayers(FLevelLocals *Level, FSerializer &arc, bool skipload)
|
||||
void FLevelLocals::SerializePlayers(FSerializer &arc, bool skipload)
|
||||
{
|
||||
int numPlayers, numPlayersNow;
|
||||
int i;
|
||||
|
@ -573,7 +570,7 @@ void P_SerializePlayers(FLevelLocals *Level, FSerializer &arc, bool skipload)
|
|||
// Count the number of players present right now.
|
||||
for (numPlayersNow = 0, i = 0; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
if (Level->PlayerInGame(i))
|
||||
if (PlayerInGame(i))
|
||||
{
|
||||
++numPlayersNow;
|
||||
}
|
||||
|
@ -588,13 +585,13 @@ void P_SerializePlayers(FLevelLocals *Level, FSerializer &arc, bool skipload)
|
|||
// Record each player's name, followed by their data.
|
||||
for (i = 0; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
if (Level->PlayerInGame(i))
|
||||
if (PlayerInGame(i))
|
||||
{
|
||||
if (arc.BeginObject(nullptr))
|
||||
{
|
||||
const char *n = Level->Players[i]->userinfo.GetName();
|
||||
const char *n = Players[i]->userinfo.GetName();
|
||||
arc.StringPtr("playername", n);
|
||||
Level->Players[i]->Serialize(arc);
|
||||
Players[i]->Serialize(arc);
|
||||
arc.EndObject();
|
||||
}
|
||||
}
|
||||
|
@ -622,10 +619,10 @@ void P_SerializePlayers(FLevelLocals *Level, FSerializer &arc, bool skipload)
|
|||
}
|
||||
if (!skipload && numPlayersNow > numPlayers)
|
||||
{
|
||||
Level->SpawnExtraPlayers();
|
||||
SpawnExtraPlayers();
|
||||
}
|
||||
// Redo pitch limits, since the spawned player has them at 0.
|
||||
auto p = Level->GetConsolePlayer();
|
||||
auto p = GetConsolePlayer();
|
||||
if (p) p->SendPitchLimits();
|
||||
}
|
||||
}
|
||||
|
@ -636,7 +633,7 @@ void P_SerializePlayers(FLevelLocals *Level, FSerializer &arc, bool skipload)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
static void ReadOnePlayer(FSerializer &arc, bool skipload)
|
||||
void FLevelLocals::ReadOnePlayer(FSerializer &arc, bool skipload)
|
||||
{
|
||||
int i;
|
||||
const char *name = NULL;
|
||||
|
@ -663,20 +660,20 @@ static void ReadOnePlayer(FSerializer &arc, bool skipload)
|
|||
// via a net command, but that won't be processed in time for a screen
|
||||
// wipe, so we need something here.
|
||||
playerTemp.MaxPitch = playerTemp.MinPitch = playerTemp.mo->Angles.Pitch;
|
||||
CopyPlayer(&players[i], &playerTemp, name);
|
||||
CopyPlayer(Players[i], &playerTemp, name);
|
||||
}
|
||||
else
|
||||
{
|
||||
// we need the player actor, so that G_FinishTravel can destroy it later.
|
||||
players[i].mo = playerTemp.mo;
|
||||
Players[i]->mo = playerTemp.mo;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (players[i].mo != NULL)
|
||||
if (Players[i]->mo != NULL)
|
||||
{
|
||||
players[i].mo->Destroy();
|
||||
players[i].mo = NULL;
|
||||
Players[i]->mo->Destroy();
|
||||
Players[i]->mo = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -691,7 +688,7 @@ static void ReadOnePlayer(FSerializer &arc, bool skipload)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
static void ReadMultiplePlayers(FSerializer &arc, int numPlayers, int numPlayersNow, bool skipload)
|
||||
void FLevelLocals::ReadMultiplePlayers(FSerializer &arc, int numPlayers, int numPlayersNow, bool skipload)
|
||||
{
|
||||
// For two or more players, read each player into a temporary array.
|
||||
int i, j;
|
||||
|
@ -729,7 +726,7 @@ static void ReadMultiplePlayers(FSerializer &arc, int numPlayers, int numPlayers
|
|||
if (playerUsed[j] == 0 && stricmp(players[j].userinfo.GetName(), nametemp[i]) == 0)
|
||||
{ // Found a match, so copy our temp player to the real player
|
||||
Printf("Found player %d (%s) at %d\n", i, nametemp[i], j);
|
||||
CopyPlayer(&players[j], &playertemp[i], nametemp[i]);
|
||||
CopyPlayer(Players[j], &playertemp[i], nametemp[i]);
|
||||
playerUsed[j] = 1;
|
||||
tempPlayerUsed[i] = 1;
|
||||
break;
|
||||
|
@ -802,7 +799,7 @@ static void ReadMultiplePlayers(FSerializer &arc, int numPlayers, int numPlayers
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void CopyPlayer(player_t *dst, player_t *src, const char *name)
|
||||
void FLevelLocals::CopyPlayer(player_t *dst, player_t *src, const char *name)
|
||||
{
|
||||
// The userinfo needs to be saved for real players, but it
|
||||
// needs to come from the save for bots.
|
||||
|
@ -823,7 +820,7 @@ void CopyPlayer(player_t *dst, player_t *src, const char *name)
|
|||
|
||||
if (dst->Bot != nullptr)
|
||||
{
|
||||
botinfo_t *thebot = src->mo->Level->BotInfo.botinfo;
|
||||
botinfo_t *thebot = BotInfo.botinfo;
|
||||
while (thebot && stricmp(name, thebot->name))
|
||||
{
|
||||
thebot = thebot->next;
|
||||
|
@ -832,14 +829,14 @@ void CopyPlayer(player_t *dst, player_t *src, const char *name)
|
|||
{
|
||||
thebot->inuse = BOTINUSE_Yes;
|
||||
}
|
||||
src->mo->Level->BotInfo.botnum++;
|
||||
BotInfo.botnum++;
|
||||
dst->userinfo.TransferFrom(uibackup2);
|
||||
}
|
||||
else
|
||||
{
|
||||
dst->userinfo.TransferFrom(uibackup);
|
||||
// The player class must come from the save, so that the menu reflects the currently playing one.
|
||||
dst->userinfo.PlayerClassChanged(src->mo->GetInfo()->DisplayName);
|
||||
dst->userinfo.PlayerClassChanged(src->mo->GetInfo()->DisplayName);
|
||||
}
|
||||
|
||||
// Validate the skin
|
||||
|
@ -868,6 +865,7 @@ void CopyPlayer(player_t *dst, player_t *src, const char *name)
|
|||
dst->usedown = usedown;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
@ -1006,8 +1004,8 @@ void FLevelLocals::Serialize(FSerializer &arc, bool hubload)
|
|||
StatusBar->SerializeMessages(arc);
|
||||
FRemapTable::StaticSerializeTranslations(arc);
|
||||
canvasTextureInfo.Serialize(arc);
|
||||
P_SerializePlayers(this, arc, hubload);
|
||||
P_SerializeSounds(this, arc);
|
||||
SerializePlayers(arc, hubload);
|
||||
SerializeSounds(arc);
|
||||
|
||||
// Regenerate some data that wasn't saved
|
||||
if (arc.isReading())
|
||||
|
@ -1036,3 +1034,87 @@ void FLevelLocals::Serialize(FSerializer &arc, bool hubload)
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Archives the current level
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FLevelLocals::SnapshotLevel()
|
||||
{
|
||||
info->Snapshot.Clean();
|
||||
|
||||
if (info->isValid())
|
||||
{
|
||||
FSerializer arc(this);
|
||||
|
||||
if (arc.OpenWriter(save_formatted))
|
||||
{
|
||||
SaveVersion = SAVEVER;
|
||||
Serialize(arc, false);
|
||||
info->Snapshot = arc.GetCompressedOutput();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Unarchives the current level based on its snapshot
|
||||
// The level should have already been loaded and setup.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FLevelLocals::UnSnapshotLevel(bool hubLoad)
|
||||
{
|
||||
if (info->Snapshot.mBuffer == nullptr)
|
||||
return;
|
||||
|
||||
if (info->isValid())
|
||||
{
|
||||
FSerializer arc(this);
|
||||
if (!arc.OpenReader(&info->Snapshot))
|
||||
{
|
||||
I_Error("Failed to load savegame");
|
||||
return;
|
||||
}
|
||||
|
||||
Serialize(arc, hubLoad);
|
||||
FromSnapshot = true;
|
||||
|
||||
auto it = GetThinkerIterator<AActor>(NAME_PlayerPawn);
|
||||
AActor *pawn, *next;
|
||||
|
||||
next = it.Next();
|
||||
while ((pawn = next) != 0)
|
||||
{
|
||||
next = it.Next();
|
||||
if (pawn->player == nullptr || pawn->player->mo == nullptr || !PlayerInGame(pawn->player))
|
||||
{
|
||||
int i;
|
||||
|
||||
// If this isn't the unmorphed original copy of a player, destroy it, because it's extra.
|
||||
for (i = 0; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
if (PlayerInGame(i) && Players[i]->morphTics && Players[i]->mo->alternative == pawn)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == MAXPLAYERS)
|
||||
{
|
||||
pawn->Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
arc.Close();
|
||||
}
|
||||
// No reason to keep the snapshot around once the level's been entered.
|
||||
info->Snapshot.Clean();
|
||||
if (hubLoad)
|
||||
{
|
||||
// Unlock ACS global strings that were locked when the snapshot was made.
|
||||
Behaviors.UnlockLevelVarStrings(levelnum);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -68,3 +68,7 @@ EXTERN_CVAR(Int, gl_enhanced_nv_stealth)
|
|||
EXTERN_CVAR(Int, gl_fuzztype)
|
||||
|
||||
EXTERN_CVAR(Int, gl_shadowmap_filter)
|
||||
|
||||
EXTERN_CVAR(Bool, gl_brightfog)
|
||||
EXTERN_CVAR(Bool, gl_lightadditivesurfaces)
|
||||
EXTERN_CVAR(Bool, gl_notexturefill)
|
||||
|
|
|
@ -49,6 +49,8 @@
|
|||
#include "i_music.h"
|
||||
#include "am_map.h"
|
||||
#include "v_video.h"
|
||||
#include "gi.h"
|
||||
#include "intermission/intermission.h"
|
||||
|
||||
DVector2 AM_GetPosition();
|
||||
int Net_GetLatency(int *ld, int *ad);
|
||||
|
@ -1627,6 +1629,76 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Sector, SetXOffset, SetXOffset)
|
|||
//
|
||||
//=====================================================================================
|
||||
|
||||
static int IsJumpingAllowed(FLevelLocals *self)
|
||||
{
|
||||
return self->IsJumpingAllowed();
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, IsJumpingAllowed, IsJumpingAllowed)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
|
||||
ACTION_RETURN_BOOL(self->IsJumpingAllowed());
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static int IsCrouchingAllowed(FLevelLocals *self)
|
||||
{
|
||||
return self->IsCrouchingAllowed();
|
||||
}
|
||||
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, IsCrouchingAllowed, IsCrouchingAllowed)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
|
||||
ACTION_RETURN_BOOL(self->IsCrouchingAllowed());
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static int IsFreelookAllowed(FLevelLocals *self)
|
||||
{
|
||||
return self->IsFreelookAllowed();
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, IsFreelookAllowed, IsFreelookAllowed)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
|
||||
ACTION_RETURN_BOOL(self->IsFreelookAllowed());
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ZScript counterpart to ACS ChangeSky, uses TextureIDs
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_ACTION_FUNCTION(FLevelLocals, ChangeSky)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
|
||||
PARAM_INT(sky1);
|
||||
PARAM_INT(sky2);
|
||||
self->skytexture1 = FSetTextureID(sky1);
|
||||
self->skytexture2 = FSetTextureID(sky2);
|
||||
InitSkyMap(self);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FLevelLocals, StartIntermission)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals);
|
||||
PARAM_NAME(seq);
|
||||
PARAM_INT(state);
|
||||
F_StartIntermission(seq, (uint8_t)state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// This is needed to convert the strings to char pointers.
|
||||
static void ReplaceTextures(FLevelLocals *self, const FString &from, const FString &to, int flags)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue