Browse Source

Moved generation of new rumors to server

Ivan Savenko 1 year ago
parent
commit
5178e4842e

+ 3 - 3
lib/CGameInfoCallback.cpp

@@ -658,11 +658,11 @@ std::string CGameInfoCallback::getTavernRumor(const CGObjectInstance * townOrTav
 	text.appendLocalString(EMetaText::GENERAL_TXT, 216);
 	
 	std::string extraText;
-	if(gs->rumor.type == RumorState::TYPE_NONE)
+	if(gs->currentRumor.type == RumorState::TYPE_NONE)
 		return text.toString();
 
-	auto rumor = gs->rumor.last[gs->rumor.type];
-	switch(gs->rumor.type)
+	auto rumor = gs->currentRumor.last[gs->currentRumor.type];
+	switch(gs->currentRumor.type)
 	{
 	case RumorState::TYPE_SPECIAL:
 		text.replaceLocalString(EMetaText::GENERAL_TXT, rumor.first);

+ 2 - 0
lib/CMakeLists.txt

@@ -93,6 +93,7 @@ set(lib_MAIN_SRCS
 	gameState/CGameState.cpp
 	gameState/CGameStateCampaign.cpp
 	gameState/InfoAboutArmy.cpp
+	gameState/RumorState.cpp
 	gameState/TavernHeroesPool.cpp
 
 	mapObjectConstructors/AObjectTypeHandler.cpp
@@ -448,6 +449,7 @@ set(lib_MAIN_HEADERS
 	gameState/CGameStateCampaign.h
 	gameState/EVictoryLossCheckResult.h
 	gameState/InfoAboutArmy.h
+	gameState/RumorState.h
 	gameState/SThievesGuildInfo.h
 	gameState/TavernHeroesPool.h
 	gameState/TavernSlot.h

+ 10 - 22
lib/gameState/CGameState.cpp

@@ -1213,8 +1213,10 @@ int3 CGameState::guardingCreaturePosition (int3 pos) const
 	return gs->map->guardingCreaturePositions[pos.z][pos.x][pos.y];
 }
 
-void CGameState::updateRumor()
+RumorState CGameState::pickNewRumor()
 {
+	RumorState newRumor;
+
 	static const std::vector<RumorState::ERumorType> rumorTypes = {RumorState::TYPE_MAP, RumorState::TYPE_SPECIAL, RumorState::TYPE_RAND, RumorState::TYPE_RAND};
 	std::vector<RumorState::ERumorTypeSpecial> sRumorTypes = {
 		RumorState::RUMOR_OBELISKS, RumorState::RUMOR_ARTIFACTS, RumorState::RUMOR_ARMY, RumorState::RUMOR_INCOME};
@@ -1224,11 +1226,11 @@ void CGameState::updateRumor()
 	int rumorId = -1;
 	int rumorExtra = -1;
 	auto & rand = getRandomGenerator();
-	rumor.type = *RandomGeneratorUtil::nextItem(rumorTypes, rand);
+	newRumor.type = *RandomGeneratorUtil::nextItem(rumorTypes, rand);
 
 	do
 	{
-		switch(rumor.type)
+		switch(newRumor.type)
 		{
 		case RumorState::TYPE_SPECIAL:
 		{
@@ -1266,13 +1268,13 @@ void CGameState::updateRumor()
 		}
 		case RumorState::TYPE_MAP:
 			// Makes sure that map rumors only used if there enough rumors too choose from
-			if(!map->rumors.empty() && (map->rumors.size() > 1 || !rumor.last.count(RumorState::TYPE_MAP)))
+			if(!map->rumors.empty() && (map->rumors.size() > 1 || !currentRumor.last.count(RumorState::TYPE_MAP)))
 			{
 				rumorId = rand.nextInt((int)map->rumors.size() - 1);
 				break;
 			}
 			else
-				rumor.type = RumorState::TYPE_RAND;
+				newRumor.type = RumorState::TYPE_RAND;
 			[[fallthrough]];
 
 		case RumorState::TYPE_RAND:
@@ -1282,7 +1284,9 @@ void CGameState::updateRumor()
 			break;
 		}
 	}
-	while(!rumor.update(rumorId, rumorExtra));
+	while(!newRumor.update(rumorId, rumorExtra));
+
+	return newRumor;
 }
 
 bool CGameState::isVisible(int3 pos, const std::optional<PlayerColor> & player) const
@@ -1906,23 +1910,7 @@ CGHeroInstance * CGameState::getUsedHero(const HeroTypeID & hid) const
 	return nullptr;
 }
 
-bool RumorState::update(int id, int extra)
-{
-	if(vstd::contains(last, type))
-	{
-		if(last[type].first != id)
-		{
-			last[type].first = id;
-			last[type].second = extra;
-		}
-		else
-			return false;
-	}
-	else
-		last[type] = std::make_pair(id, extra);
 
-	return true;
-}
 
 TeamState::TeamState()
 {

+ 5 - 32
lib/gameState/CGameState.h

@@ -14,6 +14,8 @@
 #include "../LoadProgress.h"
 #include "../ConstTransitivePtr.h"
 
+#include "RumorState.h"
+
 namespace boost
 {
 class shared_mutex;
@@ -38,35 +40,6 @@ class CRandomGenerator;
 template<typename T> class CApplier;
 class CBaseForGSApply;
 
-struct DLL_LINKAGE RumorState
-{
-	enum ERumorType : ui8
-	{
-		TYPE_NONE = 0, TYPE_RAND, TYPE_SPECIAL, TYPE_MAP
-	};
-
-	enum ERumorTypeSpecial : ui8
-	{
-		RUMOR_OBELISKS = 208,
-		RUMOR_ARTIFACTS = 209,
-		RUMOR_ARMY = 210,
-		RUMOR_INCOME = 211,
-		RUMOR_GRAIL = 212
-	};
-
-	ERumorType type;
-	std::map<ERumorType, std::pair<int, int>> last;
-
-	RumorState(){type = TYPE_NONE;};
-	bool update(int id, int extra);
-
-	template <typename Handler> void serialize(Handler &h)
-	{
-		h & type;
-		h & last;
-	}
-};
-
 struct UpgradeInfo
 {
 	CreatureID oldID; //creature to be upgraded
@@ -115,7 +88,7 @@ public:
 	std::map<PlayerColor, PlayerState> players;
 	std::map<TeamID, TeamState> teams;
 	CBonusSystemNode globalEffects;
-	RumorState rumor;
+	RumorState currentRumor;
 
 	static boost::shared_mutex mutex;
 
@@ -135,7 +108,7 @@ public:
 	void calculatePaths(const std::shared_ptr<PathfinderConfig> & config) override;
 	int3 guardingCreaturePosition (int3 pos) const override;
 	std::vector<CGObjectInstance*> guardingCreatures (int3 pos) const;
-	void updateRumor();
+	RumorState pickNewRumor();
 
 	/// Gets a artifact ID randomly and removes the selected artifact from this handler.
 	ArtifactID pickRandomArtifact(vstd::RNG & rand, int flags);
@@ -191,7 +164,7 @@ public:
 			std::string oldStateOfRNG;
 			h & oldStateOfRNG;
 		}
-		h & rumor;
+		h & currentRumor;
 		h & campaign;
 		h & allocatedArtifacts;
 

+ 29 - 0
lib/gameState/RumorState.cpp

@@ -0,0 +1,29 @@
+/*
+ * RumorState.cpp, part of VCMI engine
+ *
+ * Authors: listed in file AUTHORS in main folder
+ *
+ * License: GNU General Public License v2.0 or later
+ * Full text of license available in license.txt file, in main folder
+ *
+ */
+#include "StdInc.h"
+#include "RumorState.h"
+
+bool RumorState::update(int id, int extra)
+{
+	if(vstd::contains(last, type))
+	{
+		if(last[type].first != id)
+		{
+			last[type].first = id;
+			last[type].second = extra;
+		}
+		else
+			return false;
+	}
+	else
+		last[type] = std::make_pair(id, extra);
+
+	return true;
+}

+ 43 - 0
lib/gameState/RumorState.h

@@ -0,0 +1,43 @@
+/*
+ * RumorState.h, part of VCMI engine
+ *
+ * Authors: listed in file AUTHORS in main folder
+ *
+ * License: GNU General Public License v2.0 or later
+ * Full text of license available in license.txt file, in main folder
+ *
+ */
+#pragma once
+
+VCMI_LIB_NAMESPACE_BEGIN
+
+struct DLL_LINKAGE RumorState
+{
+	enum ERumorType : ui8
+	{
+		TYPE_NONE = 0, TYPE_RAND, TYPE_SPECIAL, TYPE_MAP
+	};
+
+	enum ERumorTypeSpecial : ui8
+	{
+		RUMOR_OBELISKS = 208,
+		RUMOR_ARTIFACTS = 209,
+		RUMOR_ARMY = 210,
+		RUMOR_INCOME = 211,
+		RUMOR_GRAIL = 212
+	};
+
+	ERumorType type;
+	std::map<ERumorType, std::pair<int, int>> last;
+
+	RumorState(){type = TYPE_NONE;};
+	bool update(int id, int extra);
+
+	template <typename Handler> void serialize(Handler &h)
+	{
+		h & type;
+		h & last;
+	}
+};
+
+VCMI_LIB_NAMESPACE_END

+ 2 - 2
lib/networkPacks/NetPacksLib.cpp

@@ -1984,8 +1984,8 @@ void NewTurn::applyGs(CGameState *gs)
 	for(CGTownInstance* t : gs->map->towns)
 		t->built = 0;
 
-	if(gs->getDate(Date::DAY_OF_WEEK) == 1)
-		gs->updateRumor();
+	if(newRumor)
+		gs->currentRumor = *newRumor;
 }
 
 void SetObjectProperty::applyGs(CGameState * gs) const

+ 3 - 0
lib/networkPacks/PacksForClient.h

@@ -22,6 +22,7 @@
 #include "../ResourceSet.h"
 #include "../TurnTimerInfo.h"
 #include "../gameState/EVictoryLossCheckResult.h"
+#include "../gameState/RumorState.h"
 #include "../gameState/QuestInfo.h"
 #include "../gameState/TavernSlot.h"
 #include "../int3.h"
@@ -1169,6 +1170,7 @@ struct DLL_LINKAGE NewTurn : public CPackForClient
 	ui32 day = 0;
 	ui8 specialWeek = 0; //weekType
 	CreatureID creatureid; //for creature weeks
+	std::optional<RumorState> newRumor; // only on new weeks
 
 	NewTurn() = default;
 
@@ -1180,6 +1182,7 @@ struct DLL_LINKAGE NewTurn : public CPackForClient
 		h & day;
 		h & specialWeek;
 		h & creatureid;
+		h & newRumor;
 	}
 };
 

+ 3 - 0
server/CGameHandler.cpp

@@ -908,6 +908,9 @@ void CGameHandler::onNewTurn()
 		}
 	}
 
+	if (newWeek)
+		n.newRumor = gameState()->pickNewRumor();
+
 	if (newMonth)
 	{
 		SetAvailableArtifacts saa;