public Job TakeClosestJobToTile(Tile t) { Job found = null; int distance = int.MaxValue; foreach (var job in _jobQueue) { var route = new Path_AStar() { World = World.Instance, Start = t, End = job.Tile }; route.Calculate(); if (found == null || route.Length() < distance) { found = job; distance = route.Length(); } } if (found != null) { _jobQueue.Remove(found); } return(found); }
bool Update_DoJob(float deltaTime) { if (myJob == null) { myJob = currTile.world.jobQueue.Dequeue(); if (myJob != null) { //We have a job! destTile = myJob.tile; myJob.RegisterJobCancelCallback(OnJobEnded); myJob.RegisterJobCompleteCallback(OnJobEnded); } } if (currTile == destTile) { pathAStar = null; if (myJob != null) { myJob.DoWork(deltaTime); } return(false); } return(true); }
public Path_AStar GetPathToClosestInventoryOfType(string objectType, Tile t, int desiredAmount, bool canTakeFromStockpile) { QuickCheck(objectType); // We can also avoid going through the Astar construction if we know // that all available inventories are stockpiles and we are not allowed // to touch those if (!canTakeFromStockpile && inventories[objectType].TrueForAll(i => i.tile != null && i.tile.Furniture != null && i.tile.Furniture.IsStockpile())) { return(null); } // We shouldn't search if all inventories are locked. if (inventories[objectType].TrueForAll(i => i.tile != null && i.tile.Furniture != null && i.tile.Inventory != null && i.tile.Inventory.locked)) { return(null); } // Test that there is at least one stack on the floor, otherwise the // search below might cause a full map search for nothing. if (inventories[objectType].Find(i => i.tile != null) == null) { return(null); } // We know the objects are out there, now find the closest. Path_AStar path = new Path_AStar(World.Current, t, null, objectType, desiredAmount, canTakeFromStockpile); return(path); }
public void AbandonJob() { nextTile = destTile = currTile; path_AStar = null; currTile.world.jobsQueue.Enqueue(myJob); myJob = null; }
public void AbandonJob() { nextTile = destTile = currTile; path_AStar = null; WorldController.Instance.World.jobQueue.Enqueue(myJob); myJob = null; }
/// <summary> /// Get a job from the world list and tests it reachability. /// </summary> /// <returns>True if succeeded</returns> void GetNewJob() { myJob = currTile.world.jobQueue.Dequeue(); if (myJob == null) { // There was no job on the queue for us, so just return false. return; } // We have a Job! // Immediately check if the job tile is reachable // NOTE: We might not be pathing to it right away. // Set job's nearest walkable tile as destination //destTile = GetNearestWalkableNeighbour(myJob.tile); destTile = myJob.tile; // Job Ended Callback myJob.RegisterJobCancelCallback(OnJobEnded); myJob.RegisterJobCompleteCallback(OnJobEnded); // Try to get a pathfinding from character to destTile. pathAStar = new Path_AStar(WorldController.Instance.world, currTile, destTile); if (pathAStar.Lenght() == 0) { // Pathfinding couldn't get a path to the destination. Debug.LogError("Path_AStar returned no path to target job tile!"); // Re-enqueue Job, set current to null and return false. AbandonJob(); return; } return; }
public void AbandonJob(bool ReEnqueue = true) { this.nextTile = this.destTile = this.currTile; this.pathAStar = null; this.currTile.world.jobQueue.Enqueue(this.currJob); this.currJob = null; }
void GetNewJob() { // Get the first job on the queue. myJob = World.current.jobQueue.Dequeue(); if (myJob == null) { myJob = new Job(CurrTile, "Waiting", null, UnityEngine.Random.Range(0.1f, 0.5f), null, false); } // Get our destination from the job DestTile = myJob.tile; myJob.cbJobStopped += OnJobStopped; // Immediately check to see if the job tile is reachable. // NOTE: We might not be pathing to it right away (due to // requiring materials), but we still need to verify that the // final location can be reached. Profiler.BeginSample("PathGeneration"); pathAStar = new Path_AStar(World.current, CurrTile, DestTile); // This will calculate a path from curr to dest. Profiler.EndSample(); if (pathAStar.Length() == 0) { Debug.LogError("Path_AStar returned no path to target job tile!"); AbandonJob(); DestTile = CurrTile; } }
void GetNewJob() { myJob = World.Current.jobQueue.Dequeue(); if (myJob == null) { myJob = new Job(CurrTile, "Waiting", null, UnityEngine.Random.Range(0.1f, 0.5f), null, false); } DestTile = myJob.tile; myJob.cbJobStopped += OnJobStopped; // Immediately check to see if the job tile is reachable pathAStar = new Path_AStar(World.Current, CurrTile, DestTile); // This will calculate path from curr to dest if (pathAStar.Length() == 0) { Debug.LogError("Path_AStar returned no path to destination!"); AbandonJob(); DestTile = CurrTile; } }
/// <summary> /// Grab a new job from the queue. This will first check if the tile is reachable. /// </summary> private void GetNewJob() { // Grab job from jobQueue currentJob = currentTile.World.jobQueue.Dequeue(); if (currentJob == null) { return; } // Set the destinationtile DestinationTile = currentJob.tile; // Add job callback actions currentJob.RegisterJobCancelCallback(OnJobEnded); currentJob.RegisterJobCompleteCallback(OnJobEnded); // Check if the job tile is reachable // NOTE: We might not be pathing to it right away (due to requiring materials), // but we still need to verify that the final tile is reachalbe. #region Check tile is reachable // Generate new A* path from currentTile to destinationTile path_AStar = new Path_AStar(currentTile.World, currentTile, DestinationTile); // Check if path isn't null if (path_AStar.Length() == 0) { Debug.LogError("Path_AStar: Returned no path to target job tile!"); // FIXME: Job should get added back to queue AbandonJob(); DestinationTile = currentTile; } #endregion }
/* #################################################################### */ /* # METHODS # */ /* #################################################################### */ public void AbandonJob() { nextTile = destTile = currTile; pathAStar = null; currTile.World.JobQueue.Enqueue(myJob); myJob = null; }
void AbandonJob() { nextTile = destTile = currTile; path = null; // FIXME BLUEPRINT CONTROLLER 25, JOBQUEUE 21; CHARACTER 68/85/115; WORLD 52; WORLDCOMTROLLER 26 - ELEMENT WITH THE SAME KEY ALLREADY EXISTS currTile.World.jobQueue.Enqueue(myJob); myJob = null; }
public void AbandonJob() { Debug.Log("Character Abandon Job"); nextTile = destTile = currTile; pather = null; currTile.world.jobQueue.Enqueue(myJob, true); myJob = null; }
void StopMove() { isMoving = false; movePercent = 0; SetDirection(); path = null; //aI_Controller.anim.SetTrigger("idle"); }
void UpdateDoMovement(float deltaTime) { if (currentTile == destinationTile) { pathAStar = null; return; } if (nextTile == null || nextTile == currentTile) { if (pathAStar == null || pathAStar.count() == 0) { pathAStar = new Path_AStar(World.worldInstance, currentTile, destinationTile); if (pathAStar.count() == 0) { Debug.LogError("Path_AStar -- returned (0) no path to destinationTile"); AbbandonJob(); return; } pathAStar.Dequeue(); } nextTile = pathAStar.Dequeue(); /*if (nextTile == destinationTile) { * nextTile = currentTile; * destinationTile = currentTile; * }*/ } float distanceToTravel = Mathf.Sqrt(Mathf.Pow(currentTile.X - nextTile.X, 2) + Mathf.Pow(currentTile.Y - nextTile.Y, 2)); if (nextTile.isAccessible() == Accessiblity.NEVER) { Debug.LogError("Charcter tried to enter in unwalkable tile"); nextTile = null; pathAStar = null; return; } else if (nextTile.isAccessible() == Accessiblity.SOON) { return; } float distanceThisFrame = speed / nextTile.movementCost * deltaTime; float percentageThisFrame = distanceThisFrame / distanceToTravel; movementPercentage += percentageThisFrame; if (movementPercentage >= 1) { currentTile = nextTile; movementPercentage = 0; } }
private BehaviourTreeStatus DoWork_Action(float deltaTime) { // Debug.Log("DoWork_Action"); // If there isn't a current job, that probably means while this step was running, the job was completed. if (CurrentJob == null) { if (DebugAi) { Debug.Log(Name + ": DoWork returning success"); } return(BehaviourTreeStatus.Success); } // TODO: Not sure if we need to check this - that should've been handled by the preceeding actions. Can jobs move by themselves? var rangeToJob = 0; if (CurrentTile == CurrentJob.Tile) { // We're stood on the Job site. rangeToJob = 0; } if (_path != null) { // We're stood close enough to the job site. rangeToJob = _path.Length(); } // If we're too far from the job site, something went wrong. if (rangeToJob > CurrentJob.MinRange) { if (DebugAi) { Debug.Log(Name + ": DoWork returning failure"); } return(BehaviourTreeStatus.Failure); } // Debug.LogFormat("DoWork_Action working job \"{3}\" at [{0},{1}] ({2:F2})", CurrentTile.X, CurrentTile.Y, CurrentJob.JobTime, CurrentJob.Name); CurrentState = State.WorkingJob; // Set dest to current, just in case it was the proximity-check that got us here. DestinationTile = CurrentTile; _path = null; // Do some work. CurrentJob.DoWork(deltaTime); if (DebugAi) { Debug.Log(Name + ": DoWork returning running"); } return(BehaviourTreeStatus.Running); }
void Update_DoMovement(float deltaTime) { if (CurrentTile == _destTile) { CurrentTile.SetUnit(this); _pathAStar = null; return; // We're already were we want to be. } if (_nextTile == null || _nextTile == CurrentTile) { // Get the next tile from the pathfinder. if (_pathAStar == null || _pathAStar.Length() == 0) { // Generate a path to our destination CurrentTile.SetUnit(null); _pathAStar = new Path_AStar(CurrentTile.World, CurrentTile, _destTile); // This will calculate a path from curr to dest. if (_pathAStar.Length() == 0) { Debug.LogError("Path_AStar returned no path to destination!"); _destTile = CurrentTile; _pathAStar = null; return; } } // Grab the next waypoint from the pathing system! _nextTile = _pathAStar.Dequeue(); } float distToTravel = Mathf.Sqrt( Mathf.Pow(CurrentTile.X - _nextTile.X, 2) + Mathf.Pow(CurrentTile.Y - _nextTile.Y, 2) ); // How much distance can be travel this Update? float distThisFrame = Speed * deltaTime; // How much is that in terms of percentage to our destination? float percThisFrame = distThisFrame / distToTravel; // Add that to overall percentage travelled. _movementPercentage += percThisFrame; if (_movementPercentage >= 1) { // We have reached our destination // If there are no more tiles, then we have TRULY // reached our destination. CurrentTile = _nextTile; _movementPercentage = 0; } }
public static Room FindNearestRoom(Tile start) { Path_AStar tileResolver = new Path_AStar(World.Current, start, GoalHasRoomEvaluator(), DijkstraDistance()); if (tileResolver.Length() >= 1) { return(tileResolver.EndTile().Room); } return(null); }
public void AbandonJob() { myJob.UnRegisterJobCompleteCallback(OnJobEnded); myJob.UnRegisterJobCanceledCallback(OnJobEnded); nextTile = currTile; destTile = null; mainPath = null; WorldController.Instance.World.jobQueue.Requeue(myJob); //TODO: Puts the job back on the jobQueue, might not be best idea?? myJob = null; }
public void OnJobEnded(Job j) { if (this.currJob != j) { Debug.LogError("Job does not match the current job this character is handling."); return; } this.nextTile = this.destTile = this.currTile; this.pathAStar = null; this.currJob = null; }
public void PrioritizeJob(Job job) { AbandonJob(false); World.Current.jobQueue.Remove(job); job.IsBeingWorked = true; /*Check if the character is carrying any materials and if they could be used for the new job, * if the character is carrying materials but is not used in the new job, then drop them * on the current tile for now.*/ if (inventory != null && !job.inventoryRequirements.ContainsKey(inventory.ObjectType)) { World.Current.inventoryManager.PlaceInventory(CurrTile, inventory); DumpExcessInventory(); } MyJob = job; // Get our destination from the job. DestTile = MyJob.tile; // If the destination tile does not have neighbours that are walkable it's very likable that they can't be walked to. if (DestTile.HasWalkableNeighbours() == false) { Debug.ULogChannel("Character", "No neighbouring floor tiles! Abandoning job."); AbandonJob(false); return; } MyJob.OnJobStopped += OnJobStopped; pathAStar = new Path_AStar(World.Current, CurrTile, DestTile); if (pathAStar != null && pathAStar.Length() == 0) { Debug.ULogChannel("Character", "Path_AStar returned no path to target job tile!"); AbandonJob(false); return; } if (MyJob.adjacent) { IEnumerable <Tile> reversed = pathAStar.Reverse(); reversed = reversed.Skip(1); pathAStar = new Path_AStar(new Queue <Tile>(reversed.Reverse())); DestTile = pathAStar.EndTile(); jobTile = DestTile; } else { jobTile = MyJob.tile; } }
public Path_AStar GetPathToClosestInventoryOfType(string objectType, Tile t, int desiredAmount, bool canTakeFromStockpile) { if (inventories.ContainsKey(objectType) == false) { //Debug.LogError("GetClosestInventoryType -- no itmes of desired type."); return(null); } Path_AStar path = new Path_AStar(World.Current, t, null, objectType, desiredAmount, canTakeFromStockpile); return(path); }
bool find_If_Tile_Job_Is_Rechable(Vector3Int jobTile) { Path_AStar path_to_job = new Path_AStar(WorldController.Instance.World, currTile, jobTile); if (path_to_job.Length() == 0) { return(false); } else { return(true); } }
/// <summary> /// Finds the path to any inventory with type in <paramref name="types"/> /// </summary> public static List <Tile> FindPathToInventory(Tile start, string[] types, bool canTakeFromStockpile = true) { if (start == null || types == null || types.Length == 0) { return(null); } RoomPath_AStar roomResolver = new RoomPath_AStar(World.Current, start.GetNearestRoom(), RoomGoalInventoryEvaluator(types, canTakeFromStockpile), RoomHeuristic()); List <Room> roomPath = roomResolver.GetList(); if (roomPath.Count >= 1) { Tile nearestExit; if (roomPath.Count == 1) { nearestExit = start; } else { nearestExit = GetNearestExit(roomPath); } Tile targetTile = null; float distance = 0f; foreach (Inventory inventory in World.Current.InventoryManager.Inventories.Where(dictEntry => types.Contains(dictEntry.Key)).SelectMany(dictEntry => dictEntry.Value)) { if (inventory.Tile == null || !inventory.CanBePickedUp(canTakeFromStockpile)) { continue; } if (targetTile == null || Vector3.Distance(nearestExit.Vector3, inventory.Tile.Vector3) < distance) { distance = Vector3.Distance(nearestExit.Vector3, inventory.Tile.Vector3); targetTile = inventory.Tile; } } return(FindPathToTile(start, targetTile)); } else { // Since we don't have a roomPath, someone's done something weird, like a room of doors, so just use Dijkstra to find our way Path_AStar resolver = new Path_AStar(World.Current, start, GoalInventoryEvaluator(types, canTakeFromStockpile), DijkstraDistance()); List <Tile> path = resolver.GetList(); return(path); } }
/// <summary> /// Finds the path to a nearby tile where inventory of type <paramref name="type"/> can be dumped. /// </summary> public static List <Tile> FindPathToDumpInventory(Tile start, string type, int amount) { if (start == null || type == null || amount <= 0) { return(null); } Path_AStar resolver = new Path_AStar(World.Current, start, GoalCanFitInventoryEvaluator(type, amount), DijkstraDistance()); List <Tile> path = resolver.GetList(); DebugLogIf(path.Count > 0, "FindPathToDumpInventory from: {0}, to: {1}, found {2} [Length: {3}, took: {4}ms]", start, type, path.LastOrDefault(), path.Count, (int)(resolver.Duration * 1000)); DebugLogIf(path == null, "Failed to find path to furniture of type {0}", type); return(path); }
/// <summary> /// Finds the path to an inventory of type <paramref name="type"/>. /// </summary> public static List <Tile> FindPathToInventory(Tile start, string type, bool canTakeFromStockpile = true) { if (start == null || type == null) { return(null); } Path_AStar resolver = new Path_AStar(World.Current, start, GoalInventoryEvaluator(type, canTakeFromStockpile), DijkstraDistance()); List <Tile> path = resolver.GetList(); DebugLogIf(path.Count > 0, "FindPathToInventory from: {0}, to: {1}, found {2} [Length: {3}, took: {4}ms]", start, type, path.LastOrDefault(), path.Count, (int)(resolver.Duration * 1000)); DebugLogIf(path == null, "Failed to find path to inventory of type {0}", type); return(path); }
public Path_AStar GetClosestPathToInventoryOfType(string objectType, Tile t, int desiredQty, bool searchInStockpiles) { if (Inventories.ContainsKey(objectType) == false) { return(null); } var path = new Path_AStar() { World = World.Instance, Start = t, ObjectType = objectType, CanTakeFromStockpile = true }; path.Calculate(); return(path); }
void Update_Movement(float deltaTime) { if (currTile == destTile) { path = null; return; // we are where we want to be; } if (nextTile == null || nextTile == currTile) { //pathfind next tile if (path == null || path.Lenght() == 0) { path = new Path_AStar(currTile.World, currTile, destTile); if (path.Lenght() == 0) { //Debug.Log ("no path to dest"); //FIXME job maybe must be reenqued instead; AbandonJob(); //FIXME cancel Job; return; } } //grab next tile nextTile = path.DequeueNextTile(); if (nextTile == currTile) { //Debug.LogError ("Update movement - next tile is currtile"); } } //total distance float distToTravel = Mathf.Sqrt(Mathf.Pow(currTile.X - nextTile.X, 2) + Mathf.Pow(currTile.Y - nextTile.Y, 2)); // float distThisFrame = speed * deltaTime; float percThisFrame = distThisFrame / distToTravel; movementPercentage += percThisFrame; if (movementPercentage >= 1) { currTile = nextTile; movementPercentage = 0; // FIXME => overshotmovement????? } }
/// <summary> /// Finds the path to furniture. /// </summary> /// <returns>The path to furniture.</returns> /// <param name="start">Start tile.</param> /// <param name="objectType">Object type of the furniture.</param> public static List <Tile> FindPathToFurniture(Tile start, string type) { if (start == null || type == null) { return(null); } RoomPath_AStar roomResolver = new RoomPath_AStar(World.Current, start.GetNearestRoom(), RoomGoalFurnitureEvaluator(type), RoomHeuristic()); List <Room> roomPath = roomResolver.GetList(); if (roomPath.Count >= 1) { Tile nearestExit; if (roomPath.Count == 1) { nearestExit = start; } else { nearestExit = GetNearestExit(roomPath); } Tile targetTile = null; float distance = float.MaxValue; foreach (Furniture furniture in World.Current.FurnitureManager.Where(furniture => furniture.Type == type)) { if (Vector3.Distance(nearestExit.Vector3, furniture.Tile.Vector3) < distance) { distance = Vector3.Distance(nearestExit.Vector3, furniture.Tile.Vector3); targetTile = furniture.Tile; } } return(FindPathToTile(start, targetTile)); } else { // Since we don't have a roomPath, someone's done something weird, like a room of doors, so just use Dijkstra to find our way Path_AStar resolver = new Path_AStar(World.Current, start, GoalFurnitureEvaluator(type), DijkstraDistance()); List <Tile> path = resolver.GetList(); return(path); } }
// Start Pathfinding from Start to Goal tile public bool StartPathfinding() { Debug.Log("Start Path Finding"); if (World.startTile == null || World.goalTile == null) { Debug.LogError("No Start or Goal tile"); return(false); } Path_AStar oldPathAStar = pathAStar; // Update old path way not valid anymore if (oldPathAStar != null) { foreach (Tile t in oldPathAStar.Path()) { //Debug.Log("Old Path:"+ tileGraphicController.tileGameObjectMap[t] ); t.isPathway = false; tileGraphicController.tileGameObjectMap[t].GetComponent <GroundCube>().UpdatePathfindingGraphic(); } } // Generate New pathway pathAStar = new Path_AStar(true, World.startTile, World.goalTile); if (pathAStar.Length() == 0) { // No valid Pathfinding way Debug.LogError("Path_AStar returned no path to destination!"); pathAStar = null; return(false); } else { foreach (Tile t in pathAStar.Path()) { t.isPathway = true; tileGraphicController.tileGameObjectMap[t].GetComponent <GroundCube>().UpdatePathfindingGraphic(); } return(true); } }