diff --git a/src/g_level.cpp b/src/g_level.cpp index ec48fd939..d5044942e 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -694,11 +694,13 @@ const char *G_GetSecretExitMap() void G_ExitLevel (int position, bool keepFacing) { + level.flags3 |= LEVEL3_EXITNORMALUSED; G_ChangeLevel(G_GetExitMap(), position, keepFacing ? CHANGELEVEL_KEEPFACING : 0); } void G_SecretExitLevel (int position) { + level.flags3 |= LEVEL3_EXITSECRETUSED; G_ChangeLevel(G_GetSecretExitMap(), position, 0); } @@ -1110,16 +1112,55 @@ void G_WorldDone (void) } } - 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, endsequence); + auto ext = level.info->ExitMapTexts.CheckKey(level.flags3 & LEVEL3_EXITSECRETUSED ? NAME_Secret : NAME_Normal); + if (ext != nullptr && (ext->mDefined & FExitText::DEF_TEXT)) + { + F_StartFinale(ext->mDefined & FExitText::DEF_MUSIC ? ext->mMusic : gameinfo.finaleMusic, + ext->mDefined & FExitText::DEF_MUSIC ? ext->mOrder : gameinfo.finaleOrder, + -1, 0, + ext->mDefined & FExitText::DEF_BACKDROP ? ext->mBackdrop : gameinfo.FinaleFlat, + ext->mText, + false, + ext->mDefined & FExitText::DEF_PIC, + ext->mDefined & FExitText::DEF_LOOKUP, + true, endsequence); + } + else + { + 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, endsequence); + } } else { + FExitText *ext = nullptr; + + if (level.flags3 & LEVEL3_EXITSECRETUSED) ext = level.info->ExitMapTexts.CheckKey(NAME_Secret); + else if (level.flags3 & LEVEL3_EXITNORMALUSED) ext = level.info->ExitMapTexts.CheckKey(NAME_Normal); + if (ext == nullptr) ext = level.info->ExitMapTexts.CheckKey(nextlevel); + + if (ext != nullptr) + { + if ((ext->mDefined & FExitText::DEF_TEXT)) + { + F_StartFinale(ext->mDefined & FExitText::DEF_MUSIC ? ext->mMusic : gameinfo.finaleMusic, + ext->mDefined & FExitText::DEF_MUSIC ? ext->mOrder : gameinfo.finaleOrder, + -1, 0, + ext->mDefined & FExitText::DEF_BACKDROP ? ext->mBackdrop : gameinfo.FinaleFlat, + ext->mText, + false, + ext->mDefined & FExitText::DEF_PIC, + ext->mDefined & FExitText::DEF_LOOKUP, + false); + } + return; + } + nextcluster = FindClusterInfo (FindLevelInfo (nextlevel)->cluster); if (nextcluster->cluster != level.cluster && !deathmatch) diff --git a/src/g_level.h b/src/g_level.h index d332a0093..2df5af946 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -95,6 +95,9 @@ struct FMapInfoParser void ParseMusic(FString &name, int &order); //void ParseLumpOrTextureName(char *name); void ParseLumpOrTextureName(FString &name); + void ParseExitText(FName formap, level_info_t *info); + void ParseExitMusic(FName formap, level_info_t *info); + void ParseExitBackdrop(FName formap, level_info_t *info, bool ispic); void ParseCluster(); void ParseNextMap(FString &mapname); @@ -241,6 +244,8 @@ enum ELevelFlags : unsigned int LEVEL3_ATTENUATE = 0x00000004, // attenuate lights? LEVEL3_NOLIGHTFADE = 0x00000008, // no light fading to black. LEVEL3_NOCOLOREDSPRITELIGHTING = 0x00000010, // draw sprites only with color-less light + LEVEL3_EXITNORMALUSED = 0x00000020, + LEVEL3_EXITSECRETUSED = 0x00000040, }; @@ -287,6 +292,23 @@ enum EMapType : int MAPTYPE_UDMF // This does not distinguish between namespaces. }; +struct FExitText +{ + enum EDefined + { + DEF_TEXT = 1, + DEF_MUSIC = 2, + DEF_BACKDROP = 4, + DEF_LOOKUP = 8, + DEF_PIC = 16 + }; + int16_t mDefined = 0; + int16_t mOrder = -1; + FString mText; + FString mMusic; + FString mBackdrop; +}; + struct level_info_t { int levelnum; @@ -302,6 +324,8 @@ struct level_info_t FString BorderTexture; FString MapBackground; + TMap ExitMapTexts; + int cluster; int partime; int sucktime; diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index a39508e6c..5f22b25cf 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -607,15 +607,6 @@ bool FMapInfoParser::ParseLookupName(FString &dest) // //========================================================================== -/* -void FMapInfoParser::ParseLumpOrTextureName(char *name) -{ - sc.MustGetString(); - uppercopy(name, sc.String); - name[8]=0; -} -*/ - void FMapInfoParser::ParseLumpOrTextureName(FString &name) { sc.MustGetString(); @@ -623,6 +614,91 @@ void FMapInfoParser::ParseLumpOrTextureName(FString &name) } +//========================================================================== +// +// +//========================================================================== + +void FMapInfoParser::ParseExitText(FName formap, level_info_t *info) +{ + FString nexttext; + bool nextlookup = ParseLookupName(nexttext); + + auto def = info->ExitMapTexts.CheckKey(formap); + if (def != nullptr) + { + def->mText = nexttext; + if (nextlookup) def->mDefined |= FExitText::DEF_LOOKUP; + else def->mDefined &= ~FExitText::DEF_LOOKUP; + def->mDefined |= FExitText::DEF_TEXT; + } + else + { + FExitText def; + def.mText = nexttext; + if (nextlookup) def.mDefined |= FExitText::DEF_LOOKUP; + def.mDefined |= FExitText::DEF_TEXT; + info->ExitMapTexts.Insert(formap, def); + } +} + +//========================================================================== +// +// +//========================================================================== + +void FMapInfoParser::ParseExitMusic(FName formap, level_info_t *info) +{ + FString music; + int order; + ParseMusic(music, order); + + auto def = info->ExitMapTexts.CheckKey(formap); + if (def != nullptr) + { + def->mMusic = music; + def->mOrder = order; + def->mDefined |= FExitText::DEF_MUSIC; + } + else + { + FExitText def; + def.mMusic = music; + def.mOrder = order; + def.mDefined |= FExitText::DEF_MUSIC; + info->ExitMapTexts.Insert(formap, def); + } +} + +//========================================================================== +// +// +//========================================================================== + +void FMapInfoParser::ParseExitBackdrop(FName formap, level_info_t *info, bool ispic) +{ + FString drop; + ParseLumpOrTextureName(drop); + + auto def = info->ExitMapTexts.CheckKey(formap); + if (def != nullptr) + { + def->mBackdrop = drop; + def->mDefined |= FExitText::DEF_BACKDROP; + if (ispic) def->mDefined |= FExitText::DEF_PIC; + else def->mDefined &= ~FExitText::DEF_PIC; + } + else + { + FExitText def; + def.mBackdrop = drop; + def.mDefined |= FExitText::DEF_BACKDROP; + def.mDefined |= FExitText::DEF_MUSIC; + if (ispic) def.mDefined |= FExitText::DEF_PIC; + info->ExitMapTexts.Insert(formap, def); + } +} + //========================================================================== // // @@ -1177,6 +1253,42 @@ DEFINE_MAP_OPTION(mapbackground, true) parse.ParseLumpOrTextureName(info->MapBackground); } +DEFINE_MAP_OPTION(exittext, false) +{ + parse.ParseAssign(); + parse.sc.MustGetString(); + FName nextmap = parse.sc.String; + parse.ParseComma(); + parse.ParseExitText(nextmap, info); +} + +DEFINE_MAP_OPTION(textmusic, false) +{ + parse.ParseAssign(); + parse.sc.MustGetString(); + FName nextmap = parse.sc.String; + parse.ParseComma(); + parse.ParseExitMusic(nextmap, info); +} + +DEFINE_MAP_OPTION(textflat, false) +{ + parse.ParseAssign(); + parse.sc.MustGetString(); + FName nextmap = parse.sc.String; + parse.ParseComma(); + parse.ParseExitBackdrop(nextmap, info, false); +} + +DEFINE_MAP_OPTION(textpic, false) +{ + parse.ParseAssign(); + parse.sc.MustGetString(); + FName nextmap = parse.sc.String; + parse.ParseComma(); + parse.ParseExitBackdrop(nextmap, info, true); +} + DEFINE_MAP_OPTION(defaultenvironment, false) { int id;