From 17274bc15a93c9ec2d245cd20b45b8759e62c810 Mon Sep 17 00:00:00 2001 From: dymanoid <9433345+dymanoid@users.noreply.github.com> Date: Sun, 1 Jul 2018 03:08:13 +0200 Subject: [PATCH] Implement #20 by enabling of manual time speed changes (day and night) --- src/RealTime/Config/RealTimeConfig.cs | 26 +++++-- src/RealTime/Core/RealTimeCore.cs | 4 +- src/RealTime/Localization/Translations/de.xml | 4 ++ src/RealTime/Localization/Translations/en.xml | 4 ++ src/RealTime/Localization/Translations/es.xml | 4 ++ src/RealTime/Localization/Translations/fr.xml | 4 ++ src/RealTime/Localization/Translations/ko.xml | 4 ++ src/RealTime/Localization/Translations/pl.xml | 4 ++ src/RealTime/Localization/Translations/pt.xml | 4 ++ src/RealTime/Localization/Translations/ru.xml | 4 ++ src/RealTime/Localization/Translations/zh.xml | 4 ++ src/RealTime/Simulation/SimulationHandler.cs | 4 ++ src/RealTime/Simulation/TimeAdjustment.cs | 68 +++++++++++-------- 13 files changed, 104 insertions(+), 34 deletions(-) diff --git a/src/RealTime/Config/RealTimeConfig.cs b/src/RealTime/Config/RealTimeConfig.cs index 7406bf22..f84d3ece 100644 --- a/src/RealTime/Config/RealTimeConfig.cs +++ b/src/RealTime/Config/RealTimeConfig.cs @@ -13,37 +13,51 @@ namespace RealTime.Config public sealed class RealTimeConfig { /// - /// Gets or sets the virtual citizens mode. + /// Gets or sets the speed of the time flow on daytime. Valid values are 1..7. /// [ConfigItem("1General", 0)] + [ConfigItemSlider(1, 7, ValueType = SliderValueType.Default)] + public uint DayTimeSpeed { get; set; } = 5; + + /// + /// Gets or sets the speed of the time flow on night time. Valid values are 1..7. + /// + [ConfigItem("1General", 1)] + [ConfigItemSlider(1, 7, ValueType = SliderValueType.Default)] + public uint NightTimeSpeed { get; set; } = 5; + + /// + /// Gets or sets the virtual citizens mode. + /// + [ConfigItem("1General", 2)] [ConfigItemComboBox] public VirtualCitizensLevel VirtualCitizens { get; set; } = VirtualCitizensLevel.Few; /// /// Gets or sets a value indicating whether the weekends are enabled. Cims don't go to work on weekends. /// - [ConfigItem("1General", 1)] + [ConfigItem("1General", 3)] [ConfigItemCheckBox] public bool IsWeekendEnabled { get; set; } = true; /// /// Gets or sets a value indicating whether Cims should go out at lunch for food. /// - [ConfigItem("1General", 2)] + [ConfigItem("1General", 4)] [ConfigItemCheckBox] public bool IsLunchtimeEnabled { get; set; } = true; /// /// Gets or sets a value indicating whether the construction sites should pause at night time. /// - [ConfigItem("1General", 3)] + [ConfigItem("1General", 5)] [ConfigItemCheckBox] public bool StopConstructionAtNight { get; set; } = true; /// /// Gets or sets the percentage value of the building construction speed. Valid values are 1..100. /// - [ConfigItem("1General", 4)] + [ConfigItem("1General", 6)] [ConfigItemSlider(1, 100)] public uint ConstructionSpeed { get; set; } = 50; @@ -155,6 +169,8 @@ public sealed class RealTimeConfig /// This instance. public RealTimeConfig Validate() { + DayTimeSpeed = Clamp(DayTimeSpeed, 1u, 7u); + NightTimeSpeed = Clamp(NightTimeSpeed, 1u, 7u); VirtualCitizens = (VirtualCitizensLevel)Clamp((int)VirtualCitizens, (int)VirtualCitizensLevel.None, (int)VirtualCitizensLevel.Many); ConstructionSpeed = Clamp(ConstructionSpeed, 0u, 100u); LunchQuota = Clamp(LunchQuota, 0u, 100u); diff --git a/src/RealTime/Core/RealTimeCore.cs b/src/RealTime/Core/RealTimeCore.cs index c995714b..385a8da0 100644 --- a/src/RealTime/Core/RealTimeCore.cs +++ b/src/RealTime/Core/RealTimeCore.cs @@ -80,8 +80,9 @@ public static RealTimeCore Run(RealTimeConfig config, string rootPath, Localizat return null; } - var timeAdjustment = new TimeAdjustment(); + var timeAdjustment = new TimeAdjustment(config); DateTime gameDate = timeAdjustment.Enable(); + SimulationHandler.TimeAdjustment = timeAdjustment; var timeInfo = new TimeInfo(); var buildingManager = new BuildingManagerConnection(); @@ -155,6 +156,7 @@ public void Stop() SimulationHandler.EventManager = null; SimulationHandler.DayTimeSimulation = null; SimulationHandler.CommercialAI = null; + SimulationHandler.TimeAdjustment = null; try { diff --git a/src/RealTime/Localization/Translations/de.xml b/src/RealTime/Localization/Translations/de.xml index 3a8682cc..acf41ae4 100644 --- a/src/RealTime/Localization/Translations/de.xml +++ b/src/RealTime/Localization/Translations/de.xml @@ -2,6 +2,10 @@ + + + + diff --git a/src/RealTime/Localization/Translations/en.xml b/src/RealTime/Localization/Translations/en.xml index 4eced2e3..5e9891ee 100644 --- a/src/RealTime/Localization/Translations/en.xml +++ b/src/RealTime/Localization/Translations/en.xml @@ -2,6 +2,10 @@ + + + + diff --git a/src/RealTime/Localization/Translations/es.xml b/src/RealTime/Localization/Translations/es.xml index 59fe7ad7..6f2e0b6c 100644 --- a/src/RealTime/Localization/Translations/es.xml +++ b/src/RealTime/Localization/Translations/es.xml @@ -2,6 +2,10 @@ + + + + diff --git a/src/RealTime/Localization/Translations/fr.xml b/src/RealTime/Localization/Translations/fr.xml index a50951e4..fb60bb8d 100644 --- a/src/RealTime/Localization/Translations/fr.xml +++ b/src/RealTime/Localization/Translations/fr.xml @@ -2,6 +2,10 @@ + + + + diff --git a/src/RealTime/Localization/Translations/ko.xml b/src/RealTime/Localization/Translations/ko.xml index 89721a2a..86fd5a2a 100644 --- a/src/RealTime/Localization/Translations/ko.xml +++ b/src/RealTime/Localization/Translations/ko.xml @@ -2,6 +2,10 @@ + + + + diff --git a/src/RealTime/Localization/Translations/pl.xml b/src/RealTime/Localization/Translations/pl.xml index da87a949..776c4323 100644 --- a/src/RealTime/Localization/Translations/pl.xml +++ b/src/RealTime/Localization/Translations/pl.xml @@ -2,6 +2,10 @@ + + + + diff --git a/src/RealTime/Localization/Translations/pt.xml b/src/RealTime/Localization/Translations/pt.xml index 65467097..d59393b6 100644 --- a/src/RealTime/Localization/Translations/pt.xml +++ b/src/RealTime/Localization/Translations/pt.xml @@ -2,6 +2,10 @@ + + + + diff --git a/src/RealTime/Localization/Translations/ru.xml b/src/RealTime/Localization/Translations/ru.xml index d188c8a1..55338206 100644 --- a/src/RealTime/Localization/Translations/ru.xml +++ b/src/RealTime/Localization/Translations/ru.xml @@ -2,6 +2,10 @@ + + + + diff --git a/src/RealTime/Localization/Translations/zh.xml b/src/RealTime/Localization/Translations/zh.xml index 63dbff06..a12d2eba 100644 --- a/src/RealTime/Localization/Translations/zh.xml +++ b/src/RealTime/Localization/Translations/zh.xml @@ -2,6 +2,10 @@ + + + + diff --git a/src/RealTime/Simulation/SimulationHandler.cs b/src/RealTime/Simulation/SimulationHandler.cs index e13aa93f..1837076a 100644 --- a/src/RealTime/Simulation/SimulationHandler.cs +++ b/src/RealTime/Simulation/SimulationHandler.cs @@ -37,6 +37,9 @@ public sealed class SimulationHandler : ThreadingExtensionBase /// internal static RealTimeCommercialBuildingAI CommercialAI { get; set; } + /// Gets or sets the time adjustment simulation class instance. + internal static TimeAdjustment TimeAdjustment { get; set; } + /// /// Called after each game simulation tick. A tick contains multiple frames. /// Performs the dispatching for this simulation phase. @@ -44,6 +47,7 @@ public sealed class SimulationHandler : ThreadingExtensionBase public override void OnAfterSimulationTick() { EventManager?.ProcessEvents(); + TimeAdjustment?.Update(); DateTime currentDate = SimulationManager.instance.m_currentGameTime.Date; if (currentDate != lastHandledDate) diff --git a/src/RealTime/Simulation/TimeAdjustment.cs b/src/RealTime/Simulation/TimeAdjustment.cs index 8e1e09a9..7a05b1f3 100644 --- a/src/RealTime/Simulation/TimeAdjustment.cs +++ b/src/RealTime/Simulation/TimeAdjustment.cs @@ -1,56 +1,62 @@ -// -// Copyright (c) dymanoid. All rights reserved. -// +// Copyright (c) dymanoid. All rights reserved. namespace RealTime.Simulation { using System; - using RealTime.Tools; + using RealTime.Config; /// /// Manages the customized time adjustment. This class depends on the class. /// internal sealed class TimeAdjustment { - private const int CustomFramesPerDay = 1 << 17; - private static readonly TimeSpan CustomTimePerFrame = new TimeSpan(24L * 3600L * 10_000_000L / CustomFramesPerDay); - + private const int RealtimeSpeed = 23; private readonly uint vanillaFramesPerDay; - private readonly TimeSpan vanillaTimePerFrame; + private readonly RealTimeConfig config; + private uint lastDayTimeSpeed; + private uint lastNightTimeSpeed; + private bool isDayTime; - /// - /// Initializes a new instance of the class. - /// - public TimeAdjustment() + /// Initializes a new instance of the class. + /// The configuration to run with. + /// Thrown when the argument is null. + public TimeAdjustment(RealTimeConfig config) { + this.config = config ?? throw new ArgumentNullException(nameof(config)); + lastDayTimeSpeed = config.DayTimeSpeed; + lastNightTimeSpeed = config.NightTimeSpeed; vanillaFramesPerDay = SimulationManager.DAYTIME_FRAMES; - vanillaTimePerFrame = SimulationManager.instance.m_timePerFrame; } - /// - /// Enables the customized time adjustment. - /// - /// + /// Enables the customized time adjustment. /// The current game date and time. public DateTime Enable() { - if (vanillaTimePerFrame == CustomTimePerFrame) + isDayTime = !SimulationManager.instance.m_isNightTime; + return UpdateTimeSimulationValues(CalculateFramesPerDay()); + } + + /// Updates the time adjustment to be synchronized with the configuration and the daytime. + public void Update() + { + if (SimulationManager.instance.m_isNightTime == isDayTime + || lastDayTimeSpeed != config.DayTimeSpeed + || lastNightTimeSpeed != config.NightTimeSpeed) { - Log.Warning("The 'Real Time' mod has not been properly deactivated! Check the TimeAdjustment.Disable() calls."); + isDayTime = !SimulationManager.instance.m_isNightTime; + lastDayTimeSpeed = config.DayTimeSpeed; + lastNightTimeSpeed = config.NightTimeSpeed; + UpdateTimeSimulationValues(CalculateFramesPerDay()); } - - return UpdateTimeSimulationValues(CustomFramesPerDay, CustomTimePerFrame); } - /// - /// Disables the customized time adjustment restoring the default vanilla values. - /// + /// Disables the customized time adjustment restoring the default vanilla values. public void Disable() { - UpdateTimeSimulationValues(vanillaFramesPerDay, vanillaTimePerFrame); + UpdateTimeSimulationValues(vanillaFramesPerDay); } - private static DateTime UpdateTimeSimulationValues(uint framesPerDay, TimeSpan timePerFrame) + private static DateTime UpdateTimeSimulationValues(uint framesPerDay) { SimulationManager sm = SimulationManager.instance; DateTime originalDate = sm.m_ThreadingWrapper.simulationTime; @@ -59,7 +65,7 @@ private static DateTime UpdateTimeSimulationValues(uint framesPerDay, TimeSpan t SimulationManager.DAYTIME_FRAME_TO_HOUR = 24f / SimulationManager.DAYTIME_FRAMES; SimulationManager.DAYTIME_HOUR_TO_FRAME = SimulationManager.DAYTIME_FRAMES / 24f; - sm.m_timePerFrame = timePerFrame; + sm.m_timePerFrame = new TimeSpan(24L * 3600L * 10_000_000L / framesPerDay); sm.m_timeOffsetTicks = originalDate.Ticks - (sm.m_currentFrameIndex * sm.m_timePerFrame.Ticks); sm.m_currentGameTime = originalDate; @@ -69,5 +75,11 @@ private static DateTime UpdateTimeSimulationValues(uint framesPerDay, TimeSpan t return sm.m_currentGameTime; } + + private uint CalculateFramesPerDay() + { + uint offset = isDayTime ? lastDayTimeSpeed : lastNightTimeSpeed; + return 1u << (int)(RealtimeSpeed - offset); + } } -} +} \ No newline at end of file