mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-23 22:37:55 +02:00
refactor BattleFlowProcessor
This commit is contained in:
@@ -342,6 +342,21 @@ void BattleFlowProcessor::activateNextStack(const CBattleInfoCallback & battle)
|
|||||||
|
|
||||||
bool BattleFlowProcessor::tryMakeAutomaticAction(const CBattleInfoCallback & battle, const CStack * next)
|
bool BattleFlowProcessor::tryMakeAutomaticAction(const CBattleInfoCallback & battle, const CStack * next)
|
||||||
{
|
{
|
||||||
|
bool actionPerformed = tryActivateMoralePenalty(battle, next) || tryActivateBerserkPenalty(battle, next) || tryAutomaticActionOfWarMachines(battle, next);
|
||||||
|
|
||||||
|
if (!actionPerformed) {
|
||||||
|
stackTurnTrigger(battle, next); //various effects
|
||||||
|
|
||||||
|
if(next->fear)
|
||||||
|
{
|
||||||
|
makeStackDoNothing(battle, next); //end immediately if stack was affected by fear
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return actionPerformed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BattleFlowProcessor::tryActivateMoralePenalty(const CBattleInfoCallback & battle, const CStack * next) {
|
||||||
// check for bad morale => freeze
|
// check for bad morale => freeze
|
||||||
int nextStackMorale = next->moraleVal();
|
int nextStackMorale = next->moraleVal();
|
||||||
if(!next->hadMorale && !next->waited() && nextStackMorale < 0)
|
if(!next->hadMorale && !next->waited() && nextStackMorale < 0)
|
||||||
@@ -359,36 +374,46 @@ bool BattleFlowProcessor::tryMakeAutomaticAction(const CBattleInfoCallback & bat
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BattleFlowProcessor::tryActivateBerserkPenalty(const CBattleInfoCallback & battle, const CStack * next) {
|
||||||
if (next->hasBonusOfType(BonusType::ATTACKS_NEAREST_CREATURE)) //while in berserk
|
if (next->hasBonusOfType(BonusType::ATTACKS_NEAREST_CREATURE)) //while in berserk
|
||||||
{
|
|
||||||
logGlobal->trace("Handle Berserk effect");
|
|
||||||
std::pair<const battle::Unit *, BattleHex> attackInfo = battle.getNearestStack(next);
|
|
||||||
if (attackInfo.first != nullptr)
|
|
||||||
{
|
{
|
||||||
BattleAction attack;
|
logGlobal->trace("Handle Berserk effect");
|
||||||
attack.actionType = EActionType::WALK_AND_ATTACK;
|
std::pair<const battle::Unit *, BattleHex> attackInfo = battle.getNearestStack(next);
|
||||||
attack.side = next->unitSide();
|
if (attackInfo.first != nullptr)
|
||||||
attack.stackNumber = next->unitId();
|
{
|
||||||
attack.aimToHex(attackInfo.second);
|
BattleAction attack;
|
||||||
attack.aimToUnit(attackInfo.first);
|
attack.actionType = EActionType::WALK_AND_ATTACK;
|
||||||
|
attack.side = next->unitSide();
|
||||||
|
attack.stackNumber = next->unitId();
|
||||||
|
attack.aimToHex(attackInfo.second);
|
||||||
|
attack.aimToUnit(attackInfo.first);
|
||||||
|
|
||||||
makeAutomaticAction(battle, next, attack);
|
makeAutomaticAction(battle, next, attack);
|
||||||
logGlobal->trace("Attacked nearest target %s", attackInfo.first->getDescription());
|
logGlobal->trace("Attacked nearest target %s", attackInfo.first->getDescription());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
makeStackDoNothing(battle, next);
|
||||||
|
logGlobal->trace("No target found");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else
|
return false;
|
||||||
{
|
}
|
||||||
makeStackDoNothing(battle, next);
|
|
||||||
logGlobal->trace("No target found");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
bool BattleFlowProcessor::tryAutomaticActionOfWarMachines(const CBattleInfoCallback & battle, const CStack * next) {
|
||||||
|
return tryMakeAutomaticActionOfBallistaOrTowers(battle, next) || tryMakeAutomaticActionOfCatapult(battle, next) || tryMakeAutomaticActionOfFirstAidTent(battle, next);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BattleFlowProcessor::tryMakeAutomaticActionOfBallistaOrTowers(const CBattleInfoCallback & battle, const CStack * next) {
|
||||||
const CGHeroInstance * curOwner = battle.battleGetOwnerHero(next);
|
const CGHeroInstance * curOwner = battle.battleGetOwnerHero(next);
|
||||||
const CreatureID stackCreatureId = next->unitType()->getId();
|
const CreatureID stackCreatureId = next->unitType()->getId();
|
||||||
|
|
||||||
if ((stackCreatureId == CreatureID::ARROW_TOWERS || stackCreatureId == CreatureID::BALLISTA)
|
if ((stackCreatureId == CreatureID::ARROW_TOWERS || stackCreatureId == CreatureID::BALLISTA)
|
||||||
&& (!curOwner || !gameHandler->randomizer->rollCombatAbility(curOwner->id, curOwner->valOfBonuses(BonusType::MANUAL_CONTROL, BonusSubtypeID(stackCreatureId)))))
|
&& (!curOwner || !gameHandler->randomizer->rollCombatAbility(curOwner->id, curOwner->valOfBonuses(BonusType::MANUAL_CONTROL, BonusSubtypeID(stackCreatureId)))))
|
||||||
{
|
{
|
||||||
BattleAction attack;
|
BattleAction attack;
|
||||||
attack.actionType = EActionType::SHOOT;
|
attack.actionType = EActionType::SHOOT;
|
||||||
@@ -449,29 +474,37 @@ bool BattleFlowProcessor::tryMakeAutomaticAction(const CBattleInfoCallback & bat
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BattleFlowProcessor::tryMakeAutomaticActionOfCatapult(const CBattleInfoCallback & battle, const CStack * next) {
|
||||||
|
const CGHeroInstance * curOwner = battle.battleGetOwnerHero(next);
|
||||||
if (next->unitType()->getId() == CreatureID::CATAPULT)
|
if (next->unitType()->getId() == CreatureID::CATAPULT)
|
||||||
{
|
|
||||||
const auto & attackableBattleHexes = battle.getAttackableBattleHexes();
|
|
||||||
|
|
||||||
if (attackableBattleHexes.empty())
|
|
||||||
{
|
{
|
||||||
makeStackDoNothing(battle, next);
|
const auto & attackableBattleHexes = battle.getAttackableBattleHexes();
|
||||||
return true;
|
|
||||||
|
if (attackableBattleHexes.empty())
|
||||||
|
{
|
||||||
|
makeStackDoNothing(battle, next);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!curOwner || !gameHandler->randomizer->rollCombatAbility(curOwner->id, curOwner->valOfBonuses(BonusType::MANUAL_CONTROL, BonusSubtypeID(CreatureID(CreatureID::CATAPULT)))))
|
||||||
|
{
|
||||||
|
BattleAction attack;
|
||||||
|
attack.actionType = EActionType::CATAPULT;
|
||||||
|
attack.side = next->unitSide();
|
||||||
|
attack.stackNumber = next->unitId();
|
||||||
|
|
||||||
|
makeAutomaticAction(battle, next, attack);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!curOwner || !gameHandler->randomizer->rollCombatAbility(curOwner->id, curOwner->valOfBonuses(BonusType::MANUAL_CONTROL, BonusSubtypeID(CreatureID(CreatureID::CATAPULT)))))
|
bool BattleFlowProcessor::tryMakeAutomaticActionOfFirstAidTent(const CBattleInfoCallback & battle, const CStack * next) {
|
||||||
{
|
const CGHeroInstance * curOwner = battle.battleGetOwnerHero(next);
|
||||||
BattleAction attack;
|
|
||||||
attack.actionType = EActionType::CATAPULT;
|
|
||||||
attack.side = next->unitSide();
|
|
||||||
attack.stackNumber = next->unitId();
|
|
||||||
|
|
||||||
makeAutomaticAction(battle, next, attack);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (next->unitType()->getId() == CreatureID::FIRST_AID_TENT)
|
if (next->unitType()->getId() == CreatureID::FIRST_AID_TENT)
|
||||||
{
|
{
|
||||||
TStacks possibleStacks = battle.battleGetStacksIf([&next](const CStack * s)
|
TStacks possibleStacks = battle.battleGetStacksIf([&next](const CStack * s)
|
||||||
@@ -500,17 +533,10 @@ bool BattleFlowProcessor::tryMakeAutomaticAction(const CBattleInfoCallback & bat
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stackTurnTrigger(battle, next); //various effects
|
|
||||||
|
|
||||||
if(next->fear)
|
|
||||||
{
|
|
||||||
makeStackDoNothing(battle, next); //end immediately if stack was affected by fear
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool BattleFlowProcessor::rollGoodMorale(const CBattleInfoCallback & battle, const CStack * next)
|
bool BattleFlowProcessor::rollGoodMorale(const CBattleInfoCallback & battle, const CStack * next)
|
||||||
{
|
{
|
||||||
//check for good morale
|
//check for good morale
|
||||||
@@ -539,7 +565,7 @@ bool BattleFlowProcessor::rollGoodMorale(const CBattleInfoCallback & battle, con
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BattleFlowProcessor::onActionMade(const CBattleInfoCallback & battle, const BattleAction &ba)
|
void BattleFlowProcessor::onActionMade(const CBattleInfoCallback & battle, const BattleAction &ba) //here
|
||||||
{
|
{
|
||||||
const auto * actedStack = battle.battleGetStackByID(ba.stackNumber, false);
|
const auto * actedStack = battle.battleGetStackByID(ba.stackNumber, false);
|
||||||
const auto * activeStack = battle.battleActiveUnit();
|
const auto * activeStack = battle.battleActiveUnit();
|
||||||
|
|||||||
@@ -38,6 +38,12 @@ class BattleFlowProcessor : boost::noncopyable
|
|||||||
|
|
||||||
bool rollGoodMorale(const CBattleInfoCallback & battle, const CStack * stack);
|
bool rollGoodMorale(const CBattleInfoCallback & battle, const CStack * stack);
|
||||||
bool tryMakeAutomaticAction(const CBattleInfoCallback & battle, const CStack * stack);
|
bool tryMakeAutomaticAction(const CBattleInfoCallback & battle, const CStack * stack);
|
||||||
|
bool tryActivateMoralePenalty(const CBattleInfoCallback & battle, const CStack * stack);
|
||||||
|
bool tryActivateBerserkPenalty(const CBattleInfoCallback & battle, const CStack * stack);
|
||||||
|
bool tryAutomaticActionOfWarMachines(const CBattleInfoCallback & battle, const CStack * stack);
|
||||||
|
bool tryMakeAutomaticActionOfBallistaOrTowers(const CBattleInfoCallback & battle, const CStack * stack);
|
||||||
|
bool tryMakeAutomaticActionOfCatapult(const CBattleInfoCallback & battle, const CStack * stack);
|
||||||
|
bool tryMakeAutomaticActionOfFirstAidTent(const CBattleInfoCallback & battle, const CStack * stack);
|
||||||
|
|
||||||
void summonGuardiansHelper(const CBattleInfoCallback & battle, BattleHexArray & output, const BattleHex & targetPosition, BattleSide side, bool targetIsTwoHex);
|
void summonGuardiansHelper(const CBattleInfoCallback & battle, BattleHexArray & output, const BattleHex & targetPosition, BattleSide side, bool targetIsTwoHex);
|
||||||
void trySummonGuardians(const CBattleInfoCallback & battle, const CStack * stack);
|
void trySummonGuardians(const CBattleInfoCallback & battle, const CStack * stack);
|
||||||
@@ -54,6 +60,7 @@ class BattleFlowProcessor : boost::noncopyable
|
|||||||
void makeStackDoNothing(const CBattleInfoCallback & battle, const CStack * next);
|
void makeStackDoNothing(const CBattleInfoCallback & battle, const CStack * next);
|
||||||
bool makeAutomaticAction(const CBattleInfoCallback & battle, const CStack * stack, const BattleAction & ba); //used when action is taken by stack without volition of player (eg. unguided catapult attack)
|
bool makeAutomaticAction(const CBattleInfoCallback & battle, const CStack * stack, const BattleAction & ba); //used when action is taken by stack without volition of player (eg. unguided catapult attack)
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit BattleFlowProcessor(BattleProcessor * owner, CGameHandler * newGameHandler);
|
explicit BattleFlowProcessor(BattleProcessor * owner, CGameHandler * newGameHandler);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user