private void ReserveShipMoveTask(ShipMoveTask task) { if (task.connection == null) { return; } if (!reservationOnConnections.ContainsKey(task.connection)) { reservationOnConnections.Add(task.connection, new List <Reservation>()); } List <Reservation> reservationList = reservationOnConnections[task.connection]; Reservation reservation = new Reservation(); reservation.StartTime = task.StartTime - safetyTime; reservation.EndTime = task.EndTime + safetyTime; reservationList.Add(reservation);; }
private bool ShipMoveTaskHasConflict(ShipMoveTask task) { if (task.connection == null) { return(false); } if (!reservationOnConnections.ContainsKey(task.connection)) { return(false); } List <Reservation> reservationList = reservationOnConnections[task.connection]; foreach (Reservation reservation in reservationList) { if (reservation.ConflictWithTask(task.StartTime, task.EndTime)) { return(true); } } return(false); }
private void ResolveConflictForShipMoveTask(ShipMoveTask task, ShipSchedule schedule) { if (!ShipMoveTaskHasConflict(task)) { return; } List <Reservation> reservationList = reservationOnConnections[task.connection]; TimeSpan minTimeSpan = TimeSpan.MaxValue; foreach (Reservation reservation in reservationList) { TimeSpan timeDiff = reservation.EndTime + safetyTime - task.StartTime; if (timeDiff < TimeSpan.Zero) { continue; } if (reservation.ConflictWithTask(task.StartTime + timeDiff, task.EndTime + timeDiff)) { continue; } if (timeDiff < minTimeSpan) { minTimeSpan = timeDiff; } } if (minTimeSpan == TimeSpan.Zero) { minTimeSpan = minTimeSpan.Add(new TimeSpan(0, 0, 1)); } schedule.Postpone(minTimeSpan); }
private void processShipMoveTask(ShipMoveTask task) { Timer timer = GameObject.Find("Timer").GetComponent <Timer>(); DateTime currentTime = timer.VirtualTime; TimeSpan timeElapsed = timer.TimeElapsed; if (timeElapsed != TimeSpan.Zero) { double currentX = ship.X; double currentY = ship.Y; double targetX = task.Position.x; double targetY = task.Position.y; double distanceLeft = Math.Pow(Math.Pow(currentX - targetX, 2) + Math.Pow(currentY - targetY, 2), 0.5); TimeSpan timeRemaining = task.EndTime.Subtract(currentTime); double speedRequired = distanceLeft / timeRemaining.TotalSeconds; double distanceCanTravel = speedRequired * timeElapsed.TotalSeconds; if (distanceCanTravel > distanceLeft) { distanceCanTravel = distanceLeft; } Vector2 vectorToMove = new Vector2((float)(targetX - currentX), (float)(targetY - currentY)); vectorToMove = vectorToMove.normalized; vectorToMove = new Vector2((float)(vectorToMove.x * distanceCanTravel), (float)(vectorToMove.y * distanceCanTravel)); double nextX = currentX + vectorToMove.x; double nextY = currentY + vectorToMove.y; ship.X = nextX; ship.Y = nextY; // Update the heading of the ship double turnSpeed = 0.1; double targetHeading = Math.Atan2(-vectorToMove.x, vectorToMove.y) / Math.PI * 180; double angleDiff = targetHeading - heading; if (angleDiff > 180) { angleDiff -= 360; } else if (angleDiff < -180) { angleDiff += 360; } double angleCanTurn = timeElapsed.TotalSeconds * turnSpeed * Math.Sign(angleDiff); if (Math.Abs(angleCanTurn) > Math.Abs(angleDiff)) { angleCanTurn = angleDiff; } heading += angleCanTurn; if (heading >= 360) { heading %= 360; } } if (ship.cargo == 0) { this.status = ShipStatus.Leaving; } else { this.status = ShipStatus.Entering; } }
private void ForceCompleteShipMoveTask(ShipMoveTask task) { ship.X = task.Position.x; ship.Y = task.Position.y; }
public static ShipMoveTask CreateAndStartTask(ShipModel ship, Action<ATask> onCompletion = null) { var task = new ShipMoveTask(ship, onCompletion); TaskMgr.AddTask(task); return task; }
private ShipSchedule PathToSchedule(ShipPath path) { double defaultShipSpeed = GameObject.Find("SceneSetting").GetComponent <SceneSetting>().ShipSpeed; double shipSpeed = defaultShipSpeed; ShipSchedule schedule = new ShipSchedule(); MapUtil mapUtil = GameObject.Find("MapUtil").GetComponent <MapUtil>(); DateTime currentTime = GameObject.Find("Timer").GetComponent <Timer>().VirtualTime; Vector2 currentPosition = new Vector2((float)ship.Ship.X, (float)ship.Ship.Y); bool unloadingScheduled = false; Node previousNode = null; foreach (Node node in path.path) { ShipMoveTask moveTask = new ShipMoveTask(); moveTask.Position = new Vector2((float)node.X, (float)node.Y); if (previousNode != null) { moveTask.connection = mapUtil.GetConnection(previousNode, node); shipSpeed = moveTask.connection.Speed; } else { shipSpeed = defaultShipSpeed; } double distance = Math.Pow(Math.Pow(node.X - currentPosition.x, 2) + Math.Pow(node.Y - currentPosition.y, 2), 0.5); TimeSpan duration = new TimeSpan(0, 0, (int)Math.Round(distance / shipSpeed)); moveTask.StartTime = currentTime; moveTask.EndTime = currentTime.Add(duration); previousNode = node; currentTime = currentTime.Add(duration); currentPosition = new Vector2((float)node.X, (float)node.Y); schedule.AppendTask(moveTask); // Unloading task double unloadingSpeed = GameObject.Find("SceneSetting").GetComponent <SceneSetting>().UnloadingSpeed; Dock dock = mapUtil.GetDockByNode(node); if (!unloadingScheduled && dock != null) { TimeSpan unloadingDuration = new TimeSpan(0, 0, (int)Math.Round(ship.Ship.cargo / unloadingSpeed)); UnloadingTask unloadingTask = new UnloadingTask(); unloadingTask.Position = currentPosition; unloadingTask.StartTime = currentTime; unloadingTask.EndTime = currentTime.Add(unloadingDuration); unloadingTask.dock = dock; currentTime = currentTime.Add(unloadingDuration); schedule.AppendTask(unloadingTask); unloadingScheduled = true; } // Task List <Node> exits = mapUtil.ExitNodes(); if (exits.Contains(node)) { VanishTask vanishTask = new VanishTask(); vanishTask.StartTime = currentTime; vanishTask.EndTime = currentTime; schedule.AppendTask(vanishTask); } } return(schedule); }