Skip to content

Commit 2c30516

Browse files
xezonhelmutbuhler
andcommitted
[GEN][ZH] Implement new GUI error dialogs when attempting to load a Replay that was deleted or whose map is missing (#992)
Co-authored-by: Helmut Buhler <buhler@8gadgetpack.net>
1 parent fc2ffd1 commit 2c30516

File tree

7 files changed

+110
-2
lines changed

7 files changed

+110
-2
lines changed

Core/GameEngine/Include/Common/GameDefines.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,7 @@
2828
#ifndef RETAIL_COMPATIBLE_XFER_SAVE
2929
#define RETAIL_COMPATIBLE_XFER_SAVE (1) // Game is expected to be Xfer Save compatible with retail Generals 1.08, Zero Hour 1.04
3030
#endif
31+
32+
#ifndef ENABLE_GAMETEXT_SUBSTITUTES
33+
#define ENABLE_GAMETEXT_SUBSTITUTES (1) // The code can provide substitute texts when labels and strings are missing in the STR or CSF translation file
34+
#endif

Generals/Code/GameEngine/Include/GameClient/GameText.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ class GameTextInterface : public SubsystemInterface
7878

7979
virtual UnicodeString fetch( const Char *label, Bool *exists = NULL ) = 0; ///< Returns the associated labeled unicode text
8080
virtual UnicodeString fetch( AsciiString label, Bool *exists = NULL ) = 0; ///< Returns the associated labeled unicode text
81+
82+
// Do not call this directly, but use the FETCH_OR_SUBSTITUTE macro
83+
virtual UnicodeString fetchOrSubstitute( const Char *label, const WideChar *substituteText ) = 0;
84+
8185
// This function is not performance tuned.. Its really only for Worldbuilder. jkmcd
8286
virtual AsciiStringVec& getStringsWithLabelPrefix(AsciiString label) = 0;
8387

@@ -92,5 +96,14 @@ extern GameTextInterface* CreateGameTextInterface( void );
9296
// Inlining
9397
//----------------------------------------------------------------------------
9498

99+
// TheSuperHackers @info This is meant to be used like:
100+
// TheGameText->FETCH_OR_SUBSTITUTE("GUI:LabelName", L"Substitute Fallback Text")
101+
// The substitute text will be compiled out if ENABLE_GAMETEXT_SUBSTITUTES is not defined.
102+
#if ENABLE_GAMETEXT_SUBSTITUTES
103+
#define FETCH_OR_SUBSTITUTE(labelA, substituteTextW) fetchOrSubstitute(labelA, substituteTextW)
104+
#else
105+
#define FETCH_OR_SUBSTITUTE(labelA, substituteTextW) fetch(labelA)
106+
#endif
107+
95108

96109
#endif // __GAMECLIENT_GAMETEXT_H_

Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/ReplayMenu.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -491,8 +491,32 @@ static void loadReplay(UnicodeString filename)
491491
AsciiString asciiFilename;
492492
asciiFilename.translate(filename);
493493

494-
if(!TheRecorder->replayMatchesGameVersion(asciiFilename))
494+
RecorderClass::ReplayHeader header;
495+
ReplayGameInfo info;
496+
const MapMetaData *mapData;
497+
498+
if(!readReplayMapInfo(asciiFilename, header, info, mapData))
499+
{
500+
// TheSuperHackers @bugfix Prompts a message box when the replay was deleted by the user while the Replay Menu was opened.
501+
502+
UnicodeString title = TheGameText->FETCH_OR_SUBSTITUTE("GUI:ReplayFileNotFoundTitle", L"REPLAY NOT FOUND");
503+
UnicodeString body = TheGameText->FETCH_OR_SUBSTITUTE("GUI:ReplayFileNotFound", L"This replay cannot be loaded because the file no longer exists on this device.");
504+
505+
MessageBoxOk(title, body, NULL);
506+
}
507+
else if(mapData == NULL)
495508
{
509+
// TheSuperHackers @bugfix Prompts a message box when the map used by the replay was not found.
510+
511+
UnicodeString title = TheGameText->FETCH_OR_SUBSTITUTE("GUI:ReplayMapNotFoundTitle", L"MAP NOT FOUND");
512+
UnicodeString body = TheGameText->FETCH_OR_SUBSTITUTE("GUI:ReplayMapNotFound", L"This replay cannot be loaded because the map was not found on this device.");
513+
514+
MessageBoxOk(title, body, NULL);
515+
}
516+
else if(!TheRecorder->replayMatchesGameVersion(header))
517+
{
518+
// Pressing OK loads the replay.
519+
496520
MessageBoxOkCancel(TheGameText->fetch("GUI:OlderReplayVersionTitle"), TheGameText->fetch("GUI:OlderReplayVersion"), reallyLoadReplay, NULL);
497521
}
498522
else

Generals/Code/GameEngine/Source/GameClient/GameText.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ class GameTextManager : public GameTextInterface
152152

153153
virtual UnicodeString fetch( const Char *label, Bool *exists = NULL ); ///< Returns the associated labeled unicode text
154154
virtual UnicodeString fetch( AsciiString label, Bool *exists = NULL ); ///< Returns the associated labeled unicode text
155+
virtual UnicodeString fetchOrSubstitute( const Char *label, const WideChar *substituteText );
156+
155157
virtual AsciiStringVec& getStringsWithLabelPrefix(AsciiString label);
156158

157159
virtual void initMapStringFile( const AsciiString& filename );
@@ -1341,6 +1343,19 @@ UnicodeString GameTextManager::fetch( AsciiString label, Bool *exists )
13411343
return fetch(label.str(), exists);
13421344
}
13431345

1346+
//============================================================================
1347+
// GameTextManager::fetchOrSubstitute
1348+
//============================================================================
1349+
1350+
UnicodeString GameTextManager::fetchOrSubstitute( const Char *label, const WideChar *substituteText )
1351+
{
1352+
Bool exists;
1353+
UnicodeString str = fetch(label, &exists);
1354+
if (!exists)
1355+
str = substituteText;
1356+
return str;
1357+
}
1358+
13441359
//============================================================================
13451360
// GameTextManager::getStringsWithLabelPrefix
13461361
//============================================================================

GeneralsMD/Code/GameEngine/Include/GameClient/GameText.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ class GameTextInterface : public SubsystemInterface
7878

7979
virtual UnicodeString fetch( const Char *label, Bool *exists = NULL ) = 0; ///< Returns the associated labeled unicode text
8080
virtual UnicodeString fetch( AsciiString label, Bool *exists = NULL ) = 0; ///< Returns the associated labeled unicode text
81+
82+
// Do not call this directly, but use the FETCH_OR_SUBSTITUTE macro
83+
virtual UnicodeString fetchOrSubstitute( const Char *label, const WideChar *substituteText ) = 0;
84+
8185
// This function is not performance tuned.. Its really only for Worldbuilder. jkmcd
8286
virtual AsciiStringVec& getStringsWithLabelPrefix(AsciiString label) = 0;
8387

@@ -92,5 +96,14 @@ extern GameTextInterface* CreateGameTextInterface( void );
9296
// Inlining
9397
//----------------------------------------------------------------------------
9498

99+
// TheSuperHackers @info This is meant to be used like:
100+
// TheGameText->FETCH_OR_SUBSTITUTE("GUI:LabelName", L"Substitute Fallback Text")
101+
// The substitute text will be compiled out if ENABLE_GAMETEXT_SUBSTITUTES is not defined.
102+
#if ENABLE_GAMETEXT_SUBSTITUTES
103+
#define FETCH_OR_SUBSTITUTE(labelA, substituteTextW) fetchOrSubstitute(labelA, substituteTextW)
104+
#else
105+
#define FETCH_OR_SUBSTITUTE(labelA, substituteTextW) fetch(labelA)
106+
#endif
107+
95108

96109
#endif // __GAMECLIENT_GAMETEXT_H_

GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/ReplayMenu.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -491,8 +491,32 @@ static void loadReplay(UnicodeString filename)
491491
AsciiString asciiFilename;
492492
asciiFilename.translate(filename);
493493

494-
if(!TheRecorder->replayMatchesGameVersion(asciiFilename))
494+
RecorderClass::ReplayHeader header;
495+
ReplayGameInfo info;
496+
const MapMetaData *mapData;
497+
498+
if(!readReplayMapInfo(asciiFilename, header, info, mapData))
499+
{
500+
// TheSuperHackers @bugfix Prompts a message box when the replay was deleted by the user while the Replay Menu was opened.
501+
502+
UnicodeString title = TheGameText->FETCH_OR_SUBSTITUTE("GUI:ReplayFileNotFoundTitle", L"REPLAY NOT FOUND");
503+
UnicodeString body = TheGameText->FETCH_OR_SUBSTITUTE("GUI:ReplayFileNotFound", L"This replay cannot be loaded because the file no longer exists on this device.");
504+
505+
MessageBoxOk(title, body, NULL);
506+
}
507+
else if(mapData == NULL)
495508
{
509+
// TheSuperHackers @bugfix Prompts a message box when the map used by the replay was not found.
510+
511+
UnicodeString title = TheGameText->FETCH_OR_SUBSTITUTE("GUI:ReplayMapNotFoundTitle", L"MAP NOT FOUND");
512+
UnicodeString body = TheGameText->FETCH_OR_SUBSTITUTE("GUI:ReplayMapNotFound", L"This replay cannot be loaded because the map was not found on this device.");
513+
514+
MessageBoxOk(title, body, NULL);
515+
}
516+
else if(!TheRecorder->replayMatchesGameVersion(header))
517+
{
518+
// Pressing OK loads the replay.
519+
496520
MessageBoxOkCancel(TheGameText->fetch("GUI:OlderReplayVersionTitle"), TheGameText->fetch("GUI:OlderReplayVersion"), reallyLoadReplay, NULL);
497521
}
498522
else

GeneralsMD/Code/GameEngine/Source/GameClient/GameText.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ class GameTextManager : public GameTextInterface
152152

153153
virtual UnicodeString fetch( const Char *label, Bool *exists = NULL ); ///< Returns the associated labeled unicode text
154154
virtual UnicodeString fetch( AsciiString label, Bool *exists = NULL ); ///< Returns the associated labeled unicode text
155+
virtual UnicodeString fetchOrSubstitute( const Char *label, const WideChar *substituteText );
156+
155157
virtual AsciiStringVec& getStringsWithLabelPrefix(AsciiString label);
156158

157159
virtual void initMapStringFile( const AsciiString& filename );
@@ -1341,6 +1343,19 @@ UnicodeString GameTextManager::fetch( AsciiString label, Bool *exists )
13411343
return fetch(label.str(), exists);
13421344
}
13431345

1346+
//============================================================================
1347+
// GameTextManager::fetchOrSubstitute
1348+
//============================================================================
1349+
1350+
UnicodeString GameTextManager::fetchOrSubstitute( const Char *label, const WideChar *substituteText )
1351+
{
1352+
Bool exists;
1353+
UnicodeString str = fetch(label, &exists);
1354+
if (!exists)
1355+
str = substituteText;
1356+
return str;
1357+
}
1358+
13441359
//============================================================================
13451360
// GameTextManager::getStringsWithLabelPrefix
13461361
//============================================================================

0 commit comments

Comments
 (0)