1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-13 19:54:17 +02:00

found a bug in code where AI can change client gamestate directly causing sorting crash

This commit is contained in:
Andrii Danylchenko
2021-01-30 14:13:45 +02:00
parent 5dc6d782f7
commit ade84699b0
4 changed files with 17 additions and 23 deletions

View File

@@ -578,6 +578,7 @@ void CBattleAI::attemptCastingSpell()
size_t minTurnSpan = ourUnits/3; //todo: tweak this size_t minTurnSpan = ourUnits/3; //todo: tweak this
std::vector<battle::Units> newTurnOrder; std::vector<battle::Units> newTurnOrder;
state.battleGetTurnOrder(newTurnOrder, amount, 2); state.battleGetTurnOrder(newTurnOrder, amount, 2);
const bool turnSpanOK = evaluateQueue(newValueOfStack, newTurnOrder, &state, minTurnSpan, nullptr); const bool turnSpanOK = evaluateQueue(newValueOfStack, newTurnOrder, &state, minTurnSpan, nullptr);

View File

@@ -14,11 +14,16 @@
void actualizeEffect(TBonusListPtr target, const Bonus & ef) void actualizeEffect(TBonusListPtr target, const Bonus & ef)
{ {
for(auto bonus : *target) //TODO: optimize for(auto & bonus : *target) //TODO: optimize
{ {
if(bonus->source == Bonus::SPELL_EFFECT && bonus->type == ef.type && bonus->subtype == ef.subtype) if(bonus->source == Bonus::SPELL_EFFECT && bonus->type == ef.type && bonus->subtype == ef.subtype)
{ {
bonus->turnsRemain = std::max(bonus->turnsRemain, ef.turnsRemain); if(bonus->turnsRemain < ef.turnsRemain)
{
bonus.reset(new Bonus(*bonus));
bonus->turnsRemain = ef.turnsRemain;
}
} }
} }
} }

View File

@@ -137,7 +137,7 @@ CPlayerInterface::CPlayerInterface(PlayerColor Player)
CPlayerInterface::~CPlayerInterface() CPlayerInterface::~CPlayerInterface()
{ {
CCS->soundh->ambientStopAllChannels(); if(CCS->soundh) CCS->soundh->ambientStopAllChannels();
logGlobal->trace("\tHuman player interface for player %s being destructed", playerID.getStr()); logGlobal->trace("\tHuman player interface for player %s being destructed", playerID.getStr());
delete showingDialog; delete showingDialog;
delete cingconsole; delete cingconsole;

View File

@@ -1066,33 +1066,21 @@ bool CMP_stack::operator()(const battle::Unit * a, const battle::Unit * b)
{ {
case 0: //catapult moves after turrets case 0: //catapult moves after turrets
return a->creatureIndex() > b->creatureIndex(); //catapult is 145 and turrets are 149 return a->creatureIndex() > b->creatureIndex(); //catapult is 145 and turrets are 149
case 1: //fastest first, upper slot first case 1:
case 2:
case 3:
{ {
int as = a->getInitiative(turn), bs = b->getInitiative(turn); int as = a->getInitiative(turn), bs = b->getInitiative(turn);
if(as != bs)
return as > bs;
if (a->unitSide() == b->unitSide())
return a->unitSlot() < b->unitSlot();
else if (a->unitSide() == side || b->unitSide() == side)
return a->unitSide() != side;
//FIXME: what about summoned stacks
return std::addressof(a) > std::addressof(b);
}
case 2: //fastest last, upper slot first
case 3: //fastest last, upper slot first
{
int as = a->getInitiative(turn), bs = b->getInitiative(turn);
if(as != bs) if(as != bs)
return as > bs; return as > bs;
if(a->unitSide() == b->unitSide()) if(a->unitSide() == b->unitSide())
return a->unitSlot() < b->unitSlot(); return a->unitSlot() < b->unitSlot();
else if (a->unitSide() == side || b->unitSide() == side)
return a->unitSide() != side;
return std::addressof(a) > std::addressof(b); return (a->unitSide() == side || b->unitSide() == side)
? a->unitSide() != side
: a->unitSide() < b->unitSide();
} }
default: default:
assert(false); assert(false);