mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-01-18 07:02:03 +00:00
- merged finale branch back into trunk.
SVN r2911 (trunk)
This commit is contained in:
parent
0490c35347
commit
d9970ab9b6
30 changed files with 5732 additions and 4757 deletions
|
@ -61,7 +61,7 @@ const IWADInfo IWADInfos[NUM_IWAD_TYPES] =
|
|||
{ "Final Doom: TNT - Evilution", "TNT", MAKERGB(168,0,0), MAKERGB(168,168,168), GAME_Doom, "mapinfo/tnt.txt", GI_MAPxx | GI_COMPATSHORTTEX | GI_COMPATSTAIRS },
|
||||
{ "Final Doom: Plutonia Experiment", "Plutonia", MAKERGB(168,0,0), MAKERGB(168,168,168), GAME_Doom, "mapinfo/plutonia.txt", GI_MAPxx | GI_COMPATSHORTTEX },
|
||||
{ "Hexen: Beyond Heretic", NULL, MAKERGB(240,240,240), MAKERGB(107,44,24), GAME_Hexen, "mapinfo/hexen.txt", GI_MAPxx | GI_COMPATPOLY1 },
|
||||
{ "Hexen: Deathkings of the Dark Citadel", "HexenDK", MAKERGB(240,240,240), MAKERGB(139,68,9), GAME_Hexen, "mapinfo/hexen.txt", GI_MAPxx | GI_COMPATPOLY1 | GI_COMPATPOLY2 },
|
||||
{ "Hexen: Deathkings of the Dark Citadel", "HexenDK", MAKERGB(240,240,240), MAKERGB(139,68,9), GAME_Hexen, "mapinfo/hexdd.txt", GI_MAPxx | GI_COMPATPOLY1 | GI_COMPATPOLY2 },
|
||||
{ "Hexen: Demo Version", "HexenDemo",MAKERGB(240,240,240), MAKERGB(107,44,24), GAME_Hexen, "mapinfo/hexen.txt", GI_MAPxx | GI_SHAREWARE },
|
||||
{ "DOOM 2: Hell on Earth", "Doom2", MAKERGB(168,0,0), MAKERGB(168,168,168), GAME_Doom, "mapinfo/doom2.txt", GI_MAPxx | GI_COMPATSHORTTEX },
|
||||
{ "Heretic Shareware", NULL, MAKERGB(252,252,0), MAKERGB(168,0,0), GAME_Heretic, "mapinfo/hereticsw.txt",GI_SHAREWARE },
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
#include "w_wad.h"
|
||||
#include "s_sound.h"
|
||||
#include "v_video.h"
|
||||
#include "f_finale.h"
|
||||
#include "intermission/intermission.h"
|
||||
#include "f_wipe.h"
|
||||
#include "m_argv.h"
|
||||
#include "m_misc.h"
|
||||
|
@ -677,13 +677,23 @@ void D_Display ()
|
|||
else if (gamestate != wipegamestate && gamestate != GS_FULLCONSOLE && gamestate != GS_TITLELEVEL)
|
||||
{ // save the current screen if about to wipe
|
||||
BorderNeedRefresh = screen->GetPageCount ();
|
||||
if (wipegamestate != GS_FORCEWIPEFADE)
|
||||
switch (wipegamestate)
|
||||
{
|
||||
default:
|
||||
wipe = screen->WipeStartScreen (wipetype);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
|
||||
case GS_FORCEWIPEFADE:
|
||||
wipe = screen->WipeStartScreen (wipe_Fade);
|
||||
break;
|
||||
|
||||
case GS_FORCEWIPEBURN:
|
||||
wipe = screen->WipeStartScreen (wipe_Burn);
|
||||
break;
|
||||
|
||||
case GS_FORCEWIPEMELT:
|
||||
wipe = screen->WipeStartScreen (wipe_Melt);
|
||||
break;
|
||||
}
|
||||
wipegamestate = gamestate;
|
||||
}
|
||||
|
|
|
@ -73,6 +73,7 @@
|
|||
#include "m_argv.h"
|
||||
#include "po_man.h"
|
||||
#include "menu/menu.h"
|
||||
#include "intermission/intermission.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
@ -300,6 +301,7 @@ static void MarkRoot()
|
|||
Mark(screen);
|
||||
Mark(StatusBar);
|
||||
Mark(DMenu::CurrentMenu);
|
||||
Mark(DIntermissionController::CurrentIntermission);
|
||||
DThinker::MarkRoots();
|
||||
FCanvasTextureInfo::Mark();
|
||||
Mark(DACSThinker::ActiveThinker);
|
||||
|
|
|
@ -76,7 +76,9 @@ typedef enum
|
|||
GS_TITLELEVEL, // [RH] A combination of GS_LEVEL and GS_DEMOSCREEN
|
||||
|
||||
GS_FORCEWIPE = -1,
|
||||
GS_FORCEWIPEFADE = -2
|
||||
GS_FORCEWIPEFADE = -2,
|
||||
GS_FORCEWIPEBURN = -3,
|
||||
GS_FORCEWIPEMELT = -4
|
||||
} gamestate_t;
|
||||
|
||||
extern gamestate_t gamestate;
|
||||
|
|
1374
src/f_finale.cpp
1374
src/f_finale.cpp
File diff suppressed because it is too large
Load diff
|
@ -1,53 +0,0 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Id:$
|
||||
//
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
//
|
||||
// This source is available for distribution and/or modification
|
||||
// only under the terms of the DOOM Source Code License as
|
||||
// published by id Software. All rights reserved.
|
||||
//
|
||||
// The source is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
|
||||
// for more details.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef __F_FINALE__
|
||||
#define __F_FINALE__
|
||||
|
||||
#include "basictypes.h"
|
||||
|
||||
struct event_t;
|
||||
|
||||
|
||||
//
|
||||
// FINALE
|
||||
//
|
||||
|
||||
// Called by main loop.
|
||||
bool F_Responder (event_t* ev);
|
||||
|
||||
// Called by main loop.
|
||||
void F_Ticker ();
|
||||
|
||||
// Called by main loop.
|
||||
void F_Drawer ();
|
||||
|
||||
|
||||
void F_StartFinale (const char *music, int musicorder, int cdtrack, unsigned int cdid, const char *flat,
|
||||
const char *text, INTBOOL textInLump, INTBOOL finalePic, INTBOOL lookupText,
|
||||
bool ending, int endsequence = 0);
|
||||
|
||||
void F_StartSlideshow ();
|
||||
|
||||
void F_EndFinale ();
|
||||
|
||||
#endif
|
|
@ -37,7 +37,7 @@
|
|||
#include "doomstat.h"
|
||||
#include "d_protocol.h"
|
||||
#include "d_netinf.h"
|
||||
#include "f_finale.h"
|
||||
#include "intermission/intermission.h"
|
||||
#include "m_argv.h"
|
||||
#include "m_misc.h"
|
||||
#include "menu/menu.h"
|
||||
|
@ -1031,7 +1031,7 @@ void G_Ticker ()
|
|||
G_DoCompleted ();
|
||||
break;
|
||||
case ga_slideshow:
|
||||
F_StartSlideshow ();
|
||||
if (gamestate == GS_LEVEL) F_StartIntermission(level.info->slideshow, FSTATE_InLevel);
|
||||
break;
|
||||
case ga_worlddone:
|
||||
G_DoWorldDone ();
|
||||
|
|
116
src/g_level.cpp
116
src/g_level.cpp
|
@ -51,7 +51,7 @@
|
|||
#include "p_local.h"
|
||||
#include "r_sky.h"
|
||||
#include "c_console.h"
|
||||
#include "f_finale.h"
|
||||
#include "intermission/intermission.h"
|
||||
#include "gstrings.h"
|
||||
#include "v_video.h"
|
||||
#include "st_stuff.h"
|
||||
|
@ -78,6 +78,7 @@
|
|||
#include "d_netinf.h"
|
||||
#include "v_palette.h"
|
||||
#include "menu/menu.h"
|
||||
#include "a_strifeglobal.h"
|
||||
|
||||
#include "gi.h"
|
||||
|
||||
|
@ -99,22 +100,11 @@ EXTERN_CVAR (String, playerclass)
|
|||
#define RCLS_ID MAKE_ID('r','c','L','s')
|
||||
#define PCLS_ID MAKE_ID('p','c','L','s')
|
||||
|
||||
static void SetEndSequence (char *nextmap, int type);
|
||||
void G_VerifySkill();
|
||||
|
||||
|
||||
static FRandom pr_classchoice ("RandomPlayerClassChoice");
|
||||
|
||||
TArray<EndSequence> EndSequences;
|
||||
|
||||
EndSequence::EndSequence()
|
||||
{
|
||||
EndType = END_Pic;
|
||||
Advanced = false;
|
||||
MusicLooping = false;
|
||||
PlayTheEnd = false;
|
||||
}
|
||||
|
||||
extern level_info_t TheDefaultLevelInfo;
|
||||
extern bool timingdemo;
|
||||
|
||||
|
@ -135,73 +125,6 @@ void *statcopy; // for statistics driver
|
|||
|
||||
FLevelLocals level; // info about current level
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int FindEndSequence (int type, const char *picname)
|
||||
{
|
||||
unsigned int i, num;
|
||||
|
||||
num = EndSequences.Size ();
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
if (EndSequences[i].EndType == type && !EndSequences[i].Advanced &&
|
||||
(type != END_Pic || stricmp (EndSequences[i].PicName, picname) == 0))
|
||||
{
|
||||
return (int)i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void SetEndSequence (char *nextmap, int type)
|
||||
{
|
||||
int seqnum;
|
||||
|
||||
seqnum = FindEndSequence (type, NULL);
|
||||
if (seqnum == -1)
|
||||
{
|
||||
EndSequence newseq;
|
||||
newseq.EndType = type;
|
||||
seqnum = (int)EndSequences.Push (newseq);
|
||||
}
|
||||
mysnprintf(nextmap, 11, "enDSeQ%04x", (WORD)seqnum);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void G_SetForEndGame (char *nextmap)
|
||||
{
|
||||
if (!strncmp(nextmap, "enDSeQ",6)) return; // If there is already an end sequence please leave it alone!!!
|
||||
|
||||
if (gameinfo.gametype == GAME_Strife)
|
||||
{
|
||||
SetEndSequence (nextmap, gameinfo.flags & GI_SHAREWARE ? END_BuyStrife : END_Strife);
|
||||
}
|
||||
else if (gameinfo.gametype == GAME_Hexen)
|
||||
{
|
||||
SetEndSequence (nextmap, END_Chess);
|
||||
}
|
||||
else if (gameinfo.gametype == GAME_Doom && (gameinfo.flags & GI_MAPxx))
|
||||
{
|
||||
SetEndSequence (nextmap, END_Cast);
|
||||
}
|
||||
else
|
||||
{ // The ExMx games actually have different ends based on the episode,
|
||||
// but I want to keep this simple.
|
||||
SetEndSequence (nextmap, END_Pic1);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -541,7 +464,6 @@ static bool unloading;
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
|
||||
void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill)
|
||||
{
|
||||
level_info_t *nextinfo = NULL;
|
||||
|
@ -552,7 +474,20 @@ void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill
|
|||
return;
|
||||
}
|
||||
|
||||
if (strncmp(levelname, "enDSeQ", 6) != 0)
|
||||
if (levelname == NULL || *levelname == 0)
|
||||
{
|
||||
// end the game
|
||||
levelname = NULL;
|
||||
if (!strncmp(level.nextmap, "enDSeQ",6))
|
||||
{
|
||||
levelname = level.nextmap; // If there is already an end sequence please leave it alone!
|
||||
}
|
||||
else
|
||||
{
|
||||
nextlevel.Format("enDSeQ%04x", int(gameinfo.DefaultEndSequence));
|
||||
}
|
||||
}
|
||||
else if (strncmp(levelname, "enDSeQ", 6) != 0)
|
||||
{
|
||||
nextinfo = FindLevelInfo (levelname);
|
||||
if (nextinfo != NULL)
|
||||
|
@ -566,7 +501,7 @@ void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill
|
|||
}
|
||||
}
|
||||
|
||||
nextlevel = levelname;
|
||||
if (levelname != NULL) nextlevel = levelname;
|
||||
|
||||
if (nextSkill != -1)
|
||||
NextSkill = nextSkill;
|
||||
|
@ -1026,13 +961,28 @@ void G_WorldDone (void)
|
|||
|
||||
if (strncmp (nextlevel, "enDSeQ", 6) == 0)
|
||||
{
|
||||
FName endsequence = ENamedName(strtol(nextlevel.GetChars()+6, NULL, 16));
|
||||
// Strife needs a special case here to choose between good and sad ending. Bad is handled elsewherw.
|
||||
if (endsequence == NAME_Inter_Strife)
|
||||
{
|
||||
if (players[0].mo->FindInventory (QuestItemClasses[24]) ||
|
||||
players[0].mo->FindInventory (QuestItemClasses[27]))
|
||||
{
|
||||
endsequence = NAME_Inter_Strife_Good;
|
||||
}
|
||||
else
|
||||
{
|
||||
endsequence = NAME_Inter_Strife_Sad;
|
||||
}
|
||||
}
|
||||
|
||||
F_StartFinale (thiscluster->MessageMusic, thiscluster->musicorder,
|
||||
thiscluster->cdtrack, thiscluster->cdid,
|
||||
thiscluster->FinaleFlat, thiscluster->ExitText,
|
||||
thiscluster->flags & CLUSTER_EXITTEXTINLUMP,
|
||||
thiscluster->flags & CLUSTER_FINALEPIC,
|
||||
thiscluster->flags & CLUSTER_LOOKUPEXITTEXT,
|
||||
true, strtol(nextlevel.GetChars()+6, NULL, 16));
|
||||
true, endsequence);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -54,6 +54,8 @@ class FScanner;
|
|||
#define GCC_YSEG __attribute__((section(SECTION_YREG)))
|
||||
#endif
|
||||
|
||||
struct FIntermissionDescriptor;
|
||||
struct FIntermissionAction;
|
||||
|
||||
struct FMapInfoParser
|
||||
{
|
||||
|
@ -98,6 +100,11 @@ struct FMapInfoParser
|
|||
bool CheckFloat();
|
||||
void SkipToNext();
|
||||
void CheckEndOfFile(const char *block);
|
||||
|
||||
void ParseIntermissionAction(FIntermissionDescriptor *Desc);
|
||||
void ParseIntermission();
|
||||
FName CheckEndSequence();
|
||||
FName ParseEndGame();
|
||||
};
|
||||
|
||||
#define DEFINE_MAP_OPTION(name, old) \
|
||||
|
@ -163,7 +170,7 @@ enum ELevelFlags
|
|||
LEVEL_VISITED = 0x80000000, // Used for intermission map
|
||||
|
||||
// The flags QWORD is now split into 2 DWORDs
|
||||
LEVEL2_DEATHSLIDESHOW = 0x00000001, // Slideshow on death
|
||||
//LEVEL2_DEATHSLIDESHOW = 0x00000001, // Slideshow on death
|
||||
LEVEL2_ALLMAP = 0x00000002, // The player picked up a map on this level
|
||||
|
||||
LEVEL2_LAXMONSTERACTIVATION = 0x00000004, // Monsters can open doors depending on the door speed
|
||||
|
@ -251,7 +258,7 @@ struct level_info_t
|
|||
|
||||
char mapname[9];
|
||||
char pname[9];
|
||||
char nextmap[11]; // The endsequence string is 10 chars so we need more space here
|
||||
char nextmap[11];
|
||||
char secretmap[11];
|
||||
char skypic1[9];
|
||||
char skypic2[9];
|
||||
|
@ -286,6 +293,9 @@ struct level_info_t
|
|||
DWORD compatmask;
|
||||
FString Translator; // for converting Doom-format linedef and sector types.
|
||||
int DefaultEnvironment; // Default sound environment for the map.
|
||||
FName Intermission;
|
||||
FName deathsequence;
|
||||
FName slideshow;
|
||||
|
||||
// Redirection: If any player is carrying the specified item, then
|
||||
// you go to the RedirectMap instead of this one.
|
||||
|
@ -415,36 +425,6 @@ struct FLevelLocals
|
|||
bool IsFreelookAllowed() const;
|
||||
};
|
||||
|
||||
enum EndTypes
|
||||
{
|
||||
END_Pic,
|
||||
END_Pic1,
|
||||
END_Pic2,
|
||||
END_Pic3,
|
||||
END_Bunny,
|
||||
END_Cast,
|
||||
END_Demon,
|
||||
END_Underwater,
|
||||
END_Chess,
|
||||
END_Strife,
|
||||
END_BuyStrife,
|
||||
END_TitleScreen
|
||||
};
|
||||
|
||||
struct EndSequence
|
||||
{
|
||||
BYTE EndType;
|
||||
bool Advanced;
|
||||
bool MusicLooping;
|
||||
bool PlayTheEnd;
|
||||
FString PicName;
|
||||
FString PicName2;
|
||||
FString Music;
|
||||
|
||||
EndSequence();
|
||||
};
|
||||
|
||||
extern TArray<EndSequence> EndSequences;
|
||||
|
||||
struct cluster_info_t
|
||||
{
|
||||
|
@ -509,8 +489,6 @@ enum
|
|||
|
||||
void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill=-1);
|
||||
|
||||
void G_SetForEndGame (char *nextmap);
|
||||
|
||||
void G_StartTravel ();
|
||||
void G_FinishTravel ();
|
||||
|
||||
|
|
|
@ -53,9 +53,6 @@
|
|||
#include "version.h"
|
||||
#include "v_text.h"
|
||||
|
||||
int FindEndSequence (int type, const char *picname);
|
||||
|
||||
|
||||
TArray<cluster_info_t> wadclusterinfos;
|
||||
TArray<level_info_t> wadlevelinfos;
|
||||
|
||||
|
@ -757,9 +754,6 @@ void FMapInfoParser::ParseCluster()
|
|||
|
||||
void FMapInfoParser::ParseNextMap(char *mapname)
|
||||
{
|
||||
EndSequence newSeq;
|
||||
bool useseq = false;
|
||||
|
||||
if (sc.CheckNumber())
|
||||
{
|
||||
if (HexenHack)
|
||||
|
@ -773,163 +767,14 @@ void FMapInfoParser::ParseNextMap(char *mapname)
|
|||
}
|
||||
else
|
||||
{
|
||||
|
||||
*mapname = 0;
|
||||
sc.MustGetString();
|
||||
if (sc.Compare("endgame"))
|
||||
strncpy (mapname, sc.String, 8);
|
||||
mapname[8] = 0;
|
||||
FName seq = CheckEndSequence();
|
||||
if (seq != NAME_None)
|
||||
{
|
||||
if (!sc.CheckString("{"))
|
||||
{
|
||||
// Make Demon Eclipse work again
|
||||
sc.UnGet();
|
||||
goto standard_endgame;
|
||||
}
|
||||
newSeq.Advanced = true;
|
||||
newSeq.EndType = END_Pic1;
|
||||
newSeq.PlayTheEnd = false;
|
||||
newSeq.MusicLooping = true;
|
||||
while (!sc.CheckString("}"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
if (sc.Compare("pic"))
|
||||
{
|
||||
ParseAssign();
|
||||
sc.MustGetString();
|
||||
newSeq.EndType = END_Pic;
|
||||
newSeq.PicName = sc.String;
|
||||
}
|
||||
else if (sc.Compare("hscroll"))
|
||||
{
|
||||
ParseAssign();
|
||||
newSeq.EndType = END_Bunny;
|
||||
sc.MustGetString();
|
||||
newSeq.PicName = sc.String;
|
||||
ParseComma();
|
||||
sc.MustGetString();
|
||||
newSeq.PicName2 = sc.String;
|
||||
if (CheckNumber())
|
||||
newSeq.PlayTheEnd = !!sc.Number;
|
||||
}
|
||||
else if (sc.Compare("vscroll"))
|
||||
{
|
||||
ParseAssign();
|
||||
newSeq.EndType = END_Demon;
|
||||
sc.MustGetString();
|
||||
newSeq.PicName = sc.String;
|
||||
ParseComma();
|
||||
sc.MustGetString();
|
||||
newSeq.PicName2 = sc.String;
|
||||
}
|
||||
else if (sc.Compare("cast"))
|
||||
{
|
||||
newSeq.EndType = END_Cast;
|
||||
}
|
||||
else if (sc.Compare("music"))
|
||||
{
|
||||
ParseAssign();
|
||||
sc.MustGetString();
|
||||
newSeq.Music = sc.String;
|
||||
if (CheckNumber())
|
||||
{
|
||||
newSeq.MusicLooping = !!sc.Number;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (format_type == FMT_New)
|
||||
{
|
||||
// Unknown
|
||||
sc.ScriptMessage("Unknown property '%s' found in endgame definition\n", sc.String);
|
||||
SkipToNext();
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.ScriptError("Unknown property '%s' found in endgame definition\n", sc.String);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
useseq = true;
|
||||
}
|
||||
else if (strnicmp (sc.String, "EndGame", 7) == 0)
|
||||
{
|
||||
int type;
|
||||
switch (sc.String[7])
|
||||
{
|
||||
case '1': type = END_Pic1; break;
|
||||
case '2': type = END_Pic2; break;
|
||||
case '3': type = END_Bunny; break;
|
||||
case 'C': type = END_Cast; break;
|
||||
case 'W': type = END_Underwater; break;
|
||||
case 'S': type = END_Strife; break;
|
||||
standard_endgame:
|
||||
default: type = END_Pic3; break;
|
||||
}
|
||||
newSeq.EndType = type;
|
||||
useseq = true;
|
||||
}
|
||||
else if (sc.Compare("endpic"))
|
||||
{
|
||||
ParseComma();
|
||||
sc.MustGetString ();
|
||||
newSeq.EndType = END_Pic;
|
||||
newSeq.PicName = sc.String;
|
||||
useseq = true;
|
||||
}
|
||||
else if (sc.Compare("endbunny"))
|
||||
{
|
||||
newSeq.EndType = END_Bunny;
|
||||
useseq = true;
|
||||
}
|
||||
else if (sc.Compare("endcast"))
|
||||
{
|
||||
newSeq.EndType = END_Cast;
|
||||
useseq = true;
|
||||
}
|
||||
else if (sc.Compare("enddemon"))
|
||||
{
|
||||
newSeq.EndType = END_Demon;
|
||||
useseq = true;
|
||||
}
|
||||
else if (sc.Compare("endchess"))
|
||||
{
|
||||
newSeq.EndType = END_Chess;
|
||||
useseq = true;
|
||||
}
|
||||
else if (sc.Compare("endunderwater"))
|
||||
{
|
||||
newSeq.EndType = END_Underwater;
|
||||
useseq = true;
|
||||
}
|
||||
else if (sc.Compare("endbuystrife"))
|
||||
{
|
||||
newSeq.EndType = END_BuyStrife;
|
||||
useseq = true;
|
||||
}
|
||||
else if (sc.Compare("endtitle"))
|
||||
{
|
||||
newSeq.EndType = END_TitleScreen;
|
||||
useseq = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy (mapname, sc.String, 8);
|
||||
mapname[8] = 0;
|
||||
}
|
||||
if (useseq)
|
||||
{
|
||||
int seqnum = -1;
|
||||
|
||||
if (!newSeq.Advanced)
|
||||
{
|
||||
seqnum = FindEndSequence (newSeq.EndType, newSeq.PicName);
|
||||
}
|
||||
|
||||
if (seqnum == -1)
|
||||
{
|
||||
seqnum = (int)EndSequences.Push (newSeq);
|
||||
}
|
||||
// mapname can point to nextmap and secretmap which are both 12 characters long
|
||||
mysnprintf(mapname, 11, "enDSeQ%04x", (WORD)seqnum);
|
||||
mysnprintf(mapname, 11, "enDSeQ%04x", int(seq));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1229,6 +1074,20 @@ DEFINE_MAP_OPTION(translator, true)
|
|||
info->Translator = parse.sc.String;
|
||||
}
|
||||
|
||||
DEFINE_MAP_OPTION(deathsequence, false)
|
||||
{
|
||||
parse.ParseAssign();
|
||||
parse.sc.MustGetString();
|
||||
info->deathsequence = parse.sc.String;
|
||||
}
|
||||
|
||||
DEFINE_MAP_OPTION(slideshow, false)
|
||||
{
|
||||
parse.ParseAssign();
|
||||
parse.sc.MustGetString();
|
||||
info->slideshow = parse.sc.String;
|
||||
}
|
||||
|
||||
DEFINE_MAP_OPTION(bordertexture, true)
|
||||
{
|
||||
parse.ParseAssign();
|
||||
|
@ -1351,7 +1210,7 @@ MapFlagHandlers[] =
|
|||
{ "missilesactivateimpactlines", MITYPE_SETFLAG2, LEVEL2_MISSILESACTIVATEIMPACT, 0 },
|
||||
{ "missileshootersactivetimpactlines",MITYPE_CLRFLAG2, LEVEL2_MISSILESACTIVATEIMPACT, 0 },
|
||||
{ "noinventorybar", MITYPE_SETFLAG, LEVEL_NOINVENTORYBAR, 0 },
|
||||
{ "deathslideshow", MITYPE_SETFLAG2, LEVEL2_DEATHSLIDESHOW, 0 },
|
||||
{ "deathslideshow", MITYPE_SETFLAG2, 0, 0 },
|
||||
{ "strictmonsteractivation", MITYPE_CLRFLAG2, LEVEL2_LAXMONSTERACTIVATION, LEVEL2_LAXACTIVATIONMAPINFO },
|
||||
{ "laxmonsteractivation", MITYPE_SETFLAG2, LEVEL2_LAXMONSTERACTIVATION, LEVEL2_LAXACTIVATIONMAPINFO },
|
||||
{ "additive_scrollers", MITYPE_COMPATFLAG, COMPATF_BOOMSCROLL},
|
||||
|
@ -1908,6 +1767,18 @@ void FMapInfoParser::ParseMapInfo (int lump, level_info_t &gamedefaults, level_i
|
|||
sc.ScriptError("gameinfo definitions not supported with old MAPINFO syntax");
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("intermission"))
|
||||
{
|
||||
if (format_type != FMT_Old)
|
||||
{
|
||||
format_type = FMT_New;
|
||||
ParseIntermission();
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.ScriptError("intermission definitions not supported with old MAPINFO syntax");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.ScriptError("%s: Unknown top level keyword", sc.String);
|
||||
|
@ -1965,7 +1836,6 @@ void G_ParseMapInfo (const char *basemapinfo)
|
|||
level_info_t defaultinfo;
|
||||
parse.ParseMapInfo(lump, gamedefaults, defaultinfo);
|
||||
}
|
||||
EndSequences.ShrinkToFit ();
|
||||
|
||||
if (AllEpisodes.Size() == 0)
|
||||
{
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include "p_enemy.h"
|
||||
#include "s_sound.h"
|
||||
#include "a_strifeglobal.h"
|
||||
#include "f_finale.h"
|
||||
#include "thingdef/thingdef.h"
|
||||
#include "g_level.h"
|
||||
#include "doomstat.h"
|
||||
|
|
|
@ -297,6 +297,9 @@ void FMapInfoParser::ParseGameInfo()
|
|||
GAMEINFOKEY_STRING(mFontColorHighlight, "menufontcolor_highlight")
|
||||
GAMEINFOKEY_STRING(mFontColorSelection, "menufontcolor_selection")
|
||||
GAMEINFOKEY_CSTRING(mBackButton, "menubackbutton", 8)
|
||||
GAMEINFOKEY_INT(TextScreenX, "textscreenx")
|
||||
GAMEINFOKEY_INT(TextScreenY, "textscreeny")
|
||||
GAMEINFOKEY_STRING(DefaultEndSequence, "defaultendsequence")
|
||||
|
||||
else
|
||||
{
|
||||
|
|
3
src/gi.h
3
src/gi.h
|
@ -125,6 +125,9 @@ struct gameinfo_t
|
|||
FName mFontColorSelection;
|
||||
char mBackButton[9];
|
||||
fixed_t gibfactor;
|
||||
int TextScreenX;
|
||||
int TextScreenY;
|
||||
FName DefaultEndSequence;
|
||||
|
||||
const char *GetFinalePage(unsigned int num) const;
|
||||
};
|
||||
|
|
875
src/intermission/intermission.cpp
Normal file
875
src/intermission/intermission.cpp
Normal file
|
@ -0,0 +1,875 @@
|
|||
/*
|
||||
** intermission.cpp
|
||||
** Framework for intermissions (text screens, slideshows, etc)
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2010 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
#include "doomtype.h"
|
||||
#include "doomstat.h"
|
||||
#include "d_event.h"
|
||||
#include "w_wad.h"
|
||||
#include "gi.h"
|
||||
#include "v_video.h"
|
||||
#include "v_palette.h"
|
||||
#include "d_main.h"
|
||||
#include "gstrings.h"
|
||||
#include "intermission/intermission.h"
|
||||
#include "actor.h"
|
||||
#include "d_player.h"
|
||||
#include "r_state.h"
|
||||
#include "r_translate.h"
|
||||
#include "c_bind.h"
|
||||
#include "g_level.h"
|
||||
#include "p_conversation.h"
|
||||
#include "menu/menu.h"
|
||||
|
||||
FIntermissionDescriptorList IntermissionDescriptors;
|
||||
|
||||
IMPLEMENT_CLASS(DIntermissionScreen)
|
||||
IMPLEMENT_CLASS(DIntermissionScreenFader)
|
||||
IMPLEMENT_CLASS(DIntermissionScreenText)
|
||||
IMPLEMENT_CLASS(DIntermissionScreenCast)
|
||||
IMPLEMENT_CLASS(DIntermissionScreenScroller)
|
||||
IMPLEMENT_POINTY_CLASS(DIntermissionController)
|
||||
DECLARE_POINTER(mScreen)
|
||||
END_POINTERS
|
||||
|
||||
extern int NoWipe;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void DIntermissionScreen::Init(FIntermissionAction *desc, bool first)
|
||||
{
|
||||
int lumpnum;
|
||||
|
||||
if (desc->mCdTrack == 0 || !S_ChangeCDMusic (desc->mCdTrack, desc->mCdId))
|
||||
{
|
||||
if (desc->mMusic.IsEmpty())
|
||||
{
|
||||
// only start the default music if this is the first action in an intermission
|
||||
if (first) S_ChangeMusic (gameinfo.finaleMusic, 0, desc->mMusicLooping);
|
||||
}
|
||||
else
|
||||
{
|
||||
S_ChangeMusic (desc->mMusic, desc->mMusicOrder, desc->mMusicLooping);
|
||||
}
|
||||
}
|
||||
mDuration = desc->mDuration;
|
||||
|
||||
const char *texname = desc->mBackground;
|
||||
if (*texname == '@')
|
||||
{
|
||||
char *pp;
|
||||
unsigned int v = strtoul(texname+1, &pp, 10) - 1;
|
||||
if (*pp == 0 && v < gameinfo.finalePages.Size())
|
||||
{
|
||||
texname = gameinfo.finalePages[v].GetChars();
|
||||
}
|
||||
else if (gameinfo.finalePages.Size() > 0)
|
||||
{
|
||||
texname = gameinfo.finalePages[0].GetChars();
|
||||
}
|
||||
else
|
||||
{
|
||||
texname = gameinfo.titlePage;
|
||||
}
|
||||
}
|
||||
else if (*texname == '$')
|
||||
{
|
||||
texname = GStrings[texname+1];
|
||||
}
|
||||
FTextureID tex = TexMan.CheckForTexture(texname, FTexture::TEX_MiscPatch);
|
||||
if (tex.isValid())
|
||||
{
|
||||
mBackground = tex;
|
||||
mFlatfill = desc->mFlatfill;
|
||||
}
|
||||
S_Sound (CHAN_VOICE | CHAN_UI, desc->mSound, 1.0f, ATTN_NONE);
|
||||
if (desc->mPalette.IsNotEmpty() && (lumpnum = Wads.CheckNumForFullName(desc->mPalette, true)) > 0)
|
||||
{
|
||||
PalEntry *palette;
|
||||
const BYTE *orgpal;
|
||||
FMemLump lump;
|
||||
int i;
|
||||
|
||||
lump = Wads.ReadLump (lumpnum);
|
||||
orgpal = (BYTE *)lump.GetMem();
|
||||
palette = screen->GetPalette ();
|
||||
for (i = 256; i > 0; i--, orgpal += 3)
|
||||
{
|
||||
*palette++ = PalEntry (orgpal[0], orgpal[1], orgpal[2]);
|
||||
}
|
||||
screen->UpdatePalette ();
|
||||
mPaletteChanged = true;
|
||||
NoWipe = 1;
|
||||
M_EnableMenu(false);
|
||||
}
|
||||
mOverlays.Resize(desc->mOverlays.Size());
|
||||
for (unsigned i=0; i < mOverlays.Size(); i++)
|
||||
{
|
||||
mOverlays[i].x = desc->mOverlays[i].x;
|
||||
mOverlays[i].y = desc->mOverlays[i].y;
|
||||
mOverlays[i].mCondition = desc->mOverlays[i].mCondition;
|
||||
mOverlays[i].mPic = TexMan.CheckForTexture(desc->mOverlays[i].mName, FTexture::TEX_MiscPatch);
|
||||
}
|
||||
mTicker = 0;
|
||||
}
|
||||
|
||||
|
||||
int DIntermissionScreen::Responder (event_t *ev)
|
||||
{
|
||||
if (ev->type == EV_KeyDown)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DIntermissionScreen::Ticker ()
|
||||
{
|
||||
if (++mTicker >= mDuration && mDuration > 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool DIntermissionScreen::CheckOverlay(int i)
|
||||
{
|
||||
if (mOverlays[i].mCondition == NAME_Multiplayer && !multiplayer) return false;
|
||||
else if (mOverlays[i].mCondition != NAME_None)
|
||||
{
|
||||
if (multiplayer || players[0].mo == NULL) return false;
|
||||
const PClass *cls = PClass::FindClass(mOverlays[i].mCondition);
|
||||
if (cls == NULL) return false;
|
||||
if (!players[0].mo->IsKindOf(cls)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void DIntermissionScreen::Drawer ()
|
||||
{
|
||||
if (mBackground.isValid())
|
||||
{
|
||||
if (!mFlatfill)
|
||||
{
|
||||
screen->DrawTexture (TexMan[mBackground], 0, 0, DTA_Fullscreen, true, TAG_DONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
screen->FlatFill (0,0, SCREENWIDTH, SCREENHEIGHT, TexMan[mBackground]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
screen->Clear (0, 0, SCREENWIDTH, SCREENHEIGHT, 0, 0);
|
||||
}
|
||||
for (unsigned i=0; i < mOverlays.Size(); i++)
|
||||
{
|
||||
if (CheckOverlay(i))
|
||||
screen->DrawTexture (TexMan[mOverlays[i].mPic], mOverlays[i].x, mOverlays[i].y, DTA_320x200, true, TAG_DONE);
|
||||
}
|
||||
if (!mFlatfill) screen->FillBorder (NULL);
|
||||
}
|
||||
|
||||
void DIntermissionScreen::Destroy()
|
||||
{
|
||||
if (mPaletteChanged)
|
||||
{
|
||||
PalEntry *palette;
|
||||
int i;
|
||||
|
||||
palette = screen->GetPalette ();
|
||||
for (i = 0; i < 256; ++i)
|
||||
{
|
||||
palette[i] = GPalette.BaseColors[i];
|
||||
}
|
||||
screen->UpdatePalette ();
|
||||
NoWipe = 5;
|
||||
mPaletteChanged = false;
|
||||
M_EnableMenu(true);
|
||||
}
|
||||
S_StopSound(CHAN_VOICE);
|
||||
Super::Destroy();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void DIntermissionScreenFader::Init(FIntermissionAction *desc, bool first)
|
||||
{
|
||||
Super::Init(desc, first);
|
||||
mType = static_cast<FIntermissionActionFader*>(desc)->mFadeType;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// FadePic
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
int DIntermissionScreenFader::Responder (event_t *ev)
|
||||
{
|
||||
if (ev->type == EV_KeyDown)
|
||||
{
|
||||
V_SetBlend(0,0,0,0);
|
||||
return -1;
|
||||
}
|
||||
return Super::Responder(ev);
|
||||
}
|
||||
|
||||
int DIntermissionScreenFader::Ticker ()
|
||||
{
|
||||
if (mFlatfill || !mBackground.isValid()) return -1;
|
||||
return Super::Ticker();
|
||||
}
|
||||
|
||||
void DIntermissionScreenFader::Drawer ()
|
||||
{
|
||||
if (!mFlatfill && mBackground.isValid())
|
||||
{
|
||||
double factor = clamp(double(mTicker) / mDuration, 0., 1.);
|
||||
if (mType == FADE_In) factor = 1.0 - factor;
|
||||
int color = MAKEARGB(xs_RoundToInt(factor*255), 0,0,0);
|
||||
|
||||
if (screen->Begin2D(false))
|
||||
{
|
||||
screen->DrawTexture (TexMan[mBackground], 0, 0, DTA_Fullscreen, true, DTA_ColorOverlay, color, TAG_DONE);
|
||||
for (unsigned i=0; i < mOverlays.Size(); i++)
|
||||
{
|
||||
if (CheckOverlay(i))
|
||||
screen->DrawTexture (TexMan[mOverlays[i].mPic], mOverlays[i].x, mOverlays[i].y, DTA_320x200, true, DTA_ColorOverlay, color, TAG_DONE);
|
||||
}
|
||||
screen->FillBorder (NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
V_SetBlend (0,0,0,int(256*factor));
|
||||
Super::Drawer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void DIntermissionScreenText::Init(FIntermissionAction *desc, bool first)
|
||||
{
|
||||
Super::Init(desc, first);
|
||||
mText = static_cast<FIntermissionActionTextscreen*>(desc)->mText;
|
||||
if (mText[0] == '$') mText = GStrings[&mText[1]];
|
||||
mTextSpeed = static_cast<FIntermissionActionTextscreen*>(desc)->mTextSpeed;
|
||||
mTextX = static_cast<FIntermissionActionTextscreen*>(desc)->mTextX;
|
||||
if (mTextX < 0) mTextX =gameinfo.TextScreenX;
|
||||
mTextY = static_cast<FIntermissionActionTextscreen*>(desc)->mTextY;
|
||||
if (mTextY < 0) mTextY =gameinfo.TextScreenY;
|
||||
mTextLen = (int)strlen(mText);
|
||||
mTextDelay = static_cast<FIntermissionActionTextscreen*>(desc)->mTextDelay;
|
||||
mTextColor = static_cast<FIntermissionActionTextscreen*>(desc)->mTextColor;
|
||||
// For text screens, the duration only counts when the text is complete.
|
||||
if (mDuration > 0) mDuration += mTextDelay + mTextSpeed * mTextLen;
|
||||
}
|
||||
|
||||
int DIntermissionScreenText::Responder (event_t *ev)
|
||||
{
|
||||
if (ev->type == EV_KeyDown)
|
||||
{
|
||||
if (mTicker < mTextDelay + (mTextLen * mTextSpeed))
|
||||
{
|
||||
mTicker = mTextDelay + (mTextLen * mTextSpeed);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return Super::Responder(ev);
|
||||
}
|
||||
|
||||
void DIntermissionScreenText::Drawer ()
|
||||
{
|
||||
Super::Drawer();
|
||||
if (mTicker >= mTextDelay)
|
||||
{
|
||||
FTexture *pic;
|
||||
int w;
|
||||
size_t count;
|
||||
int c;
|
||||
const FRemapTable *range;
|
||||
|
||||
// draw some of the text onto the screen
|
||||
int rowheight = SmallFont->GetHeight () + (gameinfo.gametype & (GAME_DoomStrifeChex) ? 3 : -1);
|
||||
bool scale = (CleanXfac != 1 || CleanYfac != 1);
|
||||
|
||||
int cx = mTextX;
|
||||
int cy = mTextY;
|
||||
const char *ch = mText;
|
||||
|
||||
count = (mTicker - mTextDelay) / mTextSpeed;
|
||||
range = SmallFont->GetColorTranslation (mTextColor);
|
||||
|
||||
for ( ; count > 0 ; count-- )
|
||||
{
|
||||
c = *ch++;
|
||||
if (!c)
|
||||
break;
|
||||
if (c == '\n')
|
||||
{
|
||||
cx = mTextX;
|
||||
cy += rowheight;
|
||||
continue;
|
||||
}
|
||||
|
||||
pic = SmallFont->GetChar (c, &w);
|
||||
if (cx+w > SCREENWIDTH)
|
||||
continue;
|
||||
if (pic != NULL)
|
||||
{
|
||||
if (scale)
|
||||
{
|
||||
screen->DrawTexture (pic,
|
||||
cx,// + 320 / 2,
|
||||
cy,// + 200 / 2,
|
||||
DTA_Translation, range,
|
||||
DTA_Clean, true,
|
||||
TAG_DONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
screen->DrawTexture (pic,
|
||||
cx,// + 320 / 2,
|
||||
cy,// + 200 / 2,
|
||||
DTA_Translation, range,
|
||||
TAG_DONE);
|
||||
}
|
||||
}
|
||||
cx += w;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void DIntermissionScreenCast::Init(FIntermissionAction *desc, bool first)
|
||||
{
|
||||
Super::Init(desc, first);
|
||||
mName = static_cast<FIntermissionActionCast*>(desc)->mName;
|
||||
mClass = PClass::FindClass(static_cast<FIntermissionActionCast*>(desc)->mCastClass);
|
||||
if (mClass != NULL) mDefaults = GetDefaultByType(mClass);
|
||||
else mDefaults = NULL;
|
||||
|
||||
mCastSounds.Resize(static_cast<FIntermissionActionCast*>(desc)->mCastSounds.Size());
|
||||
for (unsigned i=0; i < mCastSounds.Size(); i++)
|
||||
{
|
||||
mCastSounds[i].mSequence = static_cast<FIntermissionActionCast*>(desc)->mCastSounds[i].mSequence;
|
||||
mCastSounds[i].mIndex = static_cast<FIntermissionActionCast*>(desc)->mCastSounds[i].mIndex;
|
||||
mCastSounds[i].mSound = static_cast<FIntermissionActionCast*>(desc)->mCastSounds[i].mSound;
|
||||
}
|
||||
caststate = mDefaults->SeeState;
|
||||
if (mClass->IsDescendantOf(RUNTIME_CLASS(APlayerPawn)))
|
||||
{
|
||||
advplayerstate = mDefaults->MissileState;
|
||||
castsprite = skins[players[consoleplayer].userinfo.skin].sprite;
|
||||
casttranslation = translationtables[TRANSLATION_Players][consoleplayer];
|
||||
}
|
||||
else
|
||||
{
|
||||
advplayerstate = NULL;
|
||||
if (caststate != NULL) castsprite = caststate->sprite;
|
||||
else castsprite = -1;
|
||||
casttranslation = NULL;
|
||||
}
|
||||
castdeath = false;
|
||||
castframes = 0;
|
||||
castonmelee = 0;
|
||||
castattacking = false;
|
||||
if (mDefaults->SeeSound)
|
||||
{
|
||||
S_Sound (CHAN_VOICE | CHAN_UI, mDefaults->SeeSound, 1, ATTN_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
int DIntermissionScreenCast::Responder (event_t *ev)
|
||||
{
|
||||
if (ev->type != EV_KeyDown) return 0;
|
||||
|
||||
if (castdeath)
|
||||
return 1; // already in dying frames
|
||||
|
||||
castdeath = true;
|
||||
caststate = mClass->ActorInfo->FindState(NAME_Death);
|
||||
if (caststate == NULL) return -1;
|
||||
|
||||
casttics = caststate->GetTics();
|
||||
castframes = 0;
|
||||
castattacking = false;
|
||||
|
||||
if (mClass->IsDescendantOf(RUNTIME_CLASS(APlayerPawn)))
|
||||
{
|
||||
int snd = S_FindSkinnedSound(players[consoleplayer].mo, "*death");
|
||||
if (snd != 0) S_Sound (CHAN_VOICE | CHAN_UI, snd, 1, ATTN_NONE);
|
||||
}
|
||||
else if (mDefaults->DeathSound)
|
||||
{
|
||||
S_Sound (CHAN_VOICE | CHAN_UI, mDefaults->DeathSound, 1, ATTN_NONE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int DIntermissionScreenCast::Ticker ()
|
||||
{
|
||||
Super::Ticker();
|
||||
|
||||
if (--casttics > 0 && caststate != NULL)
|
||||
return 0; // not time to change state yet
|
||||
|
||||
if (caststate == NULL || caststate->GetTics() == -1 || caststate->GetNextState() == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// sound hacks....
|
||||
if (caststate != NULL && castattacking)
|
||||
{
|
||||
for (unsigned i = 0; i < mCastSounds.Size(); i++)
|
||||
{
|
||||
if ((!!mCastSounds[i].mSequence) == (basestate != mDefaults->MissileState) &&
|
||||
(caststate == basestate + mCastSounds[i].mIndex - 1))
|
||||
{
|
||||
S_StopAllChannels ();
|
||||
S_Sound (CHAN_WEAPON | CHAN_UI, mCastSounds[i].mSound, 1, ATTN_NONE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// just advance to next state in animation
|
||||
if (caststate == advplayerstate)
|
||||
goto stopattack; // Oh, gross hack!
|
||||
|
||||
caststate = caststate->GetNextState();
|
||||
castframes++;
|
||||
}
|
||||
|
||||
if (castframes == 12)
|
||||
{
|
||||
// go into attack frame
|
||||
castattacking = true;
|
||||
if (castonmelee)
|
||||
basestate = caststate = mDefaults->MeleeState;
|
||||
else
|
||||
basestate = caststate = mDefaults->MissileState;
|
||||
castonmelee ^= 1;
|
||||
if (caststate == NULL)
|
||||
{
|
||||
if (castonmelee)
|
||||
basestate = caststate = mDefaults->MeleeState;
|
||||
else
|
||||
basestate = caststate = mDefaults->MissileState;
|
||||
}
|
||||
}
|
||||
|
||||
if (castattacking)
|
||||
{
|
||||
if (castframes == 24 || caststate == mDefaults->SeeState )
|
||||
{
|
||||
stopattack:
|
||||
castattacking = false;
|
||||
castframes = 0;
|
||||
caststate = mDefaults->SeeState;
|
||||
}
|
||||
}
|
||||
|
||||
casttics = caststate->GetTics();
|
||||
if (casttics == -1)
|
||||
casttics = 15;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DIntermissionScreenCast::Drawer ()
|
||||
{
|
||||
spriteframe_t* sprframe;
|
||||
FTexture* pic;
|
||||
|
||||
Super::Drawer();
|
||||
|
||||
const char *name = mName;
|
||||
if (name != NULL)
|
||||
{
|
||||
if (*name == '$') name = GStrings(name+1);
|
||||
screen->DrawText (SmallFont, CR_UNTRANSLATED,
|
||||
(SCREENWIDTH - SmallFont->StringWidth (name) * CleanXfac)/2,
|
||||
(SCREENHEIGHT * 180) / 200,
|
||||
name,
|
||||
DTA_CleanNoMove, true, TAG_DONE);
|
||||
}
|
||||
|
||||
// draw the current frame in the middle of the screen
|
||||
if (caststate != NULL)
|
||||
{
|
||||
sprframe = &SpriteFrames[sprites[castsprite].spriteframes + caststate->GetFrame()];
|
||||
pic = TexMan(sprframe->Texture[0]);
|
||||
|
||||
screen->DrawTexture (pic, 160, 170,
|
||||
DTA_320x200, true,
|
||||
DTA_FlipX, sprframe->Flip & 1,
|
||||
DTA_Translation, casttranslation,
|
||||
TAG_DONE);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void DIntermissionScreenScroller::Init(FIntermissionAction *desc, bool first)
|
||||
{
|
||||
Super::Init(desc, first);
|
||||
mFirstPic = mBackground;
|
||||
mSecondPic = TexMan.CheckForTexture(static_cast<FIntermissionActionScroller*>(desc)->mSecondPic, FTexture::TEX_MiscPatch);
|
||||
mScrollDelay = static_cast<FIntermissionActionScroller*>(desc)->mScrollDelay;
|
||||
mScrollTime = static_cast<FIntermissionActionScroller*>(desc)->mScrollTime;
|
||||
mScrollDir = static_cast<FIntermissionActionScroller*>(desc)->mScrollDir;
|
||||
}
|
||||
|
||||
void DIntermissionScreenScroller::Drawer ()
|
||||
{
|
||||
FTexture *tex = TexMan[mFirstPic];
|
||||
FTexture *tex2 = TexMan[mSecondPic];
|
||||
if (mTicker >= mScrollDelay && mTicker < mScrollDelay + mScrollTime && tex != NULL && tex2 != NULL)
|
||||
{
|
||||
|
||||
int fwidth = tex->GetScaledWidth();
|
||||
int fheight = tex->GetScaledHeight();
|
||||
|
||||
double xpos1 = 0, ypos1 = 0, xpos2 = 0, ypos2 = 0;
|
||||
|
||||
switch (mScrollDir)
|
||||
{
|
||||
case SCROLL_Up:
|
||||
ypos1 = double(mTicker - mScrollDelay) * fheight / mScrollTime;
|
||||
ypos2 = ypos1 - fheight;
|
||||
break;
|
||||
|
||||
case SCROLL_Down:
|
||||
ypos1 = -double(mTicker - mScrollDelay) * fheight / mScrollTime;
|
||||
ypos2 = ypos1 + fheight;
|
||||
break;
|
||||
|
||||
case SCROLL_Left:
|
||||
default:
|
||||
xpos1 = double(mTicker - mScrollDelay) * fwidth / mScrollTime;
|
||||
xpos2 = xpos1 - fwidth;
|
||||
break;
|
||||
|
||||
case SCROLL_Right:
|
||||
xpos1 = -double(mTicker - mScrollDelay) * fwidth / mScrollTime;
|
||||
xpos2 = xpos1 + fwidth;
|
||||
break;
|
||||
}
|
||||
|
||||
screen->DrawTexture (tex, xpos1, ypos1,
|
||||
DTA_VirtualWidth, fwidth,
|
||||
DTA_VirtualHeight, fheight,
|
||||
DTA_Masked, false,
|
||||
TAG_DONE);
|
||||
screen->DrawTexture (tex2, xpos2, ypos2,
|
||||
DTA_VirtualWidth, fwidth,
|
||||
DTA_VirtualHeight, fheight,
|
||||
DTA_Masked, false,
|
||||
TAG_DONE);
|
||||
|
||||
screen->FillBorder (NULL);
|
||||
mBackground = mSecondPic;
|
||||
}
|
||||
else
|
||||
{
|
||||
Super::Drawer();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
DIntermissionController *DIntermissionController::CurrentIntermission;
|
||||
|
||||
DIntermissionController::DIntermissionController(FIntermissionDescriptor *Desc, bool DeleteDesc, BYTE state)
|
||||
{
|
||||
mDesc = Desc;
|
||||
mDeleteDesc = DeleteDesc;
|
||||
mIndex = 0;
|
||||
mAdvance = false;
|
||||
mScreen = NULL;
|
||||
mFirst = true;
|
||||
mGameState = state;
|
||||
NextPage();
|
||||
}
|
||||
|
||||
bool DIntermissionController::NextPage ()
|
||||
{
|
||||
FTextureID bg;
|
||||
bool fill = false;
|
||||
|
||||
if (mIndex == (int)mDesc->mActions.Size() && mDesc->mLink == NAME_None)
|
||||
{
|
||||
// last page
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mScreen != NULL)
|
||||
{
|
||||
bg = mScreen->GetBackground(&fill);
|
||||
mScreen->Destroy();
|
||||
}
|
||||
again:
|
||||
while ((unsigned)mIndex < mDesc->mActions.Size())
|
||||
{
|
||||
FIntermissionAction *action = mDesc->mActions[mIndex++];
|
||||
if (action->mClass == WIPER_ID)
|
||||
{
|
||||
wipegamestate = static_cast<FIntermissionActionWiper*>(action)->mWipeType;
|
||||
}
|
||||
else if (action->mClass == TITLE_ID)
|
||||
{
|
||||
Destroy();
|
||||
D_StartTitle ();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// create page here
|
||||
mScreen = (DIntermissionScreen*)action->mClass->CreateNew();
|
||||
mScreen->SetBackground(bg, fill); // copy last screen's background before initializing
|
||||
mScreen->Init(action, mFirst);
|
||||
mFirst = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (mDesc->mLink != NAME_None)
|
||||
{
|
||||
FIntermissionDescriptor **pDesc = IntermissionDescriptors.CheckKey(mDesc->mLink);
|
||||
if (pDesc != NULL)
|
||||
{
|
||||
if (mDeleteDesc) delete mDesc;
|
||||
mDeleteDesc = false;
|
||||
mIndex = 0;
|
||||
mDesc = *pDesc;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DIntermissionController::Responder (event_t *ev)
|
||||
{
|
||||
if (mScreen != NULL)
|
||||
{
|
||||
if (!mScreen->mPaletteChanged && ev->type == EV_KeyDown)
|
||||
{
|
||||
const char *cmd = Bindings.GetBind (ev->data1);
|
||||
|
||||
if (cmd != NULL && !stricmp (cmd, "toggleconsole"))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mScreen->mTicker < 2) return false; // prevent some leftover events from auto-advancing
|
||||
int res = mScreen->Responder(ev);
|
||||
mAdvance = (res == -1);
|
||||
return !!res;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DIntermissionController::Ticker ()
|
||||
{
|
||||
if (mScreen != NULL)
|
||||
{
|
||||
mAdvance |= (mScreen->Ticker() == -1);
|
||||
}
|
||||
if (mAdvance)
|
||||
{
|
||||
mAdvance = false;
|
||||
if (!NextPage())
|
||||
{
|
||||
switch (mGameState)
|
||||
{
|
||||
case FSTATE_InLevel:
|
||||
if (level.cdtrack == 0 || !S_ChangeCDMusic (level.cdtrack, level.cdid))
|
||||
S_ChangeMusic (level.Music, level.musicorder);
|
||||
gamestate = GS_LEVEL;
|
||||
wipegamestate = GS_LEVEL;
|
||||
P_ResumeConversation ();
|
||||
viewactive = true;
|
||||
Destroy();
|
||||
break;
|
||||
|
||||
case FSTATE_ChangingLevel:
|
||||
gameaction = ga_worlddone;
|
||||
Destroy();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DIntermissionController::Drawer ()
|
||||
{
|
||||
if (mScreen != NULL)
|
||||
{
|
||||
mScreen->Drawer();
|
||||
}
|
||||
}
|
||||
|
||||
void DIntermissionController::Destroy ()
|
||||
{
|
||||
Super::Destroy();
|
||||
if (mScreen != NULL) mScreen->Destroy();
|
||||
if (mDeleteDesc) delete mDesc;
|
||||
mDesc = NULL;
|
||||
if (CurrentIntermission == this) CurrentIntermission = NULL;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// starts a new intermission
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void F_StartIntermission(FIntermissionDescriptor *desc, bool deleteme, BYTE state)
|
||||
{
|
||||
if (DIntermissionController::CurrentIntermission != NULL)
|
||||
{
|
||||
DIntermissionController::CurrentIntermission->Destroy();
|
||||
}
|
||||
V_SetBlend (0,0,0,0);
|
||||
S_StopAllChannels ();
|
||||
gameaction = ga_nothing;
|
||||
gamestate = GS_FINALE;
|
||||
if (state == FSTATE_InLevel) wipegamestate = GS_FINALE; // don't wipe when within a level.
|
||||
viewactive = false;
|
||||
automapactive = false;
|
||||
DIntermissionController::CurrentIntermission = new DIntermissionController(desc, deleteme, state);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// starts a new intermission
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void F_StartIntermission(FName seq, BYTE state)
|
||||
{
|
||||
FIntermissionDescriptor **pdesc = IntermissionDescriptors.CheckKey(seq);
|
||||
if (pdesc != NULL)
|
||||
{
|
||||
F_StartIntermission(*pdesc, false, state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Called by main loop.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool F_Responder (event_t* ev)
|
||||
{
|
||||
if (DIntermissionController::CurrentIntermission != NULL)
|
||||
{
|
||||
return DIntermissionController::CurrentIntermission->Responder(ev);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Called by main loop.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void F_Ticker ()
|
||||
{
|
||||
if (DIntermissionController::CurrentIntermission != NULL)
|
||||
{
|
||||
DIntermissionController::CurrentIntermission->Ticker();
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Called by main loop.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void F_Drawer ()
|
||||
{
|
||||
if (DIntermissionController::CurrentIntermission != NULL)
|
||||
{
|
||||
DIntermissionController::CurrentIntermission->Drawer();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Called by main loop.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void F_EndFinale ()
|
||||
{
|
||||
if (DIntermissionController::CurrentIntermission != NULL)
|
||||
{
|
||||
DIntermissionController::CurrentIntermission->Destroy();
|
||||
DIntermissionController::CurrentIntermission = NULL;
|
||||
}
|
||||
}
|
320
src/intermission/intermission.h
Normal file
320
src/intermission/intermission.h
Normal file
|
@ -0,0 +1,320 @@
|
|||
#ifndef __INTERMISSION_H
|
||||
#define __INTERMISSION_H
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "dobject.h"
|
||||
#include "m_fixed.h"
|
||||
#include "textures/textures.h"
|
||||
#include "s_sound.h"
|
||||
#include "v_font.h"
|
||||
|
||||
struct event_t;
|
||||
|
||||
#define DECLARE_SUPER_CLASS(cls,parent) \
|
||||
private: \
|
||||
typedef parent Super; \
|
||||
typedef cls ThisClass;
|
||||
|
||||
struct FIntermissionPatch
|
||||
{
|
||||
FName mCondition;
|
||||
FString mName;
|
||||
double x, y;
|
||||
};
|
||||
|
||||
struct FIIntermissionPatch
|
||||
{
|
||||
FName mCondition;
|
||||
FTextureID mPic;
|
||||
double x, y;
|
||||
};
|
||||
|
||||
struct FCastSound
|
||||
{
|
||||
BYTE mSequence;
|
||||
BYTE mIndex;
|
||||
FString mSound;
|
||||
};
|
||||
|
||||
struct FICastSound
|
||||
{
|
||||
BYTE mSequence;
|
||||
BYTE mIndex;
|
||||
FSoundID mSound;
|
||||
};
|
||||
|
||||
enum EFadeType
|
||||
{
|
||||
FADE_In,
|
||||
FADE_Out,
|
||||
};
|
||||
|
||||
enum EScrollDir
|
||||
{
|
||||
SCROLL_Left,
|
||||
SCROLL_Right,
|
||||
SCROLL_Up,
|
||||
SCROLL_Down,
|
||||
};
|
||||
|
||||
// actions that don't create objects
|
||||
#define WIPER_ID ((const PClass*)intptr_t(-1))
|
||||
#define TITLE_ID ((const PClass*)intptr_t(-2))
|
||||
|
||||
//==========================================================================
|
||||
|
||||
struct FIntermissionAction
|
||||
{
|
||||
int mSize;
|
||||
const PClass *mClass;
|
||||
FString mMusic;
|
||||
int mMusicOrder;
|
||||
int mCdTrack;
|
||||
int mCdId;
|
||||
int mDuration;
|
||||
FString mBackground;
|
||||
FString mPalette;
|
||||
FString mSound;
|
||||
bool mFlatfill;
|
||||
bool mMusicLooping;
|
||||
TArray<FIntermissionPatch> mOverlays;
|
||||
|
||||
FIntermissionAction();
|
||||
virtual bool ParseKey(FScanner &sc);
|
||||
};
|
||||
|
||||
struct FIntermissionActionFader : public FIntermissionAction
|
||||
{
|
||||
typedef FIntermissionAction Super;
|
||||
|
||||
EFadeType mFadeType;
|
||||
|
||||
FIntermissionActionFader();
|
||||
virtual bool ParseKey(FScanner &sc);
|
||||
};
|
||||
|
||||
struct FIntermissionActionWiper : public FIntermissionAction
|
||||
{
|
||||
typedef FIntermissionAction Super;
|
||||
|
||||
gamestate_t mWipeType;
|
||||
|
||||
FIntermissionActionWiper();
|
||||
virtual bool ParseKey(FScanner &sc);
|
||||
};
|
||||
|
||||
struct FIntermissionActionTextscreen : public FIntermissionAction
|
||||
{
|
||||
typedef FIntermissionAction Super;
|
||||
|
||||
FString mText;
|
||||
int mTextDelay;
|
||||
int mTextSpeed;
|
||||
int mTextX, mTextY;
|
||||
EColorRange mTextColor;
|
||||
|
||||
FIntermissionActionTextscreen();
|
||||
virtual bool ParseKey(FScanner &sc);
|
||||
};
|
||||
|
||||
struct FIntermissionActionCast : public FIntermissionAction
|
||||
{
|
||||
typedef FIntermissionAction Super;
|
||||
|
||||
FString mName;
|
||||
FName mCastClass;
|
||||
TArray<FCastSound> mCastSounds;
|
||||
|
||||
FIntermissionActionCast();
|
||||
virtual bool ParseKey(FScanner &sc);
|
||||
};
|
||||
|
||||
struct FIntermissionActionScroller : public FIntermissionAction
|
||||
{
|
||||
typedef FIntermissionAction Super;
|
||||
|
||||
FString mSecondPic;
|
||||
int mScrollDelay;
|
||||
int mScrollTime;
|
||||
int mScrollDir;
|
||||
|
||||
FIntermissionActionScroller();
|
||||
virtual bool ParseKey(FScanner &sc);
|
||||
};
|
||||
|
||||
struct FIntermissionDescriptor
|
||||
{
|
||||
FName mLink;
|
||||
TArray<FIntermissionAction *> mActions;
|
||||
};
|
||||
|
||||
typedef TMap<FName, FIntermissionDescriptor*> FIntermissionDescriptorList;
|
||||
|
||||
extern FIntermissionDescriptorList IntermissionDescriptors;
|
||||
|
||||
//==========================================================================
|
||||
|
||||
class DIntermissionScreen : public DObject
|
||||
{
|
||||
DECLARE_CLASS (DIntermissionScreen, DObject)
|
||||
|
||||
protected:
|
||||
int mDuration;
|
||||
FTextureID mBackground;
|
||||
bool mFlatfill;
|
||||
TArray<FIIntermissionPatch> mOverlays;
|
||||
|
||||
bool CheckOverlay(int i);
|
||||
|
||||
public:
|
||||
int mTicker;
|
||||
bool mPaletteChanged;
|
||||
|
||||
DIntermissionScreen() {}
|
||||
virtual void Init(FIntermissionAction *desc, bool first);
|
||||
virtual int Responder (event_t *ev);
|
||||
virtual int Ticker ();
|
||||
virtual void Drawer ();
|
||||
void Destroy();
|
||||
FTextureID GetBackground(bool *fill)
|
||||
{
|
||||
*fill = mFlatfill;
|
||||
return mBackground;
|
||||
}
|
||||
void SetBackground(FTextureID tex, bool fill)
|
||||
{
|
||||
mBackground = tex;
|
||||
mFlatfill = fill;
|
||||
}
|
||||
};
|
||||
|
||||
class DIntermissionScreenFader : public DIntermissionScreen
|
||||
{
|
||||
DECLARE_CLASS (DIntermissionScreenFader, DIntermissionScreen)
|
||||
|
||||
EFadeType mType;
|
||||
|
||||
public:
|
||||
|
||||
DIntermissionScreenFader() {}
|
||||
virtual void Init(FIntermissionAction *desc, bool first);
|
||||
virtual int Responder (event_t *ev);
|
||||
virtual int Ticker ();
|
||||
virtual void Drawer ();
|
||||
};
|
||||
|
||||
class DIntermissionScreenText : public DIntermissionScreen
|
||||
{
|
||||
DECLARE_CLASS (DIntermissionScreenText, DIntermissionScreen)
|
||||
|
||||
const char *mText;
|
||||
int mTextSpeed;
|
||||
int mTextX, mTextY;
|
||||
int mTextCounter;
|
||||
int mTextDelay;
|
||||
int mTextLen;
|
||||
EColorRange mTextColor;
|
||||
|
||||
public:
|
||||
|
||||
DIntermissionScreenText() {}
|
||||
virtual void Init(FIntermissionAction *desc, bool first);
|
||||
virtual int Responder (event_t *ev);
|
||||
virtual void Drawer ();
|
||||
};
|
||||
|
||||
class DIntermissionScreenCast : public DIntermissionScreen
|
||||
{
|
||||
DECLARE_CLASS (DIntermissionScreenCast, DIntermissionScreen)
|
||||
|
||||
const char *mName;
|
||||
const PClass *mClass;
|
||||
AActor *mDefaults;
|
||||
TArray<FICastSound> mCastSounds;
|
||||
|
||||
int casttics;
|
||||
int castsprite; // [RH] For overriding the player sprite with a skin
|
||||
const FRemapTable *casttranslation; // [RH] Draw "our hero" with their chosen suit color
|
||||
FState* caststate;
|
||||
FState* basestate;
|
||||
FState* advplayerstate;
|
||||
bool castdeath;
|
||||
bool castattacking;
|
||||
int castframes;
|
||||
int castonmelee;
|
||||
|
||||
public:
|
||||
|
||||
DIntermissionScreenCast() {}
|
||||
virtual void Init(FIntermissionAction *desc, bool first);
|
||||
virtual int Responder (event_t *ev);
|
||||
virtual int Ticker ();
|
||||
virtual void Drawer ();
|
||||
};
|
||||
|
||||
class DIntermissionScreenScroller : public DIntermissionScreen
|
||||
{
|
||||
DECLARE_CLASS (DIntermissionScreenScroller, DIntermissionScreen)
|
||||
|
||||
FTextureID mFirstPic;
|
||||
FTextureID mSecondPic;
|
||||
int mScrollDelay;
|
||||
int mScrollTime;
|
||||
int mScrollDir;
|
||||
|
||||
public:
|
||||
|
||||
DIntermissionScreenScroller() {}
|
||||
virtual void Init(FIntermissionAction *desc, bool first);
|
||||
virtual void Drawer ();
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
FSTATE_EndingGame = 0,
|
||||
FSTATE_ChangingLevel = 1,
|
||||
FSTATE_InLevel = 2
|
||||
};
|
||||
|
||||
class DIntermissionController : public DObject
|
||||
{
|
||||
DECLARE_CLASS (DIntermissionController, DObject)
|
||||
HAS_OBJECT_POINTERS
|
||||
|
||||
FIntermissionDescriptor *mDesc;
|
||||
TObjPtr<DIntermissionScreen> mScreen;
|
||||
bool mDeleteDesc;
|
||||
bool mFirst;
|
||||
bool mAdvance;
|
||||
BYTE mGameState;
|
||||
int mIndex;
|
||||
|
||||
bool NextPage();
|
||||
|
||||
public:
|
||||
static DIntermissionController *CurrentIntermission;
|
||||
|
||||
DIntermissionController(FIntermissionDescriptor *mDesc = NULL, bool mDeleteDesc = false, BYTE state = FSTATE_ChangingLevel);
|
||||
bool Responder (event_t *ev);
|
||||
void Ticker ();
|
||||
void Drawer ();
|
||||
void Destroy();
|
||||
};
|
||||
|
||||
|
||||
// Interface for main loop
|
||||
bool F_Responder (event_t* ev);
|
||||
void F_Ticker ();
|
||||
void F_Drawer ();
|
||||
void F_StartIntermission(FIntermissionDescriptor *desc, bool deleteme, BYTE state);
|
||||
void F_StartIntermission(FName desc, BYTE state);
|
||||
void F_EndFinale ();
|
||||
|
||||
// Create an intermission from old cluster data
|
||||
void F_StartFinale (const char *music, int musicorder, int cdtrack, unsigned int cdid, const char *flat,
|
||||
const char *text, INTBOOL textInLump, INTBOOL finalePic, INTBOOL lookupText,
|
||||
bool ending, FName endsequence = NAME_None);
|
||||
|
||||
|
||||
|
||||
#endif
|
848
src/intermission/intermission_parse.cpp
Normal file
848
src/intermission/intermission_parse.cpp
Normal file
|
@ -0,0 +1,848 @@
|
|||
/*
|
||||
** intermission_parser.cpp
|
||||
** Parser for intermission definitions in MAPINFO
|
||||
** (both new style and old style 'ENDGAME' blocks)
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2010 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#include "intermission/intermission.h"
|
||||
#include "g_level.h"
|
||||
#include "w_wad.h"
|
||||
#include "gi.h"
|
||||
|
||||
|
||||
static void ReplaceIntermission(FName intname,FIntermissionDescriptor *desc)
|
||||
{
|
||||
FIntermissionDescriptor ** pDesc = IntermissionDescriptors.CheckKey(intname);
|
||||
if (pDesc != NULL && *pDesc != NULL) delete *pDesc;
|
||||
IntermissionDescriptors[intname] = desc;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FIntermissionAction
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FIntermissionAction::FIntermissionAction()
|
||||
{
|
||||
mSize = sizeof(FIntermissionAction);
|
||||
mClass = RUNTIME_CLASS(DIntermissionScreen);
|
||||
mMusicOrder =
|
||||
mCdId =
|
||||
mCdTrack =
|
||||
mDuration = 0;
|
||||
mFlatfill = false;
|
||||
mMusicLooping = true;
|
||||
}
|
||||
|
||||
bool FIntermissionAction::ParseKey(FScanner &sc)
|
||||
{
|
||||
if (sc.Compare("music"))
|
||||
{
|
||||
sc.MustGetToken('=');
|
||||
sc.MustGetToken(TK_StringConst);
|
||||
mMusic = sc.String;
|
||||
mMusicOrder = 0;
|
||||
if (sc.CheckToken(','))
|
||||
{
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
mMusicOrder = sc.Number;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (sc.Compare("cdmusic"))
|
||||
{
|
||||
sc.MustGetToken('=');
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
mCdTrack = sc.Number;
|
||||
mCdId = 0;
|
||||
if (sc.CheckToken(','))
|
||||
{
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
mCdId = sc.Number;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (sc.Compare("Time"))
|
||||
{
|
||||
sc.MustGetToken('=');
|
||||
if (!sc.CheckToken('-'))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
mDuration = xs_RoundToInt(sc.Float*TICRATE);
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
mDuration = sc.Number;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (sc.Compare("Background"))
|
||||
{
|
||||
sc.MustGetToken('=');
|
||||
sc.MustGetToken(TK_StringConst);
|
||||
mBackground = sc.String;
|
||||
mFlatfill = 0;
|
||||
if (sc.CheckToken(','))
|
||||
{
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
mFlatfill = !!sc.Number;
|
||||
if (sc.CheckToken(','))
|
||||
{
|
||||
sc.MustGetToken(TK_StringConst);
|
||||
mPalette = sc.String;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (sc.Compare("Sound"))
|
||||
{
|
||||
sc.MustGetToken('=');
|
||||
sc.MustGetToken(TK_StringConst);
|
||||
mSound = sc.String;
|
||||
return true;
|
||||
}
|
||||
else if (sc.Compare("Draw"))
|
||||
{
|
||||
FIntermissionPatch *pat = &mOverlays[mOverlays.Reserve(1)];
|
||||
sc.MustGetToken('=');
|
||||
sc.MustGetToken(TK_StringConst);
|
||||
pat->mName = sc.String;
|
||||
sc.MustGetToken(',');
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
pat->x = sc.Number;
|
||||
sc.MustGetToken(',');
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
pat->y = sc.Number;
|
||||
pat->mCondition = NAME_None;
|
||||
return true;
|
||||
}
|
||||
else if (sc.Compare("DrawConditional"))
|
||||
{
|
||||
FIntermissionPatch *pat = &mOverlays[mOverlays.Reserve(1)];
|
||||
sc.MustGetToken('=');
|
||||
sc.MustGetToken(TK_StringConst);
|
||||
pat->mCondition = sc.String;
|
||||
sc.MustGetToken(',');
|
||||
sc.MustGetToken(TK_StringConst);
|
||||
pat->mName = sc.String;
|
||||
sc.MustGetToken(',');
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
pat->x = sc.Number;
|
||||
sc.MustGetToken(',');
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
pat->y = sc.Number;
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FIntermissionActionFader
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FIntermissionActionFader::FIntermissionActionFader()
|
||||
{
|
||||
mSize = sizeof(FIntermissionActionFader);
|
||||
mClass = RUNTIME_CLASS(DIntermissionScreenFader);
|
||||
mFadeType = FADE_In;
|
||||
}
|
||||
|
||||
bool FIntermissionActionFader::ParseKey(FScanner &sc)
|
||||
{
|
||||
struct FadeType
|
||||
{
|
||||
const char *Name;
|
||||
EFadeType Type;
|
||||
}
|
||||
const FT[] = {
|
||||
{ "FadeIn", FADE_In },
|
||||
{ "FadeOut", FADE_Out },
|
||||
{ NULL, FADE_In }
|
||||
};
|
||||
|
||||
if (sc.Compare("FadeType"))
|
||||
{
|
||||
sc.MustGetToken('=');
|
||||
sc.MustGetToken(TK_Identifier);
|
||||
int v = sc.MatchString(&FT[0].Name, sizeof(FT[0]));
|
||||
if (v != -1) mFadeType = FT[v].Type;
|
||||
return true;
|
||||
}
|
||||
else return Super::ParseKey(sc);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FIntermissionActionWiper
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FIntermissionActionWiper::FIntermissionActionWiper()
|
||||
{
|
||||
mSize = sizeof(FIntermissionActionWiper);
|
||||
mClass = WIPER_ID;
|
||||
mWipeType = GS_FORCEWIPE;
|
||||
}
|
||||
|
||||
bool FIntermissionActionWiper::ParseKey(FScanner &sc)
|
||||
{
|
||||
struct WipeType
|
||||
{
|
||||
const char *Name;
|
||||
gamestate_t Type;
|
||||
}
|
||||
const FT[] = {
|
||||
{ "Crossfade", GS_FORCEWIPEFADE },
|
||||
{ "Melt", GS_FORCEWIPEMELT },
|
||||
{ "Burn", GS_FORCEWIPEBURN },
|
||||
{ "Default", GS_FORCEWIPE },
|
||||
{ NULL, GS_FORCEWIPE }
|
||||
};
|
||||
|
||||
if (sc.Compare("WipeType"))
|
||||
{
|
||||
sc.MustGetToken('=');
|
||||
sc.MustGetToken(TK_Identifier);
|
||||
int v = sc.MatchString(&FT[0].Name, sizeof(FT[0]));
|
||||
if (v != -1) mWipeType = FT[v].Type;
|
||||
return true;
|
||||
}
|
||||
else return Super::ParseKey(sc);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FIntermissionActionFader
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FIntermissionActionTextscreen::FIntermissionActionTextscreen()
|
||||
{
|
||||
mSize = sizeof(FIntermissionActionTextscreen);
|
||||
mClass = RUNTIME_CLASS(DIntermissionScreenText);
|
||||
mTextSpeed = 2;
|
||||
mTextX = -1; // use gameinfo defaults
|
||||
mTextY = -1;
|
||||
mTextColor = CR_UNTRANSLATED;
|
||||
mTextDelay = 10;
|
||||
}
|
||||
|
||||
bool FIntermissionActionTextscreen::ParseKey(FScanner &sc)
|
||||
{
|
||||
if (sc.Compare("Position"))
|
||||
{
|
||||
sc.MustGetToken('=');
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
mTextX = sc.Number;
|
||||
sc.MustGetToken(',');
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
mTextY = sc.Number;
|
||||
return true;
|
||||
}
|
||||
else if (sc.Compare("TextLump"))
|
||||
{
|
||||
sc.MustGetToken('=');
|
||||
sc.MustGetToken(TK_StringConst);
|
||||
int lump = Wads.CheckNumForFullName(sc.String, true);
|
||||
if (lump > 0)
|
||||
{
|
||||
mText = Wads.ReadLump(lump).GetString();
|
||||
}
|
||||
else
|
||||
{
|
||||
// only print an error if coming from a PWAD
|
||||
if (Wads.GetLumpFile(sc.LumpNum) > 1)
|
||||
sc.ScriptMessage("Unknown text lump '%s'", sc.String);
|
||||
mText.Format("Unknown text lump '%s'", sc.String);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (sc.Compare("Text"))
|
||||
{
|
||||
sc.MustGetToken('=');
|
||||
do
|
||||
{
|
||||
sc.MustGetToken(TK_StringConst);
|
||||
mText << sc.String << '\n';
|
||||
}
|
||||
while (sc.CheckToken(','));
|
||||
return true;
|
||||
}
|
||||
else if (sc.Compare("TextColor"))
|
||||
{
|
||||
sc.MustGetToken('=');
|
||||
sc.MustGetToken(TK_StringConst);
|
||||
mTextColor = V_FindFontColor(sc.String);
|
||||
return true;
|
||||
}
|
||||
else if (sc.Compare("TextDelay"))
|
||||
{
|
||||
sc.MustGetToken('=');
|
||||
if (!sc.CheckToken('-'))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
mTextDelay = xs_RoundToInt(sc.Float*TICRATE);
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
mTextDelay = sc.Number;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (sc.Compare("textspeed"))
|
||||
{
|
||||
sc.MustGetToken('=');
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
mTextSpeed = sc.Number;
|
||||
return true;
|
||||
}
|
||||
else return Super::ParseKey(sc);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FIntermissionAction
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FIntermissionActionCast::FIntermissionActionCast()
|
||||
{
|
||||
mSize = sizeof(FIntermissionActionCast);
|
||||
mClass = RUNTIME_CLASS(DIntermissionScreenCast);
|
||||
}
|
||||
|
||||
bool FIntermissionActionCast::ParseKey(FScanner &sc)
|
||||
{
|
||||
if (sc.Compare("CastName"))
|
||||
{
|
||||
sc.MustGetToken('=');
|
||||
sc.MustGetToken(TK_StringConst);
|
||||
mName = sc.String;
|
||||
return true;
|
||||
}
|
||||
else if (sc.Compare("CastClass"))
|
||||
{
|
||||
sc.MustGetToken('=');
|
||||
sc.MustGetToken(TK_StringConst);
|
||||
mCastClass = sc.String;
|
||||
return true;
|
||||
}
|
||||
else if (sc.Compare("AttackSound"))
|
||||
{
|
||||
static const char *const seqs[] = {"Missile", "Melee", NULL};
|
||||
FCastSound *cs = &mCastSounds[mCastSounds.Reserve(1)];
|
||||
sc.MustGetToken('=');
|
||||
sc.MustGetToken(TK_StringConst);
|
||||
cs->mSequence = (BYTE)sc.MatchString(seqs);
|
||||
sc.MustGetToken(',');
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
cs->mIndex = (BYTE)sc.Number;
|
||||
sc.MustGetToken(',');
|
||||
sc.MustGetToken(TK_StringConst);
|
||||
cs->mSound = sc.String;
|
||||
return true;
|
||||
}
|
||||
else return Super::ParseKey(sc);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FIntermissionActionScroller
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FIntermissionActionScroller::FIntermissionActionScroller()
|
||||
{
|
||||
mSize = sizeof(FIntermissionActionScroller);
|
||||
mClass = RUNTIME_CLASS(DIntermissionScreenScroller);
|
||||
mScrollDelay = 0;
|
||||
mScrollTime = 640;
|
||||
mScrollDir = SCROLL_Right;
|
||||
}
|
||||
|
||||
bool FIntermissionActionScroller::ParseKey(FScanner &sc)
|
||||
{
|
||||
struct ScrollType
|
||||
{
|
||||
const char *Name;
|
||||
EScrollDir Type;
|
||||
}
|
||||
const ST[] = {
|
||||
{ "Left", SCROLL_Left },
|
||||
{ "Right", SCROLL_Right },
|
||||
{ "Up", SCROLL_Up },
|
||||
{ "Down", SCROLL_Down },
|
||||
{ NULL, SCROLL_Left }
|
||||
};
|
||||
|
||||
if (sc.Compare("ScrollDirection"))
|
||||
{
|
||||
sc.MustGetToken('=');
|
||||
sc.MustGetToken(TK_Identifier);
|
||||
int v = sc.MatchString(&ST[0].Name, sizeof(ST[0]));
|
||||
if (v != -1) mScrollDir = ST[v].Type;
|
||||
return true;
|
||||
}
|
||||
else if (sc.Compare("InitialDelay"))
|
||||
{
|
||||
sc.MustGetToken('=');
|
||||
if (!sc.CheckToken('-'))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
mScrollDelay = xs_RoundToInt(sc.Float*TICRATE);
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
mScrollDelay = sc.Number;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (sc.Compare("ScrollTime"))
|
||||
{
|
||||
sc.MustGetToken('=');
|
||||
if (!sc.CheckToken('-'))
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
mScrollTime = xs_RoundToInt(sc.Float*TICRATE);
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
mScrollTime = sc.Number;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (sc.Compare("Background2"))
|
||||
{
|
||||
sc.MustGetToken('=');
|
||||
sc.MustGetToken(TK_StringConst);
|
||||
mSecondPic = sc.String;
|
||||
return true;
|
||||
}
|
||||
else return Super::ParseKey(sc);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ParseIntermission
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FMapInfoParser::ParseIntermissionAction(FIntermissionDescriptor *desc)
|
||||
{
|
||||
FIntermissionAction *ac = NULL;
|
||||
|
||||
sc.MustGetToken(TK_Identifier);
|
||||
if (sc.Compare("image"))
|
||||
{
|
||||
ac = new FIntermissionAction;
|
||||
}
|
||||
else if (sc.Compare("scroller"))
|
||||
{
|
||||
ac = new FIntermissionActionScroller;
|
||||
}
|
||||
else if (sc.Compare("cast"))
|
||||
{
|
||||
ac = new FIntermissionActionCast;
|
||||
}
|
||||
else if (sc.Compare("Fader"))
|
||||
{
|
||||
ac = new FIntermissionActionFader;
|
||||
}
|
||||
else if (sc.Compare("Wiper"))
|
||||
{
|
||||
ac = new FIntermissionActionWiper;
|
||||
}
|
||||
else if (sc.Compare("TextScreen"))
|
||||
{
|
||||
ac = new FIntermissionActionTextscreen;
|
||||
}
|
||||
else if (sc.Compare("GotoTitle"))
|
||||
{
|
||||
ac = new FIntermissionAction;
|
||||
ac->mClass = TITLE_ID;
|
||||
}
|
||||
else if (sc.Compare("Link"))
|
||||
{
|
||||
sc.MustGetToken('=');
|
||||
sc.MustGetToken(TK_Identifier);
|
||||
desc->mLink = sc.String;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.ScriptMessage("Unknown intermission type '%s'", sc.String);
|
||||
}
|
||||
|
||||
sc.MustGetToken('{');
|
||||
while (!sc.CheckToken('}'))
|
||||
{
|
||||
bool success = false;
|
||||
if (!sc.CheckToken(TK_Sound))
|
||||
{
|
||||
sc.MustGetToken(TK_Identifier);
|
||||
}
|
||||
if (ac != NULL)
|
||||
{
|
||||
success = ac->ParseKey(sc);
|
||||
if (!success)
|
||||
{
|
||||
sc.ScriptMessage("Unknown key name '%s'\n", sc.String);
|
||||
}
|
||||
}
|
||||
if (!success) SkipToNext();
|
||||
}
|
||||
if (ac != NULL) desc->mActions.Push(ac);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ParseIntermission
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FMapInfoParser::ParseIntermission()
|
||||
{
|
||||
sc.MustGetString();
|
||||
FName intname = sc.String;
|
||||
FIntermissionDescriptor *desc = new FIntermissionDescriptor();
|
||||
|
||||
ReplaceIntermission(intname, desc);
|
||||
sc.MustGetToken('{');
|
||||
while (!sc.CheckToken('}'))
|
||||
{
|
||||
ParseIntermissionAction(desc);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Parse old style endsequence
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
struct EndSequence
|
||||
{
|
||||
SBYTE EndType;
|
||||
bool MusicLooping;
|
||||
bool PlayTheEnd;
|
||||
FString PicName;
|
||||
FString PicName2;
|
||||
FString Music;
|
||||
};
|
||||
|
||||
enum EndTypes
|
||||
{
|
||||
END_Pic,
|
||||
END_Bunny,
|
||||
END_Cast,
|
||||
END_Demon
|
||||
};
|
||||
|
||||
FName FMapInfoParser::ParseEndGame()
|
||||
{
|
||||
EndSequence newSeq;
|
||||
static int generated = 0;
|
||||
|
||||
newSeq.EndType = -1;
|
||||
newSeq.PlayTheEnd = false;
|
||||
newSeq.MusicLooping = true;
|
||||
while (!sc.CheckString("}"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
if (sc.Compare("pic"))
|
||||
{
|
||||
ParseAssign();
|
||||
sc.MustGetString();
|
||||
newSeq.EndType = END_Pic;
|
||||
newSeq.PicName = sc.String;
|
||||
}
|
||||
else if (sc.Compare("hscroll"))
|
||||
{
|
||||
ParseAssign();
|
||||
newSeq.EndType = END_Bunny;
|
||||
sc.MustGetString();
|
||||
newSeq.PicName = sc.String;
|
||||
ParseComma();
|
||||
sc.MustGetString();
|
||||
newSeq.PicName2 = sc.String;
|
||||
if (CheckNumber())
|
||||
newSeq.PlayTheEnd = !!sc.Number;
|
||||
}
|
||||
else if (sc.Compare("vscroll"))
|
||||
{
|
||||
ParseAssign();
|
||||
newSeq.EndType = END_Demon;
|
||||
sc.MustGetString();
|
||||
newSeq.PicName = sc.String;
|
||||
ParseComma();
|
||||
sc.MustGetString();
|
||||
newSeq.PicName2 = sc.String;
|
||||
}
|
||||
else if (sc.Compare("cast"))
|
||||
{
|
||||
newSeq.EndType = END_Cast;
|
||||
}
|
||||
else if (sc.Compare("music"))
|
||||
{
|
||||
ParseAssign();
|
||||
sc.MustGetString();
|
||||
newSeq.Music = sc.String;
|
||||
if (CheckNumber())
|
||||
{
|
||||
newSeq.MusicLooping = !!sc.Number;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (format_type == FMT_New)
|
||||
{
|
||||
// Unknown
|
||||
sc.ScriptMessage("Unknown property '%s' found in endgame definition\n", sc.String);
|
||||
SkipToNext();
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.ScriptError("Unknown property '%s' found in endgame definition\n", sc.String);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
FIntermissionDescriptor *desc = new FIntermissionDescriptor;
|
||||
FIntermissionAction *action;
|
||||
|
||||
switch (newSeq.EndType)
|
||||
{
|
||||
case END_Pic:
|
||||
action = new FIntermissionAction;
|
||||
break;
|
||||
|
||||
case END_Bunny:
|
||||
{
|
||||
FIntermissionActionScroller *bunny = new FIntermissionActionScroller;
|
||||
bunny->mSecondPic = newSeq.PicName2;
|
||||
bunny->mScrollDir = SCROLL_Left;
|
||||
bunny->mScrollDelay = 230;
|
||||
bunny->mScrollTime = 640;
|
||||
bunny->mDuration = 1130;
|
||||
action = bunny;
|
||||
if (newSeq.PlayTheEnd) desc->mLink = "TheEnd";
|
||||
break;
|
||||
}
|
||||
|
||||
case END_Demon:
|
||||
{
|
||||
FIntermissionActionScroller *demon = new FIntermissionActionScroller;
|
||||
demon->mSecondPic = newSeq.PicName2;
|
||||
demon->mScrollDir = SCROLL_Up;
|
||||
demon->mScrollDelay = 70;
|
||||
demon->mScrollTime = 600;
|
||||
action = demon;
|
||||
break;
|
||||
}
|
||||
|
||||
case END_Cast:
|
||||
action = new FIntermissionAction;
|
||||
action->mDuration = 1;
|
||||
desc->mLink = "Doom2Cast";
|
||||
break;
|
||||
}
|
||||
|
||||
action->mBackground = newSeq.PicName;
|
||||
action->mMusic = newSeq.Music;
|
||||
action->mMusicLooping = newSeq.MusicLooping;
|
||||
|
||||
FString seq;
|
||||
seq.Format("@EndSequence_%d_", generated++);
|
||||
ReplaceIntermission(seq, desc);
|
||||
return FName(seq);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Checks map name for end sequence
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FName FMapInfoParser::CheckEndSequence()
|
||||
{
|
||||
const char *seqname = NULL;
|
||||
|
||||
if (sc.Compare("endgame"))
|
||||
{
|
||||
if (!sc.CheckString("{"))
|
||||
{
|
||||
// Make Demon Eclipse work again
|
||||
sc.UnGet();
|
||||
goto standard_endgame;
|
||||
}
|
||||
return ParseEndGame();
|
||||
}
|
||||
else if (strnicmp (sc.String, "EndGame", 7) == 0)
|
||||
{
|
||||
switch (sc.String[7])
|
||||
{
|
||||
case '1': seqname = "Inter_Pic1"; break;
|
||||
case '2': seqname = "Inter_Pic2"; break;
|
||||
case '3': seqname = "Inter_Bunny"; break;
|
||||
case 'C': seqname = "Inter_Cast"; break;
|
||||
case 'W': seqname = "Inter_Underwater"; break;
|
||||
case 'S': seqname = "Inter_Strife"; break;
|
||||
standard_endgame:
|
||||
default: seqname = "Inter_Pic3"; break;
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("endpic"))
|
||||
{
|
||||
ParseComma();
|
||||
sc.MustGetString ();
|
||||
FString seqname;
|
||||
seqname << "@EndPic_" << sc.String;
|
||||
FIntermissionDescriptor *desc = new FIntermissionDescriptor;
|
||||
FIntermissionAction *action = new FIntermissionAction;
|
||||
action->mBackground = sc.String;
|
||||
desc->mActions.Push(action);
|
||||
ReplaceIntermission(seqname, desc);
|
||||
return FName(seqname);
|
||||
}
|
||||
else if (sc.Compare("endbunny"))
|
||||
{
|
||||
seqname = "Inter_Bunny";
|
||||
}
|
||||
else if (sc.Compare("endcast"))
|
||||
{
|
||||
seqname = "Inter_Cast";
|
||||
}
|
||||
else if (sc.Compare("enddemon"))
|
||||
{
|
||||
seqname = "Inter_Demonscroll";
|
||||
}
|
||||
else if (sc.Compare("endchess"))
|
||||
{
|
||||
seqname = "Inter_Chess";
|
||||
}
|
||||
else if (sc.Compare("endunderwater"))
|
||||
{
|
||||
seqname = "Inter_Underwater";
|
||||
}
|
||||
else if (sc.Compare("endbuystrife"))
|
||||
{
|
||||
seqname = "Inter_BuyStrife";
|
||||
}
|
||||
else if (sc.Compare("endtitle"))
|
||||
{
|
||||
seqname = "Inter_Titlescreen";
|
||||
}
|
||||
|
||||
if (seqname != NULL)
|
||||
{
|
||||
return FName(seqname);
|
||||
}
|
||||
return NAME_None;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Creates an intermission from the cluster's finale info
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void F_StartFinale (const char *music, int musicorder, int cdtrack, unsigned int cdid, const char *flat,
|
||||
const char *text, INTBOOL textInLump, INTBOOL finalePic, INTBOOL lookupText,
|
||||
bool ending, FName endsequence)
|
||||
{
|
||||
if (text != NULL && *text != 0)
|
||||
{
|
||||
FIntermissionActionTextscreen *textscreen = new FIntermissionActionTextscreen;
|
||||
if (textInLump)
|
||||
{
|
||||
int lump = Wads.CheckNumForFullName(text, true);
|
||||
if (lump > 0)
|
||||
{
|
||||
textscreen->mText = Wads.ReadLump(lump).GetString();
|
||||
}
|
||||
else
|
||||
{
|
||||
textscreen->mText.Format("Unknown text lump '%s'", text);
|
||||
}
|
||||
}
|
||||
else if (!lookupText)
|
||||
{
|
||||
textscreen->mText = text;
|
||||
}
|
||||
else
|
||||
{
|
||||
textscreen->mText << '$' << text;
|
||||
}
|
||||
textscreen->mTextDelay = 10;
|
||||
textscreen->mBackground = flat;
|
||||
textscreen->mFlatfill = !finalePic;
|
||||
|
||||
if (music != NULL && *music != 0)
|
||||
{
|
||||
textscreen->mMusic = music;
|
||||
textscreen->mMusicOrder = musicorder;
|
||||
}
|
||||
if (cdtrack > 0)
|
||||
{
|
||||
textscreen->mCdTrack = cdtrack;
|
||||
textscreen->mCdId = cdid;
|
||||
}
|
||||
FIntermissionDescriptor *desc = new FIntermissionDescriptor;
|
||||
desc->mActions.Push(textscreen);
|
||||
|
||||
if (ending)
|
||||
{
|
||||
desc->mLink = endsequence;
|
||||
FIntermissionActionWiper *wiper = new FIntermissionActionWiper;
|
||||
desc->mActions.Push(wiper);
|
||||
}
|
||||
|
||||
F_StartIntermission(desc, true, ending? FSTATE_EndingGame : FSTATE_ChangingLevel);
|
||||
}
|
||||
else if (ending)
|
||||
{
|
||||
FIntermissionDescriptor **pdesc = IntermissionDescriptors.CheckKey(endsequence);
|
||||
if (pdesc != NULL)
|
||||
{
|
||||
F_StartIntermission(*pdesc, false, ending? FSTATE_EndingGame : FSTATE_ChangingLevel);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -79,6 +79,7 @@ int MenuButtonTickers[NUM_MKEYS];
|
|||
bool MenuButtonOrigin[NUM_MKEYS];
|
||||
int BackbuttonTime;
|
||||
fixed_t BackbuttonAlpha;
|
||||
static bool MenuEnabled = true;
|
||||
|
||||
|
||||
#define KEY_REPEAT_DELAY (TICRATE*5/12)
|
||||
|
@ -633,7 +634,7 @@ bool M_Responder (event_t *ev)
|
|||
}
|
||||
return DMenu::CurrentMenu->Responder(ev) || !keyup;
|
||||
}
|
||||
else
|
||||
else if (MenuEnabled)
|
||||
{
|
||||
if (ev->type == EV_KeyDown)
|
||||
{
|
||||
|
@ -761,6 +762,18 @@ void M_Init (void)
|
|||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
void M_EnableMenu (bool on)
|
||||
{
|
||||
MenuEnabled = on;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// [RH] Most menus can now be accessed directly
|
||||
|
|
|
@ -637,6 +637,7 @@ public:
|
|||
|
||||
|
||||
struct event_t;
|
||||
void M_EnableMenu (bool on) ;
|
||||
bool M_Responder (event_t *ev);
|
||||
void M_Ticker (void);
|
||||
void M_Drawer (void);
|
||||
|
|
|
@ -528,3 +528,13 @@ xx(res_7)
|
|||
xx(res_8)
|
||||
xx(res_9)
|
||||
xx(AlwaysRun)
|
||||
|
||||
// end sequences
|
||||
xx(Inter_Strife)
|
||||
xx(Inter_Strife_Good)
|
||||
xx(Inter_Strife_Sad)
|
||||
xx(Inter_Strife_Bad)
|
||||
xx(Inter_Strife_Lose)
|
||||
xx(Inter_Strife_MAP03)
|
||||
xx(Inter_Strife_MAP10)
|
||||
xx(Multiplayer)
|
|
@ -895,8 +895,7 @@ FUNC(LS_Teleport_EndGame)
|
|||
{
|
||||
if (!backSide && CheckIfExitIsGood (it, NULL))
|
||||
{
|
||||
G_SetForEndGame (level.nextmap);
|
||||
G_ExitLevel (0, false);
|
||||
G_ChangeLevel(NULL, 0, 0);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
#include "w_wad.h"
|
||||
#include "cmdlib.h"
|
||||
#include "sbar.h"
|
||||
#include "f_finale.h"
|
||||
#include "intermission/intermission.h"
|
||||
#include "c_console.h"
|
||||
#include "doomdef.h"
|
||||
#include "c_dispatch.h"
|
||||
|
@ -1215,9 +1215,9 @@ void APlayerPawn::Die (AActor *source, AActor *inflictor)
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!multiplayer && (level.flags2 & LEVEL2_DEATHSLIDESHOW))
|
||||
if (!multiplayer && level.info->deathsequence != NAME_None)
|
||||
{
|
||||
F_StartSlideshow ();
|
||||
F_StartIntermission(level.info->deathsequence, FSTATE_EndingGame);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -453,7 +453,6 @@ void STAT_ChangeLevel(const char *newl)
|
|||
level_info_t *l = FindLevelInfo (newl);
|
||||
nextinfo = l->CheckLevelRedirect ();
|
||||
if (nextinfo == NULL) nextinfo = l;
|
||||
|
||||
}
|
||||
|
||||
if (savestatistics == 1)
|
||||
|
@ -602,8 +601,7 @@ CCMD(printstats)
|
|||
CCMD(finishgame)
|
||||
{
|
||||
// This CCMD simulates an end-of-game action and exists to end mods that never exit their last level.
|
||||
G_SetForEndGame (level.nextmap);
|
||||
G_ExitLevel (0, false);
|
||||
G_ChangeLevel(NULL, 0, 0);
|
||||
}
|
||||
|
||||
ADD_STAT(statistics)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// MAPINFO for Chex Quest
|
||||
include "mapinfo/common.txt"
|
||||
|
||||
gameinfo
|
||||
{
|
||||
|
@ -56,6 +57,9 @@ gameinfo
|
|||
pausesign = "M_PAUSE"
|
||||
gibfactor = 1
|
||||
cursorpic = "chexcurs"
|
||||
textscreenx = 10
|
||||
textscreeny = 10
|
||||
defaultendsequence = "Inter_Pic1"
|
||||
}
|
||||
|
||||
skill baby
|
||||
|
|
308
wadsrc/static/mapinfo/common.txt
Normal file
308
wadsrc/static/mapinfo/common.txt
Normal file
|
@ -0,0 +1,308 @@
|
|||
|
||||
Intermission Inter_Titlescreen
|
||||
{
|
||||
GotoTitle
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Intermission Inter_Pic1
|
||||
{
|
||||
Image
|
||||
{
|
||||
Background = "@1" // index into finalepic FadeIn gameinfo block
|
||||
}
|
||||
}
|
||||
|
||||
Intermission Inter_Pic2
|
||||
{
|
||||
Image
|
||||
{
|
||||
Background = "@2"
|
||||
}
|
||||
}
|
||||
|
||||
Intermission Inter_Pic3
|
||||
{
|
||||
Image
|
||||
{
|
||||
Background = "@3"
|
||||
}
|
||||
}
|
||||
|
||||
Intermission Inter_Bunny
|
||||
{
|
||||
Scroller
|
||||
{
|
||||
ScrollDirection = Left
|
||||
Background = "PFUB1"
|
||||
Background2 = "PFUB2"
|
||||
Music = "$MUSIC_BUNNY"
|
||||
InitialDelay = -230
|
||||
Scrolltime = -640
|
||||
Time = -1130
|
||||
}
|
||||
Link = TheEnd
|
||||
}
|
||||
|
||||
Intermission TheEnd
|
||||
{
|
||||
// no backgrounds are set here so this will reuse the previous one.
|
||||
Image
|
||||
{
|
||||
Draw = "END0", 108, 68
|
||||
Time = -50
|
||||
}
|
||||
Image
|
||||
{
|
||||
Draw = "END1", 108, 68
|
||||
Time = -5
|
||||
Sound = "weapons/pistol"
|
||||
}
|
||||
Image
|
||||
{
|
||||
Draw = "END2", 108, 68
|
||||
Time = -5
|
||||
Sound = "weapons/pistol"
|
||||
}
|
||||
Image
|
||||
{
|
||||
Draw = "END3", 108, 68
|
||||
Time = -5
|
||||
Sound = "weapons/pistol"
|
||||
}
|
||||
Image
|
||||
{
|
||||
Draw = "END4", 108, 68
|
||||
Time = -5
|
||||
Sound = "weapons/pistol"
|
||||
}
|
||||
Image
|
||||
{
|
||||
Draw = "END5", 108, 68
|
||||
Time = -5
|
||||
Sound = "weapons/pistol"
|
||||
}
|
||||
Image
|
||||
{
|
||||
Draw = "END6", 108, 68
|
||||
Time = -5
|
||||
Sound = "weapons/pistol"
|
||||
}
|
||||
}
|
||||
|
||||
Intermission Inter_Underwater
|
||||
{
|
||||
Image
|
||||
{
|
||||
Background = "E2END", 0, "E2PAL"
|
||||
}
|
||||
GotoTitle
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
Intermission Inter_Demonscroll
|
||||
{
|
||||
Scroller
|
||||
{
|
||||
ScrollDirection = Up
|
||||
Background = "FINAL1"
|
||||
Background2 = "FINAL2"
|
||||
InitialDelay = 2
|
||||
Scrolltime = -600
|
||||
}
|
||||
}
|
||||
|
||||
Intermission Inter_BuyStrife
|
||||
{
|
||||
Scroller
|
||||
{
|
||||
ScrollDirection = Left
|
||||
Background = "CREDIT"
|
||||
Background2 = "VELLOGO"
|
||||
InitialDelay = -230
|
||||
Scrolltime = -640
|
||||
}
|
||||
}
|
||||
|
||||
Intermission Inter_Cast
|
||||
{
|
||||
Image
|
||||
{
|
||||
// This is only here to initialize the background and the music
|
||||
Background = "$bgcastcall"
|
||||
Time = -1
|
||||
Music = "$MUSIC_EVIL"
|
||||
}
|
||||
Link = Doom2Cast
|
||||
}
|
||||
|
||||
Intermission Doom2Cast
|
||||
{
|
||||
Cast
|
||||
{
|
||||
CastClass = "Zombieman"
|
||||
CastName = "$CC_ZOMBIE"
|
||||
AttackSound = "Missile", 1, "grunt/attack"
|
||||
}
|
||||
Cast
|
||||
{
|
||||
CastClass = "ShotgunGuy"
|
||||
CastName = "$CC_SHOTGUN"
|
||||
AttackSound = "Missile", 1, "shotguy/attack"
|
||||
}
|
||||
Cast
|
||||
{
|
||||
CastClass = "ChaingunGuy"
|
||||
CastName = "$CC_HEAVY"
|
||||
AttackSound = "Missile", 1, "chainguy/attack"
|
||||
AttackSound = "Missile", 2, "chainguy/attack"
|
||||
AttackSound = "Missile", 3, "chainguy/attack"
|
||||
}
|
||||
Cast
|
||||
{
|
||||
CastClass = "DoomImp"
|
||||
CastName = "$CC_IMP"
|
||||
AttackSound = "Missile", 2, "imp/attack"
|
||||
}
|
||||
Cast
|
||||
{
|
||||
CastClass = "Demon"
|
||||
CastName = "$CC_DEMON"
|
||||
AttackSound = "Melee", 1, "demon/melee"
|
||||
}
|
||||
Cast
|
||||
{
|
||||
CastClass = "LostSoul"
|
||||
CastName = "$CC_LOST"
|
||||
AttackSound = "Missile", 1, "grunt/attack"
|
||||
}
|
||||
Cast
|
||||
{
|
||||
CastClass = "Cacodemon"
|
||||
CastName = "$CC_CACO"
|
||||
AttackSound = "Missile", 1, "caco/attack"
|
||||
}
|
||||
Cast
|
||||
{
|
||||
CastClass = "HellKnight"
|
||||
CastName = "$CC_HELL"
|
||||
AttackSound = "Missile", 1, "baron/attack"
|
||||
}
|
||||
Cast
|
||||
{
|
||||
CastClass = "BaronOfHell"
|
||||
CastName = "$CC_BARON"
|
||||
AttackSound = "Missile", 1, "baron/attack"
|
||||
}
|
||||
Cast
|
||||
{
|
||||
CastClass = "Arachnotron"
|
||||
CastName = "$CC_ARACH"
|
||||
AttackSound = "Missile", 1, "baby/attack"
|
||||
}
|
||||
Cast
|
||||
{
|
||||
CastClass = "PainElemental"
|
||||
CastName = "$CC_PAIN"
|
||||
AttackSound = "Missile", 2, "skull/melee"
|
||||
}
|
||||
Cast
|
||||
{
|
||||
CastClass = "Revenant"
|
||||
CastName = "$CC_REVEN"
|
||||
AttackSound = "Missile", 1, "skeleton/attack"
|
||||
AttackSound = "Melee", 1, "skeleton/swing"
|
||||
AttackSound = "Melee", 3, "skeleton/melee"
|
||||
}
|
||||
Cast
|
||||
{
|
||||
CastClass = "Fatso"
|
||||
CastName = "$CC_MANCU"
|
||||
AttackSound = "Missile", 1, "fatso/attack"
|
||||
AttackSound = "Missile", 4, "fatso/attack"
|
||||
AttackSound = "Missile", 7, "fatso/attack"
|
||||
}
|
||||
Cast
|
||||
{
|
||||
CastClass = "Archvile"
|
||||
CastName = "$CC_ARCH"
|
||||
AttackSound = "Missile", 1, "vile/start"
|
||||
}
|
||||
Cast
|
||||
{
|
||||
CastClass = "SpiderMastermind"
|
||||
CastName = "$CC_SPIDER"
|
||||
AttackSound = "Missile", 1, "spider/attack"
|
||||
AttackSound = "Missile", 2, "spider/attack"
|
||||
}
|
||||
Cast
|
||||
{
|
||||
CastClass = "Cyberdemon"
|
||||
CastName = "$CC_CYBER"
|
||||
AttackSound = "Missile", 1, "weapons/rocklf"
|
||||
AttackSound = "Missile", 3, "weapons/rocklf"
|
||||
AttackSound = "Missile", 5, "weapons/rocklf"
|
||||
}
|
||||
Cast
|
||||
{
|
||||
CastClass = "DoomPlayer"
|
||||
CastName = "$CC_HERO"
|
||||
AttackSound = "Missile", 0, "weapons/sshotf"
|
||||
}
|
||||
Link = Doom2Cast // restart cast call
|
||||
}
|
||||
|
||||
Intermission Inter_Chess
|
||||
{
|
||||
Fader
|
||||
{
|
||||
Music = "Hall"
|
||||
Background = "FINALE1"
|
||||
Time = 2
|
||||
FadeType = FadeIn
|
||||
}
|
||||
TextScreen
|
||||
{
|
||||
Background = "FINALE1"
|
||||
TextSpeed = 3
|
||||
TextLump = "win1msg"
|
||||
Time = -250
|
||||
}
|
||||
TextScreen
|
||||
{
|
||||
Music = "Orb"
|
||||
Background = "FINALE2"
|
||||
TextSpeed = 3
|
||||
TextLump = "win2msg"
|
||||
Time = -250
|
||||
}
|
||||
Fader
|
||||
{
|
||||
Background = "FINALE2"
|
||||
Time = 2
|
||||
FadeType = FadeOut
|
||||
}
|
||||
Fader
|
||||
{
|
||||
Music = "Chess"
|
||||
Background = "FINALE3"
|
||||
DrawConditional = "Multiplayer", "CHESSALL", 20, 0
|
||||
DrawConditional = "ClericPlayer", "CHESSC", 60, 0
|
||||
DrawConditional = "MagePlayer", "CHESSM", 60, 0
|
||||
Time = 2
|
||||
FadeType = FadeIn
|
||||
}
|
||||
TextScreen
|
||||
{
|
||||
Background = "FINALE3"
|
||||
DrawConditional = "Multiplayer", "CHESSALL", 20, 0
|
||||
DrawConditional = "ClericPlayer", "CHESSC", 60, 0
|
||||
DrawConditional = "MagePlayer", "CHESSM", 60, 0
|
||||
TextSpeed = 3
|
||||
TextLump = "win3msg"
|
||||
Position = 5, 135
|
||||
}
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
include "mapinfo/common.txt"
|
||||
|
||||
gameinfo
|
||||
{
|
||||
titlepage = "TITLEPIC"
|
||||
|
@ -56,6 +58,9 @@ gameinfo
|
|||
pausesign = "M_PAUSE"
|
||||
gibfactor = 1
|
||||
cursorpic = "doomcurs"
|
||||
textscreenx = 10
|
||||
textscreeny = 10
|
||||
defaultendsequence = "Inter_Cast"
|
||||
}
|
||||
|
||||
skill baby
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// MAPINFO for Heretic (Shareware and Retail)
|
||||
include "mapinfo/common.txt"
|
||||
|
||||
gameinfo
|
||||
{
|
||||
|
@ -56,6 +57,9 @@ gameinfo
|
|||
pausesign = "PAUSED"
|
||||
gibfactor = 0.5
|
||||
cursorpic = "herecurs"
|
||||
textscreenx = 20
|
||||
textscreeny = 5
|
||||
defaultendsequence = "Inter_Pic1"
|
||||
}
|
||||
|
||||
skill baby
|
||||
|
|
8
wadsrc/static/mapinfo/hexdd.txt
Normal file
8
wadsrc/static/mapinfo/hexdd.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
include "mapinfo/hexen.txt"
|
||||
|
||||
cluster 3
|
||||
{
|
||||
hub
|
||||
music = "hub"
|
||||
pic = "interpic"
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
// A bare-bones MAPINFO for Hexen.
|
||||
include "mapinfo/common.txt"
|
||||
|
||||
// Most of the MAPINFO is still in hexen.wad.
|
||||
|
||||
|
@ -54,6 +55,9 @@ gameinfo
|
|||
pausesign = "PAUSED"
|
||||
gibfactor = 0.5
|
||||
cursorpic = "hexncurs"
|
||||
textscreenx = 10
|
||||
textscreeny = 5
|
||||
defaultendsequence = "Inter_Chess"
|
||||
}
|
||||
|
||||
skill baby
|
||||
|
@ -117,7 +121,7 @@ skill nightmare
|
|||
clearepisodes
|
||||
episode "&wt@01"
|
||||
{
|
||||
name = "Hexen"
|
||||
name = "Hexen - Beyond Heretic"
|
||||
key = "h"
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// MAPINFO for Strife (full version and teaser)
|
||||
include "mapinfo/common.txt"
|
||||
|
||||
gameinfo
|
||||
{
|
||||
|
@ -56,6 +57,175 @@ gameinfo
|
|||
pausesign = "M_PAUSE"
|
||||
gibfactor = 0.5
|
||||
cursorpic = "strfcurs"
|
||||
textscreenx = 10
|
||||
textscreeny = 10
|
||||
defaultendsequence = "Inter_Strife"
|
||||
}
|
||||
|
||||
Intermission Inter_Strife_Good
|
||||
{
|
||||
Image
|
||||
{
|
||||
Music = "D_HAPPY"
|
||||
Background = "SS4F1"
|
||||
Sound = "svox/rie01"
|
||||
Time = 13
|
||||
}
|
||||
Image
|
||||
{
|
||||
Background = "SS4F2"
|
||||
Sound = "svox/bbx01"
|
||||
Time = 11
|
||||
}
|
||||
Image
|
||||
{
|
||||
Background = "SS4F3"
|
||||
Sound = "svox/bbx02"
|
||||
Time = 14
|
||||
}
|
||||
Image
|
||||
{
|
||||
Background = "SS4F4"
|
||||
Time = 28
|
||||
}
|
||||
Wiper
|
||||
{
|
||||
WipeType = Crossfade
|
||||
}
|
||||
Image
|
||||
{
|
||||
Music = "D_FAST"
|
||||
Background = "CREDIT"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Intermission Inter_Strife_Sad
|
||||
{
|
||||
Image
|
||||
{
|
||||
Music = "D_SAD"
|
||||
Background = "SS6F1"
|
||||
Sound = "svox/ss601a"
|
||||
Time = 8
|
||||
}
|
||||
Image
|
||||
{
|
||||
Background = "SS6F2"
|
||||
Sound = "svox/ss602a"
|
||||
Time = 8
|
||||
}
|
||||
Image
|
||||
{
|
||||
Background = "SS6F3"
|
||||
Sound = "svox/ss603a"
|
||||
Time = 9
|
||||
}
|
||||
Wiper
|
||||
{
|
||||
WipeType = Crossfade
|
||||
}
|
||||
Image
|
||||
{
|
||||
Music = "D_FAST"
|
||||
Background = "CREDIT"
|
||||
}
|
||||
}
|
||||
|
||||
Intermission Inter_Strife_Lose
|
||||
{
|
||||
Image
|
||||
{
|
||||
Music = "D_SAD"
|
||||
Background = "SS5F1"
|
||||
Sound = "svox/ss501b"
|
||||
Time = 11
|
||||
}
|
||||
Image
|
||||
{
|
||||
Background = "SS5F2"
|
||||
Sound = "svox/ss502b"
|
||||
Time = 10
|
||||
}
|
||||
Image
|
||||
{
|
||||
Background = "SS5F3"
|
||||
Sound = "svox/ss503b"
|
||||
Time = 11
|
||||
}
|
||||
Wiper
|
||||
{
|
||||
WipeType = Crossfade
|
||||
}
|
||||
Image
|
||||
{
|
||||
Music = "D_FAST"
|
||||
Background = "CREDIT"
|
||||
}
|
||||
}
|
||||
|
||||
/* later
|
||||
Intermission Inter_Strife_Intro
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
Intermission Inter_Strife_MAP03
|
||||
{
|
||||
Image
|
||||
{
|
||||
Music = "D_DARK"
|
||||
Background = "SS2F1"
|
||||
Sound = "svox/mac10"
|
||||
Time = 9
|
||||
}
|
||||
Image
|
||||
{
|
||||
Background = "SS2F2"
|
||||
Sound = "svox/mac11"
|
||||
Time = 10
|
||||
}
|
||||
Image
|
||||
{
|
||||
Background = "SS2F3"
|
||||
Sound = "svox/mac12"
|
||||
Time = 12
|
||||
}
|
||||
Image
|
||||
{
|
||||
Background = "SS2F4"
|
||||
Sound = "svox/mac13"
|
||||
Time = 17
|
||||
}
|
||||
}
|
||||
|
||||
Intermission Inter_Strife_MAP10
|
||||
{
|
||||
Image
|
||||
{
|
||||
Music = "D_DARK"
|
||||
Background = "SS3F1"
|
||||
Sound = "svox/mac16"
|
||||
Time = 10
|
||||
}
|
||||
Image
|
||||
{
|
||||
Background = "SS3F2"
|
||||
Sound = "svox/mac17"
|
||||
Time = 12
|
||||
}
|
||||
Image
|
||||
{
|
||||
Background = "SS3F3"
|
||||
Sound = "svox/mac18"
|
||||
Time = 12
|
||||
}
|
||||
Image
|
||||
{
|
||||
Background = "SS3F4"
|
||||
Sound = "svox/mac19"
|
||||
Time = 11
|
||||
}
|
||||
}
|
||||
|
||||
skill baby
|
||||
|
@ -140,6 +310,7 @@ map MAP03 "AREA 3: front base"
|
|||
cluster = 1
|
||||
noallies
|
||||
redirect = "Sigil", "map30"
|
||||
slideshow = "Inter_Strife_MAP03"
|
||||
}
|
||||
|
||||
map MAP04 "AREA 4: power station"
|
||||
|
@ -212,6 +383,7 @@ map MAP10 "AREA 10: New Front Base"
|
|||
sky1 = "SKYMNT01"
|
||||
music = "D_MARCH"
|
||||
cluster = 1
|
||||
slideshow = "Inter_Strife_MAP10"
|
||||
}
|
||||
|
||||
map MAP11 "AREA 11: Borderlands"
|
||||
|
@ -364,7 +536,7 @@ map MAP29 "AREA 29: Entity's Lair"
|
|||
sky1 = "SKYMNT01"
|
||||
music = "D_INSTRY"
|
||||
cluster = 1
|
||||
deathslideshow
|
||||
deathsequence = "Inter_Strife_Lose"
|
||||
}
|
||||
|
||||
map MAP30 "AREA 30: Abandoned Front Base"
|
||||
|
|
6074
zdoom.vcproj
6074
zdoom.vcproj
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue