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()
{
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)

View File

@@ -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;

View File

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

View File

@@ -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)

View File

@@ -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);

View File

@@ -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)