예제 #1
0
void FindAndGatherResource(CUnit* unit, int resourceType) {
    CUnit* dest;
    int x, y, result;

    switch (resourceType) {
        case GoldCost:
            dest = UnitFindResource(unit, unit->X, unit->Y, FIND_RESOURCE_RANGE, resourceType);
            if (dest != NoUnitP) {
                SendCommandResource(unit, dest, 1);
                // TODO: don't know what StopResourceFlag corresponds to in 2.2.4 code
                // unit->StopResourceFlag = 1;
            } else {
                SendResponseMessage("Unable to find gold within range.\n", 3);
                return;
            }
            break;
        case WoodCost:
            result = FindTerrainType(unit->Type->MovementMask, MapFieldForest, 0, FIND_RESOURCE_RANGE, unit->Player, unit->X, unit->Y, &x, &y);
            if (result) {
                SendCommandResourceLoc(unit, x, y, 1);
                // TODO: don't know what StopResourceFlag corresponds to in 2.2.4 code
                //unit->StopResourceFlag = 1;
            } else {
                SendResponseMessage("Unable to find wood within range.\n", 3);
                return;
            }
            break;
        default:
            SendResponseMessage("Unknown resource type\n", 3);
    }
    SendResponseMessage("OK\n", 3);
}
예제 #2
0
/**
**  Get a suitable depot for better resource harvesting.
**
**  @param worker    Worker itself.
**  @param oldDepot  Old assigned depot.
**  @param resUnit   Resource to harvest from, if succeed
**
**  @return          new depot if found, NULL otherwise.
*/
CUnit *AiGetSuitableDepot(const CUnit &worker, const CUnit &oldDepot, CUnit **resUnit)
{
	Assert(worker.CurrentAction() == UnitActionResource);
	COrder_Resource &order = *static_cast<COrder_Resource *>(worker.CurrentOrder());
	const int resource = order.GetCurrentResource();
	std::vector<CUnit *> depots;
	const Vec2i offset(MaxMapWidth, MaxMapHeight);

	for (std::vector<CUnit *>::iterator it = worker.Player->UnitBegin(); it != worker.Player->UnitEnd(); ++it) {
		CUnit &unit = **it;

		if (unit.Type->CanStore[resource] && !unit.IsUnusable()) {
			depots.push_back(&unit);
		}
	}
	// If there aren't any alternatives, exit
	if (depots.size() < 2) {
		return NULL;
	}
	std::sort(depots.begin(), depots.end(), CompareDepotsByDistance(worker));

	for (std::vector<CUnit *>::iterator it = depots.begin(); it != depots.end(); ++it) {
		CUnit &unit = **it;

		const unsigned int tooManyWorkers = 15;
		const int range = 15;

		if (&oldDepot == &unit) {
			continue;
		}
		if (unit.Refs > tooManyWorkers) {
			continue;
		}
		//Wyrmgus start
//		if (AiEnemyUnitsInDistance(worker, range)) {
		if (AiEnemyUnitsInDistance(worker, range, worker.MapLayer)) {
		//Wyrmgus end
			continue;
		}
		CUnit *res = UnitFindResource(worker, unit, range, resource, unit.Player->AiEnabled);
		if (res) {
			*resUnit = res;
			return &unit;
		}
	}
	return NULL;
}
예제 #3
0
void HarvestResAtLoc(int resourceType, int x, int y) {
    CUnit *unit;
    CUnit *dest;

    if (resourceType == GoldCost || resourceType == OilCost) {
        dest = UnitFindResource(unit, x, y, FIND_RESOURCE_RANGE, resourceType);
        if (dest != NoUnitP) {
            SendCommandResource(unit, dest, 1);
        } else {
            SendResponseMessage("Unable to find resource in range.\n", 3);
            return;
        }
    } else if (resourceType == WoodCost) {
        SendCommandResourceLoc(unit, x, y, 1);
    } else {
        SendResponseMessage("Unknown resource type\n", 3);
        return;
    }
    SendResponseMessage("OK\n", 3);
}
예제 #4
0
bool COrder_Resource::FindAnotherResource(CUnit &unit)
{
	if (this->CurrentResource) {
		const ResourceInfo *resinfo = unit.Type->ResInfo[this->CurrentResource];
		if (resinfo) {
			//Wyrmgus start
	//		if (!resinfo.TerrainHarvester) {
			if (!Map.Info.IsPointOnMap(this->goalPos)) {
			//Wyrmgus end
				CUnit *newGoal = UnitFindResource(unit, this->Resource.Mine ? *this->Resource.Mine : unit, 8, this->CurrentResource, 1);

				if (newGoal) {
					CUnit *mine = this->Resource.Mine;
					if (mine) {
						unit.DeAssignWorkerFromMine(*mine);
					}
					unit.AssignWorkerToMine(*newGoal);
					this->Resource.Mine = newGoal;
					this->goalPos.x = -1;
					this->goalPos.y = -1;
					this->State = SUB_MOVE_TO_RESOURCE;
					this->SetGoal(newGoal);
					return true;
				}
			} else {
				Vec2i resPos;
				//Wyrmgus start
//				if (FindTerrainType(unit.Type->MovementMask, MapFieldForest, 8, *unit.Player, unit.tilePos, &resPos)) {
				if ((this->CurrentResource == WoodCost && FindTerrainType(unit.Type->MovementMask, MapFieldForest, 8, *unit.Player, unit.tilePos, &resPos)) || (this->CurrentResource == StoneCost && FindTerrainType(unit.Type->MovementMask, MapFieldRocks, 8, *unit.Player, unit.tilePos, &resPos))) {
				//Wyrmgus end
					this->goalPos = resPos;
					this->State = SUB_MOVE_TO_RESOURCE;
					DebugPrint("Found a better place to harvest %d,%d\n" _C_ resPos.x _C_ resPos.y);
					return true;
				}
			}
		}
	}
	return false;
}
예제 #5
0
/**
**  Assign worker to gather a certain resource from Unit.
**
**  @param unit      pointer to the unit.
**  @param resource  resource identification.
**
**  @return          1 if the worker was assigned, 0 otherwise.
*/
static int AiAssignHarvesterFromUnit(CUnit &unit, int resource)
{
    // Try to find the nearest depot first.
    CUnit *depot = FindDeposit(unit, 1000, resource);
    // Find a resource to harvest from.
    CUnit *mine = UnitFindResource(unit, depot ? *depot : unit, 1000, resource, true);

    if (mine) {
        CommandResource(unit, *mine, FlushCommands);
        return 1;
    }

    int exploremask = 0;

    for (size_t i = 0; i != UnitTypes.size(); ++i) {
        const CUnitType *type = UnitTypes[i];

        if (type && type->GivesResource == resource) {
            switch (type->UnitType) {
            case UnitTypeLand:
                exploremask |= MapFieldLandUnit;
                break;
            case UnitTypeFly:
                exploremask |= MapFieldAirUnit;
                break;
            case UnitTypeNaval:
                exploremask |= MapFieldSeaUnit;
                break;
            default:
                Assert(0);
            }
        }
    }
    // Ask the AI to explore
    AiExplore(unit.tilePos, exploremask);
    // Failed.
    return 0;
}
예제 #6
0
/**
**  Assign worker to gather a certain resource.
**
**  @param unit      pointer to the unit.
**  @param resource  resource identification.
**
**  @return          1 if the worker was assigned, 0 otherwise.
*/
static int AiAssignHarvester(CUnit &unit, int resource)
{
	ResourceInfo *resinfo;

	// It can't.
	if (unit.Removed) {
		return 0;
	}

	resinfo = unit.Type->ResInfo[resource];
	Assert(resinfo);
	if (resinfo->TerrainHarvester) {
		Vec2i forestPos;

		//
		// Code for terrain harvesters. Search for piece of terrain to mine.
		//
		if (FindTerrainType(unit.Type->MovementMask, MapFieldForest, 0, 1000,
				unit.Player, unit.tilePos, &forestPos)) {
			CommandResourceLoc(unit, forestPos, FlushCommands);
			return 1;
		}
		// Ask the AI to explore...
		AiExplore(unit.tilePos, MapFieldLandUnit);
	} else {
		int exploremask = 0;
		//
		// Find a resource to harvest from.
		//
		CUnit *dest = UnitFindResource(unit,
				unit.tilePos.x, unit.tilePos.y, 1000, resource, true);

		if (dest) {
			//FIXME: rb - when workers can speedup building then such assign may be ok.
			//if(dest->CurrentAction() == UnitActionBuilt)
				//CommandBuildBuilding(unit, dest->tilePos, dest->Type, FlushCommands);
			//else
				CommandResource(unit, *dest, FlushCommands);
			return 1;
		}
#if 0
		//may this code touch needmask which will be reseted before next cycle
		if (resinfo->RefineryHarvester &&
			 (dest = UnitFindMiningArea(unit, unit.X, unit.Y, 1000, resource))) {
			int needmask;
			//int counter[UnitTypeMax];

			//
			// Count the already made build requests.
			//
			//AiGetBuildRequestsCount(counter);
			int n = AiHelpers.Refinery[resource - 1].size();
			for (int i = 0; i < n; ++i) {
				CUnitType *type = AiHelpers.Refinery[resource - 1][i];
				//if (counter[type->Slot]) { // Already ordered.
				//	return 0;
				//}

				if (!AiRequestedTypeAllowed(AiPlayer->Player, type)) {
					continue;
				}

				//
				// Check if resources available.
				//
				needmask = AiCheckUnitTypeCosts(type);
				if(!needmask && AiMakeUnit(type)) {
					AiBuildQueue newqueue;
					newqueue.Type = type;
					newqueue.Want = 1;
					newqueue.Made = 1;
					newqueue.X = dest->X;
					newqueue.Y = dest->Y;
					AiPlayer->UnitTypeBuilt.insert(
						AiPlayer->UnitTypeBuilt.begin(), newqueue);
					return 0;
				}

			}

			return 0;
		}
#endif

		for (std::vector<CUnitType *>::iterator i = UnitTypes.begin();
			 i != UnitTypes.end(); i++) {
			if (*i && (*i)->GivesResource == resource) {
				switch ((*i)->UnitType) {
				case UnitTypeLand:
					exploremask |= MapFieldLandUnit;
					break;
				case UnitTypeFly:
					exploremask |= MapFieldAirUnit;
					break;
				case UnitTypeNaval:
					exploremask |= MapFieldSeaUnit;
					break;
				default:
					Assert(0);
				}
			}
		}
		// Ask the AI to explore
		AiExplore(unit.tilePos, exploremask);
	}

	// Failed.
	return 0;
}
예제 #7
0
/**
**  Find something else to do when the resource is exhausted.
**  This is called from GatherResource when the resource is empty.
**
**  @param unit    pointer to harvester unit.
**  @param source  pointer to resource unit.
*/
void COrder_Resource::LoseResource(CUnit &unit, CUnit &source)
{
	CUnit *depot;
	const ResourceInfo &resinfo = *unit.Type->ResInfo[this->CurrentResource];

	//Wyrmgus start
	const CUnitType &source_type = *source.Type;
	
//	Assert((unit.Container == &source && !resinfo.HarvestFromOutside)
//		   || (!unit.Container && resinfo.HarvestFromOutside));
	Assert((unit.Container == &source && !source_type.BoolFlag[HARVESTFROMOUTSIDE_INDEX].value)
		   || (!unit.Container && source_type.BoolFlag[HARVESTFROMOUTSIDE_INDEX].value));
	//Wyrmgus end

	//Wyrmgus start
//	if (resinfo.HarvestFromOutside) {
	if (source_type.BoolFlag[HARVESTFROMOUTSIDE_INDEX].value) {
	//Wyrmgus end
		this->ClearGoal();
		--source.Resource.Active;
	}

	// Continue to harvest if we aren't fully loaded
	//Wyrmgus start
//	if (resinfo.HarvestFromOutside && unit.ResourcesHeld < resinfo.ResourceCapacity) {
	if (source_type.BoolFlag[HARVESTFROMOUTSIDE_INDEX].value && unit.ResourcesHeld < resinfo.ResourceCapacity) {
	//Wyrmgus end
		CUnit *goal = UnitFindResource(unit, unit, 15, this->CurrentResource, 1);

		if (goal) {
			this->goalPos.x = -1;
			this->goalPos.y = -1;
			this->State = SUB_START_RESOURCE;
			this->SetGoal(goal);
			return;
		}
	}

	// If we are fully loaded first search for a depot.
	if (unit.ResourcesHeld && (depot = FindDeposit(unit, 1000, unit.CurrentResource))) {
		if (unit.Container) {
			DropOutNearest(unit, depot->tilePos + depot->Type->GetHalfTileSize(), &source);
		}
		// Remember where it mined, so it can look around for another resource.
		//
		//FIXME!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
		//unit.CurrentOrder()->Arg1.ResourcePos = (unit.X << 16) | unit.Y;
		this->DoneHarvesting = true;
		UnitGotoGoal(unit, depot, SUB_MOVE_TO_DEPOT);
		DebugPrint("%d: Worker %d report: Resource is exhausted, Going to depot\n"
				   _C_ unit.Player->Index _C_ UnitNumber(unit));
		return;
	}
	// No depot found, or harvester empty
	// Dump the unit outside and look for something to do.
	if (unit.Container) {
		//Wyrmgus start
//		Assert(!resinfo.HarvestFromOutside);
		Assert(!source_type.BoolFlag[HARVESTFROMOUTSIDE_INDEX].value);
		//Wyrmgus end
		DropOutOnSide(unit, LookingW, &source);
	}
	this->goalPos.x = -1;
	this->goalPos.y = -1;
	//use depot as goal
	depot = UnitFindResource(unit, unit, 15, this->CurrentResource, unit.Player->AiEnabled);
	if (depot) {
		DebugPrint("%d: Worker %d report: Resource is exhausted, Found another resource.\n"
				   _C_ unit.Player->Index _C_ UnitNumber(unit));
		this->State = SUB_START_RESOURCE;
		this->SetGoal(depot);
	} else {
		DebugPrint("%d: Worker %d report: Resource is exhausted, Just sits around confused.\n"
				   _C_ unit.Player->Index _C_ UnitNumber(unit));
		this->Finished = true;
	}
}
예제 #8
0
/**
**  Start harvesting the resource.
**
**  @param unit  Pointer to unit.
**
**  @return      TRUE if ready, otherwise FALSE.
*/
int COrder_Resource::StartGathering(CUnit &unit)
{
	CUnit *goal;
	const ResourceInfo &resinfo = *unit.Type->ResInfo[this->CurrentResource];
	Assert(!unit.IX);
	Assert(!unit.IY);

	//Wyrmgus start
//	if (resinfo.TerrainHarvester) {
	if (Map.Info.IsPointOnMap(this->goalPos)) {
	//Wyrmgus end
		// This shouldn't happened?
#if 0
		if (!Map.IsTerrainResourceOnMap(unit.Orders->goalPos, this->CurrentResource)) {
			DebugPrint("Wood gone, just like that?\n");
			return 0;
		}
#endif
		UnitHeadingFromDeltaXY(unit, this->goalPos - unit.tilePos);
		if (resinfo.WaitAtResource) {
			this->TimeToHarvest = std::max<int>(1, resinfo.WaitAtResource * SPEEDUP_FACTOR / unit.Player->SpeedResourcesHarvest[resinfo.ResourceId]);
		} else {
			this->TimeToHarvest = 1;
		}
		this->DoneHarvesting = 0;
		if (this->CurrentResource != unit.CurrentResource) {
			DropResource(unit);
			unit.CurrentResource = this->CurrentResource;
		}
		return 1;
	}

	goal = this->GetGoal();

	// Target is dead, stop getting resources.
	if (!goal || goal->IsVisibleAsGoal(*unit.Player) == false) {
		// Find an alternative, but don't look too far.
		this->goalPos.x = -1;
		this->goalPos.y = -1;
		if ((goal = UnitFindResource(unit, unit, 15, this->CurrentResource, unit.Player->AiEnabled))) {
			this->State = SUB_START_RESOURCE;
			this->SetGoal(goal);
		} else {
			this->ClearGoal();
			this->Finished = true;
		}
		return 0;
	}

	// FIXME: 0 can happen, if to near placed by map designer.
	Assert(unit.MapDistanceTo(*goal) <= 1);

	// Update the heading of a harvesting unit to looks straight at the resource.
	//Wyrmgus start
//	UnitHeadingFromDeltaXY(unit, goal->tilePos - unit.tilePos + goal->Type->GetHalfTileSize());
	UnitHeadingFromDeltaXY(unit, Vec2i(goal->tilePos.x * PixelTileSize.x, goal->tilePos.y * PixelTileSize.y) - Vec2i(unit.tilePos.x * PixelTileSize.x, unit.tilePos.y * PixelTileSize.y) + goal->Type->GetHalfTilePixelSize() - unit.Type->GetHalfTilePixelSize());
	//Wyrmgus end

	// If resource is still under construction, wait!
	if ((goal->Type->MaxOnBoard && goal->Resource.Active >= goal->Type->MaxOnBoard)
		|| goal->CurrentAction() == UnitActionBuilt) {
		// FIXME: Determine somehow when the resource will be free to use
		// FIXME: Could we somehow find another resource? Think minerals
		// FIXME: We should add a flag for that, and a limited range.
		// However the CPU usage is really low (no pathfinding stuff).
		unit.Wait = 10;
		return 0;
	}

	// Place unit inside the resource
	//Wyrmgus start
//	if (!resinfo.HarvestFromOutside) {
	if (!goal->Type->BoolFlag[HARVESTFROMOUTSIDE_INDEX].value) {
	//Wyrmgus end
		if (goal->Variable[MAXHARVESTERS_INDEX].Value == 0 || goal->Variable[MAXHARVESTERS_INDEX].Value > goal->InsideCount) {
			this->ClearGoal();
			int selected = unit.Selected;
			unit.Remove(goal);
			if (selected && !Preference.DeselectInMine) {
				unit.Removed = 0;
				SelectUnit(unit);
				SelectionChanged();
				unit.Removed = 1;
			}
		} else if (goal->Variable[MAXHARVESTERS_INDEX].Value <= goal->InsideCount) {
			//Resource is full, wait
			unit.Wait = 10;
			return 0;
		}
	}

	if (this->CurrentResource != unit.CurrentResource) {
		DropResource(unit);
		unit.CurrentResource = this->CurrentResource;
	}

	// Activate the resource
	goal->Resource.Active++;

	if (resinfo.WaitAtResource) {
		//Wyrmgus start
//		this->TimeToHarvest = std::max<int>(1, resinfo.WaitAtResource * SPEEDUP_FACTOR / unit.Player->SpeedResourcesHarvest[resinfo.ResourceId]);
		int wait_at_resource = resinfo.WaitAtResource;
		if (!goal->Type->BoolFlag[HARVESTFROMOUTSIDE_INDEX].value) {
			wait_at_resource = resinfo.WaitAtResource * 100 / resinfo.ResourceStep;
		}
		this->TimeToHarvest = std::max<int>(1, wait_at_resource * SPEEDUP_FACTOR / (unit.Player->SpeedResourcesHarvest[resinfo.ResourceId] + goal->Variable[TIMEEFFICIENCYBONUS_INDEX].Value));
		//Wyrmgus end
	} else {
		this->TimeToHarvest = 1;
	}
	this->DoneHarvesting = 0;
	return 1;
}
예제 #9
0
/**
**  Wait in depot, for the resources stored.
**
**  @param unit  Pointer to unit.
**
**  @return      TRUE if ready, otherwise FALSE.
*/
bool COrder_Resource::WaitInDepot(CUnit &unit)
{
	const ResourceInfo &resinfo = *unit.Type->ResInfo[this->CurrentResource];
	const CUnit *depot = ResourceDepositOnMap(unit.tilePos, resinfo.ResourceId);

	//Assert(depot);

	// Range hardcoded. don't stray too far though
	//Wyrmgus start
//	if (resinfo.TerrainHarvester) {
	if (!this->Resource.Mine) {
	//Wyrmgus end
		Vec2i pos = this->Resource.Pos;

		//Wyrmgus start
//		if (FindTerrainType(unit.Type->MovementMask, MapFieldForest, 10, *unit.Player, pos, &pos)) {
		if ((this->CurrentResource == WoodCost && FindTerrainType(unit.Type->MovementMask, MapFieldForest, 10, *unit.Player, pos, &pos)) || (this->CurrentResource == StoneCost && FindTerrainType(unit.Type->MovementMask, MapFieldRocks, 10, *unit.Player, pos, &pos))) {
		//Wyrmgus end
			if (depot) {
				DropOutNearest(unit, pos, depot);
			}
			this->goalPos = pos;
			//Wyrmgus start
			if (this->CurrentResource == WoodCost) { //tree tiles can regrow, so we need to check if any have regrown closer to the worker
				Vec2i forestPos;
				int max_forest_range = std::max<int>(abs(unit.tilePos.x - this->goalPos.x), abs(unit.tilePos.y - this->goalPos.y));
				if (FindTerrainType(unit.Type->MovementMask, MapFieldForest, max_forest_range, *unit.Player, unit.tilePos, &forestPos)) {
					if (PlaceReachable(unit, forestPos, 1, 1, 0, 1, max_forest_range * 4)) {
						this->goalPos = forestPos;
					}
				}
			}
			//Wyrmgus end
		} else {
			if (depot) {
				DropOutOnSide(unit, LookingW, depot);
			}
			this->Finished = true;
			return false;
		}
	} else {
		const unsigned int tooManyWorkers = 15;
		CUnit *mine = this->Resource.Mine;
		const int range = 15;
		CUnit *newdepot = NULL;
		CUnit *goal = NULL;
		const bool longWay = unit.pathFinderData->output.Cycles > 500;

		//Wyrmgus start
//		if (unit.Player->AiEnabled && AiPlayer && AiPlayer->BuildDepots) {
		if (depot && unit.Player->AiEnabled && AiPlayer && AiPlayer->BuildDepots) { //check if the depot is valid
		//Wyrmgus end
			// If the depot is overused, we need first to try to switch into another depot
			// Use depot's ref counter for that
			if (longWay || !mine || (depot->Refs > tooManyWorkers)) {
				newdepot = AiGetSuitableDepot(unit, *depot, &goal);
				if (newdepot == NULL && longWay) {
					// We need a new depot
					AiNewDepotRequest(unit);
				}
			}
		}

		// If goal is not NULL, then we got it in AiGetSuitableDepot
		if (!goal) {
			goal = UnitFindResource(unit, newdepot ? *newdepot : (mine ? *mine : unit), mine ? range : 1000,
									this->CurrentResource, unit.Player->AiEnabled, newdepot ? newdepot : depot);
		}

		if (goal) {
			if (depot) {
				DropOutNearest(unit, goal->tilePos + goal->Type->GetHalfTileSize(), depot);
			}

			if (goal != mine) {
				if (mine) {
					unit.DeAssignWorkerFromMine(*mine);
				}
				unit.AssignWorkerToMine(*goal);
				this->Resource.Mine = goal;
			}
			this->SetGoal(goal);
			this->goalPos.x = this->goalPos.y = -1;
		} else {
#ifdef DEBUG
			const Vec2i &pos = mine ? mine->tilePos : unit.tilePos;
			DebugPrint("%d: Worker %d report: [%d,%d] Resource gone near [%d,%d] in range %d. Sit and play dumb.\n"
					   _C_ unit.Player->Index _C_ UnitNumber(unit)
					   _C_ unit.tilePos.x _C_ unit.tilePos.y
					   _C_ pos.x _C_ pos.y _C_ range);
#endif // DEBUG
			if (depot) {
				DropOutOnSide(unit, LookingW, depot);
			}
			if (mine) {
				unit.DeAssignWorkerFromMine(*mine);
				this->Resource.Mine = NULL;
			}
			this->Finished = true;
			return false;
		}
	}
	return true;
}
예제 #10
0
//Wyrmgus start
//static int AiAssignHarvesterFromUnit(CUnit &unit, int resource)
static int AiAssignHarvesterFromUnit(CUnit &unit, int resource, int resource_range)
//Wyrmgus end
{
	// Try to find the nearest depot first.
	CUnit *depot = FindDeposit(unit, 1000, resource);
	
	// Find a resource to harvest from.
	//Wyrmgus start
//	CUnit *mine = UnitFindResource(unit, depot ? *depot : unit, 1000, resource, true);
	CUnit *mine = UnitFindResource(unit, depot ? *depot : unit, resource_range, resource, true, NULL, false);
	//Wyrmgus end

	if (mine) {
		//Wyrmgus start
//		CommandResource(unit, *mine, FlushCommands);
//		return 1;
		if (mine->Type->BoolFlag[CANHARVEST_INDEX].value) {
			CommandResource(unit, *mine, FlushCommands);
			return 1;
		} else { // if the resource isn't readily harvestable (but is a deposit), build a mine there
			const int n = AiHelpers.Refinery[resource - 1].size();

			for (int i = 0; i < n; ++i) {
				CUnitType &type = *AiHelpers.Refinery[resource - 1][i];

				if (CanBuildUnitType(&unit, type, mine->tilePos, 1, true, mine->MapLayer)) {
					CommandBuildBuilding(unit, mine->tilePos, type, FlushCommands, mine->MapLayer);
					return 1;
				}
			}
		}
		//Wyrmgus end
	}
	
	//Wyrmgus start
	/*
	int exploremask = 0;

	for (size_t i = 0; i != UnitTypes.size(); ++i) {
		const CUnitType *type = UnitTypes[i];

		if (type && type->GivesResource == resource) {
			switch (type->UnitType) {
				case UnitTypeLand:
					exploremask |= MapFieldLandUnit;
					break;
				case UnitTypeFly:
					exploremask |= MapFieldAirUnit;
					break;
				//Wyrmgus start
				case UnitTypeFlyLow:
					exploremask |= MapFieldLandUnit;
					break;
				//Wyrmgus end
				case UnitTypeNaval:
					exploremask |= MapFieldSeaUnit;
					break;
				default:
					Assert(0);
			}
		}
	}
	// Ask the AI to explore
	AiExplore(unit.tilePos, exploremask);
	*/
	//Wyrmgus end
	// Failed.
	return 0;
}