/// <summary>
        /// Gets a state if there is one already in progress.
        /// </summary>
        /// <param name="currentTime">The current time.</param>
        /// <returns>
        /// Returns an instance of ITimeOfDayState that represents the current time of day if an instance with a StartTime
        /// before the current world-time can be found
        /// </returns>
        private TimeOfDayState GetInProgressState(TimeOfDay currentTime)
        {
            TimeOfDayState inProgressState = null;

            foreach (TimeOfDayState state in this.timeOfDayStates)
            {
                // If the state is already in progress, w
                if (state.StateStartTime.Hour <= currentTime.Hour ||
                    (state.StateStartTime.Hour <= currentTime.Hour &&
                     state.StateStartTime.Minute <= currentTime.Minute))
                {
                    if (inProgressState == null)
                    {
                        inProgressState = state;
                        continue;
                    }
                    else
                    {
                        if (inProgressState.StateStartTime.Hour <= currentTime.Hour &&
                            inProgressState.StateStartTime.Minute <= currentTime.Minute)
                        {
                            inProgressState = state;
                        }
                    }
                }
            }

            return(inProgressState);
        }
        /// <summary>
        /// Gets the state that is up next.
        /// </summary>
        /// <param name="currentTime">The current time.</param>
        /// <returns>
        /// Returns an instance of ITimeOfDayState that represents the up coming time of day if an instance with a StartTime
        /// after the current world-time can be found
        /// </returns>
        private TimeOfDayState GetNextState(TimeOfDay currentTime)
        {
            TimeOfDayState nextState = null;

            foreach (TimeOfDayState state in this.timeOfDayStates)
            {
                // If this state is a future state, then preserve it as a possible next state.
                if (state.StateStartTime.Hour > currentTime.Hour ||
                    (state.StateStartTime.Hour >= currentTime.Hour &&
                     state.StateStartTime.Minute > currentTime.Minute))
                {
                    // If we do not have a next state, set it.
                    if (nextState == null)
                    {
                        nextState = state;
                        continue;
                    }
                    else
                    {
                        // We have a next state, so we must check which is sooner.
                        if (nextState.StateStartTime.Hour > state.StateStartTime.Hour &&
                            nextState.StateStartTime.Minute >= state.StateStartTime.Minute)
                        {
                            nextState = state;
                        }
                    }
                }
            }

            return(nextState);
        }
示例#3
0
        /// <summary>
        /// Event handler method fired when the Current TimeOfDay state has its time changed.
        /// </summary>
        /// <param name="sender">The TimeOfDayState that caused the time change.</param>
        /// <param name="updatedTimeOfDay">The new time of day.</param>
        private void CurrentTimeOfDayState_TimeUpdated(object sender, TimeOfDay updatedTimeOfDay)
        {
            // Takes our current time of day within the time of day state, and updates the realms with it.
            this.UpdateTimeOfDayStatesForRealms();

            // Fetch the world time of day.
            // This acts as +0 GMT in-game. Each realm can have an offset via its own timezone.
            TimeOfDayState newTimeOfDay = this.timeOfDayStateManager.GetTimeOfDayState(updatedTimeOfDay);

            if (this.CurrentTimeOfDay == newTimeOfDay)
            {
                return;
            }

            // We need to store a reference to the current state, since the Setup method overwrites it.
            var currentTimeOfDay = this.CurrentTimeOfDay;

            this.SetupWorldClock(newTimeOfDay);

            // Since the world time of day state was changed, we need to re-evaluate our realms.
            this.UpdateTimeOfDayStatesForRealms();

            // Invoke our event handler with the old state and the new state.
            this.OnTimeOfDayChanged(currentTimeOfDay, newTimeOfDay);
        }
示例#4
0
        /// <summary>
        /// Gets the state of the current time of day.
        /// </summary>
        /// <returns>Returns an instance representing the current time of day state.</returns>
        public TimeOfDayState GetCurrentTimeOfDayState()
        {
            TimeOfDayState state = this.timeOfDayStateManager.GetTimeOfDayState(this.CurrentTimeOfDay);

            if (state == null)
            {
                return(this.World.CurrentTimeOfDay);
            }
            else
            {
                return(state);
            }
        }
示例#5
0
        /// <summary>
        /// Called when the current time of day has changed and a new one is transitioning in.
        /// </summary>
        /// <param name="oldTimeOfDay">The old time of day.</param>
        /// <param name="newTimeOfDay">The new time of day.</param>
        protected virtual void OnTimeOfDayChanged(TimeOfDayState oldTimeOfDay, TimeOfDayState newTimeOfDay)
        {
            // Our event handler
            EventHandler <TimeOfDayChangedEventArgs> handler = this.TimeOfDayChanged;

            if (handler == null)
            {
                return;
            }

            // Invoke the handler
            handler(this.CurrentTimeOfDay, new TimeOfDayChangedEventArgs(oldTimeOfDay, newTimeOfDay));
        }
示例#6
0
        /// <summary>
        /// Adds the time of day state to the world.
        /// </summary>
        /// <param name="state">The state.</param>
        /// <exception cref="System.InvalidOperationException">You can not have two states with the same start time in the same world.</exception>
        /// <exception cref="System.NullReferenceException">State's start time must not be null.</exception>
        public void AddTimeOfDayState(TimeOfDayState state)
        {
            // We prevent states with the same start time from being added to the world
            if (this.TimeOfDayStates.Any(s => s.StateStartTime.Equals(state)))
            {
                throw new InvalidOperationException("You can not have two states with the same start time in the same world.");
            }

            // Null start times engine from transitioning to the new state.
            if (state.StateStartTime == null)
            {
                throw new NullReferenceException("State's start time must not be null.");
            }

            this.timeOfDayStates.Add(state);
        }
示例#7
0
        /// <summary>
        /// Sets up the world clock.
        /// </summary>
        /// <param name="initialState">The initial state.</param>
        private void SetupWorldClock(TimeOfDayState initialState)
        {
            // We want to reset our current state before we set up the next state
            // The next state starts on a background thread and can cause listeners to access
            // the old state before the new state is assigned preventing a proper reset.
            if (this.CurrentTimeOfDay != null)
            {
                this.CurrentTimeOfDay.TimeUpdated -= this.CurrentTimeOfDayState_TimeUpdated;
            }

            // Register for event updates
            initialState.TimeUpdated += this.CurrentTimeOfDayState_TimeUpdated;

            // Initialize the state.
            // TODO: This could potentially reset an in-use state if a zone has a large time-zone offset. An exception should be thrown if still in-use.
            initialState.Initialize(this.GameTimeAdjustmentFactor, this.HoursPerDay);

            this.CurrentTimeOfDay = initialState;
        }
        /// <summary>
        /// Looks at a supplied time of day and figures out what TimeOfDayState needs to be returned that matches the time of day.
        /// </summary>
        /// <param name="currentGameTime">The current time.</param>
        /// <returns>
        /// Returns an instance of ITimeOfDayState that represents the current time of day in the game.
        /// </returns>
        internal TimeOfDayState GetTimeOfDayState(TimeOfDay currentGameTime = null)
        {
            TimeOfDayState inProgressState = null;
            TimeOfDayState nextState       = null;

            Parallel.Invoke(
                () => inProgressState = this.GetInProgressState(currentGameTime),
                () => nextState       = this.GetNextState(currentGameTime));

            if (inProgressState != null)
            {
                return(inProgressState);
            }
            else if (nextState != null && nextState.StateStartTime.Hour <= currentGameTime.Hour && nextState.StateStartTime.Minute <= currentGameTime.Minute)
            {
                return(nextState);
            }

            return(null);
        }
        public async Task<IEnumerable<TimeOfDayState>> GetTimeOfDayStates()
        {
            IEnumerable<string> stateFiles = this.storageService.GetAllFilesByExtension(".tods", "TimeOfDayStates");
            var states = new List<TimeOfDayState>();

            foreach(string file in stateFiles)
            {
                var state = new TimeOfDayState();
                state.Name = await this.storageService.LoadValueFromKeyAsync(file, state.GetPropertyName(p => p.Name));
                state.StateStartTime.Hour = Convert.ToInt32(await this.storageService.LoadValueFromKeyAsync(
                    file,
                    state.StateStartTime.GetPropertyName(p => p.Hour)));
                state.StateStartTime.Minute = Convert.ToInt32(await this.storageService.LoadValueFromKeyAsync(
                    file, 
                    state.StateStartTime.GetPropertyName(p => p.Minute)));
                state.StateStartTime.HoursPerDay = Convert.ToInt32(await this.storageService.LoadValueFromKeyAsync(
                    file,
                    state.StateStartTime.GetPropertyName(p => p.HoursPerDay)));

                states.Add(state);
            }

            return states;
        }
示例#10
0
        /// <summary>
        /// Determines whether the specified <see cref="System.Object" />, is equal to this instance.
        /// </summary>
        /// <param name="obj">The <see cref="System.Object" /> to compare with this instance.</param>
        /// <returns>
        ///   <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.
        /// </returns>
        public override bool Equals(object obj)
        {
            TimeOfDayState secondState = (TimeOfDayState)obj;

            return(secondState.StateStartTime.Hour == this.StateStartTime.Hour && secondState.StateStartTime.Minute == this.StateStartTime.Minute);
        }
示例#11
0
        /// <summary>
        /// Constructs the world.
        /// </summary>
        /// <param name="game">The game.</param>
        private async Task ConstructWorld(IGame game)
        {
            // Set up the Room
            var bedroom = new DefaultRoom { IsEnabled = true };
            var hallway = new DefaultRoom { IsEnabled = true };

            // Set up the Zone            
            var weatherStates = new List<IWeatherState> { new ClearWeather(), new RainyWeather(), new ThunderstormWeather() };
            DefaultZone zone = new DefaultZone();
            zone.Name = "Country Side";
            zone.Rooms = new List<DefaultRoom>() { bedroom };
            zone.WeatherStates = weatherStates;
            zone.WeatherUpdateFrequency = 6;
            zone.WeatherChanged += (sender, weatherArgs) => Console.WriteLine($"{zone.Name} zone weather has changed to {weatherArgs.CurrentState.Name}");
            DefaultZone zone2 = new DefaultZone();
            zone2.Name = "Castle Rock";
            zone2.Rooms = new List<DefaultRoom> { hallway };
            zone2.WeatherStates = weatherStates;
            zone2.WeatherUpdateFrequency = 2;
            zone2.WeatherChanged += (sender, weatherArgs) => Console.WriteLine($"{zone2.Name} zone weather has changed to {weatherArgs.CurrentState.Name}");
            
            // Set up the World.
            IWorld world = new DefaultWorld();
            world.GameDayToRealHourRatio = 0.4;
            world.HoursPerDay = 10;
            world.Name = "Sample World";
            world.SetNotificationManager(game.NotificationCenter);

            var morningState = new TimeOfDayState { Name = "Morning", StateStartTime = new TimeOfDay { Hour = 2 } };
            var afternoonState = new TimeOfDayState { Name = "Afternoon", StateStartTime = new TimeOfDay { Hour = 5 } };
            var nightState = new TimeOfDayState { Name = "Night", StateStartTime = new TimeOfDay { Hour = 8 } };

            world.AddTimeOfDayState(morningState);
            world.AddTimeOfDayState(afternoonState);
            world.AddTimeOfDayState(nightState);
            world.TimeOfDayChanged += World_TimeOfDayChanged;

            // Set up the Realm.
            DefaultRealm realm = new DefaultRealm(world, new TimeOfDay { Hour = 3, HoursPerDay = 10 });
            realm.TimeZoneOffset = new TimeOfDay { Hour = 3, Minute = 10, HoursPerDay = world.HoursPerDay };
            realm.Name = "Realm 1";
            realm.SetNotificationManager(game.NotificationCenter);

            // Initialize the environment.
            Task task = world.Initialize();
            task.Wait();

            await world.AddRealmToWorld(realm);
            realm.AddZoneToRealm(zone);
            realm.AddZoneToRealm(zone2);
            await game.AddWorld(world);
        }
示例#12
0
        /// <summary>
        /// Sets up the world clock.
        /// </summary>
        /// <param name="initialState">The initial state.</param>
        private void SetupWorldClock(TimeOfDayState initialState)
        {
            // We want to reset our current state before we set up the next state
            // The next state starts on a background thread and can cause listeners to access
            // the old state before the new state is assigned preventing a proper reset.
            if (this.CurrentTimeOfDay != null)
            {
                this.CurrentTimeOfDay.TimeUpdated -= this.CurrentTimeOfDayState_TimeUpdated;
            }

            // Register for event updates
            initialState.TimeUpdated += this.CurrentTimeOfDayState_TimeUpdated;

            // Initialize the state.
            // TODO: This could potentially reset an in-use state if a zone has a large time-zone offset. An exception should be thrown if still in-use.
            initialState.Initialize(this.GameTimeAdjustmentFactor, this.HoursPerDay);

            this.CurrentTimeOfDay = initialState;
        }
示例#13
0
        /// <summary>
        /// Called when the current time of day has changed and a new one is transitioning in.
        /// </summary>
        /// <param name="oldTimeOfDay">The old time of day.</param>
        /// <param name="newTimeOfDay">The new time of day.</param>
        protected virtual void OnTimeOfDayChanged(TimeOfDayState oldTimeOfDay, TimeOfDayState newTimeOfDay)
        {
            // Our event handler
            EventHandler<TimeOfDayChangedEventArgs> handler = this.TimeOfDayChanged;
            if (handler == null)
            {
                return;
            }

            // Invoke the handler
            handler(this.CurrentTimeOfDay, new TimeOfDayChangedEventArgs(oldTimeOfDay, newTimeOfDay));
        }
示例#14
0
        /// <summary>
        /// Adds the time of day state to the world.
        /// </summary>
        /// <param name="state">The state.</param>
        /// <exception cref="System.InvalidOperationException">You can not have two states with the same start time in the same world.</exception>
        /// <exception cref="System.NullReferenceException">State's start time must not be null.</exception>
        public void AddTimeOfDayState(TimeOfDayState state)
        {
            // We prevent states with the same start time from being added to the world
            if (this.TimeOfDayStates.Any(s => s.StateStartTime.Equals(state)))
            {
                throw new InvalidOperationException("You can not have two states with the same start time in the same world.");
            }

            // Null start times engine from transitioning to the new state.
            if (state.StateStartTime == null)
            {
                throw new NullReferenceException("State's start time must not be null.");
            }

            this.timeOfDayStates.Add(state);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="TimeOfDayChangedEventArgs"/> class.
 /// </summary>
 /// <param name="transitionFrom">The transition from.</param>
 /// <param name="transitionTo">The transition to.</param>
 public TimeOfDayChangedEventArgs(TimeOfDayState transitionFrom, TimeOfDayState transitionTo)
 {
     this.TransitioningFrom = transitionFrom;
     this.TransitioningTo   = transitionTo;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="TimeOfDayChangedEventArgs"/> class.
 /// </summary>
 /// <param name="transitionFrom">The transition from.</param>
 /// <param name="transitionTo">The transition to.</param>
 public TimeOfDayChangedEventArgs(TimeOfDayState transitionFrom, TimeOfDayState transitionTo)
 {
     this.TransitioningFrom = transitionFrom;
     this.TransitioningTo = transitionTo;
 }