1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-06-17 00:07:41 +02:00

outro for RoE

This commit is contained in:
Laserlicht
2024-09-05 21:31:17 +02:00
parent 6179521364
commit 6d9385b8bd
10 changed files with 69 additions and 37 deletions

View File

@ -21,7 +21,9 @@
#include "globalLobby/GlobalLobbyClient.h" #include "globalLobby/GlobalLobbyClient.h"
#include "lobby/CSelectionBase.h" #include "lobby/CSelectionBase.h"
#include "lobby/CLobbyScreen.h" #include "lobby/CLobbyScreen.h"
#include "lobby/CBonusSelection.h"
#include "windows/InfoWindows.h" #include "windows/InfoWindows.h"
#include "media/CMusicHandler.h"
#include "mainmenu/CMainMenu.h" #include "mainmenu/CMainMenu.h"
#include "mainmenu/CPrologEpilogVideo.h" #include "mainmenu/CPrologEpilogVideo.h"
@ -704,6 +706,14 @@ void CServerHandler::startCampaignScenario(HighScoreParameter param, std::shared
else else
{ {
CMM->openCampaignScreen(ourCampaign->campaignSet); CMM->openCampaignScreen(ourCampaign->campaignSet);
if(!ourCampaign->getOutroVideo().empty())
{
CCS->musich->stopMusic();
GH.windows().createAndPushWindow<CampaignRimVideo>(ourCampaign->getOutroVideo(), ourCampaign->getVideoRim().empty() ? ImagePath::builtin("INTRORIM") : ourCampaign->getVideoRim(), [campaignScoreCalculator, statistic](){
GH.windows().createAndPushWindow<CHighScoreInputScreen>(true, *campaignScoreCalculator, statistic);
});
}
else
GH.windows().createAndPushWindow<CHighScoreInputScreen>(true, *campaignScoreCalculator, statistic); GH.windows().createAndPushWindow<CHighScoreInputScreen>(true, *campaignScoreCalculator, statistic);
} }
}; };

View File

@ -31,6 +31,7 @@
#include "gui/WindowHandler.h" #include "gui/WindowHandler.h"
#include "widgets/Buttons.h" #include "widgets/Buttons.h"
#include "widgets/TextControls.h" #include "widgets/TextControls.h"
#include "media/CMusicHandler.h"
#include "../lib/CConfigHandler.h" #include "../lib/CConfigHandler.h"
#include "../lib/texts/CGeneralTextHandler.h" #include "../lib/texts/CGeneralTextHandler.h"
@ -203,11 +204,19 @@ void ApplyOnLobbyScreenNetPackVisitor::visitLobbyUpdateState(LobbyUpdateState &
if(!lobby->bonusSel && handler.si->campState && handler.getState() == EClientState::LOBBY_CAMPAIGN) if(!lobby->bonusSel && handler.si->campState && handler.getState() == EClientState::LOBBY_CAMPAIGN)
{ {
lobby->bonusSel = std::make_shared<CBonusSelection>(); auto bonusSel = std::make_shared<CBonusSelection>();
lobby->bonusSel = bonusSel;
if(!handler.si->campState->conqueredScenarios().size() && !handler.si->campState->getIntroVideo().empty()) if(!handler.si->campState->conqueredScenarios().size() && !handler.si->campState->getIntroVideo().empty())
GH.windows().createAndPushWindow<CampaignIntroVideo>(handler.si->campState->getIntroVideo(), handler.si->campState->getIntroVideoRim().empty() ? ImagePath::builtin("INTRORIM") : handler.si->campState->getIntroVideoRim(), lobby->bonusSel); {
CCS->musich->stopMusic();
GH.windows().createAndPushWindow<CampaignRimVideo>(handler.si->campState->getIntroVideo(), handler.si->campState->getVideoRim().empty() ? ImagePath::builtin("INTRORIM") : handler.si->campState->getVideoRim(), [bonusSel](){
if(!CSH->si->campState->getMusic().empty())
CCS->musich->playMusic(CSH->si->campState->getMusic(), true, false);
GH.windows().pushWindow(bonusSel);
});
}
else else
GH.windows().pushWindow(lobby->bonusSel); GH.windows().pushWindow(bonusSel);
} }
if(lobby->bonusSel) if(lobby->bonusSel)

View File

@ -59,8 +59,8 @@
#include "../../lib/mapObjects/CGHeroInstance.h" #include "../../lib/mapObjects/CGHeroInstance.h"
CampaignIntroVideo::CampaignIntroVideo(VideoPath video, ImagePath rim, std::shared_ptr<CBonusSelection> bonusSel) CampaignRimVideo::CampaignRimVideo(VideoPath video, ImagePath rim, std::function<void()> closeCb)
: CWindowObject(BORDERED), bonusSel(bonusSel) : CWindowObject(BORDERED), closeCb(closeCb)
{ {
OBJECT_CONSTRUCTION; OBJECT_CONSTRUCTION;
@ -70,26 +70,21 @@ CampaignIntroVideo::CampaignIntroVideo(VideoPath video, ImagePath rim, std::shar
videoPlayer = std::make_shared<VideoWidgetOnce>(Point(80, 186), video, true, [this](){ exit(); }); videoPlayer = std::make_shared<VideoWidgetOnce>(Point(80, 186), video, true, [this](){ exit(); });
setBackground(rim); setBackground(rim);
CCS->musich->stopMusic();
} }
void CampaignIntroVideo::exit() void CampaignRimVideo::exit()
{ {
close(); close();
if(closeCb)
if (!CSH->si->campState->getMusic().empty()) closeCb();
CCS->musich->playMusic(CSH->si->campState->getMusic(), true, false);
GH.windows().pushWindow(bonusSel);
} }
void CampaignIntroVideo::clickPressed(const Point & cursorPosition) void CampaignRimVideo::clickPressed(const Point & cursorPosition)
{ {
exit(); exit();
} }
void CampaignIntroVideo::keyPressed(EShortcut key) void CampaignRimVideo::keyPressed(EShortcut key)
{ {
exit(); exit();
} }

View File

@ -33,14 +33,15 @@ class VideoWidgetOnce;
class CBonusSelection; class CBonusSelection;
class CampaignIntroVideo : public CWindowObject class CampaignRimVideo : public CWindowObject
{ {
std::shared_ptr<VideoWidgetOnce> videoPlayer; std::shared_ptr<VideoWidgetOnce> videoPlayer;
std::shared_ptr<CBonusSelection> bonusSel;
std::function<void()> closeCb;
void exit(); void exit();
public: public:
CampaignIntroVideo(VideoPath video, ImagePath rim, std::shared_ptr<CBonusSelection> bonusSel); CampaignRimVideo(VideoPath video, ImagePath rim, std::function<void()> closeCb);
void clickPressed(const Point & cursorPosition) override; void clickPressed(const Point & cursorPosition) override;
void keyPressed(EShortcut key) override; void keyPressed(EShortcut key) override;

View File

@ -1,4 +1,7 @@
{ {
"DATA/GOOD3" : { // RoE - "Song for the Father"
"outroVideo": "Endgame"
},
"MAPS/HC1_MAIN" : { // Heroes Chronicles 1 "MAPS/HC1_MAIN" : { // Heroes Chronicles 1
"regions": "regions":
{ {
@ -29,7 +32,7 @@
{ "voiceProlog": "chronicles_1/H3X2BBF", "voiceEpilog": "chronicles_1/N1C_D" } { "voiceProlog": "chronicles_1/H3X2BBF", "voiceEpilog": "chronicles_1/N1C_D" }
], ],
"loadingBackground": "chronicles_1/LoadBar", "loadingBackground": "chronicles_1/LoadBar",
"introVideoRim": "chronicles_1/INTRORIM", "videoRim": "chronicles_1/INTRORIM",
"introVideo": "chronicles_1/Intro" "introVideo": "chronicles_1/Intro"
}, },
"MAPS/HC2_MAIN" : { // Heroes Chronicles 2 "MAPS/HC2_MAIN" : { // Heroes Chronicles 2
@ -62,7 +65,7 @@
{ "voiceProlog": "chronicles_2/G1A", "voiceEpilog": "chronicles_2/S1C" } { "voiceProlog": "chronicles_2/G1A", "voiceEpilog": "chronicles_2/S1C" }
], ],
"loadingBackground": "chronicles_2/LoadBar", "loadingBackground": "chronicles_2/LoadBar",
"introVideoRim": "chronicles_2/INTRORIM", "videoRim": "chronicles_2/INTRORIM",
"introVideo": "chronicles_2/Intro" "introVideo": "chronicles_2/Intro"
}, },
"MAPS/HC3_MAIN" : { // Heroes Chronicles 3 "MAPS/HC3_MAIN" : { // Heroes Chronicles 3
@ -95,7 +98,7 @@
{ "voiceProlog": "chronicles_3/G3B", "voiceEpilog": "chronicles_3/ABVOFL2" } { "voiceProlog": "chronicles_3/G3B", "voiceEpilog": "chronicles_3/ABVOFL2" }
], ],
"loadingBackground": "chronicles_3/LoadBar", "loadingBackground": "chronicles_3/LoadBar",
"introVideoRim": "chronicles_3/INTRORIM", "videoRim": "chronicles_3/INTRORIM",
"introVideo": "chronicles_3/Intro" "introVideo": "chronicles_3/Intro"
}, },
"MAPS/HC4_MAIN" : { // Heroes Chronicles 4 "MAPS/HC4_MAIN" : { // Heroes Chronicles 4
@ -128,7 +131,7 @@
{ "voiceProlog": "chronicles_4/H3X2NBD", "voiceEpilog": "chronicles_4/S1C" } { "voiceProlog": "chronicles_4/H3X2NBD", "voiceEpilog": "chronicles_4/S1C" }
], ],
"loadingBackground": "chronicles_4/LoadBar", "loadingBackground": "chronicles_4/LoadBar",
"introVideoRim": "chronicles_4/INTRORIM", "videoRim": "chronicles_4/INTRORIM",
"introVideo": "chronicles_4/Intro" "introVideo": "chronicles_4/Intro"
}, },
"MAPS/HC5_MAIN" : { // Heroes Chronicles 5 "MAPS/HC5_MAIN" : { // Heroes Chronicles 5
@ -155,7 +158,7 @@
{ "voiceProlog": "chronicles_5/H3X2UAH", "voiceEpilog": "chronicles_5/N1C_D" } { "voiceProlog": "chronicles_5/H3X2UAH", "voiceEpilog": "chronicles_5/N1C_D" }
], ],
"loadingBackground": "chronicles_5/LoadBar", "loadingBackground": "chronicles_5/LoadBar",
"introVideoRim": "chronicles_5/INTRORIM", "videoRim": "chronicles_5/INTRORIM",
"introVideo": "chronicles_5/Intro" "introVideo": "chronicles_5/Intro"
}, },
"MAPS/HC6_MAIN" : { // Heroes Chronicles 6 "MAPS/HC6_MAIN" : { // Heroes Chronicles 6
@ -182,7 +185,7 @@
{ "voiceProlog": "chronicles_6/ABVOAB5", "voiceEpilog": "chronicles_6/ABVODB2" } { "voiceProlog": "chronicles_6/ABVOAB5", "voiceEpilog": "chronicles_6/ABVODB2" }
], ],
"loadingBackground": "chronicles_6/LoadBar", "loadingBackground": "chronicles_6/LoadBar",
"introVideoRim": "chronicles_6/INTRORIM", "videoRim": "chronicles_6/INTRORIM",
"introVideo": "chronicles_6/Intro" "introVideo": "chronicles_6/Intro"
}, },
"MAPS/HC7_MAIN" : { // Heroes Chronicles 7 "MAPS/HC7_MAIN" : { // Heroes Chronicles 7
@ -215,7 +218,7 @@
{ "voiceProlog": "chronicles_7/ABVOFW4", "voiceEpilog": "chronicles_7/ABVOAB1" } { "voiceProlog": "chronicles_7/ABVOFW4", "voiceEpilog": "chronicles_7/ABVOAB1" }
], ],
"loadingBackground": "chronicles_7/LoadBar", "loadingBackground": "chronicles_7/LoadBar",
"introVideoRim": "chronicles_7/INTRORIM", "videoRim": "chronicles_7/INTRORIM",
"introVideo": "chronicles_7/Intro5" "introVideo": "chronicles_7/Intro5"
}, },
"MAPS/HC8_MAIN" : { // Heroes Chronicles 8 "MAPS/HC8_MAIN" : { // Heroes Chronicles 8
@ -248,7 +251,7 @@
{ "voiceProlog": "chronicles_8/H3X2ELE", "voiceEpilog": "chronicles_8/ABVOAB7" } { "voiceProlog": "chronicles_8/H3X2ELE", "voiceEpilog": "chronicles_8/ABVOAB7" }
], ],
"loadingBackground": "chronicles_8/LoadBar", "loadingBackground": "chronicles_8/LoadBar",
"introVideoRim": "chronicles_8/INTRORIM", "videoRim": "chronicles_8/INTRORIM",
"introVideo": "chronicles_8/Intro6" "introVideo": "chronicles_8/Intro6"
} }
} }

View File

@ -54,7 +54,8 @@ In header are parameters describing campaign properties
- `"allowDifficultySelection"` is a boolean field (`true`/`false`) which allows or disallows to choose difficulty before scenario start - `"allowDifficultySelection"` is a boolean field (`true`/`false`) which allows or disallows to choose difficulty before scenario start
- `"loadingBackground"` is for setting a different loading screen background - `"loadingBackground"` is for setting a different loading screen background
- `"introVideo"` is for defining an optional intro video - `"introVideo"` is for defining an optional intro video
- `"introVideoRim"` is for the Rim around the optional video (default is INTRORIM) - `"introVideo"` is for defining an optional outro video
- `"videoRim"` is for the Rim around the optional video (default is INTRORIM)
## Scenario description ## Scenario description

View File

@ -169,8 +169,9 @@ void CampaignHandler::readHeaderFromJson(CampaignHeader & ret, JsonNode & reader
ret.modName = modName; ret.modName = modName;
ret.encoding = encoding; ret.encoding = encoding;
ret.loadingBackground = ImagePath::fromJson(reader["loadingBackground"]); ret.loadingBackground = ImagePath::fromJson(reader["loadingBackground"]);
ret.introVideoRim = ImagePath::fromJson(reader["introVideoRim"]); ret.videoRim = ImagePath::fromJson(reader["videoRim"]);
ret.introVideo = VideoPath::fromJson(reader["introVideo"]); ret.introVideo = VideoPath::fromJson(reader["introVideo"]);
ret.outroVideo = VideoPath::fromJson(reader["outroVideo"]);
} }
CampaignScenario CampaignHandler::readScenarioFromJson(JsonNode & reader) CampaignScenario CampaignHandler::readScenarioFromJson(JsonNode & reader)

View File

@ -210,9 +210,9 @@ ImagePath CampaignHeader::getLoadingBackground() const
return loadingBackground; return loadingBackground;
} }
ImagePath CampaignHeader::getIntroVideoRim() const ImagePath CampaignHeader::getVideoRim() const
{ {
return introVideoRim; return videoRim;
} }
VideoPath CampaignHeader::getIntroVideo() const VideoPath CampaignHeader::getIntroVideo() const
@ -220,6 +220,11 @@ VideoPath CampaignHeader::getIntroVideo() const
return introVideo; return introVideo;
} }
VideoPath CampaignHeader::getOutroVideo() const
{
return outroVideo;
}
const CampaignRegions & CampaignHeader::getRegions() const const CampaignRegions & CampaignHeader::getRegions() const
{ {
return campaignRegions; return campaignRegions;
@ -490,10 +495,12 @@ void Campaign::overrideCampaign()
loadLegacyData(CampaignRegions::fromJson(entry.second["regions"]), entry.second["scenarioCount"].Integer()); loadLegacyData(CampaignRegions::fromJson(entry.second["regions"]), entry.second["scenarioCount"].Integer());
if(!entry.second["loadingBackground"].isNull()) if(!entry.second["loadingBackground"].isNull())
loadingBackground = ImagePath::builtin(entry.second["loadingBackground"].String()); loadingBackground = ImagePath::builtin(entry.second["loadingBackground"].String());
if(!entry.second["introVideoRim"].isNull()) if(!entry.second["videoRim"].isNull())
introVideoRim = ImagePath::builtin(entry.second["introVideoRim"].String()); videoRim = ImagePath::builtin(entry.second["videoRim"].String());
if(!entry.second["introVideo"].isNull()) if(!entry.second["introVideo"].isNull())
introVideo = VideoPath::builtin(entry.second["introVideo"].String()); introVideo = VideoPath::builtin(entry.second["introVideo"].String());
if(!entry.second["outroVideo"].isNull())
outroVideo = VideoPath::builtin(entry.second["outroVideo"].String());
} }
} }

View File

@ -98,8 +98,9 @@ class DLL_LINKAGE CampaignHeader : public boost::noncopyable
std::string modName; std::string modName;
std::string encoding; std::string encoding;
ImagePath loadingBackground; ImagePath loadingBackground;
ImagePath introVideoRim; ImagePath videoRim;
VideoPath introVideo; VideoPath introVideo;
VideoPath outroVideo;
int numberOfScenarios = 0; int numberOfScenarios = 0;
bool difficultyChosenByPlayer = false; bool difficultyChosenByPlayer = false;
@ -124,8 +125,9 @@ public:
std::string getEncoding() const; std::string getEncoding() const;
AudioPath getMusic() const; AudioPath getMusic() const;
ImagePath getLoadingBackground() const; ImagePath getLoadingBackground() const;
ImagePath getIntroVideoRim() const; ImagePath getVideoRim() const;
VideoPath getIntroVideo() const; VideoPath getIntroVideo() const;
VideoPath getOutroVideo() const;
const CampaignRegions & getRegions() const; const CampaignRegions & getRegions() const;
TextContainerRegistrable & getTexts(); TextContainerRegistrable & getTexts();
@ -153,9 +155,11 @@ public:
if (h.version >= Handler::Version::CHRONICLES_SUPPORT) if (h.version >= Handler::Version::CHRONICLES_SUPPORT)
{ {
h & loadingBackground; h & loadingBackground;
h & introVideoRim; h & videoRim;
h & introVideo; h & introVideo;
} }
if (h.version >= Handler::Version::CAMPAIGN_OUTRO_SUPPORT)
h & outroVideo;
} }
}; };

View File

@ -57,6 +57,7 @@ enum class ESerializationVersion : int32_t
PLAYER_STATE_OWNED_OBJECTS, // 858 - player state stores all owned objects in a single list PLAYER_STATE_OWNED_OBJECTS, // 858 - player state stores all owned objects in a single list
SAVE_COMPATIBILITY_FIXES, // 859 - implementation of previoulsy postponed changes to serialization SAVE_COMPATIBILITY_FIXES, // 859 - implementation of previoulsy postponed changes to serialization
CHRONICLES_SUPPORT, // 860 - support for heroes chronicles CHRONICLES_SUPPORT, // 860 - support for heroes chronicles
CAMPAIGN_OUTRO_SUPPORT, // 861 - support for campaign outro video
CURRENT = CHRONICLES_SUPPORT CURRENT = CAMPAIGN_OUTRO_SUPPORT
}; };