mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-27 22:42:57 +00:00
- Externalized all default episode definitions. Added an 'optional' keyword
to handle M4 and 5 in Doom and Heretic. - Added P_CheckMapData functions and replaced all calls to P_OpenMapData that only checked for a map's presence with it. - Added Martin Howe's player statusbar face submission. - Added an 'adddefaultmap' option for MAPINFO. This is the same as 'defaultmap' but keeps all existing information in the default and just adds to it. This is needed because Hexen and Strife set some information in their base MAPINFO and using 'defaultmap' in a PWAD would override that. - Fixed: Using MAPINFO's f1 option could cause memory leaks. - Added option to load lumps by full name to several places: * Finale texts loaded from a text lump * Demos * Local SNDINFOs * Local SNDSEQs * Image names in FONTDEFS * intermission script names - Changed the STCFN121 handling. The character is not an 'I' but a '|' so instead of discarding it it should be inserted at position 124. - Renamed indexfont.fon to indexfont so that I could remove a special case from V_GetFont that was just added for this one font. - Added a 'dumpspawnedthings' CVAR that enables a listing of all things in the map and the actor type they spawned. SVN r882 (trunk)
This commit is contained in:
parent
7b23f6eb8b
commit
e105a29e99
34 changed files with 409 additions and 318 deletions
|
@ -1,3 +1,28 @@
|
|||
April 5, 2008 (Changes by Graf Zahl)
|
||||
- Externalized all default episode definitions. Added an 'optional' keyword
|
||||
to handle M4 and 5 in Doom and Heretic.
|
||||
- Added P_CheckMapData function and replaced all calls to P_OpenMapData that
|
||||
only checked for a map's presence with it.
|
||||
- Added Martin Howe's player statusbar face submission.
|
||||
- Added an 'adddefaultmap' option for MAPINFO. This is the same as 'defaultmap'
|
||||
but keeps all existing information in the default and just adds to it. This
|
||||
is needed because Hexen and Strife set some information in their base
|
||||
MAPINFO and using 'defaultmap' in a PWAD would override that.
|
||||
- Fixed: Using MAPINFO's f1 option could cause memory leaks.
|
||||
- Added option to load lumps by full name to several places:
|
||||
* Finale texts loaded from a text lump
|
||||
* Demos
|
||||
* Local SNDINFOs
|
||||
* Local SNDSEQs
|
||||
* Image names in FONTDEFS
|
||||
* intermission script names
|
||||
- Changed the STCFN121 handling. The character is not an 'I' but a '|' so
|
||||
instead of discarding it it should be inserted at position 124.
|
||||
- Renamed indexfont.fon to indexfont so that I could remove a special case
|
||||
from V_GetFont that was just added for this one font.
|
||||
- Added a 'dumpspawnedthings' CVAR that enables a listing of all things in
|
||||
the map and the actor type they spawned.
|
||||
|
||||
April 5, 2008 (SBarInfo Update #16)
|
||||
- Added: fillzeros flag for drawnumber. When set the string will always have
|
||||
a length of the specified size and zeros will fill in for the missing places.
|
||||
|
|
|
@ -266,12 +266,10 @@ CCMD (idclev)
|
|||
// Catch invalid maps.
|
||||
mapname = CalcMapName (epsd, map);
|
||||
|
||||
MapData * mapd = P_OpenMapData(mapname);
|
||||
if (mapd == NULL)
|
||||
if (!P_CheckMapData(mapname))
|
||||
return;
|
||||
|
||||
// So be it.
|
||||
delete mapd;
|
||||
Printf ("%s\n", GStrings("STSTR_CLEV"));
|
||||
G_DeferedInitNew (mapname);
|
||||
players[0].health = 0; // Force reset
|
||||
|
@ -293,11 +291,9 @@ CCMD (hxvisit)
|
|||
{
|
||||
// Just because it's in MAPINFO doesn't mean it's in the wad.
|
||||
|
||||
MapData * map = P_OpenMapData(mapname);
|
||||
if (map != NULL)
|
||||
if (P_CheckMapData(mapname))
|
||||
{
|
||||
// So be it.
|
||||
delete map;
|
||||
Printf ("%s\n", GStrings("STSTR_CLEV"));
|
||||
G_DeferedInitNew (mapname);
|
||||
return;
|
||||
|
@ -323,14 +319,12 @@ CCMD (changemap)
|
|||
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
MapData * map = P_OpenMapData(argv[1]);
|
||||
if (map == NULL)
|
||||
if (!P_CheckMapData(argv[1]))
|
||||
{
|
||||
Printf ("No map %s\n", argv[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete map;
|
||||
if (argv.argc() > 2)
|
||||
{
|
||||
Net_WriteByte (DEM_CHANGEMAP2);
|
||||
|
|
|
@ -2184,8 +2184,15 @@ void DoDehPatch (const char *patchfile, bool autoloading)
|
|||
if (!PatchFile)
|
||||
{
|
||||
// Couldn't find it on disk, try reading it from a lump
|
||||
FString filebase(ExtractFileBase (patchfile));
|
||||
lump = Wads.CheckNumForName (filebase);
|
||||
lump = Wads.CheckNumForFullName(patchfile, true);
|
||||
if (lump == -1)
|
||||
{
|
||||
// Compatibility fallback. It's just here because
|
||||
// some WAD may need it. Should be deleted it it can
|
||||
// be confirmed that nothing uses this case.
|
||||
FString filebase(ExtractFileBase (patchfile));
|
||||
lump = Wads.CheckNumForName (filebase);
|
||||
}
|
||||
if (lump >= 0)
|
||||
{
|
||||
filelen = Wads.LumpLength (lump);
|
||||
|
|
|
@ -1013,10 +1013,8 @@ void D_DoAdvanceDemo (void)
|
|||
// [RH] If you want something more dynamic for your title, create a map
|
||||
// and name it TITLEMAP. That map will be loaded and used as the title.
|
||||
|
||||
MapData * map = P_OpenMapData("TITLEMAP");
|
||||
if (map != NULL)
|
||||
if (P_CheckMapData("TITLEMAP"))
|
||||
{
|
||||
delete map;
|
||||
G_InitNew ("TITLEMAP", true);
|
||||
return;
|
||||
}
|
||||
|
@ -2281,14 +2279,12 @@ void D_DoomMain (void)
|
|||
p = Args->CheckParm ("+map");
|
||||
if (p && p < Args->NumArgs()-1)
|
||||
{
|
||||
MapData * map = P_OpenMapData(Args->GetArg (p+1));
|
||||
if (map == NULL)
|
||||
if (!P_CheckMapData(Args->GetArg (p+1)))
|
||||
{
|
||||
Printf ("Can't find map %s\n", Args->GetArg (p+1));
|
||||
}
|
||||
else
|
||||
{
|
||||
delete map;
|
||||
strncpy (startmap, Args->GetArg (p+1), 8);
|
||||
Args->GetArg (p)[0] = '-';
|
||||
autostart = true;
|
||||
|
@ -2355,10 +2351,6 @@ void D_DoomMain (void)
|
|||
StartScreen->AppendStatusLine(temp);
|
||||
}
|
||||
|
||||
// [RH] Now that all text strings are set up,
|
||||
// insert them into the level and cluster data.
|
||||
G_MakeEpisodes ();
|
||||
|
||||
// [RH] Parse through all loaded mapinfo lumps
|
||||
Printf ("G_ParseMapInfo: Load map definitions.\n");
|
||||
G_ParseMapInfo ();
|
||||
|
|
|
@ -51,6 +51,7 @@ enum
|
|||
|
||||
APMETA_DisplayName, // display name (used in menus etc.)
|
||||
APMETA_SoundClass, // sound class
|
||||
APMETA_Face, // doom status bar face (when used)
|
||||
APMETA_ColorRange, // skin color range
|
||||
APMETA_InvulMode,
|
||||
APMETA_HealingRadius,
|
||||
|
@ -252,6 +253,7 @@ public:
|
|||
int fixedcolormap; // can be set to REDCOLORMAP, etc.
|
||||
pspdef_t psprites[NUMPSPRITES]; // view sprites (gun, etc)
|
||||
int morphTics; // player is a chicken/pig if > 0
|
||||
BYTE MorphedPlayerClass; // [MH] (for SBARINFO) class # for this player instance when morphed
|
||||
AWeapon *PremorphWeapon; // ready weapon before morphing
|
||||
int chickenPeck; // chicken peck countdown
|
||||
int jumpTics; // delay the next jump for a moment
|
||||
|
|
|
@ -149,9 +149,6 @@ extern int viewangleoffset;
|
|||
extern int consoleplayer;
|
||||
|
||||
|
||||
extern level_locals_t level;
|
||||
|
||||
|
||||
// --------------------------------------
|
||||
// DEMO playback/recording related stuff.
|
||||
// No demo, there is a human player in charge?
|
||||
|
|
|
@ -1314,7 +1314,7 @@ static void GetFinaleText (const char *msgLumpName)
|
|||
{
|
||||
int msgLump;
|
||||
|
||||
msgLump = Wads.CheckNumForName(msgLumpName);
|
||||
msgLump = Wads.CheckNumForFullName(msgLumpName, true);
|
||||
if (msgLump != -1)
|
||||
{
|
||||
char *textbuf;
|
||||
|
|
|
@ -2291,11 +2291,11 @@ void G_BeginRecording (const char *startmap)
|
|||
// G_PlayDemo
|
||||
//
|
||||
|
||||
char defdemoname[128];
|
||||
FString defdemoname;
|
||||
|
||||
void G_DeferedPlayDemo (char *name)
|
||||
{
|
||||
strncpy (defdemoname, name, 127);
|
||||
defdemoname = name;
|
||||
gameaction = ga_playdemo;
|
||||
}
|
||||
|
||||
|
@ -2457,7 +2457,7 @@ void G_DoPlayDemo (void)
|
|||
gameaction = ga_nothing;
|
||||
|
||||
// [RH] Allow for demos not loaded as lumps
|
||||
demolump = Wads.CheckNumForName (defdemoname);
|
||||
demolump = Wads.CheckNumForFullName (defdemoname, true);
|
||||
if (demolump >= 0)
|
||||
{
|
||||
int demolen = Wads.LumpLength (demolump);
|
||||
|
@ -2472,7 +2472,7 @@ void G_DoPlayDemo (void)
|
|||
}
|
||||
demo_p = demobuffer;
|
||||
|
||||
Printf ("Playing demo %s\n", defdemoname);
|
||||
Printf ("Playing demo %s\n", defdemoname.GetChars());
|
||||
|
||||
C_BackupCVars (); // [RH] Save cvars that might be affected by demo
|
||||
|
||||
|
@ -2520,7 +2520,7 @@ void G_TimeDemo (char* name)
|
|||
timingdemo = true;
|
||||
singletics = true;
|
||||
|
||||
strncpy (defdemoname, name, 128);
|
||||
defdemoname = name;
|
||||
gameaction = ga_playdemo;
|
||||
}
|
||||
|
||||
|
|
336
src/g_level.cpp
336
src/g_level.cpp
|
@ -136,7 +136,7 @@ extern const AInventory *SendItemUse, *SendItemDrop;
|
|||
|
||||
void *statcopy; // for statistics driver
|
||||
|
||||
level_locals_t level; // info about current level
|
||||
FLevelLocals level; // info about current level
|
||||
|
||||
static TArray<cluster_info_t> wadclusterinfos;
|
||||
TArray<level_info_t> wadlevelinfos;
|
||||
|
@ -179,6 +179,7 @@ static const char *MapInfoTopLevel[] =
|
|||
"clearepisodes",
|
||||
"skill",
|
||||
"clearskills",
|
||||
"adddefaultmap",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -191,6 +192,7 @@ enum
|
|||
MITL_CLEAREPISODES,
|
||||
MITL_SKILL,
|
||||
MITL_CLEARSKILLS,
|
||||
MITL_ADDDEFAULTMAP,
|
||||
};
|
||||
|
||||
static const char *MapInfoMapLevel[] =
|
||||
|
@ -336,7 +338,6 @@ enum EMIType
|
|||
MITYPE_REDIRECT,
|
||||
MITYPE_SPECIALACTION,
|
||||
MITYPE_COMPATFLAG,
|
||||
MITYPE_F1, // [RC] F1 help
|
||||
};
|
||||
|
||||
struct MapInfoHandler
|
||||
|
@ -413,18 +414,18 @@ MapHandlers[] =
|
|||
{ MITYPE_CLRFLAG, LEVEL_LAXMONSTERACTIVATION, LEVEL_LAXACTIVATIONMAPINFO },
|
||||
{ MITYPE_SETFLAG, LEVEL_LAXMONSTERACTIVATION, LEVEL_LAXACTIVATIONMAPINFO },
|
||||
{ MITYPE_COMPATFLAG, COMPATF_BOOMSCROLL},
|
||||
{ MITYPE_LUMPNAME, lioffset(exitpic), 0 },
|
||||
{ MITYPE_LUMPNAME, lioffset(exitpic), 0 },
|
||||
{ MITYPE_LUMPNAME, lioffset(enterpic), 0 },
|
||||
{ MITYPE_STRING, lioffset(exitpic), 0 },
|
||||
{ MITYPE_STRING, lioffset(exitpic), 0 },
|
||||
{ MITYPE_STRING, lioffset(enterpic), 0 },
|
||||
{ MITYPE_MUSIC, lioffset(intermusic), lioffset(intermusicorder) },
|
||||
{ MITYPE_INT, lioffset(airsupply), 0 },
|
||||
{ MITYPE_SPECIALACTION, lioffset(specialactions), 0 },
|
||||
{ MITYPE_SETFLAG, LEVEL_KEEPFULLINVENTORY, 0 },
|
||||
{ MITYPE_SETFLAG, LEVEL_MONSTERFALLINGDAMAGE, 0 },
|
||||
{ MITYPE_CLRFLAG, LEVEL_MONSTERFALLINGDAMAGE, 0 },
|
||||
{ MITYPE_LUMPNAME, lioffset(sndseq), 0 },
|
||||
{ MITYPE_LUMPNAME, lioffset(soundinfo), 0 },
|
||||
{ MITYPE_LUMPNAME, lioffset(soundinfo), 0 },
|
||||
{ MITYPE_STRING, lioffset(sndseq), 0 },
|
||||
{ MITYPE_STRING, lioffset(soundinfo), 0 },
|
||||
{ MITYPE_STRING, lioffset(soundinfo), 0 },
|
||||
{ MITYPE_SETFLAG, LEVEL_CLIPMIDTEX, 0 },
|
||||
{ MITYPE_SETFLAG, LEVEL_WRAPMIDTEX, 0 },
|
||||
{ MITYPE_CLRFLAG, LEVEL_CROUCH_NO, 0 },
|
||||
|
@ -445,7 +446,7 @@ MapHandlers[] =
|
|||
{ MITYPE_COMPATFLAG, COMPATF_BOOMSCROLL},
|
||||
{ MITYPE_COMPATFLAG, COMPATF_INVISIBILITY},
|
||||
{ MITYPE_LUMPNAME, lioffset(bordertexture), 0 },
|
||||
{ MITYPE_F1, lioffset(f1), 0, },
|
||||
{ MITYPE_LUMPNAME, lioffset(f1), 0, },
|
||||
{ MITYPE_SCFLAGS, LEVEL_NOINFIGHTING, ~LEVEL_TOTALINFIGHTING },
|
||||
{ MITYPE_SCFLAGS, 0, ~(LEVEL_NOINFIGHTING|LEVEL_TOTALINFIGHTING)},
|
||||
{ MITYPE_SCFLAGS, LEVEL_TOTALINFIGHTING, ~LEVEL_NOINFIGHTING },
|
||||
|
@ -536,10 +537,6 @@ static void SetLevelDefaults (level_info_t *levelinfo)
|
|||
// For maps without a BEHAVIOR, this will be cleared.
|
||||
levelinfo->flags |= LEVEL_LAXMONSTERACTIVATION;
|
||||
}
|
||||
else
|
||||
{
|
||||
levelinfo->flags |= LEVEL_MONSTERFALLINGDAMAGE;
|
||||
}
|
||||
levelinfo->airsupply = 10;
|
||||
}
|
||||
|
||||
|
@ -623,6 +620,48 @@ static FSpecialAction *CopySpecialActions(FSpecialAction *spec)
|
|||
return spec;
|
||||
}
|
||||
|
||||
static void CopyString (char *& string)
|
||||
{
|
||||
if (string != NULL)
|
||||
string = copystring(string);
|
||||
}
|
||||
|
||||
static void SafeDelete(char *&string)
|
||||
{
|
||||
if (string != NULL)
|
||||
{
|
||||
delete[] string;
|
||||
string = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void ClearLevelInfoStrings(level_info_t *linfo)
|
||||
{
|
||||
SafeDelete(linfo->music);
|
||||
SafeDelete(linfo->intermusic);
|
||||
SafeDelete(linfo->level_name);
|
||||
SafeDelete(linfo->translator);
|
||||
SafeDelete(linfo->enterpic);
|
||||
SafeDelete(linfo->exitpic);
|
||||
SafeDelete(linfo->soundinfo);
|
||||
SafeDelete(linfo->sndseq);
|
||||
for (FSpecialAction *spac = linfo->specialactions; spac != NULL; )
|
||||
{
|
||||
FSpecialAction *next = spac->Next;
|
||||
delete spac;
|
||||
spac = next;
|
||||
}
|
||||
}
|
||||
|
||||
static void ClearClusterInfoStrings(cluster_info_t *cinfo)
|
||||
{
|
||||
SafeDelete(cinfo->exittext);
|
||||
SafeDelete(cinfo->entertext);
|
||||
SafeDelete(cinfo->messagemusic);
|
||||
SafeDelete(cinfo->clustername);
|
||||
}
|
||||
|
||||
|
||||
static void G_DoParseMapInfo (int lump)
|
||||
{
|
||||
level_info_t defaultinfo;
|
||||
|
@ -647,6 +686,11 @@ static void G_DoParseMapInfo (int lump)
|
|||
ParseMapInfoLower (sc, MapHandlers, MapInfoMapLevel, &defaultinfo, NULL, defaultinfo.flags);
|
||||
break;
|
||||
|
||||
case MITL_ADDDEFAULTMAP:
|
||||
// Same as above but adds to the existing definitions instead of replacing them completely
|
||||
ParseMapInfoLower (sc, MapHandlers, MapInfoMapLevel, &defaultinfo, NULL, defaultinfo.flags);
|
||||
break;
|
||||
|
||||
case MITL_MAP: // map <MAPNAME> <Nice Name>
|
||||
levelflags = defaultinfo.flags;
|
||||
sc.MustGetString ();
|
||||
|
@ -664,7 +708,8 @@ static void G_DoParseMapInfo (int lump)
|
|||
| LEVEL_FALLDMG_HX
|
||||
| LEVEL_ACTOWNSPECIAL
|
||||
| LEVEL_MISSILESACTIVATEIMPACT
|
||||
| LEVEL_INFINITE_FLIGHT;
|
||||
| LEVEL_INFINITE_FLIGHT
|
||||
| LEVEL_MONSTERFALLINGDAMAGE;
|
||||
}
|
||||
levelindex = FindWadLevelInfo (sc.String);
|
||||
if (levelindex == -1)
|
||||
|
@ -677,18 +722,13 @@ static void G_DoParseMapInfo (int lump)
|
|||
}
|
||||
levelinfo = &wadlevelinfos[levelindex];
|
||||
memcpy (levelinfo, &defaultinfo, sizeof(*levelinfo));
|
||||
if (levelinfo->music != NULL)
|
||||
{
|
||||
levelinfo->music = copystring (levelinfo->music);
|
||||
}
|
||||
if (levelinfo->intermusic != NULL)
|
||||
{
|
||||
levelinfo->intermusic = copystring (levelinfo->intermusic);
|
||||
}
|
||||
if (levelinfo->translator != NULL)
|
||||
{
|
||||
levelinfo->translator = copystring (levelinfo->translator);
|
||||
}
|
||||
CopyString(levelinfo->music);
|
||||
CopyString(levelinfo->intermusic);
|
||||
CopyString(levelinfo->translator);
|
||||
CopyString(levelinfo->enterpic);
|
||||
CopyString(levelinfo->exitpic);
|
||||
CopyString(levelinfo->soundinfo);
|
||||
CopyString(levelinfo->sndseq);
|
||||
levelinfo->specialactions = CopySpecialActions(levelinfo->specialactions);
|
||||
if (HexenHack)
|
||||
{
|
||||
|
@ -699,13 +739,9 @@ static void G_DoParseMapInfo (int lump)
|
|||
if (sc.Compare ("lookup"))
|
||||
{
|
||||
sc.MustGetString ();
|
||||
ReplaceString (&levelinfo->level_name, sc.String);
|
||||
levelflags |= LEVEL_LOOKUPLEVELNAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
ReplaceString (&levelinfo->level_name, sc.String);
|
||||
}
|
||||
ReplaceString (&levelinfo->level_name, sc.String);
|
||||
// Set up levelnum now so that you can use Teleport_NewMap specials
|
||||
// to teleport to maps with standard names without needing a levelnum.
|
||||
if (!strnicmp (levelinfo->mapname, "MAP", 3) && levelinfo->mapname[5] == 0)
|
||||
|
@ -730,10 +766,6 @@ static void G_DoParseMapInfo (int lump)
|
|||
{
|
||||
strcpy (levelinfo->skypic2, levelinfo->skypic1);
|
||||
}
|
||||
if (levelinfo->f1 != NULL)
|
||||
{
|
||||
levelinfo->f1 = copystring (levelinfo->f1);
|
||||
}
|
||||
SetLevelNum (levelinfo, levelinfo->levelnum); // Wipe out matching levelnums from other maps.
|
||||
if (levelinfo->pname[0] != 0)
|
||||
{
|
||||
|
@ -755,22 +787,7 @@ static void G_DoParseMapInfo (int lump)
|
|||
else
|
||||
{
|
||||
clusterinfo = &wadclusterinfos[clusterindex];
|
||||
if (clusterinfo->entertext != NULL)
|
||||
{
|
||||
delete[] clusterinfo->entertext;
|
||||
}
|
||||
if (clusterinfo->exittext != NULL)
|
||||
{
|
||||
delete[] clusterinfo->exittext;
|
||||
}
|
||||
if (clusterinfo->messagemusic != NULL)
|
||||
{
|
||||
delete[] clusterinfo->messagemusic;
|
||||
}
|
||||
if (clusterinfo->clustername != NULL)
|
||||
{
|
||||
delete[] clusterinfo->clustername;
|
||||
}
|
||||
ClearClusterInfoStrings(clusterinfo);
|
||||
}
|
||||
memset (clusterinfo, 0, sizeof(cluster_info_t));
|
||||
clusterinfo->cluster = sc.Number;
|
||||
|
@ -798,60 +815,6 @@ static void G_DoParseMapInfo (int lump)
|
|||
ClearLevelInfoStrings(&defaultinfo);
|
||||
}
|
||||
|
||||
static void ClearLevelInfoStrings(level_info_t *linfo)
|
||||
{
|
||||
if (linfo->music != NULL)
|
||||
{
|
||||
delete[] linfo->music;
|
||||
linfo->music = NULL;
|
||||
}
|
||||
if (linfo->intermusic != NULL)
|
||||
{
|
||||
delete[] linfo->intermusic;
|
||||
linfo->intermusic = NULL;
|
||||
}
|
||||
if (linfo->level_name != NULL)
|
||||
{
|
||||
delete[] linfo->level_name;
|
||||
linfo->level_name = NULL;
|
||||
}
|
||||
if (linfo->translator != NULL)
|
||||
{
|
||||
delete[] linfo->translator;
|
||||
linfo->translator = NULL;
|
||||
}
|
||||
for (FSpecialAction *spac = linfo->specialactions; spac != NULL; )
|
||||
{
|
||||
FSpecialAction *next = spac->Next;
|
||||
delete spac;
|
||||
spac = next;
|
||||
}
|
||||
}
|
||||
|
||||
static void ClearClusterInfoStrings(cluster_info_t *cinfo)
|
||||
{
|
||||
if (cinfo->exittext != NULL)
|
||||
{
|
||||
delete[] cinfo->exittext;
|
||||
cinfo->exittext = NULL;
|
||||
}
|
||||
if (cinfo->entertext != NULL)
|
||||
{
|
||||
delete[] cinfo->entertext;
|
||||
cinfo->entertext = NULL;
|
||||
}
|
||||
if (cinfo->messagemusic != NULL)
|
||||
{
|
||||
delete[] cinfo->messagemusic;
|
||||
cinfo->messagemusic = NULL;
|
||||
}
|
||||
if (cinfo->clustername != NULL)
|
||||
{
|
||||
delete[] cinfo->clustername;
|
||||
cinfo->clustername = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void ClearEpisodes()
|
||||
{
|
||||
for (int i = 0; i < EpiDef.numitems; ++i)
|
||||
|
@ -916,13 +879,6 @@ static void ParseMapInfoLower (FScanner &sc,
|
|||
case MITYPE_REDIRECT:
|
||||
sc.MustGetString ();
|
||||
levelinfo->RedirectType = sc.String;
|
||||
/*
|
||||
if (levelinfo->RedirectType == NULL ||
|
||||
!(levelinfo->RedirectType->IsDescendantOf (RUNTIME_CLASS(AInventory))))
|
||||
{
|
||||
SC_ScriptError ("%s is not an inventory item", sc.String);
|
||||
}
|
||||
*/
|
||||
// Intentional fall-through
|
||||
|
||||
case MITYPE_MAPNAME: {
|
||||
|
@ -1077,18 +1033,6 @@ static void ParseMapInfoLower (FScanner &sc,
|
|||
ReplaceString ((char **)(info + handler->data1), sc.String);
|
||||
break;
|
||||
|
||||
case MITYPE_F1:
|
||||
sc.MustGetString ();
|
||||
{
|
||||
char *colon = strchr (sc.String, ':');
|
||||
if (colon)
|
||||
{
|
||||
*colon = 0;
|
||||
}
|
||||
ReplaceString ((char **)(info + handler->data1), sc.String);
|
||||
}
|
||||
break;
|
||||
|
||||
case MITYPE_MUSIC:
|
||||
sc.MustGetString ();
|
||||
{
|
||||
|
@ -1190,6 +1134,7 @@ static void ParseEpisodeInfo (FScanner &sc)
|
|||
bool remove = false;
|
||||
char key = 0;
|
||||
bool noskill = false;
|
||||
bool optional = false;
|
||||
|
||||
// Get map name
|
||||
sc.MustGetString ();
|
||||
|
@ -1208,7 +1153,12 @@ static void ParseEpisodeInfo (FScanner &sc)
|
|||
}
|
||||
do
|
||||
{
|
||||
if (sc.Compare ("name"))
|
||||
if (sc.Compare ("optional"))
|
||||
{
|
||||
// For M4 in Doom and M4 and M5 in Heretic
|
||||
optional = true;
|
||||
}
|
||||
else if (sc.Compare ("name"))
|
||||
{
|
||||
sc.MustGetString ();
|
||||
ReplaceString (&pic, sc.String);
|
||||
|
@ -1241,6 +1191,17 @@ static void ParseEpisodeInfo (FScanner &sc)
|
|||
}
|
||||
while (sc.GetString ());
|
||||
|
||||
if (optional && !remove)
|
||||
{
|
||||
if (!P_CheckMapData(map))
|
||||
{
|
||||
// If the episode is optional and the map does not exist
|
||||
// just ignore this episode definition.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < EpiDef.numitems; ++i)
|
||||
{
|
||||
if (strncmp (EpisodeMaps[i], map, 8) == 0)
|
||||
|
@ -1408,8 +1369,8 @@ void P_RemoveDefereds (void)
|
|||
|
||||
bool CheckWarpTransMap (char mapname[9], bool substitute)
|
||||
{
|
||||
if (mapname[0] == '&' && mapname[1] == 'w' &&
|
||||
mapname[2] == 't' && mapname[3] == '@')
|
||||
if (mapname[0] == '&' && (mapname[1]&223) == 'W' &&
|
||||
(mapname[2]&223) == 'T' && mapname[3] == '@')
|
||||
{
|
||||
level_info_t *lev = FindLevelByWarpTrans (atoi (mapname + 4));
|
||||
if (lev != NULL)
|
||||
|
@ -1457,12 +1418,12 @@ CCMD (map)
|
|||
}
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
MapData * map = P_OpenMapData(argv[1]);
|
||||
if (map == NULL)
|
||||
if (!P_CheckMapData(argv[1]))
|
||||
{
|
||||
Printf ("No map %s\n", argv[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete map;
|
||||
G_DeferedInitNew (argv[1]);
|
||||
}
|
||||
}
|
||||
|
@ -1482,12 +1443,12 @@ CCMD (open)
|
|||
if (argv.argc() > 1)
|
||||
{
|
||||
sprintf(d_mapname, "file:%s", argv[1]);
|
||||
MapData * map = P_OpenMapData(d_mapname);
|
||||
if (map == NULL)
|
||||
if (!P_CheckMapData(d_mapname))
|
||||
{
|
||||
Printf ("No map %s\n", d_mapname);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete map;
|
||||
gameaction = ga_newgame2;
|
||||
d_skill = -1;
|
||||
}
|
||||
|
@ -1638,12 +1599,10 @@ void G_InitNew (const char *mapname, bool bTitleLevel)
|
|||
}
|
||||
|
||||
// [RH] If this map doesn't exist, bomb out
|
||||
MapData * map = P_OpenMapData(mapname);
|
||||
if (!map)
|
||||
if (!P_CheckMapData(mapname))
|
||||
{
|
||||
I_Error ("Could not find map %s\n", mapname);
|
||||
}
|
||||
delete map;
|
||||
|
||||
oldSpeed = GameSpeed;
|
||||
wantFast = !!G_SkillProperty(SKILLP_FastMonsters);
|
||||
|
@ -1815,10 +1774,8 @@ const char *G_GetSecretExitMap()
|
|||
|
||||
if (level.secretmap[0] != 0)
|
||||
{
|
||||
MapData *map = P_OpenMapData(level.secretmap);
|
||||
if (map != NULL)
|
||||
if (P_CheckMapData(level.secretmap))
|
||||
{
|
||||
delete map;
|
||||
nextmap = level.secretmap;
|
||||
}
|
||||
}
|
||||
|
@ -2061,7 +2018,7 @@ void G_DoLoadLevel (int position, bool autosave)
|
|||
|
||||
// DOOM determines the sky texture to be used
|
||||
// depending on the current episode and the game version.
|
||||
// [RH] Fetch sky parameters from level_locals_t.
|
||||
// [RH] Fetch sky parameters from FLevelLocals.
|
||||
sky1texture = TexMan.GetTexture (level.skypic1, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable);
|
||||
sky2texture = TexMan.GetTexture (level.skypic2, FTexture::TEX_Wall, FTextureManager::TEXMAN_Overridable);
|
||||
|
||||
|
@ -2421,7 +2378,6 @@ void G_InitLevelLocals ()
|
|||
level.levelnum = info->levelnum;
|
||||
level.music = info->music;
|
||||
level.musicorder = info->musicorder;
|
||||
level.f1 = info->f1; // [RC] And import the f1 name
|
||||
|
||||
strncpy (level.level_name, info->level_name, 63);
|
||||
G_MaybeLookupLevelName (NULL);
|
||||
|
@ -2454,7 +2410,7 @@ void G_InitLevelLocals ()
|
|||
NormalLight.ChangeFade (level.fadeto);
|
||||
}
|
||||
|
||||
bool level_locals_s::IsJumpingAllowed() const
|
||||
bool FLevelLocals::IsJumpingAllowed() const
|
||||
{
|
||||
if (dmflags & DF_NO_JUMP)
|
||||
return false;
|
||||
|
@ -2463,7 +2419,7 @@ bool level_locals_s::IsJumpingAllowed() const
|
|||
return !(level.flags & LEVEL_JUMP_NO);
|
||||
}
|
||||
|
||||
bool level_locals_s::IsCrouchingAllowed() const
|
||||
bool FLevelLocals::IsCrouchingAllowed() const
|
||||
{
|
||||
if (dmflags & DF_NO_CROUCH)
|
||||
return false;
|
||||
|
@ -2472,7 +2428,7 @@ bool level_locals_s::IsCrouchingAllowed() const
|
|||
return !(level.flags & LEVEL_CROUCH_NO);
|
||||
}
|
||||
|
||||
bool level_locals_s::IsFreelookAllowed() const
|
||||
bool FLevelLocals::IsFreelookAllowed() const
|
||||
{
|
||||
if (level.flags & LEVEL_FREELOOK_NO)
|
||||
return false;
|
||||
|
@ -2531,10 +2487,8 @@ level_info_t *CheckLevelRedirect (level_info_t *info)
|
|||
if (playeringame[i] && players[i].mo->FindInventory (type))
|
||||
{
|
||||
// check for actual presence of the map.
|
||||
MapData * map = P_OpenMapData(info->RedirectMap);
|
||||
if (map != NULL)
|
||||
if (P_CheckMapData(info->RedirectMap))
|
||||
{
|
||||
delete map;
|
||||
return FindLevelInfo(info->RedirectMap);
|
||||
}
|
||||
break;
|
||||
|
@ -2621,90 +2575,6 @@ const char *G_MaybeLookupLevelName (level_info_t *ininfo)
|
|||
return info != NULL ? info->level_name : NULL;
|
||||
}
|
||||
|
||||
void G_MakeEpisodes ()
|
||||
{
|
||||
int i;
|
||||
|
||||
// Set the default episodes
|
||||
if (EpiDef.numitems == 0)
|
||||
{
|
||||
static const char eps[5][8] =
|
||||
{
|
||||
"E1M1", "E2M1", "E3M1", "E4M1", "E5M1"
|
||||
};
|
||||
static const char depinames[4][7] =
|
||||
{
|
||||
"M_EPI1", "M_EPI2", "M_EPI3", "M_EPI4"
|
||||
};
|
||||
static const char depikeys[4] = { 'k', 't', 'i', 't' };
|
||||
|
||||
static const char *hepinames[5] =
|
||||
{
|
||||
"$MNU_COTD",
|
||||
"$MNU_HELLSMAW",
|
||||
"$MNU_DOME",
|
||||
"$MNU_OSSUARY",
|
||||
"$MNU_DEMESNE",
|
||||
};
|
||||
static const char hepikeys[5] = { 'c', 'h', 'd', 'o', 's' };
|
||||
|
||||
if (gameinfo.flags & GI_MAPxx)
|
||||
{
|
||||
if (gameinfo.gametype == GAME_Hexen)
|
||||
{
|
||||
// "&wt@01" is a magic name that will become whatever map has
|
||||
// warptrans 1.
|
||||
strcpy (EpisodeMaps[0], "&wt@01");
|
||||
EpisodeMenu[0].name = copystring ("Hexen");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy (EpisodeMaps[0], "MAP01");
|
||||
EpisodeMenu[0].name = copystring ("Hell on Earth");
|
||||
}
|
||||
EpisodeMenu[0].alphaKey = 'h';
|
||||
EpisodeMenu[0].fulltext = true;
|
||||
EpiDef.numitems = 1;
|
||||
}
|
||||
else if (gameinfo.gametype == GAME_Doom)
|
||||
{
|
||||
memcpy (EpisodeMaps, eps, 4*8);
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
EpisodeMenu[i].name = copystring (depinames[i]);
|
||||
EpisodeMenu[i].fulltext = false;
|
||||
EpisodeMenu[i].alphaKey = depikeys[i];
|
||||
}
|
||||
if (gameinfo.flags & GI_MENUHACK_RETAIL)
|
||||
{
|
||||
EpiDef.numitems = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
EpiDef.numitems = 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy (EpisodeMaps, eps, 5*8);
|
||||
for (i = 0; i < 5; ++i)
|
||||
{
|
||||
EpisodeMenu[i].name = copystring (hepinames[i]);
|
||||
EpisodeMenu[i].fulltext = true;
|
||||
EpisodeMenu[i].alphaKey = hepikeys[i];
|
||||
}
|
||||
if (gameinfo.flags & GI_MENUHACK_EXTENDED)
|
||||
{
|
||||
EpiDef.numitems = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
EpiDef.numitems = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void G_AirControlChanged ()
|
||||
{
|
||||
if (level.aircontrol <= 256)
|
||||
|
@ -3145,7 +3015,7 @@ void P_ReadACSDefereds (PNGHandle *png)
|
|||
}
|
||||
|
||||
|
||||
void level_locals_s::Tick ()
|
||||
void FLevelLocals::Tick ()
|
||||
{
|
||||
// Reset carry sectors
|
||||
if (Scrolls != NULL)
|
||||
|
@ -3154,7 +3024,7 @@ void level_locals_s::Tick ()
|
|||
}
|
||||
}
|
||||
|
||||
void level_locals_s::AddScroller (DScroller *scroller, int secnum)
|
||||
void FLevelLocals::AddScroller (DScroller *scroller, int secnum)
|
||||
{
|
||||
if (secnum < 0)
|
||||
{
|
||||
|
|
|
@ -130,7 +130,7 @@ struct FSpecialAction
|
|||
FSpecialAction *Next;
|
||||
};
|
||||
|
||||
struct level_info_s
|
||||
struct level_info_t
|
||||
{
|
||||
char mapname[9];
|
||||
int levelnum;
|
||||
|
@ -146,7 +146,7 @@ struct level_info_s
|
|||
char *level_name;
|
||||
char fadetable[9];
|
||||
SBYTE WallVertLight, WallHorizLight;
|
||||
const char *f1;
|
||||
char f1[9];
|
||||
// TheDefaultLevelInfo initializes everything above this line.
|
||||
int musicorder;
|
||||
FCompressedMemFile *snapshot;
|
||||
|
@ -172,13 +172,13 @@ struct level_info_s
|
|||
FName RedirectType;
|
||||
char RedirectMap[9];
|
||||
|
||||
char enterpic[9];
|
||||
char exitpic[9];
|
||||
char *enterpic;
|
||||
char *exitpic;
|
||||
char *intermusic;
|
||||
int intermusicorder;
|
||||
|
||||
char soundinfo[9];
|
||||
char sndseq[9];
|
||||
char *soundinfo;
|
||||
char *sndseq;
|
||||
char bordertexture[9];
|
||||
|
||||
int fogdensity;
|
||||
|
@ -187,8 +187,8 @@ struct level_info_s
|
|||
FSpecialAction * specialactions;
|
||||
|
||||
float teamdamage;
|
||||
|
||||
};
|
||||
typedef struct level_info_s level_info_t;
|
||||
|
||||
// [RH] These get zeroed every tic and are updated by thinkers.
|
||||
struct FSectorScrollValues
|
||||
|
@ -196,7 +196,7 @@ struct FSectorScrollValues
|
|||
fixed_t ScrollX, ScrollY;
|
||||
};
|
||||
|
||||
struct level_locals_s
|
||||
struct FLevelLocals
|
||||
{
|
||||
void Tick ();
|
||||
void AddScroller (DScroller *, int secnum);
|
||||
|
@ -254,15 +254,12 @@ struct level_locals_s
|
|||
|
||||
bool FromSnapshot; // The current map was restored from a snapshot
|
||||
|
||||
const char *f1;
|
||||
|
||||
float teamdamage;
|
||||
|
||||
bool IsJumpingAllowed() const;
|
||||
bool IsCrouchingAllowed() const;
|
||||
bool IsFreelookAllowed() const;
|
||||
};
|
||||
typedef struct level_locals_s level_locals_t;
|
||||
|
||||
enum EndTypes
|
||||
{
|
||||
|
@ -310,7 +307,7 @@ typedef struct cluster_info_s cluster_info_t;
|
|||
#define CLUSTER_LOOKUPEXITTEXT 0x00000010 // Exit text is the name of a language string
|
||||
#define CLUSTER_LOOKUPENTERTEXT 0x00000020 // Enter text is the name of a language string
|
||||
|
||||
extern level_locals_t level;
|
||||
extern FLevelLocals level;
|
||||
|
||||
extern TArray<level_info_t> wadlevelinfos;
|
||||
|
||||
|
@ -360,7 +357,6 @@ void G_InitLevelLocals (void);
|
|||
|
||||
void G_AirControlChanged ();
|
||||
|
||||
void G_MakeEpisodes (void);
|
||||
const char *G_MaybeLookupLevelName (level_info_t *level);
|
||||
|
||||
cluster_info_t *FindClusterInfo (int cluster);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "s_sound.h"
|
||||
#include "m_random.h"
|
||||
#include "a_sharedglobal.h"
|
||||
#include "sbar.h"
|
||||
|
||||
#define MORPHTICS (40*TICRATE)
|
||||
|
||||
|
@ -56,6 +57,10 @@ bool P_MorphPlayer (player_t *p, const PClass *spawntype)
|
|||
{
|
||||
return false;
|
||||
}
|
||||
if (spawntype == p->mo->GetClass())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
morphed = static_cast<APlayerPawn *>(Spawn (spawntype, actor->x, actor->y, actor->z, NO_REPLACE));
|
||||
DObject::StaticPointerSubstitution (actor, morphed);
|
||||
|
@ -78,6 +83,18 @@ bool P_MorphPlayer (player_t *p, const PClass *spawntype)
|
|||
actor->flags |= MF_UNMORPHED;
|
||||
actor->renderflags |= RF_INVISIBLE;
|
||||
p->morphTics = MORPHTICS;
|
||||
|
||||
// [MH] Used by SBARINFO to speed up face drawing
|
||||
p->MorphedPlayerClass = 0;
|
||||
for (unsigned int i = 1; i < PlayerClasses.Size (); i++)
|
||||
{
|
||||
if (PlayerClasses[i].Type == spawntype)
|
||||
{
|
||||
p->MorphedPlayerClass = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
p->health = morphed->health;
|
||||
p->mo = morphed;
|
||||
p->momx = p->momy = 0;
|
||||
|
@ -116,6 +133,18 @@ bool P_MorphPlayer (player_t *p, const PClass *spawntype)
|
|||
p->camera = morphed;
|
||||
}
|
||||
morphed->ScoreIcon = actor->ScoreIcon; // [GRB]
|
||||
|
||||
// [MH]
|
||||
// If the player that was morphed is the one
|
||||
// taking events, set up the face, if any;
|
||||
// this is only needed for old-skool skins
|
||||
// and for the original DOOM status bar.
|
||||
if ((p == &players[consoleplayer]) &&
|
||||
(strcmp(spawntype->Meta.GetMetaString (APMETA_Face), "None") != 0))
|
||||
{
|
||||
StatusBar->SetFace(&skins[p->MorphedPlayerClass]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -182,6 +211,39 @@ bool P_UndoPlayerMorph (player_t *player, bool force)
|
|||
{
|
||||
player->camera = mo;
|
||||
}
|
||||
|
||||
// [MH]
|
||||
// If the player that was morphed is the one
|
||||
// taking events, reset up the face, if any;
|
||||
// this is only needed for old-skool skins
|
||||
// and for the original DOOM status bar.
|
||||
if ((player == &players[consoleplayer]) &&
|
||||
(strcmp(pmo->GetClass()->Meta.GetMetaString (APMETA_Face), "None") != 0))
|
||||
{
|
||||
// Assume root-level base skin to begin with
|
||||
size_t skinindex = 0;
|
||||
// If a custom skin was in use, then reload it
|
||||
// or else the base skin for the player class.
|
||||
if ((unsigned int)player->userinfo.skin >= PlayerClasses.Size () &&
|
||||
(size_t)player->userinfo.skin < numskins)
|
||||
{
|
||||
skinindex = player->userinfo.skin;
|
||||
}
|
||||
else if (PlayerClasses.Size () > 1)
|
||||
{
|
||||
const PClass *whatami = player->mo->GetClass();
|
||||
for (unsigned int i = 0; i < PlayerClasses.Size (); ++i)
|
||||
{
|
||||
if (PlayerClasses[i].Type == whatami)
|
||||
{
|
||||
skinindex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
StatusBar->SetFace(&skins[skinindex]);
|
||||
}
|
||||
|
||||
angle = mo->angle >> ANGLETOFINESHIFT;
|
||||
Spawn<ATeleportFog> (pmo->x + 20*finecosine[angle],
|
||||
pmo->y + 20*finesine[angle], pmo->z + TELEFOGHEIGHT, ALLOW_REPLACE);
|
||||
|
|
|
@ -1178,6 +1178,10 @@ void DSBarInfo::doCommands(SBarInfoBlock &block)
|
|||
//draws an image with the specified flags
|
||||
void DSBarInfo::DrawGraphic(FTexture* texture, int x, int y, int flags)
|
||||
{
|
||||
if (texture == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if((flags & DRAWIMAGE_OFFSET_CENTER))
|
||||
{
|
||||
x -= (texture->GetWidth()/2)-texture->LeftOffset;
|
||||
|
@ -1285,16 +1289,20 @@ void DSBarInfo::DrawFace(FString &defaultFace, int accuracy, bool xdth, bool ani
|
|||
for(level = 0;CPlayer->health < (accuracy-level-1)*(CPlayer->mo->GetMaxHealth()/accuracy);level++);
|
||||
if(currentState != NULL)
|
||||
{
|
||||
FTexture *face = currentState->getCurrentFrameTexture(defaultFace, &skins[CPlayer->userinfo.skin], level, angle);
|
||||
x += ST_X;
|
||||
y += ST_Y;
|
||||
int w = face->GetScaledWidth();
|
||||
int h = face->GetScaledHeight();
|
||||
screen->VirtualToRealCoordsInt(x, y, w, h, 320, 200, true);
|
||||
screen->DrawTexture(face, x, y,
|
||||
DTA_DestWidth, w,
|
||||
DTA_DestHeight, h,
|
||||
TAG_DONE);
|
||||
FPlayerSkin *skin = &skins[CPlayer->morphTics ? CPlayer->MorphedPlayerClass : CPlayer->userinfo.skin];
|
||||
FTexture *face = currentState->getCurrentFrameTexture(defaultFace, skin, level, angle);
|
||||
if (face != NULL)
|
||||
{
|
||||
x += ST_X;
|
||||
y += ST_Y;
|
||||
int w = face->GetScaledWidth();
|
||||
int h = face->GetScaledHeight();
|
||||
screen->VirtualToRealCoordsInt(x, y, w, h, 320, 200, true);
|
||||
screen->DrawTexture(face, x, y,
|
||||
DTA_DestWidth, w,
|
||||
DTA_DestHeight, h,
|
||||
TAG_DONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -247,6 +247,7 @@ enum
|
|||
ADEF_PlayerPawn_CrouchSprite,
|
||||
ADEF_PlayerPawn_DisplayName,
|
||||
ADEF_PlayerPawn_SoundClass,
|
||||
ADEF_PlayerPawn_Face,
|
||||
ADEF_PlayerPawn_ScoreIcon,
|
||||
ADEF_PlayerPawn_MorphWeapon,
|
||||
ADEF_LastString = ADEF_PlayerPawn_MorphWeapon,
|
||||
|
|
|
@ -328,6 +328,9 @@ static void ApplyActorDefault (int defnum, const char *datastr, int dataint)
|
|||
case ADEF_PlayerPawn_SoundClass:
|
||||
sgClass->Meta.SetMetaString (APMETA_SoundClass, datastr);
|
||||
break;
|
||||
case ADEF_PlayerPawn_Face:
|
||||
sgClass->Meta.SetMetaString (APMETA_Face, datastr);
|
||||
break;
|
||||
case ADEF_PlayerPawn_ScoreIcon:
|
||||
player->ScoreIcon = TexMan.AddPatch (datastr);
|
||||
if (player->ScoreIcon <= 0)
|
||||
|
|
|
@ -218,8 +218,9 @@ public:
|
|||
#define PROP_PlayerPawn_CrouchSprite(x) ADD_STRING_PROP(ADEF_PlayerPawn_CrouchSprite,"\24",x)
|
||||
#define PROP_PlayerPawn_DisplayName(x) ADD_STRING_PROP(ADEF_PlayerPawn_DisplayName,"\25",x)
|
||||
#define PROP_PlayerPawn_SoundClass(x) ADD_STRING_PROP(ADEF_PlayerPawn_SoundClass,"\26",x)
|
||||
#define PROP_PlayerPawn_ScoreIcon(x) ADD_STRING_PROP(ADEF_PlayerPawn_ScoreIcon,"\27",x)
|
||||
#define PROP_PlayerPawn_MorphWeapon(x) ADD_STRING_PROP(ADEF_PlayerPawn_MorphWeapon,"\30",x)
|
||||
#define PROP_PlayerPawn_Face(x) ADD_STRING_PROP(ADEF_PlayerPawn_Face,"\27",x) // Octal - 'tis quaint!
|
||||
#define PROP_PlayerPawn_ScoreIcon(x) ADD_STRING_PROP(ADEF_PlayerPawn_ScoreIcon,"\30",x)
|
||||
#define PROP_PlayerPawn_MorphWeapon(x) ADD_STRING_PROP(ADEF_PlayerPawn_MorphWeapon,"\31",x)
|
||||
|
||||
#define PROP_XScale(x) ADD_LONG_PROP(ADEF_XScale,x)
|
||||
#define PROP_YScale(x) ADD_LONG_PROP(ADEF_YScale,x)
|
||||
|
|
|
@ -1446,7 +1446,7 @@ void M_QuickLoad ()
|
|||
//
|
||||
void M_DrawReadThis ()
|
||||
{
|
||||
FTexture *tex, *prevpic = NULL;
|
||||
FTexture *tex = NULL, *prevpic = NULL;
|
||||
fixed_t alpha;
|
||||
|
||||
if (gameinfo.flags & GI_INFOINDEXED)
|
||||
|
@ -1463,11 +1463,15 @@ void M_DrawReadThis ()
|
|||
}
|
||||
else
|
||||
{
|
||||
tex = TexMan[gameinfo.info.infoPage[InfoType-1]];
|
||||
// Did the mapper choose a custom help page via MAPINFO?
|
||||
if((level.f1 != NULL) && (strlen(level.f1) > 0))
|
||||
if (level.info->f1[0] != 0)
|
||||
{
|
||||
tex = TexMan.FindTexture(level.f1);
|
||||
tex = TexMan.FindTexture(level.info->f1);
|
||||
}
|
||||
|
||||
if (tex == NULL)
|
||||
{
|
||||
tex = TexMan[gameinfo.info.infoPage[InfoType-1]];
|
||||
}
|
||||
|
||||
if (InfoType > 1)
|
||||
|
|
|
@ -4052,11 +4052,10 @@ AActor *P_SpawnMapThing (mapthing2_t *mthing, int position)
|
|||
|
||||
mobj->angle = (DWORD)((mthing->angle * UCONST64(0x100000000)) / 360);
|
||||
mobj->BeginPlay ();
|
||||
if (mobj->ObjectFlags & OF_EuthanizeMe)
|
||||
if (!(mobj->ObjectFlags & OF_EuthanizeMe))
|
||||
{
|
||||
return NULL;
|
||||
mobj->LevelSpawned ();
|
||||
}
|
||||
mobj->LevelSpawned ();
|
||||
return mobj;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "p_lnspec.h"
|
||||
#include "v_palette.h"
|
||||
#include "c_console.h"
|
||||
#include "c_cvars.h"
|
||||
#include "p_acs.h"
|
||||
#include "vectors.h"
|
||||
#include "announcer.h"
|
||||
|
@ -279,7 +280,7 @@ MapData *P_OpenMapData(const char * mapname)
|
|||
if (lumpfile != nextfile)
|
||||
{
|
||||
// The following lump is from a different file so whatever this is,
|
||||
// it is not a multi-lump Doom level.
|
||||
// it is not a multi-lump Doom level so let's assume it is a Build map.
|
||||
return map;
|
||||
}
|
||||
|
||||
|
@ -379,6 +380,13 @@ MapData *P_OpenMapData(const char * mapname)
|
|||
return map;
|
||||
}
|
||||
|
||||
bool P_CheckMapData(const char *mapname)
|
||||
{
|
||||
MapData *mapd = P_OpenMapData(mapname);
|
||||
if (mapd == NULL) return false;
|
||||
delete mapd;
|
||||
return true;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
@ -1207,6 +1215,23 @@ void P_LoadNodes (MapData * map)
|
|||
delete[] mnp;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// SpawnMapThing
|
||||
//
|
||||
//===========================================================================
|
||||
CVAR(Bool, dumpspawnedthings, false, 0)
|
||||
|
||||
static void SpawnMapThing(int index, mapthing2_t *mt, int position)
|
||||
{
|
||||
AActor *spawned = P_SpawnMapThing(mt, position);
|
||||
if (dumpspawnedthings)
|
||||
{
|
||||
Printf("%5d: (%5d, %5d, %5d), doomednum = %5d, flags = %04x, type = %s\n",
|
||||
index, mt->x, mt->y, mt->z, mt->type, mt->flags,
|
||||
spawned? spawned->GetClass()->TypeName.GetChars() : "(none)");
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
@ -1268,7 +1293,7 @@ void P_LoadThings (MapData * map, int position)
|
|||
mt2.angle = LittleShort(mt->angle);
|
||||
mt2.type = LittleShort(mt->type);
|
||||
|
||||
P_SpawnMapThing (&mt2, position);
|
||||
SpawnMapThing (i, &mt2, position);
|
||||
}
|
||||
delete [] mtp;
|
||||
}
|
||||
|
@ -1712,7 +1737,7 @@ void P_LoadThings2 (MapData * map, int position)
|
|||
|
||||
for (i=0, mt = (mapthing2_t*)mtp; i < numthings; i++,mt++)
|
||||
{
|
||||
P_SpawnMapThing (mt, position);
|
||||
SpawnMapThing (i, mt, position);
|
||||
}
|
||||
delete[] mtp;
|
||||
}
|
||||
|
@ -3792,7 +3817,7 @@ void P_SetupLevel (char *lumpname, int position)
|
|||
{
|
||||
for (i = 0; i < numbuildthings; ++i)
|
||||
{
|
||||
P_SpawnMapThing (&buildthings[i], 0);
|
||||
SpawnMapThing (i, &buildthings[i], 0);
|
||||
}
|
||||
delete[] buildthings;
|
||||
}
|
||||
|
|
|
@ -81,6 +81,7 @@ struct MapData
|
|||
};
|
||||
|
||||
MapData * P_OpenMapData(const char * mapname);
|
||||
bool P_CheckMapData(const char * mapname);
|
||||
|
||||
// NOT called by W_Ticker. Fixme. [RH] Is that bad?
|
||||
//
|
||||
|
|
|
@ -416,6 +416,7 @@ BEGIN_STATELESS_DEFAULTS (APlayerPawn, Any, -1, 0)
|
|||
PROP_PlayerPawn_SideMove2 (FRACUNIT)
|
||||
PROP_PlayerPawn_ColorRange (0, 0)
|
||||
PROP_PlayerPawn_SoundClass ("player")
|
||||
PROP_PlayerPawn_Face ("None")
|
||||
PROP_PlayerPawn_MorphWeapon ("None")
|
||||
END_DEFAULTS
|
||||
|
||||
|
|
|
@ -1046,7 +1046,7 @@ class FPlayerSkin
|
|||
{
|
||||
public:
|
||||
char name[17]; // 16 chars + NULL
|
||||
char face[3];
|
||||
char face[4]; // 3 chars ([MH] + NULL so can use as a C string)
|
||||
BYTE gender; // This skin's gender (not really used)
|
||||
BYTE range0start;
|
||||
BYTE range0end;
|
||||
|
|
|
@ -501,6 +501,7 @@ void R_InitSkins (void)
|
|||
{
|
||||
for (j = 2; j >= 0; j--)
|
||||
skins[i].face[j] = toupper (sc.String[j]);
|
||||
skins[i].face[3] = '\0';
|
||||
}
|
||||
else if (0 == stricmp (key, "gender"))
|
||||
{
|
||||
|
@ -886,11 +887,20 @@ void R_InitSprites ()
|
|||
for (i = 0; i < PlayerClasses.Size (); i++)
|
||||
{
|
||||
const PClass *basetype = PlayerClasses[i].Type;
|
||||
const char *pclassface = basetype->Meta.GetMetaString (APMETA_Face);
|
||||
|
||||
strcpy (skins[i].name, "Base");
|
||||
skins[i].face[0] = 'S';
|
||||
skins[i].face[1] = 'T';
|
||||
skins[i].face[2] = 'F';
|
||||
if (strcmp(pclassface, "None") == 0)
|
||||
{
|
||||
skins[i].face[0] = 'S';
|
||||
skins[i].face[1] = 'T';
|
||||
skins[i].face[2] = 'F';
|
||||
skins[i].face[3] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(skins[i].face, pclassface);
|
||||
}
|
||||
skins[i].range0start = basetype->Meta.GetMetaInt (APMETA_ColorRange) & 255;
|
||||
skins[i].range0end = basetype->Meta.GetMetaInt (APMETA_ColorRange) >> 8;
|
||||
skins[i].Scale = GetDefaultByType (basetype)->scaleX;
|
||||
|
|
|
@ -561,7 +561,6 @@ int S_AddPlayerSound (const char *pclass, int gender, int refid,
|
|||
if (lumpname)
|
||||
{
|
||||
lump = Wads.CheckNumForFullName (lumpname, true, ns_sounds);
|
||||
if (lump == -1) lump = Wads.CheckNumForName (lumpname, ns_sounds);
|
||||
}
|
||||
|
||||
return S_AddPlayerSound (pclass, gender, refid, lump);
|
||||
|
|
|
@ -379,7 +379,7 @@ void S_Start ()
|
|||
if (*LocalSndInfo)
|
||||
{
|
||||
// Now parse the local SNDINFO
|
||||
int j = Wads.CheckNumForName(LocalSndInfo);
|
||||
int j = Wads.CheckNumForFullName(LocalSndInfo, true);
|
||||
if (j>=0) S_AddLocalSndInfo(j);
|
||||
}
|
||||
|
||||
|
@ -392,7 +392,7 @@ void S_Start ()
|
|||
}
|
||||
if (parse_ss)
|
||||
{
|
||||
S_ParseSndSeq(*LocalSndSeq? Wads.CheckNumForName(LocalSndSeq) : -1);
|
||||
S_ParseSndSeq(*LocalSndSeq? Wads.CheckNumForFullName(LocalSndSeq, true) : -1);
|
||||
}
|
||||
else
|
||||
|
||||
|
|
|
@ -2184,6 +2184,36 @@ static void PlayerSoundClass (FScanner &sc, APlayerPawn *defaults, Baggage &bag)
|
|||
bag.Info->Class->Meta.SetMetaString (APMETA_SoundClass, tmp);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
static void PlayerFace (FScanner &sc, APlayerPawn *defaults, Baggage &bag)
|
||||
{
|
||||
FString tmp;
|
||||
|
||||
sc.MustGetString ();
|
||||
tmp = sc.String;
|
||||
if (tmp.Len() != 3)
|
||||
{
|
||||
Printf("Invalid face '%s' for '%s';\nSTF replacement codes must be 3 characters.\n",
|
||||
sc.String, bag.Info->Class->TypeName.GetChars ());
|
||||
}
|
||||
|
||||
tmp.ToUpper();
|
||||
bool valid = (
|
||||
(((tmp[0] >= 'A') && (tmp[0] <= 'Z')) || ((tmp[0] >= '0') && (tmp[0] <= '9'))) &&
|
||||
(((tmp[1] >= 'A') && (tmp[1] <= 'Z')) || ((tmp[1] >= '0') && (tmp[1] <= '9'))) &&
|
||||
(((tmp[2] >= 'A') && (tmp[2] <= 'Z')) || ((tmp[2] >= '0') && (tmp[2] <= '9')))
|
||||
);
|
||||
if (!valid)
|
||||
{
|
||||
Printf("Invalid face '%s' for '%s';\nSTF replacement codes must be alphanumeric.\n",
|
||||
sc.String, bag.Info->Class->TypeName.GetChars ());
|
||||
}
|
||||
|
||||
bag.Info->Class->Meta.SetMetaString (APMETA_Face, tmp);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
|
@ -2552,6 +2582,7 @@ static const ActorProps props[] =
|
|||
{ "player.crouchsprite", (apf)PlayerCrouchSprite, RUNTIME_CLASS(APlayerPawn) },
|
||||
{ "player.damagescreencolor", (apf)PlayerDmgScreenColor, RUNTIME_CLASS(APlayerPawn) },
|
||||
{ "player.displayname", (apf)PlayerDisplayName, RUNTIME_CLASS(APlayerPawn) },
|
||||
{ "player.face", (apf)PlayerFace, RUNTIME_CLASS(APlayerPawn) },
|
||||
{ "player.forwardmove", (apf)PlayerForwardMove, RUNTIME_CLASS(APlayerPawn) },
|
||||
{ "player.healradiustype", (apf)PlayerHealRadius, RUNTIME_CLASS(APlayerPawn) },
|
||||
{ "player.hexenarmor", (apf)PlayerHexenArmor, RUNTIME_CLASS(APlayerPawn) },
|
||||
|
|
|
@ -218,12 +218,6 @@ FFont *V_GetFont(const char *name)
|
|||
int lump = -1;
|
||||
|
||||
lump = Wads.CheckNumForFullName(name, true);
|
||||
if (lump < 0 && strlen(name) > 8)
|
||||
{
|
||||
FString fullname;
|
||||
fullname.Format("%s.fon", name);
|
||||
lump = Wads.CheckNumForFullName(fullname);
|
||||
}
|
||||
|
||||
if (lump != -1)
|
||||
{
|
||||
|
@ -293,6 +287,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
|
|||
double *luminosity;
|
||||
int maxyoffs;
|
||||
bool doomtemplate = gameinfo.gametype == GAME_Doom ? strncmp (nametemplate, "STCFN", 5) == 0 : false;
|
||||
bool stcfn121 = false;
|
||||
|
||||
Chars = new CharData[count];
|
||||
charlumps = new int[count];
|
||||
|
@ -314,17 +309,22 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
|
|||
lump = Wads.CheckNumForName (buffer, ns_graphics);
|
||||
if (doomtemplate && lump >= 0 && i + start == 121)
|
||||
{ // HACKHACK: Don't load STCFN121 in doom(2), because
|
||||
// it's not really a lower-case 'y' but an upper-case 'I'.
|
||||
// it's not really a lower-case 'y' but a '|'.
|
||||
// Because a lot of wads with their own font seem to foolishly
|
||||
// copy STCFN121 and make it an 'I' themselves, wads must
|
||||
// copy STCFN121 and make it a '|' themselves, wads must
|
||||
// provide STCFN120 (x) and STCFN122 (z) for STCFN121 to load.
|
||||
if (Wads.CheckNumForName ("STCFN120", ns_graphics) == -1 ||
|
||||
Wads.CheckNumForName ("STCFN122", ns_graphics) == -1)
|
||||
{
|
||||
// insert the incorrectly named '|' graphic in its correct position.
|
||||
if (count > 124-start) charlumps[124-start] = lump;
|
||||
lump = -1;
|
||||
stcfn121 = true;
|
||||
}
|
||||
}
|
||||
charlumps[i] = lump;
|
||||
if (lump != -1 || i != 124-start || !stcfn121)
|
||||
charlumps[i] = lump;
|
||||
|
||||
if (lump >= 0)
|
||||
{
|
||||
FTexture *pic = TexMan[buffer];
|
||||
|
@ -1691,7 +1691,7 @@ void V_InitCustomFonts()
|
|||
if (format == 1) goto wrong;
|
||||
int *p = &lumplist[*(unsigned char*)sc.String];
|
||||
sc.MustGetString();
|
||||
*p = Wads.CheckNumForName (sc.String);
|
||||
*p = Wads.CheckNumForFullName (sc.String, true);
|
||||
format=2;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -395,7 +395,7 @@ void WI_LoadBackground(bool isenterpic)
|
|||
}
|
||||
else
|
||||
{
|
||||
int lumpnum=Wads.GetNumForName(lumpname+1);
|
||||
int lumpnum=Wads.CheckNumForFullName(lumpname+1, true);
|
||||
if (lumpnum>=0)
|
||||
{
|
||||
FScanner sc(lumpnum);
|
||||
|
|
|
@ -1,5 +1,24 @@
|
|||
// MAPINFO for Doom 1 (Shareware, Registered, and Retail)
|
||||
|
||||
clearepisodes
|
||||
episode e1m1
|
||||
picname "M_EPI1"
|
||||
key k
|
||||
|
||||
episode e2m1
|
||||
picname "M_EPI2"
|
||||
key t
|
||||
|
||||
episode e3m1
|
||||
picname "M_EPI3"
|
||||
key i
|
||||
|
||||
episode e4m1
|
||||
picname "M_EPI4"
|
||||
key t
|
||||
optional
|
||||
|
||||
|
||||
// Registered/Retail Episode 1
|
||||
|
||||
map E1M1 lookup HUSTR_E1M1
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
// MAPINFO for Doom 2
|
||||
|
||||
clearepisodes
|
||||
episode map01
|
||||
name "Hell On Earth"
|
||||
key h
|
||||
|
||||
|
||||
map MAP01 lookup HUSTR_1
|
||||
titlepatch CWILV00
|
||||
next MAP02
|
||||
|
|
|
@ -31,6 +31,29 @@ skill nightmare
|
|||
SpawnFilter "Hard"
|
||||
Name "$MNU_BLACKPLAGUE"
|
||||
|
||||
clearepisodes
|
||||
episode e1m1
|
||||
name "$MNU_COTD"
|
||||
key c
|
||||
|
||||
episode e2m1
|
||||
name "$MNU_HELLSMAW"
|
||||
key h
|
||||
|
||||
episode e3m1
|
||||
name "$MNU_DOME"
|
||||
key d
|
||||
|
||||
episode e4m1
|
||||
name "$MNU_OSSUARY"
|
||||
key o
|
||||
optional
|
||||
|
||||
episode e5m1
|
||||
name "$MNU_DEMESNE"
|
||||
key s
|
||||
optional
|
||||
|
||||
|
||||
|
||||
// Episode 1
|
||||
|
|
|
@ -48,6 +48,10 @@ skill nightmare
|
|||
PlayerClassName "cleric" "$MNU_POPE"
|
||||
PlayerClassName "mage" "$MNU_ARCHMAGE"
|
||||
|
||||
clearepisodes
|
||||
episode "&wt@01"
|
||||
name "Hexen"
|
||||
key h
|
||||
|
||||
clusterdef 1
|
||||
hub
|
||||
|
@ -84,6 +88,7 @@ defaultmap
|
|||
nointermission
|
||||
noautosequences
|
||||
missilesactivateimpactlines
|
||||
monsterfallingdamage
|
||||
|
||||
// There is also support for showing a clus5msg after cluster 5, but
|
||||
// since it isn't used, and it would intefere with the finale if I
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
// MAPINFO for Plutonia. Exactly the same as Doom 2, except it
|
||||
// has different map names and cluster messages.
|
||||
|
||||
clearepisodes
|
||||
episode map01
|
||||
name "The Plutonia Experiment"
|
||||
key t
|
||||
|
||||
map MAP01 lookup PHUSTR_1
|
||||
titlepatch CWILV00
|
||||
next MAP02
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
// MAPINFO for TNT. Exactly the same as Doom 2, except it
|
||||
// has different map names and cluster messages.
|
||||
|
||||
clearepisodes
|
||||
episode map01
|
||||
name "TNT: Evilution"
|
||||
key t
|
||||
|
||||
map MAP01 lookup THUSTR_1
|
||||
titlepatch CWILV00
|
||||
next MAP02
|
||||
|
|
|
@ -255,7 +255,7 @@ acs/strfhelp.o strfhelp.o
|
|||
# Font color ranges
|
||||
textcolors.txt textcolors.txt
|
||||
fontdefs.txt fontdefs.txt
|
||||
indexfont.fon indexfont.fon
|
||||
indexfont indexfont.fon
|
||||
|
||||
========
|
||||
# Decorate stuff
|
||||
|
|
Loading…
Reference in a new issue