Пример #1
0
/** 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;
}
Пример #2
0
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;
}