std::vector<int> CBattleInfoCallback::battleGetDistances(const CStack * stack, BattleHex hex /*= BattleHex::INVALID*/, BattleHex * predecessors /*= NULL*/) { // FIXME - This method is broken, hex argument is not used. However AI depends on that wrong behaviour. if(!hex.isValid()) hex = stack->position; std::vector<int> ret(GameConstants::BFIELD_SIZE, -1); //fill initial ret with -1's if(!hex.isValid()) //stack has bad position? probably castle turret, return initial values (they can't move) return ret; bool ac[GameConstants::BFIELD_SIZE] = {0}; std::set<BattleHex> occupyable; gs->curB->getAccessibilityMap(ac, stack->doubleWide(), stack->attackerOwned, false, occupyable, stack->hasBonusOfType(Bonus::FLYING), stack); BattleHex pr[GameConstants::BFIELD_SIZE]; int dist[GameConstants::BFIELD_SIZE]; gs->curB->makeBFS(stack->position, ac, pr, dist, stack->doubleWide(), stack->attackerOwned, stack->hasBonusOfType(Bonus::FLYING), false); for(int i=0; i<GameConstants::BFIELD_SIZE; ++i) { if(pr[i] != -1) ret[i] = dist[i]; } if(predecessors) { memcpy(predecessors, pr, GameConstants::BFIELD_SIZE * sizeof(BattleHex)); } return ret; }
std::vector<BattleHex> CObstacleInfo::getBlocked(BattleHex hex) const { std::vector<BattleHex> ret; if(isAbsoluteObstacle) { assert(!hex.isValid()); range::copy(blockedTiles, std::back_inserter(ret)); return ret; } for(int offset : blockedTiles) { BattleHex toBlock = hex + offset; if((hex.getY() & 1) && !(toBlock.getY() & 1)) toBlock += BattleHex::LEFT; if(!toBlock.isValid()) logGlobal->errorStream() << "Misplaced obstacle!"; else ret.push_back(toBlock); } return ret; }
std::vector<BattleHex> CObstacleInfo::getBlocked(BattleHex hex) const { std::vector<BattleHex> ret; if(isAbsoluteObstacle) { assert(!hex.isValid()); range::copy(blockedTiles, std::back_inserter(ret)); return ret; } BOOST_FOREACH(int offset, blockedTiles) { BattleHex toBlock = hex + offset; if((hex.getY() & 1) && !(toBlock.getY() & 1)) toBlock += BattleHex::LEFT; if(!toBlock.isValid()) tlog1 << "Misplaced obstacle!\n"; else ret.push_back(toBlock); }
bool Teleport::prepareEffects(std::string & errorMessage, BattleStackMoved & pack, const Mechanics * m, const EffectTarget & target) const { if(target.size() != 2) { errorMessage = "Teleport requires 2 destinations."; return false; } auto targetUnit = target[0].unitValue; if(nullptr == targetUnit) { errorMessage = "No unit to teleport"; return false; } const BattleHex destination = target[1].hexValue; if(!destination.isValid()) { errorMessage = "Invalid teleport destination"; return false; } //TODO: move here all teleport checks if(!m->cb->battleCanTeleportTo(targetUnit, destination, m->getEffectLevel())) { errorMessage = "Forbidden teleport."; return false; } pack.distance = 0; pack.stack = targetUnit->unitId(); std::vector<BattleHex> tiles; tiles.push_back(destination); pack.tilesToMove = tiles; pack.teleporting = true; return true; }