/** Determine legality of a proposed move for a unit. This function is the absolute last say * in such matters. * @param unit the unit attempting to move * @param pos2 the position unit desires to move to * @return true if move may proceed, false if not legal. */ bool RoutePlanner::isLegalMove(Unit *unit, const Vec2i &pos2) const { assert(world->getMap()->isInside(pos2)); assert(unit->getPos().dist(pos2) < 1.5); if (unit->getPos().dist(pos2) > 1.5) { unit->clearPath(); return false; } const Vec2i &pos1 = unit->getPos(); const int &size = unit->getSize(); const Field &field = unit->getCurrField(); Zone zone = field == Field::AIR ? Zone::AIR : Zone::LAND; AnnotatedMap *annotatedMap = world->getCartographer()->getMasterMap(); if (!annotatedMap->canOccupy(pos2, size, field)) { return false; // obstruction in field } if ( pos1.x != pos2.x && pos1.y != pos2.y ) { // Proposed move is diagonal, check if cells either 'side' are free. // eg.. XXXX // X1FX The Cells marked 'F' must both be free // XF2X for the move 1->2 to be legit // XXXX Vec2i diag1, diag2; getDiags(pos1, pos2, size, diag1, diag2); if (!annotatedMap->canOccupy(diag1, 1, field) || !annotatedMap->canOccupy(diag2, 1, field) || !world->getMap()->getCell(diag1)->isFree(zone) || !world->getMap()->getCell(diag2)->isFree(zone)) { return false; // obstruction, can not move to pos2 } } for (int i = pos2.x; i < unit->getSize() + pos2.x; ++i) { for (int j = pos2.y; j < unit->getSize() + pos2.y; ++j) { if (world->getMap()->getCell(i,j)->getUnit(zone) != unit && !world->getMap()->isFreeCell(Vec2i(i, j), field)) { return false; // blocked by another unit } } } // pos2 is free, and nothing is in the way return true; }
bool RoutePlanner::isLegalMove(Unit *unit, const Vec2i &pos2) const { assert(world->getMap()->isInside(pos2)); assert(unit->getPos().dist(pos2) < 1.5); if (unit->getPos().dist(pos2) > 1.5) { unit->clearPath(); return false; } const Vec2i &pos1 = unit->getPos(); const int &size = unit->getSize(); const Field &field = unit->getCurrField(); Zone zone; if (field == Field::AIR) { zone = Zone::AIR; } else if (field == Field::LAND) { zone = Zone::LAND; } else if (field == Field::WALL || field == Field::STAIR) { zone = Zone::WALL; } AnnotatedMap *annotatedMap = world->getCartographer()->getMasterMap(); if (!annotatedMap->canOccupy(pos2, size, field)) { return false; } if ( pos1.x != pos2.x && pos1.y != pos2.y ) { Vec2i diag1, diag2; getDiags(pos1, pos2, size, diag1, diag2); if (!annotatedMap->canOccupy(diag1, 1, field) || !annotatedMap->canOccupy(diag2, 1, field) || !world->getMap()->getCell(diag1)->isFree(zone) || !world->getMap()->getCell(diag2)->isFree(zone)) { return false; } } for (int i = pos2.x; i < unit->getSize() + pos2.x; ++i) { for (int j = pos2.y; j < unit->getSize() + pos2.y; ++j) { if (world->getMap()->getCell(i,j)->getUnit(zone) != unit && !world->getMap()->isFreeCell(Vec2i(i, j), field)) { return false; } } } return true; }