Browse Source

Moved most of town growth handling to NewTurnProcessor

Ivan Savenko 1 year ago
parent
commit
691a1a666d

+ 10 - 0
lib/constants/Enumerations.h

@@ -256,4 +256,14 @@ enum class EMapLevel : int8_t
 	UNDERGROUND = 1
 	UNDERGROUND = 1
 };
 };
 
 
+enum class EWeekType : int8_t
+{
+	FIRST_WEEK,
+	NORMAL,
+	DOUBLE_GROWTH,
+	BONUS_GROWTH,
+	DEITYOFFIRE,
+	PLAGUE
+};
+
 VCMI_LIB_NAMESPACE_END
 VCMI_LIB_NAMESPACE_END

+ 2 - 2
lib/networkPacks/NetPacksLib.cpp

@@ -1922,8 +1922,8 @@ void NewTurn::applyGs(CGameState *gs)
 		gs->getPlayerState(entry.first)->resources.amin(GameConstants::PLAYER_RESOURCES_CAP);
 		gs->getPlayerState(entry.first)->resources.amin(GameConstants::PLAYER_RESOURCES_CAP);
 	}
 	}
 
 
-	for(auto & creatureSet : cres) //set available creatures in towns
-		creatureSet.second.applyGs(gs);
+	for(auto & creatureSet : availableCreatures) //set available creatures in towns
+		creatureSet.applyGs(gs);
 
 
 	for(CGTownInstance* t : gs->map->towns)
 	for(CGTownInstance* t : gs->map->towns)
 		t->built = 0;
 		t->built = 0;

+ 3 - 5
lib/networkPacks/PacksForClient.h

@@ -1115,8 +1115,6 @@ struct DLL_LINKAGE HeroVisit : public CPackForClient
 
 
 struct DLL_LINKAGE NewTurn : public CPackForClient
 struct DLL_LINKAGE NewTurn : public CPackForClient
 {
 {
-	enum weekType { NORMAL, DOUBLE_GROWTH, BONUS_GROWTH, DEITYOFFIRE, PLAGUE, NO_ACTION };
-
 	void applyGs(CGameState * gs) override;
 	void applyGs(CGameState * gs) override;
 
 
 	void visitTyped(ICPackVisitor & visitor) override;
 	void visitTyped(ICPackVisitor & visitor) override;
@@ -1136,10 +1134,10 @@ struct DLL_LINKAGE NewTurn : public CPackForClient
 	};
 	};
 
 
 	std::set<Hero> heroes; //updates movement and mana points
 	std::set<Hero> heroes; //updates movement and mana points
-	std::map<ObjectInstanceID, SetAvailableCreatures> cres;//creatures to be placed in towns
+	std::vector<SetAvailableCreatures> availableCreatures;//creatures to be placed in towns
 	std::map<PlayerColor, ResourceSet> playerIncome; //player ID => resource value[res_id]
 	std::map<PlayerColor, ResourceSet> playerIncome; //player ID => resource value[res_id]
 	ui32 day = 0;
 	ui32 day = 0;
-	ui8 specialWeek = 0; //weekType
+	EWeekType specialWeek = EWeekType::NORMAL;
 	CreatureID creatureid; //for creature weeks
 	CreatureID creatureid; //for creature weeks
 	std::optional<RumorState> newRumor; // only on new weeks
 	std::optional<RumorState> newRumor; // only on new weeks
 
 
@@ -1148,7 +1146,7 @@ struct DLL_LINKAGE NewTurn : public CPackForClient
 	template <typename Handler> void serialize(Handler & h)
 	template <typename Handler> void serialize(Handler & h)
 	{
 	{
 		h & heroes;
 		h & heroes;
-		h & cres;
+		h & availableCreatures;
 		h & playerIncome;
 		h & playerIncome;
 		h & day;
 		h & day;
 		h & specialWeek;
 		h & specialWeek;

+ 22 - 54
server/CGameHandler.cpp

@@ -609,7 +609,7 @@ void CGameHandler::onNewTurn()
 {
 {
 	logGlobal->trace("Turn %d", gs->day+1);
 	logGlobal->trace("Turn %d", gs->day+1);
 	NewTurn n;
 	NewTurn n;
-	n.specialWeek = NewTurn::NO_ACTION;
+	n.specialWeek = EWeekType::FIRST_WEEK;
 	n.creatureid = CreatureID::NONE;
 	n.creatureid = CreatureID::NONE;
 	n.day = gs->day + 1;
 	n.day = gs->day + 1;
 
 
@@ -651,7 +651,7 @@ void CGameHandler::onNewTurn()
 
 
 	if (newWeek && !firstTurn)
 	if (newWeek && !firstTurn)
 	{
 	{
-		n.specialWeek = NewTurn::NORMAL;
+		n.specialWeek = EWeekType::NORMAL;
 		bool deityOfFireBuilt = false;
 		bool deityOfFireBuilt = false;
 		for (const CGTownInstance *t : gs->map->towns)
 		for (const CGTownInstance *t : gs->map->towns)
 		{
 		{
@@ -664,7 +664,7 @@ void CGameHandler::onNewTurn()
 
 
 		if (deityOfFireBuilt)
 		if (deityOfFireBuilt)
 		{
 		{
-			n.specialWeek = NewTurn::DEITYOFFIRE;
+			n.specialWeek = EWeekType::DEITYOFFIRE;
 			n.creatureid = CreatureID::IMP;
 			n.creatureid = CreatureID::IMP;
 		}
 		}
 		else if(VLC->settings()->getBoolean(EGameSettings::CREATURES_ALLOW_RANDOM_SPECIAL_WEEKS))
 		else if(VLC->settings()->getBoolean(EGameSettings::CREATURES_ALLOW_RANDOM_SPECIAL_WEEKS))
@@ -674,7 +674,7 @@ void CGameHandler::onNewTurn()
 			{
 			{
 				if (monthType < 40) //double growth
 				if (monthType < 40) //double growth
 				{
 				{
-					n.specialWeek = NewTurn::DOUBLE_GROWTH;
+					n.specialWeek = EWeekType::DOUBLE_GROWTH;
 					if (VLC->settings()->getBoolean(EGameSettings::CREATURES_ALLOW_ALL_FOR_DOUBLE_MONTH))
 					if (VLC->settings()->getBoolean(EGameSettings::CREATURES_ALLOW_ALL_FOR_DOUBLE_MONTH))
 					{
 					{
 						n.creatureid = VLC->creh->pickRandomMonster(getRandomGenerator());
 						n.creatureid = VLC->creh->pickRandomMonster(getRandomGenerator());
@@ -686,17 +686,17 @@ void CGameHandler::onNewTurn()
 					else
 					else
 					{
 					{
 						complain("Cannot find creature that can be spawned!");
 						complain("Cannot find creature that can be spawned!");
-						n.specialWeek = NewTurn::NORMAL;
+						n.specialWeek = EWeekType::NORMAL;
 					}
 					}
 				}
 				}
 				else if (monthType < 50)
 				else if (monthType < 50)
-					n.specialWeek = NewTurn::PLAGUE;
+					n.specialWeek = EWeekType::PLAGUE;
 			}
 			}
 			else //it's a week, but not full month
 			else //it's a week, but not full month
 			{
 			{
 				if (monthType < 25)
 				if (monthType < 25)
 				{
 				{
-					n.specialWeek = NewTurn::BONUS_GROWTH; //+5
+					n.specialWeek = EWeekType::BONUS_GROWTH; //+5
 					std::pair<int, CreatureID> newMonster(54, CreatureID());
 					std::pair<int, CreatureID> newMonster(54, CreatureID());
 					do
 					do
 					{
 					{
@@ -739,52 +739,20 @@ void CGameHandler::onNewTurn()
 			n.heroes.insert(hth);
 			n.heroes.insert(hth);
 		}
 		}
 	}
 	}
-	for (CGTownInstance *t : gs->map->towns)
+
+	if (newWeek)
 	{
 	{
-		PlayerColor player = t->tempOwner;
-		if (newWeek) //first day of week
-		{
+		for (CGTownInstance *t : gs->map->towns)
 			if (t->hasBuilt(BuildingSubID::PORTAL_OF_SUMMONING))
 			if (t->hasBuilt(BuildingSubID::PORTAL_OF_SUMMONING))
-				setPortalDwelling(t, true, (n.specialWeek == NewTurn::PLAGUE ? true : false)); //set creatures for Portal of Summoning
+				setPortalDwelling(t, true, (n.specialWeek == EWeekType::PLAGUE ? true : false)); //set creatures for Portal of Summoning
 
 
-			if (!vstd::contains(n.cres, t->id))
-			{
-				n.cres[t->id].tid = t->id;
-				n.cres[t->id].creatures = t->creatures;
-			}
-			auto & sac = n.cres.at(t->id);
-
-			for (int k=0; k < t->town->creatures.size(); k++) //creature growths
-			{
-				if (!t->creatures.at(k).second.empty()) // there are creatures at this level
-				{
-					ui32 &availableCount = sac.creatures.at(k).first;
-					const CCreature *cre = t->creatures.at(k).second.back().toCreature();
+		for (CGTownInstance *t : gs->map->towns)
+			n.availableCreatures.push_back(newTurnProcessor->generateTownGrowth(t, n.specialWeek, n.creatureid, firstTurn));
+	}
 
 
-					if (n.specialWeek == NewTurn::PLAGUE)
-						availableCount = t->creatures.at(k).first / 2; //halve their number, no growth
-					else
-					{
-						if (firstTurn) //first day of game: use only basic growths
-							availableCount = cre->getGrowth();
-						else
-							availableCount += t->creatureGrowth(k);
-
-						//Deity of fire week - upgrade both imps and upgrades
-						if (n.specialWeek == NewTurn::DEITYOFFIRE && vstd::contains(t->creatures.at(k).second, n.creatureid))
-							availableCount += 15;
-
-						if (cre->getId() == n.creatureid) //bonus week, effect applies only to identical creatures
-						{
-							if (n.specialWeek == NewTurn::DOUBLE_GROWTH)
-								availableCount *= 2;
-							else if (n.specialWeek == NewTurn::BONUS_GROWTH)
-								availableCount += 5;
-						}
-					}
-				}
-			}
-		}
+	for (CGTownInstance *t : gs->map->towns)
+	{
+		PlayerColor player = t->tempOwner;
 
 
 		if(t->hasBuilt(BuildingID::GRAIL)
 		if(t->hasBuilt(BuildingID::GRAIL)
 			&& t->town->buildings.at(BuildingID::GRAIL)->height == CBuilding::HEIGHT_SKYSHIP)
 			&& t->town->buildings.at(BuildingID::GRAIL)->height == CBuilding::HEIGHT_SKYSHIP)
@@ -835,7 +803,7 @@ void CGameHandler::onNewTurn()
 	if (newWeek)
 	if (newWeek)
 	{
 	{
 		//spawn wandering monsters
 		//spawn wandering monsters
-		if (newMonth && (n.specialWeek == NewTurn::DOUBLE_GROWTH || n.specialWeek == NewTurn::DEITYOFFIRE))
+		if (newMonth && (n.specialWeek == EWeekType::DOUBLE_GROWTH || n.specialWeek == EWeekType::DEITYOFFIRE))
 		{
 		{
 			spawnWanderingMonsters(n.creatureid);
 			spawnWanderingMonsters(n.creatureid);
 		}
 		}
@@ -846,20 +814,20 @@ void CGameHandler::onNewTurn()
 			InfoWindow iw;
 			InfoWindow iw;
 			switch (n.specialWeek)
 			switch (n.specialWeek)
 			{
 			{
-				case NewTurn::DOUBLE_GROWTH:
+				case EWeekType::DOUBLE_GROWTH:
 					iw.text.appendLocalString(EMetaText::ARRAY_TXT, 131);
 					iw.text.appendLocalString(EMetaText::ARRAY_TXT, 131);
 					iw.text.replaceNameSingular(n.creatureid);
 					iw.text.replaceNameSingular(n.creatureid);
 					iw.text.replaceNameSingular(n.creatureid);
 					iw.text.replaceNameSingular(n.creatureid);
 					break;
 					break;
-				case NewTurn::PLAGUE:
+				case EWeekType::PLAGUE:
 					iw.text.appendLocalString(EMetaText::ARRAY_TXT, 132);
 					iw.text.appendLocalString(EMetaText::ARRAY_TXT, 132);
 					break;
 					break;
-				case NewTurn::BONUS_GROWTH:
+				case EWeekType::BONUS_GROWTH:
 					iw.text.appendLocalString(EMetaText::ARRAY_TXT, 134);
 					iw.text.appendLocalString(EMetaText::ARRAY_TXT, 134);
 					iw.text.replaceNameSingular(n.creatureid);
 					iw.text.replaceNameSingular(n.creatureid);
 					iw.text.replaceNameSingular(n.creatureid);
 					iw.text.replaceNameSingular(n.creatureid);
 					break;
 					break;
-				case NewTurn::DEITYOFFIRE:
+				case EWeekType::DEITYOFFIRE:
 					iw.text.appendLocalString(EMetaText::ARRAY_TXT, 135);
 					iw.text.appendLocalString(EMetaText::ARRAY_TXT, 135);
 					iw.text.replaceNameSingular(CreatureID::IMP); //%s imp
 					iw.text.replaceNameSingular(CreatureID::IMP); //%s imp
 					iw.text.replaceNameSingular(CreatureID::IMP); //%s imp
 					iw.text.replaceNameSingular(CreatureID::IMP); //%s imp

+ 53 - 0
server/processors/NewTurnProcessor.cpp

@@ -151,3 +151,56 @@ ResourceSet NewTurnProcessor::generatePlayerIncome(PlayerColor playerID, bool ne
 
 
 	return incomeHandicapped;
 	return incomeHandicapped;
 }
 }
+
+SetAvailableCreatures NewTurnProcessor::generateTownGrowth(const CGTownInstance * t, EWeekType weekType, CreatureID creatureWeek, bool firstDay)
+{
+	SetAvailableCreatures sac;
+	PlayerColor player = t->tempOwner;
+
+	sac.tid = t->id;
+	sac.creatures = t->creatures;
+
+	for (int k=0; k < t->town->creatures.size(); k++)
+	{
+		if (t->creatures.at(k).second.empty())
+			continue;
+
+		uint32_t creaturesBefore = t->creatures.at(k).first;
+		uint32_t creatureGrowth = 0;
+		const CCreature *cre = t->creatures.at(k).second.back().toCreature();
+
+		if (firstDay)
+		{
+			creatureGrowth = cre->getGrowth();
+		}
+		else
+		{
+			creatureGrowth = t->creatureGrowth(k);
+
+			//Deity of fire week - upgrade both imps and upgrades
+			if (weekType == EWeekType::DEITYOFFIRE && vstd::contains(t->creatures.at(k).second, creatureWeek))
+				creatureGrowth += 15;
+
+			//bonus week, effect applies only to identical creatures
+			if (weekType == EWeekType::BONUS_GROWTH && cre->getId() == creatureWeek)
+				creatureGrowth += 5;
+		}
+
+		// Neutral towns have halved creature growth
+		if (!player.isValidPlayer())
+			creatureGrowth /= 2;
+
+		uint32_t resultingCreatures = 0;
+
+		if (weekType == EWeekType::PLAGUE)
+			resultingCreatures = creaturesBefore / 2;
+		else if (weekType == EWeekType::DOUBLE_GROWTH)
+			resultingCreatures = (creaturesBefore + creatureGrowth) * 2;
+		else
+			resultingCreatures = creaturesBefore + creatureGrowth;
+
+		sac.creatures.at(k).first = resultingCreatures;
+	}
+
+	return sac;
+}

+ 3 - 0
server/processors/NewTurnProcessor.h

@@ -10,10 +10,12 @@
 #pragma once
 #pragma once
 
 
 #include "../../lib/constants/EntityIdentifiers.h"
 #include "../../lib/constants/EntityIdentifiers.h"
+#include "../../lib/constants/Enumerations.h"
 
 
 VCMI_LIB_NAMESPACE_BEGIN
 VCMI_LIB_NAMESPACE_BEGIN
 class CGTownInstance;
 class CGTownInstance;
 class ResourceSet;
 class ResourceSet;
+struct SetAvailableCreatures;
 VCMI_LIB_NAMESPACE_END
 VCMI_LIB_NAMESPACE_END
 
 
 class CGameHandler;
 class CGameHandler;
@@ -25,6 +27,7 @@ public:
 	NewTurnProcessor(CGameHandler * gameHandler);
 	NewTurnProcessor(CGameHandler * gameHandler);
 
 
 	ResourceSet generatePlayerIncome(PlayerColor playerID, bool newWeek);
 	ResourceSet generatePlayerIncome(PlayerColor playerID, bool newWeek);
+	SetAvailableCreatures generateTownGrowth(const CGTownInstance * town, EWeekType weekType, CreatureID creatureWeek, bool firstDay);
 
 
 	void onPlayerTurnStarted(PlayerColor color);
 	void onPlayerTurnStarted(PlayerColor color);
 	void onPlayerTurnEnded(PlayerColor color);
 	void onPlayerTurnEnded(PlayerColor color);