2
0
Эх сурвалжийг харах

Remove pointers to hero instances from HeroPool class

Ivan Savenko 7 сар өмнө
parent
commit
d9aabb47e6

+ 2 - 2
lib/gameState/CGameState.cpp

@@ -142,7 +142,7 @@ int CGameState::getDate(Date mode) const
 CGameState::CGameState()
 {
 	gs = this;
-	heroesPool = std::make_unique<TavernHeroesPool>();
+	heroesPool = std::make_unique<TavernHeroesPool>(this);
 	globalEffects.setNodeType(CBonusSystemNode::GLOBAL_EFFECTS);
 }
 
@@ -638,7 +638,7 @@ void CGameState::initHeroes()
 		}
 
 		map->addToHeroPool(vhi);
-		heroesPool->addHeroToPool(vhi);
+		heroesPool->addHeroToPool(vhi->getHeroTypeID());
 	}
 
 	for(auto & elem : map->disposedHeroes)

+ 3 - 2
lib/gameState/CGameState.h

@@ -175,10 +175,11 @@ public:
 		h & map;
 		h & players;
 		h & teams;
-		h & heroesPool;
+		h & *heroesPool;
 		h & globalEffects;
 		h & currentRumor;
-		h & campaign;
+		if (campaign)
+			h & *campaign;
 		h & allocatedArtifacts;
 		h & statistic;
 

+ 0 - 1
lib/gameState/CGameStateCampaign.h

@@ -54,7 +54,6 @@ class CGameStateCampaign : public Serializeable
 	void giveCampaignBonusToHero(CGHeroInstance * hero);
 
 public:
-	CGameStateCampaign() = default;
 	CGameStateCampaign(CGameState * owner);
 
 	void placeCampaignHeroes();

+ 29 - 26
lib/gameState/TavernHeroesPool.cpp

@@ -10,19 +10,26 @@
 #include "StdInc.h"
 #include "TavernHeroesPool.h"
 
+#include "CGameState.h"
+
 #include "../mapObjects/CGHeroInstance.h"
+#include "../mapping/CMap.h"
 
 VCMI_LIB_NAMESPACE_BEGIN
 
+TavernHeroesPool::TavernHeroesPool(CGameState * owner)
+	: owner(owner)
+{}
+
 std::map<HeroTypeID, CGHeroInstance*> TavernHeroesPool::unusedHeroesFromPool() const
 {
 	std::map<HeroTypeID, CGHeroInstance*> pool;
 
 	for (const auto & hero : heroesPool)
-		pool[hero.first] = hero.second.get();
+		pool[hero] = owner->getMap().tryGetFromHeroPool(hero);
 
 	for(const auto & slot : currentTavern)
-		pool.erase(slot.hero->getHeroTypeID());
+		pool.erase(slot.hero);
 
 	return pool;
 }
@@ -31,7 +38,7 @@ TavernSlotRole TavernHeroesPool::getSlotRole(HeroTypeID hero) const
 {
 	for (auto const & slot : currentTavern)
 	{
-		if (slot.hero->getHeroTypeID() == hero)
+		if (slot.hero == hero)
 			return slot.role;
 	}
 	return TavernSlotRole::NONE;
@@ -46,7 +53,7 @@ void TavernHeroesPool::setHeroForPlayer(PlayerColor player, TavernHeroSlot slot,
 	if (hero == HeroTypeID::NONE)
 		return;
 
-	auto h = heroesPool[hero];
+	auto h = owner->getMap().tryGetFromHeroPool(hero);
 
 	if (h && army)
 		h->setToArmy(army);
@@ -58,7 +65,7 @@ void TavernHeroesPool::setHeroForPlayer(PlayerColor player, TavernHeroSlot slot,
 	}
 
 	TavernSlot newSlot;
-	newSlot.hero = h.get();
+	newSlot.hero = hero;
 	newSlot.player = player;
 	newSlot.role = role;
 	newSlot.slot = slot;
@@ -89,7 +96,7 @@ std::vector<const CGHeroInstance *> TavernHeroesPool::getHeroesFor(PlayerColor c
 	for(const auto & slot : currentTavern)
 	{
 		if (slot.player == color)
-			result.push_back(slot.hero);
+			result.push_back(owner->getMap().tryGetFromHeroPool(slot.hero));
 	}
 
 	return result;
@@ -97,45 +104,41 @@ std::vector<const CGHeroInstance *> TavernHeroesPool::getHeroesFor(PlayerColor c
 
 std::shared_ptr<CGHeroInstance> TavernHeroesPool::takeHeroFromPool(HeroTypeID hero)
 {
-	assert(heroesPool.count(hero));
-
-	auto result = heroesPool[hero];
-	heroesPool.erase(hero);
-
+	assert(vstd::contains(heroesPool, hero));
+	vstd::erase(heroesPool, hero);
 	vstd::erase_if(currentTavern, [&](const TavernSlot & entry){
-		return entry.hero->getHeroTypeID() == hero;
+		return entry.hero == hero;
 	});
 
-	assert(result);
-	return result;
+	return owner->getMap().tryTakeFromHeroPool(hero);;
 }
 
 void TavernHeroesPool::onNewDay()
 {
 	auto unusedHeroes = unusedHeroesFromPool();
 
-	for(auto & hero : heroesPool)
+	for(auto & heroID : heroesPool)
 	{
-		assert(hero.second);
-		if(!hero.second)
-			continue;
+		auto heroPtr = owner->getMap().tryGetFromHeroPool(heroID);
+		assert(heroPtr);
 
-		hero.second->removeBonusesRecursive(Bonus::OneDay);
-		hero.second->reduceBonusDurations(Bonus::NDays);
-		hero.second->reduceBonusDurations(Bonus::OneWeek);
+		heroPtr->removeBonusesRecursive(Bonus::OneDay);
+		heroPtr->reduceBonusDurations(Bonus::NDays);
+		heroPtr->reduceBonusDurations(Bonus::OneWeek);
 
 		// do not access heroes who are not present in tavern of any players
-		if (vstd::contains(unusedHeroes, hero.first))
+		if (vstd::contains(unusedHeroes, heroID))
 			continue;
 
-		hero.second->setMovementPoints(hero.second->movementPointsLimit(true));
-		hero.second->mana = hero.second->getManaNewTurn();
+		heroPtr->setMovementPoints(heroPtr->movementPointsLimit(true));
+		heroPtr->mana = heroPtr->getManaNewTurn();
 	}
 }
 
-void TavernHeroesPool::addHeroToPool(std::shared_ptr<CGHeroInstance> hero)
+void TavernHeroesPool::addHeroToPool(HeroTypeID hero)
 {
-	heroesPool[hero->getHeroTypeID()] = hero;
+	assert(!vstd::contains(heroesPool, hero));
+	heroesPool.push_back(hero);
 }
 
 void TavernHeroesPool::setAvailability(HeroTypeID hero, std::set<PlayerColor> mask)

+ 7 - 4
lib/gameState/TavernHeroesPool.h

@@ -13,7 +13,6 @@
 #include "TavernSlot.h"
 #include "../serializer/Serializeable.h"
 
-
 VCMI_LIB_NAMESPACE_BEGIN
 
 class CGHeroInstance;
@@ -24,9 +23,11 @@ class CSimpleArmy;
 
 class DLL_LINKAGE TavernHeroesPool : public Serializeable
 {
+	CGameState * owner;
+
 	struct TavernSlot
 	{
-		CGHeroInstance * hero;
+		HeroTypeID hero;
 		TavernHeroSlot slot;
 		TavernSlotRole role;
 		PlayerColor player;
@@ -41,7 +42,7 @@ class DLL_LINKAGE TavernHeroesPool : public Serializeable
 	};
 
 	/// list of all heroes in pool, including those currently present in taverns
-	std::map<HeroTypeID, std::shared_ptr<CGHeroInstance> > heroesPool;
+	std::vector<HeroTypeID> heroesPool;
 
 	/// list of which players are able to purchase specific hero
 	/// if hero is not present in list, he is available for everyone
@@ -51,6 +52,8 @@ class DLL_LINKAGE TavernHeroesPool : public Serializeable
 	std::vector<TavernSlot> currentTavern;
 
 public:
+	TavernHeroesPool(CGameState * owner);
+
 	/// Returns heroes currently available in tavern of a specific player
 	std::vector<const CGHeroInstance *> getHeroesFor(PlayerColor color) const;
 
@@ -67,7 +70,7 @@ public:
 	/// reset mana and movement points for all heroes in pool
 	void onNewDay();
 
-	void addHeroToPool(std::shared_ptr<CGHeroInstance> hero);
+	void addHeroToPool(HeroTypeID hero);
 
 	/// Marks hero as available to only specific set of players
 	void setAvailability(HeroTypeID hero, std::set<PlayerColor> mask);

+ 1 - 1
lib/networkPacks/NetPacksLib.cpp

@@ -1223,7 +1223,7 @@ void RemoveObject::applyGs(CGameState *gs)
 		}
 		//return hero to the pool, so he may reappear in tavern
 
-		gs->heroesPool->addHeroToPool(beatenHero);
+		gs->heroesPool->addHeroToPool(beatenHero->getHeroTypeID());
 
 		//If hero on Boat is removed, the Boat disappears
 		if(beatenHero->boat)