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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user