diff --git a/Content.Client/_EE/Supermatter/Consoles/SupermatterConsoleBoundUserInterface.cs b/Content.Client/_EE/Supermatter/Consoles/SupermatterConsoleBoundUserInterface.cs new file mode 100644 index 0000000000..80c0fc0276 --- /dev/null +++ b/Content.Client/_EE/Supermatter/Consoles/SupermatterConsoleBoundUserInterface.cs @@ -0,0 +1,40 @@ +using Content.Shared._EE.Supermatter.Components; + +namespace Content.Client._EE.Supermatter.Consoles; + +public sealed class SupermatterConsoleBoundUserInterface : BoundUserInterface +{ + [ViewVariables] + private SupermatterConsoleWindow? _menu; + + public SupermatterConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) { } + + protected override void Open() + { + _menu = new SupermatterConsoleWindow(this, Owner); + _menu.OpenCentered(); + _menu.OnClose += Close; + } + + protected override void UpdateState(BoundUserInterfaceState state) + { + base.UpdateState(state); + + var castState = (SupermatterConsoleBoundInterfaceState)state; + _menu?.UpdateUI(castState.Supermatters, castState.FocusData); + } + + public void SendFocusChangeMessage(NetEntity? netEntity) + { + SendMessage(new SupermatterConsoleFocusChangeMessage(netEntity)); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + if (!disposing) + return; + + _menu?.Dispose(); + } +} diff --git a/Content.Client/_EE/Supermatter/Consoles/SupermatterConsoleWindow.xaml b/Content.Client/_EE/Supermatter/Consoles/SupermatterConsoleWindow.xaml new file mode 100644 index 0000000000..3d2c638c16 --- /dev/null +++ b/Content.Client/_EE/Supermatter/Consoles/SupermatterConsoleWindow.xaml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Content.Client/_EE/Supermatter/Consoles/SupermatterConsoleWindow.xaml.cs b/Content.Client/_EE/Supermatter/Consoles/SupermatterConsoleWindow.xaml.cs new file mode 100644 index 0000000000..1d68dbb53c --- /dev/null +++ b/Content.Client/_EE/Supermatter/Consoles/SupermatterConsoleWindow.xaml.cs @@ -0,0 +1,258 @@ +using Content.Client.Message; +using Content.Client.Stylesheets; +using Content.Client.UserInterface.Controls; +using Content.Shared._EE.Supermatter.Components; +using Content.Shared._EE.Supermatter.Monitor; +using Content.Shared.Pinpointer; +using Robust.Client.AutoGenerated; +using Robust.Client.GameObjects; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.XAML; +using Robust.Shared.Timing; +using Robust.Shared.Utility; +using System.Diagnostics.CodeAnalysis; +using System.Linq; + +namespace Content.Client._EE.Supermatter.Consoles; + +[GenerateTypedNameReferences] +public sealed partial class SupermatterConsoleWindow : FancyWindow +{ + private readonly IEntityManager _entManager; + private readonly SpriteSystem _spriteSystem; + private readonly SharedNavMapSystem _navMapSystem; + + private EntityUid? _owner; + private NetEntity? _trackedEntity; + + private SupermatterConsoleEntry[]? _supermatters = null; + private IEnumerable? _activeAlerts = null; + + public event Action? SendFocusChangeMessageAction; + + private bool _autoScrollActive = false; + private bool _autoScrollAwaitsUpdate = false; + + // Colors + private Color _wallColor = new Color(64, 64, 64); + private Color _tileColor = new Color(28, 28, 28); + private Color _monitorBlipColor = Color.Cyan; + private Color _untrackedEntColor = Color.DimGray; + private Color _regionBaseColor = new Color(154, 154, 154); + private Color _inactiveColor = StyleNano.DisabledFore; + private Color _statusTextColor = StyleNano.GoodGreenFore; + private Color _goodColor = Color.LimeGreen; + private Color _warningColor = new Color(255, 182, 72); + private Color _dangerColor = new Color(255, 67, 67); + + public SupermatterConsoleWindow(SupermatterConsoleBoundUserInterface userInterface, EntityUid? owner) + { + RobustXamlLoader.Load(this); + _entManager = IoCManager.Resolve(); + _spriteSystem = _entManager.System(); + _navMapSystem = _entManager.System(); + + // Pass the owner to nav map + _owner = owner; + + // Set supermatter monitoring message action + SendFocusChangeMessageAction += userInterface.SendFocusChangeMessage; + } + + public void UpdateUI(SupermatterConsoleEntry[] supermatters, SupermatterFocusData? focusData) + { + if (_owner == null) + return; + + if (!_entManager.TryGetComponent(_owner.Value, out var console)) + return; + + if (_trackedEntity != focusData?.NetEntity) + { + SendFocusChangeMessageAction?.Invoke(_trackedEntity); + focusData = null; + } + + // Retain supermatter data for use inbetween updates + _supermatters = supermatters; + + // Clear excess children from the tables + var supermattersCount = _supermatters.Count(); + + while (SupermattersTable.ChildCount > supermattersCount) + SupermattersTable.RemoveChild(SupermattersTable.GetChild(SupermattersTable.ChildCount - 1)); + + // Update all entries in each table + for (int index = 0; index < _supermatters.Count(); index++) + { + var entry = _supermatters.ElementAt(index); + UpdateUIEntry(entry, index, SupermattersTable, console, focusData); + } + + // If no alerts are active, display a message + if (supermattersCount == 0) + { + var label = new RichTextLabel() + { + HorizontalExpand = true, + VerticalExpand = true, + HorizontalAlignment = HAlignment.Center, + VerticalAlignment = VAlignment.Center, + }; + + label.SetMarkup(Loc.GetString("supermatter-console-window-no-supermatters")); + + SupermattersTable.AddChild(label); + } + + // Auto-scroll re-enable + if (_autoScrollAwaitsUpdate) + { + _autoScrollActive = true; + _autoScrollAwaitsUpdate = false; + } + } + + private void UpdateUIEntry(SupermatterConsoleEntry entry, int index, Control table, SupermatterConsoleComponent console, SupermatterFocusData? focusData = null) + { + // Make new UI entry if required + if (index >= table.ChildCount) + { + var newEntryContainer = new SupermatterEntryContainer(entry.NetEntity); + + // On click + newEntryContainer.FocusButton.OnButtonUp += args => + { + if (_trackedEntity == newEntryContainer.NetEntity) + { + _trackedEntity = null; + } + + else + { + _trackedEntity = newEntryContainer.NetEntity; + } + + // Send message to console that the focus has changed + SendFocusChangeMessageAction?.Invoke(_trackedEntity); + }; + + // Add the entry to the current table + table.AddChild(newEntryContainer); + } + + // Update values and UI elements + var tableChild = table.GetChild(index); + + if (tableChild is not SupermatterEntryContainer) + { + table.RemoveChild(tableChild); + UpdateUIEntry(entry, index, table, console, focusData); + + return; + } + + var entryContainer = (SupermatterEntryContainer)tableChild; + + entryContainer.UpdateEntry(entry, entry.NetEntity == _trackedEntity, focusData); + } + + protected override void FrameUpdate(FrameEventArgs args) + { + AutoScrollToFocus(); + } + + private void ActivateAutoScrollToFocus() + { + _autoScrollActive = false; + _autoScrollAwaitsUpdate = true; + } + + private void AutoScrollToFocus() + { + if (!_autoScrollActive) + return; + + var scroll = SupermattersTable.Parent as ScrollContainer; + if (scroll == null) + return; + + if (!TryGetVerticalScrollbar(scroll, out var vScrollbar)) + return; + + if (!TryGetNextScrollPosition(out float? nextScrollPosition)) + return; + + vScrollbar.ValueTarget = nextScrollPosition.Value; + + if (MathHelper.CloseToPercent(vScrollbar.Value, vScrollbar.ValueTarget)) + _autoScrollActive = false; + } + + private bool TryGetVerticalScrollbar(ScrollContainer scroll, [NotNullWhen(true)] out VScrollBar? vScrollBar) + { + vScrollBar = null; + + foreach (var child in scroll.Children) + { + if (child is not VScrollBar) + continue; + + var castChild = child as VScrollBar; + + if (castChild != null) + { + vScrollBar = castChild; + return true; + } + } + + return false; + } + + private bool TryGetNextScrollPosition([NotNullWhen(true)] out float? nextScrollPosition) + { + nextScrollPosition = null; + + var scroll = SupermattersTable.Parent as ScrollContainer; + if (scroll == null) + return false; + + var container = scroll.Children.ElementAt(0) as BoxContainer; + if (container == null || container.Children.Count() == 0) + return false; + + // Exit if the heights of the children haven't been initialized yet + if (!container.Children.Any(x => x.Height > 0)) + return false; + + nextScrollPosition = 0; + + foreach (var control in container.Children) + { + if (control == null || control is not SupermatterEntryContainer) + continue; + + if (((SupermatterEntryContainer)control).NetEntity == _trackedEntity) + return true; + + nextScrollPosition += control.Height; + } + + // Failed to find control + nextScrollPosition = null; + + return false; + } + + private SupermatterStatusType GetStatus(NetEntity netEntity) + { + var status = _supermatters?.FirstOrNull(x => x.NetEntity == netEntity)?.EntityStatus; + + if (status == null) + return SupermatterStatusType.Error; + + return status.Value; + } +} diff --git a/Content.Client/_EE/Supermatter/Consoles/SupermatterEntryContainer.xaml b/Content.Client/_EE/Supermatter/Consoles/SupermatterEntryContainer.xaml new file mode 100644 index 0000000000..6cabb4ab33 --- /dev/null +++ b/Content.Client/_EE/Supermatter/Consoles/SupermatterEntryContainer.xaml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Content.Client/_EE/Supermatter/Consoles/SupermatterEntryContainer.xaml.cs b/Content.Client/_EE/Supermatter/Consoles/SupermatterEntryContainer.xaml.cs new file mode 100644 index 0000000000..68f8ddf7b7 --- /dev/null +++ b/Content.Client/_EE/Supermatter/Consoles/SupermatterEntryContainer.xaml.cs @@ -0,0 +1,285 @@ +using Content.Client.Atmos.EntitySystems; +using Content.Client.Stylesheets; +using Content.Shared._EE.Supermatter.Components; +using Content.Shared._EE.Supermatter.Monitor; +using Content.Shared.Atmos; +using Content.Shared.Atmos.Prototypes; +using Robust.Client.AutoGenerated; +using Robust.Client.Graphics; +using Robust.Client.ResourceManagement; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.XAML; +using System.Linq; + +namespace Content.Client._EE.Supermatter.Consoles; + +[GenerateTypedNameReferences] +public sealed partial class SupermatterEntryContainer : BoxContainer +{ + public NetEntity NetEntity; + + private readonly IEntityManager _entManager; + private readonly IResourceCache _cache; + + private Dictionary _statusStrings = new() + { + [SupermatterStatusType.Inactive] = "supermatter-console-window-inactive-status", + [SupermatterStatusType.Normal] = "supermatter-console-window-normal-status", + [SupermatterStatusType.Caution] = "supermatter-console-window-caution-status", + [SupermatterStatusType.Warning] = "supermatter-console-window-warning-status", + [SupermatterStatusType.Danger] = "supermatter-console-window-danger-status", + [SupermatterStatusType.Emergency] = "supermatter-console-window-emergency-status", + [SupermatterStatusType.Delaminating] = "supermatter-console-window-delaminating-status" + }; + + public SupermatterEntryContainer(NetEntity uid) + { + RobustXamlLoader.Load(this); + + _entManager = IoCManager.Resolve(); + _cache = IoCManager.Resolve(); + + NetEntity = uid; + + // Load fonts + var headerFont = new VectorFont(_cache.GetResource("/Fonts/NotoSans/NotoSans-Bold.ttf"), 11); + var normalFont = new VectorFont(_cache.GetResource("/Fonts/NotoSansDisplay/NotoSansDisplay-Regular.ttf"), 11); + var monoFont = new VectorFont(_cache.GetResource("/EngineFonts/NotoSans/NotoSansMono-Regular.ttf"), 10); + + // Set fonts + SupermatterNameLabel.FontOverride = headerFont; + + SupermatterStatusLabel.FontOverride = normalFont; + + IntegrityLabel.FontOverride = normalFont; + PowerLabel.FontOverride = normalFont; + RadiationLabel.FontOverride = normalFont; + MolesLabel.FontOverride = normalFont; + TemperatureLabel.FontOverride = normalFont; + TemperatureLimitLabel.FontOverride = normalFont; + WasteLabel.FontOverride = normalFont; + AbsorptionLabel.FontOverride = normalFont; + + IntegrityBarLabel.FontOverride = monoFont; + PowerBarLabel.FontOverride = monoFont; + RadiationBarLabel.FontOverride = monoFont; + MolesBarLabel.FontOverride = monoFont; + TemperatureBarLabel.FontOverride = monoFont; + TemperatureLimitBarLabel.FontOverride = monoFont; + WasteBarLabel.FontOverride = monoFont; + AbsorptionBarLabel.FontOverride = monoFont; + } + + public void UpdateEntry(SupermatterConsoleEntry entry, bool isFocus, SupermatterFocusData? focusData = null) + { + NetEntity = entry.NetEntity; + + // Load fonts + var normalFont = new VectorFont(_cache.GetResource("/Fonts/NotoSansDisplay/NotoSansDisplay-Regular.ttf"), 11); + + // Update supermatter name + SupermatterNameLabel.Text = Loc.GetString("supermatter-console-window-label-sm", ("name", entry.EntityName)); + + // Update supermatter status + SupermatterStatusLabel.Text = Loc.GetString(GetStatusLabel(entry.EntityStatus)); + SupermatterStatusLabel.FontColorOverride = GetStatusColor(entry.EntityStatus); + + // Focus updates + FocusContainer.Visible = isFocus; + + if (isFocus) + { + if (focusData != null) + { + var red = StyleNano.DangerousRedFore; + var orange = StyleNano.ConcerningOrangeFore; + var green = StyleNano.GoodGreenFore; + var turqoise = Color.FromHex("#009893"); + + // TODO: please don't define this dictionary every update you animal + var engineDictionary = new Dictionary() + { + { "integrity", (IntegrityBarLabel, IntegrityBar, IntegrityBarBorder, focusData.Value.Integrity, 0.9f, 0.1f, red, orange, green) }, + { "power", (PowerBarLabel, PowerBar, PowerBarBorder, focusData.Value.Power, 0.9f, 0.1f, green, orange, red ) }, + { "radiation", (RadiationBarLabel, RadiationBar, RadiationBarBorder, focusData.Value.Radiation, 0.1f, 0.9f, green, orange, red ) }, + { "moles", (MolesBarLabel, MolesBar, MolesBarBorder, focusData.Value.AbsorbedMoles, 0.5f, 0.5f, green, orange, red ) }, + { "temperature", (TemperatureBarLabel, TemperatureBar, TemperatureBarBorder, focusData.Value.Temperature, 0.5f, 0.5f, turqoise, green, red ) }, + { "waste", (WasteBarLabel, WasteBar, WasteBarBorder, focusData.Value.WasteMultiplier, 0.5f, 0.5f, green, orange, red ) } + }; + + // Special cases + var powerBar = engineDictionary["power"]; + var powerPrefix = powerBar.value switch { >= 1000 => "G", >= 1 => "M", _ => "" }; + var powerMultiplier = powerBar.value switch { >= 1000 => 0.001, >= 1 => 1, _ => 1000 }; + powerBar.label.Text = Loc.GetString("supermatter-console-window-label-power-bar", ("power", (powerBar.value * powerMultiplier).ToString("0.000")), ("prefix", powerPrefix)); + + var temperatureLimit = focusData.Value.TemperatureLimit; + TemperatureBar.MaxValue = temperatureLimit; + TemperatureLimitBarLabel.Text = Loc.GetString("supermatter-console-window-label-temperature-bar", ("temperature", temperatureLimit.ToString("0.00"))); + + var absorptionRatio = focusData.Value.AbsorptionRatio; + AbsorptionBarLabel.Text = Loc.GetString("supermatter-console-window-label-absorption-bar", ("absorption", absorptionRatio.ToString("0"))); + + // Update engine bars + foreach (var bar in engineDictionary) + { + var current = bar.Value; + UpdateEngineBar(current.bar, current.border, current.value, current.leftSize, current.rightSize, current.leftColor, current.middleColor, current.rightColor); + + if (bar.Key == "power") + continue; + + current.label.Text = Loc.GetString("supermatter-console-window-label-" + bar.Key + "-bar", (bar.Key, current.value.ToString("0.00"))); + } + + // Update gas bars + var atmosphereSystem = _entManager.System(); + var gases = atmosphereSystem.Gases.OrderByDescending(gas => GetStoredGas(gas, focusData)); + var index = 0; + + foreach (var gas in gases) + { + var name = gas.Name; + var color = Color.FromHex("#" + gas.Color); + var value = GetStoredGas(gas, focusData) / focusData.Value.AbsorbedMoles * 100; + + UpdateGasBar(index, GasTable, name, color, value); + index++; + } + } + } + } + + private string GetStatusLabel(SupermatterStatusType status) + { + switch (status) + { + case SupermatterStatusType.Inactive: + return "supermatter-console-window-inactive-status"; + + case SupermatterStatusType.Normal: + return "supermatter-console-window-normal-status"; + + case SupermatterStatusType.Caution: + return "supermatter-console-window-caution-status"; + + case SupermatterStatusType.Warning: + return "supermatter-console-window-warning-status"; + + case SupermatterStatusType.Danger: + return "supermatter-console-window-danger-status"; + + case SupermatterStatusType.Emergency: + return "supermatter-console-window-emergency-status"; + + case SupermatterStatusType.Delaminating: + return "supermatter-console-window-delaminating-status"; + } + + return "supermatter-console-window-error-status"; + } + + private Color GetStatusColor(SupermatterStatusType status) + { + switch (status) + { + case SupermatterStatusType.Inactive: + return Color.DarkGray; + + case SupermatterStatusType.Normal: + return StyleNano.GoodGreenFore; + + case SupermatterStatusType.Caution: + case SupermatterStatusType.Warning: + return StyleNano.ConcerningOrangeFore; + + case SupermatterStatusType.Danger: + case SupermatterStatusType.Emergency: + case SupermatterStatusType.Delaminating: + return StyleNano.DangerousRedFore; + } + + return StyleNano.DisabledFore; + } + + private float GetStoredGas(GasPrototype gas, SupermatterFocusData? focusData) + { + var id = int.Parse(gas.ID); + + if (focusData == null) + return 0; + + return focusData.Value.GasStorage[(Gas)id]; + } + + private void UpdateEngineBar(ProgressBar bar, PanelContainer border, float value, float leftSize, float rightSize, Color leftColor, Color middleColor, Color rightColor) + { + var clamped = Math.Clamp(value, bar.MinValue, bar.MaxValue); + + var normalized = clamped / bar.MaxValue; + var leftHsv = Color.ToHsv(leftColor); + var middleHsv = Color.ToHsv(middleColor); + var rightHsv = Color.ToHsv(rightColor); + + // Ensure leftSize and rightSize add up to 1.0 or the transition won't be smooth + var minColor = new Vector4(0, 0, 0, 0); + var maxColor = new Vector4(1, 1, 1, 1); + Color finalColor; + + if (normalized <= leftSize) + { + normalized /= leftSize; // Adjust range to 0.0 to 1.0 + var calcColor = Vector4.Lerp(leftHsv, middleHsv, normalized); + var clampedColor = Vector4.Clamp(calcColor, minColor, maxColor); + finalColor = Color.FromHsv(clampedColor); + } + + else + { + normalized = (normalized - leftSize) / rightSize; // Adjust range to 0.0 to 1.0 + var calcColor = Vector4.Lerp(middleHsv, rightHsv, normalized); + var clampedColor = Vector4.Clamp(calcColor, minColor, maxColor); + finalColor = Color.FromHsv(clampedColor); + } + + // Check if null first to avoid repeatedly creating this. + bar.ForegroundStyleBoxOverride ??= new StyleBoxFlat(); + border.PanelOverride ??= new StyleBoxFlat(); + + var barOverride = (StyleBoxFlat)bar.ForegroundStyleBoxOverride; + barOverride.BackgroundColor = finalColor; + + var panelOverride = (StyleBoxFlat)border.PanelOverride; + panelOverride.BackgroundColor = finalColor; + + bar.Value = clamped; + } + + private void UpdateGasBar(int index, Control table, string name, Color color, float value) + { + // Make new UI entry if required + if (index >= table.ChildCount) + { + var newEntryContainer = new SupermatterGasBarContainer(); + + // Add the entry to the current table + table.AddChild(newEntryContainer); + } + + // Update values and UI elements + var tableChild = table.GetChild(index); + + if (tableChild is not SupermatterGasBarContainer) + { + table.RemoveChild(tableChild); + UpdateGasBar(index, table, name, color, value); + + return; + } + + var entryContainer = (SupermatterGasBarContainer)tableChild; + + entryContainer.UpdateEntry(name, color, value); + } +} diff --git a/Content.Client/_EE/Supermatter/Consoles/SupermatterGasBarContainer.xaml b/Content.Client/_EE/Supermatter/Consoles/SupermatterGasBarContainer.xaml new file mode 100644 index 0000000000..6382d38934 --- /dev/null +++ b/Content.Client/_EE/Supermatter/Consoles/SupermatterGasBarContainer.xaml @@ -0,0 +1,16 @@ + + + + + + diff --git a/Content.Client/_EE/Supermatter/Consoles/SupermatterGasBarContainer.xaml.cs b/Content.Client/_EE/Supermatter/Consoles/SupermatterGasBarContainer.xaml.cs new file mode 100644 index 0000000000..77b83dd652 --- /dev/null +++ b/Content.Client/_EE/Supermatter/Consoles/SupermatterGasBarContainer.xaml.cs @@ -0,0 +1,47 @@ +using Robust.Client.AutoGenerated; +using Robust.Client.Graphics; +using Robust.Client.ResourceManagement; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.XAML; + +namespace Content.Client._EE.Supermatter.Consoles; + +[GenerateTypedNameReferences] +public sealed partial class SupermatterGasBarContainer : BoxContainer +{ + private readonly IEntityManager _entManager; + private readonly IResourceCache _cache; + + public SupermatterGasBarContainer() + { + RobustXamlLoader.Load(this); + + _entManager = IoCManager.Resolve(); + _cache = IoCManager.Resolve(); + + // Load fonts + var normalFont = new VectorFont(_cache.GetResource("/Fonts/NotoSansDisplay/NotoSansDisplay-Regular.ttf"), 11); + var monoFont = new VectorFont(_cache.GetResource("/EngineFonts/NotoSans/NotoSansMono-Regular.ttf"), 10); + + // Set fonts + GasLabel.FontOverride = normalFont; + GasBarLabel.FontOverride = monoFont; + } + + public void UpdateEntry(string name, Color color, float value) + { + GasBar.Value = value; + GasLabel.Text = Loc.GetString(name) + ":"; + GasBarLabel.Text = Loc.GetString("supermatter-console-window-label-gas-bar", ("gas", value.ToString("0.00"))); + + // Check if null first to avoid repeatedly creating this. + GasBar.ForegroundStyleBoxOverride ??= new StyleBoxFlat(); + GasBarBorder.PanelOverride ??= new StyleBoxFlat(); + + var barOverride = (StyleBoxFlat)GasBar.ForegroundStyleBoxOverride; + barOverride.BackgroundColor = color; + + var borderOverride = (StyleBoxFlat)GasBarBorder.PanelOverride; + borderOverride.BackgroundColor = color; + } +} diff --git a/Content.Server/Beam/BeamSystem.cs b/Content.Server/Beam/BeamSystem.cs index ad67f983c2..9c1ebfa213 100644 --- a/Content.Server/Beam/BeamSystem.cs +++ b/Content.Server/Beam/BeamSystem.cs @@ -1,10 +1,9 @@ -using System.Numerics; +using System.Numerics; using Content.Server.Beam.Components; using Content.Shared.Beam; using Content.Shared.Beam.Components; using Content.Shared.Physics; using Robust.Server.GameObjects; -using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; using Robust.Shared.Map; using Robust.Shared.Physics; @@ -83,6 +82,11 @@ public sealed class BeamSystem : SharedBeamSystem if (!TryComp(ent, out var physics) || !TryComp(ent, out var beam)) return; + // imp - start non-randomized lightning sprites + if (!beam.AllowSpriteOverwrite) + bodyState = null; + // imp - end non-randomized lightning sprites + FixturesComponent? manager = null; _fixture.TryCreateFixture( ent, @@ -146,21 +150,8 @@ public sealed class BeamSystem : SharedBeamSystem if (Deleted(user) || Deleted(target)) return; - var userMapPos = _transform.GetMapCoordinates(user); - var targetMapPos = _transform.GetMapCoordinates(target); - - //The distance between the target and the user. - var calculatedDistance = targetMapPos.Position - userMapPos.Position; - var userAngle = calculatedDistance.ToWorldAngle(); - - if (userMapPos.MapId != targetMapPos.MapId) - return; - - //Where the start of the beam will spawn - var beamStartPos = userMapPos.Offset(calculatedDistance.Normalized()); - - //Don't divide by zero - if (calculatedDistance.Length() == 0) + // imp - Beam creation was changed to a coordinate-to-coordinate method to allow for more flexibility. + if (!TryCreateBeam(_transform.GetMapCoordinates(user), _transform.GetMapCoordinates(target), bodyPrototype, bodyState, shader, controller)) return; if (controller != null && TryComp(controller, out var controllerBeamComp)) @@ -169,11 +160,95 @@ public sealed class BeamSystem : SharedBeamSystem controllerBeamComp.HitTargets.Add(target); } - var distanceCorrection = calculatedDistance - calculatedDistance.Normalized(); - - CreateBeam(bodyPrototype, userAngle, calculatedDistance, beamStartPos, distanceCorrection, controller, bodyState, shader); - var ev = new CreateBeamSuccessEvent(user, target); RaiseLocalEvent(user, ev); } + + /// + /// Called where you want an entity to create a beam from one set of coordinates to another. + /// Tries to create the beam and does calculations like the distance, angle, and offset. + /// + /// + /// Ported from imp + /// + /// The coordinates that the beam is being fired from + /// The coordinates that are being targeted + /// The prototype spawned when this beam is created + /// Optional sprite state for the if a default one is not given + /// Optional shader for the if a default one is not given + /// + public bool TryCreateBeam(MapCoordinates coordinates, MapCoordinates targetCoordinates, string bodyPrototype, string? bodyState = null, string shader = "unshaded", EntityUid? controller = null) + { + //The distance between the target and the user. + var calculatedDistance = targetCoordinates.Position - coordinates.Position; + var userAngle = calculatedDistance.ToWorldAngle(); + + if (coordinates.MapId != targetCoordinates.MapId) + return false; + + //Where the start of the beam will spawn + var beamStartPos = coordinates.Offset(calculatedDistance.Normalized()); + + //Don't divide by zero + if (calculatedDistance.Length() == 0) + return false; + + var distanceCorrection = calculatedDistance - calculatedDistance.Normalized(); + + CreateBeam(bodyPrototype, userAngle, calculatedDistance, beamStartPos, distanceCorrection, controller, bodyState, shader); + return true; + } + + /// + /// Called where you want an entity to create a beam from a set of coordinates to an entity. + /// Tries to create the beam and does calculations like the distance, angle, and offset. + /// + /// + /// Ported from imp + /// + /// The coordinates that the beam is being fired from + /// The entity that's being targeted by the user + /// The prototype spawned when this beam is created + /// Optional sprite state for the if a default one is not given + /// Optional shader for the if a default one is not given + /// + public void TryCreateBeam(MapCoordinates coordinates, EntityUid target, string bodyPrototype, string? bodyState = null, string shader = "unshaded", EntityUid? controller = null) + { + if (Deleted(target)) + return; + + if (TryCreateBeam(coordinates, _transform.GetMapCoordinates(target), bodyPrototype, bodyState, shader, controller)) + { + if (controller != null && TryComp(controller, out var controllerBeamComp)) + controllerBeamComp.HitTargets.Add(target); + } + } + + /// + /// Called where you want an entity to create a beam from an entity to a set of coordinates. + /// Tries to create the beam and does calculations like the distance, angle, and offset. + /// + /// + /// Ported from imp + /// + /// The entity that's firing off the beam + /// The coordinates that are being targeted + /// The prototype spawned when this beam is created + /// Optional sprite state for the if a default one is not given + /// Optional shader for the if a default one is not given + /// + public void TryCreateBeam(EntityUid user, MapCoordinates targetCoordinates, string bodyPrototype, string? bodyState = null, string shader = "unshaded", EntityUid? controller = null) + { + if (Deleted(user)) + return; + + if (TryCreateBeam(_transform.GetMapCoordinates(user), targetCoordinates, bodyPrototype, bodyState, shader, controller)) + { + if (controller != null && TryComp(controller, out var controllerBeamComp)) + controllerBeamComp.HitTargets.Add(user); + + var ev = new CreateBeamSuccessEvent(user, targetCoordinates); + RaiseLocalEvent(user, ev); + } + } } diff --git a/Content.Server/Lightning/LightningSystem.cs b/Content.Server/Lightning/LightningSystem.cs index 5a7b85d26e..18c47dbf70 100644 --- a/Content.Server/Lightning/LightningSystem.cs +++ b/Content.Server/Lightning/LightningSystem.cs @@ -4,6 +4,7 @@ using Content.Server.Beam.Components; using Content.Server.Lightning.Components; using Content.Shared.Lightning; using Robust.Server.GameObjects; +using Robust.Shared.Map; using Robust.Shared.Random; namespace Content.Server.Lightning; @@ -21,7 +22,7 @@ public sealed class LightningSystem : SharedLightningSystem [Dependency] private readonly BeamSystem _beam = default!; [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly EntityLookupSystem _lookup = default!; - [Dependency] private readonly SharedTransformSystem _transform = default!; + [Dependency] private readonly TransformSystem _transform = default!; public override void Initialize() { @@ -59,6 +60,134 @@ public sealed class LightningSystem : SharedLightningSystem } } + /// + /// Fires lightning from user to coordinates + /// + /// + /// Ported from imp + /// + /// Where the lightning fires from + /// Where the lightning fires to + /// The prototype for the lightning to be created + /// if the lightnings being fired should trigger lightning events. + public void ShootLightning(EntityUid user, MapCoordinates targetCoordinates, string lightningPrototype = "Lightning", bool triggerLightningEvents = true) + { + var spriteState = LightningRandomizer(); + _beam.TryCreateBeam(user, targetCoordinates, lightningPrototype, spriteState); + } + + /// + /// Fires lightning from coordinates to target + /// + /// + /// Ported from imp + /// + /// Where the lightning fires from + /// Where the lightning fires to + /// The prototype for the lightning to be created + /// if the lightnings being fired should trigger lightning events. + public void ShootLightning(MapCoordinates coordinates, EntityUid target, string lightningPrototype = "Lightning", bool triggerLightningEvents = true) + { + var spriteState = LightningRandomizer(); + _beam.TryCreateBeam(coordinates, target, lightningPrototype, spriteState); + + if (triggerLightningEvents) // we don't want certain prototypes to trigger lightning level events + { + var ev = new HitByLightningEvent(null, target); + RaiseLocalEvent(target, ref ev); + } + } + + /// + /// Fires lightning from coordinates to other coordinates + /// + /// + /// Ported from imp + /// + /// Where the lightning fires from + /// Where the lightning fires to + /// The prototype for the lightning to be created + /// if the lightnings being fired should trigger lightning events. + public void ShootLightning(MapCoordinates coordinates, MapCoordinates targetCoordinates, string lightningPrototype = "Lightning", bool triggerLightningEvents = true) + { + var spriteState = LightningRandomizer(); + _beam.TryCreateBeam(coordinates, targetCoordinates, lightningPrototype, spriteState); + } + + + /// + /// Looks for objects with a LightningTarget component in the radius, prioritizes them, and hits the highest priority targets with lightning. + /// + /// + /// Ported from imp. + /// + /// Where the lightning fires from + /// Targets selection radius + /// Number of lightning bolts + /// The prototype for the lightning to be created + /// how many times to recursively fire lightning bolts from the target points of the first shot. + /// if the lightnings being fired should trigger lightning events. + /// Chance for lightning to strike random coordinates instead of an entity. + public void ShootRandomLightnings(MapCoordinates coordinates, float range, int boltCount, string lightningPrototype = "Lightning", int arcDepth = 0, bool triggerLightningEvents = true, float hitCoordsChance = 0f, EntityUid? user = null) + { + //TODO: add support to different priority target tablem for different lightning types + //TODO: Remove Hardcode LightningTargetComponent (this should be a parameter of the SharedLightningComponent) + //TODO: This is still pretty bad for perf but better than before and at least it doesn't re-allocate + // several hashsets every time + + var targets = _lookup.GetEntitiesInRange(coordinates, range).ToList(); + _random.Shuffle(targets); + targets.Sort((x, y) => y.Comp.Priority.CompareTo(x.Comp.Priority)); + + int shootedCount = 0; + int count = -1; + int mobLightningResistance = 2; // imp - If the target has a lightning resistance less than or equal to this, the lightning can hit random coordinates instead. + while (shootedCount < boltCount) + { + count++; + + // imp - random coordinate lightning start + var outOfRange = count >= targets.Count; + var targetLightningResistance = outOfRange ? 0 : targets[count].Comp.LightningResistance; + + if (hitCoordsChance > 0 && targetLightningResistance <= mobLightningResistance && _random.Prob(hitCoordsChance)) + { + var targetCoordinate = coordinates.Offset(_random.NextVector2(range, range)); + + if (user != null) + ShootLightning(user.Value, targetCoordinate, lightningPrototype, triggerLightningEvents); + else + ShootLightning(coordinates, targetCoordinate, lightningPrototype, triggerLightningEvents); + + if (arcDepth > 0) + { + ShootRandomLightnings(targetCoordinate, range, 1, lightningPrototype, arcDepth - 1, triggerLightningEvents, hitCoordsChance, user); + } + + shootedCount++; + continue; + } + + if (outOfRange) { break; } + // imp - random coordinate lightning end + + var curTarget = targets[count]; + if (!_random.Prob(curTarget.Comp.HitProbability)) //Chance to ignore target + continue; + + // imp - use correct shoot lightning method based on whether this is coordinates-based or entity-based + if (user != null) + ShootLightning(user.Value, targets[count].Owner, lightningPrototype, triggerLightningEvents); + else + ShootLightning(coordinates, targets[count].Owner, lightningPrototype, triggerLightningEvents); + + if (arcDepth - targetLightningResistance > 0) + { + ShootRandomLightnings(targets[count].Owner, range, 1, lightningPrototype, arcDepth - targetLightningResistance, triggerLightningEvents, hitCoordsChance); + } + shootedCount++; + } + } /// /// Looks for objects with a LightningTarget component in the radius, prioritizes them, and hits the highest priority targets with lightning. @@ -69,45 +198,18 @@ public sealed class LightningSystem : SharedLightningSystem /// The prototype for the lightning to be created /// how many times to recursively fire lightning bolts from the target points of the first shot. /// if the lightnings being fired should trigger lightning events. - public void ShootRandomLightnings(EntityUid user, float range, int boltCount, string lightningPrototype = "Lightning", int arcDepth = 0, bool triggerLightningEvents = true) + /// Chance for lightning to strike random coordinates instead of an entity. + public void ShootRandomLightnings(EntityUid user, float range, int boltCount, string lightningPrototype = "Lightning", int arcDepth = 0, bool triggerLightningEvents = true, float hitCoordsChance = 0f) { - //To Do: add support to different priority target tablem for different lightning types - //To Do: Remove Hardcode LightningTargetComponent (this should be a parameter of the SharedLightningComponent) - //To Do: This is still pretty bad for perf but better than before and at least it doesn't re-allocate - // several hashsets every time - var mapCoords = _transform.GetMapCoordinates(user); - var targets = _lookup.GetEntitiesInRange(mapCoords, range).ToList(); - _random.Shuffle(targets); - targets.Sort((x, y) => y.Comp.Priority.CompareTo(x.Comp.Priority)); - - int shotCount = 0; - int count = -1; - - while (shotCount < boltCount) - { - count++; - - if (count >= targets.Count) { break; } - var curTarget = targets[count]; - - // Chance to ignore target - if (!_random.Prob(curTarget.Comp.HitProbability)) - continue; - - ShootLightning(user, targets[count].Owner, lightningPrototype, triggerLightningEvents); - - if (arcDepth - targets[count].Comp.LightningResistance > 0) - ShootRandomLightnings(targets[count].Owner, range, 1, lightningPrototype, arcDepth - targets[count].Comp.LightningResistance, triggerLightningEvents); - - shotCount++; - } + // imp - Redirect to the other function for compatibility + ShootRandomLightnings(_transform.GetMapCoordinates(user), range, boltCount, lightningPrototype, arcDepth, triggerLightningEvents, hitCoordsChance, user); } } /// /// Raised directed on the target when an entity becomes the target of a lightning strike (not when touched) /// -/// The entity that created the lightning +/// The entity that created the lightning. May be null if the lightning came from coordinates rather than an entity. /// The entity that was struck by lightning. [ByRefEvent] -public readonly record struct HitByLightningEvent(EntityUid Source, EntityUid Target); +public readonly record struct HitByLightningEvent(EntityUid? Source, EntityUid Target); // imp - Lightning might come from coordinates instead of an entity, so Source can be null diff --git a/Content.Server/_EE/Supermatter/Consoles/SupermatterConsoleSystem.cs b/Content.Server/_EE/Supermatter/Consoles/SupermatterConsoleSystem.cs new file mode 100644 index 0000000000..1ad0cc9f7e --- /dev/null +++ b/Content.Server/_EE/Supermatter/Consoles/SupermatterConsoleSystem.cs @@ -0,0 +1,217 @@ +using Content.Server.Pinpointer; +using Content.Shared._EE.Supermatter.Components; +using Content.Shared._EE.Supermatter.Consoles; +using Content.Shared._EE.Supermatter.Monitor; +using Content.Shared.Atmos; +using Content.Shared.Pinpointer; +using Content.Shared.Radiation.Components; +using Robust.Server.GameObjects; +using Robust.Shared.Map.Components; +using System.Diagnostics.CodeAnalysis; +using System.Linq; + +namespace Content.Server._EE.Supermatter.Console.Systems; + +public sealed class SupermatterConsoleSystem : SharedSupermatterConsoleSystem +{ + [Dependency] private readonly UserInterfaceSystem _userInterfaceSystem = default!; + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + [Dependency] private readonly NavMapSystem _navMapSystem = default!; + + private const float UpdateTime = 1.0f; + + // Note: this data does not need to be saved + private float _updateTimer = 1.0f; + + public override void Initialize() + { + base.Initialize(); + + // Console events + SubscribeLocalEvent(OnConsoleInit); + SubscribeLocalEvent(OnConsoleParentChanged); + SubscribeLocalEvent(OnFocusChangedMessage); + + // Grid events + SubscribeLocalEvent(OnGridSplit); + } + + #region Event handling + + private void OnConsoleInit(EntityUid uid, SupermatterConsoleComponent component, ComponentInit args) + { + InitalizeConsole(uid, component); + } + + private void OnConsoleParentChanged(EntityUid uid, SupermatterConsoleComponent component, EntParentChangedMessage args) + { + InitalizeConsole(uid, component); + } + + private void OnFocusChangedMessage(EntityUid uid, SupermatterConsoleComponent component, SupermatterConsoleFocusChangeMessage args) + { + component.FocusSupermatter = args.FocusSupermatter; + } + + private void OnGridSplit(ref GridSplitEvent args) + { + // Collect grids + var allGrids = args.NewGrids.ToList(); + + if (!allGrids.Contains(args.Grid)) + allGrids.Add(args.Grid); + + // Update supermatter monitoring consoles that stand upon an updated grid + var query = AllEntityQuery(); + while (query.MoveNext(out var ent, out var entConsole, out var entXform)) + { + if (entXform.GridUid == null) + continue; + + if (!allGrids.Contains(entXform.GridUid.Value)) + continue; + + InitalizeConsole(ent, entConsole); + } + } + + #endregion + + public override void Update(float frameTime) + { + base.Update(frameTime); + + // Keep a list of UI entries for each gridUid, in case multiple consoles stand on the same grid + var supermatterEntriesForEachGrid = new Dictionary(); + + var query = AllEntityQuery(); + while (query.MoveNext(out var ent, out var entConsole, out var entXform)) + { + if (entXform?.GridUid == null) + continue; + + // Make a list of alarm state data for all the supermatters on the grid + if (!supermatterEntriesForEachGrid.TryGetValue(entXform.GridUid.Value, out var supermatterEntries)) + { + supermatterEntries = GetSupermatterStateData(entXform.GridUid.Value).ToArray(); + supermatterEntriesForEachGrid[entXform.GridUid.Value] = supermatterEntries; + } + + // Determine the highest level of status for the console + var highestStatus = SupermatterStatusType.Inactive; + + foreach (var entry in supermatterEntries) + { + var status = entry.EntityStatus; + + if (status > highestStatus) + highestStatus = status; + } + + // Update the appearance of the console based on the highest recorded level of alert + if (TryComp(ent, out var entAppearance)) + _appearance.SetData(ent, SupermatterConsoleVisuals.ComputerLayerScreen, (int)highestStatus, entAppearance); + + // If the console UI is open, send UI data to each subscribed session + UpdateUIState(ent, supermatterEntries, entConsole, entXform); + } + } + + public void UpdateUIState + (EntityUid uid, + SupermatterConsoleEntry[] supermatterStateData, + SupermatterConsoleComponent component, + TransformComponent xform) + { + if (!_userInterfaceSystem.IsUiOpen(uid, SupermatterConsoleUiKey.Key)) + return; + + var gridUid = xform.GridUid!.Value; + + // Gathering remaining data to be send to the client + var focusSupermatterData = GetFocusSupermatterData(uid, GetEntity(component.FocusSupermatter), gridUid); + + // Set the UI state + _userInterfaceSystem.SetUiState(uid, SupermatterConsoleUiKey.Key, + new SupermatterConsoleBoundInterfaceState(supermatterStateData, focusSupermatterData)); + } + + private List GetSupermatterStateData(EntityUid gridUid) + { + var supermatterStateData = new List(); + + var querySupermatters = AllEntityQuery(); + while (querySupermatters.MoveNext(out var ent, out var entSupermatter, out var entXform)) + { + if (entXform.GridUid != gridUid) + continue; + + if (!entXform.Anchored) + continue; + + // Create entry + var netEnt = GetNetEntity(ent); + + var entry = new SupermatterConsoleEntry + (netEnt, + MetaData(ent).EntityName, + entSupermatter.Status); + + supermatterStateData.Add(entry); + } + + return supermatterStateData; + } + + private SupermatterFocusData? GetFocusSupermatterData(EntityUid uid, EntityUid? focusSupermatter, EntityUid gridUid) + { + if (focusSupermatter == null) + return null; + + var focusSupermatterXform = Transform(focusSupermatter.Value); + + if (!focusSupermatterXform.Anchored || + focusSupermatterXform.GridUid != gridUid || + !TryComp(focusSupermatter.Value, out var focusComp)) + return null; + + if (!TryComp(focusSupermatter.Value, out var sm)) + return null; + + if (!TryComp(focusSupermatter.Value, out var radiationComp)) + return null; + + var gases = sm.GasStorage; + var tempThreshold = Atmospherics.T0C + sm.HeatPenaltyThreshold; + + return new SupermatterFocusData( + GetNetEntity(focusSupermatter.Value), + GetIntegrity(sm), + sm.Power, + radiationComp.Intensity, + gases.Sum(gas => gases[gas.Key]), + sm.Temperature, + tempThreshold * sm.DynamicHeatResistance, + sm.WasteMultiplier, + sm.GasEfficiency * 100, + sm.GasStorage); + } + + public float GetIntegrity(SupermatterComponent sm) + { + var integrity = sm.Damage / sm.DamageDelaminationPoint; + integrity = (float)Math.Round(100 - integrity * 100, 2); + integrity = integrity < 0 ? 0 : integrity; + return integrity; + } + + private void InitalizeConsole(EntityUid uid, SupermatterConsoleComponent component) + { + var xform = Transform(uid); + + if (xform.GridUid == null) + return; + + Dirty(uid, component); + } +} diff --git a/Content.Server/Supermatter/Systems/SupermatterSystem.Processing.cs b/Content.Server/_EE/Supermatter/Systems/SupermatterSystem.Processing.cs similarity index 59% rename from Content.Server/Supermatter/Systems/SupermatterSystem.Processing.cs rename to Content.Server/_EE/Supermatter/Systems/SupermatterSystem.Processing.cs index 36ae2646b8..6e1e0b63a5 100644 --- a/Content.Server/Supermatter/Systems/SupermatterSystem.Processing.cs +++ b/Content.Server/_EE/Supermatter/Systems/SupermatterSystem.Processing.cs @@ -1,13 +1,25 @@ -using Content.Shared.Atmos; -using Content.Shared.Radiation.Components; -using Content.Shared.Supermatter.Components; -using System.Text; -using Content.Shared.Chat; using System.Linq; +using System.Text; +using Content.Server.Chat.Systems; +using Content.Server.Explosion.EntitySystems; +using Content.Server.Sound.Components; +using Content.Shared._EE.CCVars; +using Content.Shared._EE.Supermatter.Components; +using Content.Shared._EE.Supermatter.Monitor; +using Content.Shared.Atmos; using Content.Shared.Audio; using Content.Shared.CCVar; +using Content.Shared.Chat; +using Content.Shared.Popups; +using Content.Shared.Radiation.Components; +using Content.Shared.Speech; +using Robust.Shared.Audio; +using Robust.Shared.Configuration; +using Robust.Shared.Player; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; -namespace Content.Server.Supermatter.Systems; +namespace Content.Server._EE.Supermatter.Systems; public sealed partial class SupermatterSystem { @@ -97,11 +109,16 @@ public sealed partial class SupermatterSystem // Irradiate stuff if (TryComp(uid, out var rad)) + { rad.Intensity = - sm.Power + _config.GetCVar(ECCVars.SupermatterRadsBase) + + (sm.Power * Math.Max(0, 1f + transmissionBonus / 10f) * 0.003f - * _config.GetCVar(CCVars.SupermatterRadsModifier); + * _config.GetCVar(ECCVars.SupermatterRadsModifier)); + + rad.Slope = Math.Clamp(rad.Intensity / 15, 0.2f, 1f); + } // Power * 0.55 * 0.8~1 // This has to be differentiated with respect to time, since its going to be interacting with systems @@ -126,6 +143,14 @@ public sealed partial class SupermatterSystem // After this point power is lowered // This wraps around to the begining of the function sm.Power = Math.Max(sm.Power - Math.Min(powerReduction * powerlossInhibitor, sm.Power * 0.83f * powerlossInhibitor), 0f); + + // Save values to the supermatter + sm.GasStorage = sm.GasStorage.ToDictionary( + gas => gas.Key, + gas => absorbedGas.GetMoles(gas.Key) + ); + sm.Temperature = absorbedGas.Temperature; + sm.WasteMultiplier = heatModifier; } /// @@ -133,10 +158,35 @@ public sealed partial class SupermatterSystem /// private void SupermatterZap(EntityUid uid, SupermatterComponent sm) { - // Divide power by its' threshold to get a value from 0-1, then multiply by the amount of possible lightnings - var zapPower = sm.Power / sm.PowerPenaltyThreshold * sm.LightningPrototypes.Length; - var zapPowerNorm = (int) Math.Clamp(zapPower, 0, sm.LightningPrototypes.Length - 1); - _lightning.ShootRandomLightnings(uid, 3.5f, sm.Power > sm.PowerPenaltyThreshold ? 3 : 1, sm.LightningPrototypes[zapPowerNorm]); + var zapPower = 0; + var zapCount = 0; + var zapRange = Math.Clamp(sm.Power / 1000, 2, 7); + + // fuck this + if (_random.Prob(0.05f)) + { + zapCount += 1; + } + + if (sm.Power >= sm.PowerPenaltyThreshold) + { + zapCount += 2; + } + + if (sm.Power >= sm.SeverePowerPenaltyThreshold) + { + zapPower = 1; + zapCount++; + } + + if (sm.Power >= sm.CriticalPowerPenaltyThreshold) + { + zapPower = 2; + zapCount++; + } + + if (zapCount >= 1) + _lightning.ShootRandomLightnings(uid, zapRange, zapCount, sm.LightningPrototypes[zapPower], hitCoordsChance: sm.ZapHitCoordinatesChance); } /// @@ -184,20 +234,16 @@ public sealed partial class SupermatterSystem totalDamage += powerDamage; // Mol count only starts affecting damage when it is above 1800 - var moleDamage = Math.Max(moles - sm.MolePenaltyThreshold, 0) / 80 * sm.DamageIncreaseMultiplier; + var moleDamage = Math.Max(moles - sm.MolePenaltyThreshold, 0f) / 80 * sm.DamageIncreaseMultiplier; totalDamage += moleDamage; // Healing damage if (moles < sm.MolePenaltyThreshold) { - // There's a very small float so that it doesn't divide by 0 - var healHeatDamage = Math.Min(absorbedGas.Temperature - tempThreshold, 0.001f) / 150; + var healHeatDamage = Math.Min(absorbedGas.Temperature - tempThreshold, 0f) / 150; totalDamage += healHeatDamage; } - // Return the manipulated gas back to the mix - _atmosphere.Merge(mix, absorbedGas); - // Check for space tiles next to SM //TODO: Change moles out for checking if adjacent tiles exist var enumerator = _atmosphere.GetAdjacentTileMixtures(xform.GridUid.Value, indices, false, false); @@ -217,12 +263,12 @@ public sealed partial class SupermatterSystem _ => 0f }; - totalDamage += Math.Clamp(sm.Power * factor * sm.DamageIncreaseMultiplier, 0, sm.MaxSpaceExposureDamage); + totalDamage += Math.Clamp(sm.Power * factor * sm.DamageIncreaseMultiplier, 0f, sm.MaxSpaceExposureDamage); break; } - var damage = Math.Min(sm.DamageArchived + sm.DamageHardcap * sm.DamageDelaminationPoint, totalDamage); + var damage = Math.Min(sm.DamageArchived + sm.DamageHardcap * sm.DamageDelaminationPoint, sm.Damage + totalDamage); // Prevent it from going negative sm.Damage = Math.Clamp(damage, 0, float.PositiveInfinity); @@ -233,19 +279,16 @@ public sealed partial class SupermatterSystem /// private void AnnounceCoreDamage(EntityUid uid, SupermatterComponent sm) { + // If undamaged, no need to announce anything + if (sm.Damage == 0) + return; + var message = string.Empty; var global = false; var integrity = GetIntegrity(sm).ToString("0.00"); - // Special cases - if (sm.Damage < sm.DamageDelaminationPoint && sm.Delamming) - { - message = Loc.GetString("supermatter-delam-cancel", ("integrity", integrity)); - sm.DelamAnnounced = false; - global = true; - } - + // Instantly announce delamination if (sm.Delamming && !sm.DelamAnnounced) { var sb = new StringBuilder(); @@ -259,18 +302,73 @@ public sealed partial class SupermatterSystem default: loc = "supermatter-delam-explosion"; break; } - var station = _station.GetOwningStation(uid); - if (station != null) - _alert.SetLevel((EntityUid) station, sm.AlertCodeDeltaId, true, true, true, false); - sb.AppendLine(Loc.GetString(loc)); - sb.AppendLine(Loc.GetString("supermatter-seconds-before-delam", ("seconds", sm.DelamTimer))); + sb.Append(Loc.GetString("supermatter-seconds-before-delam", ("seconds", sm.DelamTimer))); message = sb.ToString(); global = true; sm.DelamAnnounced = true; + sm.YellTimer = TimeSpan.FromSeconds(sm.DelamTimer / 2); - SendSupermatterAnnouncement(uid, message, global); + SendSupermatterAnnouncement(uid, sm, message, global); + return; + } + + // Only announce every YellTimer seconds + if (_timing.CurTime < sm.YellLast + sm.YellTimer) + return; + + // Recovered after the delamination point + if (sm.Damage < sm.DamageDelaminationPoint && sm.DelamAnnounced) + { + message = Loc.GetString("supermatter-delam-cancel", ("integrity", integrity)); + sm.DelamAnnounced = false; + sm.YellTimer = TimeSpan.FromSeconds(_config.GetCVar(ECCVars.SupermatterYellTimer)); + global = true; + + SendSupermatterAnnouncement(uid, sm, message, global); + return; + } + + // Oh god oh fuck + if (sm.Delamming && sm.DelamAnnounced) + { + var seconds = Math.Ceiling(sm.DelamEndTime.TotalSeconds - _timing.CurTime.TotalSeconds); + + if (seconds <= 0) + return; + + var loc = seconds switch + { + > 5 => "supermatter-seconds-before-delam-countdown", + <= 5 => "supermatter-seconds-before-delam-imminent", + _ => String.Empty + }; + + sm.YellTimer = seconds switch + { + > 30 => TimeSpan.FromSeconds(10), + > 5 => TimeSpan.FromSeconds(5), + <= 5 => TimeSpan.FromSeconds(1), + _ => TimeSpan.FromSeconds(_config.GetCVar(ECCVars.SupermatterYellTimer)) + }; + + message = Loc.GetString(loc, ("seconds", seconds)); + global = true; + + SendSupermatterAnnouncement(uid, sm, message, global); + return; + } + + // We're safe + if (sm.Damage < sm.DamageArchived && sm.Status >= SupermatterStatusType.Warning) + { + message = Loc.GetString("supermatter-healing", ("integrity", integrity)); + + if (sm.Status >= SupermatterStatusType.Emergency) + global = true; + + SendSupermatterAnnouncement(uid, sm, message, global); return; } @@ -292,21 +390,27 @@ public sealed partial class SupermatterSystem } } - SendSupermatterAnnouncement(uid, message, global); + SendSupermatterAnnouncement(uid, sm, message, global); } - /// If true, sends a station announcement + /// If true, sends the message to the common radio /// Localisation string for a custom announcer name - public void SendSupermatterAnnouncement(EntityUid uid, string message, bool global = false, string? customSender = null) + public void SendSupermatterAnnouncement(EntityUid uid, SupermatterComponent sm, string message, bool global = false) { - if (global) - { - var sender = Loc.GetString(customSender != null ? customSender : "supermatter-announcer"); - _chat.DispatchStationAnnouncement(uid, message, sender, colorOverride: Color.Yellow); + if (message == String.Empty) return; - } + var channel = sm.Channel; + + if (global) + channel = sm.ChannelGlobal; + + // Ensure status, otherwise the wrong speech sound may be used + HandleStatus(uid, sm); + + sm.YellLast = _timing.CurTime; _chat.TrySendInGameICMessage(uid, message, InGameICChatType.Speak, hideChat: false, checkRadioPrefix: true); + _radio.SendRadioMessage(uid, message, channel, uid); } /// @@ -325,8 +429,8 @@ public sealed partial class SupermatterSystem /// public DelamType ChooseDelamType(EntityUid uid, SupermatterComponent sm) { - if (_config.GetCVar(CCVars.SupermatterDoForceDelam)) - return _config.GetCVar(CCVars.SupermatterForcedDelamType); + if (_config.GetCVar(ECCVars.SupermatterDoForceDelam)) + return _config.GetCVar(ECCVars.SupermatterForcedDelamType); var mix = _atmosphere.GetContainingMixture(uid, true, true); @@ -335,13 +439,13 @@ public sealed partial class SupermatterSystem var absorbedGas = mix.Remove(sm.GasEfficiency * mix.TotalMoles); var moles = absorbedGas.TotalMoles; - if (_config.GetCVar(CCVars.SupermatterDoSingulooseDelam) - && moles >= sm.MolePenaltyThreshold * _config.GetCVar(CCVars.SupermatterSingulooseMolesModifier)) + if (_config.GetCVar(ECCVars.SupermatterDoSingulooseDelam) + && moles >= sm.MolePenaltyThreshold * _config.GetCVar(ECCVars.SupermatterSingulooseMolesModifier)) return DelamType.Singulo; } - if (_config.GetCVar(CCVars.SupermatterDoTeslooseDelam) - && sm.Power >= sm.PowerPenaltyThreshold * _config.GetCVar(CCVars.SupermatterTesloosePowerModifier)) + if (_config.GetCVar(ECCVars.SupermatterDoTeslooseDelam) + && sm.Power >= sm.PowerPenaltyThreshold * _config.GetCVar(ECCVars.SupermatterTesloosePowerModifier)) return DelamType.Tesla; //TODO: Add resonance cascade when there's crazy conditions or a destabilizing crystal @@ -361,6 +465,7 @@ public sealed partial class SupermatterSystem if (!sm.Delamming) { sm.Delamming = true; + sm.DelamEndTime = _timing.CurTime + TimeSpan.FromSeconds(sm.DelamTimer); AnnounceCoreDamage(uid, sm); } @@ -370,11 +475,23 @@ public sealed partial class SupermatterSystem AnnounceCoreDamage(uid, sm); } - sm.DelamTimerAccumulator++; - - if (sm.DelamTimerAccumulator < sm.DelamTimer) + if (_timing.CurTime < sm.DelamEndTime) return; + var smTransform = Transform(uid); + + foreach (var pSession in Filter.GetAllPlayers()) + { + var pEntity = pSession.AttachedEntity; + + if (pEntity != null + && TryComp(pEntity, out var pTransform) + && pTransform.MapID == smTransform.MapID) + _popup.PopupEntity(Loc.GetString("supermatter-delam-player"), pEntity.Value, pEntity.Value, PopupType.MediumCaution); + } + + _audio.PlayGlobal(sm.DistortSound, Filter.BroadcastMap(Transform(uid).MapID), true); + switch (sm.PreferredDelamType) { case DelamType.Cascade: @@ -395,6 +512,55 @@ public sealed partial class SupermatterSystem } } + /// + /// Sets the supermatter's status and speech sound based on thresholds + /// + private void HandleStatus(EntityUid uid, SupermatterComponent sm) + { + var currentStatus = GetStatus(uid, sm); + + if (sm.Status != currentStatus) + { + sm.Status = currentStatus; + + if (!TryComp(uid, out var speech)) + return; + + sm.StatusCurrentSound = currentStatus switch + { + SupermatterStatusType.Warning => sm.StatusWarningSound, + SupermatterStatusType.Danger => sm.StatusDangerSound, + SupermatterStatusType.Emergency => sm.StatusEmergencySound, + SupermatterStatusType.Delaminating => sm.StatusDelamSound, + _ => null + }; + + ProtoId? speechSound = sm.StatusCurrentSound; + + if (currentStatus == SupermatterStatusType.Warning) + speech.AudioParams = AudioParams.Default.AddVolume(7.5f); + else + speech.AudioParams = AudioParams.Default.AddVolume(10f); + + if (currentStatus == SupermatterStatusType.Delaminating) + speech.SoundCooldownTime = 6.8f; // approximate length of bloblarm.ogg + else + speech.SoundCooldownTime = 0.0f; + + speech.SpeechSounds = speechSound; + } + + // Supermatter is healing, don't play any speech sounds + if (sm.Damage < sm.DamageArchived) + { + if (!TryComp(uid, out var speech)) + return; + + sm.StatusCurrentSound = null; + speech.SpeechSounds = null; + } + } + /// /// Swaps out ambience sounds when the SM is delamming or not. /// @@ -405,13 +571,48 @@ public sealed partial class SupermatterSystem if (ambient == null) return; - if (sm.Delamming && sm.CurrentSoundLoop != sm.DelamSound) - sm.CurrentSoundLoop = sm.DelamSound; + var volume = (float) Math.Round(Math.Clamp((sm.Power / 50) - 5, -5, 5)); - else if (!sm.Delamming && sm.CurrentSoundLoop != sm.CalmSound) - sm.CurrentSoundLoop = sm.CalmSound; + _ambient.SetVolume(uid, volume); + + if (sm.Status >= SupermatterStatusType.Danger && sm.CurrentSoundLoop != sm.DelamLoopSound) + sm.CurrentSoundLoop = sm.DelamLoopSound; + + else if (sm.Status < SupermatterStatusType.Danger && sm.CurrentSoundLoop != sm.CalmLoopSound) + sm.CurrentSoundLoop = sm.CalmLoopSound; if (ambient.Sound != sm.CurrentSoundLoop) _ambient.SetSound(uid, sm.CurrentSoundLoop, ambient); } + + /// + /// Plays normal/delam sounds at a rate determined by power and damage + /// + private void HandleAccent(EntityUid uid, SupermatterComponent sm) + { + var emit = Comp(uid); + + if (emit == null) + return; + + if (sm.AccentLastTime >= _timing.CurTime || !_random.Prob(0.05f)) + return; + + var aggression = Math.Min((sm.Damage / 800) * (sm.Power / 2500), 1) * 100; + var nextSound = Math.Max(Math.Round((100 - aggression) * 5), sm.AccentMinCooldown); + + if (sm.AccentLastTime + TimeSpan.FromSeconds(nextSound) > _timing.CurTime) + return; + + if (sm.Status >= SupermatterStatusType.Danger && emit.Sound != sm.DelamAccent) + emit.Sound = sm.DelamAccent; + + else if (sm.Status < SupermatterStatusType.Danger && emit.Sound != sm.CalmAccent) + emit.Sound = sm.CalmAccent; + + sm.AccentLastTime = _timing.CurTime; + + var ev = new TriggerEvent(uid); + RaiseLocalEvent(uid, ev); + } } diff --git a/Content.Server/Supermatter/Systems/SupermatterSystem.cs b/Content.Server/_EE/Supermatter/Systems/SupermatterSystem.cs similarity index 66% rename from Content.Server/Supermatter/Systems/SupermatterSystem.cs rename to Content.Server/_EE/Supermatter/Systems/SupermatterSystem.cs index 7521b42c48..5e9ec4c48a 100644 --- a/Content.Server/Supermatter/Systems/SupermatterSystem.cs +++ b/Content.Server/_EE/Supermatter/Systems/SupermatterSystem.cs @@ -1,33 +1,46 @@ +using Content.Server.AlertLevel; +using Content.Server.Atmos.EntitySystems; +using Content.Server.Atmos.Piping.Components; +using Content.Server.Chat.Systems; +using Content.Server.Decals; +using Content.Server.DoAfter; +using Content.Server.Explosion.EntitySystems; +using Content.Server.Kitchen.Components; +using Content.Server.Lightning; +using Content.Server.Lightning.Components; +using Content.Server.Popups; +using Content.Server.Radio.EntitySystems; +using Content.Server.Speech; +using Content.Server.Station.Systems; +using Content.Shared._EE.CCVars; +using Content.Shared._EE.Supermatter.Components; +using Content.Shared._EE.Supermatter.Monitor; +using Content.Shared.Atmos; +using Content.Shared.Audio; +using Content.Shared.Body.Components; +using Content.Shared.CCVar; +using Content.Shared.DoAfter; +using Content.Shared.Examine; +using Content.Shared.Interaction; +using Content.Shared.Mobs.Components; +using Content.Shared.Popups; +using Content.Shared.Projectiles; +using Robust.Server.GameObjects; using Robust.Shared.Audio.Systems; using Robust.Shared.Configuration; using Robust.Shared.Containers; using Robust.Shared.Physics; using Robust.Shared.Physics.Events; -using Robust.Server.GameObjects; -using Content.Shared.Atmos; -using Content.Shared.Interaction; -using Content.Shared.Projectiles; -using Content.Shared.Mobs.Components; -using Content.Server.Atmos.EntitySystems; -using Content.Server.Chat.Systems; -using Content.Server.Explosion.EntitySystems; -using Content.Shared.Supermatter.Components; -using Content.Server.Lightning; -using Content.Server.AlertLevel; -using Content.Server.Station.Systems; -using Content.Server.Kitchen.Components; -using Content.Shared.DoAfter; -using Content.Shared.Examine; -using Content.Server.DoAfter; -using Content.Server.Popups; -using Content.Shared.Audio; +using Robust.Shared.Random; +using Robust.Shared.Timing; -namespace Content.Server.Supermatter.Systems; +namespace Content.Server._EE.Supermatter.Systems; public sealed partial class SupermatterSystem : EntitySystem { [Dependency] private readonly AtmosphereSystem _atmosphere = default!; [Dependency] private readonly ChatSystem _chat = default!; + [Dependency] private readonly RadioSystem _radio = default!; [Dependency] private readonly SharedContainerSystem _container = default!; [Dependency] private readonly ExplosionSystem _explosion = default!; [Dependency] private readonly TransformSystem _xform = default!; @@ -36,10 +49,13 @@ public sealed partial class SupermatterSystem : EntitySystem [Dependency] private readonly LightningSystem _lightning = default!; [Dependency] private readonly AlertLevelSystem _alert = default!; [Dependency] private readonly StationSystem _station = default!; + [Dependency] private readonly MapSystem _map = default!; [Dependency] private readonly DoAfterSystem _doAfter = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; [Dependency] private readonly PopupSystem _popup = default!; [Dependency] private readonly IConfigurationManager _config = default!; + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly IRobustRandom _random = default!; public override void Initialize() @@ -47,6 +63,7 @@ public sealed partial class SupermatterSystem : EntitySystem base.Initialize(); SubscribeLocalEvent(OnMapInit); + SubscribeLocalEvent(OnSupermatterUpdated); SubscribeLocalEvent(OnCollideEvent); SubscribeLocalEvent(OnHandInteract); @@ -55,56 +72,22 @@ public sealed partial class SupermatterSystem : EntitySystem SubscribeLocalEvent(OnGetSliver); } - public override void Update(float frameTime) { base.Update(frameTime); foreach (var sm in EntityManager.EntityQuery()) { - if (!sm.Activated) - return; - var uid = sm.Owner; - sm.UpdateAccumulator += frameTime; - - if (sm.UpdateAccumulator >= sm.UpdateTimer) - { - sm.UpdateAccumulator -= sm.UpdateTimer; - Cycle(uid, sm, frameTime); - } - } - } - - - public void Cycle(EntityUid uid, SupermatterComponent sm, float frameTime) - { - sm.ZapAccumulator++; - sm.YellAccumulator++; - - ProcessAtmos(uid, sm, frameTime); - HandleDamage(uid, sm); - - if (sm.Damage >= sm.DamageDelaminationPoint || sm.Delamming) - HandleDelamination(uid, sm); - - HandleSoundLoop(uid, sm); - - if (sm.ZapAccumulator >= sm.ZapTimer) - { - sm.ZapAccumulator -= sm.ZapTimer; - SupermatterZap(uid, sm); - } - - if (sm.YellAccumulator >= sm.YellTimer) - { - sm.YellAccumulator -= sm.YellTimer; AnnounceCoreDamage(uid, sm); } } private void OnMapInit(EntityUid uid, SupermatterComponent sm, MapInitEvent args) { + // Set the yell timer + sm.YellTimer = TimeSpan.FromSeconds(_config.GetCVar(ECCVars.SupermatterYellTimer)); + // Set the Sound _ambient.SetAmbience(uid, true); @@ -113,6 +96,21 @@ public sealed partial class SupermatterSystem : EntitySystem mix?.AdjustMoles(Gas.Oxygen, Atmospherics.OxygenMolesStandard); mix?.AdjustMoles(Gas.Nitrogen, Atmospherics.NitrogenMolesStandard); } + public void OnSupermatterUpdated(EntityUid uid, SupermatterComponent sm, AtmosDeviceUpdateEvent args) + { + ProcessAtmos(uid, sm, args.dt); + HandleDamage(uid, sm); + + if (sm.Damage >= sm.DamageDelaminationPoint || sm.Delamming) + HandleDelamination(uid, sm); + + HandleStatus(uid, sm); + HandleSoundLoop(uid, sm); + HandleAccent(uid, sm); + + if (sm.Damage >= sm.DamagePenaltyPoint) + SupermatterZap(uid, sm); + } private void OnCollideEvent(EntityUid uid, SupermatterComponent sm, ref StartCollideEvent args) { @@ -127,12 +125,26 @@ public sealed partial class SupermatterSystem : EntitySystem if (!HasComp(target)) { - EntityManager.SpawnEntity(sm.CollisionResultPrototype, Transform(target).Coordinates); - _audio.PlayPvs(sm.DustSound, uid); + var popup = "supermatter-collide"; + + if (HasComp(target)) + { + popup = "supermatter-collide-mob"; + EntityManager.SpawnEntity(sm.CollisionResultPrototype, Transform(target).Coordinates); + } + + var targetProto = MetaData(target).EntityPrototype; + if (targetProto != null && targetProto.ID != sm.CollisionResultPrototype) + { + _popup.PopupEntity(Loc.GetString(popup, ("sm", uid), ("target", target)), uid, PopupType.LargeCaution); + _audio.PlayPvs(sm.DustSound, uid); + } + sm.Power += args.OtherBody.Mass; } EntityManager.QueueDeleteEntity(target); + AddComp(target); // prevent spam or excess power production if (TryComp(target, out var food)) sm.Power += food.Energy; @@ -157,6 +169,7 @@ public sealed partial class SupermatterSystem : EntitySystem sm.MatterPower += 200; EntityManager.SpawnEntity(sm.CollisionResultPrototype, Transform(target).Coordinates); + _popup.PopupEntity(Loc.GetString("supermatter-collide-mob", ("sm", uid), ("target", target)), uid, PopupType.LargeCaution); _audio.PlayPvs(sm.DustSound, uid); EntityManager.QueueDeleteEntity(target); } @@ -176,7 +189,6 @@ public sealed partial class SupermatterSystem : EntitySystem { BreakOnDamage = true, BreakOnHandChange = false, - BreakOnMove = true, BreakOnWeightlessMove = false, NeedHand = true, RequireCanInteract = true, @@ -195,7 +207,7 @@ public sealed partial class SupermatterSystem : EntitySystem sm.Damage += sm.DamageDelaminationPoint / 10; var integrity = GetIntegrity(sm).ToString("0.00"); - SendSupermatterAnnouncement(uid, Loc.GetString("supermatter-announcement-cc-tamper", ("integrity", integrity)), true, "Central Command"); + SendSupermatterAnnouncement(uid, sm, Loc.GetString("supermatter-announcement-cc-tamper", ("integrity", integrity))); Spawn(sm.SliverPrototype, _transform.GetMapCoordinates(args.User)); _popup.PopupClient(Loc.GetString("supermatter-tamper-end"), uid, args.User); @@ -208,4 +220,32 @@ public sealed partial class SupermatterSystem : EntitySystem if (args.IsInDetailsRange) args.PushMarkup(Loc.GetString("supermatter-examine-integrity", ("integrity", GetIntegrity(sm).ToString("0.00")))); } + + private SupermatterStatusType GetStatus(EntityUid uid, SupermatterComponent sm) + { + var mix = _atmosphere.GetContainingMixture(uid, true, true); + + if (mix is not { }) + return SupermatterStatusType.Error; + + if (sm.Delamming || sm.Damage >= sm.DamageDelaminationPoint) + return SupermatterStatusType.Delaminating; + + if (sm.Damage >= sm.DamagePenaltyPoint) + return SupermatterStatusType.Emergency; + + if (sm.Damage >= sm.DamageDelamAlertPoint) + return SupermatterStatusType.Danger; + + if (sm.Damage >= sm.DamageWarningThreshold) + return SupermatterStatusType.Warning; + + if (mix.Temperature > Atmospherics.T0C + (sm.HeatPenaltyThreshold * 0.8)) + return SupermatterStatusType.Caution; + + if (sm.Power > 5) + return SupermatterStatusType.Normal; + + return SupermatterStatusType.Inactive; + } } diff --git a/Content.Shared/Beam/Components/SharedBeamComponent.cs b/Content.Shared/Beam/Components/SharedBeamComponent.cs index 9c5c5dd344..65598f88b6 100644 --- a/Content.Shared/Beam/Components/SharedBeamComponent.cs +++ b/Content.Shared/Beam/Components/SharedBeamComponent.cs @@ -1,4 +1,5 @@ -using Robust.Shared.Audio; +using Robust.Shared.Audio; +using Robust.Shared.Map; using Robust.Shared.Serialization; namespace Content.Shared.Beam.Components; @@ -44,6 +45,16 @@ public abstract partial class SharedBeamComponent : Component [ViewVariables(VVAccess.ReadWrite)] [DataField("sound")] public SoundSpecifier? Sound; + + /// + /// Allow the sprite to be randomized. + /// + /// + /// Ported from imp + /// + [ViewVariables] + [DataField("allowSpriteOverwrite")] + public bool AllowSpriteOverwrite = true; } /// @@ -68,13 +79,29 @@ public sealed class BeamControllerCreatedEvent : EntityEventArgs public sealed class CreateBeamSuccessEvent : EntityEventArgs { public readonly EntityUid User; - public readonly EntityUid Target; + + /// + /// The entity the beam targeted. + /// Imp - This may be null if the beam targeted a map coordinate. + /// + public readonly EntityUid? Target; + + /// + /// The coordinates the beam targeted. This may be null if the beam targeted an entity. + /// + public readonly MapCoordinates? Coordinates; public CreateBeamSuccessEvent(EntityUid user, EntityUid target) { User = user; Target = target; } + + public CreateBeamSuccessEvent(EntityUid user, MapCoordinates coordinates) + { + User = user; + Coordinates = coordinates; + } } /// diff --git a/Content.Shared/CCVar/CCVars.Supermatter.cs b/Content.Shared/_EE/CCVars/ECCVars.Supermatter.cs similarity index 80% rename from Content.Shared/CCVar/CCVars.Supermatter.cs rename to Content.Shared/_EE/CCVars/ECCVars.Supermatter.cs index 8aea6524ae..69e90d0216 100644 --- a/Content.Shared/CCVar/CCVars.Supermatter.cs +++ b/Content.Shared/_EE/CCVars/ECCVars.Supermatter.cs @@ -1,9 +1,11 @@ -using Content.Shared.Supermatter.Components; +using Content.Shared._EE.Supermatter.Components; using Robust.Shared.Configuration; -namespace Content.Shared.CCVar; +namespace Content.Shared._EE.CCVars; -public sealed partial class CCVars +[CVarDefs] +// ReSharper disable once InconsistentNaming +public sealed partial class ECCVars { /// /// With completely default supermatter values, Singuloose delamination will occur if engineers inject at least 900 moles of coolant per tile @@ -44,9 +46,21 @@ public sealed partial class CCVars public static readonly CVarDef SupermatterForcedDelamType = CVarDef.Create("supermatter.forced_delam_type", DelamType.Singulo, CVar.SERVER); + /// + /// Base amount of radiation that the supermatter emits. + /// + public static readonly CVarDef SupermatterRadsBase = + CVarDef.Create("supermatter.rads_base", 3f, CVar.SERVER); + /// /// Directly multiplies the amount of rads put out by the supermatter. Be VERY conservative with this. /// public static readonly CVarDef SupermatterRadsModifier = CVarDef.Create("supermatter.rads_modifier", 1f, CVar.SERVER); + + /// + /// How often the supermatter should announce its status. + /// + public static readonly CVarDef SupermatterYellTimer = + CVarDef.Create("supermatter.yell_timer", 60f, CVar.SERVER); } diff --git a/Content.Shared/Supermatter/Components/SupermatterComponent.cs b/Content.Shared/_EE/Supermatter/Components/SupermatterComponent.cs similarity index 71% rename from Content.Shared/Supermatter/Components/SupermatterComponent.cs rename to Content.Shared/_EE/Supermatter/Components/SupermatterComponent.cs index ad7604f5ba..e40fe87ba5 100644 --- a/Content.Shared/Supermatter/Components/SupermatterComponent.cs +++ b/Content.Shared/_EE/Supermatter/Components/SupermatterComponent.cs @@ -1,11 +1,14 @@ -using Robust.Shared.GameStates; -using Robust.Shared.Audio; +using Content.Shared._EE.Supermatter.Monitor; using Content.Shared.Atmos; -using Content.Shared.Whitelist; using Content.Shared.DoAfter; +using Content.Shared.Radio; +using Content.Shared.Speech; +using Robust.Shared.Audio; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; using Robust.Shared.Serialization; -namespace Content.Shared.Supermatter.Components; +namespace Content.Shared._EE.Supermatter.Components; [RegisterComponent, NetworkedComponent] public sealed partial class SupermatterComponent : Component @@ -16,7 +19,13 @@ public sealed partial class SupermatterComponent : Component /// The SM will only cycle if activated. /// [DataField] - public bool Activated = false; + public bool Activated = true; + + /// + /// The current status of the singularity, used for alert sounds and the monitoring console + /// + [DataField] + public SupermatterStatusType Status = SupermatterStatusType.Inactive; [DataField] public string SliverPrototype = "SupermatterSliver"; @@ -26,14 +35,13 @@ public sealed partial class SupermatterComponent : Component /// If removed - delamination timer is divided by 2. /// [DataField] - public bool SliverRemoved = false; + public bool SliverRemoved; public string[] LightningPrototypes = { - "Lightning", - "ChargedLightning", - "SuperchargedLightning", - "HyperchargedLightning" + "SupermatterLightning", + "SupermatterLightningCharged", + "SupermatterLightningSupercharged" }; [DataField] @@ -51,17 +59,45 @@ public sealed partial class SupermatterComponent : Component [DataField] public string CollisionResultPrototype = "Ash"; - [DataField] - public SoundSpecifier DustSound = new SoundPathSpecifier("/Audio/Effects/Grenades/Supermatter/supermatter_start.ogg"); + #endregion + + #region Sounds [DataField] - public SoundSpecifier CalmSound = new SoundPathSpecifier("/Audio/Supermatter/calm.ogg"); + public SoundSpecifier DustSound = new SoundPathSpecifier("/Audio/_EE/Supermatter/supermatter.ogg"); [DataField] - public SoundSpecifier DelamSound = new SoundPathSpecifier("/Audio/Supermatter/delamming.ogg"); + public SoundSpecifier DistortSound = new SoundPathSpecifier("/Audio/_EE/Supermatter/distort.ogg"); [DataField] - public SoundSpecifier CurrentSoundLoop = new SoundPathSpecifier("/Audio/Supermatter/calm.ogg"); + public SoundSpecifier CalmLoopSound = new SoundPathSpecifier("/Audio/_EE/Supermatter/calm.ogg"); + + [DataField] + public SoundSpecifier DelamLoopSound = new SoundPathSpecifier("/Audio/_EE/Supermatter/delamming.ogg"); + + [DataField] + public SoundSpecifier CurrentSoundLoop = new SoundPathSpecifier("/Audio/_EE/Supermatter/calm.ogg"); + + [DataField] + public SoundSpecifier CalmAccent = new SoundCollectionSpecifier("SupermatterAccentNormal"); + + [DataField] + public SoundSpecifier DelamAccent = new SoundCollectionSpecifier("SupermatterAccentDelam"); + + [DataField] + public string StatusWarningSound = "SupermatterWarning"; + + [DataField] + public string StatusDangerSound = "SupermatterDanger"; + + [DataField] + public string StatusEmergencySound = "SupermatterEmergency"; + + [DataField] + public string StatusDelamSound = "SupermatterDelaminating"; + + [DataField] + public string? StatusCurrentSound; #endregion @@ -70,6 +106,12 @@ public sealed partial class SupermatterComponent : Component [DataField] public float Power; + [DataField] + public float Temperature; + + [DataField] + public float WasteMultiplier; + [DataField] public float MatterPower; @@ -134,6 +176,12 @@ public sealed partial class SupermatterComponent : Component [DataField] public float OxygenReleaseEfficiencyModifier = 0.0031f; + /// + /// The chance for supermatter lightning to strike random coordinates instead of an entity + /// + [DataField] + public float ZapHitCoordinatesChance = 0.75f; + #endregion #region Timing @@ -142,43 +190,40 @@ public sealed partial class SupermatterComponent : Component /// We yell if over 50 damage every YellTimer Seconds /// [DataField] - public float YellTimer = 60f; + public TimeSpan YellTimer = TimeSpan.Zero; /// - /// Set to YellTimer at first so it doesnt yell a minute after being hit + /// Last time the supermatter's damage was announced /// [DataField] - public float YellAccumulator = 60f; + public TimeSpan YellLast = TimeSpan.Zero; /// - /// Timer for delam + /// Time when the delamination will occuer /// [DataField] - public float DelamTimerAccumulator; + public TimeSpan DelamEndTime; /// - /// Time until delam + /// How long it takes in seconds for the supermatter to delaminate after reaching zero integrity /// [DataField] - public float DelamTimer = 120f; + public float DelamTimer = 30f; /// - /// The message timer + /// Last time a supermatter accent sound was triggered /// [DataField] - public float SpeakAccumulator = 60f; + public TimeSpan AccentLastTime = TimeSpan.Zero; + + /// + /// Minimum time in seconds between supermatter accent sounds + /// + [DataField] + public float AccentMinCooldown = 2f; [DataField] - public float UpdateAccumulator = 0f; - - [DataField] - public float UpdateTimer = 1f; - - [DataField] - public float ZapAccumulator = 0f; - - [DataField] - public float ZapTimer = 10f; + public TimeSpan ZapLast = TimeSpan.Zero; #endregion @@ -213,7 +258,7 @@ public sealed partial class SupermatterComponent : Component /// Above this value we can get lord singulo and independent mol damage, below it we can heal damage /// [DataField] - public float MolePenaltyThreshold = 900f; + public float MolePenaltyThreshold = 1800f; /// /// More moles of gases are harder to heat than fewer, so let's scale heat damage around them @@ -226,7 +271,19 @@ public sealed partial class SupermatterComponent : Component /// and delamming into a tesla. Low chance of pyro anomalies, +2 bolts of electricity /// [DataField] - public float PowerPenaltyThreshold = 4000f; + public float PowerPenaltyThreshold = 5000f; + + /// + /// +1 bolt of electricity, TODO: anomaly spawning + /// + [DataField] + public float SeverePowerPenaltyThreshold = 7000f; + + /// + /// +1 bolt of electricity + /// + [DataField] + public float CriticalPowerPenaltyThreshold = 9000f; /// /// Maximum safe operational temperature in degrees Celsius. @@ -243,14 +300,14 @@ public sealed partial class SupermatterComponent : Component /// The amount of damage taken /// [DataField] - public float Damage = 0f; + public float Damage; /// /// The damage from before this cycle. /// Used to limit the damage we can take each cycle, and for safe alert. /// [DataField] - public float DamageArchived = 0f; + public float DamageArchived; /// /// Is multiplied by ExplosionPoint to cap evironmental damage per cycle @@ -282,14 +339,26 @@ public sealed partial class SupermatterComponent : Component [DataField] public float DamageEmergencyThreshold = 500; + /// + /// The point at which the SM begins shooting lightning. + /// + [DataField] + public int DamagePenaltyPoint = 550; + /// /// The point at which the SM begins delaminating. /// [DataField] public int DamageDelaminationPoint = 900; + /// + /// The point at which the SM begins showing warning signs. + /// [DataField] - public bool Delamming = false; + public int DamageDelamAlertPoint = 300; + + [DataField] + public bool Delamming; [DataField] public DelamType PreferredDelamType = DelamType.Explosion; @@ -299,13 +368,13 @@ public sealed partial class SupermatterComponent : Component #region Announcements [DataField] - public string AlertCodeYellowId = "yellow"; + public bool DelamAnnounced; [DataField] - public string AlertCodeDeltaId = "delta"; + public ProtoId Channel = "Engineering"; [DataField] - public bool DelamAnnounced = false; + public ProtoId ChannelGlobal = "Common"; #endregion diff --git a/Content.Shared/Supermatter/Components/SupermatterFoodComponent.cs b/Content.Shared/_EE/Supermatter/Components/SupermatterFoodComponent.cs similarity index 73% rename from Content.Shared/Supermatter/Components/SupermatterFoodComponent.cs rename to Content.Shared/_EE/Supermatter/Components/SupermatterFoodComponent.cs index 9d235a4b4d..2d7ebca607 100644 --- a/Content.Shared/Supermatter/Components/SupermatterFoodComponent.cs +++ b/Content.Shared/_EE/Supermatter/Components/SupermatterFoodComponent.cs @@ -1,4 +1,4 @@ -namespace Content.Shared.Supermatter.Components; +namespace Content.Shared._EE.Supermatter.Components; [RegisterComponent] public sealed partial class SupermatterFoodComponent : Component diff --git a/Content.Shared/Supermatter/Components/SupermatterImmuneComponent.cs b/Content.Shared/_EE/Supermatter/Components/SupermatterImmuneComponent.cs similarity index 73% rename from Content.Shared/Supermatter/Components/SupermatterImmuneComponent.cs rename to Content.Shared/_EE/Supermatter/Components/SupermatterImmuneComponent.cs index b517115eca..ca6f2701b5 100644 --- a/Content.Shared/Supermatter/Components/SupermatterImmuneComponent.cs +++ b/Content.Shared/_EE/Supermatter/Components/SupermatterImmuneComponent.cs @@ -1,6 +1,6 @@ using Robust.Shared.GameStates; -namespace Content.Shared.Supermatter.Components; +namespace Content.Shared._EE.Supermatter.Components; [RegisterComponent, NetworkedComponent] public sealed partial class SupermatterImmuneComponent : Component diff --git a/Content.Shared/_EE/Supermatter/Consoles/SharedSupermatterConsoleSystem.cs b/Content.Shared/_EE/Supermatter/Consoles/SharedSupermatterConsoleSystem.cs new file mode 100644 index 0000000000..088996c3f4 --- /dev/null +++ b/Content.Shared/_EE/Supermatter/Consoles/SharedSupermatterConsoleSystem.cs @@ -0,0 +1,3 @@ +namespace Content.Shared._EE.Supermatter.Consoles; +public abstract partial class SharedSupermatterConsoleSystem : EntitySystem +{ } diff --git a/Content.Shared/_EE/Supermatter/Consoles/SupermatterConsoleComponent.cs b/Content.Shared/_EE/Supermatter/Consoles/SupermatterConsoleComponent.cs new file mode 100644 index 0000000000..d5925b33c6 --- /dev/null +++ b/Content.Shared/_EE/Supermatter/Consoles/SupermatterConsoleComponent.cs @@ -0,0 +1,208 @@ +using Content.Shared._EE.Supermatter.Consoles; +using Content.Shared._EE.Supermatter.Monitor; +using Content.Shared.Atmos; +using Robust.Shared.GameStates; +using Robust.Shared.Map; +using Robust.Shared.Serialization; + +namespace Content.Shared._EE.Supermatter.Components; + +[RegisterComponent, NetworkedComponent] +[Access(typeof(SharedSupermatterConsoleSystem))] +public sealed partial class SupermatterConsoleComponent : Component +{ + /// + /// The current entity of interest (selected via the console UI) + /// + [ViewVariables] + public NetEntity? FocusSupermatter; +} + +[Serializable, NetSerializable] +public struct SupermatterNavMapData +{ + /// + /// The entity in question + /// + public NetEntity NetEntity; + + /// + /// Location of the entity + /// + public NetCoordinates NetCoordinates; + + /// + /// Populate the supermatter console nav map with a single entity + /// + public SupermatterNavMapData(NetEntity netEntity, NetCoordinates netCoordinates) + { + NetEntity = netEntity; + NetCoordinates = netCoordinates; + } +} + +[Serializable, NetSerializable] +public struct SupermatterFocusData +{ + /// + /// Focus entity + /// + public NetEntity NetEntity; + + /// + /// The supermatter's integrity, from 0 to 100 + /// + public float Integrity; + + /// + /// The supermatter's power + /// + public float Power; + + /// + /// The supermatter's emitted radiation + /// + public float Radiation; + + /// + /// The supermatter's total absorbed moles + /// + public float AbsorbedMoles; + + /// + /// The supermatter's temperature + /// + public float Temperature; + + /// + /// The supermatter's temperature limit + /// + public float TemperatureLimit; + + /// + /// The supermatter's waste multiplier + /// + public float WasteMultiplier; + + /// + /// The supermatter's absorption ratio + /// + public float AbsorptionRatio; + + /// + /// The supermatter's gas storage + /// + [DataField] + public Dictionary GasStorage; + + /// + /// Populates the supermatter console focus entry with supermatter data + /// + public SupermatterFocusData + (NetEntity netEntity, + float integrity, + float power, + float radiation, + float absorbedMoles, + float temperature, + float temperatureLimit, + float wasteMultiplier, + float absorptionRatio, + Dictionary gasStorage) + { + NetEntity = netEntity; + Integrity = integrity; + Power = power; + Radiation = radiation; + AbsorbedMoles = absorbedMoles; + Temperature = temperature; + TemperatureLimit = temperatureLimit; + WasteMultiplier = wasteMultiplier; + AbsorptionRatio = absorptionRatio; + GasStorage = gasStorage; + } +} + +[Serializable, NetSerializable] +public sealed class SupermatterConsoleBoundInterfaceState : BoundUserInterfaceState +{ + /// + /// A list of all supermatters + /// + public SupermatterConsoleEntry[] Supermatters; + + /// + /// Data for the UI focus (if applicable) + /// + public SupermatterFocusData? FocusData; + + /// + /// Sends data from the server to the client to populate the atmos monitoring console UI + /// + public SupermatterConsoleBoundInterfaceState(SupermatterConsoleEntry[] supermatters, SupermatterFocusData? focusData) + { + Supermatters = supermatters; + FocusData = focusData; + } +} + +[Serializable, NetSerializable] +public struct SupermatterConsoleEntry +{ + /// + /// The entity in question + /// + public NetEntity NetEntity; + + /// + /// Name of the entity + /// + public string EntityName; + + /// + /// Current alert level + /// + public SupermatterStatusType EntityStatus; + + /// + /// Used to populate the supermatter console UI with data from a single supermatter + /// + public SupermatterConsoleEntry + (NetEntity entity, + string entityName, + SupermatterStatusType status) + { + NetEntity = entity; + EntityName = entityName; + EntityStatus = status; + } +} + +[Serializable, NetSerializable] +public sealed class SupermatterConsoleFocusChangeMessage : BoundUserInterfaceMessage +{ + public NetEntity? FocusSupermatter; + + /// + /// Used to inform the server that the specified focus for the atmos monitoring console has been changed by the client + /// + public SupermatterConsoleFocusChangeMessage(NetEntity? focusSupermatter) + { + FocusSupermatter = focusSupermatter; + } +} + +[NetSerializable, Serializable] +public enum SupermatterConsoleVisuals +{ + ComputerLayerScreen, +} + +/// +/// UI key associated with the supermatter monitoring console +/// +[Serializable, NetSerializable] +public enum SupermatterConsoleUiKey +{ + Key +} diff --git a/Content.Shared/_EE/Supermatter/Monitor/SupermatterStatusType.cs b/Content.Shared/_EE/Supermatter/Monitor/SupermatterStatusType.cs new file mode 100644 index 0000000000..c43bafea86 --- /dev/null +++ b/Content.Shared/_EE/Supermatter/Monitor/SupermatterStatusType.cs @@ -0,0 +1,16 @@ +using Robust.Shared.Serialization; + +namespace Content.Shared._EE.Supermatter.Monitor; + +[Serializable, NetSerializable] +public enum SupermatterStatusType : sbyte +{ + Error = -1, + Inactive = 0, + Normal = 1, + Caution = 2, + Warning = 3, + Danger = 4, + Emergency = 5, + Delaminating = 6 +} diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/1.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/1.ogg new file mode 100644 index 0000000000..78bbddad71 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/1.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/10.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/10.ogg new file mode 100644 index 0000000000..754694f4e6 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/10.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/11.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/11.ogg new file mode 100644 index 0000000000..f023e527b7 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/11.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/12.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/12.ogg new file mode 100644 index 0000000000..f04493bb57 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/12.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/13.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/13.ogg new file mode 100644 index 0000000000..dadbb8cc0d Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/13.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/14.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/14.ogg new file mode 100644 index 0000000000..27c0f71f94 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/14.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/15.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/15.ogg new file mode 100644 index 0000000000..e615f22a4a Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/15.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/16.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/16.ogg new file mode 100644 index 0000000000..1792305868 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/16.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/17.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/17.ogg new file mode 100644 index 0000000000..f414715b31 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/17.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/18.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/18.ogg new file mode 100644 index 0000000000..7a5581a2d2 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/18.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/19.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/19.ogg new file mode 100644 index 0000000000..7b75a2bfea Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/19.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/2.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/2.ogg new file mode 100644 index 0000000000..9eb1365536 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/2.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/20.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/20.ogg new file mode 100644 index 0000000000..47875c953e Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/20.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/21.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/21.ogg new file mode 100644 index 0000000000..a1a22c00a8 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/21.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/22.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/22.ogg new file mode 100644 index 0000000000..37c155b81d Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/22.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/23.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/23.ogg new file mode 100644 index 0000000000..bfd667b5ef Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/23.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/24.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/24.ogg new file mode 100644 index 0000000000..fc11c0bbbe Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/24.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/25.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/25.ogg new file mode 100644 index 0000000000..f10f38cec2 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/25.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/26.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/26.ogg new file mode 100644 index 0000000000..6df5c1858f Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/26.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/27.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/27.ogg new file mode 100644 index 0000000000..3081d86c23 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/27.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/28.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/28.ogg new file mode 100644 index 0000000000..c3a972460f Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/28.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/29.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/29.ogg new file mode 100644 index 0000000000..a9ed3f23f7 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/29.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/3.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/3.ogg new file mode 100644 index 0000000000..8f33395656 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/3.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/30.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/30.ogg new file mode 100644 index 0000000000..ee8b23adfa Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/30.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/31.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/31.ogg new file mode 100644 index 0000000000..21839f4c04 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/31.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/32.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/32.ogg new file mode 100644 index 0000000000..204e2477ca Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/32.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/33.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/33.ogg new file mode 100644 index 0000000000..2016586382 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/33.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/4.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/4.ogg new file mode 100644 index 0000000000..ad4faa058b Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/4.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/5.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/5.ogg new file mode 100644 index 0000000000..29ded5af22 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/5.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/6.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/6.ogg new file mode 100644 index 0000000000..73ecf956e7 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/6.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/7.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/7.ogg new file mode 100644 index 0000000000..4aa20b9b7a Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/7.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/8.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/8.ogg new file mode 100644 index 0000000000..f779bcaca2 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/8.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/9.ogg b/Resources/Audio/_EE/Supermatter/accent/delam/9.ogg new file mode 100644 index 0000000000..0946bb646d Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/delam/9.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/delam/attributions.yml b/Resources/Audio/_EE/Supermatter/accent/delam/attributions.yml new file mode 100644 index 0000000000..530ce714c6 --- /dev/null +++ b/Resources/Audio/_EE/Supermatter/accent/delam/attributions.yml @@ -0,0 +1,37 @@ +- files: + - 1.ogg + - 2.ogg + - 3.ogg + - 4.ogg + - 5.ogg + - 6.ogg + - 7.ogg + - 8.ogg + - 9.ogg + - 10.ogg + - 11.ogg + - 12.ogg + - 13.ogg + - 14.ogg + - 15.ogg + - 16.ogg + - 17.ogg + - 18.ogg + - 19.ogg + - 20.ogg + - 21.ogg + - 22.ogg + - 23.ogg + - 24.ogg + - 25.ogg + - 26.ogg + - 27.ogg + - 28.ogg + - 29.ogg + - 30.ogg + - 31.ogg + - 32.ogg + - 33.ogg + copyright: "Created by actioninja for tgstation13" + license: "CC-BY-SA-3.0" + source: "https://github.com/tgstation/tgstation/pull/45462" diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/1.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/1.ogg new file mode 100644 index 0000000000..9c43ffc0a0 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/1.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/10.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/10.ogg new file mode 100644 index 0000000000..16b46c1f8a Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/10.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/11.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/11.ogg new file mode 100644 index 0000000000..8a0ae2047f Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/11.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/12.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/12.ogg new file mode 100644 index 0000000000..eaf34be0a7 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/12.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/13.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/13.ogg new file mode 100644 index 0000000000..aeb8331a83 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/13.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/14.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/14.ogg new file mode 100644 index 0000000000..ff4e89f389 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/14.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/15.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/15.ogg new file mode 100644 index 0000000000..0223a370b7 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/15.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/16.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/16.ogg new file mode 100644 index 0000000000..1d63c92f4a Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/16.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/17.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/17.ogg new file mode 100644 index 0000000000..18005458d6 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/17.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/18.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/18.ogg new file mode 100644 index 0000000000..16a67cea8c Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/18.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/19.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/19.ogg new file mode 100644 index 0000000000..c1aa8f9298 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/19.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/2.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/2.ogg new file mode 100644 index 0000000000..f12185c556 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/2.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/20.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/20.ogg new file mode 100644 index 0000000000..82ea3011b6 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/20.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/21.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/21.ogg new file mode 100644 index 0000000000..1f2bd4ff92 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/21.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/22.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/22.ogg new file mode 100644 index 0000000000..2322de2669 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/22.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/23.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/23.ogg new file mode 100644 index 0000000000..c88747f39a Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/23.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/24.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/24.ogg new file mode 100644 index 0000000000..98717fc488 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/24.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/25.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/25.ogg new file mode 100644 index 0000000000..d40654fc33 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/25.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/26.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/26.ogg new file mode 100644 index 0000000000..d3fffcb79e Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/26.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/27.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/27.ogg new file mode 100644 index 0000000000..5dd6e174de Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/27.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/28.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/28.ogg new file mode 100644 index 0000000000..0daa79e059 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/28.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/29.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/29.ogg new file mode 100644 index 0000000000..b80c4984be Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/29.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/3.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/3.ogg new file mode 100644 index 0000000000..ca0acb41cd Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/3.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/30.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/30.ogg new file mode 100644 index 0000000000..9251c034da Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/30.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/31.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/31.ogg new file mode 100644 index 0000000000..6dfa40b851 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/31.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/32.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/32.ogg new file mode 100644 index 0000000000..79fb549697 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/32.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/33.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/33.ogg new file mode 100644 index 0000000000..f640750679 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/33.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/4.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/4.ogg new file mode 100644 index 0000000000..c8ebf4ddf4 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/4.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/5.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/5.ogg new file mode 100644 index 0000000000..e4f7d8b22f Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/5.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/6.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/6.ogg new file mode 100644 index 0000000000..f0453e8ab8 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/6.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/7.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/7.ogg new file mode 100644 index 0000000000..878adba8fc Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/7.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/8.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/8.ogg new file mode 100644 index 0000000000..6fedc91aff Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/8.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/accent/normal/9.ogg b/Resources/Audio/_EE/Supermatter/accent/normal/9.ogg new file mode 100644 index 0000000000..83cdfa7320 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/accent/normal/9.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/calm.ogg b/Resources/Audio/_EE/Supermatter/calm.ogg new file mode 100644 index 0000000000..dc3102e578 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/calm.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/delamming.ogg b/Resources/Audio/_EE/Supermatter/delamming.ogg new file mode 100644 index 0000000000..a48878ec42 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/delamming.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/distort.ogg b/Resources/Audio/_EE/Supermatter/distort.ogg new file mode 100644 index 0000000000..332ff801dd Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/distort.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/lightning.ogg b/Resources/Audio/_EE/Supermatter/lightning.ogg new file mode 100644 index 0000000000..3621eba423 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/lightning.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/status/bloblarm.ogg b/Resources/Audio/_EE/Supermatter/status/bloblarm.ogg new file mode 100644 index 0000000000..10050c720f Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/status/bloblarm.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/status/engine_alert1.ogg b/Resources/Audio/_EE/Supermatter/status/engine_alert1.ogg new file mode 100644 index 0000000000..bb27649bee Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/status/engine_alert1.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/status/engine_alert2.ogg b/Resources/Audio/_EE/Supermatter/status/engine_alert2.ogg new file mode 100644 index 0000000000..f5b0c924dc Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/status/engine_alert2.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/status/terminal_alert.ogg b/Resources/Audio/_EE/Supermatter/status/terminal_alert.ogg new file mode 100644 index 0000000000..85255010e4 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/status/terminal_alert.ogg differ diff --git a/Resources/Audio/_EE/Supermatter/supermatter.ogg b/Resources/Audio/_EE/Supermatter/supermatter.ogg new file mode 100644 index 0000000000..0e9abf3ad8 Binary files /dev/null and b/Resources/Audio/_EE/Supermatter/supermatter.ogg differ diff --git a/Resources/Locale/en-US/_EE/supermatter/supermatter-console.ftl b/Resources/Locale/en-US/_EE/supermatter/supermatter-console.ftl new file mode 100644 index 0000000000..fbf1d4fbfe --- /dev/null +++ b/Resources/Locale/en-US/_EE/supermatter/supermatter-console.ftl @@ -0,0 +1,44 @@ +supermatter-console-window-title = Supermatter Monitoring Console +supermatter-console-window-station-name = [color=white][font size=14]{$stationName}[/font][/color] +supermatter-console-window-unknown-location = Unknown location +supermatter-console-window-no-supermatters = [font size=16][color=white]No supermatter detected[/font] + +supermatter-console-window-label-sm = {CAPITALIZE($name)} + +supermatter-console-window-label-alert-types = Supermatter status: +supermatter-console-window-error-status = Error +supermatter-console-window-inactive-status = Inactive +supermatter-console-window-normal-status = Normal +supermatter-console-window-caution-status = Caution +supermatter-console-window-warning-status = Warning +supermatter-console-window-danger-status = Danger +supermatter-console-window-emergency-status = Emergency +supermatter-console-window-delaminating-status = Delaminating + +supermatter-console-window-label-integrity = Integrity: +supermatter-console-window-label-integrity-bar = {$integrity}% + +supermatter-console-window-label-power = Internal Energy: +supermatter-console-window-label-power-bar = {$power} {$prefix}eV + +supermatter-console-window-label-radiation = Radiation Emission: +supermatter-console-window-label-radiation-bar = {$radiation} rads + +supermatter-console-window-label-moles = Absorbed Moles: +supermatter-console-window-label-moles-bar = {$moles} Moles + +supermatter-console-window-label-temperature = Temperature: +supermatter-console-window-label-temperature-limit = Temperature Limit: +supermatter-console-window-label-temperature-bar = {$temperature} K + +supermatter-console-window-label-waste = Waste Multiplier: +supermatter-console-window-label-waste-bar = {$waste} x + +supermatter-console-window-label-absorption = Absorption Ratio: +supermatter-console-window-label-absorption-bar = {$absorption}% + +supermatter-console-window-label-gas = Unknown gas +supermatter-console-window-label-gas-bar = {$gas}% + +supermatter-console-window-flavor-left = ⚠ Do not approach the crystal +supermatter-console-window-flavor-right = v1.1 diff --git a/Resources/Locale/en-US/supermatter/supermatter.ftl b/Resources/Locale/en-US/_EE/supermatter/supermatter.ftl similarity index 70% rename from Resources/Locale/en-US/supermatter/supermatter.ftl rename to Resources/Locale/en-US/_EE/supermatter/supermatter.ftl index 2f36560a26..d5719a7e6c 100644 --- a/Resources/Locale/en-US/supermatter/supermatter.ftl +++ b/Resources/Locale/en-US/_EE/supermatter/supermatter.ftl @@ -1,6 +1,7 @@ -supermatter-announcer = Automatic Supermatter Engine supermatter-examine-integrity = - Its' integrity is [color=yellow]{$integrity}%[/color]. + Its integrity is [color=yellow]{$integrity}%[/color]. +supermatter-healing = + Crystalline hyperstructure returning to safe operating parameters. Integrity: {$integrity}%. supermatter-warning = Warning! Crystal hyperstructure integrity faltering! Integrity: {$integrity}%. supermatter-emergency = @@ -14,9 +15,16 @@ supermatter-delam-tesla = supermatter-delam-cascade = CRYSTAL DELAMINATION IMMINENT! Harmonic frequency limits exceeded, casualty destabilization field could not be engaged! supermatter-delam-cancel = - Crystalline hyperstructure returning to safe operating parameters. Failsafe has been Disengaged. Integrity: {$integrity}%. + Crystalline hyperstructure returning to safe operating parameters. Failsafe has been disengaged. Integrity: {$integrity}%. +supermatter-delam-player = + You feel reality distort for a moment... supermatter-seconds-before-delam = Estimated time before delamination: {$seconds} seconds. +supermatter-seconds-before-delam-countdown = + {$seconds} seconds remain before causality stabilization. +supermatter-seconds-before-delam-imminent = + {$seconds}... + supermatter-tamper-begin = You begin carefully cutting a piece off the supermatter crystal... supermatter-tamper-end = @@ -24,3 +32,8 @@ supermatter-tamper-end = supermatter-announcement-cc-tamper = Our automatic casualty system has detected that the supermatter crystal structural integrity was compromised by an external force. Engineering department, report to the supermatter engine immediately. + +supermatter-collide = + {CAPITALIZE(THE($target))} slams into the {$sm}! +supermatter-collide-mob = + {CAPITALIZE(THE($target))}'s body flashes into dust! diff --git a/Resources/Locale/en-US/chat/managers/chat-manager.ftl b/Resources/Locale/en-US/chat/managers/chat-manager.ftl index d8356dfa2d..6040391bca 100644 --- a/Resources/Locale/en-US/chat/managers/chat-manager.ftl +++ b/Resources/Locale/en-US/chat/managers/chat-manager.ftl @@ -170,3 +170,6 @@ chat-speech-verb-electricity-2 = buzzes chat-speech-verb-electricity-3 = screeches chat-speech-verb-marish = Mars + +chat-speech-verb-name-supermatter = Supermatter +chat-speech-verb-supermatter = states diff --git a/Resources/Prototypes/Entities/Objects/Misc/supermatter_sliver.yml b/Resources/Prototypes/Entities/Objects/Misc/supermatter_sliver.yml deleted file mode 100644 index d62935523d..0000000000 --- a/Resources/Prototypes/Entities/Objects/Misc/supermatter_sliver.yml +++ /dev/null @@ -1,25 +0,0 @@ -- type: entity - parent: BaseItem - id: SupermatterSliver - name: supermatter sliver - description: A shard from the station's Supermatter crystal. Highly radioactive. - components: - - type: PointLight - enabled: true - radius: 3 - energy: 2 - color: "#fff633" - - type: RadiationSource - intensity: .75 - - type: Icon - sprite: Supermatter/supermatter_sliver.rsi - state: icon - - type: Sprite - sprite: Supermatter/supermatter_sliver.rsi - state: icon - - type: StealTarget - stealGroup: SupermatterSliver - - type: Tag - tags: - - HighRiskItem - - type: SupermatterImmune diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/Supermatter/supermatter.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/Supermatter/supermatter.yml deleted file mode 100644 index 6fc3429600..0000000000 --- a/Resources/Prototypes/Entities/Structures/Power/Generation/Supermatter/supermatter.yml +++ /dev/null @@ -1,66 +0,0 @@ -- type: entity - id: Supermatter - name: supermatter crystal - description: A strangely translucent and iridescent crystal. - placement: - mode: SnapgridCenter - components: - - type: Supermatter - - type: RadiationSource - - type: AmbientSound - range: 5 - volume: 0 - sound: - path: /Audio/Supermatter/calm.ogg - - type: Physics - - type: Speech - speechSounds: Pai - - type: Fixtures - fixtures: - fix1: - shape: - !type:PhysShapeAabb - bounds: "-0.25,-0.25,0.25,0.25" - mask: - - Impassable - - MidImpassable - - HighImpassable - - LowImpassable - - InteractImpassable - - Opaque - layer: - - MidImpassable - - HighImpassable - - BulletImpassable - - InteractImpassable - - type: Transform - anchored: true - noRot: true - - type: CollisionWake - enabled: false - - type: Clickable - - type: InteractionOutline - - type: Sprite - drawdepth: WallMountedItems - sprite: Supermatter/supermatter.rsi - state: supermatter - - type: Icon - sprite: Supermatter/supermatter.rsi - state: supermatter - - type: PointLight - enabled: true - radius: 10 - energy: 5 - color: "#ffe000" - - type: Explosive - explosionType: Supermatter - maxIntensity: 25000 - intensitySlope: 5 - totalIntensity: 25000 - - type: GuideHelp - guides: [ Supermatter, Power ] - - type: WarpPoint - follow: true - location: supermatter - - type: SinguloFood - energy: 10000 \ No newline at end of file diff --git a/Resources/Prototypes/Objectives/stealTargetGroups.yml b/Resources/Prototypes/Objectives/stealTargetGroups.yml index 9ba05f14c3..f014194411 100644 --- a/Resources/Prototypes/Objectives/stealTargetGroups.yml +++ b/Resources/Prototypes/Objectives/stealTargetGroups.yml @@ -1,12 +1,5 @@ # Traitor single items -- type: stealTargetGroup - id: SupermatterSliver - name: supermatter sliver - sprite: - sprite: Supermatter/supermatter_sliver.rsi - state: icon - - type: stealTargetGroup id: Hypospray name: hypospray diff --git a/Resources/Prototypes/_EE/Entities/Effects/lightning.yml b/Resources/Prototypes/_EE/Entities/Effects/lightning.yml new file mode 100644 index 0000000000..dc706641d9 --- /dev/null +++ b/Resources/Prototypes/_EE/Entities/Effects/lightning.yml @@ -0,0 +1,82 @@ +- type: entity + parent: BaseLightning + id: SupermatterLightning + name: supermatter arc + categories: [ HideSpawnMenu ] + components: + - type: Sprite + sprite: /Textures/Effects/lightning.rsi + drawdepth: Effects + layers: + - state: "yellow_lightning" + shader: unshaded + - type: Electrified + requirePower: false + shockDamage: 40 + - type: PointLight + enabled: true + color: "#FFFFEC" + radius: 3.5 + softness: 1 + autoRot: true + castShadows: false + - type: Lightning + canArc: true + lightningPrototype: SupermatterLightning + - type: Beam + sound: /Audio/_EE/Supermatter/lightning.ogg + allowSpriteOverwrite: false + - type: TimedDespawn + lifetime: 1 + +- type: entity + parent: SupermatterLightning + id: SupermatterLightningCharged + name: charged supermatter arc + categories: [ HideSpawnMenu ] + components: + - type: Sprite + sprite: /Textures/Effects/lightning.rsi + drawdepth: Effects + layers: + - state: "blue_lightning" + shader: unshaded + - type: Electrified + requirePower: false + shockDamage: 60 + - type: PointLight + enabled: true + color: "#ECF2FF" + radius: 3.5 + softness: 1 + autoRot: true + castShadows: false + - type: Lightning + canArc: true + lightningPrototype: SupermatterLightningCharged + +- type: entity + parent: SupermatterLightningCharged + id: SupermatterLightningSupercharged + name: supercharged supermatter arc + categories: [ HideSpawnMenu ] + components: + - type: Sprite + sprite: /Textures/Effects/lightning.rsi + drawdepth: Effects + layers: + - state: "red_lightning" + shader: unshaded + - type: Electrified + requirePower: false + shockDamage: 80 + - type: PointLight + enabled: true + color: "#FFECED" + radius: 3.5 + softness: 1 + autoRot: true + castShadows: false + - type: Lightning + canArc: true + lightningPrototype: SupermatterLightningSupercharged diff --git a/Resources/Prototypes/_EE/Entities/Objects/Devices/Circuitboards/computer.yml b/Resources/Prototypes/_EE/Entities/Objects/Devices/Circuitboards/computer.yml new file mode 100644 index 0000000000..dcc0204745 --- /dev/null +++ b/Resources/Prototypes/_EE/Entities/Objects/Devices/Circuitboards/computer.yml @@ -0,0 +1,10 @@ +- type: entity + parent: BaseComputerCircuitboard + id: SupermatterComputerCircuitboard + name: supermatter monitoring console board + description: A computer printed circuit board for a supermatter monitoring console. + components: + - type: Sprite + state: cpu_engineering + - type: ComputerBoard + prototype: ComputerSupermatter diff --git a/Resources/Prototypes/_EE/Entities/Objects/Misc/supermatter_sliver.yml b/Resources/Prototypes/_EE/Entities/Objects/Misc/supermatter_sliver.yml new file mode 100644 index 0000000000..699e8075e1 --- /dev/null +++ b/Resources/Prototypes/_EE/Entities/Objects/Misc/supermatter_sliver.yml @@ -0,0 +1,25 @@ +- type: entity + parent: BaseItem + id: SupermatterSliver + name: supermatter sliver + description: A shard from the station's Supermatter crystal. Highly radioactive. + components: + - type: PointLight + enabled: true + radius: 3 + energy: 2 + color: "#fff633" + - type: RadiationSource + intensity: .75 + - type: Icon + sprite: _EE/Structures/Power/Generation/Supermatter/supermatter_sliver.rsi + state: icon + - type: Sprite + sprite: _EE/Structures/Power/Generation/Supermatter/supermatter_sliver.rsi + state: icon + - type: StealTarget + stealGroup: SupermatterSliver + - type: Tag + tags: + - HighRiskItem + - type: SupermatterImmune diff --git a/Resources/Prototypes/_EE/Entities/Structures/Machines/Computers/computers.yml b/Resources/Prototypes/_EE/Entities/Structures/Machines/Computers/computers.yml new file mode 100644 index 0000000000..d0e152389e --- /dev/null +++ b/Resources/Prototypes/_EE/Entities/Structures/Machines/Computers/computers.yml @@ -0,0 +1,57 @@ +- type: entity + parent: BaseComputerAiAccess + id: ComputerSupermatter + name: supermatter monitoring console + description: Used to monitor the status of supermatter crystals. + components: + - type: Computer + board: SupermatterComputerCircuitboard + - type: Sprite + sprite: _EE/Structures/Machines/computers.rsi + layers: + - map: ["computerLayerBody"] + state: computer + - map: ["computerLayerKeyboard"] + state: generic_keyboard + - map: ["computerLayerScreen"] + state: supermatter-0 + - map: ["computerLayerKeys"] + state: supermatter_keys + - map: [ "enum.WiresVisualLayers.MaintenancePanel" ] + state: generic_panel_open + - type: PointLight + radius: 1.5 + energy: 1.6 + color: "#0f704b" + - type: GenericVisualizer + visuals: + enum.ComputerVisuals.Powered: + computerLayerScreen: + True: { visible: true, shader: unshaded } + False: { visible: false } + computerLayerKeys: + True: { visible: true, shader: unshaded } + False: { visible: true, shader: shaded } + enum.SupermatterConsoleVisuals.ComputerLayerScreen: + computerLayerScreen: + 0: { state: supermatter-0 } + 1: { state: supermatter-1 } + 2: { state: supermatter-2 } + 3: { state: supermatter-3 } + 4: { state: supermatter-4 } + 5: { state: supermatter-5 } + 6: { state: supermatter-6 } + enum.WiresVisuals.MaintenancePanelState: + enum.WiresVisualLayers.MaintenancePanel: + True: { visible: false } + False: { visible: true } + - type: SupermatterConsole + - type: ActivatableUI + singleUser: true + key: enum.SupermatterConsoleUiKey.Key + - type: UserInterface + interfaces: + enum.SupermatterConsoleUiKey.Key: + type: SupermatterConsoleBoundUserInterface + enum.WiresUiKey.Key: + type: WiresBoundUserInterface diff --git a/Resources/Prototypes/_EE/Entities/Structures/Power/Generation/Supermatter/supermatter.yml b/Resources/Prototypes/_EE/Entities/Structures/Power/Generation/Supermatter/supermatter.yml new file mode 100644 index 0000000000..e5610b652d --- /dev/null +++ b/Resources/Prototypes/_EE/Entities/Structures/Power/Generation/Supermatter/supermatter.yml @@ -0,0 +1,79 @@ +- type: entity + id: Supermatter + name: supermatter crystal + description: A strangely translucent and iridescent crystal. + placement: + mode: SnapgridCenter + components: + - type: Supermatter + - type: AtmosDevice + - type: RadiationSource + - type: AmbientSound + range: 20 + volume: -5 + sound: + path: /Audio/_EE/Supermatter/calm.ogg + - type: EmitSoundOnTrigger + sound: + collection: SupermatterAccentNormal + - type: Physics + - type: Speech + speechSounds: null + speechVerb: Supermatter + suffixSpeechVerbs: + chat-speech-verb-suffix-exclamation-strong: Supermatter + chat-speech-verb-suffix-exclamation: Supermatter + chat-speech-verb-suffix-question: Supermatter + chat-speech-verb-suffix-stutter: Supermatter + chat-speech-verb-suffix-mumble: Supermatter + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.25,-0.25,0.25,0.4" + mask: + - Impassable + - MidImpassable + - HighImpassable + - LowImpassable + - InteractImpassable + - Opaque + layer: + - MidImpassable + - HighImpassable + - BulletImpassable + - InteractImpassable + - type: Transform + anchored: true + noRot: true + - type: CollisionWake + enabled: false + - type: Clickable + - type: InteractionOutline + - type: Sprite + sprite: _EE/Structures/Power/Generation/Supermatter/supermatter.rsi + state: supermatter + drawdepth: Mobs + snapCardinals: true + offset: -0.015,0.295 + - type: Icon + sprite: _EE/Structures/Power/Generation/Supermatter/supermatter.rsi + state: supermatter + - type: PointLight + enabled: true + radius: 10 + energy: 5 + color: "#ffe000" + - type: Explosive + explosionType: Supermatter + totalIntensity: 120000 + intensitySlope: 5 + maxIntensity: 100 + - type: GuideHelp + guides: [ Supermatter, Power ] + - type: WarpPoint + follow: true + location: supermatter + - type: SinguloFood + energy: 10000 diff --git a/Resources/Prototypes/_EE/Objectives/stealTargetGroups.yml b/Resources/Prototypes/_EE/Objectives/stealTargetGroups.yml new file mode 100644 index 0000000000..f10fcee964 --- /dev/null +++ b/Resources/Prototypes/_EE/Objectives/stealTargetGroups.yml @@ -0,0 +1,6 @@ +- type: stealTargetGroup + id: SupermatterSliver + name: steal-target-supermatter-sliver + sprite: + sprite: _EE/Structures/Power/Generation/Supermatter/supermatter_sliver.rsi + state: icon diff --git a/Resources/Prototypes/_EE/Objectives/traitor.yml b/Resources/Prototypes/_EE/Objectives/traitor.yml new file mode 100644 index 0000000000..1e37e996c3 --- /dev/null +++ b/Resources/Prototypes/_EE/Objectives/traitor.yml @@ -0,0 +1,11 @@ +# imp - disabled supermatter steal objectives +#- type: entity +# parent: BaseTraitorStealObjective +# id: StealSupermatterSliverObjective +# components: +# - type: Objective +# difficulty: 3.5 +# - type: StealCondition +# stealGroup: SupermatterSliver +# objectiveNoOwnerText: objective-condition-steal-smsliver-title +# descriptionText: objective-condition-steal-smsliver-description diff --git a/Resources/Prototypes/_EE/SoundCollections/supermatter.yml b/Resources/Prototypes/_EE/SoundCollections/supermatter.yml new file mode 100644 index 0000000000..1653dbf18c --- /dev/null +++ b/Resources/Prototypes/_EE/SoundCollections/supermatter.yml @@ -0,0 +1,73 @@ +- type: soundCollection + id: SupermatterAccentNormal + files: + - /Audio/_EE/Supermatter/accent/normal/1.ogg + - /Audio/_EE/Supermatter/accent/normal/2.ogg + - /Audio/_EE/Supermatter/accent/normal/3.ogg + - /Audio/_EE/Supermatter/accent/normal/4.ogg + - /Audio/_EE/Supermatter/accent/normal/5.ogg + - /Audio/_EE/Supermatter/accent/normal/6.ogg + - /Audio/_EE/Supermatter/accent/normal/7.ogg + - /Audio/_EE/Supermatter/accent/normal/8.ogg + - /Audio/_EE/Supermatter/accent/normal/9.ogg + - /Audio/_EE/Supermatter/accent/normal/10.ogg + - /Audio/_EE/Supermatter/accent/normal/11.ogg + - /Audio/_EE/Supermatter/accent/normal/12.ogg + - /Audio/_EE/Supermatter/accent/normal/13.ogg + - /Audio/_EE/Supermatter/accent/normal/14.ogg + - /Audio/_EE/Supermatter/accent/normal/15.ogg + - /Audio/_EE/Supermatter/accent/normal/16.ogg + - /Audio/_EE/Supermatter/accent/normal/17.ogg + - /Audio/_EE/Supermatter/accent/normal/18.ogg + - /Audio/_EE/Supermatter/accent/normal/19.ogg + - /Audio/_EE/Supermatter/accent/normal/20.ogg + - /Audio/_EE/Supermatter/accent/normal/21.ogg + - /Audio/_EE/Supermatter/accent/normal/22.ogg + - /Audio/_EE/Supermatter/accent/normal/23.ogg + - /Audio/_EE/Supermatter/accent/normal/24.ogg + - /Audio/_EE/Supermatter/accent/normal/25.ogg + - /Audio/_EE/Supermatter/accent/normal/26.ogg + - /Audio/_EE/Supermatter/accent/normal/27.ogg + - /Audio/_EE/Supermatter/accent/normal/28.ogg + - /Audio/_EE/Supermatter/accent/normal/29.ogg + - /Audio/_EE/Supermatter/accent/normal/30.ogg + - /Audio/_EE/Supermatter/accent/normal/31.ogg + - /Audio/_EE/Supermatter/accent/normal/32.ogg + - /Audio/_EE/Supermatter/accent/normal/33.ogg + +- type: soundCollection + id: SupermatterAccentDelam + files: + - /Audio/_EE/Supermatter/accent/delam/1.ogg + - /Audio/_EE/Supermatter/accent/delam/2.ogg + - /Audio/_EE/Supermatter/accent/delam/3.ogg + - /Audio/_EE/Supermatter/accent/delam/4.ogg + - /Audio/_EE/Supermatter/accent/delam/5.ogg + - /Audio/_EE/Supermatter/accent/delam/6.ogg + - /Audio/_EE/Supermatter/accent/delam/7.ogg + - /Audio/_EE/Supermatter/accent/delam/8.ogg + - /Audio/_EE/Supermatter/accent/delam/9.ogg + - /Audio/_EE/Supermatter/accent/delam/10.ogg + - /Audio/_EE/Supermatter/accent/delam/11.ogg + - /Audio/_EE/Supermatter/accent/delam/12.ogg + - /Audio/_EE/Supermatter/accent/delam/13.ogg + - /Audio/_EE/Supermatter/accent/delam/14.ogg + - /Audio/_EE/Supermatter/accent/delam/15.ogg + - /Audio/_EE/Supermatter/accent/delam/16.ogg + - /Audio/_EE/Supermatter/accent/delam/17.ogg + - /Audio/_EE/Supermatter/accent/delam/18.ogg + - /Audio/_EE/Supermatter/accent/delam/19.ogg + - /Audio/_EE/Supermatter/accent/delam/20.ogg + - /Audio/_EE/Supermatter/accent/delam/21.ogg + - /Audio/_EE/Supermatter/accent/delam/22.ogg + - /Audio/_EE/Supermatter/accent/delam/23.ogg + - /Audio/_EE/Supermatter/accent/delam/24.ogg + - /Audio/_EE/Supermatter/accent/delam/25.ogg + - /Audio/_EE/Supermatter/accent/delam/26.ogg + - /Audio/_EE/Supermatter/accent/delam/27.ogg + - /Audio/_EE/Supermatter/accent/delam/28.ogg + - /Audio/_EE/Supermatter/accent/delam/29.ogg + - /Audio/_EE/Supermatter/accent/delam/30.ogg + - /Audio/_EE/Supermatter/accent/delam/31.ogg + - /Audio/_EE/Supermatter/accent/delam/32.ogg + - /Audio/_EE/Supermatter/accent/delam/33.ogg diff --git a/Resources/Prototypes/_EE/Voice/speech_sounds.yml b/Resources/Prototypes/_EE/Voice/speech_sounds.yml new file mode 100644 index 0000000000..cbd12f3687 --- /dev/null +++ b/Resources/Prototypes/_EE/Voice/speech_sounds.yml @@ -0,0 +1,39 @@ +- type: speechSounds + id: SupermatterWarning + variation: 0 + saySound: + path: /Audio/_EE/Supermatter/status/terminal_alert.ogg + askSound: + path: /Audio/_EE/Supermatter/status/terminal_alert.ogg + exclaimSound: + path: /Audio/_EE/Supermatter/status/terminal_alert.ogg + +- type: speechSounds + id: SupermatterDanger + variation: 0 + saySound: + path: /Audio/_EE/Supermatter/status/engine_alert2.ogg + askSound: + path: /Audio/_EE/Supermatter/status/engine_alert2.ogg + exclaimSound: + path: /Audio/_EE/Supermatter/status/engine_alert2.ogg + +- type: speechSounds + id: SupermatterEmergency + variation: 0 + saySound: + path: /Audio/_EE/Supermatter/status/engine_alert1.ogg + askSound: + path: /Audio/_EE/Supermatter/status/engine_alert1.ogg + exclaimSound: + path: /Audio/_EE/Supermatter/status/engine_alert1.ogg + +- type: speechSounds + id: SupermatterDelaminating + variation: 0 + saySound: + path: /Audio/_EE/Supermatter/status/bloblarm.ogg + askSound: + path: /Audio/_EE/Supermatter/status/bloblarm.ogg + exclaimSound: + path: /Audio/_EE/Supermatter/status/bloblarm.ogg diff --git a/Resources/Prototypes/_EE/Voice/speech_verbs.yml b/Resources/Prototypes/_EE/Voice/speech_verbs.yml new file mode 100644 index 0000000000..72373bd99f --- /dev/null +++ b/Resources/Prototypes/_EE/Voice/speech_verbs.yml @@ -0,0 +1,5 @@ +- type: speechVerb + id: Supermatter + name: chat-speech-verb-name-supermatter + speechVerbStrings: + - chat-speech-verb-supermatter diff --git a/Resources/Prototypes/_EE/explosion.yml b/Resources/Prototypes/_EE/explosion.yml new file mode 100644 index 0000000000..2601eb1092 --- /dev/null +++ b/Resources/Prototypes/_EE/explosion.yml @@ -0,0 +1,15 @@ +- type: explosion + id: Supermatter + damagePerIntensity: + types: + Radiation: 5 + Heat: 4 + Blunt: 3 + Piercing: 3 + tileBreakChance: [0, 0.5, 1] + tileBreakIntensity: [0, 10, 30] + tileBreakRerollReduction: 20 + lightColor: Yellow + fireColor: Green + texturePath: /Textures/Effects/fire_greyscale.rsi + fireStates: 3 diff --git a/Resources/Prototypes/explosion.yml b/Resources/Prototypes/explosion.yml index 492b752591..4f72067376 100644 --- a/Resources/Prototypes/explosion.yml +++ b/Resources/Prototypes/explosion.yml @@ -118,22 +118,6 @@ texturePath: /Textures/Effects/fire.rsi fireStates: 6 -- type: explosion - id: Supermatter - damagePerIntensity: - types: - Radiation: 5 - Heat: 4 - Blunt: 3 - Piercing: 3 - tileBreakChance: [0, 0.5, 1] - tileBreakIntensity: [0, 10, 30] - tileBreakRerollReduction: 20 - lightColor: Yellow - fireColor: Green - texturePath: /Textures/Effects/fire_greyscale.rsi - fireStates: 3 - - type: explosion id: FireBomb damagePerIntensity: diff --git a/Resources/Textures/Supermatter/supermatter.rsi/supermatter.png b/Resources/Textures/Supermatter/supermatter.rsi/supermatter.png deleted file mode 100644 index 0c5747a315..0000000000 Binary files a/Resources/Textures/Supermatter/supermatter.rsi/supermatter.png and /dev/null differ diff --git a/Resources/Textures/_EE/Interface/Supermatter/supermatter.png b/Resources/Textures/_EE/Interface/Supermatter/supermatter.png new file mode 100644 index 0000000000..e6abc87717 Binary files /dev/null and b/Resources/Textures/_EE/Interface/Supermatter/supermatter.png differ diff --git a/Resources/Textures/_EE/Structures/Machines/computers.rsi/computer.png b/Resources/Textures/_EE/Structures/Machines/computers.rsi/computer.png new file mode 100644 index 0000000000..c608b2bb4d Binary files /dev/null and b/Resources/Textures/_EE/Structures/Machines/computers.rsi/computer.png differ diff --git a/Resources/Textures/_EE/Structures/Machines/computers.rsi/generic_keyboard.png b/Resources/Textures/_EE/Structures/Machines/computers.rsi/generic_keyboard.png new file mode 100644 index 0000000000..24428eb4e3 Binary files /dev/null and b/Resources/Textures/_EE/Structures/Machines/computers.rsi/generic_keyboard.png differ diff --git a/Resources/Textures/_EE/Structures/Machines/computers.rsi/generic_panel_open.png b/Resources/Textures/_EE/Structures/Machines/computers.rsi/generic_panel_open.png new file mode 100644 index 0000000000..ac7f9f6641 Binary files /dev/null and b/Resources/Textures/_EE/Structures/Machines/computers.rsi/generic_panel_open.png differ diff --git a/Resources/Textures/_EE/Structures/Machines/computers.rsi/meta.json b/Resources/Textures/_EE/Structures/Machines/computers.rsi/meta.json new file mode 100644 index 0000000000..651e5dbcea --- /dev/null +++ b/Resources/Textures/_EE/Structures/Machines/computers.rsi/meta.json @@ -0,0 +1,73 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Generic sprites taken from tgstation at commit https://github.com/tgstation/tgstation/commit/bd6873fd4dd6a61d7e46f1d75cd4d90f64c40894. generic_panel_open made by Errant, commit https://github.com/space-wizards/space-station-14/pull/32273. Supermatter computer sprites by AftrLite(Github).", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "computer", + "directions": 4 + }, + { + "name": "generic_keyboard", + "directions": 4 + }, + { + "name": "generic_panel_open", + "directions": 4 + }, + { + "name": "supermatter_keys", + "directions": 4 + }, + { + "name": "supermatter-0", + "directions": 4 + }, + { + "name": "supermatter-1", + "directions": 4 + }, + { + "name": "supermatter-2", + "directions": 4 + }, + { + "name": "supermatter-3", + "directions": 4 + }, + { + "name": "supermatter-4", + "directions": 4 + }, + { + "name": "supermatter-5", + "directions": 4 + }, + { + "name": "supermatter-6", + "directions": 4, + "delays": [ + [ + 0.1, + 0.1 + ], + [ + 0.1, + 0.1 + ], + [ + 0.1, + 0.1 + ], + [ + 0.1, + 0.1 + ] + ] + } + ] +} diff --git a/Resources/Textures/_EE/Structures/Machines/computers.rsi/supermatter-0.png b/Resources/Textures/_EE/Structures/Machines/computers.rsi/supermatter-0.png new file mode 100644 index 0000000000..d8301a4023 Binary files /dev/null and b/Resources/Textures/_EE/Structures/Machines/computers.rsi/supermatter-0.png differ diff --git a/Resources/Textures/_EE/Structures/Machines/computers.rsi/supermatter-1.png b/Resources/Textures/_EE/Structures/Machines/computers.rsi/supermatter-1.png new file mode 100644 index 0000000000..b74452db52 Binary files /dev/null and b/Resources/Textures/_EE/Structures/Machines/computers.rsi/supermatter-1.png differ diff --git a/Resources/Textures/_EE/Structures/Machines/computers.rsi/supermatter-2.png b/Resources/Textures/_EE/Structures/Machines/computers.rsi/supermatter-2.png new file mode 100644 index 0000000000..8096e8fc4a Binary files /dev/null and b/Resources/Textures/_EE/Structures/Machines/computers.rsi/supermatter-2.png differ diff --git a/Resources/Textures/_EE/Structures/Machines/computers.rsi/supermatter-3.png b/Resources/Textures/_EE/Structures/Machines/computers.rsi/supermatter-3.png new file mode 100644 index 0000000000..fac6045054 Binary files /dev/null and b/Resources/Textures/_EE/Structures/Machines/computers.rsi/supermatter-3.png differ diff --git a/Resources/Textures/_EE/Structures/Machines/computers.rsi/supermatter-4.png b/Resources/Textures/_EE/Structures/Machines/computers.rsi/supermatter-4.png new file mode 100644 index 0000000000..4da4dc822c Binary files /dev/null and b/Resources/Textures/_EE/Structures/Machines/computers.rsi/supermatter-4.png differ diff --git a/Resources/Textures/_EE/Structures/Machines/computers.rsi/supermatter-5.png b/Resources/Textures/_EE/Structures/Machines/computers.rsi/supermatter-5.png new file mode 100644 index 0000000000..21a0631e77 Binary files /dev/null and b/Resources/Textures/_EE/Structures/Machines/computers.rsi/supermatter-5.png differ diff --git a/Resources/Textures/_EE/Structures/Machines/computers.rsi/supermatter-6.png b/Resources/Textures/_EE/Structures/Machines/computers.rsi/supermatter-6.png new file mode 100644 index 0000000000..15d55084a8 Binary files /dev/null and b/Resources/Textures/_EE/Structures/Machines/computers.rsi/supermatter-6.png differ diff --git a/Resources/Textures/_EE/Structures/Machines/computers.rsi/supermatter_keys.png b/Resources/Textures/_EE/Structures/Machines/computers.rsi/supermatter_keys.png new file mode 100644 index 0000000000..3fec5a800b Binary files /dev/null and b/Resources/Textures/_EE/Structures/Machines/computers.rsi/supermatter_keys.png differ diff --git a/Resources/Textures/Supermatter/supermatter.rsi/meta.json b/Resources/Textures/_EE/Structures/Power/Generation/Supermatter/supermatter.rsi/meta.json similarity index 64% rename from Resources/Textures/Supermatter/supermatter.rsi/meta.json rename to Resources/Textures/_EE/Structures/Power/Generation/Supermatter/supermatter.rsi/meta.json index 6bca0558a8..e174bdfe04 100644 --- a/Resources/Textures/Supermatter/supermatter.rsi/meta.json +++ b/Resources/Textures/_EE/Structures/Power/Generation/Supermatter/supermatter.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, - "copyright": "Taken and edited from https://tgstation13.org/wiki/images/a/a4/Supermatter-bg.gif", "license": "CC-BY-SA-3.0", + "copyright": "Taken and edited from https://tgstation13.org/wiki/images/a/a4/Supermatter-bg.gif", "size": { "x": 32, "y": 48 @@ -9,7 +9,13 @@ "states": [ { "name": "supermatter", - "delays": [ [ 0.08, 0.08, 0.08 ] ] + "delays": [ + [ + 0.08, + 0.08, + 0.08 + ] + ] } ] -} \ No newline at end of file +} diff --git a/Resources/Textures/_EE/Structures/Power/Generation/Supermatter/supermatter.rsi/supermatter.png b/Resources/Textures/_EE/Structures/Power/Generation/Supermatter/supermatter.rsi/supermatter.png new file mode 100644 index 0000000000..9239d348c2 Binary files /dev/null and b/Resources/Textures/_EE/Structures/Power/Generation/Supermatter/supermatter.rsi/supermatter.png differ diff --git a/Resources/Textures/Supermatter/supermatter_sliver.rsi/icon.png b/Resources/Textures/_EE/Structures/Power/Generation/Supermatter/supermatter_sliver.rsi/icon.png similarity index 100% rename from Resources/Textures/Supermatter/supermatter_sliver.rsi/icon.png rename to Resources/Textures/_EE/Structures/Power/Generation/Supermatter/supermatter_sliver.rsi/icon.png diff --git a/Resources/Textures/Supermatter/supermatter_sliver.rsi/meta.json b/Resources/Textures/_EE/Structures/Power/Generation/Supermatter/supermatter_sliver.rsi/meta.json similarity index 99% rename from Resources/Textures/Supermatter/supermatter_sliver.rsi/meta.json rename to Resources/Textures/_EE/Structures/Power/Generation/Supermatter/supermatter_sliver.rsi/meta.json index f157223291..68f10cb838 100644 --- a/Resources/Textures/Supermatter/supermatter_sliver.rsi/meta.json +++ b/Resources/Textures/_EE/Structures/Power/Generation/Supermatter/supermatter_sliver.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, - "copyright": "Taken and edited from https://github.com/tgstation/tgstation/blob/master/icons/obj/antags/syndicate_tools.dmi", "license": "CC-BY-SA-3.0", + "copyright": "Taken and edited from https://github.com/tgstation/tgstation/blob/master/icons/obj/antags/syndicate_tools.dmi", "size": { "x": 32, "y": 32 @@ -11,4 +11,4 @@ "name": "icon" } ] -} \ No newline at end of file +}