Beispiel #1
0
/**
**  Find Resource.
**
**  @param unit        The unit that wants to find a resource.
**  @param startUnit   Find closest unit from this location
**  @param range       Maximum distance to the resource.
**  @param resource    The resource id.
**
**  @note This will return an usable resource building that doesn't
**  belong to the player or one of his allies.
**
**  @return            NULL or resource unit
*/
CUnit *UnitFindResource(const CUnit &unit, const CUnit &startUnit, int range, int resource,
						//Wyrmgus start
//						bool check_usage, const CUnit *deposit)
						bool check_usage, const CUnit *deposit, bool mine_on_top)
						//Wyrmgus end
{
	if (!deposit) { // Find the nearest depot
		deposit = FindDepositNearLoc(*unit.Player, startUnit.tilePos, range, resource);
	}

	TerrainTraversal terrainTraversal;

	terrainTraversal.SetSize(Map.Info.MapWidth, Map.Info.MapHeight);
	terrainTraversal.Init();

	terrainTraversal.PushUnitPosAndNeighboor(startUnit);

	CUnit *resultMine = NULL;

	//Wyrmgus start
//	ResourceUnitFinder resourceUnitFinder(unit, deposit, resource, range, check_usage, &resultMine);
	ResourceUnitFinder resourceUnitFinder(unit, deposit, resource, range, check_usage, &resultMine, mine_on_top);
	//Wyrmgus end

	terrainTraversal.Run(resourceUnitFinder);
	return resultMine;
}
Beispiel #2
0
//Wyrmgus start
//static bool AiRepairBuilding(const CPlayer &player, const CUnitType &type, CUnit &building)
static bool AiRepairBuilding(const CPlayer &player, const CUnitType &type, CUnit &building)
//Wyrmgus end
{
	if (type.RepairRange == 0) {
		return false;
	}

	// We need to send all nearby free workers to repair that building
	// AI shouldn't send workers that are far away from repair point
	// Selection of mining workers.
	std::vector<CUnit *> table;
	FindPlayerUnitsByType(*AiPlayer->Player, type, table, true);
	int num = 0;
	for (size_t i = 0; i != table.size(); ++i) {
		CUnit &unit = *table[i];

		if (IsReadyToRepair(unit)) {
			table[num++] = &unit;
		}
	}
	table.resize(num);

	if (table.empty()) {
		return false;
	}
	TerrainTraversal terrainTraversal;

	//Wyrmgus start
//	terrainTraversal.SetSize(Map.Info.MapWidth, Map.Info.MapHeight);
	terrainTraversal.SetSize(Map.Info.MapWidths[building.MapLayer], Map.Info.MapHeights[building.MapLayer]);
	//Wyrmgus end
	terrainTraversal.Init();

	terrainTraversal.PushUnitPosAndNeighboor(building);

	const int maxRange = 15;
	const int movemask = type.MovementMask & ~(MapFieldLandUnit | MapFieldAirUnit | MapFieldSeaUnit);
	CUnit *unit = NULL;
	//Wyrmgus start
//	UnitFinder unitFinder(player, table, maxRange, movemask, &unit);
	UnitFinder unitFinder(player, table, maxRange, movemask, &unit, building.MapLayer);
	//Wyrmgus end

	if (terrainTraversal.Run(unitFinder) && unit != NULL) {
		const Vec2i invalidPos(-1, -1);
		//Wyrmgus start
//		CommandRepair(*unit, invalidPos, &building, FlushCommands);
		CommandRepair(*unit, invalidPos, &building, FlushCommands, building.MapLayer);
		//Wyrmgus end
		return true;
	}
	return false;
}
Beispiel #3
0
/**
**  Find the closest piece of terrain with the given flags.
**
**  @param movemask    The movement mask to reach that location.
**  @param resmask     Result tile mask.
**  @param range       Maximum distance for the search.
**  @param player      Only search fields explored by player
**  @param startPos    Map start position for the search.
**
**  @param terrainPos  OUT: Map position of tile.
**
**  @note Movement mask can be 0xFFFFFFFF to have no effect
**  Range is not circular, but square.
**  Player is ignored if nil(search the entire map)
**
**  @return            True if wood was found.
*/
bool FindTerrainType(int movemask, int resmask, int range,
					 const CPlayer &player, const Vec2i &startPos, Vec2i *terrainPos)
{
	TerrainTraversal terrainTraversal;

	terrainTraversal.SetSize(Map.Info.MapWidth, Map.Info.MapHeight);
	terrainTraversal.Init();

	terrainTraversal.PushPos(startPos);

	TerrainFinder terrainFinder(player, range, movemask & ~(MapFieldLandUnit | MapFieldAirUnit | MapFieldSeaUnit), resmask, terrainPos);

	return terrainTraversal.Run(terrainFinder);
}
Beispiel #4
0
/**
**  Check if we can repair the building.
**
**  @param type      Unit that can repair the building.
**  @param building  Building to be repaired.
**
**  @return          True if can repair, false if can't repair..
*/
static bool AiRepairBuilding(const CPlayer &player, const CUnitType &type, CUnit &building)
{
    if (type.RepairRange == 0) {
        return false;
    }

    // Remove all workers not mining. on the way building something
    // FIXME: It is not clever to use workers with gold
    // Idea: Antonis: Put the rest of the workers in a table in case
    // miners can't reach but others can. This will be useful if AI becomes
    // more flexible (e.g.: transports workers to an island)
    // FIXME: too hardcoded, not nice, needs improvement.
    // FIXME: too many workers repair the same building!

    // Selection of mining workers.
    std::vector<CUnit *> table;
    FindPlayerUnitsByType(*AiPlayer->Player, type, table);
    int num = 0;
    for (size_t i = 0; i != table.size(); ++i) {
        CUnit &unit = *table[i];

        if (IsReadyToRepair(unit)) {
            table[num++] = &unit;
        }
    }
    table.resize(num);

    if (table.empty()) {
        return false;
    }
    TerrainTraversal terrainTraversal;

    terrainTraversal.SetSize(Map.Info.MapWidth, Map.Info.MapHeight);
    terrainTraversal.Init();

    terrainTraversal.PushUnitPosAndNeighboor(building);

    const int maxRange = 100;
    const int movemask = type.MovementMask & ~(MapFieldLandUnit | MapFieldAirUnit | MapFieldSeaUnit);
    CUnit *unit = NULL;
    UnitFinder unitFinder(player, table, maxRange, movemask, &unit);

    if (terrainTraversal.Run(unitFinder) && unit != NULL) {
        const Vec2i invalidPos(-1, -1);
        CommandRepair(*unit, invalidPos, &building, FlushCommands);
        return true;
    }
    return false;
}
Beispiel #5
0
static bool FindNearestReachableTerrainType(int movemask, int resmask, int range,
											const CPlayer &player, const Vec2i &startPos, Vec2i *terrainPos)
{
	TerrainTraversal terrainTraversal;

	terrainTraversal.SetSize(Map.Info.MapWidth, Map.Info.MapHeight);
	terrainTraversal.Init();

	Assert(Map.Field(startPos)->CheckMask(resmask));
	terrainTraversal.PushPos(startPos);

	NearReachableTerrainFinder nearReachableTerrainFinder(player, range, movemask, resmask, terrainPos);

	return terrainTraversal.Run(nearReachableTerrainFinder);
}
Beispiel #6
0
VisitResult ResourceUnitFinder::Visit(TerrainTraversal &terrainTraversal, const Vec2i &pos, const Vec2i &from)
{
	if (!worker.Player->AiEnabled && !Map.Field(pos)->playerInfo.IsExplored(*worker.Player)) {
		return VisitResult_DeadEnd;
	}

	CUnit *mine = Map.Field(pos)->UnitCache.find(res_finder);

	if (mine && mine != *resultMine && MineIsUsable(*mine)) {
		ResourceUnitFinder::ResourceUnitFinder_Cost cost;

		cost.SetFrom(*mine, deposit, check_usage);
		if (cost < bestCost) {
			*resultMine = mine;

			if (cost.IsMin()) {
				return VisitResult_Finished;
			}
			bestCost = cost;
		}
	}
	if (CanMoveToMask(pos, movemask)) { // reachable
		if (terrainTraversal.Get(pos) < maxRange) {
			return VisitResult_Ok;
		} else {
			return VisitResult_DeadEnd;
		}
	} else { // unreachable
		return VisitResult_DeadEnd;
	}
}
Beispiel #7
0
VisitResult NearReachableTerrainFinder::Visit(TerrainTraversal &terrainTraversal, const Vec2i &pos, const Vec2i &from)
{
	//Wyrmgus start
//	if (!player.AiEnabled && !Map.Field(pos)->playerInfo.IsExplored(player)) {
	if (!Map.Field(pos)->playerInfo.IsExplored(player)) {
	//Wyrmgus end
		return VisitResult_DeadEnd;
	}
	// Look if found what was required.
	if (CanMoveToMask(pos, movemask)) {
		if (resPos) {
			*resPos = from;
		}
		return VisitResult_Finished;
	}
	if (Map.Field(pos)->CheckMask(resmask)) { // reachable
		if (terrainTraversal.Get(pos) <= maxDist) {
			return VisitResult_Ok;
		} else {
			return VisitResult_DeadEnd;
		}
	} else { // unreachable
		return VisitResult_DeadEnd;
	}
}
Beispiel #8
0
bool AiForce::NewRallyPoint(const Vec2i &startPos, Vec2i *resultPos)
{
	Assert(this->Units.size() > 0);
	const CUnit &leader = *(this->Units[0]);
	const int distance = leader.MapDistanceTo(startPos);

	WaitOnRallyPoint = AI_WAIT_ON_RALLY_POINT;

	TerrainTraversal terrainTraversal;

	terrainTraversal.SetSize(Map.Info.MapWidth, Map.Info.MapHeight);
	terrainTraversal.Init();

	Assert(Map.Info.IsPointOnMap(startPos));
	terrainTraversal.PushPos(startPos);

	AiForceRallyPointFinder aiForceRallyPointFinder(leader, distance, leader.tilePos, resultPos);

	return terrainTraversal.Run(aiForceRallyPointFinder);
}
Beispiel #9
0
VisitResult UnitFinder::Visit(TerrainTraversal &terrainTraversal, const Vec2i &pos, const Vec2i &from)
{
	if (!player.AiEnabled && !Map.Field(pos)->playerInfo.IsExplored(player)) {
		return VisitResult_DeadEnd;
	}
	// Look if found what was required.
	CUnit *unit = FindUnitAtPos(pos);
	if (unit) {
		*unitP = unit;
		return VisitResult_Finished;
	}
	if (CanMoveToMask(pos, movemask)) { // reachable
		if (terrainTraversal.Get(pos) <= maxDist) {
			return VisitResult_Ok;
		} else {
			return VisitResult_DeadEnd;
		}
	} else { // unreachable
		return VisitResult_DeadEnd;
	}
}