111 lines
3.7 KiB
C#
111 lines
3.7 KiB
C#
using System;
|
|
using UnityEngine;
|
|
|
|
namespace DanieleMarotta.RiversongCodeShowcase
|
|
{
|
|
[RequiresWorldReadyForUpdate]
|
|
[GameSystemGroup(typeof(EarlyGameSystemGroup))]
|
|
public class WorldTimeSystem : GameSystem, IUpdatable
|
|
{
|
|
[InjectService]
|
|
private GameConfig _config;
|
|
|
|
[InjectService]
|
|
private World _world;
|
|
|
|
[InjectService]
|
|
private ISignalBus _signalBus;
|
|
|
|
public WorldTimeSystem(IServiceLocator serviceLocator) : base(serviceLocator)
|
|
{
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
AdvanceCalendar();
|
|
AdvanceDayNightCycle();
|
|
}
|
|
|
|
private void AdvanceCalendar()
|
|
{
|
|
var timeState = _world.TimeState;
|
|
if (timeState.DayNightCycleStep != DayNightCycleStep.Day) return;
|
|
|
|
var weekDuration = _config.Time.WeekDuration;
|
|
|
|
timeState.WeekTime += Time.deltaTime;
|
|
|
|
if (timeState.WeekTime > weekDuration)
|
|
{
|
|
timeState.WeekTime -= weekDuration;
|
|
|
|
timeState.TotalWeeks++;
|
|
|
|
timeState.WeekNumber = (timeState.WeekNumber + 1) % 4;
|
|
if (timeState.WeekNumber > 0)
|
|
{
|
|
_signalBus.Raise(new EndOfWeekSignal());
|
|
return;
|
|
}
|
|
|
|
timeState.MonthNumber = (timeState.MonthNumber + 1) % 12;
|
|
if (timeState.MonthNumber > 0)
|
|
{
|
|
_signalBus.Raise(new EndOfWeekSignal());
|
|
_signalBus.Raise(new EndOfMonthSignal());
|
|
return;
|
|
}
|
|
|
|
timeState.YearNumber++;
|
|
_signalBus.Raise(new EndOfWeekSignal());
|
|
_signalBus.Raise(new EndOfMonthSignal());
|
|
_signalBus.Raise(new EndOfYearSignal());
|
|
}
|
|
}
|
|
|
|
private void AdvanceDayNightCycle()
|
|
{
|
|
var timeState = _world.TimeState;
|
|
var config = _config.Time;
|
|
|
|
timeState.DayNightCycleTime += Time.deltaTime;
|
|
|
|
var stepDuration = timeState.DayNightCycleStep switch
|
|
{
|
|
DayNightCycleStep.Day => config.DayDuration,
|
|
DayNightCycleStep.DayToNight => config.DayToNightDuration,
|
|
DayNightCycleStep.Night => config.NightDuration,
|
|
DayNightCycleStep.NightToDay => config.NightToDayDuration,
|
|
_ => throw new ArgumentException()
|
|
};
|
|
|
|
while (timeState.DayNightCycleTime > stepDuration)
|
|
{
|
|
timeState.DayNightCycleTime -= stepDuration;
|
|
timeState.DayNightCycleStep = (DayNightCycleStep)(((int)timeState.DayNightCycleStep + 1) % 4);
|
|
|
|
_signalBus.Raise(new DayNightCycleStepChangedSignal(timeState.DayNightCycleStep));
|
|
|
|
switch (timeState.DayNightCycleStep)
|
|
{
|
|
case DayNightCycleStep.Night:
|
|
_signalBus.Raise(new NightStartedSignal());
|
|
break;
|
|
case DayNightCycleStep.Day:
|
|
_signalBus.Raise(new DayStartedSignal());
|
|
break;
|
|
}
|
|
}
|
|
|
|
timeState.NightBlend = timeState.DayNightCycleStep switch
|
|
{
|
|
DayNightCycleStep.Day => 0,
|
|
DayNightCycleStep.DayToNight => Mathf.Clamp01(timeState.DayNightCycleTime / config.DayToNightDuration),
|
|
DayNightCycleStep.Night => 1,
|
|
DayNightCycleStep.NightToDay => 1 - Mathf.Clamp01(timeState.DayNightCycleTime / config.NightToDayDuration),
|
|
_ => throw new ArgumentException()
|
|
};
|
|
}
|
|
}
|
|
}
|