1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-23 22:37:55 +02:00

Remove ConstTransitivePtr from hero and town instances

This commit is contained in:
Ivan Savenko
2025-03-09 21:51:33 +00:00
parent 62234fcf92
commit 417ea6451a
57 changed files with 436 additions and 390 deletions

View File

@@ -59,13 +59,13 @@ void CGTownInstance::setPropertyDer(ObjProperty what, ObjPropertyID identifier)
switch (what)
{
case ObjProperty::STRUCTURE_ADD_VISITING_HERO:
rewardableBuildings.at(identifier.getNum())->setProperty(ObjProperty::VISITORS, visitingHero->id);
rewardableBuildings.at(identifier.getNum())->setProperty(ObjProperty::VISITORS, getVisitingHero()->id);
break;
case ObjProperty::STRUCTURE_CLEAR_VISITORS:
rewardableBuildings.at(identifier.getNum())->setProperty(ObjProperty::STRUCTURE_CLEAR_VISITORS, NumericID(0));
break;
case ObjProperty::STRUCTURE_ADD_GARRISONED_HERO: //add garrisoned hero to visitors
rewardableBuildings.at(identifier.getNum())->setProperty(ObjProperty::VISITORS, garrisonHero->id);
rewardableBuildings.at(identifier.getNum())->setProperty(ObjProperty::VISITORS, getGarrisonHero()->id);
break;
case ObjProperty::BONUS_VALUE_FIRST:
bonusValue.first = identifier.getNum();
@@ -296,7 +296,7 @@ int CGTownInstance::spellsAtLevel(int level, bool checkGuild) const
bool CGTownInstance::needsLastStack() const
{
return garrisonHero != nullptr;
return getGarrisonHero() != nullptr;
}
void CGTownInstance::setOwner(const PlayerColor & player) const
@@ -309,13 +309,13 @@ void CGTownInstance::onHeroVisit(const CGHeroInstance * h) const
{
if(cb->gameState()->getPlayerRelations( getOwner(), h->getOwner() ) == PlayerRelations::ENEMIES)
{
if(armedGarrison() || visitingHero)
if(armedGarrison() || getVisitingHero())
{
const CGHeroInstance * defendingHero = visitingHero ? visitingHero : garrisonHero;
const CGHeroInstance * defendingHero = getVisitingHero() ? getVisitingHero() : getGarrisonHero();
const CArmedInstance * defendingArmy = defendingHero ? (CArmedInstance *)defendingHero : this;
const bool isBattleOutside = isBattleOutsideTown(defendingHero);
if(!isBattleOutside && visitingHero && defendingHero == visitingHero)
if(!isBattleOutside && getVisitingHero() && defendingHero == getVisitingHero())
{
//we have two approaches to merge armies: mergeGarrisonOnSiege() and used in the CGameHandler::garrisonSwap(ObjectInstanceID tid)
auto * nodeSiege = defendingHero->whereShouldBeAttachedOnSiege(isBattleOutside);
@@ -323,7 +323,7 @@ void CGTownInstance::onHeroVisit(const CGHeroInstance * h) const
if(nodeSiege == (CBonusSystemNode *)this)
cb->swapGarrisonOnSiege(this->id);
const_cast<CGHeroInstance *>(defendingHero)->inTownGarrison = false; //hack to return visitor from garrison after battle
const_cast<CGHeroInstance *>(defendingHero)->setVisitedTown(this, false); //hack to return visitor from garrison after battle
}
cb->startBattle(h, defendingArmy, getSightCenter(), h, defendingHero, BattleLayout::createDefaultLayout(cb, h, defendingArmy), (isBattleOutside ? nullptr : this));
}
@@ -343,7 +343,7 @@ void CGTownInstance::onHeroVisit(const CGHeroInstance * h) const
else
{
assert(h->visitablePos() == this->visitablePos());
bool commander_recover = h->commander && !h->commander->alive;
bool commander_recover = h->getCommander() && !h->getCommander()->alive;
if (commander_recover) // rise commander from dead
{
SetCommanderProperty scp;
@@ -358,8 +358,8 @@ void CGTownInstance::onHeroVisit(const CGHeroInstance * h) const
{
InfoWindow iw;
iw.player = h->tempOwner;
iw.text.appendRawString(h->commander->getName());
iw.components.emplace_back(ComponentType::CREATURE, h->commander->getId(), h->commander->getCount());
iw.text.appendRawString(h->getCommander()->getName());
iw.components.emplace_back(ComponentType::CREATURE, h->getCommander()->getId(), h->getCommander()->getCount());
cb->showInfoDialog(&iw);
}
}
@@ -368,7 +368,7 @@ void CGTownInstance::onHeroVisit(const CGHeroInstance * h) const
void CGTownInstance::onHeroLeave(const CGHeroInstance * h) const
{
//FIXME: find out why this issue appears on random maps
if(visitingHero == h)
if(getVisitingHero() == h)
{
cb->stopHeroVisitCastle(this, h);
logGlobal->trace("%s correctly left town %s", h->getNameTranslated(), getNameTranslated());
@@ -584,13 +584,13 @@ void CGTownInstance::mergeGarrisonOnSiege() const
auto getWeakestStackSlot = [&](ui64 powerLimit)
{
std::vector<SlotID> weakSlots;
auto stacksList = visitingHero->stacks;
auto stacksList = getVisitingHero()->stacks;
std::pair<SlotID, CStackInstance *> pair;
while(!stacksList.empty())
{
pair = *vstd::minElementByFun(stacksList, [&](const std::pair<SlotID, CStackInstance *> & elem) { return elem.second->getPower(); });
if(powerLimit > pair.second->getPower() &&
(weakSlots.empty() || pair.second->getPower() == visitingHero->getStack(weakSlots.front()).getPower()))
(weakSlots.empty() || pair.second->getPower() == getVisitingHero()->getStack(weakSlots.front()).getPower()))
{
weakSlots.push_back(pair.first);
stacksList.erase(pair.first);
@@ -612,20 +612,20 @@ void CGTownInstance::mergeGarrisonOnSiege() const
auto pair = *vstd::maxElementByFun(stacks, [&](const std::pair<SlotID, CStackInstance *> & elem)
{
ui64 power = elem.second->getPower();
auto dst = visitingHero->getSlotFor(elem.second->getCreatureID());
if(dst.validSlot() && visitingHero->hasStackAtSlot(dst))
power += visitingHero->getStack(dst).getPower();
auto dst = getVisitingHero()->getSlotFor(elem.second->getCreatureID());
if(dst.validSlot() && getVisitingHero()->hasStackAtSlot(dst))
power += getVisitingHero()->getStack(dst).getPower();
return power;
});
auto dst = visitingHero->getSlotFor(pair.second->getCreatureID());
auto dst = getVisitingHero()->getSlotFor(pair.second->getCreatureID());
if(dst.validSlot())
cb->moveStack(StackLocation(id, pair.first), StackLocation(visitingHero->id, dst), -1);
cb->moveStack(StackLocation(id, pair.first), StackLocation(getVisitingHero()->id, dst), -1);
else
{
dst = getWeakestStackSlot(static_cast<int>(pair.second->getPower()));
if(dst.validSlot())
cb->swapStacks(StackLocation(id, pair.first), StackLocation(visitingHero->id, dst));
cb->swapStacks(StackLocation(id, pair.first), StackLocation(getVisitingHero()->id, dst));
}
}
}
@@ -722,10 +722,10 @@ void CGTownInstance::deserializationFix()
//Hero is already handled by CGameState::attachArmedObjects
// if(visitingHero)
// visitingHero->attachTo(&townAndVis);
// if(garrisonHero)
// garrisonHero->attachTo(this);
// if(getVisitingHero())
// getVisitingHero()->attachTo(&townAndVis);
// if(getGarrisonHero())
// getGarrisonHero()->attachTo(this);
}
void CGTownInstance::updateMoraleBonusFromArmy()
@@ -737,7 +737,7 @@ void CGTownInstance::updateMoraleBonusFromArmy()
addNewBonus(b);
}
if (garrisonHero)
if (getGarrisonHero())
{
b->val = 0;
nodeHasChanged();
@@ -786,7 +786,7 @@ void CGTownInstance::recreateBuildingsBonuses()
void CGTownInstance::setVisitingHero(CGHeroInstance *h)
{
if(visitingHero.get() == h)
if(getVisitingHero() == h)
return;
if(h)
@@ -795,23 +795,23 @@ void CGTownInstance::setVisitingHero(CGHeroInstance *h)
assert(p);
h->detachFrom(*p);
h->attachTo(townAndVis);
visitingHero = h;
h->visitedTown = this;
h->inTownGarrison = false;
h->setVisitedTown(this, false);
visitingHero = h->id;
}
else
{
PlayerState *p = cb->gameState()->getPlayerState(visitingHero->tempOwner);
visitingHero->visitedTown = nullptr;
visitingHero->detachFrom(townAndVis);
visitingHero->attachTo(*p);
visitingHero = nullptr;
auto oldVisitor = dynamic_cast<CGHeroInstance*>(cb->gameState()->getObjInstance(visitingHero));
PlayerState *p = cb->gameState()->getPlayerState(getVisitingHero()->tempOwner);
oldVisitor->setVisitedTown(nullptr, false);
oldVisitor->detachFrom(townAndVis);
oldVisitor->attachTo(*p);
visitingHero = {};
}
}
void CGTownInstance::setGarrisonedHero(CGHeroInstance *h)
{
if(garrisonHero.get() == h)
if(getGarrisonHero() == h)
return;
if(h)
@@ -820,25 +820,40 @@ void CGTownInstance::setGarrisonedHero(CGHeroInstance *h)
assert(p);
h->detachFrom(*p);
h->attachTo(*this);
garrisonHero = h;
h->visitedTown = this;
h->inTownGarrison = true;
h->setVisitedTown(this, true);
garrisonHero = h->id;
}
else
{
PlayerState *p = cb->gameState()->getPlayerState(garrisonHero->tempOwner);
garrisonHero->visitedTown = nullptr;
garrisonHero->inTownGarrison = false;
garrisonHero->detachFrom(*this);
garrisonHero->attachTo(*p);
garrisonHero = nullptr;
PlayerState *p = cb->gameState()->getPlayerState(getGarrisonHero()->tempOwner);
auto oldVisitor = dynamic_cast<CGHeroInstance*>(cb->gameState()->getObjInstance(visitingHero));
oldVisitor->setVisitedTown(nullptr, false);
oldVisitor->detachFrom(*this);
oldVisitor->attachTo(*p);
garrisonHero = {};
}
updateMoraleBonusFromArmy(); //avoid giving morale bonus for same army twice
}
const CGHeroInstance * CGTownInstance::getVisitingHero() const
{
if (!visitingHero.hasValue())
return nullptr;
return cb->getHero(visitingHero);
}
const CGHeroInstance * CGTownInstance::getGarrisonHero() const
{
if (!garrisonHero.hasValue())
return nullptr;
return cb->getHero(garrisonHero);
}
bool CGTownInstance::armedGarrison() const
{
return !stacks.empty() || garrisonHero;
return !stacks.empty() || getGarrisonHero();
}
int CGTownInstance::getTownLevel() const
@@ -876,8 +891,8 @@ void CGTownInstance::setNameTextId( const std::string & newName )
const CArmedInstance * CGTownInstance::getUpperArmy() const
{
if(garrisonHero)
return garrisonHero;
if(getGarrisonHero())
return getGarrisonHero();
return this;
}
@@ -1014,9 +1029,9 @@ CBuilding::TRequired CGTownInstance::genBuildingRequirements(const BuildingID &
void CGTownInstance::addHeroToStructureVisitors(const CGHeroInstance *h, si64 structureInstanceID ) const
{
if(visitingHero == h)
if(getVisitingHero() == h)
cb->setObjPropertyValue(id, ObjProperty::STRUCTURE_ADD_VISITING_HERO, structureInstanceID); //add to visitors
else if(garrisonHero == h)
else if(getGarrisonHero() == h)
cb->setObjPropertyValue(id, ObjProperty::STRUCTURE_ADD_GARRISONED_HERO, structureInstanceID); //then it must be garrisoned hero
else
{