mirror of
https://github.com/vcmi/vcmi.git
synced 2025-05-13 22:06:58 +02:00
Made player interface tolerant to active stack removal.
This commit is contained in:
parent
d042b08682
commit
f99bf099ca
@ -772,7 +772,8 @@ BattleAction CPlayerInterface::activeStack(const CStack * stack) //called when i
|
|||||||
{
|
{
|
||||||
THREAD_CREATED_BY_CLIENT;
|
THREAD_CREATED_BY_CLIENT;
|
||||||
logGlobal->traceStream() << "Awaiting command for " << stack->nodeName();
|
logGlobal->traceStream() << "Awaiting command for " << stack->nodeName();
|
||||||
|
auto stackId = stack->ID;
|
||||||
|
auto stackName = stack->nodeName();
|
||||||
if(autofightingAI)
|
if(autofightingAI)
|
||||||
{
|
{
|
||||||
if(isAutoFightOn)
|
if(isAutoFightOn)
|
||||||
@ -806,17 +807,27 @@ BattleAction CPlayerInterface::activeStack(const CStack * stack) //called when i
|
|||||||
while(!b->givenCommand->data)
|
while(!b->givenCommand->data)
|
||||||
{
|
{
|
||||||
b->givenCommand->cond.wait(lock);
|
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
|
throw boost::thread_interrupted(); //will shut the thread peacefully
|
||||||
}
|
}
|
||||||
|
|
||||||
//tidy up
|
//tidy up
|
||||||
BattleAction ret = *(b->givenCommand->data);
|
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;
|
delete b->givenCommand->data;
|
||||||
b->givenCommand->data = nullptr;
|
b->givenCommand->data = nullptr;
|
||||||
|
|
||||||
//return command
|
//return command
|
||||||
logGlobal->traceStream() << "Giving command for " << stack->nodeName();
|
logGlobal->traceStream() << "Giving command for " << stackName;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -750,7 +750,7 @@ void CatapultAttack::applyCl( CClient *cl )
|
|||||||
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(battleCatapultAttacked, *this);
|
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
|
//inform interfaces about removed stacks
|
||||||
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(battleStacksRemoved, *this);
|
BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(battleStacksRemoved, *this);
|
||||||
|
@ -1005,11 +1005,17 @@ void CBattleInterface::newStack(const CStack * stack)
|
|||||||
|
|
||||||
void CBattleInterface::stackRemoved(int stackID)
|
void CBattleInterface::stackRemoved(int stackID)
|
||||||
{
|
{
|
||||||
|
if(activeStack != nullptr)
|
||||||
|
{
|
||||||
|
if(activeStack->ID == stackID)
|
||||||
|
{
|
||||||
|
setActiveStack(nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delete creAnims[stackID];
|
delete creAnims[stackID];
|
||||||
creAnims.erase(stackID);
|
creAnims.erase(stackID);
|
||||||
creDir.erase(stackID);
|
creDir.erase(stackID);
|
||||||
//FIXME: what if currently removed stack is active one (Sacrifice)?
|
|
||||||
|
|
||||||
redrawBackgroundWithHexes(activeStack);
|
redrawBackgroundWithHexes(activeStack);
|
||||||
queue->update();
|
queue->update();
|
||||||
}
|
}
|
||||||
|
@ -1604,7 +1604,7 @@ struct BattleStacksRemoved : public CPackForClient //3016
|
|||||||
BattleStacksRemoved(){type = 3016;}
|
BattleStacksRemoved(){type = 3016;}
|
||||||
|
|
||||||
DLL_LINKAGE void applyGs(CGameState *gs);
|
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
|
std::set<ui32> stackIDs; //IDs of removed stacks
|
||||||
|
|
||||||
|
@ -609,7 +609,7 @@ void SacrificeMechanics::applyBattleEffects(const SpellCastEnvironment * env, co
|
|||||||
}
|
}
|
||||||
BattleSetActiveStack sas;
|
BattleSetActiveStack sas;
|
||||||
sas.stack = stackToActivate->ID;
|
sas.stack = stackToActivate->ID;
|
||||||
env->sendAndApply(&sas);
|
//env->sendAndApply(&sas);
|
||||||
}
|
}
|
||||||
BattleStacksRemoved bsr;
|
BattleStacksRemoved bsr;
|
||||||
bsr.stackIDs.insert(victim->ID);
|
bsr.stackIDs.insert(victim->ID);
|
||||||
|
@ -5452,6 +5452,8 @@ void CGameHandler::runBattle()
|
|||||||
return true;
|
return true;
|
||||||
if(battleResult.get())// battle is finished
|
if(battleResult.get())// battle is finished
|
||||||
return true;
|
return true;
|
||||||
|
if(next == nullptr)//active stack was been removed
|
||||||
|
return true;
|
||||||
return !next->alive();//active stack is dead
|
return !next->alive();//active stack is dead
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user