فهرست منبع

outro for RoE

Laserlicht 1 سال پیش
والد
کامیت
6d9385b8bd

+ 11 - 1
client/CServerHandler.cpp

@@ -21,7 +21,9 @@
 #include "globalLobby/GlobalLobbyClient.h"
 #include "lobby/CSelectionBase.h"
 #include "lobby/CLobbyScreen.h"
+#include "lobby/CBonusSelection.h"
 #include "windows/InfoWindows.h"
+#include "media/CMusicHandler.h"
 
 #include "mainmenu/CMainMenu.h"
 #include "mainmenu/CPrologEpilogVideo.h"
@@ -704,7 +706,15 @@ void CServerHandler::startCampaignScenario(HighScoreParameter param, std::shared
 		else
 		{
 			CMM->openCampaignScreen(ourCampaign->campaignSet);
-			GH.windows().createAndPushWindow<CHighScoreInputScreen>(true, *campaignScoreCalculator, statistic);
+			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);
 		}
 	};
 

+ 12 - 3
client/NetPacksLobbyClient.cpp

@@ -31,6 +31,7 @@
 #include "gui/WindowHandler.h"
 #include "widgets/Buttons.h"
 #include "widgets/TextControls.h"
+#include "media/CMusicHandler.h"
 
 #include "../lib/CConfigHandler.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)
 	{
-		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())
-			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
-			GH.windows().pushWindow(lobby->bonusSel);
+			GH.windows().pushWindow(bonusSel);
 	}
 
 	if(lobby->bonusSel)

+ 7 - 12
client/lobby/CBonusSelection.cpp

@@ -59,8 +59,8 @@
 #include "../../lib/mapObjects/CGHeroInstance.h"
 
 
-CampaignIntroVideo::CampaignIntroVideo(VideoPath video, ImagePath rim, std::shared_ptr<CBonusSelection> bonusSel)
-	: CWindowObject(BORDERED), bonusSel(bonusSel)
+CampaignRimVideo::CampaignRimVideo(VideoPath video, ImagePath rim, std::function<void()> closeCb)
+	: CWindowObject(BORDERED), closeCb(closeCb)
 {
 	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(); });
 	setBackground(rim);
-
-	CCS->musich->stopMusic();
 }
 
-void CampaignIntroVideo::exit()
+void CampaignRimVideo::exit()
 {
 	close();
-	
-	if (!CSH->si->campState->getMusic().empty())
-		CCS->musich->playMusic(CSH->si->campState->getMusic(), true, false);
-
-	GH.windows().pushWindow(bonusSel);
+	if(closeCb)
+		closeCb();
 }
 
-void CampaignIntroVideo::clickPressed(const Point & cursorPosition)
+void CampaignRimVideo::clickPressed(const Point & cursorPosition)
 {
 	exit();
 }
 
-void CampaignIntroVideo::keyPressed(EShortcut key)
+void CampaignRimVideo::keyPressed(EShortcut key)
 {
 	exit();
 }

+ 4 - 3
client/lobby/CBonusSelection.h

@@ -33,14 +33,15 @@ class VideoWidgetOnce;
 class CBonusSelection;
 
 
-class CampaignIntroVideo : public CWindowObject
+class CampaignRimVideo : public CWindowObject
 {
 	std::shared_ptr<VideoWidgetOnce> videoPlayer;
-	std::shared_ptr<CBonusSelection> bonusSel;
+
+	std::function<void()> closeCb;
 
 	void exit();
 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 keyPressed(EShortcut key) override;

+ 11 - 8
config/campaignOverrides.json

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

+ 2 - 1
docs/modders/Campaign_Format.md

@@ -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
 - `"loadingBackground"` is for setting a different loading screen background
 - `"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
 

+ 2 - 1
lib/campaign/CampaignHandler.cpp

@@ -169,8 +169,9 @@ void CampaignHandler::readHeaderFromJson(CampaignHeader & ret, JsonNode & reader
 	ret.modName = modName;
 	ret.encoding = encoding;
 	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.outroVideo = VideoPath::fromJson(reader["outroVideo"]);
 }
 
 CampaignScenario CampaignHandler::readScenarioFromJson(JsonNode & reader)

+ 11 - 4
lib/campaign/CampaignState.cpp

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

+ 7 - 3
lib/campaign/CampaignState.h

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

+ 2 - 1
lib/serializer/ESerializationVersion.h

@@ -57,6 +57,7 @@ enum class ESerializationVersion : int32_t
 	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
 	CHRONICLES_SUPPORT, // 860 - support for heroes chronicles
+	CAMPAIGN_OUTRO_SUPPORT, // 861 - support for campaign outro video
 
-	CURRENT = CHRONICLES_SUPPORT
+	CURRENT = CAMPAIGN_OUTRO_SUPPORT
 };