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

[BattleAI] Battle magic fixes

* should fix https://bugs.vcmi.eu/view.php?id=2901
This commit is contained in:
AlexVinS 2018-03-01 22:18:01 +03:00
parent e48797f7e8
commit 386805c4e0

View File

@ -359,7 +359,7 @@ void CBattleAI::attemptCastingSpell()
if(enemyHadTurnOut)
*enemyHadTurnOut = enemyHadTurn;
return ourTurnSpan > minTurnSpan;
return ourTurnSpan >= minTurnSpan;
};
RNGStub rngStub;
@ -369,12 +369,26 @@ void CBattleAI::attemptCastingSpell()
TStacks all = cb->battleGetAllStacks(false);
size_t ourRemainingTurns = 0;
for(auto unit : all)
{
healthOfStack[unit->unitId()] = unit->getAvailableHealth();
valueOfStack[unit->unitId()] = 0;
if(cb->battleGetOwner(unit) == playerID && unit->canMove() && !unit->moved())
ourRemainingTurns++;
}
LOGFL("I have %d turns left in this round", ourRemainingTurns);
const bool castNow = ourRemainingTurns <= 1;
if(castNow)
print("I should try to cast a spell now");
else
print("I could wait better moment to cast a spell");
auto amount = all.size();
std::vector<battle::Units> turnOrder;
@ -401,8 +415,6 @@ void CBattleAI::attemptCastingSpell()
auto evaluateSpellcast = [&] (PossibleSpellcast * ps)
{
int64_t totalGain = 0;
HypotheticBattle state(cb);
spells::BattleCast cast(&state, hero, spells::Mode::HERO, ps->spell);
@ -415,10 +427,13 @@ void CBattleAI::attemptCastingSpell()
for(auto unit : all)
{
newHealthOfStack[unit->unitId()] = unit->getAvailableHealth();
newValueOfStack[unit->unitId()] = 0;
auto unitId = unit->unitId();
auto localUnit = state.battleGetUnitByID(unitId);
if(state.battleGetOwner(unit) == playerID && unit->alive() && unit->willMove())
newHealthOfStack[unitId] = localUnit->getAvailableHealth();
newValueOfStack[unitId] = 0;
if(state.battleGetOwner(localUnit) == playerID && localUnit->alive() && localUnit->willMove())
ourUnits++;
}
@ -427,22 +442,32 @@ void CBattleAI::attemptCastingSpell()
std::vector<battle::Units> newTurnOrder;
state.battleGetTurnOrder(newTurnOrder, amount, 2);
if(evaluateQueue(newValueOfStack, newTurnOrder, &state, minTurnSpan, nullptr))
const bool turnSpanOK = evaluateQueue(newValueOfStack, newTurnOrder, &state, minTurnSpan, nullptr);
if(turnSpanOK || castNow)
{
int64_t totalGain = 0;
for(auto unit : all)
{
auto newValue = getValOr(newValueOfStack, unit->unitId(), 0);
auto oldValue = getValOr(valueOfStack, unit->unitId(), 0);
auto unitId = unit->unitId();
auto localUnit = state.battleGetUnitByID(unitId);
auto healthDiff = newHealthOfStack[unit->unitId()] - healthOfStack[unit->unitId()];
auto newValue = getValOr(newValueOfStack, unitId, 0);
auto oldValue = getValOr(valueOfStack, unitId, 0);
if(unit->unitOwner() != playerID)
auto healthDiff = newHealthOfStack[unitId] - healthOfStack[unitId];
if(localUnit->unitOwner() != playerID)
healthDiff = -healthDiff;
auto gain = newValue - oldValue + healthDiff;
if(healthDiff < 0)
{
ps->value = -1;
return; //do not damage own units at all
}
if(gain != 0)
totalGain += gain;
totalGain += (newValue - oldValue + healthDiff);
}
ps->value = totalGain;
@ -456,11 +481,8 @@ void CBattleAI::attemptCastingSpell()
std::vector<std::function<void()>> tasks;
for(PossibleSpellcast & psc : possibleCasts)
{
tasks.push_back(std::bind(evaluateSpellcast, &psc));
}
uint32_t threadCount = boost::thread::hardware_concurrency();
if(threadCount == 0)
@ -476,7 +498,7 @@ void CBattleAI::attemptCastingSpell()
LOGFL("Evaluation took %d ms", timer.getDiff());
auto pscValue = [] (const PossibleSpellcast &ps) -> int64_t
auto pscValue = [](const PossibleSpellcast &ps) -> int64_t
{
return ps.value;
};