瀏覽代碼

Merge pull request #4212 from alkazandzhiev/alkazandzhiev/saveMultiPlayerNames

Save all human player names in the configuration
Ivan Savenko 1 年之前
父節點
當前提交
398111f8d7
共有 3 個文件被更改,包括 59 次插入19 次删除
  1. 50 17
      client/mainmenu/CMainMenu.cpp
  2. 4 2
      client/mainmenu/CMainMenu.h
  3. 5 0
      config/schemas/settings.json

+ 50 - 17
client/mainmenu/CMainMenu.cpp

@@ -444,7 +444,7 @@ CMultiMode::CMultiMode(ESelectionScreen ScreenType)
 
 	statusBar = CGStatusBar::create(std::make_shared<CPicture>(background->getSurface(), Rect(7, 465, 440, 18), 7, 465));
 	playerName = std::make_shared<CTextInput>(Rect(19, 436, 334, 16), background->getSurface());
-	playerName->setText(getPlayerName());
+	playerName->setText(getPlayersNames()[0]);
 	playerName->setCallback(std::bind(&CMultiMode::onNameChange, this, _1));
 
 	buttonHotseat = std::make_shared<CButton>(Point(373, 78 + 57 * 0), AnimationPath::builtin("MUBHOT.DEF"), CGI->generaltexth->zelp[266], std::bind(&CMultiMode::hostTCP, this), EShortcut::MAIN_MENU_HOTSEAT);
@@ -466,22 +466,35 @@ void CMultiMode::hostTCP()
 {
 	auto savedScreenType = screenType;
 	close();
-	GH.windows().createAndPushWindow<CMultiPlayers>(getPlayerName(), savedScreenType, true, ELoadMode::MULTI);
+	GH.windows().createAndPushWindow<CMultiPlayers>(getPlayersNames(), savedScreenType, true, ELoadMode::MULTI);
 }
 
 void CMultiMode::joinTCP()
 {
 	auto savedScreenType = screenType;
 	close();
-	GH.windows().createAndPushWindow<CMultiPlayers>(getPlayerName(), savedScreenType, false, ELoadMode::MULTI);
+	GH.windows().createAndPushWindow<CMultiPlayers>(getPlayersNames(), savedScreenType, false, ELoadMode::MULTI);
 }
 
-std::string CMultiMode::getPlayerName()
+const std::vector<std::string> CMultiMode::getPlayersNames()
 {
-	std::string name = settings["general"]["playerName"].String();
-	if(name == "Player")
-		name = CGI->generaltexth->translate("core.genrltxt.434");
-	return name;
+	std::vector<std::string> playerNames;
+
+	std::string playerNameStr = settings["general"]["playerName"].String();
+	if (playerNameStr == "Player")
+		playerNameStr = CGI->generaltexth->translate("core.genrltxt.434");
+	playerNames.push_back(playerNameStr);
+
+	for (const auto & playerName : settings["general"]["multiPlayerNames"].Vector())
+	{
+		const std::string &nameStr = playerName.String();
+		if (!nameStr.empty())
+		{
+			playerNames.push_back(nameStr);
+		}
+	}
+
+	return playerNames;
 }
 
 void CMultiMode::onNameChange(std::string newText)
@@ -490,7 +503,7 @@ void CMultiMode::onNameChange(std::string newText)
 	name->String() = newText;
 }
 
-CMultiPlayers::CMultiPlayers(const std::string & firstPlayer, ESelectionScreen ScreenType, bool Host, ELoadMode LoadMode)
+CMultiPlayers::CMultiPlayers(const std::vector<std::string> & playerNames, ESelectionScreen ScreenType, bool Host, ELoadMode LoadMode)
 	: loadMode(LoadMode), screenType(ScreenType), host(Host)
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
@@ -511,7 +524,10 @@ CMultiPlayers::CMultiPlayers(const std::string & firstPlayer, ESelectionScreen S
 	buttonCancel = std::make_shared<CButton>(Point(205, 338), AnimationPath::builtin("MUBCANC.DEF"), CGI->generaltexth->zelp[561], [=](){ close();}, EShortcut::GLOBAL_CANCEL);
 	statusBar = CGStatusBar::create(std::make_shared<CPicture>(background->getSurface(), Rect(7, 381, 348, 18), 7, 381));
 
-	inputNames[0]->setText(firstPlayer);
+	for(int i = 0; i < playerNames.size(); i++)
+	{
+		inputNames[i]->setText(playerNames[i]);
+	}
 #ifndef VCMI_MOBILE
 	inputNames[0]->giveFocus();
 #endif
@@ -523,17 +539,34 @@ void CMultiPlayers::onChange(std::string newText)
 
 void CMultiPlayers::enterSelectionScreen()
 {
-	std::vector<std::string> names;
-	for(auto name : inputNames)
+	std::vector<std::string> playerNames;
+	for(auto playerName : inputNames)
 	{
-		if(name->getText().length())
-			names.push_back(name->getText());
+		if (playerName->getText().length())
+			playerNames.push_back(playerName->getText());
 	}
 
-	Settings name = settings.write["general"]["playerName"];
-	name->String() = names[0];
+	Settings playerName = settings.write["general"]["playerName"];
+	Settings multiPlayerNames = settings.write["general"]["multiPlayerNames"];
+	multiPlayerNames->Vector().clear();
+	if (!playerNames.empty())
+	{
+		playerName->String() = playerNames.front();
+		for (auto playerNameIt = playerNames.begin()+1; playerNameIt != playerNames.end(); playerNameIt++)
+		{
+			multiPlayerNames->Vector().push_back(JsonNode(*playerNameIt));
+		}
+	}
+	else
+	{
+		// Without the check the saving crashes directly.
+		// When empty reset the player's name. This would translate to it being
+		// the default for the next run. But enables deleting players, by just
+		// deleting the names, otherwise some UI element should have been added.
+		playerName->clear();
+	}
 
-	CMainMenu::openLobby(screenType, host, names, loadMode);
+	CMainMenu::openLobby(screenType, host, playerNames, loadMode);
 }
 
 CSimpleJoinScreen::CSimpleJoinScreen(bool host)

+ 4 - 2
client/mainmenu/CMainMenu.h

@@ -95,7 +95,9 @@ public:
 	void openLobby();
 	void hostTCP();
 	void joinTCP();
-	std::string getPlayerName();
+
+	/// Get all configured player names. The first name would always be present and initialized to its default value.
+	const std::vector<std::string> getPlayersNames();
 
 	void onNameChange(std::string newText);
 };
@@ -117,7 +119,7 @@ class CMultiPlayers : public WindowBase
 	void enterSelectionScreen();
 
 public:
-	CMultiPlayers(const std::string & firstPlayer, ESelectionScreen ScreenType, bool Host, ELoadMode LoadMode);
+	CMultiPlayers(const std::vector<std::string> & playerNames, ESelectionScreen ScreenType, bool Host, ELoadMode LoadMode);
 };
 
 /// Manages the configuration of pregame GUI elements like campaign screen, main menu, loading screen,...

+ 5 - 0
config/schemas/settings.json

@@ -19,6 +19,7 @@
 			"additionalProperties" : false,
 			"required" : [
 				"playerName",
+				"multiPlayerNames",
 				"music",
 				"sound",
 				"saveRandomMaps",
@@ -48,6 +49,10 @@
 					"type" : "string",
 					"default" : "Player"
 				},
+				"multiPlayerNames" : {
+					"type" : "array",
+					"default" : []
+				},
 				"music" : {
 					"type" : "number",
 					"default" : 88