Skip to content

Commit

Permalink
Merge pull request #89 from Space-Stories/master
Browse files Browse the repository at this point in the history
Upstream branch sync
  • Loading branch information
doublechest0 authored Sep 11, 2024
2 parents 2641d1d + 56d472e commit 12eecfb
Show file tree
Hide file tree
Showing 427 changed files with 717,895 additions and 572,196 deletions.
96 changes: 96 additions & 0 deletions Content.Client/Mining/MiningOverlay.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
using System.Numerics;
using Content.Shared.Mining.Components;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Shared.Enums;
using Robust.Shared.Timing;
using Robust.Shared.Utility;

namespace Content.Client.Mining;

public sealed class MiningOverlay : Overlay
{
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly IPlayerManager _player = default!;
private readonly EntityLookupSystem _lookup;
private readonly SpriteSystem _sprite;
private readonly TransformSystem _xform;

private readonly EntityQuery<SpriteComponent> _spriteQuery;
private readonly EntityQuery<TransformComponent> _xformQuery;

public override OverlaySpace Space => OverlaySpace.WorldSpace;
public override bool RequestScreenTexture => false;

private readonly HashSet<Entity<MiningScannerViewableComponent>> _viewableEnts = new();

public MiningOverlay()
{
IoCManager.InjectDependencies(this);

_lookup = _entityManager.System<EntityLookupSystem>();
_sprite = _entityManager.System<SpriteSystem>();
_xform = _entityManager.System<TransformSystem>();

_spriteQuery = _entityManager.GetEntityQuery<SpriteComponent>();
_xformQuery = _entityManager.GetEntityQuery<TransformComponent>();
}

protected override void Draw(in OverlayDrawArgs args)
{
var handle = args.WorldHandle;

if (_player.LocalEntity is not { } localEntity ||
!_entityManager.TryGetComponent<MiningScannerViewerComponent>(localEntity, out var viewerComp))
return;

if (viewerComp.LastPingLocation == null)
return;

var scaleMatrix = Matrix3Helpers.CreateScale(Vector2.One);

_viewableEnts.Clear();
_lookup.GetEntitiesInRange(viewerComp.LastPingLocation.Value, viewerComp.ViewRange, _viewableEnts);
foreach (var ore in _viewableEnts)
{
if (!_xformQuery.TryComp(ore, out var xform) ||
!_spriteQuery.TryComp(ore, out var sprite))
continue;

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

if (!sprite.LayerMapTryGet(MiningScannerVisualLayers.Overlay, out var idx))
continue;
var layer = sprite[idx];

if (layer.ActualRsi?.Path == null || layer.RsiState.Name == null)
continue;

var gridRot = xform.GridUid == null ? 0 : _xformQuery.CompOrNull(xform.GridUid.Value)?.LocalRotation ?? 0;
var rotationMatrix = Matrix3Helpers.CreateRotation(gridRot);

var worldMatrix = Matrix3Helpers.CreateTranslation(_xform.GetWorldPosition(xform));
var scaledWorld = Matrix3x2.Multiply(scaleMatrix, worldMatrix);
var matty = Matrix3x2.Multiply(rotationMatrix, scaledWorld);
handle.SetTransform(matty);

var spriteSpec = new SpriteSpecifier.Rsi(layer.ActualRsi.Path, layer.RsiState.Name);
var texture = _sprite.GetFrame(spriteSpec, TimeSpan.FromSeconds(layer.AnimationTime));

var animTime = (viewerComp.NextPingTime - _timing.CurTime).TotalSeconds;


var alpha = animTime < viewerComp.AnimationDuration
? 0
: (float) Math.Clamp((animTime - viewerComp.AnimationDuration) / viewerComp.AnimationDuration, 0f, 1f);
var color = Color.White.WithAlpha(alpha);

handle.DrawTexture(texture, -(Vector2) texture.Size / 2f / EyeManager.PixelsPerMeter, layer.Rotation, modulate: color);

}
handle.SetTransform(Matrix3x2.Identity);
}
}
54 changes: 54 additions & 0 deletions Content.Client/Mining/MiningOverlaySystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using Content.Shared.Mining.Components;
using Robust.Client.Graphics;
using Robust.Client.Player;
using Robust.Shared.Player;

namespace Content.Client.Mining;

/// <summary>
/// This handles the lifetime of the <see cref="MiningOverlay"/> for a given entity.
/// </summary>
public sealed class MiningOverlaySystem : EntitySystem
{
[Dependency] private readonly IPlayerManager _player = default!;
[Dependency] private readonly IOverlayManager _overlayMan = default!;

private MiningOverlay _overlay = default!;

/// <inheritdoc/>
public override void Initialize()
{
SubscribeLocalEvent<MiningScannerViewerComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<MiningScannerViewerComponent, ComponentShutdown>(OnShutdown);
SubscribeLocalEvent<MiningScannerViewerComponent, LocalPlayerAttachedEvent>(OnPlayerAttached);
SubscribeLocalEvent<MiningScannerViewerComponent, LocalPlayerDetachedEvent>(OnPlayerDetached);

_overlay = new();
}

private void OnPlayerAttached(Entity<MiningScannerViewerComponent> ent, ref LocalPlayerAttachedEvent args)
{
_overlayMan.AddOverlay(_overlay);
}

private void OnPlayerDetached(Entity<MiningScannerViewerComponent> ent, ref LocalPlayerDetachedEvent args)
{
_overlayMan.RemoveOverlay(_overlay);
}

private void OnInit(Entity<MiningScannerViewerComponent> ent, ref ComponentInit args)
{
if (_player.LocalEntity == ent)
{
_overlayMan.AddOverlay(_overlay);
}
}

private void OnShutdown(Entity<MiningScannerViewerComponent> ent, ref ComponentShutdown args)
{
if (_player.LocalEntity == ent)
{
_overlayMan.RemoveOverlay(_overlay);
}
}
}
6 changes: 0 additions & 6 deletions Content.Client/Mining/OreVeinVisualsComponent.cs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using Content.Shared.Nutrition.Components;
using Content.Shared.Nutrition.EntitySystems;
using Robust.Client.GameObjects;
using Robust.Shared.Utility;

namespace Content.Client.Nutrition.EntitySystems;

Expand Down Expand Up @@ -50,6 +49,7 @@ private void UpdateFoodVisuals(Entity<FoodSequenceStartPointComponent> start, Sp
sprite.AddBlankLayer(index);
sprite.LayerMapSet(keyCode, index);
sprite.LayerSetSprite(index, state.Sprite);
sprite.LayerSetScale(index, state.Scale);

//Offset the layer
var layerPos = start.Comp.StartPosition;
Expand Down
2 changes: 1 addition & 1 deletion Content.Client/Power/APC/ApcBoundUserInterface.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ public ApcBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
protected override void Open()
{
base.Open();

_menu = this.CreateWindow<ApcMenu>();
_menu.SetEntity(Owner);
_menu.OnBreaker += BreakerPressed;
}

Expand Down
61 changes: 61 additions & 0 deletions Content.Server/Anomaly/Components/TechAnomalyComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using Content.Server.Anomaly.Effects;
using Content.Shared.Destructible.Thresholds;
using Content.Shared.DeviceLinking;
using Robust.Shared.Prototypes;

namespace Content.Server.Anomaly.Components;

[RegisterComponent, AutoGenerateComponentPause, Access(typeof(TechAnomalySystem))]
public sealed partial class TechAnomalyComponent : Component
{
/// <summary>
/// the distance at which random ports will bind to the anomaly. Scales with severity.
/// </summary>
[DataField]
public MinMax LinkRadius = new(5, 10);

/// <summary>
/// the maximum number of entities with which an anomaly is associated during pulsing. Scales with severity
/// </summary>
[DataField]
public MinMax LinkCountPerPulse = new(2, 8);

/// <summary>
/// Number of linkable pairs. when supercrit, the anomaly will link random devices in the radius to each other in pairs.
/// </summary>
[DataField]
public int LinkCountSupercritical = 30;

/// <summary>
/// port activated by pulsation of the anomaly
/// </summary>
[DataField]
public ProtoId<SourcePortPrototype> PulsePort = "Pulse";

/// <summary>
/// A port that activates every few seconds of an anomaly's lifetime
/// </summary>
[DataField]
public ProtoId<SourcePortPrototype> TimerPort = "Timer";

/// <summary>
/// Chance of emag the device, when supercrit
/// </summary>
[DataField]
public float EmagSupercritProbability = 0.4f;

/// <summary>
/// A prototype beam shot into devices when pulsed
/// </summary>
[DataField]
public EntProtoId LinkBeamProto = "AnomalyTechBeam";

/// <summary>
/// time until the next activation of the timer ports
/// </summary>
[DataField, AutoPausedField]
public TimeSpan NextTimer = TimeSpan.Zero;

[DataField]
public float TimerFrequency = 3f;
}
125 changes: 125 additions & 0 deletions Content.Server/Anomaly/Effects/TechAnomalySystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
using Content.Server.Anomaly.Components;
using Content.Server.Beam;
using Content.Server.DeviceLinking.Systems;
using Content.Shared.Anomaly.Components;
using Content.Shared.DeviceLinking;
using Content.Shared.Emag.Systems;
using Robust.Shared.Random;
using Robust.Shared.Timing;

namespace Content.Server.Anomaly.Effects;

public sealed class TechAnomalySystem : EntitySystem
{
[Dependency] private readonly DeviceLinkSystem _signal = default!;
[Dependency] private readonly EntityLookupSystem _lookup = default!;
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly BeamSystem _beam = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly EmagSystem _emag = default!;

public override void Initialize()
{
base.Initialize();

SubscribeLocalEvent<TechAnomalyComponent, AnomalyPulseEvent>(OnPulse);
SubscribeLocalEvent<TechAnomalyComponent, AnomalySupercriticalEvent>(OnSupercritical);
SubscribeLocalEvent<TechAnomalyComponent, AnomalyStabilityChangedEvent>(OnStabilityChanged);
}

public override void Update(float frameTime)
{
base.Update(frameTime);

var query = EntityQueryEnumerator<TechAnomalyComponent, AnomalyComponent>();
while (query.MoveNext(out var uid, out var tech, out var anom))
{
if (_timing.CurTime < tech.NextTimer)
return;

tech.NextTimer = _timing.CurTime + TimeSpan.FromSeconds(tech.TimerFrequency * anom.Stability);

_signal.InvokePort(uid, tech.TimerPort);
}
}

private void OnStabilityChanged(Entity<TechAnomalyComponent> tech, ref AnomalyStabilityChangedEvent args)
{
var links = MathHelper.Lerp(tech.Comp.LinkCountPerPulse.Min, tech.Comp.LinkCountPerPulse.Max, args.Severity);
CreateNewRandomLink(tech, (int)links);
}

private void CreateNewRandomLink(Entity<TechAnomalyComponent> tech, int count)
{
if (!TryComp<AnomalyComponent>(tech, out var anomaly))
return;
if (!TryComp<DeviceLinkSourceComponent>(tech, out var sourceComp))
return;

var range = MathHelper.Lerp(tech.Comp.LinkRadius.Min, tech.Comp.LinkRadius.Max, anomaly.Severity);

var devices = _lookup.GetEntitiesInRange<DeviceLinkSinkComponent>(Transform(tech).Coordinates, range);
if (devices.Count < 1)
return;

for (var i = 0; i < count; i++)
{
var device = _random.Pick(devices);
CreateNewLink(tech, (tech, sourceComp), device);
}
}

private void CreateNewLink(Entity<TechAnomalyComponent> tech, Entity<DeviceLinkSourceComponent> source, Entity<DeviceLinkSinkComponent> target)
{
var sourcePort = _random.Pick(source.Comp.Ports);
var sinkPort = _random.Pick(target.Comp.Ports);

_signal.SaveLinks(null, source, target,new()
{
(sourcePort, sinkPort),
});
_beam.TryCreateBeam(source, target, tech.Comp.LinkBeamProto);
}

private void OnSupercritical(Entity<TechAnomalyComponent> tech, ref AnomalySupercriticalEvent args)
{
// We remove the component so that the anomaly does not bind itself to other devices before self destroy.
RemComp<DeviceLinkSourceComponent>(tech);

var sources =
_lookup.GetEntitiesInRange<DeviceLinkSourceComponent>(Transform(tech).Coordinates,
tech.Comp.LinkRadius.Max);

var sinks =
_lookup.GetEntitiesInRange<DeviceLinkSinkComponent>(Transform(tech).Coordinates,
tech.Comp.LinkRadius.Max);

for (var i = 0; i < tech.Comp.LinkCountSupercritical; i++)
{
if (sources.Count < 1)
return;

if (sinks.Count < 1)
return;

var source = _random.Pick(sources);
sources.Remove(source);

var sink = _random.Pick(sinks);
sinks.Remove(sink);

if (_random.Prob(tech.Comp.EmagSupercritProbability))
{
_emag.DoEmagEffect(tech, source);
_emag.DoEmagEffect(tech, sink);
}

CreateNewLink(tech, source, sink);
}
}

private void OnPulse(Entity<TechAnomalyComponent> tech, ref AnomalyPulseEvent args)
{
_signal.InvokePort(tech, tech.Comp.PulsePort);
}
}
2 changes: 1 addition & 1 deletion Content.Server/Atmos/EntitySystems/FlammableSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ public void SetFireStacks(EntityUid uid, float stacks, FlammableComponent? flamm
}
else
{
flammable.OnFire = ignite;
flammable.OnFire |= ignite;
UpdateAppearance(uid, flammable);
}
}
Expand Down
4 changes: 2 additions & 2 deletions Content.Server/Discord/DiscordWebhook.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ private string GetUrl(WebhookIdentifier identifier)
{
return await _http.GetFromJsonAsync<WebhookData>(url);
}
catch
catch (Exception e)
{
_sawmill.Error($"Error getting discord webhook data. Stack trace:\n{Environment.StackTrace}");
_sawmill.Error($"Error getting discord webhook data.\n{e}");
return null;
}
}
Expand Down
Loading

0 comments on commit 12eecfb

Please sign in to comment.