示例#1
0
    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);;
    }
示例#2
0
    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);
    }
示例#3
0
    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);
    }
示例#4
0
    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;
        }
    }
示例#5
0
 private void ForceCompleteShipMoveTask(ShipMoveTask task)
 {
     ship.X = task.Position.x;
     ship.Y = task.Position.y;
 }
示例#6
0
 public static ShipMoveTask CreateAndStartTask(ShipModel ship, Action<ATask> onCompletion = null) {
     var task = new ShipMoveTask(ship, onCompletion);
     TaskMgr.AddTask(task);
     return task;
 }
示例#7
0
    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);
    }