mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2025-01-07 18:00:51 +00:00
5eb898107f
This removes the entire palette switch and all the special checks to ensure that no menu can be drawn over this image. Instead it gives this texture its special palette in the texture manager so that the proper image is created right away. I decided against exposing this as an editing feature because it is far too specific to this particular image and the raw page format it uses. A quick check of /idgames shows no project ever replacing it - especially no ZDoom-based project - so no extended handling is needed to make this work with other texture formats.
892 lines
20 KiB
C++
892 lines
20 KiB
C++
/*
|
|
** 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;
|
|
}
|
|
|
|
void DeinitIntermissions()
|
|
{
|
|
FIntermissionDescriptorList::Iterator it(IntermissionDescriptors);
|
|
|
|
FIntermissionDescriptorList::Pair *pair;
|
|
|
|
while (it.NextPair(pair))
|
|
{
|
|
delete pair->Value;
|
|
pair->Value = NULL;
|
|
}
|
|
IntermissionDescriptors.Clear();
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// 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 = int(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);
|
|
sc.ScriptMessage("Palette override will be ignored");
|
|
}
|
|
}
|
|
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) > Wads.GetIwadNum())
|
|
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 = int(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 = (uint8_t)sc.MatchString(seqs);
|
|
sc.MustGetToken(',');
|
|
sc.MustGetToken(TK_IntConst);
|
|
cs->mIndex = (uint8_t)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 = int(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 = int(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
|
|
{
|
|
int8_t 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;
|
|
if (newSeq.PicName.IsEmpty()) newSeq.PicName = "$bgcastcall";
|
|
}
|
|
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 = NULL;
|
|
|
|
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;
|
|
}
|
|
|
|
if (action == NULL)
|
|
{
|
|
sc.ScriptError("Endgame type was not defined");
|
|
return NAME_None; // We won't really get here.
|
|
}
|
|
else
|
|
{
|
|
action->mBackground = newSeq.PicName;
|
|
action->mMusic = newSeq.Music;
|
|
action->mMusicLooping = newSeq.MusicLooping;
|
|
desc->mActions.Push(action);
|
|
|
|
FString seq;
|
|
seq.Format("@EndSequence_%d_", generated++);
|
|
ReplaceIntermission(seq, desc);
|
|
return FName(seq);
|
|
}
|
|
}
|
|
|
|
//==========================================================================
|
|
//
|
|
// Checks map name for end sequence
|
|
//
|
|
//==========================================================================
|
|
|
|
FName MakeEndPic(const char *string)
|
|
{
|
|
FString seqname;
|
|
seqname << "@EndPic_" << string;
|
|
FIntermissionDescriptor *desc = new FIntermissionDescriptor;
|
|
FIntermissionAction *action = new FIntermissionAction;
|
|
action->mBackground = string;
|
|
desc->mActions.Push(action);
|
|
ReplaceIntermission(seqname, desc);
|
|
return FName(seqname);
|
|
}
|
|
|
|
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 ();
|
|
return MakeEndPic(sc.String);
|
|
}
|
|
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";
|
|
}
|
|
else if (sc.Compare("endsequence"))
|
|
{
|
|
ParseComma();
|
|
sc.MustGetString();
|
|
seqname = sc.String;
|
|
}
|
|
|
|
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)
|
|
{
|
|
// Hexen's chess ending doesn't have a text screen, even if the cluster has a message defined.
|
|
if (text != NULL && *text != 0 && endsequence != NAME_Inter_Chess)
|
|
{
|
|
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;
|
|
if (flat != NULL && *flat != 0)
|
|
{
|
|
textscreen->mBackground = flat;
|
|
}
|
|
else
|
|
{
|
|
// force a black screen if no texture is set.
|
|
textscreen->mBackground = "-";
|
|
}
|
|
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);
|
|
}
|
|
}
|
|
}
|