Updated day cycle (#171)
* Updated day cycle * Fixed DayCycleComponent attributes * Added new commands, as well as synchronization * Update cave-arena.yml * Update alchemy_test.yml --------- Co-authored-by: Ed <edwardxperia2000@gmail.com> Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com>
This commit is contained in:
79
Content.Server/_CP14/DayCycle/CP14AddTimeEntryCommand.cs
Normal file
79
Content.Server/_CP14/DayCycle/CP14AddTimeEntryCommand.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using Content.Server.Administration;
|
||||
using Content.Shared._CP14.DayCycle;
|
||||
using Content.Shared.Administration;
|
||||
using Robust.Shared.Console;
|
||||
|
||||
namespace Content.Server._CP14.DayCycle;
|
||||
|
||||
[AdminCommand(AdminFlags.VarEdit)]
|
||||
public sealed class CP14AddTimeEntryCommand : LocalizedCommands
|
||||
{
|
||||
private const string Name = "add_time_entry";
|
||||
private const int ArgumentCount = 4;
|
||||
|
||||
public override string Command => Name;
|
||||
public override string Description => "Allows you to add a new time entry to the map list";
|
||||
public override string Help => $"{Name} <mapUid> <color> <duration> <isNight>";
|
||||
|
||||
public override void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
if (args.Length != ArgumentCount)
|
||||
{
|
||||
shell.WriteError($"{Loc.GetString("shell-wrong-arguments-number")}\n{Help}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!NetEntity.TryParse(args[0], out var netEntity))
|
||||
{
|
||||
shell.WriteError(Loc.GetString("shell-entity-uid-must-be-number"));
|
||||
return;
|
||||
}
|
||||
|
||||
var entityManager = IoCManager.Resolve<EntityManager>();
|
||||
var dayCycleSystem = entityManager.System<CP14DayCycleSystem>();
|
||||
var entity = entityManager.GetEntity(netEntity);
|
||||
|
||||
if (!entityManager.TryGetComponent<CP14DayCycleComponent>(entity, out var dayCycle))
|
||||
{
|
||||
shell.WriteError(Loc.GetString("shell-entity-with-uid-lacks-component", ("uid", entity), ("componentName", nameof(CP14DayCycleComponent))));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Color.TryParse(args[1], out var color))
|
||||
{
|
||||
shell.WriteError(Loc.GetString("parse-color-fail", ("args", args[1])));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!float.TryParse(args[2], out var duration))
|
||||
{
|
||||
shell.WriteError(Loc.GetString("parse-float-fail", ("args", args[2])));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!bool.TryParse(args[3], out var isNight))
|
||||
{
|
||||
shell.WriteError(Loc.GetString("parse-bool-fail", ("args", args[3])));
|
||||
return;
|
||||
}
|
||||
|
||||
var entry = new DayCycleEntry
|
||||
{
|
||||
Color = color,
|
||||
Duration = TimeSpan.FromSeconds(duration),
|
||||
IsNight = isNight
|
||||
};
|
||||
|
||||
dayCycleSystem.AddTimeEntry((entity, dayCycle), entry);
|
||||
}
|
||||
|
||||
public override CompletionResult GetCompletion(IConsoleShell shell, string[] args)
|
||||
{
|
||||
return args.Length switch
|
||||
{
|
||||
1 => CompletionResult.FromOptions(CompletionHelper.Components<CP14DayCycleComponent>(args[0])),
|
||||
4 => CompletionResult.FromOptions(CompletionHelper.Booleans),
|
||||
_ => CompletionResult.Empty,
|
||||
};
|
||||
}
|
||||
}
|
||||
60
Content.Server/_CP14/DayCycle/CP14InitDayCycleCommand.cs
Normal file
60
Content.Server/_CP14/DayCycle/CP14InitDayCycleCommand.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using Content.Server.Administration;
|
||||
using Content.Shared._CP14.DayCycle;
|
||||
using Content.Shared.Administration;
|
||||
using Robust.Shared.Console;
|
||||
|
||||
namespace Content.Server._CP14.DayCycle;
|
||||
|
||||
[AdminCommand(AdminFlags.VarEdit)]
|
||||
public sealed class CP14InitDayCycleCommand : LocalizedCommands
|
||||
{
|
||||
private const string Name = "init_day_cycle";
|
||||
private const int ArgumentCount = 1;
|
||||
|
||||
public override string Command => Name;
|
||||
public override string Description =>
|
||||
"Re-initializes the day and night system, but reset the current time entry stage";
|
||||
public override string Help => $"{Name} <mapUid>";
|
||||
|
||||
public override void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
if (args.Length != ArgumentCount)
|
||||
{
|
||||
shell.WriteError($"{Loc.GetString("shell-wrong-arguments-number")}\n{Help}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!NetEntity.TryParse(args[0], out var netEntity))
|
||||
{
|
||||
shell.WriteError(Loc.GetString("shell-entity-uid-must-be-number"));
|
||||
return;
|
||||
}
|
||||
|
||||
var entityManager = IoCManager.Resolve<EntityManager>();
|
||||
var dayCycleSystem = entityManager.System<CP14DayCycleSystem>();
|
||||
var entity = entityManager.GetEntity(netEntity);
|
||||
|
||||
if (!entityManager.TryGetComponent<CP14DayCycleComponent>(entity, out var dayCycle))
|
||||
{
|
||||
shell.WriteError(Loc.GetString("shell-entity-with-uid-lacks-component", ("uid", entity), ("componentName", nameof(CP14DayCycleComponent))));
|
||||
return;
|
||||
}
|
||||
|
||||
if (dayCycle.TimeEntries.Count < CP14DayCycleSystem.MinTimeEntryCount)
|
||||
{
|
||||
shell.WriteError($"Attempting to init a daily cycle with the number of time entries less than {CP14DayCycleSystem.MinTimeEntryCount}");
|
||||
return;
|
||||
}
|
||||
|
||||
dayCycleSystem.Init((entity, dayCycle));
|
||||
}
|
||||
|
||||
public override CompletionResult GetCompletion(IConsoleShell shell, string[] args)
|
||||
{
|
||||
return args.Length switch
|
||||
{
|
||||
1 => CompletionResult.FromOptions(CompletionHelper.Components<CP14DayCycleComponent>(args[0])),
|
||||
_ => CompletionResult.Empty,
|
||||
};
|
||||
}
|
||||
}
|
||||
81
Content.Server/_CP14/DayCycle/CP14SetTimeEntryCommand.cs
Normal file
81
Content.Server/_CP14/DayCycle/CP14SetTimeEntryCommand.cs
Normal file
@@ -0,0 +1,81 @@
|
||||
using Content.Server.Administration;
|
||||
using Content.Shared._CP14.DayCycle;
|
||||
using Content.Shared.Administration;
|
||||
using Robust.Shared.Console;
|
||||
|
||||
namespace Content.Server._CP14.DayCycle;
|
||||
|
||||
[AdminCommand(AdminFlags.VarEdit)]
|
||||
public sealed class CP14SetTimeEntryCommand : LocalizedCommands
|
||||
{
|
||||
private const string Name = "set_time_entry";
|
||||
private const int ArgumentCount = 2;
|
||||
|
||||
public override string Command => Name;
|
||||
public override string Description => "Sets a new entry at the specified index";
|
||||
public override string Help => $"{Name} <mapUid> <timeEntry>";
|
||||
|
||||
public override void Execute(IConsoleShell shell, string argStr, string[] args)
|
||||
{
|
||||
if (args.Length != ArgumentCount)
|
||||
{
|
||||
shell.WriteError($"{Loc.GetString("shell-wrong-arguments-number")}\n{Help}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!NetEntity.TryParse(args[0], out var netEntity))
|
||||
{
|
||||
shell.WriteError(Loc.GetString("shell-entity-uid-must-be-number"));
|
||||
return;
|
||||
}
|
||||
|
||||
var entityManager = IoCManager.Resolve<EntityManager>();
|
||||
var dayCycleSystem = entityManager.System<CP14DayCycleSystem>();
|
||||
var entity = entityManager.GetEntity(netEntity);
|
||||
|
||||
if (!entityManager.TryGetComponent<CP14DayCycleComponent>(entity, out var dayCycle))
|
||||
{
|
||||
shell.WriteError(Loc.GetString("shell-entity-with-uid-lacks-component", ("uid", entity), ("componentName", nameof(CP14DayCycleComponent))));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!int.TryParse(args[1], out var timeEntry))
|
||||
{
|
||||
shell.WriteError(Loc.GetString("parse-int-fail", ("args", args[1])));
|
||||
return;
|
||||
}
|
||||
|
||||
dayCycleSystem.SetTimeEntry((entity, dayCycle), timeEntry);
|
||||
}
|
||||
|
||||
public override CompletionResult GetCompletion(IConsoleShell shell, string[] args)
|
||||
{
|
||||
var entityManager = IoCManager.Resolve<EntityManager>();
|
||||
|
||||
switch (args.Length)
|
||||
{
|
||||
case 1:
|
||||
return CompletionResult.FromOptions(CompletionHelper.Components<CP14DayCycleComponent>(args[0], entityManager));
|
||||
|
||||
case 2:
|
||||
if (!NetEntity.TryParse(args[0], out var mapUid))
|
||||
return CompletionResult.Empty;
|
||||
|
||||
if (!entityManager.TryGetComponent<CP14DayCycleComponent>(entityManager.GetEntity(mapUid), out var component))
|
||||
return CompletionResult.Empty;
|
||||
|
||||
if (component.TimeEntries.Count - 1 < 0)
|
||||
return CompletionResult.Empty;
|
||||
|
||||
var indices = new string[component.TimeEntries.Count - 1];
|
||||
for (var i = 0; i < indices.Length; i++)
|
||||
{
|
||||
indices[i] = i.ToString();
|
||||
}
|
||||
|
||||
return CompletionResult.FromOptions(indices);
|
||||
}
|
||||
|
||||
return CompletionResult.Empty;
|
||||
}
|
||||
}
|
||||
73
Content.Shared/_CP14/DayCycle/CP14DayCycleComponent.cs
Normal file
73
Content.Shared/_CP14/DayCycle/CP14DayCycleComponent.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._CP14.DayCycle;
|
||||
|
||||
/// <summary>
|
||||
/// Stores all the necessary data for the day and night cycle system to work
|
||||
/// </summary>
|
||||
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(CP14DayCycleSystem))]
|
||||
public sealed partial class CP14DayCycleComponent : Component
|
||||
{
|
||||
[ViewVariables]
|
||||
public int NextTimeEntryIndex => CurrentTimeEntryIndex + 1 >= TimeEntries.Count ? 0 : CurrentTimeEntryIndex + 1;
|
||||
|
||||
[ViewVariables]
|
||||
public DayCycleEntry CurrentTimeEntry => TimeEntries[CurrentTimeEntryIndex];
|
||||
|
||||
[ViewVariables]
|
||||
public DayCycleEntry NextCurrentTimeEntry => TimeEntries[NextTimeEntryIndex];
|
||||
|
||||
[ViewVariables]
|
||||
public Color StartColor => CurrentTimeEntry.Color;
|
||||
|
||||
[ViewVariables]
|
||||
public Color EndColor => NextCurrentTimeEntry.Color;
|
||||
|
||||
[DataField(required: true), ViewVariables, AutoNetworkedField]
|
||||
public List<DayCycleEntry> TimeEntries = new();
|
||||
|
||||
[DataField, ViewVariables, AutoNetworkedField]
|
||||
public bool IsNight; // TODO: Rewrite this shit
|
||||
|
||||
[DataField, ViewVariables, AutoNetworkedField]
|
||||
public int CurrentTimeEntryIndex;
|
||||
|
||||
[DataField, ViewVariables, AutoNetworkedField]
|
||||
public TimeSpan EntryStartTime;
|
||||
|
||||
[DataField, ViewVariables, AutoNetworkedField]
|
||||
public TimeSpan EntryEndTime;
|
||||
}
|
||||
|
||||
[DataDefinition, NetSerializable, Serializable]
|
||||
public readonly partial record struct DayCycleEntry()
|
||||
{
|
||||
/// <summary>
|
||||
/// The color of the world's lights at the beginning of this time of day
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public Color Color { get; init; } = Color.White;
|
||||
|
||||
/// <summary>
|
||||
/// Duration of color shift to the next time of day
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public TimeSpan Duration { get; init; } = TimeSpan.FromSeconds(60);
|
||||
|
||||
[DataField]
|
||||
public bool IsNight { get; init; } = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event raised on map entity, wen night is started
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public readonly record struct DayCycleNightStartedEvent(EntityUid Map);
|
||||
|
||||
/// <summary>
|
||||
/// Event raised on map entity, wen night is started
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public readonly record struct DayCycleDayStartedEvent(EntityUid Map);
|
||||
135
Content.Shared/_CP14/DayCycle/CP14DayCycleSystem.cs
Normal file
135
Content.Shared/_CP14/DayCycle/CP14DayCycleSystem.cs
Normal file
@@ -0,0 +1,135 @@
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Shared._CP14.DayCycle;
|
||||
|
||||
public sealed partial class CP14DayCycleSystem : EntitySystem
|
||||
{
|
||||
public const int MinTimeEntryCount = 2;
|
||||
private const float MaxTimeDiff = 0.05f;
|
||||
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<CP14DayCycleComponent, MapInitEvent>(OnMapInitDayCycle);
|
||||
SubscribeLocalEvent<CP14DayCycleComponent, DayCycleDayStartedEvent>(OnDayStarted);
|
||||
SubscribeLocalEvent<CP14DayCycleComponent, DayCycleNightStartedEvent>(OnNightStarted);
|
||||
}
|
||||
|
||||
private void OnDayStarted(Entity<CP14DayCycleComponent> dayCycle, ref DayCycleDayStartedEvent args)
|
||||
{
|
||||
}
|
||||
|
||||
private void OnNightStarted(Entity<CP14DayCycleComponent> dayCycle, ref DayCycleNightStartedEvent args)
|
||||
{
|
||||
}
|
||||
|
||||
private void OnMapInitDayCycle(Entity<CP14DayCycleComponent> dayCycle, ref MapInitEvent args)
|
||||
{
|
||||
Init(dayCycle);
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
|
||||
var dayCycleQuery = EntityQueryEnumerator<CP14DayCycleComponent, MapLightComponent>();
|
||||
while (dayCycleQuery.MoveNext(out var uid, out var dayCycle, out var mapLight))
|
||||
{
|
||||
var entity = new Entity<CP14DayCycleComponent, MapLightComponent>(uid, dayCycle, mapLight);
|
||||
|
||||
if (dayCycle.TimeEntries.Count < MinTimeEntryCount)
|
||||
continue;
|
||||
|
||||
SetAmbientColor((entity, entity), GetCurrentColor(entity, _timing.CurTime.TotalSeconds));
|
||||
|
||||
if (_timing.CurTime <= dayCycle.EntryEndTime)
|
||||
continue;
|
||||
|
||||
SetTimeEntry((uid, dayCycle), dayCycle.NextTimeEntryIndex);
|
||||
}
|
||||
}
|
||||
|
||||
public void Init(Entity<CP14DayCycleComponent> dayCycle)
|
||||
{
|
||||
if (dayCycle.Comp.TimeEntries.Count < MinTimeEntryCount)
|
||||
{
|
||||
Log.Warning($"Attempting to init a daily cycle with the number of time entries less than {MinTimeEntryCount}");
|
||||
return;
|
||||
}
|
||||
|
||||
dayCycle.Comp.CurrentTimeEntryIndex = 0;
|
||||
dayCycle.Comp.EntryStartTime = _timing.CurTime;
|
||||
dayCycle.Comp.EntryEndTime = _timing.CurTime + dayCycle.Comp.CurrentTimeEntry.Duration;
|
||||
|
||||
Dirty(dayCycle);
|
||||
}
|
||||
|
||||
public void AddTimeEntry(Entity<CP14DayCycleComponent> dayCycle, DayCycleEntry entry)
|
||||
{
|
||||
dayCycle.Comp.TimeEntries.Add(entry);
|
||||
Dirty(dayCycle);
|
||||
}
|
||||
|
||||
public void SetTimeEntry(Entity<CP14DayCycleComponent> dayCycle, int nextEntry)
|
||||
{
|
||||
nextEntry = Math.Clamp(nextEntry, 0, dayCycle.Comp.TimeEntries.Count - 1);
|
||||
|
||||
dayCycle.Comp.CurrentTimeEntryIndex = nextEntry;
|
||||
dayCycle.Comp.EntryStartTime = dayCycle.Comp.EntryEndTime;
|
||||
dayCycle.Comp.EntryEndTime += dayCycle.Comp.CurrentTimeEntry.Duration;
|
||||
|
||||
// TODO: Made with states,we might need an evening or something, and besides, it's too much hardcore
|
||||
if (dayCycle.Comp.IsNight && !dayCycle.Comp.CurrentTimeEntry.IsNight) // Day started
|
||||
{
|
||||
dayCycle.Comp.IsNight = false;
|
||||
|
||||
var ev = new DayCycleDayStartedEvent(dayCycle);
|
||||
RaiseLocalEvent(dayCycle, ref ev, true);
|
||||
}
|
||||
|
||||
if (!dayCycle.Comp.IsNight && dayCycle.Comp.CurrentTimeEntry.IsNight) // Night started
|
||||
{
|
||||
dayCycle.Comp.IsNight = true;
|
||||
|
||||
var ev = new DayCycleNightStartedEvent(dayCycle);
|
||||
RaiseLocalEvent(dayCycle, ref ev, true);
|
||||
}
|
||||
|
||||
Dirty(dayCycle);
|
||||
}
|
||||
|
||||
private void SetAmbientColor(Entity<MapLightComponent> light, Color color)
|
||||
{
|
||||
if (color == light.Comp.AmbientLightColor)
|
||||
return;
|
||||
|
||||
light.Comp.AmbientLightColor = color;
|
||||
Dirty(light);
|
||||
}
|
||||
|
||||
private Color GetCurrentColor(Entity<CP14DayCycleComponent> dayCycle, double totalSeconds)
|
||||
{
|
||||
var timeScale = GetTimeScale(dayCycle, totalSeconds);
|
||||
return Color.InterpolateBetween(dayCycle.Comp.StartColor, dayCycle.Comp.EndColor, timeScale);
|
||||
}
|
||||
|
||||
private float GetTimeScale(Entity<CP14DayCycleComponent> dayCycle, double totalSeconds)
|
||||
{
|
||||
return GetLerpValue(dayCycle.Comp.EntryStartTime.TotalSeconds, dayCycle.Comp.EntryEndTime.TotalSeconds, totalSeconds);
|
||||
}
|
||||
|
||||
private static float GetLerpValue(double start, double end, double current)
|
||||
{
|
||||
if (Math.Abs(start - end) < MaxTimeDiff)
|
||||
return 0f;
|
||||
|
||||
var distanceFromStart = current - start;
|
||||
var totalDistance = end - start;
|
||||
|
||||
return MathHelper.Clamp01((float)(distanceFromStart / totalDistance));
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._CP14.DayCycle;
|
||||
|
||||
/// <summary>
|
||||
/// Stores all the necessary data for the day and night cycle system to work
|
||||
/// </summary>
|
||||
|
||||
[RegisterComponent, Access(typeof(DayCycleSystem))]
|
||||
public sealed partial class DayCycleComponent : Component
|
||||
{
|
||||
[DataField(required: true)]
|
||||
public List<DayCycleEntry> TimeEntries = new();
|
||||
|
||||
[DataField]
|
||||
public bool IsNight = false;
|
||||
|
||||
[DataField]
|
||||
public int CurrentTimeEntry = 0;
|
||||
|
||||
[DataField]
|
||||
public TimeSpan EntryStartTime;
|
||||
|
||||
[DataField]
|
||||
public TimeSpan EntryEndTime;
|
||||
}
|
||||
|
||||
[DataDefinition, NetSerializable, Serializable]
|
||||
public readonly partial record struct DayCycleEntry()
|
||||
{
|
||||
/// <summary>
|
||||
/// the color of the world's lights at the beginning of this time of day
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public Color StartColor { get; init; } = Color.White;
|
||||
|
||||
/// <summary>
|
||||
/// duration of color shift to the next time of day
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public TimeSpan Duration { get; init; } = TimeSpan.FromSeconds(60);
|
||||
|
||||
[DataField]
|
||||
public bool IsNight { get; init; } = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event raised on map entity, wen night is started
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public readonly record struct DayCycleNightStartedEvent(EntityUid Map);
|
||||
|
||||
/// <summary>
|
||||
/// Event raised on map entity, wen night is started
|
||||
/// </summary>
|
||||
[ByRefEvent]
|
||||
public readonly record struct DayCycleDayStartedEvent(EntityUid Map);
|
||||
@@ -1,95 +0,0 @@
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Shared._CP14.DayCycle;
|
||||
public sealed partial class DayCycleSystem : EntitySystem
|
||||
{
|
||||
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<DayCycleComponent, MapInitEvent>(OnMapInitDayCycle);
|
||||
SubscribeLocalEvent<DayCycleComponent, DayCycleDayStartedEvent>(OnDayStarted);
|
||||
SubscribeLocalEvent<DayCycleComponent, DayCycleNightStartedEvent>(OnNightStarted);
|
||||
}
|
||||
|
||||
private void OnDayStarted(Entity<DayCycleComponent> dayCycle, ref DayCycleDayStartedEvent args)
|
||||
{
|
||||
}
|
||||
|
||||
private void OnNightStarted(Entity<DayCycleComponent> dayCycle, ref DayCycleNightStartedEvent args)
|
||||
{
|
||||
}
|
||||
|
||||
private void OnMapInitDayCycle(Entity<DayCycleComponent> dayCycle, ref MapInitEvent args)
|
||||
{
|
||||
if (dayCycle.Comp.TimeEntries.Count == 0)
|
||||
return;
|
||||
|
||||
var currentEntry = dayCycle.Comp.TimeEntries[0];
|
||||
|
||||
dayCycle.Comp.EntryStartTime = _timing.CurTime;
|
||||
dayCycle.Comp.EntryEndTime = _timing.CurTime + currentEntry.Duration;
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
{
|
||||
base.Update(frameTime);
|
||||
|
||||
var dayCycleQuery = EntityQueryEnumerator<DayCycleComponent, MapLightComponent>();
|
||||
while (dayCycleQuery.MoveNext(out var uid, out var dayCycle, out var mapLight))
|
||||
{
|
||||
if (dayCycle.TimeEntries.Count <= 1)
|
||||
continue;
|
||||
|
||||
var curEntry = dayCycle.CurrentTimeEntry;
|
||||
var nextEntry = (curEntry + 1 >= dayCycle.TimeEntries.Count) ? 0 : (curEntry + 1);
|
||||
|
||||
var start = dayCycle.EntryStartTime;
|
||||
var end = dayCycle.EntryEndTime;
|
||||
|
||||
var lerpValue = GetLerpValue((float) start.TotalSeconds, (float) end.TotalSeconds, (float) _timing.CurTime.TotalSeconds);
|
||||
|
||||
var startColor = dayCycle.TimeEntries[curEntry].StartColor;
|
||||
var endColor = dayCycle.TimeEntries[nextEntry].StartColor;
|
||||
|
||||
mapLight.AmbientLightColor = Color.InterpolateBetween(startColor, endColor, lerpValue);
|
||||
Dirty(uid, mapLight);
|
||||
|
||||
|
||||
if (_timing.CurTime > dayCycle.EntryEndTime)
|
||||
{
|
||||
dayCycle.CurrentTimeEntry = nextEntry;
|
||||
dayCycle.EntryStartTime = dayCycle.EntryEndTime;
|
||||
dayCycle.EntryEndTime += dayCycle.TimeEntries[nextEntry].Duration;
|
||||
|
||||
if (dayCycle.IsNight && !dayCycle.TimeEntries[curEntry].IsNight) // Day started
|
||||
{
|
||||
dayCycle.IsNight = false;
|
||||
var ev = new DayCycleDayStartedEvent(uid);
|
||||
RaiseLocalEvent(uid, ref ev, true);
|
||||
}
|
||||
if (!dayCycle.IsNight && dayCycle.TimeEntries[curEntry].IsNight) // Night started
|
||||
{
|
||||
dayCycle.IsNight = true;
|
||||
var ev = new DayCycleNightStartedEvent(uid);
|
||||
RaiseLocalEvent(uid, ref ev, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static float GetLerpValue(float start, float end, float current)
|
||||
{
|
||||
if (Math.Abs(start - end) < 0.05f)
|
||||
return 0f;
|
||||
|
||||
var distanceFromStart = current - start;
|
||||
var totalDistance = end - start;
|
||||
|
||||
return MathHelper.Clamp01(distanceFromStart / totalDistance);
|
||||
}
|
||||
}
|
||||
@@ -31,25 +31,28 @@ entities:
|
||||
- type: OccluderTree
|
||||
- type: LoadedMap
|
||||
- type: MapLight
|
||||
- type: DayCycle
|
||||
- type: CP14DayCycle
|
||||
timeEntries:
|
||||
- duration: 30
|
||||
startColor: '#754A4AFF'
|
||||
- duration: 30
|
||||
startColor: '#E0BA87FF'
|
||||
- duration: 30
|
||||
startColor: '#BFEEFFFF'
|
||||
- duration: 80
|
||||
color: '#754A4AFF'
|
||||
- duration: 80
|
||||
color: '#E0BA87FF'
|
||||
- duration: 80
|
||||
color: '#BFEEFFFF'
|
||||
- isNight: True
|
||||
duration: 30
|
||||
startColor: '#385163FF'
|
||||
duration: 80
|
||||
color: '#385163FF'
|
||||
- isNight: True
|
||||
duration: 30
|
||||
startColor: '#060D12FF'
|
||||
duration: 80
|
||||
color: '#060D12FF'
|
||||
- isNight: True
|
||||
duration: 90
|
||||
startColor: '#000000FF'
|
||||
- duration: 30
|
||||
startColor: '#120906FF'
|
||||
duration: 80
|
||||
color: '#000000FF'
|
||||
- isNight: True
|
||||
duration: 80
|
||||
color: '#000000FF'
|
||||
- duration: 80
|
||||
color: '#120906FF'
|
||||
- uid: 2
|
||||
components:
|
||||
- type: MetaData
|
||||
|
||||
@@ -20,7 +20,7 @@ entities:
|
||||
- type: MovedGrids
|
||||
- type: Broadphase
|
||||
- type: MapLight
|
||||
- type: DayCycle
|
||||
- type: CP14DayCycle
|
||||
timeEntries:
|
||||
- duration: 30
|
||||
startColor: '#0A2136FF'
|
||||
|
||||
@@ -391,27 +391,27 @@ entities:
|
||||
- type: GridTree
|
||||
- type: MovedGrids
|
||||
- type: MapLight
|
||||
- type: DayCycle
|
||||
- type: CP14DayCycle
|
||||
timeEntries:
|
||||
- startColor: "#754a4a" #Рассвет
|
||||
- color: "#754a4a" #Рассвет
|
||||
duration: 30
|
||||
isNight: false
|
||||
- startColor: "#e0ba87" #Полдень
|
||||
- color: "#e0ba87" #Полдень
|
||||
duration: 30
|
||||
isNight: false
|
||||
- startColor: "#bfeeff" #Полдень
|
||||
- color: "#bfeeff" #Полдень
|
||||
duration: 30
|
||||
isNight: false
|
||||
- startColor: "#385163" #Вечер
|
||||
- color: "#385163" #Вечер
|
||||
duration: 30
|
||||
isNight: true
|
||||
- startColor: "#060d12" #Ночь
|
||||
- color: "#060d12" #Ночь
|
||||
duration: 30
|
||||
isNight: true
|
||||
- startColor: "#000000" #Ночь
|
||||
- color: "#000000" #Ночь
|
||||
duration: 30
|
||||
isNight: true
|
||||
- startColor: "#120906" #Ночь
|
||||
- color: "#120906" #Ночь
|
||||
duration: 30
|
||||
isNight: false
|
||||
- proto: AirAlarm
|
||||
|
||||
Reference in New Issue
Block a user