Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Weather #172

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Content.Client/Overlays/StencilOverlay.Weather.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public sealed partial class StencilOverlay

private void DrawWeather(in OverlayDrawArgs args, WeatherPrototype weatherProto, float alpha, Matrix3 invMatrix)
{
if (weatherProto.Sprite == null)
return;
var worldHandle = args.WorldHandle;
var mapId = args.MapId;
var worldAABB = args.WorldAABB;
Expand Down
3 changes: 2 additions & 1 deletion Content.Client/Overlays/StencilOverlay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ protected override void Draw(in OverlayDrawArgs args)
{
if (!_protoManager.TryIndex<WeatherPrototype>(proto, out var weatherProto))
continue;

if (weatherProto.Sprite == null)
continue;
var alpha = _weather.GetPercent(weather, mapUid);
DrawWeather(args, weatherProto, alpha, invMatrix);
}
Expand Down
102 changes: 102 additions & 0 deletions Content.Server/Weather/WeatherSystem.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,41 @@
using System.Linq;
using System.Numerics;
using Content.Server.Administration;
using Content.Shared.Administration;
using Content.Shared.Maps;
using Content.Shared.Weather;
using Robust.Shared.Console;
using Robust.Shared.GameStates;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Content.Shared.Atmos;
using Robust.Server.Player;
using Robust.Shared.GameObjects;
using Robust.Server.GameObjects;
using Content.Server.Atmos.Components;
using Content.Server.Atmos.EntitySystems;
using Robust.Shared.Map;
using Content.Server.GameTicking;
using Content.Server.Chat.Systems;
using Robust.Shared.Random;
using Content.Server.Radiation.Systems;

namespace Content.Server.Weather;

public sealed class WeatherSystem : SharedWeatherSystem
{
[Dependency] private readonly IConsoleHost _console = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly IEntityManager _entManager = default!;
[Dependency] private readonly MapSystem _mapSystem = default!;
[Dependency] private readonly ITileDefinitionManager _tileDefManager = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly ChatSystem _chat = default!;
[Dependency] private readonly RadiationSystem _radiation = default!;
[Dependency] private readonly TransformSystem _xform = default!;

private List<Entity<MapGridComponent>> _grids = new();

public override void Initialize()
{
Expand All @@ -22,6 +46,20 @@ public override void Initialize()
Loc.GetString("cmd-weather-help"),
WeatherTwo,
WeatherCompletion);
SubscribeLocalEvent<WeatherComponent, MapInitEvent>(OnMapInit);
}

private void OnMapInit(EntityUid uid, WeatherComponent component, MapInitEvent args)
{
Logger.InfoS("weather", $"UID = {uid}!");
EnsureComp<WeatherComponent>(uid);
var mapId = _entManager.GetComponent<TransformComponent>(uid).MapID;
if (!ProtoMan.TryIndex<WeatherPrototype>("Default", out var weatherProto))
return;
var curTime = Timing.CurTime;
Logger.InfoS("weather", $"proto = {weatherProto}!");
SetWeather(mapId, weatherProto, curTime + TimeSpan.FromSeconds(30));

}

private void OnWeatherGetState(EntityUid uid, WeatherComponent component, ref ComponentGetState args)
Expand Down Expand Up @@ -95,4 +133,68 @@ private CompletionResult WeatherCompletion(IConsoleShell shell, string[] args)
var a = CompletionHelper.PrototypeIDs<WeatherPrototype>(true, ProtoMan);
return CompletionResult.FromHintOptions(a, Loc.GetString("cmd-weather-hint"));
}

protected override void Run(EntityUid uid, WeatherData weather, WeatherPrototype weatherProto, float frameTime)
{
var atmosphereSystem = _entManager.System<AtmosphereSystem>();

foreach (var session in _playerManager.Sessions)
{
if (session.AttachedEntity is not {Valid: true} entity)
continue;
var transform = Transform(entity);
var gridUid = transform.GridUid;

if (!TryComp<MapGridComponent>(gridUid, out var map))
return;
var tiles = map.GetTilesIntersecting(Box2.CenteredAround(transform.WorldPosition,
new Vector2(5, 5))).ToArray();

foreach(var tile in tiles)
{
var tileDef = (ContentTileDefinition) _tileDefManager[tile.Tile.TypeId];
var environment = atmosphereSystem.GetTileMixture(tile.GridUid, transform.MapUid, tile.GridIndices, false);
if(environment == null)
continue;
if(tileDef.Weather)
environment.Temperature = weatherProto.Temperature;
else
environment.Temperature = 293.15f;
}
}
}

public override void SelectNewWeather(EntityUid uid, WeatherComponent component, string proto)
{
var mapId = _entManager.GetComponent<TransformComponent>(uid).MapID;
if (!TryComp<WeatherComponent>(MapManager.GetMapEntityId(mapId), out var weatherComp))
return;
var curTime = Timing.CurTime;

if(proto == "Default")
{
if (!ProtoMan.TryGetRandom<WeatherPrototype>(_random, out var wproto))
return;
Logger.InfoS("weather", $"new weather = {proto}!");
var weatherProto = (WeatherPrototype) wproto;
SetWeather(mapId, weatherProto, curTime + TimeSpan.FromSeconds(weatherProto.Duration));
if(weatherProto.ShowMessage && weatherProto.Message != string.Empty)
{
var message = Loc.GetString(weatherProto.Message);
var sender = weatherProto.Sender != null ? Loc.GetString(weatherProto.Sender) : "Inner feeling";
var color = weatherProto.Color != null ? weatherProto.Color : Color.LightGray;
_chat.DispatchGlobalAnnouncement(message, sender, playSound: false, null, color);
}
}

else
{
if(!ProtoMan.TryIndex<WeatherPrototype>("Default", out var weatherProto))
return;
Logger.InfoS("weather", $"proto = {weatherProto}!");
SetWeather(mapId, weatherProto, curTime + TimeSpan.FromSeconds(weatherProto.Duration));

}
}

}
40 changes: 39 additions & 1 deletion Content.Shared/Weather/SharedWeatherSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Timing;
using Robust.Shared.Random;
using Robust.Shared.GameObjects;

namespace Content.Shared.Weather;

Expand All @@ -18,6 +20,8 @@ public abstract class SharedWeatherSystem : EntitySystem
[Dependency] private readonly ITileDefinitionManager _tileDefManager = default!;
[Dependency] private readonly MetaDataSystem _metadata = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly IEntityManager _entManager = default!;

private EntityQuery<BlockWeatherComponent> _blockQuery;
private EntityQuery<PhysicsComponent> _physicsQuery;
Expand Down Expand Up @@ -89,6 +93,32 @@ public float GetPercent(WeatherData component, EntityUid mapUid)
return alpha;
}

public virtual void SelectNewWeather(EntityUid uid, WeatherComponent component, string proto)
{
Logger.InfoS("weather", $"UID = {uid}!");
var mapId = _entManager.GetComponent<TransformComponent>(uid).MapID;
if (!TryComp<WeatherComponent>(MapManager.GetMapEntityId(mapId), out var weatherComp))
return;
var curTime = Timing.CurTime;

if(proto == "Default")
{
if (!ProtoMan.TryGetRandom<WeatherPrototype>(_random, out var weatherProto))
return;
Logger.InfoS("weather", $"proto = {weatherProto}!");

SetWeather(mapId, (WeatherPrototype) weatherProto, curTime + TimeSpan.FromSeconds(30));
}

else
{
if(!ProtoMan.TryIndex<WeatherPrototype>("Default", out var weatherProto))
return;
Logger.InfoS("weather", $"proto = {weatherProto}!");
SetWeather(mapId, weatherProto, curTime + TimeSpan.FromSeconds(30));

}
}

public override void Update(float frameTime)
{
Expand All @@ -104,7 +134,8 @@ public override void Update(float frameTime)
{
if (comp.Weather.Count == 0)
continue;

try
{
foreach (var (proto, weather) in comp.Weather)
{
var endTime = weather.EndTime;
Expand All @@ -113,6 +144,7 @@ public override void Update(float frameTime)
if (endTime != null && endTime < curTime)
{
EndWeather(uid, comp, proto);
SelectNewWeather(uid, comp, proto);
continue;
}

Expand All @@ -123,6 +155,7 @@ public override void Update(float frameTime)
{
Log.Error($"Unable to find weather prototype for {comp.Weather}, ending!");
EndWeather(uid, comp, proto);
SelectNewWeather(uid, comp, proto);
continue;
}

Expand All @@ -146,6 +179,11 @@ public override void Update(float frameTime)
// Run whatever code we need.
Run(uid, weather, weatherProto, frameTime);
}
}
catch(InvalidOperationException)
{
// we have it since dictionary is changed in foreach loop when weather is changing. It seem not to affect anything
}
}
}

Expand Down
47 changes: 45 additions & 2 deletions Content.Shared/Weather/WeatherPrototype.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ public sealed partial class WeatherPrototype : IPrototype
{
[IdDataField] public string ID { get; } = default!;

[ViewVariables(VVAccess.ReadWrite), DataField("sprite", required: true)]
public SpriteSpecifier Sprite = default!;
[ViewVariables(VVAccess.ReadWrite), DataField("sprite")]
public SpriteSpecifier? Sprite;

[ViewVariables(VVAccess.ReadWrite), DataField("color")]
public Color? Color;
Expand All @@ -20,4 +20,47 @@ public sealed partial class WeatherPrototype : IPrototype
/// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField("sound")]
public SoundSpecifier? Sound;

/// <summary>
/// Weather temperature applied to floors.
/// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField("temperature")]
public float Temperature = 308.15f;

/// <summary>
/// Locale id of the weather announcement message.
/// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField("message")]
public LocId Message = string.Empty;

/// <summary>
/// Locale id of the announcement's sender, defaults to Inner Feeling.
/// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField("sender")]
public LocId? Sender;

/// <summary>
/// Whenever to show message about new weather or not.
/// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField("showMessage")]
public Boolean ShowMessage = false;

/// <summary>
/// If weather should deal radiation damage.
/// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField("radioactive")]
public Boolean Radioactive = false;

/// <summary>
/// How many rads damage per second
/// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField("rads")]
public float RadsPerSecond = 1;

/// <summary>
/// How long is the weather, in seconds
/// </summary>
[ViewVariables(VVAccess.ReadWrite), DataField("duration")]
public float Duration = 300;

}
6 changes: 6 additions & 0 deletions Resources/Locale/en-US/Nuclear14/weather.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
weather-announcement = The weather is changing
ashfall-heavy = Heavy ashfall is approaching
weather-fallout = Fallout is approaching
weather-sandstorm-heavy = Sandstorm is approaching
weather-snowfall-heavy = Snowfall is approaching
weather-storm = Storm is approaching
1 change: 1 addition & 0 deletions Resources/Maps/N14/wave1.yml
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ entities:
tiles: GAAAAAADGAAAAAAGGAAAAAAFGAAAAAAEGAAAAAAEGAAAAAADGAAAAAAEGAAAAAABGAAAAAAAGAAAAAADGAAAAAAAGAAAAAAAGAAAAAAAGAAAAAAGAAAAAAAAAAAAAAAAGAAAAAACGAAAAAABGAAAAAACGAAAAAAAGAAAAAADGAAAAAADGAAAAAAAGAAAAAACGAAAAAABGAAAAAAEGAAAAAAAGAAAAAABGAAAAAABGAAAAAAAAAAAAAAAAAAAAAAAGAAAAAABGAAAAAADGAAAAAABGAAAAAAFGAAAAAAGGAAAAAAAGAAAAAADGAAAAAAGGAAAAAAEGAAAAAADGAAAAAAFGAAAAAAEGAAAAAAGGAAAAAAFAAAAAAAAAAAAAAAAGAAAAAAFGAAAAAAEGAAAAAAGGAAAAAAFGAAAAAAGGAAAAAACGAAAAAAAGAAAAAACGAAAAAADGAAAAAAFGAAAAAAAGAAAAAABGAAAAAAAGAAAAAACAAAAAAAAAAAAAAAAGAAAAAAFGAAAAAAGGAAAAAACGAAAAAABGAAAAAAFGAAAAAABGAAAAAABGAAAAAAFGAAAAAAEGAAAAAACGAAAAAADGAAAAAACGAAAAAAAGAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
version: 6
- type: Broadphase
- type: Weather
- type: Physics
bodyStatus: InAir
angularDamping: 0.05
Expand Down
Loading
Loading