Files
wylab-station-14/Content.Server/_WL/DayNight/DayNightSystem.cs
wylab 0f4ceb13b4 feat: add 11 copy-paste features from ss14-wega and ss14-wl
From ss14-wega (_Wega):
- DeleteOnDrop: auto-delete items when dropped
- FriendlyFaction: prevent friendly fire by faction
- NullRod: holy weapon that removes magic
- EdibleMatter: edible entity component
- Ghost Respawn: allow ghosts to respawn to lobby
- Barks: NPC voice sounds system (99 audio files)

From ss14-wl (_WL):
- Day/Night Cycle: automatic lighting cycle for maps
- Sleep on Buckle: sleep action when buckled
- Height System: tall entities become large items
- Freeze Component: freeze entities at high cold damage
- Suckable Food: mouth-slot consumables (lollipops, gum, etc.)
- GolemHeat: bonus feature (heat mechanics for golems)

Includes:
- 34 C# files
- 99 audio files
- 68 texture files
- 9 prototype files
- 2 locale files
- WegaCVars configuration

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 06:03:12 +00:00

98 lines
3.7 KiB
C#

using Robust.Server.GameObjects;
using Robust.Shared.Map.Components;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using System.Linq;
using System.Numerics;
namespace Content.Server._WL.DayNight
{
public sealed partial class DayNightSystem : EntitySystem
{
[Dependency] private readonly IGameTiming _gameTime = default!;
[Dependency] private readonly IPrototypeManager _protoMan = default!;
[Dependency] private readonly MapSystem _mapSys = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<DayNightComponent, MapInitEvent>(OnMapInit, after: [typeof(SharedMapSystem)]);
}
public override void Update(float frameTime)
{
base.Update(frameTime);
var query = EntityQueryEnumerator<DayNightComponent>();
while (query.MoveNext(out var map, out var dayNightComp))
{
if (!TryComp<MapLightComponent>(map, out var mapLightComp))
continue;
if (!TryComp<MapComponent>(map, out var mapComponent))
continue;
if (!dayNightComp.WasInit || mapComponent.MapPaused)
continue;
if (_gameTime.CurTime >= dayNightComp.NextCycle)
dayNightComp.NextCycle += dayNightComp.FullCycle;
var color = CalculateColor(
_gameTime.CurTime,
dayNightComp.FullCycle,
dayNightComp.NextCycle,
Color.FromHex(dayNightComp.DayHex),
Color.FromHex(dayNightComp.NightHex),
dayNightComp.DayNightRatio);
if (color == mapLightComp.AmbientLightColor) //Оптимизация для случаев, если цикл дня и ночи огромен.
continue;
_mapSys.SetAmbientLight(mapComponent.MapId, color);
}
}
private void OnMapInit(EntityUid station, DayNightComponent comp, MapInitEvent args)
{
if (!TryComp<MapComponent>(station, out var mapComponent))
return;
_mapSys.SetAmbientLight(mapComponent.MapId, Color.FromHex(comp.DayHex));
comp.NextCycle = _gameTime.CurTime + comp.FullCycle;
comp.WasInit = true;
}
public static Color CalculateColor(TimeSpan currentTime, TimeSpan fullCycle, TimeSpan nextCycle, Color dayColor, Color nightColor, Vector2 dayNightRatio)
{
currentTime = currentTime - (nextCycle - fullCycle);
var pair = dayNightRatio.X + dayNightRatio.Y;
var dayTime = fullCycle.TotalMinutes / pair * dayNightRatio.X;
var nightTime = fullCycle.TotalMinutes / pair * dayNightRatio.Y;
var isDay = currentTime.TotalMinutes <= dayTime;
var filledPercentage = isDay
? currentTime.TotalMinutes / dayTime
: (currentTime.TotalMinutes - dayTime) / nightTime;
var r = isDay
? dayColor.R + (nightColor.R - dayColor.R) * filledPercentage
: nightColor.R + (dayColor.R - nightColor.R) * filledPercentage;
var g = isDay
? dayColor.G + (nightColor.G - dayColor.G) * filledPercentage
: nightColor.G + (dayColor.G - nightColor.G) * filledPercentage;
var b = isDay
? dayColor.B + (nightColor.B - dayColor.B) * filledPercentage
: nightColor.B + (dayColor.B - nightColor.B) * filledPercentage;
var result = new Color((float) r, (float) g, (float) b);
return result;
}
}
}