Laserlicht преди 1 година
родител
ревизия
8edf77afcc

+ 8 - 0
client/CServerHandler.cpp

@@ -497,6 +497,14 @@ void CServerHandler::setPlayerName(PlayerColor color, const std::string & name)
 	sendLobbyPack(lspn);
 }
 
+void CServerHandler::setPlayerHandicap(PlayerColor color, TResources handicap) const
+{
+	LobbySetPlayerHandicap lsph;
+	lsph.color = color;
+	lsph.handicap = handicap;
+	sendLobbyPack(lsph);
+}
+
 void CServerHandler::setPlayerOption(ui8 what, int32_t value, PlayerColor player) const
 {
 	LobbyChangePlayerOption lcpo;

+ 3 - 0
client/CServerHandler.h

@@ -13,6 +13,7 @@
 
 #include "../lib/network/NetworkInterface.h"
 #include "../lib/StartInfo.h"
+#include "../lib/ResourceSet.h"
 
 VCMI_LIB_NAMESPACE_BEGIN
 
@@ -81,6 +82,7 @@ public:
 	virtual void setMapInfo(std::shared_ptr<CMapInfo> to, std::shared_ptr<CMapGenOptions> mapGenOpts = {}) const = 0;
 	virtual void setPlayer(PlayerColor color) const = 0;
 	virtual void setPlayerName(PlayerColor color, const std::string & name) const = 0;
+	virtual void setPlayerHandicap(PlayerColor color, TResources handicap) const = 0;
 	virtual void setPlayerOption(ui8 what, int32_t value, PlayerColor player) const = 0;
 	virtual void setDifficulty(int to) const = 0;
 	virtual void setTurnTimerInfo(const TurnTimerInfo &) const = 0;
@@ -191,6 +193,7 @@ public:
 	void setMapInfo(std::shared_ptr<CMapInfo> to, std::shared_ptr<CMapGenOptions> mapGenOpts = {}) const override;
 	void setPlayer(PlayerColor color) const override;
 	void setPlayerName(PlayerColor color, const std::string & name) const override;
+	void setPlayerHandicap(PlayerColor color, TResources handicap) const override;
 	void setPlayerOption(ui8 what, int32_t value, PlayerColor player) const override;
 	void setDifficulty(int to) const override;
 	void setTurnTimerInfo(const TurnTimerInfo &) const override;

+ 4 - 0
client/lobby/OptionsTab.cpp

@@ -79,6 +79,10 @@ void OptionsTab::recreate()
 		entries.insert(std::make_pair(pInfo.first, std::make_shared<PlayerOptionsEntry>(pInfo.second, * this)));
 	}
 
+	/*TResources resources = TResources();
+	resources[EGameResID::GOLD] = 50000;
+	CSH->setPlayerHandicap((PlayerColor)0, resources);*/
+
 	OptionsTabBase::recreate();
 }
 

+ 1 - 1
lib/StartInfo.cpp

@@ -25,7 +25,7 @@
 VCMI_LIB_NAMESPACE_BEGIN
 
 PlayerSettings::PlayerSettings()
-	: bonus(PlayerStartingBonus::RANDOM), color(0), handicap(NO_HANDICAP), compOnly(false)
+	: bonus(PlayerStartingBonus::RANDOM), color(0), handicap(TResources()), compOnly(false)
 {
 }
 

+ 7 - 2
lib/StartInfo.h

@@ -16,6 +16,7 @@
 #include "ExtraOptionsInfo.h"
 #include "campaign/CampaignConstants.h"
 #include "serializer/Serializeable.h"
+#include "ResourceSet.h"
 
 VCMI_LIB_NAMESPACE_BEGIN
 
@@ -78,7 +79,8 @@ struct DLL_LINKAGE PlayerSettings
 	std::string heroNameTextId;
 	PlayerColor color; //from 0 -
 	enum EHandicap {NO_HANDICAP, MILD, SEVERE};
-	EHandicap handicap;//0-no, 1-mild, 2-severe
+	EHandicap handicapLegacy;//0-no, 1-mild, 2-severe
+	TResources handicap;
 
 	std::string name;
 	std::set<ui8> connectedPlayerIDs; //Empty - AI, or connectrd player ids
@@ -92,7 +94,10 @@ struct DLL_LINKAGE PlayerSettings
 		h & heroNameTextId;
 		h & bonus;
 		h & color;
-		h & handicap;
+		if (h.version >= Handler::Version::PLAYER_HANDICAP)
+			h & handicap;
+		else
+			h & handicapLegacy;
 		h & name;
 		h & connectedPlayerIDs;
 		h & compOnly;

+ 5 - 1
lib/gameState/CGameState.cpp

@@ -387,10 +387,14 @@ void CGameState::initDifficulty()
 	const JsonNode & difficultyAI(config["ai"][GameConstants::DIFFICULTY_NAMES[scenarioOps->difficulty]]);
 	const JsonNode & difficultyHuman(config["human"][GameConstants::DIFFICULTY_NAMES[scenarioOps->difficulty]]);
 	
-	auto setDifficulty = [](PlayerState & state, const JsonNode & json)
+	auto setDifficulty = [this](PlayerState & state, const JsonNode & json)
 	{
 		//set starting resources
 		state.resources = TResources(json["resources"]);
+
+		//handicap
+		const PlayerSettings &ps = scenarioOps->getIthPlayersSettings(state.color);
+		state.resources += ps.handicap;
 		
 		//set global bonuses
 		for(auto & jsonBonus : json["globalBonuses"].Vector())

+ 1 - 0
lib/networkPacks/NetPackVisitor.h

@@ -168,6 +168,7 @@ public:
 	virtual void visitLobbyChangePlayerOption(LobbyChangePlayerOption & pack) {}
 	virtual void visitLobbySetPlayer(LobbySetPlayer & pack) {}
 	virtual void visitLobbySetPlayerName(LobbySetPlayerName & pack) {}
+	virtual void visitLobbySetPlayerHandicap(LobbySetPlayerHandicap & pack) {}
 	virtual void visitLobbySetSimturns(LobbySetSimturns & pack) {}
 	virtual void visitLobbySetTurnTime(LobbySetTurnTime & pack) {}
 	virtual void visitLobbySetExtraOptions(LobbySetExtraOptions & pack) {}

+ 5 - 0
lib/networkPacks/NetPacksLib.cpp

@@ -790,6 +790,11 @@ void LobbySetPlayerName::visitTyped(ICPackVisitor & visitor)
 	visitor.visitLobbySetPlayerName(*this);
 }
 
+void LobbySetPlayerHandicap::visitTyped(ICPackVisitor & visitor)
+{
+	visitor.visitLobbySetPlayerHandicap(*this);
+}
+
 void LobbySetSimturns::visitTyped(ICPackVisitor & visitor)
 {
 	visitor.visitLobbySetSimturns(*this);

+ 14 - 0
lib/networkPacks/PacksForLobby.h

@@ -281,6 +281,20 @@ struct DLL_LINKAGE LobbySetPlayerName : public CLobbyPackToServer
 	}
 };
 
+struct DLL_LINKAGE LobbySetPlayerHandicap : public CLobbyPackToServer
+{
+	PlayerColor color = PlayerColor::CANNOT_DETERMINE;
+	TResources handicap = TResources();
+
+	void visitTyped(ICPackVisitor & visitor) override;
+
+	template <typename Handler> void serialize(Handler &h)
+	{
+		h & color;
+		h & handicap;
+	}
+};
+
 struct DLL_LINKAGE LobbySetSimturns : public CLobbyPackToServer
 {
 	SimturnsInfo simturnsInfo;

+ 1 - 0
lib/registerTypes/RegisterTypesLobbyPacks.h

@@ -55,6 +55,7 @@ void registerTypesLobbyPacks(Serializer &s)
 	s.template registerType<CLobbyPackToServer, LobbySetCampaignBonus>();
 	s.template registerType<CLobbyPackToServer, LobbySetPlayer>();
 	s.template registerType<CLobbyPackToServer, LobbySetPlayerName>();
+	s.template registerType<CLobbyPackToServer, LobbySetPlayerHandicap>();
 	s.template registerType<CLobbyPackToServer, LobbySetTurnTime>();
 	s.template registerType<CLobbyPackToServer, LobbySetSimturns>();
 	s.template registerType<CLobbyPackToServer, LobbySetDifficulty>();

+ 2 - 1
lib/serializer/ESerializationVersion.h

@@ -57,6 +57,7 @@ enum class ESerializationVersion : int32_t
 	SIMPLE_TEXT_CONTAINER_SERIALIZATION, // 847 - text container is serialized using common routine instead of custom approach
 	MAP_FORMAT_ADDITIONAL_INFOS, // 848 - serialize new infos in map format
 	REMOVE_LIB_RNG, // 849 - removed random number generators from library classes
+	PLAYER_HANDICAP, // 850 - player handicap selection at game start
 
-	CURRENT = REMOVE_LIB_RNG
+	CURRENT = PLAYER_HANDICAP
 };

+ 18 - 0
server/CVCMIServer.cpp

@@ -765,6 +765,24 @@ void CVCMIServer::setPlayerName(PlayerColor color, std::string name)
 	setPlayerConnectedId(player, nameID);
 }
 
+void CVCMIServer::setPlayerHandicap(PlayerColor color, TResources handicap)
+{
+	if(color == PlayerColor::CANNOT_DETERMINE)
+		return;
+
+	si->playerInfos[color].handicap = handicap;
+
+	int humanPlayer = 0;
+	for (const auto & pi : si->playerInfos)
+		if(pi.second.isControlledByHuman())
+			humanPlayer++;
+
+	if(humanPlayer < 2) // Singleplayer
+		return;
+
+	announceTxt("Handicap " + color.toString() + ": \n   " + handicap.toString());
+}
+
 void CVCMIServer::optionNextCastle(PlayerColor player, int dir)
 {
 	PlayerSettings & s = si->playerInfos[player];

+ 2 - 0
server/CVCMIServer.h

@@ -11,6 +11,7 @@
 
 #include "../lib/network/NetworkInterface.h"
 #include "../lib/StartInfo.h"
+#include "../lib/ResourceSet.h"
 
 VCMI_LIB_NAMESPACE_BEGIN
 
@@ -117,6 +118,7 @@ public:
 	// Work with LobbyInfo
 	void setPlayer(PlayerColor clickedColor);
 	void setPlayerName(PlayerColor player, std::string name);
+	void setPlayerHandicap(PlayerColor player, TResources handicap);
 	void optionNextHero(PlayerColor player, int dir); //dir == -1 or +1
 	void optionSetHero(PlayerColor player, HeroTypeID id);
 	HeroTypeID nextAllowedHero(PlayerColor player, HeroTypeID id, int direction);

+ 1 - 0
server/LobbyNetPackVisitors.h

@@ -89,6 +89,7 @@ public:
 	void visitLobbyChangePlayerOption(LobbyChangePlayerOption & pack) override;
 	void visitLobbySetPlayer(LobbySetPlayer & pack) override;
 	void visitLobbySetPlayerName(LobbySetPlayerName & pack) override;
+	void visitLobbySetPlayerHandicap(LobbySetPlayerHandicap & pack) override;
 	void visitLobbySetTurnTime(LobbySetTurnTime & pack) override;
 	void visitLobbySetExtraOptions(LobbySetExtraOptions & pack) override;
 	void visitLobbySetSimturns(LobbySetSimturns & pack) override;

+ 6 - 0
server/NetPacksLobbyServer.cpp

@@ -346,6 +346,12 @@ void ApplyOnServerNetPackVisitor::visitLobbySetPlayerName(LobbySetPlayerName & p
 	result = true;
 }
 
+void ApplyOnServerNetPackVisitor::visitLobbySetPlayerHandicap(LobbySetPlayerHandicap & pack)
+{
+	srv.setPlayerHandicap(pack.color, pack.handicap);
+	result = true;
+}
+
 void ApplyOnServerNetPackVisitor::visitLobbySetSimturns(LobbySetSimturns & pack)
 {
 	srv.si->simturnsInfo = pack.simturnsInfo;