1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-29 23:07:48 +02:00

Stupid AI is capable of winning / losing battle.

This commit is contained in:
Michał W. Urbańczyk
2011-01-08 18:33:40 +00:00
parent 957f1764d7
commit a53ec23556
14 changed files with 336 additions and 153 deletions

View File

@@ -14,6 +14,7 @@
#include "CCreatureHandler.h"
#include "CSpellHandler.h"
#include "CTownHandler.h"
#include "NetPacks.h"
/*
* BattleState.h, part of VCMI engine
@@ -326,7 +327,7 @@ std::vector<THex> BattleInfo::getAccessibility(const CStack * stack, bool addOcc
return ret;
}
bool BattleInfo::isStackBlocked(const CStack * stack)
bool BattleInfo::isStackBlocked(const CStack * stack) const
{
if(stack->hasBonusOfType(Bonus::SIEGE_WEAPON)) //siege weapons cannot be blocked
return false;
@@ -377,11 +378,11 @@ std::pair< std::vector<int>, int > BattleInfo::getPath(int start, int dest, bool
return std::make_pair(path, dist[dest]);
}
std::pair<ui32, ui32> BattleInfo::calculateDmgRange( const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky )
TDmgRange BattleInfo::calculateDmgRange( const CStack* attacker, const CStack* defender, TQuantity attackerCount, TQuantity defenderCount, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky ) const
{
float additiveBonus=1.0f, multBonus=1.0f,
minDmg = attacker->getMinDamage() * attacker->count,
maxDmg = attacker->getMaxDamage() * attacker->count;
minDmg = attacker->getMinDamage() * attackerCount,
maxDmg = attacker->getMaxDamage() * attackerCount;
if(attacker->getCreature()->idNumber == 149) //arrow turret
{
@@ -569,7 +570,7 @@ std::pair<ui32, ui32> BattleInfo::calculateDmgRange( const CStack* attacker, con
minDmg *= additiveBonus * multBonus;
maxDmg *= additiveBonus * multBonus;
std::pair<ui32, ui32> returnedVal;
TDmgRange returnedVal;
if(attacker->getEffect(42)) //curse handling (rest)
{
@@ -593,9 +594,14 @@ std::pair<ui32, ui32> BattleInfo::calculateDmgRange( const CStack* attacker, con
return returnedVal;
}
TDmgRange BattleInfo::calculateDmgRange(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky) const
{
return calculateDmgRange(attacker, defender, attacker->count, defender->count, attackerHero, defendingHero, shooting, charge, lucky);
}
ui32 BattleInfo::calculateDmg( const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky )
{
std::pair<ui32, ui32> range = calculateDmgRange(attacker, defender, attackerHero, defendingHero, shooting, charge, lucky);
TDmgRange range = calculateDmgRange(attacker, defender, attackerHero, defendingHero, shooting, charge, lucky);
if(range.first != range.second)
{
@@ -1021,7 +1027,7 @@ void BattleInfo::getStackQueue( std::vector<const CStack *> &out, int howMany, i
}
}
si8 BattleInfo::hasDistancePenalty( const CStack * stack, THex destHex )
si8 BattleInfo::hasDistancePenalty( const CStack * stack, THex destHex ) const
{
struct HLP
{
@@ -1042,7 +1048,7 @@ si8 BattleInfo::hasDistancePenalty( const CStack * stack, THex destHex )
}
si8 BattleInfo::sameSideOfWall(int pos1, int pos2)
si8 BattleInfo::sameSideOfWall(int pos1, int pos2) const
{
int wallInStackLine = lineToWallHex(pos1/BFIELD_WIDTH);
int wallInDestLine = lineToWallHex(pos2/BFIELD_WIDTH);
@@ -1053,7 +1059,7 @@ si8 BattleInfo::sameSideOfWall(int pos1, int pos2)
return stackLeft != destLeft;
}
si8 BattleInfo::hasWallPenalty( const CStack* stack, THex destHex )
si8 BattleInfo::hasWallPenalty( const CStack* stack, THex destHex ) const
{
if (siege == 0)
{
@@ -1067,7 +1073,7 @@ si8 BattleInfo::hasWallPenalty( const CStack* stack, THex destHex )
return !sameSideOfWall(stack->position, destHex);
}
si8 BattleInfo::canTeleportTo(const CStack * stack, THex destHex, int telportLevel)
si8 BattleInfo::canTeleportTo(const CStack * stack, THex destHex, int telportLevel) const
{
bool ac[BFIELD_SIZE];
@@ -1107,7 +1113,7 @@ si8 BattleInfo::canTeleportTo(const CStack * stack, THex destHex, int telportLev
// }
// }
bool BattleInfo::battleCanShoot(const CStack * stack, THex dest)
bool BattleInfo::battleCanShoot(const CStack * stack, THex dest) const
{
const CStack *dst = getStackT(dest);
@@ -1131,7 +1137,7 @@ bool BattleInfo::battleCanShoot(const CStack * stack, THex dest)
return false;
}
bool BattleInfo::battleCanFlee(int player)
bool BattleInfo::battleCanFlee(int player) const
{
if (player == side1)
{
@@ -1171,12 +1177,12 @@ const CStack * BattleInfo::battleGetStack(THex pos, bool onlyAlive)
return NULL;
}
const CGHeroInstance * BattleInfo::battleGetOwner(const CStack * stack)
const CGHeroInstance * BattleInfo::battleGetOwner(const CStack * stack) const
{
return heroes[!stack->attackerOwned];
}
si8 BattleInfo::battleMaxSpellLevel()
si8 BattleInfo::battleMaxSpellLevel() const
{
// if(!curB) //there is not battle
// {
@@ -1944,6 +1950,55 @@ std::string CStack::nodeName() const
return oss.str();
}
void CStack::prepareAttacked(BattleStackAttacked &bsa) const
{
bsa.killedAmount = bsa.damageAmount / MaxHealth();
unsigned damageFirst = bsa.damageAmount % MaxHealth();
if( firstHPleft <= damageFirst )
{
bsa.killedAmount++;
bsa.newHP = firstHPleft + MaxHealth() - damageFirst;
}
else
{
bsa.newHP = firstHPleft - damageFirst;
}
if(count <= bsa.killedAmount) //stack killed
{
bsa.newAmount = 0;
bsa.flags |= 1;
bsa.killedAmount = count; //we cannot kill more creatures than we have
}
else
{
bsa.newAmount = count - bsa.killedAmount;
}
}
bool CStack::isMeleeAttackPossible(const CStack * attacker, const CStack * defender, THex attackerPos /*= THex::INVALID*/, THex defenderPos /*= THex::INVALID*/)
{
if (!attackerPos.isValid())
{
attackerPos = attacker->position;
}
if (!defenderPos.isValid())
{
defenderPos = defender->position;
}
return
(THex::mutualPosition(attackerPos, defenderPos) >= 0) //front <=> front
|| (attacker->doubleWide() //back <=> front
&& THex::mutualPosition(attackerPos + (attacker->attackerOwned ? -1 : 1), defenderPos) >= 0)
|| (defender->doubleWide() //front <=> back
&& THex::mutualPosition(attackerPos, defenderPos + (defender->attackerOwned ? -1 : 1)) >= 0)
|| (defender->doubleWide() && attacker->doubleWide()//back <=> back
&& THex::mutualPosition(attackerPos + (attacker->attackerOwned ? -1 : 1), defenderPos + (defender->attackerOwned ? -1 : 1)) >= 0);
}
bool CMP_stack::operator()( const CStack* a, const CStack* b )
{
switch(phase)