Skip to content

Commit

Permalink
Merge pull request #344 from Rxup/upstream-sync
Browse files Browse the repository at this point in the history
Upstream sync
  • Loading branch information
Rxup authored Nov 23, 2023
2 parents a2fa0e7 + 86227b2 commit 9ab1283
Show file tree
Hide file tree
Showing 89 changed files with 763 additions and 268 deletions.
4 changes: 2 additions & 2 deletions Content.Client/Construction/ConstructionSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ public bool TrySpawnGhost(
var comp = EntityManager.GetComponent<ConstructionGhostComponent>(ghost.Value);
comp.Prototype = prototype;
EntityManager.GetComponent<TransformComponent>(ghost.Value).LocalRotation = dir.ToAngle();
_ghosts.Add(ghost.Value.Id, ghost.Value);
_ghosts.Add(ghost.GetHashCode(), ghost.Value);
var sprite = EntityManager.GetComponent<SpriteComponent>(ghost.Value);
sprite.Color = new Color(48, 255, 48, 128);

Expand Down Expand Up @@ -265,7 +265,7 @@ public void TryStartConstruction(EntityUid ghostId, ConstructionGhostComponent?
}

var transform = EntityManager.GetComponent<TransformComponent>(ghostId);
var msg = new TryStartStructureConstructionMessage(GetNetCoordinates(transform.Coordinates), ghostComp.Prototype.ID, transform.LocalRotation, ghostId.Id);
var msg = new TryStartStructureConstructionMessage(GetNetCoordinates(transform.Coordinates), ghostComp.Prototype.ID, transform.LocalRotation, ghostId.GetHashCode());
RaiseNetworkEvent(msg);
}

Expand Down
24 changes: 15 additions & 9 deletions Content.Client/Decals/DecalSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ public sealed class DecalSystem : SharedDecalSystem

private DecalOverlay _overlay = default!;

private HashSet<uint> _removedUids = new();
private readonly List<Vector2i> _removedChunks = new();

public override void Initialize()
{
base.Initialize();
Expand Down Expand Up @@ -65,26 +68,27 @@ private void OnHandleState(EntityUid gridUid, DecalGridComponent gridComp, ref C
return;

// is this a delta or full state?
var removedChunks = new List<Vector2i>();
_removedChunks.Clear();

if (!state.FullState)
{
foreach (var key in gridComp.ChunkCollection.ChunkCollection.Keys)
{
if (!state.AllChunks!.Contains(key))
removedChunks.Add(key);
_removedChunks.Add(key);
}
}
else
{
foreach (var key in gridComp.ChunkCollection.ChunkCollection.Keys)
{
if (!state.Chunks.ContainsKey(key))
removedChunks.Add(key);
_removedChunks.Add(key);
}
}

if (removedChunks.Count > 0)
RemoveChunks(gridUid, gridComp, removedChunks);
if (_removedChunks.Count > 0)
RemoveChunks(gridUid, gridComp, _removedChunks);

if (state.Chunks.Count > 0)
UpdateChunks(gridUid, gridComp, state.Chunks);
Expand Down Expand Up @@ -137,9 +141,10 @@ private void UpdateChunks(EntityUid gridId, DecalGridComponent gridComp, Diction
{
if (chunkCollection.TryGetValue(indices, out var chunk))
{
var removedUids = new HashSet<uint>(chunk.Decals.Keys);
removedUids.ExceptWith(newChunkData.Decals.Keys);
foreach (var removedUid in removedUids)
_removedUids.Clear();
_removedUids.UnionWith(chunk.Decals.Keys);
_removedUids.ExceptWith(newChunkData.Decals.Keys);
foreach (var removedUid in _removedUids)
{
OnDecalRemoved(gridId, removedUid, gridComp, indices, chunk);
gridComp.DecalIndex.Remove(removedUid);
Expand All @@ -166,7 +171,8 @@ private void RemoveChunks(EntityUid gridId, DecalGridComponent gridComp, IEnumer

foreach (var index in chunks)
{
if (!chunkCollection.TryGetValue(index, out var chunk)) continue;
if (!chunkCollection.TryGetValue(index, out var chunk))
continue;

foreach (var decalId in chunk.Decals.Keys)
{
Expand Down
13 changes: 7 additions & 6 deletions Content.Client/Decals/Overlays/DecalOverlay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,22 @@ protected override void Draw(in OverlayDrawArgs args)
{
// Shouldn't need to clear cached textures unless the prototypes get reloaded.
var handle = args.WorldHandle;
var xformQuery = _entManager.GetEntityQuery<TransformComponent>();
var xformSystem = _entManager.System<TransformSystem>();
var eyeAngle = args.Viewport.Eye?.Rotation ?? Angle.Zero;

foreach (var (decalGrid, xform) in _entManager.EntityQuery<DecalGridComponent, TransformComponent>(true))
var gridQuery = _entManager.AllEntityQueryEnumerator<DecalGridComponent, TransformComponent>();

while (gridQuery.MoveNext(out var decalGrid, out var xform))
{
if (xform.MapID != args.MapId)
continue;

var zIndexDictionary = decalGrid.DecalRenderIndex;

if (zIndexDictionary.Count == 0)
continue;

if (xform.MapID != args.MapId)
continue;

var (_, worldRot, worldMatrix) = xformSystem.GetWorldPositionRotationMatrix(xform, xformQuery);
var (_, worldRot, worldMatrix) = xformSystem.GetWorldPositionRotationMatrix(xform);

handle.SetTransform(worldMatrix);

Expand Down
2 changes: 1 addition & 1 deletion Content.Client/PDA/PdaWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
</Control>
<!--Footer-->
<BoxContainer Orientation="Horizontal" SetHeight="28">
<Label Text="Personal Digital Assistant" StyleClasses="PdaWindowFooterText" Margin="32 0 0 6"/>
<Label Text="{Loc 'comp-pda-ui-footer'}" StyleClasses="PdaWindowFooterText" Margin="32 0 0 6"/>
</BoxContainer>
</BoxContainer>
</pda:PdaWindow>
218 changes: 218 additions & 0 deletions Content.Client/Weather/WeatherOverlay.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
using System.Linq;
using System.Numerics;
using Content.Client.Parallax;
using Content.Shared.Weather;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.ResourceManagement;
using Robust.Client.Utility;
using Robust.Shared.Enums;
using Robust.Shared.Graphics.RSI;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Physics.Components;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using Robust.Shared.Utility;

namespace Content.Client.Weather;

public sealed class WeatherOverlay : Overlay
{
[Dependency] private readonly IClyde _clyde = default!;
[Dependency] private readonly IEntityManager _entManager = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly IPrototypeManager _protoManager = default!;
[Dependency] private readonly IResourceCache _cache = default!;
private readonly SharedTransformSystem _transform;
private readonly SpriteSystem _sprite;
private readonly WeatherSystem _weather;

public override OverlaySpace Space => OverlaySpace.WorldSpaceBelowFOV;

private IRenderTexture? _blep;

public WeatherOverlay(SharedTransformSystem transform, SpriteSystem sprite, WeatherSystem weather)
{
ZIndex = ParallaxSystem.ParallaxZIndex + 1;
_transform = transform;
_weather = weather;
_sprite = sprite;
IoCManager.InjectDependencies(this);
}

protected override bool BeforeDraw(in OverlayDrawArgs args)
{
if (args.MapId == MapId.Nullspace)
return false;

if (!_entManager.TryGetComponent<WeatherComponent>(_mapManager.GetMapEntityId(args.MapId), out var weather) ||
weather.Weather.Count == 0)
{
return false;
}

return base.BeforeDraw(in args);
}

protected override void Draw(in OverlayDrawArgs args)
{
var mapUid = _mapManager.GetMapEntityId(args.MapId);

if (!_entManager.TryGetComponent<WeatherComponent>(mapUid, out var comp))
{
return;
}

foreach (var (proto, weather) in comp.Weather)
{
if (!_protoManager.TryIndex<WeatherPrototype>(proto, out var weatherProto))
continue;

var alpha = _weather.GetPercent(weather, mapUid);
DrawWorld(args, weatherProto, alpha);
}
}

private void DrawWorld(in OverlayDrawArgs args, WeatherPrototype weatherProto, float alpha)
{
var worldHandle = args.WorldHandle;
var mapId = args.MapId;
var worldAABB = args.WorldAABB;
var worldBounds = args.WorldBounds;
var invMatrix = args.Viewport.GetWorldToLocalMatrix();
var position = args.Viewport.Eye?.Position.Position ?? Vector2.Zero;

if (_blep?.Texture.Size != args.Viewport.Size)
{
_blep?.Dispose();
_blep = _clyde.CreateRenderTarget(args.Viewport.Size, new RenderTargetFormatParameters(RenderTargetColorFormat.Rgba8Srgb), name: "weather-stencil");
}

// Cut out the irrelevant bits via stencil
// This is why we don't just use parallax; we might want specific tiles to get drawn over
// particularly for planet maps or stations.
worldHandle.RenderInRenderTarget(_blep, () =>
{
var bodyQuery = _entManager.GetEntityQuery<PhysicsComponent>();
var xformQuery = _entManager.GetEntityQuery<TransformComponent>();
var weatherIgnoreQuery = _entManager.GetEntityQuery<IgnoreWeatherComponent>();

// idk if this is safe to cache in a field and clear sloth help
var grids = new List<Entity<MapGridComponent>>();
_mapManager.FindGridsIntersecting(mapId, worldAABB, ref grids);

foreach (var grid in grids)
{
var matrix = _transform.GetWorldMatrix(grid, xformQuery);
Matrix3.Multiply(in matrix, in invMatrix, out var matty);
worldHandle.SetTransform(matty);

foreach (var tile in grid.Comp.GetTilesIntersecting(worldAABB))
{
// Ignored tiles for stencil
if (_weather.CanWeatherAffect(grid, tile, weatherIgnoreQuery, bodyQuery))
{
continue;
}

var gridTile = new Box2(tile.GridIndices * grid.Comp.TileSize,
(tile.GridIndices + Vector2i.One) * grid.Comp.TileSize);

worldHandle.DrawRect(gridTile, Color.White);
}
}

}, Color.Transparent);

worldHandle.SetTransform(Matrix3.Identity);
worldHandle.UseShader(_protoManager.Index<ShaderPrototype>("StencilMask").Instance());
worldHandle.DrawTextureRect(_blep.Texture, worldBounds);
Texture? sprite = null;
var curTime = _timing.RealTime;

switch (weatherProto.Sprite)
{
case SpriteSpecifier.Rsi rsi:
var rsiActual = _cache.GetResource<RSIResource>(rsi.RsiPath).RSI;
rsiActual.TryGetState(rsi.RsiState, out var state);
var frames = state!.GetFrames(RsiDirection.South);
var delays = state.GetDelays();
var totalDelay = delays.Sum();
var time = curTime.TotalSeconds % totalDelay;
var delaySum = 0f;

for (var i = 0; i < delays.Length; i++)
{
var delay = delays[i];
delaySum += delay;

if (time > delaySum)
continue;

sprite = frames[i];
break;
}

sprite ??= _sprite.Frame0(weatherProto.Sprite);
break;
case SpriteSpecifier.Texture texture:
sprite = texture.GetTexture(_cache);
break;
default:
throw new NotImplementedException();
}

// Draw the rain
worldHandle.UseShader(_protoManager.Index<ShaderPrototype>("StencilDraw").Instance());

// TODO: This is very similar to parallax but we need stencil support but we can probably combine these somehow
// and not make it spaghetti, while getting the advantages of not-duped code?


// Okay I have spent like 5 hours on this at this point and afaict you have one of the following comprises:
// - No scrolling so the weather is always centered on the player
// - Crappy looking rotation but strafing looks okay and scrolls
// - Crappy looking strafing but rotation looks okay.
// - No rotation
// - Storing state across frames to do scrolling and just having it always do topdown.

// I have chosen no rotation.

const float scale = 1f;
const float slowness = 0f;
var scrolling = Vector2.Zero;

// Size of the texture in world units.
var size = (sprite.Size / (float) EyeManager.PixelsPerMeter) * scale;
var scrolled = scrolling * (float) curTime.TotalSeconds;

// Origin - start with the parallax shift itself.
var originBL = position * slowness + scrolled;

// Centre the image.
originBL -= size / 2;

// Remove offset so we can floor.
var flooredBL = args.WorldAABB.BottomLeft - originBL;

// Floor to background size.
flooredBL = (flooredBL / size).Floored() * size;

// Re-offset.
flooredBL += originBL;

for (var x = flooredBL.X; x < args.WorldAABB.Right; x += size.X)
{
for (var y = flooredBL.Y; y < args.WorldAABB.Top; y += size.Y)
{
var box = Box2.FromDimensions(new Vector2(x, y), size);
worldHandle.DrawTextureRect(sprite, box, (weatherProto.Color ?? Color.White).WithAlpha(alpha));
}
}

worldHandle.SetTransform(Matrix3.Identity);
worldHandle.UseShader(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ protected void AssertDeleted(bool deleted = true, NetEntity? target = null)
/// <summary>
/// Assert whether or not the target has the given component.
/// </summary>
protected void AssertComp<T>(bool hasComp = true, NetEntity? target = null)
protected void AssertComp<T>(bool hasComp = true, NetEntity? target = null) where T : IComponent
{
target ??= Target;
if (target == null)
Expand Down
6 changes: 3 additions & 3 deletions Content.IntegrationTests/Tests/PrototypeSaveTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ await server.WaitAssertion(() =>
}

// An entity may also remove components on init -> check no components are missing.
foreach (var (compType, comp) in prototype.Components)
foreach (var compType in prototype.Components.Keys)
{
Assert.That(compNames, Does.Contain(compType), $"Prototype {prototype.ID} removes component {compType} on spawn.");
}
Expand Down Expand Up @@ -208,7 +208,7 @@ public DataNode Write(ISerializationManager serializationManager, EntityUid valu
Assert.Fail($"Uninitialized entities should not be saving entity Uids. Component: {WritingComponent}. Prototype: {Prototype.ID}");
}

return new ValueDataNode(value.ToString());
return new ValueDataNode(value.Id.ToString());
}

EntityUid ITypeReader<EntityUid, ValueDataNode>.Read(ISerializationManager serializationManager,
Expand All @@ -217,7 +217,7 @@ EntityUid ITypeReader<EntityUid, ValueDataNode>.Read(ISerializationManager seria
SerializationHookContext hookCtx,
ISerializationContext? context, ISerializationManager.InstantiationDelegate<EntityUid>? instanceProvider)
{
return EntityUid.Parse(node.Value);
return EntityUid.Parse(node.Value, "0");
}
}
}
6 changes: 3 additions & 3 deletions Content.Server/Administration/Commands/ControlMob.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ public void Execute(IConsoleShell shell, string argStr, string[] args)
return;
}

var target = new EntityUid(targetId);
var targetNet = new NetEntity(targetId);

if (!target.IsValid() || !_entities.EntityExists(target))
if (!_entities.TryGetEntity(targetNet, out var target))
{
shell.WriteLine(Loc.GetString("shell-invalid-entity-id"));
return;
}

_entities.System<MindSystem>().ControlMob(player.UserId, target);
_entities.System<MindSystem>().ControlMob(player.UserId, target.Value);
}
}
}
Loading

0 comments on commit 9ab1283

Please sign in to comment.