Ejemplo n.º 1
0
        public void Callback(object custom)
        {
            var now = SystemClock.Now;

            locker.Lock(c => assignmentTroops.Select(troop => troop.Stub).ToArray <ILockable>(), new object[] {}, Tribe)
            .Do(() =>
            {
                lock (assignmentLock)
                {
                    // Possible for reschedule to be called before we grab the assignmentLock
                    if (IsScheduled)
                    {
                        scheduler.Remove(this);
                    }

                    var troopToDispatch = assignmentTroops.FirstOrDefault(x => !x.Dispatched && x.DepartureTime <= now);

                    if (troopToDispatch != null)
                    {
                        // Make sure troop time is still valid. If not we need to put it back on the scheduler.
                        // The time may change if the user has finished upgrading a tech/unit that improves speed since adding
                        // it to the assignment.
                        var departureTime = DepartureTime(troopToDispatch.Stub);
                        if (departureTime > now)
                        {
                            troopToDispatch.DepartureTime = departureTime;
                        }
                        // If a troop dispatches, then we set the troop to dispatched.
                        else if (Dispatch(troopToDispatch.Stub))
                        {
                            troopToDispatch.Dispatched = true;
                        }
                        // Otherwise, if dispatch fails, then we remove it.
                        else
                        {
                            RemoveStubWithoutRescheduling(troopToDispatch.Stub);
                        }
                    }

                    // Take the quickest stub or the final target time.
                    Time = assignmentTroops.Any(s => !s.Dispatched)
                                         ? assignmentTroops.Where(s => !s.Dispatched).Min(x => x.DepartureTime)
                                         : TargetTime;

                    // If there are stubs that have not been dispatched or we haven't reached the time that the assignment should be over then we just reschedule it.
                    if (assignmentTroops.Any(x => !x.Dispatched) || TargetTime.CompareTo(SystemClock.Now) > 0)
                    {
                        scheduler.Put(this);
                        dbManager.Save(this);
                    }
                    else
                    {
                        // Remove all stubs from the assignment before removing it completely
                        var stubs = assignmentTroops.Select(x => x.Stub).ToList();

                        foreach (var stub in stubs)
                        {
                            RemoveStubWithoutRescheduling(stub);
                        }

                        AssignmentComplete(this);

                        // Delete the assignment
                        if (DbPersisted)
                        {
                            dbManager.Delete(this);
                        }
                    }
                }
            });
        }
Ejemplo n.º 2
0
        /// <summary>
        ///     Calculates the departure time for a given troop stub
        /// </summary>
        /// <param name="stub"></param>
        /// <returns></returns>
        private DateTime DepartureTime(ITroopStub stub)
        {
            int distance = tileLocator.TileDistance(stub.City.PrimaryPosition, 1, new Position(X, Y), 1);

            return(TargetTime.Subtract(TimeSpan.FromSeconds(formula.MoveTimeTotal(stub, distance, IsAttack))));
        }