Skip to content
This repository has been archived by the owner on Oct 23, 2024. It is now read-only.

Commit

Permalink
Weather (space-wizards#200)
Browse files Browse the repository at this point in the history
* tweak weather duration and temp a little

(cherry picked from commit 65efaa4e844e632f56256b400ed3661f8551ecd3)

* add: dynamic weather with it's own temperature

(cherry picked from commit ca5bd564ccac0c8a91662eddb9415bf7d1ec8360)

* clean up weather systems (space-wizards#28792)

* clean up weather systems

* Update WeatherComponent.cs

* Update SharedWeatherSystem.cs

* some fix

* Update SharedWeatherSystem.cs

* Update WeatherComponent.cs

* Update WeatherComponent.cs

* revert autoPause

* Update SharedWeatherSystem.cs

(cherry picked from commit a1e66cf)

* fix

* Weather fix (space-wizards#30857)

* weather fix

* localize errors

(cherry picked from commit ff412a6)

* two extreme weather variants and increase atmos transfer to mobs

* remaining commit

* fix weather localisation, remove duplicate localisation

---------

Co-authored-by: Dan <jamasty@protonmail.com>
  • Loading branch information
Peptide90 and SpaceCowboyServer authored Sep 4, 2024
1 parent 451ad68 commit 9807371
Show file tree
Hide file tree
Showing 18 changed files with 394 additions and 196 deletions.
4 changes: 3 additions & 1 deletion 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 All @@ -38,7 +40,7 @@ private void DrawWeather(in OverlayDrawArgs args, WeatherPrototype weatherProto,
foreach (var tile in grid.Comp.GetTilesIntersecting(worldAABB))
{
// Ignored tiles for stencil
if (_weather.CanWeatherAffect(grid, tile))
if (_weather.CanWeatherAffect(grid.Owner, grid, tile))
{
continue;
}
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
13 changes: 4 additions & 9 deletions Content.Client/Weather/WeatherSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,11 @@
using Content.Shared.Weather;
using Robust.Client.Audio;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
using Robust.Shared.GameStates;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems;
using Robust.Shared.Player;
using AudioComponent = Robust.Shared.Audio.Components.AudioComponent;

Expand Down Expand Up @@ -62,7 +57,7 @@ protected override void Run(EntityUid uid, WeatherData weather, WeatherPrototype
if (TryComp<MapGridComponent>(entXform.GridUid, out var grid))
{
var gridId = entXform.GridUid.Value;
// Floodfill to the nearest tile and use that for audio.
// FloodFill to the nearest tile and use that for audio.
var seed = _mapSystem.GetTileRef(gridId, grid, entXform.Coordinates);
var frontier = new Queue<TileRef>();
frontier.Enqueue(seed);
Expand All @@ -75,7 +70,7 @@ protected override void Run(EntityUid uid, WeatherData weather, WeatherPrototype
if (!visited.Add(node.GridIndices))
continue;

if (!CanWeatherAffect(grid, node))
if (!CanWeatherAffect(entXform.GridUid.Value, grid, node))
{
// Add neighbors
// TODO: Ideally we pick some deterministically random direction and use that
Expand Down Expand Up @@ -107,7 +102,7 @@ protected override void Run(EntityUid uid, WeatherData weather, WeatherPrototype
if (nearestNode != null)
{
var entPos = _transform.GetMapCoordinates(entXform);
var nodePosition = nearestNode.Value.ToMap(EntityManager, _transform).Position;
var nodePosition = _transform.ToMapCoordinates(nearestNode.Value).Position;
var delta = nodePosition - entPos.Position;
var distance = delta.Length();
occlusion = _audio.GetOcclusion(entPos, delta, distance);
Expand Down Expand Up @@ -164,7 +159,7 @@ private void OnWeatherHandleState(EntityUid uid, WeatherComponent component, ref
continue;

// New weather
StartWeather(component, ProtoMan.Index<WeatherPrototype>(proto), weather.EndTime);
StartWeather(uid, component, ProtoMan.Index<WeatherPrototype>(proto), weather.EndTime);
}
}
}
157 changes: 126 additions & 31 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 SharedMapSystem _mapSystem = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly IEntityManager _entManager = 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 All @@ -30,61 +68,54 @@ private void OnWeatherGetState(EntityUid uid, WeatherComponent component, ref Co
}

[AdminCommand(AdminFlags.Fun)]
private void WeatherTwo(IConsoleShell shell, string argstr, string[] args)
private void WeatherTwo(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length < 2)
{
shell.WriteError($"A");
shell.WriteError(Loc.GetString("cmd-weather-error-no-arguments"));
return;
}

if (!int.TryParse(args[0], out var mapInt))
{
return;
}

var mapId = new MapId(mapInt);

if (!MapManager.MapExists(mapId))
{
return;

if (!_mapSystem.TryGetMap(mapId, out var mapUid))
return;

var weatherComp = EnsureComp<WeatherComponent>(mapUid.Value);

//Weather Proto parsing
WeatherPrototype? weather = null;
if (!args[1].Equals("null"))
{
if (!ProtoMan.TryIndex(args[1], out weather))
{
shell.WriteError(Loc.GetString("cmd-weather-error-unknown-proto"));
return;
}
}

//Time parsing
TimeSpan? endTime = null;

if (args.Length == 3)
{
var curTime = Timing.CurTime;
if (int.TryParse(args[2], out var durationInt))
{
var curTime = Timing.CurTime;
var maxTime = TimeSpan.MaxValue;

// If it's already running then just fade out with how much time we're into the weather.
if (TryComp<WeatherComponent>(MapManager.GetMapEntityId(mapId), out var weatherComp) &&
weatherComp.Weather.TryGetValue(args[1], out var existing))
{
maxTime = curTime - existing.StartTime;
}

endTime = curTime + TimeSpan.FromSeconds(durationInt);

if (endTime > maxTime)
endTime = maxTime;
}
else
{
shell.WriteError(Loc.GetString("cmd-weather-error-wrong-time"));
}
}

if (args[1].Equals("null"))
{
SetWeather(mapId, null, endTime);
}
else if (ProtoMan.TryIndex<WeatherPrototype>(args[1], out var weatherProto))
{
SetWeather(mapId, weatherProto, endTime);
}
else
{
shell.WriteError($"Unable to parse weather prototype");
}
SetWeather(mapId, weather, endTime);
}

private CompletionResult WeatherCompletion(IConsoleShell shell, string[] args)
Expand All @@ -95,4 +126,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));

}
}

}
Loading

0 comments on commit 9807371

Please sign in to comment.