mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
CGTownInstance: implement armies merging on siege. Fix issue 169
Merging algorithm is replicate one from original game.
This commit is contained in:
parent
7eb8dbe0e9
commit
d15106bf63
@ -535,8 +535,12 @@ void CGTownInstance::onHeroVisit(const CGHeroInstance * h) const
|
||||
|
||||
bool outsideTown = (defendingHero == visitingHero && garrisonHero);
|
||||
|
||||
//TODO
|
||||
//"borrowing" army from garrison to visiting hero
|
||||
if(!outsideTown && armedGarrison() &&
|
||||
visitingHero && defendingHero == visitingHero)
|
||||
{
|
||||
mergeGarrisonOnSiege();
|
||||
}
|
||||
|
||||
cb->startBattlePrimary(h, defendingArmy, getSightCenter(), h, defendingHero, false, (outsideTown ? nullptr : this));
|
||||
}
|
||||
@ -725,6 +729,59 @@ void CGTownInstance::getOutOffsets( std::vector<int3> &offsets ) const
|
||||
offsets = {int3(-1,2,0), int3(-3,2,0)};
|
||||
}
|
||||
|
||||
void CGTownInstance::mergeGarrisonOnSiege() const
|
||||
{
|
||||
auto getWeakestStackSlot = [&](int powerLimit)
|
||||
{
|
||||
std::vector<SlotID> weakSlots;
|
||||
auto stacksList = visitingHero->stacks;
|
||||
std::pair<SlotID, CStackInstance *> pair;
|
||||
while(stacksList.size())
|
||||
{
|
||||
pair = *vstd::minElementByFun(stacksList, [&](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.push_back(pair.first);
|
||||
stacksList.erase(pair.first);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if(weakSlots.size())
|
||||
return *std::max_element(weakSlots.begin(), weakSlots.end());
|
||||
|
||||
return SlotID();
|
||||
};
|
||||
|
||||
int count = stacks.size();
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
auto pair = *vstd::maxElementByFun(stacks, [&](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();
|
||||
|
||||
return power;
|
||||
});
|
||||
auto dst = visitingHero->getSlotFor(pair.second->getCreatureID());
|
||||
if(dst.validSlot())
|
||||
cb->moveStack(StackLocation(this, pair.first), StackLocation(visitingHero, dst), -1);
|
||||
else
|
||||
{
|
||||
dst = getWeakestStackSlot(pair.second->getPower());
|
||||
if(dst.validSlot())
|
||||
cb->swapStacks(StackLocation(this, pair.first), StackLocation(visitingHero, dst));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGTownInstance::removeCapitols (PlayerColor owner) const
|
||||
{
|
||||
if (hasCapitol()) // search if there's an older capitol
|
||||
|
@ -237,6 +237,7 @@ public:
|
||||
|
||||
CBuilding::TRequired genBuildingRequirements(BuildingID build, bool includeUpgrade=true) const;
|
||||
|
||||
void mergeGarrisonOnSiege() const; // merge garrison into army of visiting hero
|
||||
void removeCapitols (PlayerColor owner) const;
|
||||
void addHeroToStructureVisitors(const CGHeroInstance *h, si32 structureInstanceID) const; //hero must be visiting or garrisoned in town
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user