private void DevelopFlowMap() { if (nodeList.Count == 0) { //seed list elementToMove.SetStatusMessage("Looking for path"); MapNode newNode; newNode.nodeLocation = new Vector2(elementToMove.getWorldPositionX(), elementToMove.getWorldPositionY()); newNode.nodePreviousLocation = new Vector2(elementToMove.getWorldPositionX(), elementToMove.getWorldPositionY()); nodeList.Add(newNode); nextListTarget = 0; checkedMap[elementToMove.getWorldPositionX(), elementToMove.getWorldPositionY()] = true; //check to see if my end target is populated already, and if I should shift my target if (associatedMap.getOccupied(this.destination)) { if (associatedMap.getOccupyingElement(this.destination).Idle() || (associatedMap.getOccupyingElement(this.destination).GetStuck())) { this.destination = associatedMap.FindNearest(originalDestination, "Empty"); } } } else { //check if target was populated if (associatedMap.getOccupied(destination)) { if (associatedMap.getOccupyingElement(destination).GetMovable() && !associatedMap.getOccupyingElement(destination).Idle() && !associatedMap.getOccupyingElement(destination).GetStuck()) { nodeList.Clear(); } } //grow list if (nextListTarget >= nodeList.Count) { reattemptCounter++; EventMoveTo reattempt = new EventMoveTo(associatedGame, associatedMap, elementToMove, associatedMap.FindNearest(originalDestination, "Empty"), this.gameTime); //transfer the calling event to the new event as we are giving up control reattempt.setCallingEvent(this.GetCallingEvent()); reattempt.SetReattemptCounter(reattemptCounter); reattempt.SetOriginalDestination(originalDestination); elementToMove.ReplaceLinkedMovement(reattempt); this.SetComplete(); callingEventManager.AddEvent(reattempt); } else { //still nodes to check //check 4 cardinal directions for (int i = 0; i < 4; i++) { Vector2 newNodeLocation = new Vector2(nodeList[nextListTarget].nodeLocation.X, nodeList[nextListTarget].nodeLocation.Y); if (i == 0 && newNodeLocation.Y > 0) { newNodeLocation.Y--; //North } if (i == 1 && newNodeLocation.X < associatedMap.getNumberTilesX() - 1) { newNodeLocation.X++; //East } if (i == 2 && newNodeLocation.Y < associatedMap.getNumberTilesY() - 1) { newNodeLocation.Y++; //South } if (i == 3 && newNodeLocation.X > 0) { newNodeLocation.X--; //West } //if they are already checked - ignore if (checkedMap[(int)newNodeLocation.X, (int)newNodeLocation.Y] == false) { checkedMap[(int)newNodeLocation.X, (int)newNodeLocation.Y] = true; //if they are already occupied - ignore if (!associatedMap.getOccupied(newNodeLocation)) { //at this point it is safe to assume this is a usable node and add it to the list MapNode nodeToAdd; nodeToAdd.nodeLocation = newNodeLocation; nodeToAdd.nodePreviousLocation = new Vector2(nodeList[nextListTarget].nodeLocation.X, nodeList[nextListTarget].nodeLocation.Y); nodeList.Add(nodeToAdd); //If this new point was our destination - complete this step if (nodeToAdd.nodeLocation.Equals(destination)) { elementToMove.SetStatusMessage("Found Path"); flowMapProduced = true; //start next step i = 4; //exit for loop } } } } //increment next list target for next cycle nextListTarget++; } } }
private void PerformNextMove() { bool canContinue = true; //Check if we have successfully moved, otherwise reattempt is occupier is moving if ((int)currentPath[1].X == elementToMove.getWorldPositionX() && (int)currentPath[1].Y == elementToMove.getWorldPositionY()) { //remove that step currentPath.RemoveAt(0); } else { if (associatedMap.getOccupied(new Vector2(currentPath[1].X, currentPath[1].Y))) { if (associatedMap.getOccupyingElement(new Vector2(currentPath[1].X, currentPath[1].Y)).GetMovable()) { if (elementToMove.GetStuck()) { //already stuck, stop movement elementToMove.KillLinkedMovement(); this.ShutdownSmoothly(); } else { elementToMove.SetStuck(true); } elementToMove.SetStatusMessage("Someone is in my spot!"); this.ShutdownSmoothly(); //instead of kill canContinue = false; if (associatedMap.getOccupied(elementToMove.GetFinalDestination())) { if (!associatedMap.getOccupyingElement(elementToMove.GetFinalDestination()).Moving()) { reattemptCounter++; EventMoveTo reattempt = new EventMoveTo(associatedGame, associatedMap, elementToMove, associatedMap.FindNearest(originalDestination, "Empty"), this.gameTime); //transfer the calling event to the new event as we are giving up control reattempt.setCallingEvent(this.GetCallingEvent()); reattempt.SetReattemptCounter(reattemptCounter); reattempt.SetOriginalDestination(originalDestination); elementToMove.ReplaceLinkedMovement(reattempt); callingEventManager.AddEvent(reattempt); } else { reattemptCounter++; EventMoveTo reattempt = new EventMoveTo(associatedGame, associatedMap, elementToMove, destination, this.gameTime); //transfer the calling event to the new event as we are giving up control reattempt.setCallingEvent(this.GetCallingEvent()); reattempt.SetReattemptCounter(reattemptCounter); elementToMove.ReplaceLinkedMovement(reattempt); callingEventManager.AddEvent(reattempt); } } else { reattemptCounter++; EventMoveTo reattempt = new EventMoveTo(associatedGame, associatedMap, elementToMove, destination, this.gameTime); //transfer the calling event to the new event as we are giving up control reattempt.setCallingEvent(this.GetCallingEvent()); reattempt.SetReattemptCounter(reattemptCounter); elementToMove.ReplaceLinkedMovement(reattempt); callingEventManager.AddEvent(reattempt); } } } } if (canContinue) { Event nextMove = new EventMoveTo(associatedGame, associatedMap, elementToMove, currentPath[1], this.gameTime); callingEventManager.AddEvent(nextMove); //suspend until that move event ends this.Suspend(nextMove); } else { this.SetComplete(); } }