Skip to content

Commit

Permalink
Merge branch 'master' into internal-affairs
Browse files Browse the repository at this point in the history
  • Loading branch information
EstKemran authored Aug 14, 2024
2 parents b9080a0 + 67af4ad commit 3ef9ff8
Show file tree
Hide file tree
Showing 105 changed files with 1,158 additions and 104 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
xmlns:ui="clr-namespace:Content.Client.ParticleAccelerator.UI"
xmlns:customControls="clr-namespace:Content.Client.Administration.UI.CustomControls"
Title="{Loc 'particle-accelerator-control-menu-device-version-label'}"
MinSize="420 320"
SetSize="420 320">
MinSize="480 320"
SetSize="530 320">
<BoxContainer Orientation="Vertical" VerticalExpand="True" Margin="0 10 0 0">
<BoxContainer Orientation="Horizontal" VerticalExpand="True">
<BoxContainer Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True" Margin="10 0 10 5">
Expand Down
119 changes: 119 additions & 0 deletions Content.Client/SS220/Overlays/OverlayStack.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using Robust.Client.Graphics;
using Robust.Shared.Enums;
using Robust.Shared.Timing;

namespace Content.Client.SS220.Overlays
{
/// <summary>
/// Special overlays container created to bypass limits of <see cref="IOverlayManager"/> not supporting multiple overlays of the same type.
/// </summary>
public sealed class OverlayStack : Overlay
{
public override OverlaySpace Space => _space;
private readonly SortedDictionary<StackableOverlay, OverlayData> _overlays = new(OverlayComparer.Instance);

private OverlaySpace _space;

public bool AddOverlay(StackableOverlay overlay)
{
if (_overlays.ContainsKey(overlay))
return false;
_overlays.Add(overlay, new());
_space |= overlay.Space;
return true;
}

public bool RemoveOverlay(StackableOverlay overlay)
{
if (!_overlays.ContainsKey(overlay))
return false;
_overlays.Remove(overlay);
return true;
}

protected override void FrameUpdate(FrameEventArgs args)
{
foreach (var (overlay, _) in _overlays)
{
overlay.FrameUpdatePublic(args);
}
}

protected override bool BeforeDraw(in OverlayDrawArgs args)
{
var result = false;
foreach (var (overlay, data) in _overlays)
{
if (!ShouldDraw(overlay, args))
continue;
var shouldDraw = overlay.BeforeDrawPublic(in args);
data.ShouldDrawThisFrame = shouldDraw;
result |= shouldDraw;
}
return result;
}

protected override void Draw(in OverlayDrawArgs args)
{
foreach (var (overlay, data) in _overlays)
{
if (!ShouldDraw(overlay, args) || !data.ShouldDrawThisFrame)
continue;
overlay.DrawPublic(in args);
}
}

public static OverlayStack Get(IOverlayManager overlayManager)
{
if (overlayManager.TryGetOverlay<OverlayStack>(out var overlay))
return overlay;
overlay = new OverlayStack();
overlayManager.AddOverlay(overlay);
return overlay;
}

private static bool ShouldDraw(StackableOverlay overlay, OverlayDrawArgs drawArgs)
{
return (overlay.Space & drawArgs.Space) != 0;
}

private sealed class OverlayData
{
public bool ShouldDrawThisFrame;
}

private sealed class OverlayComparer : IComparer<Overlay>
{
public static readonly OverlayComparer Instance = new();

public int Compare(Overlay? x, Overlay? y)
{
var zX = x?.ZIndex ?? 0;
var zY = y?.ZIndex ?? 0;
return zX.CompareTo(zY);
}
}
}

/// <summary>
/// An overlay supported by <see cref="OverlayStack"/>
/// </summary>
public abstract class StackableOverlay : Overlay
{
public void FrameUpdatePublic(FrameEventArgs args)
{
FrameUpdate(args);
}

public bool BeforeDrawPublic(in OverlayDrawArgs args)
{
return BeforeDraw(in args);
}

public void DrawPublic(in OverlayDrawArgs args)
{
Draw(in args);
}
}
}
75 changes: 75 additions & 0 deletions Content.Client/SS220/TextureFade/TextureFadeOverlay.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using System.Numerics;
using Content.Client.SS220.Overlays;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Shared.Enums;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using Robust.Shared.Utility;

namespace Content.Client.SS220.TextureFade;

/// <summary>
/// Performs alpha clip on the privided texture with variable threshold (threshold filter). See <see cref="TextureFadeOverlayComponent"/> for more automatic use.
/// </summary>
public sealed class TextureFadeOverlay : StackableOverlay
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IEntityManager _entityManager = default!;
private readonly SpriteSystem _spriteSystem = default!;

public override OverlaySpace Space => OverlaySpace.WorldSpace;
public SpriteSpecifier? Sprite;
public Color Modulate = Color.White;
public float FadeProgress = 0f;
public TimeSpan Time;
public bool Loop = true;

private readonly ShaderInstance _shader;

public TextureFadeOverlay()
{
IoCManager.InjectDependencies(this);
_spriteSystem = _entityManager.EntitySysManager.GetEntitySystem<SpriteSystem>();
_shader = _prototypeManager.Index<ShaderPrototype>("TextureFade").InstanceUnique();
}

protected override void FrameUpdate(FrameEventArgs args)
{
Time += TimeSpan.FromSeconds(args.DeltaSeconds);
}

protected override void Draw(in OverlayDrawArgs args)
{
if (Sprite == null)
return;

var texture = _spriteSystem.GetFrame(Sprite, Time, Loop);

var worldHandle = args.WorldHandle;
_shader.SetParameter("FadeProgress", FadeProgress);

var viewQuad = args.WorldBounds;
var viewSize = viewQuad.Box.Size;
var viewRatio = viewSize.X / viewSize.Y;
var regionSize = texture.Size;
var regionRatio = (float)regionSize.X / regionSize.Y;
var scaleBy = Vector2.One;
if (viewRatio > regionRatio)
{
scaleBy.Y = viewRatio / regionRatio;
}
else
{
scaleBy.X = regionRatio / viewRatio;
}
viewQuad.Box = viewQuad.Box.Scale(scaleBy);

worldHandle.Modulate = Modulate;
worldHandle.UseShader(_shader);
worldHandle.DrawTextureRectRegion(texture, viewQuad);
worldHandle.UseShader(null);
worldHandle.Modulate = Color.White;
}
}
36 changes: 36 additions & 0 deletions Content.Client/SS220/TextureFade/TextureFadeOverlayComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using Content.Shared.SS220.TextureFade;
using Robust.Shared.Utility;

namespace Content.Client.SS220.TextureFade;

/// <summary>
/// Component for automatic texture fade processing, you can still use <see cref="TextureFadeOverlay"/> directly.
/// You can use all this data fiels directly in code to enable/disable, set progress, etc.
/// </summary>
[RegisterComponent]
public sealed partial class TextureFadeOverlayComponent : SharedTextureFadeOverlayComponent
{
[DataField, ViewVariables(VVAccess.ReadWrite)]
public bool IsEnabled = false;
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float FadeProgress = 1;
[DataField, ViewVariables(VVAccess.ReadWrite)]
public SpriteSpecifier Sprite = SpriteSpecifier.Invalid;
[DataField, ViewVariables(VVAccess.ReadWrite)]
public Color Modulate = Color.White;
[DataField, ViewVariables(VVAccess.ReadWrite)]
public int ZIndex = 0;
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float ProgressSpeed = 0;
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float MinProgress = 0;
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float MaxProgress = 1;
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float PulseMagnitude = 0;
[DataField, ViewVariables(VVAccess.ReadWrite)]
public float PulseRate = 0;

public TextureFadeOverlay? Overlay;
}
82 changes: 82 additions & 0 deletions Content.Client/SS220/TextureFade/TextureFadeOverlaySystem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using Content.Client.SS220.Overlays;
using Robust.Client.Graphics;

namespace Content.Client.SS220.TextureFade;

public sealed class TextureFadeOverlaySystem : EntitySystem
{
[Dependency] private readonly IOverlayManager _overlayManager = default!;

public override void Initialize()
{
SubscribeLocalEvent<TextureFadeOverlayComponent, ComponentRemove>(OnRemove);
}

public override void FrameUpdate(float frameTime)
{
var componentsQuery = EntityQueryEnumerator<TextureFadeOverlayComponent>();
while (componentsQuery.MoveNext(out var comp))
{
HandleOverlayActivityUpdate(comp);
HandleOverlayProgressUpdate(comp, frameTime);
}
}

private void OnRemove(Entity<TextureFadeOverlayComponent> entity, ref ComponentRemove args)
{
DestroyOverlay(entity.Comp);
}

private void HandleOverlayActivityUpdate(TextureFadeOverlayComponent component)
{
if (component.IsEnabled && component.Overlay is null)
{
component.Overlay = CreateOverlay(component);
return;
}
if (!component.IsEnabled && component.Overlay is { })
{
DestroyOverlay(component);
return;
}
}

private void HandleOverlayProgressUpdate(TextureFadeOverlayComponent component, float frameTime)
{
if (component.Overlay == null)
return;
if (component.ProgressSpeed != 0f)
{
component.FadeProgress += component.ProgressSpeed * frameTime;
component.FadeProgress = Math.Clamp(component.FadeProgress, component.MinProgress, component.MaxProgress);
}
var fadeProgressMod = component.FadeProgress;
fadeProgressMod += (float)Math.Sin(Math.PI * component.Overlay.Time.TotalSeconds * component.PulseRate) * component.PulseMagnitude;
fadeProgressMod = Math.Clamp(fadeProgressMod, 0f, 1f);
component.Overlay.FadeProgress = fadeProgressMod;
component.Overlay.Modulate = component.Modulate;
component.Overlay.ZIndex = component.ZIndex;
}

private TextureFadeOverlay CreateOverlay(TextureFadeOverlayComponent component)
{
var overlay = new TextureFadeOverlay()
{
Sprite = component.Sprite,
Modulate = component.Modulate,
ZIndex = component.ZIndex,
};
OverlayStack.Get(_overlayManager).AddOverlay(overlay);
return overlay;
}

private void DestroyOverlay(TextureFadeOverlayComponent component)
{
if (component.Overlay is null)
return;
OverlayStack.Get(_overlayManager).RemoveOverlay(component.Overlay);
component.Overlay.Dispose();
component.Overlay = null;
}
}
16 changes: 16 additions & 0 deletions Content.Client/UserInterface/Systems/Chat/Widgets/ChatBox.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using Content.Client.UserInterface.Systems.Chat.Controls;
using Content.Shared.Chat;
using Content.Shared.Input;
using Content.Shared.SS220.ShowCodewords;
using Robust.Client.Audio;
using Robust.Client.AutoGenerated;
using Robust.Client.GameObjects;
using Robust.Client.Player;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
Expand Down Expand Up @@ -65,6 +67,20 @@ private void OnMessageAdded(ChatMessage msg)

var color = msg.MessageColorOverride ?? msg.Channel.TextColor();

//ss220 codewords highlight add start
var playerManager = IoCManager.Resolve<IPlayerManager>();
var entManager = IoCManager.Resolve<IEntityManager>();

if (playerManager.LocalEntity != null &&
entManager.TryGetComponent<ShowCodewordsComponent>(playerManager.LocalEntity, out var showCodewordsComponent))
{
foreach (var codeword in showCodewordsComponent.CodeWords)
{
msg.WrappedMessage = msg.WrappedMessage.Replace(codeword, $"[color=pink]{codeword}[/color]");
}
}
//ss220 codewords highlight add end

AddLine(msg.WrappedMessage, color);
}

Expand Down
8 changes: 8 additions & 0 deletions Content.Server/GameTicking/Rules/TraitorRuleSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
using System.Text;
using Content.Shared.GameTicking.Components;
using Content.Server.SS220.MindSlave;
using Content.Shared.SS220.ShowCodewords;

namespace Content.Server.GameTicking.Rules;

Expand Down Expand Up @@ -106,6 +107,13 @@ public bool MakeTraitor(EntityUid traitor, TraitorRuleComponent component, bool

component.TraitorMinds.Add(mindId);

//ss220 codewords highlight add start

var showCodewordsComp = EnsureComp<ShowCodewordsComponent>(traitor);
showCodewordsComp.CodeWords = component.Codewords;

//ss220 codewords highlight add end

// Assign briefing
_roleSystem.MindAddRole(mindId, new RoleBriefingComponent
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// © SS220, An EULA/CLA with a hosting restriction, full text: https://raw.githubusercontent.com/SerbiaStrong-220/space-station-14/master/CLA.txt
using Content.Shared.SS220.TextureFade;

namespace Content.Server.SS220.TextureFade;

[RegisterComponent]
public sealed partial class TextureFadeOverlayComponent : SharedTextureFadeOverlayComponent
{
}
Loading

0 comments on commit 3ef9ff8

Please sign in to comment.