Skip to content

Commit

Permalink
Implement #20 by enabling of manual time speed changes (day and night)
Browse files Browse the repository at this point in the history
  • Loading branch information
dymanoid committed Jul 1, 2018
1 parent ad23c97 commit 17274bc
Show file tree
Hide file tree
Showing 13 changed files with 104 additions and 34 deletions.
26 changes: 21 additions & 5 deletions src/RealTime/Config/RealTimeConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,37 +13,51 @@ namespace RealTime.Config
public sealed class RealTimeConfig
{
/// <summary>
/// Gets or sets the virtual citizens mode.
/// Gets or sets the speed of the time flow on daytime. Valid values are 1..7.
/// </summary>
[ConfigItem("1General", 0)]
[ConfigItemSlider(1, 7, ValueType = SliderValueType.Default)]
public uint DayTimeSpeed { get; set; } = 5;

/// <summary>
/// Gets or sets the speed of the time flow on night time. Valid values are 1..7.
/// </summary>
[ConfigItem("1General", 1)]
[ConfigItemSlider(1, 7, ValueType = SliderValueType.Default)]
public uint NightTimeSpeed { get; set; } = 5;

/// <summary>
/// Gets or sets the virtual citizens mode.
/// </summary>
[ConfigItem("1General", 2)]
[ConfigItemComboBox]
public VirtualCitizensLevel VirtualCitizens { get; set; } = VirtualCitizensLevel.Few;

/// <summary>
/// Gets or sets a value indicating whether the weekends are enabled. Cims don't go to work on weekends.
/// </summary>
[ConfigItem("1General", 1)]
[ConfigItem("1General", 3)]
[ConfigItemCheckBox]
public bool IsWeekendEnabled { get; set; } = true;

/// <summary>
/// Gets or sets a value indicating whether Cims should go out at lunch for food.
/// </summary>
[ConfigItem("1General", 2)]
[ConfigItem("1General", 4)]
[ConfigItemCheckBox]
public bool IsLunchtimeEnabled { get; set; } = true;

/// <summary>
/// Gets or sets a value indicating whether the construction sites should pause at night time.
/// </summary>
[ConfigItem("1General", 3)]
[ConfigItem("1General", 5)]
[ConfigItemCheckBox]
public bool StopConstructionAtNight { get; set; } = true;

/// <summary>
/// Gets or sets the percentage value of the building construction speed. Valid values are 1..100.
/// </summary>
[ConfigItem("1General", 4)]
[ConfigItem("1General", 6)]
[ConfigItemSlider(1, 100)]
public uint ConstructionSpeed { get; set; } = 50;

Expand Down Expand Up @@ -155,6 +169,8 @@ public sealed class RealTimeConfig
/// <returns>This instance.</returns>
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);
Expand Down
4 changes: 3 additions & 1 deletion src/RealTime/Core/RealTimeCore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -155,6 +156,7 @@ public void Stop()
SimulationHandler.EventManager = null;
SimulationHandler.DayTimeSimulation = null;
SimulationHandler.CommercialAI = null;
SimulationHandler.TimeAdjustment = null;

try
{
Expand Down
4 changes: 4 additions & 0 deletions src/RealTime/Localization/Translations/de.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
<language id="de" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<translation id="1General" value="Allgemein" />
<translation id="DayTimeSpeed" value="Zeitgeschw. (Tag)" />
<translation id="DayTimeSpeedTooltip" value="Die Zeitgeschwindigkeit am Tag. '1' ist sehr langsam - fast in Echtzeit!" />
<translation id="NightTimeSpeed" value="Zeitgeschw. (Nacht)" />
<translation id="NightTimeSpeedTooltip" value="Die Zeitgeschwindigkeit in der Nacht. '1' ist sehr langsam - fast in Echtzeit!" />
<translation id="VirtualCitizens" value="Simulation der Einwohner (real und virtuell)" />
<translation id="VirtualCitizensTooltip" value="Wählen sie 'Alle' aus für eine reale Stadt (aber max 65.535 Einw.) oder 'Original' / 'Mehr' bei schwachem PC" />
<translation id="VirtualCitizens.None" value="Alle Einwohner sind real" />
Expand Down
4 changes: 4 additions & 0 deletions src/RealTime/Localization/Translations/en.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
<language id="en" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<translation id="1General" value="General" />
<translation id="DayTimeSpeed" value="Time speed (day)" />
<translation id="DayTimeSpeedTooltip" value="The speed of the time flow on daytime. '1' is very slow - almost real time!" />
<translation id="NightTimeSpeed" value="Time speed (night)" />
<translation id="NightTimeSpeedTooltip" value="The speed of the time flow on night time. '1' is very slow - almost real time!" />
<translation id="VirtualCitizens" value="Citizens simulation mode (real and virtual)" />
<translation id="VirtualCitizensTooltip" value="Select 'All' for a real city (but max 65.535 citizens), select 'Vanilla' or 'More' if your PC is weak" />
<translation id="VirtualCitizens.None" value="All citizens are real" />
Expand Down
4 changes: 4 additions & 0 deletions src/RealTime/Localization/Translations/es.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
<language id="es" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<translation id="1General" value="General" />
<translation id="DayTimeSpeed" value="Time speed (day)" />
<translation id="DayTimeSpeedTooltip" value="The speed of the time flow on daytime. '1' is very slow - almost real time!" />
<translation id="NightTimeSpeed" value="Time speed (night)" />
<translation id="NightTimeSpeedTooltip" value="The speed of the time flow on night time. '1' is very slow - almost real time!" />
<translation id="VirtualCitizens" value="Citizens simulation mode (real and virtual)" />
<translation id="VirtualCitizensTooltip" value="Select 'All' for a real city (but max 65.535 citizens), select 'Vanilla' or 'More' if your PC is weak" />
<translation id="VirtualCitizens.None" value="All citizens are real" />
Expand Down
4 changes: 4 additions & 0 deletions src/RealTime/Localization/Translations/fr.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
<language id="fr" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<translation id="1General" value="Général" />
<translation id="DayTimeSpeed" value="Time speed (day)" />
<translation id="DayTimeSpeedTooltip" value="The speed of the time flow on daytime. '1' is very slow - almost real time!" />
<translation id="NightTimeSpeed" value="Time speed (night)" />
<translation id="NightTimeSpeedTooltip" value="The speed of the time flow on night time. '1' is very slow - almost real time!" />
<translation id="VirtualCitizens" value="Citizens simulation mode (real and virtual)" />
<translation id="VirtualCitizensTooltip" value="Select 'All' for a real city (but max 65.53k citizens), select 'Vanilla' or 'More' if your PC is weak" />
<translation id="VirtualCitizens.None" value="All citizens are real" />
Expand Down
4 changes: 4 additions & 0 deletions src/RealTime/Localization/Translations/ko.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
<language id="ko" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<translation id="1General" value="General" />
<translation id="DayTimeSpeed" value="Time speed (day)" />
<translation id="DayTimeSpeedTooltip" value="The speed of the time flow on daytime. '1' is very slow - almost real time!" />
<translation id="NightTimeSpeed" value="Time speed (night)" />
<translation id="NightTimeSpeedTooltip" value="The speed of the time flow on night time. '1' is very slow - almost real time!" />
<translation id="VirtualCitizens" value="Citizens simulation mode (real and virtual)" />
<translation id="VirtualCitizensTooltip" value="Select 'All' for a real city (but max 65.535 citizens), select 'Vanilla' or 'More' if your PC is weak" />
<translation id="VirtualCitizens.None" value="All citizens are real" />
Expand Down
4 changes: 4 additions & 0 deletions src/RealTime/Localization/Translations/pl.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
<language id="pl" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<translation id="1General" value="General" />
<translation id="DayTimeSpeed" value="Time speed (day)" />
<translation id="DayTimeSpeedTooltip" value="The speed of the time flow on daytime. '1' is very slow - almost real time!" />
<translation id="NightTimeSpeed" value="Time speed (night)" />
<translation id="NightTimeSpeedTooltip" value="The speed of the time flow on night time. '1' is very slow - almost real time!" />
<translation id="VirtualCitizens" value="Citizens simulation mode (real and virtual)" />
<translation id="VirtualCitizensTooltip" value="Select 'All' for a real city (but max 65.535 citizens), select 'Vanilla' or 'More' if your PC is weak" />
<translation id="VirtualCitizens.None" value="All citizens are real" />
Expand Down
4 changes: 4 additions & 0 deletions src/RealTime/Localization/Translations/pt.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
<language id="pt" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<translation id="1General" value="General" />
<translation id="DayTimeSpeed" value="Time speed (day)" />
<translation id="DayTimeSpeedTooltip" value="The speed of the time flow on daytime. '1' is very slow - almost real time!" />
<translation id="NightTimeSpeed" value="Time speed (night)" />
<translation id="NightTimeSpeedTooltip" value="The speed of the time flow on night time. '1' is very slow - almost real time!" />
<translation id="VirtualCitizens" value="Citizens simulation mode (real and virtual)" />
<translation id="VirtualCitizensTooltip" value="Select 'All' for a real city (but max 65.535 citizens), select 'Vanilla' or 'More' if your PC is weak" />
<translation id="VirtualCitizens.None" value="All citizens are real" />
Expand Down
4 changes: 4 additions & 0 deletions src/RealTime/Localization/Translations/ru.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
<language id="ru" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<translation id="1General" value="Основные" />
<translation id="DayTimeSpeed" value="Скорось времени (день)" />
<translation id="DayTimeSpeedTooltip" value="Скорость течения времени днём. '1' очень медленно - почти реальное время!" />
<translation id="NightTimeSpeed" value="Скорось времени (ночь)" />
<translation id="NightTimeSpeedTooltip" value="Скорость течения времени ночью. '1' очень медленно - почти реальное время!" />
<translation id="VirtualCitizens" value="Метод симуляции жителей (реальных и виртуальных)" />
<translation id="VirtualCitizensTooltip" value="Выберите 'Все' для реального города (но макс. 65.535 жителей или 'Оригинально' / 'Больше', если компьютер слаб" />
<translation id="VirtualCitizens.None" value="Все жители города реальные" />
Expand Down
4 changes: 4 additions & 0 deletions src/RealTime/Localization/Translations/zh.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
<language id="zh" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<translation id="1General" value="General" />
<translation id="DayTimeSpeed" value="Time speed (day)" />
<translation id="DayTimeSpeedTooltip" value="The speed of the time flow on daytime. '1' is very slow - almost real time!" />
<translation id="NightTimeSpeed" value="Time speed (night)" />
<translation id="NightTimeSpeedTooltip" value="The speed of the time flow on night time. '1' is very slow - almost real time!" />
<translation id="VirtualCitizens" value="Citizens simulation mode (real and virtual)" />
<translation id="VirtualCitizensTooltip" value="Select 'None' for 100% real city, select 'Vanilla' or 'More' if your PC is weak" />
<translation id="VirtualCitizens.None" value="All citizens are real" />
Expand Down
4 changes: 4 additions & 0 deletions src/RealTime/Simulation/SimulationHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,17 @@ public sealed class SimulationHandler : ThreadingExtensionBase
/// </summary>
internal static RealTimeCommercialBuildingAI CommercialAI { get; set; }

/// <summary>Gets or sets the time adjustment simulation class instance.</summary>
internal static TimeAdjustment TimeAdjustment { get; set; }

/// <summary>
/// Called after each game simulation tick. A tick contains multiple frames.
/// Performs the dispatching for this simulation phase.
/// </summary>
public override void OnAfterSimulationTick()
{
EventManager?.ProcessEvents();
TimeAdjustment?.Update();

DateTime currentDate = SimulationManager.instance.m_currentGameTime.Date;
if (currentDate != lastHandledDate)
Expand Down
68 changes: 40 additions & 28 deletions src/RealTime/Simulation/TimeAdjustment.cs
Original file line number Diff line number Diff line change
@@ -1,56 +1,62 @@
// <copyright file="TimeAdjustment.cs" company="dymanoid">
// Copyright (c) dymanoid. All rights reserved.
// </copyright>
// <copyright file="TimeAdjustment.cs" company="dymanoid">Copyright (c) dymanoid. All rights reserved.</copyright>

namespace RealTime.Simulation
{
using System;
using RealTime.Tools;
using RealTime.Config;

/// <summary>
/// Manages the customized time adjustment. This class depends on the <see cref="SimulationManager"/> class.
/// </summary>
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;

/// <summary>
/// Initializes a new instance of the <see cref="TimeAdjustment"/> class.
/// </summary>
public TimeAdjustment()
/// <summary>Initializes a new instance of the <see cref="TimeAdjustment"/> class.</summary>
/// <param name="config">The configuration to run with.</param>
/// <exception cref="ArgumentNullException">Thrown when the argument is null.</exception>
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;
}

/// <summary>
/// Enables the customized time adjustment.
/// </summary>
///
/// <summary>Enables the customized time adjustment.</summary>
/// <returns>The current game date and time.</returns>
public DateTime Enable()
{
if (vanillaTimePerFrame == CustomTimePerFrame)
isDayTime = !SimulationManager.instance.m_isNightTime;
return UpdateTimeSimulationValues(CalculateFramesPerDay());
}

/// <summary>Updates the time adjustment to be synchronized with the configuration and the daytime.</summary>
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);
}

/// <summary>
/// Disables the customized time adjustment restoring the default vanilla values.
/// </summary>
/// <summary>Disables the customized time adjustment restoring the default vanilla values.</summary>
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;
Expand All @@ -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;

Expand All @@ -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);
}
}
}
}

0 comments on commit 17274bc

Please sign in to comment.