1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Made player interface tolerant to active stack removal.

This commit is contained in:
AlexVinS 2015-10-06 03:46:35 +03:00
parent d042b08682
commit f99bf099ca
6 changed files with 27 additions and 8 deletions

View File

@ -772,7 +772,8 @@ BattleAction CPlayerInterface::activeStack(const CStack * stack) //called when i
{
THREAD_CREATED_BY_CLIENT;
logGlobal->traceStream() << "Awaiting command for " << stack->nodeName();
auto stackId = stack->ID;
auto stackName = stack->nodeName();
if(autofightingAI)
{
if(isAutoFightOn)
@ -806,17 +807,27 @@ BattleAction CPlayerInterface::activeStack(const CStack * stack) //called when i
while(!b->givenCommand->data)
{
b->givenCommand->cond.wait(lock);
if(!battleInt) //batle ended while we were waiting for movement (eg. because of spell)
if(!battleInt) //battle ended while we were waiting for movement (eg. because of spell)
throw boost::thread_interrupted(); //will shut the thread peacefully
}
//tidy up
BattleAction ret = *(b->givenCommand->data);
//todo: remove this evil hack
//dirty evil hack...
//if active stack was changed, new thread was started for new active stack but we will receive notification too
//we need check that givenCommand is for our stack (use ID as stack object may be even destroyed)
if(stackId != ret.stackNumber)
{
logGlobal->traceStream() << "Interrupted command for " << stackName;
throw boost::thread_interrupted();
}
delete b->givenCommand->data;
b->givenCommand->data = nullptr;
//return command
logGlobal->traceStream() << "Giving command for " << stack->nodeName();
logGlobal->traceStream() << "Giving command for " << stackName;
return ret;
}

View File

@ -750,7 +750,7 @@ void CatapultAttack::applyCl( CClient *cl )
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(battleCatapultAttacked, *this);
}
void BattleStacksRemoved::applyCl( CClient *cl )
void BattleStacksRemoved::applyFirstCl(CClient * cl)
{
//inform interfaces about removed stacks
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(battleStacksRemoved, *this);

View File

@ -1005,11 +1005,17 @@ void CBattleInterface::newStack(const CStack * stack)
void CBattleInterface::stackRemoved(int stackID)
{
if(activeStack != nullptr)
{
if(activeStack->ID == stackID)
{
setActiveStack(nullptr);
}
}
delete creAnims[stackID];
creAnims.erase(stackID);
creDir.erase(stackID);
//FIXME: what if currently removed stack is active one (Sacrifice)?
redrawBackgroundWithHexes(activeStack);
queue->update();
}

View File

@ -1604,7 +1604,7 @@ struct BattleStacksRemoved : public CPackForClient //3016
BattleStacksRemoved(){type = 3016;}
DLL_LINKAGE void applyGs(CGameState *gs);
void applyCl(CClient *cl);
void applyFirstCl(CClient *cl);//inform client before stack objects are destroyed
std::set<ui32> stackIDs; //IDs of removed stacks

View File

@ -609,7 +609,7 @@ void SacrificeMechanics::applyBattleEffects(const SpellCastEnvironment * env, co
}
BattleSetActiveStack sas;
sas.stack = stackToActivate->ID;
env->sendAndApply(&sas);
//env->sendAndApply(&sas);
}
BattleStacksRemoved bsr;
bsr.stackIDs.insert(victim->ID);

View File

@ -5452,6 +5452,8 @@ void CGameHandler::runBattle()
return true;
if(battleResult.get())// battle is finished
return true;
if(next == nullptr)//active stack was been removed
return true;
return !next->alive();//active stack is dead
};