123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- /*
- * BattleAction.cpp, part of VCMI engine
- *
- * Authors: listed in file AUTHORS in main folder
- *
- * License: GNU General Public License v2.0 or later
- * Full text of license available in license.txt file, in main folder
- *
- */
- #include "StdInc.h"
- #include "BattleAction.h"
- #include "Unit.h"
- #include "CBattleInfoCallback.h"
- VCMI_LIB_NAMESPACE_BEGIN
- static const int32_t INVALID_UNIT_ID = -1000;
- BattleAction::BattleAction():
- side(BattleSide::NONE),
- stackNumber(-1),
- actionType(EActionType::NO_ACTION)
- {
- }
- BattleAction BattleAction::makeHeal(const battle::Unit * healer, const battle::Unit * healed)
- {
- BattleAction ba;
- ba.side = healer->unitSide();
- ba.actionType = EActionType::STACK_HEAL;
- ba.stackNumber = healer->unitId();
- ba.aimToUnit(healed);
- return ba;
- }
- BattleAction BattleAction::makeDefend(const battle::Unit * stack)
- {
- BattleAction ba;
- ba.side = stack->unitSide();
- ba.actionType = EActionType::DEFEND;
- ba.stackNumber = stack->unitId();
- return ba;
- }
- BattleAction BattleAction::makeMeleeAttack(const battle::Unit * stack, const BattleHex & destination, const BattleHex & attackFrom, bool returnAfterAttack)
- {
- BattleAction ba;
- ba.side = stack->unitSide(); //FIXME: will it fail if stack mind controlled?
- ba.actionType = EActionType::WALK_AND_ATTACK;
- ba.stackNumber = stack->unitId();
- ba.aimToHex(attackFrom);
- ba.aimToHex(destination);
- if(returnAfterAttack && stack->hasBonusOfType(BonusType::RETURN_AFTER_STRIKE))
- ba.aimToHex(stack->getPosition());
- return ba;
- }
- BattleAction BattleAction::makeWait(const battle::Unit * stack)
- {
- BattleAction ba;
- ba.side = stack->unitSide();
- ba.actionType = EActionType::WAIT;
- ba.stackNumber = stack->unitId();
- return ba;
- }
- BattleAction BattleAction::makeShotAttack(const battle::Unit * shooter, const battle::Unit * target)
- {
- BattleAction ba;
- ba.side = shooter->unitSide();
- ba.actionType = EActionType::SHOOT;
- ba.stackNumber = shooter->unitId();
- ba.aimToUnit(target);
- return ba;
- }
- BattleAction BattleAction::makeCreatureSpellcast(const battle::Unit * stack, const battle::Target & target, const SpellID & spellID)
- {
- BattleAction ba;
- ba.actionType = EActionType::MONSTER_SPELL;
- ba.spell = spellID;
- ba.setTarget(target);
- ba.side = stack->unitSide();
- ba.stackNumber = stack->unitId();
- return ba;
- }
- BattleAction BattleAction::makeMove(const battle::Unit * stack, const BattleHex & dest)
- {
- BattleAction ba;
- ba.side = stack->unitSide();
- ba.actionType = EActionType::WALK;
- ba.stackNumber = stack->unitId();
- ba.aimToHex(dest);
- return ba;
- }
- BattleAction BattleAction::makeEndOFTacticPhase(BattleSide side)
- {
- BattleAction ba;
- ba.side = side;
- ba.actionType = EActionType::END_TACTIC_PHASE;
- return ba;
- }
- BattleAction BattleAction::makeSurrender(BattleSide side)
- {
- BattleAction ba;
- ba.side = side;
- ba.actionType = EActionType::SURRENDER;
- return ba;
- }
- BattleAction BattleAction::makeRetreat(BattleSide side)
- {
- BattleAction ba;
- ba.side = side;
- ba.actionType = EActionType::RETREAT;
- return ba;
- }
- std::string BattleAction::toString() const
- {
- std::stringstream targetStream;
- for(const DestinationInfo & info : target)
- {
- if(info.unitValue == INVALID_UNIT_ID)
- {
- targetStream << info.hexValue;
- }
- else
- {
- targetStream << info.unitValue;
- targetStream << "@";
- targetStream << info.hexValue;
- }
- targetStream << ",";
- }
- boost::format fmt("{BattleAction: side '%d', stackNumber '%d', actionType '%s', actionSubtype '%d', target {%s}}");
- fmt % static_cast<int>(side) % stackNumber % static_cast<int>(actionType) % spell.getNum() % targetStream.str();
- return fmt.str();
- }
- void BattleAction::aimToHex(const BattleHex & destination)
- {
- DestinationInfo info;
- info.hexValue = destination;
- info.unitValue = INVALID_UNIT_ID;
- target.push_back(info);
- }
- void BattleAction::aimToUnit(const battle::Unit * destination)
- {
- DestinationInfo info;
- info.hexValue = destination->getPosition();
- info.unitValue = destination->unitId();
- target.push_back(info);
- }
- battle::Target BattleAction::getTarget(const CBattleInfoCallback * cb) const
- {
- battle::Target ret;
- for(const auto & destination : target)
- {
- if(destination.unitValue == INVALID_UNIT_ID)
- ret.emplace_back(destination.hexValue);
- else
- ret.emplace_back(cb->battleGetUnitByID(destination.unitValue));
- }
- return ret;
- }
- void BattleAction::setTarget(const battle::Target & target_)
- {
- target.clear();
- for(const auto & destination : target_)
- {
- if(destination.unitValue == nullptr)
- aimToHex(destination.hexValue);
- else
- aimToUnit(destination.unitValue);
- }
- }
- bool BattleAction::isUnitAction() const
- {
- static const std::array<EActionType, 109> actions = {
- EActionType::NO_ACTION,
- EActionType::WALK,
- EActionType::WAIT,
- EActionType::DEFEND,
- EActionType::WALK_AND_ATTACK,
- EActionType::SHOOT,
- EActionType::CATAPULT,
- EActionType::MONSTER_SPELL,
- EActionType::BAD_MORALE,
- EActionType::STACK_HEAL
- };
- return vstd::contains(actions, actionType);
- }
- bool BattleAction::isSpellAction() const
- {
- static const std::array<EActionType, 2> actions = {
- EActionType::HERO_SPELL,
- EActionType::MONSTER_SPELL
- };
- return vstd::contains(actions, actionType);
- }
- bool BattleAction::isBattleEndAction() const
- {
- static const std::array<EActionType, 2> actions = {
- EActionType::RETREAT,
- EActionType::SURRENDER
- };
- return vstd::contains(actions, actionType);
- }
- bool BattleAction::isTacticsAction() const
- {
- static const std::array<EActionType, 9> actions = {
- EActionType::WALK,
- EActionType::END_TACTIC_PHASE,
- EActionType::RETREAT,
- EActionType::SURRENDER
- };
- return vstd::contains(actions, actionType);
- }
- std::ostream & operator<<(std::ostream & os, const BattleAction & ba)
- {
- os << ba.toString();
- return os;
- }
- VCMI_LIB_NAMESPACE_END
|