mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-15 20:03:15 +02:00
CGTownInstance: implement armies merging on siege. Fix issue 169
Merging algorithm is replicate one from original game.
This commit is contained in:
@@ -535,8 +535,12 @@ void CGTownInstance::onHeroVisit(const CGHeroInstance * h) const
|
|||||||
|
|
||||||
bool outsideTown = (defendingHero == visitingHero && garrisonHero);
|
bool outsideTown = (defendingHero == visitingHero && garrisonHero);
|
||||||
|
|
||||||
//TODO
|
|
||||||
//"borrowing" army from garrison to visiting hero
|
//"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));
|
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)};
|
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
|
void CGTownInstance::removeCapitols (PlayerColor owner) const
|
||||||
{
|
{
|
||||||
if (hasCapitol()) // search if there's an older capitol
|
if (hasCapitol()) // search if there's an older capitol
|
||||||
|
@@ -237,6 +237,7 @@ public:
|
|||||||
|
|
||||||
CBuilding::TRequired genBuildingRequirements(BuildingID build, bool includeUpgrade=true) const;
|
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 removeCapitols (PlayerColor owner) const;
|
||||||
void addHeroToStructureVisitors(const CGHeroInstance *h, si32 structureInstanceID) const; //hero must be visiting or garrisoned in town
|
void addHeroToStructureVisitors(const CGHeroInstance *h, si32 structureInstanceID) const; //hero must be visiting or garrisoned in town
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user