From 49b77f3a170af58bf84703f70895f43674708ed9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 30 Jul 2017 22:49:50 +0200 Subject: [PATCH] - added per-level exit texts independent of the current cluster. This is mainly to support UMAPINFO which does not have clusters but has been extended to define separate exit texts for each target map that can be reached from a given map. Special names 'normal' and 'secret' can be used to define texts specific to the default exits. New MAPINFO properties: * exittext = mapname, "text"... * textmusic = mapname, "musicname", order * textflat = mapname, flatname * textpic = mapname, picname textflat and textpic are like 'flat' and 'pic' for clusters, one defines a tiled background, the other a fullscreen image. Setting an empty exittext will disable a cluster-based text screen that may apply to the given map. --- src/g_level.cpp | 55 +++++++++++++++++--- src/g_level.h | 24 +++++++++ src/g_mapinfo.cpp | 130 ++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 193 insertions(+), 16 deletions(-) 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;