1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-12 02:28:11 +02:00

Do not remove battle stacks, make them ghosts instead.

* exclude ghost stacks from (hopefully all) get* results for now
This commit is contained in:
AlexVinS 2016-02-28 01:08:56 +03:00
parent 5d5ad99436
commit 9036d39241
6 changed files with 19 additions and 70 deletions

View File

@ -1071,9 +1071,6 @@ void CBattleInterface::stacksAreAttacked(std::vector<StackAttackedInfo> attacked
stackRemoved(attackedInfo.defender->ID);
}
/* if (attackedInfos.front().cloneKilled) //FIXME: cloned stack is already removed
return;*/
if (targets > 1)
printConsoleAttacked(attackedInfos.front().defender, damage, killed, attackedInfos.front().attacker, true); //creatures perish
else
@ -2169,14 +2166,14 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
case RISE_DEMONS:
if (shere && ourStack && !shere->alive())
{
if(!(shere->hasBonusOfType(Bonus::UNDEAD)
|| shere->hasBonusOfType(Bonus::NON_LIVING)
if(!(shere->hasBonusOfType(Bonus::UNDEAD)
|| shere->hasBonusOfType(Bonus::NON_LIVING)
|| vstd::contains(shere->state, EBattleStackState::SUMMONED)
|| vstd::contains(shere->state, EBattleStackState::CLONED)
|| shere->hasBonusOfType(Bonus::SIEGE_WEAPON)
))
legalAction = true;
}
}
break;
}
if (legalAction)
@ -2334,8 +2331,8 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
case RISE_DEMONS:
cursorType = ECursor::SPELLBOOK;
realizeAction = [=]
{
giveCommand(Battle::DAEMON_SUMMONING, myNumber, activeStack->ID);
{
giveCommand(Battle::DAEMON_SUMMONING, myNumber, activeStack->ID);
};
break;
case CATAPULT:

View File

@ -142,26 +142,6 @@ CStack * BattleInfo::generateNewStack(const CStackBasicDescriptor &base, bool at
return ret;
}
const CStack * BattleInfo::battleGetStack(BattleHex pos, bool onlyAlive)
{
CStack * stack = nullptr;
for(auto & elem : stacks)
{
if(elem->position == pos
|| (elem->doubleWide()
&&( (elem->attackerOwned && elem->position-1 == pos)
|| (!elem->attackerOwned && elem->position+1 == pos) )
) )
{
if (elem->alive())
return elem; //we prefer living stacks - there can be only one stack on the tile, so return it immediately
else if (!onlyAlive)
stack = elem; //dead stacks are only accessible when there's no alive stack on this tile
}
}
return stack;
}
const CGHeroInstance * BattleInfo::battleGetOwner(const CStack * stack) const
{
return sides[!stack->attackerOwned].hero;

View File

@ -142,7 +142,6 @@ struct DLL_LINKAGE BattleInfo : public CBonusSystemNode, public CBattleInfoCallb
const CGHeroInstance * getHero(PlayerColor player) const; //returns fighting hero that belongs to given player
const CStack * battleGetStack(BattleHex pos, bool onlyAlive); //returns stack at given tile
const CGHeroInstance * battleGetOwner(const CStack * stack) const; //returns hero that owns given stack; nullptr if none
void localInit();

View File

@ -189,7 +189,7 @@ TStacks CBattleInfoEssentials::battleGetStacksIf(TStackFilter predicate, bool in
RETURN_IF_NOT_BATTLE(ret);
vstd::copy_if(getBattle()->stacks, std::back_inserter(ret), [=](const CStack * s){
return predicate(s) && (includeTurrets || !(s->type->idNumber == CreatureID::ARROW_TOWERS));
return predicate(s) && (!vstd::contains(s->state, EBattleStackState::GHOST)) && (includeTurrets || !(s->type->idNumber == CreatureID::ARROW_TOWERS));
});
return ret;

View File

@ -1312,7 +1312,10 @@ DLL_LINKAGE void BattleStackAttacked::applyGs( CGameState *gs )
{
//remove clone as well
CStack * clone = gs->curB->getStack(at->cloneID);
clone->state.insert(EBattleStackState::GHOST);
if(clone)
{
clone->state.insert(EBattleStackState::GHOST);
}
at->cloneID = -1;
}
}
@ -1340,7 +1343,9 @@ DLL_LINKAGE void BattleStackAttacked::applyGs( CGameState *gs )
//killed summoned creature should be removed like clone
if(killed() && vstd::contains(at->state, EBattleStackState::SUMMONED))
{
at->state.insert(EBattleStackState::GHOST);
}
}
DLL_LINKAGE void BattleAttack::applyGs( CGameState *gs )
@ -1635,15 +1640,19 @@ DLL_LINKAGE void BattleStacksRemoved::applyGs( CGameState *gs )
{
CStack * toRemove = gs->curB->stacks[b];
toRemove->state.erase(EBattleStackState::ALIVE); //just in case
toRemove->state.insert(EBattleStackState::GHOST);
//stack may be removed instantly (not being killed first)
//handle clone remove also here
if(toRemove->cloneID >= 0)
{
stackIDs.insert(toRemove->cloneID);
gs->curB->stacks.erase(gs->curB->stacks.begin() + b); //remove
toRemove->cloneID = -1;
}
toRemove->detachFromAll();
delete toRemove;
break;
}
}

View File

@ -5606,19 +5606,6 @@ void CGameHandler::runBattle()
const BattleInfo & curB = *gs->curB;
//remove clones after all mechanics and animations are handled!
std::set <const CStack*> stacksToRemove;
for (auto stack : curB.stacks)
{
if (stack->isGhost())
stacksToRemove.insert(stack);
}
for (auto stack : stacksToRemove)
{
BattleStacksRemoved bsr;
bsr.stackIDs.insert(stack->ID);
sendAndApply(&bsr);
}
//stack loop
const CStack *next;
@ -6106,29 +6093,6 @@ CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance * _army, Battl
}
};
//1. Find removed stacks.
for(const auto & slotInfo : army->stacks)
{
const SlotID slot = slotInfo.first;
const CStackInstance * instance = slotInfo.second;
if(nullptr != instance)//just in case
{
bool found = false;
for(const CStack * sta : bat->stacks)
{
if(sta->base == instance)
{
found = true;
break;
}
}
//stack in this slot was removed == it is dead
if(!found)
killStack(slot, instance);
}
}
for(CStack *st : bat->stacks)
{
if(vstd::contains(st->state, EBattleStackState::SUMMONED)) //don't take into account temporary summoned stacks