2025-05-15 00:37:42 +03:00
|
|
|
using Content.Shared.GameTicking;
|
|
|
|
|
using Content.Shared.Light.Components;
|
|
|
|
|
using Content.Shared.Storage.Components;
|
|
|
|
|
using Content.Shared.Weather;
|
2025-08-25 02:03:24 +03:00
|
|
|
using Robust.Client.GameObjects;
|
|
|
|
|
using Robust.Client.Player;
|
|
|
|
|
using Robust.Shared.Console;
|
2025-05-15 00:37:42 +03:00
|
|
|
using Robust.Shared.Map;
|
|
|
|
|
using Robust.Shared.Map.Components;
|
|
|
|
|
using Robust.Shared.Timing;
|
|
|
|
|
|
|
|
|
|
namespace Content.Shared._CP14.DayCycle;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// This is an add-on to the LightCycle system that helps you determine what time of day it is on the map
|
|
|
|
|
/// </summary>
|
|
|
|
|
public sealed class CP14DayCycleSystem : EntitySystem
|
|
|
|
|
{
|
|
|
|
|
[Dependency] private readonly IGameTiming _timing = default!;
|
|
|
|
|
[Dependency] private readonly MetaDataSystem _metaData = default!;
|
|
|
|
|
[Dependency] private readonly SharedGameTicker _ticker = default!;
|
|
|
|
|
[Dependency] private readonly SharedMapSystem _maps = default!;
|
|
|
|
|
[Dependency] private readonly SharedWeatherSystem _weather = default!;
|
|
|
|
|
|
|
|
|
|
private EntityQuery<MapGridComponent> _mapGridQuery;
|
|
|
|
|
private EntityQuery<InsideEntityStorageComponent> _storageQuery;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public override void Initialize()
|
|
|
|
|
{
|
|
|
|
|
base.Initialize();
|
|
|
|
|
|
|
|
|
|
_mapGridQuery = GetEntityQuery<MapGridComponent>();
|
|
|
|
|
_storageQuery = GetEntityQuery<InsideEntityStorageComponent>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void Update(float frameTime)
|
|
|
|
|
{
|
|
|
|
|
base.Update(frameTime);
|
|
|
|
|
|
|
|
|
|
var query = EntityQueryEnumerator<LightCycleComponent, CP14DayCycleComponent, MapComponent>();
|
|
|
|
|
while (query.MoveNext(out var uid, out var lightCycle, out var dayCycle, out var map))
|
|
|
|
|
{
|
|
|
|
|
var oldLightLevel = dayCycle.LastLightLevel;
|
|
|
|
|
var newLightLevel = GetLightLevel((uid, lightCycle));
|
|
|
|
|
|
|
|
|
|
// Going into darkness
|
2025-05-15 17:32:26 +03:00
|
|
|
if (oldLightLevel > newLightLevel)
|
2025-05-15 00:37:42 +03:00
|
|
|
{
|
2025-05-15 17:32:26 +03:00
|
|
|
if (oldLightLevel > dayCycle.Threshold)
|
|
|
|
|
{
|
|
|
|
|
if (newLightLevel < dayCycle.Threshold)
|
|
|
|
|
{
|
|
|
|
|
var ev = new CP14StartNightEvent(uid);
|
|
|
|
|
RaiseLocalEvent(ev);
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-05-15 00:37:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Going into light
|
2025-05-15 17:32:26 +03:00
|
|
|
if (oldLightLevel < newLightLevel)
|
2025-05-15 00:37:42 +03:00
|
|
|
{
|
2025-05-15 17:32:26 +03:00
|
|
|
if (oldLightLevel < dayCycle.Threshold)
|
|
|
|
|
{
|
|
|
|
|
if (newLightLevel > dayCycle.Threshold)
|
|
|
|
|
{
|
|
|
|
|
var ev = new CP14StartDayEvent(uid);
|
|
|
|
|
RaiseLocalEvent(ev);
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-05-15 00:37:42 +03:00
|
|
|
}
|
2025-05-15 17:32:26 +03:00
|
|
|
|
|
|
|
|
dayCycle.LastLightLevel = newLightLevel;
|
2025-05-15 00:37:42 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-15 17:32:26 +03:00
|
|
|
public float GetLightLevel(Entity<LightCycleComponent?> map)
|
2025-05-15 00:37:42 +03:00
|
|
|
{
|
|
|
|
|
if (!Resolve(map.Owner, ref map.Comp, false))
|
|
|
|
|
return 0;
|
|
|
|
|
|
2025-05-15 17:32:26 +03:00
|
|
|
var time = (float)_timing.CurTime
|
2025-05-15 00:37:42 +03:00
|
|
|
.Add(map.Comp.Offset)
|
|
|
|
|
.Subtract(_ticker.RoundStartTimeSpan)
|
|
|
|
|
.Subtract(_metaData.GetPauseTime(map))
|
|
|
|
|
.TotalSeconds;
|
|
|
|
|
|
|
|
|
|
var normalizedTime = time % map.Comp.Duration.TotalSeconds;
|
2025-08-25 02:03:24 +03:00
|
|
|
var lightLevel = 1 - Math.Sin((normalizedTime / map.Comp.Duration.TotalSeconds) * MathF.PI);
|
2025-05-15 17:32:26 +03:00
|
|
|
return (float)lightLevel;
|
2025-05-15 00:37:42 +03:00
|
|
|
}
|
|
|
|
|
|
2025-08-21 15:28:10 -07:00
|
|
|
public bool IsDayNow(Entity<LightCycleComponent?> map)
|
|
|
|
|
{
|
2025-08-25 02:03:24 +03:00
|
|
|
return GetLightLevel(map) >= 0.4;
|
2025-08-21 15:28:10 -07:00
|
|
|
}
|
|
|
|
|
|
2025-05-15 00:37:42 +03:00
|
|
|
/// <summary>
|
|
|
|
|
/// Checks to see if the specified entity is on the map where it's daytime.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="target">An entity being tested to see if it is in daylight</param>
|
|
|
|
|
public bool UnderSunlight(EntityUid target)
|
|
|
|
|
{
|
|
|
|
|
if (_storageQuery.HasComp(target))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
var xform = Transform(target);
|
|
|
|
|
|
|
|
|
|
if (xform.MapUid is null || xform.GridUid is null)
|
|
|
|
|
return false;
|
|
|
|
|
|
2025-08-21 15:28:10 -07:00
|
|
|
var day = IsDayNow(xform.MapUid.Value);
|
2025-05-15 00:37:42 +03:00
|
|
|
|
|
|
|
|
var grid = xform.GridUid;
|
|
|
|
|
if (grid is null)
|
|
|
|
|
return day;
|
|
|
|
|
|
|
|
|
|
if (!_mapGridQuery.TryComp(grid, out var gridComp))
|
|
|
|
|
return day;
|
|
|
|
|
|
2025-05-15 17:32:26 +03:00
|
|
|
if (!_weather.CanWeatherAffect(grid.Value,
|
|
|
|
|
gridComp,
|
|
|
|
|
_maps.GetTileRef(xform.GridUid.Value, gridComp, xform.Coordinates)))
|
2025-05-15 00:37:42 +03:00
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
return day;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-15 17:32:26 +03:00
|
|
|
public sealed class CP14StartNightEvent(EntityUid map) : EntityEventArgs
|
2025-05-15 00:37:42 +03:00
|
|
|
{
|
2025-05-17 14:12:49 +03:00
|
|
|
public EntityUid Map = map;
|
2025-05-15 00:37:42 +03:00
|
|
|
}
|
|
|
|
|
|
2025-05-15 17:32:26 +03:00
|
|
|
public sealed class CP14StartDayEvent(EntityUid map) : EntityEventArgs
|
2025-05-15 00:37:42 +03:00
|
|
|
{
|
2025-05-17 14:12:49 +03:00
|
|
|
public EntityUid Map = map;
|
2025-05-15 00:37:42 +03:00
|
|
|
}
|
2025-08-25 02:03:24 +03:00
|
|
|
|
|
|
|
|
internal sealed class CheckLightLevel : LocalizedCommands
|
|
|
|
|
{
|
|
|
|
|
[Dependency] private readonly IEntitySystemManager _entityManager = default!;
|
|
|
|
|
|
|
|
|
|
public override string Command => "cp14_check_light";
|
|
|
|
|
|
|
|
|
|
public override string Help => "Checks the light level of the map you are on.";
|
|
|
|
|
|
|
|
|
|
public override void Execute(IConsoleShell shell, string argStr, string[] args)
|
|
|
|
|
{
|
|
|
|
|
var entity = shell.Player?.AttachedEntity;
|
|
|
|
|
|
|
|
|
|
if (entity is null)
|
|
|
|
|
{
|
|
|
|
|
shell.WriteLine("You don't have an attached entity.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var transformSys = _entityManager.GetEntitySystem<TransformSystem>();
|
|
|
|
|
|
|
|
|
|
var map = transformSys.GetMap(entity.Value);
|
|
|
|
|
|
|
|
|
|
if (map is null)
|
|
|
|
|
{
|
|
|
|
|
shell.WriteLine("You are not on a map.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var dayCycle = _entityManager.GetEntitySystem<CP14DayCycleSystem>();
|
|
|
|
|
shell.WriteLine("Current light level: " + dayCycle.GetLightLevel(map.Value));
|
|
|
|
|
}
|
|
|
|
|
}
|