瀏覽代碼

Merge remote-tracking branch 'origin/beta' into random_prison_distributor

Tomasz Zieliński 1 年之前
父節點
當前提交
ee6c331bad

+ 3 - 0
client/adventureMap/CInGameConsole.cpp

@@ -243,6 +243,9 @@ void CInGameConsole::startEnteringText()
 	if (!isActive())
 		return;
 
+	if(enteredText != "")
+		return;
+		
 	assert(currentStatusBar.expired());//effectively, nullptr check
 
 	currentStatusBar = GH.statusbar();

+ 7 - 7
client/lobby/OptionsTab.cpp

@@ -400,12 +400,11 @@ void OptionsTab::CPlayerOptionTooltipBox::genBonusWindow()
 	textBonusDescription = std::make_shared<CTextBox>(getDescription(), Rect(10, 100, pos.w - 20, 70), 0, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
 }
 
-OptionsTab::SelectionWindow::SelectionWindow(CPlayerSettingsHelper & helper, SelType _type)
-	: CWindowObject(BORDERED), CPlayerSettingsHelper(helper)
+OptionsTab::SelectionWindow::SelectionWindow(const PlayerColor & color, SelType _type)
+	: CWindowObject(BORDERED), color(color)
 {
 	addUsedEvents(LCLICK | SHOW_POPUP);
 
-	color = helper.playerSettings.color;
 	type = _type;
 
 	initialFaction = SEL->getStartInfo()->playerInfos.find(color)->second.castle;
@@ -481,9 +480,10 @@ void OptionsTab::SelectionWindow::setSelection()
 
 void OptionsTab::SelectionWindow::reopen()
 {
-	std::shared_ptr<SelectionWindow> window = std::shared_ptr<SelectionWindow>(new SelectionWindow(*this, type));
+	std::shared_ptr<SelectionWindow> window = std::shared_ptr<SelectionWindow>(new SelectionWindow(color, type));
 	close();
-	GH.windows().pushWindow(window);
+	if(CSH->isMyColor(color) || CSH->isHost())
+		GH.windows().pushWindow(window);
 }
 
 void OptionsTab::SelectionWindow::recreate()
@@ -632,7 +632,7 @@ void OptionsTab::SelectionWindow::genContentHeroes()
 
 void OptionsTab::SelectionWindow::genContentBonus()
 {
-	PlayerSettings set = PlayerSettings(playerSettings);
+	PlayerSettings set = SEL->getStartInfo()->playerInfos.find(color)->second;
 
 	int i = 0;
 	for(auto elem : allowedBonus)
@@ -819,7 +819,7 @@ void OptionsTab::SelectedBox::clickReleased(const Point & cursorPosition)
 		return;
 
 	GH.input().hapticFeedback();
-	GH.windows().createAndPushWindow<SelectionWindow>(*this, selectionType);
+	GH.windows().createAndPushWindow<SelectionWindow>(playerSettings.color, selectionType);
 }
 
 void OptionsTab::SelectedBox::scrollBy(int distance)

+ 2 - 2
client/lobby/OptionsTab.h

@@ -96,7 +96,7 @@ private:
 		CPlayerOptionTooltipBox(CPlayerSettingsHelper & helper);
 	};
 
-	class SelectionWindow : public CWindowObject, public CPlayerSettingsHelper
+	class SelectionWindow : public CWindowObject
 	{
 		//const int ICON_SMALL_WIDTH = 48;
 		const int ICON_SMALL_HEIGHT = 32;
@@ -148,7 +148,7 @@ private:
 	public:
 		void reopen();
 
-		SelectionWindow(CPlayerSettingsHelper & helper, SelType _type);
+		SelectionWindow(const PlayerColor & color, SelType _type);
 	};
 
 	/// Image with current town/hero/bonus

+ 19 - 1
lib/rmg/CMapGenOptions.cpp

@@ -388,6 +388,13 @@ void CMapGenOptions::setStartingTownForPlayer(const PlayerColor & color, Faction
 	it->second.setStartingTown(town);
 }
 
+void CMapGenOptions::setStartingHeroForPlayer(const PlayerColor & color, HeroTypeID hero)
+{
+	auto it = players.find(color);
+	assert(it != players.end());
+	it->second.setStartingHero(hero);
+}
+
 void CMapGenOptions::setPlayerTypeForStandardPlayer(const PlayerColor & color, EPlayerType playerType)
 {
 	// FIXME: Why actually not set it to COMP_ONLY? Ie. when swapping human to another color?
@@ -746,7 +753,7 @@ const CRmgTemplate * CMapGenOptions::getPossibleTemplate(CRandomGenerator & rand
 	return *RandomGeneratorUtil::nextItem(templates, rand);
 }
 
-CMapGenOptions::CPlayerSettings::CPlayerSettings() : color(0), startingTown(FactionID::RANDOM), playerType(EPlayerType::AI), team(TeamID::NO_TEAM)
+CMapGenOptions::CPlayerSettings::CPlayerSettings() : color(0), startingTown(FactionID::RANDOM), startingHero(HeroTypeID::RANDOM), playerType(EPlayerType::AI), team(TeamID::NO_TEAM)
 {
 
 }
@@ -778,6 +785,17 @@ void CMapGenOptions::CPlayerSettings::setStartingTown(FactionID value)
 	startingTown = value;
 }
 
+HeroTypeID CMapGenOptions::CPlayerSettings::getStartingHero() const
+{
+	return startingHero;
+}
+
+void CMapGenOptions::CPlayerSettings::setStartingHero(HeroTypeID value)
+{
+	assert(value == HeroTypeID::RANDOM || value.toEntity(VLC) != nullptr);
+	startingHero = value;
+}
+
 EPlayerType CMapGenOptions::CPlayerSettings::getPlayerType() const
 {
 	return playerType;

+ 11 - 0
lib/rmg/CMapGenOptions.h

@@ -45,6 +45,11 @@ public:
 		FactionID getStartingTown() const;
 		void setStartingTown(FactionID value);
 
+		/// The starting hero of the player ranging from 0 to hero max count or RANDOM_HERO.
+		/// The default value is RANDOM_HERO
+		HeroTypeID getStartingHero() const;
+		void setStartingHero(HeroTypeID value);
+
 		/// The default value is EPlayerType::AI.
 		EPlayerType getPlayerType() const;
 		void setPlayerType(EPlayerType value);
@@ -56,6 +61,7 @@ public:
 	private:
 		PlayerColor color;
 		FactionID startingTown;
+		HeroTypeID startingHero;
 		EPlayerType playerType;
 		TeamID team;
 
@@ -68,6 +74,10 @@ public:
 			h & playerType;
 			if(version >= 806)
 				h & team;
+			if (version >= 832)
+				h & startingHero;
+			else
+				startingHero = HeroTypeID::RANDOM;
 		}
 	};
 
@@ -120,6 +130,7 @@ public:
 	const std::map<PlayerColor, CPlayerSettings> & getPlayersSettings() const;
 	const std::map<PlayerColor, CPlayerSettings> & getSavedPlayersMap() const;
 	void setStartingTownForPlayer(const PlayerColor & color, FactionID town);
+	void setStartingHeroForPlayer(const PlayerColor & color, HeroTypeID hero);
 	/// Sets a player type for a standard player. A standard player is the opposite of a computer only player. The
 	/// values which can be chosen for the player type are EPlayerType::AI or EPlayerType::HUMAN.
 	void setPlayerTypeForStandardPlayer(const PlayerColor & color, EPlayerType playerType);

+ 17 - 5
lib/rmg/CMapGenerator.cpp

@@ -480,14 +480,26 @@ const std::vector<HeroTypeID> CMapGenerator::getAllPossibleHeroes() const
 	for (HeroTypeID hero : map->getMap(this).allowedHeroes)
 	{
 		auto * h = dynamic_cast<const CHero*>(VLC->heroTypes()->getById(hero));
-		if ((h->onlyOnWaterMap && !isWaterMap) || (h->onlyOnMapWithoutWater && isWaterMap))
-		{
+		if(h->onlyOnWaterMap && !isWaterMap)
 			continue;
-		}
-		else
+
+		if(h->onlyOnMapWithoutWater && isWaterMap)
+			continue;
+
+		bool heroUsedAsStarting = false;
+		for (auto const & player : map->getMapGenOptions().getPlayersSettings())
 		{
-			ret.push_back(hero);
+			if (player.second.getStartingHero() == hero)
+			{
+				heroUsedAsStarting = true;
+				break;
+			}
 		}
+
+		if (heroUsedAsStarting)
+			continue;
+
+		ret.push_back(hero);
 	}
 	return ret;
 }

+ 1 - 1
lib/serializer/CSerializer.h

@@ -14,7 +14,7 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
-const ui32 SERIALIZATION_VERSION = 831;
+const ui32 SERIALIZATION_VERSION = 832;
 const ui32 MINIMAL_SERIALIZATION_VERSION = 831;
 const std::string SAVEGAME_MAGIC = "VCMISVG";
 

+ 1 - 0
server/CVCMIServer.cpp

@@ -762,6 +762,7 @@ void CVCMIServer::updateAndPropagateLobbyState()
 		{
 			const auto & pset = psetPair.second;
 			si->mapGenOptions->setStartingTownForPlayer(pset.color, pset.castle);
+			si->mapGenOptions->setStartingHeroForPlayer(pset.color, pset.hero);
 			if(pset.isControlledByHuman())
 			{
 				si->mapGenOptions->setPlayerTypeForStandardPlayer(pset.color, EPlayerType::HUMAN);

+ 1 - 1
server/processors/PlayerMessageProcessor.cpp

@@ -384,7 +384,7 @@ void PlayerMessageProcessor::cheatPuzzleReveal(PlayerColor player)
 
 	for(auto & obj : gameHandler->gameState()->map->objects)
 	{
-		if(obj && obj->ID == Obj::OBELISK)
+		if(obj && obj->ID == Obj::OBELISK && !obj->wasVisited(player))
 		{
 			gameHandler->setObjPropertyID(obj->id, ObjProperty::OBELISK_VISITED, t->id);
 			for(const auto & color : t->players)