1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-06 09:09:40 +02:00

Remove pointers to hero instances from HeroPool class

This commit is contained in:
Ivan Savenko
2025-03-18 10:58:55 +00:00
parent 71bc1054d0
commit d9aabb47e6
6 changed files with 42 additions and 36 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1223,7 +1223,7 @@ void RemoveObject::applyGs(CGameState *gs)
} }
//return hero to the pool, so he may reappear in tavern //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 hero on Boat is removed, the Boat disappears
if(beatenHero->boat) if(beatenHero->boat)