mirror of
https://github.com/vcmi/vcmi.git
synced 2025-02-13 13:18:43 +02:00
Update army in case of summoned creatures
This commit is contained in:
parent
b024237e8a
commit
c94bea51e3
@ -651,8 +651,8 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
|
|||||||
sendAndApply(&cs);
|
sendAndApply(&cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
cab1.takeFromArmy(this);
|
cab1.updateArmy(this);
|
||||||
cab2.takeFromArmy(this); //take casualties after battle is deleted
|
cab2.updateArmy(this); //take casualties after battle is deleted
|
||||||
|
|
||||||
//if one hero has lost we will erase him
|
//if one hero has lost we will erase him
|
||||||
if(battleResult.data->winner!=0 && hero1)
|
if(battleResult.data->winner!=0 && hero1)
|
||||||
@ -5805,7 +5805,8 @@ void CGameHandler::duelFinished()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance *army, BattleInfo *bat)
|
CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance * _army, BattleInfo *bat):
|
||||||
|
army(_army)
|
||||||
{
|
{
|
||||||
heroWithDeadCommander = ObjectInstanceID();
|
heroWithDeadCommander = ObjectInstanceID();
|
||||||
|
|
||||||
@ -5813,6 +5814,21 @@ CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance *army, BattleI
|
|||||||
if(color == PlayerColor::UNFLAGGABLE)
|
if(color == PlayerColor::UNFLAGGABLE)
|
||||||
color = PlayerColor::NEUTRAL;
|
color = PlayerColor::NEUTRAL;
|
||||||
|
|
||||||
|
auto killStack = [&, this](const SlotID slot, const CStackInstance * instance)
|
||||||
|
{
|
||||||
|
StackLocation sl(army, slot);
|
||||||
|
newStackCounts.push_back(TStackAndItsNewCount(sl, 0));
|
||||||
|
if(nullptr == instance)
|
||||||
|
return;
|
||||||
|
auto c = dynamic_cast <const CCommanderInstance *>(instance);
|
||||||
|
if (c) //switch commander status to dead
|
||||||
|
{
|
||||||
|
auto h = dynamic_cast <const CGHeroInstance *>(army);
|
||||||
|
if (h && h->commander == c)
|
||||||
|
heroWithDeadCommander = army->id; //TODO: unify commander handling
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
//1. Find removed stacks.
|
//1. Find removed stacks.
|
||||||
for(const auto & slotInfo : army->stacks)
|
for(const auto & slotInfo : army->stacks)
|
||||||
{
|
{
|
||||||
@ -5832,10 +5848,7 @@ CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance *army, BattleI
|
|||||||
}
|
}
|
||||||
//stack in this slot was removed == it is dead
|
//stack in this slot was removed == it is dead
|
||||||
if(!found)
|
if(!found)
|
||||||
{
|
killStack(slot, instance);
|
||||||
StackLocation sl(army, slot);
|
|
||||||
newStackCounts.push_back(TStackAndItsNewCount(sl, 0));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5860,28 +5873,31 @@ CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance *army, BattleI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!army->slotEmpty(st->slot) && st->count < army->getStackCount(st->slot))
|
if(army->slotEmpty(st->slot))
|
||||||
|
{
|
||||||
|
if(st->slot == SlotID(255) && !vstd::contains(st->state, EBattleStackState::SUMMONED) && st->alive())
|
||||||
|
{
|
||||||
|
//this stack was permanently summoned
|
||||||
|
const CreatureID summonedType = st->type->idNumber;
|
||||||
|
summoned[summonedType] += st->count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(st->count == 0 || !st->alive())
|
||||||
|
{
|
||||||
|
killStack(st->slot, st->base);
|
||||||
|
}
|
||||||
|
else if(st->count < army->getStackCount(st->slot))
|
||||||
{
|
{
|
||||||
StackLocation sl(army, st->slot);
|
StackLocation sl(army, st->slot);
|
||||||
if(st->alive())
|
newStackCounts.push_back(TStackAndItsNewCount(sl, st->count));
|
||||||
newStackCounts.push_back(std::pair<StackLocation, int>(sl, st->count));
|
|
||||||
else
|
|
||||||
newStackCounts.push_back(std::pair<StackLocation, int>(sl, 0));
|
|
||||||
}
|
|
||||||
if (st->base && !st->count)
|
|
||||||
{
|
|
||||||
auto c = dynamic_cast <const CCommanderInstance *>(st->base);
|
|
||||||
if (c) //switch commander status to dead
|
|
||||||
{
|
|
||||||
auto h = dynamic_cast <const CGHeroInstance *>(army);
|
|
||||||
if (h && h->commander == c)
|
|
||||||
heroWithDeadCommander = army->id; //TODO: unify commander handling
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CasualtiesAfterBattle::takeFromArmy(CGameHandler *gh)
|
void CasualtiesAfterBattle::updateArmy(CGameHandler *gh)
|
||||||
{
|
{
|
||||||
for(TStackAndItsNewCount &ncount : newStackCounts)
|
for(TStackAndItsNewCount &ncount : newStackCounts)
|
||||||
{
|
{
|
||||||
@ -5890,6 +5906,21 @@ void CasualtiesAfterBattle::takeFromArmy(CGameHandler *gh)
|
|||||||
else
|
else
|
||||||
gh->eraseStack(ncount.first, true);
|
gh->eraseStack(ncount.first, true);
|
||||||
}
|
}
|
||||||
|
for(auto summoned_iter : summoned)
|
||||||
|
{
|
||||||
|
SlotID slot = army->getSlotFor(summoned_iter.first);
|
||||||
|
if(slot.validSlot())
|
||||||
|
{
|
||||||
|
StackLocation location(army, slot);
|
||||||
|
gh->addToSlot(location, summoned_iter.first.toCreature(), summoned_iter.second);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//even if it will be possible to summon anything permanently it should be checked for free slot
|
||||||
|
//necromancy is handled separately
|
||||||
|
gh->complain("No free slot to put summoned creature");
|
||||||
|
}
|
||||||
|
}
|
||||||
for (auto al : removedWarMachines)
|
for (auto al : removedWarMachines)
|
||||||
{
|
{
|
||||||
gh->removeArtifact(al);
|
gh->removeArtifact(al);
|
||||||
|
@ -71,13 +71,16 @@ public:
|
|||||||
struct CasualtiesAfterBattle
|
struct CasualtiesAfterBattle
|
||||||
{
|
{
|
||||||
typedef std::pair<StackLocation, int> TStackAndItsNewCount;
|
typedef std::pair<StackLocation, int> TStackAndItsNewCount;
|
||||||
|
typedef std::map<CreatureID, TQuantity> TSummoned;
|
||||||
enum {ERASE = -1};
|
enum {ERASE = -1};
|
||||||
|
const CArmedInstance * army;
|
||||||
std::vector<TStackAndItsNewCount> newStackCounts;
|
std::vector<TStackAndItsNewCount> newStackCounts;
|
||||||
std::vector<ArtifactLocation> removedWarMachines;
|
std::vector<ArtifactLocation> removedWarMachines;
|
||||||
ObjectInstanceID heroWithDeadCommander; //TODO: unify stack loactions
|
TSummoned summoned;
|
||||||
|
ObjectInstanceID heroWithDeadCommander; //TODO: unify stack locations
|
||||||
|
|
||||||
CasualtiesAfterBattle(const CArmedInstance *army, BattleInfo *bat);
|
CasualtiesAfterBattle(const CArmedInstance * _army, BattleInfo *bat);
|
||||||
void takeFromArmy(CGameHandler *gh);
|
void updateArmy(CGameHandler *gh);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CGameHandler : public IGameCallback, CBattleInfoCallback
|
class CGameHandler : public IGameCallback, CBattleInfoCallback
|
||||||
|
Loading…
x
Reference in New Issue
Block a user