- cleaned up g_level.cpp

SVN r1392 (newmapinfo)
This commit is contained in:
Christoph Oelckers 2009-02-03 18:13:58 +00:00
parent fabc0906a7
commit 92d17c0397
10 changed files with 656 additions and 330 deletions

View file

@ -73,6 +73,7 @@
#include "cmdlib.h"
#include "d_net.h"
#include "d_event.h"
#include "p_acs.h"
#include <zlib.h>
@ -1574,128 +1575,6 @@ bool G_CheckSaveGameWads (PNGHandle *png, bool printwarn)
return true;
}
static void WriteVars (FILE *file, SDWORD *vars, size_t count, DWORD id)
{
size_t i, j;
for (i = 0; i < count; ++i)
{
if (vars[i] != 0)
break;
}
if (i < count)
{
// Find last non-zero var. Anything beyond the last stored variable
// will be zeroed at load time.
for (j = count-1; j > i; --j)
{
if (vars[j] != 0)
break;
}
FPNGChunkArchive arc (file, id);
for (i = 0; i <= j; ++i)
{
DWORD var = vars[i];
arc << var;
}
}
}
static void ReadVars (PNGHandle *png, SDWORD *vars, size_t count, DWORD id)
{
size_t len = M_FindPNGChunk (png, id);
size_t used = 0;
if (len != 0)
{
DWORD var;
size_t i;
FPNGChunkArchive arc (png->File->GetFile(), id, len);
used = len / 4;
for (i = 0; i < used; ++i)
{
arc << var;
vars[i] = var;
}
png->File->ResetFilePtr();
}
if (used < count)
{
memset (&vars[used], 0, (count-used)*4);
}
}
static void WriteArrayVars (FILE *file, FWorldGlobalArray *vars, unsigned int count, DWORD id)
{
unsigned int i, j;
// Find the first non-empty array.
for (i = 0; i < count; ++i)
{
if (vars[i].CountUsed() != 0)
break;
}
if (i < count)
{
// Find last non-empty array. Anything beyond the last stored array
// will be emptied at load time.
for (j = count-1; j > i; --j)
{
if (vars[j].CountUsed() != 0)
break;
}
FPNGChunkArchive arc (file, id);
arc.WriteCount (i);
arc.WriteCount (j);
for (; i <= j; ++i)
{
arc.WriteCount (vars[i].CountUsed());
FWorldGlobalArray::ConstIterator it(vars[i]);
const FWorldGlobalArray::Pair *pair;
while (it.NextPair (pair))
{
arc.WriteCount (pair->Key);
arc.WriteCount (pair->Value);
}
}
}
}
static void ReadArrayVars (PNGHandle *png, FWorldGlobalArray *vars, size_t count, DWORD id)
{
size_t len = M_FindPNGChunk (png, id);
unsigned int i, k;
for (i = 0; i < count; ++i)
{
vars[i].Clear ();
}
if (len != 0)
{
DWORD max, size;
FPNGChunkArchive arc (png->File->GetFile(), id, len);
i = arc.ReadCount ();
max = arc.ReadCount ();
for (; i <= max; ++i)
{
size = arc.ReadCount ();
for (k = 0; k < size; ++k)
{
SDWORD key, val;
key = arc.ReadCount();
val = arc.ReadCount();
vars[i].Insert (key, val);
}
}
png->File->ResetFilePtr();
}
}
void G_DoLoadGame ()
{
@ -1815,10 +1694,7 @@ void G_DoLoadGame ()
delete[] map;
savegamerestore = false;
ReadVars (png, ACS_WorldVars, NUM_WORLDVARS, MAKE_ID('w','v','A','r'));
ReadVars (png, ACS_GlobalVars, NUM_GLOBALVARS, MAKE_ID('g','v','A','r'));
ReadArrayVars (png, ACS_WorldArrays, NUM_WORLDVARS, MAKE_ID('w','a','R','r'));
ReadArrayVars (png, ACS_GlobalArrays, NUM_GLOBALVARS, MAKE_ID('g','a','R','r'));
P_ReadACSVars(png);
NextSkill = -1;
if (M_FindPNGChunk (png, MAKE_ID('s','n','X','t')) == 1)
@ -2064,10 +1940,7 @@ void G_DoSaveGame (bool okForQuicksave, FString filename, const char *descriptio
FRandom::StaticWriteRNGState (stdfile);
P_WriteACSDefereds (stdfile);
WriteVars (stdfile, ACS_WorldVars, NUM_WORLDVARS, MAKE_ID('w','v','A','r'));
WriteVars (stdfile, ACS_GlobalVars, NUM_GLOBALVARS, MAKE_ID('g','v','A','r'));
WriteArrayVars (stdfile, ACS_WorldArrays, NUM_WORLDVARS, MAKE_ID('w','a','R','r'));
WriteArrayVars (stdfile, ACS_GlobalArrays, NUM_GLOBALVARS, MAKE_ID('g','a','R','r'));
P_WriteACSVars(stdfile);
if (NextSkill != -1)
{

View file

@ -98,6 +98,7 @@ EXTERN_CVAR (Int, disableautosave)
static void SetEndSequence (char *nextmap, int type);
void G_VerifySkill();
static FRandom pr_classchoice ("RandomPlayerClassChoice");
TArray<EndSequence> EndSequences;
@ -110,20 +111,13 @@ EndSequence::EndSequence()
PlayTheEnd = false;
}
extern level_info_t TheDefaultLevelInfo;
extern bool timingdemo;
// Start time for timing demos
int starttime;
// ACS variables with world scope
SDWORD ACS_WorldVars[NUM_WORLDVARS];
FWorldGlobalArray ACS_WorldArrays[NUM_WORLDVARS];
// ACS variables with global scope
SDWORD ACS_GlobalVars[NUM_GLOBALVARS];
FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS];
extern bool netdemo;
extern FString BackupSaveName;
@ -137,19 +131,10 @@ void *statcopy; // for statistics driver
FLevelLocals level; // info about current level
TArray<cluster_info_t> wadclusterinfos;
TArray<level_info_t> wadlevelinfos;
static level_info_t TheDefaultLevelInfo;
static cluster_info_t TheDefaultClusterInfo;
int FindWadLevelInfo (const char *name);
int FindWadClusterInfo (int cluster);
void ClearEpisodes();
//==========================================================================
//
//
//==========================================================================
int FindEndSequence (int type, const char *picname)
{
@ -167,6 +152,11 @@ int FindEndSequence (int type, const char *picname)
return -1;
}
//==========================================================================
//
//
//==========================================================================
static void SetEndSequence (char *nextmap, int type)
{
int seqnum;
@ -182,6 +172,11 @@ static void SetEndSequence (char *nextmap, int type)
*((WORD *)(nextmap + 6)) = (WORD)seqnum;
}
//==========================================================================
//
//
//==========================================================================
void G_SetForEndGame (char *nextmap)
{
if (!strncmp(nextmap, "enDSeQ",6)) return; // If there is already an end sequence please leave it alone!!!
@ -205,74 +200,14 @@ void G_SetForEndGame (char *nextmap)
}
}
void G_UnloadMapInfo ()
{
G_ClearSnapshots ();
wadlevelinfos.Clear();
wadclusterinfos.Clear();
ClearEpisodes();
}
level_info_t *FindLevelByWarpTrans (int num)
{
for (unsigned i = wadlevelinfos.Size(); i-- != 0; )
if (wadlevelinfos[i].WarpTrans == num)
return &wadlevelinfos[i];
return NULL;
}
static void zapDefereds (acsdefered_t *def)
{
while (def)
{
acsdefered_t *next = def->next;
delete def;
def = next;
}
}
void P_RemoveDefereds (void)
{
// Remove any existing defereds
for (unsigned int i = 0; i < wadlevelinfos.Size(); i++)
{
if (wadlevelinfos[i].defered)
{
zapDefereds (wadlevelinfos[i].defered);
wadlevelinfos[i].defered = NULL;
}
}
}
bool CheckWarpTransMap (FString &mapname, bool substitute)
{
if (mapname[0] == '&' && (mapname[1] & 0xDF) == 'W' &&
(mapname[2] & 0xDF) == 'T' && mapname[3] == '@')
{
level_info_t *lev = FindLevelByWarpTrans (atoi (&mapname[4]));
if (lev != NULL)
{
mapname = lev->mapname;
return true;
}
else if (substitute)
{
char a = mapname[4], b = mapname[5];
mapname = "MAP";
mapname << a << b;
}
}
return false;
}
//==========================================================================
//
// G_InitNew
// Can be called by the startup code or the menu task,
// consoleplayer, playeringame[] should be set.
//
//==========================================================================
static FString d_mapname;
static int d_skill=-1;
@ -284,6 +219,11 @@ void G_DeferedInitNew (const char *mapname, int newskill)
gameaction = ga_newgame2;
}
//==========================================================================
//
//
//==========================================================================
CCMD (map)
{
if (netgame)
@ -309,6 +249,11 @@ CCMD (map)
}
}
//==========================================================================
//
//
//==========================================================================
CCMD (open)
{
if (netgame)
@ -337,6 +282,11 @@ CCMD (open)
}
//==========================================================================
//
//
//==========================================================================
void G_NewInit ()
{
int i;
@ -369,6 +319,11 @@ void G_NewInit ()
NextSkill = -1;
}
//==========================================================================
//
//
//==========================================================================
void G_DoNewGame (void)
{
G_NewInit ();
@ -381,10 +336,15 @@ void G_DoNewGame (void)
gameaction = ga_nothing;
}
//==========================================================================
//
// Initializes player classes in case they are random.
// This gets called at the start of a new game, and the classes
// chosen here are used for the remainder of a single-player
// or coop game. These are ignored for deathmatch.
//
//==========================================================================
static void InitPlayerClasses ()
{
@ -403,6 +363,11 @@ static void InitPlayerClasses ()
}
}
//==========================================================================
//
//
//==========================================================================
void G_InitNew (const char *mapname, bool bTitleLevel)
{
EGameSpeed oldSpeed;
@ -518,16 +483,7 @@ void G_InitNew (const char *mapname, bool bTitleLevel)
rngseed = rngseed*3/2;
}
FRandom::StaticClearRandom ();
memset (ACS_WorldVars, 0, sizeof(ACS_WorldVars));
memset (ACS_GlobalVars, 0, sizeof(ACS_GlobalVars));
for (i = 0; i < NUM_WORLDVARS; ++i)
{
ACS_WorldArrays[i].Clear ();
}
for (i = 0; i < NUM_GLOBALVARS; ++i)
{
ACS_GlobalArrays[i].Clear ();
}
P_ClearACSVars(true);
level.time = 0;
level.maptime = 0;
level.totaltime = 0;
@ -581,9 +537,14 @@ static bool resetinventory; // Reset the inventory to the player's default for
static bool unloading;
static bool g_nomonsters;
//==========================================================================
//
// [RH] The position parameter to these next three functions should
// match the first parameter of the single player start spots
// that should appear in the next map.
//
//==========================================================================
void G_ChangeLevel(const char *levelname, int position, bool keepFacing, int nextSkill,
bool nointermission, bool resetinv, bool nomonsters)
@ -598,7 +559,7 @@ void G_ChangeLevel(const char *levelname, int position, bool keepFacing, int nex
if (strncmp(levelname, "enDSeQ", 6))
{
level_info_t *nextinfo = CheckLevelRedirect (FindLevelInfo (nextlevel));
level_info_t *nextinfo = FindLevelInfo (nextlevel)->CheckLevelRedirect ();
if (nextinfo)
{
nextlevel = nextinfo->mapname;
@ -660,6 +621,11 @@ void G_ChangeLevel(const char *levelname, int position, bool keepFacing, int nex
}
}
//==========================================================================
//
//
//==========================================================================
const char *G_GetExitMap()
{
return level.nextmap;
@ -679,6 +645,11 @@ const char *G_GetSecretExitMap()
return nextmap;
}
//==========================================================================
//
//
//==========================================================================
void G_ExitLevel (int position, bool keepFacing)
{
G_ChangeLevel(G_GetExitMap(), position, keepFacing);
@ -689,6 +660,11 @@ void G_SecretExitLevel (int position)
G_ChangeLevel(G_GetSecretExitMap(), position, false);
}
//==========================================================================
//
//
//==========================================================================
void G_DoCompleted (void)
{
int i;
@ -809,11 +785,7 @@ void G_DoCompleted (void)
if (mode == FINISH_NextHub)
{ // Reset world variables for the new hub.
memset (ACS_WorldVars, 0, sizeof(ACS_WorldVars));
for (i = 0; i < NUM_WORLDVARS; ++i)
{
ACS_WorldArrays[i].Clear ();
}
P_ClearACSVars(false);
}
// With hub statistics the time should be per hub.
// Additionally there is a global time counter now so nothing is missed by changing it
@ -843,6 +815,11 @@ void G_DoCompleted (void)
WI_Start (&wminfo);
}
//==========================================================================
//
//
//==========================================================================
class DAutosaver : public DThinker
{
DECLARE_CLASS (DAutosaver, DThinker)
@ -858,9 +835,12 @@ void DAutosaver::Tick ()
Destroy ();
}
//==========================================================================
//
// G_DoLoadLevel
//
//==========================================================================
extern gamestate_t wipegamestate;
void G_DoLoadLevel (int position, bool autosave)
@ -1005,9 +985,12 @@ void G_DoLoadLevel (int position, bool autosave)
}
//==========================================================================
//
// G_WorldDone
//
//==========================================================================
void G_WorldDone (void)
{
cluster_info_t *nextcluster;
@ -1062,6 +1045,11 @@ void G_WorldDone (void)
}
}
//==========================================================================
//
//
//==========================================================================
void G_DoWorldDone (void)
{
gamestate = GS_LEVEL;
@ -1205,6 +1193,11 @@ void G_FinishTravel ()
}
}
//==========================================================================
//
//
//==========================================================================
void G_InitLevelLocals ()
{
level_info_t *info;
@ -1225,7 +1218,6 @@ void G_InitLevelLocals ()
level.info = info;
level.skyspeed1 = info->skyspeed1;
level.skyspeed2 = info->skyspeed2;
info = (level_info_t *)info;
strncpy (level.skypic2, info->skypic2, 8);
level.fadeto = info->fadeto;
level.cdtrack = info->cdtrack;
@ -1307,6 +1299,11 @@ void G_InitLevelLocals ()
NormalLight.ChangeFade (level.fadeto);
}
//==========================================================================
//
//
//==========================================================================
bool FLevelLocals::IsJumpingAllowed() const
{
if (dmflags & DF_NO_JUMP)
@ -1316,6 +1313,11 @@ bool FLevelLocals::IsJumpingAllowed() const
return !(level.flags & LEVEL_JUMP_NO);
}
//==========================================================================
//
//
//==========================================================================
bool FLevelLocals::IsCrouchingAllowed() const
{
if (dmflags & DF_NO_CROUCH)
@ -1325,6 +1327,11 @@ bool FLevelLocals::IsCrouchingAllowed() const
return !(level.flags & LEVEL_CROUCH_NO);
}
//==========================================================================
//
//
//==========================================================================
bool FLevelLocals::IsFreelookAllowed() const
{
if (level.flags & LEVEL_FREELOOK_NO)
@ -1334,6 +1341,11 @@ bool FLevelLocals::IsFreelookAllowed() const
return !(dmflags & DF_NO_FREELOOK);
}
//==========================================================================
//
//
//==========================================================================
FString CalcMapName (int episode, int level)
{
FString lumpname;
@ -1350,66 +1362,10 @@ FString CalcMapName (int episode, int level)
return lumpname;
}
level_info_t *FindLevelInfo (const char *mapname)
{
int i;
if ((i = FindWadLevelInfo (mapname)) > -1)
return &wadlevelinfos[i];
else
{
if (TheDefaultLevelInfo.LevelName.IsEmpty())
{
uppercopy(TheDefaultLevelInfo.skypic1, "SKY1");
uppercopy(TheDefaultLevelInfo.skypic2, "SKY1");
TheDefaultLevelInfo.LevelName = "Unnamed";
}
return &TheDefaultLevelInfo;
}
}
level_info_t *FindLevelByNum (int num)
{
for (unsigned int i = 0; i < wadlevelinfos.Size(); i++)
if (wadlevelinfos[i].levelnum == num)
return &wadlevelinfos[i];
return NULL;
}
level_info_t *CheckLevelRedirect (level_info_t *info)
{
if (info->RedirectType != NAME_None)
{
const PClass *type = PClass::FindClass(info->RedirectType);
if (type != NULL)
{
for (int i = 0; i < MAXPLAYERS; ++i)
{
if (playeringame[i] && players[i].mo->FindInventory (type))
{
// check for actual presence of the map.
if (P_CheckMapData(info->RedirectMap))
{
return FindLevelInfo(info->RedirectMap);
}
break;
}
}
}
}
return NULL;
}
cluster_info_t *FindClusterInfo (int cluster)
{
int i;
if ((i = FindWadClusterInfo (cluster)) > -1)
return &wadclusterinfos[i];
else
return &TheDefaultClusterInfo;
}
//==========================================================================
//
//
//==========================================================================
void G_AirControlChanged ()
{
@ -1425,6 +1381,11 @@ void G_AirControlChanged ()
}
}
//==========================================================================
//
//
//==========================================================================
void G_SerializeLevel (FArchive &arc, bool hubLoad)
{
int i = level.totaltime;
@ -1537,13 +1498,18 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad)
}
}
//==========================================================================
//
// Archives the current level
//
//==========================================================================
void G_SnapshotLevel ()
{
if (level.info->snapshot)
delete level.info->snapshot;
if (level.info->mapname[0] != 0 || level.info == &TheDefaultLevelInfo)
if (level.info->isValid())
{
level.info->snapshotVer = SAVEVER;
level.info->snapshot = new FCompressedMemFile;
@ -1556,14 +1522,19 @@ void G_SnapshotLevel ()
}
}
//==========================================================================
//
// Unarchives the current level based on its snapshot
// The level should have already been loaded and setup.
//
//==========================================================================
void G_UnSnapshotLevel (bool hubLoad)
{
if (level.info->snapshot == NULL)
return;
if (level.info->mapname[0] != 0 || level.info == &TheDefaultLevelInfo)
if (level.info->isValid())
{
SaveVersion = level.info->snapshotVer;
level.info->snapshot->Reopen ();
@ -1601,21 +1572,13 @@ void G_UnSnapshotLevel (bool hubLoad)
}
}
// No reason to keep the snapshot around once the level's been entered.
delete level.info->snapshot;
level.info->snapshot = NULL;
level.info->ClearSnapshot();
}
void G_ClearSnapshots (void)
{
for (unsigned int i = 0; i < wadlevelinfos.Size(); i++)
{
if (wadlevelinfos[i].snapshot)
{
delete wadlevelinfos[i].snapshot;
wadlevelinfos[i].snapshot = NULL;
}
}
}
//==========================================================================
//
//
//==========================================================================
static void writeMapName (FArchive &arc, const char *name)
{
@ -1632,6 +1595,11 @@ static void writeMapName (FArchive &arc, const char *name)
arc.Write (name, size);
}
//==========================================================================
//
//
//==========================================================================
static void writeSnapShot (FArchive &arc, level_info_t *i)
{
arc << i->snapshotVer;
@ -1639,6 +1607,11 @@ static void writeSnapShot (FArchive &arc, level_info_t *i)
i->snapshot->Serialize (arc);
}
//==========================================================================
//
//
//==========================================================================
void G_WriteSnapshots (FILE *file)
{
unsigned int i;
@ -1706,6 +1679,11 @@ void G_WriteSnapshots (FILE *file)
}
}
//==========================================================================
//
//
//==========================================================================
void G_ReadSnapshots (PNGHandle *png)
{
DWORD chunkLen;
@ -1792,12 +1770,22 @@ void G_ReadSnapshots (PNGHandle *png)
}
//==========================================================================
//
//
//==========================================================================
static void writeDefereds (FArchive &arc, level_info_t *i)
{
writeMapName (arc, i->mapname);
arc << i->defered;
}
//==========================================================================
//
//
//==========================================================================
void P_WriteACSDefereds (FILE *file)
{
FPNGChunkArchive *arc = NULL;
@ -1823,6 +1811,11 @@ void P_WriteACSDefereds (FILE *file)
}
}
//==========================================================================
//
//
//==========================================================================
void P_ReadACSDefereds (PNGHandle *png)
{
BYTE namelen;
@ -1853,6 +1846,11 @@ void P_ReadACSDefereds (PNGHandle *png)
}
//==========================================================================
//
//
//==========================================================================
void FLevelLocals::Tick ()
{
// Reset carry sectors
@ -1862,6 +1860,11 @@ void FLevelLocals::Tick ()
}
}
//==========================================================================
//
//
//==========================================================================
void FLevelLocals::AddScroller (DScroller *scroller, int secnum)
{
if (secnum < 0)

View file

@ -112,9 +112,6 @@ struct FMapOptInfo
bool old;
};
#define NUM_WORLDVARS 256
#define NUM_GLOBALVARS 64
enum ELevelFlags
{
LEVEL_NOINTERMISSION = 0x00000001,
@ -283,9 +280,21 @@ struct level_info_t
TArray<FSpecialAction> specialactions;
level_info_t() { Reset(); }
level_info_t()
{
Reset();
}
~level_info_t()
{
ClearSnapshot();
ClearDefered();
}
void Reset();
bool isValid();
FString LookupLevelName ();
void ClearSnapshot();
void ClearDefered();
level_info_t *CheckLevelRedirect ();
};
@ -423,21 +432,6 @@ extern FLevelLocals level;
extern TArray<level_info_t> wadlevelinfos;
extern TArray<cluster_info_t> wadclusterinfos;
extern SDWORD ACS_WorldVars[NUM_WORLDVARS];
extern SDWORD ACS_GlobalVars[NUM_GLOBALVARS];
struct InitIntToZero
{
void Init(int &v)
{
v = 0;
}
};
typedef TMap<SDWORD, SDWORD, THashTraits<SDWORD>, InitIntToZero> FWorldGlobalArray;
extern FWorldGlobalArray ACS_WorldArrays[NUM_WORLDVARS];
extern FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS];
extern bool savegamerestore;
// mapname will be changed if it is a valid warptrans
@ -477,9 +471,9 @@ level_info_t *CheckLevelRedirect (level_info_t *info);
FString CalcMapName (int episode, int level);
void G_ParseMapInfo (void);
void G_UnloadMapInfo ();
void G_ClearSnapshots (void);
void P_RemoveDefereds ();
void G_SnapshotLevel (void);
void G_UnSnapshotLevel (bool keepPlayers);
struct PNGHandle;

View file

@ -46,11 +46,26 @@
#include "i_system.h"
#include "gi.h"
#include "gstrings.h"
#include "farchive.h"
#include "p_acs.h"
#include "doomstat.h"
#include "d_player.h"
int FindEndSequence (int type, const char *picname);
int FindWadLevelInfo (const char *name)
TArray<cluster_info_t> wadclusterinfos;
TArray<level_info_t> wadlevelinfos;
level_info_t TheDefaultLevelInfo;
static cluster_info_t TheDefaultClusterInfo;
//==========================================================================
//
//
//==========================================================================
static int FindWadLevelInfo (const char *name)
{
for (unsigned int i = 0; i < wadlevelinfos.Size(); i++)
if (!strnicmp (name, wadlevelinfos[i].mapname, 8))
@ -59,7 +74,90 @@ int FindWadLevelInfo (const char *name)
return -1;
}
int FindWadClusterInfo (int cluster)
//==========================================================================
//
//
//==========================================================================
level_info_t *FindLevelInfo (const char *mapname)
{
int i;
if ((i = FindWadLevelInfo (mapname)) > -1)
return &wadlevelinfos[i];
else
{
if (TheDefaultLevelInfo.LevelName.IsEmpty())
{
uppercopy(TheDefaultLevelInfo.skypic1, "SKY1");
uppercopy(TheDefaultLevelInfo.skypic2, "SKY1");
TheDefaultLevelInfo.LevelName = "Unnamed";
}
return &TheDefaultLevelInfo;
}
}
//==========================================================================
//
//
//==========================================================================
level_info_t *FindLevelByNum (int num)
{
for (unsigned int i = 0; i < wadlevelinfos.Size(); i++)
if (wadlevelinfos[i].levelnum == num)
return &wadlevelinfos[i];
return NULL;
}
//==========================================================================
//
//
//==========================================================================
static level_info_t *FindLevelByWarpTrans (int num)
{
for (unsigned i = wadlevelinfos.Size(); i-- != 0; )
if (wadlevelinfos[i].WarpTrans == num)
return &wadlevelinfos[i];
return NULL;
}
//==========================================================================
//
//
//==========================================================================
bool CheckWarpTransMap (FString &mapname, bool substitute)
{
if (mapname[0] == '&' && (mapname[1] & 0xDF) == 'W' &&
(mapname[2] & 0xDF) == 'T' && mapname[3] == '@')
{
level_info_t *lev = FindLevelByWarpTrans (atoi (&mapname[4]));
if (lev != NULL)
{
mapname = lev->mapname;
return true;
}
else if (substitute)
{
char a = mapname[4], b = mapname[5];
mapname = "MAP";
mapname << a << b;
}
}
return false;
}
//==========================================================================
//
//
//==========================================================================
static int FindWadClusterInfo (int cluster)
{
for (unsigned int i = 0; i < wadclusterinfos.Size(); i++)
if (wadclusterinfos[i].cluster == cluster)
@ -68,6 +166,49 @@ int FindWadClusterInfo (int cluster)
return -1;
}
//==========================================================================
//
//
//==========================================================================
cluster_info_t *FindClusterInfo (int cluster)
{
int i;
if ((i = FindWadClusterInfo (cluster)) > -1)
return &wadclusterinfos[i];
else
return &TheDefaultClusterInfo;
}
//==========================================================================
//
//
//==========================================================================
void G_ClearSnapshots (void)
{
for (unsigned int i = 0; i < wadlevelinfos.Size(); i++)
{
wadlevelinfos[i].ClearSnapshot();
}
}
//==========================================================================
//
// Remove any existing defereds
//
//==========================================================================
void P_RemoveDefereds (void)
{
for (unsigned int i = 0; i < wadlevelinfos.Size(); i++)
{
wadlevelinfos[i].ClearDefered();
}
}
//==========================================================================
//
//
@ -169,6 +310,73 @@ FString level_info_t::LookupLevelName()
}
//==========================================================================
//
//
//==========================================================================
void level_info_t::ClearSnapshot()
{
if (snapshot != NULL) delete snapshot;
snapshot = NULL;
}
//==========================================================================
//
//
//==========================================================================
void level_info_t::ClearDefered()
{
acsdefered_t *def = defered;
while (def)
{
acsdefered_t *next = def->next;
delete def;
def = next;
}
defered = NULL;
}
//==========================================================================
//
//
//==========================================================================
level_info_t *level_info_t::CheckLevelRedirect ()
{
if (RedirectType != NAME_None)
{
const PClass *type = PClass::FindClass(RedirectType);
if (type != NULL)
{
for (int i = 0; i < MAXPLAYERS; ++i)
{
if (playeringame[i] && players[i].mo->FindInventory (type))
{
// check for actual presence of the map.
if (P_CheckMapData(RedirectMap))
{
return FindLevelInfo(RedirectMap);
}
break;
}
}
}
}
return NULL;
}
//==========================================================================
//
//
//==========================================================================
bool level_info_t::isValid()
{
return mapname[0] != 0 || this == &TheDefaultLevelInfo;
}
//==========================================================================
//
//
@ -1609,6 +1817,8 @@ void G_ParseMapInfo ()
int lump, lastlump = 0;
level_info_t gamedefaults;
atterm(ClearEpisodes);
// Parse the default MAPINFO for the current game.
for(int i=0; i<2; i++)
{

View file

@ -56,6 +56,7 @@
#include "a_strifeglobal.h"
#include "g_level.h"
#include "v_palette.h"
#include "p_acs.h"
static FRandom pr_chainwiggle; //use the same method of chain wiggling as heretic.

View file

@ -46,6 +46,7 @@
#include "gi.h"
#include "i_system.h"
#include "g_level.h"
#include "p_acs.h"
SBarInfo *SBarInfoScript[NUM_SCRIPTS] = {NULL,NULL,NULL,NULL,NULL};
static const char *DefaultScriptNames[NUM_SCRIPTS] =

View file

@ -69,6 +69,7 @@
#include "r_translate.h"
#include "sbarinfo.h"
#include "cmdlib.h"
#include "m_png.h"
extern FILE *Logfile;
@ -118,6 +119,222 @@ struct FBehavior::ArrayInfo
TArray<FBehavior *> FBehavior::StaticModules;
//============================================================================
//
// Global and world variables
//
//============================================================================
// ACS variables with world scope
SDWORD ACS_WorldVars[NUM_WORLDVARS];
FWorldGlobalArray ACS_WorldArrays[NUM_WORLDVARS];
// ACS variables with global scope
SDWORD ACS_GlobalVars[NUM_GLOBALVARS];
FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS];
//============================================================================
//
//
//
//============================================================================
void P_ClearACSVars(bool alsoglobal)
{
int i;
memset (ACS_WorldVars, 0, sizeof(ACS_WorldVars));
for (i = 0; i < NUM_WORLDVARS; ++i)
{
ACS_WorldArrays[i].Clear ();
}
if (alsoglobal)
{
memset (ACS_GlobalVars, 0, sizeof(ACS_GlobalVars));
for (i = 0; i < NUM_GLOBALVARS; ++i)
{
ACS_GlobalArrays[i].Clear ();
}
}
}
//============================================================================
//
//
//
//============================================================================
static void WriteVars (FILE *file, SDWORD *vars, size_t count, DWORD id)
{
size_t i, j;
for (i = 0; i < count; ++i)
{
if (vars[i] != 0)
break;
}
if (i < count)
{
// Find last non-zero var. Anything beyond the last stored variable
// will be zeroed at load time.
for (j = count-1; j > i; --j)
{
if (vars[j] != 0)
break;
}
FPNGChunkArchive arc (file, id);
for (i = 0; i <= j; ++i)
{
DWORD var = vars[i];
arc << var;
}
}
}
//============================================================================
//
//
//
//============================================================================
static void ReadVars (PNGHandle *png, SDWORD *vars, size_t count, DWORD id)
{
size_t len = M_FindPNGChunk (png, id);
size_t used = 0;
if (len != 0)
{
DWORD var;
size_t i;
FPNGChunkArchive arc (png->File->GetFile(), id, len);
used = len / 4;
for (i = 0; i < used; ++i)
{
arc << var;
vars[i] = var;
}
png->File->ResetFilePtr();
}
if (used < count)
{
memset (&vars[used], 0, (count-used)*4);
}
}
//============================================================================
//
//
//
//============================================================================
static void WriteArrayVars (FILE *file, FWorldGlobalArray *vars, unsigned int count, DWORD id)
{
unsigned int i, j;
// Find the first non-empty array.
for (i = 0; i < count; ++i)
{
if (vars[i].CountUsed() != 0)
break;
}
if (i < count)
{
// Find last non-empty array. Anything beyond the last stored array
// will be emptied at load time.
for (j = count-1; j > i; --j)
{
if (vars[j].CountUsed() != 0)
break;
}
FPNGChunkArchive arc (file, id);
arc.WriteCount (i);
arc.WriteCount (j);
for (; i <= j; ++i)
{
arc.WriteCount (vars[i].CountUsed());
FWorldGlobalArray::ConstIterator it(vars[i]);
const FWorldGlobalArray::Pair *pair;
while (it.NextPair (pair))
{
arc.WriteCount (pair->Key);
arc.WriteCount (pair->Value);
}
}
}
}
//============================================================================
//
//
//
//============================================================================
static void ReadArrayVars (PNGHandle *png, FWorldGlobalArray *vars, size_t count, DWORD id)
{
size_t len = M_FindPNGChunk (png, id);
unsigned int i, k;
for (i = 0; i < count; ++i)
{
vars[i].Clear ();
}
if (len != 0)
{
DWORD max, size;
FPNGChunkArchive arc (png->File->GetFile(), id, len);
i = arc.ReadCount ();
max = arc.ReadCount ();
for (; i <= max; ++i)
{
size = arc.ReadCount ();
for (k = 0; k < size; ++k)
{
SDWORD key, val;
key = arc.ReadCount();
val = arc.ReadCount();
vars[i].Insert (key, val);
}
}
png->File->ResetFilePtr();
}
}
//============================================================================
//
//
//
//============================================================================
void P_ReadACSVars(PNGHandle *png)
{
ReadVars (png, ACS_WorldVars, NUM_WORLDVARS, MAKE_ID('w','v','A','r'));
ReadVars (png, ACS_GlobalVars, NUM_GLOBALVARS, MAKE_ID('g','v','A','r'));
ReadArrayVars (png, ACS_WorldArrays, NUM_WORLDVARS, MAKE_ID('w','a','R','r'));
ReadArrayVars (png, ACS_GlobalArrays, NUM_GLOBALVARS, MAKE_ID('g','a','R','r'));
}
//============================================================================
//
//
//
//============================================================================
void P_WriteACSVars(FILE *stdfile)
{
WriteVars (stdfile, ACS_WorldVars, NUM_WORLDVARS, MAKE_ID('w','v','A','r'));
WriteVars (stdfile, ACS_GlobalVars, NUM_GLOBALVARS, MAKE_ID('g','v','A','r'));
WriteArrayVars (stdfile, ACS_WorldArrays, NUM_WORLDVARS, MAKE_ID('w','a','R','r'));
WriteArrayVars (stdfile, ACS_GlobalArrays, NUM_GLOBALVARS, MAKE_ID('g','a','R','r'));
}
//---- Inventory functions --------------------------------------//
//

View file

@ -36,6 +36,7 @@
#define __P_ACS_H__
#include "dobject.h"
#include "dthinker.h"
#include "doomtype.h"
#define LOCAL_SIZE 20
@ -44,6 +45,34 @@
class FFont;
class FileReader;
enum
{
NUM_WORLDVARS = 256,
NUM_GLOBALVARS = 64
};
struct InitIntToZero
{
void Init(int &v)
{
v = 0;
}
};
typedef TMap<SDWORD, SDWORD, THashTraits<SDWORD>, InitIntToZero> FWorldGlobalArray;
// ACS variables with world scope
extern SDWORD ACS_WorldVars[NUM_WORLDVARS];
extern FWorldGlobalArray ACS_WorldArrays[NUM_WORLDVARS];
// ACS variables with global scope
extern SDWORD ACS_GlobalVars[NUM_GLOBALVARS];
extern FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS];
void P_ReadACSVars(PNGHandle *);
void P_WriteACSVars(FILE*);
void P_ClearACSVars(bool);
// The in-memory version
struct ScriptPtr
{

View file

@ -234,7 +234,6 @@ void I_Quit (void)
if (demorecording)
G_CheckDemoStatus();
G_ClearSnapshots ();
}

View file

@ -449,7 +449,6 @@ void I_Quit (void)
if (demorecording)
G_CheckDemoStatus();
G_ClearSnapshots ();
}