public static FullTask MakeBuildingMaterialTask(WorldManager manager, int searchDepth, GameTime gameTime, int priority) { HashSet<Carryable> validResources = new HashSet<Carryable>(); HashSet<Point> startPoints = new HashSet<Point>(); HashSet<Point> goalPoints = new HashSet<Point>(); BuildingMaterialTask task = new BuildingMaterialTask(priority); foreach (Building building in manager.Buildings) { foreach (Point point in building.AvailableSquares(BuildingInteractionType.LOAD_BUILDING_MATERIALS)) { building.MarkSquare(point.X, point.Y, task, BuildingInteractionType.LOAD_BUILDING_MATERIALS); validResources.Clear(); startPoints.Clear(); goalPoints.Clear(); goalPoints.Add(point); bool foundValidResource = false; foreach (Carryable car in manager.Carryables) { if (car.IsAvailableForUse && building.DoesResourceFitNeed(point.X, point.Y, car)) { foundValidResource = true; validResources.Add(car); startPoints.Add(car.SquareCoordinate); car.MarkForCollection(task); } } if (!foundValidResource) //clean up, move on { building.UnMarkSquare(point.X, point.Y, task, BuildingInteractionType.LOAD_BUILDING_MATERIALS); continue; } //atempt to path Path pathFromResourceToBuildingCell = PathHunter.GetPath(startPoints, goalPoints, searchDepth, manager, gameTime); //if no path, clean up and move on if (pathFromResourceToBuildingCell == null) { building.UnMarkSquare(point.X, point.Y, task, BuildingInteractionType.LOAD_BUILDING_MATERIALS); foreach (Carryable car in validResources) car.UnMarkForCollection(task); continue; } foundValidResource = false; Carryable taskResource = null; foreach (Carryable car in validResources) { if (!foundValidResource && car.SquareCoordinate == pathFromResourceToBuildingCell.Start) { taskResource = car; foundValidResource = true; } else { car.UnMarkForCollection(task); } } PickupStep pickupStep = new PickupStep(null, task, taskResource); BuildingMaterialStep materialStep = new BuildingMaterialStep(pathFromResourceToBuildingCell, taskResource, building, task); task.AddNewTask(pickupStep); task.AddNewTask(materialStep); task.Freeze(); return task; } } return null; }
/// <summary> /// Returns a new TaskList corresponding to hauling some resource /// to some stockpile, if possible. Returns null otherwise. /// </summary> /// <param name="manager"></param> /// <param name="searchDepth"></param> /// <param name="currentTime"></param> /// <param name="priority"></param> /// <returns></returns> public static FullTask MakeHaulingTask(WorldManager manager, int searchDepth, GameTime currentTime, int priority) { HaulingTask outputTaskList = new HaulingTask(priority); HashSet<Point> resourceLocations = new HashSet<Point>(); HashSet<Tuple<Point, Carryable>> markedResources = new HashSet<Tuple<Point, Carryable>>(); HashSet<Point> stockpileLocations = new HashSet<Point>(); HashSet<Tuple<Point, Stockpile>> markedStockpiles = new HashSet<Tuple<Point, Stockpile>>(); //mark all the resources foreach (Carryable car in manager.Carryables) { if (car.ShouldBeMarkedForHauling) { resourceLocations.Add(car.SquareCoordinate); car.MarkForCollection(outputTaskList); markedResources.Add(new Tuple<Point, Carryable>(car.SquareCoordinate, car)); } } //mark all the stockpiles foreach (Stockpile pile in manager.Stockpiles) { if (pile.HasAvailableSquare(BuildingInteractionType.STORAGE)) { Point point = pile.GetNextAvailableSquare(BuildingInteractionType.STORAGE); stockpileLocations.Add(point); pile.MarkSquare(point.X, point.Y, outputTaskList, BuildingInteractionType.STORAGE); markedStockpiles.Add(new Tuple<Point, Stockpile>(point, pile)); } } //attempt to path Path foundPath = PathHunter.GetPath(resourceLocations, stockpileLocations, searchDepth, manager, currentTime); if (foundPath == null) { //if impossible, clear out the marked stuff... foreach (Tuple<Point, Carryable> tup in markedResources) tup.Item2.UnMarkForCollection(outputTaskList); foreach (Tuple<Point, Stockpile> tup in markedStockpiles) tup.Item2.UnMarkSquare(tup.Item1.X, tup.Item1.Y, outputTaskList, BuildingInteractionType.STORAGE); //and give up return null; } else { //first, find the resource Tuple<Point, Carryable> toPickUp = null; foreach (Tuple<Point, Carryable> tup in markedResources) { if (toPickUp == null && tup.Item1 == foundPath.Start) toPickUp = tup; else tup.Item2.UnMarkForCollection(outputTaskList); } if (toPickUp == null) throw new InvalidOperationException(); //now make that task up! TaskStep pickupTask = new PickupStep(null, outputTaskList, toPickUp.Item2); outputTaskList.AddNewTask(pickupTask); //now, find the stockpile Tuple<Point, Stockpile> goalPile = null; foreach (Tuple<Point, Stockpile> tup in markedStockpiles) { if (goalPile == null && tup.Item1 == foundPath.End) goalPile = tup; else tup.Item2.UnMarkSquare(tup.Item1.X, tup.Item1.Y, outputTaskList, BuildingInteractionType.STORAGE); } if (goalPile == null) throw new InvalidOperationException(); //make THAT task TaskStep putdownTask = new StockpileStep(foundPath, toPickUp.Item2, goalPile.Item2, outputTaskList); outputTaskList.AddNewTask(putdownTask); //freeze and send out! outputTaskList.Freeze(); return outputTaskList; } }