Example #1
0
HAAStarResult RoutePlanner::setupHierarchicalOpenList(Unit *unit, const Vec2i &target) {
	// get Transitions for start cluster
	Transitions transitions;
	Vec2i startCluster = ClusterMap::cellToCluster(unit->getPos());
	ClusterMap *clusterMap = world->getCartographer()->getClusterMap();
	clusterMap->getTransitions(startCluster, unit->getCurrField(), transitions);

	DiagonalDistance dd(target);
	nsgSearchEngine->getNeighbourFunc().setSearchCluster(startCluster);

	bool startTrap = true;
	// attempt quick path from unit->pos to each transition, 
	// if successful add transition to open list

	AnnotatedMap *aMap = world->getCartographer()->getMasterMap();
	aMap->annotateLocal(unit);
	for (Transitions::iterator it = transitions.begin(); it != transitions.end(); ++it) {
		float cost = quickSearch(unit->getCurrField(), unit->getSize(), unit->getPos(), (*it)->nwPos);
		if (cost != numeric_limits<float>::infinity()) {
			tSearchEngine->setOpen(*it, dd((*it)->nwPos), cost);
			startTrap = false;
		}
	}
	aMap->clearLocalAnnotations(unit);
	if (startTrap) {
		// do again, without annnotations, return TRAPPED if all else goes well
		bool locked = true;
		for (Transitions::iterator it = transitions.begin(); it != transitions.end(); ++it) {
			float cost = quickSearch(unit->getCurrField(), unit->getSize(), unit->getPos(), (*it)->nwPos);
			if (cost != numeric_limits<float>::infinity()) {
				tSearchEngine->setOpen(*it, dd((*it)->nwPos), cost);
				locked = false;
			}
		}
		if (locked) {
			return HAAStarResult::FAILURE;
		}
	}
	if (startTrap) {
		return HAAStarResult::START_TRAP;
	}
	return HAAStarResult::COMPLETE;
}
Example #2
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;
}
Example #3
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;
}