diff --git a/.github/workflows/conflict-labeler.yml b/.github/workflows/conflict-labeler.yml
index fd832b9231..0bf32de8eb 100644
--- a/.github/workflows/conflict-labeler.yml
+++ b/.github/workflows/conflict-labeler.yml
@@ -9,6 +9,7 @@ on:
jobs:
Label:
runs-on: ubuntu-latest
+ if: github.event.pull_request.draft == false
steps:
- name: Check for Merge Conflicts
uses: eps1lon/actions-label-merge-conflict@513a24fc7dca40990863be2935e059e650728400
diff --git a/Content.Client/EscapeMenu/UI/EscapeMenu.xaml b/Content.Client/EscapeMenu/UI/EscapeMenu.xaml
index a9cca0bc30..3095d07a71 100644
--- a/Content.Client/EscapeMenu/UI/EscapeMenu.xaml
+++ b/Content.Client/EscapeMenu/UI/EscapeMenu.xaml
@@ -9,6 +9,7 @@
+
diff --git a/Content.Client/EscapeMenu/UI/EscapeMenu.xaml.cs b/Content.Client/EscapeMenu/UI/EscapeMenu.xaml.cs
index 3b81685ab9..c9efcd6e72 100644
--- a/Content.Client/EscapeMenu/UI/EscapeMenu.xaml.cs
+++ b/Content.Client/EscapeMenu/UI/EscapeMenu.xaml.cs
@@ -5,6 +5,8 @@ using Robust.Client.Console;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
+using Robust.Client.UserInterface;
+using Content.Client.Links;
using Robust.Shared.GameObjects;
namespace Content.Client.EscapeMenu.UI
@@ -28,6 +30,7 @@ namespace Content.Client.EscapeMenu.UI
QuitButton.OnPressed += OnQuitButtonClicked;
RulesButton.OnPressed += _ => new RulesAndInfoWindow().Open();
DisconnectButton.OnPressed += OnDisconnectButtonClicked;
+ WikiButton.OnPressed += OnWikiButtonClicked;
}
private void OnQuitButtonClicked(BaseButton.ButtonEventArgs args)
@@ -47,6 +50,12 @@ namespace Content.Client.EscapeMenu.UI
_optionsMenu.OpenCentered();
}
+ private void OnWikiButtonClicked(BaseButton.ButtonEventArgs args)
+ {
+ var uriOpener = IoCManager.Resolve();
+ uriOpener.OpenUri(UILinks.Wiki);
+ }
+
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
diff --git a/Content.Client/Ghost/Roles/UI/GhostRoleRulesWindow.xaml.cs b/Content.Client/Ghost/Roles/UI/GhostRoleRulesWindow.xaml.cs
index 915eb72db6..cd11f03b93 100644
--- a/Content.Client/Ghost/Roles/UI/GhostRoleRulesWindow.xaml.cs
+++ b/Content.Client/Ghost/Roles/UI/GhostRoleRulesWindow.xaml.cs
@@ -1,26 +1,38 @@
-using System;
-using Content.Shared.Ghost.Roles;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
-using Robust.Shared.Localization;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
+using Content.Shared.CCVar;
+using Robust.Shared.Configuration;
+
namespace Content.Client.Ghost.Roles.UI
{
[GenerateTypedNameReferences]
public sealed partial class GhostRoleRulesWindow : DefaultWindow
{
- private float _timer = 5.0f;
+ [Dependency] private readonly IConfigurationManager _cfg = IoCManager.Resolve();
+ private float _timer;
+
public GhostRoleRulesWindow(string rules, Action requestAction)
{
RobustXamlLoader.Load(this);
- TopBanner.SetMessage(FormattedMessage.FromMarkupPermissive(rules + "\n" + Loc.GetString("ghost-roles-window-rules-footer")));
+ var ghostRoleTime = _cfg.GetCVar(CCVars.GhostRoleTime);
+ _timer = ghostRoleTime;
+
+ if (ghostRoleTime > 0f)
+ {
+ RequestButton.Text = Loc.GetString("ghost-roles-window-request-role-button-timer", ("time", $"{_timer:0.0}"));
+ TopBanner.SetMessage(FormattedMessage.FromMarkupPermissive(rules + "\n" + Loc.GetString("ghost-roles-window-rules-footer", ("time", ghostRoleTime))));
+ RequestButton.Disabled = true;
+ }
+
RequestButton.OnPressed += requestAction;
}
+
protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);
@@ -28,10 +40,12 @@ namespace Content.Client.Ghost.Roles.UI
if (_timer > 0.0)
{
_timer -= args.DeltaSeconds;
+ RequestButton.Text = Loc.GetString("ghost-roles-window-request-role-button-timer", ("time", $"{_timer:0.0}"));
}
else
{
RequestButton.Disabled = false;
+ RequestButton.Text = Loc.GetString("ghost-roles-window-request-role-button");
}
}
}
diff --git a/Content.Client/MobState/DamageStateVisualizer.cs b/Content.Client/MobState/DamageStateVisualizer.cs
deleted file mode 100644
index db672bb857..0000000000
--- a/Content.Client/MobState/DamageStateVisualizer.cs
+++ /dev/null
@@ -1,109 +0,0 @@
-using System.Collections.Generic;
-using Content.Shared.MobState;
-using JetBrains.Annotations;
-using Robust.Client.GameObjects;
-using Robust.Shared.GameObjects;
-using Robust.Shared.IoC;
-using Robust.Shared.Serialization;
-using Robust.Shared.Serialization.Manager.Attributes;
-using DrawDepth = Content.Shared.DrawDepth.DrawDepth;
-
-namespace Content.Client.MobState
-{
- [UsedImplicitly]
- public sealed class DamageStateVisualizer : AppearanceVisualizer, ISerializationHooks
- {
- private DamageState _data = DamageState.Alive;
- private Dictionary _stateMap = new();
- private int? _originalDrawDepth;
-
- [DataField("normal")]
- private string? _normal;
-
- [DataField("crit")]
- private string? _crit;
-
- [DataField("dead")]
- private string? _dead;
-
- ///
- /// Should noRot be turned off when crit / dead.
- ///
- [DataField("rotate")]
- private bool _rotate;
-
- void ISerializationHooks.BeforeSerialization()
- {
- _stateMap.TryGetValue(DamageState.Alive, out _normal);
- _stateMap.TryGetValue(DamageState.Critical, out _crit);
- _stateMap.TryGetValue(DamageState.Dead, out _dead);
- }
-
- void ISerializationHooks.AfterDeserialization()
- {
- if (_normal != null)
- {
- _stateMap.Add(DamageState.Alive, _normal);
- }
-
- if (_crit != null)
- {
- _stateMap.Add(DamageState.Critical, _crit);
- }
-
- if (_dead != null)
- {
- _stateMap.Add(DamageState.Dead, _dead);
- }
- }
-
- public override void OnChangeData(AppearanceComponent component)
- {
- base.OnChangeData(component);
- var sprite = IoCManager.Resolve().GetComponent(component.Owner);
- if (!component.TryGetData(DamageStateVisuals.State, out DamageState data))
- {
- return;
- }
-
- if (_data == data)
- {
- return;
- }
-
- _data = data;
-
- if (_rotate)
- {
- sprite.NoRotation = data switch
- {
- DamageState.Critical => false,
- DamageState.Dead => false,
- _ => true
- };
- }
-
- if (_stateMap.TryGetValue(_data, out var state))
- {
- sprite.LayerSetState(DamageStateVisualLayers.Base, state);
- }
-
- // So they don't draw over mobs anymore
- if (_data == DamageState.Dead && sprite.DrawDepth > (int) DrawDepth.Items)
- {
- _originalDrawDepth = sprite.DrawDepth;
- sprite.DrawDepth = (int) DrawDepth.Items;
- }
- else if (_originalDrawDepth != null)
- {
- sprite.DrawDepth = _originalDrawDepth.Value;
- _originalDrawDepth = null;
- }
- }
- }
-
- public enum DamageStateVisualLayers : byte
- {
- Base
- }
-}
diff --git a/Content.Client/MobState/DamageStateVisualizerSystem.cs b/Content.Client/MobState/DamageStateVisualizerSystem.cs
new file mode 100644
index 0000000000..dadcdaf3d1
--- /dev/null
+++ b/Content.Client/MobState/DamageStateVisualizerSystem.cs
@@ -0,0 +1,62 @@
+using Content.Shared.MobState;
+using Robust.Client.GameObjects;
+using DrawDepth = Content.Shared.DrawDepth.DrawDepth;
+
+namespace Content.Client.MobState;
+
+public sealed class DamageStateVisualizerSystem : VisualizerSystem
+{
+ protected override void OnAppearanceChange(EntityUid uid, DamageStateVisualsComponent component, ref AppearanceChangeEvent args)
+ {
+ var sprite = args.Sprite;
+
+ if (sprite == null || !args.Component.TryGetData(DamageStateVisuals.State, out DamageState data))
+ {
+ return;
+ }
+
+ if (!component.States.TryGetValue(data, out var layers))
+ {
+ return;
+ }
+
+ if (component.Rotate)
+ {
+ sprite.NoRotation = data switch
+ {
+ DamageState.Critical => false,
+ DamageState.Dead => false,
+ _ => true
+ };
+ }
+
+ // Brain no worky rn so this was just easier.
+ foreach (var key in new []{ DamageStateVisualLayers.Base, DamageStateVisualLayers.BaseUnshaded })
+ {
+ if (!sprite.LayerMapTryGet(key, out _)) continue;
+
+ sprite.LayerSetVisible(key, false);
+ }
+
+ foreach (var (key, state) in layers)
+ {
+ // Inheritance moment.
+ if (!sprite.LayerMapTryGet(key, out _)) continue;
+
+ sprite.LayerSetVisible(key, true);
+ sprite.LayerSetState(key, state);
+ }
+
+ // So they don't draw over mobs anymore
+ if (data == DamageState.Dead && sprite.DrawDepth > (int) DrawDepth.Items)
+ {
+ component.OriginalDrawDepth = sprite.DrawDepth;
+ sprite.DrawDepth = (int) DrawDepth.Items;
+ }
+ else if (component.OriginalDrawDepth != null)
+ {
+ sprite.DrawDepth = component.OriginalDrawDepth.Value;
+ component. OriginalDrawDepth = null;
+ }
+ }
+}
diff --git a/Content.Client/MobState/DamageStateVisualsComponent.cs b/Content.Client/MobState/DamageStateVisualsComponent.cs
new file mode 100644
index 0000000000..80ffdbb2c5
--- /dev/null
+++ b/Content.Client/MobState/DamageStateVisualsComponent.cs
@@ -0,0 +1,22 @@
+using Content.Shared.MobState;
+
+namespace Content.Client.MobState;
+
+[RegisterComponent]
+public sealed class DamageStateVisualsComponent : Component
+{
+ public int? OriginalDrawDepth;
+
+ [DataField("states")] public Dictionary> States = new();
+
+ ///
+ /// Should noRot be turned off when crit / dead.
+ ///
+ [DataField("rotate")] public bool Rotate;
+}
+
+public enum DamageStateVisualLayers : byte
+{
+ Base,
+ BaseUnshaded,
+}
diff --git a/Content.Client/PowerCell/PowerCellSystem.cs b/Content.Client/PowerCell/PowerCellSystem.cs
index 9d9ea40303..9776429eb2 100644
--- a/Content.Client/PowerCell/PowerCellSystem.cs
+++ b/Content.Client/PowerCell/PowerCellSystem.cs
@@ -1,7 +1,38 @@
using Content.Shared.PowerCell;
using JetBrains.Annotations;
+using Robust.Client.GameObjects;
namespace Content.Client.PowerCell;
[UsedImplicitly]
-public sealed class PowerCellSystem : SharedPowerCellSystem { }
+public sealed class PowerCellSystem : SharedPowerCellSystem
+{
+ public override void Initialize()
+ {
+ base.Initialize();
+ SubscribeLocalEvent(OnPowerCellVisualsChange);
+ }
+
+ private void OnPowerCellVisualsChange(EntityUid uid, PowerCellVisualsComponent component, ref AppearanceChangeEvent args)
+ {
+ if (args.Sprite == null) return;
+
+ if (args.Component.TryGetData(PowerCellVisuals.ChargeLevel, out byte level))
+ {
+ if (level == 0)
+ {
+ args.Sprite.LayerSetVisible(PowerCellVisualLayers.Unshaded, false);
+ return;
+ }
+
+ args.Sprite.LayerSetVisible(PowerCellVisualLayers.Unshaded, true);
+ args.Sprite.LayerSetState(PowerCellVisualLayers.Unshaded, $"o{level}");
+ }
+ }
+
+ private enum PowerCellVisualLayers : byte
+ {
+ Base,
+ Unshaded,
+ }
+}
diff --git a/Content.Client/PowerCell/PowerCellVisualizer.cs b/Content.Client/PowerCell/PowerCellVisualizer.cs
deleted file mode 100644
index ef0b0b4305..0000000000
--- a/Content.Client/PowerCell/PowerCellVisualizer.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-using Content.Shared.PowerCell;
-using JetBrains.Annotations;
-using Robust.Client.GameObjects;
-using Robust.Shared.GameObjects;
-using Robust.Shared.IoC;
-using Robust.Shared.Serialization.Manager.Attributes;
-
-namespace Content.Client.PowerCell
-{
- [UsedImplicitly]
- public sealed class PowerCellVisualizer : AppearanceVisualizer
- {
- [DataField("prefix")]
- private string? _prefix;
-
- public override void InitializeEntity(EntityUid entity)
- {
- base.InitializeEntity(entity);
-
- var sprite = IoCManager.Resolve().GetComponent(entity);
-
- if (_prefix != null)
- {
- sprite.LayerMapSet(Layers.Charge, sprite.AddLayerState($"{_prefix}_100"));
- sprite.LayerSetShader(Layers.Charge, "unshaded");
- }
- }
-
- public override void OnChangeData(AppearanceComponent component)
- {
- base.OnChangeData(component);
-
- var sprite = IoCManager.Resolve().GetComponent(component.Owner);
- if (component.TryGetData(PowerCellVisuals.ChargeLevel, out byte level))
- {
- var adjustedLevel = level * 25;
- sprite.LayerSetState(Layers.Charge, $"{_prefix}_{adjustedLevel}");
- }
- }
-
- private enum Layers : byte
- {
- Charge
- }
- }
-}
diff --git a/Content.Client/PowerCell/PowerCellVisualsComponent.cs b/Content.Client/PowerCell/PowerCellVisualsComponent.cs
new file mode 100644
index 0000000000..7238ef6b93
--- /dev/null
+++ b/Content.Client/PowerCell/PowerCellVisualsComponent.cs
@@ -0,0 +1,4 @@
+namespace Content.Client.PowerCell;
+
+[RegisterComponent]
+public sealed class PowerCellVisualsComponent : Component {}
diff --git a/Content.Client/Radar/RadarConsoleWindow.xaml b/Content.Client/Radar/RadarConsoleWindow.xaml
deleted file mode 100644
index 92e25bf7fc..0000000000
--- a/Content.Client/Radar/RadarConsoleWindow.xaml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
diff --git a/Content.Client/Radar/RadarConsoleWindow.xaml.cs b/Content.Client/Radar/RadarConsoleWindow.xaml.cs
deleted file mode 100644
index 048541ebe4..0000000000
--- a/Content.Client/Radar/RadarConsoleWindow.xaml.cs
+++ /dev/null
@@ -1,116 +0,0 @@
-using System;
-using Content.Client.Computer;
-using Content.Shared.Radar;
-using JetBrains.Annotations;
-using Robust.Client.AutoGenerated;
-using Robust.Client.GameObjects;
-using Robust.Client.Graphics;
-using Robust.Client.UserInterface;
-using Robust.Client.UserInterface.CustomControls;
-using Robust.Client.UserInterface.XAML;
-using Robust.Shared.Maths;
-
-namespace Content.Client.Radar;
-
-[GenerateTypedNameReferences]
-public sealed partial class RadarConsoleWindow : DefaultWindow, IComputerWindow
-{
- public RadarConsoleWindow()
- {
- RobustXamlLoader.Load(this);
- }
-
- public void SetupComputerWindow(ComputerBoundUserInterfaceBase cb)
- {
-
- }
-
- public void UpdateState(RadarConsoleBoundInterfaceState scc)
- {
- Radar.UpdateState(scc);
- }
-}
-
-
-public sealed class RadarControl : Control
-{
- private const int MinimapRadius = 256;
- private const int MinimapMargin = 4;
- private const float GridLinesDistance = 32f;
-
- private float _radarRange = 256f;
- private RadarConsoleBoundInterfaceState _lastState = new(256f, Array.Empty());
-
- private int SizeFull => (int) ((MinimapRadius + MinimapMargin) * 2 * UIScale);
- private int ScaledMinimapRadius => (int) (MinimapRadius * UIScale);
- private float MinimapScale => _radarRange != 0 ? ScaledMinimapRadius / _radarRange : 0f;
-
- public RadarControl()
- {
- MinSize = (SizeFull, SizeFull);
- }
-
- public void UpdateState(RadarConsoleBoundInterfaceState ls)
- {
- if (!_radarRange.Equals(ls.Range))
- {
- _radarRange = ls.Range;
- }
-
- _lastState = ls;
- }
-
- protected override void Draw(DrawingHandleScreen handle)
- {
- var point = SizeFull / 2;
- var fakeAA = new Color(0.08f, 0.08f, 0.08f);
- var gridLines = new Color(0.08f, 0.08f, 0.08f);
- var gridLinesRadial = 8;
- var gridLinesEquatorial = (int) Math.Floor(_radarRange / GridLinesDistance);
-
- handle.DrawCircle((point, point), ScaledMinimapRadius + 1, fakeAA);
- handle.DrawCircle((point, point), ScaledMinimapRadius, Color.Black);
-
- for (var i = 1; i < gridLinesEquatorial + 1; i++)
- {
- handle.DrawCircle((point, point), GridLinesDistance * MinimapScale * i, gridLines, false);
- }
-
- for (var i = 0; i < gridLinesRadial; i++)
- {
- Angle angle = (Math.PI / gridLinesRadial) * i;
- var aExtent = angle.ToVec() * ScaledMinimapRadius;
- handle.DrawLine((point, point) - aExtent, (point, point) + aExtent, gridLines);
- }
-
- handle.DrawLine((point, point) + new Vector2(8, 8), (point, point) - new Vector2(0, 8), Color.Yellow);
- handle.DrawLine((point, point) + new Vector2(-8, 8), (point, point) - new Vector2(0, 8), Color.Yellow);
-
- foreach (var obj in _lastState.Objects)
- {
- var minimapPos = obj.Position * MinimapScale;
- var radius = obj.Radius * MinimapScale;
-
- if (minimapPos.Length + radius > ScaledMinimapRadius)
- continue;
-
- switch (obj.Shape)
- {
- case RadarObjectShape.CircleFilled:
- case RadarObjectShape.Circle:
- {
- handle.DrawCircle(minimapPos + point, radius, obj.Color, obj.Shape == RadarObjectShape.CircleFilled);
- break;
- }
- default:
- throw new NotImplementedException();
- }
- }
- }
-}
-
-[UsedImplicitly]
-public sealed class RadarConsoleBoundUserInterface : ComputerBoundUserInterface
-{
- public RadarConsoleBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey) {}
-}
diff --git a/Content.Client/Shuttles/BUI/RadarConsoleBoundUserInterface.cs b/Content.Client/Shuttles/BUI/RadarConsoleBoundUserInterface.cs
new file mode 100644
index 0000000000..4c5b4edea8
--- /dev/null
+++ b/Content.Client/Shuttles/BUI/RadarConsoleBoundUserInterface.cs
@@ -0,0 +1,29 @@
+using Content.Client.Shuttles.UI;
+using Content.Shared.Shuttles.BUIStates;
+using JetBrains.Annotations;
+using Robust.Client.GameObjects;
+
+namespace Content.Client.Shuttles.BUI;
+
+[UsedImplicitly]
+public sealed class RadarConsoleBoundUserInterface : BoundUserInterface
+{
+ private RadarConsoleWindow? _window;
+
+ public RadarConsoleBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey) {}
+
+ protected override void Open()
+ {
+ base.Open();
+ _window = new RadarConsoleWindow();
+ _window?.OpenCentered();
+ }
+
+ protected override void UpdateState(BoundUserInterfaceState state)
+ {
+ base.UpdateState(state);
+ if (state is not RadarConsoleBoundInterfaceState cState) return;
+
+ _window?.UpdateState(cState);
+ }
+}
diff --git a/Content.Client/Shuttles/BUI/ShuttleConsoleBoundUserInterface.cs b/Content.Client/Shuttles/BUI/ShuttleConsoleBoundUserInterface.cs
new file mode 100644
index 0000000000..cb60508c31
--- /dev/null
+++ b/Content.Client/Shuttles/BUI/ShuttleConsoleBoundUserInterface.cs
@@ -0,0 +1,70 @@
+using Content.Client.Shuttles.UI;
+using Content.Shared.Shuttles.BUIStates;
+using Content.Shared.Shuttles.Components;
+using Content.Shared.Shuttles.Events;
+using JetBrains.Annotations;
+using Robust.Client.GameObjects;
+
+namespace Content.Client.Shuttles.BUI;
+
+[UsedImplicitly]
+public sealed class ShuttleConsoleBoundUserInterface : BoundUserInterface
+{
+ private ShuttleConsoleWindow? _window;
+
+ public ShuttleConsoleBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey) {}
+
+ protected override void Open()
+ {
+ base.Open();
+ _window = new ShuttleConsoleWindow();
+ _window.ShuttleModePressed += OnShuttleModePressed;
+ _window.UndockPressed += OnUndockPressed;
+ _window.StartAutodockPressed += OnAutodockPressed;
+ _window.StopAutodockPressed += OnStopAutodockPressed;
+ _window.OpenCentered();
+ _window.OnClose += OnClose;
+ }
+
+ private void OnClose()
+ {
+ Close();
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+
+ if (disposing)
+ {
+ _window?.Dispose();
+ }
+ }
+
+ private void OnStopAutodockPressed(EntityUid obj)
+ {
+ SendMessage(new StopAutodockRequestMessage() {Entity = obj});
+ }
+
+ private void OnAutodockPressed(EntityUid obj)
+ {
+ SendMessage(new AutodockRequestMessage() {Entity = obj});
+ }
+
+ private void OnUndockPressed(EntityUid obj)
+ {
+ SendMessage(new UndockRequestMessage() {Entity = obj});
+ }
+
+ private void OnShuttleModePressed(ShuttleMode obj)
+ {
+ SendMessage(new ShuttleModeRequestMessage() {Mode = obj});
+ }
+
+ protected override void UpdateState(BoundUserInterfaceState state)
+ {
+ base.UpdateState(state);
+ if (state is not ShuttleConsoleBoundInterfaceState cState) return;
+ _window?.UpdateState(cState);
+ }
+}
diff --git a/Content.Client/Shuttles/ShuttleConsoleComponent.cs b/Content.Client/Shuttles/ShuttleConsoleComponent.cs
index 86c4410b86..da6b914794 100644
--- a/Content.Client/Shuttles/ShuttleConsoleComponent.cs
+++ b/Content.Client/Shuttles/ShuttleConsoleComponent.cs
@@ -1,13 +1,7 @@
-using Content.Shared.Shuttles;
using Content.Shared.Shuttles.Components;
-using Robust.Shared.GameObjects;
namespace Content.Client.Shuttles
{
[RegisterComponent]
- [ComponentReference(typeof(SharedShuttleConsoleComponent))]
- internal sealed class ShuttleConsoleComponent : SharedShuttleConsoleComponent
- {
-
- }
+ public sealed class ShuttleConsoleComponent : SharedShuttleConsoleComponent {}
}
diff --git a/Content.Client/Shuttles/ShuttleConsoleSystem.cs b/Content.Client/Shuttles/ShuttleConsoleSystem.cs
deleted file mode 100644
index cb0f6f7b0c..0000000000
--- a/Content.Client/Shuttles/ShuttleConsoleSystem.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using Content.Shared.Shuttles;
-
-namespace Content.Client.Shuttles
-{
- internal sealed class ShuttleConsoleSystem : SharedShuttleConsoleSystem
- {
-
- }
-}
diff --git a/Content.Client/Shuttles/Systems/DockingSystem.cs b/Content.Client/Shuttles/Systems/DockingSystem.cs
new file mode 100644
index 0000000000..61f0b8d06c
--- /dev/null
+++ b/Content.Client/Shuttles/Systems/DockingSystem.cs
@@ -0,0 +1,21 @@
+using Content.Shared.Shuttles.Events;
+
+namespace Content.Client.Shuttles.Systems;
+
+public sealed class DockingSystem : EntitySystem
+{
+ public void StartAutodock(EntityUid uid)
+ {
+ RaiseNetworkEvent(new AutodockRequestMessage {Entity = uid});
+ }
+
+ public void StopAutodock(EntityUid uid)
+ {
+ RaiseNetworkEvent(new StopAutodockRequestMessage() {Entity = uid});
+ }
+
+ public void Undock(EntityUid uid)
+ {
+ RaiseNetworkEvent(new UndockRequestMessage() {Entity = uid});
+ }
+}
diff --git a/Content.Client/Shuttles/Systems/RadarConsoleSystem.cs b/Content.Client/Shuttles/Systems/RadarConsoleSystem.cs
new file mode 100644
index 0000000000..0a0ddcf2ee
--- /dev/null
+++ b/Content.Client/Shuttles/Systems/RadarConsoleSystem.cs
@@ -0,0 +1,8 @@
+using Content.Shared.Shuttles.Systems;
+
+namespace Content.Client.Shuttles.Systems;
+
+public sealed class RadarConsoleSystem : SharedRadarConsoleSystem
+{
+
+}
diff --git a/Content.Client/Shuttles/Systems/ShuttleConsoleSystem.cs b/Content.Client/Shuttles/Systems/ShuttleConsoleSystem.cs
new file mode 100644
index 0000000000..7ae419c358
--- /dev/null
+++ b/Content.Client/Shuttles/Systems/ShuttleConsoleSystem.cs
@@ -0,0 +1,37 @@
+using Content.Shared.Shuttles.Components;
+using Content.Shared.Shuttles.Events;
+using Content.Shared.Shuttles.Systems;
+using Robust.Shared.GameStates;
+
+namespace Content.Client.Shuttles.Systems
+{
+ public sealed class ShuttleConsoleSystem : SharedShuttleConsoleSystem
+ {
+ public override void Initialize()
+ {
+ base.Initialize();
+ SubscribeLocalEvent(OnHandleState);
+ }
+
+ private void OnHandleState(EntityUid uid, PilotComponent component, ref ComponentHandleState args)
+ {
+ if (args.Current is not PilotComponentState state) return;
+
+ var console = state.Console.GetValueOrDefault();
+ if (!console.IsValid())
+ {
+ component.Console = null;
+ return;
+ }
+
+ if (!TryComp(console, out var shuttleConsoleComponent))
+ {
+ Logger.Warning($"Unable to set Helmsman console to {console}");
+ return;
+ }
+
+ component.Console = shuttleConsoleComponent;
+ ActionBlockerSystem.UpdateCanMove(uid);
+ }
+ }
+}
diff --git a/Content.Client/Shuttles/UI/DockingControl.cs b/Content.Client/Shuttles/UI/DockingControl.cs
new file mode 100644
index 0000000000..dfa5023a8a
--- /dev/null
+++ b/Content.Client/Shuttles/UI/DockingControl.cs
@@ -0,0 +1,251 @@
+using Content.Shared.Shuttles.BUIStates;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Shared.Map;
+using Robust.Shared.Physics;
+using Robust.Shared.Physics.Collision.Shapes;
+
+namespace Content.Client.Shuttles.UI;
+
+///
+/// Displays the docking view from a specific docking port
+///
+[Virtual]
+public class DockingControl : Control
+{
+ private readonly IEntityManager _entManager;
+ private readonly IMapManager _mapManager;
+
+ private const int MinimapRadius = 384;
+ private const int MinimapMargin = 4;
+
+ private float _range = 8f;
+ private float _rangeSquared = 0f;
+ private const float GridLinesDistance = 32f;
+
+ private int MidPoint => SizeFull / 2;
+ private int SizeFull => (int) ((MinimapRadius + MinimapMargin) * 2 * UIScale);
+ private int ScaledMinimapRadius => (int) (MinimapRadius * UIScale);
+ private float MinimapScale => _range != 0 ? ScaledMinimapRadius / _range : 0f;
+
+ public EntityUid? ViewedDock;
+ public EntityUid? GridEntity;
+
+ ///
+ /// Stored by GridID then by docks
+ ///
+ public Dictionary> Docks = new();
+
+ public DockingControl()
+ {
+ _entManager = IoCManager.Resolve();
+ _mapManager = IoCManager.Resolve();
+ _rangeSquared = _range * _range;
+ MinSize = (SizeFull, SizeFull);
+ }
+
+ protected override void Draw(DrawingHandleScreen handle)
+ {
+ base.Draw(handle);
+
+ var fakeAA = new Color(0.08f, 0.08f, 0.08f);
+
+ handle.DrawCircle((MidPoint, MidPoint), ScaledMinimapRadius + 1, fakeAA);
+ handle.DrawCircle((MidPoint, MidPoint), ScaledMinimapRadius, Color.Black);
+
+ var gridLines = new Color(0.08f, 0.08f, 0.08f);
+ var gridLinesRadial = 8;
+ var gridLinesEquatorial = (int) Math.Floor(_range / GridLinesDistance);
+
+ for (var i = 1; i < gridLinesEquatorial + 1; i++)
+ {
+ handle.DrawCircle((MidPoint, MidPoint), GridLinesDistance * MinimapScale * i, gridLines, false);
+ }
+
+ for (var i = 0; i < gridLinesRadial; i++)
+ {
+ Angle angle = (Math.PI / gridLinesRadial) * i;
+ var aExtent = angle.ToVec() * ScaledMinimapRadius;
+ handle.DrawLine((MidPoint, MidPoint) - aExtent, (MidPoint, MidPoint) + aExtent, gridLines);
+ }
+
+ if (!_entManager.TryGetComponent(ViewedDock, out var xform) ||
+ !_entManager.TryGetComponent(GridEntity, out var gridXform)) return;
+
+ var rotation = Matrix3.CreateRotation(xform.LocalRotation);
+ var matrix = Matrix3.CreateTranslation(-xform.LocalPosition);
+
+ // Draw the fixtures around the dock before drawing it
+ if (_entManager.TryGetComponent(GridEntity, out var fixtures))
+ {
+ foreach (var (_, fixture) in fixtures.Fixtures)
+ {
+ var poly = (PolygonShape) fixture.Shape;
+
+ for (var i = 0; i < poly.VertexCount; i++)
+ {
+ var start = matrix.Transform(poly.Vertices[i]);
+ var end = matrix.Transform(poly.Vertices[(i + 1) % poly.VertexCount]);
+
+ var startOut = start.LengthSquared > _rangeSquared;
+ var endOut = end.LengthSquared > _rangeSquared;
+
+ // We need to draw to the radar border so we'll cap the range,
+ // but if none of the verts are in range then just leave it.
+ if (startOut && endOut)
+ continue;
+
+ start.Y = -start.Y;
+ end.Y = -end.Y;
+
+ // If start is outside we draw capped from end to start
+ if (startOut)
+ {
+ // It's called Jobseeker now.
+ if (!MathHelper.TryGetIntersecting(start, end, _range, out var newStart)) continue;
+ start = newStart.Value;
+ }
+ // otherwise vice versa
+ else if (endOut)
+ {
+ if (!MathHelper.TryGetIntersecting(end, start, _range, out var newEnd)) continue;
+ end = newEnd.Value;
+ }
+
+ handle.DrawLine(ScalePosition(start), ScalePosition(end), Color.Goldenrod);
+ }
+ }
+ }
+
+ // Draw the dock's collision
+ handle.DrawRect(new UIBox2(
+ ScalePosition(rotation.Transform(new Vector2(-0.2f, -0.7f))),
+ ScalePosition(rotation.Transform(new Vector2(0.2f, -0.5f)))), Color.Aquamarine);
+
+ // Draw the dock itself
+ handle.DrawRect(new UIBox2(
+ ScalePosition(rotation.Transform(new Vector2(-0.5f, 0.5f))),
+ ScalePosition(rotation.Transform(new Vector2(0.5f, -0.5f)))), Color.Green);
+
+ // Draw nearby grids
+ var worldPos = gridXform.WorldMatrix.Transform(xform.LocalPosition);
+ var gridInvMatrix = gridXform.InvWorldMatrix;
+ Matrix3.Multiply(in gridInvMatrix, in matrix, out var invMatrix);
+
+ // TODO: Getting some overdraw so need to fix that.
+
+ foreach (var grid in _mapManager.FindGridsIntersecting(gridXform.MapID,
+ new Box2(worldPos - _range, worldPos + _range)))
+ {
+ if (grid.GridEntityId == GridEntity) continue;
+
+ // Draw the fixtures before drawing any docks in range.
+ if (!_entManager.TryGetComponent(grid.GridEntityId, out var gridFixtures)) continue;
+
+ var gridMatrix = grid.WorldMatrix;
+
+ Matrix3.Multiply(in gridMatrix, in invMatrix, out var matty);
+
+ foreach (var (_, fixture) in gridFixtures.Fixtures)
+ {
+ var poly = (PolygonShape) fixture.Shape;
+
+ for (var i = 0; i < poly.VertexCount; i++)
+ {
+ // This is because the same line might be on different fixtures so we don't want to draw it twice.
+ var startPos = poly.Vertices[i];
+ var endPos = poly.Vertices[(i + 1) % poly.VertexCount];
+
+ var start = matty.Transform(startPos);
+ var end = matty.Transform(endPos);
+
+ var startOut = start.LengthSquared > _rangeSquared;
+ var endOut = end.LengthSquared > _rangeSquared;
+
+ // We need to draw to the radar border so we'll cap the range,
+ // but if none of the verts are in range then just leave it.
+ if (startOut && endOut)
+ continue;
+
+ start.Y = -start.Y;
+ end.Y = -end.Y;
+
+ // If start is outside we draw capped from end to start
+ if (startOut)
+ {
+ // It's called Jobseeker now.
+ if (!MathHelper.TryGetIntersecting(start, end, _range, out var newStart)) continue;
+ start = newStart.Value;
+ }
+ // otherwise vice versa
+ else if (endOut)
+ {
+ if (!MathHelper.TryGetIntersecting(end, start, _range, out var newEnd)) continue;
+ end = newEnd.Value;
+ }
+
+ handle.DrawLine(ScalePosition(start), ScalePosition(end), Color.Aquamarine);
+ }
+ }
+
+ // Draw any docks on that grid
+ if (Docks.TryGetValue(grid.GridEntityId, out var gridDocks))
+ {
+ foreach (var dock in gridDocks)
+ {
+ var position = matty.Transform(dock.Coordinates.Position);
+
+ if (position.Length > _range - 0.8f) continue;
+
+ var otherDockRotation = Matrix3.CreateRotation(dock.Angle);
+
+ // Draw the dock's collision
+ var verts = new[]
+ {
+ matty.Transform(dock.Coordinates.Position +
+ otherDockRotation.Transform(new Vector2(-0.2f, -0.7f))),
+ matty.Transform(dock.Coordinates.Position +
+ otherDockRotation.Transform(new Vector2(0.2f, -0.7f))),
+ matty.Transform(dock.Coordinates.Position +
+ otherDockRotation.Transform(new Vector2(0.2f, -0.5f))),
+ matty.Transform(dock.Coordinates.Position +
+ otherDockRotation.Transform(new Vector2(-0.2f, -0.5f))),
+ };
+
+ for (var i = 0; i < verts.Length; i++)
+ {
+ var vert = verts[i];
+ vert.Y = -vert.Y;
+ verts[i] = ScalePosition(vert);
+ }
+
+ handle.DrawPrimitives(DrawPrimitiveTopology.TriangleFan, verts, Color.Turquoise);
+
+ // Draw the dock itself
+ verts = new[]
+ {
+ matty.Transform(dock.Coordinates.Position + new Vector2(-0.5f, -0.5f)),
+ matty.Transform(dock.Coordinates.Position + new Vector2(0.5f, -0.5f)),
+ matty.Transform(dock.Coordinates.Position + new Vector2(0.5f, 0.5f)),
+ matty.Transform(dock.Coordinates.Position + new Vector2(-0.5f, 0.5f)),
+ };
+
+ for (var i = 0; i < verts.Length; i++)
+ {
+ var vert = verts[i];
+ vert.Y = -vert.Y;
+ verts[i] = ScalePosition(vert);
+ }
+
+ handle.DrawPrimitives(DrawPrimitiveTopology.TriangleFan, verts, Color.Green);
+ }
+ }
+ }
+
+ }
+
+ private Vector2 ScalePosition(Vector2 value)
+ {
+ return value * MinimapScale + MidPoint;
+ }
+}
diff --git a/Content.Client/Shuttles/UI/RadarConsoleWindow.xaml b/Content.Client/Shuttles/UI/RadarConsoleWindow.xaml
new file mode 100644
index 0000000000..7591034b92
--- /dev/null
+++ b/Content.Client/Shuttles/UI/RadarConsoleWindow.xaml
@@ -0,0 +1,6 @@
+
+
+
diff --git a/Content.Client/Shuttles/UI/RadarConsoleWindow.xaml.cs b/Content.Client/Shuttles/UI/RadarConsoleWindow.xaml.cs
new file mode 100644
index 0000000000..7274cc23c8
--- /dev/null
+++ b/Content.Client/Shuttles/UI/RadarConsoleWindow.xaml.cs
@@ -0,0 +1,22 @@
+using Content.Client.Computer;
+using Content.Client.UserInterface;
+using Content.Shared.Shuttles.BUIStates;
+using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface.XAML;
+
+namespace Content.Client.Shuttles.UI;
+
+[GenerateTypedNameReferences]
+public sealed partial class RadarConsoleWindow : FancyWindow,
+ IComputerWindow
+{
+ public RadarConsoleWindow()
+ {
+ RobustXamlLoader.Load(this);
+ }
+
+ public void UpdateState(RadarConsoleBoundInterfaceState scc)
+ {
+ RadarScreen.UpdateState(scc);
+ }
+}
diff --git a/Content.Client/Shuttles/UI/RadarControl.cs b/Content.Client/Shuttles/UI/RadarControl.cs
new file mode 100644
index 0000000000..f8d2f8c6e8
--- /dev/null
+++ b/Content.Client/Shuttles/UI/RadarControl.cs
@@ -0,0 +1,348 @@
+using Content.Client.Stylesheets;
+using Content.Shared.Shuttles.BUIStates;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using Robust.Shared.Map;
+using Robust.Shared.Physics;
+using Robust.Shared.Physics.Collision.Shapes;
+using Robust.Shared.Utility;
+
+namespace Content.Client.Shuttles.UI;
+
+///
+/// Displays nearby grids inside of a control.
+///
+public sealed class RadarControl : Control
+{
+ [Dependency] private readonly IEntityManager _entManager = default!;
+ [Dependency] private readonly IMapManager _mapManager = default!;
+
+ private const float ScrollSensitivity = 8f;
+
+ private const int MinimapRadius = 384;
+ private const int MinimapMargin = 4;
+ private const float GridLinesDistance = 32f;
+
+ ///
+ /// Entity used to transform all of the radar objects.
+ ///
+ private EntityUid? _entity;
+
+ private float _radarMinRange = 64f;
+ private float _radarMaxRange = 256f;
+ public float RadarRange { get; private set; } = 256f;
+
+ private int MidPoint => SizeFull / 2;
+ private int SizeFull => (int) ((MinimapRadius + MinimapMargin) * 2 * UIScale);
+ private int ScaledMinimapRadius => (int) (MinimapRadius * UIScale);
+ private float MinimapScale => RadarRange != 0 ? ScaledMinimapRadius / RadarRange : 0f;
+
+ ///
+ /// Shows a label on each radar object.
+ ///
+ private Dictionary _iffControls = new();
+
+ private Dictionary> _docks = new();
+
+ public bool ShowIFF { get; set; } = true;
+ public bool ShowDocks { get; set; } = true;
+
+ ///
+ /// Currently hovered docked to show on the map.
+ ///
+ public EntityUid? HighlightedDock;
+
+ public Action? OnRadarRangeChanged;
+
+ public RadarControl()
+ {
+ IoCManager.InjectDependencies(this);
+ MinSize = (SizeFull, SizeFull);
+ }
+
+ public void UpdateState(RadarConsoleBoundInterfaceState ls)
+ {
+ _radarMaxRange = ls.MaxRange;
+
+ if (_radarMaxRange < RadarRange)
+ {
+ RadarRange = _radarMaxRange;
+ OnRadarRangeChanged?.Invoke(RadarRange);
+ }
+
+ if (_radarMaxRange < _radarMinRange)
+ _radarMinRange = _radarMaxRange;
+
+ _entity = ls.Entity;
+ _docks.Clear();
+
+ foreach (var state in ls.Docks)
+ {
+ var coordinates = state.Coordinates;
+ var grid = _docks.GetOrNew(coordinates.EntityId);
+ grid.Add(state.Entity, state);
+ }
+ }
+
+ protected override void MouseWheel(GUIMouseWheelEventArgs args)
+ {
+ base.MouseWheel(args);
+ AddRadarRange(-args.Delta.Y * ScrollSensitivity);
+ }
+
+ public void AddRadarRange(float value)
+ {
+ var oldValue = RadarRange;
+ RadarRange = MathF.Max(0f, MathF.Max(_radarMinRange, MathF.Min(RadarRange + value, _radarMaxRange)));
+
+ if (oldValue.Equals(RadarRange)) return;
+
+ OnRadarRangeChanged?.Invoke(RadarRange);
+ }
+
+ protected override void Draw(DrawingHandleScreen handle)
+ {
+ var fakeAA = new Color(0.08f, 0.08f, 0.08f);
+
+ handle.DrawCircle((MidPoint, MidPoint), ScaledMinimapRadius + 1, fakeAA);
+ handle.DrawCircle((MidPoint, MidPoint), ScaledMinimapRadius, Color.Black);
+
+ // No data
+ if (_entity == null)
+ {
+ Clear();
+ return;
+ }
+
+ var gridLines = new Color(0.08f, 0.08f, 0.08f);
+ var gridLinesRadial = 8;
+ var gridLinesEquatorial = (int) Math.Floor(RadarRange / GridLinesDistance);
+
+ for (var i = 1; i < gridLinesEquatorial + 1; i++)
+ {
+ handle.DrawCircle((MidPoint, MidPoint), GridLinesDistance * MinimapScale * i, gridLines, false);
+ }
+
+ for (var i = 0; i < gridLinesRadial; i++)
+ {
+ Angle angle = (Math.PI / gridLinesRadial) * i;
+ var aExtent = angle.ToVec() * ScaledMinimapRadius;
+ handle.DrawLine((MidPoint, MidPoint) - aExtent, (MidPoint, MidPoint) + aExtent, gridLines);
+ }
+
+ var metaQuery = _entManager.GetEntityQuery();
+ var xformQuery = _entManager.GetEntityQuery();
+ var fixturesQuery = _entManager.GetEntityQuery();
+ var bodyQuery = _entManager.GetEntityQuery();
+ var xform = xformQuery.GetComponent(_entity.Value);
+ var mapPosition = xform.MapPosition;
+
+ if (mapPosition.MapId == MapId.Nullspace)
+ {
+ Clear();
+ return;
+ }
+
+ // Can also use ourGridBody.LocalCenter
+ var offset = xform.Coordinates.Position;
+ var offsetMatrix = Matrix3.CreateTranslation(-offset);
+ Matrix3 matrix;
+
+ // Draw our grid in detail
+ var ourGridId = xform.GridID;
+ if (ourGridId != GridId.Invalid)
+ {
+ matrix = xform.InvWorldMatrix;
+ var ourGridFixtures = fixturesQuery.GetComponent(ourGridId);
+ // Draw our grid; use non-filled boxes so it doesn't look awful.
+ DrawGrid(handle, offsetMatrix, ourGridFixtures, Color.Yellow);
+
+ DrawDocks(handle, xform.GridEntityId, offsetMatrix);
+ }
+ else
+ {
+ matrix = Matrix3.CreateTranslation(-offset);
+ }
+
+ var invertedPosition = xform.Coordinates.Position - offset;
+ invertedPosition.Y = -invertedPosition.Y;
+ // Don't need to transform the InvWorldMatrix again as it's already offset to its position.
+
+ // Draw radar position on the station
+ handle.DrawCircle(ScalePosition(invertedPosition), 5f, Color.Lime);
+
+ var shown = new HashSet();
+
+ // Draw other grids... differently
+ foreach (var grid in _mapManager.FindGridsIntersecting(mapPosition.MapId,
+ new Box2(mapPosition.Position - RadarRange, mapPosition.Position + RadarRange)))
+ {
+ if (grid.Index == ourGridId) continue;
+
+ var gridBody = bodyQuery.GetComponent(grid.GridEntityId);
+ if (gridBody.Mass < 10f)
+ {
+ ClearLabel(grid.GridEntityId);
+ continue;
+ }
+
+ shown.Add(grid.GridEntityId);
+ var name = metaQuery.GetComponent(grid.GridEntityId).EntityName;
+
+ if (name == string.Empty)
+ name = Loc.GetString("shuttle-console-unknown");
+
+ var gridXform = xformQuery.GetComponent(grid.GridEntityId);
+ var gridFixtures = fixturesQuery.GetComponent(grid.GridEntityId);
+ var gridMatrix = gridXform.WorldMatrix;
+ Matrix3.Multiply(in gridMatrix, in matrix, out var matty);
+
+ if (ShowIFF)
+ {
+ if (!_iffControls.TryGetValue(grid.GridEntityId, out var control))
+ {
+ var label = new Label()
+ {
+ HorizontalAlignment = HAlignment.Left,
+ };
+
+ control = new PanelContainer()
+ {
+ HorizontalAlignment = HAlignment.Left,
+ VerticalAlignment = VAlignment.Top,
+ Children = { label },
+ StyleClasses = { StyleNano.StyleClassTooltipPanel },
+ };
+
+ _iffControls[grid.GridEntityId] = control;
+ AddChild(control);
+ }
+
+ var gridCentre = matty.Transform(gridBody.LocalCenter);
+ gridCentre.Y = -gridCentre.Y;
+
+ // TODO: When we get IFF or whatever we can show controls at a further distance; for now
+ // we don't do that because it would immediately reveal nukies.
+ if (gridCentre.Length < RadarRange)
+ {
+ control.Visible = true;
+ var label = (Label) control.GetChild(0);
+ label.Text = Loc.GetString("shuttle-console-iff-label", ("name", name), ("distance", $"{gridCentre.Length:0.0}"));
+ LayoutContainer.SetPosition(control, ScalePosition(gridCentre) / UIScale);
+ }
+ else
+ {
+ control.Visible = false;
+ }
+ }
+ else
+ {
+ ClearLabel(grid.GridEntityId);
+ }
+
+ // Detailed view
+ DrawGrid(handle, matty, gridFixtures, Color.Aquamarine);
+
+ DrawDocks(handle, grid.GridEntityId, matty);
+ }
+
+ foreach (var (ent, _) in _iffControls)
+ {
+ if (shown.Contains(ent)) continue;
+ ClearLabel(ent);
+ }
+ }
+
+ private void Clear()
+ {
+ foreach (var (_, label) in _iffControls)
+ {
+ label.Dispose();
+ }
+
+ _iffControls.Clear();
+ }
+
+ private void ClearLabel(EntityUid uid)
+ {
+ if (!_iffControls.TryGetValue(uid, out var label)) return;
+ label.Dispose();
+ _iffControls.Remove(uid);
+ }
+
+ private void DrawDocks(DrawingHandleScreen handle, EntityUid uid, Matrix3 matrix)
+ {
+ if (!ShowDocks) return;
+
+ const float DockScale = 1.2f;
+
+ if (_docks.TryGetValue(uid, out var docks))
+ {
+ foreach (var (ent, state) in docks)
+ {
+ var position = state.Coordinates.Position;
+ var uiPosition = matrix.Transform(position);
+
+ if (uiPosition.Length > RadarRange - DockScale) continue;
+
+ var color = HighlightedDock == ent ? Color.Magenta : Color.DarkViolet;
+
+ uiPosition.Y = -uiPosition.Y;
+
+ var verts = new[]
+ {
+ matrix.Transform(position + new Vector2(-DockScale, -DockScale)),
+ matrix.Transform(position + new Vector2(DockScale, -DockScale)),
+ matrix.Transform(position + new Vector2(DockScale, DockScale)),
+ matrix.Transform(position + new Vector2(-DockScale, DockScale)),
+ };
+
+ for (var i = 0; i < verts.Length; i++)
+ {
+ var vert = verts[i];
+ vert.Y = -vert.Y;
+ verts[i] = ScalePosition(vert);
+ }
+
+ handle.DrawPrimitives(DrawPrimitiveTopology.TriangleFan, verts, color);
+ }
+ }
+ }
+
+ private void DrawGrid(DrawingHandleScreen handle, Matrix3 matrix, FixturesComponent component, Color color)
+ {
+ foreach (var (_, fixture) in component.Fixtures)
+ {
+ // If the fixture has any points out of range we won't draw any of it.
+ var invalid = false;
+ var poly = (PolygonShape) fixture.Shape;
+ var verts = new Vector2[poly.VertexCount + 1];
+
+ for (var i = 0; i < poly.VertexCount; i++)
+ {
+ var vert = matrix.Transform(poly.Vertices[i]);
+
+ if (vert.Length > RadarRange)
+ {
+ invalid = true;
+ break;
+ }
+
+ vert.Y = -vert.Y;
+ verts[i] = ScalePosition(vert);
+ }
+
+ if (invalid) continue;
+
+ // Closed list
+ verts[poly.VertexCount] = verts[0];
+ handle.DrawPrimitives(DrawPrimitiveTopology.LineStrip, verts, color);
+ }
+ }
+
+ private Vector2 ScalePosition(Vector2 value)
+ {
+ return value * MinimapScale + MidPoint;
+ }
+}
diff --git a/Content.Client/Shuttles/UI/ShuttleConsoleWindow.xaml b/Content.Client/Shuttles/UI/ShuttleConsoleWindow.xaml
new file mode 100644
index 0000000000..58d06e575a
--- /dev/null
+++ b/Content.Client/Shuttles/UI/ShuttleConsoleWindow.xaml
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Content.Client/Shuttles/UI/ShuttleConsoleWindow.xaml.cs b/Content.Client/Shuttles/UI/ShuttleConsoleWindow.xaml.cs
new file mode 100644
index 0000000000..3d2c4b1a80
--- /dev/null
+++ b/Content.Client/Shuttles/UI/ShuttleConsoleWindow.xaml.cs
@@ -0,0 +1,239 @@
+using Content.Client.Computer;
+using Content.Client.UserInterface;
+using Content.Shared.Shuttles.BUIStates;
+using Content.Shared.Shuttles.Components;
+using Robust.Client.AutoGenerated;
+using Robust.Client.Graphics;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using Robust.Client.UserInterface.XAML;
+using Robust.Shared.Utility;
+
+namespace Content.Client.Shuttles.UI;
+
+[GenerateTypedNameReferences]
+public sealed partial class ShuttleConsoleWindow : FancyWindow,
+ IComputerWindow
+{
+ private readonly IEntityManager _entManager;
+
+ ///
+ /// EntityUid of the open console.
+ ///
+ private EntityUid? _entity;
+
+ ///
+ /// Currently selected dock button for camera.
+ ///
+ private BaseButton? _selectedDock;
+
+ ///
+ /// Stored by grid entityid then by states
+ ///
+ private Dictionary> _docks = new();
+
+ public Action? ShuttleModePressed;
+ public Action? UndockPressed;
+ public Action? StartAutodockPressed;
+ public Action? StopAutodockPressed;
+
+ public ShuttleConsoleWindow()
+ {
+ RobustXamlLoader.Load(this);
+ _entManager = IoCManager.Resolve();
+
+ OnRadarRangeChange(RadarScreen.RadarRange);
+ RadarScreen.OnRadarRangeChanged += OnRadarRangeChange;
+
+ IFFToggle.OnToggled += OnIFFTogglePressed;
+ IFFToggle.Pressed = RadarScreen.ShowIFF;
+
+ DockToggle.OnToggled += OnDockTogglePressed;
+ DockToggle.Pressed = RadarScreen.ShowDocks;
+
+ ShuttleModeDisplay.OnToggled += OnShuttleModePressed;
+
+ UndockButton.OnPressed += OnUndockPressed;
+ }
+
+ private void OnRadarRangeChange(float value)
+ {
+ RadarRange.Text = $"{value:0}";
+ }
+
+ private void OnShuttleModePressed(BaseButton.ButtonEventArgs obj)
+ {
+ ShuttleModePressed?.Invoke(obj.Button.Pressed ? ShuttleMode.Strafing : ShuttleMode.Cruise);
+ }
+
+ private void OnIFFTogglePressed(BaseButton.ButtonEventArgs args)
+ {
+ RadarScreen.ShowIFF ^= true;
+ args.Button.Pressed = RadarScreen.ShowIFF;
+ }
+
+ private void OnDockTogglePressed(BaseButton.ButtonEventArgs args)
+ {
+ RadarScreen.ShowDocks ^= true;
+ args.Button.Pressed = RadarScreen.ShowDocks;
+ }
+
+ private void OnUndockPressed(BaseButton.ButtonEventArgs args)
+ {
+ if (DockingScreen.ViewedDock == null) return;
+ UndockPressed?.Invoke(DockingScreen.ViewedDock.Value);
+ }
+
+ public void UpdateState(ShuttleConsoleBoundInterfaceState scc)
+ {
+ _entity = scc.Entity;
+ UpdateDocks(scc.Docks);
+ RadarScreen.UpdateState(scc);
+ MaxRadarRange.Text = $"{scc.MaxRange:0}";
+ ShuttleModeDisplay.Pressed = scc.Mode == ShuttleMode.Strafing;
+ }
+
+ #region Docking
+
+ private void UpdateDocks(List docks)
+ {
+ // TODO: We should check for changes so any existing highlighted doesn't delete.
+ // We also need to make up some pseudonumber as well for these.
+ _docks.Clear();
+
+ foreach (var dock in docks)
+ {
+ var grid = _docks.GetOrNew(dock.Coordinates.EntityId);
+ grid.Add(dock);
+ }
+
+ DockPorts.DisposeAllChildren();
+ DockingScreen.Docks = _docks;
+
+ if (!_entManager.TryGetComponent(_entity, out var xform))
+ {
+ // TODO: Show Placeholder
+ return;
+ }
+
+ if (_docks.TryGetValue(xform.GridEntityId, out var gridDocks))
+ {
+ var index = 1;
+
+ foreach (var state in gridDocks)
+ {
+ var ent = state.Entity;
+ var pressed = ent == DockingScreen.ViewedDock;
+ string suffix;
+
+ if (state.Connected)
+ {
+ suffix = Loc.GetString("shuttle-console-docked", ("index", index));
+ }
+ else
+ {
+ suffix = $"{index}";
+ }
+
+ var button = new Button()
+ {
+ Text = Loc.GetString("shuttle-console-dock-button", ("suffix", suffix)),
+ ToggleMode = true,
+ Pressed = pressed,
+ };
+
+ button.OnMouseEntered += args => OnDockMouseEntered(args, ent);
+ button.OnMouseExited += args => OnDockMouseExited(args, ent);
+ button.OnToggled += args => OnDockToggled(args, ent);
+ DockPorts.AddChild(button);
+ index++;
+ }
+ }
+ }
+
+ private void OnDockMouseEntered(GUIMouseHoverEventArgs obj, EntityUid uid)
+ {
+ RadarScreen.HighlightedDock = uid;
+ }
+
+ private void OnDockMouseExited(GUIMouseHoverEventArgs obj, EntityUid uid)
+ {
+ RadarScreen.HighlightedDock = null;
+ }
+
+ ///
+ /// Shows a docking camera instead of radar screen.
+ ///
+ private void OnDockToggled(BaseButton.ButtonEventArgs obj, EntityUid ent)
+ {
+ if (_selectedDock != null)
+ {
+ _selectedDock.Pressed = false;
+ _selectedDock = null;
+ }
+
+ if (!obj.Button.Pressed)
+ {
+ if (DockingScreen.ViewedDock != null)
+ {
+ StopAutodockPressed?.Invoke(DockingScreen.ViewedDock.Value);
+ DockingScreen.ViewedDock = null;
+ }
+
+ UndockButton.Disabled = true;
+ DockingScreen.Visible = false;
+ RadarScreen.Visible = true;
+ }
+ else
+ {
+ // DebugTools.Assert(DockingScreen.ViewedDock == null);
+ _entManager.TryGetComponent(_entity, out var xform);
+
+ UndockButton.Disabled = false;
+ RadarScreen.Visible = false;
+ DockingScreen.Visible = true;
+ DockingScreen.ViewedDock = ent;
+ StartAutodockPressed?.Invoke(ent);
+ DockingScreen.GridEntity = xform?.GridEntityId;
+ _selectedDock = obj.Button;
+ }
+ }
+
+ public override void Close()
+ {
+ base.Close();
+ if (DockingScreen.ViewedDock != null)
+ {
+ StopAutodockPressed?.Invoke(DockingScreen.ViewedDock.Value);
+ }
+ }
+
+ #endregion
+
+ protected override void Draw(DrawingHandleScreen handle)
+ {
+ base.Draw(handle);
+
+ if (!_entManager.TryGetComponent(_entity, out var entXform) ||
+ !_entManager.TryGetComponent(entXform.GridEntityId, out var gridBody) ||
+ !_entManager.TryGetComponent(entXform.GridEntityId, out var gridXform))
+ {
+ return;
+ }
+
+ var (_, worldRot, worldMatrix) = gridXform.GetWorldPositionRotationMatrix();
+ var worldPos = worldMatrix.Transform(gridBody.LocalCenter);
+
+ // Get the positive reduced angle.
+ var displayRot = -worldRot.Reduced();
+
+ GridPosition.Text = $"{worldPos.X:0.0}, {worldPos.Y:0.0}";
+ GridOrientation.Text = $"{displayRot.Degrees:0.0}";
+
+ var gridVelocity = gridBody.LinearVelocity;
+ gridVelocity = displayRot.RotateVec(gridVelocity);
+ // Get linear velocity relative to the console entity
+ GridLinearVelocity.Text = $"{gridVelocity.X:0.0}, {gridVelocity.Y:0.0}";
+ GridAngularVelocity.Text = $"{-gridBody.AngularVelocity:0.0}";
+ }
+}
diff --git a/Content.Client/SurveillanceCamera/SurveillanceCameraMonitorSystem.cs b/Content.Client/SurveillanceCamera/SurveillanceCameraMonitorSystem.cs
index 31fe357427..c946062128 100644
--- a/Content.Client/SurveillanceCamera/SurveillanceCameraMonitorSystem.cs
+++ b/Content.Client/SurveillanceCamera/SurveillanceCameraMonitorSystem.cs
@@ -4,8 +4,6 @@ namespace Content.Client.SurveillanceCamera;
public sealed class SurveillanceCameraMonitorSystem : EntitySystem
{
- private readonly RemQueue _toRemove = new();
-
public override void Update(float frameTime)
{
foreach (var comp in EntityQuery())
@@ -24,16 +22,9 @@ public sealed class SurveillanceCameraMonitorSystem : EntitySystem
comp.OnFinish();
}
- _toRemove.Add(comp.Owner);
+ EntityManager.RemoveComponentDeferred(comp.Owner);
}
}
-
- foreach (var uid in _toRemove)
- {
- EntityManager.RemoveComponent(uid);
- }
-
- _toRemove.List?.Clear();
}
public void AddTimer(EntityUid uid, Action onFinish)
diff --git a/Content.Server/Administration/UI/AdminAnnounceEui.cs b/Content.Server/Administration/UI/AdminAnnounceEui.cs
index 543ee92c4d..18e074d3f5 100644
--- a/Content.Server/Administration/UI/AdminAnnounceEui.cs
+++ b/Content.Server/Administration/UI/AdminAnnounceEui.cs
@@ -11,11 +11,12 @@ namespace Content.Server.Administration.UI
{
[Dependency] private readonly IAdminManager _adminManager = default!;
[Dependency] private readonly IChatManager _chatManager = default!;
- [Dependency] private readonly ChatSystem _chatSystem = default!;
+ private readonly ChatSystem _chatSystem;
public AdminAnnounceEui()
{
IoCManager.InjectDependencies(this);
+ _chatSystem = IoCManager.Resolve().GetEntitySystem();
}
public override void Opened()
diff --git a/Content.Server/Alert/Click/StopPiloting.cs b/Content.Server/Alert/Click/StopPiloting.cs
index e25c23a4d3..e0c3b791d0 100644
--- a/Content.Server/Alert/Click/StopPiloting.cs
+++ b/Content.Server/Alert/Click/StopPiloting.cs
@@ -1,4 +1,4 @@
-using Content.Server.Shuttles.EntitySystems;
+using Content.Server.Shuttles.Systems;
using Content.Shared.Alert;
using Content.Shared.Shuttles.Components;
using JetBrains.Annotations;
diff --git a/Content.Server/Atmos/Commands/AddAtmosCommand.cs b/Content.Server/Atmos/Commands/AddAtmosCommand.cs
index 6de7f53da8..3a86e58d13 100644
--- a/Content.Server/Atmos/Commands/AddAtmosCommand.cs
+++ b/Content.Server/Atmos/Commands/AddAtmosCommand.cs
@@ -24,7 +24,7 @@ namespace Content.Server.Atmos.Commands
var entMan = IoCManager.Resolve();
- if(EntityUid.TryParse(args[0], out var euid))
+ if (!EntityUid.TryParse(args[0], out var euid))
{
shell.WriteError($"Failed to parse euid '{args[0]}'.");
return;
diff --git a/Content.Server/Atmos/EntitySystems/AutomaticAtmosSystem.cs b/Content.Server/Atmos/EntitySystems/AutomaticAtmosSystem.cs
index b89599a156..4b9cb8dba9 100644
--- a/Content.Server/Atmos/EntitySystems/AutomaticAtmosSystem.cs
+++ b/Content.Server/Atmos/EntitySystems/AutomaticAtmosSystem.cs
@@ -1,5 +1,5 @@
using Content.Server.Atmos.Components;
-using Content.Server.Shuttles.EntitySystems;
+using Content.Server.Shuttles.Systems;
using Content.Shared.Maps;
using Robust.Shared.Map;
diff --git a/Content.Server/Atmos/Miasma/MiasmaSystem.cs b/Content.Server/Atmos/Miasma/MiasmaSystem.cs
new file mode 100644
index 0000000000..e189984a12
--- /dev/null
+++ b/Content.Server/Atmos/Miasma/MiasmaSystem.cs
@@ -0,0 +1,92 @@
+using Content.Shared.MobState;
+using Content.Shared.Damage;
+using Content.Shared.Atmos;
+using Content.Server.Atmos.EntitySystems;
+using Content.Server.Temperature.Components;
+using Content.Server.Body.Components;
+using Robust.Shared.Containers;
+
+namespace Content.Server.Atmos.Miasma
+{
+ public sealed class MiasmaSystem : EntitySystem
+ {
+ [Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
+ [Dependency] private readonly DamageableSystem _damageableSystem = default!;
+
+ public override void Update(float frameTime)
+ {
+ base.Update(frameTime);
+ foreach (var (rotting, perishable) in EntityQuery())
+ {
+ if (!perishable.Progressing)
+ continue;
+
+ if (TryComp(perishable.Owner, out var temp) && temp.CurrentTemperature < 274f)
+ continue;
+
+ perishable.DeathAccumulator += frameTime;
+ if (perishable.DeathAccumulator < perishable.RotAfter.TotalSeconds)
+ continue;
+
+ perishable.RotAccumulator += frameTime;
+ if (perishable.RotAccumulator < 1f)
+ continue;
+
+ perishable.RotAccumulator -= 1f;
+
+ DamageSpecifier damage = new();
+ damage.DamageDict.Add("Blunt", 0.25); // Slowly accumulate enough to gib after like half an hour
+ damage.DamageDict.Add("Cellular", 0.25); // Cloning rework might use this eventually
+
+ _damageableSystem.TryChangeDamage(perishable.Owner, damage, true, true);
+
+ if (!TryComp(perishable.Owner, out var physics))
+ continue;
+ // We need a way to get the mass of the mob alone without armor etc in the future
+
+ var tileMix = _atmosphereSystem.GetTileMixture(Transform(perishable.Owner).Coordinates);
+ if (tileMix != null)
+ tileMix.AdjustMoles(Gas.Miasma, perishable.MolsPerSecondPerUnitMass * physics.FixturesMass);
+ }
+ }
+
+
+ public override void Initialize()
+ {
+ base.Initialize();
+ SubscribeLocalEvent(OnMobStateChanged);
+ SubscribeLocalEvent(OnGibbed);
+ SubscribeLocalEvent(OnEntInserted);
+ SubscribeLocalEvent(OnEntRemoved);
+ }
+
+ private void OnMobStateChanged(EntityUid uid, PerishableComponent component, MobStateChangedEvent args)
+ {
+ if (args.Component.IsDead())
+ EnsureComp(uid);
+ }
+
+ private void OnGibbed(EntityUid uid, PerishableComponent component, BeingGibbedEvent args)
+ {
+ if (!TryComp(uid, out var physics))
+ return;
+
+ var molsToDump = (component.MolsPerSecondPerUnitMass * physics.FixturesMass) * component.DeathAccumulator;
+ var tileMix = _atmosphereSystem.GetTileMixture(Transform(uid).Coordinates);
+ if (tileMix != null)
+ tileMix.AdjustMoles(Gas.Miasma, molsToDump);
+ }
+
+ private void OnEntInserted(EntityUid uid, AntiRottingContainerComponent component, EntInsertedIntoContainerMessage args)
+ {
+ if (TryComp(args.Entity, out var perishable))
+ perishable.Progressing = false;
+ }
+
+ private void OnEntRemoved(EntityUid uid, AntiRottingContainerComponent component, EntRemovedFromContainerMessage args)
+ {
+ if (TryComp(args.Entity, out var perishable))
+ perishable.Progressing = true;
+ }
+ }
+}
diff --git a/Content.Server/Atmos/Miasma/NoRotContainerComponent.cs b/Content.Server/Atmos/Miasma/NoRotContainerComponent.cs
new file mode 100644
index 0000000000..668d870cac
--- /dev/null
+++ b/Content.Server/Atmos/Miasma/NoRotContainerComponent.cs
@@ -0,0 +1,9 @@
+namespace Content.Server.Atmos.Miasma
+{
+ [RegisterComponent]
+ ///
+ /// Entities inside this container will not rot.
+ ///
+ public sealed class AntiRottingContainerComponent : Component
+ {}
+}
diff --git a/Content.Server/Atmos/Miasma/PerishableComponent.cs b/Content.Server/Atmos/Miasma/PerishableComponent.cs
new file mode 100644
index 0000000000..de8c45b9ca
--- /dev/null
+++ b/Content.Server/Atmos/Miasma/PerishableComponent.cs
@@ -0,0 +1,42 @@
+namespace Content.Server.Atmos.Miasma
+{
+ [RegisterComponent]
+ ///
+ /// This makes mobs eventually start rotting when they die.
+ /// It may be expanded to food at some point, but it's just for mobs right now.
+ ///
+ public sealed class PerishableComponent : Component
+ {
+ ///
+ /// Is this progressing?
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ public bool Progressing = true;
+
+ ///
+ /// How long this creature has been dead.
+ ///
+ [DataField("deathAccumulator")]
+ [ViewVariables(VVAccess.ReadWrite)]
+ public float DeathAccumulator = 0f;
+
+ ///
+ /// When DeathAccumulator is greater than this, start rotting.
+ ///
+ public TimeSpan RotAfter = TimeSpan.FromMinutes(3);
+
+ ///
+ /// Gasses are released every second.
+ ///
+ [DataField("rotAccumulator")]
+ public float RotAccumulator = 0f;
+
+ ///
+ /// How many moles of gas released per second, adjusted for mass.
+ /// Humans have a mass of 70. I am aiming for ten mols a minute, so
+ /// 1/6 of a minute, divided by 70 as a baseline.
+ ///
+ [ViewVariables(VVAccess.ReadWrite)]
+ public float MolsPerSecondPerUnitMass = 0.0025f;
+ }
+}
diff --git a/Content.Server/Atmos/Miasma/RottingComponent.cs b/Content.Server/Atmos/Miasma/RottingComponent.cs
new file mode 100644
index 0000000000..ae9dbe78a2
--- /dev/null
+++ b/Content.Server/Atmos/Miasma/RottingComponent.cs
@@ -0,0 +1,9 @@
+namespace Content.Server.Atmos.Miasma
+{
+ [RegisterComponent]
+ ///
+ /// Tracking component for stuff that has started to rot.
+ ///
+ public sealed class RottingComponent : Component
+ {}
+}
diff --git a/Content.Server/Chemistry/ReagentEffects/ChemCauseRandomDisease.cs b/Content.Server/Chemistry/ReagentEffects/ChemCauseRandomDisease.cs
new file mode 100644
index 0000000000..acb3b87b3f
--- /dev/null
+++ b/Content.Server/Chemistry/ReagentEffects/ChemCauseRandomDisease.cs
@@ -0,0 +1,32 @@
+using Content.Shared.Chemistry.Reagent;
+using Content.Server.Disease;
+using Content.Shared.Disease.Components;
+using Robust.Shared.Random;
+using JetBrains.Annotations;
+
+namespace Content.Server.Chemistry.ReagentEffects
+{
+ ///
+ /// Default metabolism for medicine reagents.
+ ///
+ [UsedImplicitly]
+ public sealed class ChemCauseRandomDisease : ReagentEffect
+ {
+ ///
+ /// A disease to choose from.
+ ///
+ [DataField("diseases", required: true)]
+ [ViewVariables(VVAccess.ReadWrite)]
+ public List Diseases = default!;
+
+ public override void Effect(ReagentEffectArgs args)
+ {
+ if (args.EntityManager.TryGetComponent(args.SolutionEntity, out var diseased))
+ return;
+
+ var random = IoCManager.Resolve();
+
+ EntitySystem.Get().TryAddDisease(args.SolutionEntity, random.Pick(Diseases));
+ }
+ }
+}
diff --git a/Content.Server/CombatMode/CombatModeSystem.cs b/Content.Server/CombatMode/CombatModeSystem.cs
index f4398bdbdc..23533ea431 100644
--- a/Content.Server/CombatMode/CombatModeSystem.cs
+++ b/Content.Server/CombatMode/CombatModeSystem.cs
@@ -1,16 +1,20 @@
using Content.Server.Actions.Events;
using Content.Server.Administration.Logs;
+using Content.Server.CombatMode.Disarm;
using Content.Server.Hands.Components;
using Content.Server.Popups;
using Content.Server.Weapon.Melee;
using Content.Shared.ActionBlocker;
using Content.Shared.Audio;
using Content.Shared.CombatMode;
+using Content.Shared.Damage;
using Content.Shared.Database;
+using Content.Shared.Stunnable;
using JetBrains.Annotations;
using Robust.Shared.Audio;
using Robust.Shared.Player;
using Robust.Shared.Random;
+using Robust.Shared.Physics;
namespace Content.Server.CombatMode
{
@@ -38,9 +42,17 @@ namespace Content.Server.CombatMode
if (!_actionBlockerSystem.CanAttack(args.Performer))
return;
+ if (TryComp(args.Performer, out var hands)
+ && hands.ActiveHand != null
+ && !hands.ActiveHand.IsEmpty)
+ {
+ _popupSystem.PopupEntity(Loc.GetString("disarm-action-free-hand"), args.Performer, Filter.Entities(args.Performer));
+ return;
+ }
+
EntityUid? inTargetHand = null;
- if (EntityManager.TryGetComponent(args.Target, out HandsComponent? targetHandsComponent)
+ if (TryComp(args.Target, out HandsComponent? targetHandsComponent)
&& targetHandsComponent.ActiveHand != null
&& !targetHandsComponent.ActiveHand.IsEmpty)
{
@@ -64,8 +76,8 @@ namespace Content.Server.CombatMode
var filterOther = filterAll.RemoveWhereAttachedEntity(e => e == args.Performer);
args.Handled = true;
-
- if (_random.Prob(component.DisarmFailChance))
+ var chance = CalculateDisarmChance(args.Performer, args.Target, inTargetHand, component);
+ if (_random.Prob(chance))
{
SoundSystem.Play(component.DisarmFailSound.GetSound(), Filter.Pvs(args.Performer), args.Performer, AudioHelpers.WithVariation(0.025f));
@@ -89,8 +101,40 @@ namespace Content.Server.CombatMode
SoundSystem.Play(component.DisarmSuccessSound.GetSound(), filterAll, args.Performer, AudioHelpers.WithVariation(0.025f));
_adminLogger.Add(LogType.DisarmedAction, $"{ToPrettyString(args.Performer):user} used disarm on {ToPrettyString(args.Target):target}");
- var eventArgs = new DisarmedEvent() { Target = args.Target, Source = args.Performer, PushProbability = component.DisarmPushChance };
+ var eventArgs = new DisarmedEvent() { Target = args.Target, Source = args.Performer, PushProbability = chance };
RaiseLocalEvent(args.Target, eventArgs);
}
+
+
+ private float CalculateDisarmChance(EntityUid disarmer, EntityUid disarmed, EntityUid? inTargetHand, SharedCombatModeComponent disarmerComp)
+ {
+ float healthMod = 0;
+ if (TryComp(disarmer, out var disarmerDamage) && TryComp(disarmed, out var disarmedDamage))
+ {
+ // I wanted this to consider their mob state thresholds too but I'm not touching that shitcode after having a go at this.
+ healthMod = (((float) disarmedDamage.TotalDamage - (float) disarmerDamage.TotalDamage) / 200); // Ex. You have 0 damage, they have 90, you get a 45% chance increase
+ }
+
+ float massMod = 0;
+
+ if (TryComp(disarmer, out var disarmerPhysics) && TryComp(disarmed, out var disarmedPhysics))
+ {
+ if (disarmerPhysics.FixturesMass != 0) // yeah this will never happen but let's not kill the server if it does
+ massMod = (((disarmedPhysics.FixturesMass / disarmerPhysics.FixturesMass - 1 ) / 2)); // Ex, you weigh 120, they weigh 70, you get a 29% bonus
+ }
+
+ float chance = (disarmerComp.BaseDisarmFailChance - healthMod - massMod);
+ if (HasComp(disarmer)) // might need to revisit this part after stamina damage, right now this is basically "pre-stun"
+ chance += 0.35f;
+ if (HasComp(disarmed))
+ chance -= 0.35f;
+
+ if (inTargetHand != null && TryComp(inTargetHand, out var malus))
+ {
+ chance += malus.Malus;
+ }
+
+ return Math.Clamp(chance, 0f, 1f);
+ }
}
}
diff --git a/Content.Server/CombatMode/Disarm/DisarmMalusComponent.cs b/Content.Server/CombatMode/Disarm/DisarmMalusComponent.cs
new file mode 100644
index 0000000000..9e5b454ae7
--- /dev/null
+++ b/Content.Server/CombatMode/Disarm/DisarmMalusComponent.cs
@@ -0,0 +1,16 @@
+namespace Content.Server.CombatMode.Disarm
+{
+ ///
+ /// Applies a malus to disarm attempts against this item.
+ ///
+ [RegisterComponent]
+ public sealed class DisarmMalusComponent : Component
+ {
+ ///
+ /// So, disarm chances are a % chance represented as a value between 0 and 1.
+ /// This default would be a 30% penalty to that.
+ ///
+ [DataField("malus")]
+ public float Malus = 0.3f;
+ }
+}
diff --git a/Content.Server/Construction/ConstructionSystem.Guided.cs b/Content.Server/Construction/ConstructionSystem.Guided.cs
index 8d657c5727..b366705774 100644
--- a/Content.Server/Construction/ConstructionSystem.Guided.cs
+++ b/Content.Server/Construction/ConstructionSystem.Guided.cs
@@ -30,7 +30,7 @@ namespace Content.Server.Construction
private void AddDeconstructVerb(EntityUid uid, ConstructionComponent component, GetVerbsEvent args)
{
- if (!args.CanAccess || !args.CanInteract)
+ if (!args.CanAccess || !args.CanInteract || args.Hands == null)
return;
if (component.TargetNode == component.DeconstructionNode ||
diff --git a/Content.Server/Cuffs/Components/CuffableComponent.cs b/Content.Server/Cuffs/Components/CuffableComponent.cs
index ef3b3dbc96..6b3aacbf2c 100644
--- a/Content.Server/Cuffs/Components/CuffableComponent.cs
+++ b/Content.Server/Cuffs/Components/CuffableComponent.cs
@@ -245,9 +245,7 @@ namespace Content.Server.Cuffs.Components
SoundSystem.Play(cuff.EndUncuffSound.GetSound(), Filter.Pvs(Owner), Owner);
Container.ForceRemove(cuffsToRemove.Value);
- var transform = _entMan.GetComponent(cuffsToRemove.Value);
- transform.AttachToGridOrMap();
- transform.WorldPosition = _entMan.GetComponent(Owner).WorldPosition;
+ _entMan.EntitySysManager.GetEntitySystem().PickupOrDrop(user, cuffsToRemove.Value);
if (cuff.BreakOnRemove)
{
diff --git a/Content.Server/Cuffs/CuffableSystem.cs b/Content.Server/Cuffs/CuffableSystem.cs
index a92a921ffd..7df6eaed8f 100644
--- a/Content.Server/Cuffs/CuffableSystem.cs
+++ b/Content.Server/Cuffs/CuffableSystem.cs
@@ -8,6 +8,7 @@ using Content.Shared.Popups;
using Content.Shared.Verbs;
using JetBrains.Annotations;
using Robust.Shared.Player;
+using Content.Shared.Hands.EntitySystems;
namespace Content.Server.Cuffs
{
@@ -23,14 +24,13 @@ namespace Content.Server.Cuffs
SubscribeLocalEvent(OnHandCountChanged);
SubscribeLocalEvent(OnUncuffAttempt);
-
SubscribeLocalEvent>(AddUncuffVerb);
}
private void AddUncuffVerb(EntityUid uid, CuffableComponent component, GetVerbsEvent args)
{
// Can the user access the cuffs, and is there even anything to uncuff?
- if (!args.CanAccess || component.CuffedHandCount == 0)
+ if (!args.CanAccess || component.CuffedHandCount == 0 || args.Hands == null)
return;
// We only check can interact if the user is not uncuffing themselves. As a result, the verb will show up
diff --git a/Content.Server/Disease/Components/DiseaseCarrierComponent.cs b/Content.Server/Disease/Components/DiseaseCarrierComponent.cs
index e9280235f3..56c71b46bc 100644
--- a/Content.Server/Disease/Components/DiseaseCarrierComponent.cs
+++ b/Content.Server/Disease/Components/DiseaseCarrierComponent.cs
@@ -1,13 +1,14 @@
using System.Linq;
using Content.Shared.Disease;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Set;
namespace Content.Server.Disease.Components
{
- [RegisterComponent]
///
- /// Allows the enity to be infected with diseases.
+ /// Allows the entity to be infected with diseases.
/// Please use only on mobs.
///
+ [RegisterComponent]
public sealed class DiseaseCarrierComponent : Component
{
///
@@ -15,22 +16,33 @@ namespace Content.Server.Disease.Components
///
[ViewVariables(VVAccess.ReadWrite)]
public List Diseases = new();
+
///
/// The carrier's resistance to disease
///
[DataField("diseaseResist")]
[ViewVariables(VVAccess.ReadWrite)]
public float DiseaseResist = 0f;
+
///
/// Diseases the carrier has had, used for immunity.
- ///
+ ///
[ViewVariables(VVAccess.ReadWrite)]
public List PastDiseases = new();
+
///
/// All the diseases the carrier has or has had.
/// Checked against when trying to add a disease
- ///
+ ///
[ViewVariables(VVAccess.ReadWrite)]
public List AllDiseases => PastDiseases.Concat(Diseases).ToList();
+
+ ///
+ /// A list of diseases which the entity does not
+ /// exhibit direct symptoms from. They still transmit
+ /// these diseases, just without symptoms.
+ ///
+ [ViewVariables, DataField("carrierDiseases", customTypeSerializer: typeof(PrototypeIdHashSetSerializer))]
+ public HashSet? CarrierDiseases;
}
}
diff --git a/Content.Server/Disease/DiseaseSystem.cs b/Content.Server/Disease/DiseaseSystem.cs
index 97367115df..f55ee6b03d 100644
--- a/Content.Server/Disease/DiseaseSystem.cs
+++ b/Content.Server/Disease/DiseaseSystem.cs
@@ -96,17 +96,23 @@ namespace Content.Server.Disease
for (var i = 0; i < carrierComp.Diseases.Count; i++) //this is a for-loop so that it doesn't break when new diseases are added
{
var disease = carrierComp.Diseases[i];
-
- var args = new DiseaseEffectArgs(carrierComp.Owner, disease, EntityManager);
disease.Accumulator += frameTime;
- if (disease.Accumulator >= disease.TickTime)
+
+ if (disease.Accumulator < disease.TickTime) continue;
+
+ // if the disease is on the silent disease list, don't do effects
+ var doEffects = carrierComp.CarrierDiseases?.Contains(disease.ID) != true;
+ var args = new DiseaseEffectArgs(carrierComp.Owner, disease, EntityManager);
+ disease.Accumulator -= disease.TickTime;
+
+ foreach (var cure in disease.Cures)
+ {
+ if (cure.Cure(args))
+ CureDisease(carrierComp, disease);
+ }
+
+ if (doEffects)
{
- disease.Accumulator -= disease.TickTime;
- foreach (var cure in disease.Cures)
- {
- if (cure.Cure(args))
- CureDisease(carrierComp, disease);
- }
foreach (var effect in disease.Effects)
{
if (_random.Prob(effect.Probability))
@@ -383,6 +389,14 @@ namespace Content.Server.Disease
TryAddDisease(carrier.Owner, disease, carrier);
}
+ public void TryInfect(DiseaseCarrierComponent carrier, string? disease, float chance = 0.7f, bool forced = false)
+ {
+ if (disease == null || !_prototypeManager.TryIndex(disease, out var d))
+ return;
+
+ TryInfect(carrier, d, chance, forced);
+ }
+
///
/// Plays a sneeze/cough popup if applicable
/// and then tries to infect anyone in range
diff --git a/Content.Server/Doors/Systems/DoorSystem.cs b/Content.Server/Doors/Systems/DoorSystem.cs
index f2f635618b..2c7dd7b715 100644
--- a/Content.Server/Doors/Systems/DoorSystem.cs
+++ b/Content.Server/Doors/Systems/DoorSystem.cs
@@ -305,7 +305,7 @@ public sealed class DoorSystem : SharedDoorSystem
foreach (var other in PhysicsSystem.GetCollidingEntities(body))
{
if (Tags.HasTag(other.Owner, "DoorBumpOpener") &&
- TryOpen(component.Owner, component, other.Owner)) break;
+ TryOpen(component.Owner, component, other.Owner, false, quiet: true)) break;
}
}
}
diff --git a/Content.Server/Dragon/DragonComponent.cs b/Content.Server/Dragon/DragonComponent.cs
new file mode 100644
index 0000000000..3de7deff32
--- /dev/null
+++ b/Content.Server/Dragon/DragonComponent.cs
@@ -0,0 +1,108 @@
+using Content.Shared.Actions.ActionTypes;
+using Robust.Shared.Containers;
+using System.Threading;
+using Content.Shared.Actions;
+using Content.Shared.Chemistry.Reagent;
+using Content.Shared.Sound;
+using Content.Shared.Storage;
+using Content.Shared.Whitelist;
+using Robust.Shared.Audio;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
+
+namespace Content.Server.Dragon
+{
+ [RegisterComponent]
+ public sealed class DragonComponent : Component
+ {
+ ///
+ /// The chemical ID injected upon devouring
+ ///
+ [DataField("devourChemical", customTypeSerializer: typeof(PrototypeIdSerializer))]
+ public string DevourChem = "Ichor";
+
+ ///
+ /// The amount of ichor injected per devour
+ ///
+ [DataField("devourHealRate")]
+ public float DevourHealRate = 15f;
+
+ [DataField("devourActionId", customTypeSerializer: typeof(PrototypeIdSerializer))]
+ public string DevourActionId = "DragonDevour";
+
+ [DataField("devourAction")]
+ public EntityTargetAction? DevourAction;
+
+ [DataField("spawnActionId", customTypeSerializer: typeof(PrototypeIdSerializer))]
+ public string SpawnActionId = "DragonSpawn";
+
+ [DataField("spawnAction")]
+ public InstantAction? SpawnAction;
+
+ ///
+ /// The amount of time it takes to devour something
+ ///
+ /// NOTE: original intended design was to increase this proportionally with damage thresholds, but those proved quite difficult to get consistently. right now it devours the structure at a fixed timer.
+ ///
+ ///
+ [DataField("structureDevourTime")]
+ public float StructureDevourTime = 10f;
+
+ [DataField("devourTime")]
+ public float DevourTime = 2f;
+
+ [DataField("spawnCount")] public int SpawnsLeft = 2;
+
+ [DataField("maxSpawnCount")] public int MaxSpawns = 2;
+
+ [DataField("spawnProto", customTypeSerializer: typeof(PrototypeIdSerializer))]
+ public string? SpawnPrototype = "MobCarpDragon";
+
+ [ViewVariables(VVAccess.ReadWrite), DataField("soundDeath")]
+ public SoundSpecifier? SoundDeath = new SoundPathSpecifier("/Audio/Animals/space_dragon_roar.ogg");
+
+ [ViewVariables(VVAccess.ReadWrite), DataField("soundDevour")]
+ public SoundSpecifier? SoundDevour = new SoundPathSpecifier("/Audio/Effects/demon_consume.ogg")
+ {
+ Params = AudioParams.Default.WithVolume(-3f),
+ };
+
+ [ViewVariables(VVAccess.ReadWrite), DataField("soundStructureDevour")]
+ public SoundSpecifier? SoundStructureDevour = new SoundPathSpecifier("/Audio/Machines/airlock_creaking.ogg")
+ {
+ Params = AudioParams.Default.WithVolume(-3f),
+ };
+
+ [ViewVariables(VVAccess.ReadWrite), DataField("soundRoar")]
+ public SoundSpecifier? SoundRoar =
+ new SoundPathSpecifier("/Audio/Animals/space_dragon_roar.ogg")
+ {
+ Params = AudioParams.Default.WithVolume(-3f),
+ };
+
+ public CancellationTokenSource? CancelToken;
+
+ [ViewVariables(VVAccess.ReadWrite), DataField("devourWhitelist")]
+ public EntityWhitelist? DevourWhitelist = new()
+ {
+ Components = new string[]
+ {
+ "Door",
+ "MobState",
+ },
+ Tags = new List()
+ {
+ "Wall",
+ }
+ };
+
+ ///
+ /// Where the entities go when dragon devours them, empties when the dragon is butchered.
+ ///
+ public Container DragonStomach = default!;
+ }
+
+ public sealed class DragonDevourActionEvent : EntityTargetActionEvent {}
+
+ public sealed class DragonSpawnActionEvent : InstantActionEvent {}
+}
diff --git a/Content.Server/Dragon/DragonSystem.cs b/Content.Server/Dragon/DragonSystem.cs
new file mode 100644
index 0000000000..8ef43a1bdd
--- /dev/null
+++ b/Content.Server/Dragon/DragonSystem.cs
@@ -0,0 +1,209 @@
+using Content.Server.Body.Systems;
+using Content.Server.DoAfter;
+using Content.Server.Popups;
+using Content.Shared.Actions;
+using Content.Shared.CharacterAppearance.Components;
+using Content.Shared.Chemistry.Components;
+using Content.Shared.Damage;
+using Content.Shared.MobState;
+using Content.Shared.MobState.Components;
+using Content.Shared.Tag;
+using Robust.Shared.Audio;
+using Robust.Shared.Containers;
+using Robust.Shared.Player;
+using System.Threading;
+using Content.Shared.MobState.State;
+using Content.Shared.Doors.Components;
+
+namespace Content.Server.Dragon
+{
+ public sealed class DragonSystem : EntitySystem
+ {
+ [Dependency] private readonly SharedActionsSystem _actionsSystem = default!;
+ [Dependency] private readonly DoAfterSystem _doAfterSystem = default!;
+ [Dependency] private readonly PopupSystem _popupSystem = default!;
+ [Dependency] private readonly BloodstreamSystem _bloodstreamSystem = default!;
+ [Dependency] private readonly SharedContainerSystem _containerSystem = default!;
+ [Dependency] private readonly TagSystem _tagSystem = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(OnStartup);
+ SubscribeLocalEvent(OnDragonDevourComplete);
+ SubscribeLocalEvent(OnDevourAction);
+ SubscribeLocalEvent(OnDragonSpawnAction);
+
+ SubscribeLocalEvent(OnDragonStructureDevourComplete);
+ SubscribeLocalEvent(OnDragonDevourCancelled);
+ SubscribeLocalEvent(OnMobStateChanged);
+ }
+
+ private void OnMobStateChanged(EntityUid uid, DragonComponent component, MobStateChangedEvent args)
+ {
+ //Empties the stomach upon death
+ //TODO: Do this when the dragon gets butchered instead
+ if (args.CurrentMobState.IsDead())
+ {
+ if (component.SoundDeath != null)
+ SoundSystem.Play(component.SoundDeath.GetSound(), Filter.Pvs(uid, entityManager: EntityManager), uid, component.SoundDeath.Params);
+
+ component.DragonStomach.EmptyContainer();
+ }
+ }
+
+ private void OnDragonDevourCancelled(EntityUid uid, DragonComponent component, DragonDevourCancelledEvent args)
+ {
+ component.CancelToken = null;
+ }
+
+ private void OnDragonDevourComplete(EntityUid uid, DragonComponent component, DragonDevourComplete args)
+ {
+ component.CancelToken = null;
+ var ichorInjection = new Solution(component.DevourChem, component.DevourHealRate);
+
+ //Humanoid devours allow dragon to get eggs, corpses included
+ if (EntityManager.HasComponent(args.Target))
+ {
+ // Add a spawn for a consumed humanoid
+ component.SpawnsLeft = Math.Min(component.SpawnsLeft + 1, component.MaxSpawns);
+ }
+ //Non-humanoid mobs can only heal dragon for half the normal amount, with no additional spawn tickets
+ else
+ {
+ ichorInjection.ScaleSolution(0.5f);
+ }
+
+ _bloodstreamSystem.TryAddToChemicals(uid, ichorInjection);
+ component.DragonStomach.Insert(args.Target);
+
+ if (component.SoundDevour != null)
+ SoundSystem.Play(component.SoundDevour.GetSound(), Filter.Pvs(uid, entityManager: EntityManager), uid, component.SoundDevour.Params);
+ }
+
+ private void OnDragonStructureDevourComplete(EntityUid uid, DragonComponent component, DragonStructureDevourComplete args)
+ {
+ component.CancelToken = null;
+ //TODO: Figure out a better way of removing structures via devour that still entails standing still and waiting for a DoAfter. Somehow.
+ EntityManager.QueueDeleteEntity(args.Target);
+
+ if (component.SoundDevour != null)
+ SoundSystem.Play(component.SoundDevour.GetSound(), Filter.Pvs(args.User, entityManager: EntityManager), uid, component.SoundDevour.Params);
+ }
+
+ private void OnStartup(EntityUid uid, DragonComponent component, ComponentStartup args)
+ {
+ component.SpawnsLeft = Math.Min(component.SpawnsLeft, component.MaxSpawns);
+
+ //Dragon doesn't actually chew, since he sends targets right into his stomach.
+ //I did it mom, I added ERP content into upstream. Legally!
+ component.DragonStomach = _containerSystem.EnsureContainer(uid, "dragon_stomach");
+
+ if (component.DevourAction != null)
+ _actionsSystem.AddAction(uid, component.DevourAction, null);
+
+ if (component.SpawnAction != null)
+ _actionsSystem.AddAction(uid, component.SpawnAction, null);
+
+ if (component.SoundRoar != null)
+ SoundSystem.Play(component.SoundRoar.GetSound(), Filter.Pvs(uid, 4f, EntityManager), uid, component.SoundRoar.Params);
+ }
+
+ ///
+ /// The devour action
+ ///
+ private void OnDevourAction(EntityUid uid, DragonComponent component, DragonDevourActionEvent args)
+ {
+ if (component.CancelToken != null ||
+ args.Handled ||
+ component.DevourWhitelist?.IsValid(args.Target, EntityManager) != true) return;
+
+ args.Handled = true;
+ var target = args.Target;
+
+ // Structure and mob devours handled differently.
+ if (EntityManager.TryGetComponent(target, out MobStateComponent? targetState))
+ {
+ switch (targetState.CurrentState)
+ {
+ case SharedCriticalMobState:
+ case SharedDeadMobState:
+ component.CancelToken = new CancellationTokenSource();
+
+ _doAfterSystem.DoAfter(new DoAfterEventArgs(uid, component.DevourTime, component.CancelToken.Token, target)
+ {
+ UserFinishedEvent = new DragonDevourComplete(uid, target),
+ UserCancelledEvent = new DragonDevourCancelledEvent(),
+ BreakOnTargetMove = true,
+ BreakOnUserMove = true,
+ BreakOnStun = true,
+ });
+ break;
+ default:
+ _popupSystem.PopupEntity(Loc.GetString("devour-action-popup-message-fail-target-alive"), uid, Filter.Entities(uid));
+ break;
+ }
+
+ return;
+ }
+
+ _popupSystem.PopupEntity(Loc.GetString("devour-action-popup-message-structure"), uid, Filter.Entities(uid));
+
+ if (component.SoundStructureDevour != null)
+ SoundSystem.Play(component.SoundStructureDevour.GetSound(), Filter.Pvs(uid, entityManager: EntityManager), uid, component.SoundStructureDevour.Params);
+
+ component.CancelToken = new CancellationTokenSource();
+
+ _doAfterSystem.DoAfter(new DoAfterEventArgs(uid, component.StructureDevourTime, component.CancelToken.Token, target)
+ {
+ UserFinishedEvent = new DragonStructureDevourComplete(uid, target),
+ UserCancelledEvent = new DragonDevourCancelledEvent(),
+ BreakOnTargetMove = true,
+ BreakOnUserMove = true,
+ BreakOnStun = true,
+ });
+ }
+
+ private void OnDragonSpawnAction(EntityUid dragonuid, DragonComponent component, DragonSpawnActionEvent args)
+ {
+ if (component.SpawnPrototype == null) return;
+
+ // If dragon has spawns then add one.
+ if (component.SpawnsLeft > 0)
+ {
+ Spawn(component.SpawnPrototype, Transform(dragonuid).Coordinates);
+ component.SpawnsLeft--;
+ return;
+ }
+
+ _popupSystem.PopupEntity(Loc.GetString("dragon-spawn-action-popup-message-fail-no-eggs"), dragonuid, Filter.Entities(dragonuid));
+ }
+
+ private sealed class DragonDevourComplete : EntityEventArgs
+ {
+ public EntityUid User { get; }
+ public EntityUid Target { get; }
+
+ public DragonDevourComplete(EntityUid user, EntityUid target)
+ {
+ User = user;
+ Target = target;
+ }
+ }
+
+ private sealed class DragonStructureDevourComplete : EntityEventArgs
+ {
+ public EntityUid User { get; }
+ public EntityUid Target { get; }
+
+ public DragonStructureDevourComplete(EntityUid user, EntityUid target)
+ {
+ User = user;
+ Target = target;
+ }
+ }
+
+ private sealed class DragonDevourCancelledEvent : EntityEventArgs {}
+ }
+}
diff --git a/Content.Server/Engineering/EntitySystems/DisassembleOnAltVerbSystem.cs b/Content.Server/Engineering/EntitySystems/DisassembleOnAltVerbSystem.cs
index 3b6fc91fdf..af7b7dc370 100644
--- a/Content.Server/Engineering/EntitySystems/DisassembleOnAltVerbSystem.cs
+++ b/Content.Server/Engineering/EntitySystems/DisassembleOnAltVerbSystem.cs
@@ -18,7 +18,7 @@ namespace Content.Server.Engineering.EntitySystems
}
private void AddDisassembleVerb(EntityUid uid, DisassembleOnAltVerbComponent component, GetVerbsEvent args)
{
- if (!args.CanInteract || !args.CanAccess)
+ if (!args.CanInteract || !args.CanAccess || args.Hands == null)
return;
AlternativeVerb verb = new()
diff --git a/Content.Server/Entry/IgnoredComponents.cs b/Content.Server/Entry/IgnoredComponents.cs
index a223343439..f5ab20d53d 100644
--- a/Content.Server/Entry/IgnoredComponents.cs
+++ b/Content.Server/Entry/IgnoredComponents.cs
@@ -10,6 +10,7 @@ namespace Content.Server.Entry
"InteractionOutline",
"MeleeWeaponArcAnimation",
"EffectVisuals",
+ "DamageStateVisuals",
"AnimationsTest",
"ItemStatus",
"VehicleVisuals",
@@ -24,6 +25,7 @@ namespace Content.Server.Entry
"HandheldGPS",
"SpentAmmoVisuals",
"MagazineVisuals",
+ "PowerCellVisuals",
"ToggleableLightVisuals",
"CableVisualizer",
"PotencyVisuals",
diff --git a/Content.Server/Flash/FlashSystem.cs b/Content.Server/Flash/FlashSystem.cs
index e3df2eb3e0..a8ababd66b 100644
--- a/Content.Server/Flash/FlashSystem.cs
+++ b/Content.Server/Flash/FlashSystem.cs
@@ -195,12 +195,13 @@ namespace Content.Server.Flash
private void OnInventoryFlashAttempt(EntityUid uid, InventoryComponent component, FlashAttemptEvent args)
{
- // Forward the event to a worn helmet, if one is equipped.
- if (_inventorySystem.TryGetSlotEntity(uid, "head", out var maskSlotEntity, component))
- RaiseLocalEvent(maskSlotEntity.Value, args);
- // Forward the event to the glasses, if any.
- if(!args.Cancelled && _inventorySystem.TryGetSlotEntity(uid, "eyes", out var eyeSlotEntity, component))
- RaiseLocalEvent(eyeSlotEntity.Value, args);
+ foreach (var slot in new string[]{"head", "eyes", "mask"})
+ {
+ if (args.Cancelled)
+ break;
+ if (_inventorySystem.TryGetSlotEntity(uid, slot, out var item, component))
+ RaiseLocalEvent(item.Value, args);
+ }
}
private void OnFlashImmunityFlashAttempt(EntityUid uid, FlashImmunityComponent component, FlashAttemptEvent args)
diff --git a/Content.Server/Holosign/HolosignProjectorComponent.cs b/Content.Server/Holosign/HolosignProjectorComponent.cs
index c85356e173..be7c712c11 100644
--- a/Content.Server/Holosign/HolosignProjectorComponent.cs
+++ b/Content.Server/Holosign/HolosignProjectorComponent.cs
@@ -6,28 +6,14 @@ namespace Content.Server.Holosign
[RegisterComponent]
public sealed class HolosignProjectorComponent : Component
{
- [ViewVariables]
- [DataField("maxCharges")]
- public int MaxCharges = 6;
-
- [ViewVariables(VVAccess.ReadWrite), DataField("charges")]
- public int CurrentCharges = 6;
-
[ViewVariables(VVAccess.ReadWrite)]
[DataField("signProto", customTypeSerializer:typeof(PrototypeIdSerializer))]
public string SignProto = "HolosignWetFloor";
///
- /// When the holosign was last used.
+ /// How much charge a single use expends.
///
- [ViewVariables(VVAccess.ReadWrite), DataField("lastUse")]
- public TimeSpan LastUsed = TimeSpan.Zero;
-
- ///
- /// How long it takes for 1 charge to accumulate.
- ///
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("rechargeTime")]
- public TimeSpan RechargeTime = TimeSpan.FromSeconds(30);
+ [ViewVariables(VVAccess.ReadWrite), DataField("chargeUse")]
+ public float ChargeUse = 50f;
}
}
diff --git a/Content.Server/Holosign/HolosignSystem.cs b/Content.Server/Holosign/HolosignSystem.cs
index faa1deba4a..11e8ab2b1d 100644
--- a/Content.Server/Holosign/HolosignSystem.cs
+++ b/Content.Server/Holosign/HolosignSystem.cs
@@ -1,13 +1,16 @@
using Content.Shared.Interaction.Events;
using Content.Shared.Examine;
using Content.Server.Coordinates.Helpers;
+using Content.Server.Power.Components;
+using Content.Server.PowerCell;
+using Content.Shared.PowerCell.Components;
using Robust.Shared.Timing;
namespace Content.Server.Holosign
{
public sealed class HolosignSystem : EntitySystem
{
- [Dependency] private readonly IGameTiming _timing = default!;
+ [Dependency] private readonly PowerCellSystem _cellSystem = default!;
public override void Initialize()
{
@@ -16,42 +19,51 @@ namespace Content.Server.Holosign
SubscribeLocalEvent(OnExamine);
}
- private int GetCharges(HolosignProjectorComponent component)
- {
- return component.CurrentCharges + (int) ((_timing.CurTime - component.LastUsed).TotalSeconds / component.RechargeTime.TotalSeconds);
- }
-
private void OnExamine(EntityUid uid, HolosignProjectorComponent component, ExaminedEvent args)
{
// TODO: This should probably be using an itemstatus
// TODO: I'm too lazy to do this rn but it's literally copy-paste from emag.
- var timeRemaining = (component.LastUsed + component.RechargeTime * (component.MaxCharges - component.CurrentCharges) - _timing.CurTime).TotalSeconds % component.RechargeTime.TotalSeconds;
- var charges = GetCharges(component);
+ _cellSystem.TryGetBatteryFromSlot(uid, out var battery);
+ var charges = UsesRemaining(component, battery);
+ var maxCharges = MaxUses(component, battery);
args.PushMarkup(Loc.GetString("emag-charges-remaining", ("charges", charges)));
- if (charges == component.MaxCharges)
+
+ if (charges > 0 && charges == maxCharges)
{
args.PushMarkup(Loc.GetString("emag-max-charges"));
return;
}
- args.PushMarkup(Loc.GetString("emag-recharging", ("seconds", Math.Round(timeRemaining))));
}
private void OnUse(EntityUid uid, HolosignProjectorComponent component, UseInHandEvent args)
{
- if (component.CurrentCharges == 0 || args.Handled)
+ if (args.Handled ||
+ !_cellSystem.TryGetBatteryFromSlot(uid, out var battery) ||
+ !battery.TryUseCharge(component.ChargeUse))
return;
// TODO: Too tired to deal
var holo = EntityManager.SpawnEntity(component.SignProto, Transform(args.User).Coordinates.SnapToGrid(EntityManager));
Transform(holo).Anchored = true;
- // Don't reset last use time if it's already accumulating.
- if (component.CurrentCharges == component.MaxCharges)
- component.LastUsed = _timing.CurTime;
-
- component.CurrentCharges--;
args.Handled = true;
}
+
+ private int UsesRemaining(HolosignProjectorComponent component, BatteryComponent? battery = null)
+ {
+ if (battery == null ||
+ component.ChargeUse == 0f) return 0;
+
+ return (int) (battery.CurrentCharge / component.ChargeUse);
+ }
+
+ private int MaxUses(HolosignProjectorComponent component, BatteryComponent? battery = null)
+ {
+ if (battery == null ||
+ component.ChargeUse == 0f) return 0;
+
+ return (int) (battery.MaxCharge / component.ChargeUse);
+ }
}
}
diff --git a/Content.Server/Interaction/InteractionSystem.cs b/Content.Server/Interaction/InteractionSystem.cs
index 4cbd608afa..591ef3b1a9 100644
--- a/Content.Server/Interaction/InteractionSystem.cs
+++ b/Content.Server/Interaction/InteractionSystem.cs
@@ -197,6 +197,12 @@ namespace Content.Server.Interaction
if (!unobstructed)
return;
}
+ else if (ContainerSystem.IsEntityInContainer(user))
+ {
+ // No wide attacking while in containers (holos, lockers, etc).
+ // Can't think of a valid case where you would want this.
+ return;
+ }
// Verify user has a hand, and find what object they are currently holding in their active hand
if (TryComp(user, out HandsComponent? hands))
diff --git a/Content.Server/Kitchen/EntitySystems/SharpSystem.cs b/Content.Server/Kitchen/EntitySystems/SharpSystem.cs
index 0ce6da6d0d..918370c949 100644
--- a/Content.Server/Kitchen/EntitySystems/SharpSystem.cs
+++ b/Content.Server/Kitchen/EntitySystems/SharpSystem.cs
@@ -110,7 +110,7 @@ public sealed class SharpSystem : EntitySystem
private void OnGetInteractionVerbs(EntityUid uid, SharedButcherableComponent component, GetVerbsEvent args)
{
- if (component.Type != ButcheringType.Knife)
+ if (component.Type != ButcheringType.Knife || args.Hands == null)
return;
bool disabled = false;
diff --git a/Content.Server/Light/EntitySystems/HandheldLightSystem.cs b/Content.Server/Light/EntitySystems/HandheldLightSystem.cs
index 7d589ba853..562f6c0eaf 100644
--- a/Content.Server/Light/EntitySystems/HandheldLightSystem.cs
+++ b/Content.Server/Light/EntitySystems/HandheldLightSystem.cs
@@ -1,6 +1,7 @@
using Content.Server.Actions;
using Content.Server.Light.Components;
using Content.Server.Popups;
+using Content.Server.Power.Components;
using Content.Server.PowerCell;
using Content.Shared.Actions;
using Content.Shared.Actions.ActionTypes;
@@ -220,7 +221,8 @@ namespace Content.Server.Light.EntitySystems
{
if (component.Activated) return false;
- if (!_powerCell.TryGetBatteryFromSlot(component.Owner, out var battery))
+ if (!_powerCell.TryGetBatteryFromSlot(component.Owner, out var battery) &&
+ !TryComp(component.Owner, out battery))
{
SoundSystem.Play(component.TurnOnFailSound.GetSound(), Filter.Pvs(component.Owner, entityManager: EntityManager), component.Owner);
_popup.PopupEntity(Loc.GetString("handheld-light-component-cell-missing-message"), component.Owner, Filter.Entities(user));
@@ -253,7 +255,8 @@ namespace Content.Server.Light.EntitySystems
public void TryUpdate(HandheldLightComponent component, float frameTime)
{
- if (!_powerCell.TryGetBatteryFromSlot(component.Owner, out var battery))
+ if (!_powerCell.TryGetBatteryFromSlot(component.Owner, out var battery) &&
+ !TryComp(component.Owner, out battery))
{
TurnOff(component, false);
return;
diff --git a/Content.Server/Medical/SuitSensors/SuitSensorSystem.cs b/Content.Server/Medical/SuitSensors/SuitSensorSystem.cs
index 6b6bc88f54..c80e1eabd1 100644
--- a/Content.Server/Medical/SuitSensors/SuitSensorSystem.cs
+++ b/Content.Server/Medical/SuitSensors/SuitSensorSystem.cs
@@ -138,7 +138,7 @@ namespace Content.Server.Medical.SuitSensors
return;
// standard interaction checks
- if (!args.CanAccess || !args.CanInteract)
+ if (!args.CanAccess || !args.CanInteract || args.Hands == null)
return;
args.Verbs.UnionWith(new[]
diff --git a/Content.Server/Physics/Controllers/MoverController.cs b/Content.Server/Physics/Controllers/MoverController.cs
index cd24fcf4b9..208534dcdd 100644
--- a/Content.Server/Physics/Controllers/MoverController.cs
+++ b/Content.Server/Physics/Controllers/MoverController.cs
@@ -1,5 +1,5 @@
using Content.Server.Shuttles.Components;
-using Content.Server.Shuttles.EntitySystems;
+using Content.Server.Shuttles.Systems;
using Content.Shared.Vehicle.Components;
using Content.Shared.Movement;
using Content.Shared.Movement.Components;
@@ -123,7 +123,7 @@ namespace Content.Server.Physics.Controllers
angularInput += sprint.X;
}
break;
- case ShuttleMode.Docking:
+ case ShuttleMode.Strafing:
// No angular input possible
foreach (var (pilot, mover) in pilots)
{
diff --git a/Content.Server/Polymorph/Systems/PolymorphableSystem.cs b/Content.Server/Polymorph/Systems/PolymorphableSystem.cs
index a2d2771dc7..90641a4baf 100644
--- a/Content.Server/Polymorph/Systems/PolymorphableSystem.cs
+++ b/Content.Server/Polymorph/Systems/PolymorphableSystem.cs
@@ -63,7 +63,7 @@ namespace Content.Server.Polymorph.Systems
///
/// The entity that will be transformed
/// The id of the polymorph prototype
- public EntityUid? PolymorphEntity(EntityUid target, String id)
+ public EntityUid? PolymorphEntity(EntityUid target, string id)
{
if (!_proto.TryIndex(id, out var proto))
{
@@ -99,9 +99,8 @@ namespace Content.Server.Polymorph.Systems
comp.Prototype = proto;
RaiseLocalEvent(child, new PolymorphComponentSetupEvent());
- var targetXform = Transform(target);
var childXform = Transform(child);
- childXform.LocalRotation = targetXform.LocalRotation;
+ childXform.LocalRotation = targetTransformComp.LocalRotation;
if (_container.TryGetContainingContainer(target, out var cont))
cont.Insert(child);
diff --git a/Content.Server/Polymorph/Systems/PolymorphedEntitySystem.cs b/Content.Server/Polymorph/Systems/PolymorphedEntitySystem.cs
index b14354acef..ced781d2de 100644
--- a/Content.Server/Polymorph/Systems/PolymorphedEntitySystem.cs
+++ b/Content.Server/Polymorph/Systems/PolymorphedEntitySystem.cs
@@ -49,6 +49,9 @@ namespace Content.Server.Polymorph.Systems
if (!TryComp(uid, out var component))
return;
+ if (Deleted(component.Parent))
+ return;
+
var proto = component.Prototype;
var uidXform = Transform(uid);
diff --git a/Content.Server/Radar/RadarConsoleComponent.cs b/Content.Server/Radar/RadarConsoleComponent.cs
deleted file mode 100644
index 9e101a6e39..0000000000
--- a/Content.Server/Radar/RadarConsoleComponent.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Content.Server.Radar;
-
-[RegisterComponent]
-public sealed class RadarConsoleComponent : Component
-{
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("range")]
- public float Range = 512f;
-}
diff --git a/Content.Server/Radar/RadarConsoleSystem.cs b/Content.Server/Radar/RadarConsoleSystem.cs
deleted file mode 100644
index db3a0e0834..0000000000
--- a/Content.Server/Radar/RadarConsoleSystem.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-using Content.Server.UserInterface;
-using Content.Shared.Radar;
-using Robust.Shared.Map;
-
-namespace Content.Server.Radar;
-
-public sealed class RadarConsoleSystem : EntitySystem
-{
- [Dependency] private readonly IMapManager _mapManager = default!;
-
- private static float Frequency = 1.5f;
-
- private float _accumulator;
-
- public override void Update(float frameTime)
- {
- _accumulator += frameTime;
-
- if (_accumulator < Frequency)
- return;
-
- _accumulator -= Frequency;
-
- foreach (var (component, xform) in EntityManager.EntityQuery())
- {
- var s = component.Owner.GetUIOrNull(RadarConsoleUiKey.Key);
-
- if (s is null || s.SubscribedSessions.Count == 0)
- continue;
-
- var (radarPos, _, radarInvMatrix) = xform.GetWorldPositionRotationInvMatrix();
-
- var mapId = xform.MapID;
- var objects = new List();
-
- _mapManager.FindGridsIntersectingEnumerator(mapId, new Box2(radarPos - component.Range, radarPos + component.Range), out var enumerator, true);
-
- while (enumerator.MoveNext(out var grid))
- {
- var phy = Comp(grid.GridEntityId);
- var transform = Transform(grid.GridEntityId);
-
- if (phy.Mass < 50)
- continue;
-
- var rad = Math.Log2(phy.Mass);
- var gridCenter = transform.WorldMatrix.Transform(phy.LocalCenter);
-
- var pos = radarInvMatrix.Transform(gridCenter);
- pos.Y = -pos.Y; // Robust has an inverted Y, like BYOND. This undoes that.
-
- if (pos.Length > component.Range)
- continue;
-
- objects.Add(new RadarObjectData {Color = Color.Aqua, Position = pos, Radius = (float)rad});
- }
-
- s.SetState(new RadarConsoleBoundInterfaceState(component.Range, objects.ToArray()));
- }
- }
-}
diff --git a/Content.Server/RatKing/RatKingComponent.cs b/Content.Server/RatKing/RatKingComponent.cs
new file mode 100644
index 0000000000..4685d14cf2
--- /dev/null
+++ b/Content.Server/RatKing/RatKingComponent.cs
@@ -0,0 +1,54 @@
+using Content.Shared.Actions.ActionTypes;
+using Content.Shared.Disease;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
+
+namespace Content.Server.RatKing
+{
+ [RegisterComponent]
+ public sealed class RatKingComponent : Component
+ {
+ ///
+ /// The action for the Raise Army ability
+ ///
+ [DataField("actionRaiseArmy", required: true)]
+ public InstantAction ActionRaiseArmy = new();
+
+ ///
+ /// The amount of hunger one use of Raise Army consumes
+ ///
+ [ViewVariables(VVAccess.ReadWrite), DataField("hungerPerArmyUse", required: true)]
+ public float HungerPerArmyUse = 25f;
+
+ ///
+ /// The entity prototype of the mob that Raise Army summons
+ ///
+ [ViewVariables(VVAccess.ReadWrite), DataField("armyMobSpawnId", customTypeSerializer: typeof(PrototypeIdSerializer))]
+ public string ArmyMobSpawnId = "MobRatServant";
+
+ ///
+ /// The action for the Domain ability
+ ///
+ [ViewVariables, DataField("actionDomain", required: true)]
+ public InstantAction ActionDomain = new();
+
+ ///
+ /// The amount of hunger one use of Domain consumes
+ ///
+ [ViewVariables(VVAccess.ReadWrite), DataField("hungerPerDomainUse", required: true)]
+ public float HungerPerDomainUse = 50f;
+
+ ///
+ /// The disease prototype id that the Domain ability spreads
+ ///
+ [ViewVariables, DataField("domainDiseaseId", customTypeSerializer: typeof(PrototypeIdSerializer))]
+ public string DomainDiseaseId = "Plague";
+
+ ///
+ /// The range of the Domain ability.
+ ///
+ [ViewVariables(VVAccess.ReadWrite), DataField("domainRange")]
+ public float DomainRange = 3f;
+
+ }
+};
diff --git a/Content.Server/RatKing/RatKingSystem.cs b/Content.Server/RatKing/RatKingSystem.cs
new file mode 100644
index 0000000000..c39dd090ad
--- /dev/null
+++ b/Content.Server/RatKing/RatKingSystem.cs
@@ -0,0 +1,93 @@
+using Content.Server.Actions;
+using Content.Server.Disease;
+using Content.Server.Disease.Components;
+using Content.Server.Nutrition.Components;
+using Content.Server.Popups;
+using Content.Shared.Actions;
+using Robust.Shared.Player;
+
+namespace Content.Server.RatKing
+{
+ public sealed class RatKingSystem : EntitySystem
+ {
+ [Dependency] private readonly PopupSystem _popup = default!;
+ [Dependency] private readonly ActionsSystem _action = default!;
+ [Dependency] private readonly DiseaseSystem _disease = default!;
+ [Dependency] private readonly EntityLookupSystem _lookup = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(OnStartup);
+
+ SubscribeLocalEvent(OnRaiseArmy);
+ SubscribeLocalEvent(OnDomain);
+ }
+
+ private void OnStartup(EntityUid uid, RatKingComponent component, ComponentStartup args)
+ {
+ _action.AddAction(uid, component.ActionRaiseArmy, null);
+ _action.AddAction(uid, component.ActionDomain, null);
+ }
+
+ ///
+ /// Summons an allied rat servant at the King, costing a small amount of hunger
+ ///
+ private void OnRaiseArmy(EntityUid uid, RatKingComponent component, RatKingRaiseArmyActionEvent args)
+ {
+ if (args.Handled)
+ return;
+
+ if (!TryComp(uid, out var hunger))
+ return;
+
+ //make sure the hunger doesn't go into the negatives
+ if (hunger.CurrentHunger < component.HungerPerArmyUse)
+ {
+ _popup.PopupEntity(Loc.GetString("rat-king-too-hungry"), uid, Filter.Entities(uid));
+ return;
+ }
+ args.Handled = true;
+ hunger.CurrentHunger -= component.HungerPerArmyUse;
+ Spawn(component.ArmyMobSpawnId, Transform(uid).Coordinates); //spawn the little mouse boi
+ }
+
+ ///
+ /// Gets all of the nearby disease-carrying entities in a radius
+ /// and gives them the specified disease. It has a hunger cost as well
+ ///
+ private void OnDomain(EntityUid uid, RatKingComponent component, RatKingDomainActionEvent args)
+ {
+ if (args.Handled)
+ return;
+
+ if (!TryComp(uid, out var hunger))
+ return;
+
+ //make sure the hunger doesn't go into the negatives
+ if (hunger.CurrentHunger < component.HungerPerDomainUse)
+ {
+ _popup.PopupEntity(Loc.GetString("rat-king-too-hungry"), uid, Filter.Entities(uid));
+ return;
+ }
+ args.Handled = true;
+ hunger.CurrentHunger -= component.HungerPerDomainUse;
+
+ _popup.PopupEntity(Loc.GetString("rat-king-domain-popup"), uid, Filter.Pvs(uid, default, EntityManager));
+
+ var tstalker = GetEntityQuery();
+ foreach (var entity in _lookup.GetEntitiesInRange(uid, component.DomainRange)) //go through all of them, filtering only those in range that are not the king itself
+ {
+ if (entity == uid)
+ continue;
+
+ if (tstalker.TryGetComponent(entity, out var diseasecomp))
+ _disease.TryInfect(diseasecomp, component.DomainDiseaseId); //infect them with w/e disease
+ }
+ }
+ }
+
+ public sealed class RatKingRaiseArmyActionEvent : InstantActionEvent { };
+ public sealed class RatKingDomainActionEvent : InstantActionEvent { };
+};
diff --git a/Content.Server/Remotes/DoorRemoteSystem.cs b/Content.Server/Remotes/DoorRemoteSystem.cs
index eaa293f990..61a775be97 100644
--- a/Content.Server/Remotes/DoorRemoteSystem.cs
+++ b/Content.Server/Remotes/DoorRemoteSystem.cs
@@ -1,5 +1,4 @@
using Robust.Shared.Player;
-using Robust.Shared.Audio;
using Content.Shared.Interaction;
using Content.Shared.Popups;
using Content.Shared.Doors.Components;
@@ -8,7 +7,9 @@ using Content.Shared.Physics;
using Content.Shared.Access.Components;
using Content.Server.Doors.Systems;
using Content.Server.Doors.Components;
+using Content.Server.Power.EntitySystems;
using Content.Shared.Interaction.Events;
+using static Content.Server.Remotes.DoorRemoteComponent;
namespace Content.Server.Remotes
{
@@ -21,80 +22,81 @@ namespace Content.Server.Remotes
public override void Initialize()
{
- base.Initialize();
-
SubscribeLocalEvent(OnInHandActivation);
SubscribeLocalEvent(OnBeforeInteract);
}
public void OnInHandActivation(EntityUid user, DoorRemoteComponent component, UseInHandEvent args)
{
+ string switchMessageId;
switch (component.Mode)
{
- case DoorRemoteComponent.OperatingMode.OpenClose:
- component.Mode = DoorRemoteComponent.OperatingMode.ToggleBolts;
- _popupSystem.PopupEntity(Loc.GetString("door-remote-switch-state-toggle-bolts"), args.User, Filter.Entities(args.User));
+ case OperatingMode.OpenClose:
+ component.Mode = OperatingMode.ToggleBolts;
+ switchMessageId = "door-remote-switch-state-toggle-bolts";
break;
- case DoorRemoteComponent.OperatingMode.ToggleBolts:
- component.Mode = DoorRemoteComponent.OperatingMode.ToggleEmergencyAccess;
- _popupSystem.PopupEntity(Loc.GetString("door-remote-switch-state-toggle-emergency-access"), args.User, Filter.Entities(args.User));
+ case OperatingMode.ToggleBolts:
+ component.Mode = OperatingMode.ToggleEmergencyAccess;
+ switchMessageId = "door-remote-switch-state-toggle-emergency-access";
break;
- case DoorRemoteComponent.OperatingMode.ToggleEmergencyAccess:
- component.Mode = DoorRemoteComponent.OperatingMode.OpenClose;
- _popupSystem.PopupEntity(Loc.GetString("door-remote-switch-state-open-close"), args.User, Filter.Entities(args.User));
+ case OperatingMode.ToggleEmergencyAccess:
+ component.Mode = OperatingMode.OpenClose;
+ switchMessageId = "door-remote-switch-state-open-close";
break;
+ default:
+ throw new InvalidOperationException(
+ $"{nameof(DoorRemoteComponent)} had invalid mode {component.Mode}");
}
+ ShowPopupToUser(switchMessageId, args.User);
}
private void OnBeforeInteract(EntityUid uid, DoorRemoteComponent component, BeforeRangedInteractEvent args)
{
- if (!args.CanReach ||
- args.Handled
+ if (args.Handled
|| args.Target == null
- || !TryComp(args.Target, out var doorComponent) // If it isn't a door we don't use it
- || !HasComp(args.Target) // Remotes do not work on doors without access requirements
- || !TryComp(args.Target, out var airlockComponent) // Remotes only work on airlocks
- // TODO: Why the fuck is this -1f
- || !_interactionSystem.InRangeUnobstructed(args.User, doorComponent.Owner, -1f, CollisionGroup.Opaque))
- {
+ || !TryComp(args.Target, out var doorComp) // If it isn't a door we don't use it
+ || !TryComp(args.Target, out var airlockComp) // Remotes only work on airlocks
+ // The remote can be used anywhere the user can see the door.
+ // This doesn't work that well, but I don't know of an alternative
+ || !_interactionSystem.InRangeUnobstructed(args.User, args.Target.Value,
+ SharedInteractionSystem.MaxRaycastRange, CollisionGroup.Opaque))
return;
- }
args.Handled = true;
- if (component.Mode == DoorRemoteComponent.OperatingMode.OpenClose)
+ if (!this.IsPowered(args.Target.Value, EntityManager))
{
- _doorSystem.TryToggleDoor(doorComponent.Owner, user: args.Used);
+ ShowPopupToUser("door-remote-no-power", args.User);
+ return;
}
- if (component.Mode == DoorRemoteComponent.OperatingMode.ToggleBolts
- && airlockComponent.IsPowered())
+ if (TryComp(args.Target, out var accessComponent) &&
+ !_doorSystem.HasAccess(doorComp.Owner, args.Used, accessComponent))
{
- if (_doorSystem.HasAccess(doorComponent.Owner, args.Used))
- {
- airlockComponent.SetBoltsWithAudio(!airlockComponent.IsBolted());
- }
- else
- {
- if (doorComponent.State != DoorState.Open)
- {
- _doorSystem.Deny(airlockComponent.Owner, user: args.User);
- }
- else if (doorComponent.DenySound != null)
- {
- SoundSystem.Play(doorComponent.DenySound.GetSound(), Filter.Pvs(args.Target.Value, entityManager: EntityManager), args.Target.Value);
- }
- }
+ _doorSystem.Deny(airlockComp.Owner, doorComp, args.User);
+ ShowPopupToUser("door-remote-denied", args.User);
+ return;
}
- if (component.Mode == DoorRemoteComponent.OperatingMode.ToggleEmergencyAccess
- && airlockComponent.IsPowered())
+ switch (component.Mode)
{
- if (_doorSystem.HasAccess(doorComponent.Owner, args.Used))
- {
- _sharedAirlockSystem.ToggleEmergencyAccess(airlockComponent);
- }
+ case OperatingMode.OpenClose:
+ _doorSystem.TryToggleDoor(doorComp.Owner, doorComp, args.Used);
+ break;
+ case OperatingMode.ToggleBolts:
+ //TODO: What about cut wires...?
+ airlockComp.SetBoltsWithAudio(!airlockComp.IsBolted());
+ break;
+ case OperatingMode.ToggleEmergencyAccess:
+ _sharedAirlockSystem.ToggleEmergencyAccess(airlockComp);
+ break;
+ default:
+ throw new InvalidOperationException(
+ $"{nameof(DoorRemoteComponent)} had invalid mode {component.Mode}");
}
}
+
+ private void ShowPopupToUser(string messageId, EntityUid user) =>
+ _popupSystem.PopupEntity(Loc.GetString(messageId), user, Filter.Entities(user));
}
}
diff --git a/Content.Server/Shuttles/Components/AutoDockComponent.cs b/Content.Server/Shuttles/Components/AutoDockComponent.cs
new file mode 100644
index 0000000000..91e895cbdf
--- /dev/null
+++ b/Content.Server/Shuttles/Components/AutoDockComponent.cs
@@ -0,0 +1,14 @@
+namespace Content.Server.Shuttles.Components;
+
+///
+/// Added to entities when they are actively trying to dock with something else.
+/// We track it because checking every dock constantly would be expensive.
+///
+[RegisterComponent]
+public sealed class AutoDockComponent : Component
+{
+ ///
+ /// Track who has requested autodocking so we can know when to be removed.
+ ///
+ public HashSet Requesters = new();
+}
diff --git a/Content.Server/Shuttles/Components/RecentlyDockedComponent.cs b/Content.Server/Shuttles/Components/RecentlyDockedComponent.cs
new file mode 100644
index 0000000000..3f14a14fba
--- /dev/null
+++ b/Content.Server/Shuttles/Components/RecentlyDockedComponent.cs
@@ -0,0 +1,15 @@
+namespace Content.Server.Shuttles.Components;
+
+///
+/// Added to that have recently undocked.
+/// This checks for whether they've left the specified radius before allowing them to automatically dock again.
+///
+[RegisterComponent]
+public sealed class RecentlyDockedComponent : Component
+{
+ [ViewVariables, DataField("lastDocked")]
+ public EntityUid LastDocked;
+
+ [ViewVariables(VVAccess.ReadWrite), DataField("radius")]
+ public float Radius = 1.5f;
+}
diff --git a/Content.Server/Shuttles/Components/ShuttleComponent.cs b/Content.Server/Shuttles/Components/ShuttleComponent.cs
index 0705b6af53..3fc0461f6f 100644
--- a/Content.Server/Shuttles/Components/ShuttleComponent.cs
+++ b/Content.Server/Shuttles/Components/ShuttleComponent.cs
@@ -3,8 +3,14 @@ using Content.Shared.Shuttles.Components;
namespace Content.Server.Shuttles.Components
{
[RegisterComponent]
- public sealed class ShuttleComponent : SharedShuttleComponent
+ public sealed class ShuttleComponent : Component
{
+ [ViewVariables]
+ public bool Enabled = true;
+
+ [ViewVariables]
+ public ShuttleMode Mode = ShuttleMode.Cruise;
+
///
/// The cached thrust available for each cardinal direction
///
diff --git a/Content.Server/Shuttles/Components/ShuttleConsoleComponent.cs b/Content.Server/Shuttles/Components/ShuttleConsoleComponent.cs
index e724835253..1ad07afa4c 100644
--- a/Content.Server/Shuttles/Components/ShuttleConsoleComponent.cs
+++ b/Content.Server/Shuttles/Components/ShuttleConsoleComponent.cs
@@ -3,17 +3,10 @@ using Content.Shared.Shuttles.Components;
namespace Content.Server.Shuttles.Components
{
[RegisterComponent]
- [ComponentReference(typeof(SharedShuttleConsoleComponent))]
- internal sealed class ShuttleConsoleComponent : SharedShuttleConsoleComponent
+ public sealed class ShuttleConsoleComponent : SharedShuttleConsoleComponent
{
[ViewVariables]
- public List SubscribedPilots = new();
-
- ///
- /// Whether the console can be used to pilot. Toggled whenever it gets powered / unpowered.
- ///
- [ViewVariables]
- public bool Enabled { get; set; } = false;
+ public readonly List SubscribedPilots = new();
///
/// How much should the pilot's eye be zoomed by when piloting using this console?
diff --git a/Content.Server/Shuttles/Components/ThrusterComponent.cs b/Content.Server/Shuttles/Components/ThrusterComponent.cs
index 7d972159a9..b184fa841f 100644
--- a/Content.Server/Shuttles/Components/ThrusterComponent.cs
+++ b/Content.Server/Shuttles/Components/ThrusterComponent.cs
@@ -1,4 +1,4 @@
-using Content.Server.Shuttles.EntitySystems;
+using Content.Server.Shuttles.Systems;
using Content.Shared.Damage;
namespace Content.Server.Shuttles.Components
diff --git a/Content.Server/Shuttles/DockCommand.cs b/Content.Server/Shuttles/DockCommand.cs
index 0f8d15f178..88e39e3b61 100644
--- a/Content.Server/Shuttles/DockCommand.cs
+++ b/Content.Server/Shuttles/DockCommand.cs
@@ -1,6 +1,6 @@
using Content.Server.Administration;
using Content.Server.Shuttles.Components;
-using Content.Server.Shuttles.EntitySystems;
+using Content.Server.Shuttles.Systems;
using Content.Shared.Administration;
using Robust.Shared.Console;
diff --git a/Content.Server/Shuttles/EntitySystems/ShuttleConsoleSystem.cs b/Content.Server/Shuttles/EntitySystems/ShuttleConsoleSystem.cs
deleted file mode 100644
index 3f3b186b0f..0000000000
--- a/Content.Server/Shuttles/EntitySystems/ShuttleConsoleSystem.cs
+++ /dev/null
@@ -1,250 +0,0 @@
-using Content.Server.Popups;
-using Content.Server.Power.Components;
-using Content.Server.Power.EntitySystems;
-using Content.Server.Shuttles.Components;
-using Content.Shared.ActionBlocker;
-using Content.Shared.Alert;
-using Content.Shared.Interaction;
-using Content.Shared.Popups;
-using Content.Shared.Shuttles;
-using Content.Shared.Shuttles.Components;
-using Content.Shared.Tag;
-using Content.Shared.Verbs;
-using Robust.Shared.Map;
-using Robust.Shared.Player;
-using Robust.Shared.Utility;
-
-namespace Content.Server.Shuttles.EntitySystems
-{
- internal sealed class ShuttleConsoleSystem : SharedShuttleConsoleSystem
- {
- [Dependency] private readonly IMapManager _mapManager = default!;
- [Dependency] private readonly ActionBlockerSystem _blocker = default!;
- [Dependency] private readonly AlertsSystem _alertsSystem = default!;
- [Dependency] private readonly PopupSystem _popup = default!;
- [Dependency] private readonly TagSystem _tags = default!;
-
- public override void Initialize()
- {
- base.Initialize();
-
- SubscribeLocalEvent(HandleConsoleShutdown);
- SubscribeLocalEvent(HandleConsoleInteract);
- SubscribeLocalEvent(HandlePowerChange);
- SubscribeLocalEvent>(OnConsoleInteract);
-
- SubscribeLocalEvent(HandlePilotMove);
- }
-
- private void OnConsoleInteract(EntityUid uid, ShuttleConsoleComponent component, GetVerbsEvent args)
- {
- if (!args.CanAccess ||
- !args.CanInteract)
- return;
-
- var xform = EntityManager.GetComponent(uid);
-
- // Maybe move mode onto the console instead?
- if (!_mapManager.TryGetGrid(xform.GridEntityId, out var grid) ||
- !EntityManager.TryGetComponent(grid.GridEntityId, out ShuttleComponent? shuttle)) return;
-
- InteractionVerb verb = new()
- {
- Text = Loc.GetString("shuttle-mode-toggle"),
- Act = () => ToggleShuttleMode(args.User, component, shuttle),
- Disabled = !xform.Anchored || !this.IsPowered(uid, EntityManager),
- };
-
- args.Verbs.Add(verb);
- }
-
- private void ToggleShuttleMode(EntityUid user, ShuttleConsoleComponent consoleComponent, ShuttleComponent shuttleComponent, TransformComponent? consoleXform = null)
- {
- // Re-validate
- if (!this.IsPowered(consoleComponent.Owner, EntityManager)) return;
-
- if (!Resolve(consoleComponent.Owner, ref consoleXform)) return;
-
- if (!consoleXform.Anchored || consoleXform.GridEntityId != EntityManager.GetComponent(shuttleComponent.Owner).GridEntityId) return;
-
- switch (shuttleComponent.Mode)
- {
- case ShuttleMode.Cruise:
- shuttleComponent.Mode = ShuttleMode.Docking;
- _popup.PopupEntity(Loc.GetString("shuttle-mode-docking"), consoleComponent.Owner, Filter.Entities(user));
- break;
- case ShuttleMode.Docking:
- shuttleComponent.Mode = ShuttleMode.Cruise;
- _popup.PopupEntity(Loc.GetString("shuttle-mode-cruise"), consoleComponent.Owner, Filter.Entities(user));
- break;
- default:
- throw new ArgumentOutOfRangeException();
- }
- }
-
- public override void Update(float frameTime)
- {
- base.Update(frameTime);
-
- var toRemove = new RemQueue();
-
- foreach (var comp in EntityManager.EntityQuery())
- {
- if (comp.Console == null) continue;
-
- if (!_blocker.CanInteract(comp.Owner, comp.Console.Owner))
- {
- toRemove.Add(comp);
- }
- }
-
- foreach (var comp in toRemove)
- {
- RemovePilot(comp);
- }
- }
-
- ///
- /// Console requires power to operate.
- ///
- private void HandlePowerChange(EntityUid uid, ShuttleConsoleComponent component, PowerChangedEvent args)
- {
- if (!args.Powered)
- {
- component.Enabled = false;
-
- ClearPilots(component);
- }
- else
- {
- component.Enabled = true;
- }
- }
-
- ///
- /// If pilot is moved then we'll stop them from piloting.
- ///
- private void HandlePilotMove(EntityUid uid, PilotComponent component, ref MoveEvent args)
- {
- if (component.Console == null || component.Position == null)
- {
- DebugTools.Assert(component.Position == null && component.Console == null);
- EntityManager.RemoveComponent(uid);
- return;
- }
-
- if (args.NewPosition.TryDistance(EntityManager, component.Position.Value, out var distance) &&
- distance < PilotComponent.BreakDistance) return;
-
- RemovePilot(component);
- }
-
- ///
- /// For now pilots just interact with the console and can start piloting with wasd.
- ///
- private void HandleConsoleInteract(EntityUid uid, ShuttleConsoleComponent component, ActivateInWorldEvent args)
- {
- if (!_tags.HasTag(args.User, "CanPilot"))
- {
- return;
- }
-
- var pilotComponent = EntityManager.EnsureComponent(args.User);
-
- if (!component.Enabled)
- {
- args.User.PopupMessage($"Console is not powered.");
- return;
- }
-
- args.Handled = true;
- var console = pilotComponent.Console;
-
- if (console != null)
- {
- RemovePilot(pilotComponent);
-
- if (console == component)
- {
- return;
- }
- }
-
- AddPilot(args.User, component);
- }
-
- protected override void HandlePilotShutdown(EntityUid uid, PilotComponent component, ComponentShutdown args)
- {
- base.HandlePilotShutdown(uid, component, args);
- RemovePilot(component);
- }
-
- private void HandleConsoleShutdown(EntityUid uid, ShuttleConsoleComponent component, ComponentShutdown args)
- {
- ClearPilots(component);
- }
-
- public void AddPilot(EntityUid entity, ShuttleConsoleComponent component)
- {
- if (!EntityManager.TryGetComponent(entity, out PilotComponent? pilotComponent) ||
- component.SubscribedPilots.Contains(pilotComponent))
- {
- return;
- }
-
- if (TryComp(entity, out var eye))
- {
- eye.Zoom = component.Zoom;
- }
-
- component.SubscribedPilots.Add(pilotComponent);
-
- _alertsSystem.ShowAlert(entity, AlertType.PilotingShuttle);
-
- entity.PopupMessage(Loc.GetString("shuttle-pilot-start"));
- pilotComponent.Console = component;
- ActionBlockerSystem.UpdateCanMove(entity);
- pilotComponent.Position = EntityManager.GetComponent(entity).Coordinates;
- pilotComponent.Dirty();
- }
-
- public void RemovePilot(PilotComponent pilotComponent)
- {
- var console = pilotComponent.Console;
-
- if (console is not ShuttleConsoleComponent helmsman) return;
-
- pilotComponent.Console = null;
- pilotComponent.Position = null;
-
- if (TryComp(pilotComponent.Owner, out var eye))
- {
- eye.Zoom = new(1.0f, 1.0f);
- }
-
- if (!helmsman.SubscribedPilots.Remove(pilotComponent)) return;
-
- _alertsSystem.ClearAlert(pilotComponent.Owner, AlertType.PilotingShuttle);
-
- pilotComponent.Owner.PopupMessage(Loc.GetString("shuttle-pilot-end"));
-
- if (pilotComponent.LifeStage < ComponentLifeStage.Stopping)
- EntityManager.RemoveComponent(pilotComponent.Owner);
- }
-
- public void RemovePilot(EntityUid entity)
- {
- if (!EntityManager.TryGetComponent(entity, out PilotComponent? pilotComponent)) return;
-
- RemovePilot(pilotComponent);
- }
-
- public void ClearPilots(ShuttleConsoleComponent component)
- {
- while (component.SubscribedPilots.TryGetValue(0, out var pilot))
- {
- RemovePilot(pilot);
- }
- }
- }
-}
diff --git a/Content.Server/Shuttles/Events/DockEvent.cs b/Content.Server/Shuttles/Events/DockEvent.cs
new file mode 100644
index 0000000000..3b9ed46741
--- /dev/null
+++ b/Content.Server/Shuttles/Events/DockEvent.cs
@@ -0,0 +1,15 @@
+using Content.Server.Shuttles.Components;
+
+namespace Content.Server.Shuttles.Events;
+
+///
+/// Raised whenever 2 airlocks dock.
+///
+public sealed class DockEvent : EntityEventArgs
+{
+ public DockingComponent DockA = default!;
+ public DockingComponent DockB = default!;
+
+ public EntityUid GridAUid = default!;
+ public EntityUid GridBUid = default!;
+}
\ No newline at end of file
diff --git a/Content.Server/Shuttles/Events/UndockEvent.cs b/Content.Server/Shuttles/Events/UndockEvent.cs
new file mode 100644
index 0000000000..41df647aab
--- /dev/null
+++ b/Content.Server/Shuttles/Events/UndockEvent.cs
@@ -0,0 +1,15 @@
+using Content.Server.Shuttles.Components;
+
+namespace Content.Server.Shuttles.Events;
+
+///
+/// Raised whenever 2 grids undock.
+///
+public sealed class UndockEvent : EntityEventArgs
+{
+ public DockingComponent DockA = default!;
+ public DockingComponent DockB = default!;
+
+ public EntityUid GridAUid = default!;
+ public EntityUid GridBUid = default!;
+}
\ No newline at end of file
diff --git a/Content.Server/Shuttles/Systems/DockingSystem.AutoDock.cs b/Content.Server/Shuttles/Systems/DockingSystem.AutoDock.cs
new file mode 100644
index 0000000000..a87f721c31
--- /dev/null
+++ b/Content.Server/Shuttles/Systems/DockingSystem.AutoDock.cs
@@ -0,0 +1,104 @@
+using Content.Server.Shuttles.Components;
+using Content.Shared.Shuttles.Components;
+using Content.Shared.Shuttles.Events;
+using Robust.Shared.Players;
+using Robust.Shared.Utility;
+
+namespace Content.Server.Shuttles.Systems;
+
+public sealed partial class DockingSystem
+{
+ private void UpdateAutodock()
+ {
+ // Work out what we can autodock with, what we shouldn't, and when we should stop tracking.
+ // Autodocking only stops when the client closes that dock viewport OR they lose pilotcomponent.
+ var dockingQuery = GetEntityQuery();
+ var xformQuery = GetEntityQuery();
+ var recentQuery = GetEntityQuery();
+
+ foreach (var (comp, body) in EntityQuery())
+ {
+ if (comp.Requesters.Count == 0 || !dockingQuery.TryGetComponent(comp.Owner, out var dock))
+ {
+ RemComp(comp.Owner);
+ continue;
+ }
+
+ // Don't re-dock if we're already docked or recently were.
+ if (dock.Docked || recentQuery.HasComponent(comp.Owner)) continue;
+
+ var dockable = GetDockable(body, xformQuery.GetComponent(comp.Owner));
+
+ if (dockable == null) continue;
+
+ TryDock(dock, dockable);
+ }
+
+ // Work out recent docks that have gone past their designated threshold.
+ var checkedRecent = new HashSet();
+
+ foreach (var (comp, xform) in EntityQuery())
+ {
+ if (!checkedRecent.Add(comp.Owner)) continue;
+
+ if (!dockingQuery.TryGetComponent(comp.Owner, out var dock))
+ {
+ RemComp(comp.Owner);
+ continue;
+ }
+
+ if (!xformQuery.TryGetComponent(comp.LastDocked, out var otherXform))
+ {
+ RemComp(comp.Owner);
+ continue;
+ }
+
+ var worldPos = _transformSystem.GetWorldPosition(xform, xformQuery);
+ var otherWorldPos = _transformSystem.GetWorldPosition(otherXform, xformQuery);
+
+ if ((worldPos - otherWorldPos).Length < comp.Radius) continue;
+
+ _sawmill.Debug($"Removed RecentlyDocked from {ToPrettyString(comp.Owner)} and {ToPrettyString(comp.LastDocked)}");
+ RemComp(comp.Owner);
+ RemComp(comp.LastDocked);
+ }
+ }
+
+ private void OnRequestUndock(EntityUid uid, ShuttleConsoleComponent component, UndockRequestMessage args)
+ {
+ _sawmill.Debug($"Received undock request for {ToPrettyString(args.Entity)}");
+
+ // TODO: Validation
+ if (!TryComp(args.Entity, out var dock) ||
+ !dock.Docked) return;
+
+ Undock(dock);
+ }
+
+ private void OnRequestAutodock(EntityUid uid, ShuttleConsoleComponent component, AutodockRequestMessage args)
+ {
+ _sawmill.Debug($"Received autodock request for {ToPrettyString(args.Entity)}");
+ var player = args.Session.AttachedEntity;
+
+ if (player == null || !HasComp(args.Entity)) return;
+
+ // TODO: Validation
+ var comp = EnsureComp(args.Entity);
+ comp.Requesters.Add(player.Value);
+ }
+
+ private void OnRequestStopAutodock(EntityUid uid, ShuttleConsoleComponent component, StopAutodockRequestMessage args)
+ {
+ _sawmill.Debug($"Received stop autodock request for {ToPrettyString(args.Entity)}");
+
+ var player = args.Session.AttachedEntity;
+
+ // TODO: Validation
+ if (player == null || !TryComp(args.Entity, out var comp)) return;
+
+ comp.Requesters.Remove(player.Value);
+
+ if (comp.Requesters.Count == 0)
+ RemComp(args.Entity);
+ }
+}
diff --git a/Content.Server/Shuttles/EntitySystems/DockingSystem.cs b/Content.Server/Shuttles/Systems/DockingSystem.cs
similarity index 82%
rename from Content.Server/Shuttles/EntitySystems/DockingSystem.cs
rename to Content.Server/Shuttles/Systems/DockingSystem.cs
index ef06cf58ca..a88eeb4254 100644
--- a/Content.Server/Shuttles/EntitySystems/DockingSystem.cs
+++ b/Content.Server/Shuttles/Systems/DockingSystem.cs
@@ -1,24 +1,30 @@
using Content.Server.Doors.Systems;
using Content.Server.Power.Components;
using Content.Server.Shuttles.Components;
+using Content.Server.Shuttles.Events;
using Content.Shared.Doors;
using Content.Shared.Doors.Components;
+using Content.Shared.Shuttles.Events;
using Content.Shared.Verbs;
+using Robust.Server.Player;
using Robust.Shared.Map;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Collision.Shapes;
using Robust.Shared.Physics.Dynamics;
using Robust.Shared.Utility;
-namespace Content.Server.Shuttles.EntitySystems
+namespace Content.Server.Shuttles.Systems
{
- public sealed class DockingSystem : EntitySystem
+ public sealed partial class DockingSystem : EntitySystem
{
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly FixtureSystem _fixtureSystem = default!;
[Dependency] private readonly SharedJointSystem _jointSystem = default!;
+ [Dependency] private readonly SharedTransformSystem _transformSystem = default!;
+ [Dependency] private readonly ShuttleConsoleSystem _console = default!;
[Dependency] private readonly DoorSystem _doorSystem = default!;
+ private ISawmill _sawmill = default!;
private const string DockingFixture = "docking";
private const string DockingJoint = "docking";
private const float DockingRadius = 0.20f;
@@ -26,14 +32,26 @@ namespace Content.Server.Shuttles.EntitySystems
public override void Initialize()
{
base.Initialize();
+ _sawmill = Logger.GetSawmill("docking");
SubscribeLocalEvent(OnStartup);
SubscribeLocalEvent(OnShutdown);
SubscribeLocalEvent(OnPowerChange);
SubscribeLocalEvent(OnAnchorChange);
SubscribeLocalEvent(OnDockingReAnchor);
- SubscribeLocalEvent>(OnVerb);
SubscribeLocalEvent(OnAutoClose);
+
+ // Yes this isn't in shuttle console; it may be used by other systems technically.
+ // in which case I would also add their subs here.
+ SubscribeLocalEvent(OnRequestAutodock);
+ SubscribeLocalEvent(OnRequestStopAutodock);
+ SubscribeLocalEvent(OnRequestUndock);
+ }
+
+ public override void Update(float frameTime)
+ {
+ base.Update(frameTime);
+ UpdateAutodock();
}
private void OnAutoClose(EntityUid uid, DockingComponent component, BeforeDoorAutoCloseEvent args)
@@ -43,56 +61,6 @@ namespace Content.Server.Shuttles.EntitySystems
args.Cancel();
}
- private void OnVerb(EntityUid uid, DockingComponent component, GetVerbsEvent args)
- {
- if (!args.CanInteract ||
- !args.CanAccess) return;
-
- InteractionVerb? verb;
-
- // TODO: Have it open the UI and have the UI do this.
- if (!component.Docked &&
- TryComp(uid, out PhysicsComponent? body) &&
- TryComp(uid, out TransformComponent? xform))
- {
- DockingComponent? otherDock = null;
-
- if (component.Enabled)
- otherDock = GetDockable(body, xform);
-
- verb = new InteractionVerb
- {
- Disabled = otherDock == null,
- Text = Loc.GetString("docking-component-dock"),
- Act = () =>
- {
- if (otherDock == null) return;
- TryDock(component, otherDock);
- }
- };
- }
- else if (component.Docked)
- {
- verb = new InteractionVerb
- {
- Disabled = !component.Docked,
- Text = Loc.GetString("docking-component-undock"),
- Act = () =>
- {
- if (component.DockedWith == null || !component.Enabled) return;
-
- Undock(component);
- }
- };
- }
- else
- {
- return;
- }
-
- args.Verbs.Add(verb);
- }
-
private DockingComponent? GetDockable(PhysicsComponent body, TransformComponent dockingXform)
{
// Did you know Saltern is the most dockable station?
@@ -105,12 +73,9 @@ namespace Content.Server.Shuttles.EntitySystems
var transform = body.GetTransform();
var dockingFixture = _fixtureSystem.GetFixtureOrNull(body, DockingFixture);
+ // Happens if no power or whatever
if (dockingFixture == null)
- {
- DebugTools.Assert(false);
- Logger.ErrorS("docking", $"Found null fixture on {(body).Owner}");
return null;
- }
Box2? aabb = null;
@@ -142,7 +107,7 @@ namespace Content.Server.Shuttles.EntitySystems
if (otherDockingFixture == null)
{
DebugTools.Assert(false);
- Logger.ErrorS("docking", $"Found null docking fixture on {ent}");
+ _sawmill.Error($"Found null docking fixture on {ent}");
continue;
}
@@ -181,7 +146,7 @@ namespace Content.Server.Shuttles.EntitySystems
!TryComp(dockBUid, out DockingComponent? dockB))
{
DebugTools.Assert(false);
- Logger.Error("docking", $"Tried to cleanup {dockA.Owner} but not docked?");
+ _sawmill.Error($"Tried to cleanup {dockA.Owner} but not docked?");
dockA.DockedWith = null;
if (dockA.DockJoint != null)
@@ -247,6 +212,8 @@ namespace Content.Server.Shuttles.EntitySystems
{
DisableDocking(uid, component);
}
+
+ _console.RefreshShuttleConsoles();
}
private void OnDockingReAnchor(EntityUid uid, DockingComponent component, ref ReAnchorEvent args)
@@ -257,6 +224,7 @@ namespace Content.Server.Shuttles.EntitySystems
Undock(component);
Dock(component, other);
+ _console.RefreshShuttleConsoles();
}
private void OnPowerChange(EntityUid uid, DockingComponent component, PowerChangedEvent args)
@@ -329,12 +297,11 @@ namespace Content.Server.Shuttles.EntitySystems
///
public void Dock(DockingComponent dockA, DockingComponent dockB)
{
- Logger.DebugS("docking", $"Docking between {dockA.Owner} and {dockB.Owner}");
+ _sawmill.Debug($"Docking between {dockA.Owner} and {dockB.Owner}");
// https://gamedev.stackexchange.com/questions/98772/b2distancejoint-with-frequency-equal-to-0-vs-b2weldjoint
// We could also potentially use a prismatic joint? Depending if we want clamps that can extend or whatever
-
var dockAXform = EntityManager.GetComponent(dockA.Owner);
var dockBXform = EntityManager.GetComponent(dockB.Owner);
@@ -397,10 +364,7 @@ namespace Content.Server.Shuttles.EntitySystems
EntityManager.EventBus.RaiseEvent(EventSource.Local, msg);
}
- ///
- /// Attempts to dock 2 ports together and will return early if it's not possible.
- ///
- private void TryDock(DockingComponent dockA, DockingComponent dockB)
+ private bool CanDock(DockingComponent dockA, DockingComponent dockB)
{
if (!TryComp(dockA.Owner, out PhysicsComponent? bodyA) ||
!TryComp(dockB.Owner, out PhysicsComponent? bodyB) ||
@@ -409,7 +373,7 @@ namespace Content.Server.Shuttles.EntitySystems
dockA.DockedWith != null ||
dockB.DockedWith != null)
{
- return;
+ return false;
}
var fixtureA = _fixtureSystem.GetFixtureOrNull(bodyA, DockingFixture);
@@ -417,7 +381,7 @@ namespace Content.Server.Shuttles.EntitySystems
if (fixtureA == null || fixtureB == null)
{
- return;
+ return false;
}
var transformA = bodyA.GetTransform();
@@ -441,7 +405,15 @@ namespace Content.Server.Shuttles.EntitySystems
if (intersect) break;
}
- if (!intersect) return;
+ return intersect;
+ }
+
+ ///
+ /// Attempts to dock 2 ports together and will return early if it's not possible.
+ ///
+ private void TryDock(DockingComponent dockA, DockingComponent dockB)
+ {
+ if (!CanDock(dockA, dockB)) return;
Dock(dockA, dockB);
}
@@ -451,7 +423,7 @@ namespace Content.Server.Shuttles.EntitySystems
if (dock.DockedWith == null)
{
DebugTools.Assert(false);
- Logger.ErrorS("docking", $"Tried to undock {(dock).Owner} but not docked with anything?");
+ _sawmill.Error($"Tried to undock {(dock).Owner} but not docked with anything?");
return;
}
@@ -467,33 +439,12 @@ namespace Content.Server.Shuttles.EntitySystems
_doorSystem.TryClose(doorB.Owner, doorB);
}
- // Could maybe give the shuttle a light push away, or at least if there's no other docks left?
+ var recentlyDocked = EnsureComp(dock.Owner);
+ recentlyDocked.LastDocked = dock.DockedWith.Value;
+ recentlyDocked = EnsureComp(dock.DockedWith.Value);
+ recentlyDocked.LastDocked = dock.DockedWith.Value;
Cleanup(dock);
}
-
- ///
- /// Raised whenever 2 airlocks dock.
- ///
- public sealed class DockEvent : EntityEventArgs
- {
- public DockingComponent DockA = default!;
- public DockingComponent DockB = default!;
-
- public EntityUid GridAUid = default!;
- public EntityUid GridBUid = default!;
- }
-
- ///
- /// Raised whenever 2 grids undock.
- ///
- public sealed class UndockEvent : EntityEventArgs
- {
- public DockingComponent DockA = default!;
- public DockingComponent DockB = default!;
-
- public EntityUid GridAUid = default!;
- public EntityUid GridBUid = default!;
- }
}
}
diff --git a/Content.Server/Shuttles/Systems/RadarConsoleSystem.cs b/Content.Server/Shuttles/Systems/RadarConsoleSystem.cs
new file mode 100644
index 0000000000..3d2e6c0025
--- /dev/null
+++ b/Content.Server/Shuttles/Systems/RadarConsoleSystem.cs
@@ -0,0 +1,29 @@
+using Content.Shared.Shuttles.BUIStates;
+using Content.Shared.Shuttles.Components;
+using Content.Shared.Shuttles.Systems;
+using Robust.Server.GameObjects;
+using Robust.Shared.Map;
+
+namespace Content.Server.Shuttles.Systems;
+
+public sealed class RadarConsoleSystem : SharedRadarConsoleSystem
+{
+ [Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+ SubscribeLocalEvent(OnRadarStartup);
+ }
+
+ private void OnRadarStartup(EntityUid uid, RadarConsoleComponent component, ComponentStartup args)
+ {
+ UpdateState(component);
+ }
+
+ protected override void UpdateState(RadarConsoleComponent component)
+ {
+ var radarState = new RadarConsoleBoundInterfaceState(component.MaxRange, component.Owner, new List());
+ _uiSystem.GetUiOrNull(component.Owner, RadarConsoleUiKey.Key)?.SetState(radarState);
+ }
+}
diff --git a/Content.Server/Shuttles/Systems/ShuttleConsoleSystem.cs b/Content.Server/Shuttles/Systems/ShuttleConsoleSystem.cs
new file mode 100644
index 0000000000..2249f357af
--- /dev/null
+++ b/Content.Server/Shuttles/Systems/ShuttleConsoleSystem.cs
@@ -0,0 +1,337 @@
+using Content.Server.Power.Components;
+using Content.Server.Power.EntitySystems;
+using Content.Server.Shuttles.Components;
+using Content.Server.Shuttles.Events;
+using Content.Server.UserInterface;
+using Content.Shared.ActionBlocker;
+using Content.Shared.Alert;
+using Content.Shared.Popups;
+using Content.Shared.Shuttles.BUIStates;
+using Content.Shared.Shuttles.Components;
+using Content.Shared.Shuttles.Events;
+using Content.Shared.Shuttles.Systems;
+using Content.Shared.Tag;
+using Robust.Server.GameObjects;
+using Robust.Shared.GameStates;
+using Robust.Shared.Utility;
+
+namespace Content.Server.Shuttles.Systems
+{
+ public sealed class ShuttleConsoleSystem : SharedShuttleConsoleSystem
+ {
+ [Dependency] private readonly ActionBlockerSystem _blocker = default!;
+ [Dependency] private readonly AlertsSystem _alertsSystem = default!;
+ [Dependency] private readonly TagSystem _tags = default!;
+ [Dependency] private readonly UserInterfaceSystem _ui = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(OnConsoleShutdown);
+ SubscribeLocalEvent(OnConsolePowerChange);
+ SubscribeLocalEvent(OnConsoleAnchorChange);
+ SubscribeLocalEvent(OnConsoleUIOpenAttempt);
+ SubscribeLocalEvent(OnModeRequest);
+ SubscribeLocalEvent(OnConsoleUIClose);
+ SubscribeLocalEvent(OnDock);
+ SubscribeLocalEvent(OnUndock);
+
+ SubscribeLocalEvent(HandlePilotMove);
+ SubscribeLocalEvent(OnGetState);
+ }
+
+ private void OnDock(DockEvent ev)
+ {
+ RefreshShuttleConsoles();
+ }
+
+ private void OnUndock(UndockEvent ev)
+ {
+ RefreshShuttleConsoles();
+ }
+
+ ///
+ /// Refreshes all of the data for shuttle consoles.
+ ///
+ public void RefreshShuttleConsoles()
+ {
+ // TODO: Should really call this per shuttle in some instances.
+ var docks = GetAllDocks();
+
+ foreach (var comp in EntityQuery(true))
+ {
+ UpdateState(comp, docks);
+ }
+ }
+
+ ///
+ /// Stop piloting if the window is closed.
+ ///
+ private void OnConsoleUIClose(EntityUid uid, ShuttleConsoleComponent component, BoundUIClosedEvent args)
+ {
+ if ((ShuttleConsoleUiKey) args.UiKey != ShuttleConsoleUiKey.Key ||
+ args.Session.AttachedEntity is not {} user) return;
+
+ // In case they D/C should still clean them up.
+ foreach (var comp in EntityQuery(true))
+ {
+ comp.Requesters.Remove(user);
+ }
+
+ RemovePilot(user);
+ }
+
+ private void OnConsoleUIOpenAttempt(EntityUid uid, ShuttleConsoleComponent component, ActivatableUIOpenAttemptEvent args)
+ {
+ if (!TryPilot(args.User, uid))
+ args.Cancel();
+ }
+
+ private void OnConsoleAnchorChange(EntityUid uid, ShuttleConsoleComponent component, ref AnchorStateChangedEvent args)
+ {
+ UpdateState(component);
+ }
+
+ private void OnConsolePowerChange(EntityUid uid, ShuttleConsoleComponent component, PowerChangedEvent args)
+ {
+ UpdateState(component);
+ }
+
+ private bool TryPilot(EntityUid user, EntityUid uid)
+ {
+ if (!_tags.HasTag(user, "CanPilot") ||
+ !TryComp(uid, out var component) ||
+ !this.IsPowered(uid, EntityManager) ||
+ !Transform(uid).Anchored ||
+ !_blocker.CanInteract(user, uid))
+ {
+ return false;
+ }
+
+ var pilotComponent = EntityManager.EnsureComponent(user);
+ var console = pilotComponent.Console;
+
+ if (console != null)
+ {
+ RemovePilot(pilotComponent);
+
+ if (console == component)
+ {
+ return false;
+ }
+ }
+
+ AddPilot(user, component);
+ return true;
+ }
+
+ private void OnGetState(EntityUid uid, PilotComponent component, ref ComponentGetState args)
+ {
+ args.State = new PilotComponentState(component.Console?.Owner);
+ }
+
+ ///
+ /// Client is requesting a change in the shuttle's driving mode.
+ ///
+ private void OnModeRequest(EntityUid uid, ShuttleConsoleComponent component, ShuttleModeRequestMessage args)
+ {
+ if (args.Session.AttachedEntity is not { } player ||
+ !TryComp(player, out var pilot) ||
+ !TryComp(player, out var xform) ||
+ pilot.Console is not ShuttleConsoleComponent console) return;
+
+ if (!console.SubscribedPilots.Contains(pilot) ||
+ !TryComp(xform.GridEntityId, out var shuttle)) return;
+
+ SetShuttleMode(args.Mode, console, shuttle);
+ }
+
+ ///
+ /// Sets the shuttle's movement mode. Does minimal revalidation.
+ ///
+ private void SetShuttleMode(ShuttleMode mode, ShuttleConsoleComponent consoleComponent,
+ ShuttleComponent shuttleComponent, TransformComponent? consoleXform = null)
+ {
+ // Re-validate
+ if (!this.IsPowered(consoleComponent.Owner, EntityManager) ||
+ !Resolve(consoleComponent.Owner, ref consoleXform) ||
+ !consoleXform.Anchored ||
+ consoleXform.GridID != Transform(shuttleComponent.Owner).GridID)
+ {
+ UpdateState(consoleComponent);
+ return;
+ }
+
+ shuttleComponent.Mode = mode;
+
+ switch (mode)
+ {
+ case ShuttleMode.Strafing:
+ break;
+ case ShuttleMode.Cruise:
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+
+ UpdateState(consoleComponent);
+ }
+
+ ///
+ /// Returns the position and angle of all dockingcomponents.
+ ///
+ private List GetAllDocks()
+ {
+ // TODO: NEED TO MAKE SURE THIS UPDATES ON ANCHORING CHANGES!
+ var result = new List();
+
+ foreach (var (comp, xform) in EntityQuery(true))
+ {
+ if (xform.ParentUid != xform.GridUid) continue;
+
+ var state = new DockingInterfaceState()
+ {
+ Coordinates = xform.Coordinates,
+ Angle = xform.LocalRotation,
+ Entity = comp.Owner,
+ Connected = comp.Docked,
+ };
+ result.Add(state);
+ }
+
+ return result;
+ }
+
+ private void UpdateState(ShuttleConsoleComponent component, List? docks = null)
+ {
+ TryComp(component.Owner, out var radar);
+ var range = radar?.MaxRange ?? 0f;
+
+ TryComp(Transform(component.Owner).GridUid, out var shuttle);
+ var mode = shuttle?.Mode ?? ShuttleMode.Cruise;
+
+ docks ??= GetAllDocks();
+
+ _ui.GetUiOrNull(component.Owner, ShuttleConsoleUiKey.Key)
+ ?.SetState(new ShuttleConsoleBoundInterfaceState(
+ mode,
+ range,
+ component.Owner,
+ docks));
+ }
+
+ public override void Update(float frameTime)
+ {
+ base.Update(frameTime);
+
+ var toRemove = new RemQueue();
+
+ foreach (var comp in EntityManager.EntityQuery())
+ {
+ if (comp.Console == null) continue;
+
+ if (!_blocker.CanInteract(comp.Owner, comp.Console.Owner))
+ {
+ toRemove.Add(comp);
+ }
+ }
+
+ foreach (var comp in toRemove)
+ {
+ RemovePilot(comp);
+ }
+ }
+
+ ///
+ /// If pilot is moved then we'll stop them from piloting.
+ ///
+ private void HandlePilotMove(EntityUid uid, PilotComponent component, ref MoveEvent args)
+ {
+ if (component.Console == null || component.Position == null)
+ {
+ DebugTools.Assert(component.Position == null && component.Console == null);
+ EntityManager.RemoveComponent(uid);
+ return;
+ }
+
+ if (args.NewPosition.TryDistance(EntityManager, component.Position.Value, out var distance) &&
+ distance < PilotComponent.BreakDistance) return;
+
+ RemovePilot(component);
+ }
+
+ protected override void HandlePilotShutdown(EntityUid uid, PilotComponent component, ComponentShutdown args)
+ {
+ base.HandlePilotShutdown(uid, component, args);
+ RemovePilot(component);
+ }
+
+ private void OnConsoleShutdown(EntityUid uid, ShuttleConsoleComponent component, ComponentShutdown args)
+ {
+ ClearPilots(component);
+ }
+
+ public void AddPilot(EntityUid entity, ShuttleConsoleComponent component)
+ {
+ if (!EntityManager.TryGetComponent(entity, out PilotComponent? pilotComponent) ||
+ component.SubscribedPilots.Contains(pilotComponent))
+ {
+ return;
+ }
+
+ if (TryComp(entity, out var eye))
+ {
+ eye.Zoom = component.Zoom;
+ }
+
+ component.SubscribedPilots.Add(pilotComponent);
+
+ _alertsSystem.ShowAlert(entity, AlertType.PilotingShuttle);
+
+ pilotComponent.Console = component;
+ ActionBlockerSystem.UpdateCanMove(entity);
+ pilotComponent.Position = EntityManager.GetComponent(entity).Coordinates;
+ Dirty(pilotComponent);
+ }
+
+ public void RemovePilot(PilotComponent pilotComponent)
+ {
+ var console = pilotComponent.Console;
+
+ if (console is not ShuttleConsoleComponent helmsman) return;
+
+ pilotComponent.Console = null;
+ pilotComponent.Position = null;
+
+ if (TryComp(pilotComponent.Owner, out var eye))
+ {
+ eye.Zoom = new(1.0f, 1.0f);
+ }
+
+ if (!helmsman.SubscribedPilots.Remove(pilotComponent)) return;
+
+ _alertsSystem.ClearAlert(pilotComponent.Owner, AlertType.PilotingShuttle);
+
+ pilotComponent.Owner.PopupMessage(Loc.GetString("shuttle-pilot-end"));
+
+ if (pilotComponent.LifeStage < ComponentLifeStage.Stopping)
+ EntityManager.RemoveComponent(pilotComponent.Owner);
+ }
+
+ public void RemovePilot(EntityUid entity)
+ {
+ if (!EntityManager.TryGetComponent(entity, out PilotComponent? pilotComponent)) return;
+
+ RemovePilot(pilotComponent);
+ }
+
+ public void ClearPilots(ShuttleConsoleComponent component)
+ {
+ while (component.SubscribedPilots.TryGetValue(0, out var pilot))
+ {
+ RemovePilot(pilot);
+ }
+ }
+ }
+}
diff --git a/Content.Server/Shuttles/EntitySystems/ShuttleSystem.cs b/Content.Server/Shuttles/Systems/ShuttleSystem.cs
similarity index 99%
rename from Content.Server/Shuttles/EntitySystems/ShuttleSystem.cs
rename to Content.Server/Shuttles/Systems/ShuttleSystem.cs
index bf525fab8e..40f67c818f 100644
--- a/Content.Server/Shuttles/EntitySystems/ShuttleSystem.cs
+++ b/Content.Server/Shuttles/Systems/ShuttleSystem.cs
@@ -4,7 +4,7 @@ using JetBrains.Annotations;
using Robust.Shared.Configuration;
using Robust.Shared.Physics;
-namespace Content.Server.Shuttles.EntitySystems
+namespace Content.Server.Shuttles.Systems
{
[UsedImplicitly]
public sealed class ShuttleSystem : EntitySystem
diff --git a/Content.Server/Shuttles/EntitySystems/SpaceGarbageSystem.cs b/Content.Server/Shuttles/Systems/SpaceGarbageSystem.cs
similarity index 94%
rename from Content.Server/Shuttles/EntitySystems/SpaceGarbageSystem.cs
rename to Content.Server/Shuttles/Systems/SpaceGarbageSystem.cs
index 59518b6a94..dc1b5478df 100644
--- a/Content.Server/Shuttles/EntitySystems/SpaceGarbageSystem.cs
+++ b/Content.Server/Shuttles/Systems/SpaceGarbageSystem.cs
@@ -2,7 +2,7 @@ using Content.Server.Shuttles.Components;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Dynamics;
-namespace Content.Server.Shuttles.EntitySystems;
+namespace Content.Server.Shuttles.Systems;
///
/// Deletes anything with that has a cross-grid collision with a static body.
diff --git a/Content.Server/Shuttles/EntitySystems/ThrusterSystem.cs b/Content.Server/Shuttles/Systems/ThrusterSystem.cs
similarity index 99%
rename from Content.Server/Shuttles/EntitySystems/ThrusterSystem.cs
rename to Content.Server/Shuttles/Systems/ThrusterSystem.cs
index fda51ecd39..b2cab2c9a0 100644
--- a/Content.Server/Shuttles/EntitySystems/ThrusterSystem.cs
+++ b/Content.Server/Shuttles/Systems/ThrusterSystem.cs
@@ -9,8 +9,8 @@ using Content.Shared.Examine;
using Content.Shared.Interaction;
using Content.Shared.Maps;
using Content.Shared.Physics;
-using Content.Shared.Temperature;
using Content.Shared.Shuttles.Components;
+using Content.Shared.Temperature;
using Robust.Server.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Physics;
@@ -18,7 +18,7 @@ using Robust.Shared.Physics.Collision.Shapes;
using Robust.Shared.Physics.Dynamics;
using Robust.Shared.Utility;
-namespace Content.Server.Shuttles.EntitySystems
+namespace Content.Server.Shuttles.Systems
{
public sealed class ThrusterSystem : EntitySystem
{
diff --git a/Content.Server/Singularity/Components/ContainmentFieldConnection.cs b/Content.Server/Singularity/Components/ContainmentFieldConnection.cs
index 6851a3b84d..ccfc503a08 100644
--- a/Content.Server/Singularity/Components/ContainmentFieldConnection.cs
+++ b/Content.Server/Singularity/Components/ContainmentFieldConnection.cs
@@ -1,13 +1,15 @@
using System.Threading;
+using Content.Server.Singularity.EntitySystems;
using Content.Shared.Singularity.Components;
+using Robust.Server.GameObjects;
using Timer = Robust.Shared.Timing.Timer;
namespace Content.Server.Singularity.Components
{
public sealed class ContainmentFieldConnection : IDisposable
{
- public readonly ContainmentFieldGeneratorComponent Generator1;
- public readonly ContainmentFieldGeneratorComponent Generator2;
+ public ContainmentFieldGeneratorComponent Generator1;
+ public ContainmentFieldGeneratorComponent Generator2;
private readonly List _fields = new();
private int _sharedEnergyPool;
private readonly CancellationTokenSource _powerDecreaseCancellationTokenSource = new();
@@ -63,7 +65,7 @@ namespace Content.Server.Singularity.Components
}
- Timer.SpawnRepeating(1000, () => { SharedEnergyPool--;}, _powerDecreaseCancellationTokenSource.Token);
+ Timer.SpawnRepeating(1000, () => { SharedEnergyPool--; }, _powerDecreaseCancellationTokenSource.Token);
}
public bool CanRepel(SharedSingularityComponent toRepel)
@@ -82,8 +84,29 @@ namespace Content.Server.Singularity.Components
}
_fields.Clear();
- Generator1.RemoveConnection(this);
- Generator2.RemoveConnection(this);
+ RemoveConnection(this, Generator1);
+ RemoveConnection(this, Generator2);
+ }
+
+ public void RemoveConnection(ContainmentFieldConnection? connection, ContainmentFieldGeneratorComponent component)
+ {
+ if (component.Connection1?.Item2 == connection)
+ {
+ component.Connection1 = null;
+ }
+ else if (component.Connection2?.Item2 == connection)
+ {
+ component.Connection2 = null;
+ }
+ else if (connection != null)
+ {
+ Logger.Error("RemoveConnection called on Containmentfieldgenerator with a connection that can't be found in its connections.");
+ }
+ if (IoCManager.Resolve().TryGetComponent(component.Owner, out var pointLightComponent))
+ {
+ bool hasAnyConnection = (component.Connection1 != null) || (component.Connection2 != null);
+ pointLightComponent.Enabled = hasAnyConnection;
+ }
}
}
}
diff --git a/Content.Server/Singularity/Components/ContainmentFieldGeneratorComponent.cs b/Content.Server/Singularity/Components/ContainmentFieldGeneratorComponent.cs
index b9f3aad25a..0e9631c202 100644
--- a/Content.Server/Singularity/Components/ContainmentFieldGeneratorComponent.cs
+++ b/Content.Server/Singularity/Components/ContainmentFieldGeneratorComponent.cs
@@ -11,8 +11,6 @@ namespace Content.Server.Singularity.Components
[ComponentReference(typeof(SharedContainmentFieldGeneratorComponent))]
public sealed class ContainmentFieldGeneratorComponent : SharedContainmentFieldGeneratorComponent
{
- [Dependency] private readonly IEntityManager _entMan = default!;
-
private int _powerBuffer;
[ViewVariables]
@@ -22,153 +20,8 @@ namespace Content.Server.Singularity.Components
set => _powerBuffer = Math.Clamp(value, 0, 6);
}
- public void ReceivePower(int power)
- {
- var totalPower = power + PowerBuffer;
- var powerPerConnection = totalPower / 2;
- var newBuffer = totalPower % 2;
- TryPowerConnection(ref _connection1, ref newBuffer, powerPerConnection);
- TryPowerConnection(ref _connection2, ref newBuffer, powerPerConnection);
+ public Tuple? Connection1;
+ public Tuple? Connection2;
- PowerBuffer = newBuffer;
- }
-
- private void TryPowerConnection(ref Tuple? connectionProperty, ref int powerBuffer, int powerPerConnection)
- {
- if (connectionProperty != null)
- {
- connectionProperty.Item2.SharedEnergyPool += powerPerConnection;
- }
- else
- {
- if (TryGenerateFieldConnection(ref connectionProperty))
- {
- connectionProperty.Item2.SharedEnergyPool += powerPerConnection;
- }
- else
- {
- powerBuffer += powerPerConnection;
- }
- }
- }
-
- private Tuple? _connection1;
- private Tuple? _connection2;
-
- public bool CanRepel(SharedSingularityComponent toRepel) => _connection1?.Item2?.CanRepel(toRepel) == true ||
- _connection2?.Item2?.CanRepel(toRepel) == true;
-
- public void OnAnchoredChanged()
- {
- if(_entMan.TryGetComponent(Owner, out var physicsComponent) && physicsComponent.BodyType != BodyType.Static)
- {
- _connection1?.Item2.Dispose();
- _connection2?.Item2.Dispose();
- }
- }
-
- private bool IsConnectedWith(ContainmentFieldGeneratorComponent comp)
- {
-
- return comp == this || _connection1?.Item2.Generator1 == comp || _connection1?.Item2.Generator2 == comp ||
- _connection2?.Item2.Generator1 == comp || _connection2?.Item2.Generator2 == comp;
- }
-
- public bool HasFreeConnections()
- {
- return _connection1 == null || _connection2 == null;
- }
-
- private bool TryGenerateFieldConnection([NotNullWhen(true)] ref Tuple? propertyFieldTuple)
- {
- if (propertyFieldTuple != null) return false;
- if(_entMan.TryGetComponent(Owner, out var physicsComponent) && physicsComponent.BodyType != BodyType.Static) return false;
-
- foreach (var direction in new[] {Direction.North, Direction.East, Direction.South, Direction.West})
- {
- if (_connection1?.Item1 == direction || _connection2?.Item1 == direction) continue;
-
- var dirVec = _entMan.GetComponent(Owner).WorldRotation.RotateVec(direction.ToVec());
- var ray = new CollisionRay(_entMan.GetComponent(Owner).WorldPosition, dirVec, (int) CollisionGroup.MobMask);
- var rawRayCastResults = EntitySystem.Get().IntersectRay(_entMan.GetComponent(Owner).MapID, ray, 4.5f, Owner, false);
-
- var rayCastResults = rawRayCastResults as RayCastResults[] ?? rawRayCastResults.ToArray();
- if(!rayCastResults.Any()) continue;
-
- RayCastResults? closestResult = null;
- var smallestDist = 4.5f;
- foreach (var res in rayCastResults)
- {
- if (res.Distance > smallestDist) continue;
-
- smallestDist = res.Distance;
- closestResult = res;
- }
- if(closestResult == null) continue;
- var ent = closestResult.Value.HitEntity;
- if (!_entMan.TryGetComponent(ent, out var fieldGeneratorComponent) ||
- fieldGeneratorComponent.Owner == Owner ||
- !fieldGeneratorComponent.HasFreeConnections() ||
- IsConnectedWith(fieldGeneratorComponent) ||
- !_entMan.TryGetComponent(ent, out var collidableComponent) ||
- collidableComponent.BodyType != BodyType.Static)
- {
- continue;
- }
-
- var connection = new ContainmentFieldConnection(this, fieldGeneratorComponent);
- propertyFieldTuple = new Tuple(direction, connection);
- if (fieldGeneratorComponent._connection1 == null)
- {
- fieldGeneratorComponent._connection1 = new Tuple(direction.GetOpposite(), connection);
- }
- else if (fieldGeneratorComponent._connection2 == null)
- {
- fieldGeneratorComponent._connection2 = new Tuple(direction.GetOpposite(), connection);
- }
- else
- {
- Logger.Error("When trying to connect two Containmentfieldgenerators, the second one already had two connection but the check didn't catch it");
- }
- UpdateConnectionLights();
- return true;
- }
-
- return false;
- }
-
- public void RemoveConnection(ContainmentFieldConnection? connection)
- {
- if (_connection1?.Item2 == connection)
- {
- _connection1 = null;
- UpdateConnectionLights();
- }
- else if (_connection2?.Item2 == connection)
- {
- _connection2 = null;
- UpdateConnectionLights();
- }
- else if(connection != null)
- {
- Logger.Error("RemoveConnection called on Containmentfieldgenerator with a connection that can't be found in its connections.");
- }
- }
-
- public void UpdateConnectionLights()
- {
- if (_entMan.TryGetComponent(Owner, out var pointLightComponent))
- {
- bool hasAnyConnection = (_connection1 != null) || (_connection2 != null);
- pointLightComponent.Enabled = hasAnyConnection;
- }
- }
-
- protected override void OnRemove()
- {
- _connection1?.Item2.Dispose();
- _connection2?.Item2.Dispose();
- base.OnRemove();
- }
}
}
diff --git a/Content.Server/Singularity/EntitySystems/ContainmentFieldGeneratorSystem.cs b/Content.Server/Singularity/EntitySystems/ContainmentFieldGeneratorSystem.cs
index 67e92dc163..0cee86fbc0 100644
--- a/Content.Server/Singularity/EntitySystems/ContainmentFieldGeneratorSystem.cs
+++ b/Content.Server/Singularity/EntitySystems/ContainmentFieldGeneratorSystem.cs
@@ -1,8 +1,13 @@
using Content.Server.ParticleAccelerator.Components;
using Content.Server.Singularity.Components;
+using Content.Shared.Physics;
using Content.Shared.Singularity.Components;
using Content.Shared.Tag;
+using Robust.Server.GameObjects;
+using Robust.Shared.Physics;
using Robust.Shared.Physics.Dynamics;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
namespace Content.Server.Singularity.EntitySystems
{
@@ -14,10 +19,26 @@ namespace Content.Server.Singularity.EntitySystems
{
base.Initialize();
- SubscribeLocalEvent(BodyTypeChanged);
+ SubscribeLocalEvent(OnComponentRemoved);
SubscribeLocalEvent(HandleFieldCollide);
SubscribeLocalEvent(HandleGeneratorCollide);
SubscribeLocalEvent(HandleParticleCollide);
+ SubscribeLocalEvent(OnAnchorChanged);
+ }
+
+ private void OnComponentRemoved(EntityUid uid, ContainmentFieldGeneratorComponent component, ComponentRemove args)
+ {
+ component.Connection1?.Item2.Dispose();
+ component.Connection2?.Item2.Dispose();
+ }
+
+ private void OnAnchorChanged(EntityUid uid, ContainmentFieldGeneratorComponent component, ref AnchorStateChangedEvent args)
+ {
+ if (!args.Anchored)
+ {
+ component.Connection1?.Item2.Dispose();
+ component.Connection2?.Item2.Dispose();
+ }
}
private void HandleParticleCollide(EntityUid uid, ParticleProjectileComponent component, StartCollideEvent args)
@@ -40,8 +61,9 @@ namespace Content.Server.Singularity.EntitySystems
private void HandleGeneratorCollide(EntityUid uid, ContainmentFieldGeneratorComponent component, StartCollideEvent args)
{
- if (_tags.HasTag(args.OtherFixture.Body.Owner, "EmitterBolt")) {
- component.ReceivePower(6);
+ if (_tags.HasTag(args.OtherFixture.Body.Owner, "EmitterBolt"))
+ {
+ ReceivePower(6, component);
}
}
@@ -54,12 +76,135 @@ namespace Content.Server.Singularity.EntitySystems
}
}
- private static void BodyTypeChanged(
- EntityUid uid,
- ContainmentFieldGeneratorComponent component,
- ref PhysicsBodyTypeChangedEvent args)
+ public void ReceivePower(int power, ContainmentFieldGeneratorComponent component)
{
- component.OnAnchoredChanged();
+ var totalPower = power + component.PowerBuffer;
+ var powerPerConnection = totalPower / 2;
+ var newBuffer = totalPower % 2;
+ TryPowerConnection(ref component.Connection1, ref newBuffer, powerPerConnection, component);
+ TryPowerConnection(ref component.Connection2, ref newBuffer, powerPerConnection, component);
+
+ component.PowerBuffer = newBuffer;
}
+
+ public void UpdateConnectionLights(ContainmentFieldGeneratorComponent component)
+ {
+ if (EntityManager.TryGetComponent(component.Owner, out var pointLightComponent))
+ {
+ bool hasAnyConnection = (component.Connection1 != null) || (component.Connection2 != null);
+ pointLightComponent.Enabled = hasAnyConnection;
+ }
+ }
+
+ public void RemoveConnection(ContainmentFieldConnection? connection, ContainmentFieldGeneratorComponent component)
+ {
+ if (component.Connection1?.Item2 == connection)
+ {
+ component.Connection1 = null;
+ UpdateConnectionLights(component);
+ }
+ else if (component.Connection2?.Item2 == connection)
+ {
+ component.Connection2 = null;
+ UpdateConnectionLights(component);
+ }
+ else if (connection != null)
+ {
+ Logger.Error("RemoveConnection called on Containmentfieldgenerator with a connection that can't be found in its connections.");
+ }
+ }
+
+ private bool TryGenerateFieldConnection([NotNullWhen(true)] ref Tuple? propertyFieldTuple, ContainmentFieldGeneratorComponent component)
+ {
+ if (propertyFieldTuple != null) return false;
+ if (EntityManager.TryGetComponent(component.Owner, out var xform) && !xform.Anchored) return false;
+
+ foreach (var direction in new[] { Direction.North, Direction.East, Direction.South, Direction.West })
+ {
+ if (component.Connection1?.Item1 == direction || component.Connection2?.Item1 == direction) continue;
+
+ var dirVec = EntityManager.GetComponent(component.Owner).WorldRotation.RotateVec(direction.ToVec());
+ var ray = new CollisionRay(EntityManager.GetComponent(component.Owner).WorldPosition, dirVec, (int) CollisionGroup.MobMask);
+ var rawRayCastResults = EntitySystem.Get().IntersectRay(EntityManager.GetComponent(component.Owner).MapID, ray, 4.5f, component.Owner, false);
+
+ var rayCastResults = rawRayCastResults as RayCastResults[] ?? rawRayCastResults.ToArray();
+ if (!rayCastResults.Any()) continue;
+
+ RayCastResults? closestResult = null;
+ var smallestDist = 4.5f;
+ foreach (var res in rayCastResults)
+ {
+ if (res.Distance > smallestDist) continue;
+
+ smallestDist = res.Distance;
+ closestResult = res;
+ }
+ if (closestResult == null) continue;
+ var ent = closestResult.Value.HitEntity;
+ if (!EntityManager.TryGetComponent(ent, out var fieldGeneratorComponent) ||
+ fieldGeneratorComponent.Owner == component.Owner ||
+ !HasFreeConnections(fieldGeneratorComponent) ||
+ IsConnectedWith(component, fieldGeneratorComponent) ||
+ !EntityManager.TryGetComponent(ent, out var collidableComponent) ||
+ collidableComponent.BodyType != BodyType.Static)
+ {
+ continue;
+ }
+
+ var connection = new ContainmentFieldConnection(component, fieldGeneratorComponent);
+ propertyFieldTuple = new Tuple(direction, connection);
+ if (fieldGeneratorComponent.Connection1 == null)
+ {
+ fieldGeneratorComponent.Connection1 = new Tuple(direction.GetOpposite(), connection);
+ }
+ else if (fieldGeneratorComponent.Connection2 == null)
+ {
+ fieldGeneratorComponent.Connection2 = new Tuple(direction.GetOpposite(), connection);
+ }
+ else
+ {
+ Logger.Error("When trying to connect two Containmentfieldgenerators, the second one already had two connection but the check didn't catch it");
+ }
+ UpdateConnectionLights(component);
+ return true;
+ }
+
+ return false;
+ }
+
+ private bool IsConnectedWith(ContainmentFieldGeneratorComponent comp, ContainmentFieldGeneratorComponent otherComp)
+ {
+ return otherComp == comp || comp.Connection1?.Item2.Generator1 == otherComp || comp.Connection1?.Item2.Generator2 == otherComp ||
+ comp.Connection2?.Item2.Generator1 == otherComp || comp.Connection2?.Item2.Generator2 == otherComp;
+ }
+
+ public void TryPowerConnection(ref Tuple? connectionProperty, ref int powerBuffer, int powerPerConnection, ContainmentFieldGeneratorComponent component)
+ {
+ if (connectionProperty != null)
+ {
+ connectionProperty.Item2.SharedEnergyPool += powerPerConnection;
+ }
+ else
+ {
+ if (TryGenerateFieldConnection(ref connectionProperty, component))
+ {
+ connectionProperty.Item2.SharedEnergyPool += powerPerConnection;
+ }
+ else
+ {
+ powerBuffer += powerPerConnection;
+ }
+ }
+ }
+
+ public bool CanRepel(SharedSingularityComponent toRepel, ContainmentFieldGeneratorComponent component) => component.Connection1?.Item2?.CanRepel(toRepel) == true ||
+ component.Connection2?.Item2?.CanRepel(toRepel) == true;
+
+ public bool HasFreeConnections(ContainmentFieldGeneratorComponent component)
+ {
+ return component.Connection1 == null || component.Connection2 == null;
+ }
+
+
}
}
diff --git a/Content.Server/Singularity/EntitySystems/SingularitySystem.cs b/Content.Server/Singularity/EntitySystems/SingularitySystem.cs
index 671d6d5ef9..eb78038e3f 100644
--- a/Content.Server/Singularity/EntitySystems/SingularitySystem.cs
+++ b/Content.Server/Singularity/EntitySystems/SingularitySystem.cs
@@ -18,7 +18,7 @@ namespace Content.Server.Singularity.EntitySystems
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly SharedContainerSystem _container = default!;
[Dependency] private readonly PVSOverrideSystem _pvs = default!;
-
+ [Dependency] private readonly ContainmentFieldGeneratorSystem _fieldGeneratorSystem = default!;
///
/// How much energy the singulo gains from destroying a tile.
///
@@ -132,7 +132,7 @@ namespace Content.Server.Singularity.EntitySystems
!EntityManager.HasComponent(entity) &&
(component.Level > 4 ||
!EntityManager.HasComponent(entity) &&
- !(EntityManager.TryGetComponent(entity, out var containFieldGen) && containFieldGen.CanRepel(component)));
+ !(EntityManager.TryGetComponent(entity, out var containFieldGen) && _fieldGeneratorSystem.CanRepel(component, containFieldGen)));
}
private void HandleDestroy(ServerSingularityComponent component, EntityUid entity)
diff --git a/Content.Server/Speech/Components/MobsterAccentComponent.cs b/Content.Server/Speech/Components/MobsterAccentComponent.cs
new file mode 100644
index 0000000000..f67ea32792
--- /dev/null
+++ b/Content.Server/Speech/Components/MobsterAccentComponent.cs
@@ -0,0 +1,15 @@
+namespace Content.Server.Speech.Components;
+
+///
+/// Nyehh, my gabagool, see?
+/// Etc etc.
+///
+[RegisterComponent]
+public sealed class MobsterAccentComponent : Component
+{
+ ///
+ /// Do you make all the rules?
+ ///
+ [DataField("isBoss")]
+ public bool IsBoss = true;
+}
diff --git a/Content.Server/Speech/EntitySystems/MobsterAccentSystem.cs b/Content.Server/Speech/EntitySystems/MobsterAccentSystem.cs
new file mode 100644
index 0000000000..aeaf898fb1
--- /dev/null
+++ b/Content.Server/Speech/EntitySystems/MobsterAccentSystem.cs
@@ -0,0 +1,89 @@
+using System.Globalization;
+using System.Text.RegularExpressions;
+using Content.Server.Speech.Components;
+using Robust.Shared.Random;
+
+namespace Content.Server.Speech.EntitySystems;
+
+public sealed class MobsterAccentSystem : EntitySystem
+{
+ [Dependency] private readonly IRobustRandom _random = default!;
+
+ private static readonly Dictionary DirectReplacements = new()
+ {
+ { "let me", "lemme" },
+ { "should", "oughta" },
+ { "the", "da" },
+ { "kill", "whack" },
+ { "murder", "whack" },
+ { "dead", "sleepin' with da fishies"},
+ { "hey", "ey'o" },
+ { "rules", "roolz" },
+ { "you", "yous" },
+ { "have to", "gotta" },
+ { "here", "'ere" }
+ };
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(OnAccentGet);
+ }
+
+ public string Accentuate(string message, MobsterAccentComponent component)
+ {
+ // Order:
+ // Do text manipulations first
+ // Then prefix/suffix funnyies
+
+ var msg = message;
+
+ foreach (var (first, replace) in DirectReplacements)
+ {
+ msg = msg.Replace(first, replace, true, CultureInfo.InvariantCulture);
+ }
+
+ // thinking -> thinkin'
+ msg = Regex.Replace(msg, @"ing(?!\w)", "in'", RegexOptions.IgnoreCase);
+
+ // or -> uh and ar -> ah in the middle of words (fuhget, tahget)
+ msg = Regex.Replace(msg, @"(?<=\w)or(?=\w)", "uh", RegexOptions.IgnoreCase);
+ msg = Regex.Replace(msg, @"(?<=\w)ar(?=\w)", "ah", RegexOptions.IgnoreCase);
+
+ // Prefix
+ if (_random.Prob(0.15f))
+ {
+ var pick = _random.Next(1, 2);
+
+ // Reverse sanitize capital
+ msg = msg[0].ToString().ToLower() + msg.Remove(0, 1);
+ msg = Loc.GetString($"accent-mobster-prefix-{pick}") + " " + msg;
+ }
+
+ // Sanitize capital again, in case we substituted a word that should be capitalized
+ msg = msg[0].ToString().ToUpper() + msg.Remove(0, 1);
+
+ // Suffixes
+ if (_random.Prob(0.4f))
+ {
+ if (component.IsBoss)
+ {
+ var pick = _random.Next(1, 4);
+ msg += Loc.GetString($"accent-mobster-suffix-boss-{pick}");
+ }
+ else
+ {
+ var pick = _random.Next(1, 3);
+ msg += Loc.GetString($"accent-mobster-suffix-minion-{pick}");
+ }
+ }
+
+ return msg;
+ }
+
+ private void OnAccentGet(EntityUid uid, MobsterAccentComponent component, AccentGetEvent args)
+ {
+ args.Message = Accentuate(args.Message, component);
+ }
+}
diff --git a/Content.Server/Station/Systems/StationSystem.cs b/Content.Server/Station/Systems/StationSystem.cs
index 0bd3fcab66..8a72b9826c 100644
--- a/Content.Server/Station/Systems/StationSystem.cs
+++ b/Content.Server/Station/Systems/StationSystem.cs
@@ -182,24 +182,21 @@ public sealed class StationSystem : EntitySystem
if (stationConfig is not null && name is null)
{
- metaData.EntityName = GenerateStationName(stationConfig);
+ name = GenerateStationName(stationConfig);
}
- else if (name is not null)
- {
- metaData.EntityName = name;
- }
- else
+ else if (name is null)
{
_sawmill.Error($"When setting up station {station}, was unable to find a valid name in the config and no name was provided.");
- metaData.EntityName = "unnamed station";
+ name = "unnamed station";
}
+ metaData.EntityName = name;
RaiseLocalEvent(new StationInitializedEvent(station));
_sawmill.Info($"Set up station {metaData.EntityName} ({station}).");
foreach (var grid in gridIds ?? Array.Empty())
{
- AddGridToStation(station, grid, null, data);
+ AddGridToStation(station, grid, null, data, name);
}
return station;
@@ -213,13 +210,16 @@ public sealed class StationSystem : EntitySystem
/// Resolve pattern, grid component of mapGrid.
/// Resolve pattern, station data component of station.
/// Thrown when mapGrid or station are not a grid or station, respectively.
- public void AddGridToStation(EntityUid station, EntityUid mapGrid, IMapGridComponent? gridComponent = null, StationDataComponent? stationData = null)
+ public void AddGridToStation(EntityUid station, EntityUid mapGrid, IMapGridComponent? gridComponent = null, StationDataComponent? stationData = null, string? name = null)
{
if (!Resolve(mapGrid, ref gridComponent))
throw new ArgumentException("Tried to initialize a station on a non-grid entity!", nameof(mapGrid));
if (!Resolve(station, ref stationData))
throw new ArgumentException("Tried to use a non-station entity as a station!", nameof(station));
+ if (!string.IsNullOrEmpty(name))
+ MetaData(mapGrid).EntityName = name;
+
var stationMember = AddComp(mapGrid);
stationMember.Station = station;
stationData.Grids.Add(gridComponent.Owner);
diff --git a/Content.Server/StationEvents/Events/DiseaseOutbreak.cs b/Content.Server/StationEvents/Events/DiseaseOutbreak.cs
index e78cd0a1c4..756fa3f912 100644
--- a/Content.Server/StationEvents/Events/DiseaseOutbreak.cs
+++ b/Content.Server/StationEvents/Events/DiseaseOutbreak.cs
@@ -37,6 +37,8 @@ public sealed class DiseaseOutbreak : StationEvent
public override SoundSpecifier? StartAudio => new SoundPathSpecifier("/Audio/Announcements/outbreak7.ogg");
protected override float EndAfter => 1.0f;
+ public override bool AnnounceEvent => false;
+
///
/// Finds 2-5 random, alive entities that can host diseases
/// and gives them a randomly selected disease.
@@ -79,6 +81,8 @@ public sealed class DiseaseOutbreak : StationEvent
stationsToNotify.Add((EntityUid) station);
}
+ if (!AnnounceEvent)
+ return;
foreach (var station in stationsToNotify)
{
chatSystem.DispatchStationAnnouncement(station, Loc.GetString("station-event-disease-outbreak-announcement"),
diff --git a/Content.Server/StationEvents/Events/GasLeak.cs b/Content.Server/StationEvents/Events/GasLeak.cs
index ab59f6a91b..cfe80c6711 100644
--- a/Content.Server/StationEvents/Events/GasLeak.cs
+++ b/Content.Server/StationEvents/Events/GasLeak.cs
@@ -20,6 +20,7 @@ namespace Content.Server.StationEvents.Events
protected override string EndAnnouncement => Loc.GetString("station-event-gas-leak-end-announcement");
private static readonly Gas[] LeakableGases = {
+ Gas.Miasma,
Gas.Plasma,
Gas.Tritium,
};
diff --git a/Content.Server/StationEvents/Events/KudzuGrowth.cs b/Content.Server/StationEvents/Events/KudzuGrowth.cs
index 497b4a98d0..11153e2a88 100644
--- a/Content.Server/StationEvents/Events/KudzuGrowth.cs
+++ b/Content.Server/StationEvents/Events/KudzuGrowth.cs
@@ -27,6 +27,8 @@ public sealed class KudzuGrowth : StationEvent
// Give crew at least 9 minutes to either have it gone, or to suffer another event. Kudzu is not actually required to be dead for another event to roll.
protected override float EndAfter => 60*4;
+ public override bool AnnounceEvent => false;
+
private EntityUid _targetGrid;
private Vector2i _targetTile;
diff --git a/Content.Server/StationEvents/Events/MouseMigration.cs b/Content.Server/StationEvents/Events/MouseMigration.cs
new file mode 100644
index 0000000000..ee7510e6ee
--- /dev/null
+++ b/Content.Server/StationEvents/Events/MouseMigration.cs
@@ -0,0 +1,52 @@
+using System.Linq;
+using Content.Server.StationEvents.Components;
+using Robust.Shared.Random;
+
+namespace Content.Server.StationEvents.Events;
+
+public sealed class MouseMigration : StationEvent
+{
+ [Dependency] private readonly IRobustRandom _random = default!;
+ [Dependency] private readonly IEntityManager _entityManager = default!;
+
+ public static List SpawnedPrototypeChoices = new List() //we double up for that ez fake probability
+ {"MobMouse", "MobMouse1", "MobMouse2", "MobRatServant"};
+
+ public override string Name => "MouseMigration";
+
+ public override string? StartAnnouncement =>
+ Loc.GetString("station-event-mouse-migration-announcement");
+
+ public override int EarliestStart => 30;
+
+ public override int MinimumPlayers => 35; //this just ensures that it doesn't spawn on lowpop maps.
+
+ public override float Weight => WeightLow;
+
+ public override int? MaxOccurrences => 1;
+
+ public override bool AnnounceEvent => false;
+
+ protected override float StartAfter => 30f;
+
+ protected override float EndAfter => 60;
+
+ public override void Startup()
+ {
+ base.Startup();
+
+ var spawnLocations = _entityManager.EntityQuery().ToList();
+ _random.Shuffle(spawnLocations);
+
+ var spawnAmount = _random.Next(7, 15); // A small colony of critters.
+
+ for (int i = 0; i < spawnAmount && i < spawnLocations.Count - 1; i++)
+ {
+ var spawnChoice = _random.Pick(SpawnedPrototypeChoices);
+ if (_random.Prob(0.01f) || i == 0) //small chance for multiple, but always at least 1
+ spawnChoice = "MobRatKing";
+
+ _entityManager.SpawnEntity(spawnChoice, spawnLocations[i].Item2.Coordinates);
+ }
+ }
+}
diff --git a/Content.Server/StationEvents/Events/RadiationStorm.cs b/Content.Server/StationEvents/Events/RadiationStorm.cs
deleted file mode 100644
index a573ca0f56..0000000000
--- a/Content.Server/StationEvents/Events/RadiationStorm.cs
+++ /dev/null
@@ -1,136 +0,0 @@
-using Content.Server.Radiation;
-using Content.Server.Station.Components;
-using Content.Server.Station.Systems;
-using Content.Shared.Coordinates;
-using Content.Shared.Sound;
-using JetBrains.Annotations;
-using Robust.Shared.Map;
-using Robust.Shared.Random;
-
-namespace Content.Server.StationEvents.Events
-{
- [UsedImplicitly]
- public sealed class RadiationStorm : StationEvent
- {
- // Based on Goonstation style radiation storm with some TG elements (announcer, etc.)
-
- [Dependency] private readonly IEntityManager _entityManager = default!;
- [Dependency] private readonly IRobustRandom _robustRandom = default!;
-
- private StationSystem _stationSystem = default!;
-
- public override string Name => "RadiationStorm";
- public override string StartAnnouncement => Loc.GetString("station-event-radiation-storm-start-announcement");
- protected override string EndAnnouncement => Loc.GetString("station-event-radiation-storm-end-announcement");
- public override SoundSpecifier? StartAudio => new SoundPathSpecifier("/Audio/Announcements/radiation.ogg");
- protected override float StartAfter => 10.0f;
-
- // Event specific details
- private float _timeUntilPulse;
- private const float MinPulseDelay = 0.2f;
- private const float MaxPulseDelay = 0.8f;
- private EntityUid _target = EntityUid.Invalid;
-
- private void ResetTimeUntilPulse()
- {
- _timeUntilPulse = _robustRandom.NextFloat() * (MaxPulseDelay - MinPulseDelay) + MinPulseDelay;
- }
-
- public override void Announce()
- {
- base.Announce();
- EndAfter = _robustRandom.Next(30, 80) + StartAfter; // We want to be forgiving about the radstorm.
- }
-
- public override void Startup()
- {
- _entityManager.EntitySysManager.Resolve(ref _stationSystem);
- ResetTimeUntilPulse();
-
- if (_stationSystem.Stations.Count == 0)
- {
- Running = false;
- return;
- }
-
- _target = _robustRandom.Pick(_stationSystem.Stations);
- base.Startup();
- }
-
- public override void Update(float frameTime)
- {
- base.Update(frameTime);
-
- if (!Started || !Running) return;
- if (_target.Valid == false)
- {
- Running = false;
- return;
- }
-
- _timeUntilPulse -= frameTime;
-
- if (_timeUntilPulse <= 0.0f)
- {
- var mapManager = IoCManager.Resolve();
- // Account for split stations by just randomly picking a piece of it.
- var possibleTargets = _entityManager.GetComponent(_target).Grids;
- if (possibleTargets.Count == 0)
- {
- Running = false;
- return;
- }
-
- var stationEnt = _robustRandom.Pick(possibleTargets);
-
- if (!_entityManager.TryGetComponent(stationEnt, out var grid))
- return;
-
- if (mapManager.IsGridPaused(grid.Owner))
- return;
-
- SpawnPulse(grid.Grid);
- }
- }
-
- private void SpawnPulse(IMapGrid mapGrid)
- {
- if (!TryFindRandomGrid(mapGrid, out var coordinates))
- return;
-
- var pulse = _entityManager.SpawnEntity("RadiationPulse", coordinates);
- _entityManager.GetComponent(pulse).DoPulse();
- ResetTimeUntilPulse();
- }
-
- public void SpawnPulseAt(EntityCoordinates at)
- {
- var pulse = IoCManager.Resolve()
- .SpawnEntity("RadiationPulse", at);
- _entityManager.GetComponent(pulse).DoPulse();
- }
-
- private bool TryFindRandomGrid(IMapGrid mapGrid, out EntityCoordinates coordinates)
- {
- if (!(mapGrid.GridEntityId).IsValid())
- {
- coordinates = default;
- return false;
- }
-
- var bounds = mapGrid.LocalAABB;
- var randomX = _robustRandom.Next((int) bounds.Left, (int) bounds.Right);
- var randomY = _robustRandom.Next((int) bounds.Bottom, (int) bounds.Top);
-
- coordinates = mapGrid.ToCoordinates(randomX, randomY);
-
- // TODO: Need to get valid tiles? (maybe just move right if the tile we chose is invalid?)
- if (!coordinates.IsValid(_entityManager))
- {
- coordinates = default;
- return false;
- }
- return true;
- }
- }
-}
diff --git a/Content.Server/StationEvents/Events/StationEvent.cs b/Content.Server/StationEvents/Events/StationEvent.cs
index 0f8872a1e0..427d67a0f7 100644
--- a/Content.Server/StationEvents/Events/StationEvent.cs
+++ b/Content.Server/StationEvents/Events/StationEvent.cs
@@ -107,6 +107,11 @@ namespace Content.Server.StationEvents.Events
///
public virtual int? MaxOccurrences { get; } = null;
+ ///
+ /// Whether or not the event is announced when it is run
+ ///
+ public virtual bool AnnounceEvent { get; } = true;
+
///
/// Has the startup time elapsed?
///
@@ -139,13 +144,13 @@ namespace Content.Server.StationEvents.Events
IoCManager.Resolve()
.Add(LogType.EventAnnounced, $"Event announce: {Name}");
- if (StartAnnouncement != null)
+ if (AnnounceEvent && StartAnnouncement != null)
{
var chatSystem = IoCManager.Resolve().GetEntitySystem();
chatSystem.DispatchGlobalStationAnnouncement(StartAnnouncement, playDefaultSound: false, colorOverride: Color.Gold);
}
- if (StartAudio != null)
+ if (AnnounceEvent && StartAudio != null)
{
SoundSystem.Play(StartAudio.GetSound(), Filter.Broadcast(), AudioParams);
}
@@ -162,13 +167,13 @@ namespace Content.Server.StationEvents.Events
IoCManager.Resolve()
.Add(LogType.EventStopped, $"Event shutdown: {Name}");
- if (EndAnnouncement != null)
+ if (AnnounceEvent && EndAnnouncement != null)
{
var chatSystem = IoCManager.Resolve().GetEntitySystem();
chatSystem.DispatchGlobalStationAnnouncement(EndAnnouncement, playDefaultSound: false, colorOverride: Color.Gold);
}
- if (EndAudio != null)
+ if (AnnounceEvent && EndAudio != null)
{
SoundSystem.Play(EndAudio.GetSound(), Filter.Broadcast(), AudioParams);
}
diff --git a/Content.Server/StationEvents/Events/VentCritters.cs b/Content.Server/StationEvents/Events/VentCritters.cs
index fa288f7820..9788aab126 100644
--- a/Content.Server/StationEvents/Events/VentCritters.cs
+++ b/Content.Server/StationEvents/Events/VentCritters.cs
@@ -32,6 +32,8 @@ public sealed class VentCritters : StationEvent
protected override float EndAfter => 60;
+ public override bool AnnounceEvent => false;
+
public override void Startup()
{
base.Startup();
diff --git a/Content.Server/StationEvents/Events/ZombieOutbreak.cs b/Content.Server/StationEvents/Events/ZombieOutbreak.cs
index 891171833b..1025aafaf8 100644
--- a/Content.Server/StationEvents/Events/ZombieOutbreak.cs
+++ b/Content.Server/StationEvents/Events/ZombieOutbreak.cs
@@ -19,11 +19,10 @@ namespace Content.Server.StationEvents.Events
public override string Name => "ZombieOutbreak";
public override int EarliestStart => 50;
public override float Weight => WeightLow / 2;
-
public override SoundSpecifier? StartAudio => new SoundPathSpecifier("/Audio/Announcements/bloblarm.ogg");
protected override float EndAfter => 1.0f;
-
public override int? MaxOccurrences => 1;
+ public override bool AnnounceEvent => false;
///
/// Finds 1-3 random, dead entities accross the station
@@ -61,6 +60,9 @@ namespace Content.Server.StationEvents.Events
if(station == null) continue;
stationsToNotify.Add((EntityUid) station);
}
+
+ if (!AnnounceEvent)
+ return;
foreach (var station in stationsToNotify)
{
chatSystem.DispatchStationAnnouncement((EntityUid) station, Loc.GetString("station-event-zombie-outbreak-announcement"),
diff --git a/Content.Server/Sticky/Systems/StickySystem.cs b/Content.Server/Sticky/Systems/StickySystem.cs
index 6f6376e991..e2c9016100 100644
--- a/Content.Server/Sticky/Systems/StickySystem.cs
+++ b/Content.Server/Sticky/Systems/StickySystem.cs
@@ -41,7 +41,7 @@ public sealed class StickySystem : EntitySystem
private void AddUnstickVerb(EntityUid uid, StickyComponent component, GetVerbsEvent args)
{
- if (component.StuckTo == null || !component.CanUnstick || !args.CanInteract)
+ if (component.StuckTo == null || !component.CanUnstick || !args.CanInteract || args.Hands == null)
return;
// we can't use args.CanAccess, because it stuck in another container
diff --git a/Content.Server/Weapon/Melee/Components/MeleeWeaponComponent.cs b/Content.Server/Weapon/Melee/Components/MeleeWeaponComponent.cs
index c773d2f8e9..d690015857 100644
--- a/Content.Server/Weapon/Melee/Components/MeleeWeaponComponent.cs
+++ b/Content.Server/Weapon/Melee/Components/MeleeWeaponComponent.cs
@@ -28,7 +28,7 @@ namespace Content.Server.Weapon.Melee.Components
[ViewVariables(VVAccess.ReadWrite)]
[DataField("arc")]
- public string Arc { get; set; } = "default";
+ public string? Arc { get; set; } = "default";
[ViewVariables(VVAccess.ReadWrite)]
[DataField("arcwidth")]
diff --git a/Content.Server/Weapon/Melee/EnergySword/Components/EnergySwordComponent.cs b/Content.Server/Weapon/Melee/EnergySword/Components/EnergySwordComponent.cs
index 442f979faf..2f11c73661 100644
--- a/Content.Server/Weapon/Melee/EnergySword/Components/EnergySwordComponent.cs
+++ b/Content.Server/Weapon/Melee/EnergySword/Components/EnergySwordComponent.cs
@@ -36,5 +36,8 @@ namespace Content.Server.Weapon.Melee.EnergySword
[DataField("litDamageBonus", required: true)]
public DamageSpecifier LitDamageBonus = default!;
+
+ [DataField("litDisarmMalus", required: true)]
+ public float litDisarmMalus = 0.6f;
}
}
diff --git a/Content.Server/Weapon/Melee/EnergySword/EnergySwordSystem.cs b/Content.Server/Weapon/Melee/EnergySword/EnergySwordSystem.cs
index ba165e8b49..aa675681a1 100644
--- a/Content.Server/Weapon/Melee/EnergySword/EnergySwordSystem.cs
+++ b/Content.Server/Weapon/Melee/EnergySword/EnergySwordSystem.cs
@@ -5,6 +5,7 @@ using Content.Shared.Light;
using Content.Shared.Light.Component;
using Content.Shared.Toggleable;
using Content.Shared.Tools.Components;
+using Content.Server.CombatMode.Disarm;
using Robust.Shared.Audio;
using Robust.Shared.Player;
using Robust.Shared.Random;
@@ -68,6 +69,11 @@ namespace Content.Server.Weapon.Melee.EnergySword
item.Size = 5;
}
+ if (TryComp(comp.Owner, out var malus))
+ {
+ malus.Malus -= comp.litDisarmMalus;
+ }
+
SoundSystem.Play(comp.DeActivateSound.GetSound(), Filter.Pvs(comp.Owner, entityManager: EntityManager), comp.Owner);
comp.Activated = false;
@@ -85,6 +91,11 @@ namespace Content.Server.Weapon.Melee.EnergySword
SoundSystem.Play(comp.ActivateSound.GetSound(), Filter.Pvs(comp.Owner, entityManager: EntityManager), comp.Owner);
+ if (TryComp(comp.Owner, out var malus))
+ {
+ malus.Malus += comp.litDisarmMalus;
+ }
+
comp.Activated = true;
}
diff --git a/Content.Server/Weapon/Melee/MeleeWeaponSystem.cs b/Content.Server/Weapon/Melee/MeleeWeaponSystem.cs
index 7a67b48564..5b47fc89b4 100644
--- a/Content.Server/Weapon/Melee/MeleeWeaponSystem.cs
+++ b/Content.Server/Weapon/Melee/MeleeWeaponSystem.cs
@@ -124,6 +124,8 @@ namespace Content.Server.Weapon.Melee
private void OnWideAttack(EntityUid owner, MeleeWeaponComponent comp, WideAttackEvent args)
{
+ if (string.IsNullOrEmpty(comp.Arc)) return;
+
args.Handled = true;
var curTime = _gameTiming.CurTime;
diff --git a/Content.Server/Wires/WiresSystem.cs b/Content.Server/Wires/WiresSystem.cs
index eec868491f..0759a54ec4 100644
--- a/Content.Server/Wires/WiresSystem.cs
+++ b/Content.Server/Wires/WiresSystem.cs
@@ -34,8 +34,8 @@ public sealed class WiresSystem : EntitySystem
// This is where all the wire layouts are stored.
[ViewVariables] private readonly Dictionary _layouts = new();
- private const float ScrewTime = 2.5f;
- private const float ToolTime = 1f;
+ private const float ScrewTime = 1f;
+ private float _toolTime = 0f;
private static DummyWireAction _dummyWire = new DummyWireAction();
@@ -649,28 +649,36 @@ public sealed class WiresSystem : EntitySystem
break;
}
- var args = new DoAfterEventArgs(user, ToolTime, default, used)
+ if (_toolTime > 0f)
{
- NeedHand = true,
- BreakOnStun = true,
- BreakOnDamage = true,
- BreakOnUserMove = true,
- TargetFinishedEvent = new OnWireDoAfterEvent
+ var args = new DoAfterEventArgs(user, _toolTime, default, used)
{
- Target = used,
- User = user,
- Tool = toolEntity,
- Action = action,
- Id = id
- },
- TargetCancelledEvent = new OnWireDoAfterCancelEvent
- {
- Id = id
- }
- };
- _doAfter.DoAfter(args);
+ NeedHand = true,
+ BreakOnStun = true,
+ BreakOnDamage = true,
+ BreakOnUserMove = true,
+ TargetFinishedEvent = new OnWireDoAfterEvent
+ {
+ Target = used,
+ User = user,
+ Tool = toolEntity,
+ Action = action,
+ Id = id
+ },
+ TargetCancelledEvent = new OnWireDoAfterCancelEvent
+ {
+ Id = id
+ }
+ };
- wires.WiresQueue.Add(id);
+ _doAfter.DoAfter(args);
+
+ wires.WiresQueue.Add(id);
+ }
+ else
+ {
+ UpdateWires(used, user, toolEntity, id, action, wires);
+ }
}
diff --git a/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Components/GasArtifactComponent.cs b/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Components/GasArtifactComponent.cs
index aa80af0697..e68254d0b3 100644
--- a/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Components/GasArtifactComponent.cs
+++ b/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Components/GasArtifactComponent.cs
@@ -26,7 +26,8 @@ public sealed class GasArtifactComponent : Component
Gas.Plasma,
Gas.Nitrogen,
Gas.CarbonDioxide,
- Gas.Tritium
+ Gas.Tritium,
+ Gas.Miasma,
};
///
diff --git a/Content.Server/Xenoarchaeology/XenoArtifacts/Triggers/Components/ArtifactGasTriggerComponent.cs b/Content.Server/Xenoarchaeology/XenoArtifacts/Triggers/Components/ArtifactGasTriggerComponent.cs
index d1bcea62b2..620ad91978 100644
--- a/Content.Server/Xenoarchaeology/XenoArtifacts/Triggers/Components/ArtifactGasTriggerComponent.cs
+++ b/Content.Server/Xenoarchaeology/XenoArtifacts/Triggers/Components/ArtifactGasTriggerComponent.cs
@@ -17,7 +17,8 @@ public sealed class ArtifactGasTriggerComponent : Component
Gas.Oxygen,
Gas.Plasma,
Gas.Nitrogen,
- Gas.CarbonDioxide
+ Gas.CarbonDioxide,
+ Gas.Miasma
};
///
diff --git a/Content.Shared/Atmos/Atmospherics.cs b/Content.Shared/Atmos/Atmospherics.cs
index f1a3f21c50..61d57ef892 100644
--- a/Content.Shared/Atmos/Atmospherics.cs
+++ b/Content.Shared/Atmos/Atmospherics.cs
@@ -168,7 +168,7 @@ namespace Content.Shared.Atmos
///
/// Total number of gases. Increase this if you want to add more!
///
- public const int TotalNumberOfGases = 6;
+ public const int TotalNumberOfGases = 7;
///
/// This is the actual length of the gases arrays in mixtures.
@@ -285,5 +285,6 @@ namespace Content.Shared.Atmos
Plasma = 3,
Tritium = 4,
WaterVapor = 5,
+ Miasma = 6
}
}
diff --git a/Content.Shared/Atmos/Piping/Unary/Components/SharedVentScrubberComponent.cs b/Content.Shared/Atmos/Piping/Unary/Components/SharedVentScrubberComponent.cs
index c8c4c2cc90..08b7db440a 100644
--- a/Content.Shared/Atmos/Piping/Unary/Components/SharedVentScrubberComponent.cs
+++ b/Content.Shared/Atmos/Piping/Unary/Components/SharedVentScrubberComponent.cs
@@ -20,6 +20,7 @@ namespace Content.Shared.Atmos.Piping.Unary.Components
Gas.Plasma,
Gas.Tritium,
Gas.WaterVapor,
+ Gas.Miasma
};
// Presets for 'dumb' air alarm modes
diff --git a/Content.Shared/CCVar/CCVars.cs b/Content.Shared/CCVar/CCVars.cs
index ad86787728..11303d1c57 100644
--- a/Content.Shared/CCVar/CCVars.cs
+++ b/Content.Shared/CCVar/CCVars.cs
@@ -997,5 +997,15 @@ namespace Content.Shared.CCVar
///
public static readonly CVarDef UpdateRestartDelay =
CVarDef.Create("update.restart_delay", 20f, CVar.SERVERONLY);
+
+ /*
+ * Ghost
+ */
+
+ ///
+ /// The time you must spend reading the rules, before the "Request" button is enabled
+ ///
+ public static readonly CVarDef GhostRoleTime =
+ CVarDef.Create("ghost.role_time", 3f, CVar.REPLICATED);
}
}
diff --git a/Content.Shared/CombatMode/SharedCombatModeComponent.cs b/Content.Shared/CombatMode/SharedCombatModeComponent.cs
index 790a2724bd..8a958f6f59 100644
--- a/Content.Shared/CombatMode/SharedCombatModeComponent.cs
+++ b/Content.Shared/CombatMode/SharedCombatModeComponent.cs
@@ -15,10 +15,10 @@ namespace Content.Shared.CombatMode
private TargetingZone _activeZone;
[DataField("disarmFailChance")]
- public readonly float DisarmFailChance = 0.4f;
+ public readonly float BaseDisarmFailChance = 0.4f;
[DataField("pushChance")]
- public readonly float DisarmPushChance = 0.4f;
+ public readonly float BasePushFailChance = 0.4f;
[DataField("disarmFailSound")]
public readonly SoundSpecifier DisarmFailSound = new SoundPathSpecifier("/Audio/Weapons/punchmiss.ogg");
diff --git a/Content.Shared/Cuffs/SharedCuffableSystem.cs b/Content.Shared/Cuffs/SharedCuffableSystem.cs
index 403a177110..895ba9b831 100644
--- a/Content.Shared/Cuffs/SharedCuffableSystem.cs
+++ b/Content.Shared/Cuffs/SharedCuffableSystem.cs
@@ -7,6 +7,7 @@ using Content.Shared.Item;
using Content.Shared.Movement;
using Content.Shared.Physics.Pull;
using Content.Shared.Pulling.Components;
+using Content.Shared.Pulling.Events;
namespace Content.Shared.Cuffs
{
@@ -25,10 +26,20 @@ namespace Content.Shared.Cuffs
SubscribeLocalEvent(OnUnequipAttempt);
SubscribeLocalEvent(OnDropAttempt);
SubscribeLocalEvent(OnPickupAttempt);
+ SubscribeLocalEvent(OnBeingPulledAttempt);
SubscribeLocalEvent(OnPull);
SubscribeLocalEvent(OnPull);
}
+
+ private void OnBeingPulledAttempt(EntityUid uid, SharedCuffableComponent component, BeingPulledAttemptEvent args)
+ {
+ if (!TryComp(uid, out var pullable))
+ return;
+
+ if (pullable.Puller != null && !component.CanStillInteract) // If we are being pulled already and cuffed, we can't get pulled again.
+ args.Cancel();
+ }
private void OnPull(EntityUid uid, SharedCuffableComponent component, PullMessage args)
{
if (!component.CanStillInteract)
diff --git a/Content.Shared/Doors/Systems/SharedDoorSystem.cs b/Content.Shared/Doors/Systems/SharedDoorSystem.cs
index d91185ac17..06baab6635 100644
--- a/Content.Shared/Doors/Systems/SharedDoorSystem.cs
+++ b/Content.Shared/Doors/Systems/SharedDoorSystem.cs
@@ -219,12 +219,12 @@ public abstract class SharedDoorSystem : EntitySystem
#endregion
#region Opening
- public bool TryOpen(EntityUid uid, DoorComponent? door = null, EntityUid? user = null, bool predicted = false)
+ public bool TryOpen(EntityUid uid, DoorComponent? door = null, EntityUid? user = null, bool predicted = false, bool quiet = false)
{
if (!Resolve(uid, ref door))
return false;
- if (!CanOpen(uid, door, user, false))
+ if (!CanOpen(uid, door, user, quiet))
return false;
StartOpening(uid, door, user, predicted);
diff --git a/Content.Shared/Entry/EntryPoint.cs b/Content.Shared/Entry/EntryPoint.cs
index 348f8ad3be..d7f9d8374b 100644
--- a/Content.Shared/Entry/EntryPoint.cs
+++ b/Content.Shared/Entry/EntryPoint.cs
@@ -41,9 +41,13 @@ namespace Content.Shared.Entry
#if !FULL_RELEASE
var configMan = IoCManager.Resolve();
configMan.OverrideDefault(CVars.NetFakeLagMin, 0.075f);
- configMan.OverrideDefault(CVars.NetFakeLagRand, 0.01f);
configMan.OverrideDefault(CVars.NetFakeLoss, 0.005f);
configMan.OverrideDefault(CVars.NetFakeDuplicates, 0.005f);
+
+ // fake lag rand leads to messages arriving out of order. Sadly, networking is not robust enough, so for now
+ // just leaving this disabled.
+ // configMan.OverrideDefault(CVars.NetFakeLagRand, 0.01f);
+
#endif
}
diff --git a/Content.Shared/Interaction/SharedInteractionSystem.cs b/Content.Shared/Interaction/SharedInteractionSystem.cs
index b11a077e10..cab3afdaeb 100644
--- a/Content.Shared/Interaction/SharedInteractionSystem.cs
+++ b/Content.Shared/Interaction/SharedInteractionSystem.cs
@@ -55,7 +55,7 @@ namespace Content.Shared.Interaction
public const float InteractionRange = 1.4f;
public const float InteractionRangeSquared = InteractionRange * InteractionRange;
- public const float MaxRaycastRange = 100;
+ public const float MaxRaycastRange = 100f;
public delegate bool Ignored(EntityUid entity);
diff --git a/Content.Shared/PowerCell/Components/PowerCellComponent.cs b/Content.Shared/PowerCell/Components/PowerCellComponent.cs
index b8424df0a8..27a0d2ef97 100644
--- a/Content.Shared/PowerCell/Components/PowerCellComponent.cs
+++ b/Content.Shared/PowerCell/Components/PowerCellComponent.cs
@@ -12,25 +12,15 @@ namespace Content.Shared.PowerCell;
public sealed class PowerCellComponent : Component
{
public const string SolutionName = "powerCell";
- public const int PowerCellVisualsLevels = 4;
-
- [DataField("cellSize")]
- public PowerCellSize CellSize = PowerCellSize.Small;
+ public const int PowerCellVisualsLevels = 2;
// Not networked to clients
[ViewVariables(VVAccess.ReadWrite)]
public bool IsRigged { get; set; }
}
-public enum PowerCellSize
-{
- Small = 0,
- Medium = 1,
- Large = 2
-}
-
[Serializable, NetSerializable]
-public enum PowerCellVisuals
+public enum PowerCellVisuals : byte
{
ChargeLevel
}
diff --git a/Content.Shared/PowerCell/Components/PowerCellSlotComponent.cs b/Content.Shared/PowerCell/Components/PowerCellSlotComponent.cs
index 59896c83f4..304ba3dac9 100644
--- a/Content.Shared/PowerCell/Components/PowerCellSlotComponent.cs
+++ b/Content.Shared/PowerCell/Components/PowerCellSlotComponent.cs
@@ -5,13 +5,6 @@ namespace Content.Shared.PowerCell.Components;
[RegisterComponent]
public sealed class PowerCellSlotComponent : Component
{
- ///
- /// What size of cell fits into this component.
- ///
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("slotSize")]
- public PowerCellSize SlotSize { get; set; } = PowerCellSize.Small;
-
///
/// The actual item-slot that contains the cell. Allows all the interaction logic to be handled by .
///
diff --git a/Content.Shared/PowerCell/SharedPowerCellSystem.cs b/Content.Shared/PowerCell/SharedPowerCellSystem.cs
index becc8a04da..ae9c9f973c 100644
--- a/Content.Shared/PowerCell/SharedPowerCellSystem.cs
+++ b/Content.Shared/PowerCell/SharedPowerCellSystem.cs
@@ -18,8 +18,6 @@ public abstract class SharedPowerCellSystem : EntitySystem
SubscribeLocalEvent(OnCellSlotInit);
SubscribeLocalEvent(OnCellSlotRemove);
- SubscribeLocalEvent(OnSlotExamined);
-
SubscribeLocalEvent(OnCellInserted);
SubscribeLocalEvent(OnCellRemoved);
SubscribeLocalEvent(OnCellInsertAttempt);
@@ -33,7 +31,7 @@ public abstract class SharedPowerCellSystem : EntitySystem
if (args.Container.ID != component.CellSlot.ID)
return;
- if (!TryComp(args.EntityUid, out PowerCellComponent? cell) || cell.CellSize != component.SlotSize)
+ if (!HasComp(args.EntityUid))
{
args.Cancel();
}
@@ -67,41 +65,10 @@ public abstract class SharedPowerCellSystem : EntitySystem
{
component.CellSlot.Name = component.SlotName;
}
-
- if (component.StartEmpty)
- return;
-
- if (!string.IsNullOrWhiteSpace(component.CellSlot.StartingItem))
- return;
-
- // set default starting cell based on cell-type
- component.CellSlot.StartingItem = component.SlotSize switch
- {
- PowerCellSize.Small => "PowerCellSmallStandard",
- PowerCellSize.Medium => "PowerCellMediumStandard",
- PowerCellSize.Large => "PowerCellLargeStandard",
- _ => throw new ArgumentOutOfRangeException()
- };
}
private void OnCellSlotRemove(EntityUid uid, PowerCellSlotComponent component, ComponentRemove args)
{
_itemSlotsSystem.RemoveItemSlot(uid, component.CellSlot);
}
-
- private void OnSlotExamined(EntityUid uid, PowerCellSlotComponent component, ExaminedEvent args)
- {
- if (!args.IsInDetailsRange || string.IsNullOrWhiteSpace(component.DescFormatString))
- return;
-
- var sizeText = Loc.GetString(component.SlotSize switch
- {
- PowerCellSize.Small => "power-cell-slot-component-description-size-small",
- PowerCellSize.Medium => "power-cell-slot-component-description-size-medium",
- PowerCellSize.Large => "power-cell-slot-component-description-size-large",
- _ => "???"
- });
-
- args.PushMarkup(Loc.GetString(component.DescFormatString, ("size", sizeText)));
- }
}
diff --git a/Content.Shared/Pulling/Components/PullableComponent.cs b/Content.Shared/Pulling/Components/PullableComponent.cs
index b806e7fe33..a822e67910 100644
--- a/Content.Shared/Pulling/Components/PullableComponent.cs
+++ b/Content.Shared/Pulling/Components/PullableComponent.cs
@@ -11,8 +11,6 @@ namespace Content.Shared.Pulling.Components
[RegisterComponent]
public sealed class SharedPullableComponent : Component
{
- public float? MaxDistance => PullJoint?.MaxLength;
-
///
/// The current entity pulling this component.
/// SharedPullingStateManagementSystem should be writing this. This means definitely not you.
@@ -29,6 +27,20 @@ namespace Content.Shared.Pulling.Components
[Access(typeof(SharedPullingStateManagementSystem), Other = AccessPermissions.ReadExecute)] // FIXME Friends
public EntityCoordinates? MovingTo { get; set; }
+ ///
+ /// If the physics component has FixedRotation should we keep it upon being pulled
+ ///
+ [Access(typeof(SharedPullingSystem), Other = AccessPermissions.ReadExecute)]
+ [ViewVariables(VVAccess.ReadWrite), DataField("fixedRotation")]
+ public bool FixedRotationOnPull { get; set; }
+
+ ///
+ /// What the pullable's fixedrotation was set to before being pulled.
+ ///
+ [Access(typeof(SharedPullingSystem), Other = AccessPermissions.ReadExecute)]
+ [ViewVariables]
+ public bool PrevFixedRotation;
+
public override ComponentState GetComponentState()
{
return new PullableComponentState(Puller);
diff --git a/Content.Shared/Pulling/Events/BeingPulledAttemptEvent.cs b/Content.Shared/Pulling/Events/BeingPulledAttemptEvent.cs
new file mode 100644
index 0000000000..6a3089c749
--- /dev/null
+++ b/Content.Shared/Pulling/Events/BeingPulledAttemptEvent.cs
@@ -0,0 +1,17 @@
+namespace Content.Shared.Pulling.Events
+{
+ ///
+ /// Directed event raised on the pulled to see if it can be pulled.
+ ///
+ public sealed class BeingPulledAttemptEvent : CancellableEntityEventArgs
+ {
+ public BeingPulledAttemptEvent(EntityUid puller, EntityUid pulled)
+ {
+ Puller = puller;
+ Pulled = pulled;
+ }
+
+ public EntityUid Puller { get; }
+ public EntityUid Pulled { get; }
+ }
+}
diff --git a/Content.Shared/Pulling/Systems/SharedPullingSystem.Actions.cs b/Content.Shared/Pulling/Systems/SharedPullingSystem.Actions.cs
index 1daa0ec9cf..723b10a2a9 100644
--- a/Content.Shared/Pulling/Systems/SharedPullingSystem.Actions.cs
+++ b/Content.Shared/Pulling/Systems/SharedPullingSystem.Actions.cs
@@ -55,9 +55,11 @@ namespace Content.Shared.Pulling
}
}
+ var getPulled = new BeingPulledAttemptEvent(puller, pulled);
+ RaiseLocalEvent(pulled, getPulled);
var startPull = new StartPullAttemptEvent(puller, pulled);
RaiseLocalEvent(puller, startPull);
- return !startPull.Cancelled;
+ return (!startPull.Cancelled && !getPulled.Cancelled);
}
public bool TogglePull(EntityUid puller, SharedPullableComponent pullable)
@@ -83,6 +85,13 @@ namespace Content.Shared.Pulling
if (msg.Cancelled) return false;
+ // Stop pulling confirmed!
+
+ if (TryComp(pullable.Owner, out var pullablePhysics))
+ {
+ pullablePhysics.FixedRotation = pullable.PrevFixedRotation;
+ }
+
_pullSm.ForceRelationship(null, pullable);
return true;
}
@@ -170,11 +179,11 @@ namespace Content.Shared.Pulling
RaiseLocalEvent(pullable.Owner, pullAttempt);
if (pullAttempt.Cancelled)
- {
return false;
- }
_pullSm.ForceRelationship(puller, pullable);
+ pullable.PrevFixedRotation = pullablePhysics.FixedRotation;
+ pullablePhysics.FixedRotation = pullable.FixedRotationOnPull;
return true;
}
diff --git a/Content.Shared/Radar/RadarConsoleBoundInterfaceState.cs b/Content.Shared/Radar/RadarConsoleBoundInterfaceState.cs
deleted file mode 100644
index ba6d858a9f..0000000000
--- a/Content.Shared/Radar/RadarConsoleBoundInterfaceState.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using Robust.Shared.Serialization;
-
-namespace Content.Shared.Radar;
-
-[Serializable, NetSerializable]
-public sealed class RadarConsoleBoundInterfaceState : BoundUserInterfaceState
-{
- public float Range;
- public RadarObjectData[] Objects;
-
- public RadarConsoleBoundInterfaceState(float range, RadarObjectData[] objects)
- {
- Range = range;
- Objects = objects;
- }
-}
-
-[Serializable, NetSerializable]
-public struct RadarObjectData
-{
- public Color Color;
- public RadarObjectShape Shape;
- public Vector2 Position;
- public float Radius;
-}
-
-public enum RadarObjectShape : byte
-{
- Circle,
- CircleFilled,
-}
-
-[Serializable, NetSerializable]
-public enum RadarConsoleUiKey : byte
-{
- Key
-}
diff --git a/Content.Shared/Shuttles/BUIStates/RadarConsoleBoundInterfaceState.cs b/Content.Shared/Shuttles/BUIStates/RadarConsoleBoundInterfaceState.cs
new file mode 100644
index 0000000000..550c6d28f1
--- /dev/null
+++ b/Content.Shared/Shuttles/BUIStates/RadarConsoleBoundInterfaceState.cs
@@ -0,0 +1,41 @@
+using Robust.Shared.Map;
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.Shuttles.BUIStates;
+
+[Serializable, NetSerializable]
+[Virtual]
+public class RadarConsoleBoundInterfaceState : BoundUserInterfaceState
+{
+ public readonly float MaxRange;
+ public readonly EntityUid? Entity;
+ public readonly List Docks;
+
+ public RadarConsoleBoundInterfaceState(
+ float maxRange,
+ EntityUid? entity,
+ List docks)
+ {
+ MaxRange = maxRange;
+ Entity = entity;
+ Docks = docks;
+ }
+}
+
+///
+/// State of each individual docking port for interface purposes
+///
+[Serializable, NetSerializable]
+public sealed class DockingInterfaceState
+{
+ public EntityCoordinates Coordinates;
+ public Angle Angle;
+ public EntityUid Entity;
+ public bool Connected;
+}
+
+[Serializable, NetSerializable]
+public enum RadarConsoleUiKey : byte
+{
+ Key
+}
diff --git a/Content.Shared/Shuttles/BUIStates/ShuttleConsoleBoundInterfaceState.cs b/Content.Shared/Shuttles/BUIStates/ShuttleConsoleBoundInterfaceState.cs
new file mode 100644
index 0000000000..d210fd5bb6
--- /dev/null
+++ b/Content.Shared/Shuttles/BUIStates/ShuttleConsoleBoundInterfaceState.cs
@@ -0,0 +1,20 @@
+using Content.Shared.Shuttles.Components;
+using Robust.Shared.Map;
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.Shuttles.BUIStates;
+
+[Serializable, NetSerializable]
+public sealed class ShuttleConsoleBoundInterfaceState : RadarConsoleBoundInterfaceState
+{
+ public readonly ShuttleMode Mode;
+
+ public ShuttleConsoleBoundInterfaceState(
+ ShuttleMode mode,
+ float maxRange,
+ EntityUid? entity,
+ List docks) : base(maxRange, entity, docks)
+ {
+ Mode = mode;
+ }
+}
diff --git a/Content.Shared/Shuttles/Components/RadarConsoleComponent.cs b/Content.Shared/Shuttles/Components/RadarConsoleComponent.cs
new file mode 100644
index 0000000000..92d51ab607
--- /dev/null
+++ b/Content.Shared/Shuttles/Components/RadarConsoleComponent.cs
@@ -0,0 +1,21 @@
+using Content.Shared.Shuttles.Systems;
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Shuttles.Components;
+
+[RegisterComponent, NetworkedComponent, Access(typeof(SharedRadarConsoleSystem))]
+public sealed class RadarConsoleComponent : Component
+{
+ [ViewVariables(VVAccess.ReadWrite)]
+ public float RangeVV
+ {
+ get => MaxRange;
+ set => IoCManager
+ .Resolve()
+ .GetEntitySystem()
+ .SetRange(this, value);
+ }
+
+ [ViewVariables, DataField("maxRange")]
+ public float MaxRange = 120f;
+}
diff --git a/Content.Shared/Shuttles/Components/SharedShuttleComponent.cs b/Content.Shared/Shuttles/Components/SharedShuttleComponent.cs
index cce6eb0769..ac2063ef49 100644
--- a/Content.Shared/Shuttles/Components/SharedShuttleComponent.cs
+++ b/Content.Shared/Shuttles/Components/SharedShuttleComponent.cs
@@ -1,17 +1,8 @@
namespace Content.Shared.Shuttles.Components
{
- public abstract class SharedShuttleComponent : Component
- {
- [ViewVariables]
- public virtual bool Enabled { get; set; } = true;
-
- [ViewVariables]
- public ShuttleMode Mode { get; set; } = ShuttleMode.Cruise;
- }
-
public enum ShuttleMode : byte
{
- Docking,
+ Strafing,
Cruise,
}
}
diff --git a/Content.Shared/Shuttles/Components/SharedShuttleConsoleComponent.cs b/Content.Shared/Shuttles/Components/SharedShuttleConsoleComponent.cs
index f1aee2e2ed..88583b87fc 100644
--- a/Content.Shared/Shuttles/Components/SharedShuttleConsoleComponent.cs
+++ b/Content.Shared/Shuttles/Components/SharedShuttleConsoleComponent.cs
@@ -1,12 +1,20 @@
using Robust.Shared.GameStates;
+using Robust.Shared.Serialization;
namespace Content.Shared.Shuttles.Components
{
///
/// Interact with to start piloting a shuttle.
///
- [NetworkedComponent()]
+ [NetworkedComponent]
public abstract class SharedShuttleConsoleComponent : Component
{
+
+ }
+
+ [Serializable, NetSerializable]
+ public enum ShuttleConsoleUiKey : byte
+ {
+ Key,
}
}
diff --git a/Content.Shared/Shuttles/Events/AutodockRequestMessage.cs b/Content.Shared/Shuttles/Events/AutodockRequestMessage.cs
new file mode 100644
index 0000000000..49c5040661
--- /dev/null
+++ b/Content.Shared/Shuttles/Events/AutodockRequestMessage.cs
@@ -0,0 +1,12 @@
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.Shuttles.Events;
+
+///
+/// Raised on the client when it's viewing a particular docking port to try and dock it automatically.
+///
+[Serializable, NetSerializable]
+public sealed class AutodockRequestMessage : BoundUserInterfaceMessage
+{
+ public EntityUid Entity;
+}
diff --git a/Content.Shared/Shuttles/Events/ShuttleModeRequestMessage.cs b/Content.Shared/Shuttles/Events/ShuttleModeRequestMessage.cs
new file mode 100644
index 0000000000..06ccd1af2f
--- /dev/null
+++ b/Content.Shared/Shuttles/Events/ShuttleModeRequestMessage.cs
@@ -0,0 +1,13 @@
+using Content.Shared.Shuttles.Components;
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.Shuttles.Events;
+
+///
+/// Raised by the client to request the server change a particular shuttle's mode.
+///
+[Serializable, NetSerializable]
+public sealed class ShuttleModeRequestMessage : BoundUserInterfaceMessage
+{
+ public ShuttleMode Mode;
+}
diff --git a/Content.Shared/Shuttles/Events/StopAutodockRequestMessage.cs b/Content.Shared/Shuttles/Events/StopAutodockRequestMessage.cs
new file mode 100644
index 0000000000..f8773649bc
--- /dev/null
+++ b/Content.Shared/Shuttles/Events/StopAutodockRequestMessage.cs
@@ -0,0 +1,12 @@
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.Shuttles.Events;
+
+///
+/// Raised on a client when it is no longer viewing a dock.
+///
+[Serializable, NetSerializable]
+public sealed class StopAutodockRequestMessage : BoundUserInterfaceMessage
+{
+ public EntityUid Entity;
+}
diff --git a/Content.Shared/Shuttles/Events/UndockRequestMessage.cs b/Content.Shared/Shuttles/Events/UndockRequestMessage.cs
new file mode 100644
index 0000000000..9ee78aa4d6
--- /dev/null
+++ b/Content.Shared/Shuttles/Events/UndockRequestMessage.cs
@@ -0,0 +1,12 @@
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.Shuttles.Events;
+
+///
+/// Raised on the client when it wishes to not have 2 docking ports docked.
+///
+[Serializable, NetSerializable]
+public sealed class UndockRequestMessage : BoundUserInterfaceMessage
+{
+ public EntityUid Entity;
+}
diff --git a/Content.Shared/Shuttles/Systems/SharedRadarConsoleSystem.cs b/Content.Shared/Shuttles/Systems/SharedRadarConsoleSystem.cs
new file mode 100644
index 0000000000..c0754df1e1
--- /dev/null
+++ b/Content.Shared/Shuttles/Systems/SharedRadarConsoleSystem.cs
@@ -0,0 +1,45 @@
+using Content.Shared.Shuttles.Components;
+using Robust.Shared.GameStates;
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.Shuttles.Systems;
+
+public abstract class SharedRadarConsoleSystem : EntitySystem
+{
+ public override void Initialize()
+ {
+ base.Initialize();
+ SubscribeLocalEvent(OnGetState);
+ SubscribeLocalEvent(OnHandleState);
+ }
+
+ private void OnHandleState(EntityUid uid, RadarConsoleComponent component, ref ComponentHandleState args)
+ {
+ if (args.Current is not RadarConsoleComponentState state) return;
+ component.MaxRange = state.Range;
+ }
+
+ private void OnGetState(EntityUid uid, RadarConsoleComponent component, ref ComponentGetState args)
+ {
+ args.State = new RadarConsoleComponentState()
+ {
+ Range = component.MaxRange
+ };
+ }
+
+ protected virtual void UpdateState(RadarConsoleComponent component) {}
+
+ public void SetRange(RadarConsoleComponent component, float value)
+ {
+ if (component.MaxRange.Equals(value)) return;
+ component.MaxRange = value;
+ Dirty(component);
+ UpdateState(component);
+ }
+
+ [Serializable, NetSerializable]
+ protected sealed class RadarConsoleComponentState : ComponentState
+ {
+ public float Range;
+ }
+}
diff --git a/Content.Shared/Shuttles/SharedShuttleConsoleSystem.cs b/Content.Shared/Shuttles/Systems/SharedShuttleConsoleSystem.cs
similarity index 55%
rename from Content.Shared/Shuttles/SharedShuttleConsoleSystem.cs
rename to Content.Shared/Shuttles/Systems/SharedShuttleConsoleSystem.cs
index 0e0bd043a1..506fa84f10 100644
--- a/Content.Shared/Shuttles/SharedShuttleConsoleSystem.cs
+++ b/Content.Shared/Shuttles/Systems/SharedShuttleConsoleSystem.cs
@@ -1,10 +1,9 @@
using Content.Shared.ActionBlocker;
using Content.Shared.Movement;
using Content.Shared.Shuttles.Components;
-using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
-namespace Content.Shared.Shuttles
+namespace Content.Shared.Shuttles.Systems
{
public abstract class SharedShuttleConsoleSystem : EntitySystem
{
@@ -16,38 +15,10 @@ namespace Content.Shared.Shuttles
SubscribeLocalEvent(HandleMovementBlock);
SubscribeLocalEvent(OnStartup);
SubscribeLocalEvent(HandlePilotShutdown);
- SubscribeLocalEvent(OnGetState);
- SubscribeLocalEvent(OnHandleState);
- }
-
- private void OnGetState(EntityUid uid, PilotComponent component, ref ComponentGetState args)
- {
- args.State = new PilotComponentState(component.Console?.Owner);
- }
-
- private void OnHandleState(EntityUid uid, PilotComponent component, ref ComponentHandleState args)
- {
- if (args.Current is not PilotComponentState state) return;
-
- var console = state.Console.GetValueOrDefault();
- if (!console.IsValid())
- {
- component.Console = null;
- return;
- }
-
- if (!TryComp(console, out var shuttleConsoleComponent))
- {
- Logger.Warning($"Unable to set Helmsman console to {console}");
- return;
- }
-
- component.Console = shuttleConsoleComponent;
- ActionBlockerSystem.UpdateCanMove(uid);
}
[Serializable, NetSerializable]
- private sealed class PilotComponentState : ComponentState
+ protected sealed class PilotComponentState : ComponentState
{
public EntityUid? Console { get; }
diff --git a/Content.Shared/Slippery/SlipperyComponent.cs b/Content.Shared/Slippery/SlipperyComponent.cs
index 7cd8c1e028..bba71b824f 100644
--- a/Content.Shared/Slippery/SlipperyComponent.cs
+++ b/Content.Shared/Slippery/SlipperyComponent.cs
@@ -1,5 +1,3 @@
-using System.Linq;
-using Content.Shared.Sound;
using Content.Shared.Sound;
using Content.Shared.StepTrigger;
using Robust.Shared.GameStates;
diff --git a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Ballistic.cs b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Ballistic.cs
index 5295861577..b67af7514c 100644
--- a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Ballistic.cs
+++ b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Ballistic.cs
@@ -50,7 +50,7 @@ public abstract partial class SharedGunSystem
private void OnBallisticVerb(EntityUid uid, BallisticAmmoProviderComponent component, GetVerbsEvent args)
{
- if (!args.CanAccess || !args.CanInteract) return;
+ if (!args.CanAccess || !args.CanInteract || args.Hands == null) return;
args.Verbs.Add(new Verb()
{
diff --git a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Revolver.cs b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Revolver.cs
index 13a18ebbde..fb9a4c56bb 100644
--- a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Revolver.cs
+++ b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Revolver.cs
@@ -98,7 +98,7 @@ public partial class SharedGunSystem
private void OnRevolverVerbs(EntityUid uid, RevolverAmmoProviderComponent component, GetVerbsEvent args)
{
- if (!args.CanAccess || !args.CanInteract) return;
+ if (!args.CanAccess || !args.CanInteract || args.Hands == null) return;
args.Verbs.Add(new Verb()
{
diff --git a/Resources/Audio/Animals/license.txt b/Resources/Audio/Animals/license.txt
index d613b12f11..76ba446b8a 100644
--- a/Resources/Audio/Animals/license.txt
+++ b/Resources/Audio/Animals/license.txt
@@ -4,39 +4,42 @@ licensed under CC BY-NC-SA 3.0
The following sounds were used from freesound:
-cat_meow.ogg: modified from "Meow 4.wav" by freesound user "TRNGLE" (https://freesound.org/people/TRNGLE/sounds/368006/) licensed under CCBY 3.0. The original audio was trimmed, split to mono, and converted from WAV to OGG format.
+ cat_meow.ogg: modified from "Meow 4.wav" by freesound user "TRNGLE" (https://freesound.org/people/TRNGLE/sounds/368006/) licensed under CCBY 3.0. The original audio was trimmed, split to mono, and converted from WAV to OGG format.
-cat_hiss.ogg: modified from "catHisses1.wav" by freesound user "Zabuhailo" (https://freesound.org/people/Zabuhailo/sounds/146963/) licensed under CC0 1.0 (public domain). The original audio was trimmed and converted from WAV to OGG format.
+ cat_hiss.ogg: modified from "catHisses1.wav" by freesound user "Zabuhailo" (https://freesound.org/people/Zabuhailo/sounds/146963/) licensed under CC0 1.0 (public domain). The original audio was trimmed and converted from WAV to OGG format.
-small_dog_bark_happy.ogg: modified from "Dog bark2.wav" by freesound user "MisterTood" (https://freesound.org/people/MisterTood/sounds/9032/) licensed under CC0 1.0 (public domain). The original audio was trimmed and converted from WAV to OGG format.
+ small_dog_bark_happy.ogg: modified from "Dog bark2.wav" by freesound user "MisterTood" (https://freesound.org/people/MisterTood/sounds/9032/) licensed under CC0 1.0 (public domain). The original audio was trimmed and converted from WAV to OGG format.
-duck_quack_happy.ogg: modified from "Duck Quack - Sound Effect (HD).mp3" by freesound user "Tabby+Gus." (https://freesound.org/people/Tabby+Gus./sounds/515408/) licensed under CC0 1.0 (public domain). The original audio was trimmed, looped, split to mono, and converted from MP3 to OGG format.
+ duck_quack_happy.ogg: modified from "Duck Quack - Sound Effect (HD).mp3" by freesound user "Tabby+Gus." (https://freesound.org/people/Tabby+Gus./sounds/515408/) licensed under CC0 1.0 (public domain). The original audio was trimmed, looped, split to mono, and converted from MP3 to OGG format.
-chicken_cluck_happy.ogg: modified from "Chicken Single Alarm Call" by freesound user "Rudmer_Rotteveel" (https://freesound.org/people/Rudmer_Rotteveel/sounds/316920/) licensed under CC0 1.0 (public domain). The original audio was trimmed and converted from WAV to OGG format.
+ chicken_cluck_happy.ogg: modified from "Chicken Single Alarm Call" by freesound user "Rudmer_Rotteveel" (https://freesound.org/people/Rudmer_Rotteveel/sounds/316920/) licensed under CC0 1.0 (public domain). The original audio was trimmed and converted from WAV to OGG format.
-ferret_happy.ogg: modified from "Ferret" by freesound user "J.Zazvurek" (https://freesound.org/people/J.Zazvurek/sounds/155115/) licensed under CC BY 3.0. The original audio was trimmed and converted from WAV to OGG format.
+ ferret_happy.ogg: modified from "Ferret" by freesound user "J.Zazvurek" (https://freesound.org/people/J.Zazvurek/sounds/155115/) licensed under CC BY 3.0. The original audio was trimmed and converted from WAV to OGG format.
-mouse_squeak.ogg: modified from "Cartoon - Bat / Mouse Squeak" by freesound user "Breviceps" (https://freesound.org/people/Breviceps/sounds/445958/) licensed under CC0 1.0 (public domain). The original audio was converted from WAV to OGG format.
+ mouse_squeak.ogg: modified from "Cartoon - Bat / Mouse Squeak" by freesound user "Breviceps" (https://freesound.org/people/Breviceps/sounds/445958/) licensed under CC0 1.0 (public domain). The original audio was converted from WAV to OGG format.
-sloth_squeak.ogg: modified from "squeakfinal.wav" by freesound user "Higgs01" (https://freesound.org/people/Higgs01/sounds/428114/) licensed under CC0 1.0 (Public domain dedication). The original audio was converted from WAV to OFF format AND converted from stereo to mono.
+ sloth_squeak.ogg: modified from "squeakfinal.wav" by freesound user "Higgs01" (https://freesound.org/people/Higgs01/sounds/428114/) licensed under CC0 1.0 (Public domain dedication). The original audio was converted from WAV to OFF format AND converted from stereo to mono.
-parrot_raught.ogg: modified and used from "Parrot 1 raught 2.wav" by freesound user "Coral_Island_Studios" (https://freesound.org/people/Coral_Island_Studios/sounds/432588/) licensed under CC BY 3.0. The original audio was converted from WAV to OGG format.
+ parrot_raught.ogg: modified and used from "Parrot 1 raught 2.wav" by freesound user "Coral_Island_Studios" (https://freesound.org/people/Coral_Island_Studios/sounds/432588/) licensed under CC BY 3.0. The original audio was converted from WAV to OGG format.
-fox_squeak.ogg: modified from "Video Game Squeak" by freesound user "Breviceps" (https://freesound.org/people/Breviceps/sounds/468442/) licensed under CC0 1.0. The original audio was converted from WAV to OGG format
+ fox_squeak.ogg: modified from "Video Game Squeak" by freesound user "Breviceps" (https://freesound.org/people/Breviceps/sounds/468442/) licensed under CC0 1.0. The original audio was converted from WAV to OGG format
-frog_ribbit.ogg: original audio created by freesound user "egomassive" (https://freesound.org/people/egomassive/sounds/536759/). licensed under licensed under CC0 1.0
+ frog_ribbit.ogg: original audio created by freesound user "egomassive" (https://freesound.org/people/egomassive/sounds/536759/). licensed under licensed under CC0 1.0
-goose_honk.ogg: modified from " Bird Honk - 1" by freesound user "SpaceJoe" (https://freesound.org/people/SpaceJoe/sounds/510940/) licensed under CC0 1.0. The originial audio was converted from WAV to OGG format.
+ goose_honk.ogg: modified from " Bird Honk - 1" by freesound user "SpaceJoe" (https://freesound.org/people/SpaceJoe/sounds/510940/) licensed under CC0 1.0. The originial audio was converted from WAV to OGG format.
-snake_hiss.ogg: modified from "hissing snake sound effect" by freesound user "Garuda1982" (https://freesound.org/people/Garuda1982/sounds/541656/) licensed under CC BY 4.0. The original audio was convertred from WAV to OGG format.
+ snake_hiss.ogg: modified from "hissing snake sound effect" by freesound user "Garuda1982" (https://freesound.org/people/Garuda1982/sounds/541656/) licensed under CC BY 4.0. The original audio was convertred from WAV to OGG format.
+
+The following sounds are taken from TGstation github (licensed under CC by 3.0):
+
+ space_dragon_roar.ogg: taken at https://github.com/tgstation/tgstation/commit/d4f678a1772007ff8d7eddd21cf7218c8e07bfc0
The following sounds were used from youtube:
-penguin_squawk.ogg: audio is recorded/created by youtube user "ProSounds" (https://youtu.be/Anr35RbBL3Y) licensed under CC BY 3.0. The original audio was trimmed and converted from MP3 to OGG format.
+ penguin_squawk.ogg: audio is recorded/created by youtube user "ProSounds" (https://youtu.be/Anr35RbBL3Y) licensed under CC BY 3.0. The original audio was trimmed and converted from MP3 to OGG format.
-raccoon_squeak.ogg: audio is recorded by youtube user "jnargus" (https://youtu.be/BGjFP1CP7E0) licensed under CC by 3.0
+ raccoon_squeak.ogg: audio is recorded by youtube user "jnargus" (https://youtu.be/BGjFP1CP7E0) licensed under CC by 3.0
-goat_bah.ogg: audio is created by youtube user "Winry Marini" (https://youtu.be/QIhwzsk5bww) licensed under CC BY 3.0
-
-lizard_happy.ogg: audio created by youtube user "Nagaty Studio" (https://youtu.be/I7CX0AS8RNI) licensed under CC by 3.0.
+ goat_bah.ogg: audio is created by youtube user "Winry Marini" (https://youtu.be/QIhwzsk5bww) licensed under CC BY 3.0
+ lizard_happy.ogg: audio created by youtube user "Nagaty Studio" (https://youtu.be/I7CX0AS8RNI) licensed under CC by 3.0.
diff --git a/Resources/Audio/Animals/space_dragon_roar.ogg b/Resources/Audio/Animals/space_dragon_roar.ogg
new file mode 100644
index 0000000000..1f63d18e4b
Binary files /dev/null and b/Resources/Audio/Animals/space_dragon_roar.ogg differ
diff --git a/Resources/Audio/Effects/demon_attack1.ogg b/Resources/Audio/Effects/demon_attack1.ogg
new file mode 100644
index 0000000000..18b646f136
Binary files /dev/null and b/Resources/Audio/Effects/demon_attack1.ogg differ
diff --git a/Resources/Audio/Effects/demon_consume.ogg b/Resources/Audio/Effects/demon_consume.ogg
new file mode 100644
index 0000000000..2f8b51a7da
Binary files /dev/null and b/Resources/Audio/Effects/demon_consume.ogg differ
diff --git a/Resources/Audio/Effects/demon_dies.ogg b/Resources/Audio/Effects/demon_dies.ogg
new file mode 100644
index 0000000000..c3ad866c6b
Binary files /dev/null and b/Resources/Audio/Effects/demon_dies.ogg differ
diff --git a/Resources/Audio/Effects/licenses.txt b/Resources/Audio/Effects/licenses.txt
index 6ddb5dc5e7..9a49b6d509 100644
--- a/Resources/Audio/Effects/licenses.txt
+++ b/Resources/Audio/Effects/licenses.txt
@@ -31,3 +31,11 @@ minibombcountdown.ogg taken from Thomas Evdokimoff at https://freesound.org/peop
bite.ogg take from https://github.com/tgstation/tgstation/commit/d4f678a1772007ff8d7eddd21cf7218c8e07bfc0
bone_rattle.ogg licensed under CC0 1.0 and taken from spookymodem at https://freesound.org/people/spookymodem/sounds/202102/
+
+The following sounds are taken from TGstation github (licensed under CC by 3.0):
+
+ demon_attack1.ogg: taken at https://github.com/tgstation/tgstation/commit/d4f678a1772007ff8d7eddd21cf7218c8e07bfc0
+
+ demon_consume.ogg: taken at https://github.com/tgstation/tgstation/commit/d4f678a1772007ff8d7eddd21cf7218c8e07bfc0
+
+ demon_dies.ogg: taken at https://github.com/tgstation/tgstation/commit/d4f678a1772007ff8d7eddd21cf7218c8e07bfc0
diff --git a/Resources/Audio/Weapons/Xeno/alien_claw_flesh1.ogg b/Resources/Audio/Weapons/Xeno/alien_claw_flesh1.ogg
new file mode 100644
index 0000000000..7853503c8f
Binary files /dev/null and b/Resources/Audio/Weapons/Xeno/alien_claw_flesh1.ogg differ
diff --git a/Resources/Audio/Weapons/Xeno/alien_claw_flesh2.ogg b/Resources/Audio/Weapons/Xeno/alien_claw_flesh2.ogg
new file mode 100644
index 0000000000..2a1ba20dc4
Binary files /dev/null and b/Resources/Audio/Weapons/Xeno/alien_claw_flesh2.ogg differ
diff --git a/Resources/Audio/Weapons/Xeno/alien_claw_flesh3.ogg b/Resources/Audio/Weapons/Xeno/alien_claw_flesh3.ogg
new file mode 100644
index 0000000000..fe866ca747
Binary files /dev/null and b/Resources/Audio/Weapons/Xeno/alien_claw_flesh3.ogg differ
diff --git a/Resources/Audio/Weapons/Xeno/license.txt b/Resources/Audio/Weapons/Xeno/license.txt
new file mode 100644
index 0000000000..defddc5e45
--- /dev/null
+++ b/Resources/Audio/Weapons/Xeno/license.txt
@@ -0,0 +1 @@
+alien_claw_flesh1, alien_claw_flesh2, alien_claw_flesh3 were taken from: https://gitlab.com/cmdevs/colonial-warfare/-/tree/dev/sound/weapons
\ No newline at end of file
diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml
index ac911ca414..cc2693e63f 100644
--- a/Resources/Changelog/Changelog.yml
+++ b/Resources/Changelog/Changelog.yml
@@ -1,190 +1,4 @@
Entries:
-- author: Daemon
- changes:
- - {message: Lean can now be made and has effects., type: Tweak}
- id: 1192
- time: '2022-03-12T22:07:07.0000000+00:00'
-- author: Peptide90
- changes:
- - {message: All windows are now less susceptible to piercing damage and more to
- blunt., type: Tweak}
- - {message: 'Spears now take cable, a glass shard and 2 rods to craft. They break
- after 4 throws.', type: Tweak}
- id: 1193
- time: '2022-03-12T22:07:27.0000000+00:00'
-- author: Macoron
- changes:
- - {message: Guitar and other items now correctly react on quick equipment key (Z
- by default)., type: Fix}
- id: 1194
- time: '2022-03-12T22:09:11.0000000+00:00'
-- author: moony
- changes:
- - {message: All atmos devices now produce ambient noise when operating., type: Add}
- - {message: Wiring now has mains hum., type: Add}
- - {message: Atmos piping has gas movement noise., type: Add}
- - {message: 'Ambient audio volume levels have been raised, so you can hear them
- without an explosion blowing your eardrums out.', type: Tweak}
- id: 1195
- time: '2022-03-12T22:20:31.0000000+00:00'
-- author: TaralGit
- changes:
- - {message: Pulse carbine and pistol for ERT, type: Add}
- - {message: Pulse hitscan projectile, type: Add}
- - {message: The Lamia handgun is now using its own sprite instead of the gyropistol's,
- type: Tweak}
- - {message: A whole bunch of resprites for various guns and melee weapons, type: Tweak}
- id: 1196
- time: '2022-03-12T22:29:17.0000000+00:00'
-- author: DogZeroX
- changes:
- - {message: There's intel of an unknown enemy corp creating experimental mechas
- and testing them on stations., type: Add}
- id: 1197
- time: '2022-03-12T23:14:17.0000000+00:00'
-- author: Macoron
- changes:
- - {message: Add lizard accent. Hissss!, type: Add}
- id: 1198
- time: '2022-03-13T04:23:44.0000000+00:00'
-- author: Rane
- changes:
- - {message: Drones now have an innate flashlight., type: Add}
- - {message: Onestar Mechs are no longer bound by drone laws., type: Fix}
- - {message: Drones can now toggle all their innate tools within range of people.,
- type: Tweak}
- - {message: 'Added power cells, toolboxes and certain boxes to the drone whitelist.',
- type: Tweak}
- id: 1199
- time: '2022-03-13T09:53:01.0000000+00:00'
-- author: mirrorcult
- changes:
- - {message: Plant produce now scales in size depending on its potency., type: Add}
- id: 1200
- time: '2022-03-13T10:11:03.0000000+00:00'
-- author: metalgearsloth
- changes:
- - {message: Lizards now correctly no longer show up at roundstart., type: Fix}
- id: 1201
- time: '2022-03-13T15:42:07.0000000+00:00'
-- author: moony
- changes:
- - {message: 'Removed fun! No more lean, don''t do drugs kids.', type: Remove}
- id: 1202
- time: '2022-03-13T20:46:26.0000000+00:00'
-- author: Emisse
- changes:
- - {message: Add foxes and Renault., type: Add}
- id: 1203
- time: '2022-03-13T23:32:33.0000000+00:00'
-- author: Jezithyr
- changes:
- - {message: Rewrote the lobby UI, type: Add}
- - {message: Added adminhelp button to the lobby screen, type: Add}
- - {message: 'Added the ability to add custom lobby screens, (You can have multiple
- and picks a random one!)', type: Add}
- - {message: 'rewrote the backend of the lobby ui to be slightly less ass, still
- a work in progress. Please report any issues with monitor scaling.', type: Tweak}
- id: 1204
- time: '2022-03-14T02:33:19.0000000+00:00'
-- author: mirrorcult
- changes:
- - {message: Hardsuits now noticeably slow you down. Wear something else., type: Tweak}
- id: 1205
- time: '2022-03-14T06:03:50.0000000+00:00'
-- author: router
- changes:
- - {message: Desoxyephedrine no longer hardcounters the speedboost it's supposed
- to be granting., type: Tweak}
- id: 1206
- time: '2022-03-14T06:04:02.0000000+00:00'
-- author: Rane
- changes:
- - {message: 'Coffee, Tea, and Energy drinks now contain a small amount of theobromine.',
- type: Add}
- - {message: Ultragigancer progression slowed a bit. It still fulfills its purpose
- of taking up a bunch of medbay resources., type: Tweak}
- - {message: You can no longer insert swabs into disease machines while they are
- currently making something., type: Fix}
- - {message: Fixed broken localization string for the vent cough disease., type: Fix}
- id: 1207
- time: '2022-03-14T06:05:02.0000000+00:00'
-- author: Carou
- changes:
- - {message: 'Added animated friendly purple snake, with the id: purple_snake.',
- type: Add}
- id: 1208
- time: '2022-03-14T15:00:23.0000000+00:00'
-- author: Spillhelm53
- changes:
- - {message: 'Mops can now be used to add or remove liquid from most containers.
- However, Nanotrasen continues to recommend its company-made "Big Yella" brand
- mop buckets for best results.', type: Add}
- id: 1209
- time: '2022-03-14T21:02:26.0000000+00:00'
-- author: Peptide90
- changes:
- - {message: 'Added new generator types: 2x portable generators. Research their boards
- to build them.', type: Add}
- - {message: Added the RTG. Find them in a deep space wreck and try not to get burnt...,
- type: Add}
- - {message: Added wallmount generator and substation for use in shuttles and escape
- pods., type: Add}
- id: 1210
- time: '2022-03-15T01:27:39.0000000+00:00'
-- author: ElectroJr
- changes:
- - {message: 'Fixed some audio files that were causing sound effects to play globally,
- rather than being position-dependent', type: Fix}
- id: 1211
- time: '2022-03-15T03:57:54.0000000+00:00'
-- author: ElectroJr
- changes:
- - {message: Fixed some UI bugs. Ian should no longer be able to make announcements,
- type: Fix}
- id: 1212
- time: '2022-03-15T03:59:20.0000000+00:00'
-- author: Todd
- changes:
- - {message: Added flip flap to the lobby themes., type: Add}
- id: 1213
- time: '2022-03-15T12:28:24.0000000+00:00'
-- author: mirrorcult
- changes:
- - {message: You can no longer construct 'destroyed machine frames'., type: Tweak}
- id: 1214
- time: '2022-03-15T22:54:30.0000000+00:00'
-- author: HoofedEar
- changes:
- - {message: 'Drones now have access to the Omnitool, a T-Ray Scanner, and a satchel!',
- type: Add}
- - {message: Drones have 1 less available hands., type: Tweak}
- id: 1215
- time: '2022-03-16T01:11:30.0000000+00:00'
-- author: EmoGarbage
- changes:
- - {message: 'Added the Space Tick, a new salvage mob to terrorize hardworking salvage
- specialists.', type: Add}
- - {message: Tweaked salvage mob spawners to allow the Space Tick to generate., type: Tweak}
- id: 1216
- time: '2022-03-16T01:11:36.0000000+00:00'
-- author: Daemon
- changes:
- - {message: Added a variation of the cute bee plushie, type: Add}
- id: 1217
- time: '2022-03-16T18:42:08.0000000+00:00'
-- author: Mith-randalf
- changes:
- - {message: 'Due to a budget oversight, SS14 is now equipped with rotatable arcade
- machines.', type: Fix}
- id: 1218
- time: '2022-03-16T21:30:05.0000000+00:00'
-- author: Mith-randalf
- changes:
- - {message: 'Due to a budgetary oversight, possums and raccoons are now smaller.
- Also Ferrets are a little bigger.', type: Tweak}
- id: 1219
- time: '2022-03-16T21:30:14.0000000+00:00'
- author: ElectroJr
changes:
- {message: Fixed gas tank UIs not showing the current output pressure when opened.,
@@ -3005,3 +2819,181 @@ Entries:
- {message: Fixed cobra magazine so it actually goes into the gun., type: Fix}
id: 1691
time: '2022-06-13T09:30:16.0000000+00:00'
+- author: EmoGarbage404
+ changes:
+ - {message: Solar's Best Hot Drinks now only have half as much coffee and tea in
+ them., type: Tweak}
+ id: 1692
+ time: '2022-06-14T07:13:31.0000000+00:00'
+- author: metalgearsloth
+ changes:
+ - {message: Tweak pistol firerate from 8 -> 6 and cobra firerate from 8 -> 4., type: Tweak}
+ id: 1693
+ time: '2022-06-14T07:19:51.0000000+00:00'
+- author: KIBORG04
+ changes:
+ - {message: Entities without hands (like mice) can no longer perform some actions.,
+ type: Remove}
+ id: 1694
+ time: '2022-06-15T01:39:43.0000000+00:00'
+- author: themias
+ changes:
+ - {message: Syndie gas masks now provide protection from flashbangs, type: Tweak}
+ id: 1695
+ time: '2022-06-15T07:04:53.0000000+00:00'
+- author: EmoGarbage404
+ changes:
+ - {message: Added the Rat King. This regal rodent wants your food and will summon
+ minions and spread plague in order to get it., type: Add}
+ id: 1696
+ time: '2022-06-16T00:53:27.0000000+00:00'
+- author: Delete
+ changes:
+ - {message: Fireplaces provide useful light, type: Add}
+ id: 1697
+ time: '2022-06-16T01:02:51.0000000+00:00'
+- author: Rane
+ changes:
+ - {message: 'You can no longer break pulls on cuffed people if someone else is pulling.
+ Sorry griefers, maybe sec will be tolerable to play now.', type: Tweak}
+ id: 1698
+ time: '2022-06-16T01:10:03.0000000+00:00'
+- author: CrudeWax
+ changes:
+ - {message: Nanotrasen's deeper research into the space-faring carpfish has proven
+ that their meat contains extremely potent poison!, type: Add}
+ - {message: 'New carp meat dishes are on the menu for experienced cooks! Their taste
+ can only be described as "Exotic", by those willing to stomach their lethal
+ effects.', type: Add}
+ - {message: 'It seems like the carpfish kind also have an apex predator among their
+ ranks, be warned of large influxes of organic activity and leviathan space-faring
+ creatures', type: Add}
+ - {message: Some carp appear to be smarter than others and capable of humanlike
+ speech, type: Add}
+ - {message: 'due to overuse of heartstopper toxin, and it''s more daring carp alternative,
+ the effects of the former have been greatly reduced', type: Tweak}
+ - {message: Space-faring carp will no longer die of being exposed to the coldness
+ of space, type: Fix}
+ id: 1699
+ time: '2022-06-16T04:14:06.0000000+00:00'
+- author: metalgearsloth
+ changes:
+ - {message: Shuttles now have a docking camera to make docking easier., type: Add}
+ id: 1700
+ time: '2022-06-16T05:28:17.0000000+00:00'
+- author: metalgearsloth
+ changes:
+ - {message: Total door hacking time reduced from 5s to 2.5s, type: Tweak}
+ id: 1701
+ time: '2022-06-16T06:14:35.0000000+00:00'
+- author: metalgearsloth
+ changes:
+ - {message: Nerfed gun damage by 30% across the board., type: Tweak}
+ id: 1702
+ time: '2022-06-16T06:15:08.0000000+00:00'
+- author: metalgearsloth
+ changes:
+ - {message: Holofans now use power cells and not a custom recharge system., type: Tweak}
+ id: 1703
+ time: '2022-06-16T08:30:27.0000000+00:00'
+- author: metalgearsloth
+ changes:
+ - {message: Power cell bloat has been removed as it's never been used. Only small
+ cells remain., type: Remove}
+ id: 1704
+ time: '2022-06-16T08:37:08.0000000+00:00'
+- author: Peptide90
+ changes:
+ - {message: Pulse Pistol and Captains Antique Pistol are now size 10., type: Tweak}
+ id: 1705
+ time: '2022-06-16T09:16:53.0000000+00:00'
+- author: Rane
+ changes:
+ - {message: All mobs will now gib after enough damage., type: Fix}
+ id: 1706
+ time: '2022-06-16T09:25:51.0000000+00:00'
+- author: Emisse
+ changes:
+ - {message: 'Bagelstation now has a unique job, the Reporter. They exist to follow
+ the nukies around trying to get an interview and blatantly ignore any and all
+ ideas of "safety".', type: Add}
+ - {message: 'Marathon now has a unique job, Psychologist. Interview the clown to
+ discover the true machinations that drive their enigma of a mind, realize you''re
+ just a worse doctor with a cool outfit. These two roles are station exclusives,
+ and won''t be seen anywhere else.', type: Add}
+ id: 1707
+ time: '2022-06-16T09:28:38.0000000+00:00'
+- author: Emisse
+ changes:
+ - {message: 'Bicaridine, Dermaline, and Hyronalin all OD at 30u. Hyronalin has a
+ low base chance to induce vomiting.', type: Add}
+ id: 1708
+ time: '2022-06-16T09:29:11.0000000+00:00'
+- author: eclips_e
+ changes:
+ - {message: Added a wiki button to the escape menu, type: Add}
+ id: 1709
+ time: '2022-06-16T09:33:59.0000000+00:00'
+- author: ProfanedBane
+ changes:
+ - {message: 'Whilst uncuffing someone, the handcuffs are placed in the your hand,
+ rather than under the person being uncuffed.', type: Add}
+ id: 1710
+ time: '2022-06-16T09:42:32.0000000+00:00'
+- author: eclips_e
+ changes:
+ - {message: Ghost role delay is now a cvar, type: Add}
+ - {message: Set ghost role delay from 5 seconds to 3 seconds, type: Tweak}
+ id: 1711
+ time: '2022-06-16T09:56:09.0000000+00:00'
+- author: mirrorcult
+ changes:
+ - {message: Holoparasites can no longer attack their owner while recalled using
+ wide attacks., type: Fix}
+ - {message: 'You can no longer wide attack inside of lockers, crates, etc.', type: Fix}
+ id: 1712
+ time: '2022-06-16T10:59:13.0000000+00:00'
+- author: Rane
+ changes:
+ - {message: 'Disarm chance now scales with relative health, relative mass, and status
+ effects. It''s now a much, much worse tool to instantly win a fight you''re
+ losing.', type: Tweak}
+ - {message: You now need to use an empty hand to perform disarms., type: Tweak}
+ - {message: 'Purpose-built single-handed melee weapons now have a disarm malus,
+ making them much harder to disarm.', type: Add}
+ id: 1713
+ time: '2022-06-17T05:37:07.0000000+00:00'
+- author: Rane
+ changes:
+ - {message: Ported miasma from Nyano MRP., type: Add}
+ - {message: Removed the radiation storm event., type: Remove}
+ id: 1714
+ time: '2022-06-17T07:00:23.0000000+00:00'
+- author: Peptide90
+ changes:
+ - {message: Botany tools now fit on the botany belt., type: Tweak}
+ - {message: Airlock Painters now fit on utility belts., type: Tweak}
+ id: 1715
+ time: '2022-06-18T02:13:29.0000000+00:00'
+- author: mirrorcult
+ changes:
+ - {message: The Rat King and his servants now have an appropriate silly accent.,
+ type: Tweak}
+ id: 1716
+ time: '2022-06-18T02:36:19.0000000+00:00'
+- author: DogZeroX
+ changes:
+ - {message: 'There are more kinds of Exos than a simple slug with blades now. Some
+ are faster, some are stronger, and one might shoot, someday.', type: Add}
+ id: 1717
+ time: '2022-06-18T03:33:41.0000000+00:00'
+- author: Peptide90
+ changes:
+ - {message: Added the remaining botany tools to the NutriVend machine., type: Tweak}
+ id: 1718
+ time: '2022-06-18T03:34:10.0000000+00:00'
+- author: EmoGarbage404
+ changes:
+ - {message: Certain station events will no longer be announced., type: Tweak}
+ id: 1719
+ time: '2022-06-18T03:53:02.0000000+00:00'
diff --git a/Resources/Locale/en-US/accent/mobster.ftl b/Resources/Locale/en-US/accent/mobster.ftl
new file mode 100644
index 0000000000..9aca97971b
--- /dev/null
+++ b/Resources/Locale/en-US/accent/mobster.ftl
@@ -0,0 +1,8 @@
+accent-mobster-prefix-1 = Nyehh,
+
+accent-mobster-suffix-boss-1 = , see?
+accent-mobster-suffix-boss-2 = , fugeddaboutit.
+accent-mobster-suffix-boss-3 = , capiche?
+
+accent-mobster-suffix-minion-1 = , yeah!
+accent-mobster-suffix-minion-2 = , boss says!
diff --git a/Resources/Locale/en-US/actions/actions/disarm-action.ftl b/Resources/Locale/en-US/actions/actions/disarm-action.ftl
index 2625ec336e..4f97b4f766 100644
--- a/Resources/Locale/en-US/actions/actions/disarm-action.ftl
+++ b/Resources/Locale/en-US/actions/actions/disarm-action.ftl
@@ -1,3 +1,5 @@
+disarm-action-free-hand = You need to use a free hand to disarm!
+
disarm-action-popup-message-other-clients = {$performerName} fails to disarm {$targetName}!
disarm-action-popup-message-cursor = You fail to disarm {$targetName}!
diff --git a/Resources/Locale/en-US/actions/actions/dragon.ftl b/Resources/Locale/en-US/actions/actions/dragon.ftl
new file mode 100644
index 0000000000..eaa98259c6
--- /dev/null
+++ b/Resources/Locale/en-US/actions/actions/dragon.ftl
@@ -0,0 +1,12 @@
+devour-action-popup-message-structure = Your jaws dig into thick material..
+devour-action-popup-message-fail-target-not-valid = That doesn't look particularly edible.
+devour-action-popup-message-fail-target-alive = You can't consume creatures that are alive!
+
+dragon-spawn-action-popup-message-fail-no-eggs = You don't have the stamina to create a carp!
+
+
+action-name-devour = [color=red]Devour[/color]
+action-description-devour = Attempt to break a structure with your jaws or swallow a creature.
+
+action-name-carp-summon = Summon carp
+action-description-carp-summon = Summon a carp to aid you at seizing the station!
diff --git a/Resources/Locale/en-US/animals/rat-king/rat-king.ftl b/Resources/Locale/en-US/animals/rat-king/rat-king.ftl
new file mode 100644
index 0000000000..35354daa08
--- /dev/null
+++ b/Resources/Locale/en-US/animals/rat-king/rat-king.ftl
@@ -0,0 +1,8 @@
+rat-king-raise-army-name = Raise Army
+rat-king-raise-army-description = Spend some hunger to summon an allied rat to help defend you.
+
+rat-king-domain-name = Rat King's Domain
+rat-king-domain-description = Spend some hunger to infect those around you with the plague.
+rat-king-domain-popup = A cloud of plague is released into the air!
+
+rat-king-too-hungry = You are too hungry to use this ability!
\ No newline at end of file
diff --git a/Resources/Locale/en-US/door-remote/door-remote.ftl b/Resources/Locale/en-US/door-remote/door-remote.ftl
index fa35d4d659..bf2fc11861 100644
--- a/Resources/Locale/en-US/door-remote/door-remote.ftl
+++ b/Resources/Locale/en-US/door-remote/door-remote.ftl
@@ -1,3 +1,6 @@
door-remote-switch-state-open-close = You switch the remote to open and close doors
door-remote-switch-state-toggle-bolts = You switch the remote to toggle bolts
door-remote-switch-state-toggle-emergency-access = You switch the remote to toggle emergency access
+door-remote-no-power = The door is not powered
+door-remote-denied = Access denied
+
diff --git a/Resources/Locale/en-US/escape-menu/ui/escape-menu.ftl b/Resources/Locale/en-US/escape-menu/ui/escape-menu.ftl
index 45f53f9489..ca546d563a 100644
--- a/Resources/Locale/en-US/escape-menu/ui/escape-menu.ftl
+++ b/Resources/Locale/en-US/escape-menu/ui/escape-menu.ftl
@@ -3,6 +3,7 @@
ui-escape-title = Esc Menu
ui-escape-options = Options
ui-escape-rules = Rules
+ui-escape-wiki = Wiki
ui-escape-disconnect = Disconnect
ui-escape-quit = Quit
diff --git a/Resources/Locale/en-US/ghost/ghost-gui.ftl b/Resources/Locale/en-US/ghost/ghost-gui.ftl
index 51bc5529f6..0ec5f1dcac 100644
--- a/Resources/Locale/en-US/ghost/ghost-gui.ftl
+++ b/Resources/Locale/en-US/ghost/ghost-gui.ftl
@@ -7,7 +7,8 @@ ghost-target-window-current-button = Warp: {$name}
ghost-roles-window-title = Ghost Roles
ghost-roles-window-request-role-button = Request
+ghost-roles-window-request-role-button-timer = Request ({$time}s)
ghost-roles-window-follow-role-button = Follow
ghost-roles-window-no-roles-available-label = There are currently no available ghost roles.
-ghost-roles-window-rules-footer = The button will enable after 5 seconds (this delay is to make sure you read the rules).
+ghost-roles-window-rules-footer = The button will enable after {$time} seconds (this delay is to make sure you read the rules).
diff --git a/Resources/Locale/en-US/misc-computers.ftl b/Resources/Locale/en-US/misc-computers.ftl
index 31d7cdc418..f2bd3ab50c 100644
--- a/Resources/Locale/en-US/misc-computers.ftl
+++ b/Resources/Locale/en-US/misc-computers.ftl
@@ -1 +1,2 @@
-radar-window-title = Mass Scanner Console
+radar-console-window-title = Mass Scanner Console
+shuttle-console-window-title = Shuttle Console
diff --git a/Resources/Locale/en-US/reagents/meta/gases.ftl b/Resources/Locale/en-US/reagents/meta/gases.ftl
index 2567ef441f..f92a0b6ca4 100644
--- a/Resources/Locale/en-US/reagents/meta/gases.ftl
+++ b/Resources/Locale/en-US/reagents/meta/gases.ftl
@@ -12,3 +12,6 @@ reagent-desc-carbon-dioxide = You have genuinely no idea what this is.
reagent-name-nitrogen = nitrogen
reagent-desc-nitrogen = A colorless, odorless unreactive gas. Highly stable.
+
+reagent-name-miasma = miasma
+reagent-desc-miasma = Uh oh, stinky!
diff --git a/Resources/Locale/en-US/shuttles/console.ftl b/Resources/Locale/en-US/shuttles/console.ftl
index 32254244f8..bd77157087 100644
--- a/Resources/Locale/en-US/shuttles/console.ftl
+++ b/Resources/Locale/en-US/shuttles/console.ftl
@@ -1,5 +1,22 @@
shuttle-pilot-start = Piloting ship
shuttle-pilot-end = Stopped piloting
-shuttle-mode-cruise = Cruise mode
-shuttle-mode-docking = Docking mode
-shuttle-mode-toggle = Toggle mode
+
+# Display
+shuttle-console-max-radar = Max radar range:
+shuttle-console-radar = Radar range:
+shuttle-console-position = Position:
+shuttle-console-orientation = Orientation:
+shuttle-console-linear-velocity = Linear velocity:
+shuttle-console-angular-velocity = Angular velocity:
+
+shuttle-console-docked = {$index} (Docked)
+shuttle-console-dock-button = Dock {$suffix}
+
+shuttle-console-unknown = Unknown
+shuttle-console-iff-label = "{$name} ({$distance}m)
+
+# Buttons
+shuttle-console-strafing = Strafing mode
+shuttle-console-iff-toggle = Show IFF
+shuttle-console-dock-toggle = Show docks
+shuttle-console-undock = Undock
diff --git a/Resources/Locale/en-US/station-events/events/mouse-migration.ftl b/Resources/Locale/en-US/station-events/events/mouse-migration.ftl
new file mode 100644
index 0000000000..98a86ca153
--- /dev/null
+++ b/Resources/Locale/en-US/station-events/events/mouse-migration.ftl
@@ -0,0 +1 @@
+station-event-mouse-migration-announcement = We have detected an oncoming migration of rodents to the station. Please stay out of maintenance tunnels and try and avoid excessive contact.
\ No newline at end of file
diff --git a/Resources/Maps/Salvage/stationstation.yml b/Resources/Maps/Salvage/stationstation.yml
index e234bb737a..060e405f3f 100644
--- a/Resources/Maps/Salvage/stationstation.yml
+++ b/Resources/Maps/Salvage/stationstation.yml
@@ -1737,13 +1737,13 @@ entities:
parent: 179
type: Transform
- uid: 186
- type: PowerCellSmallHigh
+ type: PowerCellMedium
components:
- pos: -2.67511,-10.351
parent: 179
type: Transform
- uid: 187
- type: PowerCellSmallHigh
+ type: PowerCellMedium
components:
- pos: -2.55011,-10.6635
parent: 179
diff --git a/Resources/Maps/bagel.yml b/Resources/Maps/bagel.yml
index a78c3efba7..3537d52a93 100644
--- a/Resources/Maps/bagel.yml
+++ b/Resources/Maps/bagel.yml
@@ -86506,7 +86506,7 @@ entities:
- canCollide: False
type: Physics
- uid: 7165
- type: PowerCellMediumPotato
+ type: PowerCellPotato
components:
- pos: -20.516964,-56.33504
parent: 60
@@ -105329,7 +105329,7 @@ entities:
parent: 60
type: Transform
- uid: 9621
- type: PowerCellLargeSuper
+ type: PowerCellHigh
components:
- pos: -37.43891,14.626589
parent: 60
@@ -151805,7 +151805,7 @@ entities:
ents: []
type: ContainerContainer
- uid: 16084
- type: PowerCellSmallAutorecharge
+ type: PowerCellMicroreactor
components:
- pos: 0.55256647,20.72724
parent: 60
@@ -151861,7 +151861,7 @@ entities:
- canCollide: False
type: Physics
- uid: 16091
- type: PowerCellMediumHyper
+ type: PowerCellHyper
components:
- pos: 0.56819147,21.03974
parent: 60
diff --git a/Resources/Maps/barratry.yml b/Resources/Maps/barratry.yml
index 7018486586..fa00b0ae17 100644
--- a/Resources/Maps/barratry.yml
+++ b/Resources/Maps/barratry.yml
@@ -111283,7 +111283,7 @@ entities:
charger-slot: !type:ContainerSlot {}
type: ContainerContainer
- uid: 12271
- type: PowerCellMediumPotato
+ type: PowerCellPotato
components:
- pos: -3.516998,-36.44544
parent: 106
diff --git a/Resources/Maps/delta.yml b/Resources/Maps/delta.yml
index d6e42babd2..d570a5f332 100644
--- a/Resources/Maps/delta.yml
+++ b/Resources/Maps/delta.yml
@@ -47764,7 +47764,7 @@ entities:
charger-slot: !type:ContainerSlot {}
type: ContainerContainer
- uid: 1777
- type: PowerCellLargeStandard
+ type: PowerCellSmall
components:
- pos: -10.414857,-37.378014
parent: 60
@@ -54147,7 +54147,7 @@ entities:
- canCollide: False
type: Physics
- uid: 2674
- type: PowerCellLargeStandard
+ type: PowerCellSmall
components:
- pos: -55.456623,-37.464394
parent: 60
@@ -54155,7 +54155,7 @@ entities:
- canCollide: False
type: Physics
- uid: 2675
- type: PowerCellLargeStandard
+ type: PowerCellSmall
components:
- pos: -55.44885,-38.160557
parent: 60
@@ -57048,7 +57048,7 @@ entities:
charger-slot: !type:ContainerSlot {}
type: ContainerContainer
- uid: 3076
- type: PowerCellLargeStandard
+ type: PowerCellSmall
components:
- pos: -55.356537,-43.214397
parent: 60
@@ -79980,7 +79980,7 @@ entities:
charger-slot: !type:ContainerSlot {}
type: ContainerContainer
- uid: 6323
- type: PowerCellLargeStandard
+ type: PowerCellSmall
components:
- pos: -50.5,-9.5
parent: 60
@@ -133076,7 +133076,7 @@ entities:
- canCollide: False
type: Physics
- uid: 13755
- type: PowerCellLargeStandard
+ type: PowerCellSmall
components:
- pos: 12.5294485,82.53368
parent: 60
@@ -154878,7 +154878,7 @@ entities:
ents: []
type: ContainerContainer
- uid: 16985
- type: PowerCellLargeStandard
+ type: PowerCellSmall
components:
- pos: 16.412798,54.560455
parent: 60
@@ -171164,7 +171164,7 @@ entities:
charger-slot: !type:ContainerSlot {}
type: ContainerContainer
- uid: 19288
- type: PowerCellLargeStandard
+ type: PowerCellSmall
components:
- pos: 43.575706,-44.36233
parent: 60
diff --git a/Resources/Maps/marathon.yml b/Resources/Maps/marathon.yml
index d98b108743..2e181fedc2 100644
--- a/Resources/Maps/marathon.yml
+++ b/Resources/Maps/marathon.yml
@@ -80,7 +80,7 @@ grids:
- ind: -1,1
tiles: IAAAADcAAAAxAAADNwAAADcAAAA1AAABNQAAAjcAAAA3AAAANwAAAB4AAAE3AAAANwAAADcAAAA3AAAANwAAACAAAAAxAAADMQAAAzcAAAAeAAAANQAAAzUAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADEAAAA3AAAAHgAAADUAAAA1AAACNQAAADUAAAEzAAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAAMwAAADMAAAAzAAAANwAAAB4AAAAeAAAAHgAAAB4AAAA3AAAAMwAAADcAAAA3AAAAHgAAAjEAAAIxAAABMQAAATcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAAB4AAAMxAAACMQAAADEAAAI3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAAeAAABMQAAAjEAAAExAAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAAHgAAADEAAAMxAAAAMQAAAzcAAAA3AAAANwAAACMAAAAjAAAAIwAAACMAAAAjAAAAIwAAACMAAAA3AAAANwAAAB4AAAAxAAABMQAAADEAAAI3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAAMQAAAjcAAAAxAAAAMQAAADEAAAAxAAACMQAAAjEAAAIxAAABMQAAATEAAAAxAAABMQAAATEAAAAxAAADMQAAAjEAAAExAAACMQAAATEAAAAxAAADMQAAAzEAAAMxAAAAMQAAATEAAAMxAAABMQAAADEAAAAxAAADMQAAAjEAAAMxAAAAMQAAAzEAAAMxAAABMQAAADEAAAExAAACMQAAAzEAAAIxAAADMQAAAzEAAAMxAAADMQAAATEAAAIxAAADMQAAADEAAAMxAAADHgAAAR4AAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAAeAAACHgAAADcAAAA3AAAAMQAAAh4AAAAeAAACNwAAADYAAAA2AAAANgAAADYAAAA2AAAANgAAADYAAAA3AAAAHgAAAx4AAAM3AAAAMQAAAzEAAAIeAAAAHgAAADcAAAA2AAAANwAAADcAAAA3AAAANwAAADcAAAA2AAAANwAAAB4AAAEeAAAANwAAADcAAAA3AAAAHgAAAx4AAAA3AAAANwAAADcAAAAeAAADHgAAAB4AAAM3AAAANwAAADcAAAAeAAACHgAAAzcAAAAeAAADNQAAAQ==
- ind: -2,1
- tiles: NwAAADMAAAA3AAAAJQAAAB4AAAAeAAAAHgAAAB4AAAAeAAAAJQAAADcAAAAgAAAAIAAAACAAAAAgAAAAIAAAADcAAAAzAAAANwAAACUAAAAeAAAAJQAAACUAAAAlAAAAJQAAACUAAAA3AAAANwAAACAAAAA3AAAAIAAAACAAAAA3AAAAMwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADMAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAAMwAAADMAAAAzAAAANwAAADMAAAAzAAAAMwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAAaAAAAGgAAAjcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAAgAAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAAGgAAARoAAAA3AAAAMQAAAzEAAAExAAADMQAAAjcAAAAgAAAAIAAAACAAAAA3AAAANwAAADcAAAA3AAAANwAAABoAAAEaAAAANwAAADEAAAMxAAACMQAAAjEAAAE3AAAAIAAAACAAAAAgAAAANwAAADcAAAA3AAAANwAAADcAAAAaAAAANwAAADcAAAA3AAAANwAAADEAAAM3AAAANwAAADcAAAAgAAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAAMQAAATEAAAExAAACMQAAATEAAAIxAAAAMQAAAzEAAAIxAAABMQAAAzEAAAIxAAACMQAAAjEAAAMxAAADMQAAADEAAAIxAAAAMQAAAzEAAAExAAABMQAAADEAAAIxAAADMQAAADEAAAExAAACMQAAAzEAAAMxAAABMQAAAzEAAAAxAAADMQAAAjEAAAAxAAAAMQAAADEAAAAxAAACMQAAADEAAAMxAAACMQAAAzEAAAExAAAAMQAAATEAAAIxAAABMQAAATcAAAA3AAAANwAAADcAAAA3AAAAMQAAAzcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADEAAAIxAAAAMQAAAjEAAAExAAADMQAAAzEAAAExAAADNwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAAxAAAAMQAAATEAAAAxAAADMQAAAjEAAAAxAAADMQAAATcAAAA3AAAANQAAAzUAAAE1AAAANQAAADUAAAA3AAAAMQAAADEAAAIxAAAAMQAAAzEAAAMxAAACMQAAAjEAAAI3AAAANwAAADUAAAA1AAABNQAAAzUAAAA1AAAANwAAAA==
+ tiles: NwAAADMAAAA3AAAAJQAAAB4AAAAeAAAAHgAAAB4AAAAeAAAAJQAAADcAAAAgAAAAIAAAACAAAAAgAAAAIAAAADcAAAAzAAAANwAAACUAAAAlAAAAJQAAACUAAAAlAAAAJQAAACUAAAA3AAAANwAAACAAAAA3AAAAIAAAACAAAAA3AAAAMwAAADcAAAA3AAAAJQAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADMAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAAMwAAADMAAAAzAAAANwAAADMAAAAzAAAAMwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAAaAAAAGgAAAjcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAAgAAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAAGgAAARoAAAA3AAAAMQAAAzEAAAExAAADMQAAAjcAAAAgAAAAIAAAACAAAAA3AAAANwAAADcAAAA3AAAANwAAABoAAAEaAAAANwAAADEAAAMxAAACMQAAAjEAAAE3AAAAIAAAACAAAAAgAAAANwAAADcAAAA3AAAANwAAADcAAAAaAAAANwAAADcAAAA3AAAANwAAADEAAAM3AAAANwAAADcAAAAgAAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAAMQAAATEAAAExAAACMQAAATEAAAIxAAAAMQAAAzEAAAIxAAABMQAAAzEAAAIxAAACMQAAAjEAAAMxAAADMQAAADEAAAIxAAAAMQAAAzEAAAExAAABMQAAADEAAAIxAAADMQAAADEAAAExAAACMQAAAzEAAAMxAAABMQAAAzEAAAAxAAADMQAAAjEAAAAxAAAAMQAAADEAAAAxAAACMQAAADEAAAMxAAACMQAAAzEAAAExAAAAMQAAATEAAAIxAAABMQAAATcAAAA3AAAANwAAADcAAAA3AAAAMQAAAzcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADEAAAIxAAAAMQAAAjEAAAExAAADMQAAAzEAAAExAAADNwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAAxAAAAMQAAATEAAAAxAAADMQAAAjEAAAAxAAADMQAAATcAAAA3AAAANQAAAzUAAAE1AAAANQAAADUAAAA3AAAAMQAAADEAAAIxAAAAMQAAAzEAAAMxAAACMQAAAjEAAAI3AAAANwAAADUAAAA1AAABNQAAAzUAAAA1AAAANwAAAA==
- ind: -3,0
tiles: AAAAADcAAAAxAAACMQAAAzcAAAAoAAAAKAAAACgAAAAoAAAAKAAAADcAAAAxAAADMQAAADEAAAExAAAANwAAAAAAAAA3AAAAMQAAAzEAAAA3AAAAKAAAACgAAAAoAAAAKAAAACgAAAA3AAAAMQAAAjEAAAIxAAABMQAAAjEAAAAAAAAANwAAADEAAAAxAAAANwAAACgAAAAoAAAAKAAAACgAAAAoAAAANwAAADEAAAExAAAAMQAAAzEAAAAxAAACAAAAADcAAAAxAAACMQAAAzcAAAAoAAAAKAAAACgAAAAoAAAAKAAAADcAAAAxAAABMQAAATEAAAAxAAADMQAAAwAAAAA3AAAAMQAAAjEAAAI3AAAANwAAADcAAAAxAAAANwAAADcAAAA3AAAAMQAAAjEAAAExAAABMQAAAzEAAAMAAAAANwAAADEAAAMxAAAAMQAAAjEAAAAxAAABMQAAADEAAAIxAAADMQAAAzEAAAExAAAAMQAAAzcAAAAeAAACNwAAADcAAAAxAAABMQAAAzEAAAAxAAACMQAAAzEAAAMxAAAAMQAAATEAAAAxAAAAMQAAAzEAAAM3AAAAHgAAADEAAAExAAACMQAAAjEAAAMxAAADMQAAAzEAAAIxAAABMQAAADEAAAMxAAACMQAAAjEAAAExAAADHgAAAB4AAAAxAAADMQAAADEAAAAxAAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADEAAAIxAAABMQAAAB4AAAEeAAAAMQAAATEAAAM3AAAAMQAAATcAAAAxAAABMQAAADEAAAIxAAAAMQAAAzcAAAAxAAADMQAAADEAAAI3AAAAHgAAADEAAAIxAAABNwAAADEAAAI3AAAAMQAAATEAAAExAAADMQAAAjEAAAAxAAACMQAAAzEAAAMxAAAANwAAAB4AAAA3AAAANwAAADcAAAA3AAAANwAAADEAAAExAAADMQAAADEAAAAxAAACNwAAADEAAAMxAAADMQAAADcAAAA3AAAANwAAAB4AAAEeAAAAHgAAAjcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAAxAAACMQAAATEAAAI3AAAAHgAAAzEAAAMxAAAAMQAAAzEAAAAxAAACMQAAAjEAAAIxAAAAMQAAADEAAAMxAAAAMQAAATEAAAAxAAABNwAAAB4AAAMxAAAAMQAAAjEAAAExAAAAMQAAADEAAAExAAADMQAAATEAAAMxAAADMQAAATEAAAAxAAABMQAAAjcAAAA3AAAAMQAAAjEAAAExAAACMQAAATEAAAIxAAADMQAAATEAAAExAAAAMQAAATEAAAAxAAABMQAAADEAAAA3AAAANwAAAA==
- ind: -3,1
@@ -96,7 +96,7 @@ grids:
- ind: -2,2
tiles: MQAAAzEAAAExAAABMQAAAjEAAAExAAACMQAAAzEAAAE3AAAANwAAADUAAAE1AAADNQAAADUAAAI1AAAANwAAADEAAAIxAAADMQAAAzEAAAAxAAAAMQAAAjEAAAIxAAAANwAAADcAAAA3AAAANQAAATcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA1AAAANQAAATUAAAI1AAAANQAAAjUAAAA3AAAAMQAAADEAAAIxAAADNwAAACgAAAAoAAAAKAAAACgAAAA3AAAANQAAADUAAAI1AAADNQAAAjUAAAI1AAADNwAAADEAAAMxAAADMQAAADcAAAAoAAAAKAAAACgAAAAoAAAANwAAADUAAAE1AAACNQAAAjUAAAI1AAAANQAAAzcAAAAxAAABMQAAATEAAAA3AAAAHgAAAB4AAAAeAAACHgAAAh4AAAEeAAACHgAAAx4AAAIeAAADHgAAAh4AAAAeAAAAHgAAAh4AAAI3AAAANwAAADcAAAA1AAADNwAAADcAAAA3AAAAHgAAAjcAAAA3AAAANwAAADcAAAA3AAAANwAAAB4AAAIeAAAANwAAADQAAAM0AAAANAAAAjQAAAE3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAAHgAAAx4AAAAeAAACHgAAAzcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADMAAAAzAAAAMwAAADcAAAAeAAAAHgAAAzcAAAA3AAAAHgAAAh4AAAEeAAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADEAAAMxAAADNwAAAB4AAAIeAAADHgAAAzcAAAA3AAAANwAAADcAAAA3AAAANgAAADYAAAA2AAAANgAAADcAAAAxAAACMQAAAB4AAAAeAAABHgAAAR4AAAM3AAAANwAAADcAAAA3AAAANwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMQAAAzEAAAI3AAAAHgAAAh4AAAEeAAACNwAAADMAAAA3AAAANwAAADcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAAzAAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANgAAAAAAAAAxAAACMQAAAjEAAAEeAAABNwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADYAAAAAAAAAMQAAAzEAAAAxAAABNwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA2AAAAAAAAAA==
- ind: -3,2
- tiles: NwAAADcAAAA3AAAAKAAAACgAAAAoAAAAKAAAADcAAAAjAAAAIwAAADcAAAAxAAAAMQAAAjEAAAM3AAAAMQAAADcAAAA3AAAANwAAACgAAAAoAAAAKAAAACgAAAA3AAAAIwAAACMAAAA3AAAAMQAAAzEAAAExAAABNwAAADEAAAA3AAAAMQAAAjcAAAA3AAAANwAAADcAAAAoAAAANwAAADcAAAA3AAAANwAAADEAAAIxAAAAMQAAADcAAAA3AAAAMQAAATEAAAExAAABMQAAATEAAAMxAAAAMQAAAjEAAAExAAABMQAAAjEAAAExAAACMQAAADEAAAExAAADMQAAAjEAAAIxAAADMQAAAzEAAAExAAACMQAAAzEAAAMxAAABMQAAAzEAAAIxAAADMQAAAjEAAAAxAAACMQAAATEAAAMxAAABMQAAAjEAAAAxAAADMQAAAjEAAAIxAAADMQAAAjEAAAMxAAACMQAAAjEAAAAxAAACMQAAAzEAAAMxAAABNwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAAeAAAANwAAAB4AAAM3AAAAHgAAATEAAAIxAAACNwAAADEAAAMxAAABMQAAAzcAAAAxAAACMQAAAzEAAAA3AAAAHgAAATEAAAMeAAABHgAAAh4AAAExAAABMQAAAzcAAAAxAAABMQAAAjEAAAI3AAAAMQAAAjEAAAExAAACNwAAAB4AAAMxAAABHgAAAx4AAAEeAAACMQAAAzcAAAA3AAAANwAAADEAAAI3AAAANwAAADcAAAAxAAADNwAAADcAAAAeAAAANwAAAB4AAAE3AAAANwAAADEAAAExAAABMQAAADEAAAExAAAAMQAAATEAAAExAAABMQAAAzEAAAAxAAACMQAAAjEAAAAxAAAAMQAAAzEAAAAxAAADMQAAAzEAAAMxAAABMQAAATEAAAIxAAABMQAAAzEAAAMxAAACMQAAATEAAAMxAAABMQAAATEAAAIxAAAAMQAAADEAAAAxAAABMQAAAzEAAAMxAAABMQAAADEAAAIxAAAAMQAAAzEAAAAxAAADMQAAAzEAAAExAAAAMQAAATEAAAAxAAACNwAAADcAAAA3AAAANwAAADcAAAA3AAAALgAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADEAAAExAAACMQAAAjcAAAAuAAAALgAAAC4AAAAuAAAALgAAAC4AAAAuAAAALgAAADcAAAAxAAACMQAAATEAAAAxAAADMQAAADEAAAI3AAAALgAAAC4AAAAuAAAALgAAAC4AAAAuAAAALgAAAC4AAAA3AAAAMQAAADEAAAExAAABMQAAAg==
+ tiles: NwAAADcAAAA3AAAAKAAAACgAAAAoAAAAKAAAADcAAAAjAAAAIwAAADcAAAAxAAAAMQAAAjEAAAM3AAAAMQAAADcAAAA3AAAANwAAACgAAAAoAAAAKAAAACgAAAA3AAAAIwAAACMAAAA3AAAAMQAAAzEAAAExAAABNwAAADEAAAA3AAAAMQAAAjcAAAA3AAAANwAAADcAAAAoAAAANwAAADcAAAA3AAAANwAAADEAAAIxAAAAMQAAADcAAAA3AAAAMQAAATEAAAExAAABMQAAATEAAAMxAAAAMQAAAjEAAAExAAABMQAAAjEAAAExAAACMQAAADEAAAExAAADMQAAAjEAAAIxAAADMQAAAzEAAAExAAACMQAAAzEAAAMxAAABMQAAAzEAAAIxAAADMQAAAjEAAAAxAAACMQAAATEAAAMxAAABMQAAAjEAAAAxAAADMQAAAjEAAAIxAAADMQAAAjEAAAMxAAACMQAAAjEAAAAxAAACMQAAAzEAAAMxAAABNwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAAeAAAANwAAAB4AAAM3AAAAHgAAATEAAAIxAAACNwAAADEAAAMxAAABMQAAAzcAAAAxAAACMQAAAzEAAAA3AAAAHgAAATEAAAMeAAABHgAAAh4AAAExAAABMQAAAzcAAAAxAAABMQAAAjEAAAI3AAAAMQAAAjEAAAExAAACNwAAAB4AAAMxAAABHgAAAx4AAAEeAAACMQAAAzcAAAA3AAAANwAAADEAAAI3AAAANwAAADcAAAAxAAADNwAAADcAAAAeAAAANwAAAB4AAAE3AAAANwAAADEAAAExAAABMQAAADEAAAExAAAAMQAAATEAAAExAAABMQAAAzEAAAAxAAACMQAAAjEAAAAxAAAAMQAAAzEAAAAxAAADMQAAAzEAAAMxAAABMQAAATEAAAIxAAABMQAAAzEAAAMxAAACMQAAATEAAAMxAAABMQAAATEAAAIxAAAAMQAAADEAAAAxAAABMQAAAzEAAAMxAAABMQAAADEAAAIxAAAAMQAAAzEAAAAxAAADMQAAAzEAAAExAAAAMQAAATEAAAAxAAACNwAAADcAAAA3AAAANwAAADcAAAA3AAAALgAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADEAAAExAAACMQAAAjcAAAAuAAAALgAAAC4AAAAuAAAALgAAAC4AAAAuAAAALgAAADcAAAAxAAACMQAAATEAAAAxAAADMQAAADEAAAI3AAAALgAAAC4AAAAuAAAALgAAAC4AAAAuAAAALgAAAC4AAAAuAAAAMQAAADEAAAExAAABMQAAAg==
- ind: -4,1
tiles: AAAAADcAAAA3AAAANwAAADcAAAA3AAAAMQAAADEAAAIxAAACMQAAADEAAAExAAABMQAAATEAAAExAAABNwAAAAAAAAAAAAAANgAAADYAAAA2AAAANwAAADEAAAAxAAACMQAAAyMAAAAjAAAAIwAAADEAAAAxAAACMQAAAh4AAAIAAAAAAAAAADYAAAAAAAAANgAAADcAAAAxAAAAMQAAAzEAAAEjAAAAIwAAACMAAAAxAAACMQAAATEAAAMeAAACAAAAAAAAAAA2AAAANgAAADYAAAA3AAAAMQAAAjEAAAExAAACIwAAACMAAAAjAAAAMQAAATEAAAExAAABHgAAAQAAAAA3AAAANwAAADcAAAA3AAAANwAAADEAAAExAAADMQAAADEAAAExAAABMQAAADEAAAExAAADMQAAATcAAAAAAAAANwAAADcAAAA3AAAANwAAADcAAAAxAAABMQAAAjEAAAExAAAAMQAAAzEAAAExAAAAMQAAAzEAAAEeAAABAAAAADcAAAA3AAAANwAAADcAAAA3AAAAMQAAADEAAAExAAABIwAAADEAAAEjAAAAMQAAAzEAAAAxAAABHgAAAwAAAAA3AAAANwAAADcAAAA3AAAANwAAADEAAAAxAAACMQAAATEAAAIxAAADMQAAATEAAAExAAADMQAAAh4AAAEAAAAANwAAADcAAAA3AAAANwAAADcAAAAxAAAAMQAAATEAAAMxAAAAMQAAADEAAAAxAAACMQAAATEAAAA3AAAAAAAAAAAAAAAAAAAANgAAAAAAAAA3AAAAHgAAAx4AAAEeAAABHgAAAx4AAAMeAAAAHgAAAB4AAAIeAAADNwAAAAAAAAAAAAAAAAAAADYAAAAAAAAANwAAADcAAAA3AAAANwAAADcAAAAeAAACNwAAADcAAAA3AAAANwAAADcAAAAAAAAAAAAAAAAAAAA2AAAAAAAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAAAAAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAAAAAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAAMwAAADcAAAA1AAADNQAAADUAAAE1AAACNQAAADUAAAMAAAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADMAAAA3AAAANQAAADUAAAI1AAAANQAAAzUAAAI1AAABNgAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAAzAAAANwAAADUAAAA1AAAANQAAAjUAAAA1AAACNQAAAg==
- ind: -4,2
@@ -122,7 +122,7 @@ grids:
- ind: 1,2
tiles: NwAAADcAAAA3AAAANwAAADcAAAAxAAABMQAAATEAAAM3AAAANwAAACAAAAA3AAAANwAAADcAAAA3AAAANwAAACgAAAAoAAAAKAAAACgAAAAxAAADMQAAATEAAAMxAAACMQAAAjEAAAAxAAADMQAAAjcAAAA3AAAANwAAADcAAAAoAAAAKAAAACgAAAA3AAAAMQAAADEAAAExAAABMQAAATEAAAAxAAAAMQAAAjEAAAA3AAAAMQAAAzEAAAExAAACNwAAADcAAAA3AAAANwAAADEAAAAxAAACMQAAATEAAAAxAAACMQAAADEAAAAxAAABNwAAADEAAAIxAAAAMQAAATUAAAI1AAABNQAAAjUAAAIxAAABMQAAAjEAAAExAAAAMQAAAjEAAAMxAAADMQAAADEAAAIxAAADMQAAADEAAAA1AAAANQAAATUAAAA3AAAAMQAAAjEAAAAxAAABMQAAATEAAAIxAAACMQAAATEAAAMxAAACMQAAATEAAAExAAACNwAAADcAAAA3AAAANwAAADEAAAExAAACMQAAAzEAAAAxAAAAMQAAAzEAAAIxAAACNwAAADEAAAMxAAACMQAAADUAAAA1AAABNQAAAzUAAAMxAAACMQAAAjEAAAIxAAADMQAAAjEAAAAxAAAAMQAAAjcAAAAxAAADMQAAADEAAAE1AAADNQAAADUAAAE3AAAAMQAAAzEAAAMxAAACMQAAAzEAAAAxAAADMQAAADEAAAE3AAAANwAAACAAAAA3AAAANwAAADcAAAA3AAAANwAAACcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAACAAAAAgAAAAIAAAADMAAAA3AAAAJwAAACcAAAAnAAAAJwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAAgAAAAIAAAACAAAAA3AAAAJwAAACcAAAAnAAAAJwAAACcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAAIAAAACAAAAAgAAAANwAAADcAAAAnAAAAJwAAACcAAAAnAAAANwAAADYAAAA2AAAANgAAADYAAAA2AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADcAAAA3AAAANwAAADcAAAA3AAAAMwAAADMAAAAzAAAAMwAAADcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANwAAADcAAAA3AAAANwAAADMAAAAzAAAAMwAAADMAAAA3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADcAAAA3AAAANwAAAA==
- ind: 2,2
- tiles: NwAAACsAAAA3AAAAKwAAACsAAAArAAAAKwAAACsAAAArAAAAKwAAACsAAAArAAAANwAAADcAAAAxAAAANwAAADcAAAA3AAAANwAAACsAAAArAAAAKwAAACsAAAArAAAAKwAAACsAAAArAAAAKwAAADcAAAAxAAABMQAAAjcAAAAxAAABMQAAAjcAAAArAAAAKwAAACsAAAArAAAAKwAAACsAAAArAAAAKwAAACsAAAA3AAAAMQAAAjEAAAE3AAAAMQAAAjEAAAIxAAABKwAAACsAAAArAAAAKwAAACsAAAArAAAAKwAAACsAAAArAAAAMQAAADEAAAMxAAABNwAAADEAAAMxAAADNwAAACsAAAArAAAAKwAAACsAAAArAAAAKwAAACsAAAArAAAAKwAAADcAAAAxAAAAMQAAATcAAAAxAAAAMQAAATcAAAArAAAAKwAAACsAAAArAAAAKwAAACsAAAArAAAAKwAAACsAAAA3AAAAMQAAADEAAAM3AAAAMQAAATEAAAExAAACKwAAACsAAAArAAAAKwAAACsAAAArAAAAKwAAACsAAAArAAAAMQAAAjEAAAIxAAABNwAAADEAAAMxAAACNwAAACsAAAArAAAAKwAAACsAAAArAAAAKwAAACsAAAArAAAAKwAAADcAAAAxAAADMQAAAzcAAAA3AAAANwAAADcAAAArAAAAKwAAACsAAAArAAAAKwAAACsAAAArAAAAKwAAACsAAAA3AAAANwAAADEAAAA3AAAANwAAADcAAAA3AAAAKwAAACsAAAArAAAAKwAAACsAAAArAAAAKwAAACsAAAArAAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANQAAAjcAAAA3AAAANQAAAzcAAAA1AAADNQAAAzUAAAA3AAAANQAAATcAAAA1AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANQAAATcAAAA3AAAANQAAATUAAAI3AAAANwAAADUAAAM1AAADNwAAADcAAAA3AAAANwAAADUAAAM1AAACNQAAATcAAAA1AAAANwAAADcAAAA1AAAANQAAADcAAAA1AAACNwAAADUAAAM3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANgAAADYAAAA2AAAANgAAADYAAAA2AAAANgAAADYAAAA2AAAANgAAADYAAAA2AAAANgAAADYAAAA2AAAANgAAAA==
+ tiles: NwAAACsAAAA3AAAAHgAAAB4AAAAeAAAAHgAAAB4AAAAeAAAAHgAAAB4AAAAeAAAANwAAADcAAAAxAAAANwAAADcAAAA3AAAANwAAAB4AAAAeAAAAHgAAAB4AAAAeAAAAHgAAAB4AAAAeAAAAHgAAADcAAAAxAAABHgAAADcAAAAxAAABMQAAAjcAAAAeAAAAHgAAAB4AAAAeAAAAHgAAAB4AAAAeAAAAHgAAAB4AAAAeAAAAHgAAADEAAAE3AAAAMQAAAjEAAAIxAAABHgAAAB4AAAAeAAAAHgAAAB4AAAAeAAAAHgAAAB4AAAAeAAAANwAAADEAAAMeAAAANwAAADEAAAMxAAADNwAAADcAAAA3AAAANwAAADcAAAAeAAAANwAAADcAAAA3AAAANwAAADcAAAAeAAAAMQAAATcAAAAxAAAAMQAAATcAAAAeAAAANQAAADUAAAA1AAAANQAAADUAAAA1AAAANQAAADUAAAA3AAAAMQAAAB4AAAA3AAAAMQAAATEAAAEeAAAAHgAAADUAAAA1AAAANQAAADUAAAA1AAAANQAAADUAAAA1AAAAHgAAAB4AAAAxAAABNwAAADEAAAMxAAACNwAAAB4AAAA1AAAANQAAADUAAAA1AAAANQAAADUAAAA1AAAANQAAADcAAAAxAAADHgAAADcAAAA3AAAANwAAADcAAAAeAAAANQAAADUAAAA1AAAANQAAADUAAAA1AAAANQAAADUAAAA3AAAANwAAADEAAAA3AAAANwAAADcAAAA3AAAAHgAAADUAAAA1AAAANQAAADUAAAA1AAAANQAAADUAAAAeAAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANQAAAjcAAAA3AAAANQAAAzcAAAA1AAADNQAAAzUAAAA3AAAANQAAATcAAAA1AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANQAAATcAAAA3AAAANQAAATUAAAI3AAAANwAAADUAAAM1AAADNwAAADcAAAA3AAAANwAAADUAAAM1AAACNQAAATcAAAA1AAAANwAAADcAAAA1AAAANQAAADcAAAA1AAACNwAAADUAAAM3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANgAAADYAAAA2AAAANgAAADYAAAA2AAAANgAAADYAAAA2AAAANgAAADYAAAA2AAAANgAAADYAAAA2AAAANgAAAA==
- ind: 2,1
tiles: NwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAAAAAAADYAAAAAAAAAAAAAACAAAAAgAAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA2AAAAAAAAADYAAAAgAAAAIAAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAAIAAAACAAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA2AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAAMgAAACAAAAAgAAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANgAAADcAAAA3AAAAMgAAADcAAAAyAAAAMgAAADcAAAA0AAACNwAAADcAAAA3AAAANwAAAAAAAAAAAAAAAAAAADYAAAA3AAAANwAAADMAAAAzAAAAMgAAADIAAAA3AAAANAAAATcAAAAzAAAANwAAADcAAAAAAAAAAAAAAAAAAAA2AAAANwAAADcAAAAzAAAAMwAAADIAAAAzAAAANwAAADQAAAI3AAAAMwAAADcAAAA3AAAAAAAAAAAAAAAAAAAANgAAADcAAAA3AAAAMgAAADMAAAAzAAAAMwAAADcAAAA3AAAANwAAADMAAAA3AAAANwAAAAAAAAAAAAAAAAAAADYAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAAMwAAADMAAAAzAAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAAAwAAAAMAAAADAAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAAAMAAAADAAAAAwAAADcAAAA3AAAANwAAAB4AAAM3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAADAAAAAwAAAAMAAAA3AAAANwAAAB4AAAEeAAADNwAAAAsAAAALAAAACwAAAAsAAAALAAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAAB4AAAEeAAAAHgAAADcAAAALAAAACwAAAAsAAAALAAAACwAAADcAAAA3AAAANwAAADcAAAAzAAAAMwAAADMAAAA3AAAAHgAAAx4AAAM3AAAACwAAAAsAAAALAAAACwAAAAsAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAADcAAAA3AAAANwAAAA==
- ind: 1,0
@@ -240,7 +240,7 @@ grids:
- ind: 0,5
tiles: NwAAADcAAAAcAAAAHAAAAB4AAAA3AAAAAAAAADYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADcAAAA3AAAANwAAABwAAAAeAAAANwAAAAAAAAA2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3AAAANwAAADcAAAAcAAAAHgAAADcAAAAAAAAANgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHgAAAB4AAAAeAAAAHAAAACsAAAA3AAAAAAAAADYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAAA3AAAANwAAABwAAAAeAAAANwAAADYAAAA2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3AAAANwAAADcAAAAcAAAAHgAAADcAAAAAAAAANgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANwAAADcAAAAcAAAAHAAAAB4AAAA3AAAAAAAAADYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAAAAcAAAAHAAAACsAAAAeAAAANwAAAAAAAAA2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeAAAAHgAAAB4AAAAeAAAAHgAAADcAAAAAAAAANgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANwAAADcAAAA3AAAAHgAAAB4AAAA3AAAANgAAADYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2AAAAAAAAAAAAAAA2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2AAAANgAAADYAAAA2AAAANgAAADYAAAAAAAAANgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
- ind: 2,3
- tiles: AAAAAAAAAAA2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2AAAAAAAAAAAAAAAAAAAANgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
+ tiles: AAAAAAAAAAAAAAAANgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADYAAAAAAAAAAAAAAAAAAAAAAAAANgAAADYAAAA2AAAANgAAADYAAAA2AAAANgAAADYAAAA2AAAANgAAADYAAAA2AAAANgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
- ind: 2,-5
tiles: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAABFAAAARQAAAIUAAAAFAAAAhQAAAAUAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAIUAAAAFAAAABQAAAEUAAABFAAAARQAAAIUAAAAFAAAARQAAAIAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAUAAABFAAAAhcAAAAUAAABFAAAAhQAAAEUAAACFAAAABQAAAAUAAABFAAAAgAAAAAAAAAAAAAAAAAAAAAUAAAAFAAAAhQAAAIUAAACFAAAAhQAAAEUAAAAFAAAAhQAAAEUAAAAFAAAAhQAAAIAAAAAAAAAAAAAAAAUAAABFAAAAhQAAAAUAAAAFAAAAhQAAAIUAAABFAAAAhQAAAAUAAABFAAAARcAAAAUAAABFAAAAgAAAAAAAAAAFAAAAhQAAAAUAAAAFAAAARQAAAAUAAAAFAAAABQAAAIUAAACFAAAAhQAAAIUAAABFAAAABQAAAAUAAAAFAAAAhQAAAIUAAABFAAAABQAAAIUAAAAFAAAAhQAAAEUAAACFAAAABQAAAIUAAAAFAAAAhQAAAEUAAACFAAAABQAAAEUAAABFAAAAhQAAAAUAAABFAAAAhQAAAAUAAABFAAAAhQAAAAUAAACFAAAAhQAAAIUAAACFAAAABQAAAEUAAABFAAAABQAAAIUAAABFAAAABQAAAIUAAABFAAAARQAAAAUAAAAFAAAABQAAAAUAAACFAAAABQAAAIUAAAAFAAAARQAAAIUAAABFAAAARQAAAAUAAAAFAAAAhQAAAAUAAACFAAAARQAAAAUAAABFAAAAhQAAAAUAAACFAAAARQAAAIUAAAAFAAAABQAAAEXAAAAFAAAAhQAAAEUAAABFAAAARQAAAIUAAAAFAAAARQAAAEUAAACFAAAABQAAAEUAAACFAAAAhQAAAAUAAACFwAAABQAAAAUAAABFAAAAhQAAAAUAAACFAAAAhQAAAAUAAAAFAAAARQAAAIUAAABFAAAARQAAAAUAAACFAAAABQAAAAUAAABFAAAARQAAAEUAAAAFAAAABQAAAIUAAACFAAAABQAAAIUAAAAFAAAAQ==
- ind: 1,-5
@@ -5532,10 +5532,6 @@ entities:
color: '#EFB34196'
id: QuarterTileOverlayGreyscale270
coordinates: -4,-21
- 1023:
- color: '#EFB34196'
- id: QuarterTileOverlayGreyscale270
- coordinates: -4,-22
1024:
color: '#EFB34196'
id: QuarterTileOverlayGreyscale270
@@ -5572,10 +5568,6 @@ entities:
color: '#EFB34196'
id: QuarterTileOverlayGreyscale270
coordinates: -4,-31
- 1033:
- color: '#EFB34196'
- id: QuarterTileOverlayGreyscale180
- coordinates: -2,-22
1034:
color: '#EFB34196'
id: QuarterTileOverlayGreyscale180
@@ -5596,13 +5588,13 @@ entities:
color: '#EFB34196'
id: QuarterTileOverlayGreyscale180
coordinates: -2,-27
- 1043:
- color: '#9FED5896'
- id: HalfTileOverlayGreyscale
+ 2044:
+ color: '#EFB34196'
+ id: QuarterTileOverlayGreyscale
coordinates: -1,-28
- 1044:
- color: '#9FED5896'
- id: HalfTileOverlayGreyscale180
+ 2045:
+ color: '#EFB34196'
+ id: QuarterTileOverlayGreyscale180
coordinates: -1,-21
1057:
color: '#EFB34196'
@@ -6082,38 +6074,38 @@ entities:
color: '#EFB34196'
id: HalfTileOverlayGreyscale270
coordinates: 5,-24
- 1039:
- color: '#9FED5896'
- id: HalfTileOverlayGreyscale
+ 2040:
+ color: '#EFB34196'
+ id: CheckerNWSE
coordinates: 3,-28
- 1040:
- color: '#9FED5896'
- id: HalfTileOverlayGreyscale
+ 2041:
+ color: '#EFB34196'
+ id: QuarterTileOverlayGreyscale
coordinates: 2,-28
- 1041:
- color: '#9FED5896'
- id: HalfTileOverlayGreyscale
+ 2042:
+ color: '#EFB34196'
+ id: QuarterTileOverlayGreyscale
coordinates: 1,-28
- 1042:
- color: '#9FED5896'
- id: HalfTileOverlayGreyscale
+ 2043:
+ color: '#EFB34196'
+ id: QuarterTileOverlayGreyscale
coordinates: 0,-28
- 1045:
- color: '#9FED5896'
- id: HalfTileOverlayGreyscale180
- coordinates: 0,-21
- 1046:
- color: '#9FED5896'
- id: HalfTileOverlayGreyscale180
+ 2047:
+ color: '#EFB34196'
+ id: QuarterTileOverlayGreyscale180
coordinates: 1,-21
- 1047:
- color: '#9FED5896'
- id: HalfTileOverlayGreyscale180
- coordinates: 2,-21
- 1048:
- color: '#9FED5896'
- id: HalfTileOverlayGreyscale180
+ 2048:
+ color: '#EFB34196'
+ id: QuarterTileOverlayGreyscale180
coordinates: 3,-21
+ 2046:
+ color: '#EFB34196'
+ id: QuarterTileOverlayGreyscale180
+ coordinates: 0,-21
+ 2052:
+ color: '#EFB34196'
+ id: QuarterTileOverlayGreyscale270
+ coordinates: 11,-21
1049:
color: '#FFFFFFFF'
id: Delivery
@@ -6138,14 +6130,14 @@ entities:
color: '#FFFFFFFF'
id: WarningLine
coordinates: 5,-21
- 1055:
- color: '#FFFFFFFF'
- id: WarningLineCornerFlipped
+ 2050:
+ color: '#EFB34196'
+ id: QuarterTileOverlayGreyscale270
coordinates: 8,-21
- 1056:
- color: '#FFFFFFFF'
- id: WarningLineCorner
- coordinates: 4,-21
+ 2051:
+ color: '#EFB34196'
+ id: QuarterTileOverlayGreyscale270
+ coordinates: 9,-21
1060:
color: '#EFB34196'
id: QuarterTileOverlayGreyscale270
@@ -6222,9 +6214,9 @@ entities:
color: '#FFFFFFFF'
id: Bot
coordinates: 7,-30
- 1080:
- color: '#9FED5896'
- id: QuarterTileOverlayGreyscale270
+ 2049:
+ color: '#EFB34196'
+ id: QuarterTileOverlayGreyscale180
coordinates: 4,-21
1098:
angle: 3.141592653589793 rad
@@ -6603,26 +6595,22 @@ entities:
color: '#9FED5896'
id: HalfTileOverlayGreyscale270
coordinates: 7,-11
- 1931:
+ 2056:
+ color: '#EFB34196'
+ id: QuarterTileOverlayGreyscale180
+ coordinates: 2,-21
+ 2055:
color: '#9FED5896'
id: HalfTileOverlayGreyscale270
coordinates: 7,-12
- 1932:
- color: '#9FED5896'
- id: QuarterTileOverlayGreyscale180
- coordinates: 7,-12
- 1933:
- color: '#9FED5896'
- id: HalfTileOverlayGreyscale180
- coordinates: 8,-12
- 1934:
- color: '#9FED5896'
- id: HalfTileOverlayGreyscale180
- coordinates: 9,-12
- 1935:
- color: '#9FED5896'
- id: QuarterTileOverlayGreyscale270
- coordinates: 10,-12
+ 2059:
+ color: '#FFFFFFFF'
+ id: WarningLineCorner
+ coordinates: 4,-21
+ 2058:
+ color: '#FFFFFFFF'
+ id: WarningLineCornerFlipped
+ coordinates: 8,-21
1937:
color: '#FFFFFFFF'
id: Grasse2
@@ -6755,6 +6743,14 @@ entities:
color: '#FFFFFFFF'
id: Delivery
coordinates: 31,-3
+ 2053:
+ color: '#EFB34196'
+ id: QuarterTileOverlayGreyscale270
+ coordinates: 12,-21
+ 2054:
+ color: '#EFB34196'
+ id: QuarterTileOverlayGreyscale270
+ coordinates: 13,-21
0,-2:
1081:
color: '#FFFFFFFF'
@@ -9091,7 +9087,7 @@ entities:
6,6: 1
6,7: 5
0,17: 1
- 1,17: 5
+ 1,17: 6
2,17: 1
3,16: 1
-2,16: 1
@@ -9124,7 +9120,7 @@ entities:
-3,2: 0
-3,3: 0
-3,4: 0
- -3,5: 6
+ -3,5: 7
-3,6: 0
-3,7: 0
-3,8: 0
@@ -9145,7 +9141,7 @@ entities:
0,-1: 0
1,-10: 0
1,-2: 0
- 2,-10: 7
+ 2,-10: 8
2,-2: 0
3,-10: 0
3,-2: 0
@@ -9186,7 +9182,7 @@ entities:
4,3: 0
4,4: 0
4,5: 0
- 4,6: 0
+ 4,6: 9
4,7: 0
4,8: 0
4,9: 0
@@ -9384,7 +9380,7 @@ entities:
-5,13: 0
-5,14: 0
-5,15: 0
- -4,5: 8
+ -4,5: 10
-4,6: 0
-4,10: 0
-4,11: 0
@@ -9395,14 +9391,14 @@ entities:
-3,15: 0
4,15: 0
5,5: 0
- 5,6: 5
+ 5,6: 11
5,10: 0
5,11: 0
5,12: 0
5,13: 0
5,14: 0
5,15: 0
- 6,8: 9
+ 6,8: 12
6,9: 0
6,10: 0
6,11: 0
@@ -9502,8 +9498,8 @@ entities:
-6,-1: 0
-5,-6: 0
-5,-5: 0
- -5,-4: 10
- -5,-3: 11
+ -5,-4: 13
+ -5,-3: 14
-4,-2: 0
-4,-1: 0
10,-1: 0
@@ -13888,8 +13884,8 @@ entities:
9,-3: 0
9,-2: 0
9,-1: 0
- 10,-16: 0
- 10,-15: 0
+ 10,-16: 15
+ 10,-15: 16
10,-14: 0
10,-13: 0
10,-12: 0
@@ -16125,15 +16121,15 @@ entities:
24,-18: 0
24,-17: 0
25,-32: 0
- 25,-31: 12
+ 25,-31: 17
25,-30: 0
- 25,-29: 13
+ 25,-29: 18
25,-28: 0
- 25,-27: 13
+ 25,-27: 18
25,-26: 0
- 25,-25: 14
- 25,-24: 0
- 25,-23: 15
+ 25,-25: 19
+ 25,-24: 20
+ 25,-23: 21
25,-22: 0
25,-21: 0
25,-20: 0
@@ -16141,15 +16137,15 @@ entities:
25,-18: 0
25,-17: 0
26,-32: 0
- 26,-31: 12
+ 26,-31: 17
26,-30: 0
- 26,-29: 13
+ 26,-29: 18
26,-28: 0
- 26,-27: 13
+ 26,-27: 18
26,-26: 0
- 26,-25: 14
- 26,-24: 0
- 26,-23: 15
+ 26,-25: 19
+ 26,-24: 22
+ 26,-23: 21
26,-22: 0
26,-21: 0
26,-20: 0
@@ -16157,15 +16153,15 @@ entities:
26,-18: 0
26,-17: 0
27,-32: 0
- 27,-31: 12
+ 27,-31: 17
27,-30: 0
- 27,-29: 13
+ 27,-29: 18
27,-28: 0
- 27,-27: 13
+ 27,-27: 18
27,-26: 0
- 27,-25: 14
- 27,-24: 0
- 27,-23: 15
+ 27,-25: 19
+ 27,-24: 20
+ 27,-23: 21
27,-22: 0
27,-21: 0
27,-20: 0
@@ -16453,17 +16449,17 @@ entities:
24,-34: 0
24,-33: 0
25,-36: 0
- 25,-35: 13
+ 25,-35: 18
25,-34: 0
- 25,-33: 13
+ 25,-33: 18
26,-36: 0
- 26,-35: 13
+ 26,-35: 18
26,-34: 0
- 26,-33: 13
+ 26,-33: 18
27,-36: 0
- 27,-35: 13
+ 27,-35: 18
27,-34: 0
- 27,-33: 13
+ 27,-33: 18
28,-36: 0
28,-35: 0
28,-34: 0
@@ -19427,7 +19423,7 @@ entities:
-61,54: 0
-61,55: 0
-61,56: 0
- -61,57: 12
+ -61,57: 17
-61,58: 0
-61,59: 0
-61,60: 0
@@ -22232,15 +22228,15 @@ entities:
36,-61: 0
36,-60: 0
36,-59: 0
- 36,-58: 13
+ 36,-58: 18
36,-57: 0
36,-56: 0
36,-55: 0
37,-64: 0
37,-63: 0
37,-62: 0
- 37,-61: 13
- 37,-60: 13
+ 37,-61: 18
+ 37,-60: 18
37,-59: 0
37,-58: 0
37,-57: 0
@@ -22260,9 +22256,9 @@ entities:
38,-54: 0
38,-53: 0
39,-64: 0
- 39,-63: 13
- 39,-62: 13
- 39,-61: 13
+ 39,-63: 18
+ 39,-62: 18
+ 39,-61: 18
39,-60: 0
39,-59: 0
39,-58: 0
@@ -22271,7 +22267,7 @@ entities:
39,-55: 0
39,-54: 0
39,-53: 0
- 40,-64: 13
+ 40,-64: 18
40,-63: 0
40,-62: 0
40,-61: 0
@@ -22307,7 +22303,7 @@ entities:
43,-64: 0
43,-63: 0
43,-62: 0
- 43,-61: 13
+ 43,-61: 18
43,-60: 0
43,-59: 0
43,-58: 0
@@ -22411,8 +22407,8 @@ entities:
35,-70: 0
35,-69: 0
35,-68: 0
- 35,-67: 13
- 35,-66: 13
+ 35,-67: 18
+ 35,-66: 18
35,-65: 0
36,-76: 0
36,-75: 0
@@ -22422,9 +22418,9 @@ entities:
36,-71: 0
36,-70: 0
36,-69: 0
- 36,-68: 13
- 36,-67: 13
- 36,-66: 13
+ 36,-68: 18
+ 36,-67: 18
+ 36,-66: 18
36,-65: 0
37,-77: 0
37,-76: 0
@@ -22435,20 +22431,20 @@ entities:
37,-71: 0
37,-70: 0
37,-69: 0
- 37,-68: 13
- 37,-67: 13
+ 37,-68: 18
+ 37,-67: 18
37,-66: 0
37,-65: 0
38,-77: 0
38,-76: 0
38,-75: 0
- 38,-74: 13
+ 38,-74: 18
38,-73: 0
38,-72: 0
38,-71: 0
38,-70: 0
- 38,-69: 13
- 38,-68: 13
+ 38,-69: 18
+ 38,-68: 18
38,-67: 0
38,-66: 0
38,-65: 0
@@ -22457,7 +22453,7 @@ entities:
39,-75: 0
39,-74: 0
39,-73: 0
- 39,-72: 13
+ 39,-72: 18
39,-71: 0
39,-70: 0
39,-69: 0
@@ -22468,7 +22464,7 @@ entities:
40,-77: 0
40,-76: 0
40,-75: 0
- 40,-74: 13
+ 40,-74: 18
40,-73: 0
40,-72: 0
40,-71: 0
@@ -22481,7 +22477,7 @@ entities:
41,-77: 0
41,-76: 0
41,-75: 0
- 41,-74: 13
+ 41,-74: 18
41,-73: 0
41,-72: 0
41,-71: 0
@@ -22493,12 +22489,12 @@ entities:
41,-65: 0
42,-77: 0
42,-76: 0
- 42,-75: 13
+ 42,-75: 18
42,-74: 0
42,-73: 0
42,-72: 0
42,-71: 0
- 42,-70: 13
+ 42,-70: 18
42,-69: 0
42,-68: 0
42,-67: 0
@@ -22511,8 +22507,8 @@ entities:
43,-73: 0
43,-72: 0
43,-71: 0
- 43,-70: 13
- 43,-69: 13
+ 43,-70: 18
+ 43,-69: 18
43,-68: 0
43,-67: 0
43,-66: 0
@@ -22522,10 +22518,10 @@ entities:
44,-74: 0
44,-73: 0
44,-72: 0
- 44,-71: 13
- 44,-70: 13
- 44,-69: 13
- 44,-68: 13
+ 44,-71: 18
+ 44,-70: 18
+ 44,-69: 18
+ 44,-68: 18
44,-67: 0
44,-66: 0
44,-65: 0
@@ -22534,12 +22530,12 @@ entities:
45,-73: 0
45,-72: 0
45,-71: 0
- 45,-70: 13
+ 45,-70: 18
45,-69: 0
45,-68: 0
45,-67: 0
45,-66: 0
- 45,-65: 13
+ 45,-65: 18
46,-73: 0
46,-72: 0
46,-71: 0
@@ -22885,10 +22881,10 @@ entities:
- 0
- 0
- volume: 2500
- temperature: 288.6117
+ temperature: 288.04443
moles:
- - 21.483866
- - 80.82026
+ - 21.441238
+ - 80.6599
- 0
- 0
- 0
@@ -22896,10 +22892,10 @@ entities:
- 0
- 0
- volume: 2500
- temperature: 138.84845
+ temperature: 137.57205
moles:
- - 10.230412
- - 38.485836
+ - 10.134501
+ - 38.12503
- 0
- 0
- 0
@@ -22907,10 +22903,21 @@ entities:
- 0
- 0
- volume: 2500
- temperature: 284.07346
+ temperature: 282.79706
moles:
- - 21.14285
- - 79.5374
+ - 21.04694
+ - 79.17659
+ - 0
+ - 0
+ - 0
+ - 0
+ - 0
+ - 0
+ - volume: 2500
+ temperature: 120.69531
+ moles:
+ - 8.866357
+ - 33.354393
- 0
- 0
- 0
@@ -22929,10 +22936,21 @@ entities:
- 0
- 0
- volume: 2500
- temperature: 274.99686
+ temperature: 272.72772
moles:
- - 20.460825
- - 76.97167
+ - 20.290318
+ - 76.330246
+ - 0
+ - 0
+ - 0
+ - 0
+ - 0
+ - 0
+ - volume: 2500
+ temperature: 251.73819
+ moles:
+ - 18.713127
+ - 70.39701
- 0
- 0
- 0
@@ -22942,7 +22960,7 @@ entities:
- volume: 2500
temperature: 256.84375
moles:
- - 19.09677
+ - 19.096767
- 71.840225
- 0
- 0
@@ -22951,7 +22969,62 @@ entities:
- 0
- 0
- volume: 2500
- temperature: 220.53749
+ temperature: 215.99922
+ moles:
+ - 16.027645
+ - 60.29448
+ - 0
+ - 0
+ - 0
+ - 0
+ - 0
+ - 0
+ - volume: 2500
+ temperature: 138.84845
+ moles:
+ - 10.230412
+ - 38.485836
+ - 0
+ - 0
+ - 0
+ - 0
+ - 0
+ - 0
+ - volume: 2500
+ temperature: 177.42383
+ moles:
+ - 13.129028
+ - 49.39016
+ - 0
+ - 0
+ - 0
+ - 0
+ - 0
+ - 0
+ - volume: 2500
+ temperature: 197.8461
+ moles:
+ - 14.66359
+ - 55.163033
+ - 0
+ - 0
+ - 0
+ - 0
+ - 0
+ - 0
+ - volume: 2500
+ temperature: 196.71152
+ moles:
+ - 14.578337
+ - 54.842316
+ - 0
+ - 0
+ - 0
+ - 0
+ - 0
+ - 0
+ - volume: 2500
+ temperature: 293.15
moles:
- 16.36866
- 61.57734
@@ -22962,32 +23035,10 @@ entities:
- 0
- 0
- volume: 2500
- temperature: 184.23125
+ temperature: 293.15
moles:
- - 13.64055
- - 51.31445
- - 0
- - 0
- - 0
- - 0
- - 0
- - 0
- - volume: 2500
- temperature: 220.5375
- moles:
- - 16.36866
- - 61.57734
- - 0
- - 0
- - 0
- - 0
- - 0
- - 0
- - volume: 2500
- temperature: 202.38437
- moles:
- - 15.004604
- - 56.445892
+ - 20.460823
+ - 76.97167
- 0
- 0
- 0
@@ -23027,6 +23078,17 @@ entities:
- 0
- 0
- 0
+ - volume: 2500
+ temperature: 293.15
+ moles:
+ - 1677.6578
+ - 1707.797
+ - 0
+ - 0
+ - 0
+ - 0
+ - 0
+ - 0
- volume: 2500
temperature: 293.15
moles:
@@ -23038,6 +23100,17 @@ entities:
- 0
- 0
- 0
+ - volume: 2500
+ temperature: 293.15
+ moles:
+ - 2505.5745
+ - 2520.644
+ - 0
+ - 0
+ - 0
+ - 0
+ - 0
+ - 0
type: GridAtmosphere
- id: Marathon
type: BecomesStation
@@ -25221,18 +25294,16 @@ entities:
parent: 30
type: Transform
- uid: 356
- type: ShuttersNormalOpen
+ type: DisposalTrunk
components:
- - pos: 7.5,-17.5
+ - rot: 1.5707963267948966 rad
+ pos: -3.5,-28.5
parent: 30
type: Transform
- - inputs:
- Open: []
- Close: []
- Toggle:
- - port: Pressed
- uid: 21469
- type: SignalReceiver
+ - containers:
+ DisposalEntry: !type:Container
+ ents: []
+ type: ContainerContainer
- uid: 357
type: Grille
components:
@@ -26810,10 +26881,9 @@ entities:
parent: 30
type: Transform
- uid: 572
- type: Girder
+ type: TableWood
components:
- - rot: 1.5707963267948966 rad
- pos: 45.5,41.5
+ - pos: 39.5,40.5
parent: 30
type: Transform
- uid: 573
@@ -29838,18 +29908,15 @@ entities:
parent: 30
type: Transform
- uid: 1016
- type: ShuttersNormalOpen
+ type: DisposalUnit
components:
- - pos: 9.5,-17.5
+ - pos: -3.5,-28.5
parent: 30
type: Transform
- - inputs:
- Open: []
- Close: []
- Toggle:
- - port: Pressed
- uid: 21469
- type: SignalReceiver
+ - containers:
+ DisposalUnit: !type:Container
+ ents: []
+ type: ContainerContainer
- uid: 1017
type: TableWood
components:
@@ -35604,7 +35671,7 @@ entities:
parent: 30
type: Transform
- uid: 1873
- type: AirlockSecurityLocked
+ type: AirlockSecurityGlassLocked
components:
- pos: -35.5,55.5
parent: 30
@@ -35634,7 +35701,7 @@ entities:
parent: 30
type: Transform
- uid: 1878
- type: AirlockSecurityLocked
+ type: AirlockSecurityGlassLocked
components:
- pos: -29.5,55.5
parent: 30
@@ -36115,255 +36182,224 @@ entities:
id: Sec Cell Block
type: SurveillanceCamera
- uid: 1948
- type: ShellShotgunBeanbag
+ type: Grille
components:
- - pos: -41.63884,54.762314
+ - pos: 34.5,49.5
parent: 30
type: Transform
- - canCollide: False
- type: Physics
- uid: 1949
- type: ShellShotgunBeanbag
+ type: Grille
components:
- - pos: -41.560715,54.762314
+ - pos: 35.5,49.5
parent: 30
type: Transform
- - canCollide: False
- type: Physics
- uid: 1950
- type: ShellShotgunBeanbag
+ type: WeaponPistolMk58
components:
- - pos: -41.466965,54.762314
+ - pos: -37.608337,53.444714
parent: 30
type: Transform
- canCollide: False
type: Physics
- uid: 1951
- type: ShellShotgunBeanbag
+ type: WeaponPistolMk58
components:
- - pos: -41.38884,54.762314
+ - pos: -37.467712,53.382214
parent: 30
type: Transform
- canCollide: False
type: Physics
- uid: 1952
- type: ShellShotgunBeanbag
+ type: WeaponPistolMk58
components:
- - pos: -41.310715,54.762314
+ - pos: -37.295837,53.319714
parent: 30
type: Transform
- canCollide: False
type: Physics
- uid: 1953
- type: ShellShotgunBeanbag
+ type: BoxShotgunIncendiary
components:
- - pos: -41.279465,54.74669
+ - pos: -41.476646,54.61659
parent: 30
type: Transform
- canCollide: False
type: Physics
+ - containers:
+ storagebase: !type:Container
+ ents: []
+ type: ContainerContainer
- uid: 1954
- type: ShellShotgunBeanbag
+ type: MagazinePistol
components:
- - pos: -41.716965,54.74669
+ - pos: -37.514587,53.632214
parent: 30
type: Transform
+ - unspawnedCount: 10
+ type: BallisticAmmoProvider
- canCollide: False
type: Physics
- uid: 1955
- type: ShellShotgunBeanbag
+ type: MagazinePistol
components:
- - pos: -41.57634,54.74669
+ - pos: -37.295837,53.61659
parent: 30
type: Transform
+ - unspawnedCount: 10
+ type: BallisticAmmoProvider
- canCollide: False
type: Physics
- uid: 1956
- type: ShellShotgunBeanbag
+ type: BoxBeanbag
components:
- - pos: -41.435715,54.74669
+ - pos: -41.476646,54.757214
parent: 30
type: Transform
- canCollide: False
type: Physics
+ - containers:
+ storagebase: !type:Container
+ ents: []
+ type: ContainerContainer
- uid: 1957
- type: ShellShotgunBeanbag
+ type: Grille
components:
- - pos: -41.529465,54.77794
+ - pos: 36.5,49.5
parent: 30
type: Transform
- - canCollide: False
- type: Physics
- uid: 1958
- type: ShellShotgunFlash
+ type: MagazinePistol
components:
- - pos: -41.76384,54.52794
+ - pos: -37.702087,53.632214
parent: 30
type: Transform
+ - unspawnedCount: 10
+ type: BallisticAmmoProvider
- canCollide: False
type: Physics
- uid: 1959
- type: ShellShotgunFlash
+ type: TableWood
components:
- - pos: -41.73259,54.543564
+ - pos: 37.5,37.5
parent: 30
type: Transform
- - canCollide: False
- type: Physics
- uid: 1960
- type: ShellShotgunFlash
+ type: Chair
components:
- - pos: -41.67009,54.52794
+ - pos: 43.5,41.5
parent: 30
type: Transform
- - canCollide: False
- type: Physics
- uid: 1961
- type: ShellShotgunFlash
+ type: TableWood
components:
- - pos: -41.591965,54.52794
+ - pos: 38.5,40.5
parent: 30
type: Transform
- - canCollide: False
- type: Physics
- uid: 1962
- type: ShellShotgunFlash
+ type: TableWood
components:
- - pos: -41.51384,54.543564
+ - pos: 41.5,37.5
parent: 30
type: Transform
- - canCollide: False
- type: Physics
- uid: 1963
- type: ShellShotgunFlash
+ type: TableWood
components:
- - pos: -41.466965,54.543564
+ - pos: 41.5,38.5
parent: 30
type: Transform
- - canCollide: False
- type: Physics
- uid: 1964
- type: ShellShotgunFlash
+ type: ReinforcedWindow
components:
- - pos: -41.38884,54.543564
+ - pos: 35.5,36.5
parent: 30
type: Transform
- - canCollide: False
- type: Physics
- uid: 1965
- type: ShellShotgunFlash
+ type: Grille
components:
- - pos: -41.29509,54.52794
+ - pos: 41.5,49.5
parent: 30
type: Transform
- - canCollide: False
- type: Physics
- uid: 1966
- type: ShellShotgunFlash
+ type: TableWood
components:
- - pos: -41.435715,54.52794
+ - pos: 37.5,38.5
parent: 30
type: Transform
- - canCollide: False
- type: Physics
- uid: 1967
- type: ShellShotgunFlash
+ type: ReinforcedWindow
components:
- - pos: -41.591965,54.543564
+ - pos: 36.5,36.5
parent: 30
type: Transform
- - canCollide: False
- type: Physics
- uid: 1968
- type: ShellShotgun
+ type: Grille
components:
- - pos: -41.76384,54.324814
+ - pos: 42.5,49.5
parent: 30
type: Transform
- - canCollide: False
- type: Physics
- uid: 1969
- type: ShellShotgun
+ type: Grille
components:
- - pos: -41.67009,54.324814
+ - pos: 43.5,49.5
parent: 30
type: Transform
- - canCollide: False
- type: Physics
- uid: 1970
- type: ShellShotgun
+ type: Grille
components:
- - pos: -41.560715,54.324814
+ - pos: 44.5,49.5
parent: 30
type: Transform
- - canCollide: False
- type: Physics
- uid: 1971
- type: ShellShotgun
+ type: Grille
components:
- - pos: -41.48259,54.324814
+ - pos: 45.5,49.5
parent: 30
type: Transform
- - canCollide: False
- type: Physics
- uid: 1972
- type: ShellShotgun
+ type: Grille
components:
- - pos: -41.42009,54.324814
+ - pos: 37.5,49.5
parent: 30
type: Transform
- - canCollide: False
- type: Physics
- uid: 1973
- type: ShellShotgun
+ type: Grille
components:
- - pos: -41.341965,54.324814
+ - pos: 38.5,49.5
parent: 30
type: Transform
- - canCollide: False
- type: Physics
- uid: 1974
- type: ShellShotgun
+ type: Grille
components:
- - pos: -41.29509,54.324814
+ - pos: 39.5,49.5
parent: 30
type: Transform
- - canCollide: False
- type: Physics
- uid: 1975
- type: ShellShotgun
+ type: Grille
components:
- - pos: -41.42009,54.324814
+ - pos: 40.5,49.5
parent: 30
type: Transform
- - canCollide: False
- type: Physics
- uid: 1976
- type: ShellShotgun
+ type: Grille
components:
- - pos: -41.529465,54.324814
+ - pos: 46.5,49.5
parent: 30
type: Transform
- - canCollide: False
- type: Physics
- uid: 1977
- type: ShellShotgun
+ type: WindowReinforcedDirectional
components:
- - pos: -41.591965,54.324814
+ - rot: 3.141592653589793 rad
+ pos: 43.5,40.5
parent: 30
type: Transform
- - canCollide: False
- type: Physics
- uid: 1978
type: WeaponShotgunKammerer
components:
- - pos: -37.498955,53.30476
+ - pos: -41.42977,54.350964
parent: 30
type: Transform
- unspawnedCount: 4
type: BallisticAmmoProvider
- - canCollide: False
- type: Physics
- containers:
ballistic-ammo: !type:Container
ents: []
@@ -36371,13 +36407,11 @@ entities:
- uid: 1979
type: WeaponShotgunKammerer
components:
- - pos: -37.498955,53.42976
+ - pos: -41.42977,54.507214
parent: 30
type: Transform
- unspawnedCount: 4
type: BallisticAmmoProvider
- - canCollide: False
- type: Physics
- containers:
ballistic-ammo: !type:Container
ents: []
@@ -37441,7 +37475,7 @@ entities:
charger-slot: !type:ContainerSlot {}
type: ContainerContainer
- uid: 2119
- type: PowerCellMediumStandard
+ type: PowerCellSmall
components:
- pos: -27.504559,56.49509
parent: 30
@@ -37449,7 +37483,7 @@ entities:
- canCollide: False
type: Physics
- uid: 2120
- type: PowerCellMediumStandard
+ type: PowerCellSmall
components:
- pos: -27.504559,56.68259
parent: 30
@@ -58685,25 +58719,23 @@ entities:
- canCollide: False
type: Physics
- uid: 4883
- type: FirelockEdge
+ type: PosterContrabandDonutCorp
components:
- - pos: -29.5,56.5
+ - pos: -28.5,54.5
parent: 30
type: Transform
- - airBlocked: False
- type: Airtight
- - canCollide: False
- type: Physics
- uid: 4884
- type: FirelockEdge
+ type: FoodBoxDonut
components:
- - pos: -35.5,56.5
+ - pos: -27.495125,54.759884
parent: 30
type: Transform
- - airBlocked: False
- type: Airtight
- canCollide: False
type: Physics
+ - containers:
+ storagebase: !type:Container
+ ents: []
+ type: ContainerContainer
- uid: 4885
type: ToolboxEmergencyFilled
components:
@@ -69032,7 +69064,7 @@ entities:
parent: 30
type: Transform
- uid: 6352
- type: WallReinforced
+ type: WallSolid
components:
- pos: 32.5,43.5
parent: 30
@@ -70660,13 +70692,13 @@ entities:
parent: 30
type: Transform
- uid: 6594
- type: WallReinforced
+ type: WallSolid
components:
- pos: 32.5,41.5
parent: 30
type: Transform
- uid: 6595
- type: WallReinforced
+ type: WallSolid
components:
- pos: 32.5,40.5
parent: 30
@@ -70696,25 +70728,25 @@ entities:
parent: 30
type: Transform
- uid: 6600
- type: WallReinforced
+ type: WallSolid
components:
- pos: 29.5,44.5
parent: 30
type: Transform
- uid: 6601
- type: WallReinforced
+ type: WallSolid
components:
- pos: 30.5,44.5
parent: 30
type: Transform
- uid: 6602
- type: WallReinforced
+ type: WallSolid
components:
- pos: 31.5,44.5
parent: 30
type: Transform
- uid: 6603
- type: WallReinforced
+ type: WallSolid
components:
- pos: 32.5,44.5
parent: 30
@@ -72865,6 +72897,8 @@ entities:
pos: -33.5,-1.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 6897
type: GasPipeStraight
components:
@@ -72872,6 +72906,8 @@ entities:
pos: -33.5,-1.5
parent: 30
type: Transform
+ - color: '#FF1212FF'
+ type: AtmosPipeColor
- uid: 6898
type: GasPipeStraight
components:
@@ -72879,6 +72915,8 @@ entities:
pos: -32.5,-1.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 6899
type: filingCabinet
components:
@@ -72896,6 +72934,8 @@ entities:
pos: -28.5,-1.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 6901
type: GasPipeStraight
components:
@@ -72903,6 +72943,8 @@ entities:
pos: -29.5,-1.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 6902
type: GasPipeStraight
components:
@@ -72910,6 +72952,8 @@ entities:
pos: -31.5,-1.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 6903
type: SignMorgue
components:
@@ -72974,18 +73018,24 @@ entities:
pos: -30.5,-1.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 6910
type: GasPipeStraight
components:
- pos: -28.5,-4.5
parent: 30
type: Transform
+ - color: '#FF1212FF'
+ type: AtmosPipeColor
- uid: 6911
type: GasVentScrubber
components:
- pos: -28.5,-3.5
parent: 30
type: Transform
+ - color: '#FF1212FF'
+ type: AtmosPipeColor
- uid: 6912
type: PottedPlantRandom
components:
@@ -74987,6 +75037,8 @@ entities:
- pos: -34.5,-1.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 7209
type: ClosetL3VirologyFilled
components:
@@ -75442,6 +75494,8 @@ entities:
- pos: -28.5,-5.5
parent: 30
type: Transform
+ - color: '#FF1212FF'
+ type: AtmosPipeColor
- uid: 7275
type: WardrobeGenetics
components:
@@ -78075,6 +78129,8 @@ entities:
pos: -21.5,-21.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 7587
type: GasPassiveVent
components:
@@ -79143,33 +79199,17 @@ entities:
parent: 30
type: Transform
- uid: 7745
- type: ShuttersNormalOpen
+ type: PaintingTheGreatWave
components:
- - rot: 1.5707963267948966 rad
- pos: 10.5,-15.5
+ - pos: -27.5,38.5
parent: 30
type: Transform
- - inputs:
- Open: []
- Close: []
- Toggle:
- - port: Pressed
- uid: 21469
- type: SignalReceiver
- uid: 7746
- type: ShuttersNormalOpen
+ type: PaintingTheScream
components:
- - rot: 1.5707963267948966 rad
- pos: 10.5,-14.5
+ - pos: 0.5,34.5
parent: 30
type: Transform
- - inputs:
- Open: []
- Close: []
- Toggle:
- - port: Pressed
- uid: 21469
- type: SignalReceiver
- uid: 7747
type: ShuttersNormalOpen
components:
@@ -85296,7 +85336,7 @@ entities:
- uid: 8629
type: WallReinforced
components:
- - pos: 26.5,-23.5
+ - pos: 27.5,-23.5
parent: 30
type: Transform
- uid: 8630
@@ -85348,7 +85388,7 @@ entities:
- uid: 8637
type: WallReinforced
components:
- - pos: 27.5,-23.5
+ - pos: 26.5,-23.5
parent: 30
type: Transform
- uid: 8638
@@ -85690,7 +85730,7 @@ entities:
- fixtures: []
type: Fixtures
- uid: 8693
- type: GasPassiveVent
+ type: GasOutletInjector
components:
- rot: -1.5707963267948966 rad
pos: 25.5,-22.5
@@ -85703,7 +85743,7 @@ entities:
parent: 30
type: Transform
- uid: 8695
- type: GasPassiveVent
+ type: GasOutletInjector
components:
- rot: -1.5707963267948966 rad
pos: 25.5,-24.5
@@ -85746,35 +85786,35 @@ entities:
parent: 30
type: Transform
- uid: 8702
- type: GasPassiveVent
+ type: GasOutletInjector
components:
- rot: -1.5707963267948966 rad
pos: 25.5,-34.5
parent: 30
type: Transform
- uid: 8703
- type: GasPassiveVent
+ type: GasOutletInjector
components:
- rot: -1.5707963267948966 rad
pos: 25.5,-32.5
parent: 30
type: Transform
- uid: 8704
- type: GasPassiveVent
+ type: GasOutletInjector
components:
- rot: -1.5707963267948966 rad
pos: 25.5,-30.5
parent: 30
type: Transform
- uid: 8705
- type: GasPassiveVent
+ type: GasOutletInjector
components:
- rot: -1.5707963267948966 rad
pos: 25.5,-28.5
parent: 30
type: Transform
- uid: 8706
- type: GasPassiveVent
+ type: GasOutletInjector
components:
- rot: -1.5707963267948966 rad
pos: 25.5,-26.5
@@ -90748,11 +90788,9 @@ entities:
- uid: 9361
type: WeaponRifleLecter
components:
- - pos: -22.568516,53.59532
+ - pos: -22.570633,53.640427
parent: 30
type: Transform
- - canCollide: False
- type: Physics
- uid: 9362
type: Grille
components:
@@ -107902,6 +107940,8 @@ entities:
- pos: 35.5,-3.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 11697
type: AirlockSalvageGlassLocked
components:
@@ -107975,6 +108015,8 @@ entities:
pos: 39.5,-5.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 11705
type: AirlockSalvageGlassLocked
components:
@@ -107988,6 +108030,8 @@ entities:
pos: 37.5,-5.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 11707
type: GasPipeBend
components:
@@ -107995,12 +108039,16 @@ entities:
pos: 34.5,-3.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 11708
type: GasPipeStraight
components:
- pos: 35.5,-4.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 11709
type: GasVentPump
components:
@@ -108008,6 +108056,8 @@ entities:
pos: 39.5,-3.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 11710
type: GasPipeStraight
components:
@@ -108015,6 +108065,8 @@ entities:
pos: 37.5,-3.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 11711
type: GasPipeStraight
components:
@@ -108022,6 +108074,8 @@ entities:
pos: 38.5,-3.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 11712
type: Grille
components:
@@ -114652,6 +114706,8 @@ entities:
pos: 20.5,43.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 12583
type: GasVentScrubber
components:
@@ -115869,6 +115925,8 @@ entities:
- pos: 16.5,56.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 12746
type: ResearchAndDevelopmentServer
components:
@@ -121205,18 +121263,24 @@ entities:
- pos: 16.5,55.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 13469
type: GasVentPump
components:
- pos: 16.5,57.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 13470
type: GasVentPump
components:
- pos: 20.5,44.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 13471
type: WallSolid
components:
@@ -121434,9 +121498,9 @@ entities:
parent: 30
type: Transform
- uid: 13507
- type: WallSolid
+ type: WallReinforced
components:
- - pos: 34.5,41.5
+ - pos: 44.5,42.5
parent: 30
type: Transform
- uid: 13508
@@ -121446,9 +121510,9 @@ entities:
parent: 30
type: Transform
- uid: 13509
- type: WallSolid
+ type: WallReinforced
components:
- - pos: 34.5,42.5
+ - pos: 43.5,42.5
parent: 30
type: Transform
- uid: 13510
@@ -121500,33 +121564,33 @@ entities:
parent: 30
type: Transform
- uid: 13518
- type: WallSolid
+ type: WallReinforced
components:
- - pos: 40.5,42.5
+ - pos: 38.5,42.5
parent: 30
type: Transform
- uid: 13519
- type: WallSolid
+ type: WallReinforced
components:
- - pos: 41.5,42.5
+ - pos: 37.5,42.5
parent: 30
type: Transform
- uid: 13520
- type: WallSolid
+ type: WallReinforced
components:
- - pos: 42.5,42.5
+ - pos: 36.5,42.5
parent: 30
type: Transform
- uid: 13521
- type: WallSolid
+ type: WallReinforced
components:
- - pos: 43.5,42.5
+ - pos: 35.5,42.5
parent: 30
type: Transform
- uid: 13522
- type: WallSolid
+ type: WallReinforced
components:
- - pos: 44.5,42.5
+ - pos: 34.5,42.5
parent: 30
type: Transform
- uid: 13523
@@ -121572,33 +121636,33 @@ entities:
parent: 30
type: Transform
- uid: 13530
- type: WallSolid
+ type: WallReinforced
components:
- - pos: 36.5,42.5
+ - pos: 41.5,42.5
parent: 30
type: Transform
- uid: 13531
- type: WallSolid
+ type: WallReinforced
components:
- - pos: 37.5,42.5
+ - pos: 40.5,42.5
parent: 30
type: Transform
- uid: 13532
- type: WallSolid
+ type: WallReinforced
components:
- - pos: 38.5,42.5
+ - pos: 34.5,40.5
parent: 30
type: Transform
- uid: 13533
- type: WallSolid
+ type: WallReinforced
components:
- pos: 39.5,42.5
parent: 30
type: Transform
- uid: 13534
- type: WallSolid
+ type: WallReinforced
components:
- - pos: 35.5,42.5
+ - pos: 42.5,42.5
parent: 30
type: Transform
- uid: 13535
@@ -121674,13 +121738,13 @@ entities:
parent: 30
type: Transform
- uid: 13547
- type: WallSolid
+ type: WallReinforced
components:
- - pos: 44.5,40.5
+ - pos: 34.5,41.5
parent: 30
type: Transform
- uid: 13548
- type: WallSolid
+ type: AirlockSecurityLocked
components:
- pos: 44.5,41.5
parent: 30
@@ -121728,21 +121792,21 @@ entities:
parent: 30
type: Transform
- uid: 13556
- type: ReinforcedWindow
+ type: WallReinforced
components:
- pos: 44.5,36.5
parent: 30
type: Transform
- uid: 13557
- type: ReinforcedWindow
+ type: Grille
components:
- - pos: 44.5,34.5
+ - pos: 38.5,36.5
parent: 30
type: Transform
- uid: 13558
- type: ReinforcedWindow
+ type: Grille
components:
- - pos: 44.5,33.5
+ - pos: 44.5,35.5
parent: 30
type: Transform
- uid: 13559
@@ -121854,9 +121918,10 @@ entities:
parent: 30
type: Transform
- uid: 13577
- type: ReinforcedWindow
+ type: WindowReinforcedDirectional
components:
- - pos: 34.5,33.5
+ - rot: 1.5707963267948966 rad
+ pos: 42.5,41.5
parent: 30
type: Transform
- uid: 13578
@@ -121866,15 +121931,15 @@ entities:
parent: 30
type: Transform
- uid: 13579
- type: ReinforcedWindow
+ type: Window
components:
- - pos: 34.5,34.5
+ - pos: 44.5,35.5
parent: 30
type: Transform
- uid: 13580
- type: ReinforcedWindow
+ type: Grille
components:
- - pos: 34.5,36.5
+ - pos: 35.5,36.5
parent: 30
type: Transform
- uid: 13581
@@ -121890,13 +121955,13 @@ entities:
parent: 30
type: Transform
- uid: 13583
- type: ReinforcedWindow
+ type: TableWood
components:
- - pos: 34.5,40.5
+ - pos: 40.5,40.5
parent: 30
type: Transform
- uid: 13584
- type: WallReinforced
+ type: WallSolid
components:
- pos: 33.5,40.5
parent: 30
@@ -121950,11 +122015,13 @@ entities:
parent: 30
type: Transform
- uid: 13593
- type: WallSolid
+ type: GasVentPump
components:
- - pos: 42.5,31.5
+ - pos: 35.5,39.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 13594
type: WallSolid
components:
@@ -122456,7 +122523,7 @@ entities:
- uid: 13677
type: Grille
components:
- - pos: 34.5,36.5
+ - pos: 36.5,36.5
parent: 30
type: Transform
- uid: 13678
@@ -122466,7 +122533,7 @@ entities:
parent: 30
type: Transform
- uid: 13679
- type: Grille
+ type: WallSolid
components:
- pos: 34.5,33.5
parent: 30
@@ -122484,9 +122551,9 @@ entities:
parent: 30
type: Transform
- uid: 13682
- type: Grille
+ type: WallReinforced
components:
- - pos: 34.5,40.5
+ - pos: 44.5,40.5
parent: 30
type: Transform
- uid: 13683
@@ -122496,15 +122563,15 @@ entities:
parent: 30
type: Transform
- uid: 13684
- type: Grille
+ type: AirlockBrigGlassLocked
components:
- - pos: 44.5,34.5
+ - pos: 39.5,36.5
parent: 30
type: Transform
- uid: 13685
- type: Grille
+ type: WallReinforced
components:
- - pos: 44.5,36.5
+ - pos: 34.5,36.5
parent: 30
type: Transform
- uid: 13686
@@ -122998,15 +123065,15 @@ entities:
uid: 13729
type: SignalTransmitter
- uid: 13743
- type: AirlockGlass
+ type: Grille
components:
- - pos: 44.5,35.5
+ - pos: 37.5,36.5
parent: 30
type: Transform
- uid: 13744
- type: AirlockGlass
+ type: Grille
components:
- - pos: 44.5,38.5
+ - pos: 41.5,36.5
parent: 30
type: Transform
- uid: 13745
@@ -123016,9 +123083,9 @@ entities:
parent: 30
type: Transform
- uid: 13746
- type: AirlockGlass
+ type: Grille
components:
- - pos: 34.5,38.5
+ - pos: 40.5,36.5
parent: 30
type: Transform
- uid: 13747
@@ -123102,10 +123169,9 @@ entities:
- color: '#FF1212FF'
type: AtmosPipeColor
- uid: 13757
- type: GasPipeStraight
+ type: GasPipeTJunction
components:
- - rot: 1.5707963267948966 rad
- pos: 35.5,35.5
+ - pos: 35.5,35.5
parent: 30
type: Transform
- color: '#FF1212FF'
@@ -123174,9 +123240,9 @@ entities:
- color: '#FF1212FF'
type: AtmosPipeColor
- uid: 13765
- type: GasPipeStraight
+ type: GasPipeTJunction
components:
- - rot: 1.5707963267948966 rad
+ - rot: 3.141592653589793 rad
pos: 43.5,35.5
parent: 30
type: Transform
@@ -123237,9 +123303,9 @@ entities:
- color: '#0335FCFF'
type: AtmosPipeColor
- uid: 13772
- type: GasPipeStraight
+ type: GasPipeTJunction
components:
- - rot: 1.5707963267948966 rad
+ - rot: 3.141592653589793 rad
pos: 35.5,38.5
parent: 30
type: Transform
@@ -123273,10 +123339,9 @@ entities:
- color: '#0335FCFF'
type: AtmosPipeColor
- uid: 13776
- type: GasPipeStraight
+ type: GasPipeTJunction
components:
- - rot: 1.5707963267948966 rad
- pos: 39.5,38.5
+ - pos: 39.5,38.5
parent: 30
type: Transform
- color: '#0335FCFF'
@@ -124992,13 +125057,14 @@ entities:
ents: []
type: ContainerContainer
- uid: 13939
- type: DisposalPipe
+ type: DisposalJunctionFlipped
components:
- - pos: -2.5,-28.5
+ - rot: 3.141592653589793 rad
+ pos: -2.5,-28.5
parent: 30
type: Transform
- containers:
- DisposalTransit: !type:Container
+ DisposalJunction: !type:Container
ents: []
type: ContainerContainer
- uid: 13940
@@ -134140,12 +134206,16 @@ entities:
- pos: 16.5,45.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 14975
type: GasPipeStraight
components:
- pos: 16.5,47.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 14976
type: WoodDoor
components:
@@ -134158,6 +134228,8 @@ entities:
- pos: 16.5,44.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 14978
type: GasPipeBend
components:
@@ -134165,6 +134237,8 @@ entities:
pos: 16.5,43.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 14979
type: StoolBar
components:
@@ -134179,6 +134253,8 @@ entities:
pos: 19.5,43.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 14981
type: GasPipeStraight
components:
@@ -134186,6 +134262,8 @@ entities:
pos: 18.5,43.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 14982
type: UprightPianoInstrument
components:
@@ -134235,6 +134313,8 @@ entities:
- pos: 16.5,52.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 14989
type: CableApcExtension
components:
@@ -134247,6 +134327,8 @@ entities:
- pos: 16.5,53.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 14991
type: StoolBar
components:
@@ -134443,6 +134525,8 @@ entities:
- pos: 16.5,49.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 15019
type: Rack
components:
@@ -134629,6 +134713,8 @@ entities:
- pos: 16.5,51.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 15050
type: StoolBar
components:
@@ -134655,18 +134741,24 @@ entities:
- pos: 16.5,50.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 15054
type: GasPipeStraight
components:
- pos: 16.5,46.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 15055
type: GasPipeStraight
components:
- pos: 16.5,54.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 15056
type: Catwalk
components:
@@ -134703,6 +134795,8 @@ entities:
- pos: 16.5,48.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 15062
type: Table
components:
@@ -141653,6 +141747,8 @@ entities:
pos: 36.5,-3.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 16095
type: CableApcExtension
components:
@@ -141982,6 +142078,8 @@ entities:
pos: 38.5,-5.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 16126
type: GasPipeStraight
components:
@@ -141989,12 +142087,16 @@ entities:
pos: 36.5,-5.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 16127
type: GasPipeBend
components:
- pos: 34.5,-2.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 16128
type: GasPipeBend
components:
@@ -142002,6 +142104,8 @@ entities:
pos: 35.5,-5.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 16129
type: WarpPoint
components:
@@ -142536,19 +142640,11 @@ entities:
Toggle: []
type: SignalReceiver
- uid: 16199
- type: Poweredlight
+ type: AirlockMaintLocked
components:
- - rot: 3.141592653589793 rad
- pos: 42.5,32.5
+ - pos: 42.5,31.5
parent: 30
type: Transform
- - powerLoad: 0
- type: ApcPowerReceiver
- - inputs:
- On: []
- Off: []
- Toggle: []
- type: SignalReceiver
- uid: 16200
type: Poweredlight
components:
@@ -146256,6 +146352,8 @@ entities:
pos: 17.5,43.5
parent: 30
type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
- uid: 16784
type: WallReinforced
components:
@@ -175108,45 +175206,29 @@ entities:
- canCollide: False
type: Physics
- uid: 20962
- type: FirelockGlass
+ type: AirlockGlass
components:
- - pos: 44.5,35.5
+ - pos: 44.5,34.5
parent: 30
type: Transform
- - airBlocked: False
- type: Airtight
- - canCollide: False
- type: Physics
- uid: 20963
- type: FirelockGlass
- components:
- - pos: 44.5,38.5
- parent: 30
- type: Transform
- - airBlocked: False
- type: Airtight
- - canCollide: False
- type: Physics
-- uid: 20964
- type: FirelockGlass
- components:
- - pos: 34.5,35.5
- parent: 30
- type: Transform
- - airBlocked: False
- type: Airtight
- - canCollide: False
- type: Physics
-- uid: 20965
- type: FirelockGlass
+ type: AirlockBrigGlassLocked
components:
- pos: 34.5,38.5
parent: 30
type: Transform
- - airBlocked: False
- type: Airtight
- - canCollide: False
- type: Physics
+- uid: 20964
+ type: Window
+ components:
+ - pos: 44.5,33.5
+ parent: 30
+ type: Transform
+- uid: 20965
+ type: AirlockBrigGlassLocked
+ components:
+ - pos: 44.5,38.5
+ parent: 30
+ type: Transform
- uid: 20966
type: Table
components:
@@ -177730,6 +177812,9 @@ entities:
type: Transform
- canCollide: False
type: Physics
+ - containers:
+ cell_slot: !type:ContainerSlot {}
+ type: ContainerContainer
- uid: 21279
type: SurveillanceCameraEngineering
components:
@@ -179209,14 +179294,6 @@ entities:
uid: 7740
- port: Toggle
uid: 7747
- - port: Toggle
- uid: 7746
- - port: Toggle
- uid: 7745
- - port: Toggle
- uid: 1016
- - port: Toggle
- uid: 356
type: SignalTransmitter
- uid: 21470
type: AirlockGlass
@@ -179225,27 +179302,27 @@ entities:
parent: 30
type: Transform
- uid: 21471
- type: ReinforcedWindow
+ type: Window
components:
- - pos: 7.5,-17.5
+ - pos: 10.5,-14.5
parent: 30
type: Transform
- uid: 21472
- type: ReinforcedWindow
- components:
- - pos: 9.5,-17.5
- parent: 30
- type: Transform
-- uid: 21473
- type: ReinforcedWindow
+ type: Window
components:
- pos: 10.5,-15.5
parent: 30
type: Transform
-- uid: 21474
- type: ReinforcedWindow
+- uid: 21473
+ type: Window
components:
- - pos: 10.5,-14.5
+ - pos: 9.5,-17.5
+ parent: 30
+ type: Transform
+- uid: 21474
+ type: Window
+ components:
+ - pos: 7.5,-17.5
parent: 30
type: Transform
- uid: 21475
@@ -179378,4 +179455,611 @@ entities:
- pos: -32.5,23.5
parent: 30
type: Transform
+- uid: 21495
+ type: CableApcExtension
+ components:
+ - pos: -18.5,-4.5
+ parent: 30
+ type: Transform
+- uid: 21496
+ type: CableApcExtension
+ components:
+ - pos: -18.5,-3.5
+ parent: 30
+ type: Transform
+- uid: 21497
+ type: CableApcExtension
+ components:
+ - pos: -18.5,-2.5
+ parent: 30
+ type: Transform
+- uid: 21498
+ type: CableApcExtension
+ components:
+ - pos: -18.5,-1.5
+ parent: 30
+ type: Transform
+- uid: 21499
+ type: SpawnPointPsychologist
+ components:
+ - pos: -28.5,-2.5
+ parent: 30
+ type: Transform
+- uid: 21500
+ type: Chair
+ components:
+ - rot: -1.5707963267948966 rad
+ pos: -33.5,-2.5
+ parent: 30
+ type: Transform
+- uid: 21501
+ type: PosterLegitSoftCapPopArt
+ components:
+ - pos: -32.5,-2.5
+ parent: 30
+ type: Transform
+- uid: 21502
+ type: MorgueTray
+ components:
+ - rot: -1.5707963267948966 rad
+ pos: 0,-1
+ parent: 6908
+ type: Transform
+- uid: 21503
+ type: MorgueTray
+ components:
+ - rot: -1.5707963267948966 rad
+ pos: 0,-1
+ parent: 6907
+ type: Transform
+- uid: 21504
+ type: MorgueTray
+ components:
+ - rot: -1.5707963267948966 rad
+ pos: 0,-1
+ parent: 6906
+ type: Transform
+- uid: 21505
+ type: MorgueTray
+ components:
+ - rot: -1.5707963267948966 rad
+ pos: 0,-1
+ parent: 6877
+ type: Transform
+- uid: 21506
+ type: PaintingCafeTerraceAtNight
+ components:
+ - pos: -17.5,33.5
+ parent: 30
+ type: Transform
+- uid: 21507
+ type: FoodBoxDonut
+ components:
+ - pos: -27.4795,54.68176
+ parent: 30
+ type: Transform
+ - canCollide: False
+ type: Physics
+ - containers:
+ storagebase: !type:Container
+ ents: []
+ type: ContainerContainer
+- uid: 21508
+ type: FoodBoxDonut
+ components:
+ - pos: -27.4795,54.603634
+ parent: 30
+ type: Transform
+ - canCollide: False
+ type: Physics
+ - containers:
+ storagebase: !type:Container
+ ents: []
+ type: ContainerContainer
+- uid: 21509
+ type: ReinforcedWindow
+ components:
+ - pos: 37.5,36.5
+ parent: 30
+ type: Transform
+- uid: 21510
+ type: ReinforcedWindow
+ components:
+ - pos: 38.5,36.5
+ parent: 30
+ type: Transform
+- uid: 21511
+ type: Window
+ components:
+ - pos: 34.5,34.5
+ parent: 30
+ type: Transform
+- uid: 21512
+ type: ReinforcedWindow
+ components:
+ - pos: 40.5,36.5
+ parent: 30
+ type: Transform
+- uid: 21513
+ type: ReinforcedWindow
+ components:
+ - pos: 41.5,36.5
+ parent: 30
+ type: Transform
+- uid: 21514
+ type: ReinforcedWindow
+ components:
+ - pos: 42.5,36.5
+ parent: 30
+ type: Transform
+- uid: 21515
+ type: ReinforcedWindow
+ components:
+ - pos: 43.5,36.5
+ parent: 30
+ type: Transform
+- uid: 21516
+ type: Grille
+ components:
+ - pos: 42.5,36.5
+ parent: 30
+ type: Transform
+- uid: 21517
+ type: Grille
+ components:
+ - pos: 43.5,36.5
+ parent: 30
+ type: Transform
+- uid: 21518
+ type: ChairWood
+ components:
+ - rot: -1.5707963267948966 rad
+ pos: 42.5,37.5
+ parent: 30
+ type: Transform
+- uid: 21519
+ type: ChairWood
+ components:
+ - rot: -1.5707963267948966 rad
+ pos: 42.5,38.5
+ parent: 30
+ type: Transform
+- uid: 21520
+ type: ChairWood
+ components:
+ - rot: 1.5707963267948966 rad
+ pos: 36.5,37.5
+ parent: 30
+ type: Transform
+- uid: 21521
+ type: ChairWood
+ components:
+ - rot: 1.5707963267948966 rad
+ pos: 36.5,38.5
+ parent: 30
+ type: Transform
+- uid: 21522
+ type: ComfyChair
+ components:
+ - pos: 39.5,41.5
+ parent: 30
+ type: Transform
+- uid: 21523
+ type: ClosetLegalFilled
+ components:
+ - pos: 35.5,41.5
+ parent: 30
+ type: Transform
+- uid: 21524
+ type: Chair
+ components:
+ - pos: 36.5,41.5
+ parent: 30
+ type: Transform
+- uid: 21525
+ type: Carpet
+ components:
+ - pos: 36.5,37.5
+ parent: 30
+ type: Transform
+- uid: 21526
+ type: Carpet
+ components:
+ - pos: 36.5,38.5
+ parent: 30
+ type: Transform
+- uid: 21527
+ type: Carpet
+ components:
+ - pos: 37.5,37.5
+ parent: 30
+ type: Transform
+- uid: 21528
+ type: Carpet
+ components:
+ - pos: 37.5,38.5
+ parent: 30
+ type: Transform
+- uid: 21529
+ type: Carpet
+ components:
+ - pos: 38.5,37.5
+ parent: 30
+ type: Transform
+- uid: 21530
+ type: Carpet
+ components:
+ - pos: 38.5,38.5
+ parent: 30
+ type: Transform
+- uid: 21531
+ type: CarpetBlack
+ components:
+ - pos: 40.5,40.5
+ parent: 30
+ type: Transform
+- uid: 21532
+ type: CarpetBlack
+ components:
+ - pos: 39.5,41.5
+ parent: 30
+ type: Transform
+- uid: 21533
+ type: CarpetBlack
+ components:
+ - pos: 39.5,40.5
+ parent: 30
+ type: Transform
+- uid: 21534
+ type: CarpetBlack
+ components:
+ - pos: 38.5,41.5
+ parent: 30
+ type: Transform
+- uid: 21535
+ type: CarpetBlue
+ components:
+ - pos: 42.5,38.5
+ parent: 30
+ type: Transform
+- uid: 21536
+ type: CarpetBlack
+ components:
+ - pos: 38.5,40.5
+ parent: 30
+ type: Transform
+- uid: 21537
+ type: CarpetBlue
+ components:
+ - pos: 40.5,38.5
+ parent: 30
+ type: Transform
+- uid: 21538
+ type: CarpetBlue
+ components:
+ - pos: 41.5,37.5
+ parent: 30
+ type: Transform
+- uid: 21539
+ type: CarpetBlue
+ components:
+ - pos: 40.5,37.5
+ parent: 30
+ type: Transform
+- uid: 21540
+ type: CarpetBlue
+ components:
+ - pos: 41.5,38.5
+ parent: 30
+ type: Transform
+- uid: 21541
+ type: BoxFolderBlue
+ components:
+ - pos: 41.545937,38.59172
+ parent: 30
+ type: Transform
+ - containers:
+ storagebase: !type:Container
+ ents: []
+ type: ContainerContainer
+- uid: 21542
+ type: CarpetBlue
+ components:
+ - pos: 42.5,37.5
+ parent: 30
+ type: Transform
+- uid: 21543
+ type: BoxFolderRed
+ components:
+ - pos: 37.54579,38.509315
+ parent: 30
+ type: Transform
+ - canCollide: False
+ type: Physics
+ - containers:
+ storagebase: !type:Container
+ ents: []
+ type: ContainerContainer
+- uid: 21544
+ type: CarpetBlack
+ components:
+ - pos: 40.5,41.5
+ parent: 30
+ type: Transform
+- uid: 21545
+ type: GasVentScrubber
+ components:
+ - rot: 3.141592653589793 rad
+ pos: 35.5,34.5
+ parent: 30
+ type: Transform
+ - color: '#FF1212FF'
+ type: AtmosPipeColor
+- uid: 21546
+ type: GasPipeStraight
+ components:
+ - pos: 39.5,37.5
+ parent: 30
+ type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
+- uid: 21547
+ type: GasPipeStraight
+ components:
+ - pos: 39.5,36.5
+ parent: 30
+ type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
+- uid: 21548
+ type: GasPipeStraight
+ components:
+ - pos: 39.5,35.5
+ parent: 30
+ type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
+- uid: 21549
+ type: GasVentPump
+ components:
+ - rot: 3.141592653589793 rad
+ pos: 39.5,34.5
+ parent: 30
+ type: Transform
+ - color: '#0335FCFF'
+ type: AtmosPipeColor
+- uid: 21550
+ type: GasPipeStraight
+ components:
+ - rot: 3.141592653589793 rad
+ pos: 43.5,36.5
+ parent: 30
+ type: Transform
+ - color: '#FF1212FF'
+ type: AtmosPipeColor
+- uid: 21551
+ type: GasPipeStraight
+ components:
+ - rot: 3.141592653589793 rad
+ pos: 43.5,37.5
+ parent: 30
+ type: Transform
+ - color: '#FF1212FF'
+ type: AtmosPipeColor
+- uid: 21552
+ type: GasPipeStraight
+ components:
+ - rot: 3.141592653589793 rad
+ pos: 43.5,38.5
+ parent: 30
+ type: Transform
+ - color: '#FF1212FF'
+ type: AtmosPipeColor
+- uid: 21553
+ type: GasVentScrubber
+ components:
+ - pos: 43.5,39.5
+ parent: 30
+ type: Transform
+ - color: '#FF1212FF'
+ type: AtmosPipeColor
+- uid: 21554
+ type: PosterLegitCohibaRobustoAd
+ components:
+ - pos: 44.5,32.5
+ parent: 30
+ type: Transform
+- uid: 21555
+ type: VendingMachineCoffee
+ components:
+ - name: Hot drinks machine
+ type: MetaData
+ - pos: 35.5,32.5
+ parent: 30
+ type: Transform
+- uid: 21556
+ type: VendingMachineCigs
+ components:
+ - name: cigarette machine
+ type: MetaData
+ - pos: 43.5,32.5
+ parent: 30
+ type: Transform
+- uid: 21557
+ type: Chair
+ components:
+ - rot: 3.141592653589793 rad
+ pos: 36.5,35.5
+ parent: 30
+ type: Transform
+- uid: 21558
+ type: Chair
+ components:
+ - rot: 3.141592653589793 rad
+ pos: 36.5,34.5
+ parent: 30
+ type: Transform
+- uid: 21559
+ type: Chair
+ components:
+ - rot: 3.141592653589793 rad
+ pos: 37.5,35.5
+ parent: 30
+ type: Transform
+- uid: 21560
+ type: Chair
+ components:
+ - rot: 3.141592653589793 rad
+ pos: 37.5,34.5
+ parent: 30
+ type: Transform
+- uid: 21561
+ type: Chair
+ components:
+ - rot: 3.141592653589793 rad
+ pos: 38.5,35.5
+ parent: 30
+ type: Transform
+- uid: 21562
+ type: Chair
+ components:
+ - rot: 3.141592653589793 rad
+ pos: 38.5,34.5
+ parent: 30
+ type: Transform
+- uid: 21563
+ type: Chair
+ components:
+ - rot: 3.141592653589793 rad
+ pos: 40.5,35.5
+ parent: 30
+ type: Transform
+- uid: 21564
+ type: Chair
+ components:
+ - rot: 3.141592653589793 rad
+ pos: 40.5,34.5
+ parent: 30
+ type: Transform
+- uid: 21565
+ type: Chair
+ components:
+ - rot: 3.141592653589793 rad
+ pos: 41.5,35.5
+ parent: 30
+ type: Transform
+- uid: 21566
+ type: Chair
+ components:
+ - rot: 3.141592653589793 rad
+ pos: 41.5,34.5
+ parent: 30
+ type: Transform
+- uid: 21567
+ type: Chair
+ components:
+ - rot: 3.141592653589793 rad
+ pos: 42.5,35.5
+ parent: 30
+ type: Transform
+- uid: 21568
+ type: Chair
+ components:
+ - rot: 3.141592653589793 rad
+ pos: 42.5,34.5
+ parent: 30
+ type: Transform
+- uid: 21569
+ type: Chair
+ components:
+ - rot: 3.141592653589793 rad
+ pos: 37.5,33.5
+ parent: 30
+ type: Transform
+- uid: 21570
+ type: Chair
+ components:
+ - rot: 3.141592653589793 rad
+ pos: 38.5,33.5
+ parent: 30
+ type: Transform
+- uid: 21571
+ type: PosterLegitNanotrasenLogo
+ components:
+ - pos: 34.5,36.5
+ parent: 30
+ type: Transform
+- uid: 21572
+ type: PosterLegitNanotrasenLogo
+ components:
+ - pos: 44.5,36.5
+ parent: 30
+ type: Transform
+- uid: 21573
+ type: Chair
+ components:
+ - rot: 3.141592653589793 rad
+ pos: 40.5,33.5
+ parent: 30
+ type: Transform
+- uid: 21574
+ type: Chair
+ components:
+ - rot: 3.141592653589793 rad
+ pos: 41.5,33.5
+ parent: 30
+ type: Transform
+- uid: 21575
+ type: PottedPlantRandom
+ components:
+ - pos: 43.5,35.5
+ parent: 30
+ type: Transform
+ - containers:
+ stash: !type:ContainerSlot {}
+ type: ContainerContainer
+- uid: 21576
+ type: PottedPlantRandom
+ components:
+ - pos: 35.5,37.5
+ parent: 30
+ type: Transform
+ - containers:
+ stash: !type:ContainerSlot {}
+ type: ContainerContainer
+- uid: 21577
+ type: filingCabinet
+ components:
+ - pos: 43.5,37.5
+ parent: 30
+ type: Transform
+ - containers:
+ storagebase: !type:Container
+ ents: []
+ type: ContainerContainer
+- uid: 21578
+ type: Chair
+ components:
+ - pos: 46.5,37.5
+ parent: 30
+ type: Transform
+- uid: 21579
+ type: Chair
+ components:
+ - rot: 3.141592653589793 rad
+ pos: 46.5,35.5
+ parent: 30
+ type: Transform
+- uid: 21580
+ type: Table
+ components:
+ - pos: 46.5,36.5
+ parent: 30
+ type: Transform
+- uid: 21581
+ type: MaintenanceWeaponSpawner
+ components:
+ - pos: 31.5,27.5
+ parent: 30
+ type: Transform
...
diff --git a/Resources/Maps/nss_pillar.yml b/Resources/Maps/nss_pillar.yml
index e4d1d6bd99..f0ae08b09e 100644
--- a/Resources/Maps/nss_pillar.yml
+++ b/Resources/Maps/nss_pillar.yml
@@ -53389,7 +53389,7 @@ entities:
parent: 130
type: Transform
- uid: 4846
- type: PowerCellLargeStandard
+ type: PowerCellSmall
components:
- pos: 29.227386,-9.561591
parent: 130
@@ -90644,7 +90644,7 @@ entities:
parent: 130
type: Transform
- uid: 9699
- type: PowerCellMediumPotato
+ type: PowerCellPotato
components:
- pos: 34.5,-20.500025
parent: 130
@@ -93243,7 +93243,7 @@ entities:
charger-slot: !type:ContainerSlot {}
type: ContainerContainer
- uid: 9947
- type: PowerCellLargeHigh
+ type: PowerCellMedium
components:
- pos: 29.548517,-9.58406
parent: 130
@@ -95478,7 +95478,7 @@ entities:
parent: 130
type: Transform
- uid: 10276
- type: PowerCellLargeStandard
+ type: PowerCellSmall
components:
- pos: -40.50005,-16.500025
parent: 130
diff --git a/Resources/Maps/packedstation.yml b/Resources/Maps/packedstation.yml
index d4aef9b16a..4950333d92 100644
--- a/Resources/Maps/packedstation.yml
+++ b/Resources/Maps/packedstation.yml
@@ -28487,7 +28487,7 @@ entities:
- canCollide: False
type: Physics
- uid: 2075
- type: PowerCellMediumStandard
+ type: PowerCellSmall
components:
- pos: 9.531351,32.51714
parent: 2
@@ -50161,7 +50161,7 @@ entities:
charger-slot: !type:ContainerSlot {}
type: ContainerContainer
- uid: 5313
- type: PowerCellLargeStandard
+ type: PowerCellSmall
components:
- pos: 56.529827,20.631775
parent: 2
@@ -50725,7 +50725,7 @@ entities:
ents: []
type: ContainerContainer
- uid: 5382
- type: PowerCellLargeStandard
+ type: PowerCellSmall
components:
- pos: 50.725174,11.548619
parent: 2
@@ -94093,7 +94093,7 @@ entities:
parent: 2
type: Transform
- uid: 11070
- type: PowerCellMediumStandard
+ type: PowerCellSmall
components:
- parent: 9191
type: Transform
@@ -94878,7 +94878,7 @@ entities:
parent: 2
type: Transform
- uid: 11166
- type: PowerCellMediumStandard
+ type: PowerCellSmall
components:
- parent: 11154
type: Transform
diff --git a/Resources/Maps/packedstationxmas.yml b/Resources/Maps/packedstationxmas.yml
index 7baf96d964..4e33216d3c 100644
--- a/Resources/Maps/packedstationxmas.yml
+++ b/Resources/Maps/packedstationxmas.yml
@@ -22187,7 +22187,7 @@ entities:
- canCollide: False
type: Physics
- uid: 2097
- type: PowerCellMediumStandard
+ type: PowerCellSmall
components:
- pos: 9.531351,32.51714
parent: 0
@@ -43826,7 +43826,7 @@ entities:
charger-slot: !type:ContainerSlot {}
type: ContainerContainer
- uid: 5336
- type: PowerCellLargeStandard
+ type: PowerCellSmall
components:
- pos: 56.529827,20.631775
parent: 0
@@ -44390,7 +44390,7 @@ entities:
ents: []
type: ContainerContainer
- uid: 5405
- type: PowerCellLargeStandard
+ type: PowerCellSmall
components:
- pos: 50.725174,11.548619
parent: 0
@@ -87726,7 +87726,7 @@ entities:
- canCollide: False
type: Physics
- uid: 11108
- type: PowerCellMediumStandard
+ type: PowerCellSmall
components:
- parent: 9229
type: Transform
@@ -88505,7 +88505,7 @@ entities:
- canCollide: False
type: Physics
- uid: 11204
- type: PowerCellMediumStandard
+ type: PowerCellSmall
components:
- parent: 11192
type: Transform
diff --git a/Resources/Maps/saltern.yml b/Resources/Maps/saltern.yml
index 9863285fc1..a26c766d64 100644
--- a/Resources/Maps/saltern.yml
+++ b/Resources/Maps/saltern.yml
@@ -17902,7 +17902,7 @@ entities:
parent: 852
type: Transform
- uid: 1130
- type: PowerCellSmallStandard
+ type: PowerCellSmall
components:
- parent: 1549
type: Transform
diff --git a/Resources/Maps/splitstation.yml b/Resources/Maps/splitstation.yml
index acf1e8ff3b..d5a37fef70 100644
--- a/Resources/Maps/splitstation.yml
+++ b/Resources/Maps/splitstation.yml
@@ -105162,7 +105162,7 @@ entities:
- canCollide: False
type: Physics
- uid: 11187
- type: PowerCellLargeStandard
+ type: PowerCellSmall
components:
- pos: 14.5,-105.5
parent: 69
diff --git a/Resources/Maps/ssreach.yml b/Resources/Maps/ssreach.yml
index beb3d37953..6cd8fad41b 100644
--- a/Resources/Maps/ssreach.yml
+++ b/Resources/Maps/ssreach.yml
@@ -4210,7 +4210,7 @@ entities:
- canCollide: False
type: Physics
- uid: 153
- type: PowerCellSmallStandard
+ type: PowerCellSmall
components:
- parent: 152
type: Transform
@@ -4225,7 +4225,7 @@ entities:
- canCollide: False
type: Physics
- uid: 155
- type: PowerCellSmallStandard
+ type: PowerCellSmall
components:
- parent: 154
type: Transform
diff --git a/Resources/Maps/waystation.yml b/Resources/Maps/waystation.yml
index 8ceb89fda6..ad841c741d 100644
--- a/Resources/Maps/waystation.yml
+++ b/Resources/Maps/waystation.yml
@@ -35234,7 +35234,7 @@ entities:
- canCollide: False
type: Physics
- uid: 2452
- type: PowerCellLargeStandard
+ type: PowerCellSmall
components:
- pos: 8.459046,45.525425
parent: 82
@@ -45505,7 +45505,7 @@ entities:
- canCollide: False
type: Physics
- uid: 3700
- type: PowerCellLargeStandard
+ type: PowerCellSmall
components:
- pos: 44.656002,21.563784
parent: 82
@@ -56560,7 +56560,7 @@ entities:
parent: 82
type: Transform
- uid: 4967
- type: PowerCellMediumPotato
+ type: PowerCellPotato
components:
- pos: 32.49642,-0.21778393
parent: 82
diff --git a/Resources/Prototypes/Atmospherics/gases.yml b/Resources/Prototypes/Atmospherics/gases.yml
index 2ff48cede3..bb2bbe5675 100644
--- a/Resources/Prototypes/Atmospherics/gases.yml
+++ b/Resources/Prototypes/Atmospherics/gases.yml
@@ -57,3 +57,14 @@
gasOverlayState: water_vapor
color: bffffd
reagent: Water
+
+- type: gas
+ id: 6
+ name: Miasma
+ specificHeat: 20
+ heatCapacityRatio: 1.4
+ molarMass: 44
+ gasOverlaySprite: /Textures/Effects/atmospherics.rsi
+ gasOverlayState: miasma
+ color: 56941E
+ reagent: Miasma
\ No newline at end of file
diff --git a/Resources/Prototypes/Catalog/Cargo/cargo_service.yml b/Resources/Prototypes/Catalog/Cargo/cargo_service.yml
index 9235bd1692..d1f4a0932b 100644
--- a/Resources/Prototypes/Catalog/Cargo/cargo_service.yml
+++ b/Resources/Prototypes/Catalog/Cargo/cargo_service.yml
@@ -28,7 +28,7 @@
description: "Mousetraps, for when all of service is being haunted by an entire horde of rats. Use sparingly... or not."
icon:
sprite: Objects/Devices/mousetrap.rsi
- state: normal
+ state: mousetrap
product: CrateMousetrapBoxes
cost: 1000
category: Service
diff --git a/Resources/Prototypes/Catalog/Fills/Crates/engineering.yml b/Resources/Prototypes/Catalog/Fills/Crates/engineering.yml
index 1341c0c4ee..308a110b67 100644
--- a/Resources/Prototypes/Catalog/Fills/Crates/engineering.yml
+++ b/Resources/Prototypes/Catalog/Fills/Crates/engineering.yml
@@ -37,11 +37,7 @@
# components:
# - type: StorageFill
# contents:
-# - id: PowerCellLargeStandard
-# amount: 3
-# - id: PowerCellMediumStandard
-# amount: 3
-# - id: PowerCellSmallAutorecharge
+# - id: PowerCellMicroreactor
# amount: 3
- type: entity
diff --git a/Resources/Prototypes/Catalog/Fills/Crates/salvage.yml b/Resources/Prototypes/Catalog/Fills/Crates/salvage.yml
index 66246f2773..2620ab2380 100644
--- a/Resources/Prototypes/Catalog/Fills/Crates/salvage.yml
+++ b/Resources/Prototypes/Catalog/Fills/Crates/salvage.yml
@@ -63,9 +63,6 @@
# Interesting (1%)
# - Ammo
- id: MagazineBoxMagnum
- prob: 0.01
- # - #shinies
- - id: PowerCellLargeHyper
prob: 0.01
# Just no (0.1%)
# - Working guns
diff --git a/Resources/Prototypes/Catalog/Research/technologies.yml b/Resources/Prototypes/Catalog/Research/technologies.yml
index 06e6806b68..8b9472462d 100644
--- a/Resources/Prototypes/Catalog/Research/technologies.yml
+++ b/Resources/Prototypes/Catalog/Research/technologies.yml
@@ -400,45 +400,39 @@
id: PowerCellBasic
description: Print standard powercells.
icon:
- sprite: Objects/Power/PowerCells/power_cell_small_st.rsi
- state: s_st
+ sprite: Objects/Power/power_cells.rsi
+ state: small
requiredPoints: 2500
requiredTechnologies:
- ElectromagneticTheory
unlockedRecipes:
- - PowerCellSmallStandard
- - PowerCellMediumStandard
- - PowerCellLargeStandard
+ - PowerCellSmall
- type: technology
name: "advanced powercell printing"
id: PowerCellAdvanced
description: Print advanced powercells.
icon:
- sprite: Objects/Power/PowerCells/power_cell_small_hi.rsi
- state: s_hi
+ sprite: Objects/Power/power_cells.rsi
+ state: medium
requiredPoints: 5000
requiredTechnologies:
- PowerCellBasic
unlockedRecipes:
- - PowerCellSmallHigh
- - PowerCellMediumHigh
- - PowerCellLargeHigh
+ - PowerCellMedium
- type: technology
name: "super powercell printing"
id: PowerCellSuper
description: Print super powercells.
icon:
- sprite: Objects/Power/PowerCells/power_cell_small_sup.rsi
- state: s_sup
+ sprite: Objects/Power/power_cells.rsi
+ state: high
requiredPoints: 10000
requiredTechnologies:
- PowerCellAdvanced
unlockedRecipes:
- - PowerCellSmallSuper
- - PowerCellMediumSuper
- - PowerCellLargeSuper
+ - PowerCellHigh
# Basic Parts Technology Tree
- type: technology
diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/coffee.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/coffee.yml
index df016aaa54..4542fb8f7d 100644
--- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/coffee.yml
+++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/coffee.yml
@@ -4,5 +4,5 @@
animationDuration: 3.4
spriteName: coffee
startingInventory:
- DrinkHotCoffee: 20
- DrinkTeaGlass: 20
+ DrinkHotCoffee: 10
+ DrinkTeaGlass: 10
diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/engivend.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/engivend.yml
index 4c38fd4de7..b35681f854 100644
--- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/engivend.yml
+++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/engivend.yml
@@ -6,7 +6,7 @@
startingInventory:
ClothingEyesGlassesMeson: 4
Multitool: 4
- PowerCellSmallHigh: 5
+ PowerCellMedium: 5
ClothingHandsGlovesColorYellow: 6
InflatableWallStack1: 24
InflatableDoorStack1: 8
diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/nutri.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/nutri.yml
index 3f9d6348cc..10e5ded1be 100644
--- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/nutri.yml
+++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/nutri.yml
@@ -3,7 +3,11 @@
name: NutriMax
spriteName: nutri
startingInventory:
- HydroponicsToolSpade: 3
+ HydroponicsToolSpade: 2
+ HydroponicsToolMiniHoe: 2
+ HydroponicsToolClippers: 2
+ HydroponicsToolScythe: 2
+ HydroponicsToolHatchet: 2
PlantBag: 2
PlantBGoneSpray: 20
WeedSpray: 20
@@ -11,7 +15,5 @@
Syringe: 5
RobustHarvestChemistryBottle: 3
#TO DO:
- #cultivator
- #secateurs
#plant analyzer
diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/robotics.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/robotics.yml
index 56a49b3c2a..1236d446e4 100644
--- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/robotics.yml
+++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/robotics.yml
@@ -8,7 +8,6 @@
#roboticist under
CableStack: 4
Flash: 4
- PowerCellLargeHigh: 12
#proximity sensor
#signaller
#health anaylzer
diff --git a/Resources/Prototypes/Chemistry/metabolizer_types.yml b/Resources/Prototypes/Chemistry/metabolizer_types.yml
index 47e068d08a..5ca7770f2d 100644
--- a/Resources/Prototypes/Chemistry/metabolizer_types.yml
+++ b/Resources/Prototypes/Chemistry/metabolizer_types.yml
@@ -2,14 +2,16 @@
# you'll likely have to tag its metabolizers with something other than Human.
- type: metabolizerType
- id: Human
+ id: Animal
- type: metabolizerType
- id: Animal
+ id: Dragon
+
+- type: metabolizerType
+ id: Human
- type: metabolizerType
id: Slime
- type: metabolizerType
id: Vox
-
diff --git a/Resources/Prototypes/Diseases/infectious.yml b/Resources/Prototypes/Diseases/infectious.yml
index 067ce166b6..58f222c1f3 100644
--- a/Resources/Prototypes/Diseases/infectious.yml
+++ b/Resources/Prototypes/Diseases/infectious.yml
@@ -168,6 +168,31 @@
- !type:DiseaseReagentCure
reagent: DemonsBlood
+- type: disease
+ id: Plague
+ name: plague
+ cureResist: 0.1
+ effects:
+ - !type:DiseaseVomit
+ probability: 0.005
+ - !type:DiseasePopUp
+ probability: 0.025
+ - !type:DiseaseSnough
+ probability: 0.025
+ snoughMessage: disease-cough
+ snoughSound:
+ collection: Coughs
+ - !type:DiseaseHealthChange
+ probability: 0.05
+ damage:
+ types:
+ Poison: 2
+ cures:
+ - !type:DiseaseBedrestCure
+ maxLength: 120
+ - !type:DiseaseJustWaitCure
+ maxLength: 240
+
- type: disease
id: OwOnavirus
name: OwOnavirus
diff --git a/Resources/Prototypes/Entities/Clothing/Belt/belts.yml b/Resources/Prototypes/Entities/Clothing/Belt/belts.yml
index fd60ae2f14..11bc837875 100644
--- a/Resources/Prototypes/Entities/Clothing/Belt/belts.yml
+++ b/Resources/Prototypes/Entities/Clothing/Belt/belts.yml
@@ -19,12 +19,12 @@
- Screwdriver
- Flashlight
- Wrench
-# - Painter
# - GeigerCounter
- Flare
- CableCoil
- CigPack
components:
+ - AirlockPainter
- SignalLinker
- RCD
- RCDAmmo
@@ -82,7 +82,6 @@
- Screwdriver
- Flashlight
- Wrench
-# - Painter
# - GeigerCounter
- Flare
- CableCoil
@@ -90,6 +89,7 @@
- JawsOfLife
- CigPack
components:
+ - AirlockPainter
- SignalLinker
- RCD
- RCDAmmo
@@ -193,6 +193,7 @@
- Soap
- Flashlight
- CigPack
+ - TrashBag
components:
- LightReplacer
- type: ItemMapper
@@ -292,6 +293,9 @@
# - PlantAnalyzer
- PlantSampleTaker
- BotanyShovel
+ - BotanyHoe
+ - BotanyHatchet
+ - PlantSampleTaker
- PlantBGone
- Bottle
- CigPack
diff --git a/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml b/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml
index 1b3dc756ab..7e7da58c56 100644
--- a/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml
+++ b/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml
@@ -106,7 +106,9 @@
- type: FlashLightVisualizer
- type: HandheldLight
addPrefix: true
- - type: PowerCellSlot
- cellSlot:
- startingItem: PowerCellHardsuitHelmet # self recharging
- locked: true # no need to recharge manually
+ - type: Battery
+ maxCharge: 600 #lights drain 3/s but recharge of 2 makes this 1/s. Therefore 600 is 10 minutes of light.
+ startingCharge: 600
+ - type: BatterySelfRecharger
+ autoRecharge: true
+ autoRechargeRate: 2 #recharge of 2 makes total drain 1w / s so max charge is 1:1 with time. Time to fully charge should be 5 minutes. Having recharge gives light an extended flicker period which gives you some warning to return to light area.
diff --git a/Resources/Prototypes/Entities/Clothing/Head/hardhats.yml b/Resources/Prototypes/Entities/Clothing/Head/hardhats.yml
index 7bb577af60..f40a561fac 100644
--- a/Resources/Prototypes/Entities/Clothing/Head/hardhats.yml
+++ b/Resources/Prototypes/Entities/Clothing/Head/hardhats.yml
@@ -36,7 +36,7 @@
- state: on-equipped-HELMET
- type: PowerCellSlot
cellSlot:
- startingItem: PowerCellSmallHigh
+ startingItem: PowerCellMedium
- type: entity
parent: ClothingHeadHatHardhatBase
diff --git a/Resources/Prototypes/Entities/Clothing/Head/helmets.yml b/Resources/Prototypes/Entities/Clothing/Head/helmets.yml
index fb3e538511..818868f1b9 100644
--- a/Resources/Prototypes/Entities/Clothing/Head/helmets.yml
+++ b/Resources/Prototypes/Entities/Clothing/Head/helmets.yml
@@ -128,7 +128,7 @@
- type: Tag
tags:
- HidesHair
-
+
- type: entity
parent: ClothingHeadBase
id: ClothingHeadHelmetSpaceNinja
@@ -143,7 +143,7 @@
- type: Tag
tags:
- HidesHair
-
+
- type: entity
parent: ClothingHeadEVAHelmetBase
id: ClothingHeadHelmetSyndicate
@@ -207,7 +207,7 @@
- type: IngestionBlocker
- type: PowerCellSlot
cellSlot:
- startingItem: PowerCellSmallHigh
+ startingItem: PowerCellMedium
- type: TemperatureProtection
coefficient: 0.01
- type: Armor
diff --git a/Resources/Prototypes/Entities/Clothing/Head/misc.yml b/Resources/Prototypes/Entities/Clothing/Head/misc.yml
index 915c43b47f..f2324a861b 100644
--- a/Resources/Prototypes/Entities/Clothing/Head/misc.yml
+++ b/Resources/Prototypes/Entities/Clothing/Head/misc.yml
@@ -111,7 +111,22 @@
sprite: Clothing/Head/Misc/cone.rsi
- type: Clothing
sprite: Clothing/Head/Misc/cone.rsi
-
+
+- type: entity
+ parent: ClothingHeadBase
+ id: ClothingHeadHatFancyCrown
+ name: fancy crown
+ description: It smells like dead rat. Lets you speak like one!
+ components:
+ - type: Sprite
+ sprite: Clothing/Head/Misc/fancycrown.rsi
+ - type: Clothing
+ sprite: Clothing/Head/Misc/fancycrown.rsi
+ - type: MobPrice
+ price: 3000
+ - type: AddAccentClothing
+ accent: MobsterAccent
+
- type: entity
parent: ClothingHeadBase
id: ClothingHeadHatCatEars
diff --git a/Resources/Prototypes/Entities/Clothing/Masks/masks.yml b/Resources/Prototypes/Entities/Clothing/Masks/masks.yml
index 82efdc12b0..ef5d73db85 100644
--- a/Resources/Prototypes/Entities/Clothing/Masks/masks.yml
+++ b/Resources/Prototypes/Entities/Clothing/Masks/masks.yml
@@ -42,6 +42,7 @@
- type: IngestionBlocker
- type: DiseaseProtection
protection: 0.05
+ - type: FlashImmunity
- type: entity
parent: ClothingMaskBase
diff --git a/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml b/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml
index 056112c18a..379666a410 100644
--- a/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml
+++ b/Resources/Prototypes/Entities/Clothing/Uniforms/jumpsuits.yml
@@ -768,4 +768,35 @@
- type: Clothing
sprite: Clothing/Uniforms/Jumpsuit/atmos.rsi
+- type: entity
+ parent: ClothingUniformBase
+ id: ClothingUniformJumpsuitPsychologist
+ name: psychologist suit
+ description: I don't lose things. I place things in locations which later elude me.
+ components:
+ - type: Sprite
+ sprite: Clothing/Uniforms/Jumpsuit/psychologist.rsi
+ - type: Clothing
+ sprite: Clothing/Uniforms/Jumpsuit/psychologist.rsi
+- type: entity
+ parent: ClothingUniformBase
+ id: ClothingUniformJumpsuitReporter
+ name: reporter suit
+ description: A good reporter remains a skeptic all their life.
+ components:
+ - type: Sprite
+ sprite: Clothing/Uniforms/Jumpsuit/reporter.rsi
+ - type: Clothing
+ sprite: Clothing/Uniforms/Jumpsuit/reporter.rsi
+
+- type: entity
+ parent: ClothingUniformBase
+ id: ClothingUniformJumpsuitJournalist
+ name: journalist suit
+ description: If journalism is good, it is controversial, by nature.
+ components:
+ - type: Sprite
+ sprite: Clothing/Uniforms/Jumpsuit/journalist.rsi
+ - type: Clothing
+ sprite: Clothing/Uniforms/Jumpsuit/journalist.rsi
diff --git a/Resources/Prototypes/Entities/Markers/Spawners/Random/maintenance.yml b/Resources/Prototypes/Entities/Markers/Spawners/Random/maintenance.yml
index 3792dce72e..20df4edf75 100644
--- a/Resources/Prototypes/Entities/Markers/Spawners/Random/maintenance.yml
+++ b/Resources/Prototypes/Entities/Markers/Spawners/Random/maintenance.yml
@@ -50,14 +50,13 @@
- type: Sprite
layers:
- state: red
- - texture: Objects/Power/PowerCells/power_cell_large_sup.rsi/l_sup.png
+ - sprite: Objects/Power/power_cells.rsi
+ state: high
- type: RandomSpawner
rarePrototypes:
- lanternextrabright
- - PowerCellMediumSuper
- - PowerCellSmallSuper
- - PowerCellLargeSuper
- - PowerCellSmallAutorecharge
+ - PowerCellHigh
+ - PowerCellMicroreactor
rareChance: 0.08
prototypes:
- FlashlightLantern
diff --git a/Resources/Prototypes/Entities/Markers/Spawners/jobs.yml b/Resources/Prototypes/Entities/Markers/Spawners/jobs.yml
index 4d9bd34f4a..07f495c5f3 100644
--- a/Resources/Prototypes/Entities/Markers/Spawners/jobs.yml
+++ b/Resources/Prototypes/Entities/Markers/Spawners/jobs.yml
@@ -466,4 +466,30 @@
- type: Sprite
layers:
- state: green
- - state: ertjanitor
\ No newline at end of file
+ - state: ertjanitor
+
+# STATION SPECIFIC
+
+- type: entity
+ id: SpawnPointReporter
+ parent: SpawnPointJobBase
+ name: reporter
+ components:
+ - type: SpawnPoint
+ job_id: Reporter
+ - type: Sprite
+ layers:
+ - state: green
+ - state: reporter
+
+- type: entity
+ id: SpawnPointPsychologist
+ parent: SpawnPointJobBase
+ name: psychologist
+ components:
+ - type: SpawnPoint
+ job_id: Psychologist
+ - type: Sprite
+ layers:
+ - state: green
+ - state: psychologist
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml
index f54f9648bb..6b76b05b15 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml
@@ -29,12 +29,14 @@
- FlyingMobMask
layer:
- FlyingMobLayer
- - type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: bat
- crit: dead
- dead: dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: bat
+ Critical:
+ Base: dead
+ Dead:
+ Base: dead
- type: Butcherable
spawned:
- id: FoodMeat
@@ -97,11 +99,15 @@
5: !type:CriticalMobState {}
10: !type:DeadMobState {}
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: 0
- crit: dead
- dead: dead
+ - type: DamageStateVisuals
+ rotate: true
+ states:
+ Alive:
+ Base: 0
+ Critical:
+ Base: dead
+ Dead:
+ Base: dead
- type: Tag
tags:
- Bee
@@ -153,11 +159,14 @@
state: chicken-0
sprite: Mobs/Animals/chicken.rsi
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: chicken-0
- crit: dead-0
- dead: dead-0
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: chicken-0
+ Critical:
+ Base: dead-0
+ Dead:
+ Base: dead-0
- type: Butcherable
spawned:
- id: FoodMeatChicken
@@ -184,11 +193,14 @@
state: duck-0
sprite: Mobs/Animals/duck.rsi
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: duck-0
- crit: dead-0
- dead: dead-0
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: duck-0
+ Critical:
+ Base: dead-0
+ Dead:
+ Base: dead-0
- type: Butcherable
spawned:
- id: FoodMeatDuck
@@ -204,7 +216,7 @@
- type: entity
name: white duck #Quack
- parent: SimpleMobBase
+ parent: MobDuckMallard
id: MobDuckWhite
description: An adorable white duck, it's fluffy and soft!
components:
@@ -215,27 +227,18 @@
state: duck-1
sprite: Mobs/Animals/duck.rsi
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: duck-1
- crit: dead-1
- dead: dead-1
- - type: Butcherable
- spawned:
- - id: FoodMeatDuck
- amount: 1
- - type: InteractionPopup
- successChance: 0.9
- interactSuccessString: petting-success-bird
- interactFailureString: petting-failure-generic
- interactSuccessSound:
- path: /Audio/Animals/duck_quack_happy.ogg
- - type: Bloodstream
- bloodMaxVolume: 100
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: duck-1
+ Critical:
+ Base: dead-1
+ Dead:
+ Base: dead-1
- type: entity
name: brown duck #Quack
- parent: SimpleMobBase
+ parent: MobDuckMallard
id: MobDuckBrown
description: An adorable brown duck, it's fluffy and soft!
components:
@@ -246,23 +249,14 @@
state: duck-2
sprite: Mobs/Animals/duck.rsi
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: duck-2
- crit: dead-2
- dead: dead-2
- - type: Butcherable
- spawned:
- - id: FoodMeatDuck
- amount: 1
- - type: InteractionPopup
- successChance: 0.9
- interactSuccessString: petting-success-bird
- interactFailureString: petting-failure-generic
- interactSuccessSound:
- path: /Audio/Animals/duck_quack_happy.ogg
- - type: Bloodstream
- bloodMaxVolume: 100
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: duck-2
+ Critical:
+ Base: dead-2
+ Dead:
+ Base: dead-2
- type: entity
name: butterfly
@@ -306,11 +300,14 @@
cyan: "#18a2d5"
yellow: "#d58c18"
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: butterfly
- crit: dead
- dead: dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: butterfly
+ Critical:
+ Base: dead
+ Dead:
+ Base: dead
- type: Bloodstream
bloodMaxVolume: 0.1
- type: NoSlip
@@ -339,11 +336,14 @@
layer:
- MobLayer
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: cow
- crit: dead
- dead: dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: cow
+ Critical:
+ Base: dead
+ Dead:
+ Base: dead
- type: SolutionContainerManager
solutions:
udder:
@@ -396,11 +396,14 @@
layer:
- MobLayer
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: crab
- crit: dead
- dead: dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: crab
+ Critical:
+ Base: dead
+ Dead:
+ Base: dead
- type: Butcherable
spawned:
- id: FoodMeatCrab
@@ -425,11 +428,14 @@
state: goat
sprite: Mobs/Animals/goat.rsi
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: goat
- crit: dead
- dead: dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: goat
+ Critical:
+ Base: dead
+ Dead:
+ Base: dead
- type: SolutionContainerManager
solutions:
udder:
@@ -470,11 +476,14 @@
state: goose
sprite: Mobs/Animals/goose.rsi
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: goose
- crit: dead
- dead: dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: goose
+ Critical:
+ Base: dead
+ Dead:
+ Base: dead
- type: Butcherable
spawned:
- id: FoodMeatChicken
@@ -513,11 +522,14 @@
layer:
- MobLayer
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: crawling
- crit: dead
- dead: dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: crawling
+ Critical:
+ Base: dead
+ Dead:
+ Base: dead
- type: Butcherable
spawned:
- id: FoodMeat
@@ -553,12 +565,15 @@
layer:
- MobLayer
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: kangaroo
- # SKIPPY NO!
- crit: kangaroo-dead
- dead: kangaroo-dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: kangaroo
+ # SKIPPY NO!
+ Critical:
+ Base: kangaroo-dead
+ Dead:
+ Base: kangaroo-dead
- type: Puller
- type: entity
@@ -576,11 +591,14 @@
state: kangaroo-boxing
sprite: Mobs/Animals/kangaroo.rsi
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: kangaroo-boxing
- crit: kangaroo-boxing-dead
- dead: kangaroo-boxing-dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: kangaroo-boxing
+ Critical:
+ Base: kangaroo-boxing-dead
+ Dead:
+ Base: kangaroo-boxing-dead
- type: MeleeWeapon
range: 1.5
arcwidth: 0
@@ -626,12 +644,16 @@
- type: Body
template: PrimateTemplate
preset: PrimatePreset
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: monkey
+ Critical:
+ Base: dead
+ Dead:
+ Base: dead
- type: Appearance
visuals:
- - type: DamageStateVisualizer
- normal: monkey
- crit: dead
- dead: dead
- type: FireVisualizer
sprite: Mobs/Effects/onfire.rsi
normalState: Monkey_burning
@@ -657,10 +679,10 @@
speechSounds: Squeak
- type: Sprite
drawdepth: SmallMobs
+ sprite: Mobs/Animals/mouse.rsi
layers:
- map: ["enum.DamageStateVisualLayers.Base"]
state: mouse-0
- sprite: Mobs/Animals/mouse.rsi
- type: Clothing
size: 5
quickEquip: false
@@ -688,11 +710,14 @@
baseWalkSpeed : 5
baseSprintSpeed : 5
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: mouse-0
- crit: dead-0
- dead: splat-0
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: mouse-0
+ Critical:
+ Base: dead-0
+ Dead:
+ Base: splat-0
- type: Food
- type: Hunger
baseDecayRate: 0.5 # I'm very hungry! Give me. The cheese.
@@ -762,11 +787,14 @@
- type: Clothing
HeldPrefix: 1
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: mouse-1
- crit: dead-1
- dead: splat-1
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: mouse-1
+ Critical:
+ Base: dead-1
+ Dead:
+ Base: splat-1
- type: Bloodstream
bloodMaxVolume: 50
- type: DiseaseCarrier #Why doesn't this save if it's only on the parent wtf
@@ -785,11 +813,14 @@
- type: Clothing
HeldPrefix: 1
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: mouse-2
- crit: dead-2
- dead: splat-2
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: mouse-1
+ Critical:
+ Base: dead-1
+ Dead:
+ Base: splat-1
- type: Bloodstream
bloodMaxVolume: 50
- type: DiseaseCarrier
@@ -822,11 +853,14 @@
layer:
- MobLayer
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: lizard
- crit: dead
- dead: dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: lizard
+ Critical:
+ Base: dead
+ Dead:
+ Base: dead
- type: Butcherable
spawned:
- id: FoodMeat
@@ -870,11 +904,14 @@
layer:
- MobLayer
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: slug
- crit: dead
- dead: dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: slug
+ Critical:
+ Base: dead
+ Dead:
+ Base: dead
- type: Butcherable
spawned:
- id: FoodMeat
@@ -913,11 +950,14 @@
layer:
- SmallMobLayer
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: frog
- crit: dead
- dead: dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: frog
+ Critical:
+ Base: dead
+ Dead:
+ Base: dead
- type: Butcherable
spawned:
- id: FoodMeat
@@ -959,11 +999,14 @@
layer:
- FlyingMobLayer
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: parrot
- crit: dead
- dead: dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: parrot
+ Critical:
+ Base: dead
+ Dead:
+ Base: dead
- type: Butcherable
spawned:
- id: FoodMeat
@@ -1002,11 +1045,14 @@
layer:
- MobLayer
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: penguin
- crit: penguin_dead
- dead: penguin_dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: penguin
+ Critical:
+ Base: penguin_dead
+ Dead:
+ Base: penguin_dead
- type: Butcherable
spawned:
- id: FoodMeatPenguin
@@ -1051,11 +1097,14 @@
layer:
- MobLayer
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: penguin
- crit: dead
- dead: dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: penguin
+ Critical:
+ Base: dead
+ Dead:
+ Base: dead
- type: Butcherable
spawned:
- id: FoodMeatPenguin
@@ -1105,11 +1154,13 @@
- SmallMobMask
layer:
- SmallMobLayer
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: snake
- type: Appearance
visuals:
- type: RotationVisualizer
- - type: DamageStateVisualizer
- normal: snake
# It's death animation is animated so hopefully this should push for separation between "dying" and "death" states.
# looks stupid, Rotation visualizer for now
# dead: dead
@@ -1154,11 +1205,14 @@
layer:
- MobLayer
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: tarantula
- crit: tarantula_dead
- dead: tarantula_dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: tarantula
+ Critical:
+ Base: tarantula_dead
+ Dead:
+ Base: tarantula_dead
- type: Butcherable
spawned:
- id: FoodMeatSpider
@@ -1218,11 +1272,14 @@
layer:
- MobLayer
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: possum
- crit: possum_dead # TODO: Make it so possums can "play dead." Probably need AI changes
- dead: possum_dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: possum
+ Critical:
+ Base: possum_dead
+ Dead:
+ Base: possum_dead
- type: Butcherable
spawned:
- id: FoodMeat
@@ -1274,11 +1331,14 @@
layer:
- MobLayer
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: raccoon
- crit: raccoon_dead
- dead: raccoon_dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: raccoon
+ Critical:
+ Base: raccoon_dead
+ Dead:
+ Base: raccoon_dead
- type: Butcherable
spawned:
- id: FoodMeat
@@ -1330,11 +1390,14 @@
layer:
- MobLayer
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: fox
- crit: fox_dead
- dead: fox_dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: fox
+ Critical:
+ Base: fox_dead
+ Dead:
+ Base: fox_dead
- type: Butcherable
spawned:
- id: FoodMeat
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/bear.yml b/Resources/Prototypes/Entities/Mobs/NPCs/bear.yml
index 636316f068..200b7a9ca9 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/bear.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/bear.yml
@@ -33,11 +33,14 @@
0: !type:NormalMobState {}
150: !type:DeadMobState {}
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: bear
- crit: bear_dead
- dead: bear_dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: bear
+ Critical:
+ Base: bear_dead
+ Dead:
+ Base: bear_dead
- type: Butcherable
spawned:
- id: FoodMeatBear
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml b/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml
index 774d375ca7..34b9eda4eb 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml
@@ -17,6 +17,11 @@
- map: ["enum.DamageStateVisualLayers.Base"]
state: alive
sprite: Mobs/Aliens/Carps/space.rsi
+ - type: CombatMode
+ disarmAction:
+ enabled: false
+ autoPopulate: false
+ name: action-name-disarm
- type: Physics
- type: Fixtures
fixtures:
@@ -35,15 +40,17 @@
100: !type:DeadMobState {}
- type: MovementIgnoreGravity
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: alive
- crit: crit
- dead: dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: alive
+ Critical:
+ Base: crit
+ Dead:
+ Base: dead
- type: Butcherable
- # TODO: CrapMeat or FishMeat # - 2022-02-17 LMAO crap meat
spawned:
- - id: FoodMeat
+ - id: FoodMeatFish
amount: 2
- type: MeleeWeapon
range: 1.5
@@ -55,17 +62,6 @@
types:
Piercing: 5
Slash: 10
- - type: CombatMode
- disarmAction:
- enabled: false
- autoPopulate: false
- name: action-name-disarm
- - type: GhostTakeoverAvailable
- makeSentient: true
- name: space carp
- description: |
- If you're a salvage spawn, defend the loot inside!
- Otherwise, wreak havoc on the station!
- type: ReplacementAccent
accent: genericAggressive
- type: TypingIndicator
@@ -84,8 +80,6 @@
- map: ["enum.DamageStateVisualLayers.Base"]
state: alive
sprite: Mobs/Aliens/Carps/magic.rsi
- - type: GhostTakeoverAvailable
- name: magicarp
- type: TypingIndicator
proto: guardian
@@ -93,7 +87,7 @@
name: holocarp
parent: MobCarp
id: MobCarpHolo
- description: Carp made out of holographic energies.
+ description: Carp made out of holographic energies. Sadly for you, it is very much real.
components:
- type: Sprite
drawdepth: Mobs
@@ -112,8 +106,6 @@
- MobMask
layer:
- Opaque
- - type: GhostTakeoverAvailable
- name: holocarp
- type: TypingIndicator
proto: robot
@@ -128,3 +120,14 @@
Defend the loot inside the salvage wreck!
- type: SalvageMobRestrictions
+- type: entity
+ name: space carp
+ id: MobCarpDragon
+ suffix: DragonBrood
+ parent: MobCarp
+ components:
+ - type: GhostTakeoverAvailable
+ makeSentient: true
+ name: Sentient Carp
+ description: Help the dragon flood the station with carps!
+
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml b/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml
index 75c325956f..cfb97fcbc7 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml
@@ -24,12 +24,15 @@
- MobMask
layer:
- MobLayer
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: corgi
+ Critical:
+ Base: corgi_dead
+ Dead:
+ Base: corgi_dead
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: corgi
- crit: corgi_dead
- dead: corgi_dead
- type: Butcherable
spawned:
- id: FoodMeat
@@ -61,11 +64,14 @@
- map: ["enum.DamageStateVisualLayers.Base"]
state: narsian
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: narsian
- crit: narsian_dead
- dead: narsian_dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: narsian
+ Critical:
+ Base: narsian_dead
+ Dead:
+ Base: narsian_dead
- type: MeleeWeapon
range: 1.5
arcwidth: 0
@@ -125,11 +131,14 @@
- map: ["enum.DamageStateVisualLayers.Base"]
state: ian
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: ian
- crit: ian_dead
- dead: ian_dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: ian
+ Critical:
+ Base: ian_dead
+ Dead:
+ Base: ian_dead
- type: Grammar
attributes:
proper: true
@@ -152,11 +161,14 @@
- map: ["enum.DamageStateVisualLayers.Base"]
state: old_ian
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: old_ian
- crit: old_ian_dead
- dead: old_ian_dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: old_ian
+ Critical:
+ Base: old_ian_dead
+ Dead:
+ Base: old_ian_dead
- type: Grammar
attributes:
proper: true
@@ -175,11 +187,14 @@
- map: ["enum.DamageStateVisualLayers.Base"]
state: lisa
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: lisa
- crit: lisa_dead
- dead: lisa_dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: lisa
+ Critical:
+ Base: lisa_dead
+ Dead:
+ Base: lisa_dead
- type: Grammar
attributes:
proper: true
@@ -198,11 +213,14 @@
- map: ["enum.DamageStateVisualLayers.Base"]
state: puppy
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: puppy
- crit: puppy_dead
- dead: puppy_dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: puppy
+ Critical:
+ Base: puppy_dead
+ Dead:
+ Base: puppy_dead
- type: Grammar
attributes:
gender: epicene
@@ -231,11 +249,14 @@
layer:
- MobLayer
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: cat
- crit: cat_dead
- dead: cat_dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: cat
+ Critical:
+ Base: cat_dead
+ Dead:
+ Base: cat_dead
- type: Butcherable
spawned:
- id: FoodMeat
@@ -275,11 +296,14 @@
- map: ["enum.DamageStateVisualLayers.Base"]
state: cat2
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: cat2
- crit: cat2_dead
- dead: cat2_dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: cat2
+ Critical:
+ Base: cat2_dead
+ Dead:
+ Base: cat2_dead
- type: Grammar
attributes:
gender: epicene
@@ -307,11 +331,14 @@
- map: ["enum.DamageStateVisualLayers.Base"]
state: spacecat
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: spacecat
- crit: spacecat_dead
- dead: spacecat_dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: spacecat
+ Critical:
+ Base: spacecat_dead
+ Dead:
+ Base: spacecat_dead
- type: InteractionPopup
successChance: 0.7
interactSuccessString: petting-success-space-cat
@@ -335,11 +362,14 @@
- map: ["enum.DamageStateVisualLayers.Base"]
state: caracal_flop
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: caracal_flop
- crit: caracal_dead
- dead: caracal_dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: caracal_flop
+ Critical:
+ Base: caracal_dead
+ Dead:
+ Base: caracal_dead
- type: Grammar
attributes:
gender: epicene
@@ -381,11 +411,14 @@
layer:
- MobLayer
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: sloth
- crit: sloth_dead
- dead: sloth_dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: sloth
+ Critical:
+ Base: sloth_dead
+ Dead:
+ Base: sloth_dead
- type: Butcherable
spawned:
- id: FoodMeat
@@ -424,11 +457,14 @@
layer:
- MobLayer
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: ferret
- crit: ferret_dead
- dead: ferret_dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: ferret
+ Critical:
+ Base: ferret_dead
+ Dead:
+ Base: ferret_dead
- type: Butcherable
spawned:
- id: FoodMeat
@@ -478,11 +514,14 @@
layer:
- MobLayer
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: bingus
- crit: bingus_dead
- dead: bingus_dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: bingus
+ Critical:
+ Base: bingus_dead
+ Dead:
+ Base: bingus_dead
- type: Butcherable
spawned:
- id: FoodMeat
@@ -521,11 +560,14 @@
layer:
- MobLayer
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: mcgriff
- crit: mcgriff_dead
- dead: mcgriff_dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: mcgriff
+ Critical:
+ Base: mcgriff_dead
+ Dead:
+ Base: mcgriff_dead
- type: Butcherable
spawned:
- id: FoodMeat
@@ -556,11 +598,14 @@
- map: ["enum.DamageStateVisualLayers.Base"]
state: paperwork
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: paperwork
- crit: paperwork_dead
- dead: paperwork_dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: paperwork
+ Critical:
+ Base: paperwork_dead
+ Dead:
+ Base: paperwork_dead
- type: Butcherable
spawned:
- id: FoodMeat
@@ -598,11 +643,14 @@
layer:
- MobLayer
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: walter
- crit: walter_dead
- dead: walter_dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: walter
+ Critical:
+ Base: walter_dead
+ Dead:
+ Base: walter_dead
- type: Butcherable
spawned:
- id: FoodMeat
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml b/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml
new file mode 100644
index 0000000000..ed6e564435
--- /dev/null
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml
@@ -0,0 +1,197 @@
+- type: entity
+ name: Rat King
+ id: MobRatKing
+ parent: SimpleMobBase
+ description: He's da rat. He make da roolz.
+ components:
+ - type: CombatMode
+ - type: MovementSpeedModifier
+ baseWalkSpeed : 3.75
+ baseSprintSpeed : 3.75
+ - type: UtilityAI
+ behaviorSets:
+ - Idle
+ - UnarmedAttackHostiles
+ - type: Reactive
+ groups:
+ Flammable: [Touch]
+ Extinguish: [Touch]
+ - type: AiFactionTag
+ factions:
+ - SimpleHostile
+ - type: Sprite
+ drawdepth: Mobs
+ sprite: Mobs/Animals/regalrat.rsi
+ layers:
+ - map: ["enum.DamageStateVisualLayers.Base"]
+ state: regalrat
+ - type: Physics
+ bodyType: KinematicController
+ - type: Fixtures
+ fixtures:
+ - shape:
+ !type:PhysShapeCircle
+ radius: 0.25
+ mass: 120
+ mask:
+ - MobMask
+ layer:
+ - MobLayer
+ - type: MobState
+ thresholds:
+ 0: !type:NormalMobState {}
+ 150: !type:CriticalMobState {}
+ 200: !type:DeadMobState {}
+ - type: MeleeWeapon
+ range: 1
+ arcwidth: 0
+ arc: claw
+ damage:
+ types:
+ Slash: 12
+ Piercing: 8
+ - type: Appearance
+ - type: DamageStateVisuals
+ rotate: true
+ states:
+ Alive:
+ Base: regalrat
+ Critical:
+ Base: dead
+ Dead:
+ Base: dead
+ - type: Puller
+ - type: GhostTakeoverAvailable
+ makeSentient: true
+ name: Rat King
+ description: You are the Rat King, scavenge food in order to produce rat minions to do your bidding.
+ rules: You are an antagonist, scavenge, attack, and grow your hoarde!
+ - type: Tag
+ tags:
+ - CannotSuicide
+ - DoorBumpOpener
+ - FootstepSound
+ - type: NoSlip
+ - type: RatKing
+ actionRaiseArmy:
+ useDelay: 4
+ icon: Interface/Actions/ratKingArmy.png
+ name: rat-king-raise-army-name
+ description: rat-king-raise-army-description
+ itemIconStyle: NoItem
+ event: !type:RatKingRaiseArmyActionEvent
+ hungerPerArmyUse: 25
+ actionDomain:
+ useDelay: 10
+ icon: Interface/Actions/ratKingDomain.png
+ name: rat-king-domain-name
+ description: rat-king-domain-description
+ itemIconStyle: NoItem
+ event: !type:RatKingDomainActionEvent
+ hungerPerDomainUse: 50
+ - type: MobsterAccent
+ - type: Access #he's so baller he gets his own access. NT got nothing on him
+ tags:
+ - Maintenance
+ - Service
+ - type: Butcherable
+ spawned:
+ - id: ClothingHeadHatFancyCrown #how did that get there?
+ amount: 1
+ - type: DiseaseCarrier
+ carrierDiseases:
+ - Plague
+ - type: SlowOnDamage
+ speedModifierThresholds:
+ 50: 0.9
+ 75: 0.8
+ 100: 0.7
+ - type: MobPrice
+ price: 2500 # rat wealth
+
+- type: entity
+ name: Rat Servant
+ id: MobRatServant
+ parent: SimpleMobBase
+ description: He's da mini rat. He don't make da roolz.
+ components:
+ - type: CombatMode
+ - type: MovementSpeedModifier
+ baseWalkSpeed : 4
+ baseSprintSpeed : 4
+ - type: UtilityAI
+ behaviorSets:
+ - Idle
+ - UnarmedAttackHostiles
+ - type: Reactive
+ groups:
+ Flammable: [Touch]
+ Extinguish: [Touch]
+ - type: AiFactionTag
+ factions:
+ - SimpleHostile
+ - type: Sprite
+ drawdepth: SmallMobs
+ sprite: Mobs/Animals/mouse.rsi
+ layers:
+ - map: ["enum.DamageStateVisualLayers.Base"]
+ state: mouse-3
+ - type: Physics
+ bodyType: KinematicController
+ - type: Fixtures
+ fixtures:
+ - shape:
+ !type:PhysShapeCircle
+ radius: 0.2
+ mass: 10
+ mask:
+ - SmallMobMask
+ layer:
+ - SmallMobLayer
+ - type: MobState
+ thresholds:
+ 0: !type:NormalMobState {}
+ 25: !type:CriticalMobState {}
+ 50: !type:DeadMobState {}
+ - type: MeleeWeapon
+ range: 1
+ arcwidth: 0
+ arc: claw
+ damage:
+ types:
+ Slash: 5
+ Piercing: 2
+ - type: Appearance
+ - type: DamageStateVisuals
+ rotate: true
+ states:
+ Alive:
+ Base: mouse-3
+ Critical:
+ Base: dead-3
+ Dead:
+ Base: splat-3
+ - type: Puller
+ - type: DiseaseCarrier
+ carrierDiseases:
+ - Plague
+ - type: Vocal
+ # mice are gender neutral who cares
+ maleScream: /Audio/Animals/mouse_squeak.ogg
+ femaleScream: /Audio/Animals/mouse_squeak.ogg
+ wilhelmProbability: 0.001
+ - type: GhostTakeoverAvailable
+ makeSentient: true
+ name: Rat Servant
+ description: You are a Rat Servant. You must follow your king's orders.
+ rules: You are an antagonist, scavenge, attack, and serve your king!
+ - type: Tag
+ tags:
+ - CannotSuicide
+ - DoorBumpOpener
+ - FootstepSound
+ - type: NoSlip
+ - type: MobPrice
+ price: 500 # rat wealth
+ - type: MobsterAccent
+ isBoss: false
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml b/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml
index 53612a62b0..fff1391f47 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/simplemob.yml
@@ -95,6 +95,14 @@
0: !type:NormalMobState {}
50: !type:CriticalMobState {}
100: !type:DeadMobState {}
+ - type: Destructible
+ thresholds:
+ - trigger:
+ !type:DamageTypeTrigger
+ damageType: Blunt
+ damage: 400
+ behaviors:
+ - !type:GibBehavior { }
- type: HeatResistance
- type: CombatMode
- type: Internals
@@ -144,6 +152,7 @@
90: 0.2
- type: MobPrice
price: 1000 # Living critters are valuable in space.
+ - type: Perishable
- type: entity
save: false
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/spacetick.yml b/Resources/Prototypes/Entities/Mobs/NPCs/spacetick.yml
index 437bd15471..84bab9ef3e 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/spacetick.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/spacetick.yml
@@ -38,10 +38,12 @@
15: !type:DeadMobState {}
- type: MovementIgnoreGravity
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: alive
- dead: dead
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: alive
+ Dead:
+ Base: dead
- type: Butcherable
spawned:
- id: FoodMeatXeno
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml
index a9a8b0e538..c9d241d9a2 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml
@@ -1,6 +1,6 @@
# Hacky for the stress test so don't even consider adding to this
- type: entity
- name: Xeno
+ name: Burrower
id: MobXeno
parent: SimpleSpaceMobBase
description: They mostly come at night. Mostly.
@@ -40,7 +40,6 @@
- type: MobState
thresholds:
0: !type:NormalMobState {}
- 150: !type:CriticalMobState {}
200: !type:DeadMobState {}
- type: Bloodstream
bloodReagent: FluorosulfuricAcid
@@ -55,17 +54,22 @@
- type: MeleeWeapon
range: 1.5
arcwidth: 0
- arc: claw
+ hitSound:
+ collection: AlienClaw
+ arc:
damage:
groups:
Brute: 20
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- rotate: true
- normal: running
- crit: crit
- dead: dead
+ - type: DamageStateVisuals
+ rotate: true
+ states:
+ Alive:
+ Base: running
+ Critical:
+ Base: crit
+ Dead:
+ Base: dead
- type: Puller
- type: Butcherable
butcheringType: Spike
@@ -89,9 +93,226 @@
tags:
- CannotSuicide
- DoorBumpOpener
- - FootstepSound
+ - FootstepSound
- type: NoSlip
+- type: entity
+ name: Praetorian
+ parent: MobXeno
+ id: MobXenoPraetorian
+ components:
+ - type: Sprite
+ drawdepth: Mobs
+ sprite: Mobs/Aliens/Xenos/praetorian.rsi
+ offset: 0,0.4
+ layers:
+ - map: ["enum.DamageStateVisualLayers.Base"]
+ state: running
+ - type: MobState
+ thresholds:
+ 0: !type:NormalMobState {}
+ 300: !type:DeadMobState {}
+ - type: SlowOnDamage
+ speedModifierThresholds:
+ 250: 0.4
+ - type: Fixtures
+ fixtures:
+ - shape:
+ !type:PhysShapeCircle
+ radius: 0.45
+ mass: 120
+ mask:
+ - MobMask
+ layer:
+ - MobLayer
+
+- type: entity
+ name: Drone
+ parent: MobXeno
+ id: MobXenoDrone
+ components:
+ - type: Sprite
+ drawdepth: Mobs
+ sprite: Mobs/Aliens/Xenos/drone.rsi
+ offset: 0,0.2
+ layers:
+ - map: ["enum.DamageStateVisualLayers.Base"]
+ state: running
+ - type: MobState
+ thresholds:
+ 0: !type:NormalMobState {}
+ 200: !type:DeadMobState {}
+ - type: MovementSpeedModifier
+ baseWalkSpeed : 3.0
+ baseSprintSpeed : 5.5
+ - type: SlowOnDamage
+ speedModifierThresholds:
+ 150: 0.4
+ - type: Fixtures
+ fixtures:
+ - shape:
+ !type:PhysShapeCircle
+ radius: 0.45
+ mass: 120
+ mask:
+ - MobMask
+ layer:
+ - MobLayer
+
+- type: entity
+ name: Queen
+ parent: MobXeno
+ id: MobXenoQueen
+ components:
+ - type: Sprite
+ drawdepth: Mobs
+ sprite: Mobs/Aliens/Xenos/queen.rsi
+ offset: 0,0.4
+ layers:
+ - map: ["enum.DamageStateVisualLayers.Base"]
+ state: running
+ - type: MobState
+ thresholds:
+ 0: !type:NormalMobState {}
+ 1500: !type:DeadMobState {}
+ - type: MovementSpeedModifier
+ baseWalkSpeed : 2.8
+ baseSprintSpeed : 3.8
+ - type: MeleeWeapon
+ damage:
+ groups:
+ Brute: 40
+ cooldownTime: 2
+ - type: SlowOnDamage
+ speedModifierThresholds:
+ 1000: 0.4
+ - type: Fixtures
+ fixtures:
+ - shape:
+ !type:PhysShapeCircle
+ radius: 0.45
+ mass: 120
+ mask:
+ - MobMask
+ layer:
+ - MobLayer
+
+- type: entity
+ name: Ravager
+ parent: MobXeno
+ id: MobXenoRavager
+ components:
+ - type: Sprite
+ drawdepth: Mobs
+ sprite: Mobs/Aliens/Xenos/ravager.rsi
+ offset: 0,0.5
+ layers:
+ - map: ["enum.DamageStateVisualLayers.Base"]
+ state: running
+ - type: MobState
+ thresholds:
+ 0: !type:NormalMobState {}
+ 550: !type:DeadMobState {}
+ - type: MovementSpeedModifier
+ baseWalkSpeed : 2.3
+ baseSprintSpeed : 4.2
+ - type: MeleeWeapon
+ damage:
+ groups:
+ Brute: 35
+ cooldownTime: 1.5
+ - type: SlowOnDamage
+ speedModifierThresholds:
+ 450: 0.4
+ - type: Fixtures
+ fixtures:
+ - shape:
+ !type:PhysShapeCircle
+ radius: 0.45
+ mass: 120
+ mask:
+ - MobMask
+ layer:
+ - MobLayer
+
+- type: entity
+ name: Runner
+ parent: MobXeno
+ id: MobXenoRunner
+ components:
+ - type: Sprite
+ drawdepth: Mobs
+ sprite: Mobs/Aliens/Xenos/runner.rsi
+ offset: 0,0.6
+ layers:
+ - map: ["enum.DamageStateVisualLayers.Base"]
+ state: running
+ - type: MobState
+ thresholds:
+ 0: !type:NormalMobState {}
+ 250: !type:DeadMobState {}
+ - type: MovementSpeedModifier
+ baseWalkSpeed : 2.7
+ baseSprintSpeed : 6.0
+ - type: MeleeWeapon
+ damage:
+ groups:
+ Brute: 15
+ cooldownTime: 0.5
+ - type: SlowOnDamage
+ speedModifierThresholds:
+ 200: 0.4
+ - type: Fixtures
+ fixtures:
+ - shape:
+ !type:PhysShapeCircle
+ radius: 0.45
+ mass: 120
+ mask:
+ - MobMask
+ layer:
+ - MobLayer
+
+- type: entity
+ name: Rouny
+ parent: MobXenoRunner
+ id: MobXenoRouny
+ components:
+ - type: Sprite
+ drawdepth: Mobs
+ sprite: Mobs/Aliens/Xenos/rouny.rsi
+ offset: 0,0.6
+
+- type: entity
+ name: Spitter
+ parent: MobXeno
+ id: MobXenoSpitter
+ components:
+ - type: Sprite
+ drawdepth: Mobs
+ sprite: Mobs/Aliens/Xenos/spitter.rsi
+ offset: 0,0.3
+ layers:
+ - map: ["enum.DamageStateVisualLayers.Base"]
+ state: running
+ - type: MobState
+ thresholds:
+ 0: !type:NormalMobState {}
+ 300: !type:DeadMobState {}
+ - type: SlowOnDamage
+ speedModifierThresholds:
+ 250: 0.4
+ - type: Fixtures
+ fixtures:
+ - shape:
+ !type:PhysShapeCircle
+ radius: 0.45
+ mass: 120
+ mask:
+ - MobMask
+ layer:
+ - MobLayer
+
- type: entity
name: space adder
parent: SimpleSpaceMobBase
@@ -105,11 +326,14 @@
- map: ["enum.DamageStateVisualLayers.Base"]
state: purple_snake
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: purple_snake
- crit: dead_purple_snake
- dead: dead_purple_snake
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: purple_snake
+ Critical:
+ Base: dead_purple_snake
+ Dead:
+ Base: dead_purple_snake
- type: Grammar
attributes:
proper: true
@@ -156,10 +380,13 @@
- map: ["enum.DamageStateVisualLayers.Base"]
state: small_purple_snake
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- normal: purple_snake
- crit: dead_small_purple_snake
- dead: dead_small_purple_snake
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: small_purple_snake
+ Critical:
+ Base: dead_small_purple_snake
+ Dead:
+ Base: dead_small_purple_snake
- type: SolutionTransfer
maxTransferAmount: 1
diff --git a/Resources/Prototypes/Entities/Mobs/Player/dragon.yml b/Resources/Prototypes/Entities/Mobs/Player/dragon.yml
new file mode 100644
index 0000000000..23ce642caa
--- /dev/null
+++ b/Resources/Prototypes/Entities/Mobs/Player/dragon.yml
@@ -0,0 +1,103 @@
+- type: entity
+ name: space dragon
+ parent: SimpleSpaceMobBase
+ id: MobDragon
+ suffix:
+ description: A flying leviathan, loosely related to space carps.
+ components:
+ - type: GhostTakeoverAvailable
+ makeSentient: true
+ name: Space dragon!
+ description: Crash, roast, flood the station with carps!
+ - type: Speech
+ - type: CombatMode
+ disarmAction:
+ enabled: false
+ autoPopulate: false
+ name: action-name-disarm
+ - type: PlayerMobMover
+ - type: PlayerInputMover
+ - type: MovementSpeedModifier
+ baseWalkSpeed : 5
+ baseSprintSpeed : 5
+ - type: Sprite
+ sprite: Mobs/Aliens/Carps/dragon.rsi
+ noRot: true
+ # TODO: Randomise colors when RandomSpriteColor isn't poopoo
+ layers:
+ - map: [ "enum.DamageStateVisualLayers.Base" ]
+ state: alive
+ - map: [ "enum.DamageStateVisualLayers.BaseUnshaded" ]
+ state: alive-unshaded
+ shader: unshaded
+ - type: Appearance
+ - type: DamageStateVisuals
+ states:
+ Alive:
+ Base: alive
+ BaseUnshaded: alive-unshaded
+ Critical:
+ Base: crit
+ Dead:
+ Base: dead
+ BaseUnshaded: dead-unshaded
+ - type: Physics
+ bodyType: KinematicController
+ - type: Fixtures
+ fixtures:
+ - shape:
+ !type:PhysShapeCircle
+ radius: 0.40
+ mass: 50
+ mask:
+ - FlyingMobMask
+ layer:
+ - FlyingMobLayer
+ - type: MobState
+ thresholds:
+ 0: !type:NormalMobState {}
+ 450: !type:CriticalMobState {}
+ 500: !type:DeadMobState {}
+ - type: Metabolizer
+ solutionOnBody: false
+ updateFrequency: 0.25
+ metabolizerTypes: [Dragon]
+ groups:
+ - id: Medicine
+ - id: Poison
+ - type: MovementIgnoreGravity
+ - type: NoSlip
+ - type: Butcherable
+ spawned:
+ - id: FoodMeatDragon
+ amount: 2
+ - type: MeleeWeapon
+ hitSound:
+ path: /Audio/Effects/bite.ogg
+ damage:
+ types:
+ Piercing: 15
+ Slash: 15
+ - type: Dragon
+ spawnsLeft: 2
+ spawnsProto: MobCarpDragon
+ devourAction:
+ event: !type:DragonDevourActionEvent
+ icon: Interface/Actions/devour.png
+ name: action-name-devour
+ description: action-description-devour
+ devourChemical: Ichor
+ devourHealRate: 15.0
+ whitelist:
+ components:
+ - MobState
+ - Door
+ tags:
+ - Wall
+ spawnAction:
+ event: !type:DragonSpawnActionEvent
+ icon: Interface/Actions/carp_summon.png
+ name: action-name-carp-summon
+ description: action-description-carp-summon
+ useDelay: 5
+
diff --git a/Resources/Prototypes/Entities/Mobs/Player/silicon.yml b/Resources/Prototypes/Entities/Mobs/Player/silicon.yml
index e8d99e170c..2b53a6d7fd 100644
--- a/Resources/Prototypes/Entities/Mobs/Player/silicon.yml
+++ b/Resources/Prototypes/Entities/Mobs/Player/silicon.yml
@@ -215,9 +215,10 @@
layer:
- LargeMobLayer
- type: Appearance
- visuals:
- - type: DamageStateVisualizer
- rotate: true
- normal: onestar_boss
- dead: onestar_boss_wrecked
+ rotate: true
+ states:
+ Alive:
+ Base: onestar_boss
+ Dead:
+ Base: onestar_boss_wrecked
- type: CombatMode
diff --git a/Resources/Prototypes/Entities/Mobs/Species/human.yml b/Resources/Prototypes/Entities/Mobs/Species/human.yml
index 4f3129b534..5e0bb2ff1c 100644
--- a/Resources/Prototypes/Entities/Mobs/Species/human.yml
+++ b/Resources/Prototypes/Entities/Mobs/Species/human.yml
@@ -326,6 +326,7 @@
- type: MobPrice
price: 1500 # Kidnapping a living person and selling them for cred is a good move.
deathPenalty: 0.01 # However they really ought to be living and intact, otherwise they're worth 100x less.
+ - type: Perishable
- type: entity
save: false
diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/meals.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/meals.yml
index 7506926602..cb1e9cb493 100644
--- a/Resources/Prototypes/Entities/Objects/Consumable/Food/meals.yml
+++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/meals.yml
@@ -177,7 +177,7 @@
reagents:
- ReagentId: Nutriment
Quantity: 6
- - ReagentId: CapsaicinOil
+ - ReagentId: CarpoToxin
Quantity: 3
# Tastes like fish, batter, hot peppers.
@@ -367,6 +367,25 @@
state: queso
# Its queso! Everyone loves queso... Right?.
+- type: entity
+ name: Sashimi
+ parent: FoodMealBase
+ id: FoodMealSashimi
+ description: Its taste can only be described as "Exotic". The poisoning though? That's pretty common.
+ components:
+ - type: Sprite
+ state: sashimi
+ - type: SolutionContainerManager
+ solutions:
+ food:
+ maxVol: 18
+ reagents:
+ - ReagentId: Nutriment
+ Quantity: 6
+ - ReagentId: CarpoToxin
+ Quantity: 15
+# tastes exotic
+
- type: entity
name: enchiladas
parent: FoodMealBase
diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml
index b0e7fd65c5..a25ff7aa71 100644
--- a/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml
+++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml
@@ -48,11 +48,35 @@
food:
reagents:
- ReagentId: Toxin
- Quantity: 1
+ Quantity: 5
- type: SliceableFood
count: 3
slice: FoodMeatCutlet
+- type: entity
+ name: raw carp fillet
+ parent: FoodMeatBase
+ # MeatFish?...
+ id: FoodMeatFish
+ description: Your last words being "Wow, exotic!" are not worth it. The taste itself though? Maybe.
+ components:
+ - type: Tag
+ tags:
+ - Raw
+ - type: Sprite
+ state: fish
+ - type: SolutionContainerManager
+ solutions:
+ food:
+ reagents:
+ - ReagentId: CarpoToxin
+ Quantity: 5
+ - type: Extractable
+ juiceSolution:
+ reagents:
+ - ReagentId: CarpoToxin
+ Quantity: 5
+
- type: entity
name: raw bacon
parent: FoodMeatBase
@@ -216,6 +240,32 @@
- ReagentId: Toxin
Quantity: 5
+- type: entity
+ name: dragon flesh
+ parent: FoodMeatBase
+ id: FoodMeatDragon
+ description: The dense meat of the space-era apex predator is oozing with it's mythical ichor. Ironically, best eaten raw.
+ components:
+ - type: Tag
+ tags:
+ - Raw
+ - type: Sprite
+ layers:
+ - state: dragon
+ - state: dragon_veins
+ shader: unshaded
+ - type: SolutionContainerManager
+ solutions:
+ food:
+ reagents:
+ - ReagentId: Ichor
+ Quantity: 2
+ - type: Extractable
+ juiceSolution:
+ reagents:
+ - ReagentId: Ichor
+ Quantity: 2
+
- type: entity
name: raw lizard meat
parent: FoodMeatBase
diff --git a/Resources/Prototypes/Entities/Objects/Devices/holoprojectors.yml b/Resources/Prototypes/Entities/Objects/Devices/holoprojectors.yml
index f939c1bfe0..1bfa5164dc 100644
--- a/Resources/Prototypes/Entities/Objects/Devices/holoprojectors.yml
+++ b/Resources/Prototypes/Entities/Objects/Devices/holoprojectors.yml
@@ -5,9 +5,16 @@
description: A handy-dandy holographic projector that displays a janitorial sign.
components:
- type: HolosignProjector
+ - type: ItemCooldown
+ - type: UseDelay
+ delay: 1.0
+ - type: PowerCellSlot
+ cellSlot:
+ startingItem: PowerCellMedium
- type: Sprite
sprite: Objects/Devices/Holoprojectors/custodial.rsi
state: icon
+ netsync: false
- type: entity
parent: Holoprojector
@@ -17,7 +24,8 @@
components:
- type: HolosignProjector
signProto: HoloFan
- rechargeTime: 120
+ chargeUse: 120
- type: Sprite
sprite: Objects/Devices/Holoprojectors/atmos.rsi
state: icon
+ netsync: false
diff --git a/Resources/Prototypes/Entities/Objects/Devices/pda.yml b/Resources/Prototypes/Entities/Objects/Devices/pda.yml
index 81b4f41fde..734fa7a6ea 100644
--- a/Resources/Prototypes/Entities/Objects/Devices/pda.yml
+++ b/Resources/Prototypes/Entities/Objects/Devices/pda.yml
@@ -630,4 +630,34 @@
description: Red for firepower.
components:
- type: PDA
- id: ERTLeaderIDCard
\ No newline at end of file
+ id: ERTLeaderIDCard
+
+- type: entity
+ parent: BasePDA
+ id: PsychologistPDA
+ name: psychologist PDA
+ description: Looks immaculately cleaned.
+ components:
+ - type: PDA
+ id: PsychologistIDCard
+ - type: Appearance
+ visuals:
+ - type: PDAVisualizer
+ state: pda-medical
+ - type: Icon
+ state: pda-medical
+
+- type: entity
+ parent: BasePDA
+ id: ReporterPDA
+ name: reporter PDA
+ description: Smells like freshly printed press.
+ components:
+ - type: PDA
+ id: ReporterIDCard
+ - type: Appearance
+ visuals:
+ - type: PDAVisualizer
+ state: pda-reporter
+ - type: Icon
+ state: pda-reporter
diff --git a/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml b/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml
index c05852d842..130dfba0b1 100644
--- a/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml
+++ b/Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml
@@ -483,3 +483,25 @@
- type: Sprite
layers:
- state: syndie
+
+- type: entity
+ parent: IDCardStandard
+ id: PsychologistIDCard
+ name: psychologist ID card
+ components:
+ - type: Sprite
+ layers:
+ - state: idpsychologist
+ - type: PresetIdCard
+ job: Psychologist
+
+- type: entity
+ parent: IDCardStandard
+ id: ReporterIDCard
+ name: reporter ID card
+ components:
+ - type: Sprite
+ layers:
+ - state: idreporter
+ - type: PresetIdCard
+ job: Reporter
diff --git a/Resources/Prototypes/Entities/Objects/Power/powercells.yml b/Resources/Prototypes/Entities/Objects/Power/powercells.yml
index 39960dbe4d..c0bdd68228 100644
--- a/Resources/Prototypes/Entities/Objects/Power/powercells.yml
+++ b/Resources/Prototypes/Entities/Objects/Power/powercells.yml
@@ -1,8 +1,5 @@
-# TODO: Add descriptions (3)
-# Power cells
-
- type: entity
- id: PowerCellSmallBase
+ id: BasePowerCell
abstract: true
parent: BaseItem
components:
@@ -11,6 +8,7 @@
- type: Explosive
explosionType: Default
- type: Sprite
+ sprite: Objects/Power/power_cells.rsi
netsync: false
- type: SolutionContainerManager
solutions:
@@ -28,144 +26,125 @@
- type: Tag
tags:
- DroneUsable
-
-- type: entity
- id: PowerCellMediumBase
- abstract: true
- parent: PowerCellSmallBase
- components:
- - type: PowerCell
- cellSize: Medium
-
-- type: entity
- id: PowerCellLargeBase
- abstract: true
- parent: PowerCellSmallBase
- components:
- - type: PowerCell
- cellSize: Large
+ - type: Appearance
+ - type: PowerCellVisuals
- type: entity
name: potato battery
- description: Someone's stuck two nails and some wire in a large potato. Somehow it provides a little charge. You might be able to cram it into an M-sized slot.
- id: PowerCellMediumPotato
- parent: PowerCellMediumBase
+ description: Someone's stuck two nails and some wire in a large potato. Somehow it provides a little charge.
+ id: PowerCellPotato
+ parent: BasePowerCell
components:
- type: Sprite
- sprite: Objects/Power/PowerCells/potato_battery.rsi
layers:
- - state: potato_battery
+ - state: potato
- type: Battery
- maxCharge: 360
- startingCharge: 360
+ maxCharge: 200
+ startingCharge: 200
- type: entity
- name: small standard power cell
- description: A rechargeable standardized power cell, size S. This is the cheapest kind you can find.
- id: PowerCellSmallStandard
+ name: small-capacity power cell
+ description: A rechargeable power cell. This is the cheapest kind you can find.
+ id: PowerCellSmall
suffix: Full
- parent: PowerCellSmallBase
+ parent: BasePowerCell
components:
- type: Sprite
- sprite: Objects/Power/PowerCells/power_cell_small_st.rsi
layers:
- - state: s_st
+ - map: [ "enum.PowerCellVisualLayers.Base" ]
+ state: small
+ - map: [ "enum.PowerCellVisualLayers.Unshaded" ]
+ state: o2
+ shader: unshaded
- type: Battery
maxCharge: 360
startingCharge: 360
- - type: Appearance
- visuals:
- - type: PowerCellVisualizer
- prefix: s_st
- type: entity
- id: PowerCellSmallStandardPrinted
+ id: PowerCellSmallPrinted
suffix: Empty
- parent: PowerCellSmallStandard
+ parent: PowerCellSmall
components:
- type: Battery
maxCharge: 360
startingCharge: 0
- type: entity
- name: small high-capacity power cell
- description: A rechargeable standardized power cell, size S. This is the popular and reliable version.
- id: PowerCellSmallHigh
+ name: medium-capacity power cell
+ description: A rechargeable power cell. This is the popular and reliable version.
+ id: PowerCellMedium
suffix: Full
- parent: PowerCellSmallBase
+ parent: BasePowerCell
components:
- type: Sprite
- sprite: Objects/Power/PowerCells/power_cell_small_hi.rsi
layers:
- - state: s_hi
+ - map: [ "enum.PowerCellVisualLayers.Base" ]
+ state: medium
+ - map: [ "enum.PowerCellVisualLayers.Unshaded" ]
+ state: o2
+ shader: unshaded
- type: Battery
maxCharge: 720
startingCharge: 720
- - type: Appearance
- visuals:
- - type: PowerCellVisualizer
- prefix: s_hi
- type: entity
- id: PowerCellSmallHighPrinted
+ id: PowerCellMediumPrinted
suffix: Empty
- parent: PowerCellSmallHigh
+ parent: PowerCellMedium
components:
- type: Battery
maxCharge: 720
startingCharge: 0
- type: entity
- name: small super-capacity power cell
- description: A rechargeable standardized power cell, size S. This premium high-capacity brand stores up to 50% more energy than the competition.
- id: PowerCellSmallSuper
+ name: high-capacity power cell
+ description: A rechargeable standardized power cell. This premium brand stores up to 50% more energy than the competition.
+ id: PowerCellHigh
suffix: Full
- parent: PowerCellSmallBase
+ parent: BasePowerCell
components:
- type: Sprite
- sprite: Objects/Power/PowerCells/power_cell_small_sup.rsi
layers:
- - state: s_sup
+ - map: [ "enum.PowerCellVisualLayers.Base" ]
+ state: high
+ - map: [ "enum.PowerCellVisualLayers.Unshaded" ]
+ state: o2
+ shader: unshaded
- type: Battery
maxCharge: 1080
startingCharge: 1080
- - type: Appearance
- visuals:
- - type: PowerCellVisualizer
- prefix: s_sup
- type: entity
- id: PowerCellSmallSuperPrinted
+ id: PowerCellHighPrinted
suffix: Empty
- parent: PowerCellSmallSuper
+ parent: PowerCellHigh
components:
- type: Battery
maxCharge: 1080
startingCharge: 0
- type: entity
- name: small hyper-capacity power cell
- description: A rechargeable standardized power cell, size S. This one looks like a rare and powerful prototype.
- id: PowerCellSmallHyper
+ name: hyper-capacity power cell
+ description: A rechargeable standardized power cell. This one looks like a rare and powerful prototype.
+ id: PowerCellHyper
suffix: Full
- parent: PowerCellSmallBase
+ parent: BasePowerCell
components:
- type: Sprite
- sprite: Objects/Power/PowerCells/power_cell_small_hy.rsi
layers:
- - state: s_hy
+ - map: [ "enum.PowerCellVisualLayers.Base" ]
+ state: hyper
+ - map: [ "enum.PowerCellVisualLayers.Unshaded" ]
+ state: o2
+ shader: unshaded
- type: Battery
maxCharge: 1800
startingCharge: 1800
- - type: Appearance
- visuals:
- - type: PowerCellVisualizer
- prefix: s_hy
- type: entity
- id: PowerCellSmallHyperPrinted
+ id: PowerCellHyperPrinted
suffix: Empty
- parent: PowerCellSmallHyper
+ parent: PowerCellHyper
components:
- type: Battery
maxCharge: 1800
@@ -173,289 +152,41 @@
- type: entity
name: small microreactor cell
- description: A rechargeable standardized microreactor cell, size S. Intended for low-power devices, it slowly recharges by itself.
- id: PowerCellSmallAutorecharge
+ description: A rechargeable standardized microreactor cell. Intended for low-power devices, it slowly recharges by itself.
+ id: PowerCellMicroreactor
suffix: Full
- parent: PowerCellSmallBase
+ parent: BasePowerCell
components:
- type: Sprite
- sprite: Objects/Power/PowerCells/power_cell_small_autorecharge.rsi
layers:
- - state: s_ar
+ - map: [ "enum.PowerCellVisualLayers.Base" ]
+ state: microreactor
+ - map: [ "enum.PowerCellVisualLayers.Unshaded" ]
+ state: o2
+ shader: unshaded
- type: Battery
maxCharge: 50
startingCharge: 50
- type: BatterySelfRecharger
autoRecharge: true
autoRechargeRate: 0.16667 #takes about 5 minutes to charge itself back to full
- - type: Appearance
- visuals:
- - type: PowerCellVisualizer
- prefix: s_ar
-
-- type: entity
- name: hardsuit helmet power cell
- description: A small cell that recharges itself intended for hardsuit helmets.
- id: PowerCellHardsuitHelmet
- suffix: Full
- parent: PowerCellSmallBase
- components:
- - type: Sprite
- sprite: Objects/Power/PowerCells/power_cell_small_autorecharge.rsi
- layers:
- - state: s_ar
- - type: Battery
- maxCharge: 600 #lights drain 3/s but recharge of 2 makes this 1/s. Therefore 600 is 10 minutes of light.
- startingCharge: 600
- - type: BatterySelfRecharger
- autoRecharge: true
- autoRechargeRate: 2 #recharge of 2 makes total drain 1w / s so max charge is 1:1 with time. Time to fully charge should be 5 minutes. Having recharge gives light an extended flicker period which gives you some warning to return to light area.
- - type: Appearance
- visuals:
- - type: PowerCellVisualizer
- prefix: s_ar
- type: entity
name: antique power cell prototype
description: A small cell that self recharges. Used in old laser arms research.
id: PowerCellAntiqueProto
- parent: PowerCellSmallBase
+ parent: BasePowerCell
components:
- type: Sprite
- sprite: Objects/Power/PowerCells/power_cell_small_autorecharge.rsi
layers:
- - state: s_ar
+ - map: [ "enum.PowerCellVisualLayers.Base" ]
+ state: antique
+ - map: [ "enum.PowerCellVisualLayers.Unshaded" ]
+ state: o2
+ shader: unshaded
- type: Battery
maxCharge: 1200
startingCharge: 1200
- type: BatterySelfRecharger
autoRecharge: true
autoRechargeRate: 40
- - type: Appearance
- visuals:
- - type: PowerCellVisualizer
- prefix: s_ar
-
-- type: entity
- name: medium standard power cell
- description: A rechargeable standardized power cell, size M. This is the cheapest kind you can find.
- id: PowerCellMediumStandard
- suffix: Full
- parent: PowerCellMediumBase
- components:
- - type: Sprite
- sprite: Objects/Power/PowerCells/power_cell_medium_st.rsi
- layers:
- - state: m_st
- - type: Battery
- maxCharge: 2160
- startingCharge: 2160
- - type: Appearance
- visuals:
- - type: PowerCellVisualizer
- prefix: m_st
-
-- type: entity
- id: PowerCellMediumStandardPrinted
- suffix: Empty
- parent: PowerCellMediumStandard
- components:
- - type: Battery
- maxCharge: 2160
- startingCharge: 0
-
-- type: entity
- name: medium high-capacity power cell
- description: A rechargeable standardized power cell, size M. This is the popular and reliable version.
- id: PowerCellMediumHigh
- suffix: Full
- parent: PowerCellMediumBase
- components:
- - type: Sprite
- sprite: Objects/Power/PowerCells/power_cell_medium_hi.rsi
- layers:
- - state: m_hi
- - type: Battery
- maxCharge: 2880
- startingCharge: 2880
- - type: Appearance
- visuals:
- - type: PowerCellVisualizer
- prefix: m_hi
-
-- type: entity
- id: PowerCellMediumHighPrinted
- suffix: Empty
- parent: PowerCellMediumHigh
- components:
- - type: Battery
- maxCharge: 2880
- startingCharge: 0
-
-- type: entity
- name: medium super-capacity power cell
- description: A rechargeable standardized power cell, size M. This premium high-capacity brand stores up to 50% more energy than the competition.
- id: PowerCellMediumSuper
- suffix: Full
- parent: PowerCellMediumBase
- components:
- - type: Sprite
- sprite: Objects/Power/PowerCells/power_cell_medium_sup.rsi
- layers:
- - state: m_sup
- - type: Battery
- maxCharge: 3600
- startingCharge: 3600
- - type: Appearance
- visuals:
- - type: PowerCellVisualizer
- prefix: m_sup
-
-- type: entity
- id: PowerCellMediumSuperPrinted
- suffix: Empty
- parent: PowerCellMediumSuper
- components:
- - type: Battery
- maxCharge: 3600
- startingCharge: 0
-
-- type: entity
- name: medium hyper-capacity power cell
- description: A rechargeable standardized power cell, size M. This one looks like a rare and powerful prototype.
- id: PowerCellMediumHyper
- suffix: Full
- parent: PowerCellMediumBase
- components:
- - type: Sprite
- sprite: Objects/Power/PowerCells/power_cell_medium_hy.rsi
- layers:
- - state: m_hy
- - type: Battery
- maxCharge: 5400
- startingCharge: 5400
- - type: Appearance
- visuals:
- - type: PowerCellVisualizer
- prefix: m_hy
-
-- type: entity
- id: PowerCellMediumHyperPrinted
- suffix: Empty
- parent: PowerCellMediumHyper
- components:
- - type: Battery
- maxCharge: 5400
- startingCharge: 0
-
-- type: entity
- name: large standard power cell
- description: A rechargeable standardized power cell, size L. This is the cheapest kind you can find.
- id: PowerCellLargeStandard
- suffix: Full
- parent: PowerCellLargeBase
- components:
- - type: Sprite
- sprite: Objects/Power/PowerCells/power_cell_large_st.rsi
- layers:
- - state: l_st
- - type: Battery
- maxCharge: 9000
- startingCharge: 9000
- - type: Appearance
- visuals:
- - type: PowerCellVisualizer
- prefix: l_st
-
-- type: entity
- id: PowerCellLargeStandardPrinted
- suffix: Empty
- parent: PowerCellLargeStandard
- components:
- - type: Battery
- maxCharge: 9000
- startingCharge: 0
-
-- type: entity
- name: large high-capacity power cell
- description: A rechargeable standardized power cell, size L. This is the popular and reliable version.
- id: PowerCellLargeHigh
- suffix: Full
- parent: PowerCellLargeBase
- components:
- - type: Sprite
- sprite: Objects/Power/PowerCells/power_cell_large_hi.rsi
- layers:
- - state: l_hi
- - type: Battery
- maxCharge: 18000
- startingCharge: 18000
- - type: Appearance
- visuals:
- - type: PowerCellVisualizer
- prefix: l_hi
-
-- type: entity
- id: PowerCellLargeHighPrinted
- suffix: Empty
- parent: PowerCellLargeHigh
- components:
- - type: Battery
- maxCharge: 18000
- startingCharge: 0
-
-- type: entity
- name: large super-capacity power cell
- description: A rechargeable standardized power cell, size M. This premium high-capacity brand stores up to 50% more energy than the competition.
- id: PowerCellLargeSuper
- suffix: Full
- parent: PowerCellLargeBase
- components:
- - type: Sprite
- sprite: Objects/Power/PowerCells/power_cell_large_sup.rsi
- layers:
- - state: l_sup
- - type: Battery
- maxCharge: 54000
- startingCharge: 54000
- - type: Appearance
- visuals:
- - type: PowerCellVisualizer
- prefix: l_sup
-
-- type: entity
- id: PowerCellLargeSuperPrinted
- suffix: Empty
- parent: PowerCellLargeSuper
- components:
- - type: Battery
- maxCharge: 54000
- startingCharge: 0
-
-- type: entity
- name: large hyper-capacity power cell
- description: A rechargeable standardized power cell, size L. This one looks like a rare and powerful prototype.
- id: PowerCellLargeHyper
- suffix: Full
- parent: PowerCellLargeBase
- components:
- - type: Sprite
- sprite: Objects/Power/PowerCells/power_cell_large_hy.rsi
- layers:
- - state: l_hy
- - type: Battery
- maxCharge: 72000
- startingCharge: 72000
- - type: Appearance
- visuals:
- - type: PowerCellVisualizer
- prefix: l_hy
-
-- type: entity
- id: PowerCellLargeHyperPrinted
- suffix: Empty
- parent: PowerCellLargeHyper
- components:
- - type: Battery
- maxCharge: 72000
- startingCharge: 0
diff --git a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml
index d20509f1e7..0f2a23b7aa 100644
--- a/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml
+++ b/Resources/Prototypes/Entities/Objects/Specific/Janitorial/janitor.yml
@@ -52,7 +52,6 @@
- Wringer
- type: Physics
bodyType: Dynamic
- fixedRotation: false
- type: Transform
noRot: true
- type: Fixtures
diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml
index 8e6a5994f5..3c141613c7 100644
--- a/Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml
+++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/morgue.yml
@@ -27,7 +27,6 @@
- type: MovedByPressure
- type: Physics
bodyType: Dynamic
- fixedRotation: false
- type: Transform
noRot: true
- type: Fixtures
@@ -61,6 +60,7 @@
key: bag
- type: BodyBagVisualizer
- type: Pullable
+ - type: AntiRottingContainer
- type: entity
id: BodyBag_Folded
diff --git a/Resources/Prototypes/Entities/Objects/Tools/flashlights.yml b/Resources/Prototypes/Entities/Objects/Tools/flashlights.yml
index 09e1c9286b..169aa54bf5 100644
--- a/Resources/Prototypes/Entities/Objects/Tools/flashlights.yml
+++ b/Resources/Prototypes/Entities/Objects/Tools/flashlights.yml
@@ -27,7 +27,7 @@
shader: unshaded
- type: PowerCellSlot
cellSlot:
- startingItem: PowerCellSmallHigh
+ startingItem: PowerCellMedium
- type: ContainerContainer
containers:
cell_slot: !type:ContainerSlot
@@ -60,7 +60,7 @@
components:
- type: PowerCellSlot
cellSlot:
- startingItem: PowerCellSmallSuper
+ startingItem: PowerCellHigh
- type: HandheldLight
addPrefix: false
inhandVisuals:
diff --git a/Resources/Prototypes/Entities/Objects/Tools/lantern.yml b/Resources/Prototypes/Entities/Objects/Tools/lantern.yml
index 38f5483862..0912343c70 100644
--- a/Resources/Prototypes/Entities/Objects/Tools/lantern.yml
+++ b/Resources/Prototypes/Entities/Objects/Tools/lantern.yml
@@ -29,7 +29,7 @@
- type: ToggleableLightVisuals
- type: PowerCellSlot
cellSlot:
- startingItem: PowerCellSmallHigh
+ startingItem: PowerCellMedium
- type: entity
name: extra-bright lantern
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/antimaterial.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/antimaterial.yml
index 91d687a2ab..5c9e7a8434 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/antimaterial.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/antimaterial.yml
@@ -7,4 +7,4 @@
- type: Projectile
damage:
types:
- Piercing: 70
+ Piercing: 49
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/caseless_rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/caseless_rifle.yml
index 9f69a54076..2e81e92300 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/caseless_rifle.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/caseless_rifle.yml
@@ -7,7 +7,7 @@
- type: Projectile
damage:
types:
- Piercing: 27
+ Piercing: 19
- type: entity
id: BulletCaselessRifleFlash
@@ -29,7 +29,7 @@
- type: Projectile
damage:
types:
- Piercing: 32
+ Piercing: 22
- type: entity
id: BulletCaselessRiflePractice
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/heavy_rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/heavy_rifle.yml
index aa6531f8eb..be6a07e486 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/heavy_rifle.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/heavy_rifle.yml
@@ -7,7 +7,7 @@
- type: Projectile
damage:
types:
- Piercing: 28
+ Piercing: 19
- type: entity
id: BulletMinigun
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/light_rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/light_rifle.yml
index b3205f47f1..4cc3a4f46f 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/light_rifle.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/light_rifle.yml
@@ -7,7 +7,7 @@
- type: Projectile
damage:
types:
- Piercing: 28
+ Piercing: 19
- type: entity
id: BulletLightRifleFlash
@@ -29,7 +29,7 @@
- type: Projectile
damage:
types:
- Piercing: 30
+ Piercing: 21
- type: entity
id: BulletLightRiflePractice
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/magnum.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/magnum.yml
index 237d2c7dee..fd729cb6f5 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/magnum.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/magnum.yml
@@ -7,7 +7,7 @@
- type: Projectile
damage:
types:
- Piercing: 32
+ Piercing: 22
- type: entity
id: BulletMagnumFlash
@@ -29,7 +29,7 @@
- type: Projectile
damage:
types:
- Piercing: 35
+ Piercing: 24
- type: entity
id: BulletMagnumPractice
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/pistol.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/pistol.yml
index 6d99884f3a..c9a5e0565b 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/pistol.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/pistol.yml
@@ -7,7 +7,7 @@
- type: Projectile
damage:
types:
- Piercing: 24
+ Piercing: 16
- type: entity
id: BulletPistolFlash
@@ -29,7 +29,7 @@
- type: Projectile
damage:
types:
- Piercing: 28
+ Piercing: 19
- type: entity
id: BulletPistolPractice
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/rifle.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/rifle.yml
index af1a23a443..6e9a5873e5 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/rifle.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/rifle.yml
@@ -7,7 +7,7 @@
- type: Projectile
damage:
types:
- Piercing: 25
+ Piercing: 17
- type: entity
id: BulletRifleFlash
@@ -29,7 +29,7 @@
- type: Projectile
damage:
types:
- Piercing: 30
+ Piercing: 21
- type: entity
id: BulletRiflePractice
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/shotgun.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/shotgun.yml
index d00d8a3115..d596111e4a 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/shotgun.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Projectiles/shotgun.yml
@@ -10,7 +10,7 @@
- type: Projectile
damage:
types:
- Piercing: 8 # Should have the same or less damage than a regular pellet
+ Piercing: 5 # Should have the same or less damage than a regular pellet
- type: entity
id: PelletShotgunBeanbag
@@ -41,7 +41,7 @@
- type: Projectile
damage:
types:
- Piercing: 8
+ Piercing: 5
- type: entity
id: PelletShotgunFlash
@@ -55,7 +55,7 @@
- type: Projectile
damage:
types:
- Blunt: 3
+ Blunt: 2
- type: entity
id: PelletShotgunIncendiary
@@ -69,7 +69,7 @@
- type: Projectile
damage:
groups:
- Burn: 10
+ Burn: 7
- type: PointLight
enabled: true
color: "#ff4300"
@@ -130,7 +130,7 @@
- type: Projectile
damage:
groups:
- Burn: 20
+ Burn: 14
- type: PointLight
enabled: true
color: "#FF8080"
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/explosives.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/explosives.yml
index 6a6e3d07e0..74fd97b508 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/explosives.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/explosives.yml
@@ -89,7 +89,7 @@
- type: entity
id: GrenadeFlash
name: flash grenade
- parent: BaseItem
+ parent: BaseGrenade
components:
- type: CartridgeAmmo
proto: BulletGrenadeFlash
@@ -106,7 +106,7 @@
- type: entity
id: GrenadeFrag
name: frag grenade
- parent: BaseItem
+ parent: BaseGrenade
components:
- type: CartridgeAmmo
proto: BulletGrenadeFrag
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml
index 6fd04b32f3..89d3cb51c3 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml
@@ -24,6 +24,14 @@
zeroVisible: false
- type: Appearance
+- type: entity
+ id: BaseWeaponBatterySmall
+ parent: BaseWeaponBattery
+ abstract: true
+ components:
+ - type: Item
+ size: 10
+
- type: entity
name: retro laser gun
parent: BaseWeaponBattery
@@ -101,7 +109,7 @@
- type: entity
name: pulse pistol
- parent: BaseWeaponBattery
+ parent: BaseWeaponBatterySmall
id: WeaponPulsePistol
description: A state of the art energy pistol favoured as a sidearm by the NT-ERT operatives.
components:
@@ -143,7 +151,6 @@
map: ["enum.GunVisualLayers.MagUnshaded"]
shader: unshaded
- type: Item
- size: 10
sprite: Objects/Weapons/Guns/Battery/pulse_carbine.rsi
- type: Gun
selectedMode: SemiAuto
@@ -280,7 +287,7 @@
- type: entity
name: antique laser gun
- parent: BaseWeaponBattery
+ parent: BaseWeaponBatterySmall
id: WeaponAntiqueLaser
description: This is an antique laser gun. All craftsmanship is of the highest quality. It is decorated with assistant leather and chrome. The object menaces with spikes of energy.
components:
@@ -300,6 +307,9 @@
- type: HitscanBatteryAmmoProvider
proto: RedMediumLaser
fireCost: 100
+ - type: BatterySelfRecharger
+ autoRecharge: true
+ autoRechargeRate: 40
- type: MagazineVisuals
magState: mag
steps: 5
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/LMGs/lmgs.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/LMGs/lmgs.yml
index 8af13cb566..7885dabe27 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/LMGs/lmgs.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/LMGs/lmgs.yml
@@ -31,12 +31,14 @@
startingItem: MagazineLightRifleBox
insertSound: /Audio/Weapons/Guns/MagIn/batrifle_magin.ogg
ejectSound: /Audio/Weapons/Guns/MagOut/batrifle_magout.ogg
+ priority: 2
whitelist:
tags:
- MagazineLightRifleBox
gun_chamber:
name: Chamber
startingItem: CartridgeLightRifle
+ priority: 1
whitelist:
tags:
- CartridgeLightRifle
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Pistols/pistols.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Pistols/pistols.yml
index d8585507b0..66e63fd55c 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Pistols/pistols.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Pistols/pistols.yml
@@ -15,7 +15,7 @@
- type: Item
size: 10
- type: Gun
- fireRate: 8
+ fireRate: 6
selectedMode: SemiAuto
availableModes:
- SemiAuto
@@ -29,12 +29,14 @@
startingItem: MagazinePistol
insertSound: /Audio/Weapons/Guns/MagIn/pistol_magin.ogg
ejectSound: /Audio/Weapons/Guns/MagOut/pistol_magout.ogg
+ priority: 2
whitelist:
tags:
- MagazinePistol
gun_chamber:
name: Chamber
startingItem: CartridgePistol
+ priority: 1
whitelist:
tags:
- CartridgePistol
@@ -65,6 +67,7 @@
startingItem: MagazinePistol
insertSound: /Audio/Weapons/Guns/MagIn/pistol_magin.ogg
ejectSound: /Audio/Weapons/Guns/MagOut/pistol_magout.ogg
+ priority: 2
whitelist:
tags:
- MagazinePistol
@@ -72,6 +75,7 @@
gun_chamber:
name: Chamber
startingItem: CartridgePistol
+ priority: 1
whitelist:
tags:
- CartridgePistol
@@ -114,6 +118,7 @@
- type: Item
sprite: Objects/Weapons/Guns/Pistols/cobra.rsi
- type: Gun
+ fireRate: 4
soundGunshot:
path: /Audio/Weapons/Guns/Gunshots/silenced.ogg
- type: ItemSlots
@@ -123,12 +128,14 @@
startingItem: MagazinePistolCaselessRifle
insertSound: /Audio/Weapons/Guns/MagIn/pistol_magin.ogg
ejectSound: /Audio/Weapons/Guns/MagOut/pistol_magout.ogg
+ priority: 2
whitelist:
tags:
- MagazinePistolCaselessRifle
gun_chamber:
name: Chamber
startingItem: CartridgeCaselessRifle
+ priority: 1
whitelist:
tags:
- CartridgeCaselessRifle
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/hitscan.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/hitscan.yml
index 1491cdafb3..3cfe06efcb 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/hitscan.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/hitscan.yml
@@ -16,7 +16,7 @@
id: RedLaser
damage:
types:
- Heat: 20
+ Heat: 14
muzzleFlash:
sprite: Objects/Weapons/Guns/Projectiles/projectiles.rsi
state: muzzle_laser
@@ -31,7 +31,7 @@
id: RedMediumLaser
damage:
types:
- Heat: 25
+ Heat: 17
muzzleFlash:
sprite: Objects/Weapons/Guns/Projectiles/projectiles.rsi
state: muzzle_laser
@@ -46,7 +46,7 @@
id: OmniLaser
damage:
types:
- Heat: 30
+ Heat: 21
muzzleFlash:
sprite: Objects/Weapons/Guns/Projectiles/projectiles.rsi
state: muzzle_omni
@@ -61,8 +61,8 @@
id: XrayLaser
damage:
types:
- Heat: 15
- Radiation: 15
+ Heat: 10
+ Radiation: 10
muzzleFlash:
sprite: Objects/Weapons/Guns/Projectiles/projectiles.rsi
state: muzzle_xray
@@ -77,7 +77,7 @@
id: RedHeavyLaser
damage:
types:
- Heat: 40
+ Heat: 28
muzzleFlash:
sprite: Objects/Weapons/Guns/Projectiles/projectiles.rsi
state: muzzle_beam_heavy
@@ -92,7 +92,7 @@
id: Pulse
damage:
types:
- Heat: 50
+ Heat: 35
muzzleFlash:
sprite: Objects/Weapons/Guns/Projectiles/projectiles.rsi
state: muzzle_blue
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/meteors.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/meteors.yml
index a611750c84..d655388c4d 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/meteors.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/meteors.yml
@@ -25,7 +25,6 @@
maxIntensity: 45
- type: Physics
bodyType: Dynamic
- fixedRotation: false
- type: Fixtures
fixtures:
- shape:
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml
index 9fbf0b2d5f..534a5ae7b2 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/projectiles.yml
@@ -31,7 +31,7 @@
- type: Projectile
damage:
types:
- Piercing: 20
+ Piercing: 14
soundHit:
path: /Audio/Weapons/Guns/Hits/bullet_hit.ogg
@@ -81,7 +81,7 @@
- type: Projectile
damage:
types:
- Piercing: 12
+ Piercing: 17
- type: entity
id: BaseBulletPractice
@@ -179,7 +179,7 @@
- type: Projectile
damage:
types:
- Heat: 20
+ Heat: 14
- type: Tag
tags:
- EmitterBolt
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Rifles/rifles.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Rifles/rifles.yml
index e36cca86e1..510e532bd9 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Rifles/rifles.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Rifles/rifles.yml
@@ -25,12 +25,14 @@
startingItem: MagazineLightRifle
insertSound: /Audio/Weapons/Guns/MagIn/batrifle_magin.ogg
ejectSound: /Audio/Weapons/Guns/MagOut/batrifle_magout.ogg
+ priority: 2
whitelist:
tags:
- MagazineLightRifle
gun_chamber:
name: Chamber
startingItem: CartridgeLightRifle
+ priority: 1
whitelist:
tags:
- CartridgeLightRifle
@@ -66,12 +68,14 @@
startingItem: MagazineLightRifle
insertSound: /Audio/Weapons/Guns/MagIn/ltrifle_magin.ogg
ejectSound: /Audio/Weapons/Guns/MagOut/ltrifle_magout.ogg
+ priority: 2
whitelist:
tags:
- MagazineLightRifle
gun_chamber:
name: Chamber
startingItem: CartridgeLightRifle
+ priority: 1
whitelist:
tags:
- CartridgeLightRifle
@@ -107,12 +111,14 @@
startingItem: MagazineRifle
insertSound: /Audio/Weapons/Guns/MagIn/batrifle_magin.ogg
ejectSound: /Audio/Weapons/Guns/MagOut/batrifle_magout.ogg
+ priority: 2
whitelist:
tags:
- MagazineRifle
gun_chamber:
name: Chamber
startingItem: CartridgeRifle
+ priority: 1
whitelist:
tags:
- CartridgeRifle
@@ -151,12 +157,14 @@
startingItem: MagazineRifle
insertSound: /Audio/Weapons/Guns/MagIn/ltrifle_magin.ogg
ejectSound: /Audio/Weapons/Guns/MagOut/ltrifle_magout.ogg
+ priority: 2
whitelist:
tags:
- MagazineRifle
gun_chamber:
name: Chamber
startingItem: CartridgeRifle
+ priority: 1
whitelist:
tags:
- CartridgeRifle
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml
index 17bf1371ba..2ad36f7f6c 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/SMGs/smgs.yml
@@ -28,12 +28,14 @@
startingItem: MagazinePistolSubMachineGun
insertSound: /Audio/Weapons/Guns/MagIn/smg_magin.ogg
ejectSound: /Audio/Weapons/Guns/MagOut/smg_magout.ogg
+ priority: 2
whitelist:
tags:
- MagazinePistolSubMachineGun
gun_chamber:
name: Chamber
startingItem: CartridgePistol
+ priority: 1
whitelist:
tags:
- CartridgePistol
@@ -116,12 +118,14 @@
startingItem: MagazineMagnumSubMachineGun
insertSound: /Audio/Weapons/Guns/MagIn/smg_magin.ogg
ejectSound: /Audio/Weapons/Guns/MagOut/smg_magout.ogg
+ priority: 2
whitelist:
tags:
- MagazineMagnumSubMachineGun
gun_chamber:
name: Chamber
startingItem: CartridgeMagnum
+ priority: 1
whitelist:
tags:
- CartridgeMagnum
@@ -168,12 +172,14 @@
startingItem: MagazinePistolSubMachineGunTopMounted
insertSound: /Audio/Weapons/Guns/MagIn/smg_magin.ogg
ejectSound: /Audio/Weapons/Guns/MagOut/smg_magout.ogg
+ priority: 2
whitelist:
tags:
- MagazinePistolSubMachineGunTopMounted
gun_chamber:
name: Chamber
startingItem: CartridgePistol
+ priority: 1
whitelist:
tags:
- CartridgePistol
@@ -197,12 +203,14 @@
startingItem: MagazineMagnumSubMachineGunRubber
insertSound: /Audio/Weapons/Guns/MagIn/smg_magin.ogg
ejectSound: /Audio/Weapons/Guns/MagOut/smg_magout.ogg
+ priority: 2
whitelist:
tags:
- MagazineMagnumSubMachineGun
gun_chamber:
name: Chamber
startingItem: CartridgeMagnumRubber
+ priority: 1
whitelist:
tags:
- CartridgeMagnum
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Shotguns/shotguns.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Shotguns/shotguns.yml
index a210f7c847..a59d2bb917 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Shotguns/shotguns.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Shotguns/shotguns.yml
@@ -63,6 +63,7 @@
gun_magazine:
name: Magazine
startingItem: MagazineShotgun
+ priority: 2
whitelist:
tags:
- MagazineShotgun
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml
index b31075c040..848b95003a 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml
@@ -10,6 +10,7 @@
Slash: 12.5
Heat: 12.5
Blunt: -7
+ litDisarmMalus: 0.6
- type: Sharp
- type: Sprite
sprite: Objects/Weapons/Melee/e_sword.rsi
@@ -47,6 +48,8 @@
right:
- state: inhand-right-blade
shader: unshaded
+ - type: DisarmMalus
+ malus: 0
- type: entity
name: pen
@@ -61,6 +64,7 @@
Slash: 7.5
Heat: 7.5
Blunt: -1
+ litDisarmMalus: 0.4
- type: Sprite
sprite: Objects/Weapons/Melee/e_dagger.rsi
layers:
@@ -98,3 +102,5 @@
- type: Tag
tags:
- Write
+ - type: DisarmMalus
+ malus: 0
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/knife.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/knife.yml
index 476ece58d7..ea6799758e 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/knife.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/knife.yml
@@ -89,6 +89,8 @@
size: 10
sprite: Objects/Weapons/Melee/combat_knife.rsi
prefix: inhand
+ - type: DisarmMalus
+ malus: 0.225
- type: entity
name: survival knife
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/sword.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/sword.yml
index ef734865a3..f44fda2571 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/sword.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/sword.yml
@@ -18,6 +18,7 @@
- type: Tag
tags:
- CaptainSabre
+ - type: DisarmMalus
- type: entity
name: katana
@@ -39,6 +40,7 @@
- type: Item
size: 15
sprite: Objects/Weapons/Melee/katana.rsi
+ - type: DisarmMalus
- type: entity
name: machete
@@ -60,6 +62,7 @@
- type: Item
size: 15
sprite: Objects/Weapons/Melee/machete.rsi
+ - type: DisarmMalus
- type: entity
name: claymore
@@ -80,3 +83,4 @@
sprite: Objects/Weapons/Melee/claymore.rsi
Slots:
- back
+ - type: DisarmMalus
diff --git a/Resources/Prototypes/Entities/Objects/Weapons/security.yml b/Resources/Prototypes/Entities/Objects/Weapons/security.yml
index 1bac5df766..3db6c2463d 100644
--- a/Resources/Prototypes/Entities/Objects/Weapons/security.yml
+++ b/Resources/Prototypes/Entities/Objects/Weapons/security.yml
@@ -27,6 +27,8 @@
size: 20
Slots:
- Belt
+ - type: DisarmMalus
+ malus: 0.225
- type: entity
name: flash
diff --git a/Resources/Prototypes/Entities/Objects/base_item.yml b/Resources/Prototypes/Entities/Objects/base_item.yml
index 8498733c36..98b6976d32 100644
--- a/Resources/Prototypes/Entities/Objects/base_item.yml
+++ b/Resources/Prototypes/Entities/Objects/base_item.yml
@@ -21,7 +21,6 @@
modifier: 0.5
- type: Physics
bodyType: Dynamic
- fixedRotation: false
- type: Fixtures
fixtures:
- shape:
diff --git a/Resources/Prototypes/Entities/Structures/Decoration/fireplace.yml b/Resources/Prototypes/Entities/Structures/Decoration/fireplace.yml
index 6273331230..2459c69b53 100644
--- a/Resources/Prototypes/Entities/Structures/Decoration/fireplace.yml
+++ b/Resources/Prototypes/Entities/Structures/Decoration/fireplace.yml
@@ -14,6 +14,6 @@
- state: fireplace_glow
shader: unshaded
- type: PointLight
- radius: 1.5
- energy: 1.6
+ radius: 3
+ energy: 3
color: "#FF6F00"
diff --git a/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml b/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml
index f06a3f9bf6..a4840f2fa6 100644
--- a/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml
+++ b/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml
@@ -11,7 +11,6 @@
- type: InteractionOutline
- type: Physics
bodyType: Static
- fixedRotation: false
- type: Fixtures
fixtures:
- shape:
diff --git a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/access.yml b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/access.yml
index 178cb78d8d..1b56833ff6 100644
--- a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/access.yml
+++ b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/access.yml
@@ -666,3 +666,11 @@
components:
- type: AccessReader
access: [["Captain"]]
+
+- type: entity
+ parent: HighSecDoor
+ id: HighSecArmoryLocked
+ suffix: Armory, Locked
+ components:
+ - type: AccessReader
+ access: [["Armory"]]
diff --git a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/assembly.yml b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/assembly.yml
index 7529eff354..7418ad8dee 100644
--- a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/assembly.yml
+++ b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/assembly.yml
@@ -10,7 +10,6 @@
sprite: Structures/Doors/Airlocks/Standard/basic.rsi
state: "assembly"
- type: Physics
- fixedRotation: false
- type: Fixtures
fixtures:
- shape:
diff --git a/Resources/Prototypes/Entities/Structures/Furniture/instruments.yml b/Resources/Prototypes/Entities/Structures/Furniture/instruments.yml
index 4c7647673a..f321af379f 100644
--- a/Resources/Prototypes/Entities/Structures/Furniture/instruments.yml
+++ b/Resources/Prototypes/Entities/Structures/Furniture/instruments.yml
@@ -9,6 +9,7 @@
allowSpectator: false # otherwise they can play client-side music
inHandsOnly: false
singleUser: true
+ requireHands: true
verbText: verb-instrument-openui
key: enum.InstrumentUiKey.Key
- type: InteractionOutline
diff --git a/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml b/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml
index 76c3cacbf4..2c8bae918e 100644
--- a/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml
+++ b/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml
@@ -20,6 +20,14 @@
abstract: true
components:
- type: ShuttleConsole
+ - type: ActivatableUI
+ key: enum.ShuttleConsoleUiKey.Key
+ - type: ActivatableUIRequiresPower
+ - type: UserInterface
+ interfaces:
+ - key: enum.ShuttleConsoleUiKey.Key
+ type: ShuttleConsoleBoundUserInterface
+ - type: RadarConsole
- type: ExtensionCableReceiver
- type: PointLight
radius: 1.5
@@ -53,6 +61,8 @@
- type: ComputerVisualizer
key: syndie_key
screen: syndishuttle
+ - type: RadarConsole
+ maxRange: 512
- type: PointLight
radius: 1.5
energy: 1.6
diff --git a/Resources/Prototypes/Entities/Structures/Machines/Computers/frame.yml b/Resources/Prototypes/Entities/Structures/Machines/Computers/frame.yml
index 686dcb94ee..365166c4ff 100644
--- a/Resources/Prototypes/Entities/Structures/Machines/Computers/frame.yml
+++ b/Resources/Prototypes/Entities/Structures/Machines/Computers/frame.yml
@@ -6,7 +6,6 @@
components:
- type: Physics
bodyType: Static
- fixedRotation: false
- type: Fixtures
fixtures:
- shape:
diff --git a/Resources/Prototypes/Entities/Structures/Machines/frame.yml b/Resources/Prototypes/Entities/Structures/Machines/frame.yml
index 36ee3bfe95..a4b51770a6 100644
--- a/Resources/Prototypes/Entities/Structures/Machines/frame.yml
+++ b/Resources/Prototypes/Entities/Structures/Machines/frame.yml
@@ -11,7 +11,6 @@
noRot: true
- type: Physics
bodyType: Static
- fixedRotation: false
- type: Fixtures
fixtures:
- shape:
@@ -59,7 +58,6 @@
noRot: true
- type: Physics
bodyType: Static
- fixedRotation: false
- type: Fixtures
fixtures:
- shape:
@@ -114,8 +112,6 @@
- type: Construction
graph: Machine
node: destroyedMachineFrame
- - type: Physics
- fixedRotation: false
- type: Damageable
damageContainer: Inorganic
damageModifierSet: Metallic
diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml
index 027038a8b4..8b82310d90 100644
--- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml
+++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml
@@ -193,15 +193,9 @@
- FlashPayload
- Signaller
- SignalTrigger
- - PowerCellSmallStandard
- - PowerCellSmallHigh
- - PowerCellSmallSuper
- - PowerCellMediumStandard
- - PowerCellMediumHigh
- - PowerCellMediumSuper
- - PowerCellLargeStandard
- - PowerCellLargeHigh
- - PowerCellLargeSuper
+ - PowerCellSmall
+ - PowerCellMedium
+ - PowerCellHigh
- type: ActivatableUI
key: enum.LatheUiKey.Key #Yes only having 1 of them here doesn't break anything
- type: ActivatableUIRequiresPower
diff --git a/Resources/Prototypes/Entities/Structures/Piping/Disposal/high_pressure_machine_frame.yml b/Resources/Prototypes/Entities/Structures/Piping/Disposal/high_pressure_machine_frame.yml
index 43cb3bfee2..82373b19a8 100644
--- a/Resources/Prototypes/Entities/Structures/Piping/Disposal/high_pressure_machine_frame.yml
+++ b/Resources/Prototypes/Entities/Structures/Piping/Disposal/high_pressure_machine_frame.yml
@@ -10,7 +10,6 @@
noRot: true
- type: Physics
bodyType: Static
- fixedRotation: false
- type: Fixtures
fixtures:
- shape:
diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/PA/base_particleaccelerator.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/PA/base_particleaccelerator.yml
index f984fad200..e29b50743d 100644
--- a/Resources/Prototypes/Entities/Structures/Power/Generation/PA/base_particleaccelerator.yml
+++ b/Resources/Prototypes/Entities/Structures/Power/Generation/PA/base_particleaccelerator.yml
@@ -9,7 +9,6 @@
- type: Rotatable
- type: Physics
bodyType: Static
- fixedRotation: false
- type: Fixtures
fixtures:
- shape:
diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/collector.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/collector.yml
index e07d42d2db..08e3bf0530 100644
--- a/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/collector.yml
+++ b/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/collector.yml
@@ -9,7 +9,6 @@
- type: InteractionOutline
- type: Physics
bodyType: Static
- fixedRotation: false
- type: Fixtures
fixtures:
- shape:
diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/emitter.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/emitter.yml
index ece4e2d167..f430c6d5cd 100644
--- a/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/emitter.yml
+++ b/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/emitter.yml
@@ -9,7 +9,6 @@
- type: InteractionOutline
- type: Physics
bodyType: Static
- fixedRotation: false
- type: Fixtures
fixtures:
- shape:
@@ -75,4 +74,4 @@
graph: Machine
node: machine
- type: Machine
- board: EmitterCircuitboard
\ No newline at end of file
+ board: EmitterCircuitboard
diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/generator.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/generator.yml
index ef70b21dc2..16f2f5eca9 100644
--- a/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/generator.yml
+++ b/Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/generator.yml
@@ -14,7 +14,6 @@
- type: Clickable
- type: Physics
bodyType: Static
- fixedRotation: false
- type: Fixtures
fixtures:
- shape:
diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/ame.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/ame.yml
index 1c8ca857f2..9df2dcdb41 100644
--- a/Resources/Prototypes/Entities/Structures/Power/Generation/ame.yml
+++ b/Resources/Prototypes/Entities/Structures/Power/Generation/ame.yml
@@ -11,7 +11,6 @@
sprite: Structures/Power/Generation/ame.rsi
state: control
- type: Physics
- fixedRotation: false
- type: Fixtures
fixtures:
- shape:
diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/generators.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/generators.yml
index 52b1bfd548..9a659a181f 100644
--- a/Resources/Prototypes/Entities/Structures/Power/Generation/generators.yml
+++ b/Resources/Prototypes/Entities/Structures/Power/Generation/generators.yml
@@ -16,7 +16,6 @@
- type: InteractionOutline
- type: Physics
bodyType: Static
- fixedRotation: false
- type: Fixtures
fixtures:
- shape:
diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/solar.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/solar.yml
index 5fa17d3641..5e5af7e8b4 100644
--- a/Resources/Prototypes/Entities/Structures/Power/Generation/solar.yml
+++ b/Resources/Prototypes/Entities/Structures/Power/Generation/solar.yml
@@ -16,7 +16,6 @@
anchored: true
- type: Physics
bodyType: Static
- fixedRotation: false
- type: Fixtures
fixtures:
- shape:
@@ -111,7 +110,6 @@
- type: InteractionOutline
- type: Physics
bodyType: Static
- fixedRotation: false
- type: Fixtures
fixtures:
- shape:
@@ -155,7 +153,6 @@
- type: InteractionOutline
- type: Physics
bodyType: Static
- fixedRotation: false
- type: Fixtures
fixtures:
- shape:
diff --git a/Resources/Prototypes/Entities/Structures/Storage/Canisters/gas_canisters.yml b/Resources/Prototypes/Entities/Structures/Storage/Canisters/gas_canisters.yml
index bd60492a3f..1a29d4a95a 100644
--- a/Resources/Prototypes/Entities/Structures/Storage/Canisters/gas_canisters.yml
+++ b/Resources/Prototypes/Entities/Structures/Storage/Canisters/gas_canisters.yml
@@ -338,6 +338,43 @@
- !type:DoActsBehavior
acts: [ "Destruction" ]
+- type: entity
+ parent: GasCanister
+ id: MiasmaCanister
+ name: miasma canister
+ components:
+ - type: Sprite
+ state: redws
+ - type: GasCanister
+ gasMixture:
+ volume: 1000
+ moles:
+ - 0 # oxygen
+ - 0 # nitrogen
+ - 0 # CO2
+ - 0 # Plasma
+ - 0 # Tritium
+ - 0 # Water vapor
+ - 1871.71051 # Miasma
+ temperature: 293.15
+ - type: Destructible
+ thresholds:
+ - trigger:
+ !type:DamageTrigger
+ damage: 300
+ behaviors:
+ - !type:PlaySoundBehavior
+ sound:
+ path: /Audio/Effects/metalbreak.ogg
+ - !type:SpawnEntitiesBehavior
+ spawn:
+ MiasmaCanisterBroken:
+ min: 1
+ max: 1
+ - !type:DoActsBehavior
+ acts: [ "Destruction" ]
+
+
# Broke Entities
- type: entity
@@ -453,3 +490,12 @@
components:
- type: Sprite
state: water_vapor-1
+
+- type: entity
+ parent: GasCanisterBrokenBase
+ id: MiasmaCanisterBroken
+ name: broken miasma canister
+ noSpawn: true
+ components:
+ - type: Sprite
+ state: redws-1
diff --git a/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/lockers.yml b/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/lockers.yml
index 705ae11d9b..6e1bfd514a 100644
--- a/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/lockers.yml
+++ b/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/lockers.yml
@@ -47,8 +47,8 @@
state_open: mining_open
state_closed: mining_door
- type: AccessReader
- access: [["Salvage"]]
-
+ access: [["Salvage"]]
+
# Command
- type: entity
id: LockerCaptain
@@ -169,6 +169,7 @@
access: [ [ "Kitchen" ] ]
- type: ExplosionResistance
resistance: 0.90
+ - type: AntiRottingContainer
# Botanist
- type: entity
diff --git a/Resources/Prototypes/Entities/Structures/Storage/morgue.yml b/Resources/Prototypes/Entities/Structures/Storage/morgue.yml
index 38d64ee7de..efec0f2224 100644
--- a/Resources/Prototypes/Entities/Structures/Storage/morgue.yml
+++ b/Resources/Prototypes/Entities/Structures/Storage/morgue.yml
@@ -49,6 +49,7 @@
light_soul: morgue_soul_light
- type: Transform
anchored: true
+ - type: AntiRottingContainer
- type: entity
id: MorgueTray
@@ -72,7 +73,7 @@
- type: Clickable
- type: InteractionOutline
- type: MorgueTray
-
+ - type: AntiRottingContainer
- type: entity
id: Crematorium
diff --git a/Resources/Prototypes/Entities/Structures/Wallmounts/Signs/bar_sign.yml b/Resources/Prototypes/Entities/Structures/Wallmounts/Signs/bar_sign.yml
index 00a3e2c876..3dd12a9a7e 100644
--- a/Resources/Prototypes/Entities/Structures/Wallmounts/Signs/bar_sign.yml
+++ b/Resources/Prototypes/Entities/Structures/Wallmounts/Signs/bar_sign.yml
@@ -2,6 +2,7 @@
id: BarSign
parent: BaseStructure
name: bar sign
+ suffix: Random
components:
- type: MeleeSound
soundGroups:
@@ -39,11 +40,201 @@
- type: ApcPowerReceiver
- type: ExtensionCableReceiver
- type: BarSign
+
+- type: entity
+ id: BarSignComboCafe
+ name: Combo Cafe
+ description: Renowned system-wide for their utterly uncreative drink combinations.
+ parent: BarSign
+ components:
+ - type: BarSign
+ current: ComboCafe
+
+- type: entity
+ id: BarSignEmergencyRumParty
+ name: Emergency Rum Party
+ description: Recently relicensed after a long closure.
+ parent: BarSign
+ components:
+ - type: BarSign
+ current: EmergencyRumParty
+- type: entity
+ id: BarSignLV426
+ name: LV426
+ description: Drinking with fancy facemasks is clearly more important than going to medbay.
+ parent: BarSign
+ components:
+ - type: BarSign
+ current: LV426
+
+- type: entity
+ id: BarSignMaidCafe
+ name: Maid Cafe
+ description: Welcome back, master!
+ parent: BarSign
+ components:
+ - type: BarSign
+ current: MaidCafe
+
+- type: entity
+ id: BarSignMalteseFalcon
+ name: Maltese Falcon
+ description: Play it again, sam.
+ parent: BarSign
+ components:
+ - type: BarSign
+ current: MalteseFalcon
+
+- type: entity
+ id: BarSignOfficerBeersky
+ name: Officer Beersky
+ description: Man eat a dong, these drinks are great.
+ parent: BarSign
+ components:
+ - type: BarSign
+ current: OfficerBeersky
+
+- type: entity
+ id: BarSignRobustaCafe
+ name: Robusta Cafe
+ description: Holder of the 'Most Lethal Barfights' record 5 years uncontested.
+ parent: BarSign
+ components:
+ - type: BarSign
+ current: RobustaCafe
+
+- type: entity
+ id: BarSignTheAleNath
+ name: The Ale Nath
+ description: All right, buddy. I think you've had EI NATH. Time to get a cab.
+ parent: BarSign
+ components:
+ - type: BarSign
+ current: TheAleNath
+
+- type: entity
+ id: BarSignTheBirdCage
+ name: The Bird Cage
+ description: Caw caw!
+ parent: BarSign
+ components:
+ - type: BarSign
+ current: TheBirdCage
+
+- type: entity
+ id: BarSignTheCoderbus
+ name: The Coderbus
+ description: A very controversial bar known for its wide variety of constantly-changing drinks.
+ parent: BarSign
+ components:
+ - type: BarSign
+ current: TheCoderbus
+
+- type: entity
+ id: BarSignTheDrunkCarp
+ name: The Drunk Carp
+ description: Don't drink and swim.
+ parent: BarSign
+ components:
+ - type: BarSign
+ current: TheDrunkCarp
+
- type: entity
id: BarSignEngineChange
name: The Engine Change
+ description: Still waiting.
parent: BarSign
components:
- type: BarSign
current: EngineChange
+
+- type: entity
+ id: BarSignTheHarmbaton
+ name: The Harmbaton
+ description: A great dining experience for both security members and passengers.
+ parent: BarSign
+ components:
+ - type: BarSign
+ current: Harmbaton
+
+- type: entity
+ id: BarSignTheLightbulb
+ name: The Lightbulb
+ description: A cafe popular among moths and moffs. Once shut down for a week after the bartender used mothballs to protect her spare uniforms.
+ parent: BarSign
+ components:
+ - type: BarSign
+ current: TheLightbulb
+
+- type: entity
+ id: BarSignTheLooseGoose
+ name: The Loose Goose
+ description: Drink till you puke and/or break the laws of reality!
+ parent: BarSign
+ components:
+ - type: BarSign
+ current: Goose
+
+- type: entity
+ id: BarSignTheNet
+ name: The Net
+ description: You just seem to get caught up in it for hours.
+ parent: BarSign
+ components:
+ - type: BarSign
+ current: TheNet
+
+- type: entity
+ id: BarSignTheOuterSpess
+ name: The Outer Spess
+ description: This bar isn't actually located in outer space.
+ parent: BarSign
+ components:
+ - type: BarSign
+ current: TheOuterSpess
+
+- type: entity
+ id: BarSignTheSingulo
+ name: The Singulo
+ description: Where people go that'd rather not be called by their name.
+ parent: BarSign
+ components:
+ - type: BarSign
+ current: TheSingulo
+
+- type: entity
+ id: BarSignTheSun
+ name: The Sun
+ description: Ironically bright for such a shady bar.
+ parent: BarSign
+ components:
+ - type: BarSign
+ current: TheSun
+
+- type: entity
+ id: BarSignWiggleRoom
+ name: Wiggle Room
+ description: MoMMIs got moves.
+ parent: BarSign
+ components:
+ - type: BarSign
+ current: WiggleRoom
+
+- type: entity
+ id: BarSignZocalo
+ name: Zocalo
+ description: Anteriormente ubicado en Spessmerica.
+ parent: BarSign
+ components:
+ - type: BarSign
+ current: Zocalo
+
+- type: entity
+ id: BarSignEmprah
+ name: 4 The Emprah
+ description: Enjoyed by fanatics, heretics, and brain-damaged patrons alike.
+ parent: BarSign
+ components:
+ - type: BarSign
+ current: Emprah
\ No newline at end of file
diff --git a/Resources/Prototypes/Entities/Structures/Wallmounts/air_alarm.yml b/Resources/Prototypes/Entities/Structures/Wallmounts/air_alarm.yml
index ee01601bce..d07ac4ecee 100644
--- a/Resources/Prototypes/Entities/Structures/Wallmounts/air_alarm.yml
+++ b/Resources/Prototypes/Entities/Structures/Wallmounts/air_alarm.yml
@@ -26,6 +26,7 @@
Plasma: danger # everything below is usually bad
Tritium: danger
WaterVapor: danger
+ Miasma: danger
- type: AtmosAlarmable
alarmedBy: ["AirAlarm"]
- type: AtmosDevice
diff --git a/Resources/Prototypes/Entities/Structures/Walls/walls.yml b/Resources/Prototypes/Entities/Structures/Walls/walls.yml
index 58e433de84..3b2ad757c0 100644
--- a/Resources/Prototypes/Entities/Structures/Walls/walls.yml
+++ b/Resources/Prototypes/Entities/Structures/Walls/walls.yml
@@ -96,8 +96,8 @@
components:
- type: Tag
tags:
- - Wall
- RCDDeconstructWhitelist
+ - Wall
- type: Sprite
sprite: Structures/Walls/cult.rsi
- type: Icon
diff --git a/Resources/Prototypes/Entities/Structures/base_structure.yml b/Resources/Prototypes/Entities/Structures/base_structure.yml
index 841d1839dd..a486260f88 100644
--- a/Resources/Prototypes/Entities/Structures/base_structure.yml
+++ b/Resources/Prototypes/Entities/Structures/base_structure.yml
@@ -9,7 +9,6 @@
- type: Clickable
- type: Physics
bodyType: Static
- fixedRotation: false
- type: Fixtures
fixtures:
- shape:
diff --git a/Resources/Prototypes/Entities/Structures/hydro_tray.yml b/Resources/Prototypes/Entities/Structures/hydro_tray.yml
index 5253c523e2..756d53fa70 100644
--- a/Resources/Prototypes/Entities/Structures/hydro_tray.yml
+++ b/Resources/Prototypes/Entities/Structures/hydro_tray.yml
@@ -4,8 +4,6 @@
id: hydroponicsTray
description: An interstellar-grade space farmplot allowing for rapid growth and selective breeding of crops. Just... keep in mind the space weeds.
components:
- - type: Physics
- fixedRotation: false
- type: Transform
noRot: true
- type: Fixtures
diff --git a/Resources/Prototypes/Maps/bagel.yml b/Resources/Prototypes/Maps/bagel.yml
index bfaed22f58..7acd299262 100644
--- a/Resources/Prototypes/Maps/bagel.yml
+++ b/Resources/Prototypes/Maps/bagel.yml
@@ -43,3 +43,4 @@
MedicalIntern: [ 2, 2 ]
ServiceWorker: [ 2, 2 ]
SecurityCadet: [ 2, 2 ]
+ Reporter: [ 1, 1 ]
diff --git a/Resources/Prototypes/Maps/marathon.yml b/Resources/Prototypes/Maps/marathon.yml
index 45adb69555..295f157bff 100644
--- a/Resources/Prototypes/Maps/marathon.yml
+++ b/Resources/Prototypes/Maps/marathon.yml
@@ -44,3 +44,4 @@
MedicalIntern: [ 2, 2 ]
ServiceWorker: [ 2, 2 ]
SecurityCadet: [ 2, 2 ]
+ Psychologist: [ 1, 1 ]
diff --git a/Resources/Prototypes/Reagents/biological.yml b/Resources/Prototypes/Reagents/biological.yml
index 435b599176..9f09766723 100644
--- a/Resources/Prototypes/Reagents/biological.yml
+++ b/Resources/Prototypes/Reagents/biological.yml
@@ -28,3 +28,31 @@
effects:
- !type:SatiateHunger
factor: 1.5
+
+- type: reagent
+ id: Ichor
+ name: Ichor
+ group: Biological
+ desc: An extremely potent regenerative chemical, perfected by space fauna evolution. Produced in the dragon's digestive system, it is seen as an exotic commodity due to the gargantuan effort of hunting for it.
+ physicalDesc: roaring
+ color: "#f4692e"
+ metabolisms:
+ Drink:
+ effects:
+ - !type:SatiateThirst
+ factor: 1.5
+ # Dragon doesn't require airloss healing, so omnizine is still best for humans.
+ Medicine:
+ effects:
+ - !type:HealthChange
+ damage:
+ groups:
+ Burn: -5
+ Brute: -5
+ Toxin: -2
+ types:
+ Bloodloss: -5
+ # Just in case you REALLY want to water your plants
+ plantMetabolism:
+ - !type:PlantAdjustWater
+ amount: 0.5
diff --git a/Resources/Prototypes/Reagents/fun.yml b/Resources/Prototypes/Reagents/fun.yml
index 5eff994bf3..929a6fc3a3 100644
--- a/Resources/Prototypes/Reagents/fun.yml
+++ b/Resources/Prototypes/Reagents/fun.yml
@@ -17,6 +17,14 @@
type: Local
messages: [ "carpetium-effect-blood-fibrous", "carpetium-effect-jumpsuit-insides" ]
probability: 0.1
+ # Hail the madman logic, if it has CARP, means it helps against CARPs
+ - !type:AdjustReagent
+ conditions:
+ - !type:ReagentThreshold
+ reagent: CarpoToxin
+ min: 1
+ reagent: CarpoToxin
+ amount: -3
- type: reagent
id: Fiber
diff --git a/Resources/Prototypes/Reagents/gases.yml b/Resources/Prototypes/Reagents/gases.yml
index 02ec854791..da7c940a3a 100644
--- a/Resources/Prototypes/Reagents/gases.yml
+++ b/Resources/Prototypes/Reagents/gases.yml
@@ -144,3 +144,43 @@
CarbonDioxide: 1.0
Nitrogen: -1.0
+- type: reagent
+ id: Miasma
+ name: reagent-name-miasma
+ desc: reagent-desc-miasma
+ physicalDesc: reagent-physical-desc-gaseous
+ color: "#56941E"
+ boilingPoint: -195.8
+ meltingPoint: -210.0
+ metabolisms:
+ Gas:
+ effects:
+ - !type:ChemCauseRandomDisease
+ conditions:
+ - !type:ReagentThreshold
+ reagent: Miasma
+ min: 1
+ diseases:
+ - VentCough
+ - AMIV
+ - SpaceCold
+ - SpaceFlu
+ - Bird Flew
+ - VanAusdallsRobovirus
+ - BleedersBite
+ - !type:HealthChange
+ conditions:
+ - !type:ReagentThreshold
+ reagent: Miasma
+ min: 1
+ scaleByQuantity: true
+ ignoreResistances: true
+ damage:
+ types:
+ Poison: 0.25
+ - !type:ChemVomit
+ probability: 0.12
+ conditions:
+ - !type:ReagentThreshold
+ reagent: Miasma
+ min: 0.8
diff --git a/Resources/Prototypes/Reagents/medicine.yml b/Resources/Prototypes/Reagents/medicine.yml
index 953d53216f..94c377712d 100644
--- a/Resources/Prototypes/Reagents/medicine.yml
+++ b/Resources/Prototypes/Reagents/medicine.yml
@@ -76,6 +76,18 @@
damage:
groups:
Brute: -2
+ - !type:HealthChange
+ conditions:
+ - !type:ReagentThreshold
+ min: 30
+ damage:
+ types:
+ Asphyxiation: 1
+ Poison: 0.5
+ - !type:Jitter
+ conditions:
+ - !type:ReagentThreshold
+ min: 30
- type: reagent
id: Cryoxadone
@@ -133,6 +145,19 @@
damage:
groups:
Burn: -3
+ - !type:HealthChange
+ conditions:
+ - !type:ReagentThreshold
+ min: 30
+ damage:
+ types:
+ Asphyxiation: 1
+ groups:
+ Brute: 0.5
+ - !type:Jitter
+ conditions:
+ - !type:ReagentThreshold
+ min: 30
- type: reagent
id: Dexalin
@@ -248,6 +273,19 @@
damage:
types:
Radiation: -1
+ - !type:ChemVomit
+ probability: 0.02
+ - !type:HealthChange
+ conditions:
+ - !type:ReagentThreshold
+ min: 30
+ damage:
+ types:
+ Heat: 0.5
+ - !type:Jitter
+ conditions:
+ - !type:ReagentThreshold
+ min: 30
- type: reagent
id: Ipecac
@@ -539,6 +577,7 @@
- !type:SatiateHunger
factor: -1
+ # Should heal quite literally everything, use in very small amounts
- type: reagent
id: Omnizine
name: reagent-name-omnizine
@@ -598,3 +637,4 @@
min: 1
reagent: Ultravasculine
amount: 0.5
+
diff --git a/Resources/Prototypes/Reagents/toxins.yml b/Resources/Prototypes/Reagents/toxins.yml
index b0a5485dfa..15ac3cad36 100644
--- a/Resources/Prototypes/Reagents/toxins.yml
+++ b/Resources/Prototypes/Reagents/toxins.yml
@@ -18,6 +18,30 @@
types:
Poison: 2
+- type: reagent
+ id: CarpoToxin
+ name: Carpotoxin
+ group: Toxins
+ desc: Toxic secretions of a space carp. Causes a painful burning sensation.
+ color: "#e2a38c"
+ physicalDesc: exotic-smelling
+ plantMetabolism:
+ - !type:PlantAdjustToxins
+ amount: 10
+ - !type:PlantAdjustHealth
+ amount: -5
+ metabolisms:
+ Poison:
+ effects:
+ - !type:HealthChange
+ damage:
+ types:
+ Poison: 4
+ - !type:PopupMessage
+ type: Local
+ messages: [ "generic-reagent-effect-burning-insides" ]
+ probability: 0.33
+
- type: reagent
id: PolytrinicAcid
name: reagent-name-polytrinic-acid
@@ -164,7 +188,7 @@
- !type:HealthChange
damage:
types:
- Asphyxiation: 4
+ Asphyxiation: 2
plantMetabolism:
- !type:PlantAdjustToxins
amount: 10
@@ -215,7 +239,7 @@
- !type:HealthChange
conditions:
- !type:ReagentThreshold
- min: 30
+ min: 45
damage:
groups:
Brute: 2
@@ -228,7 +252,7 @@
- !type:PopupMessage
conditions:
- !type:ReagentThreshold
- min: 30
+ min: 45
type: Local
messages: [ "histamine-effect-heavy-itchiness" ]
probability: 0.2
diff --git a/Resources/Prototypes/Recipes/Cooking/meal_recipes.yml b/Resources/Prototypes/Recipes/Cooking/meal_recipes.yml
index 88f19cef12..3003c1d265 100644
--- a/Resources/Prototypes/Recipes/Cooking/meal_recipes.yml
+++ b/Resources/Prototypes/Recipes/Cooking/meal_recipes.yml
@@ -392,6 +392,28 @@
# solids:
# FoodMeat: 1
+- type: microwaveMealRecipe
+ id: RecipeCubanCarp
+ name: cuban carp recipe
+ result: FoodMealCubancarp
+ time: 15
+ solids:
+ FoodDough: 1
+ FoodCheeseSlice: 2
+ FoodChili: 1
+ FoodMeatFish: 2
+
+- type: microwaveMealRecipe
+ id: RecipeSashimi
+ name: sashimi recipe
+ result: FoodMealCubancarp
+ time: 15
+ reagents:
+ TableSalt: 1
+ solids:
+ FoodMeatFish: 2
+
+
- type: microwaveMealRecipe
id: RecipeMisoColaSoup
name: salty sweet milocola soup recipe
diff --git a/Resources/Prototypes/Recipes/Lathes/powercells.yml b/Resources/Prototypes/Recipes/Lathes/powercells.yml
index 3d92190ea9..ab5c0b1e63 100644
--- a/Resources/Prototypes/Recipes/Lathes/powercells.yml
+++ b/Resources/Prototypes/Recipes/Lathes/powercells.yml
@@ -1,16 +1,20 @@
- type: latheRecipe
- id: PowerCellSmallStandard
- icon: Objects/Power/PowerCells/power_cell_small_st.rsi/s_st.png
- result: PowerCellSmallStandardPrinted
+ id: PowerCellSmall
+ icon:
+ sprite: Objects/Power/power_cells.rsi
+ state: small
+ result: PowerCellSmallPrinted
completetime: 1
materials:
Steel: 100
Plastic: 50
- type: latheRecipe
- id: PowerCellSmallHigh
- icon: Objects/Power/PowerCells/power_cell_small_hi.rsi/s_hi.png
- result: PowerCellSmallHighPrinted
+ id: PowerCellMedium
+ icon:
+ sprite: Objects/Power/power_cells.rsi
+ state: medium
+ result: PowerCellMediumPrinted
completetime: 6
materials:
Steel: 300
@@ -19,75 +23,14 @@
Gold: 10
- type: latheRecipe
- id: PowerCellSmallSuper
- icon: Objects/Power/PowerCells/power_cell_small_sup.rsi/s_sup.png
- result: PowerCellSmallSuperPrinted
+ id: PowerCellHigh
+ icon:
+ sprite: Objects/Power/power_cells.rsi
+ state: high
+ result: PowerCellHighPrinted
completetime: 10
materials:
Steel: 300
Glass: 400
Plastic: 200
Gold: 50
-
-# The resource required is scaled to their power capacity
-- type: latheRecipe
- id: PowerCellMediumStandard
- icon: Objects/Power/PowerCells/power_cell_medium_st.rsi/m_st.png
- result: PowerCellMediumStandardPrinted
- completetime: 1
- materials:
- Steel: 600
- Plastic: 300
-
-- type: latheRecipe
- id: PowerCellMediumHigh
- icon: Objects/Power/PowerCells/power_cell_medium_hi.rsi/m_hi.png
- result: PowerCellMediumHighPrinted
- completetime: 6
- materials:
- Steel: 1800
- Glass: 1800
- Plastic: 600
- Gold: 60
-
-- type: latheRecipe
- id: PowerCellMediumSuper
- icon: Objects/Power/PowerCells/power_cell_medium_sup.rsi/m_sup.png
- result: PowerCellMediumSuperPrinted
- completetime: 10
- materials:
- Steel: 1800
- Glass: 2400
- Plastic: 1200
- Gold: 300
-
-- type: latheRecipe
- id: PowerCellLargeStandard
- icon: Objects/Power/PowerCells/power_cell_large_st.rsi/l_st.png
- result: PowerCellLargeStandardPrinted
- completetime: 1
- materials:
- Steel: 2500
- Plastic: 1250
-
-- type: latheRecipe
- id: PowerCellLargeHigh
- icon: Objects/Power/PowerCells/power_cell_large_hi.rsi/l_hi.png
- result: PowerCellLargeHighPrinted
- completetime: 6
- materials:
- Steel: 7500
- Glass: 7500
- Plastic: 2500
- Gold: 250
-
-- type: latheRecipe
- id: PowerCellLargeSuper
- icon: Objects/Power/PowerCells/power_cell_large_sup.rsi/l_sup.png
- result: PowerCellLargeSuperPrinted
- completetime: 10
- materials:
- Steel: 7500
- Glass: 10000
- Plastic: 5000
- Gold: 1250
\ No newline at end of file
diff --git a/Resources/Prototypes/Roles/Jobs/Civilian/reporter.yml b/Resources/Prototypes/Roles/Jobs/Civilian/reporter.yml
new file mode 100644
index 0000000000..4c924a095b
--- /dev/null
+++ b/Resources/Prototypes/Roles/Jobs/Civilian/reporter.yml
@@ -0,0 +1,23 @@
+- type: job
+ id: Reporter
+ name: "reporter"
+ startingGear: ReporterGear
+ departments:
+ - Civilian
+ icon: "Reporter"
+ supervisors: "the head of personnel"
+ access:
+ - Service
+ - Maintenance
+
+- type: startingGear
+ id: ReporterGear
+ equipment:
+ jumpsuit: ClothingUniformJumpsuitReporter
+ back: ClothingBackpackFilled
+ shoes: ClothingShoesColorWhite
+ id: ReporterPDA
+ ears: ClothingHeadsetService
+ innerclothingskirt: ClothingUniformJumpsuitJournalist
+ satchel: ClothingBackpackSatchelFilled
+ duffelbag: ClothingBackpackDuffelFilled
diff --git a/Resources/Prototypes/Roles/Jobs/Medical/psychologist.yml b/Resources/Prototypes/Roles/Jobs/Medical/psychologist.yml
new file mode 100644
index 0000000000..f44112e487
--- /dev/null
+++ b/Resources/Prototypes/Roles/Jobs/Medical/psychologist.yml
@@ -0,0 +1,25 @@
+- type: job
+ id: Psychologist
+ name: "psychologist"
+ startingGear: PsychologistGear
+ departments:
+ - Medical
+ icon: "Psychologist"
+ supervisors: "the chief medical officer"
+ access:
+ - Medical
+ - Maintenance
+ extendedAccess:
+ - Chemistry
+
+- type: startingGear
+ id: PsychologistGear
+ equipment:
+ jumpsuit: ClothingUniformJumpsuitPsychologist
+ back: ClothingBackpackMedicalFilled
+ shoes: ClothingShoesLeather
+ id: PsychologistPDA
+ ears: ClothingHeadsetMedical
+ innerclothingskirt: ClothingUniformJumpsuitPsychologist
+ satchel: ClothingBackpackSatchelMedicalFilled
+ duffelbag: ClothingBackpackDuffelMedicalFilled
\ No newline at end of file
diff --git a/Resources/Prototypes/SoundCollections/alien_claw.yml b/Resources/Prototypes/SoundCollections/alien_claw.yml
new file mode 100644
index 0000000000..6e4c506faa
--- /dev/null
+++ b/Resources/Prototypes/SoundCollections/alien_claw.yml
@@ -0,0 +1,6 @@
+- type: soundCollection
+ id: AlienClaw
+ files:
+ - /Audio/Weapons/Xeno/alien_claw_flesh1.ogg
+ - /Audio/Weapons/Xeno/alien_claw_flesh2.ogg
+ - /Audio/Weapons/Xeno/alien_claw_flesh3.ogg
diff --git a/Resources/Textures/Clothing/Head/Misc/fancycrown.rsi/equipped-HELMET.png b/Resources/Textures/Clothing/Head/Misc/fancycrown.rsi/equipped-HELMET.png
new file mode 100644
index 0000000000..e44fd7e7e2
Binary files /dev/null and b/Resources/Textures/Clothing/Head/Misc/fancycrown.rsi/equipped-HELMET.png differ
diff --git a/Resources/Textures/Clothing/Head/Misc/fancycrown.rsi/icon.png b/Resources/Textures/Clothing/Head/Misc/fancycrown.rsi/icon.png
new file mode 100644
index 0000000000..f656459ea6
Binary files /dev/null and b/Resources/Textures/Clothing/Head/Misc/fancycrown.rsi/icon.png differ
diff --git a/Resources/Textures/Clothing/Head/Misc/fancycrown.rsi/meta.json b/Resources/Textures/Clothing/Head/Misc/fancycrown.rsi/meta.json
new file mode 100644
index 0000000000..5868e6f365
--- /dev/null
+++ b/Resources/Textures/Clothing/Head/Misc/fancycrown.rsi/meta.json
@@ -0,0 +1,18 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Taken from tgstation",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "icon"
+ },
+ {
+ "name": "equipped-HELMET",
+ "directions": 4
+ }
+ ]
+}
diff --git a/Resources/Textures/Clothing/Uniforms/Jumpsuit/journalist.rsi/equipped-INNERCLOTHING.png b/Resources/Textures/Clothing/Uniforms/Jumpsuit/journalist.rsi/equipped-INNERCLOTHING.png
new file mode 100644
index 0000000000..379ca3bce8
Binary files /dev/null and b/Resources/Textures/Clothing/Uniforms/Jumpsuit/journalist.rsi/equipped-INNERCLOTHING.png differ
diff --git a/Resources/Textures/Clothing/Uniforms/Jumpsuit/journalist.rsi/icon.png b/Resources/Textures/Clothing/Uniforms/Jumpsuit/journalist.rsi/icon.png
new file mode 100644
index 0000000000..70f76a475b
Binary files /dev/null and b/Resources/Textures/Clothing/Uniforms/Jumpsuit/journalist.rsi/icon.png differ
diff --git a/Resources/Textures/Clothing/Uniforms/Jumpsuit/journalist.rsi/inhand-left.png b/Resources/Textures/Clothing/Uniforms/Jumpsuit/journalist.rsi/inhand-left.png
new file mode 100644
index 0000000000..2e94292ad3
Binary files /dev/null and b/Resources/Textures/Clothing/Uniforms/Jumpsuit/journalist.rsi/inhand-left.png differ
diff --git a/Resources/Textures/Clothing/Uniforms/Jumpsuit/journalist.rsi/inhand-right.png b/Resources/Textures/Clothing/Uniforms/Jumpsuit/journalist.rsi/inhand-right.png
new file mode 100644
index 0000000000..acf07a848d
Binary files /dev/null and b/Resources/Textures/Clothing/Uniforms/Jumpsuit/journalist.rsi/inhand-right.png differ
diff --git a/Resources/Textures/Clothing/Uniforms/Jumpsuit/journalist.rsi/meta.json b/Resources/Textures/Clothing/Uniforms/Jumpsuit/journalist.rsi/meta.json
new file mode 100644
index 0000000000..d3528b0c8d
--- /dev/null
+++ b/Resources/Textures/Clothing/Uniforms/Jumpsuit/journalist.rsi/meta.json
@@ -0,0 +1,26 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Taken from vgstation at commit https://github.com/vgstation-coders/vgstation13/commit/78a56e1a22ba1d8d6023ed9bdae55a6de7fe8a39 and modified by emisse",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "icon"
+ },
+ {
+ "name": "equipped-INNERCLOTHING",
+ "directions": 4
+ },
+ {
+ "name": "inhand-left",
+ "directions": 4
+ },
+ {
+ "name": "inhand-right",
+ "directions": 4
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Resources/Textures/Clothing/Uniforms/Jumpsuit/psychologist.rsi/equipped-INNERCLOTHING.png b/Resources/Textures/Clothing/Uniforms/Jumpsuit/psychologist.rsi/equipped-INNERCLOTHING.png
new file mode 100644
index 0000000000..2b83e34216
Binary files /dev/null and b/Resources/Textures/Clothing/Uniforms/Jumpsuit/psychologist.rsi/equipped-INNERCLOTHING.png differ
diff --git a/Resources/Textures/Clothing/Uniforms/Jumpsuit/psychologist.rsi/icon.png b/Resources/Textures/Clothing/Uniforms/Jumpsuit/psychologist.rsi/icon.png
new file mode 100644
index 0000000000..e6d91f6afb
Binary files /dev/null and b/Resources/Textures/Clothing/Uniforms/Jumpsuit/psychologist.rsi/icon.png differ
diff --git a/Resources/Textures/Clothing/Uniforms/Jumpsuit/psychologist.rsi/inhand-left.png b/Resources/Textures/Clothing/Uniforms/Jumpsuit/psychologist.rsi/inhand-left.png
new file mode 100644
index 0000000000..3d5d498bba
Binary files /dev/null and b/Resources/Textures/Clothing/Uniforms/Jumpsuit/psychologist.rsi/inhand-left.png differ
diff --git a/Resources/Textures/Clothing/Uniforms/Jumpsuit/psychologist.rsi/inhand-right.png b/Resources/Textures/Clothing/Uniforms/Jumpsuit/psychologist.rsi/inhand-right.png
new file mode 100644
index 0000000000..73e19be658
Binary files /dev/null and b/Resources/Textures/Clothing/Uniforms/Jumpsuit/psychologist.rsi/inhand-right.png differ
diff --git a/Resources/Textures/Clothing/Uniforms/Jumpsuit/psychologist.rsi/meta.json b/Resources/Textures/Clothing/Uniforms/Jumpsuit/psychologist.rsi/meta.json
new file mode 100644
index 0000000000..d3528b0c8d
--- /dev/null
+++ b/Resources/Textures/Clothing/Uniforms/Jumpsuit/psychologist.rsi/meta.json
@@ -0,0 +1,26 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Taken from vgstation at commit https://github.com/vgstation-coders/vgstation13/commit/78a56e1a22ba1d8d6023ed9bdae55a6de7fe8a39 and modified by emisse",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "icon"
+ },
+ {
+ "name": "equipped-INNERCLOTHING",
+ "directions": 4
+ },
+ {
+ "name": "inhand-left",
+ "directions": 4
+ },
+ {
+ "name": "inhand-right",
+ "directions": 4
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Resources/Textures/Clothing/Uniforms/Jumpsuit/reporter.rsi/equipped-INNERCLOTHING.png b/Resources/Textures/Clothing/Uniforms/Jumpsuit/reporter.rsi/equipped-INNERCLOTHING.png
new file mode 100644
index 0000000000..88f006a555
Binary files /dev/null and b/Resources/Textures/Clothing/Uniforms/Jumpsuit/reporter.rsi/equipped-INNERCLOTHING.png differ
diff --git a/Resources/Textures/Clothing/Uniforms/Jumpsuit/reporter.rsi/icon.png b/Resources/Textures/Clothing/Uniforms/Jumpsuit/reporter.rsi/icon.png
new file mode 100644
index 0000000000..f7ab944b20
Binary files /dev/null and b/Resources/Textures/Clothing/Uniforms/Jumpsuit/reporter.rsi/icon.png differ
diff --git a/Resources/Textures/Clothing/Uniforms/Jumpsuit/reporter.rsi/inhand-left.png b/Resources/Textures/Clothing/Uniforms/Jumpsuit/reporter.rsi/inhand-left.png
new file mode 100644
index 0000000000..5f606fcde3
Binary files /dev/null and b/Resources/Textures/Clothing/Uniforms/Jumpsuit/reporter.rsi/inhand-left.png differ
diff --git a/Resources/Textures/Clothing/Uniforms/Jumpsuit/reporter.rsi/inhand-right.png b/Resources/Textures/Clothing/Uniforms/Jumpsuit/reporter.rsi/inhand-right.png
new file mode 100644
index 0000000000..aa2058812d
Binary files /dev/null and b/Resources/Textures/Clothing/Uniforms/Jumpsuit/reporter.rsi/inhand-right.png differ
diff --git a/Resources/Textures/Clothing/Uniforms/Jumpsuit/reporter.rsi/meta.json b/Resources/Textures/Clothing/Uniforms/Jumpsuit/reporter.rsi/meta.json
new file mode 100644
index 0000000000..d3528b0c8d
--- /dev/null
+++ b/Resources/Textures/Clothing/Uniforms/Jumpsuit/reporter.rsi/meta.json
@@ -0,0 +1,26 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Taken from vgstation at commit https://github.com/vgstation-coders/vgstation13/commit/78a56e1a22ba1d8d6023ed9bdae55a6de7fe8a39 and modified by emisse",
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "states": [
+ {
+ "name": "icon"
+ },
+ {
+ "name": "equipped-INNERCLOTHING",
+ "directions": 4
+ },
+ {
+ "name": "inhand-left",
+ "directions": 4
+ },
+ {
+ "name": "inhand-right",
+ "directions": 4
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Resources/Textures/Interface/Actions/carp_summon.png b/Resources/Textures/Interface/Actions/carp_summon.png
new file mode 100644
index 0000000000..15ea2ecf4c
Binary files /dev/null and b/Resources/Textures/Interface/Actions/carp_summon.png differ
diff --git a/Resources/Textures/Interface/Actions/devour.png b/Resources/Textures/Interface/Actions/devour.png
new file mode 100644
index 0000000000..d23d26ce8c
Binary files /dev/null and b/Resources/Textures/Interface/Actions/devour.png differ
diff --git a/Resources/Textures/Interface/Actions/meta.json b/Resources/Textures/Interface/Actions/meta.json
index 316ef865c0..20880fc792 100644
--- a/Resources/Textures/Interface/Actions/meta.json
+++ b/Resources/Textures/Interface/Actions/meta.json
@@ -19,11 +19,23 @@
{
"name": "disarm"
},
- {
- "name": "harm"
- },
- {
- "name": "manifest"
- }
+ {
+ "name": "harm"
+ },
+ {
+ "name": "manifest"
+ },
+ {
+ "name": "devour"
+ },
+ {
+ "name": "carp_summon"
+ },
+ {
+ "name": "ratKingArmy"
+ },
+ {
+ "name": "ratKingDomain"
+ }
]
-}
+}
\ No newline at end of file
diff --git a/Resources/Textures/Interface/Actions/ratKingArmy.png b/Resources/Textures/Interface/Actions/ratKingArmy.png
new file mode 100644
index 0000000000..fee9c2a444
Binary files /dev/null and b/Resources/Textures/Interface/Actions/ratKingArmy.png differ
diff --git a/Resources/Textures/Interface/Actions/ratKingDomain.png b/Resources/Textures/Interface/Actions/ratKingDomain.png
new file mode 100644
index 0000000000..4fbdb4d94b
Binary files /dev/null and b/Resources/Textures/Interface/Actions/ratKingDomain.png differ
diff --git a/Resources/Textures/Interface/Misc/job_icons.rsi/Psychologist.png b/Resources/Textures/Interface/Misc/job_icons.rsi/Psychologist.png
new file mode 100644
index 0000000000..f3362ed041
Binary files /dev/null and b/Resources/Textures/Interface/Misc/job_icons.rsi/Psychologist.png differ
diff --git a/Resources/Textures/Interface/Misc/job_icons.rsi/Reporter.png b/Resources/Textures/Interface/Misc/job_icons.rsi/Reporter.png
new file mode 100644
index 0000000000..679f8d4490
Binary files /dev/null and b/Resources/Textures/Interface/Misc/job_icons.rsi/Reporter.png differ
diff --git a/Resources/Textures/Interface/Misc/job_icons.rsi/meta.json b/Resources/Textures/Interface/Misc/job_icons.rsi/meta.json
index de4ba7caf8..6cd0776d09 100644
--- a/Resources/Textures/Interface/Misc/job_icons.rsi/meta.json
+++ b/Resources/Textures/Interface/Misc/job_icons.rsi/meta.json
@@ -112,6 +112,12 @@
{
"name": "Musician"
},
+ {
+ "name": "Reporter"
+ },
+ {
+ "name": "Psychologist"
+ },
{
"name": "MedicalIntern"
},
diff --git a/Resources/Textures/Markers/jobs.rsi/meta.json b/Resources/Textures/Markers/jobs.rsi/meta.json
index ea50a4cd64..50d5328c7d 100644
--- a/Resources/Textures/Markers/jobs.rsi/meta.json
+++ b/Resources/Textures/Markers/jobs.rsi/meta.json
@@ -112,6 +112,9 @@
{
"name": "mime"
},
+ {
+ "name": "reporter"
+ },
{
"name": "paramedic"
},
diff --git a/Resources/Textures/Markers/jobs.rsi/reporter.png b/Resources/Textures/Markers/jobs.rsi/reporter.png
new file mode 100644
index 0000000000..7bb31e77af
Binary files /dev/null and b/Resources/Textures/Markers/jobs.rsi/reporter.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Carps/dragon.rsi/alive-unshaded.png b/Resources/Textures/Mobs/Aliens/Carps/dragon.rsi/alive-unshaded.png
new file mode 100644
index 0000000000..4d11267792
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Carps/dragon.rsi/alive-unshaded.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Carps/dragon.rsi/alive.png b/Resources/Textures/Mobs/Aliens/Carps/dragon.rsi/alive.png
new file mode 100644
index 0000000000..0d9baa9d8e
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Carps/dragon.rsi/alive.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Carps/dragon.rsi/crit.png b/Resources/Textures/Mobs/Aliens/Carps/dragon.rsi/crit.png
new file mode 100644
index 0000000000..1fe5d25437
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Carps/dragon.rsi/crit.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Carps/dragon.rsi/dead-unshaded.png b/Resources/Textures/Mobs/Aliens/Carps/dragon.rsi/dead-unshaded.png
new file mode 100644
index 0000000000..df41900b88
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Carps/dragon.rsi/dead-unshaded.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Carps/dragon.rsi/dead.png b/Resources/Textures/Mobs/Aliens/Carps/dragon.rsi/dead.png
new file mode 100644
index 0000000000..d9c8d55905
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Carps/dragon.rsi/dead.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Carps/dragon.rsi/meta.json b/Resources/Textures/Mobs/Aliens/Carps/dragon.rsi/meta.json
new file mode 100644
index 0000000000..b29668aed9
--- /dev/null
+++ b/Resources/Textures/Mobs/Aliens/Carps/dragon.rsi/meta.json
@@ -0,0 +1,80 @@
+{
+ "version": 1,
+ "size": {
+ "x": 64,
+ "y": 64
+ },
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Taken from /tg/station at https://github.com/Toastgoats/tgstation/commit/024a840eed2a1be3f72435c2bb39faac8025f822",
+ "states": [
+ {
+ "name": "alive",
+ "directions": 4,
+ "delays": [
+ [
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2
+ ],
+ [
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2
+ ],
+ [
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2
+ ],
+ [
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2
+ ]
+ ]
+ },
+ {
+ "name": "alive-unshaded",
+ "directions": 4,
+ "delays": [
+ [
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2
+ ],
+ [
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2
+ ],
+ [
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2
+ ],
+ [
+ 0.2,
+ 0.2,
+ 0.2,
+ 0.2
+ ]
+ ]
+ },
+ {
+ "name": "crit"
+ },
+ {
+ "name": "dead"
+ },
+ {
+ "name": "dead-unshaded"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/drone.rsi/crit.png b/Resources/Textures/Mobs/Aliens/Xenos/drone.rsi/crit.png
new file mode 100644
index 0000000000..744b543e41
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Xenos/drone.rsi/crit.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/drone.rsi/dead.png b/Resources/Textures/Mobs/Aliens/Xenos/drone.rsi/dead.png
new file mode 100644
index 0000000000..44673b4948
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Xenos/drone.rsi/dead.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/drone.rsi/meta.json b/Resources/Textures/Mobs/Aliens/Xenos/drone.rsi/meta.json
new file mode 100644
index 0000000000..d175e4aa89
--- /dev/null
+++ b/Resources/Textures/Mobs/Aliens/Xenos/drone.rsi/meta.json
@@ -0,0 +1,24 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "https://gitlab.com/cmdevs/colonial-warfare/-/tree/dev/icons/mob/xenonids",
+ "size": {
+ "x": 48,
+ "y": 48
+ },
+ "states": [
+ {
+ "name": "running",
+ "directions": 4
+ },
+ {
+ "name": "sleeping"
+ },
+ {
+ "name": "crit"
+ },
+ {
+ "name": "dead"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/drone.rsi/running.png b/Resources/Textures/Mobs/Aliens/Xenos/drone.rsi/running.png
new file mode 100644
index 0000000000..d04c987191
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Xenos/drone.rsi/running.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/drone.rsi/sleeping.png b/Resources/Textures/Mobs/Aliens/Xenos/drone.rsi/sleeping.png
new file mode 100644
index 0000000000..79a352a649
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Xenos/drone.rsi/sleeping.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/praetorian.rsi/crit.png b/Resources/Textures/Mobs/Aliens/Xenos/praetorian.rsi/crit.png
new file mode 100644
index 0000000000..a2b941fa0f
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Xenos/praetorian.rsi/crit.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/praetorian.rsi/dead.png b/Resources/Textures/Mobs/Aliens/Xenos/praetorian.rsi/dead.png
new file mode 100644
index 0000000000..95e1dd001d
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Xenos/praetorian.rsi/dead.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/praetorian.rsi/meta.json b/Resources/Textures/Mobs/Aliens/Xenos/praetorian.rsi/meta.json
new file mode 100644
index 0000000000..e9f98745bc
--- /dev/null
+++ b/Resources/Textures/Mobs/Aliens/Xenos/praetorian.rsi/meta.json
@@ -0,0 +1,24 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "https://gitlab.com/cmdevs/colonial-warfare/-/blob/dev/icons/mob/xenonids/praetorian.dmi",
+ "size": {
+ "x": 64,
+ "y": 64
+ },
+ "states": [
+ {
+ "name": "running",
+ "directions": 4
+ },
+ {
+ "name": "sleeping"
+ },
+ {
+ "name": "crit"
+ },
+ {
+ "name": "dead"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/praetorian.rsi/running.png b/Resources/Textures/Mobs/Aliens/Xenos/praetorian.rsi/running.png
new file mode 100644
index 0000000000..83236cf152
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Xenos/praetorian.rsi/running.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/praetorian.rsi/sleeping.png b/Resources/Textures/Mobs/Aliens/Xenos/praetorian.rsi/sleeping.png
new file mode 100644
index 0000000000..8e7616ee8e
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Xenos/praetorian.rsi/sleeping.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/queen.rsi/crit.png b/Resources/Textures/Mobs/Aliens/Xenos/queen.rsi/crit.png
new file mode 100644
index 0000000000..97fd948177
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Xenos/queen.rsi/crit.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/queen.rsi/dead.png b/Resources/Textures/Mobs/Aliens/Xenos/queen.rsi/dead.png
new file mode 100644
index 0000000000..c04eddbac5
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Xenos/queen.rsi/dead.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/queen.rsi/meta.json b/Resources/Textures/Mobs/Aliens/Xenos/queen.rsi/meta.json
new file mode 100644
index 0000000000..19161ee8fa
--- /dev/null
+++ b/Resources/Textures/Mobs/Aliens/Xenos/queen.rsi/meta.json
@@ -0,0 +1,24 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "https://gitlab.com/cmdevs/colonial-warfare/-/tree/dev/icons/mob/xenonids",
+ "size": {
+ "x": 64,
+ "y": 64
+ },
+ "states": [
+ {
+ "name": "running",
+ "directions": 4
+ },
+ {
+ "name": "sleeping"
+ },
+ {
+ "name": "crit"
+ },
+ {
+ "name": "dead"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/queen.rsi/running.png b/Resources/Textures/Mobs/Aliens/Xenos/queen.rsi/running.png
new file mode 100644
index 0000000000..a7b39bf9d1
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Xenos/queen.rsi/running.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/queen.rsi/sleeping.png b/Resources/Textures/Mobs/Aliens/Xenos/queen.rsi/sleeping.png
new file mode 100644
index 0000000000..59b0248e90
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Xenos/queen.rsi/sleeping.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/ravager.rsi/crit.png b/Resources/Textures/Mobs/Aliens/Xenos/ravager.rsi/crit.png
new file mode 100644
index 0000000000..c0319d89fc
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Xenos/ravager.rsi/crit.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/ravager.rsi/dead.png b/Resources/Textures/Mobs/Aliens/Xenos/ravager.rsi/dead.png
new file mode 100644
index 0000000000..fe3a6351d8
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Xenos/ravager.rsi/dead.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/ravager.rsi/meta.json b/Resources/Textures/Mobs/Aliens/Xenos/ravager.rsi/meta.json
new file mode 100644
index 0000000000..19161ee8fa
--- /dev/null
+++ b/Resources/Textures/Mobs/Aliens/Xenos/ravager.rsi/meta.json
@@ -0,0 +1,24 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "https://gitlab.com/cmdevs/colonial-warfare/-/tree/dev/icons/mob/xenonids",
+ "size": {
+ "x": 64,
+ "y": 64
+ },
+ "states": [
+ {
+ "name": "running",
+ "directions": 4
+ },
+ {
+ "name": "sleeping"
+ },
+ {
+ "name": "crit"
+ },
+ {
+ "name": "dead"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/ravager.rsi/running.png b/Resources/Textures/Mobs/Aliens/Xenos/ravager.rsi/running.png
new file mode 100644
index 0000000000..56019b47d9
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Xenos/ravager.rsi/running.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/ravager.rsi/sleeping.png b/Resources/Textures/Mobs/Aliens/Xenos/ravager.rsi/sleeping.png
new file mode 100644
index 0000000000..a0cc012cca
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Xenos/ravager.rsi/sleeping.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/rouny.rsi/crit.png b/Resources/Textures/Mobs/Aliens/Xenos/rouny.rsi/crit.png
new file mode 100644
index 0000000000..0be8b9b1dd
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Xenos/rouny.rsi/crit.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/rouny.rsi/dead.png b/Resources/Textures/Mobs/Aliens/Xenos/rouny.rsi/dead.png
new file mode 100644
index 0000000000..2761d22dbf
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Xenos/rouny.rsi/dead.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/rouny.rsi/meta.json b/Resources/Textures/Mobs/Aliens/Xenos/rouny.rsi/meta.json
new file mode 100644
index 0000000000..ce2209e72d
--- /dev/null
+++ b/Resources/Textures/Mobs/Aliens/Xenos/rouny.rsi/meta.json
@@ -0,0 +1,24 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "https://github.com/tgstation/TerraGov-Marine-Corps/blob/a2034543920664ddf0c0f3c681bf1d8003dc2ade/icons/Xeno/2x2_Xenos.dmi",
+ "size": {
+ "x": 64,
+ "y": 64
+ },
+ "states": [
+ {
+ "name": "running",
+ "directions": 4
+ },
+ {
+ "name": "sleeping"
+ },
+ {
+ "name": "dead"
+ },
+ {
+ "name": "crit"
+ }
+ ]
+}
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/rouny.rsi/running.png b/Resources/Textures/Mobs/Aliens/Xenos/rouny.rsi/running.png
new file mode 100644
index 0000000000..2bbe1c603e
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Xenos/rouny.rsi/running.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/rouny.rsi/sleeping.png b/Resources/Textures/Mobs/Aliens/Xenos/rouny.rsi/sleeping.png
new file mode 100644
index 0000000000..06ff2250d0
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Xenos/rouny.rsi/sleeping.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/runner.rsi/crit.png b/Resources/Textures/Mobs/Aliens/Xenos/runner.rsi/crit.png
new file mode 100644
index 0000000000..42b91bf970
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Xenos/runner.rsi/crit.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/runner.rsi/dead.png b/Resources/Textures/Mobs/Aliens/Xenos/runner.rsi/dead.png
new file mode 100644
index 0000000000..b253f3a5a4
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Xenos/runner.rsi/dead.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/runner.rsi/meta.json b/Resources/Textures/Mobs/Aliens/Xenos/runner.rsi/meta.json
new file mode 100644
index 0000000000..19161ee8fa
--- /dev/null
+++ b/Resources/Textures/Mobs/Aliens/Xenos/runner.rsi/meta.json
@@ -0,0 +1,24 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "https://gitlab.com/cmdevs/colonial-warfare/-/tree/dev/icons/mob/xenonids",
+ "size": {
+ "x": 64,
+ "y": 64
+ },
+ "states": [
+ {
+ "name": "running",
+ "directions": 4
+ },
+ {
+ "name": "sleeping"
+ },
+ {
+ "name": "crit"
+ },
+ {
+ "name": "dead"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/runner.rsi/running.png b/Resources/Textures/Mobs/Aliens/Xenos/runner.rsi/running.png
new file mode 100644
index 0000000000..a76129f2dd
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Xenos/runner.rsi/running.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/runner.rsi/sleeping.png b/Resources/Textures/Mobs/Aliens/Xenos/runner.rsi/sleeping.png
new file mode 100644
index 0000000000..303473a4ec
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Xenos/runner.rsi/sleeping.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/spitter.rsi/crit.png b/Resources/Textures/Mobs/Aliens/Xenos/spitter.rsi/crit.png
new file mode 100644
index 0000000000..5d64c5988a
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Xenos/spitter.rsi/crit.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/spitter.rsi/dead.png b/Resources/Textures/Mobs/Aliens/Xenos/spitter.rsi/dead.png
new file mode 100644
index 0000000000..de9b13ccfe
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Xenos/spitter.rsi/dead.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/spitter.rsi/meta.json b/Resources/Textures/Mobs/Aliens/Xenos/spitter.rsi/meta.json
new file mode 100644
index 0000000000..d175e4aa89
--- /dev/null
+++ b/Resources/Textures/Mobs/Aliens/Xenos/spitter.rsi/meta.json
@@ -0,0 +1,24 @@
+{
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "https://gitlab.com/cmdevs/colonial-warfare/-/tree/dev/icons/mob/xenonids",
+ "size": {
+ "x": 48,
+ "y": 48
+ },
+ "states": [
+ {
+ "name": "running",
+ "directions": 4
+ },
+ {
+ "name": "sleeping"
+ },
+ {
+ "name": "crit"
+ },
+ {
+ "name": "dead"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/spitter.rsi/running.png b/Resources/Textures/Mobs/Aliens/Xenos/spitter.rsi/running.png
new file mode 100644
index 0000000000..ed27b7a21a
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Xenos/spitter.rsi/running.png differ
diff --git a/Resources/Textures/Mobs/Aliens/Xenos/spitter.rsi/sleeping.png b/Resources/Textures/Mobs/Aliens/Xenos/spitter.rsi/sleeping.png
new file mode 100644
index 0000000000..fe12bb11ba
Binary files /dev/null and b/Resources/Textures/Mobs/Aliens/Xenos/spitter.rsi/sleeping.png differ
diff --git a/Resources/Textures/Mobs/Animals/mouse.rsi/dead-3.png b/Resources/Textures/Mobs/Animals/mouse.rsi/dead-3.png
new file mode 100644
index 0000000000..63c0d553ac
Binary files /dev/null and b/Resources/Textures/Mobs/Animals/mouse.rsi/dead-3.png differ
diff --git a/Resources/Textures/Mobs/Animals/mouse.rsi/icon-3.png b/Resources/Textures/Mobs/Animals/mouse.rsi/icon-3.png
new file mode 100644
index 0000000000..19c758da48
Binary files /dev/null and b/Resources/Textures/Mobs/Animals/mouse.rsi/icon-3.png differ
diff --git a/Resources/Textures/Mobs/Animals/mouse.rsi/meta.json b/Resources/Textures/Mobs/Animals/mouse.rsi/meta.json
index 20f5439e93..b144e0e973 100644
--- a/Resources/Textures/Mobs/Animals/mouse.rsi/meta.json
+++ b/Resources/Textures/Mobs/Animals/mouse.rsi/meta.json
@@ -15,6 +15,9 @@
},
{
"name": "icon-2"
+ },
+ {
+ "name": "icon-3"
},
{
"name": "mouse-0",
@@ -93,6 +96,32 @@
0.2
]
]
+ },
+ {
+ "name": "mouse-3",
+ "directions": 4,
+ "delays": [
+ [
+ 0.2,
+ 0.2,
+ 0.2
+ ],
+ [
+ 0.2,
+ 0.2,
+ 0.2
+ ],
+ [
+ 0.2,
+ 0.2,
+ 0.2
+ ],
+ [
+ 0.2,
+ 0.2,
+ 0.2
+ ]
+ ]
},
{
"name": "dead-0"
@@ -102,6 +131,9 @@
},
{
"name": "dead-2"
+ },
+ {
+ "name": "dead-3"
},
{
"name": "splat-0"
@@ -111,6 +143,9 @@
},
{
"name": "splat-2"
+ },
+ {
+ "name": "splat-3"
},
{
"name": "0-equipped-HELMET",
diff --git a/Resources/Textures/Mobs/Animals/mouse.rsi/mouse-3.png b/Resources/Textures/Mobs/Animals/mouse.rsi/mouse-3.png
new file mode 100644
index 0000000000..6f98406802
Binary files /dev/null and b/Resources/Textures/Mobs/Animals/mouse.rsi/mouse-3.png differ
diff --git a/Resources/Textures/Mobs/Animals/mouse.rsi/splat-3.png b/Resources/Textures/Mobs/Animals/mouse.rsi/splat-3.png
new file mode 100644
index 0000000000..057e71d6aa
Binary files /dev/null and b/Resources/Textures/Mobs/Animals/mouse.rsi/splat-3.png differ
diff --git a/Resources/Textures/Mobs/Animals/regalrat.rsi/dead.png b/Resources/Textures/Mobs/Animals/regalrat.rsi/dead.png
new file mode 100644
index 0000000000..83c8014fda
Binary files /dev/null and b/Resources/Textures/Mobs/Animals/regalrat.rsi/dead.png differ
diff --git a/Resources/Textures/Mobs/Animals/regalrat.rsi/icon.png b/Resources/Textures/Mobs/Animals/regalrat.rsi/icon.png
new file mode 100644
index 0000000000..601624ced4
Binary files /dev/null and b/Resources/Textures/Mobs/Animals/regalrat.rsi/icon.png differ
diff --git a/Resources/Textures/Mobs/Animals/regalrat.rsi/meta.json b/Resources/Textures/Mobs/Animals/regalrat.rsi/meta.json
new file mode 100644
index 0000000000..98a5d7e891
--- /dev/null
+++ b/Resources/Textures/Mobs/Animals/regalrat.rsi/meta.json
@@ -0,0 +1,21 @@
+{
+ "version": 1,
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Taken from https://github.com/tgstation/tgstation/commit/53d1f1477d22a11a99c6c6924977cd431075761b",
+ "states": [
+ {
+ "name": "dead"
+ },
+ {
+ "name": "icon"
+ },
+ {
+ "name": "regalrat",
+ "directions": 4
+ }
+ ]
+}
diff --git a/Resources/Textures/Mobs/Animals/regalrat.rsi/regalrat.png b/Resources/Textures/Mobs/Animals/regalrat.rsi/regalrat.png
new file mode 100644
index 0000000000..340c0b46dd
Binary files /dev/null and b/Resources/Textures/Mobs/Animals/regalrat.rsi/regalrat.png differ
diff --git a/Resources/Textures/Objects/Consumable/Food/meat.rsi/dragon.png b/Resources/Textures/Objects/Consumable/Food/meat.rsi/dragon.png
new file mode 100644
index 0000000000..9a85807e24
Binary files /dev/null and b/Resources/Textures/Objects/Consumable/Food/meat.rsi/dragon.png differ
diff --git a/Resources/Textures/Objects/Consumable/Food/meat.rsi/dragon_veins.png b/Resources/Textures/Objects/Consumable/Food/meat.rsi/dragon_veins.png
new file mode 100644
index 0000000000..6b35cc5900
Binary files /dev/null and b/Resources/Textures/Objects/Consumable/Food/meat.rsi/dragon_veins.png differ
diff --git a/Resources/Textures/Objects/Consumable/Food/meat.rsi/meta.json b/Resources/Textures/Objects/Consumable/Food/meat.rsi/meta.json
index 5a34066758..79eb49da9f 100644
--- a/Resources/Textures/Objects/Consumable/Food/meat.rsi/meta.json
+++ b/Resources/Textures/Objects/Consumable/Food/meat.rsi/meta.json
@@ -170,6 +170,12 @@
},
{
"name": "xeno"
+ },
+ {
+ "name": "dragon"
+ },
+ {
+ "name": "dragon_veins"
}
]
}
diff --git a/Resources/Textures/Objects/Devices/pda.rsi/meta.json b/Resources/Textures/Objects/Devices/pda.rsi/meta.json
index f92f0672ed..dc89c59d69 100644
--- a/Resources/Textures/Objects/Devices/pda.rsi/meta.json
+++ b/Resources/Textures/Objects/Devices/pda.rsi/meta.json
@@ -145,6 +145,9 @@
{
"name": "pda-musician"
},
+ {
+ "name": "pda-reporter"
+ },
{
"name": "pda-interncadet"
},
diff --git a/Resources/Textures/Objects/Devices/pda.rsi/pda-reporter.png b/Resources/Textures/Objects/Devices/pda.rsi/pda-reporter.png
new file mode 100644
index 0000000000..d932722546
Binary files /dev/null and b/Resources/Textures/Objects/Devices/pda.rsi/pda-reporter.png differ
diff --git a/Resources/Textures/Objects/Misc/id_cards.rsi/idpassenger.png b/Resources/Textures/Objects/Misc/id_cards.rsi/idpassenger.png
index bb13533c0c..88866eb169 100644
Binary files a/Resources/Textures/Objects/Misc/id_cards.rsi/idpassenger.png and b/Resources/Textures/Objects/Misc/id_cards.rsi/idpassenger.png differ
diff --git a/Resources/Textures/Objects/Misc/id_cards.rsi/idpsychologist.png b/Resources/Textures/Objects/Misc/id_cards.rsi/idpsychologist.png
new file mode 100644
index 0000000000..038a5321d4
Binary files /dev/null and b/Resources/Textures/Objects/Misc/id_cards.rsi/idpsychologist.png differ
diff --git a/Resources/Textures/Objects/Misc/id_cards.rsi/idreporter.png b/Resources/Textures/Objects/Misc/id_cards.rsi/idreporter.png
new file mode 100644
index 0000000000..e4ea4f9588
Binary files /dev/null and b/Resources/Textures/Objects/Misc/id_cards.rsi/idreporter.png differ
diff --git a/Resources/Textures/Objects/Misc/id_cards.rsi/meta.json b/Resources/Textures/Objects/Misc/id_cards.rsi/meta.json
index 49ae5369fa..185ea7fa83 100644
--- a/Resources/Textures/Objects/Misc/id_cards.rsi/meta.json
+++ b/Resources/Textures/Objects/Misc/id_cards.rsi/meta.json
@@ -103,6 +103,12 @@
{
"name": "idparamedic"
},
+ {
+ "name": "idpsychologist"
+ },
+ {
+ "name": "idreporter"
+ },
{
"name": "idprisoner"
},
diff --git a/Resources/Textures/Objects/Power/PowerCells/potato_battery.rsi/meta.json b/Resources/Textures/Objects/Power/PowerCells/potato_battery.rsi/meta.json
deleted file mode 100644
index 71a7f31af1..0000000000
--- a/Resources/Textures/Objects/Power/PowerCells/potato_battery.rsi/meta.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "version": 1,
- "size": {
- "x": 32,
- "y": 32
- },
- "license": "CC-BY-SA-3.0",
- "copyright": "https://github.com/tgstation/tgstation/commit/7dcdbc1468ffdc8689b984cb6b181d48ae41dbf2",
- "states": [
- {
- "name": "potato_battery",
-
- }
- ]
-}
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hi.rsi/l_hi.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hi.rsi/l_hi.png
deleted file mode 100644
index 24319ba7b6..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hi.rsi/l_hi.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hi.rsi/l_hi_0.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hi.rsi/l_hi_0.png
deleted file mode 100644
index 7f189021e5..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hi.rsi/l_hi_0.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hi.rsi/l_hi_100.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hi.rsi/l_hi_100.png
deleted file mode 100644
index 7500ff37b6..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hi.rsi/l_hi_100.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hi.rsi/l_hi_25.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hi.rsi/l_hi_25.png
deleted file mode 100644
index 9ec9c4a60f..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hi.rsi/l_hi_25.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hi.rsi/l_hi_50.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hi.rsi/l_hi_50.png
deleted file mode 100644
index e78b3016f9..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hi.rsi/l_hi_50.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hi.rsi/l_hi_75.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hi.rsi/l_hi_75.png
deleted file mode 100644
index 0e1badd891..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hi.rsi/l_hi_75.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hi.rsi/meta.json b/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hi.rsi/meta.json
deleted file mode 100644
index 2d9343f885..0000000000
--- a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hi.rsi/meta.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
- "version": 1,
- "size": {
- "x": 32,
- "y": 32
- },
- "license": "CC-BY-SA-3.0",
- "copyright": "Taken from https://github.com/discordia-space/CEV-Eris/",
- "states": [
- {
- "name": "l_hi",
-
- },
- {
- "name": "l_hi_0",
- "delays": [
- [
- 0.2,
- 0.2
- ]
- ]
- },
- {
- "name": "l_hi_100",
-
- },
- {
- "name": "l_hi_25",
-
- },
- {
- "name": "l_hi_50",
-
- },
- {
- "name": "l_hi_75",
-
- }
- ]
-}
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hy.rsi/l_hy.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hy.rsi/l_hy.png
deleted file mode 100644
index 4f6aaee081..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hy.rsi/l_hy.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hy.rsi/l_hy_0.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hy.rsi/l_hy_0.png
deleted file mode 100644
index 7969203665..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hy.rsi/l_hy_0.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hy.rsi/l_hy_100.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hy.rsi/l_hy_100.png
deleted file mode 100644
index 97c6df65ae..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hy.rsi/l_hy_100.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hy.rsi/l_hy_25.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hy.rsi/l_hy_25.png
deleted file mode 100644
index b4d7074179..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hy.rsi/l_hy_25.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hy.rsi/l_hy_50.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hy.rsi/l_hy_50.png
deleted file mode 100644
index fb1540d6b3..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hy.rsi/l_hy_50.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hy.rsi/l_hy_75.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hy.rsi/l_hy_75.png
deleted file mode 100644
index 7de1faebd2..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hy.rsi/l_hy_75.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hy.rsi/meta.json b/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hy.rsi/meta.json
deleted file mode 100644
index 53734ad567..0000000000
--- a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_hy.rsi/meta.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
- "version": 1,
- "size": {
- "x": 32,
- "y": 32
- },
- "license": "CC-BY-SA-3.0",
- "copyright": "Taken from https://github.com/discordia-space/CEV-Eris/",
- "states": [
- {
- "name": "l_hy",
-
- },
- {
- "name": "l_hy_0",
- "delays": [
- [
- 0.2,
- 0.2
- ]
- ]
- },
- {
- "name": "l_hy_100",
-
- },
- {
- "name": "l_hy_25",
-
- },
- {
- "name": "l_hy_50",
-
- },
- {
- "name": "l_hy_75",
-
- }
- ]
-}
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_st.rsi/l_st.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_large_st.rsi/l_st.png
deleted file mode 100644
index bbe727eea7..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_st.rsi/l_st.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_st.rsi/l_st_0.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_large_st.rsi/l_st_0.png
deleted file mode 100644
index e87e324901..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_st.rsi/l_st_0.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_st.rsi/l_st_100.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_large_st.rsi/l_st_100.png
deleted file mode 100644
index d5f070f7c4..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_st.rsi/l_st_100.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_st.rsi/l_st_25.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_large_st.rsi/l_st_25.png
deleted file mode 100644
index a15d4eac39..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_st.rsi/l_st_25.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_st.rsi/l_st_50.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_large_st.rsi/l_st_50.png
deleted file mode 100644
index a10e8e9126..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_st.rsi/l_st_50.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_st.rsi/l_st_75.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_large_st.rsi/l_st_75.png
deleted file mode 100644
index 5d62807d25..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_st.rsi/l_st_75.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_st.rsi/meta.json b/Resources/Textures/Objects/Power/PowerCells/power_cell_large_st.rsi/meta.json
deleted file mode 100644
index e1ef25e8ad..0000000000
--- a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_st.rsi/meta.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
- "version": 1,
- "size": {
- "x": 32,
- "y": 32
- },
- "license": "CC-BY-SA-3.0",
- "copyright": "Taken from https://github.com/discordia-space/CEV-Eris/",
- "states": [
- {
- "name": "l_st",
-
- },
- {
- "name": "l_st_0",
- "delays": [
- [
- 0.2,
- 0.2
- ]
- ]
- },
- {
- "name": "l_st_100",
-
- },
- {
- "name": "l_st_25",
-
- },
- {
- "name": "l_st_50",
-
- },
- {
- "name": "l_st_75",
-
- }
- ]
-}
\ No newline at end of file
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_sup.rsi/l_sup.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_large_sup.rsi/l_sup.png
deleted file mode 100644
index b19282034e..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_sup.rsi/l_sup.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_sup.rsi/l_sup_0.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_large_sup.rsi/l_sup_0.png
deleted file mode 100644
index 099a6cb151..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_sup.rsi/l_sup_0.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_sup.rsi/l_sup_100.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_large_sup.rsi/l_sup_100.png
deleted file mode 100644
index f21fd15b25..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_sup.rsi/l_sup_100.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_sup.rsi/l_sup_25.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_large_sup.rsi/l_sup_25.png
deleted file mode 100644
index d6180813b4..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_sup.rsi/l_sup_25.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_sup.rsi/l_sup_50.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_large_sup.rsi/l_sup_50.png
deleted file mode 100644
index 93a0899293..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_sup.rsi/l_sup_50.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_sup.rsi/l_sup_75.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_large_sup.rsi/l_sup_75.png
deleted file mode 100644
index 25191ae890..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_sup.rsi/l_sup_75.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_sup.rsi/meta.json b/Resources/Textures/Objects/Power/PowerCells/power_cell_large_sup.rsi/meta.json
deleted file mode 100644
index be0c0e1ed1..0000000000
--- a/Resources/Textures/Objects/Power/PowerCells/power_cell_large_sup.rsi/meta.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
- "version": 1,
- "size": {
- "x": 32,
- "y": 32
- },
- "license": "CC-BY-SA-3.0",
- "copyright": "Taken from https://github.com/discordia-space/CEV-Eris/",
- "states": [
- {
- "name": "l_sup",
-
- },
- {
- "name": "l_sup_0",
- "delays": [
- [
- 0.2,
- 0.2
- ]
- ]
- },
- {
- "name": "l_sup_100",
-
- },
- {
- "name": "l_sup_25",
-
- },
- {
- "name": "l_sup_50",
-
- },
- {
- "name": "l_sup_75",
-
- }
- ]
-}
\ No newline at end of file
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hi.rsi/m_hi.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hi.rsi/m_hi.png
deleted file mode 100644
index 45f00d2a64..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hi.rsi/m_hi.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hi.rsi/m_hi_0.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hi.rsi/m_hi_0.png
deleted file mode 100644
index 023a923808..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hi.rsi/m_hi_0.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hi.rsi/m_hi_100.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hi.rsi/m_hi_100.png
deleted file mode 100644
index 5f73abd4f0..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hi.rsi/m_hi_100.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hi.rsi/m_hi_25.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hi.rsi/m_hi_25.png
deleted file mode 100644
index bccefded5d..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hi.rsi/m_hi_25.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hi.rsi/m_hi_50.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hi.rsi/m_hi_50.png
deleted file mode 100644
index 6069362b2b..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hi.rsi/m_hi_50.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hi.rsi/m_hi_75.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hi.rsi/m_hi_75.png
deleted file mode 100644
index 1b59115d33..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hi.rsi/m_hi_75.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hi.rsi/meta.json b/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hi.rsi/meta.json
deleted file mode 100644
index 6f99c41d68..0000000000
--- a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hi.rsi/meta.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
- "version": 1,
- "size": {
- "x": 32,
- "y": 32
- },
- "license": "CC-BY-SA-3.0",
- "copyright": "Taken from https://github.com/discordia-space/CEV-Eris/",
- "states": [
- {
- "name": "m_hi",
-
- },
- {
- "name": "m_hi_0",
- "delays": [
- [
- 0.2,
- 0.2
- ]
- ]
- },
- {
- "name": "m_hi_100",
-
- },
- {
- "name": "m_hi_25",
-
- },
- {
- "name": "m_hi_50",
-
- },
- {
- "name": "m_hi_75",
-
- }
- ]
-}
\ No newline at end of file
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hy.rsi/m_hy.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hy.rsi/m_hy.png
deleted file mode 100644
index 99b9d25e87..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hy.rsi/m_hy.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hy.rsi/m_hy_0.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hy.rsi/m_hy_0.png
deleted file mode 100644
index e87acc3dcd..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hy.rsi/m_hy_0.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hy.rsi/m_hy_100.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hy.rsi/m_hy_100.png
deleted file mode 100644
index 18c2cdbf0f..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hy.rsi/m_hy_100.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hy.rsi/m_hy_25.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hy.rsi/m_hy_25.png
deleted file mode 100644
index fbf162abc2..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hy.rsi/m_hy_25.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hy.rsi/m_hy_50.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hy.rsi/m_hy_50.png
deleted file mode 100644
index 3ec152d2e4..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hy.rsi/m_hy_50.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hy.rsi/m_hy_75.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hy.rsi/m_hy_75.png
deleted file mode 100644
index aec9b65dca..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hy.rsi/m_hy_75.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hy.rsi/meta.json b/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hy.rsi/meta.json
deleted file mode 100644
index d5b2771be5..0000000000
--- a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_hy.rsi/meta.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
- "version": 1,
- "size": {
- "x": 32,
- "y": 32
- },
- "license": "CC-BY-SA-3.0",
- "copyright": "Taken from https://github.com/discordia-space/CEV-Eris/",
- "states": [
- {
- "name": "m_hy",
-
- },
- {
- "name": "m_hy_0",
- "delays": [
- [
- 0.2,
- 0.2
- ]
- ]
- },
- {
- "name": "m_hy_100",
-
- },
- {
- "name": "m_hy_25",
-
- },
- {
- "name": "m_hy_50",
-
- },
- {
- "name": "m_hy_75",
-
- }
- ]
-}
\ No newline at end of file
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_st.rsi/m_st.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_st.rsi/m_st.png
deleted file mode 100644
index fa74c07965..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_st.rsi/m_st.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_st.rsi/m_st_0.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_st.rsi/m_st_0.png
deleted file mode 100644
index d9df7bb487..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_st.rsi/m_st_0.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_st.rsi/m_st_100.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_st.rsi/m_st_100.png
deleted file mode 100644
index b00811e0c0..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_st.rsi/m_st_100.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_st.rsi/m_st_25.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_st.rsi/m_st_25.png
deleted file mode 100644
index 797a8f8189..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_st.rsi/m_st_25.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_st.rsi/m_st_50.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_st.rsi/m_st_50.png
deleted file mode 100644
index 5756932076..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_st.rsi/m_st_50.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_st.rsi/m_st_75.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_st.rsi/m_st_75.png
deleted file mode 100644
index 0ac081dcaf..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_st.rsi/m_st_75.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_st.rsi/meta.json b/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_st.rsi/meta.json
deleted file mode 100644
index e6f88e7e5d..0000000000
--- a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_st.rsi/meta.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
- "version": 1,
- "size": {
- "x": 32,
- "y": 32
- },
- "license": "CC-BY-SA-3.0",
- "copyright": "Taken from https://github.com/discordia-space/CEV-Eris/",
- "states": [
- {
- "name": "m_st",
-
- },
- {
- "name": "m_st_0",
- "delays": [
- [
- 0.2,
- 0.2
- ]
- ]
- },
- {
- "name": "m_st_100",
-
- },
- {
- "name": "m_st_25",
-
- },
- {
- "name": "m_st_50",
-
- },
- {
- "name": "m_st_75",
-
- }
- ]
-}
\ No newline at end of file
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_sup.rsi/m_sup.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_sup.rsi/m_sup.png
deleted file mode 100644
index a966f9ad4a..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_sup.rsi/m_sup.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_sup.rsi/m_sup_0.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_sup.rsi/m_sup_0.png
deleted file mode 100644
index 43a174574c..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_sup.rsi/m_sup_0.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_sup.rsi/m_sup_100.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_sup.rsi/m_sup_100.png
deleted file mode 100644
index 3d38694cb6..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_sup.rsi/m_sup_100.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_sup.rsi/m_sup_25.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_sup.rsi/m_sup_25.png
deleted file mode 100644
index e6172f39a7..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_sup.rsi/m_sup_25.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_sup.rsi/m_sup_50.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_sup.rsi/m_sup_50.png
deleted file mode 100644
index 56b6bef020..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_sup.rsi/m_sup_50.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_sup.rsi/m_sup_75.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_sup.rsi/m_sup_75.png
deleted file mode 100644
index 1f90ad41d9..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_sup.rsi/m_sup_75.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_sup.rsi/meta.json b/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_sup.rsi/meta.json
deleted file mode 100644
index 9eee5bb770..0000000000
--- a/Resources/Textures/Objects/Power/PowerCells/power_cell_medium_sup.rsi/meta.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
- "version": 1,
- "size": {
- "x": 32,
- "y": 32
- },
- "license": "CC-BY-SA-3.0",
- "copyright": "Taken from https://github.com/discordia-space/CEV-Eris/",
- "states": [
- {
- "name": "m_sup",
-
- },
- {
- "name": "m_sup_0",
- "delays": [
- [
- 0.2,
- 0.2
- ]
- ]
- },
- {
- "name": "m_sup_100",
-
- },
- {
- "name": "m_sup_25",
-
- },
- {
- "name": "m_sup_50",
-
- },
- {
- "name": "m_sup_75",
-
- }
- ]
-}
\ No newline at end of file
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_autorecharge.rsi/meta.json b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_autorecharge.rsi/meta.json
deleted file mode 100644
index ef93a794cf..0000000000
--- a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_autorecharge.rsi/meta.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
- "version": 1,
- "size": {
- "x": 32,
- "y": 32
- },
- "license": "CC-BY-SA-3.0",
- "copyright": "https://github.com/discordia-space/CEV-Eris/blob/master/icons/obj/power_cells.dmi",
- "states": [
- {
- "name": "s_ar",
-
- },
- {
- "name": "s_ar_0",
- "delays": [
- [
- 0.2,
- 0.2
- ]
- ]
- },
- {
- "name": "s_ar_100",
-
- },
- {
- "name": "s_ar_25",
-
- },
- {
- "name": "s_ar_50",
-
- },
- {
- "name": "s_ar_75",
-
- }
- ]
-}
\ No newline at end of file
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_autorecharge.rsi/s_ar.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_autorecharge.rsi/s_ar.png
deleted file mode 100644
index fec988a177..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_autorecharge.rsi/s_ar.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_autorecharge.rsi/s_ar_0.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_autorecharge.rsi/s_ar_0.png
deleted file mode 100644
index d619413512..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_autorecharge.rsi/s_ar_0.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_autorecharge.rsi/s_ar_100.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_autorecharge.rsi/s_ar_100.png
deleted file mode 100644
index 179172cf96..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_autorecharge.rsi/s_ar_100.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_autorecharge.rsi/s_ar_25.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_autorecharge.rsi/s_ar_25.png
deleted file mode 100644
index 49e5340fbb..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_autorecharge.rsi/s_ar_25.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_autorecharge.rsi/s_ar_50.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_autorecharge.rsi/s_ar_50.png
deleted file mode 100644
index 4d1042d449..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_autorecharge.rsi/s_ar_50.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_autorecharge.rsi/s_ar_75.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_autorecharge.rsi/s_ar_75.png
deleted file mode 100644
index dee613303f..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_autorecharge.rsi/s_ar_75.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hi.rsi/meta.json b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hi.rsi/meta.json
deleted file mode 100644
index 68e2ca9153..0000000000
--- a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hi.rsi/meta.json
+++ /dev/null
@@ -1 +0,0 @@
-{"version": 1, "size": {"x": 32, "y": 32}, "license": "CC-BY-SA-3.0", "copyright": "Taken from https://github.com/discordia-space/CEV-Eris at commit 9a3a3a180344460263e8df7ea2565128e07b86b5", "states": [{"name": "s_hi", "delays": [[1.0]]}, {"name": "s_hi_0", "delays": [[0.2, 0.2]]}, {"name": "s_hi_100", "delays": [[1.0]]}, {"name": "s_hi_25", "delays": [[1.0]]}, {"name": "s_hi_50", "delays": [[1.0]]}, {"name": "s_hi_75", "delays": [[1.0]]}]}
\ No newline at end of file
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hi.rsi/s_hi.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hi.rsi/s_hi.png
deleted file mode 100644
index 0393d1131a..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hi.rsi/s_hi.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hi.rsi/s_hi_0.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hi.rsi/s_hi_0.png
deleted file mode 100644
index dd1b92ce1b..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hi.rsi/s_hi_0.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hi.rsi/s_hi_100.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hi.rsi/s_hi_100.png
deleted file mode 100644
index 1b8c8d515e..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hi.rsi/s_hi_100.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hi.rsi/s_hi_25.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hi.rsi/s_hi_25.png
deleted file mode 100644
index 5af6d17664..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hi.rsi/s_hi_25.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hi.rsi/s_hi_50.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hi.rsi/s_hi_50.png
deleted file mode 100644
index b738cb0250..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hi.rsi/s_hi_50.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hi.rsi/s_hi_75.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hi.rsi/s_hi_75.png
deleted file mode 100644
index b7a6380255..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hi.rsi/s_hi_75.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hy.rsi/meta.json b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hy.rsi/meta.json
deleted file mode 100644
index f5694ced90..0000000000
--- a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hy.rsi/meta.json
+++ /dev/null
@@ -1 +0,0 @@
-{"version": 1, "size": {"x": 32, "y": 32}, "license": "CC-BY-SA-3.0", "copyright": "Taken from https://github.com/discordia-space/CEV-Eris at commit 9a3a3a180344460263e8df7ea2565128e07b86b5", "states": [{"name": "s_hy", "delays": [[1.0]]}, {"name": "s_hy_0", "delays": [[0.2, 0.2]]}, {"name": "s_hy_100", "delays": [[1.0]]}, {"name": "s_hy_25", "delays": [[1.0]]}, {"name": "s_hy_50", "delays": [[1.0]]}, {"name": "s_hy_75", "delays": [[1.0]]}]}
\ No newline at end of file
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hy.rsi/s_hy.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hy.rsi/s_hy.png
deleted file mode 100644
index 9daf4f0008..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hy.rsi/s_hy.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hy.rsi/s_hy_0.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hy.rsi/s_hy_0.png
deleted file mode 100644
index 18c8b885c0..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hy.rsi/s_hy_0.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hy.rsi/s_hy_100.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hy.rsi/s_hy_100.png
deleted file mode 100644
index 6e87d55d2b..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hy.rsi/s_hy_100.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hy.rsi/s_hy_25.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hy.rsi/s_hy_25.png
deleted file mode 100644
index 46f46328d0..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hy.rsi/s_hy_25.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hy.rsi/s_hy_50.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hy.rsi/s_hy_50.png
deleted file mode 100644
index 8faafe600a..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hy.rsi/s_hy_50.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hy.rsi/s_hy_75.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hy.rsi/s_hy_75.png
deleted file mode 100644
index a0ce4bbfbe..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_hy.rsi/s_hy_75.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_st.rsi/meta.json b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_st.rsi/meta.json
deleted file mode 100644
index de99aab706..0000000000
--- a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_st.rsi/meta.json
+++ /dev/null
@@ -1 +0,0 @@
-{"version": 1, "size": {"x": 32, "y": 32}, "license": "CC-BY-SA-3.0", "copyright": "Taken from https://github.com/discordia-space/CEV-Eris at commit 9a3a3a180344460263e8df7ea2565128e07b86b5", "states": [{"name": "s_st", "delays": [[1.0]]}, {"name": "s_st_0", "delays": [[0.2, 0.2]]}, {"name": "s_st_100", "delays": [[1.0]]}, {"name": "s_st_25", "delays": [[1.0]]}, {"name": "s_st_50", "delays": [[1.0]]}, {"name": "s_st_75", "delays": [[1.0]]}]}
\ No newline at end of file
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_st.rsi/s_st.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_st.rsi/s_st.png
deleted file mode 100644
index 7942c24471..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_st.rsi/s_st.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_st.rsi/s_st_0.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_st.rsi/s_st_0.png
deleted file mode 100644
index 4484d0df68..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_st.rsi/s_st_0.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_st.rsi/s_st_100.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_st.rsi/s_st_100.png
deleted file mode 100644
index d1de9c09ac..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_st.rsi/s_st_100.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_st.rsi/s_st_25.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_st.rsi/s_st_25.png
deleted file mode 100644
index 3ed8e64f9c..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_st.rsi/s_st_25.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_st.rsi/s_st_50.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_st.rsi/s_st_50.png
deleted file mode 100644
index 69c46ce946..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_st.rsi/s_st_50.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_st.rsi/s_st_75.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_st.rsi/s_st_75.png
deleted file mode 100644
index 27bad16031..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_st.rsi/s_st_75.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_sup.rsi/meta.json b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_sup.rsi/meta.json
deleted file mode 100644
index 79ed6e45a2..0000000000
--- a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_sup.rsi/meta.json
+++ /dev/null
@@ -1 +0,0 @@
-{"version": 1, "size": {"x": 32, "y": 32}, "license": "CC-BY-SA-3.0", "copyright": "Taken from https://github.com/discordia-space/CEV-Eris at commit 9a3a3a180344460263e8df7ea2565128e07b86b5", "states": [{"name": "s_sup", "delays": [[1.0]]}, {"name": "s_sup_0", "delays": [[0.2, 0.2]]}, {"name": "s_sup_100", "delays": [[1.0]]}, {"name": "s_sup_25", "delays": [[1.0]]}, {"name": "s_sup_50", "delays": [[1.0]]}, {"name": "s_sup_75", "delays": [[1.0]]}]}
\ No newline at end of file
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_sup.rsi/s_sup.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_sup.rsi/s_sup.png
deleted file mode 100644
index 4bb892e29d..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_sup.rsi/s_sup.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_sup.rsi/s_sup_0.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_sup.rsi/s_sup_0.png
deleted file mode 100644
index 615a56bb7b..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_sup.rsi/s_sup_0.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_sup.rsi/s_sup_100.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_sup.rsi/s_sup_100.png
deleted file mode 100644
index 2113bc0ffd..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_sup.rsi/s_sup_100.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_sup.rsi/s_sup_25.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_sup.rsi/s_sup_25.png
deleted file mode 100644
index 1a6f6dded8..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_sup.rsi/s_sup_25.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_sup.rsi/s_sup_50.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_sup.rsi/s_sup_50.png
deleted file mode 100644
index 0850afe461..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_sup.rsi/s_sup_50.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_sup.rsi/s_sup_75.png b/Resources/Textures/Objects/Power/PowerCells/power_cell_small_sup.rsi/s_sup_75.png
deleted file mode 100644
index b2f57efdd0..0000000000
Binary files a/Resources/Textures/Objects/Power/PowerCells/power_cell_small_sup.rsi/s_sup_75.png and /dev/null differ
diff --git a/Resources/Textures/Objects/Power/power_cells.rsi/antique.png b/Resources/Textures/Objects/Power/power_cells.rsi/antique.png
new file mode 100644
index 0000000000..e8fbf6f287
Binary files /dev/null and b/Resources/Textures/Objects/Power/power_cells.rsi/antique.png differ
diff --git a/Resources/Textures/Objects/Power/power_cells.rsi/high.png b/Resources/Textures/Objects/Power/power_cells.rsi/high.png
new file mode 100644
index 0000000000..966d10dcab
Binary files /dev/null and b/Resources/Textures/Objects/Power/power_cells.rsi/high.png differ
diff --git a/Resources/Textures/Objects/Power/power_cells.rsi/hyper.png b/Resources/Textures/Objects/Power/power_cells.rsi/hyper.png
new file mode 100644
index 0000000000..c2af41fc06
Binary files /dev/null and b/Resources/Textures/Objects/Power/power_cells.rsi/hyper.png differ
diff --git a/Resources/Textures/Objects/Power/power_cells.rsi/medium.png b/Resources/Textures/Objects/Power/power_cells.rsi/medium.png
new file mode 100644
index 0000000000..f231a622a7
Binary files /dev/null and b/Resources/Textures/Objects/Power/power_cells.rsi/medium.png differ
diff --git a/Resources/Textures/Objects/Power/power_cells.rsi/meta.json b/Resources/Textures/Objects/Power/power_cells.rsi/meta.json
new file mode 100644
index 0000000000..01c2300621
--- /dev/null
+++ b/Resources/Textures/Objects/Power/power_cells.rsi/meta.json
@@ -0,0 +1,38 @@
+{
+ "version": 1,
+ "size": {
+ "x": 32,
+ "y": 32
+ },
+ "license": "CC-BY-SA-3.0",
+ "copyright": "https://github.com/tgstation/tgstation/commit/7dcdbc1468ffdc8689b984cb6b181d48ae41dbf2",
+ "states": [
+ {
+ "name": "potato"
+ },
+ {
+ "name": "small"
+ },
+ {
+ "name": "medium"
+ },
+ {
+ "name": "high"
+ },
+ {
+ "name": "hyper"
+ },
+ {
+ "name": "microreactor"
+ },
+ {
+ "name": "antique"
+ },
+ {
+ "name": "o1"
+ },
+ {
+ "name": "o2"
+ }
+ ]
+}
diff --git a/Resources/Textures/Objects/Power/power_cells.rsi/microreactor.png b/Resources/Textures/Objects/Power/power_cells.rsi/microreactor.png
new file mode 100644
index 0000000000..d9e0f6d59f
Binary files /dev/null and b/Resources/Textures/Objects/Power/power_cells.rsi/microreactor.png differ
diff --git a/Resources/Textures/Objects/Power/power_cells.rsi/o1.png b/Resources/Textures/Objects/Power/power_cells.rsi/o1.png
new file mode 100644
index 0000000000..7d28199193
Binary files /dev/null and b/Resources/Textures/Objects/Power/power_cells.rsi/o1.png differ
diff --git a/Resources/Textures/Objects/Power/power_cells.rsi/o2.png b/Resources/Textures/Objects/Power/power_cells.rsi/o2.png
new file mode 100644
index 0000000000..33c2be42d7
Binary files /dev/null and b/Resources/Textures/Objects/Power/power_cells.rsi/o2.png differ
diff --git a/Resources/Textures/Objects/Power/PowerCells/potato_battery.rsi/potato_battery.png b/Resources/Textures/Objects/Power/power_cells.rsi/potato.png
similarity index 100%
rename from Resources/Textures/Objects/Power/PowerCells/potato_battery.rsi/potato_battery.png
rename to Resources/Textures/Objects/Power/power_cells.rsi/potato.png
diff --git a/Resources/Textures/Objects/Power/power_cells.rsi/small.png b/Resources/Textures/Objects/Power/power_cells.rsi/small.png
new file mode 100644
index 0000000000..32feddb0da
Binary files /dev/null and b/Resources/Textures/Objects/Power/power_cells.rsi/small.png differ
diff --git a/Resources/Textures/Objects/Weapons/Guns/Battery/laser_gun.rsi/meta.json b/Resources/Textures/Objects/Weapons/Guns/Battery/laser_gun.rsi/meta.json
index 033d627581..da85b7e10f 100644
--- a/Resources/Textures/Objects/Weapons/Guns/Battery/laser_gun.rsi/meta.json
+++ b/Resources/Textures/Objects/Weapons/Guns/Battery/laser_gun.rsi/meta.json
@@ -1,7 +1,7 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
- "copyright": "Taken from Polaris at https://github.com/PolarisSS13/Polaris/commits/master?after=edb54f137d6ac4ca06fb76b36dc5c603f92586b8+104&branch=master&path%5B%5D=icons&path%5B%5D=obj&path%5B%5D=gun.dmi&qualified_name=refs%2Fheads%2Fmaster",
+ "copyright": "Taken from Polaris at https://github.com/PolarisSS13/Polaris/commit/9ded73fb85b9106d6bbf1c9a34d1d2fa27ee0e2e",
"size": {
"x": 32,
"y": 32
diff --git a/Resources/Textures/Objects/Weapons/Guns/Rifles/carbine.rsi/meta.json b/Resources/Textures/Objects/Weapons/Guns/Rifles/carbine.rsi/meta.json
index 7b90c1abec..c98adde97d 100644
--- a/Resources/Textures/Objects/Weapons/Guns/Rifles/carbine.rsi/meta.json
+++ b/Resources/Textures/Objects/Weapons/Guns/Rifles/carbine.rsi/meta.json
@@ -1,7 +1,7 @@
{
"version": 1,
- "license": "GNU Affero General Public License version 3",
- "copyright": "Taken from The World Server at https://github.com/TheNick5527/The-World-Server/commit/91677c25160ccc0265f84189d2cd1ed44bc39742",
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Taken from Polaris at https://github.com/PolarisSS13/Polaris/commit/ff87150c3dfc387c46db7d1c956abf19ddff7819",
"size": {
"x": 32,
"y": 32
diff --git a/Resources/Textures/Objects/Weapons/Guns/Rifles/lecter.rsi/base.png b/Resources/Textures/Objects/Weapons/Guns/Rifles/lecter.rsi/base.png
index 02d1e9e24f..fc6d6f78db 100644
Binary files a/Resources/Textures/Objects/Weapons/Guns/Rifles/lecter.rsi/base.png and b/Resources/Textures/Objects/Weapons/Guns/Rifles/lecter.rsi/base.png differ
diff --git a/Resources/Textures/Objects/Weapons/Guns/Rifles/lecter.rsi/icon.png b/Resources/Textures/Objects/Weapons/Guns/Rifles/lecter.rsi/icon.png
index da2084c375..9e6d62d34f 100644
Binary files a/Resources/Textures/Objects/Weapons/Guns/Rifles/lecter.rsi/icon.png and b/Resources/Textures/Objects/Weapons/Guns/Rifles/lecter.rsi/icon.png differ
diff --git a/Resources/Textures/Objects/Weapons/Guns/Rifles/lecter.rsi/mag-0.png b/Resources/Textures/Objects/Weapons/Guns/Rifles/lecter.rsi/mag-0.png
index a19c870efa..ce87258d82 100644
Binary files a/Resources/Textures/Objects/Weapons/Guns/Rifles/lecter.rsi/mag-0.png and b/Resources/Textures/Objects/Weapons/Guns/Rifles/lecter.rsi/mag-0.png differ
diff --git a/Resources/Textures/Objects/Weapons/Guns/Rifles/lecter.rsi/meta.json b/Resources/Textures/Objects/Weapons/Guns/Rifles/lecter.rsi/meta.json
index 9a0a79a7a5..4c54091b28 100644
--- a/Resources/Textures/Objects/Weapons/Guns/Rifles/lecter.rsi/meta.json
+++ b/Resources/Textures/Objects/Weapons/Guns/Rifles/lecter.rsi/meta.json
@@ -1,28 +1,28 @@
{
- "version": 1,
- "license": "CC-BY-SA-3.0",
- "copyright": "Taken/modified from cev-eris at https://github.com/discordia-space/CEV-Eris/raw/56cbafd6ad8c013ccd5472d6c4a0db790f7f872a/icons/obj/guns/projectile/wintermute.dmi",
- "size": {
- "x": 32,
- "y": 32
- },
- "states": [
- {
- "name": "icon"
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Taken/modified from tgstation at https://github.com/tgstation/tgstation/pull/41393/commits/1e56473177d0994d163c9edca3d13d6e5b640cc4",
+ "size": {
+ "x": 32,
+ "y": 32
},
- {
- "name": "base"
- },
- {
- "name": "mag-0"
- },
- {
- "name": "inhand-left",
- "directions": 4
- },
- {
- "name": "inhand-right",
- "directions": 4
- }
- ]
+ "states": [
+ {
+ "name": "icon"
+ },
+ {
+ "name": "base"
+ },
+ {
+ "name": "mag-0"
+ },
+ {
+ "name": "inhand-left",
+ "directions": 4
+ },
+ {
+ "name": "inhand-right",
+ "directions": 4
+ }
+ ]
}
diff --git a/Resources/Textures/Objects/Weapons/Melee/combat_knife.rsi/icon.png b/Resources/Textures/Objects/Weapons/Melee/combat_knife.rsi/icon.png
index da1c4d5a80..0bb7498e95 100644
Binary files a/Resources/Textures/Objects/Weapons/Melee/combat_knife.rsi/icon.png and b/Resources/Textures/Objects/Weapons/Melee/combat_knife.rsi/icon.png differ
diff --git a/Resources/Textures/Objects/Weapons/Melee/combat_knife.rsi/meta.json b/Resources/Textures/Objects/Weapons/Melee/combat_knife.rsi/meta.json
index 5068e960f6..08894a12a7 100644
--- a/Resources/Textures/Objects/Weapons/Melee/combat_knife.rsi/meta.json
+++ b/Resources/Textures/Objects/Weapons/Melee/combat_knife.rsi/meta.json
@@ -1,7 +1,7 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
- "copyright": "Taken/modified from Cev-Eris at https://github.com/discordia-space/CEV-Eris/pull/4712/commits/f8baeca66b8af61347186f887bed20431ea8180f",
+ "copyright": "Taken/modified from desertrose at https://github.com/DesertRose2/desertrose/pull/378/commits/9e081bd2a0d7614be5a9dabbca34886ce204105d",
"size": {
"x": 32,
"y": 32
diff --git a/Resources/Textures/Objects/Weapons/Melee/kitchen_knife.rsi/icon.png b/Resources/Textures/Objects/Weapons/Melee/kitchen_knife.rsi/icon.png
index 03da75b454..4a9e66b72a 100644
Binary files a/Resources/Textures/Objects/Weapons/Melee/kitchen_knife.rsi/icon.png and b/Resources/Textures/Objects/Weapons/Melee/kitchen_knife.rsi/icon.png differ
diff --git a/Resources/Textures/Objects/Weapons/Melee/kitchen_knife.rsi/meta.json b/Resources/Textures/Objects/Weapons/Melee/kitchen_knife.rsi/meta.json
index 9fac57fa05..08894a12a7 100644
--- a/Resources/Textures/Objects/Weapons/Melee/kitchen_knife.rsi/meta.json
+++ b/Resources/Textures/Objects/Weapons/Melee/kitchen_knife.rsi/meta.json
@@ -1,26 +1,26 @@
{
- "version": 1,
- "license": "CC-BY-SA-3.0",
- "copyright": "Taken from cev-eris at https://github.com/discordia-space/CEV-Eris/commit/baeadc0388aba2e74106f99b1551a465b825e3b1",
- "size": {
- "x": 32,
- "y": 32
- },
- "states": [
- {
- "name": "icon"
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Taken/modified from desertrose at https://github.com/DesertRose2/desertrose/pull/378/commits/9e081bd2a0d7614be5a9dabbca34886ce204105d",
+ "size": {
+ "x": 32,
+ "y": 32
},
- {
- "name": "inhand-left",
- "directions": 4
- },
- {
- "name": "inhand-right",
- "directions": 4
- },
- {
- "name": "equipped-BELT",
- "directions": 4
- }
- ]
+ "states": [
+ {
+ "name": "icon"
+ },
+ {
+ "name": "inhand-left",
+ "directions": 4
+ },
+ {
+ "name": "inhand-right",
+ "directions": 4
+ },
+ {
+ "name": "equipped-BELT",
+ "directions": 4
+ }
+ ]
}
diff --git a/Resources/Textures/Objects/Weapons/Melee/machete.rsi/icon.png b/Resources/Textures/Objects/Weapons/Melee/machete.rsi/icon.png
index 0f99f31a9f..8c426b9b26 100644
Binary files a/Resources/Textures/Objects/Weapons/Melee/machete.rsi/icon.png and b/Resources/Textures/Objects/Weapons/Melee/machete.rsi/icon.png differ
diff --git a/Resources/Textures/Objects/Weapons/Melee/machete.rsi/meta.json b/Resources/Textures/Objects/Weapons/Melee/machete.rsi/meta.json
index ae93abf331..069cee5a70 100644
--- a/Resources/Textures/Objects/Weapons/Melee/machete.rsi/meta.json
+++ b/Resources/Textures/Objects/Weapons/Melee/machete.rsi/meta.json
@@ -1,7 +1,7 @@
{
"version": 1,
"license": "CC-BY-NC-SA-3.0",
- "copyright": "Taken from goonstation and modified by Taral at https://github.com/goonstation/goonstation/pull/6094/commits/c8b97b970d189e566f63b74c6b453b016a5391c5",
+ "copyright": "Taken from Baystation12 and modified by Taral at https://github.com/Baystation12/Baystation12/pull/29841/commits/57265cd89e6b66b9a67915172f60bbbeacbeced0",
"size": {
"x": 32,
"y": 32
diff --git a/Resources/Textures/Objects/Weapons/Melee/pickaxe.rsi/meta.json b/Resources/Textures/Objects/Weapons/Melee/pickaxe.rsi/meta.json
index 483c049a3d..8179728a35 100644
--- a/Resources/Textures/Objects/Weapons/Melee/pickaxe.rsi/meta.json
+++ b/Resources/Textures/Objects/Weapons/Melee/pickaxe.rsi/meta.json
@@ -1,22 +1,22 @@
{
- "version": 1,
- "license": "CC-BY-SA-3.0",
- "copyright": "Taken from cev-eris at https://github.com/discordia-space/CEV-Eris/commit/740ff31a81313086cf16761f3677cf1e2ab46c93",
- "size": {
- "x": 32,
- "y": 32
- },
- "states": [
- {
- "name": "inhand-left",
- "directions": 4
+ "version": 1,
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/pull/29929/commits/8c0509a4725602d0be2e9a7b29b556a39fb5cca2",
+ "size": {
+ "x": 32,
+ "y": 32
},
- {
- "name": "inhand-right",
- "directions": 4
- },
- {
- "name": "pickaxe"
- }
- ]
+ "states": [
+ {
+ "name": "inhand-left",
+ "directions": 4
+ },
+ {
+ "name": "inhand-right",
+ "directions": 4
+ },
+ {
+ "name": "pickaxe"
+ }
+ ]
}
diff --git a/Resources/Textures/Objects/Weapons/Melee/pickaxe.rsi/pickaxe.png b/Resources/Textures/Objects/Weapons/Melee/pickaxe.rsi/pickaxe.png
index a157fd81f7..a8fc9a58b0 100644
Binary files a/Resources/Textures/Objects/Weapons/Melee/pickaxe.rsi/pickaxe.png and b/Resources/Textures/Objects/Weapons/Melee/pickaxe.rsi/pickaxe.png differ
diff --git a/RobustToolbox b/RobustToolbox
index a03eecaa36..0dfd71c990 160000
--- a/RobustToolbox
+++ b/RobustToolbox
@@ -1 +1 @@
-Subproject commit a03eecaa36aa9f83931ba53cde0063cf1886c829
+Subproject commit 0dfd71c990e4e3afaf390f9706ee547a69b76168