From 9036d3924142f86988d1aa13d8bafbaf55581c55 Mon Sep 17 00:00:00 2001 From: AlexVinS Date: Sun, 28 Feb 2016 01:08:56 +0300 Subject: [PATCH] Do not remove battle stacks, make them ghosts instead. * exclude ghost stacks from (hopefully all) get* results for now --- client/battle/CBattleInterface.cpp | 13 +++++------ lib/BattleState.cpp | 20 ----------------- lib/BattleState.h | 1 - lib/CBattleCallback.cpp | 2 +- lib/NetPacksLib.cpp | 17 ++++++++++---- server/CGameHandler.cpp | 36 ------------------------------ 6 files changed, 19 insertions(+), 70 deletions(-) diff --git a/client/battle/CBattleInterface.cpp b/client/battle/CBattleInterface.cpp index a0f1725d4..c0a5547f2 100644 --- a/client/battle/CBattleInterface.cpp +++ b/client/battle/CBattleInterface.cpp @@ -1071,9 +1071,6 @@ void CBattleInterface::stacksAreAttacked(std::vector 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: diff --git a/lib/BattleState.cpp b/lib/BattleState.cpp index b1e83bc3d..80bf8829e 100644 --- a/lib/BattleState.cpp +++ b/lib/BattleState.cpp @@ -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; diff --git a/lib/BattleState.h b/lib/BattleState.h index a175a6045..a39229948 100644 --- a/lib/BattleState.h +++ b/lib/BattleState.h @@ -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(); diff --git a/lib/CBattleCallback.cpp b/lib/CBattleCallback.cpp index bea4a62b3..a7ecaa7c2 100644 --- a/lib/CBattleCallback.cpp +++ b/lib/CBattleCallback.cpp @@ -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; diff --git a/lib/NetPacksLib.cpp b/lib/NetPacksLib.cpp index 1e51dbf26..bf2bbc151 100644 --- a/lib/NetPacksLib.cpp +++ b/lib/NetPacksLib.cpp @@ -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; } } diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 464e4ddb4..b95071d28 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -5606,19 +5606,6 @@ void CGameHandler::runBattle() const BattleInfo & curB = *gs->curB; - //remove clones after all mechanics and animations are handled! - std::set 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