浏览代码

- Fixed starting another map from campaign bonus selection screen while playing a campaign mission

beegee1 12 年之前
父节点
当前提交
d1002f7e8f
共有 3 个文件被更改,包括 87 次插入37 次删除
  1. 12 11
      client/CMT.cpp
  2. 61 23
      client/CPreGame.cpp
  3. 14 3
      client/CPreGame.h

+ 12 - 11
client/CMT.cpp

@@ -89,6 +89,7 @@ void playIntro();
 static void listenForEvents();
 //void requestChangingResolution();
 void startGame(StartInfo * options, CConnection *serv = nullptr);
+void endGame();
 
 #ifndef _WIN32
 #ifndef _GNU_SOURCE
@@ -856,17 +857,6 @@ static void listenForEvents()
 		}
 		else if(ev.type == SDL_USEREVENT)
 		{
-			auto endGame = []
-			{
-				client->endGame();
-				vstd::clear_pointer(client);
-
-				delete CGI->dobjinfo.get();
-				const_cast<CGameInfo*>(CGI)->dobjinfo = new CDefObjInfoHandler; 
-
-				const_cast<CGameInfo*>(CGI)->modh->reload(); //add info about new creatures to dobjinfo
-			};
-
 			switch(ev.user.code)
 			{
 			case RETURN_TO_MAIN_MENU:
@@ -954,6 +944,17 @@ void startGame(StartInfo * options, CConnection *serv/* = nullptr*/)
 		client->connectionHandler = new boost::thread(&CClient::run, client);
 }
 
+void endGame()
+{
+	client->endGame();
+	vstd::clear_pointer(client);
+
+	delete CGI->dobjinfo.get();
+	const_cast<CGameInfo*>(CGI)->dobjinfo = new CDefObjInfoHandler;
+
+	const_cast<CGameInfo*>(CGI)->modh->reload(); //add info about new creatures to dobjinfo
+}
+
 void handleQuit()
 {
 	auto quitApplication = []()

+ 61 - 23
client/CPreGame.cpp

@@ -55,6 +55,7 @@
 namespace fs = boost::filesystem;
 
 void startGame(StartInfo * options, CConnection *serv = nullptr);
+void endGame();
 
 CGPreGame * CGP = nullptr;
 ISelectionScreenInfo *SEL;
@@ -440,15 +441,30 @@ void CreditsScreen::clickRight(tribool down, bool previousState)
 	menu->setActive(0);
 }
 
-CGPreGame::CGPreGame():
-	pregameConfig(new JsonNode(ResourceID("config/mainmenu.json")))
+CGPreGameConfig & CGPreGameConfig::get()
+{
+	static CGPreGameConfig config;
+	return config;
+}
+
+const JsonNode & CGPreGameConfig::getConfig() const
+{
+	return config;
+}
+
+CGPreGameConfig::CGPreGameConfig() : config(JsonNode(ResourceID("config/mainmenu.json")))
+{
+
+}
+
+CGPreGame::CGPreGame()
 {
 	pos.w = screen->w;
 	pos.h = screen->h;
 
 	GH.defActionsDef = 63;
 	CGP = this;
-	menu = new CMenuScreen((*pregameConfig)["window"]);
+	menu = new CMenuScreen(CGPreGameConfig::get().getConfig()["window"]);
 	loadGraphics();
 }
 
@@ -519,7 +535,7 @@ void CGPreGame::update()
 
 void CGPreGame::openCampaignScreen(std::string name)
 {
-	for(const JsonNode& node : (*pregameConfig)["campaignsset"].Vector())
+	for(const JsonNode& node : CGPreGameConfig::get().getConfig()["campaignsset"].Vector())
 	{
 		if (node["name"].String() == name)
 		{
@@ -582,7 +598,7 @@ CSelectionScreen::CSelectionScreen(CMenuScreen::EState Type, CMenuScreen::EMulti
 	{
 		bordered = true;
 		//load random background
-		const JsonVector & bgNames = (*CGP->pregameConfig)["game-select"].Vector();
+		const JsonVector & bgNames = CGPreGameConfig::get().getConfig()["game-select"].Vector();
 		bg = new CPicture(bgNames[rand() % bgNames.size()].String(), 0, 0);
 		pos = bg->center();
 	}
@@ -3594,35 +3610,52 @@ void CBonusSelection::updateCampaignState()
 
 void CBonusSelection::startMap()
 {
-	updateCampaignState();
-
-	logGlobal->infoStream() << "Starting scenario " << selectedMap;
-
-	const CCampaignScenario & scenario = ourCampaign->camp->scenarios[selectedMap];
 	auto si = new StartInfo(startInfo);
-	auto exitCb = [si]()
+	auto showPrologVideo = [=]()
 	{
-		CGP->showLoadingScreen(boost::bind(&startGame, si, (CConnection *)nullptr));
+		auto exitCb = [=]()
+		{
+			logGlobal->infoStream() << "Starting scenario " << selectedMap;
+			CGP->showLoadingScreen(boost::bind(&startGame, si, (CConnection *)nullptr));
+		};
+
+		const CCampaignScenario & scenario = ourCampaign->camp->scenarios[selectedMap];
+		if (scenario.prolog.hasPrologEpilog)
+		{
+			GH.pushInt(new CPrologEpilogVideo(scenario.prolog, exitCb));
+		}
+		else
+		{
+			exitCb();
+		}
 	};
 
-	if (scenario.prolog.hasPrologEpilog)
+	if(LOCPLINT) // we're currently ingame, so ask for starting new map and end game
 	{
-		GH.pushInt(new CPrologEpilogVideo(scenario.prolog, exitCb));
+		GH.popInt(this);
+		LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[67], [=]
+		{
+			updateCampaignState();
+			endGame();
+			GH.curInt = CGPreGame::create();
+			showPrologVideo();
+		}, 0);
 	}
 	else
 	{
-		exitCb();
+		updateCampaignState();
+		showPrologVideo();
 	}
 }
 
 void CBonusSelection::restartMap()
 {
-	updateCampaignState();
-	auto si = new StartInfo(startInfo); // copy before this object will be destroyed
-
-	GH.popIntTotally(this);
-	LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[67], [si]
+	GH.popInt(this);
+	LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[67], [=]
 	{
+		updateCampaignState();
+		auto si = new StartInfo(startInfo);
+
 		SDL_Event event;
 		event.type = SDL_USEREVENT;
 		event.user.code = PREPARE_RESTART_CAMPAIGN;
@@ -4089,11 +4122,16 @@ void CGPreGame::showLoadingScreen(std::function<void()> loader)
 
 std::string CLoadingScreen::getBackground()
 {
-	const JsonVector & conf = (*CGP->pregameConfig)["loading"].Vector();
+	const auto & conf = CGPreGameConfig::get().getConfig()["loading"].Vector();
 
-	if (conf.empty())
+	if(conf.empty())
+	{
 		return "loadbar";
-	return conf[ rand() % conf.size() ].String();
+	}
+	else
+	{
+		return conf[ rand() % conf.size() ].String();
+	}
 }
 
 CLoadingScreen::CLoadingScreen(std::function<void ()> loader):

+ 14 - 3
client/CPreGame.h

@@ -572,6 +572,19 @@ public:
 	void showAll(SDL_Surface *to);
 };
 
+/// Manages the configuration of pregame GUI elements like campaign screen, main menu, loading screen,...
+class CGPreGameConfig
+{
+public:
+	static CGPreGameConfig & get();
+	const JsonNode & getConfig() const;
+
+private:
+	CGPreGameConfig();
+
+	const JsonNode config;
+};
+
 /// Handles background screen, loads graphics for victory/loss condition and random town or hero selection
 class CGPreGame : public CIntObject, public IUpdateable
 {
@@ -581,9 +594,7 @@ class CGPreGame : public CIntObject, public IUpdateable
 	CGPreGame(); //Use createIfNotPresent
 
 public:
-	const JsonNode * const pregameConfig;
-
-	CMenuScreen* menu;
+	CMenuScreen * menu;
 
 	CDefHandler *victory, *loss;